code:
App.Intro.acquisition = function() {
	const el = new DocumentFragment();

	const valueOwed = (V.saveImported === 1) ? 5000 : 50000;

	const r = [];

	if (_.isArray(V.careerBonusNeeded)) {
		V.slaves.filter(s => V.careerBonusNeeded.includes(s.ID)).forEach(App.StartingGirls.applyCareerBonus);
		delete V.careerBonusNeeded;
		delete V.applyCareerBonus;
	}
	V.slaves.filter(s => s.origin === "$auto").forEach(x => App.StartingGirls.playerOrigin(x).apply());

	if (V.freshPC === 1 || V.saveImported === 0) {
		PCSetup();
	}

	parentSetup();
	inbreedingCalc();
	if (V.plot === 1 && V.neighboringArcologies > 0) {
		V.arcologies.reduce((acc, val) => (val.direction !== 0 && val.prosperity > acc.prosperity) ? val : acc, V.arcologies[1]).rival = 1;
		V.rival.state = 2;
	}
	V.targetAge = V.minimumSlaveAge;
	V.targetAgeNursery = V.minimumSlaveAge;
	resetFamilyCounters();

	App.UI.DOM.appendNewElement("p", el, "You've done it.");
	App.UI.DOM.appendNewElement("p", el, `You arrive at your new arcology, ${V.arcologies[0].name}, and head straight to the penthouse to enter the access codes that will tell the ${V.arcologies[0].name} systems to recognize you as their owner. The penthouse office is ready to receive the codes, and they authenticate. A voice activates in your earpiece.`);
	App.UI.DOM.appendNewElement("p", el, `Congratulations. I am a personal assistant program, and it is my pleasure to assist you, ${PlayerName()} the new owner of ${V.arcologies[0].name}. I will offer useful information whenever possible in italics. Your new arcology has some unusual equipment. The previous owner kept a small stable of sex slaves. The penthouse therefore has a body modification studio for tattooing, bleaching and piercing, and an auto salon for more prosaic things like hair care. It also has a remote surgery, a small surgical theater that can be operated remotely by a qualified surgeon if you can pay the fee. Finally, it has a slave nutrition system connected to the arcology's hydroponics bays. This system produces a tasty protein-rich drink that provides the physically active female body all its necessary nutrients while leaving the lower digestive tract extremely clean. It even causes a mild increase in sex drive.`, "note");

	r.push(`The previous owner seems to have left in something of a hurry.`);
	let valueGiven = 0;
	if (V.cheatMode === 1) {
		r.push(`Since you've elected to take over an arcology with special advantages, you've acquired a very special group of slaves.`);
		r.push(App.Intro.cheatModeSlaves());
	} else if (V.saveImported === 1) {
		r.push(`Since it took some time for you to ensure that your existing stable of slaves were safely moved to ${V.arcologies[0].name}, the previous owner had the time to get most of their things away.`);
	} else if ((V.targetArcology.fs !== "New") && (V.targetArcology.fs !== "FSNull")) {
		for (let j = 0; j < 5; j++) {
			if (valueOwed - valueGiven <= 5000) {
				break;
			}
			const slave = generateFSSlave(V.targetArcology.fs);
			const slaveCostValue = slaveCost(slave);
			if (["FSAztecRevivalist", "FSChineseRevivalist", "FSNeoImperialist", "FSRestart", "FSSlaveProfessionalism"].includes(V.targetArcology.fs)) {
				valueGiven += slaveCostValue * 4;
			} else {
				valueGiven += slaveCostValue;
			}
			newSlave(slave);
		}
		const {He, his, girl} = getPronouns(V.slaves.random());
		switch (V.targetArcology.fs) {
			case "FSSupremacist":
				r.push(`They kept a personal stable of fearful ${V.arcologies[0].FSSupremacistRace} sex slaves, but their sexual training is incomplete. Several of them are still here.`);
				break;
			case "FSSubjugationist":
				r.push(`They made it a special goal to enslave and whore out as many ${V.arcologies[0].FSSubjugationistRace} people as possible. Several of them are still here.`);
				break;
			case "FSGenderRadicalist":
				r.push(`They were in the process of building a stable of pretty young shemale whores. Several of them are still here. They're are all very attracted to men, and skilled at pleasing them.`);
				break;
			case "FSGenderFundamentalist":
				r.push(`They kept a personal stable of slaves for breeding purposes. Several of them are still here. They've been kept pregnant, and work as servants when they aren't being bred.`);
				break;
			case "FSPaternalist":
				r.push(`Their slaves were all very well treated. Several of them are still here. They were allowed to work as maids, and weren't even forced to have sex.`);
				break;
			case "FSDegradationist":
				r.push(`Their personal slaves were all Fuckdolls, slaves who have been permanently encased in advanced latex suits and converted into living sex toys. Several of them are still here.`);
				break;
			case "FSAssetExpansionist":
				r.push(`They kept a collection of bejeweled boobs for company, but they focused on breast expansion to the exclusion the slaves' emotional training. Several of them are still here.`);
				break;
			case "FSSlimnessEnthusiast":
				r.push(`They kept a harem of slim, pretty girls, and treated them very well. Several of them are still here. They should be very trusting of a new owner.`);
				break;
			case "FSTransformationFetishist":
				r.push(`They were just putting the finishing touches on a planned brothel's worth of surgically enhanced whores. Several of them are still here. They are already used to prostitution.`);
				break;
			case "FSBodyPurist":
				r.push(`Their slaves were trained for sexual use, but their health, fitness, and natural appearance were the main priorities. Several of them are still here.`);
				break;
			case "FSMaturityPreferentialist":
				r.push(`They preferred to keep their MILFs as scantily clad servants. Several of them are still here. They aren't all happy to be sex objects, but they're used to it.`);
				break;
			case "FSYouthPreferentialist":
				r.push(`They treated their young slaves very well. Several of them are still here. Virgins have been carefully preserved, but have learned to use their mouths through experience.`);
				break;
			case "FSPastoralist":
				r.push(`Their herd of cow girls was progressing nicely, though more progress had been made on milk production than on training. Several of them are still here.`);
				break;
			case "FSPhysicalIdealist":
				r.push(`Their slaves worked as prostitutes, but mostly to fund a program of muscle building for all of them, which was nearing completion. Several of them are still here.`);
				break;
			case "FSChattelReligionist":
				r.push(`They were recruiting a stable of slave whores by targeting people with religious complexes that made them particularly vulnerable to recruitment. Several of them are still here.`);
				break;
			case "FSRomanRevivalist":
				r.push(`The only one of their slaves left is the bodyguard. ${He} should be very willing to transfer ${his} loyalty to you, as ${his} new owner.`);
				break;
			case "FSNeoImperialist":
				r.push(`This arcology kept their Knights as actively enslaved and docile servants; you find one of them remaining here. ${He} immediately pledges ${his} loyalty over to you.`);
				break;
			case "FSAztecRevivalist":
				r.push(`They maintained a combination of disobedient slaves, deemed incorrigible and blood priestesses. Since they offer themselves as slaves willingly, one has remained loyal to the owner of the arcology.`);
				break;
			case "FSEgyptianRevivalist":
				r.push(`They kept a harem of beautiful slave girls, who have been well-treated and well-trained. They should be very willing to serve you in turn.`);
				break;
			case "FSEdoRevivalist":
				r.push(`They put considerable effort into creating modern slave geisha, elegant Japanese slaves who were assigned to serve the public. Several of them are still here.`);
				break;
			case "FSArabianRevivalist":
				r.push(`They trained slaves personally, and never kept slaves for very long. The slaves they left are all partway through being trained.`);
				break;
			case "FSChineseRevivalist":
				r.push(`The only one of their slaves left is the Head Girl. ${He} should be willing to transfer ${his} loyalty to you, as ${his} proper superior.`);
				break;
			case "FSRestart":
				r.push(`The only one of their slaves left is an absolute beauty of a ${girl}. ${He} is too smart for ${his} own good and will likely not trust you.`);
				break;
			case "FSRepopulationFocus":
				r.push(`They kept a personal stable of slaves for breeding purposes. Several of them are still here. They've been kept heavily pregnant, and are used to being used whilst so.`);
				break;
			case "FSHedonisticDecadence":
				r.push(`Their slaves were heavily pampered; free to lie about, fuck, and eat as much as they wanted. Several of them are still here, too lazy and spoiled to leave. They eagerly paw at you upon your arrival, begging for their bellies to be filled with food and for a good, hard fucking.`);
				break;
			case "FSIntellectualDependency":
				r.push(`They kept several vapid sluts, who are now desperately begging you for sex. It seems they've drained the life out of every toy left behind and have no idea how to recharge them.`);
				break;
			case "FSSlaveProfessionalism":
				r.push(`The only one of their slaves left has made it ${his} mission to have the penthouse ready for whomever should come to own it. ${He} greets you cordially, hands you a detailed summary of ${his} skills and information on your new arcology, and calmly awaits further orders.`);
				break;
			case "FSPetiteAdmiration":
				r.push(`They had quite the impish little harem. Several of them are still here and immediately swarm you as a welcome, eager to see someone taller again.`);
				break;
			case "FSStatuesqueGlorification":
				r.push(`They had quite the collection of towering slaves. Several of them are still here. They gaze down on you, evaluating how best to serve their new owner.`);
				break;
			default:
				r.push(`ERROR: bad arcology type`);
		}
	} else {
		r.push(`They could not get all of their personal effects away. Since they`);
		if (V.targetArcology.fs === "FSNull") {
			r.push(`tried to sample different kinds of sexual slavery,`);
		} else {
			r.push(`did not have the time in control of the arcology to develop a specific stable of sex slaves,`);
		}
		r.push(`their slaves were quite varied.`);
		const heroSlaves = App.Utils.buildHeroArray().shuffle();
		for (let j = 0; j < heroSlaves.length; j++) {
			if (valueOwed - valueGiven <= 5000) {
				break;
			}
			const slave = App.Utils.getHeroSlave(heroSlaves[j]);
			heroSlaves.splice(j, 1);
			let slaveCostValue = slaveCost(slave);
			if (valueGiven + slaveCostValue < valueOwed * 2) {
				const {him, he, his, himself} = getPronouns(slave);
				nationalityToAccent(slave);
				slave.oldDevotion = slave.devotion;
				slave.oldTrust = slave.trust;
				slave.health.tired = 0;
				valueGiven += slaveCostValue;
				newSlave(slave);

				r.push(slave.slaveName);
				if (slave.fetish === "mindbroken") {
					r.push(`is, sadly, not mentally competent, and is wandering through the penthouse at the moment.`);
				} else if (isAmputee(slave)) {
					r.push(`is a quadruple amputee and is quite helpless, so you can attend to ${him} at your leisure.`);
				} else if (slave.devotion < -50) {
					r.push(`is quite rebellious and was attempting to escape, so I have locked ${him} in the slave quarters.`);
				} else if (slave.devotion < -20) {
					r.push(`resists my orders and was considering escape, so I have locked ${him} in the slave quarters.`);
				} else if (slave.devotion <= 20) {
					r.push(`is reasonably obedient, and is waiting for you in the dormitory, I believe in the hope of making a good impression.`);
				} else if (slave.energy > 95) {
					r.push(`is a remarkable sexual addict, and I believe ${he} will be very happy to meet you.`);
				} else if (slave.fetish === "pregnancy") {
					if (slave.bellyPreg >= 500) {
						r.push(`is currently in the dormitory masturbating over ${his} growing pregnancy, and`);
						if (V.PC.belly >= 5000) {
							r.push(`will certainly be eager to meet you.`);
						} else {
							r.push(`I believe ${he} will be happy to show it to you.`);
						}
					} else {
						r.push(`is currently in the dormitory examining ${himself} to try to discern ${his} fertility, and I believe ${he} will be`);
						if (V.PC.belly >= 5000) {
							r.push(`eager to get acquainted with you.`);
						} else {
							r.push(`happy to meet you.`);
						}
					}
				} else if (slave.belly >= 5000) { // had to be placed after pregnancy or it would intercept
					r.push(`is currently in the dormitory massaging ${his} greatly distended belly.`);
				} else if (slave.fetish === "buttslut") {
					r.push(`is currently in the dormitory masturbating anally, and I believe ${he} will be happy to meet you.`);
				} else if (slave.fetish === "cumslut") {
					r.push(`is currently in the dormitory exhibiting oral fixation, and I believe ${he} will be happy to meet you.`);
				} else if (slave.fetish === "boobs") {
					r.push(`is currently in the dormitory playing with ${his} nipples, and I believe ${he} will be happy to meet you.`);
				} else if (slave.fetish === "humiliation") {
					r.push(`is currently in the entryway flashing passersby, and I believe ${he} will be happy to meet you.`);
				} else if (slave.fetish === "submissive") {
					r.push(`is currently in the dormitory, experimenting with self-bondage using the sheets; I believe ${he} will be happy to meet you.`);
				} else if (slave.fetish === "dom") {
					r.push(`is currently in the exercise area keeping fit; ${he} likes to take an active role sexually and is using this down time to work out.`);
				} else if (slave.fetish === "sadist") {
					r.push(`is currently outside your office; ${he} enjoys being superior to other slaves and I believe ${he} means to ingratiate ${himself} to you.`);
				} else if (slave.fetish === "masochist") {
					r.push(`is a sexual masochist; ${he} is currently in the bathroom, experimenting with auto-flagellation with a wet towel.`);
				} else {
					r.push(`is currently outside your office, and I believe ${he} is attempting to maintain sexual arousal to make a good first impression on you.`);
				}
			}
		}
	}
	if (valueOwed - valueGiven > 0) {
		r.push(`There are some valuables present, worth ${cashFormat(valueOwed - valueGiven)}.`);
		cashX((valueOwed - valueGiven), "event");
	}
	App.Events.addNode(el, r, "p", "note");

	V.averageTrust = 0;
	V.averageDevotion = 0;
	let slavesContributing = 0;
	for (const slave of V.slaves) {
		updateHealth(slave);
		slave.oldDevotion = slave.devotion;
		slave.oldTrust = slave.trust;
		// AVERAGE VALUES UPDATE
		if (assignmentVisible(slave)) {
			V.averageTrust += slave.trust;
			V.averageDevotion += slave.devotion;
			slavesContributing += 1;
		} else {
			if (slave.assignment !== Job.CELLBLOCK && slave.assignment !== Job.ARCADE) {
				if (slave.assignment !== Job.DAIRY || V.dairyRestraintsSetting < 2) {
					V.averageTrust += slave.trust * 0.5;
					V.averageDevotion += slave.devotion * 0.5;
					slavesContributing += 0.5;
				}
			}
		}
	}
	if (slavesContributing !== 0) {
		V.averageTrust = V.averageTrust / slavesContributing;
		V.averageDevotion = V.averageDevotion / slavesContributing;
	}
	V.enduringTrust = V.averageTrust;
	V.enduringDevotion = V.averageDevotion;
	App.UI.SlaveSummary.settingsChanged();

	el.append(
		App.UI.DOM.link(
			"Continue",
			() => {
				V.ui = "main";
				if (V.terrain === "urban") {
					V.slaveCostFactor = 0.85;
					V.menialSupplyFactor = 30000;
					V.menialDemandFactor = -30000;
				} else if (V.terrain === "marine") {
					V.slaveCostFactor = 1;
				} else {
					V.slaveCostFactor = 1.15;
					V.menialDemandFactor = 30000;
					V.menialSupplyFactor = -30000;
				}
				Save.autosave.save("Week Start Autosave");
			},
			[],
			"Main"
		)
	);
	return el;

	function PCSetup() {
		if (V.PC.vagina > 0) {
			V.PC.counter.birthsTotal = 0;
			if (V.PC.career === "servant" || V.PC.career === "handmaiden" || V.PC.career === "child servant") {
				if (V.PC.pregType !== 8) {
					if (V.PC.actualAge >= 50) {
						V.PC.counter.birthsTotal = 9;
						V.PC.counter.birthMaster = 9;
					} else if (V.PC.actualAge >= 35) {
						V.PC.counter.birthsTotal = 6;
						V.PC.counter.birthMaster = 6;
					} else if (V.PC.actualAge >= 16) {
						V.PC.counter.birthsTotal = 3;
						V.PC.counter.birthMaster = 3;
					} else if (V.PC.pubertyXX === 1) {
						V.PC.counter.birthsTotal = 2;
						V.PC.counter.birthMaster = 2;
					}
				} else { // Master kept you pregged up
					if (V.PC.actualAge >= 50) {
						V.PC.counter.birthsTotal = 70;
						V.PC.counter.birthMaster = 70;
					} else if (V.PC.actualAge >= 35) {
						V.PC.counter.birthsTotal = 40;
						V.PC.counter.birthMaster = 40;
					} else if (V.PC.actualAge >= 16) {
						V.PC.counter.birthsTotal = 16;
						V.PC.counter.birthMaster = 16;
					} else if (V.PC.pubertyXX === 1) {
						V.PC.counter.birthsTotal = 8;
						V.PC.counter.birthMaster = 8;
					}
				}
				for (const slave of V.slaves) {
					if (slave.mother === -1) {
						V.PC.counter.birthsTotal += 1;
						if (slave.father === -1) {
							V.PC.counter.birthSelf += 1;
						} else {
							slave.father = -3;
							V.PC.counter.birthMaster += 1;
						}
					}
				}
			} else if (V.PC.career === "escort" || V.PC.career === "prostitute" || V.PC.career === "child prostitute") {
				for (const slave of V.slaves) {
					if (slave.mother === -1) {
						V.PC.counter.birthsTotal += 1;
						if (slave.father === -1) {
							V.PC.counter.birthSelf += 1;
						} else {
							slave.father = -5;
							V.PC.counter.birthClient += 1;
						}
					} else if (slave.father === -1) {
						slave.mother = -5;
					}
				}
			} else {
				for (const slave of V.slaves) {
					if (slave.mother === -1) {
						V.PC.counter.birthsTotal += 1;
						if (slave.father === -1) {
							V.PC.counter.birthSelf += 1;
						} else {
							V.PC.counter.birthOther += 1;
						}
					}
				}
			}
			if (V.PC.preg > 0) {
				V.PC.pregWeek = V.PC.preg;
				if (V.PC.pregType !== 8) {
					V.PC.pregType = 1;
				} else {
					V.PC.geneticQuirks.hyperFertility = 2;
				}
				if (V.PC.career === "servant" || V.PC.career === "handmaiden" || V.PC.career === "child servant") {
					V.PC.pregSource = -3;
					if (V.PC.pregType !== 8) {
						V.PC.pregType += either(0, 0, 1);
					}
				} else if (V.PC.career === "escort" || V.PC.career === "prostitute" || V.PC.career === "child prostitute") {
					V.PC.pregSource = -5;
				}
				V.PC.pregKnown = 1;
				V.PC.belly = getPregBellySize(V.PC);
				WombImpregnate(V.PC, V.PC.pregType, V.PC.pregSource, V.PC.preg);
			}
		} else {
			V.PC.trueVirgin = 1;
		}
	}

	function parentSetup() {
		/** @type {Map<number, number>} */
		const missingMap = new Map();

		/** @param {FC.HumanState} slave */
		function checkMissingParents(slave) {
			const missingMom = missingMap.get(slave.mother);
			if (missingMom) {
				slave.mother = missingMom;
			} else if (slave.mother > 0 && !getSlave(slave.mother)) {
				missingMap.set(slave.mother, V.missingParentID);
				V.missingParentID--;
			}

			const missingDad = missingMap.get(slave.father);
			if (missingDad) {
				slave.father = missingDad;
			} else if (slave.father > 0 && !getSlave(slave.father)) {
				missingMap.set(slave.father, V.missingParentID);
				V.missingParentID--;
			}
		}
		checkMissingParents(V.PC);
		V.slaves.forEach(checkMissingParents);
	}

	function inbreedingCalc() {
		const coeffSlaves = [];
		const genePoolMap = {};
		for (const slave of V.genePool) {
			genePoolMap[slave.ID] = slave;
		}
		for (const slave of V.slaves) {
			if (slave.newGamePlus === 0) {
				slave.inbreedingCoeff = -1;
				genePoolMap[slave.ID].inbreedingCoeff = -1;
				coeffSlaves.push(slave);
			}
		}
		const ibcoeffs = ibc.coeff_slaves(coeffSlaves);
		for (const slave of coeffSlaves) {
			slave.inbreedingCoeff = ibcoeffs[slave.ID];
			genePoolMap[slave.ID].inbreedingCoeff = ibcoeffs[slave.ID];
		}
	}

	/** @param {FC.FutureSociety} FS */
	function generateFSSlave(FS) {
		let slave;
		switch (FS) {
			case "FSSupremacist":
				slave = GenerateNewSlave("XX", {race: V.arcologies[0].FSSupremacistRace, disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(-25, -45);
				setHealth(slave, jsRandom(0, 20), 0, 0, 0, 0);
				slave.face = random(15, 100);
				slave.skill.oral = random(15, 35);
				slave.skill.anal = random(15, 35);
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(15, 35);
				}
				slave.skill.entertainment = random(15, 35);
				slave.clothes = "uncomfortable straps";
				slave.collar = "uncomfortable leather";
				slave.shoes = "flats";
				slave.assignment = "please you";
				break;
			case "FSSubjugationist":
				slave = GenerateNewSlave("XX", {race: V.arcologies[0].FSSubjugationistRace, disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(-25, -45);
				setHealth(slave, jsRandom(0, 20), 0, 0, 0, 0);
				slave.face = random(15, 100);
				slave.skill.oral = random(15, 35);
				slave.skill.anal = random(15, 35);
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(15, 35);
				}
				slave.skill.whoring = random(15, 35);
				slave.clothes = "uncomfortable straps";
				slave.collar = "uncomfortable leather";
				slave.shoes = "flats";
				slave.assignment = "whore";
				break;
			case "FSGenderRadicalist":
				slave = GenerateNewSlave("XY", {disableDisability: 1, maxAge: 25});
				slave.devotion = random(25, 45);
				slave.trust = random(15, -15);
				setHealth(slave, 100, 0, 0, 0, jsRandom(0, 20));
				slave.face = random(0, 55);
				slave.boobs += 100 * random(2, 4);
				slave.butt += random(1, 2);
				slave.attrXY = random(70, 90);
				slave.attrXX = 0;
				slave.skill.oral = random(35, 65);
				slave.skill.anal = random(35, 65);
				slave.skill.whoring = random(35, 65);
				SoftenSexualFlaw(slave);
				slave.clothes = "uncomfortable straps";
				slave.collar = "stylish leather";
				slave.shoes = "heels";
				slave.assignment = "whore";
				break;
			case "FSGenderFundamentalist":
				slave = GenerateNewSlave("XX", {minAge: V.fertilityAge, maxAge: 25, disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(-25, -45);
				setHealth(slave, jsRandom(55, 65), 0, 0, 0, 0);
				slave.face = random(15, 100);
				slave.preg = random(1, 40);
				slave.lactation = 1;
				slave.lactationDuration = 2;
				SetBellySize(slave);
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(15, 35);
				}
				slave.clothes = "a nice maid outfit";
				slave.collar = "tight steel";
				slave.shoes = "flats";
				slave.assignment = "be a servant";
				break;
			case "FSPaternalist":
				slave = GenerateNewSlave("XX", {disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(55, 65);
				setHealth(slave, jsRandom(55, 65), 0, 0, 0, 0);
				slave.face = random(15, 100);
				slave.intelligence = random(0, 100);
				slave.intelligenceImplant = 30;
				slave.skill.entertainment = random(15, 35);
				slave.clothes = "conservative clothing";
				slave.collar = "none";
				slave.shoes = "flats";
				slave.assignment = "be a servant";
				break;
			case "FSDegradationist":
				slave = GenerateNewSlave("XX");
				setHealth(slave, jsRandom(0, 15), 0, 0, 0, 0);
				slave.fuckdoll = 100;
				slave.career = "a Fuckdoll";
				applyMindbroken(slave);
				slave.boobs += 100 * random(10, 20);
				slave.butt += random(2, 3);
				slave.lips = random(2, 4);
				slave.weight = random(-15, 15);
				slave.clothes = "a Fuckdoll suit";
				slave.assignment = "please you";
				break;
			case "FSAssetExpansionist":
				slave = GenerateNewSlave("XX", {disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(-15, 15);
				setHealth(slave, jsRandom(25, 45), 0, 0, 0, 0);
				slave.chem = 50;
				slave.face = random(15, 100);
				slave.boobs += 100 * random(10, 20);
				slave.butt += random(2, 3);
				slave.lips += random(0, 1);
				if (slave.balls > 0) {
					slave.balls++;
				}
				if (slave.dick > 0) {
					slave.dick++;
				}
				slave.weight = random(15, 90);
				slave.skill.oral = random(15, 35);
				slave.skill.anal = 0;
				slave.anus = 0;
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(15, 35);
				}
				slave.skill.entertainment = random(15, 35);
				slave.clothes = "slutty jewelry";
				slave.collar = "pretty jewelry";
				slave.shoes = "heels";
				slave.assignment = "please you";
				break;
			case "FSSlimnessEnthusiast":
				slave = GenerateNewSlave("XX", {disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(55, 65);
				setHealth(slave, jsRandom(55, 65), 0, 0, 0, 0);
				slave.face = random(15, 100);
				slave.boobs = 100 * random(1, 4);
				slave.butt = random(1, 2);
				slave.weight = random(-25, -15);
				slave.skill.oral = random(15, 35);
				slave.skill.anal = 0;
				slave.anus = 0;
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(15, 35);
				}
				slave.skill.entertainment = random(15, 35);
				slave.clothes = "a leotard";
				slave.collar = "pretty jewelry";
				slave.shoes = "flats";
				slave.assignment = "please you";
				break;
			case "FSTransformationFetishist":
				slave = GenerateNewSlave("XX", {disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(-15, 15);
				setHealth(slave, jsRandom(-15, 0), Math.max(normalRandInt(5, 3), 0), Math.max(normalRandInt(5, 3), 0), 0, 0);
				slave.faceImplant = random(40, 70);
				slave.face = Math.clamp(Math.trunc(slave.face + slave.faceImplant / 2), -100, 100);
				slave.boobsImplant = 200 * random(4, 8);
				slave.boobs += slave.boobsImplant;
				slave.boobsImplantType = "normal";
				slave.buttImplant = random(2, 4);
				slave.butt += slave.buttImplant;
				slave.buttImplantType = "normal";
				slave.lipsImplant = random(1, 2);
				slave.lips = Math.clamp(Math.trunc(slave.lipsImplant + 2), -3, 3);
				slave.weight = random(-25, -15);
				slave.skill.oral = random(15, 35);
				slave.skill.anal = random(15, 35);
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(15, 35);
				}
				slave.clothes = "a string bikini";
				slave.collar = "shock punishment";
				slave.shoes = "extreme heels";
				slave.assignment = "whore";
				break;
			case "FSBodyPurist":
				slave = GenerateNewSlave("XX", {disableDisability: 1});
				slave.devotion = random(55, 65);
				slave.trust = random(25, 45);
				setHealth(slave, 100, 0, 0, 0, jsRandom(0, 20));
				slave.face = random(15, 100);
				slave.weight = random(-5, 5);
				slave.muscles = random(10, 25);
				slave.skill.oral = random(15, 35);
				slave.skill.anal = random(15, 35);
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(15, 35);
				}
				slave.clothes = "a nice maid outfit";
				slave.collar = "pretty jewelry";
				slave.shoes = "heels";
				slave.assignment = "be a servant";
				break;
			case "FSMaturityPreferentialist":
				slave = GenerateNewSlave("XX", {
					minAge: 36, maxAge: 39, ageOverridesPedoMode: 1, disableDisability: 1
				});
				slave.devotion = random(55, 65);
				slave.trust = random(-15, 15);
				setHealth(slave, jsRandom(25, 45), 0, 0, 0, 0);
				slave.face = random(15, 100);
				slave.boobs += 100 * random(1, 4);
				slave.butt += random(1, 2);
				slave.weight = random(-5, 90);
				slave.skill.oral = random(15, 35);
				slave.skill.anal = random(15, 35);
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(15, 35);
				}
				SoftenBehavioralFlaw(slave);
				slave.clothes = "a slutty maid outfit";
				slave.collar = "pretty jewelry";
				slave.shoes = "heels";
				slave.assignment = "be a servant";
				break;
			case "FSYouthPreferentialist":
				slave = GenerateNewSlave("XX", {maxAge: 19, disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(55, 65);
				setHealth(slave, jsRandom(25, 45), 0, 0, 0, 0);
				slave.face = random(15, 100);
				slave.boobs = 100 * random(1, 4);
				slave.butt = random(1, 3);
				slave.weight = random(-25, 25);
				slave.skill.oral = random(15, 35);
				slave.skill.anal = 0;
				slave.anus = 0;
				if (slave.vagina > -1) {
					slave.skill.vaginal = 0;
					slave.vagina = 0;
				}
				slave.skill.entertainment = random(15, 35);
				slave.clothes = "a schoolgirl outfit";
				slave.collar = "pretty jewelry";
				slave.shoes = "heels";
				slave.assignment = "be a servant";
				break;
			case "FSPastoralist":
				slave = GenerateNewSlave("XX", {disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(-25, -45);
				setHealth(slave, jsRandom(25, 45), 0, 0, 0, 0);
				slave.boobs += 100 * random(10, 20);
				if (slave.balls > 0) {
					slave.balls++;
				}
				slave.lactation = 2;
				slave.lactationDuration = 2;
				slave.clothes = "Western clothing";
				slave.collar = "leather with cowbell";
				slave.shoes = "flats";
				slave.assignment = "get milked";
				break;
			case "FSPhysicalIdealist":
				slave = GenerateNewSlave("XX", {disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(25, 45);
				setHealth(slave, 100, 0, 0, 0, jsRandom(10, 40));
				slave.muscles = random(50, 100);
				slave.skill.oral = random(15, 35);
				slave.skill.anal = random(15, 35);
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(15, 35);
				}
				slave.skill.whoring = random(15, 35);
				slave.clothes = "body oil";
				slave.collar = "none";
				slave.shoes = "none";
				slave.assignment = "whore";
				break;
			case "FSChattelReligionist":
				slave = GenerateNewSlave("XX", {disableDisability: 1});
				slave.devotion = random(55, 65);
				slave.trust = random(55, 65);
				setHealth(slave, jsRandom(0, 15), 0, 0, 0, 0);
				if (slave.vagina === 0) {
					slave.vagina++;
				}
				slave.skill.whoring = random(10, 20);
				slave.behavioralFlaw = "none";
				slave.behavioralQuirk = "sinful";
				slave.clothes = "a chattel habit";
				slave.collar = "heavy gold";
				slave.shoes = "flats";
				slave.assignment = "whore";
				break;
			case "FSRomanRevivalist":
				slave = GenerateNewSlave("XX", {maxAge: 19, disableDisability: 1});
				slave.devotion = 100;
				slave.trust = random(55, 65);
				setHealth(slave, 100, 0, 0, 0, jsRandom(10, 30));
				slave.face = random(0, 55);
				slave.muscles = random(25, 50);
				slave.skill.combat = 1;
				slave.behavioralFlaw = "none";
				slave.behavioralQuirk = "fitness";
				slave.clothes = "a toga";
				slave.collar = "pretty jewelry";
				slave.shoes = "flats";
				slave.assignment = "guard you";
				V.BodyguardID = slave.ID;
				break;
			case "FSNeoImperialist":
				slave = GenerateNewSlave("XX", {
					minAge: 16, maxAge: 28, race: "white", disableDisability: 1
				});
				slave.devotion = 100;
				slave.trust = random(55, 65);
				setHealth(slave, 100, 0, 0, 0, jsRandom(10, 30));
				slave.face = random(20, 75);
				slave.muscles = random(25, 60);
				slave.skill.combat = 1;
				slave.behavioralFlaw = "none";
				slave.behavioralQuirk = "fitness";
				slave.skill.entertainment = random(15, 35);
				slave.clothes = "a tight Imperial bodysuit";
				slave.shoes = "flats";
				slave.assignment = "guard you";
				V.BodyguardID = slave.ID;
				break;
			case "FSAztecRevivalist":
				slave = GenerateNewSlave(null, {race: "latina", nationality: "Mexican", disableDisability: 1});
				slave.accent = 0;
				slave.devotion = 75;
				slave.trust = 75;
				setHealth(slave, jsRandom(-20, 20), 0, 0, 0, 0);
				slave.muscles = random(50, 75);
				slave.skill.combat = 1;
				slave.sexualFlaw = "malicious";
				slave.behavioralQuirk = "none";
				slave.clothes = "a huipil";
				slave.collar = "pretty jewelry";
				slave.shoes = "none";
				slave.assignment = "be your Head Girl";
				V.HeadGirlID = slave.ID;
				break;
			case "FSEgyptianRevivalist":
				slave = GenerateNewSlave("XX", {disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(25, 45);
				setHealth(slave, jsRandom(25, 45), 0, 0, 0, 0);
				slave.face = random(15, 100);
				slave.skill.oral = random(15, 35);
				slave.skill.anal = random(15, 35);
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(15, 35);
				}
				slave.skill.entertainment = random(15, 35);
				SoftenSexualFlaw(slave);
				slave.clothes = "slutty jewelry";
				slave.collar = "ancient Egyptian";
				slave.shoes = "flats";
				slave.assignment = "please you";
				break;
			case "FSEdoRevivalist":
				slave = GenerateNewSlave(null, {race: "asian", nationality: "Japanese", disableDisability: 1});
				slave.accent = 0;
				slave.devotion = random(25, 45);
				slave.trust = random(25, 45);
				setHealth(slave, jsRandom(25, 45), 0, 0, 0, 0);
				slave.face = random(15, 100);
				slave.intelligence = random(0, 100);
				slave.intelligenceImplant = 30;
				slave.skill.entertainment = 100;
				slave.clothes = "a kimono";
				slave.collar = "satin choker";
				slave.shoes = "heels";
				slave.assignment = "serve the public";
				break;
			case "FSArabianRevivalist":
				slave = GenerateNewSlave("XX", {disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(-15, 15);
				setHealth(slave, jsRandom(25, 45), 0, 0, 0, 0);
				slave.face = random(15, 100);
				slave.intelligence = random(-15, 80);
				slave.intelligenceImplant = 0;
				slave.clothes = "harem gauze";
				slave.collar = "uncomfortable leather";
				slave.shoes = "flats";
				slave.assignment = "take classes";
				break;
			case "FSChineseRevivalist":
				slave = GenerateNewSlave(null, {
					race: "asian", nationality: "Chinese", minAge: 36, maxAge: 38, ageOverridesPedoMode: 1, disableDisability: 1
				});
				slave.devotion = random(55, 65);
				slave.trust = random(25, 45);
				setHealth(slave, jsRandom(25, 45), 0, 0, 0, 0);
				slave.face = random(0, 55);
				slave.accent = 0;
				slave.intelligence = 100;
				slave.intelligenceImplant = 30;
				slave.skill.oral = 100;
				slave.skill.anal = 100;
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = 100;
				}
				slave.skill.entertainment = 100;
				slave.skill.whoring = 100;
				SoftenBehavioralFlaw(slave);
				SoftenSexualFlaw(slave);
				slave.clothes = "a slutty qipao";
				slave.collar = "pretty jewelry";
				slave.shoes = "heels";
				slave.assignment = "be your Head Girl";
				V.HeadGirlID = slave.ID;
				break;
			case "FSRestart":
				slave = GenerateNewSlave("XX", {disableDisability: 1});
				slave.devotion = -100;
				slave.trust = -100;
				setHealth(slave, jsRandom(80, 90), 0, 0, 0, 0);
				slave.intelligence = 100;
				slave.intelligenceImplant = 30;
				slave.face = 100;
				slave.faceShape = "sensual";
				slave.skill.oral = random(35, 75);
				slave.skill.anal = random(35, 75);
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(35, 75);
				}
				slave.skill.entertainment = random(15, 35);
				slave.skill.whoring = 0;
				SoftenSexualFlaw(slave);
				slave.clothes = "a ball gown";
				slave.shoes = "flats";
				slave.assignment = Job.REST;
				break;
			case "FSRepopulationFocus":
				slave = GenerateNewSlave("XX", {
					minAge: V.fertilityAge + 3, maxAge: 25, ageOverridesPedoMode: 1, disableDisability: 1
				});
				slave.devotion = random(25, 45);
				slave.trust = random(-25, -45);
				setHealth(slave, jsRandom(55, 65), 0, 0, 0, 0);
				slave.face = random(15, 100);
				slave.preg = random(10, 40);
				slave.pregType = random(3, 8);
				slave.lactation = 1;
				slave.lactationDuration = 2;
				SetBellySize(slave);
				slave.counter.birthsTotal = 5;
				slave.bellySag = 20;
				slave.bellySagPreg = 20;
				if (slave.vagina > -1) {
					slave.vagina = 4;
					slave.skill.vaginal = random(15, 35);
				}
				slave.clothes = "a nice maid outfit";
				slave.shoes = "flats";
				slave.assignment = "please you";
				break;
			case "FSHedonisticDecadence":
				slave = GenerateNewSlave("XX", {maxAge: 25, disableDisability: 1});
				slave.devotion = random(25, 45);
				slave.trust = random(-25, -45);
				setHealth(slave, jsRandom(-20, 20), 0, 0, 0, 0);
				slave.face = random(15, 40);
				slave.boobs += 100 * random(3, 6);
				slave.butt += random(2, 5);
				slave.weight = random(100, 200);
				slave.skill.oral = random(15, 35);
				slave.skill.anal = random(15, 35);
				slave.anus = 2;
				if (slave.vagina > -1) {
					slave.skill.vaginal = random(15, 35);
					slave.vagina = 3;
				}
				slave.skill.entertainment = 0;
				slave.energy = random(60, 80);
				slave.behavioralFlaw = "gluttonous";
				slave.clothes = "attractive lingerie";
				slave.shoes = "flats";
				slave.diet = "fattening";
				slave.rules.living = "luxurious";
				slave.assignment = Job.REST;
				break;
			case "FSIntellectualDependency":
				slave = GenerateNewSlave("XX", {minAge: 14, maxAge: 18, disableDisability: 1});
				setHealth(slave, jsRandom(55, 65), 0, 0, 0, 0);
				slave.devotion = random(45, 65);
				slave.trust = random(-15, 45);
				slave.face = random(30, 100);
				slave.energy = 100;
				slave.weight = random(-25, -15);
				slave.skill.oral = 0;
				slave.skill.anal = 0;
				slave.skill.vaginal = 0;
				slave.skill.entertainment = 0;
				slave.skill.whoring = 0;
				slave.intelligence = -100;
				slave.intelligenceImplant = 0;
				if (slave.vagina === 0) {
					slave.vagina++;
				}
				slave.anus++;
				break;
			case "FSSlaveProfessionalism":
				slave = GenerateNewSlave("XX", {minAge: 18, maxAge: 25, disableDisability: 1});
				slave.devotion = 100;
				slave.trust = 20;
				setHealth(slave, 80, 0, 0, 0, jsRandom(10, 30));
				slave.face = random(30, 100);
				slave.energy = 10;
				slave.weight = random(-15, 5);
				slave.skill.oral = 100;
				slave.skill.anal = 100;
				slave.skill.vaginal = 100;
				slave.skill.entertainment = 100;
				slave.skill.whoring = 100;
				slave.intelligence = 100;
				slave.intelligenceImplant = 30;
				slave.accent = 0;
				SoftenBehavioralFlaw(slave);
				SoftenSexualFlaw(slave);
				slave.clothes = "a nice maid outfit";
				slave.collar = "pretty jewelry";
				slave.assignment = "be your Head Girl";
				V.HeadGirlID = slave.ID;
				break;
			case "FSPetiteAdmiration":
				slave = GenerateNewSlave("XX", {minAge: 14, maxAge: 18, disableDisability: 1});
				slave.devotion = random(55, 65);
				slave.trust = random(-15, 15);
				setHealth(slave, jsRandom(25, 45), 0, 0, 0, 0);
				slave.face = random(15, 100);
				if (slave.height >= 150) {
					slave.height = Height.random(slave, {limitMult: [-3, -1]});
					if (slave.height >= 150) {
						slave.height = Height.random(slave, {limitMult: [-4, -2]});
						if (slave.height >= 150) {
							slave.height = random(90, 130);
							slave.geneticQuirks.dwarfism = 2;
						}
					}
				}
				slave.skill.oral = random(35, 65);
				slave.skill.anal = random(15, 35);
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(15, 35);
				}
				slave.clothes = "a succubus outfit";
				slave.legAccessory = "long stockings";
				slave.assignment = "please you";
				break;
			case "FSStatuesqueGlorification":
				slave = GenerateNewSlave("XX", {
					minAge: 18, maxAge: 30, ageOverridesPedoMode: 1, disableDisability: 1
				});
				slave.devotion = random(55, 65);
				slave.trust = random(-15, 15);
				setHealth(slave, jsRandom(25, 45), 0, 0, 0, 0);
				slave.face = random(15, 100);
				slave.weight = random(-5, 5);
				slave.muscles = random(20, 40);
				if (slave.height < 185) {
					slave.height = Height.random(slave, {limitMult: [1, 3]});
					if (slave.height < 185) {
						slave.height = Height.random(slave, {limitMult: [2, 4]});
						if (slave.height < 185) {
							slave.height = random(200, 264);
							slave.geneticQuirks.gigantism = 2;
						}
					}
				}
				slave.skill.oral = random(15, 35);
				slave.skill.anal = random(15, 35);
				if (slave.vagina > -1) {
					if (slave.vagina === 0) {
						slave.vagina++;
					}
					slave.skill.vaginal = random(15, 35);
				}
				slave.clothes = "slutty business attire";
				slave.shoes = "heels";
				slave.assignment = "please you";
				break;
			default:
				r.push(`ERROR: bad arcology type`);
		}
		slave.origin = "You acquired $him along with the arcology.";
		slave.career = "a slave";
		return slave;
	}
};


code:
/** @param {number} [price] */
App.Intro.generateEstablishedArcologies = function(price) {
	/* setup */
	const fsAllowed = {
		FSGenderRadicalist: () => V.seeDicks !== 0,
		FSGenderFundamentalist: () => V.seeDicks !== 100,
		FSDegradationist: () => V.seeExtreme !== 0
	};
	const allowedFS = App.Data.FutureSociety.playerFSNames.filter(fs => !(fs in fsAllowed) || fsAllowed[fs]());

	let targets = 4;
	if (V.PC.career === "arcology owner") {
		targets += 2;
	}

	/* generation */
	const div = document.createElement("div");
	for (let i = 0; i < targets; i++) {
		div.append(arcologyCard());
	}
	return div;

	function arcologyCard() {
		const div = document.createElement("div");
		const arcology = generateArcology();
		const sectionPrice = {
			"penthouse": 10_000_000,
			"shops": 1_000_000,
			"apartments": 500_000,
			"markets": 250_000,
			"manufacturing": 100_000,
		};
		const rows = (/** @type {App.Arcology.Section} */ section) => section.rows
			.reduce((acc, cur) => acc + cur.length * sectionPrice[section.id], 0);
		const _price = price ?? arcology.building.sections
			.reduce((acc, cur) => acc + rows(cur), 10_000_000); // base price of ¤10,000,000

		div.classList.add("card");
		div.append(
			App.UI.DOM.makeElement("span", arcology.name, ['bold']),
			` is an established arcology located in a Free City `,
		);
		if (arcology.terrain === "urban") {
			div.append(`carved out of an urban area of ${arcology.continent}.`);
		} else if (arcology.terrain === "rural") {
			div.append(`built in a rural area of ${arcology.continent}.`);
		} else if (arcology.terrain === "marine") {
			div.append(`constructed just offshore of ${arcology.continent}.`);
		} else if (arcology.terrain === "ravine") {
			div.append(`constructed in a large canyon of ${arcology.continent}.`);
		} else {
			div.append(`in the middle of the ocean.`);
		}

		function newLine(...content) {
			const line = document.createElement("div");
			line.classList.add("indent");
			line.append(...content);
			div.append(line);
		}

		if (arcology.prosperity >= 60) {
			newLine("It is unusually prosperous for a vulnerable arcology.");
		} else if (arcology.prosperity <= 40) {
			newLine("It has little economic prosperity and is vulnerable.");
		}

		if (arcology.citizens > 0) {
			newLine("It has an unusually high ratio of citizens to sex slaves, increasing demand for sexual services.");
		} else if (arcology.citizens < 0) {
			newLine("It has an unusually low ratio of citizens to sex slaves, reducing demand for sexual services.");
		}

		let innerDiv = document.createElement("div");
		innerDiv.classList.add("indent");
		div.append(innerDiv);

		innerDiv.append("Its society ");
		if (arcology.FSProgress >= 50) {
			innerDiv.append("has advanced towards");
		} else if (arcology.FSProgress >= 30) {
			innerDiv.append("has devoted resources to");
		} else {
			innerDiv.append("has just begun to adopt");
		}
		innerDiv.append(" ");
		switch (arcology.fs) {
			case "FSSupremacist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Supremacy of the ${arcology.race} ${arcology.race !== "mixed race" ? "race" : ""}.`, ["intro", "question"]));
				break;
			case "FSSubjugationist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Subjugation of the ${arcology.race} ${arcology.race !== "mixed race" ? "race" : ""}.`, ["intro", "question"]));
				break;
			case "FSGenderRadicalist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Gender Radicalism,`, ["intro", "question"]), " a movement that supports feminization of slavegirls with dicks.");
				break;
			case "FSGenderFundamentalist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Gender Fundamentalism,`, ["intro", "question"]), " a reaction to modern libertinism that seeks to reinforce gender roles.");
				break;
			case "FSPaternalist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Paternalism,`, ["intro", "question"]), " an optimistic strain of slavery that protects and improves slaves.");
				break;
			case "FSDegradationist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Degradationism,`, ["intro", "question"]), " an extreme branch of modern slavery that treats slaves as subhuman.");
				break;
			case "FSAssetExpansionist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Asset Expansionism,`, ["intro", "question"]), " a societal preoccupation with expansion of body parts, especially breasts.");
				break;
			case "FSSlimnessEnthusiast":
				innerDiv.append(App.UI.DOM.makeElement("span", `Slimness Enthusiasm,`, ["intro", "question"]), " an aesthetic movement that fetishizes the lithe female form.");
				break;
			case "FSTransformationFetishist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Transformation Fetishism,`, ["intro", "question"]), " a focus on implants and other kinds of surgical alteration.");
				break;
			case "FSBodyPurist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Body Purism,`, ["intro", "question"]), " a reaction to extreme surgical fetishism that prefers bodies grown biologically.");
				break;
			case "FSMaturityPreferentialist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Maturity Preferentialism,`, ["intro", "question"]), " an appetite for mature slaves based on MILF fetishism.");
				break;
			case "FSYouthPreferentialist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Youth Preferentialism,`, ["intro", "question"]), " which focuses on youth and virginity in slaves.");
				break;
			case "FSPastoralist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Pastoralism,`, ["intro", "question"]), " an appetite for products of the human body, especially milk.");
				break;
			case "FSPhysicalIdealist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Physical Idealism,`, ["intro", "question"]), " an aspirational movement which fetishizes muscle and physical fitness.");
				break;
			case "FSChattelReligionist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Chattel Religionism,`, ["intro", "question"]), " a religious revival in the context of modern slavery.");
				break;
			case "FSRomanRevivalist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Roman Revivalism,`, ["intro", "question"]), " which seeks to recreate the glory that was ancient Rome.");
				innerDiv.append(App.UI.DOM.makeElement("div", "It has an established lingua franca: Latin."));
				break;
			case "FSNeoImperialist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Neo-Imperialism,`, ["intro", "question"]), " adopting old world customs and remodeling them under an absolutist Imperial fist.");
				break;
			case "FSAztecRevivalist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Aztec Revivalism,`, ["intro", "question"]), " which aspires to reach the heights of the Aztec Empire at its peak.");
				innerDiv.append(App.UI.DOM.makeElement("div", "It has an established lingua franca: Nahuatl."));
				break;
			case "FSEgyptianRevivalist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Egyptian Revivalism,`, ["intro", "question"]), " a movement to rebuild the monuments and greatness of ancient Egypt.");
				innerDiv.append(App.UI.DOM.makeElement("div", "It has an established lingua franca: Ancient Egyptian."));
				break;
			case "FSEdoRevivalist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Edo Revivalism,`, ["intro", "question"]), " an insular movement with a focus on the cultural superiority of old Japan.");
				innerDiv.append(App.UI.DOM.makeElement("div", "It has an established lingua franca: Japanese."));
				break;
			case "FSArabianRevivalist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Arabian Revivalism,`, ["intro", "question"]), " a melding of Arabian history and recent mythology of the Near East.");
				innerDiv.append(App.UI.DOM.makeElement("div", "It has an established lingua franca: Arabic."));
				break;
			case "FSChineseRevivalist":
				innerDiv.append(App.UI.DOM.makeElement("span", `Chinese Revivalism,`, ["intro", "question"]), " which modernizes the assumed superiority of the Middle Kingdom.");
				innerDiv.append(App.UI.DOM.makeElement("div", "It has an established lingua franca: Chinese."));
				break;
			case "FSRepopulationFocus":
				innerDiv.append(App.UI.DOM.makeElement("span", `Repopulationism,`, ["intro", "question"]), " the belief that the key to humanity's survival is a child in every fertile womb.");
				break;
			case "FSRestart":
				innerDiv.append(App.UI.DOM.makeElement("span", `Eugenics,`, ["intro", "question"]), " the belief that the world's failings were caused by rampant breeding of the inferior, and as such, only society's best should reproduce.");
				break;
			case "FSHedonisticDecadence":
				innerDiv.append(App.UI.DOM.makeElement("span", `Decadent Hedonism,`, ["intro", "question"]), " a movement to embody life's pleasures, particularly eating and sex.");
				break;
			case "FSIntellectualDependency":
				innerDiv.append(App.UI.DOM.makeElement("span", `Intellectual Dependency,`, ["intro", "question"]), " an appetite for horny, stupid slaves based on bimbo fetishism.");
				break;
			case "FSSlaveProfessionalism":
				innerDiv.append(App.UI.DOM.makeElement("span", `Slave Professionalism,`, ["intro", "question"]), " a strain of slavery that seeks smart, skilled, elegant slaves to hone to perfection.");
				break;
			case "FSPetiteAdmiration":
				innerDiv.append(App.UI.DOM.makeElement("span", `Petite Admiration,`, ["intro", "question"]), " which prefers its slaves to stand heads and shoulders shorter than their masters.");
				break;
			case "FSStatuesqueGlorification":
				innerDiv.append(App.UI.DOM.makeElement("span", `Statuesque Glorification,`, ["intro", "question"]), " an obsession, both sexual and otherwise, over height.");
				break;
			default:
				innerDiv.append(App.UI.DOM.makeElement("span", `Multiculturalism,`, ["intro", "question"]), " a celebration of the total liberty that was the original purpose of the Free Cities.");
		}

		div.append(
			innerDiv,
			App.UI.DOM.makeElement("div", arcology.building.render(), ["intro"]),
			App.UI.DOM.makeElement("div", makePurchase(`Purchase ${arcology.name}`, _price, "capEx", {
				handler: () => {
					V.targetArcology = arcology;
					V.terrain = arcology.terrain;
					V.continent = arcology.continent;
					V.language = arcology.language;
					V.building = arcology.building;
					V.weatherCladding = 0;
					V.rep = 0;

					if (V.secExpEnabled && V.SecExp.core) {
						V.SecExp.core.authority = 0;
					}

					arcology.apply();

					if (passage() === "Takeover Target") {
						Engine.play("Intro Summary");
					} else {
						updatePlayerArcology();
						Engine.play("Main");
					}
				},
				prereqs: [
					[
						V.rival.state === 0 || V.rival.state > 2,
						`Your inter-arcology war is preventing you from leaving ${arcology.name}.`
					],
					[
						V.daughtersVictory !== 1,
						`You cannot leave ${arcology.name} behind while the Daughters of Liberty are still a threat.`
					],
				],
			}), ['center']),
		);

		return div;

		function updatePlayerArcology() {
			V.arcologies[0].name = arcology.name;
			V.arcologies[0].weeks = 1;

			updateFS();
		}

		function updateFS() {
			const {fs} = arcology;

			App.Data.FutureSociety.fsNames.forEach(f => {
				FutureSocieties.remove(f);
			});

			if (fs) {
				V.arcologies[0][fs] = arcology.FSProgress;
			}
		}
	}

	function generateArcology() {
		const arcology = {};
		arcology.fs = getFS();
		arcology.name = getName();
		arcology.FSProgress = either(10, 30, 50);
		arcology.prosperity = either(40, 50, 60);
		arcology.citizens = random(-1, 1);
		arcology.terrain = App.Data.Arcology.Terrain.random();
		arcology.continent = App.Data.Arcology.Continents.random();
		arcology.language = getLanguage();

		const env = {terrain: arcology.terrain, established: true, fs: arcology.fs};
		const preset = App.Arcology.randomPreset(env).construct(env);
		arcology.building = preset.building;
		arcology.apply = preset.apply;

		return arcology;

		function getFS() {
			const type = allowedFS.pluck();
			if (type === "FSSupremacist" || type === "FSSubjugationist") {
				arcology.race = App.Data.Slave.Races.random();
			}
			return type;
		}

		function getName() {
			switch (arcology.fs) {
				case "FSSupremacist":
					switch (arcology.race) {
						case "white":
							return App.Data.ArcologyNames.SupremacistWhite.random();
						case "asian":
							return App.Data.ArcologyNames.SupremacistAsian.random();
						case "latina":
							return App.Data.ArcologyNames.SupremacistLatina.random();
						case "middle eastern":
							return App.Data.ArcologyNames.SupremacistMiddleEastern.random();
						case "black":
							return App.Data.ArcologyNames.SupremacistBlack.random();
						case "indo-aryan":
							return App.Data.ArcologyNames.SupremacistIndoAryan.random();
						case "pacific islander":
							return App.Data.ArcologyNames.SupremacistPacificIslander.random();
						case "malay":
							return App.Data.ArcologyNames.SupremacistMalay.random();
						case "amerindian":
							return App.Data.ArcologyNames.SupremacistAmerindian.random();
						case "southern european":
							return App.Data.ArcologyNames.SupremacistSouthernEuropean.random();
						case "semitic":
							return App.Data.ArcologyNames.SupremacistSemitic.random();
						default:
							return App.Data.ArcologyNames.SupremacistMixedRace.random();
					}
				case "FSSubjugationist":
					switch (arcology.race) {
						case "white":
							return App.Data.ArcologyNames.SubjugationistWhite.random();
						case "asian":
							return App.Data.ArcologyNames.SubjugationistAsian.random();
						case "latina":
							return App.Data.ArcologyNames.SubjugationistLatina.random();
						case "middle eastern":
							return App.Data.ArcologyNames.SubjugationistMiddleEastern.random();
						case "black":
							return App.Data.ArcologyNames.SubjugationistBlack.random();
						case "indo-aryan":
							return App.Data.ArcologyNames.SubjugationistIndoAryan.random();
						case "pacific islander":
							return App.Data.ArcologyNames.SubjugationistPacificIslander.random();
						case "malay":
							return App.Data.ArcologyNames.SubjugationistMalay.random();
						case "amerindian":
							return App.Data.ArcologyNames.SubjugationistAmerindian.random();
						case "southern european":
							return App.Data.ArcologyNames.SubjugationistSouthernEuropean.random();
						case "semitic":
							return App.Data.ArcologyNames.SubjugationistSemitic.random();
						default:
							return App.Data.ArcologyNames.SubjugationistMixedRace.random();
					}
				case "FSGenderRadicalist":
					return App.Data.ArcologyNames.GenderRadicalist.random();
				case "FSGenderFundamentalist":
					return App.Data.ArcologyNames.GenderFundamentalist.random();
				case "FSPaternalist":
					return App.Data.ArcologyNames.Paternalist.random();
				case "FSDegradationist":
					return App.Data.ArcologyNames.Degradationist.random();
				case "FSAssetExpansionist":
					return App.Data.ArcologyNames.AssetExpansionist.random();
				case "FSSlimnessEnthusiast":
					return App.Data.ArcologyNames.SlimnessEnthusiast.random();
				case "FSTransformationFetishist":
					return App.Data.ArcologyNames.TransformationFetishist.random();
				case "FSBodyPurist":
					return App.Data.ArcologyNames.BodyPurist.random();
				case "FSMaturityPreferentialist":
					return App.Data.ArcologyNames.MaturityPreferentialist.random();
				case "FSYouthPreferentialist":
					if (V.pedo_mode === 1 || V.minimumSlaveAge < 6) {
						return App.Data.ArcologyNames.YouthPreferentialistLow.random();
					} else if (V.minimumSlaveAge < 14) {
						return App.Data.ArcologyNames.YouthPreferentialist.concat(App.Data.ArcologyNames.YouthPreferentialistLow).random();
					} else {
						return App.Data.ArcologyNames.YouthPreferentialist.random();
					}
				case "FSPastoralist":
					return App.Data.ArcologyNames.Pastoralist.random();
				case "FSPhysicalIdealist":
					return App.Data.ArcologyNames.PhysicalIdealist.random();
				case "FSChattelReligionist":
					return App.Data.ArcologyNames.ChattelReligionist.random();
				case "FSRomanRevivalist":
					return App.Data.ArcologyNames.RomanRevivalist.random();
				case "FSNeoImperialist":
					return App.Data.ArcologyNames.NeoImperialist.random();
				case "FSAztecRevivalist":
					return App.Data.ArcologyNames.AztecRevivalist.random();
				case "FSEgyptianRevivalist":
					return App.Data.ArcologyNames.EgyptianRevivalist.random();
				case "FSEdoRevivalist":
					return App.Data.ArcologyNames.EdoRevivalist.random();
				case "FSArabianRevivalist":
					return App.Data.ArcologyNames.ArabianRevivalist.random();
				case "FSChineseRevivalist":
					return App.Data.ArcologyNames.ChineseRevivalist.random();
				case "FSRepopulationFocus":
					return App.Data.ArcologyNames.Repopulationist.random();
				case "FSRestart":
					return App.Data.ArcologyNames.Eugenics.random();
				case "FSHedonisticDecadence":
					return App.Data.ArcologyNames.HedonisticDecadence.random();
				case "FSIntellectualDependency":
					return App.Data.ArcologyNames.IntellectualDependency.random();
				case "FSSlaveProfessionalism":
					return App.Data.ArcologyNames.SlaveProfessionalism.random();
				case "FSPetiteAdmiration":
					return App.Data.ArcologyNames.PetiteAdmiration.random();
				case "FSStatuesqueGlorification":
					return App.Data.ArcologyNames.StatuesqueGlorification.random();
				default:
					return "Arcology X-4";
			}
		}

		function getLanguage() {
			const language = App.Data.FutureSociety.records[arcology.fs].language;
			if (language) {
				return language;
			} else {
				switch (arcology.terrain) {
					case "South America":
						return "Spanish";
					case "Brazil":
						return "Portuguese";
					case "the Middle East":
					case "Africa": /* shouldn't that be portuguese, spanish or something? */
						return "Arabic";
					case "Asia":
						return "Chinese";
					case "Central Europe":
						return "German";
					case "Eastern Europe":
						return "Russian";
					case "Western Europe":
						return "English";
					case "Southern Europe":
						return "Italian";
					case "Scandinavia":
						return "Norwegian";
					case "Japan":
						return "Japanese";
					case "oceanic":
					case "North America":
					case "Australia":
					default:
						return "English";
				}
			}
		}
	}
};

repo_name: Fanatey/fc

license: mit


code:
App.Intro.CustomSlaveTrade = function() {
	const frag = new DocumentFragment();
	let span = document.createElement("span");
	let baseControlsFilter = "all";
	App.UI.DOM.appendNewElement("p", frag, `When civilization turned upon itself, some countries readily took to enslaving their own. Others were raided by their neighbors for their desirable, and profitable, citizens. Which nationalities were most affected by the booming slave trade, and thus, likely to appear in your local slave markets?`);
	App.UI.DOM.appendNewElement("p", frag, `+ to increase pop. – to reduce pop. 0 to remove entirely`, "bold");

	span.id = "pop-control";
	span.append(baseNationalitiesControls());
	frag.append(span);

	return frag;

	function baseNationalitiesControls() {
		const frag = new DocumentFragment();
		let p = document.createElement("p");
		let destination;
		let div;
		let array;
		let list;
		let span;
		const nationalitiesCheck = App.UI.nationalitiesCheck();

		if (hashSum(V.nationalities) < 1) {
			App.UI.DOM.appendNewElement("div", p, `You cannot be a slaveowner without a slave trade. Please add nationalities to continue.`, "note");
		} else {
			destination = V.customWA ? "Extreme Intro" : "Intro Summary";
			App.UI.DOM.appendNewElement(
				"div",
				p,
				App.UI.DOM.passageLink(
					"Confirm customization",
					destination,
					() => baseControlsFilter = undefined
				)
			);
		}
		frag.append(p);

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

		p = document.createElement("p");

		/* Fine control tweaking of populations */
		App.UI.DOM.appendNewElement("div", p, `Adjust slave populations:`);

		p.append(sectionBreak());

		/* Filter controls */
		div = document.createElement("div");
		App.UI.DOM.appendNewElement("span", div, `Filter by Race: `);
		array = [];
		for (const [race, capRace] of App.Data.misc.filterRaces) {
			if (baseControlsFilter === race) {
				array.push(
					App.UI.DOM.disabledLink(
						capRace,
						["currently selected race"]
					)
				);
			} else {
				array.push(
					App.UI.DOM.link(
						capRace,
						() => {
							baseControlsFilter = race;
							refresh();
						}
					)
				);
			}
		}
		div.append(App.UI.DOM.generateLinksStrip(array));
		p.append(div);

		div = document.createElement("div");
		App.UI.DOM.appendNewElement("span", div, `Filter by Region: `);
		array = [];
		for (const region of App.Data.misc.filterRegions) {
			if (baseControlsFilter === uncapFirstChar(region).replace(/[ -]/g, '')) {
				array.push(
					App.UI.DOM.disabledLink(
						region,
						["currently selected region"]
					)
				);
			} else {
				array.push(
					App.UI.DOM.link(
						region,
						() => {
							baseControlsFilter = uncapFirstChar(region).replace(/[ -]/g, '');
							refresh();
						}
					)
				);
			}
		}
		div.append(App.UI.DOM.generateLinksStrip(array));
		p.append(div);

		p.append(sectionBreak());

		div = document.createElement("div");
		div.style.whiteSpace = "nowrap";
		div.style.float = "left";

		/* Unfiltered pop controls */
		list = document.createElement("UL");
		list.classList.add("customize-slave-trade-ul");
		if (baseControlsFilter === "all") {
			for (const nation of App.Data.misc.baseNationalities) {
				const li = document.createElement("LI");
				li.classList.add("customize-slave-trade-li");
				li.append(nation);

				span = document.createElement("span");
				span.classList.add("customize-slave-trade-li-container");
				App.UI.DOM.appendNewElement(
					"span",
					span,
					App.UI.DOM.link(
						`+`,
						() => {
							hashPush(V.nationalities, nation);
							refresh();
						}
					),
					"plusButton"
				);
				if (nationalitiesCheck[nation]) {
					App.UI.DOM.appendNewElement(
						"span",
						span,
						App.UI.DOM.link(
							`-`,
							() => {
								V.nationalities[nation] -= 1;
								if (V.nationalities[nation] <= 0) {
									delete V.nationalities[nation];
								}
								refresh();
							}
						),
						"minusButton"
					);
				}
				if (V.nationalities[nation] > 1) {
					App.UI.DOM.appendNewElement(
						"span",
						span,
						App.UI.DOM.link(
							`0`,
							() => {
								delete V.nationalities[nation];
								refresh();
							}
						),
						"zeroButton"
					);
				}
				li.append(span);
				list.append(li);
			}
			p.append(list);
			App.UI.DOM.appendNewElement("div", p, `By dominant race/ethnicity (hover over the name to see the nationalities affected):`);
			list = document.createElement("UL");
			list.classList.add("customize-slave-trade-ul");
			for (const race of App.Data.misc.filterRaces.keys()) {
				const racialNationalities = App.Data.misc.baseNationalities.filter(function(n) {
					let races = App.Data.misc.raceSelector[n] || App.Data.misc.raceSelector[''];
					return races[race] * 3.5 > hashSum(races);
				});

				if (racialNationalities.length > 0) {
					const li = document.createElement("LI");
					li.classList.add("customize-slave-trade-li");
					li.title = racialNationalities.length > 0 ? racialNationalities.join(", ") : "(none)";
					li.append(race);
					span = document.createElement("span");
					span.classList.add("customize-slave-trade-li-container");
					App.UI.DOM.appendNewElement(
						"span",
						span,
						App.UI.DOM.link(
							`+`,
							() => {
								racialNationalities.forEach(n => hashPush(V.nationalities, n));
								refresh();
							}
						),
						"plusButton"
					);
					App.UI.DOM.appendNewElement(
						"span",
						span,
						App.UI.DOM.link(
							`0`,
							() => {
								racialNationalities.forEach(n => delete V.nationalities[n]);
								refresh();
							}
						),
						"zeroButton"
					);
					li.append(span);
					list.append(li);
				}
			}
		} else {
			/* Filtered pop controls */
			const controlsNationality = App.Data.misc.nationalitiesByRace[baseControlsFilter] || App.Data.misc[baseControlsFilter + 'Nationalities'];
			const keys = Object.keys(controlsNationality);
			for (const nation of keys) {
				const li = document.createElement("LI");
				li.classList.add("customize-slave-trade-li");
				li.append(nation);
				span = document.createElement("span");
				span.classList.add("customize-slave-trade-li-container");
				App.UI.DOM.appendNewElement(
					"span",
					span,
					App.UI.DOM.link(
						`+`,
						() => {
							hashPush(V.nationalities, nation);
							refresh();
						}
					),
					"plusButton"
				);

				if (nationalitiesCheck[nation]) {
					App.UI.DOM.appendNewElement(
						"span",
						span,
						App.UI.DOM.link(
							`-`,
							() => {
								V.nationalities[nation] -= 1;
								if (V.nationalities[nation] <= 0) {
									delete V.nationalities[nation];
								}
								refresh();
							}
						),
						"minusButton"
					);
				}
				if (V.nationalities[nation] > 1) {
					App.UI.DOM.appendNewElement(
						"span",
						span,
						App.UI.DOM.link(
							`0`,
							() => {
								delete V.nationalities[nation];
								refresh();
							}
						),
						"zeroButton"
					);
				}
				li.append(span);
				list.append(li);
			}
		}
		p.append(list);
		frag.append(p);

		div = document.createElement("div");

		div.append(
			App.UI.DOM.link(
				"Reset filters",
				() => {
					baseControlsFilter = "all";
					refresh();
				}
			)
		);

		div.append(" | ");

		div.append(
			App.UI.DOM.link(
				"Clear all nationalities",
				() => {
					V.nationalities = {};
					refresh();
				}
			)
		);

		frag.append(div);

		frag.append(sectionBreak());

		div = document.createElement("div");
		div.append(`Vanilla presets: `);
		div.append(generatePresetLinks("Vanilla"));
		frag.append(div);

		div = document.createElement("div");
		div.append(`Mod presets: `);
		div.append(generatePresetLinks("Mod"));
		frag.append(div);

		p = document.createElement("p");
		App.UI.DOM.appendNewElement(
			"span",
			p,
			App.UI.DOM.link(
				"Export Settings",
				() => {
					settingsExport();
				}
			)
		);
		p.append(" | ");
		App.UI.DOM.appendNewElement(
			"span",
			p,
			App.UI.DOM.link(
				"Import Settings",
				() => {
					settingsImport();
				}
			)
		);
		frag.append(p);
		div = document.createElement("div");
		div.id = "importExportArea";
		frag.append(div);

		return frag;
	}

	function sectionBreak() {
		const hr = document.createElement("hr");
		hr.style.margin = "0";
		return hr;
	}

	function refresh() {
		return jQuery('#pop-control').empty().append(baseNationalitiesControls());
	}

	function settingsExport() {
		let textArea = document.createElement("textarea");
		textArea.value = JSON.stringify(V.nationalities);
		$("#importExportArea").html(textArea);
	}

	function settingsImport() {
		let textArea = document.createElement("textarea");
		let button = document.createElement("button");
		button.name = "Load";
		button.innerHTML = "Load";
		button.onclick = () => {
			V.nationalities = JSON.parse(textArea.value);
			State.display(State.passage);
		};

		$("#importExportArea").html("").append(textArea).append(button);
	}

	function generatePresetLinks(group) {
		let links = [];
		for (const [name, nationalities] of App.Data.NationalityPresets[group]) {
			links.push(
				App.UI.DOM.link(
					name,
					() => {
						V.nationalities = clone(nationalities);
						refresh();
					}
				)
			);
		}
		return App.UI.DOM.generateLinksStrip(links);
	}
};

/**
 * @returns {HTMLElement}
 */
App.UI.nationalitiesDisplay = function() {
	const p = document.createElement("p");

	/* Generates cloned array of V.nationalities, removing duplicates and then sorting */
	const nationalitiesCheck = App.UI.nationalitiesCheck();

	/* Prints distribution of V.nationalities, using nationalitiesCheck to render array */
	let percentPerPoint = 100.0 / hashSum(V.nationalities);
	let len = Object.keys(nationalitiesCheck).length;
	let j = 0;
	for (const nation in nationalitiesCheck) {
		const span = document.createElement("span");
		span.append(`${nation} `);
		App.UI.DOM.appendNewElement("span", span, (V.nationalities[nation] * percentPerPoint).toFixed(2), "orange");
		j++;
		if (j < len) {
			span.append(` | `);
		}
		p.append(span);
	}
	return p;
};

App.UI.nationalitiesCheck = function() {
	return Object.assign(
		{
			// Player can add custom nations here.
		},
		V.nationalities);
};


code:
App.Intro.economyIntro = function() {
	const node = new DocumentFragment();

	App.Events.addParagraph(node, [
		`It is the year 2037, and the past 21 years have not been kind. The world is starting to fall apart. The climate is deteriorating, resources are being exhausted, and there are more people to feed every year. Technology is advancing, but not fast enough to save everyone. `,
	]);

	if (V.PC.career === "arcology owner" || V.saveImported === 1) {
		setTimeout(() => Engine.play("Takeover Target"), Engine.minDomActionDelay);
	}

	const options = new App.UI.OptionsGroup();

	const difficultyComment = new Map([
		[1, `Not truly dire. Not yet.`],
		[2, `Getting a touch dire.`],
		[3, `Very serious.`],
		[4, `It won't be pretty.`],
		[5, `This is the last dance.`],
	]);

	options.addOption(`Exactly how bad is the situation?`, "baseDifficulty")
		.addValue(`Very Easy`, 1).addCallback(() => V.economy = 200)
		.addValue(`Easy`, 2).addCallback(() => V.economy = 125)
		.addValue(`Very serious (default)`, 3).addCallback(() => V.economy = 100)
		.addValue(`Hard`, 4).addCallback(() => V.economy = 80)
		.addValue(`Very Hard`, 5).addCallback(() => V.economy = 67)
		.addComment(difficultyComment.get(V.baseDifficulty));

	const difficultyComment2 = new Map([
		[0, `Barely noticeable, for now.`],
		[1, `A slow decline.`],
		[2, `It's visibly deteriorating before your eyes.`],
		[4, `It's going to hell in a handbasket.`],
	]);

	if (V.difficultySwitch === 0) {
		options.addOption(`How fast is it crumbling?`, "difficultySwitch")
			.addValue(`Vanilla`, 0)
			.addValue(`Harder`, 1).addCallback(()=>{ V.econRate = 2; })
			.addComment(`Some economic content requires this to be set to harder than vanilla`);
	} else {
		options.addOption(`How fast is it crumbling?`, "econRate")
			.addValue(`Return to vanilla`, 0).addCallback(() => {
				V.difficultySwitch = 0;
			})
			.addValue(`Easy`, 1)
			.addValue(`Medium`, 2)
			.addValue(`Hard`, 4)
			.addComment(difficultyComment2.get(V.econRate));
	}
	node.append(options.render());

	/* Not functional yet, place V.incomeRate = 1 in storyInit when ready for use
	//

		r.push(`All the things you need to run your arcology are getting more expensive`);
		if (V.incomeMod === 0) {
			r.push(`while all forms of income`);
			//remain static. [[Easier|Economy Intro][V.incomeRate = 1]]
		} else if (V.incomeMod === 1) {
			r.push(`while all forms of income <span style="font-weight:Bold">rise but cannot keep pace.</span> [[Easier|Economy Intro][${V.incomeRate} = 2]] | [[Harder|Economy Intro][V.incomeRate = 0]]`);
		} else {
			r.push(`but luckily all forms of income <span style="font-weight:Bold">rise in lockstep.</span> [[Harder|Economy Intro][${V.incomeRate} = 1]]`);
		}
	//

	//

		[[Play with static economy|Economy Intro][V.difficultySwitch = 0]]
	//

	*/
	//

	//

	App.Events.addResponses(node, [
		new App.Events.Result(`Next`, next),
		new App.Events.Result(`Skip Intro`, skip, `This will preclude you from taking over an established arcology.`),
	]);

	return node;

	function next() {
		Engine.play("Trade Intro");
		return ``;
	}
	function skip() {
		Engine.play("Intro Summary");
		return ``;
	}
};


code:
App.Intro.extremeIntro = function() {
	const node = new DocumentFragment();

	App.Events.addParagraph(node, [
		`The early Free Cities were wild places where the writ of law did not run. In some of the most depraved, slaves' bodies, minds and even lives were playthings of the wealthy and powerful. Though modern Free Cities are tremendously varied, a majority of the new communities made a choice about whether extreme practices were a flaw in a lawless society or one of its benefits.`,
		App.UI.DOM.makeElement("span", `How did most Free Cities react to the excesses of the early days?`, ["intro", "question"])
	]);

	App.Events.addResponses(node, [
		new App.Events.Result(`They drew back from them.`, drewBack, `Extreme content such as amputation and castration will not appear.`),
		new App.Events.Result(`They reveled in them.`, reveled, `Extreme content will appear.`),
		new App.Events.Result(`They drew back from them, but remained creative.`, creative, `Extreme content will not appear, but hyper-pregnancy related content might appear.`),
		new App.Events.Result(`They reveled in them and were particularly inventive.`, inventive, `Extreme content will appear, including hyper-pregnancy related content`),
	]);

	return node;

	function drewBack() {
		V.seeExtreme = 0;
		Engine.play("Gender Intro");
		return ``;
	}

	function reveled() {
		V.seeExtreme = 1;
		Engine.play("Gender Intro");
		return ``;
	}

	function creative() {
		V.seeExtreme = 0;
		V.seeHyperPreg = 1;
		Engine.play("Gender Intro");
		return ``;
	}

	function inventive() {
		V.seeExtreme = 1;
		V.seeHyperPreg = 1;
		Engine.play("Gender Intro");
		return ``;
	}
};


code:
App.Intro.genderIntro = function() {
	const node = new DocumentFragment();

	App.Events.addParagraph(node, [
		`The Free Cities are sexually libertine places, and sexual slavery is ubiquitous. Some of the early Free Cities upheld or even strengthened traditional gender roles, expecting men to be men and women to be women. Others subscribed to an interesting refinement of those gender roles, considering any sex slave female, regardless of her biology. A small minority even went so far as to strongly favor societal feminization of slaves born male; in these, biologically female slaves were a rare sight.`,
		App.UI.DOM.makeElement("span", `Which kind of Free City came to predominate?`, ["intro", "question"])
	]);

	App.Events.addResponses(node, [
		new App.Events.Result(`Free Cities that were open-minded about who could be a slave girl.`, open, `Default setting. The majority of slaves will be biologically female, and all content will be available.`),
		new App.Events.Result(`Free Cities that understood that girls are girls.`, girlIsGirl, `Almost all slaves will be biologically female, restricting some content.`),
		new App.Events.Result(`Free Cities that understood that girls are girls with some exceptions.`, exceptions, `This option will make almost all generated slaves female, but will allow for the attachment of a certain organ through surgery.`),
		new App.Events.Result(`Free Cities that preferred girls with dicks.`, slaveIsBoy, `Almost all slaves will be biologically male, restricting some content.`),
	]);

	return node;

	function open() {
		V.seeDicks = 25;
		Engine.play("Slave Age Intro");
		return ``;
	}

	function girlIsGirl() {
		V.seeDicks = 0;
		Engine.play("Slave Age Intro");
		return ``;
	}

	function exceptions() {
		V.seeDicks = 0;
		V.makeDicks = 1;
		Engine.play("Slave Age Intro");
		return ``;
	}

	function slaveIsBoy() {
		V.seeDicks = 100;
		Engine.play("Slave Age Intro");
		return ``;
	}
};


code:
App.Intro.initNationalities = function() {
	function applyPCQualities() {
		resetEyeColor(V.PC);
		generatePlayerPronouns(V.PC);

		switch (V.PC.career) {
			case "arcology owner":
				addTrinket("a miniature model of your first arcology");
				repX(2000, "event");
				break;
			case "wealth":
				addTrinket("a collection of diplomas from expensive schools");
				cashX(10000, "personalBusiness");
				break;
			case "trust fund":
				addTrinket("a diploma from your expensive boarding school");
				cashX(8000, "personalBusiness");
				break;
			case "rich kid":
				addTrinket("an extensive collection of pricey Old World trading cards.");
				cashX(6000, "personalBusiness");
				break;
			case "capitalist":
			case "entrepreneur":
			case "business kid":
				addTrinket("a framed low denomination piece of paper money from your native country");
				break;
			case "mercenary":
				addTrinket("a battered old assault rifle");
				break;
			case "recruit":
				addTrinket("a battered old pistol");
				break;
			case "child soldier":
				addTrinket("a combat knife");
				break;
			case "slaver":
				addTrinket("a framed picture of a slave with her sale price scrawled across the bottom");
				break;
			case "slave overseer":
				addTrinket("a framed picture of slave pens you used to lord over");
				break;
			case "slave tender":
				addTrinket("a framed picture of you hosing down a slave for market");
				break;
			case "engineer":
				addTrinket("an artist's impression of an early arcology design");
				V.arcologyUpgrade.drones = 1;
				V.arcologyUpgrade.hydro = 1;
				App.Mods.SecExp.unit.gen("bots", true);
				break;
			case "construction":
				addTrinket("the blueprints of a proto-arcology you helped construct");
				V.arcologyUpgrade.drones = 1;
				App.Mods.SecExp.unit.gen("bots", true);
				break;
			case "worksite helper":
				addTrinket("the hardhat you used to wear around worksites");
				break;
			case "medicine":
				addTrinket("a framed postsurgical x-ray");
				V.surgeryCost = Math.trunc(V.surgeryCost / 2);
				break;
			case "medical assistant":
				addTrinket("your personal set of surgical tools");
				V.surgeryCost = Math.trunc(V.surgeryCost / 2);
				break;
			case "nurse":
				addTrinket("a framed picture of you outside the clinic you worked in");
				V.surgeryCost = Math.trunc(V.surgeryCost / 2);
				break;
			case "celebrity":
				addTrinket("a framed copy of the first news story featuring yourself");
				repX(4000, "event");
				break;
			case "rising star":
				addTrinket("a framed poster of the first movie you starred in");
				repX(3000, "event");
				break;
			case "child star":
				addTrinket("a copy of the movie that gave you fame");
				repX(2000, "event");
				break;
			case "BlackHat":
				addTrinket("a news clipping of your first successful live hack");
				break;
			case "hacker":
				addTrinket("an old USB stick that ruined a corporation");
				break;
			case "script kiddy":
				addTrinket("a CD containing your first foray into scripting");
				break;
			case "escort":
				addTrinket("a copy of the first porno you starred in");
				break;
			case "prostitute":
				addTrinket("a nude pinup of you from the brothel you used to work in");
				V.PC.boobsTat = "You have your ID number from your days as a prostitute tattooed on your left breast.";
				break;
			case "child prostitute":
				addTrinket("a pair of your used underwear");
				V.PC.boobsTat = "You have your ID number from your days as a prostitute tattooed on your left breast.";
				break;
			case "servant":
				addTrinket("a framed picture of your late Master");
				V.PC.boobsTat = "You have your Master's brand tattooed on your left breast.";
				break;
			case "handmaiden":
				addTrinket("a framed picture of your late Master's family");
				V.PC.boobsTat = "You have your Master's brand tattooed on your left breast.";
				break;
			case "child servant":
				addTrinket("a framed picture of your late Master patting your head");
				V.PC.boobsTat = "You have your Master's brand tattooed on your left breast.";
				break;
			case "gang":
				addTrinket("your favorite handgun, whose sight has instilled fear in many");
				break;
			case "hoodlum":
				addTrinket("a hood ornament stolen from a fancy Old World vehicle");
				V.PC.shouldersTat = "You have a tattoo denoting your gang affiliation on your neck.";
				break;
			case "street urchin":
				addTrinket("your trusty knife, whose kept you safe many a night");
				V.PC.shouldersTat = "You have a tattoo denoting your gang affiliation on your neck.";
				break;
		}

		if (V.PC.rumor === "wealth") {
			cashX(10000, "personalBusiness");
		} else if (V.PC.rumor === "social engineering") {
			V.FSAnnounced = 1;
			V.FSGotRepCredits = 1;
		} else if (V.PC.rumor === "luck") {
			repX(4000, "event");
		}

		if (V.PC.visualAge >= 50) {
			repX(2000, "event");
		} else if (V.PC.visualAge < 35) {
			if (V.rep >= 2000) {
				repX(-2000, "event");
			} else {
				/* set rep to zero */
				repX(forceNeg(Math.abs(V.rep)), "event");
			}
		}
	}

	function initArcologies() {
		/** @type {Array<FC.ArcologyDirection>} */
		const seed = ["east", "north", "northeast", "northwest", "south", "southeast", "southwest", "west"];
		const govtypes = ["a committee", "a corporation", "an individual", "an oligarchy", "direct democracy", "elected officials"];

		V.neighboringArcologies = variableAsNumber(V.neighboringArcologies, 0, 8, 3);
		for (let i = 0; i <= V.neighboringArcologies; i++) {
			/** @type {FC.ArcologyState} */
			const newArcology = {
				name: "",
				direction: "north",
				government: "an individual",
				leaderID: 0,
				honeymoon: 0,
				prosperity: 50,
				ownership: 50,
				minority: 20,
				PCminority: 0,
				demandFactor: 0,
				FSSupremacist: "unset",
				FSSupremacistRace: 0,
				FSSubjugationist: "unset",
				FSSubjugationistRace: 0,
				FSGenderRadicalist: "unset",
				FSGenderFundamentalist: "unset",
				FSPaternalist: "unset",
				FSDegradationist: "unset",
				FSBodyPurist: "unset",
				FSTransformationFetishist: "unset",
				FSYouthPreferentialist: "unset",
				FSMaturityPreferentialist: "unset",
				FSSlimnessEnthusiast: "unset",
				FSAssetExpansionist: "unset",
				FSPastoralist: "unset",
				FSPhysicalIdealist: "unset",
				FSChattelReligionist: "unset",
				FSRomanRevivalist: "unset",
				FSAztecRevivalist: "unset",
				FSEgyptianRevivalist: "unset",
				FSEdoRevivalist: "unset",
				FSNeoImperialist: "unset",
				FSArabianRevivalist: "unset",
				FSChineseRevivalist: "unset",
				FSNull: "unset",
				embargo: 1,
				embargoTarget: -1,
				influenceTarget: -1,
				influenceBonus: 0,
				CyberEconomic: 1,
				CyberEconomicTarget: -1,
				CyberReputation: 1,
				CyberReputationTarget: -1,
				rival: 0,
				FSRestart: "unset",
				FSRepopulationFocus: "unset",
				FSHedonisticDecadence: "unset",
				FSIntellectualDependency: "unset",
				FSSlaveProfessionalism: "unset",
				FSPetiteAdmiration: "unset",
				FSStatuesqueGlorification: "unset",
				FSCummunism: "unset",
				FSIncestFetishist: "unset",
				FSGenderRadicalistResearch: 0,
				FSGenderFundamentalistResearch: 0,
				FSPaternalistResearch: 0,
				FSDegradationistResearch: 0,
				FSBodyPuristResearch: 0,
				FSTransformationFetishistResearch: 0,
				FSYouthPreferentialistResearch: 0,
				FSMaturityPreferentialistResearch: 0,
				FSSlimnessEnthusiastResearch: 0,
				FSAssetExpansionistResearch: 0,
				FSPastoralistResearch: 0,
				FSPhysicalIdealistResearch: 0,
				FSRepopulationFocusResearch: 0,
				FSRestartResearch: 0,
				FSHedonisticDecadenceResearch: 0,
				FSHedonisticDecadenceDietResearch: 0,
				FSIntellectualDependencyResearch: 0,
				FSSlaveProfessionalismResearch: 0,
				FSPetiteAdmirationResearch: 0,
				FSStatuesqueGlorificationResearch: 0,
				FSCummunismResearch: 0,
				FSIncestFetishistResearch: 0,
				weeks: 0,
			};
			if (i === 0) {
				newArcology.direction = 0;
				newArcology.name = "Arcology X-4";
				newArcology.FSSupremacistDecoration = 20;
				newArcology.FSSubjugationistDecoration = 20;
				newArcology.FSGenderRadicalistDecoration = 20;
				newArcology.FSGenderFundamentalistDecoration = 20;
				newArcology.FSPaternalistDecoration = 20;
				newArcology.FSDegradationistDecoration = 20;
				newArcology.FSBodyPuristDecoration = 20;
				newArcology.FSTransformationFetishistDecoration = 20;
				newArcology.FSYouthPreferentialistDecoration = 20;
				newArcology.FSMaturityPreferentialistDecoration = 20;
				newArcology.FSSlimnessEnthusiastDecoration = 20;
				newArcology.FSAssetExpansionistDecoration = 20;
				newArcology.FSPastoralistDecoration = 20;
				newArcology.FSPhysicalIdealistDecoration = 20;
				newArcology.FSChattelReligionistDecoration = 20;
				newArcology.FSRomanRevivalistDecoration = 20;
				newArcology.FSNeoImperialistDecoration = 20;
				newArcology.FSAztecRevivalistDecoration = 20;
				newArcology.FSEgyptianRevivalistDecoration = 20;
				newArcology.FSEdoRevivalistDecoration = 20;
				newArcology.FSArabianRevivalistDecoration = 20;
				newArcology.FSChineseRevivalistDecoration = 20;
				newArcology.FSRepopulationFocusDecoration = 20;
				newArcology.FSRestartDecoration = 20;
				newArcology.FSHedonisticDecadenceDecoration = 20;
				newArcology.FSIntellectualDependencyDecoration = 20;
				newArcology.FSSlaveProfessionalismDecoration = 20;
				newArcology.FSPetiteAdmirationDecoration = 20;
				newArcology.FSStatuesqueGlorificationDecoration = 20;
				newArcology.FSCummunismDecoration = 20;
				newArcology.FSIncestFetishistDecoration = 20;
				if (V.targetArcology.fs !== "New") {
					V.FSAnnounced = 1;
					V.FSGotRepCredits = 1;
					newArcology.name = V.targetArcology.name;
					newArcology.prosperity = V.targetArcology.prosperity;
					V.ACitizens += V.targetArcology.citizens*500;
					if (V.targetArcology.fs === "FSNull") {
						newArcology.FSNull = 20;
					} else {
						const decoration = V.targetArcology.FSProgress + 10;
						newArcology[V.targetArcology.fs] = V.targetArcology.FSProgress;
						newArcology[`${V.targetArcology.fs}Decoration`] = decoration;
						if (V.targetArcology.fs === "FSSupremacist") {
							newArcology.FSSupremacistRace = V.targetArcology.race;
						} else if (V.targetArcology.fs === "FSSubjugationist") {
							newArcology.FSSubjugationistRace = V.targetArcology.race;
						}
					}
					const fsLanguage = App.Data.FutureSociety.records[V.targetArcology.fs].language;
					if (fsLanguage) {
						V.language = fsLanguage;
					}
					if (V.PC.rumor === "social engineering") {
						V.FSGotRepCredits += 1;
					}
				} else {
					newArcology.honeymoon = 20;
				}
			} else {
				if (i < 4) {
					/* X-4 is reserved for player's arcology, so X-1 is available */
					newArcology.name = `Arcology X-${i}`;
				} else {
					newArcology.name = `Arcology X-${i+1}`;
				}
				newArcology.direction = seed.pluck();
				newArcology.government = govtypes.random();
				newArcology.prosperity += jsRandom(-20, 20);
				newArcology.ownership += jsRandom(-10, 0);
				newArcology.minority += jsRandom(-5, 5);
			}
			V.arcologies.push(newArcology);
		}

		V.arcologies[0].FSSupremacistLawME = 0;
		V.arcologies[0].FSSupremacistSMR = 0;
		V.arcologies[0].FSSubjugationistLawME = 0;
		V.arcologies[0].FSSubjugationistSMR = 0;
		V.arcologies[0].FSGenderRadicalistLawFuta = 0;
		V.arcologies[0].FSGenderRadicalistLawBeauty = 0;
		V.arcologies[0].FSGenderFundamentalistLawBimbo = 0;
		V.arcologies[0].FSGenderFundamentalistSMR = 0;
		V.arcologies[0].FSGenderFundamentalistLawBeauty = 0;
		V.arcologies[0].FSPaternalistLaw = 0;
		V.arcologies[0].FSPaternalistSMR = 0;
		V.arcologies[0].FSDegradationistLaw = 0;
		V.arcologies[0].FSDegradationistSMR = 0;
		V.arcologies[0].FSBodyPuristLaw = 0;
		V.arcologies[0].FSBodyPuristSMR = 0;
		V.arcologies[0].FSBodyPuristCatLaw = 0;
		V.arcologies[0].FSTransformationFetishistSMR = 0;
		V.arcologies[0].FSYouthPreferentialistLaw = 0;
		V.arcologies[0].FSYouthPreferentialistSMR = 0;
		V.arcologies[0].FSMaturityPreferentialistLaw = 0;
		V.arcologies[0].FSMaturityPreferentialistSMR = 0;
		V.arcologies[0].FSSlimnessEnthusiastSMR = 0;
		V.arcologies[0].FSSlimnessEnthusiastLaw = 0;
		V.arcologies[0].FSAssetExpansionistSMR = 0;
		V.arcologies[0].FSPastoralistLaw = 0;
		V.arcologies[0].FSPastoralistSMR = 0;
		V.arcologies[0].FSPhysicalIdealistSMR = 0;
		V.arcologies[0].FSPhysicalIdealistLaw = 0;
		V.arcologies[0].FSPhysicalIdealistStrongFat = 0;
		V.arcologies[0].FSChattelReligionistLaw = 0;
		V.arcologies[0].FSChattelReligionistSMR = 0;
		V.arcologies[0].FSChattelReligionistCreed = 0;
		V.arcologies[0].FSRomanRevivalistLaw = 0;
		V.arcologies[0].FSRomanRevivalistSMR = 0;
		V.arcologies[0].FSNeoImperialistSMR = 0;
		V.arcologies[0].FSNeoImperialistLaw1 = 0;
		V.arcologies[0].FSNeoImperialistLaw2 = 0;
		V.arcologies[0].FSAztecRevivalistLaw = 0;
		V.arcologies[0].FSAztecRevivalistSMR = 0;
		V.arcologies[0].FSEgyptianRevivalistLaw = 0;
		V.arcologies[0].FSEgyptianRevivalistSMR = 0;
		V.arcologies[0].FSEdoRevivalistLaw = 0;
		V.arcologies[0].FSEdoRevivalistSMR = 0;
		V.arcologies[0].FSArabianRevivalistLaw = 0;
		V.arcologies[0].FSArabianRevivalistSMR = 0;
		V.arcologies[0].FSChineseRevivalistLaw = 0;
		V.arcologies[0].FSChineseRevivalistSMR = 0;
		V.arcologies[0].FSRepopulationFocusLaw = 0;
		V.arcologies[0].FSRepopulationFocusSMR = 0;
		V.arcologies[0].FSRestartLaw = 0;
		V.arcologies[0].FSRestartSMR = 0;
		V.arcologies[0].FSHedonisticDecadenceLaw = 0;
		V.arcologies[0].FSHedonisticDecadenceLaw2 = 0;
		V.arcologies[0].FSHedonisticDecadenceStrongFat = 0;
		V.arcologies[0].FSHedonisticDecadenceSMR = 0;
		V.arcologies[0].FSIntellectualDependencyLaw = 0;
		V.arcologies[0].FSIntellectualDependencyLawBeauty = 0;
		V.arcologies[0].FSIntellectualDependencySMR = 0;
		V.arcologies[0].FSSlaveProfessionalismLaw = 0;
		V.arcologies[0].FSSlaveProfessionalismSMR = 0;
		V.arcologies[0].FSPetiteAdmirationLaw = 0;
		V.arcologies[0].FSPetiteAdmirationLaw2 = 0;
		V.arcologies[0].FSPetiteAdmirationSMR = 0;
		V.arcologies[0].FSStatuesqueGlorificationLaw = 0;
		V.arcologies[0].FSStatuesqueGlorificationLaw2 = 0;
		V.arcologies[0].FSStatuesqueGlorificationSMR = 0;

		V.arcologies[0].FSGenderRadicalistResearch = 0;
		V.arcologies[0].FSGenderFundamentalistResearch = 0;
		V.arcologies[0].FSPaternalistResearch = 0;
		V.arcologies[0].FSDegradationistResearch = 0;
		V.arcologies[0].FSBodyPuristResearch = 0;
		V.arcologies[0].FSTransformationFetishistResearch = 0;
		V.arcologies[0].FSYouthPreferentialistResearch = 0;
		V.arcologies[0].FSMaturityPreferentialistResearch = 0;
		V.arcologies[0].FSSlimnessEnthusiastResearch = 0;
		V.arcologies[0].FSAssetExpansionistResearch = 0;
		V.arcologies[0].FSPastoralistResearch = 0;
		V.arcologies[0].FSPhysicalIdealistResearch = 0;
		V.arcologies[0].FSRepopulationFocusResearch = 0;
		V.arcologies[0].FSRestartResearch = 0;
		V.arcologies[0].FSHedonisticDecadenceResearch = 0;
		V.arcologies[0].FSHedonisticDecadenceDietResearch = 0;
		V.arcologies[0].FSCummunismResearch = 0;
		V.arcologies[0].FSIncestFetishistResearch = 0;
		V.arcologies[0].FSIntellectualDependencyResearch = 0;
		V.arcologies[0].FSSlaveProfessionalismResearch = 0;
		V.arcologies[0].FSPetiteAdmirationResearch = 0;
		V.arcologies[0].FSStatuesqueGlorificationResearch = 0;

		V.arcologies[0].FSEgyptianRevivalistIncestPolicy = 0;
		V.arcologies[0].FSEgyptianRevivalistInterest = 0;
		V.arcologies[0].FSRepopulationFocusPregPolicy = 0;
		V.arcologies[0].FSRepopulationFocusMilfPolicy = 0;
		V.arcologies[0].FSRepopulationFocusInterest = 0;
		V.arcologies[0].FSEugenicsChastityPolicy = 0;
		V.arcologies[0].FSEugenicsSterilizationPolicy = 0;
		V.arcologies[0].FSEugenicsInterest = 0;

		V.arcologies[0].childhoodFertilityInducedNCSResearch = 0;
	}

	if (V.targetArcology.fs !== "New") {
		V.building = V.targetArcology.building;
		delete V.targetArcology.building;
	} else {
		V.building = App.Arcology.defaultBuilding(V.terrain);
	}
	const sellable = V.building.findCells(cell => cell.canBeSold());
	const random12 = jsRandomMany(sellable, 12);
	random12.forEach(cell => { cell.owner = 0; });

	App.Mods.SecExp.Init();

	if (V.localEcon > 100) {
		V.mods.food.cost = Math.max(5 / (1 + (Math.trunc(1000-100000/V.localEcon)/10)/100), 3.125);
	} else if (V.localEcon === 100) {
		V.mods.food.cost = 5;
	} else {
		V.mods.food.cost = Math.min(5 * (1 + 1.5 * Math.sqrt(Math.trunc(100000/V.localEcon-1000)/10)/100), 6.5);
	}

	V.minimumSlaveAge = variableAsNumber(V.minimumSlaveAge, 3, 18, 18);
	V.retirementAge = variableAsNumber(V.retirementAge, 25, 120, 45);
	V.fertilityAge = variableAsNumber(V.fertilityAge, 3, 18, 13);
	V.potencyAge = variableAsNumber(V.potencyAge, 3, 18, 13);

	applyPCQualities();

	/* SET STARTING CONDITIONS */

	V.enduringRep = V.rep;

	initArcologies();

	V.HackingSkillMultiplier = upgradeMultiplier('hacking');
	V.upgradeMultiplierArcology = upgradeMultiplier('engineering');
	V.upgradeMultiplierMedicine = upgradeMultiplier('medicine');
	V.upgradeMultiplierTrade = upgradeMultiplier('trading');

	/* Nationalities Setup */

	if (!V.customVariety) {
		/* If non-custom variety, empties or defines V.nationalities */
		V.nationalities = {};
	}
	const needLocalNationalities = !V.customVariety && !V.internationalTrade;
	if (V.terrain === "oceanic") {
		if (V.targetArcology.fs !== "FSSupremacist") {
			V.arcologies[0].FSSupremacistRace = "white";
		}
		if (V.targetArcology.fs !== "FSSubjugationist") {
			V.arcologies[0].FSSubjugationistRace = "middle eastern";
		}
		if (needLocalNationalities) {
			// FIXME: equal distributions? probably should use weighted variety instead
			V.nationalities = arr2obj(App.Data.misc.baseNationalities);
		}
	} else {
		/** @type {Map<string, {supr: FC.Race, subj: FC.Race, preset: string}>} */
		const continentalDefaults = new Map([
			["North America",	{supr: "white", subj: "black", preset: "Vanilla North America"}],
			["South America",	{supr: "latina", subj: "black", preset: "Vanilla South America"}],
			["Brazil",			{supr: "white", subj: "black", preset: "Vanilla South America"}],
			["the Middle East",	{supr: "middle eastern", subj: "asian", preset: "Vanilla Middle East"}],
			["Africa",			{supr: "black", subj: "white", preset: "Vanilla Africa"}],
			["Asia",			{supr: "asian", subj: "indo-aryan", preset: "Vanilla Asia"}],
			["Western Europe",	{supr: "white", subj: "middle eastern", preset: "Vanilla Europe"}],
			["Central Europe",	{supr: "white", subj: "middle eastern", preset: "Vanilla Europe"}],
			["Eastern Europe",	{supr: "white", subj: "asian", preset: "Vanilla Europe"}],
			["Scandinavia",		{supr: "white", subj: "southern european", preset: "Vanilla Europe"}],
			["Southern Europe",	{supr: "southern european", subj: "middle eastern", preset: "Vanilla Europe"}],
			["Australia",		{supr: "white", subj: "asian", preset: "Vanilla Australia"}],
			["Japan",			{supr: "asian", subj: "asian", preset: null}]
		]);

		const defaults = continentalDefaults.get(V.continent);
		if (!defaults) {
			throw Error(`Missing defaults for continent: ${V.continent}`);
		}
		if (V.targetArcology.fs !== "FSSupremacist") {
			V.arcologies[0].FSSupremacistRace = defaults.supr;
		}
		if (V.targetArcology.fs !== "FSSubjugationist") {
			V.arcologies[0].FSSubjugationistRace = defaults.subj;
		}
		if (needLocalNationalities) {
			if (V.continent === "Japan") { // special case, no preset for Japan
				hashPush(V.nationalities, "Japanese", "Japanese", "Japanese");
			} else {
				hashMerge(V.nationalities, App.Data.NationalityPresets.Vanilla.get(defaults.preset));
			}
		}
	}

	if (!V.customVariety && V.internationalTrade) {
		if (V.internationalVariety === 0) { // weighted
			hashMerge(V.nationalities, App.Data.NationalityPresets.Vanilla.get("Vanilla Global"));
		} else { // normalized
			V.nationalities = arr2obj(App.Data.misc.baseNationalities);
		}
	}
};