code:
:: Related Links [nobr]

/* pages asking the player to click a link for more information have no section heading */
<<if !["Being in Charge", "Body", "Fetishes", "Game Mods", "Inflation", "Leadership Positions", "Lolimod", "Lore", "Obtaining Slaves", "Paraphilias", "Playing Free Cities", "Skills", "Slave Assignments", "Slave Modification", "Slaves", "Terrain Types", "The X-Series Arcology"].includes($encyclopedia)>>

Related Links

<</if>>

<<set _pass = App.Encyclopedia.renderCategory($encyclopedia)>>
<<if _pass>>
	<<includeDOM _pass>>
<<else>>

<<switch $encyclopedia>>

/**********
SLAVE LEADERS:
**********/
<<case "Attendant" "Bodyguard" "Career Experience" "Concubine" "DJ" "Farmer" "Head Girl" "Leadership Positions" "Madam" "Matron" "Milkmaid" "Nurse" "Recruiter" "Schoolteacher" "Stewardess" "Wardeness">>
	<<= App.Encyclopedia.Dialog.linkSC("Leadership Positions", "Leadership Positions")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Career Experience", "Career Experience")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Attendant", "Attendant")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Bodyguard", "Bodyguard")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Concubine", "Concubine")>>
	| <<= App.Encyclopedia.Dialog.linkSC("DJ", "DJ")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Farmer", "Farmer")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Head Girl", "Head Girl")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Madam", "Madam")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Matron", "Matron")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Milkmaid", "Milkmaid")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Nurse", "Nurse")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Recruiter", "Recruiter")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Schoolteacher", "Schoolteacher")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Stewardess", "Stewardess")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Wardeness", "Wardeness")>>

/**********
SLAVE SKILLS
**********/
<<case "Anal Skill" "Combat Skill" "Entertainment Skill" "Oral Skill" "Skills" "Vaginal Skill" "Whoring Skill">>
	<<= App.Encyclopedia.Dialog.linkSC("Anal Skill", "Anal Skill")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Combat Skill", "Combat Skill")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Entertainment Skill", "Entertainment Skill")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Oral Skill", "Oral Skill")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Vaginal Skill", "Vaginal Skill")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Whoring Skill", "Whoring Skill")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Career Experience", "Career Experience")>>

/**********
SLAVE FETISHES:
**********/
<<case "Boob Fetishists" "Buttsluts" "Cumsluts" "Doms" "Fetishes" "Humiliation Fetishists" "Masochists" "Pregnancy Fetishists" "Sadists" "Submissives">>
	<<= App.Encyclopedia.Dialog.linkSC("Boob Fetishists", "Boob Fetishists")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Buttsluts", "Buttsluts")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Cumsluts", "Cumsluts")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Doms", "Doms")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Humiliation Fetishists", "Humiliation Fetishists")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Masochists", "Masochists")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Pregnancy Fetishists", "Pregnancy Fetishists")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Sadists", "Sadists")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Submissives", "Submissives")>>

/**********
SLAVE PARAPHILIAS
**********/
<<case "Abusiveness" "Anal Addicts" "Attention Whores" "Breast Obsession" "Breeding Obsession" "Cum Addicts" "Maliciousness" "Paraphilias" "Self Hatred" "Self Neglect">>
	<<= App.Encyclopedia.Dialog.linkSC("Abusiveness", "Abusiveness")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Anal Addicts", "Anal Addicts")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Attention Whores", "Attention Whores")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Breast Obsession", "Breast Obsession")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Breeding Obsession", "Breeding Obsession")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Cum Addicts", "Cum Addicts")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Maliciousness", "Maliciousness")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Self Hatred", "Self Hatred")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Self Neglect", "Self Neglect")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Fetishes", "Fetishes")>>

/**********
SLAVE QUIRKS
**********/
<<case "Adores Men" "Adores Women" "Advocate" "Confident" "Cutting" "Fitness" "Funny" "Insecure" "Sinful" "Caring" "Gagfuck Queen" "Painal Queen" "Perverted" "Quirks" "Romantic" "Size Queen" "Strugglefuck Queen" "Tease" "Unflinching">>
	//Behavioral <<= App.Encyclopedia.Dialog.linkSC("Quirks", "Quirks")>>://
	<<= App.Encyclopedia.Dialog.linkSC("Adores men", "Adores Men")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Adores women", "Adores Women")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Advocate", "Advocate")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Confident", "Confident")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Cutting", "Cutting")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Fitness", "Fitness")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Funny", "Funny")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Insecure", "Insecure")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Sinful", "Sinful")>>

	//Sexual <<= App.Encyclopedia.Dialog.linkSC("Quirks", "Quirks")>>://
	<<= App.Encyclopedia.Dialog.linkSC("Caring", "Caring")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Gagfuck Queen", "Gagfuck Queen")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Painal Queen", "Painal Queen")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Perverted", "Perverted")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Romantic", "Romantic")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Size Queen", "Size Queen")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Strugglefuck Queen", "Strugglefuck Queen")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Tease", "Tease")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Unflinching", "Unflinching")>>

/**********
SLAVE FLAWS
**********/
<<case "Anorexic" "Arrogant" "Bitchy" "Devout" "Flaws" "Gluttonous" "Hates Men" "Hates Women" "Liberated" "Odd" "Apathetic" "Crude" "Hates Anal" "Hates Oral" "Hates Penetration" "Idealistic" "Judgemental" "Repressed" "Shamefast">>
	//Behavioral <<= App.Encyclopedia.Dialog.linkSC("Flaws", "Flaws")>>://
	<<= App.Encyclopedia.Dialog.linkSC("Anorexic", "Anorexic")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Arrogant", "Arrogant")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Bitchy", "Bitchy")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Devout", "Devout")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Gluttonous", "Gluttonous")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Hates men", "Hates Men")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Hates women", "Hates Women")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Liberated", "Liberated")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Odd", "Odd")>>

	//Sexual <<= App.Encyclopedia.Dialog.linkSC("Flaws", "Flaws")>>://
	<<= App.Encyclopedia.Dialog.linkSC("Apathetic", "Apathetic")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Crude", "Crude")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Hates anal", "Hates Anal")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Hates oral", "Hates Oral")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Hates penetration", "Hates Penetration")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Idealistic", "Idealistic")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Judgemental", "Judgemental")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Repressed", "Repressed")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Shamefast", "Shamefast")>>

/**********
SLAVE RELATIONSHIPS
**********/
<<case "Emotional Slut" "Emotionally Bonded" "Relationships" "Rivalries" "Romances" "Slave Marriages" "Slaveowner Marriages">>
	<<= App.Encyclopedia.Dialog.linkSC("Relationships", "Relationships")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Rivalries", "Rivalries")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Romances", "Romances")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Emotionally Bonded", "Emotionally Bonded")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Emotional Slut", "Emotional Slut")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slave Marriages", "Slave Marriages")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slaveowner Marriages", "Slaveowner Marriages")>>

/**********
PREGNANCY
**********/
<<case "Artificial Insemination" "Breeders Dietary Blend" "Childbirth and C-Secs" "Cloning" "Fertility Mix" "Gestation Drugs and Labor Suppressants" "Hyper-Pregnancy" "Ova Transplantation" "Player Pregnancy" "Pregnancy" "Pregnancy Generator" "Slave Fertility" "Super Fertility Drugs" "Surrogacy" "Inbreeding">>
	<<= App.Encyclopedia.Dialog.linkSC("Pregnancy", "Pregnancy")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slave Fertility", "Slave Fertility")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Player Pregnancy", "Player Pregnancy")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Hyper-Pregnancy", "Hyper-Pregnancy")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Super Fertility Drugs", "Super Fertility Drugs")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Fertility Mix", "Fertility Mix")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Breeders Dietary Blend", "Breeders Dietary Blend")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Pregnancy Generator", "Pregnancy Generator")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Childbirth and C-Secs", "Childbirth and C-Secs")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Gestation Drugs and Labor Suppressants", "Gestation Drugs and Labor Suppressants")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Artificial Insemination", "Artificial Insemination")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Surrogacy", "Surrogacy")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Cloning", "Cloning")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Ova Transplantation", "Ova Transplantation")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Eugenics Breeding Proposal", "Eugenics Breeding Proposal")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Repopulationist Breeding School", "Repopulationist Breeding School")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Inbreeding", "Inbreeding")>>

/**********
INFLATION
**********/
<<case "Belly Implants" "Cervix Micropump Filter" "Enemas and Force-Feeding" "Inflation" "Organic Mesh Breast Implant">>
	<<= App.Encyclopedia.Dialog.linkSC("Inflation", "Inflation")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Enemas and Force-Feeding", "Enemas and Force-Feeding")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Belly Implants", "Belly Implants")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Cervix Micropump Filter", "Cervix Micropump Filter")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Organic Mesh Breast Implant", "Organic Mesh Breast Implant")>>

/**********
SLAVE MODIFICATION
**********/
<<case "Slave Modification">>
	<<= App.Encyclopedia.Dialog.linkSC("Slave Modification", "Slave Modification")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Corrective Diet", "Corrective Diet")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Nipple Conversion — Penetratable", "Nipple Conversion — Penetratable")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Ejaculation Boosting Prostate Implant", "Ejaculation Boosting Prostate Implant")>>

/**********
THE X-SERIES ARCOLOGY
**********/
<<case "Personal Assistant" "Security Drones" "Slave Nutrition" "The Auto Salon" "The Pharmaceutical Fab." "The Remote Surgery" "The Studio" "The Wardrobe" "The X-Series Arcology" "Water Filtration" "What the Upgrades Do">>
	<<= App.Encyclopedia.Dialog.linkSC("What the Upgrades Do", "What the Upgrades Do")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Personal Assistant", "Personal Assistant")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Wardrobe", "The Wardrobe")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Auto Salon", "The Auto Salon")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Body Mod Studio", "The Studio")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Remote Surgery", "The Remote Surgery")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Pharmaceutical Fab.", "The Pharmaceutical Fab.")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Security Drones", "Security Drones")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Water Filtration", "Water Filtration")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slave Nutrition", "Slave Nutrition")>>

