code:
App.UI.fsPassage = function() {
	const arc = V.arcologies[0];
	V.FSReminder = 0;
	const FSCredits = FutureSocieties.availCredits();
	setup();

	V.nextButton = "Back";
	V.nextLink = "Main";
	V.encyclopedia = "Future Societies";

	const f = new DocumentFragment();

	if (V.cheatMode) {
		App.UI.DOM.appendNewElement("div", f, App.UI.DOM.passageLink(
			"Cheat Edit Future Society",
			"MOD_Edit Arcology Cheat",
			() => {
				V.cheater = 1;
			}
		), "cheat-menu");
	}

	App.UI.DOM.appendNewElement("h1", f, "Future Societies");

	f.append(overview());
	f.append(FSPerception());
	f.append(unlocks());
	f.append(spending());
	f.append(rename());
	f.append(selectFS());

	App.UI.DOM.appendNewElement("h2", f, "Facility Redecoration");

	f.append(App.UI.facilityRedecoration());
	return f;

	/**
	 * FIRST FS STORING FOR RIVALRY
	 */
	function setup() {
		if (V.rival.FS.name === "") {
			if (arc.FSSubjugationist !== "unset") {
				V.rival.FS.name = "Racial Subjugationism";
				V.rival.FS.race = arc.FSSubjugationistRace;
			}
			if (arc.FSSupremacist !== "unset") {
				V.rival.FS.name = "Racial Supremacism";
				V.rival.FS.race = arc.FSSupremacistRace;
			}
			if (arc.FSGenderRadicalist !== "unset") {
				V.rival.FS.name = "Gender Radicalism";
			} else if (arc.FSGenderFundamentalist !== "unset") {
				V.rival.FS.name = "Gender Fundamentalism";
			}
			if (arc.FSRepopulationFocus !== "unset") {
				V.rival.FS.name = "Repopulation Focus";
			} else if (arc.FSRestart !== "unset") {
				V.rival.FS.name = "Eugenics";
			}
			if (arc.FSPaternalist !== "unset") {
				V.rival.FS.name = "Paternalism";
			} else if (arc.FSDegradationist !== "unset") {
				V.rival.FS.name = "Degradationism";
			}
			if (arc.FSBodyPurist !== "unset") {
				V.rival.FS.name = "Body Purism";
			} else if (arc.FSTransformationFetishist !== "unset") {
				V.rival.FS.name = "Transformation Fetishism";
			}
			if (arc.FSYouthPreferentialist !== "unset") {
				V.rival.FS.name = "Youth Preferentialism";
			} else if (arc.FSMaturityPreferentialist !== "unset") {
				V.rival.FS.name = "Maturity Preferentialism";
			}
			if (arc.FSSlimnessEnthusiast !== "unset") {
				V.rival.FS.name = "Slimness Enthusiasm";
			} else if (arc.FSAssetExpansionist !== "unset") {
				V.rival.FS.name = "Asset Expansionism";
			}
			if (arc.FSPastoralist !== "unset") {
				V.rival.FS.name = "Pastoralism";
			} else if (arc.FSCummunism !== "unset") {
				V.rival.FS.name = "Cummunism";
			}
			if (arc.FSHedonisticDecadence !== "unset") {
				V.rival.FS.name = "Hedonistic Decadence";
			} else if (arc.FSPhysicalIdealist !== "unset") {
				V.rival.FS.name = "Physical Idealism";
			}
			if (arc.FSIntellectualDependency !== "unset") {
				V.rival.FS.name = "Intellectual Dependency";
			} else if (arc.FSSlaveProfessionalism !== "unset") {
				V.rival.FS.name = "Slave Professionalism";
			}
			if (arc.FSPetiteAdmiration !== "unset") {
				V.rival.FS.name = "Petite Admiration";
			} else if (arc.FSStatuesqueGlorification !== "unset") {
				V.rival.FS.name = "Statuesque Glorification";
			}
			if (arc.FSChattelReligionist !== "unset") {
				V.rival.FS.name = "Chattel Religionism";
			} else if (arc.FSNull !== "unset") {
				V.rival.FS.name = "Multiculturalism";
			}
			if (arc.FSRomanRevivalist !== "unset") {
				V.rival.FS.name = "Roman Revivalism";
			} else if (arc.FSNeoImperialist !== "unset") {
				V.rival.FS.name = "Neo-Imperialism";
			} else if (arc.FSAztecRevivalist !== "unset") {
				V.rival.FS.name = "Aztec Revivalism";
			} else if (arc.FSEgyptianRevivalist !== "unset") {
				V.rival.FS.name = "Egyptian Revivalism";
			} else if (arc.FSEdoRevivalist !== "unset") {
				V.rival.FS.name = "Edo Revivalism";
			} else if (arc.FSArabianRevivalist !== "unset") {
				V.rival.FS.name = "Arabian Revivalism";
			} else if (arc.FSChineseRevivalist !== "unset") {
				V.rival.FS.name = "Chinese Revivalism";
			}
		}
	}

	function overview() {
		const el = new DocumentFragment();
		const r = [];
		if (FSCredits > 0) {
			r.push(App.UI.DOM.makeElement("span", `${arc.name}'s society is ready to begin accepting a new societal direction.`, "yellow"));
		} else if (V.FSGotRepCredits >= 3) {
			r.push(`Your society is so radically changed that it is starting to take on a life of its own. The major decisions about its direction have been made.`);
		} else {
			r.push(`You must develop your reputation further for ${arc.name}'s society to be ready for a new societal direction.`);
		}
		App.Events.addNode(el, r, "div");
		return el;
	}

	function FSPerception() {
		const el = new DocumentFragment();
		for (const FS of App.Data.FutureSociety.playerFSNames) {
			if (arc[FS] !== "unset") {
				App.UI.DOM.appendNewElement("div", el, FutureSocieties.arcSupport(FS, arc));
			}
		}
		return el;
	}

	function unlocks() {
		const el = new DocumentFragment();
		const r = [];
		r.push(`You have unlocked`);
		r.push(App.UI.DOM.makeElement("span", `${num(V.FSGotRepCredits, true)} of ${num(V.FSCreditCount, true)}`, "note"));
		r.push(`possible societal customizations.`);
		App.Events.addNode(el, r, "div");
		return el;
	}

	function spending() {
		const el = new DocumentFragment();
		let r = [];
		V.FSSpending = Number(V.FSSpending) || 0;
		V.FSSpending = Math.clamp(Math.ceil(V.FSSpending / 1000) * 1000, 0, 10000);
		r.push(`You are spending ¤`);
		r.push(App.UI.DOM.makeTextBox(
			V.FSSpending,
			(v) => { V.FSSpending = v; },
			true
		));
		r.push(`each week to support your societal goals.`);
		App.Events.addNode(el, r, "div");
		if (V.FSSpending > 10000) {
			App.UI.DOM.appendNewElement("div", el, `Spending more than ${cashFormat(10000)} weekly is a waste`, "note");
		}
		return el;
	}

	function rename() {
		const el = document.createElement('span');
		el.id = "mass";
		const linkArray = [];

		if (arc.FSChattelReligionist !== "unset") {
			linkArray.push(
				App.UI.DOM.link(
					"Give all your slaves devotional names",
					() => {
						for (const slave of V.slaves) {
							slave.slaveName = App.Data.misc.chattelReligionistSlaveNames.random();
						}
						refresh();
					}
				)
			);
		}

		if (arc.FSPastoralist !== "unset") {
			linkArray.push(
				App.UI.DOM.link(
					"Give all your lactating slaves cow names",
					() => {
						for (const slave of V.slaves) {
							if (slave.lactation) {
								slave.slaveName = App.Data.misc.cowSlaveNames.random();
							}
						}
						refresh();
					}
				)
			);
		}

		if (arc.FSIntellectualDependency !== "unset") {
			linkArray.push(
				App.UI.DOM.link(
					"Give all your idiotic slaves stripper names",
					() => {
						for (const slave of V.slaves) {
							if (slave.intelligence < -15) {
								slave.slaveName = App.Data.misc.bimboSlaveNames.random();
							}
						}
						refresh();
					}
				)
			);
		}

		if (arc.FSRomanRevivalist !== "unset") {
			linkArray.push(
				App.UI.DOM.link(
					"Rename all your slaves according to Roman custom",
					() => {
						for (const slave of V.slaves) {
							slave.slaveName = App.Data.misc.romanSlaveNames.random();
							slave.slaveSurname = App.Data.misc.romanSlaveSurnames.random();
						}
						refresh();
					}
				)
			);
		} else if (arc.FSAztecRevivalist !== "unset") {
			linkArray.push(
				App.UI.DOM.link(
					"Rename all your slaves according to ancient Aztec custom",
					() => {
						for (const slave of V.slaves) {
							slave.slaveName = App.Data.misc.aztecSlaveNames.random();
							slave.slaveSurname = 0;
						}
						refresh();
					}
				)
			);
		} else if (arc.FSEgyptianRevivalist !== "unset") {
			linkArray.push(
				App.UI.DOM.link(
					"Rename all your slaves according to ancient Egyptian custom",
					() => {
						for (const slave of V.slaves) {
							slave.slaveName = App.Data.misc.ancientEgyptianSlaveNames.random();
							slave.slaveSurname = 0;
						}
						refresh();
					}
				)
			);
		} else if (arc.FSEdoRevivalist !== "unset") {
			linkArray.push(
				App.UI.DOM.link(
					"Rename all your slaves according to feudal Japanese custom",
					() => {
						for (const slave of V.slaves) {
							slave.slaveName = App.Data.misc.edoSlaveNames.random();
							slave.slaveSurname = App.Data.misc.edoSlaveSurnames.random();
						}
						refresh();
					}
				)
			);
		}
		if (arc.FSDegradationist !== "unset") {
			linkArray.push(
				App.UI.DOM.link(
					"Rename all your slaves according to Degradationist custom",
					() => {
						for (const slave of V.slaves) {
							DegradingName(slave);
						}
						refresh();
					}
				)
			);
		}

		if (arc.FSPaternalist !== "unset") {
			linkArray.push(
				App.UI.DOM.link(
					"Rename your obedient slaves according to Paternalist custom",
					() => {
						for (const slave of V.slaves) {
							if (slave.devotion > 20 || (slave.devotion >= -20 && slave.trust < -20)) {
								if (!["Miss", "Ms.", "Mrs."].some(title => slave.slaveName.includes(title))) {
									if (slave.relationship > 4) {
										slave.slaveName = ("Mrs. " + slave.slaveName);
									} else if (slave.actualAge > 24) {
										slave.slaveName = ("Ms. " + slave.slaveName);
									} else {
										slave.slaveName = ("Miss " + slave.slaveName);
									}
								}
							}
						}
						refresh("Obedient slaves renamed.");
					}
				)
			);
		}

		if (arc.FSIntellectualDependency !== "unset") {
			linkArray.push(
				App.UI.DOM.link(
					"Give all your slaves simple bimbo names",
					() => {
						for (const slave of V.slaves) {
							slave.slaveName = App.Data.misc.bimboSlaveNames.random();
							slave.slaveSurname = 0;
						}
						refresh();
					}
				)
			);
		}

		if (linkArray.length > 0) {
			App.UI.DOM.appendNewElement("h3", el, "Names");
			el.append(App.UI.DOM.generateLinksStrip(linkArray));
		}

		return el;

		function refresh(text = "Slaves renamed.") {
			jQuery("#mass").empty().append(text);
		}
	}

	function selectFS() {
		const el = new DocumentFragment();
		let r;
		let p;

		/* Race */
		p = document.createElement("p");
		r = [];
		if (arc.FSSupremacist !== "unset") {
			r.push(pursuit());
			r.push(`${arc.FSSupremacistRace} superiority.`);
			r.push(activeFS("FSSupremacist"));
		} else {
			if (FSCredits > 0) {
				r.push(
					App.UI.DOM.link(
						"Racial Supremacism",
						() => {
							arc.FSSupremacist = 4;
							App.UI.reload();
						}
					)
				);
				r.push(`is a belief in`);
				if (arc.FSSupremacistRace === 0) {
					r.push(`the superiority of a chosen race.`);
				} else {
					r.push(`${arc.FSSupremacistRace} superiority.`);
				}
				r.push(`Select race:`);
				const options = [];
				for (const race of App.Utils.getRaceArrayWithoutParamRace(arc.FSSubjugationistRace)) { // Subjugation race cannot be superior, so remove
					options.push({key: race, name: capFirstChar(race)});
				}
				r.push(App.UI.DOM.makeSelect(options, arc.FSSupremacistRace, race => {
					arc.FSSupremacistRace = /** @type {FC.Race} */ (race);
					App.UI.reload();
				}));
			} else {
				/* Racial Supremacism: a belief in the superiority of a chosen race.*/
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if (arc.FSSubjugationist !== "unset") {
			r.push(pursuit());
			r.push(`${arc.FSSubjugationistRace} inferiority.`);
			r.push(activeFS("FSSubjugationist"));
		} else {
			if (FSCredits > 0) {
				r.push(
					App.UI.DOM.link(
						"Racial Subjugationism",
						() => {
							arc.FSSubjugationist = 4;
							App.UI.reload();
						}
					)
				);
				r.push(`is a belief in`);
				if (arc.FSSubjugationistRace === 0) {
					r.push(`the inferiority of a chosen race.`);
				} else {
					r.push(`${arc.FSSubjugationistRace} inferiority.`);
				}
				r.push(`Select race:`);

				const options = [];
				for (const race of App.Utils.getRaceArrayWithoutParamRace(arc.FSSupremacistRace)) { // Superior race cannot be subj, so remove
					options.push({key: race, name: capFirstChar(race)});
				}
				r.push(App.UI.DOM.makeSelect(options, arc.FSSubjugationistRace, race => {
					arc.FSSubjugationistRace = race;
					App.UI.reload();
				}));
			} else {
				/* Racial Subjugationism: a belief in the inferiority of a subject race.*/
			}
		}
		App.Events.addNode(p, r, "div");
		el.append(p);

		/* Preg vs Eugenics */
		if (V.seePreg !== 0) {
			p = document.createElement("p");
			r = [];
			if (arc.FSRestart === "unset") {
				if (arc.FSRepopulationFocus !== "unset") {
					r.push(pursuit());
					r.push(`the belief that mass breeding will save humanity.`);
					r.push(activeFS("FSRepopulationFocus", ["boughtItem.clothing.maternityLingerie", "boughtItem.clothing.maternityDress", "boughtItem.clothing.belly"]));
				} else {
					if (FSCredits > 0) {
						r.push(
							App.UI.DOM.link(
								"Repopulation Efforts",
								() => {
									arc.FSRepopulationFocus = 4 + arc.FSRepopulationFocusInterest - arc.FSEugenicsInterest;
									arc.FSRepopulationFocusPregPolicy = 0;
									arc.FSRepopulationFocusMilfPolicy = 0;
									App.UI.reload();
								}
							)
						);
						r.push(`is a focus on mass breeding in order to repopulate the future world.`);
					} else {
						/* Repopulation Efforts: societal fetishization of pregnancy.*/
					}
				}
			}
			App.Events.addNode(p, r, "div");
			r = [];
			if (arc.FSRepopulationFocus === "unset") {
				if (arc.FSRestart !== "unset") {
					if (arc.FSRestartDecoration !== 100) {
						r.push(pursuit());
						r.push(`Eugenics.`);
						r.push(activeFS("FSRestart"));
					} else {
						r.push(App.UI.DOM.makeElement("span", "You have established", "bold"));
						r.push(`Eugenics.`);
						r.push(activeFS("FSRestart"));
						r.push(`The Societal Elite exist as the highest class, allowing you access to all manner of benefits.`);
					}
				} else {
					if (FSCredits > 0) {
						r.push(
							App.UI.DOM.link(
								"Eugenics",
								() => {
									arc.FSRestart = 4 + arc.FSEugenicsInterest - arc.FSRepopulationFocusInterest;
									arc.FSRepopulationFocusPregPolicy = 0;
									arc.FSRepopulationFocusMilfPolicy = 0;
									App.UI.reload();
								}
							)
						);
						r.push(`is rebuilding society using restrictive breeding programs reserved solely for society's finest.`);
					} else {
						/* Complete Societal Reconstruction: rebuilding society based off the elite.*/
					}
				}
			}
			App.Events.addNode(p, r, "div");
			el.append(p);
		}

		/* Pro vs Dependant */
		p = document.createElement("p");
		r = [];
		if (arc.FSSlaveProfessionalism === "unset") {
			if (arc.FSIntellectualDependency !== "unset") {
				r.push(pursuit());
				r.push(`intellectual dependency, a belief that slaves should be airheaded, horny and fully dependent on their owners.`);
				r.push(activeFS("FSIntellectualDependency", ["boughtItem.clothing.bimbo"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Intellectual Dependency",
							() => {
								arc.FSIntellectualDependency = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is a belief that slaves should be airheaded, horny and fully dependent on their owners.`);
				} else {
					/* Intellectual Dependency: a belief that slaves should be airheaded, horny and fully dependent on their owners.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if (arc.FSIntellectualDependency === "unset") {
			if (arc.FSSlaveProfessionalism !== "unset") {
				r.push(pursuit());
				r.push(`slave professionalism, a focus on smart, refined, altogether perfect slaves.`);
				r.push(activeFS("FSSlaveProfessionalism", ["boughtItem.clothing.courtesan"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Slave Professionalism",
							() => {
								arc.FSSlaveProfessionalism = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is increased interest in smart, refined, altogether perfect slaves.`);
				} else {
					/* Slave Professionalism: increased interest in smart, refined, altogether perfect slaves.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		el.append(p);

		/* Gender */
		p = document.createElement("p");
		r = [];
		if (V.seeDicks !== 0 || V.makeDicks === 1) {
			if (arc.FSGenderFundamentalist === "unset") {
				if (arc.FSGenderRadicalist !== "unset") {
					r.push(pursuit());
					r.push(`a radical redefinition of gender that identifies powerful people as male, and everyone else as female.`);
					r.push(activeFS("FSGenderRadicalist"));
				} else {
					if (FSCredits > 0) {
						r.push(
							App.UI.DOM.link(
								"Gender radicalism",
								() => {
									arc.FSGenderRadicalist = 4;
									App.UI.reload();
								}
							)
						);
						r.push(`is a radical redefinition of gender that identifies powerful people as male, and everyone else as female.`);
					} else {
						/* Gender radicalism: a radical redefinition of gender that identifies powerful people as male, and everyone else as female.*/
					}
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if (arc.FSGenderRadicalist === "unset") {
			if (arc.FSGenderFundamentalist !== "unset") {
				r.push(pursuit());
				r.push(`gender traditionalism, including a societal preference for feminine slaves ${(V.seePreg !== 0) ? ` and support for slave pregnancy` : ``}.`);
				r.push(activeFS("FSGenderFundamentalist", ["boughtItem.clothing.bunny"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Gender traditionalism",
							() => {
								arc.FSGenderFundamentalist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`gender traditionalism, including a societal preference for feminine slaves ${(V.seePreg !== 0) ? ` and support for slave pregnancy` : ``}.`);
				} else {
					/* Gender traditionalism: a societal preference for feminine slaves
						if (V.seePreg !== 0) {
							r.push(`and support for slave pregnancy`);
						}
						r.push(`.</span>`);*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		el.append(p);

		/* Deg vs Paternalist */
		p = document.createElement("p");
		r = [];
		if (arc.FSDegradationist === "unset") {
			if (arc.FSPaternalist !== "unset") {
				r.push(pursuit());
				r.push(`a vision of slave improvement, including slaves' health, mental well-being, and education.`);
				r.push(activeFS("FSPaternalist", ["boughtItem.clothing.conservative"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Paternalism",
							() => {
								arc.FSPaternalist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is a vision of slave improvement, including slaves' health, mental well-being, and education.`);
				} else {
					/* Paternalism: a vision of slave improvement, including slaves' health, mental well-being, and education.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if (arc.FSPaternalist === "unset") {
			if (arc.FSDegradationist !== "unset") {
				r.push(pursuit());
				r.push(`slave degradation, a belief that slaves are not human and should not be treated decently.`);
				r.push(activeFS("FSDegradationist", ["boughtItem.clothing.chains"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Degradationism",
							() => {
								arc.FSDegradationist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is a belief that slaves are not human and should not be treated decently.`);
				} else {
					/* Degradation: a belief that slaves are not human and should not be treated decently.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		el.append(p);

		/* TF vs Purist */
		p = document.createElement("p");
		r = [];
		if (arc.FSTransformationFetishist === "unset") {
			if (arc.FSBodyPurist !== "unset") {
				r.push(pursuit());
				r.push(`societal disapproval of implant surgery.`);
				r.push(activeFS("FSBodyPurist"));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Body Purism",
							() => {
								arc.FSBodyPurist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is societal disapproval of implant surgery.`);
				} else {
					/* Body Purism: societal disapproval of implant surgery.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if (arc.FSBodyPurist === "unset") {
			if (arc.FSTransformationFetishist !== "unset") {
				r.push(pursuit());
				r.push(`societal fetishization of implant surgery.`);
				r.push(activeFS("FSTransformationFetishist"));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Transformation Fetishism",
							() => {
								arc.FSTransformationFetishist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is societal fetishization of implant surgery.`);
				} else {
					/* Transformation Fetishism: societal fetishization of implant surgery.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		el.append(p);

		/* Maturity vs Youth */
		p = document.createElement("p");
		r = [];
		if (arc.FSMaturityPreferentialist === "unset") {
			if (arc.FSYouthPreferentialist !== "unset") {
				r.push(pursuit());
				r.push(`an accentuated societal preference for younger slaves.`);
				r.push(activeFS("FSYouthPreferentialist"));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Youth Preferentialism",
							() => {
								arc.FSYouthPreferentialist = 4;
								if (V.idealAge >= 30) {
									V.idealAge = 29;
								}
								if (V.targetIdealAge >= 30) {
									V.targetIdealAge = 29;
								}
								if (V.targetIdealAge !== 18) {
									V.policies.idealAge = 1;
								}
								App.UI.reload();
							}
						)
					);
					r.push(`is increased interest in girls just past their majority.`);
				} else {
					/* Youth Preferentialism: increased interest in girls just past their majority.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if (arc.FSYouthPreferentialist === "unset") {
			if (arc.FSMaturityPreferentialist !== "unset") {
				r.push(pursuit());
				r.push(`a societal preference for older women.`);
				r.push(activeFS("FSMaturityPreferentialist"));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Maturity Preferentialism",
							() => {
								arc.FSMaturityPreferentialist = 4;
								if (V.idealAge < 30) {
									V.idealAge = 30;
								}
								if (V.targetIdealAge < 30) {
									V.targetIdealAge = 30;
								}
								V.policies.idealAge = 1;
								App.UI.reload();
							}
						)
					);
					r.push(`is increased interest in mature slaves.`);
				} else {
					/* Maturity Preferentialism: increased interest in mature slaves.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		el.append(p);

		/* Statuesque vs Petite */
		p = document.createElement("p");
		r = [];
		if (arc.FSStatuesqueGlorification === "unset") {
			if (arc.FSPetiteAdmiration !== "unset") {
				r.push(pursuit());
				r.push(`an accentuated societal preference for short slaves.`);
				r.push(activeFS("FSPetiteAdmiration"));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Petite Admiration",
							() => {
								arc.FSPetiteAdmiration = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is increased interest in short slaves.`);
				} else {
					/* Petite Admiration: increased interest in short slaves.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if (arc.FSPetiteAdmiration === "unset") {
			if (arc.FSStatuesqueGlorification !== "unset") {
				r.push(pursuit());
				r.push(`a societal fixation on tallness.`);
				r.push(activeFS("FSStatuesqueGlorification"));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Statuesque Glorification",
							() => {
								arc.FSStatuesqueGlorification = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is societal fixation on tallness.`);
				} else {
					/* Statuesque Glorification: societal fixation on tallness.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		el.append(p);

		/* Expand vs Slim */
		p = document.createElement("p");
		r = [];
		if (arc.FSAssetExpansionist === "unset") {
			if (arc.FSSlimnessEnthusiast !== "unset") {
				r.push(App.UI.DOM.makeElement("span", "You are supporting", "bold"));
				r.push(`enthusiasm for slaves with girlish figures.`);
				r.push(activeFS("FSSlimnessEnthusiast"));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Slimness Enthusiasm",
							() => {
								arc.FSSlimnessEnthusiast = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is a fashion for slaves with girlish figures.`);
				} else {
					/* Slimness Enthusiasm: a fashion for slaves with girlish figures.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if (arc.FSSlimnessEnthusiast === "unset") {
			if (arc.FSAssetExpansionist !== "unset") {
				r.push(pursuit());
				r.push(`societal hunger for huge assets.`);
				r.push(activeFS("FSAssetExpansionist"));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Asset Expansionism",
							() => {
								arc.FSAssetExpansionist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is societal hunger for huge assets of whatever origin.`);
				} else {
					/* Asset Expansionism: societal hunger for huge assets of whatever origin.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		el.append(p);

		/* Milking stands alone */
		r = [];
		if (arc.FSPastoralist !== "unset") {
			r.push(pursuit());
			r.push(`societal normalization of slave milking.`);
			r.push(activeFS("FSPastoralist", ["boughtItem.clothing.western"]));
		} else {
			if (FSCredits > 0) {
				r.push(
					App.UI.DOM.link(
						"Slave Pastoralism",
						() => {
							arc.FSPastoralist = 4;
							App.UI.reload();
						}
					)
				);
				r.push(`is societal acceptance of slave products like milk.`);
			} else {
				/* Slave Pastoralism: societal acceptance of slave products like milk.*/
			}
		}
		App.Events.addNode(el, r, "p");

		/* Physical Idealist vs Hedonist */
		p = document.createElement("p");
		r = [];
		if (arc.FSHedonisticDecadence === "unset") {
			if (arc.FSPhysicalIdealist !== "unset") {
				r.push(pursuit());
				r.push(`societal reverence for the idealized human form, including height, health and muscle.`);
				r.push(activeFS("FSPhysicalIdealist", ["boughtItem.clothing.oil"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Physical Idealism",
							() => {
								arc.FSPhysicalIdealist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is societal reverence for the idealized human form, including height, health and muscle.`);
				} else {
					/* Physical Idealism: societal reverence for the idealized human form, including height, health and muscle.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if (arc.FSPhysicalIdealist === "unset") {
			if (arc.FSHedonisticDecadence !== "unset") {
				r.push(pursuit());
				r.push(`societal normalization of overindulgence and immediate gratification. Be it food, drink, sex, drugs or whatever one's desire may be.`);
				r.push(activeFS("FSHedonisticDecadence"));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Hedonistic Decadence",
							() => {
								arc.FSHedonisticDecadence = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is societal acceptance of overindulgence and immediate gratification. Be it food, drink, sex, drugs or whatever one's desire may be.`);
				} else {
					/* HedonisticDecadence: societal acceptance of over indulgence, particularly of food, drink, sex and drugs.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		el.append(p);

		/* Chattel religionist vs Multicultural */
		p = document.createElement("p");
		r = [];
		if (arc.FSNull === "unset") {
			if (arc.FSChattelReligionist !== "unset") {
				r.push(pursuit());
				r.push(`a new strain of religion that emphasizes the slaveholding portions of religious history.`);
				r.push(activeFS("FSChattelReligionist", ["boughtItem.clothing.habit"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Chattel Religionism",
							() => {
								arc.FSChattelReligionist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is a new strain of religion that emphasizes the slaveholding portions of religious history.`);
				} else {
					/* Chattel Religionism: a new strain of religion that emphasizes the slaveholding portions of religious history.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if (arc.FSChattelReligionist === "unset") {
			if (arc.FSNull !== "unset") {
				const freedomArray = [`You are permitting`];
				if (arc.FSNull <= 25) {
					freedomArray.push(`basic`);
				} else if (arc.FSNull <= 50) {
					freedomArray.push(`considerable`);
				} else if (arc.FSNull <= 75) {
					freedomArray.push(`advanced`);
				} else {
					freedomArray.push(`absolute`);
				}
				r.push(App.UI.DOM.makeElement("span", freedomArray.join(" "), "bold"));
				r.push(`cultural freedom in your arcology.`);
			}
			if (V.FSCreditCount === 4) {
				if (arc.FSNull !== "unset") {
					r.push(activeFS("FSChattelReligionist"));
					if (arc.FSNull <= 25) {
						r.push(abandonRel());
					} else {
						r.push(withdrawRel(25));
					}
					if (FSCredits > 0) {
						if (arc.FSNull < V.FSLockinLevel) {
							r.push(advanceRel(25));
						}
					}
				} else {
					if (FSCredits > 0) {
						r.push(MulticulturalismRel(25));
					}
				}
			} else if (V.FSCreditCount === 6) {
				if (arc.FSNull !== "unset") {
					if (arc.FSNull <= 20) {
						r.push(abandonRel());
					} else {
						r.push(withdrawRel(17));
					}
					if (FSCredits > 0) {
						if (arc.FSNull < V.FSLockinLevel) {
							r.push(advanceRel(17));
						}
					}
				} else {
					if (FSCredits > 0) {
						r.push(MulticulturalismRel(17));
					}
				}
			} else if (V.FSCreditCount === 7) {
				if (arc.FSNull !== "unset") {
					if (arc.FSNull <= 20) {
						r.push(abandonRel());
					} else {
						r.push(withdrawRel(15));
					}
					if (FSCredits > 0) {
						if (arc.FSNull < V.FSLockinLevel) {
							r.push(advanceRel(15));
						}
					}
				} else {
					if (FSCredits > 0) {
						r.push(MulticulturalismRel(15));
					}
				}
			} else {
				if (arc.FSNull !== "unset") {
					if (arc.FSNull <= 20) {
						r.push(abandonRel());
					} else {
						r.push(withdrawRel(20));
					}
					if (FSCredits > 0) {
						if (arc.FSNull < V.FSLockinLevel) {
							r.push(advanceRel(20));
						}
					}
				} else {
					if (FSCredits > 0) {
						r.push(MulticulturalismRel(20));
					}
				}
			}
		}
		App.Events.addNode(p, r, "div");
		el.append(p);

		function withdrawRel(num) {
			return App.UI.DOM.link(
				"Withdraw",
				() => {
					if (arc.FSNull !== "unset") {
						arc.FSNull -= num;
					}
					App.UI.reload();
				}
			);
		}

		function abandonRel() {
			return App.UI.DOM.link(
				"Abandon",
				() => {
					FutureSocieties.remove("FSNull");
					App.UI.reload();
				}
			);
		}

		function advanceRel(num) {
			return App.UI.DOM.link(
				"Advance",
				() => {
					if (arc.FSNull !== "unset") {
						arc.FSNull += num;
					}
					App.UI.reload();
				},
				[],
				"",
				"a further commitment to allow your arcology's citizens cultural freedom"
			);
		}

		function MulticulturalismRel(num) {
			const multicultural = App.UI.DOM.makeElement(
				"span",
				App.UI.DOM.link(
					"Multiculturalism",
					() => {
						arc.FSNull = num;
						App.UI.reload();
					},
					[],
					"",
					"a commitment to allow your arcology's citizens cultural freedom."
				)
			);
			multicultural.append(` is an alternative to societal advancement, and will not advance naturally.`);
			return multicultural;
		}

		/* Revival section */
		p = document.createElement("p");
		r = [];
		if ((arc.FSAztecRevivalist === "unset") && (arc.FSEgyptianRevivalist === "unset") && (arc.FSEdoRevivalist === "unset") && (arc.FSArabianRevivalist === "unset") && (arc.FSChineseRevivalist === "unset") && (arc.FSNeoImperialist === "unset")) {
			if (arc.FSRomanRevivalist !== "unset") {
				r.push(pursuit());
				r.push(`a vision of a new Rome.`);
				r.push(activeFS("FSRomanRevivalist", ["boughtItem.clothing.toga"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Roman Revivalism",
							() => {
								arc.FSRomanRevivalist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is a vision of a new Rome.`);
				} else {
					/* Roman Revivalism: a vision of a new Rome.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if ((arc.FSAztecRevivalist === "unset") && (arc.FSEgyptianRevivalist === "unset") && (arc.FSEdoRevivalist === "unset") && (arc.FSArabianRevivalist === "unset") && (arc.FSChineseRevivalist === "unset") && (arc.FSRomanRevivalist === "unset")) {
			if (arc.FSNeoImperialist !== "unset") {
				r.push(pursuit());
				r.push(`a vision of a new Imperial Society.`);
				r.push(activeFS("FSNeoImperialist", ["boughtItem.clothing.imperialarmor", "boughtItem.clothing.imperialsuit"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Neo-Imperialism",
							() => {
								arc.FSNeoImperialist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is a vision of a new Imperial society, integrating high technology and old-world culture under the iron fist of your absolute rule.`);
				} else {
					/* Neo-Imperialism: a vision of a new Imperial Society, integrating high technology and old-world culture under the iron fist of your absolute rule.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if ((arc.FSRomanRevivalist === "unset") && (arc.FSEgyptianRevivalist === "unset") && (arc.FSEdoRevivalist === "unset") && (arc.FSArabianRevivalist === "unset") && (arc.FSChineseRevivalist === "unset") && (arc.FSNeoImperialist === "unset")) {
			if (arc.FSAztecRevivalist !== "unset") {
				r.push(pursuit());
				r.push(`a vision of a new Aztec Empire.`);
				r.push(activeFS("FSAztecRevivalist", ["boughtItem.clothing.huipil"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Aztec Revivalism",
							() => {
								arc.FSAztecRevivalist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is a vision of a new Aztec Empire.`);
				} else {
					/* Aztec Revivalism: a vision of a new Aztec Empire.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if ((arc.FSRomanRevivalist === "unset") && (arc.FSAztecRevivalist === "unset") && (arc.FSEdoRevivalist === "unset") && (arc.FSArabianRevivalist === "unset") && (arc.FSChineseRevivalist === "unset") && (arc.FSNeoImperialist === "unset")) {
			if (arc.FSEgyptianRevivalist !== "unset") {
				r.push(pursuit());
				r.push(`a vision of Pharaoh's Egypt.`);
				r.push(activeFS("FSEgyptianRevivalist", ["boughtItem.clothing.egypt"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Egyptian Revivalism",
							() => {
								arc.FSEgyptianRevivalist = 4 + arc.FSEgyptianRevivalistInterest;
								arc.FSEgyptianRevivalistIncestPolicy = 0;
								App.UI.reload();
							}
						)
					);
					r.push(`is a vision of a Pharaoh's Egypt.`);
				} else {
					/* Egyptian Revivalism: a vision of Pharaoh's Egypt.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if ((arc.FSRomanRevivalist === "unset") && (arc.FSAztecRevivalist === "unset") && (arc.FSEgyptianRevivalist === "unset") && (arc.FSArabianRevivalist === "unset") && (arc.FSChineseRevivalist === "unset") && (arc.FSNeoImperialist === "unset")) {
			if (arc.FSEdoRevivalist !== "unset") {
				r.push(pursuit());
				r.push(`a vision of Edo Japan.`);
				r.push(activeFS("FSEdoRevivalist", ["boughtItem.clothing.kimono"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Edo Revivalism",
							() => {
								arc.FSEdoRevivalist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is a vision of Edo Japan.`);
				} else {
					/* Edo Revivalism: a vision of Edo Japan.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if ((arc.FSRomanRevivalist === "unset") && (arc.FSAztecRevivalist === "unset") && (arc.FSEgyptianRevivalist === "unset") && (arc.FSEdoRevivalist === "unset") && (arc.FSChineseRevivalist === "unset") && (arc.FSNeoImperialist === "unset")) {
			if (arc.FSArabianRevivalist !== "unset") {
				r.push(pursuit());
				r.push(`a vision of the Sultanate of old.`);
				r.push(activeFS("FSArabianRevivalist", ["boughtItem.clothing.harem"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Arabian Revivalism",
							() => {
								arc.FSArabianRevivalist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is a vision of the Sultanate of old.`);
				} else {
					/* Arabian Revivalism: a vision of the Sultanate of old.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		r = [];
		if ((arc.FSRomanRevivalist === "unset") && (arc.FSAztecRevivalist === "unset") && (arc.FSEgyptianRevivalist === "unset") && (arc.FSEdoRevivalist === "unset") && (arc.FSArabianRevivalist === "unset") && (arc.FSNeoImperialist === "unset")) {
			if (arc.FSChineseRevivalist !== "unset") {
				r.push(pursuit());
				r.push(`a vision of ancient China.`);
				r.push(activeFS("FSChineseRevivalist", ["boughtItem.clothing.qipao"]));
			} else {
				if (FSCredits > 0) {
					r.push(
						App.UI.DOM.link(
							"Chinese Revivalism",
							() => {
								arc.FSChineseRevivalist = 4;
								App.UI.reload();
							}
						)
					);
					r.push(`is a vision of ancient China.`);
				} else {
					/* Chinese Revivalism: a vision of ancient China.*/
				}
			}
		}
		App.Events.addNode(p, r, "div");
		el.append(p);

		return el;

		function pursuit() {
			return App.UI.DOM.makeElement("span", "You are pursuing", "bold");
		}

		/**
		 *
		 * @param {FC.FutureSociety} FS
		 * @param {Array} [itemArray]
		 */
		function activeFS(FS, itemArray) {
			const el = new DocumentFragment();
			const r = [];

			// Abandon
			if (FS === "FSRestart" && V.eugenicsFullControl !== 1) {
				r.push(`The Societal Elite will not permit you to abandon Eugenics.`);
			} else {
				r.push(
					App.UI.DOM.link(
						"Abandon",
						() => {
							FutureSocieties.remove(FS);
							App.UI.reload();
						}
					)
				);
			}

			// Decoration
			r.push(App.UI.FSChangeDecoration(FS, itemArray));

			// Assistant
			if (V.policies.publicPA === 1) {
				if (App.Data.Assistant.appearanceForFS.get(FS).includes(V.assistant.appearance)) {
					const {hisA} = getPronouns(assistant.pronouns().main).appendSuffix('A');
					r.push(`With ${hisA} ${V.assistant.appearance} appearance,`);
					r.push(
						App.UI.DOM.passageLink(V.assistant.name, "Personal assistant options")
					);
					r.push(`is a good public mascot for this goal.`);
				}
			}

			App.Events.addNode(el, r);
			return el;
		}
	}
};


code:
globalThis.FutureSocieties = (function() {
	/** @type {Map<FC.FutureSocietyDeco, FC.FutureSociety>} */
	const DecoToFSMap = new Map();
	for (const [fsName, details] of Object.entries(App.Data.FutureSociety.records)) {
		if (details.deco) {
			// @ts-ignore - Object.entries loses type information, apparently intentionally
			DecoToFSMap.set(details.deco, fsName);
		}
	}

	return {
		activeFSes: activeFSes,
		activeCount: activeCount,
		applyBroadProgress: applyBroadProgress,
		availCredits: calcFSCredits,
		influenceSources: influenceSources,
		decorationName: decorationName,
		diplomaticFSes: diplomaticFSes,
		displayName: displayName,
		displayAdj: displayAdj,
		decay: decayFSes,
		overflowToInfluence: overflowToInfluence,
		remove: removeFS,
		validAdoptions: validAdoptions,
		DecorationCleanup: DecorationCleanup,
		DecorationBonus: FSDecorationBonus,
		Change: FSChange,
		HighestDecoration: FSHighestDecoration,
		arcSupport: arcSupport,
		researchAvailable,
		isActive,
	};

	/** get the list of FSes active for a particular arcology
	 * @param {FC.ArcologyState} arcology
	 * @returns {FC.FutureSociety[]}
	 */
	function activeFSes(arcology) {
		return App.Data.FutureSociety.fsNames.filter((fs) => Number.isFinite(arcology[fs]));
	}

	/** call as FutureSocieties.activeCount(arcology)
	 * @param {FC.ArcologyState} arcology
	 * @returns {number}
	 */
	function activeCount(arcology) {
		return activeFSes(arcology).length;
	}

	/** call as FutureSocieties.applyBroadProgress(arcologyID, progress)
	 * @param {number} arcologyID
	 * @param {number} progress
	 */
	function applyBroadProgress(arcologyID, progress) {
		/** @type {FC.ArcologyState} */
		const arcology = V.arcologies[arcologyID];
		for (const fs of activeFSes(arcology)) {
			if (fs !== "FSNull") { // does not progress this way
				// @ts-ignore // Because of activeFSes() we know it cannot be "unset", the only valid non numeric value.
				arcology[fs] += progress;
			}
		}
	}

	/** converts excess progress into influence bonus
	 * call as FutureSocieties.overflowToInfluence(arcologyID)
	 * @param {number} arcologyID
	 */
	function overflowToInfluence(arcologyID) {
		const arcology = V.arcologies[arcologyID];
		for (const fs of activeFSes(arcology)) {
			if (fs !== "FSNull") { // no conventional progress
				if (arcology[fs] > V.FSLockinLevel) {
					// @ts-ignore // Because of activeFSes() we know it cannot be "unset", the only valid non numeric value.
					arcology.influenceBonus += arcology[fs] - V.FSLockinLevel;
					arcology[fs] = V.FSLockinLevel;
				}
			}
		}
	}

	/** returns an array of FSes which the arcology has developed enough to influence others
	 * call as FutureSocieties.influenceSources(arcologyID)
	 * @param {number} arcologyID
	 */
	function influenceSources(arcologyID) {
		let fses = [];
		const arcology = V.arcologies[arcologyID];
		for (const fs of activeFSes(arcology)) {
			if (fs !== "FSNull") { // no influence from Multiculturalism?
				if (arcology[fs] > 60) {
					fses.push(fs);
				}
			}
		}
		return fses;
	}

	/** determines whether two named FSes are naturally conflicting or not
	 * @param {FC.FutureSociety} left FS
	 * @param {FC.FutureSociety} right FS
	 * @returns {boolean}
	 */
	function conflictingFSes(left, right) {
		if (left !== right) { // identical FSes are not opposed
			for (const group of App.Data.FutureSociety.mutexGroups) {
				if (group.includesAll(left, right)) {
					return true; // but any other FS in the mutex group is
				}
			}
		}
		return false;
	}

	/** returns an array of all of the FSes that would be valid for this arcology to adopt right now
	 * @param {number} arcID
	 * @returns {FC.FutureSociety[]}
	 */
	function validAdoptions(arcID) {
		const arcology = V.arcologies[arcID];
		const societies = Array.from(arcID !== 0 ? App.Data.FutureSociety.fsNames : App.Data.FutureSociety.playerFSNames);
		const arcFSes = activeFSes(arcology);

		// apply game rules
		if (!V.seeIncest) {
			societies.delete("FSIncestFetishist");
		}
		if (!V.seePreg) {
			societies.delete("FSRepopulationFocus");
		}

		// FSes already adopted by the arcology are invalid
		societies.deleteWith(fs => arcFSes.includes(fs));

		// FSes that conflict with FSes adopted by the arcology are invalid
		societies.deleteWith(fs1 => arcFSes.some(fs2 => conflictingFSes(fs1, fs2)));

		// if the government is loyal to you, FSes that conflict with FSes adopted by the player are invalid
		if (arcology.government === "your agent" || arcology.government === "your trustees") {
			const playerFSes = activeFSes(V.arcologies[0]);
			societies.deleteWith(fs1 => playerFSes.some(fs2 => conflictingFSes(fs1, fs2)));
		}

		return societies;
	}

	/** returns the set of shared FSes between two arcologies, and the set of conflicts between pairs of FSes between the arcologies
	 * relatively expensive, try not to call frequently
	 * call as FutureSocieties.diplomaticFSes(arc1, arc2)
	 * @param {FC.ArcologyState} arc1
	 * @param {FC.ArcologyState} arc2
	 * @returns {{shared: FC.FutureSociety[], conflicting: FC.FutureSociety[][]}}
	 */
	function diplomaticFSes(arc1, arc2) {
		/** @type {FC.FutureSociety[]} */
		let shared = [];
		/** @type {FC.FutureSociety[][]} */
		let conflicting = [];
		const arc1FSes = activeFSes(arc1);
		const arc2FSes = activeFSes(arc2);
		// find ordinary shared and conflicting FSes
		for (const fs1 of arc1FSes) {
			for (const fs2 of arc2FSes) {
				if (fs1 === fs2) {
					shared.push(fs1);
				} else if (conflictingFSes(fs1, fs2)) {
					conflicting.push([fs1, fs2]);
				}
			}
		}
		// special cases: racial FSes might be conflicting even when shared
		if (shared.contains("FSSupremacist")) {
			// a different race is supreme
			if (arc1.FSSupremacistRace !== arc2.FSSupremacistRace) {
				shared.delete("FSSupremacist");
				conflicting.push(["FSSupremacist", "FSSupremacist"]);
			}
			// subjugating the supreme race
			if (arc2FSes.contains("FSSubjugationist") && arc2.FSSubjugationistRace === arc1.FSSupremacistRace) {
				shared.delete("FSSupremacist");
				conflicting.push(["FSSupremacist", "FSSubjugationist"]);
			}
		}
		if (shared.contains("FSSubjugationist")) {
			// subjugating a different race
			if (arc1.FSSubjugationistRace !== arc2.FSSubjugationistRace) {
				shared.delete("FSSubjugationist");
				conflicting.push(["FSSubjugationist", "FSSubjugationist"]);
			}
			// believe the subjugated race is supreme
			if (arc2FSes.contains("FSSupremacist") && arc2.FSSupremacistRace === arc1.FSSubjugationistRace) {
				shared.delete("FSSubjugationist");
				conflicting.push(["FSSubjugationist", "FSSupremacist"]);
			}
		}
		return {shared, conflicting};
	}

	/** returns the future society display name (typically an "ism") for the given property
	 * @param {FC.FutureSociety} FSProp
	 * @returns {FC.FutureSocietyNoun}
	 */
	function displayName(FSProp) {
		return App.Data.FutureSociety.records[FSProp].noun;
	}

	/** returns the future society adjective (typically an "ist") for the given property
	 * @param {FC.FutureSociety} FSProp
	 * @returns {FC.FutureSocietyAdj}
	 */
	function displayAdj(FSProp) {
		return App.Data.FutureSociety.records[FSProp].adj;
	}

	/** returns the future society decoration name (for use in decoration properties) for the given FS property
	 * @param {FC.FutureSociety} FSProp
	 * @returns {FC.FutureSocietyDeco}
	 */
	function decorationName(FSProp) {
		return App.Data.FutureSociety.records[FSProp].deco;
	}

	/** decays all the FSes adopted by a particular arcology (for example, because of government instability)
	 * call as FutureSocieties.decay(arcologyID)
	 * @param {number} arcologyID
	 * @returns {FC.FutureSociety[]} FSes which purged completely
	 */
	function decayFSes(arcologyID) {
		const arc = V.arcologies[arcologyID];
		const fses = activeFSes(arc);
		/** @type {FC.FutureSociety[]} */
		let purged = [];
		for (const fs of fses) {
			if (fs !== "FSNull") { // exempt for some reason?
				if (arc[fs] < jsRandom(10, 150)) {
					purged.push(fs);
					arc[fs] = "unset";
				} else {
					// @ts-ignore // Because of activeFSes() we know it cannot be "unset", the only valid non numeric value.
					arc[fs] -= 10;
				}
			}
		}
		return purged;
	}

	/** Remove an FS and all associated attributes from an arcology
	 * call as FutureSocieties.remove(FS)
	 * @param {FC.FutureSociety} FS (e.g. "FSPaternalist" or "FSDegradationist")
	 */
	function removeFS(FS) {
		const arcology = V.arcologies[0];
		const FSDecoration = `${FS}Decoration`;
		const FSSMR = `${FS}SMR`;
		let FSLaw = `${FS}Law`;
		if (arcology[FS] === undefined) {
			// eslint-disable-next-line no-console
			console.log(`ERROR: bad FS reference, $arcologies[0].${FS} not defined`);
			return;
		}

		if (FS === "FSSupremacist" || FS === "FSSubjugationist") { FSLaw += "ME"; }
		if (FS !== "FSNull") { arcology[FSDecoration] = 20; }
		arcology[FS] = "unset";
		switch (FS) {
			case "FSPaternalist":
				arcology[FSLaw] = 0;
				arcology[FSSMR] = 0;
				if (_.get(V, "SecExp.edicts")) {
					V.SecExp.edicts.slaveWatch = 0;
				}
				break;
			case "FSDegradationist":
				arcology[FSLaw] = 0;
				arcology[FSSMR] = 0;
				if (_.get(V, "SecExp.edicts")) {
					V.SecExp.edicts.defense.liveTargets = 0;
				}
				break;
			case "FSGenderRadicalist":
				arcology.FSGenderRadicalistLawBeauty = 0;
				arcology.FSGenderRadicalistLawFuta = 0;
				break;
			case "FSGenderFundamentalist":
				arcology.FSGenderFundamentalistLawBeauty = 0;
				arcology.FSGenderFundamentalistLawBimbo = 0;
				arcology.FSGenderFundamentalistSMR = 0;
				break;
			case "FSSupremacist":
				arcology[FSLaw] = 0;
				arcology[FSSMR] = 0;
				if (_.get(V, "SecExp.edicts")) {
					V.SecExp.edicts.defense.noSubhumansInArmy = 0;
				}
				break;
			case "FSTransformationFetishist":
			case "FSAssetExpansionist":
				arcology[FSSMR] = 0;
				break;
			case "FSPhysicalIdealist":
				arcology.FSPhysicalIdealistLaw = 0;
				arcology.FSPhysicalIdealistSMR = 0;
				arcology.FSPhysicalIdealistStrongFat = 0;
				if (_.get(V, "SecExp.edicts")) {
					V.SecExp.edicts.defense.martialSchool = 0;
				}
				break;
			case "FSHedonisticDecadence":
				arcology.FSHedonisticDecadenceLaw = 0;
				arcology.FSHedonisticDecadenceLaw2 = 0;
				arcology.FSHedonisticDecadenceSMR = 0;
				arcology.FSHedonisticDecadenceStrongFat = 0;
				break;
			case "FSChattelReligionist":
				arcology.FSChattelReligionistLaw = 0;
				arcology.FSChattelReligionistSMR = 0;
				arcology.FSChattelReligionistCreed = 0;
				if (_.get(V, "SecExp.edicts")) {
					V.SecExp.edicts.subsidyChurch = 0;
				}
				break;
			case "FSRepopulationFocus":
				arcology[FSLaw] = 0;
				arcology[FSSMR] = 0;
				V.universalRulesChildrenBecomeBreeders = 0;
				if (_.get(V, "SecExp.edicts")) {
					V.SecExp.edicts.defense.pregExemption = 0;
				}
				break;
			case "FSRestart":
				arcology[FSLaw] = 0;
				arcology[FSSMR] = 0;
				arcology.FSRestartResearch = 0; // not really research at all; reset breeding program
				if (_.get(V, "SecExp.edicts")) {
					V.SecExp.edicts.defense.eliteOfficers = 0;
				}
				V.propOutcome = 0;
				V.failedElite = 0;
				V.playerBred = 0;
				break;
			case "FSIntellectualDependency":
				arcology.FSIntellectualDependencyLaw = 0;
				arcology.FSIntellectualDependencyLawBeauty = 0;
				arcology.FSIntellectualDependencySMR = 0;
				break;
			case "FSPetiteAdmiration":
				arcology.FSPetiteAdmirationLaw = 0;
				arcology.FSPetiteAdmirationLaw2 = 0;
				arcology.FSPetiteAdmirationSMR = 0;
				break;
			case "FSStatuesqueGlorification":
				arcology.FSStatuesqueGlorificationLaw = 0;
				arcology.FSStatuesqueGlorificationLaw2 = 0;
				arcology.FSStatuesqueGlorificationSMR = 0;
				break;
			case "FSBodyPurist":
				arcology[FSLaw] = 0;
				arcology[FSSMR] = 0;
				arcology.FSBodyPuristCatLaw = 0;
				break;
			case "FSNeoImperialist":
				arcology.FSNeoImperialistLaw1 = 0;
				arcology.FSNeoImperialistLaw2 = 0;
				arcology.FSNeoImperialistSMR = 0;
				break;
			case "FSNull":
				break;
			default: // all others have one law and one SMR
				arcology[FSLaw] = 0;
				arcology[FSSMR] = 0;
				break;
		}

		DecorationCleanup();

		// Clean up assistant
		if (
			(V.assistant.fsAppearance === App.Data.FutureSociety.records[FS].adj.toLowerCase()) ||
			(V.assistant.fsAppearance === App.Data.FutureSociety.records[FS].noun.toLowerCase()) ||
			(FS === "FSHedonisticDecadence" && V.assistant.fsAppearance === "hedonistic decadence") ||
			(FS === "FSNeoImperialist" && V.assistant.fsAppearance === "neoimperialist")
		) {
			V.assistant.fsAppearance = "default";
		}
	}

	/** Calculate the number of FS credits that the player still has available (unspent)
	 * Call as FutureSocieties.availCredits()
	 * @returns {number}
	 */
	function calcFSCredits() {
		const arcology = V.arcologies[0];
		let activeFS = activeCount(arcology);
		if (typeof arcology.FSNull === 'number' && arcology.FSNull > 0) { // multiculturalism is accounted for separately
			activeFS -= 1; // already counted once, remove that one and count investments instead
			if (V.FSCreditCount === 4) {
				activeFS += arcology.FSNull / 25;
			} else if (V.FSCreditCount === 6) {
				activeFS += arcology.FSNull / 17;
			} else if (V.FSCreditCount === 7) {
				activeFS += arcology.FSNull / 15;
			} else {
				activeFS += arcology.FSNull / 20;
			}
		}
		return Math.max(Math.trunc(V.FSGotRepCredits - activeFS), 0);
	}

	/* call as FutureSocieties.DecorationCleanup() */
	function DecorationCleanup() {
		for (const facility of Object.values(App.Entity.facilities).filter(f => f.established && f.isDecorated)) {
			ValidateFacilityDecoration(facility);
		}
	}

	/** helper function, not callable externally
	 * @param {App.Entity.Facilities.Facility} facility
	 */
	function ValidateFacilityDecoration(facility) {
		// Backwards compatibility, do not remove
		// @ts-ignore BC
		if (facility.decoration === "Hedonism" || facility.decoration === "Hedonistic Decadence") {
			facility.decoration = "Hedonistic";
		// @ts-ignore BC
		} else if (facility.decoration === "Repopulation Focus") {
			facility.decoration = "Repopulationist";
		// @ts-ignore BC
		} else if (facility.decoration === "Neo Imperialist") {
			facility.decoration = "Neo-Imperialist";
		}

		const activeFS = DecoToFSMap.get(facility.decoration); // gets the property name

		if (facility.decoration === "standard") {
			// nothing to do
		} else if (activeFS === undefined) {
			// eslint-disable-next-line no-console
			console.log(`Error: ${facility.nameCaps} decoration is ${facility.decoration}`);
			facility.decoration = "standard";
		} else if (!Number.isFinite(V.arcologies[0][activeFS])) {
			if (V.arcologies[0][activeFS] !== "unset") {
				// eslint-disable-next-line no-console
				console.log(`Error: $arcologies[0].${activeFS} is ${V.arcologies[0][activeFS]}`);
			}
			facility.decoration = "standard";
		}
	}

	/** Apply the decoration bonus for a slave working in a facility to the FS
	 * call as FutureSocieties.DecorationBonus()
	 * @param {FC.FutureSocietyDeco} decoration - not quoted, just pass it straight in
	 * @param {number} magnitude - will be multiplied by V.FSSingleSlaveRep
	 */
	function FSDecorationBonus(decoration, magnitude) {
		if (decoration === "standard") {
			return; // no bonus
		}

		const FSProp = DecoToFSMap.get(decoration); // gets the property name
		const arc = V.arcologies[0];

		if (FSProp && Number.isFinite(arc[FSProp])) {
			/** @type {number} */
			// @ts-ignore // We know this is true because of Number.isFinite()
			const n = arc[FSProp];
			arc[FSProp] = Math.clamp(n + magnitude * V.FSSingleSlaveRep, 0, 100);
		}
	}

	/** call as FutureSocieties.Change()
	 * @param {FC.FutureSociety|FC.FutureSocietyDeco} FSString either decoration or FS property
	 * @param {number} magnitude size of change
	 * @param {number} [bonusMultiplier=1] multiplier to be applied to FS change (but NOT to rep change)
	 * @returns {number} reputation change value (for recordkeeping)
	 */
	function FSChange(FSString, magnitude, bonusMultiplier = 1) {
		const arcology = V.arcologies[0];
		// @ts-ignore - could be a decoration string; just try to convert it to a property name, and if we can't then assume it's a property name and use it as-is
		const activeFS = DecoToFSMap.get(FSString) || FSString;

		if (Number.isFinite(arcology[activeFS])) {
			let repChange = magnitude * V.FSSingleSlaveRep * (arcology[activeFS] / V.FSLockinLevel);
			if (magnitude < 0) {
				repChange /= 3; // Reducing the reputation impact of slaves that are not adhering to societal ideals properly
			}
			repX(repChange, 'futureSocieties');
			arcology[activeFS] += 0.05 * magnitude * V.FSSingleSlaveRep * bonusMultiplier;
			return repChange;
		} else {
			console.log(`Attempted to change unset FS ${activeFS}`);
			return 0;
		}
	}

	/**
	 * Returns the highest decoration level of active future societies, call as FutureSocieties.HighestDecoration()
	 * @returns {number}
	 */
	function FSHighestDecoration() {
		const arcology = V.arcologies[0];
		const decorationList = App.Data.FutureSociety.playerFSNames.map(FS => `${FS}Decoration`);
		let level = 20; // All decorations start at 20

		for (const deco of decorationList) {
			if (arcology[deco] > level) {
				level = arcology[deco];
			}
		}
		return level;
	}

	/**
	 *
	 * @param {FC.FutureSociety} FS
	 * @param {*} [arc]
	 */
	function arcSupport(FS, arc = V.arcologies[0]) {
		const arcSupportMap = new Map([
			[
				"FSSupremacist",
				[
					`${arc.name} believes implicitly in ${arc.FSSupremacistRace} superiority.`,
					`${arc.name} agrees strongly with ${arc.FSSupremacistRace} superiority.`,
					`${arc.name} is sympathetic to ${arc.FSSupremacistRace} superiority.`,
					`${arc.name} is unconvinced of ${arc.FSSupremacistRace} superiority.`
				]
			],
			[
				"FSSubjugationist",
				[
					`${arc.name} believes implicitly in the inferiority of ${arc.FSSubjugationistRace} people.`,
					`${arc.name} agrees strongly with the inferiority of ${arc.FSSubjugationistRace} people.`,
					`${arc.name} is sympathetic to the inferiority of ${arc.FSSubjugationistRace} people.`,
					`${arc.name} is unconvinced of the inferiority of ${arc.FSSubjugationistRace} people.`
				]
			],
			[
				"FSRepopulationFocus",
				[
					`${arc.name} believes implicitly that all women should be pregnant.`,
					`${arc.name} agrees strongly that all women should be pregnant.`,
					`${arc.name} is sympathetic to the idea that all women should be pregnant.`,
					`${arc.name} is unconvinced that all women should be pregnant.`,

				]
			],
			[
				"FSRestart",
				[
					`${arc.name} believes implicitly that only the elite should reproduce.`,
					`${arc.name} agrees strongly that only the elite should reproduce.`,
					`${arc.name} is sympathetic to the idea only the elite should reproduce.`,
					`${arc.name} is unconvinced that only the elite should reproduce.`
				]
			],
			[
				"FSIntellectualDependency",
				[
					`${arc.name} believes implicitly that all slaves should be mentally dependant on their owner.`,
					`${arc.name} agrees strongly that all slaves should be bimbos.`,
					`${arc.name} is sympathetic to the idea that slaves should be dumb and horny.`,
					`${arc.name} is unconvinced that all slaves should be morons.`
				]
			],
			[
				"FSSlaveProfessionalism",
				[
					`${arc.name} believes implicitly that slaves should be masters of the sexual arts.`,
					`${arc.name} agrees strongly with slavery as a profession.`,
					`${arc.name} is sympathetic to the notion of slavery as a profession.`,
					`${arc.name} is unconvinced that slaves should be highly intelligent.`
				]
			],
			[
				"FSGenderRadicalist",
				[
					`${arc.name} believes implicitly in the need to redefine gender around power.`,
					`${arc.name} agrees strongly with the need to redefine gender around power.`,
					`${arc.name} is sympathetic to the need to redefine gender around power.`,
					`${arc.name} is unconvinced of the need to redefine gender around power.`
				]
			],
			[
				"FSGenderFundamentalist",
				[
					`${arc.name} believes implicitly in the need to preserve traditional gender roles.`,
					`${arc.name} agrees strongly with the need to preserve traditional gender roles.`,
					`${arc.name} is sympathetic to the need to preserve traditional gender roles.`,
					`${arc.name} is unconvinced of the need to preserve traditional gender roles.`
				]
			],
			[
				"FSPaternalist",
				[
					`${arc.name} believes implicitly in the vision of a well-bred race of slaves.`,
					`${arc.name} agrees strongly with the vision of a well-bred race of slaves.`,
					`${arc.name} is sympathetic to the vision of a well-bred race of slaves.`,
					`${arc.name} is unconvinced of the vision of a well-bred race of slaves.`
				]
			],
			[
				"FSDegradationist",
				[
					`${arc.name} believes implicitly that slaves are not human and should be thoroughly degraded.`,
					`${arc.name} agrees strongly with the idea that slaves are not human and should be thoroughly degraded.`,
					`${arc.name} is sympathetic to the proposition that slaves are not human and should be thoroughly degraded.`,
					`${arc.name} is unconvinced that slaves are not human and should be thoroughly degraded.`
				]
			],
			[
				"FSBodyPurist",
				[
					`${arc.name} believes implicitly in the unattractive nature of implants.`,
					`${arc.name} agrees strongly with the unattractive nature of implants.`,
					`${arc.name} is sympathetic to the unattractive nature of implants.`,
					`${arc.name} is unconvinced of the unattractive nature of implants.`
				]
			],
			[
				"FSTransformationFetishist",
				[
					`${arc.name} passionately fetishizes implants.`,
					`${arc.name} strongly fetishizes implants.`,
					`${arc.name} fetishizes implants.`,
					`${arc.name} is beginning to fetishize implants.`
				]
			],
			[
				"FSMaturityPreferentialist",
				[
					`${arc.name} is passionately enthusiastic for older ladies.`,
					`${arc.name} is very enthusiastic for older ladies.`,
					`${arc.name} is enthusiastic for older ladies.`,
					`${arc.name} is beginning to be enthusiastic for older ladies.`
				]
			],
			[
				"FSYouthPreferentialist",
				[
					`${arc.name} is passionately enthusiastic for young women.`,
					`${arc.name} is very enthusiastic for young women.`,
					`${arc.name} is enthusiastic for young women.`,
					`${arc.name} is beginning to be enthusiastic for young women.`
				]
			],
			[
				"FSPetiteAdmiration",
				[
					`${arc.name} is passionately enthusiastic for short slaves.`,
					`${arc.name} is very enthusiastic for short slaves.`,
					`${arc.name} is enthusiastic for short slaves.`,
					`${arc.name} is beginning to be enthusiastic for short slaves.`
				]
			],
			[
				"FSStatuesqueGlorification",
				[
					`${arc.name} believes implicitly that the tall are superior.`,
					`${arc.name} agrees strongly with the idea that the tall are superior.`,
					`${arc.name} is sympathetic to the idea that the tall are superior.`,
					`${arc.name} is unconvinced that the tall are superior.`
				]
			],
			[
				"FSSlimnessEnthusiast",
				[
					`${arc.name} is passionately enthusiastic about slim slaves with girlish figures.`,
					`${arc.name} is very enthusiastic about slim slaves with girlish figures.`,
					`${arc.name} is enthusiastic about slim slaves with girlish figures.`,
					`${arc.name} is beginning to be enthusiastic about slim slaves with girlish figures.`
				]
			],
			[
				"FSAssetExpansionist",
				[
					`${arc.name} believes implicitly that all tits and asses should be bigger.`,
					`${arc.name} agrees strongly with the idea that all tits and asses should be bigger.`,
					`${arc.name} is sympathetic to the idea that all tits and asses should be bigger.`,
					`${arc.name} is unconvinced that all tits and asses should be bigger.`
				]
			],
			[
				"FSPastoralist",
				[
					`${arc.name} believes implicitly that slaves should be milked.`,
					`${arc.name} agrees strongly with the idea that slaves should be milked.`,
					`${arc.name} is sympathetic to the idea that slaves should be milked.`,
					`${arc.name} is unconvinced that slaves should be milked.`
				]
			],
			[
				"FSPhysicalIdealist",
				[
					`${arc.name} believes implicitly that all slaves should be tall and strong.`,
					`${arc.name} agrees strongly with the idea that all slaves should be tall and strong.`,
					`${arc.name} is sympathetic to the idea that all slaves should be tall and strong.`,
					`${arc.name} is unconvinced that all slaves should be tall and strong.`
				]
			],
			[
				"FSHedonisticDecadence",
				[
					`${arc.name} believes implicitly that all slaves should be soft and laid-back.`,
					`${arc.name} agrees strongly with the idea that all slaves should be soft and laid-back.`,
					`${arc.name} is sympathetic to the idea that all slaves should be soft and laid-back.`,
					`${arc.name} is unconvinced that all slaves should be soft and laid-back.`
				]
			],
			[
				"FSChattelReligionist",
				[
					`${arc.name} believes implicitly in a version of religion that emphasizes slaveholding traditions.`,
					`${arc.name} agrees strongly with a version of religion that emphasizes slaveholding traditions.`,
					`${arc.name} is sympathetic to a version of religion that emphasizes slaveholding traditions.`,
					`${arc.name} is unconvinced of a version of religion that emphasizes slaveholding traditions.`

				]
			],
			[
				"FSNull",
				[
					`${arc.name} is committed to affording its citizens absolute cultural freedom.`,
					`${arc.name} is committed to affording its citizens great cultural freedom.`,
					`${arc.name} is committed to affording its citizens considerable cultural freedom.`,
					`${arc.name} is committed to affording its citizens basic cultural freedom.`
				]
			],
			[
				"FSRomanRevivalist",
				[
					`${arc.name} believes implicitly that it is the new Rome.`,
					`${arc.name} agrees strongly with your project to build the new Rome.`,
					`${arc.name} is sympathetic to your project to build the new Rome.`,
					`${arc.name} is unconvinced of the wisdom of your project to build the new Rome.`
				]
			],
			[
				"FSNeoImperialist",
				[
					`${arc.name} believes implicitly that your arcology is truly a new Imperial Society.`,
					`${arc.name} agrees strongly with your project to build a new Imperial Society.`,
					`${arc.name} is sympathetic to your project to build a new Imperial Society.`,
					`${arc.name} is unconvinced of the wisdom of your project to build a new Imperial Society.`
				]
			],
			[
				"FSAztecRevivalist",
				[
					`${arc.name} believes implicitly that it is the new Aztec Empire.`,
					`${arc.name} agrees strongly with your project to build the new Aztec Empire.`,
					`${arc.name} is sympathetic to your project to build the new Aztec Empire.`,
					`${arc.name} is unconvinced of the wisdom of your project to build the new Aztec Empire.`
				]
			],
			[
				"FSEgyptianRevivalist",
				[
					`${arc.name} believes implicitly that it is the land of the Pharaohs, reborn.`,
					`${arc.name} agrees strongly with your project to build a new land of the Pharaohs.`,
					`${arc.name} is sympathetic to your project to build a new land of the Pharaohs.`,
					`${arc.name} is unconvinced of the wisdom of your project to build a new land of the Pharaohs.`
				]
			],
			[
				"FSEdoRevivalist",
				[
					`${arc.name} believes implicitly that it is the land of the Shogun, reborn.`,
					`${arc.name} agrees strongly with your project to build a new Edo Japan.`,
					`${arc.name} is sympathetic to your project to build a new Edo Japan.`,
					`${arc.name} is unconvinced of the wisdom of your project to build a new Edo Japan.`
				]
			],
			[
				"FSArabianRevivalist",
				[
					`${arc.name} believes implicitly that it is ancient Baghdad reborn.`,
					`${arc.name} agrees strongly with your project to build a new Sultanate.`,
					`${arc.name} is sympathetic to your project to build a new Sultanate.`,
					`${arc.name} is unconvinced of the wisdom of your project to build a new Sultanate.`
				]
			],
			[
				"FSChineseRevivalist",
				[
					`${arc.name} believes implicitly that possesses the Mandate of Heaven.`,
					`${arc.name} agrees strongly with your pursuit of the Mandate of Heaven.`,
					`${arc.name} is sympathetic to your pursuit of the Mandate of Heaven.`,
					`${arc.name} is unconvinced of the wisdom of your pursuit of the Mandate of Heaven.`
				]
			],
		]);
		if (arc[FS] !== "unset") {
			if (arc[FS] >= V.FSLockinLevel) {
				return arcSupportMap.get(FS)[0];
			} else if (arc[FS] >= V.FSLockinLevel * 0.6) {
				return arcSupportMap.get(FS)[1];
			} else if (arc[FS] >= V.FSLockinLevel * 0.3) {
				return arcSupportMap.get(FS)[2];
			} else {
				return arcSupportMap.get(FS)[3];
			}
		}
	}

	/**
	 *
	 * @param {FC.FSName<keyof FC.FutureSocietyWithResearchMap>} fs
	 * @param {FC.ArcologyState}[arcology] Arcology to test, defaults to the PC's arcology
	 * @returns {boolean}
	 */
	function researchAvailable(fs, arcology) {
		return (arcology || V.arcologies[0])[`FS${fs}Research`] === 1;
	}

	/**
	 * Checks if the given FS active (i.e. not "unset")
	 * @param {FC.FutureSociety} fs
	 * @param {FC.ArcologyState} [arcology] Arcology to test, defaults to the PC's arcology
	 * @returns {boolean}
	 */
	function isActive(fs, arcology) {
		return (arcology || V.arcologies[0])[fs] !== "unset";
	}
})();

license: mit


code:
App.Encyclopedia.addArticle("Being in Charge", function() {
	const f = new DocumentFragment();
	App.UI.DOM.appendNewElement("p", f, "Future room for lore text", "scene-intro");
	App.UI.DOM.appendNewElement("p", f, "Choose a more particular entry below:");
	return f;
}, "beingInCharge");

App.Encyclopedia.addArticle("Arcologies and Reputation", function() {
	const f = new DocumentFragment();
	let r;

	const intro = App.UI.DOM.appendNewElement("div", f, "", "scene-intro");
	App.UI.DOM.appendNewElement("p", intro, "Arcologies are the urban buildings of the future: almost completely self-contained, almost completely self sufficient. In the anarcho-liberal 'paradise' of the Free Cities, as owner of your own arcology you are like a modern-day feudal suzerain, lord and master.");

	App.UI.DOM.appendNewElement("p", intro, "Your arcology is a flared structure, needle thin at the top where you live in your penthouse, and broad at the base. The base below ground contains storage and machinery. The lowest aboveground levels are commercial; above them are the residential areas. The entire structure is jacketed in dense gardens and solar arrays, cleverly structured to create naturally lit corridors and beautiful park-like balconies.");

	App.UI.DOM.appendNewElement("p", intro, "— Owner's Report");

	App.UI.DOM.appendNewElement("p", f, "You may wish to improve your arcology, but should be able to ignore its development, if you wish.");

	r = [];
	r.push("Your reputation is, of course, already quite impressive. The reputation tracked in the sidebar is specifically your reputation as a slaveowner. It can be raised through decadent actions that display your munificence and opulence. Some random events can increase it, but the most reliable way to improve your reputation is to send sexually skilled slaves out into the arcology to offer free sexual services. This assignment is very similar to prostitution, but produces reputation rather than");
	r.push(App.UI.DOM.makeElement("span", App.UI.DOM.combineNodes(App.Encyclopedia.Dialog.linkDOM("money", "Money"), "."), "cash"));
	r.push(`Your`, App.Encyclopedia.Dialog.linkDOM("Concubine", "Concubine"), `and to a lesser extent, other slaves assigned to your personal sexual service, also have a direct impact on your reputation. Maintaining an exclusive harem of beautiful, talented girls is not just one of the greatest perks of being an arcology owner, it's also a grand statement to the world about your personal standing and power.`);
	App.Events.addParagraph(f, r);

	r = [];
	r.push("As your reputation develops, you may have the opportunity to guide the future of your arcology's society. Successfully doing so will increase your reputation in turn, which will duly enable you to further shape society. Managing societal development well will have a recursive effect on your reputation, and can drive it to great heights.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push("Because societal development and reputation build upon each other, arcology owners who have a natural reputation disadvantage (such as young women) may find it best to develop a future society model for which they can easily build wide support early on in their arcology's development. Arcology owners who choose to focus on an especially challenging path at the start of their career, such as");
	r.push(App.Encyclopedia.Dialog.linkDOM("Repopulation", "Repopulationism"), "or", App.Encyclopedia.Dialog.linkDOM("Eugenics,", "Eugenics Focus"));
	r.push("may find that they have difficulty accumulating and maintaining enough reputation to shape additional societal development.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push("The benefits of high reputation are numerous. Many business and enslavement opportunities will open to you once you are reputable. Some of the most advanced technology is only available to those with impeccable reputations as slaveowners, and many of the finer slave markets will only consider reputable buyers. You may eventually become so renowned that merely branding a slave with your mark will increase her value on the open market.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push("However, your reputation will not look after itself. At a certain point, you will become so reputable that continual effort will be necessary to maintain your renown and greater feats will be needed to cultivate it further. The old world question \"What have you done for me lately?\" is asked with twice the force in the Free Cities! You will quickly find that this natural decay of reputation can overwhelm your efforts to improve it by the end of the week. A concerted strategy will be necessary to overcome this.");
	App.Events.addParagraph(f, r);

	return f;
}, "beingInCharge");

App.Encyclopedia.addArticle("Random Events", function() {
	const f = new DocumentFragment();
	let r;

	r = [];
	r.push("At the end of every turn, a random event may occur. Almost all random events are tied to necessary preconditions. For example, events concerning");
	r.push(App.Encyclopedia.Dialog.linkDOM("rebellious", "From Rebellious to Devoted", "devotion resistant"));
	r.push("slaves will stop happening if all the player's slaves become obedient.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push("Usually, a situation will be presented and the player may choose one of two or three resolutions. Please note that the player may also to choose none of these by using the Continue button in the sidebar; in effect, this usually means the player's character has simply declined to involve himself.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push("Almost all choices will result in small effects. The most common are changes to a slave's attitude towards the player's character, but there are others.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push("Finally, there are events that can result in the player being offered the chance to acquire new slaves, some of which can be unique or valuable. Generally, these events offer this livestock at an extremely discounted price. These events will appear more often the higher the player's");
	r.push(App.Encyclopedia.Dialog.linkDOM("reputation", "Arcologies and Reputation", "reputation inc"));
	r.push("becomes.");
	App.Events.addParagraph(f, r);

	return f;
}, "beingInCharge");

App.Encyclopedia.addArticle("Costs Summary", function() {
	const f = new DocumentFragment();
	let r;

	const basicDrugCost = 100;
	const basicRulesCost = 100;

	r = [];
	r.push("Aphrodisiacs are");
	r.push(App.Encyclopedia.Dialog.linkDOM("cheap", "Money", "cash"));
	r.push(`and cost ${cashFormat(basicDrugCost)} weekly; curatives are expensive and cost ${cashFormat(basicDrugCost * 3)} weekly; while all other drug regimes cost ${cashFormat(basicDrugCost * 2)}. Standard hormone regimens cost ${Math.trunc(basicDrugCost * 0.5)} while intensive hormone treatment costs ${Math.trunc(basicDrugCost * 2 * 0.5)}. Contraceptives cost ${Math.trunc(basicDrugCost * 0.5)}.`);
	App.Events.addParagraph(f, r);

	r = [];
	r.push(`Slaves on spare living standards are fed a bland diet and obliged to sleep on bedrolls. Keeping a slave under restrictive rules costs <span class='cash'>${cashFormat(basicRulesCost)}</span> weekly.`);
	App.Events.addParagraph(f, r);

	r = [];
	r.push(`Slaves enjoying luxurious living standards on the other hand are fed a tasty diet and permitted to sleep in comfortable beds, and are generally pampered. The increased luxury of permissive rules costs ${cashFormat(basicRulesCost * 3)} weekly.`);
	App.Events.addParagraph(f, r);

	App.UI.DOM.appendNewElement("p", f, "Costs given are only the base costs, they can be affected by a variety of modifiers, for example economy settings, player background and arcology upgrades. Some upgrades may have associated upkeep costs as well.");

	return f;
}, "beingInCharge");

App.Encyclopedia.addArticle("Rules Assistant", function() {
	const f = new DocumentFragment();
	let r;

	r = [];
	r.push(App.Encyclopedia.topic("The Rules Assistant"));
	r.push("is a system to apply multiple rule sets to multiple slaves at once. You can apply rules to slaves based on slave");
	r.push(App.UI.DOM.makeElement("span", App.UI.DOM.combineNodes(App.Encyclopedia.Dialog.linkDOM("devotion", "From Rebellious to Devoted"), ","), ["devotion", "accept"]));
	r.push(App.UI.DOM.makeElement("span", App.UI.DOM.combineNodes(App.Encyclopedia.Dialog.linkDOM("trust", "Trust"), ","), ["trust", "careful"]));
	r.push("sex drive, health,");
	r.push(App.UI.DOM.combineNodes(App.Encyclopedia.Dialog.linkDOM("weight", "Weight"), ","));
	r.push(App.UI.DOM.combineNodes(App.Encyclopedia.Dialog.linkDOM("muscles", "Musculature"), ","));
	r.push("lactation, pregnancy, number of fetuses, abdominal implants and age.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Rule settings"));
	r.push("Rules can be used to control certain aspects of slaves everyday lives, for example to automatically give slaves a certain clothing option, collar, footwear or allow slaves to choose their own outfit. They can be used to give unhealthy slaves curatives to improve their health or to put slaves on a diet so that their");
	r.push(App.Encyclopedia.Dialog.linkDOM("weight", "Weight"));
	r.push("can be closer to the ideal weight. Rules set to No default setting will not apply that particular condition to slaves. Rules can also be renamed to be more indicative of their intended purpose.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Rule activation conditions"));
	r.push("To have control over which slaves the rule will apply to conditions can be created.");
	r.push(App.Encyclopedia.Dialog.linkDOM("In-depth explanation", "RA Condition Editor"));
	r.push("of the condition editor.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Selecting or excluding slaves from a rule"));
	r.push("Slaves can be selected for a rule by selecting slaves from the list so that a rule can apply only to them. Slaves can similarly be excluded from a rule.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Automatically giving an assignment"));
	r.push("A rule can be set to automatically set a slave to an assignment when activated. For example a");
	r.push(App.Encyclopedia.Dialog.linkDOM("devoted", "From Rebellious to Devoted", "devotion accept"));
	r.push("slave can be set to automatically be put on the whoring assignment. This is mutually exclusive to applying a rule to assignments.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Automatically assigning slaves to a facility"));
	r.push("A rule can be set to automatically put a slave into a facility when activated. For example disobedient slaves can be set to automatically be confined in the arcade if it has been constructed. This is mutually exclusive to applying a rule to facilities.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Saving a rule"));
	r.push("If you are finished setting up a rule make sure to save it by clicking Save rule at the bottom before clicking another link otherwise your settings will be lost.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Applying a rule"));
	r.push("Clicking on Apply rules will automatically save the current rule and apply all rules to slaves at once.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Adding or removing a rule"));
	r.push("The game starts with 3 basic default rule settings but more can be added and/or removed as needed. To add a new rule, click Add a new rule at the bottom, removing a rule is the same by clicking Remove rule.");
	App.Events.addParagraph(f, r);

	return f;
}, "beingInCharge");

App.Encyclopedia.addArticle("The Corporation", function() {
	const f = new DocumentFragment();
	let r;

	r = [];
	r.push("Once you are fairly reputable and have a large sum of cash in the bank, you will receive a brief end of turn event that unlocks the ability to found a corporation dedicated to slaving. Once this happens, you can incorporate from the Manage Corporation link on the sidebar, and once you've done that, you can manage your corporation every week from the same place.");
	App.Events.addParagraph(f, r);

	App.UI.DOM.appendNewElement("h3", f, "Shares");
	r = [];
	r.push("Buying shares from the corporation or issuing new shares will create new shares in the corporation. If you buy them yourself, cash will be transferred from you to the corporation in return for the shares; if you direct the corporation to issue new public shares,");
	r.push(App.Encyclopedia.Dialog.linkDOM("money", "Money", "cash"));
	r.push("will come into the corporation from the market. If you direct the corporation to buy back shares from the public, cash will be transferred from the corporation to reduce the number of public shares, which will increase your ownership percentage. You are not permitted to give up majority ownership of the corporation. Selling your shares or buying publicly held shares are both transactions between you and your shares and shareholders and their shares. All transactions impact the stock price.");
	App.Events.addParagraph(f, r);

	App.UI.DOM.appendNewElement("h3", f, "Divisions");
	App.UI.DOM.appendNewElement("p", f, "The corporation consists of divisions. Starting up your corporation requires you to choose a single division as starting point and you will be able to expand into linked divisions once you have grown sufficiently in size. There are 3 general categories of divisions; acquisition, modification and exploitation. The first consists of legal and extralegal enslavement and they feed fresh slaves into either your corporation or the market at large. Investing in one of these is a good starting point when slave prices are high. Do note that each slave acquired and sold reduces the demand for slaves on the market. This means little at first, but when large enough will impact the market significantly.");
	App.UI.DOM.appendNewElement("p", f, "The second category consists of slave breaking, physical slave modifications and slave training. These divisions either take improvable slaves from your acquisition divisions or the slave market and improve them. Slaves can go from breaking to physical modifications to training and become highly valuable slaves by the end of it. If the slave market is balanced or you are looking for a safe initial investment these divisions are a good choice. Their market impact is neutral, buying slaves reduces supply but selling them back onto the market reduces demand by the same amount.");
	App.UI.DOM.appendNewElement("p", f, "The final category consists of an arcade, menial services, dairy and escort division. These divisions require a particular quality of slave and then put them to work in their respective fields. As these divisions operate they will have to write off some of their slaves and replace them with fresh ones, you can provide these slaves through your acquisition or modification divisions or the market. Whenever prices are low these divisions operate at a higher margin, making them a great first division when slave prices are low. Do note that each slave bought from the market reduces the supply of slaves. As these divisions grow and write off more and more slaves each week, replenishing them from the market will begin to impact the market significantly.");

	App.UI.DOM.appendNewElement("h3", f, "Management");
	App.UI.DOM.appendNewElement("p", f, "Your first division will automatically buy and/or sell slaves in order to do business and make money. It is up to you to decide when to expand the division's capacity, but investing aggressively early will pay off in the long run. Once your corporation has gotten a little time to grow its value (the sum of slave value, division value, cash on hand and dividends reserved) the end of week report will prompt you that a new division can be added. This requires a significant cash investment so you may have to save up a little. Adding divisions comes with efficiency benefits, but also adds overhead costs. Adding a second division will hardly slow you down, but as you grow these costs grow ever larger; depending on the number of divisions, but also the size of them.");
	App.UI.DOM.appendNewElement("p", f, "Any new division will have at least one direct link to your current divisions, meaning it can either use slaves from a division or provide them to another division. New divisions are not automatically set to buy and/or sell slaves from the market. It is expected you either manually move slaves between divisions or sets up automatic links between them using several rules.");
	App.UI.DOM.appendNewElement("p", f, "You have the ability to reduce the size of your divisions or dissolve them entirely. While this only recoups 80% of the investment it may sometimes be prudent to do so, i.e. in case market conditions have become unfavorable for the division and/or overhead costs are becoming oppressively high. Also note that divisions become less efficient the larger they get (even without considering overhead), eventually growing it further will hurt your profit, not improve it. You will want to cut your losses early or otherwise suffer the consequences.");
	App.UI.DOM.appendNewElement("p", f, "In order to personally benefit monetarily from your corporation you will have to decide how much of its profit will be set aside to be paid out as dividends. Setting low or no dividends allows for rapid development, while siphoning a lot of profits away from the corporation will slow it down significantly. Please note that the corporation does not pay out every week but only every quarter (13 weeks).");

	App.UI.DOM.appendNewElement("h3", f, "Slave Sales");
	App.UI.DOM.appendNewElement("p", f, "Once a corporation is created, it will get its own establishment in the slave market. As the corporation's value increase, it can be given direction about what kind of slaves it should train and how it should train them, which will affect the slaves seen in the corporate catalog. As with divisions; the higher your corporation's value, the more specializations you are allowed to choose. Your corporation's divisions determine which specialization options are available. Each division has a unique specialization associated with it while many others are slightly more general and linked to either acquisition or modification. All kinds of restrictions may apply depending on Future Society choices and the size of your divisions. Several specializations can be enhanced beyond the first choice, but again you may need to satisfy certain conditions first.");
	r = [];
	r.push("If the corporation's slaves have qualities that make them especially appealing to an arcology's citizens, the corporation will enjoy increased profits, and the");
	r.push(App.Encyclopedia.Dialog.linkDOM("future society", "Future Societies"));
	r.push("creating the demand will progress more rapidly due to the supply of appealing slaves. All arcologies present in the Free City will interact with the corporation this way, making shares in a corporation which supplies girls that appeal to the whole city extremely lucrative.");
	App.Events.addParagraph(f, r);

	return f;
}, "beingInCharge");

App.Encyclopedia.addArticle("Sexual Energy", function() {
	const f = new DocumentFragment();
	let r;

	App.UI.DOM.appendNewElement("p", f, `Though you're (naturally) a virile, oversexed oligarch, even your reserves of sexual energy are not infinite. They're impressive, but not infinite. Since one turn represents one week, the game does not allow you direct control over every sexual interaction between you character and your slaves. Put another way, the game assumes there's an impressive amount of off-screen sex going on between the you and your chattel.`);

	r = [];
	r.push(`Your sexual energy can have gameplay effects. Though of course all slaves are at the owner's sexual beck and call, some assignments and training methods involve close sexual attention by yourself. If a large number of slaves are subject to this, your attention will be somewhat diluted, and the effects on each slave will be reduced. Slaves assigned to be fucktoys and serve in the master suite count towards a hidden estimation of your sexual foci. With two or fewer such slaves, the your sexual attention on these slaves will be intense and have intense effects. With five or more, the you may have some difficulty in using every slave every day, diluting the mental effects of being one's personal sex toy.`);
	App.Events.addParagraph(f, r);

	App.UI.DOM.appendNewElement("p", f, `It is possible to raise these limits by focusing on sexual decadence for the week. By paying less attention to business and not using sexual training on specific slaves, you will have more energy to spare and can offer intense sexual attention to three slaves or give sexual attention to up to seven slaves without dilution.`);

	App.UI.DOM.appendNewElement("p", f, `There exist several other ways to raise your sexual energy as well.`);

	return f;
}, "beingInCharge");

App.Encyclopedia.addArticle("PC Skills", function() {
	const f = new DocumentFragment();
	let r;

	r = [];
	r.push(App.Encyclopedia.topic("Trading"));
	r.push("signifies how efficient you are at making exchanges. Provides more passive income the higher it is. Can be increased through acquiring slaves.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Warfare"));
	r.push("is an indication your combat prowess. Cuts cost of housing mercs in half. Can be increased through use in relevant situations.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Hacking"));
	r.push("is an indication of your effectiveness at manipulating computer systems. Higher levels make technological upgrades");
	r.push(App.Encyclopedia.Dialog.linkDOM("cheaper", "Money", "cash"));
	r.push("or free, provides a boost situations where fame is measured digitally. Can be increased through choosing to Sell your intrusion services to the highest bidder once the option becomes available after having some skill and purchasing technological upgrades.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Slaving"));
	r.push("improves your effectiveness as a slave driver. At max level it allows you to more easily spot");
	r.push(App.UI.DOM.combineNodes(App.Encyclopedia.Dialog.linkDOM("gingering", "Gingering"), "."));
	r.push("Can be increased through acquiring performing the duties of a slave driver.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Engineering"));
	r.push("is a sign of how effective you are building and maintenance. Mastering the skill reduces the cost of arcology upgrades and expansions. Can be increased through purchasing arcology upgrades or expanding facility capacity. If the");
	r.push(App.Encyclopedia.Dialog.linkDOM("Security Expansion", "Security Expansion"));
	r.push("mod is enabled, the skill is also increased by repairing your arcology.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push(App.Encyclopedia.topic("Medicine"));
	r.push("shows how effective you are treating wounds. Max level reduces a slave's health and");
	r.push(App.Encyclopedia.Dialog.linkDOM("trust", "Trust", "trust careful"));
	r.push("loss during surgery.");
	App.Events.addParagraph(f, r);

	r = [];
	r.push("In addition to the above methods of increasing a skill (if any), all of them can be learnt by retaining a trainer");
	if (V.SF.Toggle && V.SF.Active >= 1) {
		r.push("or by talking to/learning from The Colonel");
	}
	r.push(r.pop() + ".");
	App.Events.addParagraph(f, r);

	return f;
}, "beingInCharge");

App.Encyclopedia.addArticle("Drug grades and you", function() {
	const f = new DocumentFragment();
	App.Events.addNode(f, ["There exist a trio of important differences between consumer-grade drugs made for citizens and slave-grade drugs reserved for chattel:"], "div");
	App.Events.addNode(f, [`${App.UI.DOM.makeElement("span", "Health", ["strong"])}: Consumer drugs generally lack the side-effects associated with long term slave-grade drug use. It is also far more difficult to accidentally ruin your body with their use.`], "div");
	App.Events.addNode(f, [`${App.UI.DOM.makeElement("span", "Strength", ["strong"])}: Overall, consumer drugs are weaker by comparison as a trade off for the improved health benefits. This does not mean they are necessarily worse, however; they are slower, but more consistent and able to confer their benefits past the point that slave-grade injections would cease to be reasonable.`], "div");
	App.Events.addNode(f, [`${App.UI.DOM.makeElement("span", "Price", ["strong"])}: With most production focused on cheap slave-grade drugs, consumer drugs run at a premium and usually require a physician to prescribe them.`], "div");
	return f;
}, "beingInCharge");

App.Encyclopedia.addCategory("beingInCharge", function() {
	const links = [];
	links.push(App.Encyclopedia.Dialog.linkDOM("Arcologies and Reputation"));
	links.push(App.Encyclopedia.Dialog.linkDOM("Random Events"));
	links.push(App.Encyclopedia.Dialog.linkDOM("Costs Summary"));
	links.push(App.Encyclopedia.Dialog.linkDOM("Rules Assistant"));
	links.push(App.Encyclopedia.Dialog.linkDOM("RA Condition Editor"));
	links.push(App.Encyclopedia.Dialog.linkDOM("The Corporation"));
	links.push(App.Encyclopedia.Dialog.linkDOM("Sexual Energy"));
	links.push(App.Encyclopedia.Dialog.linkDOM("PC Skills"));
	links.push(App.Encyclopedia.Dialog.linkDOM("Drug grades and you"));
	return App.UI.DOM.generateLinksStrip(links);
});


code:
App.Encyclopedia.addArticle("The Black Market", function() {
 const t = new DocumentFragment();
	const r = new SpacedTextAccumulator(t);

 r.push("You may be the ruler of your arcology, but you don't exist in a vacuum. You can do all kinds of thing and get lots of things that regular citizens can't. So the Black Market, is a chance for less prominent citizens to do or get stuff like an arcology leader might experience. But for a ruler like yourself, it's a chance to avoid the severe scrutiny you're subject to on a regular basis, and to get a hold of bleeding edge or illegal research and technologies. The market itself is always moving from place to place, but if you're reputable enough, you can find it when you need it.");
 r.toNode("div");

 r.push("You will be able to find all manner of Future Society technologies which are not exactly illegal, but difficult to get through regular channels. Every week, the dealers will have a few for you to purchase, but for the truly illegal or unethical items, your only choice is to go to the Black Market.");
 r.toNode("p");

 r.push("Specialty goods:", App.Encyclopedia.Dialog.linkDOM("Childhood Fertility Induced NCS"));
 r.toNode("p");

 return t;
}, "BlackMarket");

App.Encyclopedia.addArticle("Contraband and Illegal Goods", function() {
 const t = new DocumentFragment();
	const r = new SpacedTextAccumulator(t);

 r.push("While there is little to no issue with possessing nearly anything, getting your hands on it may not always be feasible. Be it local policy or overreaching business deals, certain goods may not be found for sale in the Free City. This does not stop some of the shadier dealers from risking the sale of them, of course; this is where smugglers come in. There is always a market for contraband and illicit goods and never a shortage of people looking to buy them. Not all smugglers are successful, and those that aren't soon find themselves up for sale in the slave markets.");
 r.toNode("div");

 return t;
}, "BlackMarket");

App.Encyclopedia.addArticle("Childhood Fertility Induced NCS", function() {
 const t = new DocumentFragment();
	const r = new SpacedTextAccumulator(t);

 r.push("This uses a designer retrograde virus to set the genetic markers for the Neotenic Complex Syndrome, a syndrome originally called Syndrome X discovered in the early 2000s.");
 r.push("In layman's terms, it", App.UI.DOM.makeElement("span", "suppresses the growth and secondary sexual characteristics of slaves", ["gold"]), "both male and female.");
 r.push("The original condition was usually fatal or dangerous.");
 r.push("This modified version of the genetic flaw is not harmful (relatively speaking), and in addition to the growth blockage, it permits the slave to continue the", App.UI.DOM.makeElement("span", "development of gonads", ["lime"]), "at a slightly faster than normal pace.");
 r.push("Secondary sexual characteristics are also reversed, though interestingly enough, pregnancy is still possible.Slaves put on this genetic engineered blend will be permanently changed and will no longer grow in stature or assets without severe chemical assistance, and even then at a reduced rate when compared to non-NCS-induced slaves, and should their ongoing growth treatments stop they will slowly regress back to the physicality of a child.");
 r.toNode("div");

 r.push(App.UI.DOM.makeElement("span", "The genetic tampering is considered illegal,", ["red"]), "but there is also a", App.UI.DOM.makeElement("span", "moral question as this abrogates the rights of slaves to ever grow up.", ["yellow"]));
 r.toNode("p");

 r.push("Can only be purchased in", App.Encyclopedia.Dialog.linkDOM("The Black Market"));
 r.addToLast(".");
 r.toNode("p");

 return t;
}, "BlackMarket");

App.Encyclopedia.addCategory("BlackMarket", function() {
 const r = [];
 r.push(App.Encyclopedia.Dialog.linkDOM("The Black Market"));
 r.push(App.Encyclopedia.Dialog.linkDOM("Contraband and Illegal Goods"));
	/* Can be uncommented once converted to DOM.
 r.push(App.Encyclopedia.Dialog.linkDOM("Gender Radicalism Research"));
 r.push(App.Encyclopedia.Dialog.linkDOM("Slave Professionalism Research"));
 r.push(App.Encyclopedia.Dialog.linkDOM("Transformation Fetishism Research"));
 r.push(App.Encyclopedia.Dialog.linkDOM("Asset Expansionist Research"));
 r.push(App.Encyclopedia.Dialog.linkDOM("Slimness Enthusiast Research"));
	r.push(App.Encyclopedia.Dialog.linkDOM("Youth Preferentialism Research"));
	r.push(App.Encyclopedia.Dialog.linkDOM("Hedonistic Decadence Research"));
	*/
 r.push(App.Encyclopedia.Dialog.linkDOM("Childhood Fertility Induced NCS"));
 return App.UI.DOM.generateLinksStrip(r);
});