/**********
ARCOLOGY FACILITIES
**********/
<<case "Advertising" "Arcade" "Brothel" "Cellblock" "Clinic" "Club" "Dairy" "Facilities" "Farmyard" "Head Girl Suite" "Master Suite" "Nursery" "Pit" "Schoolroom" "Servants' Quarters" "Spa" "The Incubation Facility" "Variety">>
	//Arcology <<= App.Encyclopedia.Dialog.linkSC("Facilities", "Facilities")>>://
	<<= App.Encyclopedia.Dialog.linkSC("Arcade", "Arcade")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Brothel", "Brothel")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Cellblock", "Cellblock")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Clinic", "Clinic")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Club", "Club")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Dairy", "Dairy")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Head Girl Suite", "Head Girl Suite")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Master Suite", "Master Suite")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Pit", "Pit")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Schoolroom", "Schoolroom")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Servants' Quarters", "Servants' Quarters")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Spa", "Spa")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Nursery", "Nursery")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Farmyard", "Farmyard")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Incubation Facility ", "The Incubation Facility")>>

	//Facility Bonuses://
	<<= App.Encyclopedia.Dialog.linkSC("Advertising", "Advertising")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Variety", "Variety")>>

/**********
TERRAIN TYPES
**********/
<<case "Terrain Types" "Urban Terrain" "Rural Terrain" "Marine Terrain" "Oceanic Terrain">>
	<<= App.Encyclopedia.Dialog.linkSC("Urban", "Urban Terrain")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Rural", "Rural Terrain")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Marine", "Marine Terrain")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Oceanic", "Oceanic Terrain")>>

/**********
FUTURE SOCIETIES
**********/
<<case "Arabian Revivalism" "Asset Expansionism" "Aztec Revivalism" "Body Purism" "Chattel Religionism" "Chinese Revivalism" "Degradationism" "Edo Revivalism" "Egyptian Revivalism" "Ethnic Subjugationism" "Ethnic Supremacy" "Eugenics Focus" "Future Societies" "Gender Fundamentalism" "Gender Radicalism" "Hedonistic Decadence" "Intellectual Dependency" "Maturity Preferentialism" "Multiculturalism" "Pastoralism" "Paternalism" "Petite Admiration" "Physical Idealism" "Repopulationism" "Roman Revivalism" "Slave Professionalism" "Slimness Enthusiasm" "Statuesque Glorification" "Transformation Fetishism" "Youth Preferentialism" "Neo-Imperialism">>
	//Vanilla Future Societies://
	<<= App.Encyclopedia.Dialog.linkSC("Ethnic Supremacy", "Ethnic Supremacy")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Ethnic Subjugationism", "Ethnic Subjugationism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Gender Radicalism", "Gender Radicalism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Gender Fundamentalism", "Gender Fundamentalism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Paternalism", "Paternalism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Degradationism", "Degradationism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Body Purism", "Body Purism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Transformation Fetishism", "Transformation Fetishism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Maturity Preferentialism", "Maturity Preferentialism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Youth Preferentialism", "Youth Preferentialism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slimness Enthusiasm", "Slimness Enthusiasm")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Asset Expansionism", "Asset Expansionism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Pastoralism", "Pastoralism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Physical Idealism", "Physical Idealism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Chattel Religionism", "Chattel Religionism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Multiculturalism", "Multiculturalism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Roman Revivalism", "Roman Revivalism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Egyptian Revivalism", "Egyptian Revivalism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Edo Revivalism", "Edo Revivalism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Arabian Revivalism", "Arabian Revivalism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Chinese Revivalism", "Chinese Revivalism")>>

	//Modded Future Societies://
	<<= App.Encyclopedia.Dialog.linkSC("Repopulationism", "Repopulationism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Eugenics Focus", "Eugenics Focus")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slave Professionalism", "Slave Professionalism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Intellectual Dependency", "Intellectual Dependency")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Petite Admiration", "Petite Admiration")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Statuesque Glorification", "Statuesque Glorification")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Hedonistic Decadence", "Hedonistic Decadence")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Aztec Revivalism", "Aztec Revivalism")>>
 	| <<= App.Encyclopedia.Dialog.linkSC("Neo-Imperialism", "Neo-Imperialism")>>

/**********
LORE: THE FREE CITIES TODAY
**********/
<<case "Lore" "Money" "Food" "Disease in the Free Cities" "Free Cities Justice" "Modern Anal" "Slave Couture" "Slave Marriage" "The Ejaculate Market" "Gingering" "Dyes"
/**********
LORE: FREE CITIES CULTURE TOMORROW
**********/
"The New Rome" "The Return of Feudalism" "Naked, Barefoot, and Pregnant" "The Sons of Sekhmet" "The Top" "The Bottom" "The Purity of the Human Form" "A World Built on Implants" "Slaves as Stock" "Slavery and the Physical Ideal" "Faith in the Free Cities"
/**********
LORE: INTERVIEWS
**********/
"Slave Whore, Arcology K-2" "Slave Acolyte, Arcology V-7" "Public Slave, Arcology A-3" "Mercenary, Arcology B-2" "Slave Trainer, Arcology D-10" "Monarch, Arcology F-8">>
	//The Free Cities today://
	@@.yellowgreen; <<= App.Encyclopedia.Dialog.linkSC("Money", "Money")>>@@
	| <<= App.Encyclopedia.Dialog.linkSC("Disease in the Free Cities", "Disease in the Free Cities")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Free Cities Justice", "Free Cities Justice")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Modern Anal", "Modern Anal")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slave Couture", "Slave Couture")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slave Marriage", "Slave Marriage")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Ejaculate Market", "The Ejaculate Market")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Gingering", "Gingering")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Dyes", "Dyes")>>

//Free Cities culture tomorrow://
	<<= App.Encyclopedia.Dialog.linkSC("The New Rome", "The New Rome")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Return of Feudalism", "The Return of Feudalism")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Naked, Barefoot, and Pregnant", "Naked, Barefoot, and Pregnant")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Sons of Sekhmet", "The Sons of Sekhmet")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Top", "The Top")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Bottom", "The Bottom")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Purity of the Human Form", "The Purity of the Human Form")>>
	| <<= App.Encyclopedia.Dialog.linkSC("A World Built on Implants", "A World Built on Implants")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slaves as Stock", "Slaves as Stock")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slavery and the Physical Ideal", "Slavery and the Physical Ideal")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Faith in the Free Cities", "Faith in the Free Cities")>>

//Interviews://
	<<= App.Encyclopedia.Dialog.linkSC("Slave Whore, Arcology K-2", "Slave Whore, Arcology K-2")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slave Acolyte, Arcology V-7", "Slave Acolyte, Arcology V-7")>>
	<<if $seeExtreme != 0>>
		| <<= App.Encyclopedia.Dialog.linkSC("Public Slave, Arcology A-3", "Public Slave, Arcology A-3")>>
	<</if>>
	| <<= App.Encyclopedia.Dialog.linkSC("Mercenary, Arcology B-2", "Mercenary, Arcology B-2")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slave Trainer, Arcology D-10", "Slave Trainer, Arcology D-10")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Monarch, Arcology F-8", "Monarch, Arcology F-8")>>

/**********
BLACK MARKET
**********/
<<case "The Black Market" "Contraband and Illegal Goods" "Gender Radicalism Research" "Slave Professionalism Research" "Transformation Fetishism Research" "Asset Expansionist Research" "Slimness Enthusiast Research" "Hedonistic Decadence Research" "Eugenics Breeding Proposal" "Youth Preferentialism Research" "Repopulationist Breeding School">>
	<<= App.Encyclopedia.Dialog.linkSC("The Black Market", "The Black Market")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Contraband and Illegal Goods", "Contraband and Illegal Goods")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Gender Radicalism Research", "Gender Radicalism Research")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slave Professionalism Research", "Slave Professionalism Research")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Transformation Fetishism Research", "Transformation Fetishism Research")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Asset Expansionist Research", "Asset Expansionist Research")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Slimness Enthusiast Research", "Slimness Enthusiast Research")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Youth Preferentialism Research", "Youth Preferentialism Research")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Hedonistic Decadence Research", "Hedonistic Decadence Research")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Childhood Fertility Induced NCS", "Childhood Fertility Induced NCS")>>

/**********
MODS
**********/
<<case "Game Mods">>
	<<= App.Encyclopedia.Dialog.linkSC("Lolimod", "Lolimod")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Special Force Mod", "Special Force")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Security Expansion Mod", "Security Expansion")>>
	| <<= App.Encyclopedia.Dialog.linkSC("FCTV", "FCTV")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Catmod", "Catmod")>>

<<case "Lolimod" "Lolis and the Free Cities" "Fertility Age" "Male Fertility" "Cradle Robbers" "Precocious Puberty" "Childhood Fertility Induced NCS">>
	<<= App.Encyclopedia.Dialog.linkSC("Lolis and the Free Cities", "Lolis and the Free Cities")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Fertility Age", "Fertility Age")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Male Fertility", "Male Fertility")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Precocious Puberty", "Precocious Puberty")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Cradle Robbers", "Cradle Robbers")>>
	| <<= App.Encyclopedia.Dialog.linkSC("The Incubation Facility", "The Incubation Facility")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Childhood Fertility Induced NCS", "Childhood Fertility Induced NCS")>>

<<case "Security Expansion" "Battles">>
	<<= App.Encyclopedia.Dialog.linkSC("The Security Expansion Mod", "Security Expansion")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Battles", "Battles")>>

<<case "FCTV" "FCTVReceiver">>
	<<= App.Encyclopedia.Dialog.linkSC("FCTV", "FCTV")>>
	| <<= App.Encyclopedia.Dialog.linkSC("FCTVReceiver", "FCTVReceiver")>>

<<case "Catmod" "Bioengineering" "Catgirls">>
	<<= App.Encyclopedia.Dialog.linkSC("Catmod", "Catmod")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Catgirls", "Catgirls")>>
	| <<= App.Encyclopedia.Dialog.linkSC("Bioengineering", "Bioengineering")>>

<</switch>>
<</if>>


code:
/** Render a link that toggles the slave's favorite status
 * @param {App.Entity.SlaveState} slave
 * @param {function():void} [handler]
 * @returns {HTMLAnchorElement}
 */
App.UI.favoriteToggle = function(slave, handler) {
	function favLink() {
		const linkID = `fav-link-${slave.ID}`;
		if (V.favorites.includes(slave.ID)) {
			const link = App.UI.DOM.link(String.fromCharCode(0xe800), () => {
				V.favorites.delete(slave.ID);
				$(`#${linkID}`).replaceWith(favLink());

				if (handler) {
					handler();
				}
			});
			link.classList.add("icons", "favorite");
			link.id = linkID;
			return link;
		} else {
			const link = App.UI.DOM.link(String.fromCharCode(0xe801), () => {
				V.favorites.push(slave.ID);
				$(`#${linkID}`).replaceWith(favLink());

				if (handler) {
					handler();
				}
			});
			link.classList.add("icons", "not-favorite");
			link.id = linkID;
			return link;
		}
	}

	return favLink();
};

repo_name: Elohiem/fc

license: mit


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

	App.UI.DOM.appendNewElement("h2", node, "Warning");

	App.UI.DOM.appendNewElement("p", node, `This is a text-based game that includes descriptions of sexual activity, graphic violence, drug use, and other subjects not suitable for persons under the age of 18. This is a work of fiction; any resemblance to actual persons, places, or events is unintended.`, "yellow");

	App.UI.DOM.appendNewElement("h2", node, "Welcome!");

	App.UI.DOM.appendNewElement("p", node, `An in-game encyclopedia is available from the sidebar, with answers to most basic gameplay questions.`);
	App.Events.addParagraph(node, [
		App.UI.DOM.makeElement("span", `Important info for new players, and a reminder for FC veterans:`, "bold"),
		`when the player is offered a set of choices, the`,
		App.UI.DOM.makeElement("span", `Continue`, "bold"),
		`button at the top of the left sidebar will almost always remain available. Using this to decline all the options presented is not cheating. If it's available, it's supposed to be available. It represents the player character politely bowing out of the situation.`
	]);

	App.UI.DOM.appendNewElement("h2", node, "Please note");
	const p = App.UI.DOM.appendNewElement("p", node);
	App.Events.addNode(p, [
		App.UI.DOM.makeElement("span", `This is an alpha.`, "bold"),
		`That means the game is missing content, is full of bugs, is imbalanced, and is generally in an incomplete state. The game will keep a start of turn autosave. If you encounter a bug, we strongly recommend you reload your start of turn autosave immediately. Please submit your feedback and bug reports here. Consider attaching a save file and screenshot of the problem.`,
	], "div");
	App.Events.addNode(p, [`Pregmod is a modification of the original <i>Free Cities</i> ${V.ver} created by FCdev, which can be seen <a href='https://freecitiesblog.blogspot.com/' target='_blank'>here</a>.`], "div");

	App.Events.addNode(p, [`mod version: ${V.pmodVer}, build: ${V.releaseID}${App.Version.commitHash ? `, commit: ${App.Version.commitHash}` : ``}`], "div", "note");
	App.Events.addNode(p, [`4.0.0 is an alpha release. This means the new player content has minimal implementation.`], "div", "bold"); /* remove me with 4.0.0! */

	App.Events.addResponses(node, [
		new App.Events.Result(`More version info`, versionInfo)
	]);

	App.UI.DOM.appendNewElement("p", node, App.UI.DOM.passageLink(
		"I am 18 or more years of age, I understand, and I wish to continue",
		"Economy Intro"
	));

	return node;

	function versionInfo() {
		const frag = new DocumentFragment();
		App.Events.addNode(frag, [
			App.UI.DOM.makeElement("span", "Mod: expanded age ranges and other tweaks 2016-08-30", ["green", "note"]),
			App.UI.DOM.makeElement("span", `+SV`, "darkred"),
		], "div");
		App.UI.DOM.appendNewElement("div", frag, "Mod: extra preg content and other crap", ["green", "note"]);
		App.UI.DOM.appendNewElement("div", frag, "Saves from versions prior to 0.6 are not compatible.", "bold");

		return frag;
	}
};


code:
/**
 * Provide a mechanism to inspect multiple slaves at once (for example, for Household Liquidators and recETS).
 * @param {Array<App.Entity.SlaveState>} slaves
 * @param {boolean} showFamilyTree
 * @param {FC.SlaveMarketName} [market]
 * @returns {DocumentFragment}
 */
App.UI.MultipleInspect = function(slaves, showFamilyTree, market) {
	const tabBar = new App.UI.Tabs.TabBar("MultipleInspect");

	for (const slave of slaves) {
		tabBar.addTab(slave.slaveName, `slave${slave.ID}`, App.Desc.longSlave(slave, {market: market}));
	}

	if (slaves.length > 1 && showFamilyTree) {
		tabBar.addTab("Family Tree", "family-tree-tab", renderFamilyTree(slaves, slaves[0].ID));
	}

	return tabBar.render();
};


code:
App.UI.descriptionOptions = function() {
	const f = document.createDocumentFragment();
	App.UI.DOM.appendNewElement("h1", f, "Description Options");

	App.UI.DOM.appendNewElement("p", f,
		"These options will affect both the long form description of each slave and the miniscenes available from the main menu.",
		"scene-intro");

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

	options.addOption("", "surnameOrder")
		.addValue("Allow nationality name order", 0).customDescription("Order names ''based on country of origin''.")
		.addValue("Force name surname", 1).customDescription("Names will always be ''Name Surname''.")
		.addValue("Force surname name", 2).customDescription("Names will always be ''Surname Name''.");

	options.addOption("", "seeRace")
		.addValue("Disable most mentions of race", 0).off()
		.customDescription("Ethnicity will ''almost never'' be mentioned.")
		.addValue("Enable mentions of race", 1).on().customDescription("Ethnicity will ''occasionally'' be mentioned.");

	options.addOption("", "seeNationality")
		.addValue("Disable most mentions of nationality", 0).off()
		.customDescription("Nationality will ''almost never'' be mentioned.")
		.addValue("Enable mentions of nationality", 1).on()
		.customDescription("Nationality will ''occasionally'' be mentioned.");

	options.addOption("The effects of implants are", "showImplantEffects")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Clothing is mostly", "showClothing")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Detailed slave age information is", "showAgeDetail")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Approximate height is", "showHeightCMs")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Cosmetic body mods are", "showBodyMods")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Sexual histories are", "showSexualHistory")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Attractiveness and Sexual scores are", "showScores")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Volume, in CCs, of breasts is", "showBoobCCs")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Height and length units are in", "showInches")
		.addValueList([["Metric", 0], ["Both", 1], ["Imperial", 2]]);

	if (V.seeDicks > 0) {
		options.addOption("Approximate sizes of dicks and balls are", "showDickCMs")
			.addValue("Shown", 1).on().addValue("Hidden", 0).off();
	}

	options.addOption("Numbers are displayed as", "showNumbers")
		.addValueList([["Integers", 2], ["Both", 1], ["Words", 0]]);

	if (V.showNumbers === 1) {
		options.addOption(`Only numbers up to ${V.showNumbersMax} are displayed as words`, "showNumbersMax")
			.addValue("Default (20)", 20).showTextBox();
	}

	App.UI.DOM.appendNewElement("p", f, options.render());

	return f;
};


code:
App.UI.optionsPassage = function() {
	const el = new DocumentFragment();
	V.passageSwitchHandler = App.EventHandlers.optionsChanged;
	el.append(intro());

	// Results
	const results = document.createElement("div");
	results.id = "results";
	el.append(results);

	try {
		const tabBar = new App.UI.Tabs.TabBar("Options");
		tabBar.addTab("Display", "display", App.Intro.display(false));
		tabBar.addTab("Content & flavour", "content-flavor", App.Intro.contentAndFlavor(false));
		tabBar.addTab("Mods", "mods", mods());
		tabBar.addTab("Debug & cheating", "debug-cheating", debugCheating());
		if (V.cheatMode) {
			tabBar.addTab("Cheats", "cheat", cheat());
			tabBar.addTab("Cheat edit schools", "cheat-school", cheatSchools());
		}
		tabBar.addTab("Experimental", "experimental", experimental());
		el.append(tabBar.render());
	} catch (e) {
		App.UI.DOM.appendNewElement("p", el,
			"Options cannot be displayed. Try running Backwards Compatibility and see if the problem persists.",
			["bold", "error"]);
		el.append(App.UI.DOM.formatException(e));
	}
	return el;

	function intro() {
		let links;
		let options;
		let r;
		const el = new DocumentFragment();

		options = new App.UI.OptionsGroup();
		options.addOption("End of week autosaving is currently", "autosave")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
		el.append(options.render());

		const table = App.UI.DOM.appendNewElement("table", el);
		let row;
		fillRow([
			`You are currently playing:`,
			`FC version: ${App.Version.base},`,
			`mod version: ${App.Version.pmod},`,
			`build: ${App.Version.release}${App.Version.commitHash ? `, commit: ${App.Version.commitHash}` : ``}`
		]);
		fillRow([
			`This save was created using:`,
			App.UI.DOM.makeElement("span", `FC version: ${V.ver},`, (V.ver !== App.Version.base)? "yellow": null),
			``,
			App.UI.DOM.makeElement("span", `build: ${V.releaseID}.`, (V.releaseID !== App.Version.release) ? "red" : null)
		]);

		function fillRow(contents) {
			row = App.UI.DOM.appendNewElement("tr", table);
			for (const content of contents) {
				App.UI.DOM.appendNewElement("td", row, content);
			}
		}

		links = [];
		links.push(App.UI.DOM.passageLink("Apply Backwards Compatibility Update", "Backwards Compatibility"));

		links.push(
			App.UI.DOM.link(
				`Reset extended family mode controllers`,
				() => {
					resetFamilyCounters();
					const span = document.createElement("span");
					span.classList.add("note");
					App.UI.DOM.appendNewElement("span", span, "Done: ", "lightgreen");
					span.append("all family relations flushed and rebuilt.");
					jQuery("#results").empty().append(span);
				},
				[],
				"",
				"Clears and rebuilds .sister and .daughter tracking."
			)
		);

		if (isNaN(V.rep)) {
			links.push(
				App.UI.DOM.link(
					`Reset Reputation (${V.rep})`,
					() => {
						V.rep = 0;
						jQuery("#results").empty().append(`Reputation reset to ${V.rep}`);
					},
					[],
					"Options"
				)
			);
		}

		if (isNaN(V.rep)) {
			links.push(
				App.UI.DOM.link(
					`Reset Money (${V.cash})`,
					() => {
						V.cash = 500;
						jQuery("#results").empty().append(`Cash reset to ${V.cash}`);
					},
					[],
					"Options"
				)
			);
		}

		if (V.releaseID === 1057) {
			links.push(
				App.UI.DOM.link(
					`Free male anatomy removal due to accidentally flawed updater`,
					() => {
						V.PC.dick = 0;
						V.PC.balls = 0;
						V.PC.prostate = 0;
						V.PC.scrotum = 0;
						V.PC.ballsImplant = 0;
						jQuery("#results").empty().append(`Cash reset to ${V.cash}`);
					},
					[],
					"Options",
					"Use this if your female PC picked up a few extra parts during the conversion process.",
				)
			);
		}

		App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(links));

		if ((V.releaseID >= 1000) || V.ver.startsWith("0.9") || V.ver.startsWith("0.8") || V.ver.startsWith("0.7") || V.ver.startsWith("0.6")) {
			App.UI.DOM.appendNewElement("h3", el, `NEW GAME PLUS`);
			App.UI.DOM.appendNewElement("div", el, `You can begin a new game with up to five (or more) of your current slaves, although starting resources other than these slaves will be reduced.`);
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.link(
				"Activate New Game Plus.",
				() => {
					V.ui = "start";
				},
				[],
				"New Game Plus"
			));
		} else {
			App.UI.DOM.appendNewElement("div", el, `New Game Plus is not available because this game was not started with a compatible version.`, "note");
		}
		return el;
	}

	function mods() {
		const el = new DocumentFragment();
		let options;
		let option;

		options = new App.UI.OptionsGroup();

		options.addOption("The Special Force Mod is currently", "Toggle", V.SF)
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
			.addComment("
This mod is triggered after week 72. It is non-canon where it conflicts with canonical updates to the base game.
");

		options.addOption("The Security Expansion mod is", "secExpEnabled")
			.addValue("Enabled", 1).on().addCallback(() => App.SecExp.generalBC())
			.addValue("Disabled", 0).off()
			.addComment("
The mod can be activated in any moment, but it may result in unbalanced gameplay if activated very late in the game.
");

		option = options.addOption("Catmod is currently", "seeCats")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
		if (V.seeCats) {
			option.addComment(`Disabling Catmod will not murder existing catgirls, you have to do that yourself. <span style="font-style:normal">😿</span>`);
		}

		el.append(options.render());

		if (V.secExpEnabled > 0) {
			App.UI.DOM.appendNewElement("h2", el, `Security Expansion mod options`);
			options = new App.UI.OptionsGroup();

			if (V.SecExp.settings.battle.enabled > 0 || V.SecExp.settings.rebellion.enabled > 0) {
				options.addOption("Detailed battle statistics are", "showStats", V.SecExp.settings)
					.addValue("Shown", 1).on().addValue("Hidden", 0).off()
					.addComment("Visibility of detailed statistics and battle turns.");

				options.addOption("Difficulty is", "difficulty", V.SecExp.settings)
					.addValueList([["Extremely hard", 2], ["Very hard", 1.5], ["Hard", 1.25], ["Normal", 1], ["Easy", 0.75], ["Very easy", 0.5]]);

				options.addOption("Unit descriptions are", "unitDescriptions", V.SecExp.settings)
					.addValue("Abbreviated", 1).addValue("Summarized", 0);
			}

			options.addOption("Battles are", "enabled", V.SecExp.settings.battle)
				.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

			options.addOption("Rebellions are", "enabled", V.SecExp.settings.rebellion)
				.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

			if (V.SecExp.settings.battle.enabled > 0) {
				options.addOption("Battle frequency", "frequency", V.SecExp.settings.battle)
					.addValueList([["Extremely high", 2], ["Very high", 1.5], ["High", 1.25], ["Normal", 1], ["Low", 0.75], ["Very low", 0.5]]);
			}

			if (V.SecExp.settings.rebellion.enabled > 0) {
				options.addOption("Rebellion buildup", "speed", V.SecExp.settings.rebellion)
					.addValueList([["Extremely fast", 2], ["Very fast", 1.5], ["Fast", 1.25], ["Normal", 1], ["Slow", 0.75], ["Very slow", 0.5]]);
			}

			if (V.SecExp.settings.battle.enabled > 0) {
				options.addOption("Commanders gain a prestige rank every 10 victories", "allowSlavePrestige", V.SecExp.settings.battle)
					.addValue("Yes", 1).on().addValue("No", 0).off();
			}

			if (V.SecExp.settings.battle.enabled > 0) {
				options.addOption("Force battles", "force", V.SecExp.settings.battle)
					.addValue("Yes", 1).on().addValue("No", 0).off();
			}
			if (V.SecExp.settings.rebellion.enabled > 0) {
				options.addOption("Force rebellions", "force", V.SecExp.settings.rebellion)
					.addValue("Yes", 1).on().addValue("No", 0).off()
					.addComment("Rebellions take precedence over Battles.");
			}

			if (V.SecExp.settings.battle.enabled > 0) {
				options.addOption("Late game major battles are", "enabled", V.SecExp.settings.battle.major)
					.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
					.addComment("More likely after week 120");
			}

			if (V.SecExp.settings.battle.enabled > 0 && V.SecExp.settings.battle.major.enabled > 0) {
				options.addOption("Multiplier is", "mult", V.SecExp.settings.battle.major)
					.addValueList([["Extremely high", 2], ["Very high", 1.5], ["High", 1.25], ["Normal", 1], ["Low", 0.75], ["Very low", 0.5]]);

				options.addOption("This week a major battle is", "force", V.SecExp.settings.battle.major)
					.addValue("Guaranteed", 1).on().addValue("Not guaranteed", 0).off();
			}

			if (V.SecExp.settings.battle.enabled > 0 && V.SecExp.settings.battle.major.enabled > 0) {
				options.addOption("Gameover on battle loss", "gameOver", V.SecExp.settings.battle.major)
					.addValue("Yes", 1).on().addValue("No", 0).off();
			}

			if (V.SecExp.settings.rebellion.enabled > 0) {
				options.addOption("Gameover on rebellion loss", "gameOver", V.SecExp.settings.rebellion)
					.addValue("Yes", 1).on().addValue("No", 0).off();
			}

			el.append(options.render());

			const subHeading = document.createElement("div");
			subHeading.classList.add("subHeading");

			if (V.debugMode || V.cheatMode || V.cheatModeM) { // TODO: make me a fucking function
				App.UI.DOM.appendNewElement("div", subHeading, "Debug/cheat", "bold");
				let td;
				let links;
				const table = document.createElement("table");
				table.classList.add("invisible");
				el.append(table);

				let tr = document.createElement("tr");
				tr.style.textAlign = "center";

				td = createTd();
				links = [];
				links.push(
					App.UI.DOM.link(
						"Set loyalty high",
						() => {
							changeLoyalty("high");
						},
						[],
						"Options"
					)
				);
				links.push(
					App.UI.DOM.link(
						"Set loyalty average",
						() => {
							changeLoyalty("average");
						},
						[],
						"Options"
					)
				);
				links.push(
					App.UI.DOM.link(
						"Set loyalty low",
						() => {
							changeLoyalty("low");
						},
						[],
						"Options"
					)
				);
				links.push(
					App.UI.DOM.link(
						"Randomize loyalty",
						() => {
							changeLoyalty("random");
						},
						[],
						"Options"
					)
				);

				td.append(App.UI.DOM.generateLinksStrip(links));
				tr.append(td);
				table.append(tr);

				tr = document.createElement("tr");
				tr.style.textAlign = "center";
				td = createTd();
				links = [];
				links.push(App.UI.DOM.link(
					"Give Authority",
					() => {
						V.SecExp.core.authority = Math.clamp(V.SecExp.core.authority + 1000, 0, 20000);
					},
					[],
					"Options"
				));
				links.push(App.UI.DOM.link(
					"Remove Authority",
					() => {
						V.SecExp.core.authority = Math.clamp(V.SecExp.core.authority - 1000, 0, 20000);
					},
					[],
					"Options"
				));
				td.append(App.UI.DOM.generateLinksStrip(links));
				tr.append(td);
				table.append(tr);

				tr = document.createElement("tr");
				td = document.createElement("td");
				td.style.textAlign = "right";
				links = [];
				links.push(App.UI.DOM.link(
					"Raise security",
					() => {
						V.SecExp.core.security = Math.clamp(V.SecExp.core.security + 5, 0, 100);
					},
					[],
					"Options"
				));
				links.push(App.UI.DOM.link(
					"Lower security",
					() => {
						V.SecExp.core.security = Math.clamp(V.SecExp.core.security - 5, 0, 100);
					},
					[],
					"Options"
				));
				tr.append(App.UI.DOM.generateLinksStrip(links));
				tr.append(td);

				td = document.createElement("td");
				td.style.textAlign = "left";
				links = [];
				links.push(App.UI.DOM.link(
					"Raise crime",
					() => {
						V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow + 5, 0, 100);
					},
					[],
					"Options"
				));
				links.push(App.UI.DOM.link(
					"Lower crime",
					() => {
						V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow - 5, 0, 100);
					},
					[],
					"Options"
				));
				tr.append(App.UI.DOM.generateLinksStrip(links));
				tr.append(td);
				table.append(tr);

				tr = document.createElement("tr");
				td = document.createElement("td");
				td.style.textAlign = "right";
				links = [];
				links.push(App.UI.DOM.link(
					"Give militia manpower",
					() => {
						V.SecExp.units.militia.free += 30;
					},
					[],
					"Options"
				));
				links.push(App.UI.DOM.link(
					"Remove militia manpower",
					() => {
						V.SecExp.units.militia.free = Math.max(V.SecExp.units.militia.free - 30, 0);
					},
					[],
					"Options"
				));
				tr.append(App.UI.DOM.generateLinksStrip(links));
				tr.append(td);

				td = document.createElement("td");
				td.style.textAlign = "left";
				links = [];
				links.push(App.UI.DOM.link(
					"Give mercs manpower",
					() => {
						V.SecExp.units.mercs.free += 30;
					},
					[],
					"Options"
				));
				links.push(App.UI.DOM.link(
					"Remove mercs manpower",
					() => {
						V.SecExp.units.mercs.free = Math.max(V.SecExp.units.mercs.free - 30, 0);
					},
					[],
					"Options"
				));
				tr.append(App.UI.DOM.generateLinksStrip(links));
				tr.append(td);
				table.append(tr);
				subHeading.append(table);
				el.append(subHeading);
			}	/* closes cheatmode check */
		} /* closes SecExp check*/
		return el;

		function createTd() {
			const td = document.createElement("td");
			td.style.columnSpan = "2";
			return td;
		}

		/**
		 *
		 * @param {"high"|"average"|"low"|"random"} level
		 */
		function changeLoyalty(level) {
			const numberMap = new Map([
				["high", [80, 100]],
				["average", [40, 60]],
				["low", [20]],
				["random", [100]],
			]);

			App.SecExp.unit.squads("human").forEach(u => u.loyalty = numberGenerator());
			function numberGenerator() {
				const range = numberMap.get(level);
				if (range[1]) {
					return random(range[0], range[1]);
				} else {
					return random(range[0]);
				}
			}
		}
	}

	function cheat() {
		const el = new DocumentFragment();
		const options = new App.UI.OptionsGroup();
		options.addOption("Arcology sex slaves", "NPCSlaves").showTextBox();
		options.addOption("Arcology prosperity cap", "AProsperityCap").showTextBox();
		options.addOption("Shelter Abuse Counter", "shelterAbuse").showTextBox();
		el.append(options.render());

		el.append(App.Intro.economy(false));
		return el;
	}

	function cheatSchools() {
		const el = new DocumentFragment();
		const options = new App.UI.OptionsGroup();
		options.addCustom(App.UI.DOM.makeElement("h2", "Schools"));
		for (const [key, obj] of App.Data.misc.schools) {
			if (typeof obj.requirements === "function" && !obj.requirements()) {
				continue;
			}
			options.addCustom(App.UI.DOM.makeElement("h3", obj.title));
			options.addOption("Students Bought", "studentsBought", V[key]).showTextBox();
			options.addOption("Upgrades", "schoolUpgrade", V[key])
				.addValueList([
					["None", 0],
					["Partial", 1],
					["Full", 2],
				]);
			options.addOption("Moved to arcology", "schoolPresent", V[key])
				.addValue("No", 0).off()
				.addValue("Yes", 1).on();
			options.addOption("Prosperity", "schoolProsperity", V[key]).showTextBox();
			options.addOption("Failed", "schoolAnnexed", V[key])
				.addValue("No", 0).off()
				.addValue("Yes", 1).on();
		}
		el.append(options.render());
		return el;
	}

	function debugCheating() {
		const el = new DocumentFragment();
		let options;
		let option;
		let links;
		let r;
		const popCap = menialPopCap();

		App.UI.DOM.appendNewElement("h2", el, `Debug`);

		options = new App.UI.OptionsGroup();

		options.addOption("DebugMode is", "debugMode")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
			.addComment("This will add passages to Display Variables and create Bug Reports to the sidebar.");

		if (V.debugMode > 0) {
			options.addOption("The custom function part of debug mode is", "debugModeCustomFunction")
				.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
			options.addOption("Event selection is", "debugModeEventSelection")
				.addValue("Manual", 1).on().addValue("Automatic", 0).off();
		}

		option = options.addCustomOption("Genetics array");
		if (V.cheatMode === 1) {
			option.addButton("Edit Genetics", () => { }, "Edit Genetics");
		} else {
			option.addComment("Enable cheat mode to edit genetics.");
		}

		options.addCustomOption("Rules Assistant").addButton("Reset Rules", () => { initRules(); }, "Rules Assistant");

		options.addOption("Passage Profiler is", "profiler")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
			.addComment("Outputs performance data at the bottom of every passage.");

		el.append(options.render());

		App.UI.DOM.appendNewElement("h2", el, `Cheating`);

		options = new App.UI.OptionsGroup();

		options.addOption("CheatMode is", "cheatMode")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
			.addComment("This will unlock some options that would usually be restricted by progress.");

		if (V.cheatMode === 0) {
			el.append(options.render());
		} else {
			options.addOption("Sidebar Cheats are currently", "cheatModeM")
				.addValue("Shown", 1).on().addValue("Hidden", 0).off();

			options.addOption("Slave aging", "seeAge")
				.addValue("Enabled", 1).on().addValue("Celebrate birthdays, but don't age.", 2).addValue("Disabled", 0).off();

			el.append(options.render());

			links = [];

			links.push(
				App.UI.DOM.link(
					`Add ${commaNum(100000)} money`,
					() => {
						V.cheater = 1;
						cashX(100000, "cheating");
					},
					[],
					"Options"
				)
			);

			links.push(
				App.UI.DOM.link(
					`Add ${commaNum(10000)} rep`,
					() => {
						V.cheater = 1;
						repX(10000, "cheating");
					},
					[],
					"Options"
				)
			);

			r = [];
			r.push(App.UI.DOM.generateLinksStrip(links));
			r.push(App.UI.DOM.makeElement("span", "Cheating will be flagged in your save", "note"));
			App.Events.addNode(el, r, "div", "scLink2");

			SectorCounts();

			links = [];
			links.push(
				App.UI.DOM.link(
					"Raise prosperity cap",
					() => {
						V.AProsperityCapModified += 10;
					},
					[],
					"Options"
				)
			);

			links.push(
				App.UI.DOM.link(
					"Lower prosperity cap",
					() => {
						V.AProsperityCapModified -= 10;
					},
					[],
					"Options"
				)
			);
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(links), "scLink2");

			links = [];
			links.push(
				App.UI.DOM.link(
					"Raise prosperity",
					() => {
						V.arcologies[0].prosperity = Math.clamp(V.arcologies[0].prosperity + 10, 0, V.AProsperityCap);
					},
					[],
					"Options"
				)
			);

			links.push(
				App.UI.DOM.link(
					"Lower prosperity",
					() => {
						V.arcologies[0].prosperity = Math.clamp(V.arcologies[0].prosperity - 10, 0, V.AProsperityCap);
					},
					[],
					"Options"
				)
			);
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(links), "scLink2");

			links = [];
			links.push(
				App.UI.DOM.link(
					"Give menial slaves",
					() => {
						V.menials = Math.clamp(V.menials + 30, 0, popCap.value);
					},
					[],
					"Options"
				)
			);

			links.push(
				App.UI.DOM.link(
					"Remove menial slaves",
					() => {
						V.menials = Math.clamp(V.menials - 30, 0, popCap.value);
					},
					[],
					"Options"
				)
			);
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(links), "scLink2");

			links = [];

			// Will no longer work as intended due to population changes
			links.push(
				App.UI.DOM.link(
					"Add citizens",
					() => {
						V.lowerClass = Math.max(V.lowerClass + 200, 0);
					},
					[],
					"Options"
				)
			);

			// also no longer properly functional
			links.push(
				App.UI.DOM.link(
					"Remove citizens",
					() => {
						V.lowerClass = Math.max(V.lowerClass - 200, 0);
					},
					[],
					"Options"
				)
			);
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(links), "scLink2");

			links = [];
			// Will work to a limited degree, minimums and maximums for slaves are set through population
			links.push(
				App.UI.DOM.link(
					"Add slaves",
					() => {
						V.NPCSlaves = Math.max(V.NPCSlaves + 200, 0);
					},
					[],
					"Options"
				)
			);

			// Will work to a limited degree
			links.push(
				App.UI.DOM.link(
					"Remove slaves",
					() => {
						V.NPCSlaves = Math.max(V.NPCSlaves - 200, 0);
					},
					[],
					"Options"
				)
			);
			if (V.corp.Announced !== 1) {
				links = [];
				links.push(
					App.UI.DOM.link(
						"Enable Corporation",
						() => {
							V.corp.Announced = 1;
						},
						[],
						"Options"
					)
				);
			}
			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(links), "scLink2");
		}
		return (el);
	}

	function experimental() {
		const el = new DocumentFragment();
		let options;
		let r;

		r = [];
		r.push(`Experimental means just that: experimental. Options below are likely to be in an`);
		r.push(App.UI.DOM.makeElement("span", `even more incomplete or broken state than usual.`, "yellow"));
		r.push(App.UI.DOM.makeElement("span", `THEY MAY NOT WORK AT ALL.`, "red"));
		r.push(`Make sure you back up your save before enabling any of these, and if you are that interested, consider helping to improve them.`);
		App.Events.addNode(el, r, "div", "bold");

		options = new App.UI.OptionsGroup();

		if (V.seePreg !== 0) {
			options.addOption("Nursery is", "nursery", V.experimental)
				.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
				.addComment("This will enable the experimental nursery, which allows players to interact with growing slave children. An alternative to the incubator.");
		}

		options.addOption("Food is", "food", V.experimental)
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
			.addComment("This will enable the experimental food supply and demand system, as well as a new farmyard building and assignments.");

		if (V.seeExtreme === 1 && V.seeBestiality === 1) {
			options.addOption("Animal Ovaries are", "animalOvaries", V.experimental)
				.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
				.addComment("This will allow slaves to be impregnated by animals.");
		}

		if (V.seeExtreme === 1) {
			options.addOption("Dinner party", "dinnerParty", V.experimental)
				.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
				.addComment("This will enable a controversial but very broken event. Warning: Snuff, cannibalism.");
		}

		if (V.debugMode && V.imageChoice === 1) {
			options.addOption("If art for Deepmurk's clothing has not yet been reported, log it in console", "reportMissingClothing", V.experimental)
				.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
		}

		options.addOption("Rules Assistant target growth expressions", "raGrowthExpr", V.experimental)
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
			.addComment("This will allow javascript expressions to be used in the Rules Assistant growth target setters.");

		options.addOption("New event", "tempEventToggle")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

		options.addOption("Sex overhaul", "sexOverhaul", V.experimental)
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
			.addComment("This will enable a new way to interact with slaves. Currently working but missing flavor text.");

		el.append(options.render());
		return el;
	}
};
/**
 *
 * @param {boolean} isIntro
 * @returns {DocumentFragment}
 */
App.Intro.display = function(isIntro) {
	const el = new DocumentFragment();
	let options;
	let r;

	App.UI.DOM.appendNewElement("h2", el, "Reports");

	options = new App.UI.OptionsGroup();

	options.addOption("End week report descriptive details are", "showEWD")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("End week report performance details are", "showEWM")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Master Suite report details such as slave changes are", "verboseDescriptions")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("End week societal effects from slaves are", "compressSocialEffects", V.UI)
		.addValue("Expanded", 0).on().addValue("Compacted", 1).off();

	options.addOption("Accordion on week end defaults to", "useAccordion")
		.addValue("Open", 0).on().addValue("Collapsed", 1).off();

	options.addOption("Economic Tabs on weekly reports are", "useTabs")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Economic detail sheets for facilities are", "showEconomicDetails")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Economic report neighbor details such as trade impacts on culture are", "showNeighborDetails")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Numeric formatting is currently", "formatNumbers")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
		.addComment("This will comma-format numbers in some areas.");

	el.append(options.render());

	App.UI.DOM.appendNewElement("h2", el, "General");

	options = new App.UI.OptionsGroup();

	options.addOption("Main menu leadership controls displayed", "positionMainLinks")
		.addValueList([["Above", 1], ["Above and below", 0], ["Below", -1]]);

	options.addOption("New Model UI", "newModelUI")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Penthouse Facility Display", "verticalizeArcologyLinks")
		.addValueList([["Triple column", 3], ["Double Column", 2], ["Single Column", 1], ["Collapsed", 0]]);

	options.addOption("Main menu arcology description", "seeArcology")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Main menu desk description", "seeDesk")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Main menu newsfeed", "seeFCNN")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Tips from the Encyclopedia are", "showTipsFromEncy")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Help tooltips are", "tooltipsEnabled")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
		.addComment(`This is mostly for new players. <span class='exampleTooltip noteworthy'>Colored text</span> can have tooltips.`)
		.addCallbackToEach(App.UI.GlobalTooltips.update);

	options.addOption("Main menu slave tabs are", "useSlaveSummaryTabs")
		.addValue("Enabled", 1).on().addValue("CardStyle", 2).on().addValue("Disabled", 0).off();

	options.addOption("The slave Quick list in-page scroll-to is", "useSlaveListInPageJSNavigation")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Condense special slaves into their own tab", "useSlaveSummaryOverviewTab")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Interactions with your fucktoys are", "fucktoyInteractionsPosition")
		.addValueList([["next to them", 1], ["at page bottom", 0]]);

	options.addOption("Hide tabs in Slave Interact", "slaveInteractLongForm")
		.addValue("Enabled", true).on().addValue("Disabled", false).off();

	options.addOption("Line separations are", "lineSeparations")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Warning on end week saving", "endweekSaveWarning")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	el.append(options.render());

	r = [];
	r.push(`UI theme selector. Allows to select a single CSS file to be loaded.`);
	r.push(App.UI.DOM.makeElement("span", `The file has to be located in the same directory as the HTML file otherwise it will simply not load at all.`, "red"));
	r.push(App.UI.Theme.selector());
	App.Events.addParagraph(el, r);

	App.UI.DOM.appendNewElement("h2", el, "Sidebar");

	options = new App.UI.OptionsGroup();

	options.addOption("Cash is", "Cash", V.sideBarOptions)
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Upkeep is", "Upkeep", V.sideBarOptions)
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Sex slave count is", "SexSlaveCount", V.sideBarOptions)
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Room population is", "roomPop", V.sideBarOptions)
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("GSP is", "GSP", V.sideBarOptions)
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Rep is", "Rep", V.sideBarOptions)
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Confirmation before ending a week is", "confirmWeekEnd", V.sideBarOptions)
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
		.addComment("Enabling this will open a dialog box to confirm you meant to end a week.");

	if (V.secExpEnabled > 0) {
		options.addOption("Authority is", "Authority", V.sideBarOptions)
			.addValue("Shown", 1).on().addValue("Hidden", 0).off();

		options.addOption("Security is", "Security", V.sideBarOptions)
			.addValue("Shown", 1).on().addValue("Hidden", 0).off();

		options.addOption("Crime is", "Crime", V.sideBarOptions)
			.addValue("Shown", 1).on().addValue("Hidden", 0).off();
	}

	el.append(options.render());

	App.UI.DOM.appendNewElement("h2", el, "Images");
	el.append(App.UI.artOptions());

	return el;
};

/**
 *
 * @param {boolean} isIntro
 * @returns {DocumentFragment}
 */
App.Intro.contentAndFlavor = function(isIntro) {
	const el = new DocumentFragment();
	let r;
	let options;
	let option;

	App.UI.DOM.appendNewElement("h2", el, "Content");

	const descOptions = App.UI.DOM.makeElement("div");
	r = [];
	r.push("More granular control of what appears is in");
	r.push(App.UI.DOM.link("Description Options", ()=> {
		jQuery(descOptions).empty().append(App.UI.descriptionOptions());
	}));

	App.Events.addNode(descOptions, r, "div");
	el.append(descOptions);

	options = new App.UI.OptionsGroup();

	options.addOption("The difficulty setting is currently set to", "baseDifficulty")
		.addValueList([["Very easy", 1], ["Easy", 2], ["Default", 3], ["Hard", 4], ["Very hard", 5]]);

	options.addOption("Slaves falling ill is currently", "seeIllness")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
		.addComment("Will not affect existing ill slaves already in-game.");

	options.addOption("Extreme content like amputation is currently", "seeExtreme")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
		.addComment("Will not affect extreme surgeries already applied in-game.");

	options.addOption("Bestiality related content is currently", "seeBestiality")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Watersports related content is currently", "seePee")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Incest content is currently", "seeIncest")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Pregnancy related content is currently", "seePreg")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
		.addComment("Will not affect existing pregnancies already in-game.");

	options.addOption("Proportion of slave girls with dicks", "seeDicks")
		.addValueList([
			["None (0%)", 0],
			["Nearly none (1%)", 1],
			["A few (10%)", 10],
			["Some (25%)", 25],
			["Half (50%)", 50],
			["Lots (75%)", 75],
			["Most (90%)", 90],
			["Almost all (99%)", 99],
			["All (100%)", 100]
		]);
	if (V.seeDicks !== 0 || V.makeDicks !== 0) {
		options.addOption("Circumcision is", "seeCircumcision")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
	}

	if (V.seeDicksAffectsPregnancy === 0 || isIntro) {
		options.addOption("XX slaves only father daughters", "adamPrinciple")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
			.addComment("Will not affect existing pregnancies already in-game.");
	}

	options.addOption("Extreme pregnancy content like broodmothers is currently", "seeHyperPreg")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
		.addComment("Will not affect existing hyperpregnancies already in-game.");

	options.addOption("Pregnancy complications due to multiples and body size are currently", "dangerousPregnancy")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	option = options.addOption(`Precocious puberty (pregnancy younger than ${V.fertilityAge})`, "precociousPuberty")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
	if (isIntro) {
		option.addComment(`Under certain conditions slaves can become pregnant or impregnate others younger than normal age (${V.fertilityAge}); they may also experience delayed puberty.`);
	} else {
		option.addComment("Will not affect existing precocious puberty cases already in-game.");
	}

	options.addOption("Slaves with fat lips or heavy oral piercings may lisp", "disableLisping")
		.addValue("Yes", 0).on().addValue("No", 1).off();

	options.addOption("(Temp option) The long-term damage mechanic is currently", "disableLongDamage")
		.addValue("Enabled", 0).on().addValue("Disabled", 1).off();

	options.addOption("Experimental male pronouns are currently", "diversePronouns")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
		.addComment("Apply Backwards Compatibility after changing to update slave's pronouns. Not all scenes support male pronouns and this is not yet incorporated into the lore or mechanics.");

	options.addOption("Male slave names are currently", "allowMaleSlaveNames")
		.addValue("Enabled", true).on().addValue("Disabled", false).off()
		.addComment("This only affects slave generation and not your ability to name your slaves.");

	options.addOption("Missing slave names are currently", "showMissingSlaves")
		.addValue("Enabled", true).on().addValue("Disabled", false).off();

	el.append(options.render());

	App.UI.DOM.appendNewElement("h2", el, `Intersecting mechanics`);

	options = new App.UI.OptionsGroup();

	options.addOption("Slave assets affected by weight is", "weightAffectsAssets")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
		.addComment("Diet will still affect asset size.");

	options.addOption("Chem damage from drugs is", "curativeSideEffects") // Yes, this variable controls all chem damage. The vestigial "curatives" name isn't worth changing.
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
		.addComment("If enabled, many drugs will cause harmful, though curable, carcinogen buildup and genomic damage over time.");

	el.append(options.render());

	App.UI.DOM.appendNewElement("h2", el, `Flavour`);

	options = new App.UI.OptionsGroup();

	options.addOption("Slave reactions to facility assignments are", "showAssignToScenes")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Post sex clean up", "postSexCleanUp")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Appraisal miniscenes on slave sale are", "showAppraisal")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Assignment performance vignettes on the end week report are", "showVignettes")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Slaves can have alternate titles", "newDescriptions")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Family titles for relatives", "allowFamilyTitles")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	options.addOption("Limit family growth", "limitFamilies")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
		.addComment("Restricts acquisition of additional relatives, by means other than birth, for slaves with families.");

	options.addOption("Distant relatives such as aunts, nieces and cousins are", "showDistantRelatives")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	el.append(options.render());
	return el;
};

App.UI.artOptions = function() {
	const el = new DocumentFragment();
	let options = new App.UI.OptionsGroup();

	const art = App.UI.DOM.appendNewElement("div", el, App.Art.SlaveArtElement(BaseSlave(), 2, 0), ["imageRef", "medImg"]);
	art.style.float = "none";
	art.style.display = "block";
	art.style.marginLeft = "auto";
	art.style.marginRight = "auto";

	options.addOption("Images are", "seeImages")
		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

	/* REMOVE THIS WARNING ONCE ART DEVELOPMENT RESUMES */
	options.addComment('All image packs are currently out of date; some outfits will not be displayed.');

	if (V.seeImages > 0) {
		options.addOption("Image style is", "imageChoice")
			.addValueList([["Revamped embedded vector art", 3], ["Non-embedded vector art", 2], ["NoX/Deepmurk's vector art", 1], ["Shokushu's rendered image pack", 0], ["Elohiem's interactive WebGL", 4]]);

		if (V.imageChoice === 1) {
			options.addOption("Face artwork is", "seeFaces")
				.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

			options.addOption("Highlights on shiny clothing are", "seeVectorArtHighlights")
				.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

			options.addOption("Height scaling", "seeHeight")
				.addValue("All images", 2).on().addValue("Small images", 1).addValue("Disabled", 0).off();

			options.addOption("Clothing erection bulges are", "showClothingErection")
				.addValue("Enabled", true).on().addValue("Disabled", false).off();
		} else if (V.imageChoice === 0) {
			options.addComment("You need to" +
				" download the image" +
				" pack and put the 'renders' folder into the resources/ folder where this html file is.");

			options.addOption("Slave summary fetish images are", "seeMainFetishes")
				.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
		} else if (V.imageChoice === 3) {
			options.addOption("Clothing erection bulges are", "showClothingErection")
				.addValue("Enabled", true).on().addValue("Disabled", false).off();
		} else if (V.imageChoice === 4) {
			options.addComment(` Download the WebGL art assets and place the 'webgl' folder into the resources/ folder where this HTML file is.
			Then refresh the page.
			Create the resources folder if it does not exist. (Android/MacOS not supported)`);

			let option = options.addOption("Supersampling (SSAA)", "setSuperSampling");
			for (const value of [0.25, 0.5, 1, 2, 4]) {
				option.addValue(`${value}`, value);
			}
			option.addComment("Refresh the page to take affect.");

			option = options.addOption("Texture resolution", "setTextureResolution");
			for (const value of [512, 1024, 2048, 4096]) {
				option.addValue(`${value}`, value);
			}
			option.addComment("This effectively multiplies the resolution of the render before downsampling again. Use a smaller factor for low-end GPU's.");

			options.addOption("Zoom speed", "setZoomSpeed")
				.addValue("0.25", 0.25).off().addValue("0.5", 0.5).off().addValue("1", 1).on().addValue("2", 2).off().addValue("4", 4).off();
			options.addOption("Face culling", "setFaceCulling")
				.addValue("Enabled", true).off().addValue("Disabled", false).on()
				.addComment("Wether to draw the backside of the model, affects transparent surfaces such as hair. Enabling is recommended for low-end GPU's.");
			options.addOption("Texture resolution", "setTextureResolution")
				.addValue("1024", 1024).on().addValue("2048", 2048).off().addValue("4096", 4096).off()
				.addComment("Refresh the page to take affect.");
		}

		options.addOption("PA avatar art is", "seeAvatar")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

		options.addOption("Slave images in lists are", "seeSummaryImages")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();

		options.addOption("Slave images in the weekly report are", "seeReportImages")
			.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
	}
	el.append(options.render());
	return el;
};


code:
App.UI.OptionsGroup = (function() {
	class Row {
		/**
		 * @param {HTMLDivElement} container
		 * @param {function():void} refresh
		 */
		render(container, refresh) {} // jshint ignore:line
	}

	/**
	 * @typedef value
	 * @property {*} value
	 * @property {string} [name]
	 * @property {string} mode
	 * @property {number} [compareValue]
	 * @property {string} [descAppend] can be SC markup
	 * @property {boolean} [on]
	 * @property {boolean} [off]
	 * @property {boolean} [neutral]
	 * @property {Function} [callback]
	 */

	class OptionButtonRow extends Row {
		/**
		 * @param {string|HTMLElement} description string can be HTML markup
		 * @param {string} property
		 * @param {object} [object=V]
		 */
		constructor(description, property, object = V) {
			super();
			this.description = description;
			this.property = property;
			this.object = object;
			/**
			 * @type {Array<value>}
			 */
			this.valuePairs = [];
		}

		/**
		 * @template {any} T
		 * @param {string} name
		 * @param {T|string} [value=name]
		 * @param {function(T|string):void} [callback]
		 * @returns {OptionButtonRow}
		 */
		addValue(name, value = name, callback = undefined) {
			this.valuePairs.push({
				name: name, value: value, mode: "=", callback: callback
			});
			return this;
		}

		/**
		 * @param {Array<*|Array>} values
		 * @returns {OptionButtonRow}
		 */
		addValueList(values) {
			for (const value of values) {
				if (Array.isArray(value)) {
					this.addValue(value[0], value[1], value[2]);
				} else {
					this.addValue(value);
				}
			}
			return this;
		}

		/**
		 * @param {Map} values
		 * @returns {OptionButtonRow}
		 */
		addValueMap(values) {
			for (const [key, value] of values) {
				this.addValue(key, value);
			}
			return this;
		}

		/**
		 * @param {*} value
		 * @param {number} compareValue
		 * @param {string} mode on of: "<", "<=", ">", ">="
		 * @param {string} [name=value]
		 */
		addRange(value, compareValue, mode, name = value) {
			this.valuePairs.push({
				name: name, value: value, mode: mode, compareValue: compareValue
			});
			return this;
		}

		/**
		 * @param {Object} [params]
		 * @param {string} [params.unit]
		 * @param {boolean} [params.large=false]
		 * @param {boolean} [params.forceString=false]
		 * @returns {OptionButtonRow}
		 */
		showTextBox({unit, large = false, forceString = false} = {}) {
			this.textbox = {unit: unit, large: large, forceString: forceString};
			return this;
		}

		/**
		 * @param {string|DocumentFragment|HTMLElement} comment string can be HTML
		 * @returns {OptionButtonRow}
		 */
		addComment(comment) {
			this.comment = comment;
			return this;
		}

		/**
		 * Adds a button that executes the callback when clicked AND reloads the passage
		 *
		 * @param {string} name
		 * @param {function():void} callback
		 * @param {string} passage
		 */
		customButton(name, callback, passage) {
			this.valuePairs.push({
				name: name, value: passage, callback: callback, mode: "custom"
			});
			return this;
		}

		/**
		 * @param {Node} node
		 * @returns {OptionButtonRow}
		 */
		addCustomDOM(node) {
			this.valuePairs.push({
				value: node, mode: "DOM"
			});
			return this;
		}

		/* modify last added option */

		/**
		 * Added to the description if last added value is selected.
		 * example use: addValue(...).customDescription(...).addValue(...).customDescription(...)
		 * @param {string} description can be SC markup
		 */
		customDescription(description) {
			this.valuePairs.last().descAppend = description;
			return this;
		}

		/**
		 * @param {function(any):void} callback gets executed on every button click. Selected value is given as argument.
		 */
		addCallback(callback) {
			this.valuePairs.last().callback = callback;
			return this;
		}

		/**
		 * TODO: Replace with a global callback
		 *
		 * @param {function(any):void} callback gets executed on every button click. Selected value is given as argument.
		 */
		addCallbackToEach(callback) {
			this.valuePairs.forEach(pair => pair.callback = callback);
			return this;
		}

		/**
		 * Mark option as on to style differently.
		 * @returns {OptionButtonRow}
		 */
		on() {
			this.valuePairs.last().on = true;
			return this;
		}

		/**
		 * Mark option as off to style differently.
		 * @returns {OptionButtonRow}
		 */
		off() {
			this.valuePairs.last().off = true;
			return this;
		}

		/**
		 * Puts the options in side a pulldown if there are at least 6.
		 * Not counting text boxes or comments.
		 * @returns {OptionButtonRow}
		 */
		pulldown() {
			this.enablePulldown = true;
			return this;
		}

		/**
		 * @param {HTMLDivElement} container
		 * @param {function():void} refresh
		 */
		render(container, refresh) {
			/* left side */
			const desc = document.createElement("div");
			desc.className = "description";
			$(desc).append(this.description);
			container.append(desc);

			/* right side */
			const currentValue = this.object[this.property];
			if (currentValue === undefined) {
				throw new TypeError(`Current value is undefined for option row "${this.description}"`);
			}
			let anySelected = false;

			const buttonGroup = document.createElement("div");
			buttonGroup.classList.add("button-group");
			if (!this.enablePulldown || this.valuePairs.length < 6) {
				for (const value of this.valuePairs) {
					if (value.mode === "DOM") {
						/* insert DOM and go to next element */
						buttonGroup.append(value.value);
						continue;
					}
					const button = document.createElement("button");
					button.append(value.name);
					if (value.on) {
						button.classList.add("on");
					} else if (value.off) {
						button.classList.add("off");
					}
					if (value.mode === "custom") {
						button.onclick = () => {
							value.callback();
							if (value.value) {
								Engine.play(value.value);
							} else {
								refresh();
							}
						};
					} else {
						if (value.mode === "=" && _.isEqual(currentValue, value.value)) {
							button.classList.add("selected", "disabled");
							anySelected = true;
							if (value.descAppend !== undefined) {
								desc.append(" ");
								$(desc).wiki(value.descAppend);
							}
						} else if (!anySelected && inRange(value.mode, value.compareValue, currentValue)) {
							button.classList.add("selected");
							// disable the button if clicking it won't change the variable value
							if (_.isEqual(currentValue, value.value)) {
								button.classList.add("disabled");
							}
							anySelected = true;
							if (value.descAppend !== undefined) {
								desc.append(" ");
								$(desc).wiki(value.descAppend);
							}
						}
						button.onclick = () => {
							this.object[this.property] = value.value;
							if (value.callback) {
								value.callback(value.value);
							}
							refresh();
						};
					}
					buttonGroup.append(button);
				}
			} else {
				let matchFound = false;
				let select = document.createElement("select");

				for (const value of this.valuePairs) {
					let el = document.createElement("option");
					el.textContent = value.name;
					el.value = value.value;
					if (this.object[this.property] === value.value) {
						el.selected = true;
						matchFound = true;
					}
					select.appendChild(el);
				}
				if (!matchFound) {
					select.selectedIndex = -1;
				}
				select.onchange = () => {
					const O = select.options[select.selectedIndex];
					if (isNaN(Number(O.value))) {
						this.object[this.property] = O.value;
					} else {
						this.object[this.property] = Number(O.value);
					}
					const originalObj = this.valuePairs.find(obj => obj.name === O.textContent);
					if (originalObj && typeof originalObj.callback === "function") {
						originalObj.callback(originalObj.value);
					}
					refresh();
				};
				buttonGroup.append(select);
			}

			if (this.textbox) {
				const onlyNumber = !this.textbox.forceString && typeof currentValue === "number";
				const textbox = App.UI.DOM.makeTextBox(currentValue, input => {
					this.object[this.property] = input;
					refresh();
				}, onlyNumber);
				if (onlyNumber) {
					textbox.classList.add("number");
				}
				if (this.textbox.large) {
					textbox.classList.add("full-width");
				}
				buttonGroup.append(textbox);
				if (this.textbox.unit) {
					buttonGroup.append(" ", this.textbox.unit);
				}
			}

			if (this.comment) {
				const comment = document.createElement("span");
				comment.classList.add("comment");
				$(comment).append(this.comment);
				buttonGroup.append(comment);
			}
			container.append(buttonGroup);

			function inRange(mode, compareValue, value) {
				if (mode === "<") {
					return value < compareValue;
				} else if (mode === "<=") {
					return value <= compareValue;
				} else if (mode === ">") {
					return value > compareValue;
				} else if (mode === ">=") {
					return value >= compareValue;
				}
				return false;
			}
		}
	}

	class CustomButtonRow extends Row {
		/**
		 * @typedef CustomButton
		 * @property {string} name
		 * @property {function():void} callback
		 * @property {string} [passage] if undefined reloads current passage
		 */

		/**
		 * @param {string} description may be HTML markup
		 */
		constructor(description) {
			super();
			/**
			 * @private
			 */
			this._description = description;
			/**
			 * @type {string}
			 * @private
			 */
			this._comment = undefined;
			/**
			 * @type {Array<CustomButton>}
			 * @private
			 */
			this._buttons = [];
		}

		/**
		 * @param {string} name
		 * @param {function():void} callback
		 * @param {string} [passage] if undefined reloads current passage
		 * @returns {CustomButtonRow}
		 */
		addButton(name, callback, passage) {
			this._buttons.push({
				name: name,
				callback: callback,
				passage: passage
			});
			return this;
		}

		/**
		 * @param {string} comment may be HTML markup
		 * @returns {CustomButtonRow}
		 */
		addComment(comment) {
			this._comment = comment;
			return this;
		}

		/**
		 * @param {HTMLDivElement} container
		 * @param {function():void} refresh
		 */
		render(container, refresh) {
			/* left side */
			const desc = document.createElement("div");
			desc.className = "description";
			$(desc).append(this._description);
			container.append(desc);

			/* right side */
			const buttonGroup = document.createElement("div");
			buttonGroup.classList.add("button-group");

			for (const button of this._buttons) {
				const buttonElement = document.createElement("button");
				buttonElement.append(button.name);
				buttonElement.onclick = () => {
					button.callback();
					if (button.passage) {
						Engine.play(button.passage);
					} else {
						refresh();
					}
				};
				buttonGroup.append(buttonElement);
			}

			if (this._comment) {
				const comment = document.createElement("span");
				comment.classList.add("comment");
				$(comment).append(this._comment);
				buttonGroup.append(comment);
			}

			container.append(buttonGroup);
		}
	}

	class Comment extends Row {
		/**
		 * @param {string} comment can be SC markup
		 */
		constructor(comment) {
			super();
			this.comment = comment;
			this.long = false;
		}

		/**
		 * @param {HTMLDivElement} container
		 * @param {function():void} refresh
		 */
		render(container, refresh) {
			/* left */
			container.append(document.createElement("div"));

			/* right */
			const comment = document.createElement("div");
			comment.classList.add("comment");
			$(comment).wiki(this.comment);
			container.append(comment);
		}
	}

	class CustomRow extends Row {
		/**
		 * @param {HTMLElement|string} element
		 */
		constructor(element) {
			super();
			this.element = element;
		}

		/**
		 * @param {HTMLDivElement} container
		 */
		render(container) {
			/** @type {HTMLDivElement} */
			const div = App.UI.DOM.makeElement("div", this.element, "custom-row");
			container.append(div);
		}
	}

	return class OptionsGroup {
		constructor() {
			/**
			 * @type {Array<Row>}
			 */
			this.rows = [];
			this.doubleColumn = false;
			this.refresh = App.UI.reload;
		}

		/**
		 * @returns {OptionsGroup}
		 */
		enableDoubleColumn() {
			this.doubleColumn = true;
			return this;
		}

		/**
		 * Adds a custom function to be executed when changing an option. By default App.UI.reload() is executed.
		 * Can be overwritten by some options, the behaviour is the same as with the default function.
		 *
		 * @param {function():void} refresh
		 * @returns {OptionsGroup}
		 */
		customRefresh(refresh) {
			this.refresh = refresh;
			return this;
		}

		/**
		 * @template {Row} T
		 * @param {T} row
		 * @returns {T}
		 * @private
		 */
		_addRow(row) {
			this.rows.push(row);
			return row;
		}

		/**
		 * @param {string|HTMLElement} name
		 * @param {string} property
		 * @param {object} [object=V]
		 * @returns {OptionButtonRow}
		 */
		addOption(name, property, object = V) {
			const option = new OptionButtonRow(name, property, object);
			return this._addRow(option);
		}

		/**
		 * @param {string} name
		 * @returns {CustomButtonRow}
		 */
		addCustomOption(name) {
			return this._addRow(new CustomButtonRow(name));
		}

		/**
		 * @param {string} comment may contain SC markup
		 * @returns {Comment}
		 */
		addComment(comment) {
			const c = new Comment(comment);
			return this._addRow(c);
		}

		/**
		 * Adds a custom element taking up both rows
		 *
		 * @param {HTMLElement|string} element
		 * @returns {CustomRow}
		 */
		addCustom(element) {
			return this._addRow(new CustomRow(element));
		}

		/**
		 * @returns {HTMLDivElement}
		 */
		render() {
			const container = document.createElement("div");
			container.className = "options-group";
			if (this.doubleColumn) {
				container.classList.add("double");
			}

			for (const row of this.rows) {
				row.render(container, this.refresh);
			}

			return container;
		}
	};
})();


code:
App.UI.summaryOptions = function() {
	const el = new DocumentFragment();
	let options;

	App.UI.DOM.appendNewElement("h1", el, "Summary Options");

	App.UI.DOM.appendNewElement("p", el, `These options will affect the short slave summaries that appear on the main menu and the facility management screens.`, "scene-intro");

	App.UI.DOM.appendNewElement("h2", el, "Main menu features");

	options = new App.UI.OptionsGroup();

	options.addOption("Rules Assistant visibility", "rulesAssistantMain")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Facilities in the sidebar are", "abbreviateSidebar")
		.addValueList([["Summarized", 2], ["Abbreviated", 1]]);

	options.addOption("Sorting main menu options are", "sortSlavesMain")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	if (V.sortSlavesMain > 0) {
		options.addOption("Sorting direction", "sortSlavesOrder")
			.addValueList([["Ascending", "ascending"], ["Descending", "descending"]]);

		options.addOption("Slaves are sorted by", "sortSlavesBy")
			.addValueList([
				["Devotion", "devotion"],
				["Name", "name"],
				["Date purchased", "seniority"],
				["Age", "actualAge"],
				["How old they look", "visualAge"],
				["Age of their body", "physicalAge"],
				["Assignment", "assignment"],
				["Weekly Income", "weeklyIncome"]
			]);
	}

	el.append(options.render());

	App.UI.DOM.appendNewElement("h2", el, "Individual panels");
	App.UI.DOM.appendNewElement("div", el, "Sample summary:");
	el.append(App.UI.SlaveList.render([V.slaves.random().ID], [], App.UI.SlaveList.SlaveInteract.stdInteract));

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

	options.addOption("Panel style is", "slavePanelStyle")
		.addValueList([
			["None", 0],
			["Line Separator", 1],
			["Card", 2]
		]);

	App.UI.SlaveSummary.addOptions(options);

	options.addOption("Granular slave stat numbers are", "summaryStats")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	options.addOption("Main menu assignment shortcuts are", "displayAssignments")
		.addValue("Shown", 1).on().addValue("Hidden", 0).off();

	if (V.showMissingSlaves) {
		options.addOption("Missing slave parents are", "showMissingSlavesSD")
			.addValue("Shown", true).on().addValue("Hidden", false).off();
	}

	options.addCustomOption("FC Dev's preferred options")
		.addButton(
			"Apply",
			() => {
				V.seeDesk = 0;
				V.seeFCNN = 0;
				V.sortSlavesBy = "devotion";
				V.sortSlavesOrder = "descending";
				V.sortSlavesMain = 0;
				V.rulesAssistantMain = 1;
				Object.assign(
					V.UI.slaveSummary.abbreviation,
					{
						devotion: 1,
						mental: 1,
						rules: 1,
						health: 1,
						diet: 1,
						drugs: 1,
						hormoneBalance: 1,
						race: 1,
						genitalia: 1,
						physicals: 1,
						skills: 1,
						nationality: 1,
						rulesets: 1,
						clothes: 0,
						origins: 0
					}
				);
				V.abbreviateSidebar = 1;
			}
		);

	el.append(options.render());

	return el;
};