diff --git a/.eslintrc.json b/.eslintrc.json
index c43caf1d84c8b3f96761dc94b952c936e17edd0d..9dbbf5be39e4ecde617e97743837e526704bbaac 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -25,7 +25,7 @@
 		"postdisplay": true
 	},
 	"parserOptions": {
-		"ecmaVersion": 2019,
+		"ecmaVersion": 2021,
 		"sourceType": "script",
 		"ecmaFeatures": {
 			"impliedStrict": true
diff --git a/.gitignore b/.gitignore
index 3f1f7a8519bc2eb5fd1984c9bd98f7eba8e21f8c..2db28904a7f6875834614b3f000015f2a1659a88 100644
--- a/.gitignore
+++ b/.gitignore
@@ -70,3 +70,6 @@ src/002-config/fc-version.js.commitHash.js
 
 # macOS devices
 *.icloud
+
+# legacy
+devNotes/legacy files/*
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 19bd80bd30a44f93b3f3715fc8cade24e42586a3..a422617ad8b134281fb8e123e2848e01d4868965 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,30 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
 
 ## Unreleased
 
+* Fixes.
+* New Security Expansion features (boost rep gain and both relationship with the peacekeeper General as an alternative to selling slaves).
+* c-section option available during report birth.
+* Updated slave art.
+* Edo or Chinese revivalist slave's name now follow the surname-name order.
+* Can purchase larger slave capacity slots for some facilities.
+* Move Special Force deployment focuses from AfterActionReport to Firebase.
+* Bodyguard's sword can now reflect some Future Societies.
+
+## 0.10.7.1-4.0.0-alpha.14 - 2022-03-25
+
+* added loans
+* age now centered around  an ideal age + policies to manage it
+* fixes
+
+## 0.10.7.1-4.0.0-alpha.13 - 2022-02-12
+
+* first stages of a rudimentary modding API
+* physicalDevelopment now applies to a growing PC
+* dairy converted to DOM
+* personal attention applicable to master suite slaves
+* Cosmetic implant surgeries reworked to be more realistic: implant size that can be fit in is dynamically computed based on asset size, players don't need to begin with the smallest size anymore if a bigger fits. Cosmetic implant surgeries now cost a lot more (beware, autosurgery is also affected!) to compensate for achieving the grow targets quickly. Autosurgery can be tuned to use only specific set of implant types and its note in the end week logs became more detailed and visually detectable.
+* fixes
+
 ## 0.10.7.1-4.0.0-alpha.12 - 2022-01-06
 
 * Sugarcube updated to 2.36.1
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ed7535737478aa4ae640700024e465f521ec75b1..c291d1f7dfbb943d34f09d1ae2983045724291bd 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -141,15 +141,11 @@ const foo = {
 New code should generally get organized into the `App` namespace. See [fc-js-init.js](js/002-config/fc-js-init.js) for a rough outline.
 
 ## JavaScript Features
-
-* Avoid using very new JavaScript features
-  * Generally, we're currently targeting ECMAScript 2018, though we use a few widely-implemented ECMAScript 2019
-    features, like `globalThis`.
-* Conversely, do use modern features, it's not 2010 anymore and we don't try to support Internet Explorer or anything
-  stupid like that.
-  * use `let`/`const` rather than `var`
-  * prefer fat arrow functions to inline long-form functions
-  * etc.
+* Generally, we're currently targeting ECMAScript 2021.
+* It's not 2010 anymore and we don't try to support Internet Explorer or anything stupid like that.
+* use `let`/`const` rather than `var`
+* prefer fat arrow functions to inline long-form functions
+* etc.
 
 ## Code quality
 
@@ -214,3 +210,4 @@ errors, it's not totally clean as is and there are a few false positives.
 * [Classes in Game State](https://gitgud.io/pregmodfan/fc-pregmod/-/issues/696)
 * [Self executing functions](https://gitgud.io/pregmodfan/fc-pregmod/-/issues/2325)
 * [Sort a map](https://gitgud.io/pregmodfan/fc-pregmod/-/issues/2642)
+* [How to create a Merge Request (MR)](https://gitgud.io/pregmodfan/fc-pregmod/-/issues/3903)
diff --git a/css/art/art.css b/css/art/art.css
index 823dc50712358a9214b83de33ac234987354ec0a..2d16ae8b0131c95739adf8c2b1dc65ef5b3474f3 100644
--- a/css/art/art.css
+++ b/css/art/art.css
@@ -13,24 +13,24 @@ img {
 }
 
 .imageRef {
+	align-items: flex-start;
+	background-color: rgba(80, 80, 80, 0.5);
 	display: flex;
 	flex-direction: column;
 	flex-wrap: wrap;
-	align-items: flex-start;
 	position: relative;
-	background-color: rgba(80, 80, 80, 0.5);
-	margin: 2px;
 }
 
 .tinyImg {
-	height: 120px;
-	width: 120px;
+	border: 1px solid #333333;
 	float: left;
+	height: 8em;
+	width: 8em;
 }
 
 .smlImg {
-	height: 150px;
-	width: 150px;
+	height: 10em;
+	width: 10em;
 	float: left;
 }
 
@@ -39,8 +39,8 @@ img {
 }
 
 .medImg {
-	height: 300px;
-	width: 300px;
+	height: 16em;
+	width: 16em;
 	float: right;
 }
 
@@ -49,53 +49,37 @@ img {
 }
 
 .lrgRender {
-	height: 531px;
-	width: 506px;
-	margin-right: -50px;
-	margin-left: 0px;
+	border: 2px solid #333333;
 	float: right;
+	margin-left: 1em;
+	margin-top: 1em;
+	width: 33%;
 }
 
 .lrgVector {
-	height: 600px;
-	width: 600px;
-	margin-right: -125px;
-	margin-left: -125px;
+	border: 2px solid #333333;
 	float: right;
-	z-index: -1;
-}
-
-.lrgRender > div.mask {
-	width: 180px;
-	height: 100%;
-	background: linear-gradient(90deg, rgba(17, 17, 17, 1), rgba(17, 17, 17, 0.8) 60%, rgba(17, 17, 17, 0));
-	z-index: 1;
-	/*position: absolute;*/
+	height: 40em;
+	margin-left: 1em;
+	margin-top: 1em;
+	width: 33%;
 }
 
 .lrgRender > img, .lrgRender > video {
-	margin-left: -150px;
-	height: 531px;
+	height: 4em;
 	width: auto;
 }
 
-.lrgVector > div.mask {
-	width: 150px;
-	height: 100%;
-	background: linear-gradient(90deg, rgba(17, 17, 17, 1), rgba(17, 17, 17, 0.8) 60%, rgba(17, 17, 17, 0));
-	z-index: 1;
+.lrgRender > svg {
+	height: 40em;
+	position: relative;
 }
 
 .lrgVector > img, .lrgVector > video {
-	margin-left: -150px;
-	height: 600px;
+	height: 4em;
 	width: auto;
 }
 
-.lrgVector svg {
-	width: 336px;
-}
-
 object {
 	object-fit: scale-down;
 	position: absolute;
diff --git a/css/general/layout.css b/css/general/layout.css
index 7afeedf7bd19bfae455be300b9ac5d8b0f55d42b..ba770051df7155ef4cb68119dad2b134f8fdc6ee 100644
--- a/css/general/layout.css
+++ b/css/general/layout.css
@@ -43,6 +43,12 @@ div.grid-2columns-auto {
 	grid-column-gap: 1em;
 }
 
+div.grid-3columns-auto {
+	display: grid;
+	grid-template-columns: max-content auto auto;
+	grid-column-gap: 1em;
+}
+
 .margin-top {
 	margin-top: 1em;
 }
@@ -73,6 +79,47 @@ div.grid-2columns-auto {
 	margin: 1em;
 }
 
+.padding-left {
+	padding-left: 2em;
+}
+
+.padding-right {
+	padding-right: 2em;
+}
+
+.padding-x {
+	padding-left: 2em;
+	padding-right: 2em;
+}
+
+.padding-y {
+	padding-top: 1em;
+	padding-bottom: 1em;
+}
+
+.padding-full {
+	padding: 1em;
+}
+
+.padded-columns {
+	border-collapse: separate;
+	border-spacing: 1em 0;
+}
+
+.padded-columns td,
+.padded-columns th {
+	padding: 0 1em;
+}
+
+.padded-rows {
+	border-collapse: separate;
+	border-spacing: 0 1em;
+}
+
+.padded-rows td {
+	padding: 1em 0;
+}
+
 .space-evenly {
 	justify-content: space-evenly;
 }
@@ -87,3 +134,8 @@ div.cheat-menu {
 	position: absolute;
 	right: 50px;
 }
+
+input[type="text"].number {
+	min-width: 6em;
+	max-width: 6em;
+}
diff --git a/css/general/textColors.css b/css/general/textColors.css
index d5de893fd713c4e87b219a0c5a97aadfea63085f..7cd98be1785c161dd64e47bcac96c257916b80c8 100644
--- a/css/general/textColors.css
+++ b/css/general/textColors.css
@@ -139,11 +139,6 @@
 	color: orangered
 }
 
-/* used once (wrong? */
-.orchid, .orchid a {
-	color: orchid
-}
-
 /* also fetish start ??? , and a lot of other stuff */
 .pink, .pink a, .slave.name.simple {
 	color: pink
@@ -157,17 +152,6 @@
 	color: red
 }
 
-/* FIXME: not working correctly - displays at top right corner of screen instead of after content in container */
-div > span.warning.notification::after {
-	font-family: "tme-fa-icons";
-	position: absolute;
-	right: 5px;
-	top: 0;
-	content: "\e80c";
-	color: red;
-	font-style: normal;
-}
-
 .seagreen, .seagreen a, .trust.prof-trusting, .trust.prof-trusting a {
 	color: seagreen
 }
diff --git a/css/gui/buttons.css b/css/gui/buttons.css
index 4e4409f3359debd63952a9954d1dca6d1ed5bee7..a58ce9208f85ee279b7096039feca3685409b56b 100644
--- a/css/gui/buttons.css
+++ b/css/gui/buttons.css
@@ -2,7 +2,7 @@
 	background-color: var(--button-color);
 	border: solid 2px var(--button-border-color);
 	font-style: normal;
-	margin-left: 1em;
+	margin: 0.25em 1em;
 	outline: none;
 	transition: 0.2s;
 }
@@ -14,4 +14,5 @@
 
 .purchase-button.disabled, .purchase-button.disabled:hover {
 	background-color: black;
+	cursor: not-allowed;
 }
diff --git a/css/gui/lists.css b/css/gui/lists.css
new file mode 100644
index 0000000000000000000000000000000000000000..aea8edd67f6e6d5686167a295d8f85d10c1bcb8b
--- /dev/null
+++ b/css/gui/lists.css
@@ -0,0 +1,3 @@
+.no-bullet {
+	list-style-type: none;
+}
diff --git a/css/gui/slaveList/cardStyle.css b/css/gui/slaveList/cardStyle.css
index 6a07e857601ecf03fd2e89b13113c39e85d0a260..f560bfb0c5a6dff5e87726ca532b2e13be610abb 100644
--- a/css/gui/slaveList/cardStyle.css
+++ b/css/gui/slaveList/cardStyle.css
@@ -1,4 +1,4 @@
-div.card {
+.card {
 	border: 2px solid #333333;
 	background-color: #1a1a1a;
 	box-shadow: 10px 10px 10px black,
diff --git a/css/interaction/slaveInteract.css b/css/interaction/slaveInteract.css
index 8050ac2aea95201e974c5a3c031d8b788c1e719c..403f30d2892fa168071b423359ded448114626f9 100644
--- a/css/interaction/slaveInteract.css
+++ b/css/interaction/slaveInteract.css
@@ -9,3 +9,11 @@
 .si-header {
 	font-size: 1.5em;
 }
+
+/* notification */
+a.with-note::after /*notification for links with notes in tooltips */
+{
+	font-family: "tme-fa-icons";
+	content: " \e80c";
+	color: yellow;
+}
diff --git a/css/rulesAssistant/conditionEditor.css b/css/rulesAssistant/conditionEditor.css
new file mode 100644
index 0000000000000000000000000000000000000000..a84be73f23a161bb6857d698520f36decc11be97
--- /dev/null
+++ b/css/rulesAssistant/conditionEditor.css
@@ -0,0 +1,154 @@
+@media only screen and (min-width: 1000px) {
+    .rule-builder {
+        display: grid;
+        grid-template-columns: 60% 40%;
+        grid-column-gap: 1em;
+    }
+}
+
+.rule-builder button {
+    color: var(--link-color);
+    background-color: var(--button-color);
+    border: solid 2px var(--button-border-color);
+    border-radius: 4px;
+    margin-left: 4px;
+}
+
+.rule-builder button:hover {
+    background-color: var(--button-hover-color);
+    color: var(--link-hover-color);
+}
+
+.rule-builder textarea {
+    margin-left: 0.2em;
+    min-width: 20em;
+}
+
+.rule-part-browser {
+}
+
+.rule-part {
+    display: inline-block;
+    border-radius: 8px;
+    border: 2px solid #333333;
+    background-color: #1a1a1a;
+    padding: 4px;
+    margin: 4px;
+}
+
+.validation-error::before {
+    font-family: "tme-fa-icons";
+    content: "\e80d";
+    color: red;
+    margin-right: 4px;
+}
+
+.rule-draggable {
+    cursor: grab;
+}
+
+.rule-draggable:hover{
+    background: #2c2c2c;
+}
+
+.rule-drag-element {
+    display: inline-block;
+    background-image: repeating-linear-gradient(0, #1a1a1a, transparent 0.2em, transparent 0.2em, #1a1a1a 0.4em),
+    repeating-linear-gradient(90deg, #1a1a1a, #777 0.2em, #777 0.2em, #1a1a1a 0.4em);
+    width: 1.6em;
+    height: 2em;
+    vertical-align: middle;
+}
+
+.rule-drag-element:hover{
+    background-image: repeating-linear-gradient(0, #2c2c2c, transparent 0.2em, transparent 0.2em, #2c2c2c 0.4em),
+    repeating-linear-gradient(90deg, #2c2c2c, #888 0.2em, #888 0.2em, #2c2c2c 0.4em);
+}
+
+.rule-drop-location {
+    border: #999 dashed 1px;
+    border-radius: 4px;
+    display: inline-block;
+    background-color: #555;
+    width: 5em;
+    height: 1.5em;
+    vertical-align: middle;
+    margin: 0 4px;
+}
+
+.part-dragging .condition-viewer .rule-drop-location {
+    animation: 1.5s ease-in-out infinite rule-drop-location-blink;
+}
+
+@keyframes rule-drop-location-blink {
+    0% {
+        background: #555;
+    }
+    50% {
+        background: #638022;
+    }
+    100% {
+        background: #555;
+    }
+}
+
+.rule-builder input[type="text"] {
+    margin-left: 0.2em;
+}
+
+.rule-right-margin {
+    margin-right: 0.2em;
+}
+
+.rule-left-margin {
+    margin-left: 0.2em;
+}
+
+.rule-custom-controls {
+    display: inline-block;
+    vertical-align: top;
+}
+
+.rule-custom-mode {
+    text-align: center;
+}
+
+.rule-trash {
+    border: #F55 1px;
+    border-radius: 4px;
+    background-color: palevioletred;
+    width: 12em;
+    height: 2em;
+    text-align: center;
+    margin: 4px;
+    color: black;
+}
+
+.rule-trash::before {
+    font-family: "tme-fa-icons";
+    content: "\e828";
+}
+
+/* Encyclopedia help entry */
+
+.rule-help-table {
+    display: grid;
+    grid-template-columns: max-content auto auto;
+}
+
+.rule-help-table .head {
+    font-weight: bold;
+    position: sticky;
+    top: -1em;
+    background-color: #111;
+}
+
+.rule-help-table > div {
+    padding: 0 0.5em
+}
+
+.rule-help-table > :nth-child(6n+4),
+.rule-help-table > :nth-child(6n+5),
+.rule-help-table > :nth-child(6n+6) {
+    background-color: #222;
+}
diff --git a/devNotes/gitSetup.md b/devNotes/gitSetup.md
index 0cceb0942d335e3382aa39f14c8bebfc9bf1d04d..75b62dd46b452fa46ceaf4ecca05890c567419b8 100644
--- a/devNotes/gitSetup.md
+++ b/devNotes/gitSetup.md
@@ -4,6 +4,7 @@
 
 0. [Install Git for terminal](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) or a Git GUI of your
    choice.
+   * If you are on Linux Git is usually preinstalled.
 
 1. Create an account on gitgud if you don't have a usable one.
     * (optional) Add an SSH key to your account for easier pushing. This allows you to connect to gitgud through SHH,
@@ -12,42 +13,56 @@
 2. Fork the main repository through gitgud interface.
    * (optional) Delete all branches other than pregmod-master, so you don't get them locally when fetching.
 
-3. Clone the repo and then change to the new directory
-    * Clicking on the dropdown arrow on the far right blue clone button in the gitgud interface on your fork gives you the relevant URLs.
-    * Via terminal: `git clone --depth 1 --single-branch <url-to-your-fork> && cd fc-pregmod`
+3. Clone the repo
+   * Clicking on the dropdown arrow on the far right blue clone button in the GitGud interface on your fork gives you
+     the relevant URLs. If you added an SSH key in step 2, use the SSH URL, otherwise use the HTTPS one.
+   * Via terminal: `git clone --depth 1 <url-to-your-fork>`
 
-4. Add the main repository as a remote target
-    * Via terminal: `git remote add upstream https://gitgud.io/pregmodfan/fc-pregmod.git`
+4. Change into the new directory
+   * Via terminal: `cd fc-pregmod`
+
+5. Add the main repository as a remote target
+   * Via terminal: `git remote add upstream https://gitgud.io/pregmodfan/fc-pregmod.git`
+
+6. Make your local `pregmod-master` track the main repository, makes getting future updates easier.
+   * Via terminal `git branch --set-upstream-to=upstream`
 
 ## Typical cycle with Git:
 
-0. Switch to the pregmod-master branch, then check for and merge any upstream updates 
- before updating your remote if any updates are present
-    * Via terminal: `git checkout -q pregmod-master && git fetch upstream && git merge upstream/pregmod-master && git push -q`   
+0. Switch to the `pregmod-master` branch, then apply any updates from upstream
+   * Via terminal: `git checkout pregmod-master && git pull upstream`
 
 1. Checkout a new branch for your work
-    * Via terminal: `git checkout -b <branch-name>`
+   * Via terminal: `git checkout -b <branch-name>`
 
 2. Make desired changes
-3. Add them to be committed
-    * Via terminal: `git add *`
-4. Commit
-	* Make the commit message useful (`Fix X`, `Add Y`, etc.)
-    * Via terminal: `git commit -m "MESSAGE"`
+
+3. Add your changes to be committed
+   * Via terminal: `git add *`
+
+4. Commit your changes
+   * Via terminal: `git commit`
+   * Make the commit message useful (`Fix X`, `Add Y`, etc.)
 
 5. (optional, but recommended) Run sanityCheck before final push to catch any errors you missed.
-    * You can ignore errors that already existed
+   * You can ignore errors that already existed
+
 6. Push result into your forked repository
-    * Via terminal:
-        * Initially: `git push -u origin $(git rev-parse --abbrev-ref HEAD)`
-        * Afterwards `git push` will suffice.
+   * Via terminal:
+      * Initially: `git push -u origin $(git rev-parse --abbrev-ref HEAD)`
+      * Afterwards `git push` will suffice.
 
 7. Create merge request through gitgud interface.
- * Suggestion: Tick "Delete source branch when merge request is accepted." 
-  to help automatically tidy up your fork.
+   * Suggestion: Tick `Delete source branch when merge request is accepted.` to help automatically tidy up your fork.
+
 8. Checkout `pregmod-master` in preparation of next change.
-    * Via terminal: `git checkout -q pregmod-master`
+   * Via terminal: `git checkout pregmod-master`
+
 9. Once the merge request was accepted, delete your local branch.
-    * Via terminal: `git branch -dq <branch-name>`
+   * Via terminal: `git branch -d <branch-name>`
+
+## Tips
 
-To get a list of all current branches run `git branch --list` via terminal.
+* Never commit anything on the main `pregmod-master` branch, always use feature branches.
+* To check the current state of your local copy, use `git status`.
+* To get a list of all current branches run `git branch --list` via terminal.
diff --git a/src/npc/surgery/surgeryDegradation.js b/devNotes/legacy files/Unused_Surgery_Scenes.js
similarity index 87%
rename from src/npc/surgery/surgeryDegradation.js
rename to devNotes/legacy files/Unused_Surgery_Scenes.js
index 29b944a28775cbd47a02698086b83ab9282ea6c3..b9e55704dd44ba3203f4ca43461fc367d2d89bd9 100644
--- a/src/npc/surgery/surgeryDegradation.js
+++ b/devNotes/legacy files/Unused_Surgery_Scenes.js	
@@ -1,85 +1,3 @@
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {HTMLElement|DocumentFragment}
- */
-App.UI.SlaveInteract.surgeryDegradation = function(slave) {
-	const el = new DocumentFragment();
-	let r = [];
-	const {his, him} = getPronouns(slave);
-
-	/* disallow surgery for slaves on certain assignments */
-	// TODO: do this before apply, this is too late
-	switch (slave.assignment) {
-		case "be your agent":
-		case "live with your agent":
-			return App.UI.DOM.makeElement("span", `You must retrieve ${slave.slaveName} from ${his} assignment before performing surgery on ${him}.`, "red");
-	}
-
-	// TODO: do this during apply
-	if (slave.dick === 0) {
-		if (slave.vagina === -1) {
-			slave.piercing.genitals.weight = 0;
-			slave.piercing.genitals.smart = false;
-		}
-		if (slave.drugs === "penis enhancement" || slave.drugs === "hyper penis enhancement" || slave.drugs === "breast redistributors") {
-			slave.drugs = "no drugs";
-		}
-	}
-	if (slave.balls === 0) {
-		if (slave.drugs === "testicle enhancement" || slave.drugs === "hyper testicle enhancement" || slave.drugs === "testicle atrophiers") {
-			slave.drugs = "no drugs";
-		}
-	}
-
-
-	// Search for Reaction class and apply if there is one.
-	if (App.Medicine.Surgery.ReactionsMap.has(V.surgeryType)) {
-		const reaction = App.Medicine.Surgery.ReactionsMap.get(V.surgeryType);
-
-		if (reaction.invasive && slave.health.condition < random(-100, -80)) {
-			r.push(`${slave.slaveName} <span class="health dec">has died from complications of surgery.</span>`);
-			App.Events.addParagraph(el, r);
-			removeSlave(slave);
-			V.nextLink = "Main";
-			return el;
-		}
-
-		if (reaction.removeJob) {
-			removeJob(slave, Job.LURCHER, true);
-			removeJob(slave, Job.PIT, true);
-			removeJob(slave, slave.assignment);
-		}
-
-		r.push(...reaction.intro(slave, {}));
-
-		const resultMain = reaction.reaction(slave, {});
-		for (const p of resultMain.longReaction) {
-			r.push(...p);
-			App.Events.addParagraph(el, r);
-			r = [];
-		}
-		slave.devotion += resultMain.devotion;
-		slave.trust += resultMain.trust;
-
-		const resultOutro = reaction.outro(slave, {}, resultMain);
-		for (const p of resultOutro.longReaction) {
-			r.push(...p);
-			App.Events.addParagraph(el, r);
-			r = [];
-		}
-		slave.devotion += resultOutro.devotion;
-		slave.trust += resultOutro.trust;
-
-		return el;
-	} else {
-		r.push(`<span class="error">ERROR bad/missing surgery description</span>`);
-		r.push(`surgeryType: ${V.surgeryType}`);
-		App.Events.addParagraph(el, r);
-	}
-
-	return null;
-};
-
 // switch (V.surgeryType) {
 /*
 
diff --git a/devNotes/tests/diffProxyTest.js b/devNotes/tests/diffProxyTest.js
deleted file mode 100644
index 72ec17ec588e68cdeda1321db39cd22df152e01f..0000000000000000000000000000000000000000
--- a/devNotes/tests/diffProxyTest.js
+++ /dev/null
@@ -1,82 +0,0 @@
-function tests() {
-	const getProxy = App.Utils.Diff.getProxy;
-
-	function orig() {
-		return {
-			a: 1,
-			b: [1, 2],
-			c: {a: 1}
-		};
-	}
-
-	function log(name, p) {
-		console.log(name);
-		const original = p.diffOriginal;
-		const diff = p.diffChange;
-		console.log("Original:", _.cloneDeep(original));
-		console.log("Diff: ", diff);
-		App.Utils.Diff.applyDiff(original, diff);
-		console.log("Apply: ", original);
-	}
-
-	log("Proxy", getProxy(orig()));
-
-	let o = getProxy(orig());
-	o.a = 2;
-	log(1, o);
-
-	o = getProxy(orig());
-	delete o.a;
-	log(2, o);
-
-	o = getProxy(orig());
-	o.c.a = 2;
-	log(3, o);
-
-	o = getProxy(orig());
-	delete o.c.a;
-	log(4, o);
-
-	o = getProxy(orig());
-	delete o.c;
-	log(5, o);
-
-	o = getProxy(orig());
-	o.b[1] = 5;
-	log(6, o);
-
-	o = getProxy(orig());
-	o.b.push(5);
-	log(7, o);
-
-	o = getProxy(orig());
-	o.b.push(5);
-	console.log("EXPECT: 5, IS: ", o.b[2]);
-	log(8, o);
-
-	o = getProxy(orig());
-	console.log("POP 1:", o.b.pop());
-	log(9, o);
-
-	o = getProxy(orig());
-	o.d = 7;
-	log(10, o);
-
-	o = getProxy(orig());
-	o.d = {a: 5};
-	console.log("Expect 5:", o.d.a);
-	log(11, o);
-	o = getProxy(orig());
-
-	o.d = {a: [5]};
-	o.d.a.unshift(9);
-	log(12, o);
-
-	let slaveDummy = getProxy({eye: new App.Entity.EyeState()});
-	eyeSurgery(slaveDummy, "left", "remove");
-	log(20, slaveDummy);
-
-	slaveDummy = getProxy({eye: new App.Entity.EyeState()});
-	eyeSurgery(slaveDummy, "both", "remove");
-	log(20, slaveDummy);
-}
diff --git a/devNotes/usefulJSFunctionDocumentation.md b/devNotes/usefulJSFunctionDocumentation.md
index 7a483acadca3fab27ef5907f18652f6b8016479f..e67ded88ad0348b7382b6bf5888169ccc0141df7 100644
--- a/devNotes/usefulJSFunctionDocumentation.md
+++ b/devNotes/usefulJSFunctionDocumentation.md
@@ -1,4 +1,7 @@
-## Assay Functions ##
+# Useful Functions
+
+## Assay Functions
+
 ```js
 isSlim(slave) // Returns if slave is considered slim or not by arcology standards.
 
@@ -149,12 +152,14 @@ canLift(actor1, actor2) // Returns if actor2 is capable of picking up and carryi
 heelLength(slave) // Returns the length of a slave's heels should she be wearing any
 ```
 
-## Player Functions ##
+## Player Functions
+
 ```js
 onBedRest(actor) // Returns if the actor is on mandatory bedrest or just incapable of leaving their bed. (Mostly for player use.)
 ```
 
-## Display Functions ##
+## Display Functions
+
 ```js
 properTitle() // Returns the player's proper title. (customTitle, Sir, Ma'am)
 
@@ -177,74 +182,76 @@ SlaveTitle(slave) // Returns the slave's descriptive title.
 relativeTerm(slave1, slave2) // Returns the term for slave2's relation to slave1. (daughter, mother, etc.)
 
 relationshipChecks [script] All work as expected with <<if X.rivalryTarget == $slaves[$i].ID>> preceding them.
-	rivalryTerm(id) // Returns the rivalry term for the input. e.g. lines 99-100 of brothelReport.
-		//<<if $Madam.rivalryTarget == $slaves[$i].ID>>
-			//$He forces $his <<print rivalryTerm($Madam)>>, to service all the men in the brothel.
-		//Would print 'She forces her growing rival, to service all the men in the brothel.'
-
-	relationshipTerm(id) Returns the long form relationship term for the input. e.g. lines 147-148 of saRules.
-		//<<if $slaves[$i].relationship > 0>>
-			//$He often asks to save these breaks so $he can spend them with $his <<print relationshipTerm($slaves[$i])>>.
-		//Would print '$He often asks to save these breaks so $he can spend them with $his friend.'
-
-	relationshipTermShort(id) Prints the short form of the above. e.g. line 321 of slaveInteract.
-		//`"Fuck $him with $his <<print relationshipTermShort($activeSlave)>> <<= SlaveFullName($slaves[_si])>>"`
-		//Would print 'Fuck $him with $his BFF <<= SlaveFullName($slaves[_si])>>'
-
-	PCrelationshipTerm(id) Prints the relationship term for the input (relative to the PC) if the relationship is < -1.
-		//<<if $slaves[$i].relationship < -1>>
-			//$He loves being your <<print PCrelationshipTerm($slaves[$i])>>.
-		//Would print '$He loves being your wife.'
-
-	contextualIntro(context, actor, insertComma=false) // Introduces an actor by using any meaningful relationship(s) with an already on-screen actor, and their name.
-		//Returns strings like: "your husband John", "his growing rival and mother Alice", or "her best friend and twin sister Carla".
-		//If there is no known relationship between them, retuns the name alone. If insertComma is true, it will generate "her father, Dave" instead of "her father Dave".
-		//Use this function instead of just printing the slave's name when you'd like to let the player to know if two actors are related, even though it's not going to have any mechanical impact on the scene.
+ rivalryTerm(id) // Returns the rivalry term for the input. e.g. lines 99-100 of brothelReport.
+  //<<if $Madam.rivalryTarget == $slaves[$i].ID>>
+   //$He forces $his <<print rivalryTerm($Madam)>>, to service all the men in the brothel.
+  //Would print 'She forces her growing rival, to service all the men in the brothel.'
+
+ relationshipTerm(id) Returns the long form relationship term for the input. e.g. lines 147-148 of saRules.
+  //<<if $slaves[$i].relationship > 0>>
+   //$He often asks to save these breaks so $he can spend them with $his <<print relationshipTerm($slaves[$i])>>.
+  //Would print '$He often asks to save these breaks so $he can spend them with $his friend.'
+
+ relationshipTermShort(id) Prints the short form of the above. e.g. line 321 of slaveInteract.
+  //`"Fuck $him with $his <<print relationshipTermShort($activeSlave)>> <<= SlaveFullName($slaves[_si])>>"`
+  //Would print 'Fuck $him with $his BFF <<= SlaveFullName($slaves[_si])>>'
+
+ PCrelationshipTerm(id) Prints the relationship term for the input (relative to the PC) if the relationship is < -1.
+  //<<if $slaves[$i].relationship < -1>>
+   //$He loves being your <<print PCrelationshipTerm($slaves[$i])>>.
+  //Would print '$He loves being your wife.'
+
+ contextualIntro(context, actor, insertComma=false) // Introduces an actor by using any meaningful relationship(s) with an already on-screen actor, and their name.
+  //Returns strings like: "your husband John", "his growing rival and mother Alice", or "her best friend and twin sister Carla".
+  //If there is no known relationship between them, returns the name alone. If insertComma is true, it will generate "her father, Dave" instead of "her father Dave".
+  //Use this function instead of just printing the slave's name when you'd like to let the player to know if two actors are related, even though it's not going to have any mechanical impact on the scene.
 
 bellyAdjective(slave) // Returns a string describing her belly size.
 
-lispReplace(string) // Returns the string lispified.
+lispReplace(string) // Returns the string with a lisp.
 
 nippleColor(slave) // Returns the slave's nipple color.
 
 UtilJS [script]
-	num() // Returns the value thousand separated with ',' if $formatNumbers > 0 else provides the raw value. Returns an integer if $showNumbers == 0, numbers up to a preset max as words if $showNumbers == 1, or only words if $showNumbers == 2.
-		//line 138 of src/SpecialForce/Report.tw, '...focused their <<print num($SFUnit.Troops)>> troops'
-		//if $formatNumbers > 0 'focused their 1,589 troops' else 'focused their 1589 troops'
-		//if $showNumbers == 0 'focused their 1,589 troops', if $showNumbers == 1 'focused their 1,589 troops' (unless the max is set to more than 1,589), else 'focused their one thousand five hundred eighty-nine troops'
+ num() // Returns the value thousand separated with ',' if $formatNumbers > 0 else provides the raw value. Returns an integer if $showNumbers == 0, numbers up to a preset max as words if $showNumbers == 1, or only words if $showNumbers == 2.
+  //line 138 of src/SpecialForce/Report.tw, '...focused their <<print num($SFUnit.Troops)>> troops'
+  //if $formatNumbers > 0 'focused their 1,589 troops' else 'focused their 1589 troops'
+  //if $showNumbers == 0 'focused their 1,589 troops', if $showNumbers == 1 'focused their 1,589 troops' (unless the max is set to more than 1,589), else 'focused their one thousand five hundred eighty-nine troops'
 
-	cashFormat() // uses the above function to return the value thousand separated with ',' if $formatNumbers > 0 else provides the raw value. either way prepends ¤ (the fc domination) symbol.
-		//line 157 of the previously listed file, '...totaling @@.yellowgreen;<<print cashFormat(_SFIncome)>>@@'
-		//if $formatNumbers > 0 'totaling @@.yellowgreen;¤1,500,000@@' else 'totaling @@.yellowgreen;¤1500000@@'
+ cashFormat() // uses the above function to return the value thousand separated with ',' if $formatNumbers > 0 else provides the raw value. either way prepends ¤ (the fc domination) symbol.
+  //line 157 of the previously listed file, '...totaling @@.yellowgreen;<<print cashFormat(_SFIncome)>>@@'
+  //if $formatNumbers > 0 'totaling @@.yellowgreen;¤1,500,000@@' else 'totaling @@.yellowgreen;¤1500000@@'
 
-	isFloat() // Checks if value is float.
+ isFloat() // Checks if value is float.
 
-	isInt() // Checks if value is an integer.
+ isInt() // Checks if value is an integer.
 
-	numberWithCommas() // Currently unused.
+ numberWithCommas() // Currently unused.
 
-	jsRandom() // JS equivalent of SugarCube's random().
+ jsRandom() // JS equivalent of SugarCube's random().
 
-	jsRandomMany() // JS equivalent of SugarCube's randomMany().
+ jsRandomMany() // JS equivalent of SugarCube's randomMany().
 
-	jsEither() // This function wants an array // which explains why it works like array.random(). Give it one or you'll face a NaN. JS equivalent of SugarCube's either() and array.random().
+ jsEither() // This function wants an array // which explains why it works like array.random(). Give it one or you'll face a NaN. JS equivalent of SugarCube's either() and array.random().
 
-	deepCopy() // This function is alternative to clone // usage needed if nested objects present. Slower but result is separate object tree, not with reference to source object.
+ deepCopy() // This function is alternative to clone // usage needed if nested objects present. Slower but result is separate object tree, not with reference to source object.
 
-	hashChoice() // hashes provided input.
+ hashChoice() // hashes provided input.
 
-	hashSum() // totals provided input and then hashes.
+ hashSum() // totals provided input and then hashes.
 
-	arr2obj() // Converts an array to an object. e.g. line 250 of :: init Nationalities [silently]
-		<<set $nationalities = arr2obj(setup.baseNationalities)>>
+ arr2obj() // Converts an array to an object. e.g. line 250 of :: init Nationalities [silently]
+  <<set $nationalities = arr2obj(setup.baseNationalities)>>
 
-	hashPush() //Note really sure where input is being pushed to.
+ hashPush() //Note really sure where input is being pushed to.
 
-	weightedArray2HashMap()
+ weightedArray2HashMap()
 
-	def() // Returns whether the input is defined, similar to SugarCube's def.
+ def() // Returns whether the input is defined, similar to SugarCube's def.
 ```
-## Core Slave Functions ##
+
+## Core Slave Functions
+
 ```js
 newSlave(slave) // Adds slave object to main slave array. Do not use without care!
 
@@ -292,7 +299,7 @@ removeLimbs(slave, limb) // Remove limb(s) and clean up connected variables.
 attachLimbs(slave, limb, id) // Attach limb(s). Expects amputated limbs, will overwrite existing.
 
 //UtilJS [script]
-	Height.mean(nationality, race, genes, age) // returns the mean height for the given combination and age in years (>=2).
+ Height.mean(nationality, race, genes, age) // returns the mean height for the given combination and age in years (>=2).
  Height.mean(nationality, race, genes) // returns the mean adult height for the given combination.
  Height.mean(slave) // returns the mean (expected) height for the given slave.
 
@@ -313,7 +320,9 @@ attachLimbs(slave, limb, id) // Attach limb(s). Expects amputated limbs, will ov
 
  getSlaveTrustClass(slave) // returns the trust of the target as text. e.g. if (slave.trust < -95) return 'extremely-terrified';
 ```
-## Health Functions ##
+
+## Health Functions
+
 ```js
 setHealth(slave, condition, shortDamage, longDamage, illness, tired) // Sets the health (primarily) of new slaves, it helps ensure the desired values do not immediately kill the slave and corrects them if needed
 
@@ -327,7 +336,9 @@ illness(slave) // A start of the 'end week loop' function to see if a slave has
 
 endWeekHealthDamage // An end of the 'end week loop' function to move shortDamage to the appropriate longer term variables and such.
 ```
-## Sex Functions ##
+
+## Sex Functions
+
 ```js
 knockMeUp(actor, chance, hole, fatherID, displayOverride) // Attempts to impregnate actor.
 
@@ -349,19 +360,21 @@ SimpleSexAct.Slaves(slave1, slave2, count) // Runs a slave2 on slave1 sex act co
 
 //UtilJS [script]
 
-	dickToInchString() // takes a dick value e.g. $activeSlave.dick, returns a string in the format 6 inches
+ dickToInchString() // takes a dick value e.g. $activeSlave.dick, returns a string in the format 6 inches
 
-	dickToCM() // takes a dick value e.g. $activeSlave.dick, returns an int of the dick length in cm
+ dickToCM() // takes a dick value e.g. $activeSlave.dick, returns an int of the dick length in cm
 
-	ballsToInchString() // takes a ball value e.g. $activeSlave.balls, returns a string in the format 3 inches
+ ballsToInchString() // takes a ball value e.g. $activeSlave.balls, returns a string in the format 3 inches
 
-	ballsToCM() // takes a ball value e.g. $activeSlave.balls, returns an int of the ball size in cm
+ ballsToCM() // takes a ball value e.g. $activeSlave.balls, returns an int of the ball size in cm
 
-	dickToEitherUnit() // takes a dick value e.g. $activeSlave.dick, returns a string in the format of either `20cm (8 inches)`, `8 inches`, or `20cm`
+ dickToEitherUnit() // takes a dick value e.g. $activeSlave.dick, returns a string in the format of either `20cm (8 inches)`, `8 inches`, or `20cm`
 
-	ballsToEitherUnit() // takes a ball value e.g. $activeSlave.balls, returns a string in the format of either `20cm (8 inches)`, `8 inches`, or `20cm`
+ ballsToEitherUnit() // takes a ball value e.g. $activeSlave.balls, returns a string in the format of either `20cm (8 inches)`, `8 inches`, or `20cm`
 ```
-## Pregnancy Functions ##
+
+## Pregnancy Functions
+
 ```js
 WombInit($slave) // before first pregnancy, at slave creation, of as backward compatibility update.
 
@@ -375,13 +388,15 @@ $children = WombBirth($slave, $birth_ready_age) // for actual birth. Return arra
 
 WombFlush($slave) // clean womb (array). Can be used at broodmother birthstorm or abortion situations in game. But birthstorm logically should use WombBirth($slave, 35) or so before // some children in this event is live capable, others is not.
 
-TerminatePregnancy($slave) // end a pregancy early, clean the womb, update the belly size, and automatically set an appropriate postpartum length.
+TerminatePregnancy($slave) // end a pregnancy early, clean the womb, update the belly size, and automatically set an appropriate postpartum length.
 
 $slave.bellyPreg = WombGetVolume($slave) // return double, with current womb volume in CC // for updating $slave.bellyPreg, or if need to update individual fetuses sizes.
 
 findFather(ID) // searches for the ID given and returns an object or undefined
 ```
-## Release Functions ##
+
+## Release Functions
+
 ```js
 sexAllowed // returns true if both slaves are allowed to have sex with each other. All non-assignment sex should check here first; use disobedience() to determine if the slave or slaves involved will ignore the rules.
 
@@ -393,31 +408,35 @@ hasNonassignmentSex // returns true if the slave is having some kind of sex whil
 
 releaseRestricted // returns true if the slave has some kind of rule limiting the off-duty sex they have. If it returns false, the slave is completely free to fuck whomever they want.
 ```
-## Other Functions ##
+
+## Other Functions
+
 ```js
 //UtilJS [script]
-	cmToInchString() // takes an integer e.g. $activeSlave.hLength, returns a string in the format 10 inches
+ cmToInchString() // takes an integer e.g. $activeSlave.hLength, returns a string in the format 10 inches
 
-	cmToFootInchString() // takes an integer e.g. $activeSlave.height, returns a string in the format 6'5"
+ cmToFootInchString() // takes an integer e.g. $activeSlave.height, returns a string in the format 6'5"
 
-	lengthToEitherUnit() // takes an int in centimeters e.g. $activeSlave.hLength, returns a string in the format of either `30cm (12 inches)`, `12 inches`, or `30cm`
+ lengthToEitherUnit() // takes an int in centimeters e.g. $activeSlave.hLength, returns a string in the format of either `30cm (12 inches)`, `12 inches`, or `30cm`
 
-	ValidateFacilityDecoration() // checks the value of the associated variable and it if it infinite i.e. NA the text description is reset back to standard.
-		/* decoration should be passed as "facilityDecoration" in quotes. For example, ValidateFacilityDecoration("brothelDecoration"). The quotes are important, do not pass it as a story variable. */
+ ValidateFacilityDecoration() // checks the value of the associated variable and it if it infinite i.e. NA the text description is reset back to standard.
+  /* decoration should be passed as "facilityDecoration" in quotes. For example, ValidateFacilityDecoration("brothelDecoration"). The quotes are important, do not pass it as a story variable. */
 
-	FSChangePorn() // //Currently unused, widget version routes directly through FSChange()
+ stretchedAnusSize() // Calculates the minimum anus size to accommodate a particular dick size
 
-	HackingSkillMultiplier() // outputs a value based off of the PC's hacking skill.
+ FSChangePorn() // // Currently unused, widget version routes directly through FSChange()
 
-	upgradeMultiplierArcology() // outputs a value based off of the PC's engineering skill.
+ HackingSkillMultiplier() // outputs a value based off of the PC's hacking skill.
 
-	upgradeMultiplierMedicine() // outputs a value based off of the PC's medicine skill.
+ upgradeMultiplierArcology() // outputs a value based off of the PC's engineering skill.
 
-	upgradeMultiplierTrade() // outputs a value based off of the PC's trading skill.
+ upgradeMultiplierMedicine() // outputs a value based off of the PC's medicine skill.
 
-	passageLink() // Creates a HTML element with custom SugarCube attributes which works as a passage link
+ upgradeMultiplierTrade() // outputs a value based off of the PC's trading skill.
 
-	SkillIncrease() // Depreciates the SugarCube functions.
+ passageLink() // Creates a HTML element with custom SugarCube attributes which works as a passage link
 
-	disobedience // Returns a 0-100 value indicating likelihood of a slave ignoring the rules.
-```
\ No newline at end of file
+ SkillIncrease() // Depreciates the SugarCube functions.
+
+ disobedience // Returns a 0-100 value indicating likelihood of a slave ignoring the rules.
+```
diff --git a/devTools/types/FC/RA.d.ts b/devTools/types/FC/RA.d.ts
index 5dd435443af1d8922530503eae9de35becb24b5f..d9c75fff29ffea78e0b574b757ee501e71f33834 100644
--- a/devTools/types/FC/RA.d.ts
+++ b/devTools/types/FC/RA.d.ts
@@ -1,24 +1,15 @@
 declare namespace FC {
 	namespace RA {
-		interface NumericTarget {
-			cond: string;
-			val: number;
-		}
-
-		interface ExpressiveNumericTarget {
-			cond: string;
-			val: string | number;
-		}
 
-		interface NumericRange {
-			min: number;
-			max: number;
+		interface GenericNumericTarget<T> {
+			cond: "==" | ">=" | "<=" | ">" | "<";
+			val: T;
 		}
+		type NumericTarget = GenericNumericTarget<number>;
+		type ExpressiveNumericTarget = GenericNumericTarget<number | string>;
 
 		interface RuleConditions {
-			function: boolean | string;
-			data: any;
-			assignment: Assignment[];
+			activation: PostFixRule;
 			selectedSlaves: number[];
 			excludedSlaves: number[];
 			applyRuleOnce: boolean;
@@ -36,12 +27,16 @@ declare namespace FC {
 			accent: number;
 			shoulders: number;
 			shouldersImplant: number;
-			boobs: NumericTarget;
+			boobs: NumericRange;
+			boobsImplantTypes: SizingImplantType[];
+			boobsImplantAllowReplacing: boolean;
 			hips: number;
 			hipsImplant: number;
-			butt: NumericTarget;
+			butt: NumericRange;
+			buttImplantTypes: SizingImplantType[];
+			buttImplantAllowReplacing: boolean;
 			faceShape: FaceShape;
-			lips: NumericTarget;
+			lips: NumericRange;
 			holes: number;
 			hair: number;
 			bodyhair: number;
@@ -140,7 +135,7 @@ declare namespace FC {
 			weight: NumericRange;
 			diet: string;
 			dietCum: number;
-			dietMilk: number;
+			dietMilk: FC.dietMilkType;
 			onDiet: number;
 			muscles: NumericTarget;
 			XY: number;
@@ -178,7 +173,7 @@ declare namespace FC {
 			scarDesign: string;
 			hornColor: string;
 			labelTagsClear: boolean;
-			choosesOwnClothes: 0|1;
+			choosesOwnClothes: 0 | 1;
 			pronoun: number;
 		}
 
@@ -188,5 +183,7 @@ declare namespace FC {
 			condition: RuleConditions;
 			set: RuleSetters;
 		}
+
+		type PostFixRule = Array<string | number | boolean>
 	}
 }
diff --git a/devTools/types/FC/facilities.d.ts b/devTools/types/FC/facilities.d.ts
index c33c4f173ecbf44b74dbb1309eea611d75bbbc98..d506384103756c3cad822b247186462f4e2a3beb 100644
--- a/devTools/types/FC/facilities.d.ts
+++ b/devTools/types/FC/facilities.d.ts
@@ -28,7 +28,7 @@ declare namespace FC {
 		/** Any handler to run upon purchase. */
 		handler?: () => void;
 		/** Any additional information to display upon hover on the link. */
-		note?: string;
+		notes?: string[];
 		/**
 		 * Any prerequisites that must be met before the upgrade is available.
 		 *
@@ -59,11 +59,11 @@ declare namespace FC {
 				/** The value to set `property` to when the rule is active. */
 				value: any;
 				/** Any handler to run upon setting the value. */
-				handler?: () => void;
+				handler?: (value: any) => void;
 				/** Any additional information to display with on the link. */
 				note?: string;
 				/** Any prerequisites that must be met for the option to be displayed. */
-				prereqs?: Array<() => boolean>
+				prereqs?: Array<() => boolean>;
 			}>
 			/** Any additional nodes to attach. */
 			nodes?: Array<string|HTMLElement|DocumentFragment>
@@ -124,6 +124,8 @@ declare namespace FC {
 			audience: "none" | "free" | "paid";
 			/** Whether or not the bodyguard is fighting this week. */
 			bodyguardFights: boolean;
+			/** The type of decoration the Pit is using. */
+			decoration: FC.FutureSocietyDeco;
 			/**
 			 * Who is fighting this week.
 			 *
diff --git a/devTools/types/FC/financial.d.ts b/devTools/types/FC/financial.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d108e80567dc5b2b488a379d1ad820adf1acd0b5
--- /dev/null
+++ b/devTools/types/FC/financial.d.ts
@@ -0,0 +1,35 @@
+declare namespace FC {
+    interface Loan {
+		/** The lender's name. */
+		name: 'bank' | 'shark';
+		/** The amount they've lent. */
+		principal: number;
+		/** The week on which repayment is due. */
+		deadline: number;
+		/** The number of installments remaining until the full amount is paid. */
+		installments: number;
+		/** The Annual Percentage Rate. */
+		apr: number;
+		/** The amount of interest the loan will accumulate. */
+		interest: number;
+		/** The full amount that will be paid. */
+		full: number;
+	}
+
+	interface SlaveStatisticData {
+		/** ID of relevant slave */
+		ID: number,
+		slaveName: string,
+		customLabel: string,
+		income: number,
+		adsIncome: number,
+		rep: number,
+		food: number,
+		cost: number,
+		customers: number,
+
+		milk?:number,
+		cum?:number,
+		fluid?:number,
+	}
+}
diff --git a/devTools/types/FC/gameState.d.ts b/devTools/types/FC/gameState.d.ts
index d5217a28ac6b0dd06739a5385c22e093d0afdbe3..748bce5e5d823197620ee8a2d6a21eae3fea1dad 100644
--- a/devTools/types/FC/gameState.d.ts
+++ b/devTools/types/FC/gameState.d.ts
@@ -12,14 +12,54 @@ declare namespace FC {
 		say: string;
 	}
 
-	interface PeacekeepersState {
-		generalName: string;
-		strength: number;
-		attitude: number;
-		independent: number;
-		undermining: number;
-		influenceAnnounced: number;
-		tastes: Zeroable<String>;
+	interface Rival {
+		/**
+		- 0: Init
+		- 1: Not established
+		- 2: Established
+		- 3: Captured
+		- 4: Killed
+		- 5: Enslaved
+		 */
+		state: number;
+		duration: number;
+		prosperity: number;
+		power: number;
+		race?: FC.Race;
+		/**
+		- 1: Female
+		- 2: Male
+		 */
+		gender?: number;
+		ID?: number;
+		FS: {
+			name: string;
+			race?: FC.Race; 
+			adopted?: number;
+		}
+		/**
+			- 0: Unknown / Gone
+			- 1: Announced
+			- 2: Rescued
+			- 3: Given in. Currently unused, is checked but commented out within src/endWeek/saDevotion.js
+			*/
+		hostageState: number,
+	}
+
+	interface Peacekeepers {
+		/**
+		- 0: Gone
+		- 1: Not established
+		- 2: Established
+		- 3: Independent
+		 */
+		state: number;
+		generalName?: string;
+		strength?: number;
+		attitude?: number;
+		undermining?: number;
+		influenceAnnounced?: number;
+		tastes?: string;
 	}
 
 	export type RecruiterTarget = "desperate whores" | "young migrants" | "recent divorcees" |
@@ -50,6 +90,13 @@ declare namespace FC {
 		slaveID?: number;
 	}
 
+	export interface TrinketData {
+		name: string,
+		id?: number | null
+		extra?: string,
+		napkinShape?: string
+	}
+
 	/**
 	 * These variables shall not be in the game state and there is a hope they will be exterminated in the future
 	 */
@@ -100,7 +147,7 @@ declare namespace FC {
 		applyCareerBonus?: Bool;
 		careerBonusNeeded?: number[];
 		prostheticsConfig?: string;
-		
+
 		oldLimbs: any;
 
 		heroSlaves: SlaveTemplate[];
diff --git a/devTools/types/FC/global.d.ts b/devTools/types/FC/global.d.ts
index ba8cd416540d0ee07d7618ca6dccdf6480282d10..ee7b843d96d40b828f285df281676118f3ffcdd9 100644
--- a/devTools/types/FC/global.d.ts
+++ b/devTools/types/FC/global.d.ts
@@ -4,10 +4,6 @@ declare global {
 		includes(needle: any): boolean; // because we use silly unions with 0
 	}
 
-	interface Number {
-		toFixedHTML(fractionDigits?: number): string;
-	}
-
 	interface Window {
 		storyProxy?: object;
 	}
diff --git a/devTools/types/FC/human.d.ts b/devTools/types/FC/human.d.ts
index 4dac6309be72e77071b4b640d704a06bfea54f7d..23ef528c941aa38f747d8df9d0c601c561d67594 100644
--- a/devTools/types/FC/human.d.ts
+++ b/devTools/types/FC/human.d.ts
@@ -311,7 +311,22 @@ declare global {
 		type Piercing = "ear" | "nose" | "eyebrow" | "lips" | "tongue" | "nipple" | "areola" | "navel" | "corset" | "genitals" | "vagina" | "dick" | "anus";
 		type Race = "amerindian" | "asian" | "black" | "indo-aryan" | "latina" | "malay" | "middle eastern" | "mixed race" |
 			"pacific islander" | "catgirl" | "semitic" | "southern european" | "white";
-		type SizingImplantType = WithNone<"normal" | "string" | "fillable" | "advanced fillable" | "hyper fillable">;
+
+		type SizingImplantType = "normal" | "string" | "fillable" | "advanced fillable" | "hyper fillable";
+		type LipsImplantType = "normal";
+		type InstalledSizingImplantType = WithNone<SizingImplantType>;
+		type InstalledLipsImplantType = WithNone<LipsImplantType>;
+		type SizableBodyPart = "lips" | "boobs" | "butt" | "dick" | "balls";
+		type SizingImplantTarget = "boobs" | "butt" | "lips";
+
+		interface BodyPartImplantTypeMap {
+			lips: LipsImplantType;
+			boobs: SizingImplantType;
+			butt: SizingImplantType;
+		}
+
+		type BodyPartInstalledImplantType<Target extends SizingImplantTarget> = WithNone<BodyPartImplantTypeMap[Target]>;
+
 		type SmartPiercingSetting = WithNone<"off" | "all" | "no default setting" | "random" | "women" | "men" | "vanilla" | "oral" | "anal" |
 			"boobs" | "submissive" | "humiliation" | "pregnancy" | "dom" | "masochist" | "sadist" | "anti-women" | "anti-men">;
 		type TeethType = "normal" | "crooked" | "gapped" | "straightening braces" | "cosmetic braces" | "removable" | "pointy" |
@@ -449,16 +464,17 @@ declare global {
 		}
 		//#endregion
 
-		type LimbState = InstanceType<typeof App.Entity.LimbState>;
+		type ArmState = InstanceType<typeof App.Entity.ArmState>;
+		type LegState = InstanceType<typeof App.Entity.LegState>;
 
 		interface LimbsState {
 			arm: {
-				left: LimbState;
-				right: LimbState;
+				left: ArmState;
+				right: ArmState;
 			};
 			leg: {
-				left: LimbState,
-				right: LimbState;
+				left: LegState,
+				right: LegState;
 			};
 			PLimb: number;
 		}
@@ -478,70 +494,6 @@ declare global {
 
 		type HumanState = SlaveState | PlayerState;
 
-		export namespace Medicine {
-			export namespace Surgery {
-				/**
-				 * Describes surgical procedure
-				 */
-				export interface Procedure {
-					/**
-					 * Type code that identifies this kind of procedure.
-					 * Currently unused, but planned for future use by RA for prioritizing procedures
-					 */
-					typeId: string;
-					/**
-					 * Short label for the procedure. Can be used as a link text.
-					 */
-					label: string;
-					/**
-					 * If procedure is targeted at changing object characteristic, this is the net change (signed)
-					 */
-					targetEffect: number;
-					/**
-					 * Description of the procedure, more or less detailed
-					 */
-					description: string;
-					/**
-					 * Money costs (positive when you pay for it)
-					 */
-					costs: number;
-					/**
-					 * Projected health loss (positive when health decreases)
-					 */
-					healthCosts: number;
-					/**
-					 * Function to perform the procedure
-					 * If action is undefined, the procedure can't be applied (and .description contains the reason)
-					 */
-					action: slaveOperation;
-					/**
-					 * surgery type for passages like "Surgery Degradation"
-					 */
-					surgeryType: string;
-				}
-
-				export interface SizingOptions {
-					/** include possible augmentation procedures */
-					augmentation?: boolean;
-					/** include possible reduction procedures */
-					reduction?: boolean;
-					/** include option to install string implants */
-					strings?: boolean;
-					/** include implant change options */
-					replace?: boolean;
-				}
-			}
-			export namespace OrganFarm {
-				interface GrowingOrgan {
-					type: string;
-					weeksToCompletion: number;
-					ID: number;
-				}
-				export namespace Organs {
-				}
-			}
-		}
-
 		type ImageFormat = "png"|"jpg"|"gif"|"webp"|"webm"|"mp4";
 		export interface CustomImage {
 			filename?: string;
diff --git a/devTools/types/FC/medicine.d.ts b/devTools/types/FC/medicine.d.ts
index 8c2bae4ca46436193bafe16eb5993f1b9a904a35..620f6a48e6b1dbe94c39360a934c5c953ade837d 100644
--- a/devTools/types/FC/medicine.d.ts
+++ b/devTools/types/FC/medicine.d.ts
@@ -1,45 +1,165 @@
+
 declare namespace FC {
-    type prostheticID = "interfaceP1" | "interfaceP2" | "interfaceP3" | "basicL" | "sexL" | "beautyL" | "combatL" | "felidaeL" | "canidaeL" | "felidaeCL" | "canidaeCL" | "cyberneticL" 
-    | "ocular" | "cochlear" | "electrolarynx" | "interfaceTail" | "modT" | "sexT" | "combatT" | "combatT2" |/* "erectile" |*/ "interfaceBack" | "modW" | "flightW" 
-    | "sexA" | "combatW" | "combatA1" | "combatA2";
-
-    type prostheticName = "basic prosthetic interface" | "advanced prosthetic interface" | "quadrupedal prosthetic interface" | "set of basic prosthetic limbs" | "set of advanced sex limbs" 
-    | "set of advanced beauty limbs" | "set of advanced combat limbs" | "set of quadruped feline limbs" | "set of quadruped canine limbs" | "set of feline combat limbs" 
-    | "set of canine combat limbs" | "set of cybernetic limbs" | "ocular implant" | "cochlear implant" | "electrolarynx" | "prosthetic tail interface" | "modular tail" 
-    | "pleasure tail" | "combat tail" | `combat tail, type "Stinger"` | "prosthetic back interface" | "modular pair of wings" | "pair of flight capable wings" 
-    | "set of pleasure appendages" | `"set of combat appendages, type "Falcon"` | `set of combat appendages, type "Arachnid"` | `set of combat appendages, type "Kraken"`;
-
-
-    type LimbArgument = "left arm" | "right arm" | "left leg" | "right leg"
-    type LimbArgumentAll = "all" | LimbArgument
-
-    type BodySide = "left" | "right"
-    type BodySideAll = "both" | BodySide
-
-    interface AdjustProsthetics {
-        id: prostheticID;
-        workLeft: number;
-        slaveID: number;
-    }
-
-    type TaskType = "research" | "craft" | "craftFit"; 
-
-    interface Tasks {
-            type: TaskType;
-            id: prostheticID;
-            workLeft: number;
-            craftFit?: number;
-        }
-
-    interface ResearchLab {
-            level: number;
-            aiModule: number;
-            tasks: Tasks;
-            maxSpace: number;
-            hired: number;
-            menials: number;
-    }
-   
-}
+	type prostheticID = "interfaceP1" | "interfaceP2" | "interfaceP3" | "basicL" | "sexL" | "beautyL" | "combatL" | "felidaeL" | "canidaeL" | "felidaeCL" | "canidaeCL" | "cyberneticL"
+		| "ocular" | "cochlear" | "electrolarynx" | "interfaceTail" | "modT" | "sexT" | "combatT" | "combatT2" |/* "erectile" |*/ "interfaceBack" | "modW" | "flightW"
+		| "sexA" | "combatW" | "combatA1" | "combatA2";
+
+	type prostheticName = "basic prosthetic interface" | "advanced prosthetic interface" | "quadrupedal prosthetic interface" | "set of basic prosthetic limbs" | "set of advanced sex limbs"
+		| "set of advanced beauty limbs" | "set of advanced combat limbs" | "set of quadruped feline limbs" | "set of quadruped canine limbs" | "set of feline combat limbs"
+		| "set of canine combat limbs" | "set of cybernetic limbs" | "ocular implant" | "cochlear implant" | "electrolarynx" | "prosthetic tail interface" | "modular tail"
+		| "pleasure tail" | "combat tail" | `combat tail, type "Stinger"` | "prosthetic back interface" | "modular pair of wings" | "pair of flight capable wings"
+		| "set of pleasure appendages" | `"set of combat appendages, type "Falcon"` | `set of combat appendages, type "Arachnid"` | `set of combat appendages, type "Kraken"`;
+
+
+	type LimbArgument = "left arm" | "right arm" | "left leg" | "right leg"
+	type LimbArgumentAll = "all" | LimbArgument
+
+	type BodySide = "left" | "right"
+	type BodySideAll = "both" | BodySide
+
+	interface AdjustProsthetics {
+		id: prostheticID;
+		workLeft: number;
+		slaveID: number;
+	}
+
+	type TaskType = "research" | "craft" | "craftFit";
+
+	interface Tasks {
+		type: TaskType;
+		id: prostheticID;
+		workLeft: number;
+		craftFit?: number;
+	}
+
+	interface ResearchLab {
+		level: number;
+		aiModule: number;
+		tasks: Tasks;
+		maxSpace: number;
+		hired: number;
+		menials: number;
+	}
+
+	namespace Data.Medicine.SizingImplants {
+		type DynamicName = (volume: number) => string;
+		type DynamicCostFactor = (volume: number) => number;
+
+		interface FillDrainData {
+			limit: number;
+			step: number[];
+			healthCost: number;
+			materialCostFactor: number;
+		}
+		interface ImplantType {
+			name: string | DynamicName;
+			specificMaterialCost: number | DynamicCostFactor;
+			workCostFactor: {
+				installation: number;
+				removal: number;
+			}
+			healthCostFactor: {
+				installation: number;
+				removal: number;
+			},
+			availableSizes: number[] | (() => number[]);
+			/** If defined the implant is fillable and can be filled up to the given size */
+			fill?: FillDrainData;
+			/** If defined the implant is drainable and can be drained down to the given size */
+			drain?: FillDrainData;
+		}
 
- 
\ No newline at end of file
+		type SizingImplantDatabase = {
+			[K in SizingImplantTarget]: Record<BodyPartImplantTypeMap[K], FC.Data.Medicine.SizingImplants.ImplantType>;
+		}
+	}
+
+	namespace Medicine {
+
+		type ProcedureInstance = InstanceType<typeof App.Medicine.Surgery.Procedure>;
+		type SizingImplantProcedure = InstanceType<typeof App.Medicine.Surgery.Procedures.SizingImplantProcedure>;
+
+		type SizingImplantProcedureConstructor<T extends SizingImplantProcedure = SizingImplantProcedure> = new (...args: any[]) => T;
+
+		interface ImplantProcedureCreators {
+			install: (slave: FC.SlaveState, implantType: SizingImplantType, volume: number, fleshExcess: number) => ProcedureInstance;
+			remove: (slave: FC.SlaveState) => ProcedureInstance;
+			replace: (slave: FC.SlaveState, implantType: SizingImplantType, volume: number, fleshExcess: number) => ProcedureInstance;
+
+			fill: (slave: FC.SlaveState, amount: number) => ProcedureInstance;
+			drain: (slave: FC.SlaveState, amount: number) => ProcedureInstance;
+		}
+
+		type ImplantInfo<Target extends SizingImplantTarget> = {
+			type: BodyPartInstalledImplantType<Target>;
+			volume: number;
+		}
+
+		interface AssetSizingProcedureSet extends ImplantProcedureCreators {
+			reduce: (slave: SlaveState, name: string, amount: number) => ProcedureInstance;
+		}
+
+		namespace Surgery {
+			/**
+			 * Describes surgical procedure
+			 */
+			interface Procedure {
+				/**
+				 * Type code that identifies this kind of procedure.
+				 * Currently unused, but planned for future use by RA for prioritizing procedures
+				 */
+				typeId: string;
+				/**
+				 * Short label for the procedure. Can be used as a link text.
+				 */
+				label: string;
+				/**
+				 * If procedure is targeted at changing object characteristic, this is the net change (signed)
+				 */
+				targetEffect: number;
+				/**
+				 * Description of the procedure, more or less detailed
+				 */
+				description: string;
+				/**
+				 * Money costs (positive when you pay for it)
+				 */
+				costs: number;
+				/**
+				 * Projected health loss (positive when health decreases)
+				 */
+				healthCosts: number;
+				/**
+				 * Function to perform the procedure
+				 * If action is undefined, the procedure can't be applied (and .description contains the reason)
+				 */
+				action: slaveOperation;
+				/**
+				 * surgery type for passages like "Surgery Degradation"
+				 */
+				surgeryType: string;
+			}
+
+			type SizingOptions<Target extends SizingImplantTarget> = {
+				targetSize?: NumericRange;
+				/**
+				 * Allowed procedures for given implant type
+				 */
+				allowedTypes?: Set<BodyPartInstalledImplantType<Target>>;
+				/** include options with implant change */
+				replace?: boolean;
+			}
+
+			type DefinitiveSizedOptions<Target extends SizingImplantTarget> = Required<SizingOptions<Target>>;
+		}
+		namespace OrganFarm {
+			interface GrowingOrgan {
+				type: string;
+				weeksToCompletion: number;
+				ID: number;
+			}
+			namespace Organs {
+			}
+		}
+	}
+}
diff --git a/devTools/types/FC/util.d.ts b/devTools/types/FC/util.d.ts
index 5dd8757958ccef4ca9823b5f3c38adaa4c9c415c..3ed3029b8ef312d7d6465dbab41f8009f3ada656 100644
--- a/devTools/types/FC/util.d.ts
+++ b/devTools/types/FC/util.d.ts
@@ -12,5 +12,10 @@ declare namespace FC {
         }
 
         type DiffRecorder<T> = T & DiffBase<T>
-    }
+	}
+
+	interface NumericRange {
+		min: number;
+		max: number;
+	}
 }
diff --git a/devTools/types/SugarCubeExtensions.d.ts b/devTools/types/SugarCubeExtensions.d.ts
index d4b18a0a50ce841e21a86df911895f1937e34645..a4971ee3f33967a24c476ea9663eef4290014657 100644
--- a/devTools/types/SugarCubeExtensions.d.ts
+++ b/devTools/types/SugarCubeExtensions.d.ts
@@ -5,44 +5,7 @@ declare module "twine-sugarcube" {
 	}
 
 	interface SugarCubeSetupObject {
-		badWords: string[];
-		badNames: string[];
-		chattelReligionistSlaveNames: string[];
-		romanSlaveNames: string[];
-		romanSlaveSurnames: string[];
-		aztecSlaveNames: string[];
-		ancientEgyptianSlaveNames: string[];
-		edoSlaveNames: string[];
-		edoSlaveSurnames: string[];
-		bimboSlaveNames: string[];
-		cowSlaveNames: string[];
-		whiteAmericanMaleNames: string[];
-		whiteAmericanSlaveNames: string[];
-		whiteAmericanSlaveSurnames: string[];
-		catSlaveNames: string [];
-
-		fakeBellies: string[];
-		filterRaces: Map<FC.Race, string>;
-		filterRegions: string[];
-
-		pregData: Record<string, FC.PregnancyData>;
-
-		malenamePoolSelector: Record<string, string[]>;
-		maleSurnamePoolSelector: Record<string, string[]>;
-		namePoolSelector: Record<string, string[]>;
-		surnamePoolSelector: Record<string, string[]>;
-		raceSelector: Record<string, Record<FC.Race, number>>;
-
-		naturalSkins: string[];
-		naturalNippleColors: string[];
-
-		pettyCriminalPool: string[];
-		gangCriminalPool: string[];
-		militaryCriminalPool: string[];
-		whiteCollarCriminalPool: string[];
-
-		baseNationalities: string[];
-		paraphiliaList: string[]; // actually FC.SexualFlaw[]
+		// Any usages of the global setup object should be replaced by App.Data.misc
 	}
 
 	// These are SugarCube private APIs used in the project
diff --git a/devTools/types/extensions.d.ts b/devTools/types/extensions.d.ts
index d166c6b86673fd880061c75dd374d1ce86f31126..07c495c194f1cb1f82c91c0135b92ea8b7d30e03 100644
--- a/devTools/types/extensions.d.ts
+++ b/devTools/types/extensions.d.ts
@@ -13,11 +13,11 @@ interface Number {
 	 isBetween(min: number, max: number, inclusive?: boolean): boolean;
 }
 
-type ActualPropertyKey<T extends PropertyKey> = T extends number ? string : T;
+type EnumerablePropertyKey<T extends PropertyKey> = T extends symbol ? never : (T extends number ? string : T);
 
 interface ObjectConstructor {
-	keys<K extends PropertyKey, V>(o: Partial<Record<K, V>>): ActualPropertyKey<K>[];
-	entries<K extends PropertyKey, V>(o: Partial<Record<K, V>>): [ActualPropertyKey<K>, V][];
+	keys<K extends PropertyKey, V>(o: Partial<Record<K, V>>): EnumerablePropertyKey<K>[];
+	entries<K extends PropertyKey, V>(o: Partial<Record<K, V>>): [EnumerablePropertyKey<K>, V][];
 }
 
 // d3-dtree
diff --git a/js/002-config/fc-js-init.js b/js/002-config/fc-js-init.js
index dde6cc0b140c088f96e868d50adf0d4c0aba9135..8050993cbf9fe9e92e8bfdf055bd86bfb9709408 100644
--- a/js/002-config/fc-js-init.js
+++ b/js/002-config/fc-js-init.js
@@ -20,6 +20,7 @@ App.Corporate = {};
 App.Data = {};
 App.Data.FCTV = {};
 App.Data.HeroSlaves = {};
+App.Data.Medicine = {};
 App.Data.Policies = {};
 App.Data.Policies.Selection = {};
 App.Data.SecExp = {};
@@ -31,6 +32,7 @@ App.Desc.Player = {};
 App.Encyclopedia = {};
 App.EndWeek = {};
 App.EndWeek.Player = {};
+App.EndWeek.Shared = {};
 App.Entity = {};
 App.Entity.Utils = {};
 App.Events = {};
@@ -54,7 +56,6 @@ App.Facilities.TransportHub = {};
 App.Interact = {};
 App.Interact.Sale = {};
 App.Intro = {};
-App.Neighbor = {};
 App.MainView = {};
 App.Markets = {};
 App.Medicine = {};
@@ -66,11 +67,18 @@ App.Medicine.Salon = {};
 App.Medicine.Surgery = {};
 App.Medicine.Surgery.Procedures = {};
 App.Medicine.Surgery.Reactions = {};
+App.Mods = {};
+App.Mods.SecExp = {};
+App.Mods.SF = {};
+App.Neighbor = {};
+App.PersonalAttention = {};
 App.RA = {};
-App.SF = {};
-App.SecExp = {};
+App.RA.Activation = {};
+App.Ratings = {};
 App.SlaveAssignment = {};
 App.StartingGirls = {};
+App.Status = {};
+App.Status.storyReady = false;
 App.UI = {};
 App.UI.Cheat = {};
 App.UI.DOM = {};
@@ -79,4 +87,3 @@ App.UI.SlaveInteract = {};
 App.UI.View = {};
 App.Update = {};
 App.Utils = {};
-App.personalAttention = {};
diff --git a/js/003-data/assistantData.js b/js/003-data/assistantData.js
index 512626647898426a5de724a854f1d6a7fe7b7926..e09d7ffcfb22e72cca5d1a2c26ce7001e642de07 100644
--- a/js/003-data/assistantData.js
+++ b/js/003-data/assistantData.js
@@ -16,7 +16,7 @@ App.Data.Assistant.appearanceForFS = new Map([
 	["FSMaturityPreferentialist", ["angel", "businesswoman", "goddess", "incubus", "succubus", "witch"]],
 	["FSSlimnessEnthusiast", ["cherub", "imp", "loli", "schoolgirl", "shemale", "succubus", "witch"]],
 	["FSAssetExpansionist", ["businesswoman", "hypergoddess", "incubus", "shemale", "succubus", "witch"]],
-	["FSPastoralist", ["goddess", "hypergoddess", "incubus", "shemale", "succubus", "witch"]],
+	["FSPastoralist", ["cowgirl", "goddess", "hypergoddess", "incubus", "shemale", "succubus", "witch"]],
 	["FSPhysicalIdealist", ["amazon", "incubus", "shemale", "succubus", "witch"]],
 	["FSHedonisticDecadence", ["goddess", "hypergoddess", "imp", "incubus", "preggololi", "succubus", "witch"]],
 	["FSChattelReligionist", ["angel", "cherub", "goddess", "imp", "incubus", "monstergirl", "succubus", "witch"]],
diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js
index 4d3009c1116326453bae3cb68200f74522250b07..0d7f4a6b8bd84be738d56e4899da8bb196fe5983 100644
--- a/js/003-data/gameVariableData.js
+++ b/js/003-data/gameVariableData.js
@@ -121,15 +121,16 @@ App.Data.defaultGameStateVariables = {
 	seeArcology: 1,
 	seeAvatar: 1,
 	seeBestiality: 0,
+	seeCats: 0,
 	seeCircumcision: 1,
+	seeCustomImagesOnly: 0,
 	seeDesk: 1,
 	seeDetails: 1,
 	seeDicks: 25,
 	seeDicksAffectsPregnancy: 1,
 	seeExtreme: 0,
-	seeCats: 0,
-	seeFCNN: 1,
 	seeFaces: 1,
+	seeFCNN: 1,
 	seeHeight: 0,
 	seeHyperPreg: 0,
 	seeIllness: 1,
@@ -141,6 +142,7 @@ App.Data.defaultGameStateVariables = {
 	seePreg: 1,
 	seeRace: 1,
 	seeReportImages: 1,
+	seeStretching: 1,
 	seeSummaryImages: 1,
 	seeVectorArtHighlights: 1,
 	setSuperSampling: 2,
@@ -173,6 +175,13 @@ App.Data.defaultGameStateVariables = {
 	showMissingSlaves: false,
 	showMissingSlavesSD: false,
 	showNeighborDetails: 1,
+	/**
+	 * | ***Value*** | **Description** |
+	 * |------------:|:----------------|
+	 * | *0*         | Words only      |
+	 * | *1*	     | Both            |
+	 * | *2*    	 | Numbers only    |
+	 */
 	showNumbers: 2,
 	showNumbersMax: 20,
 	showScores: 1,
@@ -226,6 +235,9 @@ App.Data.defaultGameStateVariables = {
 	retirementAge: 45,
 	customRetirementAge: 45,
 	customMenialRetirementAge: 65,
+	idealAge: 18,
+	targetIdealAge: 18,
+	idealAgeAdoption: 0,
 	sortIncubatorList: "Unsorted",
 	AgeEffectOnTrainerPricingPC: 1,
 	AgeEffectOnTrainerEffectivenessPC: 1,
@@ -367,6 +379,7 @@ App.Data.resetOnNGPlus = {
 		},
 
 		childProtectionAct: 1,
+		idealAge: 0,
 		culturalOpenness: 0,
 		proRefugees: 0,
 		publicFuckdolls: 0,
@@ -432,7 +445,6 @@ App.Data.resetOnNGPlus = {
 	/** @type {Array<Array<App.Events.BaseEvent>>} */
 	eventQueue: [],
 
-	rivalID: 0,
 	eliteAuctioned: 0,
 	slavesSacrificedThisWeek: 0,
 
@@ -550,13 +562,10 @@ App.Data.resetOnNGPlus = {
 	dairyPrepUpgrade: 0,
 	dairyStimulatorsUpgrade: 0,
 	dairyStimulatorsSetting: 0,
-	dairyStimulatorsSettingChanged: 0,
 	dairyFeedersUpgrade: 0,
 	dairyFeedersSetting: 0,
-	dairyFeedersSettingChanged: 0,
 	dairyPregUpgrade: 0,
 	dairyPregSetting: 0,
-	dairyPregSettingChanged: 0,
 	dairyRestraintsUpgrade: 0,
 	dairyRestraintsSetting: 0,
 	dairySlimMaintainUpgrade: 0,
@@ -678,8 +687,7 @@ App.Data.resetOnNGPlus = {
 
 	// Farmyard Subsection
 	farmyard: 0,
-	farmyardShowgirls: [],			/* array of farmhands putting on shows */
-	farmyardFarmers: [],			/* array of farmhands farming */
+	farmyardFarmers: [],
 	farmMenials: 0,
 	farmMenialsSpace: 0,
 	/** @type {FC.FutureSocietyDeco} */
@@ -704,11 +712,11 @@ App.Data.resetOnNGPlus = {
 		feline: null,
 	},
 	animals: {
-		/** @type {App.Entity.Animal[]} */
+		/** @type {string[]} */
 		canine: [],
-		/** @type {App.Entity.Animal[]} */
+		/** @type {string[]} */
 		hooved: [],
-		/** @type {App.Entity.Animal[]} */
+		/** @type {string[]} */
 		feline: [],
 	},
 	farmyardName: "the Farmyard",
@@ -775,7 +783,7 @@ App.Data.resetOnNGPlus = {
 		lowerClass: 0, middleClass: 0, upperClass: 0, topClass: 0
 	},
 	arcadePrice: 2,
-	/** @type {App.Entity.SlaveState|number} */
+	/** @type {FC.Zeroable<App.Entity.SlaveState>} */
 	shelterSlave: 0,
 	shelterSlaveBought: 0,
 	shelterAbuse: 0,
@@ -847,7 +855,6 @@ App.Data.resetOnNGPlus = {
 	/** @type {Map<number, "oldAge"|"overdosed"|"lowHealth">} */
 	slaveDeath: new Map(),
 	playerBred: 0,
-	playerBredTube: 0,
 	propOutcome: 0,
 	EliteSires: [],
 	raped: -1,
@@ -991,28 +998,10 @@ App.Data.resetOnNGPlus = {
 	hackerSupport: 0,
 	/** @type {FC.SlaveStateOrZero} */
 	hostage: 0,
-	/** @type {FC.Bool} */
-	hostageAnnounced: 0,
-	/** @type {FC.Bool} */
-	hostageRescued: 0,
-	/** @type {FC.Bool} */
-	hostageGiveIn: 0, // TODO: Set up code block to set to one. This is already checked in src/endWeek/saDevotion.js
 	/** @type {FC.SlaveStateOrZero} */
 	hostageWife: 0,
-	rivalSet: 0,
-	/** @type {FC.Zeroable<FC.FutureSocietyNoun>} */
-	rivalryFS: 0,
-	/** @type {FC.Bool} */
-	rivalryFSAdopted: 0,
-	/** @type {FC.Zeroable<FC.Race>} */
-	rivalryFSRace: 0,
-	rivalOwner: 0,
-	rivalOwnerEnslaved: 0,
-	rivalryPower: 0,
-	rivalryDuration: 0,
-	/** @type {FC.Zeroable<FC.Race>} */
-	rivalRace: 0,
-	rivalGender: 0,
+	/** @type {FC.Rival} */
+	rival: {state: 0, duration: 0, prosperity: 0, power: 0, FS: {name: ""}, hostageState: 0},
 	nationHate: 0,
 	eventResults: {},
 
@@ -1106,6 +1095,9 @@ App.Data.resetOnNGPlus = {
 
 	encyclopedia: "How to Play",
 
+	/**
+	 * @type {Map<string, (Array<FC.TrinketData>|number)>}
+	 */
 	trinkets: new Map([]),
 	SPcost: 1000,
 	debtWarned: 0,
@@ -1214,11 +1206,7 @@ App.Data.resetOnNGPlus = {
 		influence: 0,
 		eventWeek: 0
 	},
-
-	/** @type {FC.Zeroable<FC.PeacekeepersState>} */
-	peacekeepers: 0,
-	peacekeepersFate: 0,
-	peacekeepersGone: 0,
+	/** @type {FC.Peacekeepers} */ peacekeepers: {state: 1},
 	mercRomeo: 0,
 
 	oralUseWeight: 5,
@@ -1293,6 +1281,7 @@ App.Data.resetOnNGPlus = {
 	merchantIllegalWares: App.Data.illegalWares,
 	RapidCellGrowthFormula: 0,
 	immortalityFormula: 0,
+	bioEngineeredFlavoringResearch: 0,
 	UterineRestraintMesh: 0,
 	PGHack: 0,
 	BlackmarketPregAdaptation: 0,
@@ -1344,5 +1333,10 @@ App.Data.resetOnNGPlus = {
 	 * @type {Object.<number, string>}
 	 */
 	choosesOwnAssignmentText: {},
-	favorites: []
+	favorites: [],
+	/**
+	 * Any loans the player has taken out.
+	 * @type {FC.Loan[]}
+	 */
+	loans: [],
 };
diff --git a/js/003-data/medicine/implants.js b/js/003-data/medicine/implants.js
new file mode 100644
index 0000000000000000000000000000000000000000..2a2cd7e51b78cc873fd5ee0144c54236348d012a
--- /dev/null
+++ b/js/003-data/medicine/implants.js
@@ -0,0 +1,256 @@
+/** @type {FC.Data.Medicine.SizingImplants.SizingImplantDatabase} */
+App.Data.Medicine.sizingImplants = {
+	boobs: {
+		normal: {
+			name: volume => volume > 500
+				? "large"
+				: (volume < 300 ? "small" : "standard"),
+			specificMaterialCost: () => V.ImplantProductionUpgrade ? 0.1 : 1.3,
+			workCostFactor: {
+				installation: 1,
+				removal: 0.5
+			},
+			healthCostFactor: {
+				installation: 0.1,
+				removal: 0.05
+			},
+			availableSizes: () => _.range(200, V.ImplantProductionUpgrade ? 601 : 401, 200)
+		},
+		fillable: {
+			name: "fillable",
+			availableSizes: [800],
+			specificMaterialCost: () => V.ImplantProductionUpgrade ? 0.15 : 1.5,
+			workCostFactor: {
+				installation: 1.5,
+				removal: 0.7
+			},
+			healthCostFactor: {
+				installation: 0.05,
+				removal: 0.05
+			},
+			fill: {
+				limit: 1800,
+				step: [200],
+				healthCost: 10,
+				materialCostFactor: 0,
+			},
+			drain: {
+				limit: 800,
+				step: [200],
+				healthCost: 10,
+				materialCostFactor: 0,
+			}
+		},
+		"advanced fillable": {
+			name: () => V.ImplantProductionUpgrade > 0 ? "advanced fillable" : "advanced fillable (special order)",
+			availableSizes: [2200],
+			specificMaterialCost: () => V.ImplantProductionUpgrade > 0 ? 0.4 : 4.5,
+			workCostFactor: {
+				installation: 1.5,
+				removal: 0.7
+			},
+			healthCostFactor: {
+				installation: 0.005,
+				removal: 0.003
+			},
+			fill: {
+				limit: 10000,
+				step: [200, 400, 1000],
+				healthCost: 10,
+				materialCostFactor: 0,
+			},
+			drain: {
+				limit: 2200,
+				step: [200, 400, 1000],
+				healthCost: 5,
+				materialCostFactor: 0,
+			}
+		},
+		"hyper fillable": {
+			name: "hyper fillable",
+			availableSizes: () => FutureSocieties.researchAvailable("TransformationFetishist")
+				? [11000] : [],
+			specificMaterialCost: 0.5,
+			workCostFactor: {
+				installation: 0.5,
+				removal: 0.25
+			},
+			healthCostFactor: {
+				installation: 0.01,
+				removal: 0.005
+			},
+			fill: {
+				limit: 50000,
+				step: [1000],
+				healthCost: 10,
+				materialCostFactor: 0.1,
+			},
+			drain: {
+				limit: 11000,
+				step: [1000],
+				healthCost: 5,
+				materialCostFactor: 0,
+			}
+		},
+		string: {
+			name: "string",
+			availableSizes: [400],
+			specificMaterialCost: () => V.ImplantProductionUpgrade > 0 ? 0.4 : 4,
+			workCostFactor: {
+				installation: 2,
+				removal: 5,
+			},
+			healthCostFactor: {
+				installation: 0.2,
+				removal: 0.005
+			},
+			drain: {
+				limit: 600, // yes, can't be drained dry
+				step: [200],
+				healthCost: 5,
+				materialCostFactor: 0,
+			}
+		}
+	},
+	butt: {
+		normal: {
+			name: volume => volume > 1 ? "large" : "standard",
+			specificMaterialCost: () => V.ImplantProductionUpgrade ? 100 : 130,
+			workCostFactor: {
+				installation: 100,
+				removal: 50
+			},
+			healthCostFactor: {
+				installation: 10,
+				removal: 5
+			},
+			availableSizes: () => V.ImplantProductionUpgrade ? [1, 2] : [1]
+		},
+		fillable: {
+			name: "fillable",
+			availableSizes: [3],
+			specificMaterialCost: () => V.ImplantProductionUpgrade ? 150 : 1500,
+			workCostFactor: {
+				installation: 150,
+				removal: 70
+			},
+			healthCostFactor: {
+				installation: 5,
+				removal: 5
+			},
+			fill: {
+				limit: 4,
+				step: [1],
+				healthCost: 10,
+				materialCostFactor: 0,
+			},
+			drain: {
+				limit: 3,
+				step: [1],
+				healthCost: 5,
+				materialCostFactor: 0,
+			}
+		},
+		"advanced fillable": {
+			name: () => V.ImplantProductionUpgrade > 0 ? "advanced fillable" : "advanced fillable (special order)",
+			availableSizes: [5],
+			specificMaterialCost: () => V.ImplantProductionUpgrade > 0 ? 150 : 1500,
+			workCostFactor: {
+				installation: 600,
+				removal: 300
+			},
+			healthCostFactor: {
+				installation: 2.5,
+				removal: 0.3
+			},
+			fill: {
+				limit: 8,
+				step: [1],
+				healthCost: 10,
+				materialCostFactor: 0,
+			},
+			drain: {
+				limit: 5,
+				step: [1],
+				healthCost: 5,
+				materialCostFactor: 0,
+			}
+		},
+		"hyper fillable": {
+			name: "hyper fillable",
+			availableSizes: () => FutureSocieties.researchAvailable("TransformationFetishist")
+				? [9] : [],
+			specificMaterialCost: 400,
+			workCostFactor: {
+				installation: 100,
+				removal: 50
+			},
+			healthCostFactor: {
+				installation: 2,
+				removal: 1
+			},
+			fill: {
+				limit: 20,
+				step: [1],
+				healthCost: 10,
+				materialCostFactor: 100,
+			},
+			drain: {
+				limit: 9,
+				step: [1],
+				healthCost: 5,
+				materialCostFactor: 0,
+			}
+		},
+		string: {
+			name: "string",
+			availableSizes: [1],
+			specificMaterialCost: () => V.ImplantProductionUpgrade > 0 ? 150 : 1500,
+			workCostFactor: {
+				installation: 800,
+				removal: 500,
+			},
+			healthCostFactor: {
+				installation: 80,
+				removal: 10
+			},
+			drain: {
+				limit: 1,
+				step: [1],
+				healthCost: 5,
+				materialCostFactor: 0,
+			}
+		}
+	},
+	lips: {
+		normal: {
+			availableSizes: [10],
+			name: (volume) => {
+				const names = {
+					10: "moderate",
+					20: "large",
+					100: "enormous"
+				};
+				return App.Ratings.numeric(names, volume);
+			},
+			healthCostFactor: {
+				installation: 1,
+				removal: 0.01,
+			},
+			specificMaterialCost: 0,
+			workCostFactor: {
+				installation: 0,
+				removal: 0,
+			},
+			// this is a fake fill data to implement implant sizing
+			// used because there are no names for large implants and they
+			// can be installed in steps only
+			fill: {
+				healthCost: 10,
+				limit: 90,
+				materialCostFactor: 0,
+				step: [10],
+			}
+		}
+	}
+};
diff --git a/js/003-data/miscData.js b/js/003-data/miscData.js
index d13fea99b4d10fc900f2cab9fe1deb85c36df593..e1cb4a0f4a230fad7f42915189defae9491bd253 100644
--- a/js/003-data/miscData.js
+++ b/js/003-data/miscData.js
@@ -136,6 +136,58 @@ App.Data.misc = {
 			sizeType: 0
 		},
 
+		eggS: {
+			type: "eggModS",
+			normalOvaMin: 30,
+			normalOvaMax: 100,
+			normalBirth: 4,
+			minLiveBirth: 1,
+			drugsEffect: 0.05,
+			fetusWeek: [0, 1, 2, 3, 4, 99999],
+			fetusSize: [1, 100, 225, 350, 500, 500],
+			fetusRate: [4, 4, 4, 4, 4, 4],
+			sizeType: 2
+		},
+
+		eggM: {
+			type: "eggModM",
+			normalOvaMin: 5,
+			normalOvaMax: 30,
+			normalBirth: 4,
+			minLiveBirth: 1,
+			drugsEffect: 0.05,
+			fetusWeek: [0, 1, 2, 3, 4, 99999],
+			fetusSize: [1, 500, 1000, 1500, 2000, 2000],
+			fetusRate: [4, 4, 4, 4, 4, 4],
+			sizeType: 2
+		},
+
+		eggL: {
+			type: "eggModL",
+			normalOvaMin: 5,
+			normalOvaMax: 15,
+			normalBirth: 4,
+			minLiveBirth: 1,
+			drugsEffect: 0.05,
+			fetusWeek: [0, 1, 2, 3, 4, 99999],
+			fetusSize: [1, 500, 2000, 5000, 10000, 10000],
+			fetusRate: [4, 4, 4, 4, 4, 4],
+			sizeType: 2
+		},
+
+		eggXL: {
+			type: "eggModXL",
+			normalOvaMin: 1,
+			normalOvaMax: 1,
+			normalBirth: 4,
+			minLiveBirth: 1,
+			drugsEffect: 0.05,
+			fetusWeek: [0, 1, 2, 3, 4, 99999],
+			fetusSize: [1, 1000, 5000, 10000, 30000, 30000],
+			fetusRate: [4, 4, 4, 4, 4, 4],
+			sizeType: 2
+		},
+
 	},
 	/* Source data for canine include CTR (not head to toe size), so CTR do not apply anywhere, always 1.*/
 	/* sizeType: control of source data type 0 - length in centimeters for fetusSize and CTR for fetusRate, 1 - weight in grams and womb to fetus rate, 2 - direct volume in cc, fetusRate not used*/
@@ -163,6 +215,7 @@ App.Data.misc = {
 	})(),
 
 	/**
+	 * All active races
 	 * @returns {Map<FC.Race, string>}
 	 */
 	get filterRaces() {
@@ -173,6 +226,18 @@ App.Data.misc = {
 		return map;
 	},
 
+	/**
+	 * All races that are publicly available
+	 * @returns {Map<FC.Race, string>}
+	 */
+	get filterRacesPublic() {
+		const map = new Map(App.Data.misc.filterRacesBase);
+		if (V.seeCats && V.projectN.techReleased) {
+			map.set("catgirl", "Catgirl");
+		}
+		return map;
+	},
+
 	filterRegions: ["Africa", "Asia", "Australia", "Europe", "Middle East", "North America", "South America"],
 
 	/* START Custom Nationalities region filter */
@@ -1461,7 +1526,7 @@ App.Data.misc = {
 
 	militaryCriminalPool: ["deserter", "gunner", "officer", "private", "sniper", "soldier", "specOps", "spy", "terrorist", "war criminal"],
 
-	juvenileCriminalPool: ["theft", "robbery", "pickpocketing", "assault", "manslaughter", "smuggling", "mule", "prostitution", "truancy", "curfew"],
+	juvenileCriminalPool: ["assault", "curfew", "manslaughter", "mule", "pickpocketing", "prostitution", "robbery", "smuggling", "theft", "truancy"],
 
 	fakeBellies: ["a huge empathy belly", "a large empathy belly", "a medium empathy belly", "a small empathy belly"],
 	/* lets fake bellies be separated from other .bellyAccessory */
@@ -1733,6 +1798,8 @@ App.Data.misc = {
 		},
 	},
 
+	redheadColors: ["auburn", "blazing red", "copper", "chestnut", "deep red", "ginger", "red", "strawberry-blonde"],
+
 	badWords: ["anus", "ass", "bitch", "boob", "butt", "cock", "crap", "cum", "cunny", "cunt", "dick", "fuck", "jizz", "junk", "piss", "prick", "pussy", "shit", "slave", "slut", "tit", "trash", "whore"],
 
 	badNames: ["Ass Kisser", "Ass Licker", "Ass", "Assfucker", "Asshole", "Ballsack", "Bastard", "Beta", "Bitch", "Cock", "Cocksucker", "Coward", "Creep", "Cum Rag", "Cunt", "Degenerate", "Despoiler", "Dick", "Dickhead", "Dicksucker", "Dickweed", "Dipshit", "Douchebag", "Dumbass", "DumbFuck", "Dunderfuck", "Dyke", "Faggot", "Fucker", "Fuckface", "Fuckhead", "Fucko", "Fucktard", "Fuckwit", "Idiot", "Inbred", "Jackass", "Jerk", "Jizz Stain", "Loser", "Moron", "Motherfucker", "Nutsack", "Pissbaby", "Prick", "Pussy", "Rapist", "Ratfuck", "Retard", "Ruiner", "Schmuck", "Scumbag", "Shitbird", "Shithead", "Slave", "Slaver", "Sleazeball", "Slut", "Sodomite", "Thundercunt", "Traitor", "Trash", "Whore", "Wimp"],
diff --git a/js/003-data/miscDataNames.js b/js/003-data/miscDataNames.js
index c14677fcf5aa948669d2a392bfa99b4721991faa..3371fe8233c87d1048b9ac440dfeafda2262346b 100644
--- a/js/003-data/miscDataNames.js
+++ b/js/003-data/miscDataNames.js
@@ -224,9 +224,1011 @@ App.Data.misc.czechMaleNames = ["Adam", "Adolf", "Aleš", "Alexander", "Alexandr
 App.Data.misc.czechSlaveSurnames = ["Absolonová", "Adamcová", "Adamíková", "Adámková", "Adamová", "Antošová", "Bábova", "Bajerová", "Balážová", "Balogová", "Barešová", "Bartáková", "Bartoňová", "Bartošová", "Bartová", "Bártová", "Bauerová", "Bednaříková", "Bednárová", "Bednářová", "Bělonohá", "Bendová", "Benešová", "Beránková", "Beranová", "Berková", "Bezděková", "Bilá", "Bilková", "Bílková", "Blahová", "Bláhová", "Blažková", "Blechová", "Bočanová", "Bocková", "Bočková", "Boháčová", "Bohmanová", "Böhmová", "Brabcová", "Braunerová", "Brázdová", "Brejchová", "Březinová", "Brožková", "Brožová", "Bubeníčková", "Buchtová", "Bugárová", "Bukovská", "Burdová", "Burešová", "Burianová", "Čapková", "Čápová", "Čechová", "Čejková", "Čermáková", "Černá", "Červená", "Červenková", "Červinková", "Chaloupková", "Chalupová", "Charvátová", "Chládková", "Chlastáková", "Chlebovská", "Chmelařová", "Chmelíková", "Chmelová", "Chorváthová", "Chovancová", "Chramostová", "Chudá", "Chytilová", "Cibulková", "Čiháková", "Čížková", "Čonková", "Coufalová", "Čuboňová", "Danielová", "Danková", "Daňková", "Davidová", "Demčová", "Demeterová", "Desenská", "Divišová", "Dlouhá", "Dobešová", "Dočkalová", "Dohnalová", "Dolejšová", "Doležalová", "Doleželová", "Dostalová", "Dostálová", "Doubková", "Drabínová", "Drábková", "Drahotová", "Drajzajtlová", "Drobná", "Drtinová", "Dubská", "Dudková", "Dudová", "Dufková", "Dušková", "Dvořáčková", "Dvoráková", "Dvořáková", "Eliášová", "Fajksová", "Fastrová", "Ferencová", "Fialová", "Fibingerová", "Filipová", "Fischerová", "Fišerová", "Fojtíková", "Formánková", "Formanová", "Francová", "Franková", "Gabrielová", "Gajdošová", "Glosová", "Gregorová", "Hajková", "Hájková", "Hamplová", "Hanáková", "Haničincová", "Hanusová", "Hanzlíková", "Hašková", "Havelková", "Havlíčková", "Havlíková", "Havlová", "Havránková", "Hejdová", "Hejnová", "Herman", "Hermanová", "Heřmanová", "Herzigová", "Hladíková", "Hladká", "Hlavačková", "Hlaváčková", "Hlaváčová", "Hlavatá", "Hlavoňová", "Hloušková", "Hofmanová", "Holá", "Holečková", "Holíková", "Holotová", "Holubová", "Holušová", "Homolková", "Homolová", "Horáčková", "Horáková", "Hořejšová", "Horká", "Horová", "Horvathová", "Horváthová", "Hošková", "Houdková", "Housková", "Hovorková", "Hradilová", "Hrbková", "Hrdinová", "Hrdličková", "Hromkovičová", "Hronová", "Hrstková", "Hrubá", "Hrušková", "Hubáčková", "Hudcová", "Hudečková", "Husáková", "Hynková", "Irrová", "Jakubcová", "Jandová", "Janečková", "Janíčková", "Janíková", "Janků", "Janoušková", "Janovská", "Janská", "Jánská", "Jansová", "Janů", "Jarošová", "Javůrková", "Jebavá", "Jedličková", "Jelinková", "Jelínková", "Jeřábková", "Ježková", "Jílková", "Jindrová", "Jirásková", "Jiříčková", "Jirků", "Jonášová", "Jurečková", "Juškova", "Kadlecová", "Kafková", "Kalinová", "Kalivodová", "Kaminková", "Kaňová", "Kantorková", "Kantorová", "Kaplanová", "Karásková", "Karasová", "Kašpárková", "Kašparová", "Kindermann", "Kleinová", "Klementová", "Klimešová", "Klimová", "Klímová", "Klučinová", "Knotková", "Kocembová", "Kočí", "Kocianová", "Kocourková", "Kočová", "Kohoutková", "Kohoutová", "Koláčková", "Kolaříková", "Kolárová", "Kolářová", "Komárková", "Konečná", "Konvalinková", "Kopáčiková", "Kopecká", "Kopečková", "Kopřivová", "Kořínková", "Kosová", "Košťálová", "Kostková", "Kotková", "Koubková", "Koubová", "Koudelková", "Kouřilová", "Koutná", "Kovačová", "Kovaříková", "Kovárová", "Kovářová", "Kozáková", "Kožešníková", "Kozlová", "Králíčková", "Králová", "Krátká", "Kratochvilová", "Kratochvílová", "Krausová", "Krejčíková", "Krejčová", "Křenková", "Křivánková", "Křížková", "Křížová", "Kroupová", "Krupičková", "Kubátová", "Kubešová", "Kubičková", "Kubíčková", "Kubíková", "Kubínová", "Kubová", "Kučerová", "Kuchařová", "Kudělka", "Kudličková", "Kudrnová", "Kulhánková", "Kuncová", "Kupková", "Kurková", "Kuželová", "Kvapilová", "Kvasničková", "Kynosová", "Lacinová", "Laláková", "Landová", "Langerová", "Langová", "Látalová", "Linhartová", "Lisková", "Lišková", "Lorencová", "Ludvíková", "Lukášová", "Lukešová", "Lupínková", "Lustigová", "Lutovská", "Machačková", "Macháčková", "Machačová", "Machalová", "Machová", "Macková", "Majerová", "Majorová", "Mäki", "Malá", "Malíková", "Malinová", "Málková", "Malysová", "Marečková", "Marešová", "Maříková", "Markova", "Marková", "Martincová", "Martinková", "Martínková", "Mašková", "Masláková", "Matejková", "Matějková", "Matějkovičová", "Matoušková", "Matulová", "Matušková", "Melicharová", "Menšíková", "Mertlíková", "Mezuliáníková", "Michalková", "Michálková", "Michalová", "Micková", "Mikešová", "Miková", "Mikulášová", "Mikulová", "Minaříková", "Moravčíková", "Moravcová", "Morávková", "Morkesová", "Mrázková", "Mrázová", "Muchová", "Müllerová", "Munclingerová", "Musilová", "Mužíková", "Myslivečková", "Navrátilová", "Nečasová", "Nedvědová", "Nejedlá", "Nekolová", "Nemcová", "Němcová", "Němečková", "Nesvadbová", "Neumannová", "Nguyenová", "Nosková", "Nová", "Nováčková", "Novaková", "Nováková", "Novotná", "Nývltová", "Odložilová", "Olahová", "Ondráčková", "Paličková", "Pánková", "Pařízková", "Pavelková", "Pavlíčková", "Pavlíková", "Pavlů", "Pazderová", "Pechová", "Pecková", "Pekárková", "Pelantová", "Pelcová", "Pelikánová", "Pešavová", "Peskova", "Pešková", "Peterková", "Petrova", "Petrová", "Petrů", "Pilařová", "Pitáková", "Plachá", "Podkapová", "Pokorná", "Poláčková", "Poláková", "Polášková", "Polívková", "Poloniová", "Popelková", "Pospíchalová", "Pospíšilová", "Potyšová", "Prachařová", "Pražáková", "Prchalová", "Preissová", "Přibylová", "Přikrylová", "Procházková", "Prokešová", "Prokopová", "Průchová", "Průšová", "Ptáčková", "Ptáčníková", "Putnová", "Radová", "Rašková", "Reháková", "Řeháková", "Řezáčová", "Řezníčková", "Richterová", "Říhová", "Rosolová", "Rulcová", "Ružičková", "Růžičková", "Ryšavá", "Šafránková", "Samková", "Sátorová", "Ščerbová", "Schneiderová", "Schwarzová", "Šebestová", "Šebková", "Šedivá", "Sedláčková", "Sedláková", "Seidlová", "Sekanová", "Sekerová", "Sekyrová", "Šeredová", "Šestáková", "Ševčíková", "Sikorová", "Šilhavá", "Šimečková", "Šimková", "Simonová", "Šímová", "Šimůnková", "Šindelářová", "Siváková", "Skalická", "Skaličková", "Skalová", "Sklenářová", "Škodová", "Škorpilová", "Škrobáková", "Slabá", "Sládková", "Slámová", "Slavíčková", "Slavíková", "Slezáková", "Slováková", "Smejkalová", "Šmerdová", "Smetanová", "Šmidová", "Šmídová", "Smolíková", "Smrčková", "Smržová", "Smutná", "Šnajdrová", "Šoborová", "Sobotková", "Sochorová", "Sojková", "Sokolová", "Šolcová", "Šormová", "Součková", "Soukupová", "Sovová", "Spáčilová", "Špačková", "Špotáková", "Spurná", "Šrámková", "Srbová", "Stanková", "Staňková", "Stará", "Šťastná", "Štefková", "Stehlíková", "Stejskalová", "Štěpánková", "Štěpánová", "Štěrbová", "Straková", "Strankmüllerová", "Stránská", "Stráská", "Strejčková", "Strnadová", "Stromšíkova", "Studená", "Šubrtová", "Suchá", "Suchánková", "Suková", "Šulcová", "Šustrová", "Švarcová", "Svatošová", "Švecová", "Švejdová", "Svitáková", "Svobodová", "Sýkorová", "Synková", "Teplá", "Tesáčková", "Tesařová", "Theodorová", "Tichá", "Tománková", "Tomanová", "Tomášková", "Tomečková", "Tomková", "Trávníčková", "Trnková", "Trojanová", "Tučková", "Tumová", "Tůmová", "Turková", "Uhlířová", "Uhrinová", "Uhrová", "Urbánková", "Urbanová", "Uvizlová", "Vachová", "Váchová", "Vacková", "Václavíčková", "Václavíková", "Vaculíková", "Vagnerová", "Valášková", "Valentová", "Valešová", "Válková", "Valová", "Vančurová", "Vaněčková", "Vaníčková", "Vanková", "Vaňková", "Váňová", "Vařeková", "Vargová", "Vašíčková", "Vašková", "Vavrová", "Vávrová", "Večeřová", "Velebová", "Vernerová", "Veselá", "Veverková", "Vilhelmová", "Vítková", "Vítová", "Vlachová", "Vlasáková", "Vlčková", "Vlková", "Vodičková", "Vojáčková", "Vojtová", "Volfová", "Vondráčková", "Vondráková", "Vondrová", "Votavová", "Vozáková", "Vrabcová", "Vraná", "Vranová", "Vránová", "Vrbová", "Vrzalová", "Vybíralová", "Vydrová", "Vyskočilová", "Wagnerová", "Walterová", "Wolfová", "Zachová", "Žáčková", "Zahradníková", "Zajíčková", "Zajícová", "Žáková", "Zámečníková", "Zapletalová", "Zárubová", "Zatloukalová", "Zátopková", "Zavadilová", "Zbořilová", "Zelená", "Zelenková", "Zelenohorská", "Železná", "Železnovová", "Zelinková", "Zemánková", "Zemanová", "Zikmundová", "Ziková", "Zimová", "Žižková", "Zvarová", "Zvěřinová", "Zvolenská"];
 App.Data.misc.czechMaleSurnames = {"Absolonová": "Absolon", "Adamcová": "Adamec", "Adamíková": "Adamík", "Adámková": "Adámek", "Adamová": "Adam", "Antošová": "Antoš", "Bábova": "Bába", "Bajerová": "Bajer", "Balážová": "Baláž", "Balogová": "Balog", "Barešová": "Bareš", "Bartáková": "Barták", "Bartoňová": "Bartoň", "Bartošová": "Bartoš", "Bartová": "Barta", "Bártová": "Bárta", "Bauerová": "Bauer", "Bednaříková": "Bednařík", "Bednárová": "Bednár", "Bednářová": "Bednář", "Bělonohá": "Bělonohý", "Bendová": "Benda", "Benešová": "Beneš", "Beránková": "Beránek", "Beranová": "Beran", "Berková": "Berka", "Bezděková": "Bezděk", "Bilá": "Bilý", "Bilková": "Bilek", "Bílková": "Bílek", "Blahová": "Blaha", "Blahová": "Bláha", "Bláhová": "Bláha", "Blažková": "Blažek", "Blechová": "Blech", "Bočanová": "Bočan", "Bočková": "Boček", "Bocková": "Bock", "Boháčová": "Boháč", "Bohmanová": "Bohman", "Böhmová": "Böhm", "Brabcová": "Brabec", "Braunerová": "Brauner", "Brázdová": "Brázda", "Brejchová": "Brejcha", "Březinová": "Březina", "Brožková": "Brožek", "Brožová": "Brož", "Bubeníčková": "Bubeníček", "Buchtová": "Buchta", "Bugárová": "Bugár", "Bukovská": "Bukovský", "Burdová": "Burda", "Burešová": "Bureš", "Burianová": "Burian", "Čapková": "Čapek", "Čápová": "Čáp", "Čechová": "Čech", "Čejková": "Čejka", "Čermáková": "Čermák", "Černá": "Černý", "Červená": "Červený", "Červenková": "Červenka", "Červinková": "Červinka", "Chaloupková": "Chaloupka", "Chalupová": "Chalupa", "Charvátová": "Charvát", "Chládková": "Chládek", "Chlastáková": "Chlasták", "Chlebovská": "Chlebovský", "Chmelařová": "Chmelař", "Chmelíková": "Chmelík", "Chmelová": "Chmel", "Chorváthová": "Chorváth", "Chovancová": "Chovanec", "Chramostová": "Chramosta", "Chudá": "Chudý", "Chytilová": "Chytil", "Cibulková": "Cibulka", "Čiháková": "Čihák", "Čížková": "Čížek", "Čonková": "Čonka", "Coufalová": "Coufal", "Čuboňová": "Čuboň", "Danielová": "Daniel", "Danková": "Danek", "Daňková": "Daněk", "Davidová": "David", "Demčová": "Demeč", "Demeterová": "Demeter", "Desenská": "Desenský", "Divišová": "Diviš", "Dlouhá": "Dlouhý", "Dobešová": "Dobeš", "Dočkalová": "Dočkal", "Dohnalová": "Dohnal", "Dolejšová": "Dolejš", "Doležalová": "Doležal", "Doleželová": "Doležel", "Dostalová": "Dostal", "Dostálová": "Dostál", "Doubková": "Doubek", "Drabínová": "Drabín", "Drábková": "Drábek", "Drahotová": "Drahota", "Drajzajtlová": "Drajzajtl", "Drobná": "Drobný", "Drtinová": "Drtina", "Dubská": "Dubský", "Dudková": "Dudek", "Dudová": "Duda", "Dufková": "Dufek", "Dušková": "Dušek", "Dvořáčková": "Dvořáček", "Dvoráková": "Dvorák", "Dvořáková": "Dvořák", "Eliášová": "Eliáš", "Fajksová": "Fajks", "Fastrová": "Faster", "Ferencová": "Ferenc", "Fialová": "Fiala", "Fibingerová": "Fibinger", "Filipová": "Filip", "Fischerová": "Fischer", "Fišerová": "Fišer", "Fojtíková": "Fojtík", "Formánková": "Formánek", "Formanová": "Forman", "Francová": "Franc", "Franková": "Franek", "Gabrielová": "Gabriel", "Gajdošová": "Gajdoš", "Glosová": "Glos", "Gregorová": "Gregor", "Hajková": "Hajek", "Hájková": "Hájek", "Hamplová": "Hampl", "Hanáková": "Hanák", "Haničincová": "Haničinec", "Hanusová": "Hanus", "Hanzlíková": "Hanzlík", "Hašková": "Hašek", "Havelková": "Havelka", "Havlíčková": "Havlíček", "Havlíková": "Havlík", "Havlová": "Havel", "Havránková": "Havránek", "Hejdová": "Hejda", "Hejnová": "Hejna", "Hermanová": "Herman", "Heřmanová": "Heřman", "Herzigová": "Herzig", "Hladíková": "Hladík", "Hladká": "Hladký", "Hlaváčková": "Hlaváček", "Hlavačková": "Hlavačka", "Hlaváčová": "Hlaváč", "Hlavatá": "Hlavatý", "Hlavoňová": "Hlavoň", "Hloušková": "Hloušek", "Hofmanová": "Hofman", "Holá": "Holý", "Holečková": "Holeček", "Holíková": "Holík", "Holotová": "Holota", "Holubová": "Holub", "Holušová": "Holuša", "Homolková": "Homolka", "Homolová": "Homola", "Horáčková": "Horáček", "Horáková": "Horák", "Hořejšová": "Hořejší", "Horká": "Horký", "Horová": "Hora", "Horvathová": "Horvath", "Horváthová": "Horváth", "Hošková": "Hošek", "Houdková": "Houdek", "Housková": "Houska", "Hovorková": "Hovorka", "Hradilová": "Hradil", "Hrbková": "Hrbek", "Hrdinová": "Hrdina", "Hrdličková": "Hrdlička", "Hromkovičová": "Hromkovič", "Hronová": "Hron", "Hrstková": "Hrstka", "Hrubá": "Hrubý", "Hrušková": "Hruška", "Hubáčková": "Hubáček", "Hudcová": "Hudec", "Hudečková": "Hudeček", "Husáková": "Husák", "Hynková": "Hynek", "Irrová": "Irra", "Jakubcová": "Jakubec", "Jandová": "Janda", "Janečková": "Janeček", "Janíčková": "Janíček", "Janíková": "Janík", "Janoušková": "Janoušek", "Janovská": "Janovský", "Janská": "Jánský", "Jánská": "Janský", "Jansová": "Jansa", "Jarošová": "Jaroš", "Javůrková": "Javůrek", "Jebavá": "Jebavý", "Jedličková": "Jedlička", "Jelinková": "Jelinek", "Jelínková": "Jelínek", "Jeřábková": "Jeřábek", "Ježková": "Ježek", "Jílková": "Jílek", "Jindrová": "Jindra", "Jirásková": "Jirásek", "Jiříčková": "Jiříček", "Jonášová": "Jonáš", "Jurečková": "Jurečka", "Jušková": "Juška", "Kadlecová": "Kadlec", "Kafková": "Kafka", "Kalinová": "Kalina", "Kalivodová": "Kalivoda", "Kaminková": "Kamínek", "Kaňová": "Kaňa", "Kantorková": "Kantorek", "Kantorová": "Kantor", "Kaplanová": "Kaplan", "Karásková": "Karásek", "Karasová": "Karas", "Kašpárková": "Kašpárek", "Kašparová": "Kašpar", "Kleinová": "Klein", "Klementová": "Klement", "Klimešová": "Klimeš", "Klimová": "Klima", "Klímová": "Klíma", "Klučinová": "Klučina", "Knotková": "Knotek", "Kocembová": "Kocemba", "Kocianová": "Kocian", "Kocourková": "Kocourek", "Kočová": "Kočí", "Kohoutková": "Kohoutek", "Kohoutová": "Kohout", "Koláčková": "Koláček", "Kolaříková": "Kolařík", "Kolárová": "Kolár", "Kolářová": "Kolár", "Kolářová": "Kolář", "Komárková": "Komárek", "Konečná": "Konečný", "Konvalinková": "Konvalinka", "Kopáčiková": "Kopáčik", "Kopecká": "Kopecký", "Kopečková": "Kopeček", "Kopřivová": "Kopřiva", "Kořínková": "Kořínek", "Kosová": "Kos", "Košťálová": "Košťál", "Kostková": "Kostka", "Kotková": "Kotek", "Koubková": "Koubek", "Koubová": "Kouba", "Koudelková": "Koudelka", "Kouřilová": "Kouřil", "Koutná": "Koutný", "Kovačová": "Kovač", "Kovaříková": "Kovařík", "Kovárová": "Kovár", "Kovářová": "Kovář", "Kozáková": "Kozák", "Kožešníková": "Kožešník", "Kozlová": "Kozel", "Králíčková": "Králíček", "Králová": "Král", "Krátká": "Krátký", "Kratochvilová": "Kratochvil", "Kratochvílová": "Kratochvíl", "Krausová": "Kraus", "Krausová": "Krause", "Krejčíková": "Krejčík", "Krejčová": "Krejča", "Krejčová": "Krejčí", "Křenková": "Křenek", "Křivánková": "Křivánek", "Křížková": "Křížek", "Křížová": "Kříž", "Kroupová": "Kroupa", "Krupičková": "Krupička", "Kubátová": "Kubát", "Kubešová": "Kubeš", "Kubičková": "Kubiček", "Kubíčková": "Kubíček", "Kubíková": "Kubík", "Kubínová": "Kubín", "Kubová": "Kuba", "Kučerová": "Kučera", "Kuchařová": "Kuchař", "Kudrnová": "Kudrna", "Kulhánková": "Kulhánek", "Kuncová": "Kunc", "Kupková": "Kupka", "Kurková": "Kurka", "Kuželová": "Kužel", "Kvapilová": "Kvapil", "Kvasničková": "Kvasnička", "Kynosová": "Kynos", "Lacinová": "Lacina", "Laláková": "Lalák", "Landová": "Landa", "Langerová": "Langer", "Langová": "Lang", "Látalová": "Látal", "Linhartová": "Linhart", "Lisková": "Liska", "Lišková": "Liška", "Lorencová": "Lorenc", "Ludvíková": "Ludvík", "Lukášová": "Lukáš", "Lukešová": "Lukeš", "Lupínková": "Lupínek", "Lustigová": "Lustig", "Lutovská": "Lutov", "Macháčková": "Macháček", "Machačková": "Machačka", "Machačová": "Machač", "Machalová": "Machala", "Machová": "Mach", "Macková": "Macek", "Majerová": "Majer", "Majorová": "Major", "Malá": "Malý", "Malíková": "Malík", "Malinová": "Malina", "Málková": "Málek", "Malysová": "Malysa", "Marečková": "Mareček", "Marešová": "Mareš", "Maříková": "Mařík", "Marková": "Marek", "Markova": "Markov", "Martincová": "Martinec", "Martinková": "Martinek", "Martínková": "Martínek", "Mašková": "Mašek", "Masláková": "Maslák", "Matejková": "Matejka", "Matějková": "Matějka", "Matějkovičová": "Matějkovič", "Matoušková": "Matoušek", "Matulová": "Matula", "Matušková": "Matuška", "Melicharová": "Melichar", "Menšíková": "Menšík", "Mertlíková": "Mertlík", "Mezihoráková": "Mezihorák", "Mezuliáníková": "Mezuliáník", "Michálková": "Michálek", "Michalková": "Michalka", "Michalová": "Michal", "Micková": "Micka", "Mikešová": "Mikeš", "Miková": "Mika", "Mikulášová": "Mikuláš", "Mikulová": "Mikula", "Minaříková": "Minařík", "Moravčíková": "Moravčík", "Moravcová": "Moravec", "Morávková": "Morávek", "Morkesová": "Morkes", "Mrázková": "Mrázek", "Mrázová": "Mráz", "Muchová": "Mucha", "Müllerová": "Müller", "Munclingerová": "Munclinger", "Musilová": "Musil", "Mužíková": "Mužík", "Myslivečková": "Mysliveček", "Navrátilová": "Navrátil", "Nečasová": "Nečas", "Nedvědová": "Nedvěd", "Nejedlá": "Nejedlý", "Nekolová": "Nekola", "Nemcová": "Nemec", "Němcová": "Němec", "Němečková": "Němeček", "Nesvadbová": "Nesvadba", "Neumannová": "Neumann", "Nguyenová": "Nguyen", "Nosková": "Nosek", "Nová": "Nový", "Nováčková": "Nováček", "Novaková": "Novak", "Nováková": "Novák", "Novotná": "Novotný", "Nývltová": "Nývlt", "Odložilová": "Odložil", "Olahová": "Olah", "Ondráčková": "Ondráček", "Paličková": "Palička", "Pánková": "Pánek", "Pařízková": "Pařízek", "Pavelková": "Pavelka", "Pavlíčková": "Pavlíček", "Pavlíková": "Pavlík", "Pazderová": "Pazdera", "Pechová": "Pech", "Pecková": "Peck", "Pekárková": "Pekárek", "Pelantová": "Pelant", "Pelcová": "Pelc", "Pelikánová": "Pelikán", "Pešavová": "Pešava", "Pešková": "Pešek", "Peskova": "Peskov", "Peterková": "Peterka", "Petrová": "Petr", "Petrova": "Petrov", "Pilařová": "Pilař", "Pitáková": "Piták", "Plachá": "Plachý", "Podkapová": "Podkap", "Pokorná": "Pokorný", "Poláčková": "Poláček", "Poláková": "Polák", "Polášková": "Polášek", "Polívková": "Polívka", "Poloniová": "Polonia", "Popelková": "Popelka", "Pospíchalová": "Pospíchal", "Pospíšilová": "Pospíšil", "Potyšová": "Potyš", "Prachařová": "Prachař", "Pražáková": "Pražák", "Prchalová": "Prchal", "Preissová": "Preiss", "Přibylová": "Přibyl", "Přikrylová": "Přikryl", "Procházková": "Procházka", "Prokešová": "Prokeš", "Prokopová": "Prokop", "Průchová": "Průcha", "Průšová": "Průš", "Průšová": "Průša", "Ptáčková": "Ptáček", "Ptáčníková": "Ptáčník", "Putnová": "Putna", "Radová": "Rada", "Rašková": "Raška", "Reháková": "Rehák", "Řeháková": "Řehák", "Řezáčová": "Řezáč", "Řezníčková": "Řezníček", "Richterová": "Richter", "Říhová": "Říha", "Rosolová": "Rosol", "Rulcová": "Rulc", "Růžičková": "Růžičk", "Ružičková": "Ružička", "Růžičková": "Růžička", "Ryšavá": "Ryšavý", "Šafránková": "Šafránek", "Samková": "Samek", "Sátorová": "Sátora", "Ščerbová": "Ščerba", "Schneiderová": "Schneider", "Schwarzová": "Schwarz", "Šebestová": "Šebesta", "Šebková": "Šebek", "Šedivá": "Šedivý", "Sedláčková": "Sedláček", "Sedláková": "Sedlák", "Seidlová": "Seidl", "Sekanová": "Sekana", "Sekerová": "Sekera", "Sekyrová": "Sekyra", "Šeredová": "Šereda", "Šestáková": "Šesták", "Ševčíková": "Ševčík", "Sikorová": "Sikora", "Šilhavá": "Šilhavý", "Šimečková": "Šimeček", "Šimková": "Šimek", "Simonová": "Simon", "Šímová": "Šíma", "Šimůnková": "Šimůnek", "Šindelářová": "Šindelář", "Siváková": "Sivák", "Skalická": "Skalický", "Skaličková": "Skalička", "Skalová": "Skala", "Sklenářová": "Sklenář", "Škodová": "Škoda", "Škorpilová": "Škorpil", "Škrobáková": "Škrobák", "Slabá": "Slabý", "Sládková": "Sládek", "Slámová": "Sláma", "Slavíčková": "Slavíček", "Slavíková": "Slavík", "Slezáková": "Slezák", "Slováková": "Slovák", "Smejkalová": "Smejkal", "Šmerdová": "Šmerda", "Smetanová": "Smetana", "Šmidová": "Šmid", "Šmídová": "Šmíd", "Smolíková": "Smolík", "Smrčková": "Smrček", "Smržová": "Smrž", "Smutná": "Smutný", "Šnajdrová": "Šnajdr", "Šoborová": "Šobor", "Sobotková": "Sobotka", "Sochorová": "Sochor", "Sojková": "Sojka", "Sokolová": "Sokol", "Šolcová": "Šolc", "Šormová": "Šorm", "Součková": "Souček", "Soukupová": "Soukop", "Soukupová": "Soukup", "Sovová": "Sova", "Spáčilová": "Spáčil", "Špačková": "Špaček", "Špotáková": "Špoták", "Spurná": "Spurný", "Šrámková": "Šrámek", "Srbová": "Srb", "Stanková": "Stanek", "Staňková": "Staněk", "Staňková": "Staňek", "Stará": "Starý", "Šťastná": "Šťastný", "Štefková": "Štefek", "Stehlíková": "Stehlík", "Stejskalová": "Stejskal", "Štěpánková": "Štěpánek", "Štěpánová": "Štěpán", "Štěrbová": "Štěrba", "Straková": "Straka", "Strankmüllerová": "Strankmüller", "Stránská": "Stránský", "Stráská": "Stráský", "Strejčková": "Strejček", "Strnadová": "Strnad", "Stromšíková": "Stromšík", "Studená": "Studený", "Šubrtová": "Šubrt", "Suchá": "Suchý", "Suchánková": "Suchánek", "Suková": "Suk", "Šulcová": "Šulc", "Šustrová": "Šustr", "Švarcová": "Švarc", "Svatošová": "Svatoš", "Švecová": "Švec", "Švejdová": "Švejda", "Svitáková": "Sviták", "Svobodová": "Svoboda", "Sýkorová": "Sýkora", "Synková": "Synek", "Teplá": "Teplý", "Tesáčková": "Tesáček", "Tesařová": "Tesař", "Theodorová": "Theodor", "Tichá": "Tichý", "Tománková": "Tománek", "Tomanová": "Toman", "Tomášková": "Tomášek", "Tomečková": "Tomeček", "Tomková": "Tomek", "Trávníčková": "Trávníček", "Trnková": "Trnka", "Trojanová": "Trojan", "Tučková": "Tuček", "Tumová": "Tuma", "Tůmová": "Tůma", "Turková": "Turek", "Uhlířová": "Uhlíř", "Uhrinová": "Uhrin", "Uhrová": "Uher", "Urbánková": "Urbánek", "Urbanová": "Urban", "Uvizlová": "Uvizl", "Vachová": "Vach", "Váchová": "Vácha", "Vacková": "Vacek", "Václavíčková": "Václavíček", "Václavíková": "Václavík", "Vaculíková": "Vaculík", "Vagnerová": "Vagner", "Valášková": "Valášek", "Valentová": "Valenta", "Valešová": "Valeš", "Válková": "Válek", "Valová": "Vala", "Vančurová": "Vančura", "Vaněčková": "Vaněček", "Vaníčková": "Vaníček", "Vanková": "Vanek", "Vaňková": "Vaněk", "Vaňková": "Vaňek", "Váňová": "Váňa", "Vařeková": "Vařeka", "Vargová": "Varga", "Vašíčková": "Vašíček", "Vašková": "Vašek", "Vavrová": "Vavra", "Vávrová": "Vávra", "Večeřová": "Večeřa", "Velebová": "Veleba", "Vernerová": "Verner", "Veselá": "Veselý", "Veverková": "Veverka", "Vilhelmová": "Vilhelm", "Vítková": "Vitek", "Vítková": "Vítek", "Vítová": "Vít", "Vlachová": "Vlach", "Vlasáková": "Vlasák", "Vlčková": "Vlček", "Vlková": "Vlk", "Vodičková": "Vodička", "Vojáčková": "Vojáček", "Vojtová": "Vojta", "Volfová": "Volf", "Vondráčková": "Vondráček", "Vondráková": "Vondrák", "Vondrová": "Vondra", "Votavová": "Votava", "Vozáková": "Vozák", "Vrabcová": "Vrabec", "Vraná": "Vraný", "Vranová": "Vrana", "Vránová": "Vrána", "Vrbová": "Vrba", "Vrzalová": "Vrzal", "Vybíralová": "Vybíral", "Vydrová": "Vydra", "Vyskočilová": "Vyskočil", "Wagnerová": "Wagner", "Walterová": "Walter", "Wolfová": "Wolf", "Zachová": "Zach", "Žáčková": "Žáček", "Zahradníková": "Zahradník", "Zajíčková": "Zajíček", "Zajícová": "Zajíc", "Žáková": "Žák", "Zámečníková": "Zámečník", "Zapletalová": "Zapletal", "Zárubová": "Záruba", "Zatloukalová": "Zatloukal", "Zátopková": "Zátopek", "Zavadilová": "Zavadil", "Zbořilová": "Zbořil", "Zelená": "Zelený", "Zelenková": "Zelenka", "Zelenohorská": "Zelenohorský", "Železná": "Železný", "Železnovová": "Železnov", "Zelinková": "Zelinka", "Zemánková": "Zemánek", "Zemanová": "Zeman", "Zikmundová": "Zikmund", "Ziková": "Zika", "Zimová": "Zima", "Žižková": "Žižka", "Zvarová": "Zvara", "Zvěřinová": "Zvěřina", "Zvolenská": "Zvolenský"};
 
-App.Data.misc.danishSlaveNames = ["Aase", "Abluna", "Adin", "Agda", "Agnes", "Agneta", "Agnete", "Agnetha", "Aina", "Aino", "Aisha", "Ajda", "Alberte", "Alette", "Alex", "Alexandra", "Alfa", "Alfhild", "Alice", "Alicia", "Alma", "Alvilda", "Amalie", "Amanda", "Andrea", "Andrine", "Ane", "Anette", "Anita", "Anja", "Ann", "Anna", "Annali", "Anne-Lise", "Anne-Marie", "Anne-Mette", "Anne-Sofie", "Anne", "Anneli", "Annelise", "Annelouise", "Annemette", "Annette", "Anni-Frid", "Anni", "Annie", "Anny", "Antje", "Arna", "Åse", "Aslaug", "Asta", "Astrid", "Aud", "Audun", "Barbro", "Beate", "Belinda", "Benedicte", "Bengta", "Bente", "Beret", "Bergitte", "Berit", "Berta", "Berte", "Betina", "Bianca", "Birgit", "Birgitta", "Birgitte", "Birthe", "Bitten", "Bjoerg", "Bjørg", "Björk", "Bodil", "Bolla", "Borghild", "Botilda", "Brigitte", "Brit", "Britt", "Britta", "Calla", "Camilla", "Carina", "Carla", "Carola", "Caroline", "Catharina", "Cathrine", "Cecilia", "Cecilie", "Celina", "Charlotte", "Christa", "Christence", "Christenze", "Christiane", "Christina", "Christine", "Clara", "Connie", "Dagmar", "Dana", "Danielle", "Diana", "Dina", "Disa", "Ditte", "Dojn", "Dordi", "Doris", "Dorit", "Dorrit", "Dorte", "Dorthe", "Dorthea", "Dyveke", "Ebba", "Ebbe", "Edit", "Edith", "Edla", "Eira", "Eirin", "Elaine", "Elena", "Eli", "Elin", "Elina", "Elisa", "Elisabet", "Elisabeth", "Elise", "Eljena", "Ella", "Elle", "Ellen", "Elli", "Ellika", "Ellinor", "Elly", "Elna", "Elsa", "Else", "Elsje", "Emelie", "Emilie", "Emma", "Ena", "Engel", "Engla", "Erika", "Erna", "Ester", "Esther", "Eva", "Evy", "Fie", "Filippa", "Frede", "Frederikke", "Freja", "Frida", "Gerd", "Gerda", "Gertrud", "Gertrude", "Gesa", "Gisela", "Gitte", "Gjertrud", "Gladys", "Görel", "Göta", "Grete", "Grethe", "Gro", "Gry", "Gudrun", "Gunhild", "Gunilla", "Gunn", "Gunnel", "Gunnhild", "Gunvor", "Gustava", "Gyde", "Gyrid", "Haldis", "Hanna", "Hannah", "Hanne", "Hedda", "Hedvig", "Hege", "Heidi", "Helen", "Helena", "Helene", "Helga", "Helle", "Henriette", "Henrikke", "Herdis", "Hertha", "Hilde", "Hjørdis", "Holmfrid", "Iben", "Ida", "Ilse", "Ina", "Inga", "Inge-Lise", "Inge", "Ingeborg", "Inger", "Ingerd", "Ingfrid", "Ingrid", "Ingunn", "Ingvil", "Ingvor", "Irene", "Iris", "Isa", "Isabel", "Isabella", "Jane", "Janne", "Janneche", "Jannie", "Jannike", "Jasmin", "Jeanett", "Jeanette", "Jeanne", "Jeannette", "Jenny", "Jensina", "Jessica", "Jette", "Joan", "Johanna", "Johanne", "Jonna", "Jorid", "Jorun", "Jorunn", "Josefine", "Josephine", "Judit", "Julia", "Juliane", "Julie", "Jyette", "Jytte", "Kajsa", "Kamilla", "Kamma", "Kara", "Karen", "Kari", "Karin", "Karina", "Karita", "Karla", "Karna", "Karoline", "Kate", "Katharina", "Kathrine", "Katja", "Katje", "Katrin", "Katrine", "Kerstin", "Kerstina", "Kirsten", "Kirsti", "Kirstine", "Kjella", "Kjersti", "Kjerstin", "Klara", "Klaudia", "Krista", "Kristen", "Kristiane", "Kristin", "Kristina", "Kristine", "Laerke", "Lærke", "Laila", "Laura", "Lea", "Lena", "Lene", "Leonora", "Lesja", "Lilian", "Lilja", "Lill", "Lillian", "Lilly", "Lily", "Lina", "Linda", "Line", "Linette", "Linn", "Linnéa", "Lis", "Lisa", "Lisbet", "Lisbeth", "Lise-Lotte", "Lise", "Lisken", "Lissette", "Lissie", "Liv", "Liva", "Lizzie", "Loa", "Lone", "Lore", "Lotta", "Lotte", "Louise", "Lovisa", "Luna", "Lykke", "Magda", "Mai", "Maibritt", "Maiken", "Maj-Britt", "Maj", "Maja", "Majbritt", "Malene", "Malin", "Malou", "Maren", "Maret", "Margit", "Margrethe", "Mari", "Maria", "Marianne", "Marie", "Marina", "Marit", "Marlene", "Marte", "Martha", "Martine", "Mary", "Mathilde", "Maud", "May", "Maya", "Mektild", "Melanie", "Merete", "Meta", "Metha", "Mette", "Mia", "Mie", "Mikaela", "Mille", "Moa", "Mona", "Monica", "Monika", "My", "Nadia", "Nadin", "Nadja", "Naja", "Nana", "Nanna", "Nanny", "Natalie", "Nataliya", "Natasja", "Nelly", "Nicoline", "Nikoline", "Nina", "Nora", "Oda", "Oddbjorg", "Olava", "Olina", "Oline", "Olivia", "Olu", "Olufina", "Ottilia", "Patricia", "Pernille", "Petra", "Petrea", "Pia", "Priska", "Ragna", "Ragnhild", "Rakel", "Randi", "Rebecca", "Rebekka", "Regitze", "Reidun", "Renata", "Rie", "Rikke", "Rikki", "Rita", "Ró", "Ronja", "Rosa", "Rósa", "Ruth", "Sabine", "Sabrina", "Saffi", "Saga", "Sally", "Sandra", "Sanna", "Sanne", "Sara", "Sarah", "Sassa", "Seborg", "Selma", "Sharon", "Sidsel", "Sif", "Signe", "Signild", "Sigrid", "Silja", "Silje", "Sille", "Simone", "Sine", "Sini", "Siri", "Sisse", "Sissel", "Sissela", "Siv", "Sixten", "Sofia", "Sofía", "Sofie", "Solbritt", "Solveig", "Solvej", "Solvi", "Sonja", "Sonje", "Sophia", "Sophie", "Stella", "Stephanie", "Stina", "Stine", "Sunniva", "Susan", "Susanna", "Susanne", "Sussie", "Svea", "Svenborg", "Sylvi", "Synni", "Synnøve", "Tanja", "Tara", "Taya", "Tenna", "Terese", "Thea", "Therese", "Thora", "Tilde", "Tina-Lissette", "Tina", "Tine", "Tjorven", "Tona", "Tone", "Tonje", "Tora", "Torill", "Tova", "Tove", "Trine", "Trude", "Truen", "Tua", "Turid", "Turið", "Tyre", "Tyrvi", "Ulla", "Ulrika", "Ulrikke", "Ulrka", "Unni", "Ursilla", "Vanessa", "Vega", "Vendela", "Vera", "Vibeke", "Victoria", "Vigdis", "Viktoria", "Vilde", "Vinnie", "Viola", "Vita", "Viveka", "Vivi", "Vivian", "Wenche", "Winnie", "Yet", "Ylva", "Yngvil", "Yrsa", "Yvonne", "Žaklina", "Zelma"];
-App.Data.misc.danishMaleNames = ["Aage", "Adam", "Aksel", "Albert", "Albrekt", "Alex", "Alexander", "Alf", "Alfred", "Allan", "Alrik", "Alvaster", "Amund", "Anders", "Andreas", "Anker", "Ansgar", "Anton", "Årad", "Are", "Arild", "Arle", "Arne", "Arnold", "Aron", "Arthur", "Arvid", "Asbjörn", "Asbjørn", "Asger", "Aske", "Aslak", "Asmus", "Atle", "Axel", "Axl", "Bård", "Bartold", "Beck", "Bendt", "Bengt", "Benjamin", "Benny", "Bent", "Bernhard", "Bernie", "Bernt", "Bertel", "Bertil", "Bertram", "Birger", "Bjarke", "Bjarne", "Bjarni", "Björn", "Bjørn", "Bjørnar", "Bo", "Boje", "Bonde", "Borge", "Børge", "Boye", "Brage", "Brandur", "Brian", "Broder", "Bror", "Bruno", "Carl", "Carsten", "Casper", "Cato", "Cecil", "Chris", "Christian", "Christoffer", "Christopher", "Claus", "Corfitz", "Dag", "Dan", "Dane", "Daniel", "Danny", "David", "Dávid", "Dennis", "Didrik", "Diederik", "Dierk", "Ditlev", "Djur", "Ebbe", "Edvard", "Edvin", "Egil", "Egon", "Eigil", "Eiler", "Einar", "Eivind", "Ejnar", "Ejvind", "Elias", "Elmer", "Elo", "Emil", "Erich", "Erik", "Erland", "Erling", "Ernst", "Esben", "Esbjörn", "Eskild", "Espen", "Even", "Falk", "Felix", "Ferdinand", "Filip", "Finn", "Finnvid", "Flemming", "Folke", "Frank", "Frans", "Freddy", "Frede", "Frederik", "Fredrik", "Fríði", "Fritz", "Frode", "Gabriel", "Garth", "Geir", "Georg", "Gerhard", "Germund", "Gert", "Göran", "Gorm", "Gregers", "Gudjon", "Gundvast", "Gunnar", "Gunner", "Gustaf", "Gustav", "Haakan", "Hagen", "Hakan", "Håkon", "Halvard", "Hampus", "Hans", "Harald", "Harry", "Havard", "Helge", "Henning", "Henric", "Henrik", "Henry", "Herlek", "Herman", "Hilding", "Hjalmar", "Hjalte", "Holger", "Hugo", "Ib", "Ingar", "Ingemar", "Ingmar", "Ingvar", "Isak", "Ivan", "Ivar", "Iver", "Jacob", "Jakob", "Jan-Ove", "Jan", "Janick", "Jannik", "Janus", "Jarl", "Jarle", "Jenner", "Jens", "Jeppe", "Jes", "Jesper", "Jim", "Jimmy", "Joachim", "Joakim", "Joar", "Joen", "Johan", "Johannes", "John", "Johnny", "Jokum", "Jon-Ivar", "Jon", "Jonas", "Jonathan", "Joran", "Jørgen", "Jørn", "Josef", "Jostein", "Julius", "Jurd", "Kai", "Kaj", "Kalle", "Kåre", "Karl", "Karsten", "Kasper", "Kelby", "Keld", "Kenn", "Kenneth", "Kent", "Ketilbjörn", "Ketilvast", "Kevin", "Kim", "Kjartan", "Kjeld", "Kjell", "Kjerbeck", "Kjetil", "Klas", "Klaus", "Klemet", "Knud", "Knut", "Kosmo", "Kresten", "Kristian", "Kristjan", "Kristoffer", "Kurt", "Lars", "Lasse", "Lau", "Lauritz", "Laust", "Leif", "Lennart", "Lenne", "Leo", "Leon", "Liam", "Linnar", "Linus", "Loke", "Loren", "Love", "Lucas", "Ludvig", "Ludvik", "Lukas", "Lunde", "Mads", "Magne", "Magnus", "Mags", "Malthe", "Måns", "Marc", "Marcus", "Marius", "Mark", "Markus", "Mårten", "Martin", "Mathias", "Mattias", "Melker", "Michael", "Mikael", "Mike", "Mikkel", "Mogens", "Morten", "Nels", "Nichlas", "Nick", "Nicklas", "Nicolai", "Nicolaj", "Niels", "Niklas", "Nikolai", "Nikolaj", "Nils", "Nis", "Njård", "Njord", "Nóa", "Noah", "Odd", "Oddbjørn", "Oddvar", "Odin", "Olaf", "Olav", "Ole", "Oliver", "Olle", "Olof", "Oluf", "Onne", "Ored", "Ørjan", "Orla", "Oscar", "Oskar", "Osvald", "Otto", "Ove", "Owe", "Øyvind", "Paal", "Pal", "Pål", "Palle", "Patrick", "Patrik", "Paul", "Peder", "Per", "Peter", "Philip", "Piotr", "Pontus", "Poul", "Preben", "Ragnar", "Ragner", "Ramund", "Rasmus", "Reidar", "René", "Renholt", "Richard", "Rickard", "Rikard", "Roald", "Roar", "Robert", "Robin", "Roeland", "Roger", "Roine", "Rókur", "Rolf", "Ronnie", "Ruben", "Rune", "Rutger", "Sakarias", "Sakris", "Salmund", "Sebastian", "Segol", "Sigbjørn", "Sigfrid", "Sigmund", "Sigsten", "Sigurd", "Sigve", "Silas", "Simon", "Sixten", "Sjunne", "Sjur", "Sjurd", "Sofus", "Sondre", "Sonny", "Sophus", "Soren", "Søren", "Stale", "Steen", "Stefan", "Steffan", "Steffen", "Stein", "Steinar", "Stian", "Stig", "Storm", "Styrbjörn", "Sune", "Svein", "Sven", "Svend", "Sverre", "Tage", "Teddy", "Terje", "Theis", "Thomas", "Thor", "Thorben", "Thorbjørn", "Thorfinn", "Thorkild", "Thorleif", "Thorvald", "Thyge", "Tim", "Tobias", "Toke", "Tom", "Tommy", "Tonny", "Tony", "Tor", "Torben", "Torbjörn", "Tord", "Tore", "Torger", "Torgrim", "Torkel", "Torkil", "Torkild", "Tormod", "Torsten", "Torvald", "Troels", "Tron", "Trond", "Trued", "Trygve", "Tue", "Tuve", "Tycho", "Tyge", "Tyr", "Uffe", "Ulf", "Ulrik", "Une", "Vagn", "Valdemar", "Vegard", "Verner", "Victor", "Vidar", "Vidkun", "Viggo", "Viktor", "Vilfred", "Vilhelm", "Villads", "Villy", "William", "Wilson", "Ygge", "Yngvar", "Zeth"];
-App.Data.misc.danishSlaveSurnames = ["Aaberg", "Aaen", "Aagaard", "Aagard", "Aagesen", "Aakjær", "Aandahl", "Aarup", "Aase", "Aasen", "Abel", "Abelson", "Abild", "Abildgaard", "Abildtrup", "Abrahamsen", "Abrahamson", "Acree", "Acrey", "Adamsen", "Adell", "Adolfson", "Adolfsson", "Adolphsen", "Adolphson", "Agdal", "Agerbo", "Agerholm", "Agerskov", "Aggebo", "Agger", "Aggerholm", "Ahl", "Ahlberg", "Ahlgren", "Ahlin", "Ahlquist", "Ahlstad", "Ahlstedt", "Ahlstrom", "Ahmad", "Ahmed", "Akre", "Alberg", "Albertsen", "Albertsson", "Albrechtsen", "Albrektsen", "Alexandersen", "Ali", "Alm", "Almgren", "Almquist", "Almskog", "Als", "Alstrup", "Alverson", "Amstrup", "Amundsen", "Amundson", "Anderberg", "Andersen", "Anderson", "Andersson", "Andreasen", "Andreassen", "Andresen", "Anfinson", "Angerman", "Angstrom", "Anker", "Antonsen", "Appel", "Appelquist", "Arenander", "Arentoft", "Arge", "Arild", "Arildsen", "Arnason", "Arndt", "Arnell", "Arneson", "Arntzen", "Arvidson", "Aslaksen", "Asmussen", "Asplund", "Astrand", "Astrom", "Astrup", "Aune", "Averina", "Axelsen", "Axelson", "Axelsson", "Baadsgaard", "Bach", "Bachmann", "Backlund", "Backman", "Backstrom", "Bæk", "Bækgaard", "Bærentsen", "Bager", "Bagge", "Bagger", "Bak", "Bakke", "Bakken", "Balle", "Balling", "Balslev", "Baltzer", "Bang", "Bank", "Banke", "Bankston", "Bardenfleth", "Barfod", "Bark", "Barkdoll", "Barkdull", "Barstad", "Bastlund", "Bauer", "Baun", "Baunsgaard", "Bay", "Bebe", "Bech", "Bechmann", "Beck", "Becker", "Beckstrand", "Beckstrom", "Beier", "Bekker", "Bender", "Bendickson", "Bendix", "Bendixen", "Bendsen", "Bendtsen", "Bengston", "Bengtson", "Bengtsson", "Bennedsen", "Bennetsen", "Bensen", "Benson", "Bentsen", "Bentson", "Bentzen", "Benzon", "Berg", "Bergdahl", "Berge", "Bergen", "Berger", "Bergersen", "Bergerson", "Bergeson", "Berggren", "Bergh", "Berglund", "Bergman", "Bergmann", "Bergo", "Bergquist", "Bergren", "Bergstrand", "Bergstrom", "Bergstrøm", "Bering", "Berntsen", "Berntson", "Berntsson", "Berquist", "Bertelsen", "Berthelsen", "Bertram", "Bethelsen", "Beyer", "Bidstrup", "Bielecki", "Bigum", "Bilde", "Bill", "Bille", "Binderup", "Birch", "Birk", "Birkelund", "Birkland", "Bisgaard", "Bitsch", "Bjelland", "Bjerg", "Bjerke", "Bjerkedal", "Bjerre", "Bjerregaard", "Bjerring", "Bjerrum", "Bjorgas", "Bjork", "Bjorke", "Bjorklund", "Bjorkman", "Bjørn", "Bjornson", "Bjornssen", "Bjornsson", "Bjornstad", "Blaabjerg", "Bladt", "Blegen", "Blicher", "Blichfeldt", "Blix", "Blixberg", "Bloch", "Blom", "Blomberg", "Blomgren", "Blomquist", "Bloom", "Bloomberg", "Bloomquist", "Bock", "Bodin", "Bødker", "Boe", "Boel", "Boen", "Boesen", "Boeson", "Bogen", "Bøgh", "Bogren", "Bohman", "Bohn", "Boisen", "Boje", "Bojesen", "Bojsen", "Bolander", "Boll", "Bolstad", "Boman", "Bomholt", "Bonde", "Bong", "Borberg", "Borch", "Borg", "Borge", "Borgen", "Borgeson", "Bork", "Borke", "Borkman", "Borre", "Borregaard", "Borstad", "Borum", "Borup", "Boserup", "Bossen", "Bostrom", "Botolfsen", "Bove", "Boye", "Boysen", "Braaten", "Bradt", "Brahe", "Brams", "Bramsen", "Branch", "Brand", "Branden", "Brandstrom", "Brandstrup", "Brandt", "Brasch", "Brask", "Brat", "Bratt", "Bredahl", "Bredesen", "Bredeson", "Brekke", "Breland", "Bremer", "Brems", "Brenden", "Breum", "Brevig", "Brevik", "Brinch", "Brink", "Brix", "Bro", "Broberg", "Broch", "Brock", "Brockenhuus", "Broden", "Brøderbund", "Brodersen", "Brodin", "Broe", "Brogaard", "Broge", "Brom", "Broman", "Brøndum", "Brostrom", "Bruds", "Bruhn", "Brun", "Bruun", "Bruus", "Bube", "Buch", "Buciarski", "Bugge", "Buhl", "Bülow", "Bundgaard", "Burgeson", "Busk", "Buur", "Buus", "Bye", "Byskov", "Bystrom", "Cajacob", "Callesen", "Carlander", "Carlberg", "Carlen", "Carlquist", "Carls", "Carlsen", "Carlson", "Carlsson", "Carlstedt", "Carlstrom", "Carsten", "Carstens", "Carstensen", "Caspersen", "Casperson", "Cedarblade", "Cederblad", "Cederland", "Cederquist", "Celik", "Centerwall", "Chen", "Christensen", "Christenson", "Christesen", "Christiaens", "Christiansen", "Christianson", "Christjansen", "Christofersen", "Christoffersen", "Christofferson", "Christophersen", "Christopherson", "Classon", "Clausen", "Clauson", "Claussen", "Clemens", "Clemenson", "Clemmensen", "Colberg", "Conradsen", "Corinth", "Corneliussen", "Cramer", "Dahl", "Dahlbeck", "Dahlberg", "Dahle", "Dahlem", "Dahlen", "Dahlgaard", "Dahlgren", "Dahlin", "Dahlman", "Dahlquist", "Dahlstrom", "Dalberg", "Dalborg", "Dalby", "Dalen", "Dalgaard", "Dalin", "Dall", "Dalsgaard", "Dalum", "Dam", "Damborg", "Damgaard", "Damkjær", "Damm", "Damsgaard", "Danielsen", "Danielson", "Danneskjold", "Daugaard", "Davidsen", "Degn", "Dehn", "Deleuran", "Demant", "Demsitz", "Dencker", "Dideriksen", "Didrichsen", "Didriksen", "Dietrichson", "Dinesen", "Dissing", "Ditlevsen", "Dixgaard", "Djurhuus", "Dokken", "Dolbow", "Dollerup", "Drachmann", "Dreier", "Drejer", "Dreyer", "Drube", "Due", "Dueholm", "Duelund", "Dupont", "Duus", "Dybdahl", "Dybdal", "Dyhr", "Ebbesen", "Ebdrup", "Ebsen", "Ecklund", "Eckstrom", "Edberg", "Edlund", "Edstrom", "Edvardsen", "Edvardsson", "Ege", "Egeberg", "Egeland", "Egelund", "Egge", "Eggen", "Egholm", "Ehlers", "Eide", "Eidem", "Eilertsen", "Ejlersen", "Ek", "Ekberg", "Ekblad", "Ekdahl", "Ekelund", "Ekenger", "Ekholm", "Eklund", "Ekman", "Ekstrand", "Ekstrom", "Ekvall", "Elbæk", "Elgaard", "Eliasen", "Eliason", "Eliassen", "Eliasson", "Elkjær", "Ellefson", "Ellegaard", "Ellingsen", "Ellingson", "Elstad", "Emborg", "Enderson", "Enemark", "Enevoldsen", "Engberg", "Engebretsen", "Engebretson", "Engel", "Engelbrecht", "Engelhardtsen", "Engelholm", "Engen", "Enger", "Enggaard", "Engh", "Engholm", "Englund", "Engman", "Engstrom", "Enstrom", "Epson", "Erichsen", "Ericksen", "Erickson", "Ericson", "Ericsson", "Eriksen", "Erikson", "Eriksson", "Erlandsen", "Erlandson", "Ernst", "Esbensen", "Eskelson", "Eskesen", "Eskildsen", "Eskilson", "Espensen", "Espersen", "Ester", "Evanson", "Evensen", "Evenson", "Evinude", "Faber", "Fabricius", "Færch", "Fahlander", "Falck", "Falk", "Falkenberg", "Fallesen", "Farlin", "Farstad", "Faurbye", "Faxe", "Feddersen", "Fenger", "Fernlund", "Filtenborg", "Fink", "Finsen", "Finstad", "Fischer", "Fisk", "Fiske", "Fisker", "Fjalldal", "Fjell", "Flagestad", "Flaten", "Fleinert", "Flensborg", "Flindt", "Flink", "Flom", "Florin", "Fog", "Foged", "Fogh", "Foldager", "Folden", "Follerup", "Fors", "Forsberg", "Forselius", "Forsgren", "Forslund", "Forsman", "Foruseth", "Foss", "Fosse", "Fossen", "Fossum", "Franck", "Frandsen", "Frank", "Fransen", "Franson", "Frantzen", "Fred", "Fredell", "Fredericksen", "Frederickson", "Frederiksen", "Fredricksen", "Fredriksen", "Fredslund", "Freeberg", "Friberg", "Fridell", "Fridlund", "Friesen", "Friis", "Frisk", "Frohlander", "Frolander", "From", "Fromberg", "Fromgensen", "Frost", "Fuglsang", "Fulkerson", "Funkquist", "Fyhn", "Gaarde", "Gaarder", "Gabrielsen", "Gabrielson", "Gad", "Gade", "Gadegaard", "Gammelgaard", "Gangestad", "Garbo", "Gardin", "Gaustad", "Geisler", "Gilbertson", "Gissel", "Givskav", "Glad", "Glerup", "Glücksburg", "Glud", "Goranson", "Gormsen", "Gotfredsen", "Gottlieb", "Graff", "Grahn", "Gram", "Gran", "Granberg", "Granholm", "Grankvist", "Granlund", "Grau", "Gravdal", "Graversen", "Graversgaard", "Gravesen", "Gravgaard", "Green", "Gregers", "Gregersen", "Gregerson", "Gren", "Greve", "Grøn", "Grondal", "Groth", "Grove", "Gulbranson", "Guldager", "Guldbæk", "Guldberg", "Guldborg", "Gullickson", "Gundersen", "Gunderson", "Gunnarson", "Gunnerson", "Gunwaldsen", "Gustafson", "Gustafsson", "Gustavsen", "Gustavson", "Gustavsson", "Gydesen", "Gylling", "Haagensen", "Haahr", "Haakansson", "Haakenson", "Haaland", "Haaning", "Haastrup", "Haavardsen", "Hackzell", "Hafstrom", "Hagberg", "Hagen", "Hagg", "Haglund", "Hagstrom", "Hahn", "Hakanson", "Halberg", "Hald", "Halkjær", "Hall", "Hallberg", "Hallengren", "Hallin", "Hallstrom", "Hallum", "Halm", "Halseth", "Halverson", "Halvorsen", "Halvorson", "Hamann", "Hamar", "Hammar", "Hammarquist", "Hammer", "Hamner", "Handberg", "Hannibal", "Hanse", "Hansen", "Hanson", "Hansson", "Haraldson", "Haraldsson", "Haralson", "Harbo", "Harboe", "Harder", "Harelson", "Hari", "Harmsen", "Harrelson", "Harstad", "Hartling", "Hartmann", "Hartquist", "Hartvig", "Hartvigsen", "Haslund", "Hassan", "Hastrup", "Hattlestad", "Haugaard", "Haugan", "Hauge", "Haugland", "Haukaas", "Have", "Hecht", "Hed", "Hedberg", "Hede", "Hedegaard", "Hedegård", "Hedin", "Hedlund", "Hedman", "Hedmark", "Hedstrom", "Heegaard", "Hegelund", "Hegg", "Hegge", "Hegland", "Hegna", "Hegstad", "Heiberg", "Heide", "Hein", "Heinesen", "Hejlesen", "Helberg", "Helbo", "Helenius", "Helgason", "Helgerson", "Helgeson", "Helgren", "Helin", "Helland", "Hellberg", "Helle", "Hellickson", "Helliesen", "Helshoj", "Helson", "Helstrom", "Helwigh", "Hemmingsen", "Hemstrom", "Hendrickson", "Hendriksen", "Hendrixson", "Henius", "Henneberg", "Henning", "Henningsen", "Henningson", "Henricksen", "Henriksen", "Henrikson", "Hensen", "Henson", "Hermann", "Hermansen", "Hermanson", "Herskind", "Hertz", "Heske", "Hess", "Hesselberg", "Hessellund", "Hesselmann", "Hetland", "Heuser", "Hewitt", "Heyerdahl", "Hildebrandt", "Hillstrom", "Hinrichsen", "Hirsbro", "Hirse", "Hjartland", "Hjelle", "Hjelm", "Hjerrild", "Hjort", "Hjorth", "Hoagland", "Hoberg", "Høeg", "Høegh", "Hoel", "Hoff", "Hoffenblad", "Hoffmann", "Hogberg", "Hogfelt", "Høgh", "Hogland", "Hoglund", "Høiler", "Høj", "Hojgaard", "Højgaard", "Hokanson", "Hokenson", "Holck", "Holdt", "Holen", "Holgersen", "Holien", "Hollmann", "Holm", "Holmberg", "Holme", "Holmgaard", "Holmgrain", "Holmgren", "Holmlund", "Holmquist", "Holmstrom", "Holst", "Holt", "Holte", "Holten", "Holter", "Homme", "Honore", "Honoré", "Hoppe", "Hord", "Horn", "Hornstrup", "Hostrup", "Hou", "Hougaard", "Hougen", "Houmann", "Hovde", "Hove", "Hoversten", "Hovgaard", "Hovland", "Hovmand", "Hoydal", "Hoyer", "Høyer", "Hulsroj", "Hultberg", "Hultgreen", "Hultgren", "Hultman", "Hultquist", "Husby", "Huseby", "Huseth", "Hussain", "Hussein", "Husted", "Husum", "Hvam", "Hvass", "Hvid", "Hvidberg", "Hviid", "Hvirvelkær", "Hyde", "Hyer", "Hyldahl", "Hyldgaard", "Hyllested", "Ibrahim", "Ibsen", "Illum", "Ingemann", "Ingerslev", "Ingerson", "Ingwersen", "Ingwerson", "Ipsen", "Iqbal", "Isaksen", "Isakson", "Iversen", "Iverson", "Jacobsen", "Jacobson", "Jacobsson", "Jæger", "Jakobsen", "Jakobson", "Jannsen", "Jansen", "Janson", "Janssen", "Jansson", "Jasperson", "Jen", "Jennes", "Jensby", "Jensen", "Jensens", "Jenson", "Jeppesen", "Jeppson", "Jepsen", "Jespersen", "Jesperson", "Jessen", "Jevne", "Jochumsen", "Joens", "Joensen", "Johannesen", "Johannessen", "Johannsen", "Johansen", "Johanson", "Johanssen", "Johansson", "Johnsen", "Johnson", "Johnsrud", "Jokumsen", "Jonason", "Jonassen", "Jonathan", "Jonson", "Jonsson", "Jønsson", "Jordahl", "Jorgensen", "Jörgensen", "Jørgensen", "Jorgenson", "Jorstad", "Josefsen", "Josefson", "Josephsen", "Josephson", "Jrgensen", "Juel", "Juhl", "Juhler", "Julin", "Julson", "Junge", "Jungholm", "Junker", "Jurgensen", "Jürgensen", "Just", "Justesen", "Juul", "Kaae", "Kaas", "Kaeldersvends", "Kai", "Kaiser", "Kaland", "Kalgaard", "Kalisz", "Kall", "Kamp", "Kamper", "Kamstrup", "Kanstrup", "Kappel", "Karlsen", "Karlshøj", "Karlson", "Karlsson", "Karstensen", "Karstoft", "Kaspersen", "Kastbjerg", "Kastrup", "Kaya", "Kehlet", "Kejser", "Keller", "Kellstrom", "Ketelsen", "Khan", "Kiel", "Kiilerich", "Kilander", "Kilic", "Kindahl", "Kingo", "Kingspol", "Kipketer", "Kirk", "Kirkeby", "Kirkegaard", "Kittelson", "Kittleson", "Kjaer", "Kjær", "Kjærgaard", "Kjærsgaard", "Kjærulff", "Kjeldgaard", "Kjeldsen", "Kjellberg", "Kjelleren", "Kjellerup", "Kjelling", "Kjellsen", "Kjellson", "Kjer", "Kjøller", "Kjos", "Klarksen", "Klarskov", "Klassen", "Klausen", "Klein", "Klemmensen", "Kleven", "Klinge", "Klingenberg", "Klint", "Klit", "Klitgaard", "Kloster", "Klum", "Knudsen", "Knudson", "Knudtson", "Knutsen", "Knutson", "Koch", "Kock", "Koefoed", "Kofod", "Kofoed", "Køhler", "Koht", "Kokholm", "Kold", "Kolding", "Koldings", "Kolstad", "Kondrup", "Kongstad", "Kongsted", "Konradsen", "Korczynski", "Koren", "Kornum", "Korsgaard", "Korsholm", "Korva", "Korwa", "Krabbe", "Kraft", "Krag", "Kragelund", "Kragh", "Kramer", "Krarup", "Krause", "Kreander", "Krebs", "Kring", "Kristensen", "Kristiansen", "Kristoffersen", "Krog", "Krogh", "Krogsgaard", "Krohn", "Kroijer", "Kroll", "Kromann", "Kronberg", "Kronborg", "Kronquist", "Kruckow", "Krüger", "Kruhl", "Kruse", "Kryger", "Krygermeier", "Kudsk", "Kullberg", "Kure", "Kusk", "Kvandal", "Kvist", "Kyed", "Kylander", "Kyst", "La Cour", "Ladefoged", "Ladegaard", "Lagerquist", "Lagerstrom", "Lairson", "Lalin", "Lambertson", "Landbaek", "Landgren", "Landin", "Landstrom", "Lang", "Langballe", "Lange", "Langerup", "Langhoff", "Langkilde", "Langkjær", "Lango", "Larison", "Larsen", "Larson", "Larssen", "Larsson", "Lassen", "Lau", "Lauersen", "Lauesen", "Laugesen", "Lauridsen", "Lauridses", "Lauritsen", "Lauritzen", "Laursen", "Lausen", "Lausten", "Laustsen", "Lautrup", "Lav", "Le", "Leaf", "Lefeuve", "Lehmann", "Leif", "Lekander", "Lemming", "Lents", "Lentz", "Lerche", "Leth", "Li", "Lian", "Lien", "Liljenquist", "Lime", "Lind", "Lindahl", "Lindbeck", "Lindberg", "Lindbergh", "Lindblad", "Lindblom", "Linde", "Lindegaard", "Lindell", "Linder", "Lindfjeld", "Lindfors", "Lindgaard", "Lindgreen", "Lindgren", "Lindhardt", "Lindholm", "Lindquist", "Lindskoog", "Lindstedt", "Lindstrom", "Lindstrøm", "Linnet", "Linquist", "List", "Ljung", "Ljungdahl", "Ljungquist", "Loberg", "Lodahl", "Lodberg", "Loden", "Loe", "Lofberg", "Lofgren", "Lofquist", "Lohmann", "Lohse", "Loken", "Lokken", "Lomholt", "Lonnquist", "Lønstad", "Loof", "Lorensen", "Lorenson", "Lorentsen", "Lorentzen", "Lorenzen", "Ludvigsen", "Lund", "Lundahl", "Lundberg", "Lundblad", "Lundborg", "Lunde", "Lundeen", "Lundell", "Lundgaard", "Lundgreen", "Lundgren", "Lundholm", "Lundin", "Lunding", "Lundmark", "Lundquist", "Lundqvist", "Lundsgaard", "Lundsten", "Lundstrom", "Lundstrøm", "Lungren", "Lyhne", "Lykke", "Lykkegaard", "Lyng", "Lynge", "Lynggaard", "Lyngstad", "Lysgaard", "Maagaard", "Madsen", "Madsens", "Madson", "Maestad", "Magnuson", "Magnussen", "Magnusson", "Mahler", "Mahlum", "Maland", "Malling", "Malm", "Malmberg", "Malmedahl", "Malmer", "Malmgren", "Malmquist", "Malmstrom", "Mandrup", "Manson", "Mansson", "Månsson", "Marcher", "Marcussen", "Mark", "Marken", "Marker", "Markussen", "Martens", "Martensen", "Martensson", "Martinsen", "Martinson", "Martinussen", "Mathiasen", "Mathiason", "Mathiassen", "Mathiesen", "Mathisen", "Matthiesen", "Mattison", "Mattson", "Mattsson", "Matzen", "Mehlsen", "Meier", "Mejer", "Mejlhede", "Melby", "Melchiorsen", "Meldgaard", "Melgaard", "Melin", "Melquist", "Menzel", "Merrild", "Meyer", "Michaelsen", "Michaelson", "Michelsen", "Michelson", "Michelsson", "Mickelsen", "Mickelson", "Midtgaard", "Mikelson", "Mikkelsen", "Mikkelson", "Miller", "Milling", "Moberg", "Moe", "Moen", "Moesgaard", "Mogensen", "Mohamed", "Mohr", "Molander", "Møldrup", "Mølgaard", "Molin", "Moller", "Møller", "Mollerup", "Monrad", "Monsen", "Monson", "Mønsted", "Mønster", "Moos", "Mørch", "Mork", "Mørk", "Morsing", "Mortensen", "Mortenson", "Mørup", "Mosby", "Mose", "Mosegaard", "Mouridsen", "Mouritsen", "Mouritzen", "Mulbjerg", "Müller", "Mulvad", "Munch", "Munck", "Munk", "Munkholm", "Munksgaard", "Munson", "Mustad", "Mygind", "Myhre", "Myklebust", "Myre", "Myren", "Myrup", "Naas", "Nansen", "Naslund", "Nathansen", "Nattestad", "Nedergaard", "Nedstrom", "Neergaard", "Neilsen", "Neilson", "Nellemann", "Nelsen", "Nelson", "Netterstrom", "Neumann", "Newberg", "Newbranch", "Newquist", "Newstrom", "Nguyen", "Nickelson", "Nicolaisen", "Nicolajsen", "Niebuhr", "Nielsen", "Nielson", "Niemann", "Niklasson", "Nikolajsen", "Niland", "Nilsen", "Nilson", "Nilsson", "Nissen", "Nobel", "Noberg", "Noer", "Nøhr", "Norberg", "Norblad", "Norby", "Nord", "Nordahl", "Nordberg", "Nordbrandt", "Nordby", "Nordeen", "Nordell", "Nordenberg", "Nordenstahl", "Nordentoft", "Nordgren", "Nordin", "Nordlie", "Nordlund", "Nordman", "Nordquist", "Nordstrom", "Nordstrøm", "Noreen", "Noren", "Norgaard", "Nørgaard", "Norgard", "Norland", "Norling", "Norlund", "Normann", "Norquist", "Nørregaard", "Nørskov", "Norstrom", "Norup", "Norvang", "Nowen", "Nrgaard", "Nyberg", "Nybo", "Nyborg", "Nygaard", "Nygard", "Nygren", "Nyholm", "Nyhus", "Nylander", "Nylen", "Nylund", "Nyman", "Nymand", "Nymann", "Nymark", "Nyquist", "Nyreen", "Nystrom", "Oakeson", "Oas", "Obel", "Oberg", "Oddershede", "Odegaard", "Odegard", "Odfjell", "Odgaard", "Offersen", "Ogren", "Ohlin", "Ohlsen", "Ohlson", "Ohlsson", "Ohman", "Okerlund", "Olafsson", "Olaisen", "Olan", "Oland", "Olander", "Oldenborg", "Olen", "Olesen", "Oleson", "Olin", "Olofson", "Olofsson", "Olsen", "Olson", "Olsson", "Olstad", "Olufsen", "Onstad", "Opheim", "Orden", "Oren", "Orum", "Osby", "Oslin", "Oslund", "Osmundsen", "Osmundson", "Ost", "Ostby", "Ostbye", "Osterberg", "Ostergaard", "Østergaard", "Osterlund", "Osterman", "Ostlund", "Ostman", "Ostrander", "Ostrem", "Ostrom", "Otte", "Ottersen", "Ottesen", "Otteson", "Otto", "Ottosen", "Ottosson", "Ouborg", "Outzen", "Overby", "Overgaard", "Overland", "Ovesen", "Oyen", "Paaske", "Pagh", "Palles", "Pallesen", "Palm", "Palmberg", "Palmquist", "Panduro", "Pape", "Parsberg", "Paulsen", "Paulson", "Paulsson", "Pearson", "Pedersen", "Pederson", "Pedersson", "Peerson", "Pehrson", "Perfeldt", "Person", "Persson", "Peters", "Petersen", "Peterson", "Petersson", "Petre", "Petri", "Pettersen", "Petterson", "Pettersson", "Pham", "Philipsen", "Philipson", "Pihl", "Pilgaard", "Pind", "Plesner", "Ploug", "Pontoppidan", "Post", "Poulsen", "Poulson", "Povlsen", "Præst", "Presby", "Primdahl", "Prom", "Puggaard", "Pust", "Quam", "Quande", "Quisling", "Quist", "Quistorff", "Qvist", "Qvortrup", "Raahauge", "Rafn", "Rahbek", "Ram", "Rambo", "Randrup", "Rank", "Rasborg", "Rasch", "Rask", "Raske", "Rasmus", "Rasmussen", "Rasmusson", "Raun", "Ravn", "Ree", "Reenberg", "Refsgaard", "Rehn", "Reimer", "Reinholdt", "Reistad", "Riber", "Richter", "Ridder", "Riis", "Riise", "Rindom", "Ring", "Ringdahl", "Ringgaard", "Risager", "Rise", "Rising", "Ritter", "Rix", "Rockne", "Rode", "Rodin", "Roed", "Rogne", "Rohde", "Romberg", "Rømer", "Romhild", "Rongstad", "Rønholt", "Rønn", "Rønne", "Ronning", "Rønnow", "Rose", "Rosell", "Rosenberg", "Rosenberry", "Rosendahl", "Rosendal", "Rosenkilde", "Rosenlund", "Rosenquist", "Rosing", "Rossen", "Rostad", "Roth", "Rozell", "Rozelle", "Rud", "Rudbeck", "Rudberg", "Rudlong", "Rudman", "Rudolfsson", "Rue", "Rundblad", "Rundquist", "Rundstrom", "Runge", "Running", "Runquist", "Rustad", "Ruud", "Ryberg", "Rydberg", "Rydell", "Ryden", "Rygaard", "Rylander", "Rytter", "Saabye", "Sabo", "Sae", "Sagedahl", "Sahin", "Sahl", "Salberg", "Salling", "Salomonsen", "Salomonsson", "Salto", "Samuelsen", "Samuelson", "Samuelsson", "Sand", "Sandager", "Sandahl", "Sandberg", "Sandburg", "Sande", "Sandelin", "Sandell", "Sanden", "Sandenskog", "Sander", "Sanderlin", "Sanderud", "Sandin", "Sandlin", "Sandmark", "Sandquist", "Sandstrom", "Sandvik", "Sångren", "Sather", "Sauer", "Schack", "Schaufuss", "Scheel", "Scherwin", "Schmidt", "Schneider", "Schou", "Schrøder", "Schultz", "Schulz", "Schumacher", "Schwartz", "Schytte", "Seaberg", "Seagren", "Seaquist", "Seashore", "Sebo", "Secher", "Seerup", "Segerstrom", "Sehested", "Seiersen", "Sejersen", "Sejr", "Selander", "Selin", "Sellen", "Selvig", "Sem", "Serup", "Severin", "Severinsen", "Seversen", "Severson", "Severtson", "Sichlau", "Silberg", "Simenson", "Simonsen", "Simonson", "Sinding", "Singh", "Sivertsen", "Sivertson", "Sjo", "Sjoberg", "Sjoblom", "Sjodin", "Sjogren", "Sjolander", "Sjolund", "Sjoman", "Sjoquist", "Sjostrand", "Sjostrom", "Skaaning", "Skaar", "Skaarup", "Skadhauge", "Skafte", "Skanland", "Skardal", "Skare", "Skeem", "Skibsted", "Skipper", "Skjødt", "Skjoldborg", "Skog", "Skogen", "Skoglund", "Skomagers", "Skoog", "Skøtt", "Skou", "Skov", "Skovbjerg", "Skovbo", "Skovby", "Skovgaard", "Skovlund", "Skovsgaard", "Skow", "Skriver", "Skytte", "Skyum", "Sletten", "Slogvag", "Slot", "Sloth", "Smed", "Smedegaard", "Smidt", "Smith", "Snaevarr", "Snare", "Snedker", "Sodahl", "Soder", "Soderberg", "Soderholm", "Soderlund", "Soderman", "Soderquist", "Sodersten", "Soderstrom", "Soegaard", "Soelberg", "Soerensen", "Søgaard", "Sohlstrom", "Šojić", "Soland", "Solberg", "Solem", "Solie", "Solness", "Solum", "Sommer", "Sondergaard", "Søndergaard", "Sonne", "Soren", "Sorensen", "Sørensen", "Sorenson", "Spandemager", "Spell", "Splids", "Spliid", "Spliids", "Spohr", "Spong", "Sponneck", "Srensen", "Staal", "Staehr", "Stæhr", "Stage", "Stalcup", "Stallcup", "Stampe", "Standlund", "Stausholm", "Steen", "Steenberg", "Stefansen", "Steffensen", "Steffenson", "Stenberg", "Stender", "Stene", "Stenger", "Stensgaard", "Stensland", "Stensrud", "Stenstrom", "Stentoft", "Stephansen", "Stergaard", "Stianson", "Stigson", "Stilling", "Stisage", "Stobbe", "Stockdahl", "Stockholm", "Stokholm", "Stolberg", "Stoneberg", "Stordahl", "Storgaard", "Storlie", "Storm", "Stougaard", "Straarup", "Strand", "Strandberg", "Strandlund", "Strange", "Streed", "Strid", "Strom", "Strøm", "Strombeck", "Stromberg", "Strombom", "Stromgren", "Stromholm", "Stromme", "Stromquist", "Stryhn", "Suder", "Suhr", "Sund", "Sundback", "Sundberg", "Sundby", "Sunde", "Sundeen", "Sundell", "Sunderlin", "Sundet", "Sundgren", "Sundin", "Sundquist", "Sundstrand", "Sundstrom", "Sundt", "Sunesen", "Sværke", "Svane", "Svedin", "Svendsen", "Svenningsen", "Svenson", "Svensson", "Svenstrup", "Swanberg", "Swaner", "Swanner", "Swanson", "Swanstrom", "Sward", "Swedberg", "Swedlund", "Swensen", "Swenson", "Sylvest", "Syverson", "Tanberg", "Tandrup", "Tang", "Tange", "Tangen", "Tanquist", "Tapper", "Tarp", "Taul", "Teglgaard", "Terkelsen", "Terkildsen", "Terp", "Thagard", "Thaysen", "Theil", "Theilgaard", "Therkelsen", "Therkildsen", "Thestrup", "Thiesen", "Thinggaard", "Thisted", "Thøgersen", "Tholstrup", "Thomasen", "Thomassen", "Thomasson", "Thomsen", "Thomson", "Thor", "Thorell", "Thoresen", "Thoreson", "Thorhauge", "Thorn", "Thornberg", "Thorning-Schmidt", "Thorning", "Thorsager", "Thorsen", "Thorson", "Thorstad", "Thorsted", "Thorup", "Thorvaldson", "Thostrup", "Thrane", "Thronson", "Thuesen", "Thulin", "Thybo", "Thygerson", "Thygesen", "Thyssen", "Tilling", "Tillstrom", "Timm", "Timmermann", "Tisby", "Tjarnlund", "Tjelmeland", "Toft", "Tofte", "Tollefson", "Tollerson", "Tolleson", "Tollison", "Tolstrup", "Tønnesen", "Topp", "Toppenberg", "Torborg", "Torgersen", "Torgerson", "Torgeson", "Torgrimson", "Torkelson", "Torkillus", "Torp", "Tougaard", "Toviassen", "Trajkovski", "Tran", "Tranberg", "Trenholm", "Trier", "Troelsen", "Trolle", "Truelsen", "Trulson", "Tunsen", "Tunson", "Turnquist", "Twedt", "Uhlgren", "Ulfeldt", "Ulfsax", "Ullerup", "Ulrich", "Ulriksen", "Ulving", "Underdahl", "Utne", "Utter", "Vad", "Vaden", "Valentin", "Valfells", "Valkendorff", "Valla", "Vallentin", "Vammen", "Vang", "Vangsgaard", "Varn", "Vedel", "Velling", "Vendelbo", "Vernersen", "Vernlund", "Vest", "Vester", "Vestergaard", "Vetlesen", "Viborg", "Vig", "Vilhelmsen", "Villadsen", "Villum", "Villumsen", "Vilstrup", "Vind", "Vinding", "Vinhofvers", "Vinstrup", "Vinter", "Vinther", "Vistisen", "Vittrup", "Vognsen", "Voigt", "Voss", "Vrang", "Waage", "Wagner", "Wahl", "Wahlander", "Wahlberg", "Wahlgren", "Wahlstrom", "Wahlund", "Walberg", "Waldenstrom", "Waldum", "Wallander", "Wallen", "Wallin", "Walquist", "Walstad", "Walstrom", "Walther", "Wang", "Warming", "Weber", "Wedlund", "Weima", "Weinreich", "Weiss", "Wellemberg", "Wenstrom", "Wernquist", "West", "Westberg", "Westby", "Westerberg", "Westergaard", "Westergard", "Westerlund", "Westermann", "Westh", "Westin", "Westling", "Westlund", "Westmark", "Wetterstrom", "Wiberg", "Wiborg", "Wichmann", "Wicklund", "Wickstrom", "Widegren", "Widemark", "Widerberg", "Widholm", "Wiered", "Wiese", "Wike", "Wiklander", "Wikstrom", "Wilhelmsen", "Willadsen", "Willemsen", "Willumsen", "Wiltse", "Winberg", "Winberry", "Wind", "Windell", "Winding", "Winkel", "Winkler", "Winther", "Wiren", "Wisell", "Witt", "Wold", "Wolf", "Wolff", "Wolfsberg", "Wolin", "Wollesen", "Worm", "Wozniacki", "Wulff", "Wullum", "Würtz", "Ydby", "Yde", "Yildirim", "Yilmaz", "Young", "Youngberg", "Youngdahl", "Younggreen", "Younglove", "Youngquist", "Youngren", "Zachariasen", "Zachariassen", "Zacho", "Zadeh", "Ziegler", "Zimmermann", "Zinck"];
+App.Data.misc.danishSlaveNames = [
+  "Anne",
+  "Mette",
+  "Kirsten",
+  "Hanne",
+  "Helle",
+  "Anna",
+  "Susanne",
+  "Lene",
+  "Maria",
+  "Marianne",
+  "Lone",
+  "Camilla",
+  "Louise",
+  "Pia",
+  "Charlotte",
+  "Tina",
+  "Gitte",
+  "Jette",
+  "Bente",
+  "Julie",
+  "Karen",
+  "Inge",
+  "Ida",
+  "Rikke",
+  "Emma",
+  "Sofie",
+  "Christina",
+  "Laura",
+  "Marie",
+  "Birgit",
+  "Pernille",
+  "Line",
+  "Inger",
+  "Birthe",
+  "Annette",
+  "Ulla",
+  "Heidi",
+  "Else",
+  "Cecilie",
+  "Jytte",
+  "Anette",
+  "Eva",
+  "Karin",
+  "Birgitte",
+  "Dorthe",
+  "Lis",
+  "Signe",
+  "Lisbeth",
+  "Tove",
+  "Maja",
+  "Mathilde",
+  "Trine",
+  "Emilie",
+  "Sara",
+  "Nanna",
+  "Katrine",
+  "Caroline",
+  "Dorte",
+  "Ellen",
+  "Karina",
+  "Stine",
+  "Freja",
+  "Sarah",
+  "Vibeke",
+  "Malene",
+  "Lise",
+  "Bodil",
+  "Jane",
+  "Grethe",
+  "Anja",
+  "Mia",
+  "Lærke",
+  "Linda",
+  "Isabella",
+  "Amalie",
+  "Nina",
+  "Clara",
+  "Josefine",
+  "Ingrid",
+  "Astrid",
+  "Anni",
+  "Mona",
+  "Henriette",
+  "Alberte",
+  "Lotte",
+  "Ruth",
+  "Jeanette",
+  "Aase",
+  "Tine",
+  "Anita",
+  "Victoria",
+  "Ella",
+  "Johanne",
+  "Michelle",
+  "Sonja",
+  "Frida",
+  "Ditte",
+  "Mie",
+  "Mille",
+  "Alice",
+  "Alma",
+  "Olivia",
+  "Simone",
+  "Lea",
+  "Laila",
+  "Margit",
+  "Bettina",
+  "Jonna",
+  "Ann",
+  "Sofia",
+  "Elisabeth",
+  "Kristina",
+  "Helene",
+  "Britta",
+  "Connie",
+  "Frederikke",
+  "Tanja",
+  "Joan",
+  "Lena",
+  "Sanne",
+  "Rita",
+  "Inga",
+  "Agnes",
+  "Kathrine",
+  "Merete",
+  "Gerda",
+  "Lisa",
+  "Asta",
+  "Liva",
+  "Birte",
+  "Andrea",
+  "Esther",
+  "Karoline",
+  "Betina",
+  "Josephine",
+  "Sandra",
+  "Berit",
+  "Christine",
+  "Thea",
+  "Irene",
+  "Amanda",
+  "Jannie",
+  "Janne",
+  "Iben",
+  "Kristine",
+  "Liv",
+  "Carina",
+  "Susan",
+  "Karla",
+  "Rosa",
+  "Luna",
+  "Elin",
+  "Edith",
+  "Vivi",
+  "Diana",
+  "Randi",
+  "Annie",
+  "Katja",
+  "Nadia",
+  "Nicoline",
+  "Janni",
+  "Annelise",
+  "Solveig",
+  "Sophia",
+  "Helena",
+  "Lillian",
+  "Liselotte",
+  "Vera",
+  "Rebecca",
+  "Malou",
+  "Hannah",
+  "Nora",
+  "Kirstine",
+  "Conny",
+  "Grete",
+  "Kamilla",
+  "Ane",
+  "Marlene",
+  "Sophie",
+  "Annika",
+  "Naja",
+  "Sigrid",
+  "Elsebeth",
+  "Winnie",
+  "Emily",
+  "Ingelise",
+  "Maiken",
+  "Matilde",
+  "Anne-Marie",
+  "Selma",
+  "Anne-Mette",
+  "Britt",
+  "Lykke",
+  "Gurli",
+  "Maya",
+  "Yvonne",
+  "Silje",
+  "Julia",
+  "Jasmin",
+  "Cathrine",
+  // "Aya", // Immigrant
+  "Henny",
+  "Lilian",
+  "Filippa",
+  "Gry",
+  "Nikoline",
+  "Emilia",
+  "Klara",
+  "Lilly",
+  "Sabrina",
+  "Kate",
+  "Majbritt",
+  "Freya",
+  "Celina",
+  "Silke",
+  "Tilde",
+  "Elly",
+  // "Thi", // Probably Vietnamese
+  "Sille",
+  "Stephanie",
+  "Hanna",
+  "Melanie",
+  "Erna",
+  "Carla",
+  "Doris",
+  "Merle",
+  "Margrethe",
+  "Gudrun",
+  "Natasja",
+  "Mai",
+  "Lisbet",
+  "Lissi",
+  "Fie",
+  "Martha",
+  "Monica",
+  "Ina",
+  "Elena",
+  "Vigga",
+  "Helen",
+  "Annemette",
+  "Alba",
+  "Helga",
+  "Lina",
+  "Maj-Britt",
+  "Viola",
+  "Ninna",
+  "Dagmar",
+  "Sine",
+  "Anny",
+  "Sidsel",
+  "Ea",
+  "Agnete",
+  "Mary",
+  "Lilli",
+  "Jessica",
+  "Ketty",
+  "Nadja",
+  "Cecilia",
+  "Jeanne",
+  // "Fatima", // Immigrant
+  "Ronja",
+  "Inge-Lise",
+  "Jenny",
+  "Melissa",
+  "Lise-Lotte",
+  "Ester",
+  "Dina",
+  "Majken",
+  "Conni",
+  "Vivian",
+  "Sally",
+  "Stella",
+  "Sabine",
+  "Monika",
+  "Nicole",
+  "Ingeborg",
+  "Rebekka",
+  "Ellie",
+  "Leonora",
+  "Natascha",
+  // "Yasmin", // Alternate spelling of Jasmin, this one seems to be primarily used by immigrants. Whereas, Jasmin is used by people of Danish origin as well.
+  "Mira",
+  "Betty",
+  "Augusta",
+  "Nana",
+  "Minna",
+  "Marie-Louise",
+  "Vita",
+  "Sif",
+  "Elise",
+  "Olga",
+  "Ilse",
+  "Alexandra",
+  "Barbara",
+  "Rose",
+  "Molly",
+  "Therese",
+  "Ebba",
+  "Johanna",
+  "Smilla",
+  "Patricia",
+  "Thilde",
+  "Annemarie",
+  "Saga",
+  "Rie",
+  "Kira",
+  "Dicte",
+  "Kaja",
+  "Tenna",
+  "Bitten",
+  "Kaya",
+  "Gunhild",
+  "Lily",
+  "Majbrit",
+  // "Mariam", // Immigrant
+  "Kamma",
+  "Nynne",
+  "Maj",
+  "Irma",
+  "Mariann",
+  "Isabel",
+  "Elisa",
+  "Anne-Lise",
+  "Claudia",
+  "Celine",
+  "Rigmor",
+  "Dorrit",
+  "Maibritt",
+  "Nathalie",
+  "Vilma",
+  "Sussi",
+  "Jennifer",
+  // "Amina", // Immigrant
+  "Stina",
+  "Natasha",
+  "Ana",
+  "Christa",
+  "Marina",
+  "Sisse",
+  "Camille",
+  "Benedikte",
+  "Christel",
+  // "Fatma", // Immigrant
+  "Elvira",
+  "Sascha",
+  "Natalia",
+  "Anne-Sofie",
+  "Regitze",
+  "Vega",
+  "Elizabeth",
+  "Natalie",
+  "Sabina",
+  "Judith",
+  "Silja",
+  "Jeannette",
+  "Herdis",
+  "Bianca",
+  "Edel",
+  "Alva",
+  "Søs",
+  "Marta",
+  "Mai-Britt",
+  "Iris",
+  "Elna",
+  "Vanessa",
+  "Lissy",
+  "Viktoria",
+  // "Alina", // Probably immigrant, but might have some foothold within Danish naming.
+  "Naya",
+  "Joanna",
+  "Miriam",
+  "Benedicte",
+  "Maren",
+  "Petra",
+  "Melina",
+  "Ellinor",
+  "Jeanett",
+  "Lonnie",
+  "Elina",
+  "Sia",
+  "Belinda",
+  "Marian",
+  "Agnethe",
+  "Kamille",
+  "Flora",
+  "Annalise",
+  "Lara",
+  "Linea",
+  "Nova",
+  "Solvejg",
+  "Erika",
+  "Sussie",
+  "Yrsa",
+  "Selina",
+  "Solvej",
+  // "Ayse", // Immigrant
+  "Juliane",
+  "Katharina",
+  "Sissel",
+  "Lili",
+  "June",
+  "Nellie",
+  "Elsa",
+  // "Aisha", // Immigrant
+  // "Maryam", // Immigrant
+  // "Zahra", // Immigrant
+  "Linette",
+  "Vicki",
+  // "Katarzyna", // Polish
+  "Kia",
+  "Mynte",
+  "Linnea",
+  "Benthe",
+  "Siri",
+  "Lucca",
+  "Wilma",
+  "Magdalena",
+  "Nancy",
+  "My",
+  // "Mila", // Immigrant
+  "Lisette",
+  "Sandie",
+  "Daniella",
+  "Dagny",
+  // "Leila", // Primarily immigrant, but might have some foothold within Danish naming. Laila is much more common though.
+  "Aleksandra",
+  "Anne-Grethe",
+  "Tinna",
+  "Theresa",
+  "Bolette",
+  "Oda",
+  // "Mina", // Primarily immigrant, but probably has some foothold within Danish naming.
+  "Brita",
+  "Michella",
+  "Michala",
+  "Vibe",
+  "Leah",
+  "Karolina",
+  "Isabell",
+  "Gertrud",
+  "Lucia",
+  // "Agnieszka", // Polish
+  "Merethe",
+  "Krista",
+  "Katarina",
+  "Fiona",
+  "Ragnhild",
+  // "Daniela", // Pretty rare and not famous enough to include
+  "Lizzie",
+  "Emmelie",
+  "Gabriella",
+  "Dorit",
+  "Bjørk",
+  "Cille",
+  "Milla",
+  "Suzanne",
+  "Kathe",
+  "Maia",
+  "Stefanie",
+  "Zenia",
+  "Paula",
+  "Vilde",
+  "Lizzi",
+  // "Zainab", // Immigrant
+  "Emmy",
+  "Monique",
+  "Xenia",
+  "Lydia",
+  "Nete",
+  "Else-Marie",
+  "Eline",
+  "Tania",
+  // "Iman", // Immigrant
+  "Cornelia",
+  // "Amal", // Immigrant
+  "Vinni",
+  "Cristina",
+  "Evy",
+  "Martine",
+  "Mynthe",
+  "Mariane",
+  "Stinne",
+  "Ena",
+  "Teresa",
+  "Bella",
+  "Ann-Sofie",
+  "Lilje",
+  // "Amelia", // Primarily immigrant, but probably has some foothold within Danish naming.
+  // "Jacqueline", // Pretty rare and not famous enough to include
+  "Kit",
+  "Lonni",
+  // "Amira", // Immigrant
+  "Birgith",
+  "Didde",
+  "Jeanet",
+  // "Malgorzata", // Polish
+  "Ã…se",
+  "Veronica",
+  "Luise",
+  "Carolina"
+];
+App.Data.misc.danishMaleNames = [
+  "Peter",
+  "Michael",
+  "Lars",
+  "Jens",
+  "Thomas",
+  "Henrik",
+  "Søren",
+  "Christian",
+  "Martin",
+  "Jan",
+  "Morten",
+  "Anders",
+  "Jesper",
+  "Niels",
+  "Mads",
+  "Rasmus",
+  "Per",
+  "Hans",
+  "Mikkel",
+  "Jørgen",
+  "Ole",
+  "Kim",
+  "Erik",
+  "John",
+  "Frederik",
+  "Jonas",
+  "Emil",
+  "Mathias",
+  "Claus",
+  "Daniel",
+  "Poul",
+  "Simon",
+  "Jacob",
+  "Andreas",
+  "Kasper",
+  "Torben",
+  "Flemming",
+  "Oliver",
+  "Bent",
+  "Brian",
+  "Carsten",
+  "Magnus",
+  "Allan",
+  "Lasse",
+  "Jakob",
+  "Kristian",
+  "Sebastian",
+  "Bjarne",
+  "Tobias",
+  "Finn",
+  "Henning",
+  "Alexander",
+  "Kenneth",
+  "Steen",
+  "William",
+  "Svend",
+  "Leif",
+  "Kurt",
+  "Knud",
+  "Mogens",
+  "Benjamin",
+  "Casper",
+  "Dennis",
+  "Noah",
+  "Jeppe",
+  "Bo",
+  "Victor",
+  "Frank",
+  "Lucas",
+  "Preben",
+  "Arne",
+  "Nikolaj",
+  "Nicolai",
+  "René",
+  "Carl",
+  "Klaus",
+  "Anton",
+  "Karsten",
+  "Tommy",
+  "Marcus",
+  "David",
+  "Patrick",
+  "Johnny",
+  "Jørn",
+  "Karl",
+  "Johan",
+  "Kaj",
+  "Gustav",
+  "Malthe",
+  "Elias",
+  "Nicklas",
+  "Johannes",
+  "Lukas",
+  "Benny",
+  "Adam",
+  "Oscar",
+  "Steffen",
+  "Palle",
+  "August",
+  "Valdemar",
+  "Dan",
+  "Gert",
+  "Alfred",
+  "Mark",
+  "Tom",
+  "Jonathan",
+  "Christoffer",
+  "Rune",
+  "Asger",
+  "Philip",
+  "Bjørn",
+  "Ib",
+  "Kjeld",
+  "Marius",
+  "Stefan",
+  "Aksel",
+  "Mikael",
+  "Oskar",
+  "Viktor",
+  "Alex",
+  // "Mohammad", // Immigrant
+  "Ove",
+  "Erling",
+  "Rene",
+  // "Ali", // Immigrant
+  "Albert",
+  "Stig",
+  "Robert",
+  "Peder",
+  "Felix",
+  "Keld",
+  "Max",
+  "Ivan",
+  "Viggo",
+  "Kristoffer",
+  "Troels",
+  "Villads",
+  "Mike",
+  "Ulrik",
+  "Børge",
+  "Thor",
+  "Silas",
+  "Otto",
+  "Liam",
+  "Vagn",
+  "Arthur",
+  "Esben",
+  "Holger",
+  "Kent",
+  "Bertram",
+  "Malte",
+  "Kevin",
+  "Laurits",
+  "Egon",
+  "Gunnar",
+  "Nicolaj",
+  "Julius",
+  "Niklas",
+  "Jimmy",
+  // "Ahmad", // Immigrant
+  "Leo",
+  "Storm",
+  "Theodor",
+  "Sune",
+  "Asbjørn",
+  "Hugo",
+  "Helge",
+  "Markus",
+  "Christopher",
+  "Villy",
+  "Sigurd",
+  "Tim",
+  "Tage",
+  "Marc",
+  "Ebbe",
+  "Tonny",
+  "Hjalte",
+  "Axel",
+  "Uffe",
+  "Lauge",
+  "Bjarke",
+  "Aage",
+  "Bastian",
+  "Elliot",
+  "Tristan",
+  // "Mohamed", // Immigrant
+  "Paul",
+  "Jon",
+  "Nick",
+  "Theo",
+  // "Mohamad", // Immigrant
+  "Samuel",
+  "Sven",
+  "Joachim",
+  "Theis",
+  "Frede",
+  "Marco",
+  "Henry",
+  "Verner",
+  "Jimmi",
+  "Anker",
+  "Phillip",
+  "Jes",
+  "Nils",
+  "Jack",
+  "Gabriel",
+  "Sander",
+  // "Mohammed", // Immigrant
+  "Sylvester",
+  "Pelle",
+  "Chris",
+  "Kai",
+  "Adrian",
+  "Aske",
+  "Filip",
+  // "Mustafa", // Immigrant
+  "Louis",
+  "Nikolai",
+  // "Ibrahim", // Immigrant
+  // "Muhammad", // Immigrant
+  "Birger",
+  "Sofus",
+  "Freddy",
+  "Sten",
+  "Bruno",
+  "Magne",
+  // "Ahmed", // Immigrant
+  "Ludvig",
+  "Jannik",
+  "Danny",
+  "Ronni",
+  "Ernst",
+  "Niclas",
+  "Milas",
+  "Charlie",
+  "Vincent",
+  // "Omar", // Immigrant
+  "Nicolas",
+  "Richard",
+  "Leon",
+  "Harald",
+  "Villum",
+  "Nicholas",
+  "Orla",
+  "Nohr",
+  // "Luca", // Probably immigrant
+  "Joakim",
+  "Konrad",
+  "Eigil",
+  "Thorkild",
+  "Kalle",
+  "Rolf",
+  "André",
+  "Ejvind",
+  "Jim",
+  "Birk",
+  "Harry",
+  "Matias",
+  // "Hassan", // Immigrant
+  // "Mehmet", // Immigrant
+  "Lennart",
+  "Jannick",
+  "Malik",
+  "Isak",
+  "Vitus",
+  "Julian",
+  "Peer",
+  "Janus",
+  "Paw",
+  "Danni",
+  "Robin",
+  "Georg",
+  "Linus",
+  "Ken",
+  "Thorbjørn",
+  "Bertil",
+  "Kenn",
+  "Tomas",
+  "Willy",
+  "Heine",
+  // "Abdul", // Immigrant
+  // "Mahmoud", // Immigrant
+  "Milo",
+  "Glenn",
+  "Steven",
+  "Toke",
+  "Nichlas",
+  "James",
+  "Conrad",
+  "Ronnie",
+  "Nicki",
+  "Hector",
+  "Lau",
+  "Vilhelm",
+  "Jess",
+  // "Yusuf", // Immigrant
+  "Alan",
+  // "Amir", // Immigrant
+  "Ruben",
+  "Frej",
+  "Frode",
+  "Torsten",
+  "Louie",
+  "Matti",
+  "Kian",
+  "Michal",
+  "Tue",
+  "Eskild",
+  "Gorm",
+  "Loui",
+  "Carlo",
+  // "Muhammed", // Immigrant
+  // "Milan", // Probably immigrant
+  "Ejner",
+  "Jonatan",
+  "Jamie",
+  "Tony",
+  "Kenny",
+  // "Piotr", // Immigrant
+  // "Tomasz", // Immigrant
+  "Aleksander",
+  "Laust",
+  "Cornelius",
+  "Ejnar",
+  "Walter",
+  // "Hasan", // Immigrant
+  // "Hussein", // Immigrant
+  "Frits",
+  "Sean",
+  "Sonny",
+  "Stephan",
+  "Steffan",
+  "Ian",
+  // "Hamza", // Immigrant
+  "Hardy",
+  "Sami",
+  // "Krzysztof", // Immigrant
+  "Tonni",
+  "Teddy",
+  "KÃ¥re",
+  "Claes",
+  "Laurids",
+  "Gunner",
+  "Ulrich",
+  // "Marcin", // Polish
+  "Kennet",
+  "Poul-Erik",
+  "Matthias",
+  "Bendt",
+  "Povl",
+  "Buster",
+  // "Ismail", // Immigrant
+  // "Abdullah", // Immigrant
+  // "Pawel", // Polish
+  "Lauritz",
+  // "Anas", // Immigrant
+  "Johnni",
+  "Kresten",
+  "Denis",
+  // "Ahmet", // Immigrant
+  "Vilfred",
+  // "Lukasz", // Polish
+  // "Khaled", // Immigrant
+  "Eddie",
+  "Olav",
+  "Herman",
+  // "Bilal", // Immigrant
+  "Kenni",
+  // "Luka", // Probably immigrant
+  "Eric",
+  "Hans-Henrik",
+  "Andrew",
+  // "Van", // Very rare, not famous enough
+  // "Nor", // Very rare, not famous enough
+  "Kaare",
+  "Nis",
+  "Ulf",
+  // "Adnan", // Immigrant
+  "Walther",
+  // "Jakub", // Polish
+  "Alvin",
+  "Jean",
+  // "Osman", // Immigrant
+  "Ask",
+  // "Yasin", // Immigrant
+  "Charles",
+  "Stephen",
+  "Alf",
+  // "Yousef", // Immigrant
+  "Ryan",
+  "Xander",
+  "Jason",
+  "Joshua",
+  "Luis",
+  "Josef",
+  "Ejgil",
+  "Mick",
+  "Joseph",
+  // "Juan", // Spanish
+  "Marcel",
+  "Halfdan",
+  // "Oleksandr", // Ukranian
+  // "Samir", // Immigrant
+  "Michel",
+  "Loke",
+  "Valentin",
+  // "Grzegorz", // Polish
+  // "Deniz", // Immigrant
+  // "Marek", // Polish
+  // "Amin", // Immigrant, although one notable danish person has this name
+  "Andy",
+  "Ronny",
+  "Wilhelm",
+  "Tore",
+  "Isaac",
+  "Christen",
+  // "Carlos", // Some Danish usage, but seems mostly immigrant
+  // "Roman", // Immigrant
+  "Ditlev",
+  // "Mikail", // Immigrant
+  "Gregers",
+  "Matheo",
+  // "Andrei", // Some Danish usage, but seems mostly immigrant
+  // "Matthew", // Foreign
+  // "Andrzej", // Polish
+  "Oluf",
+  "Kristen",
+  "Marvin",
+  "Evald",
+  "Heinrich",
+  "Olaf",
+  // "Mateusz", // Polish
+  "Tino",
+  // "Said", // Immigrant
+  "Mattias",
+  "George",
+  "Eske",
+  // "Youssef", // Immigrant
+  // "Damian", // Very rare, not famous enough
+  "Herluf",
+  "Ralf",
+  "Hasse",
+  // "Emir", // Immigrant
+  "Erland",
+  "Mickey",
+  "Sam",
+  "Artur",
+  // "Murat", // Immigrant
+  "Mason",
+  // "Alexandru", // Immigrant
+  "Nicky",
+  // "Kamil", // Immigrant
+  // "Antonio", // Immigrant
+  // "Rafal", // Immigrant
+  "Pierre",
+  "Noa",
+  "Ingolf",
+  "Valde",
+  "Lui",
+  "Klavs",
+  "Andre",
+  "Hannibal",
+  // "Mariusz", // Polish
+  "Fritz",
+  "Asmus",
+  "Heino",
+  "Constantin",
+  "Rudi",
+  // "Jose", // Spanih
+  "Karlo",
+  "Elmer",
+  // "Yunus", // Immigrant
+  // "Mario", // Italian
+  "Hubert",
+  "Tor",
+  "Roland",
+  "Jeff",
+  // "Khalid", // Immigrant
+  "Kris",
+  // "Maciej", // Polish
+  "Caspar",
+  "Bille",
+  "Werner",
+  "Kaspar",
+  "Carl-Emil",
+  "Ivar",
+  // "Jamal", // Immigrant
+  "Rico",
+  // "Matteo", // Primarily immigrant
+  // "Enes", // Immigrant
+  "Elliott",
+  "Balder",
+  "Patrik",
+  "Anthony",
+  // "Adem", // Immigrant
+  "Eik",
+  "Leander",
+  "Elo", // Immigrant
+  // "Dariusz", // Polish
+  "Willum"
+];
+App.Data.misc.danishSlaveSurnames = ["Jensen", "Nielsen", "Hansen", "Pedersen", "Andersen", "Christensen", "Larsen", "Sørensen", "Rasmussen", "Petersen", "Jørgensen", "Madsen", "Kristensen", "Olsen", "Thomsen", "Christiansen", "Poulsen", "Johansen", "Knudsen", "Mortensen", "Møller", "Jakobsen", "Jacobsen", "Olesen", "Mikkelsen", "Lund", "Frederiksen", "Holm", "Laursen", "Henriksen", "Schmidt", "Eriksen", "Clausen", "Simonsen", "Kristiansen", "Svendsen", "Andreasen", "Iversen", "Jeppesen", "Vestergaard", "Jespersen", "Mogensen", "Lauridsen", "Nissen", "Dahl", "Jepsen", "Kjær", "Skov", "Frandsen", "Jessen", "Bach", "Carlsen", "Bruun", "Friis", "Nørgaard", "Bertelsen", "Srensen", "Christoffersen", "Gregersen", "Bech", "Søndergaard", "Krogh", "Lassen", "Winther", "Johnsen", "Ravn", "Jrgensen", "Østergaard", "Kjeldsen", "Steffensen", "Toft", "Brandt", "Berg", "Lauritsen", "Lind", "Holst", "Juul", "Danielsen", "Dam", "Andresen", "Nygaard", "Mathiesen", "Bak", "Damgaard", "Schultz", "Overgaard", "Schou", "Nilsson", "Thygesen", "Hermansen", "Hedegaard", "Juhl", "Mathiasen", "Klausen", "Paulsen", "Kruse", "Thorsen", "Kristoffersen", "Munk", "Koch", "Bjerregaard", "Lorenzen", "Karlsen", "Beck", "Riis", "Miller", "Lauritzen", "Villadsen", "Lorentzen", "Bundgaard", "Aagaard", "Hald", "Davidsen", "Bonde", "Lange", "Svensson", "Bendtsen", "Justesen", "Bjerre", "Johannsen", "Fischer", "Meyer", "Sommer", "Andersson", "Carstensen", "Enevoldsen", "Johannesen", "Hemmingsen", "Ibsen", "Gade", "Hjorth", "Eskildsen", "Kofoed", "Dalsgaard", "Michelsen", "Markussen", "Persson", "Laustsen", "Berthelsen", "Vinther", "Henningsen", "Asmussen", "Kragh", "Johansson", "Søgaard", "Kirkegaard", "Graversen", "Olsson", "Brodersen", "Ipsen", "Frost", "Kjærgaard", "Hougaard", "Nikolajsen", "Buch", "Marcussen", "Ludvigsen", "Ottosen", "Laugesen", "Axelsen", "Dalgaard", "Therkildsen", "Krog", "Storm", "Clemmensen", "Bisgaard", "Svenningsen", "Nicolaisen", "Michaelsen", "Leth", "Bentsen", "Bendixen", "Ottesen", "Westergaard", "Matthiesen", "Fisker", "Dinesen", "Erichsen", "Albrechtsen", "Ebbesen", "Lindberg", "Villumsen", "Sloth", "Munch", "Thuesen", "Thomassen", "Ovesen", "Buhl", "Boesen", "Bentzen", "Smith", "Mouritsen", "Greve", "Vilhelmsen", "Skovgaard", "Bjerg", "Bay", "Müller", "Gram", "Korsgaard", "Johannessen", "Haugaard", "Magnussen", "Thrane", "Thomasen", "Espersen", "Bruhn", "Pallesen", "Wagner", "Kofod", "Isaksen", "Rahbek", "Callesen", "Hammer", "Gravesen", "Lykke", "Nedergaard", "Borup", "Storgaard", "Daugaard", "Thorup", "Boysen", "Rask", "Abrahamsen", "Christophersen", "Fabricius", "Sand", "Dall", "Wulff", "Mølgaard", "Damsgaard", "Kirk", "Bang", "Hartmann", "Sonne", "Hviid", "Larsson", "Andreassen", "Rohde", "Pihl", "Due", "Ladefoged", "Damm", "Smidt", "Degn", "Torp", "Hjort", "Antonsen", "Bloch", "Troelsen", "Duus", "Balle", "Birch", "Borg", "Skou", "Skaarup", "Schrøder", "Brix", "Abildgaard", "Truelsen", "Vester", "Svane", "Brink", "Birk", "Karlsson", "Ditlevsen", "Steen", "Stokholm", "Busk", "Philipsen", "Therkelsen", "Skriver", "Rosenberg", "Pilgaard", "Martinsen", "Kvist", "Lundberg", "Lundsgaard", "Bagger", "Gammelgaard", "Wind", "Odgaard", "Voss", "Sandberg", "Hvid", "Caspersen", "Jansen", "Klitgaard", "Meldgaard", "Blom", "Holmgaard", "Green", "Groth", "Kjærsgaard", "Qvist", "Schwartz", "Astrup", "Willumsen", "Joensen", "Weber", "Rømer", "Kragelund", "Falk", "Adamsen", "Bager", "Hauge", "Krarup", "Krag", "Wolff", "Boisen", "Haagensen", "Drejer", "Thøgersen", "Krogsgaard", "Keller", "Kock", "Tolstrup", "Kronborg", "Lehmann", "Kramer", "Bro", "Fogh", "Strøm", "Holt", "Lynge", "Husted", "Yde", "Dupont", "Skytte", "Elkjær", "Gundersen", "Rytter", "Meier", "Lindholm", "Schneider", "Severinsen", "Bagge", "Kaas", "Bergmann", "Khan", "Rosendahl", "Nyborg", "Kjeldgaard", "Sander", "Vang", "Smed", "Buus", "Roed", "Hein", "Lundgaard", "Jæger", "Frank", "Koefoed", "Martinussen", "Høgh", "Bille", "Lerche", "Kirkeby", "Just", "Lindegaard", "From", "Vad", "Westh", "Høj", "Carlsson", "Bjerrum", "Krabbe", "Borch", "Würtz", "Dideriksen", "Junker", "Dueholm", "Rosenkilde", "Hertz", "Hermann", "Lorentsen", "Salling", "Worm", "Terp", "Bidstrup", "Jønsson", "Bitsch", "Stougaard", "Hansson", "Foged", "Hove", "Ploug", "Lynggaard", "Kromann", "Dissing", "Smedegaard", "Tang", "Rosendal", "Munck", "Harder", "Josefsen", "Boye", "Haahr", "Linde", "Guldager", "Kloster", "Elgaard", "Lindhardt", "Vind", "Nicolajsen", "Norup", "Holmberg", "Dyhr", "Jonassen", "Bork", "Lyhne", "Foldager", "Slot", "Vedel", "Højgaard", "Have", "Kastrup", "Steenberg", "Matzen", "Egholm", "Neumann", "Mouritzen", "Stage", "Kure", "Terkelsen", "Raun", "Falkenberg", "Flindt", "Bæk", "Damkjær", "Munkholm", "Eliasen", "Gotfredsen", "Stampe", "Hede", "Sejersen", "Lang", "Pagh", "Brogaard", "Bjerring", "Aarup", "Ladegaard", "Mørch", "Brun", "Rønne", "Harboe", "Valentin", "Enemark", "Warming", "Refsgaard", "Risager", "Staal", "Kold", "Månsson", "Lindgaard", "Rossen", "Beyer", "Vangsgaard", "Lindstrøm", "Dreyer", "Post", "Engel", "Samuelsen", "Schulz", "Schack", "Jochumsen", "Lykkegaard", "Anderson", "Kaae", "Kanstrup", "Esbensen", "Faber", "Feddersen", "Cramer", "Kusk", "West", "Mørk", "Tran", "Agerskov", "Hendriksen", "Salomonsen", "Horn", "Kryger", "Vendelbo", "Stæhr", "Bank", "Mose", "Boel", "Hinrichsen", "Broberg", "Malling", "Strand", "Rose", "Høyer", "Juel", "Deleuran", "Stephansen", "Holme", "Klein", "Paaske", "Lohmann", "Lausen", "Kaspersen", "Melgaard", "Skaaning", "Bækgaard", "Bülow", "Espensen", "Alstrup", "Nymann", "Mygind", "Hoffmann", "Gottlieb", "Egelund", "Marker", "Hyldgaard", "Stilling", "Bjørn", "Riber", "Voigt", "Klemmensen", "Bojsen", "Mark", "Petersson", "Witt", "Lohse", "Bugge", "Eskesen", "Moesgaard", "Noer", "Kjøller", "Egeberg", "Balslev", "Kolding", "Korsholm", "Linnet", "Serup", "Wolf", "Vinding", "Lomholt", "Mohr", "Ehlers", "Fenger", "Hoff", "Harbo", "Dahlgaard", "Rasch", "Vittrup", "Bendix", "Hartvig", "Holgersen", "Agger", "Strange", "Becker", "Byskov", "Dalby", "Breum", "Vistisen", "Lausten", "Carstens", "Zacho", "Lyng", "Wichmann", "Mollerup", "Fink", "Skipper", "Tranberg", "Lundgren", "Aggerholm", "Blaabjerg", "Overby", "Engberg", "Bossen", "Brøndum", "Hagen", "Marcher", "Secher", "La Cour", "Suhr", "Outzen", "Holck", "Hovgaard", "Conradsen", "Kyed", "Trolle", "Rafn", "Kjærulff", "Appel", "Kamp", "Langhoff", "Nyholm", "Zachariassen", "Palm", "Rønn", "Soelberg", "Ryberg", "Tange", "Midtgaard", "Grøn", "Mosegaard", "Brinch", "Bøgh", "Munksgaard", "Richter", "Bering", "Niemann", "Nørregaard", "Halkjær", "Hvidberg", "Langballe", "Otte", "Hamann", "Pontoppidan", "Banke", "Mørup", "Berntsen", "Viborg", "Bachmann", "Ulrich", "Ring", "Boll", "Helbo", "Straarup", "Pape", "Gaarde", "Stensgaard", "Mejer", "Guldberg", "Kokholm", "Singh", "Gormsen", "Thiesen", "Didriksen", "Balling", "Vest", "Krüger", "Skovsgaard", "Kappel", "Thaysen", "Walther", "Hvass", "Karstensen", "Randrup", "Foss", "Krebs", "Aagesen", "Stender", "Bredahl", "Kilic", "Quist", "Mathiassen", "Skovbjerg", "Sorensen", "Bødker", "Brandstrup", "Bramsen", "Fog", "Baun", "Sylvest", "Weinreich", "Jonsson", "Halberg", "Husum", "Klit", "Drachmann", "Svenstrup", "Albrektsen", "Gadegaard", "Nørskov", "Hall", "Lysgaard", "Brask", "Reimer", "Franck", "Hejlesen", "Kejser", "Handberg", "Lunde", "Panduro", "Gravgaard", "Ejlersen", "Yilmaz", "Glerup", "Neergaard", "Martens", "Broe", "Emborg", "Kudsk", "Stergaard", "Amstrup", "Ernst", "Peters", "Haslund", "Vinter", "Thorhauge", "Rindom", "Heide", "Ringgaard", "Bladt", "Gustavsen", "Beier", "Wiberg", "Wiese", "Corneliussen", "Mønster", "Frisk", "Lindgren", "Hessellund", "Rygaard", "Bock", "Nymark", "Hegelund", "Petterson", "Thestrup", "Glud", "Kring", "Nrgaard", "Winkel", "Ebsen", "Klint", "Honoré", "Fallesen", "Konradsen", "Stentoft", "Moos", "List", "Rode", "Weiss", "Alexandersen", "Hahn", "Thyssen", "Dreier", "Sunesen", "Damborg", "Rosenlund", "Holdt", "Gylling", "Nybo", "Hovmand", "Dencker", "Wilhelmsen", "Boje", "Martensen", "Skøtt", "Duelund", "Lentz", "Bauer", "Bilde", "Winkler", "Aaen", "Raahauge", "Skafte", "Ohlsen", "Pettersson", "Rønnow", "Anker", "Hesselberg", "Langkjær", "Thisted", "Ulriksen", "Lodberg", "Binderup", "Buur", "Kondrup", "Køhler", "Kamper", "Hartvigsen", "Lindahl", "Langkilde", "Hyllested", "Nordentoft", "Honore", "Høeg", "Josephsen", "Bendsen", "Nymand", "Zimmermann", "Bechmann", "Bennedsen", "Hostrup", "Nellemann", "Fredslund", "Henneberg", "Elbæk", "Primdahl", "Djurhuus", "Dehn", "Erlandsen", "Reinholdt", "Stryhn", "Borum", "Fuglsang", "Lunding", "Tarp", "Riise", "Thinggaard", "Borregaard", "Hildebrandt", "Hoppe", "Timm", "Lauesen", "Topp", "Vilstrup", "Demant", "Bigum", "Mandrup", "Lindgreen", "Magnusson", "Melchiorsen", "Grau", "Lundstrøm", "Bruus", "Sandager", "Skovby", "Engelbrecht", "Brock", "Hjelm", "Lemming", "Bojesen", "Thorsager", "Haastrup", "Klinge", "Filtenborg", "Bennetsen", "Sehested", "Sinding", "Ziegler", "Kaiser", "Johnson", "Lundgreen", "Mahler", "Baltzer", "Skjødt", "Haaning", "Vognsen", "Friberg", "Bertram", "Halvorsen", "Normann", "Sahl", "Seerup", "Guldborg", "Trier", "Berger", "Houmann", "Kamstrup", "Skovbo", "Stefansen", "Thybo", "Jorgensen", "Willadsen", "Westermann", "Scheel", "Tougaard", "Borre", "Sund", "Herskind", "Nøhr", "Eriksson", "Fyhn", "Junge", "Lautrup", "Lundquist", "Mønsted", "Baadsgaard", "Bekker", "Boe", "Høegh", "Ingemann", "Kiel", "Blicher", "Gad", "Lauersen", "Jokumsen", "Thorsted", "Monrad", "Arildsen", "Dybdal", "Plesner", "Saabye", "Pehrson", "Ebdrup", "Hornstrup", "Velling", "Enggaard", "Merrild", "Sauer", "Heegaard", "Kjer", "Lodahl", "Lundqvist", "Hvam", "Juhler", "Niebuhr", "Vammen", "Dybdahl", "Morsing", "Tofte", "Boserup", "Timmermann", "Rix", "Malmberg", "Pind", "Abel", "Jürgensen", "Stausholm", "Runge", "Arentoft", "Kongsted", "Skibsted", "Reenberg", "Falck", "Kehlet", "Krause", "Broch", "Winding", "Agerholm", "Dollerup", "Illum", "Mehlsen", "Mouridsen", "Grove", "Myrup", "Puggaard", "Forsberg", "Jensby", "Mulvad", "Blichfeldt", "Kiilerich", "Kornum", "Lau", "Geisler", "Tønnesen", "Agerbo", "Carlson", "Dalum", "Nordstrøm", "Flensborg", "Gissel", "Snedker", "Graff", "Wollesen", "Bergstrøm", "Guldbæk", "Klarskov", "Tandrup", "Tholstrup", "Skyum", "Baunsgaard", "Hjerrild", "Theilgaard", "Færch", "Hess", "Møldrup", "Ritter", "Skjoldborg", "Milling", "Molin", "Thostrup", "Bomholt", "Roth", "Hyldahl", "Abildtrup", "Hastrup", "Obel", "Heiberg", "Terkildsen", "Yildirim", "Offersen", "Skovlund", "Bærentsen", "Engholm", "Krohn", "Maagaard", "Ingerslev", "Kjellerup", "Oddershede", "Præst", "Soerensen", "Barfod", "Bohn", "Vig"];
 
 App.Data.misc.djiboutianSlaveNames = ["Aamal", "Abdah", "Abia", "Abida", "Abir", "Abla", "Adara", "Adélaïde", "Adèle", "Adila", "Adiva", "Adjah", "Adrienne", "Afaaf", "Afaf", "Afra", "Afriah", "Afton", "Agathe", "Agnès", "Ahlam", "Ahsia", "Aicha", "Aïcha", "Aile", "Aimée", "Ain", "Aisha", "Aishah", "Akilah", "Akram", "Alaia", "Alaine", "Albane", "Ale", "Aleah", "Alette", "Alexandra", "Alexanne", "Alexis", "Ali", "Alia", "Alice", "Alima", "Alina", "Aline", "Alix", "Aliya", "Alizée", "Almira", "Alya", "Amal", "Amalie", "Amandine", "Amani", "Amatullah", "Ambre", "Amée", "Amélie", "Amimah", "Amina", "Aminah", "Amira", "Amna", "Anabelle", "Anaëlle", "Anaïs", "Andréa", "Andréanne", "Andrée", "Andrie", "Ange", "Angélique", "Anisa", "Annabelle", "Anne-Marie", "Anne-Sophie", "Anne", "Annette", "Annick", "Annie", "Antoinette", "Appoline", "Ara", "Ariane", "Arielle", "Arlette", "Armelle", "Aseel", "Ashra", "Asiya", "Asly", "Asma", "Astérie", "Atifa", "Aubine", "Aurélie", "Aurore", "Avril", "Awo", "Axelle", "Ayane", "Ayasha", "Ayesha", "Aza", "Aziah", "Aziza", "Azza", "Babette", "Bahira", "Bahiyya", "Banah", "Baraka", "Barakah", "Barbe", "Barika", "Basimah", "Basma", "Basmah", "Bathsira", "Batool", "Béatrice", "Belle", "Bernadette", "Bernice", "Bertille", "Bibi", "Bien Aimée", "Blaisotte", "Blanche", "Blanchette", "Bluette", "Brigitte", "Buthayna", "Cala", "Calanthe", "Camille", "Cantara", "Capucine", "Carolane", "Carole", "Caroline", "Cassandre", "Catherine", "Cécilie", "Celeste", "Célia", "Céline", "Cerise", "Chanel", "Chantal", "Chardae", "Charde", "Charline", "Charlotte", "Charmaine", "Cherie", "Chloë", "Chouchii", "Choukri", "Christelle", "Christiane", "Christine", "Claire-Marie", "Claire", "Clarisse", "Claude", "Claudette", "Claudie", "Claudine", "Clémence", "Clémentine", "Clervie", "Cloé", "Clothilde", "Clotilde", "Colette", "Coline", "Colombe", "Constance", "Coralie", "Cordélie", "Corentine", "Corinne", "Cornélie", "Cosette", "Crescence", "Dahah", "Daifa", "Dalal", "Dalia", "Dananir", "Danielle", "Daphné", "Daphnée", "Delphine", "Denise", "Desirée", "Dhakirah", "Dianne", "Dima", "Dionne", "Doha", "Dominique", "Doralice", "Doré", "Dorette", "Doriane", "Dorothée", "Du'a", "Duha", "Duqaq", "Égérie", "Ehteram", "Elaheh", "Elaine", "Éléanore", "Eléna", "Éliane", "Élisabeth", "Elise", "Élizabeth", "Elmira", "Élodie", "Eloise", "Eman", "Emeline", "Émilie", "Émilienne", "Emine", "Emmanuelle", "Emy", "Eram", "Ernestine", "Esmé", "Estée", "Estelle", "Eugénie", "Eulalie", "Evangeline", "Eve", "Evelyne", "Faaiza", "Fabienne", "Fadia", "Fadila", "Fairuz", "Faizah", "Falestine", "Fanny", "Fantine", "Farah", "Fard", "Fardoos", "Farhaana", "Farida", "Fatemeh", "Fathia", "Fathiyya", "Fatima", "Fatimah", "Fatma", "Fatoum", "Fatouma", "Fatunah", "Fayruz", "Fayza", "Fernande", "Fifi", "Fimiro", "Fizza", "Fleur", "Florence", "Florie", "Francine", "Françoise", "Frédérique", "Fukayna", "Gabrielle", "Geneviève", "Genna", "Georgette", "Georgine", "Germaine", "Gervaise", "Ghada", "Ghaliya", "Ghaniyah", "Ghislaine", "Ginette", "Gisèle", "Grâce", "Hababah", "Habibah", "Habibeh", "Hadil", "Hadya", "Hafiya", "Hafsa", "Hafsah", "Haïbado", "Haideh", "Hala", "Haleh", "Halima", "Hamida", "Hamideh", "Hana", "Hanan", "Haneen", "Hanifa", "Haniyya", "Hasna", "Hatima", "Hawa", "Hawwa", "Hélène", "Héloïse", "Henriette", "Hermine", "Hibo", "Hinda", "Hoda", "Hodal", "Hodan", "Houda", "Huda", "Husniyah", "Hyacinthe", "Iamar", "Idil", "Iesha", "Ihsan", "Ikram", "Ilham", "Iman", "Inam", "Inan", "Inés", "Innas", "Irène", "Iris", "Isabeau", "Isabelle", "Ismat", "Isra", "Jacqueline", "Jalila", "Jamila", "Jana", "Janine", "Jasmine", "Jeand'arc", "Jeanette", "Jeanine", "Jeanne-Aimée", "Jeanne-Yvette", "Jeanne", "Jeannine", "Jena", "Jenaw", "Jenevieve", "Jinan", "Joëlle", "Jolène", "Jomana", "Josephine", "Josette", "Josiane", "Juju", "Julie", "Juliette", "Jumana", "Justine", "Kadra", "Kali", "Kalifa", "Kalila", "Kamala", "Kamilah", "Karida", "Karima", "Karimah", "Karine", "Khadija", "Khadijah", "Khadrita", "Khalida", "Khalifa", "Khalilah", "Kobra", "Laetitia", "Laila", "Lakia", "Laure", "Laurence", "Lauriane", "Laurianne", "Laurie", "Laurine", "Layla", "Léa", "Leen", "Leila", "Léonie", "Léonore", "Leyla", "Liane", "Lianne", "Lidvine", "Liliane", "Lilianne", "Lina", "Lise", "Lisette", "Loelia", "Loraine", "Loréline", "Lorraine", "Louise", "Lubna", "Lucie", "Lucienne", "Lucile", "Lucille", "Lucrèce", "Ludivine", "Lujayn", "Lulah", "Lydie", "Mabelle", "Madeleine", "Madiha", "Madima", "Maelle", "Magalie", "Magda", "Maha", "Mahasin", "Mahlagha", "Mahlayba", "Maimuna", "Maiza", "Majidah", "Malak", "Malika", "Maliki", "Manhalah", "Manon", "Marcelle", "Margaux", "Margot", "Marguerite", "Mariah", "Mariam", "Marian", "Marianne", "Marie-Anne", "Marie-Claire", "Marie-Claude", "Marie-Ève", "Marie-France", "Marie-Hélène", "Marie-Laure", "Marie-Louise", "Marie-Noelle", "Marie-Pier", "Marie-Pierre", "Marie-Sophie", "Marie-Sylvie", "Marie-Thérèse", "Marie", "Marielle", "Marine", "Marion", "Mariyah", "Marjolaine", "Marthe", "Martine", "Marwa", "Maryam", "Mathilde", "Maude", "Maxime", "Maxine", "Maysun", "Mégane", "Mélaine", "Mélanie", "Mélina", "Mélissa", "Mélodie", "Michèle", "Micheline", "Mignon", "Mimi", "Mirabelle", "Mireille", "Monette", "Monique", "Morgane", "Moumina", "Mouna", "Mufidah", "Munira", "Musette", "Muslimah", "Mylène", "Myriam", "Nabila", "Nabilia", "Nada", "Nadan", "Nadège", "Nadia", "Nadine", "Nadira", "Nadrah", "Nadya", "Naeemah", "Nafisa", "Nahida", "Naila", "Nailah", "Naima", "Naimah", "Najla", "Najlah", "Najmah", "Najwa", "Nanette", "Natalie", "Nathalie", "Nathifa", "Nawal", "Nedira", "Neima", "Nicole", "Nicolette", "Nida", "Nima", "Nini", "Noelle", "Noemi", "Noemie", "Noémie", "Noha", "Noor", "Noura", "Nuha", "Nujood", "Numa", "Nur", "Nuri", "Nusaiba", "Océane", "Odette", "Odile", "Oma", "Ombeline", "Ophélie", "Orégane", "Patrice", "Paulette", "Pauline", "Philippine", "Qamar", "Qubilah", "Quitterie", "Rabi", "Rabiah", "Rachelle", "Radwa", "Rahmat", "Raja", "Rana", "Randa", "Ranya", "Rara", "Rashida", "Raymonde", "Rayya", "Raziya", "Reem", "Renée", "Rezeya", "Rida", "Rihana", "Rima", "Rochelle", "Roda", "Romaine", "Romane", "Rosalie", "Rose", "Rosine", "Roxane", "Rukhsar", "Rusa", "Saba", "Sabad", "Sabah", "Sabine", "Sabra", "Sabrine", "Sadaf", "Sadika", "Sadira", "Saduf", "Safa", "Safia", "Safinaz", "Safiya", "Safwah", "Saham", "Sahar", "Sahara", "Saliha", "Salima", "Salimah", "Sally", "Salma", "Salome", "Salomé", "Salwa", "Samar", "Samara", "Samarah", "Sameen", "Sami", "Samira", "Samya", "Sana", "Sanah", "Sandrine", "Sara", "Sarab", "Sarah", "Saredo", "Sawsan", "Semeeah", "Séraphine", "Sereen", "Shadiya", "Shadya", "Shafiqa", "Shagayegh", "Shahar", "Shahida", "Shahira", "Shahrazad", "Shahrizad", "Shajar", "Shakira", "Shamoona", "Sharda", "Sharday", "Shareen", "Sharifa", "Sheba", "Shiklah", "Shurooq", "Sidonie", "Siham", "Simone", "Simonne", "Sisi", "Sixtine", "Soheyla", "Solange", "Solène", "Solenne", "Sophie", "Soso", "Stéphanie", "Subreen", "Suha", "Suhad", "Suhair", "Sulema", "Sulma", "Sultaana", "Summar", "Sundus", "Suzanne", "Sylvie", "Tabina", "Tala", "Taliba", "Tamasha", "Tarra", "Thalia", "Thérèse", "Tiphaine", "Ulayyah", "Ulima", "Umniya", "Uzma", "Valentine", "Valérie", "Véronique", "Victoire", "Violette", "Virgie", "Virginie", "Vivienne", "Wafa", "Wahiba", "Wahshiyah", "Walaa", "Widad", "Xabiiba", "Yamilex", "Yamina", "Yannick", "Yara", "Yasmeen", "Yasmin", "Yasmina", "Yazmina", "Yusra", "Yvette", "Yvonne", "Zada", "Zahira", "Zahra", "Zahrah", "Zakiayah", "Zakiyya", "Zara", "Zaria", "Zaynab", "Zebeebah", "Zeina", "Zeinab", "Zena", "Zizi", "Zoë", "Zouhra", "Zourah", "Zourha", "Zubaydah", "Zuhair", "Zukha", "Zulaikha", "Zuleika", "Zunaira", "Zuzi"];
 App.Data.misc.djiboutianMaleNames = ["Aamir", "Aashid", "Aashish", "Abbud", "Abdelaziz", "Abdi", "Abdiel", "Abdoulrahman", "Abdourahman", "Abdul", "Abdulaziz", "Abdullah", "Abdulmalik", "Abdulrahman", "Abdulsalaam", "Aboubaker", "Abu", "Abubakr", "Achille", "Achmed", "Adad", "Adam", "Adel", "Adhem", "Adil", "Adrien", "Afif", "Ahmad", "Ahmed", "Aïdan", "Aiman", "Akbar", "Akeem", "Akil", "Aladdin", "Alain-René", "Alain", "Alaoui", "Alban", "Albert", "Alexandre", "Alexis", "Ali", "Allah", "Aloïs", "Alphonse", "Amal", "Amar", "Amaury", "Ambroise", "Amédée", "Ameer", "Amer", "Amin", "Amir", "Amit", "Anass", "Anatole", "André", "Anicet", "Anselme", "Antoine", "Anwar", "Aref", "Arif", "Aristide", "Armand", "Arnan", "Arnaud", "Arsène", "Arthur", "Asadel", "Ashraf", "Aslan", "Assoweh", "Aswad", "Atif", "Atiq", "Aubert", "Aubin", "Audefroy", "Auguste", "Augustin", "Aurélien", "Ayame", "Ayanleh", "Ayman", "Aymeric", "Ayoub", "Azim", "Aziz", "Badr", "Bahir", "Bahjat", "Baptiste", "Bardiou", "Barthélémy", "Basheer", "Basile", "Basim", "Bassam", "Bastien", "Baudier", "Baudouin", "Beau", "Benjamin", "Benoît", "Bérenger", "Bernard", "Bertrand", "Bilal", "Blaise", "Borhane", "Boudreaux", "Bourhan", "Brice", "Brieux", "Bruno", "Cécil", "Cédric", "Cédrick", "Céléstin", "César", "Charles Étienne", "Charles-Antoine", "Charles", "Chrétien", "Christophe", "Clair", "Claude", "Clément", "Clovis", "Coman", "Côme", "Constantin", "Corentin", "Cyprien", "Cyriaque", "Cyrille", "Dabir", "Damien", "Danick", "Daniel", "Dany", "Dartagnan", "David", "Dawud", "Dédé", "Dekel", "Denis", "Déreck", "Didier", "Dijani", "Diya", "Djama", "Dodi", "Dominique", "Donatien", "Ebi", "Edmond", "Édouard", "Égide", "Ehsan", "Élias", "Élie", "Éliot", "Éloi", "Emad", "Émerick", "Emeril", "Émile", "Émilien", "Emin", "Emmanuel", "Enrick", "Éric", "Esmé", "Étienne", "Eugène", "Evarist", "Évrard", "Fabien", "Fabrice", "Fadi", "Fadil", "Fahim", "Faisal", "Faiz", "Faraj", "Farhan", "Farid", "Faris", "Farouq", "Farran", "Faruq", "Fathi", "Faust", "Fawzi", "Faysal", "Félix Antoine", "Félix", "Fernand", "Fidèle", "Firmin", "Flavien", "Florent", "Florian", "Fouad", "Franck", "François", "Frédéric", "Frédérick", "Fuad", "Gabin", "Gabriel", "Gadi", "Gaël", "Gaétan", "Gaëtan", "Gaspard", "Gaston", "Gatien", "Gauthier", "Gautier", "Gédéon", "Geoffroy", "George-Marie", "Georges", "Gérard", "Germain", "Ghislain", "Gilbert", "Giles", "Gilles", "Giraud", "Grégoire", "Guillaume", "Gustave", "Guy", "Habib", "Haddad", "Hadi", "Hafeez", "Hafiz", "Haidar", "Hakeem", "Hakim", "Halim", "Hamal", "Hamdi", "Hameed", "Hamid", "Hammad", "Hamza", "Hamzah", "Hamze", "Hanif", "Haroun", "Hasan", "Hashim", "Hasim", "Hassad", "Hassan", "Hathem", "Hatim", "Hazim", "Henri", "Hervé", "Hesam", "Heydar", "Hibah", "Hilaire", "Hilal", "Hilel", "Hisein", "Hisham", "Hoche", "Honoré", "Hosain", "Hosni", "Houssein", "Hubert", "Hugo", "Hugues", "Husain", "Husayn", "Hüseyin", "Husnain", "Hussam", "Hussein", "Ibraheem", "Ibrahim", "Idiamin", "Ignace", "Ihab", "Imani", "Imran", "Iourhanta", "Irène", "Isidore", "Ismael", "Ismaël", "Ismail", "Jabbar", "Jacques-Yves", "Jacques", "Jacquot", "Jafar", "Jakeem", "Jaleel", "Jalil", "Jamahl", "Jamal", "Jamil", "Javad", "Jean-Albert", "Jean-André", "Jean-Baptise", "Jean-Christophe", "Jean-Claude", "Jean-Didier", "Jean-France", "Jean-François", "Jean-Guy", "Jean-Jacques", "Jean-Jérôme", "Jean-Lou", "Jean-Louis", "Jean-Luc", "Jean-Marc", "Jean-Marie", "Jean-Michel", "Jean-Paul", "Jean-Philippe", "Jean-Pierre", "Jean-René", "Jean-Sébastien", "Jean-Simon", "Jean-Xavier", "Jean-Yves", "Jean", "Jérémi", "Jérémie", "Jérémy", "Jermaine", "Jérôme", "Jessy", "Jinan", "Joël", "Jojo", "Joscelin", "Joseph-Benoît", "Joseph", "Jourdain", "Jules", "Julien", "Jumah", "Juste", "Justin", "Kabir", "Kadar", "Kadeem", "Kadin", "Kadir", "Kaleef", "Kaleel", "Kalil", "Kamal", "Kamali", "Kamil", "Kandari", "Karam", "Kardal", "Kareem", "Karif", "Karim", "Kaseem", "Kasib", "Kasim", "Khailil", "Khaled", "Khalid", "Khalil", "Khari", "Khayrat", "Koran", "Lateef", "Laurent", "Lazare", "Léandre", "Léo", "Léon", "Léonard", "Léopold", "Lilian", "Loïc", "Lou", "Louis Philippe", "Louis-Charles", "Louis-Joseph", "Louis", "Louka", "Luc", "Lucas", "Lucien", "Ludovic", "Macaire", "Maël", "Mahamoud", "Mahmoud", "Mahmud", "Maimun", "Makram", "Malik", "Mamduh", "Mansoor", "Mansur", "Marc André", "Marc Antoine", "Marc Olivier", "Marc-Alexandre", "Marc-André", "Marc-Antoine", "Marc-Henri", "Marc", "Marcel", "Marcellin", "Marid", "Martin", "Marwan", "Masoud", "Masud", "Mathias", "Mathieu", "Mathis", "Mattéo", "Matthieu", "Maurice", "Maxence", "Maxime", "Maximilien", "Mazen", "Mehdi", "Mehmet", "Mekhi", "Michel", "Mickaël", "Moamen", "Mohamed", "Mohammed", "Mohsen", "Moneeb", "Moussa", "Mubarak", "Muftah", "Muhammad", "Muhammed", "Muhanna", "Mumin", "Munir", "Murtada", "Musad", "Mushtaq", "Mustafa", "Muzzammil", "Nabeel", "Nabil", "Nader", "Nadim", "Naeem", "Nahim", "Najar", "Najee", "Naji", "Najib", "Namdar", "Narcisse", "Nasair", "Nasawi", "Nasser", "Nazih", "Nazir", "Nicéphore", "Nicolas", "Nihad", "Nizar", "Noé", "Noël", "Nordine", "Numar", "Nuri", "Nusair", "Nyel", "Octavien", "Odilon", "Olivier", "Omar", "Omri", "Owais", "Pascal", "Patrice", "Paul", "Philippe", "Pier-Olivier", "Pierre Alexandre", "Pierre Olivier", "Pierre-Luc", "Pierre", "Pierrick", "Pierrot", "Prosper", "Qaasim", "Qamar", "Qasim", "Quentin", "Quran", "Qusay", "Rabi", "Raed", "Rafaël", "Raffi", "Rafi", "Rafiq", "Rahim", "Rahman", "Rahsaan", "Rahsan", "Rahul", "Rajab", "Ramadan", "Rami", "Ramir", "Ramzi", "Raoul", "Raphaël", "Rashaad", "Rashad", "Rasheed", "Rasheem", "Rashid", "Rayan", "Raymond", "Réal", "Régis", "Réjean", "Rémi", "Rémy", "Renald", "Renaud", "René", "Reyham", "Reza", "Richard", "Rida", "Riyad", "Riyaz", "Robert", "Robleh", "Rodolphe", "Rodrigue", "Roger", "Roland", "Romain", "Romaine", "Rushdi", "Saad", "Sadik", "Sadiq", "Safwan", "Sahar", "Said", "Saleem", "Salih", "Salim", "Salman", "Sameer", "Sami", "Samir", "Samuel", "Samy", "Sayyid", "Sébastien", "Seif", "Serge", "Séverin", "Shadi", "Shafiq", "Shahien", "Shareef", "Sharif", "Shaukat", "Shazad", "Shereef", "Sherin", "Shukri", "Sidiq", "Simeon", "Simon Olivier", "Sina", "Soda", "Sofiane", "Sohil", "Stanislas", "Stefan-André", "Stephan", "Stéphane", "Suha", "Sulaiman", "Sulpice", "Syed", "Sylvain", "Sylvestre", "Taha", "Tahid", "Tahir", "Talal", "Talib", "Tamer", "Tancrede", "Tarek", "Tariq", "Tawfiq", "Théo", "Théodore", "Théophile", "Thibaud", "Thibault", "Thibaut", "Thierry", "Thomas", "Timothé", "Timothée", "Toussaint", "Umar", "Usman", "Valentin", "Valère", "Victor", "Vincent", "Virgile", "Wa'il", "Wafa", "Wahid", "Waleed", "Walid", "Wathan", "Xavier", "Yahya", "Yamil", "Yan", "Yanick", "Yanis", "Yasar", "Yasir", "Yazid", "Yoan", "Yohan", "Youness", "Yousef", "Yousouf", "Youssef", "Youssouf", "Yusuf", "Yves", "Yvon", "Zacharie", "Zahir", "Zahur", "Zaid", "Zaki", "Zamil", "Zayn", "Zephrin", "Zinnedine", "Ziyad", "Zuhd"];
@@ -921,7 +1923,7 @@ App.Data.misc.bimboMaleNames = ["A.J.", "Aaron", "Abe", "Adam", "Aiden", "Al", "
 
 /*
 Name pool selector based on nationality and race. Use as follows, given some slave "slave":
-namePool = (setup.namePoolSelector[slave.nationality + "." + slave.race] || setup.namePoolSelector[slave.nationality] || setup.whiteAmericanSlaveNames)
+namePool = (App.Data.misc.namePoolSelector[slave.nationality + "." + slave.race] || App.Data.misc.namePoolSelector[slave.nationality] || App.Data.misc.whiteAmericanSlaveNames)
 Then pick namePool.random(), or display those names as possible choices, or do whatever else you do with name pools.
 */
 App.Data.misc.namePoolSelector = {
diff --git a/js/003-data/playerData.js b/js/003-data/playerData.js
index 5ba750946df64541a1d20331aebf4563bf88586f..096abdf69305d0737ccd9b22172e2fe2b1837262 100644
--- a/js/003-data/playerData.js
+++ b/js/003-data/playerData.js
@@ -1,6 +1,5 @@
 App.Data.player = {
 	refreshmentType: new Map([
-			//Imagine using drugs. Cringe!
 		[0,
 			{
 				name: `Smoked`,
@@ -10,13 +9,13 @@ App.Data.player = {
 		[1,
 			{
 				name: `Drank`,
-				suggestions: new Set(["whiskey", "rum", "wine", "sake", "vodka", "beer"])
+				suggestions: new Set(["whiskey", "rum", "wine", "sake", "vodka", "beer", "bourbon", "scotch"])
 			}
 		],
 		[2,
 			{
 				name: `Eaten`,
-				suggestions: new Set(["steak"])
+				suggestions: new Set(["steak", "edibles"])
 			}
 		],
 		[3,
@@ -28,7 +27,7 @@ App.Data.player = {
 		[4,
 			{
 				name: `Injected`,
-				suggestions: new Set(["stimulants", "DMT"])
+				suggestions: new Set(["stimulants", "heroin"])
 			}
 		],
 		[5,
diff --git a/js/003-data/policiesData.js b/js/003-data/policiesData.js
index 19e9957434bab8c5fd5658c504fced4130a49559..8bdc865473e9e8b15aaa9ff692032c198bd909be 100644
--- a/js/003-data/policiesData.js
+++ b/js/003-data/policiesData.js
@@ -254,7 +254,7 @@ App.Data.Policies.Selection = {
 			{
 				title: "Oral Sex Encouragement",
 				text: "you will use your personal influence to make blowjobs the most fashionable sex act in the arcology.",
-				activatedText: "you are using your personal influence to make blowjobs the most fashionable sex act in the arcology..",
+				activatedText: "you are using your personal influence to make blowjobs the most fashionable sex act in the arcology.",
 				note: "Will increase the weight on slaves' oral skills"
 			},
 			{
@@ -312,6 +312,61 @@ App.Data.Policies.Selection = {
 				get hide() { return (V.extremeUnderage === 1) ? {button: 0} : {button: 1}; } // CPA is complicated. It inits to "on". Make sure button is hidden if extreme underage is OFF. If a player enables extreme underage, then we can let them control it.
 			}
 		],
+		"policies.idealAge": [
+			{
+				title: "Age Of Sexual Appeal",
+				get text() {
+					const el = new DocumentFragment;
+					if(V.idealAge === 18) {
+						el.append(`many consider the most sexually appealing age to be the old world default of 18. You will use your influence to change the sexual ideal to `);
+					}
+					else {
+						el.append(`many consider the most sexually appealing age to be ${V.idealAge}. You will use your influence to change the sexual ideal to `);
+					}
+					el.append(
+						App.UI.DOM.makeElement(
+							"div",
+							App.UI.DOM.makeTextBox(
+								V.targetIdealAge,
+								v => {
+									let minAge = V.minimumSlaveAge;
+									let maxAge = V.retirementAge - 1 > 60 ? 60 : V.retirementAge - 1;/* problems do occur if idealAge can be set to over 60 */
+									if(V.arcologies[0].FSMaturityPreferentialist !== "unset") {
+										minAge = 30;
+									}
+									if(V.arcologies[0].FSYouthPreferentialist !== "unset") {
+										maxAge = 29;
+									}
+									V.targetIdealAge = Math.clamp(v, minAge, maxAge);
+									App.UI.reload();
+								},
+								true
+							),
+							["indent"]
+						)
+					);
+					return el;
+				},
+				get activatedText() {
+					return `you are using your personal influence to make ${V.targetIdealAge} the most sexually appealing age. The current perceived ideal age is ${V.idealAge}.`;
+				},
+				onRepeal: function() { 
+					if(V.arcologies[0].FSMaturityPreferentialist !== "unset") {
+						if(V.idealAge < 30) {
+							V.idealAge = 30;
+						}
+						V.targetIdealAge = 30;
+					}
+					else {
+						if(V.idealAge >= 30) {
+							V.idealAge = 29;
+						}
+						V.targetIdealAge = 18;
+					}
+				},
+				get note() { return `Will cost ${cashFormat(1500)} weekly until the target age is reached; high reputation will accelerate adoption.`}
+			}
+		],
 		"arcologies[0].FSEgyptianRevivalistIncestPolicy": [
 			{
 				title: "Incest Encouragement",
@@ -746,6 +801,9 @@ App.Data.Policies.Selection = {
 									const age = Math.clamp(v, 20, 120);
 									V.customRetirementAge = age;
 									V.retirementAge = age;
+									if (V.idealAge >= V.retirementAge) {
+										V.idealAge = V.retirementAge - 1;
+									}
 									App.UI.reload();
 								},
 								true
@@ -776,6 +834,9 @@ App.Data.Policies.Selection = {
 									const age = Math.clamp(v, 20, 120);
 									V.customRetirementAge = age;
 									V.retirementAge = age;
+									if(V.idealAge >= V.retirementAge) {
+										V.idealAge = V.retirementAge - 1;
+									}
 									App.UI.reload();
 								},
 								true
diff --git a/js/003-data/slaveGeneData.js b/js/003-data/slaveGeneData.js
index fb6a3ee3c9c8129e6191e243729630b10a35d748..e642acf3c0b6119d8806521846e769c9d21bbc92 100644
--- a/js/003-data/slaveGeneData.js
+++ b/js/003-data/slaveGeneData.js
@@ -220,3 +220,29 @@ App.Data.geneticMods = new Map([
 		},
 	],
 ]);
+
+App.Data.milk = {
+	Flavors: [
+		{value: "almond"},
+		{value: "apricot"},
+		{value: "banana"},
+		{value: "blackberry"},
+		{value: "blueberry"},
+		{value: "caramel"},
+		{value: "cherry"},
+		{value: "chocolate"},
+		{value: "cinnamon"},
+		{value: "coconut"},
+		{value: "coffee"},
+		{value: "honey"},
+		{value: "mango"},
+		{value: "melon"},
+		{value: "mint"},
+		{value: "peach"},
+		{value: "peanut butter"},
+		{value: "pineapple"},
+		{value: "raspberry"},
+		{value: "strawberry"},
+		{value: "vanilla"}
+	]
+};
diff --git a/js/003-data/slaveMods.js b/js/003-data/slaveMods.js
index 6b7f94f5d9c079ea84a10f84045823dd259ad0c5..a07bac2d4e89f34d6d5fe634d7891e17275c8016 100644
--- a/js/003-data/slaveMods.js
+++ b/js/003-data/slaveMods.js
@@ -479,7 +479,8 @@ App.Medicine.Modification.eyeShape = [
 	{value: "wide-eyed"}
 ];
 
-App.Medicine.Modification.naturalSkins = ["pure white", "ivory", "white", "extremely pale", "very pale", "pale", "extremely fair", "very fair", "fair", "light", "light olive", "tan", "olive", "bronze", "dark olive", "dark", "light beige", "beige", "dark beige", "light brown", "brown", "dark brown", "black", "ebony", "pure black", "black and white striped", "red", "yellow"];
+App.Medicine.Modification.naturalSkins = ["pure white", "ivory", "white", "extremely pale", "very pale", "pale", "extremely fair", "very fair", "fair", "light", "light olive", "tan", "olive", "bronze", "dark olive", "dark", "light beige", "beige", "dark beige", "light brown", "brown", "dark brown", "black", "ebony", "pure black"];
+App.Medicine.Modification.catgirlNaturalSkins = ["white", "brown", "black", "red", "yellow", "black and white striped"];
 App.Medicine.Modification.dyedSkins = ["camouflage patterned", "dyed blue", "dyed white", "dyed gray", "dyed black", "dyed green", "dyed pink", "dyed red", "tiger striped", "dyed purple", "clown"];
 App.Medicine.Modification.naturalNippleColors = ["black", "brown", "dark brown", "ebony", "ivory", "light brown", "pale pink", "pink"];
 App.Medicine.Modification.eyebrowStyles = new Set(["shaved", "straight", "rounded", "natural", "slanted inwards", "slanted outwards", "high-arched", "elongated", "shortened", "curved"]);
@@ -561,7 +562,8 @@ App.Medicine.Modification.teeth = new Map([
 	}],
 ]);
 /**
- * @type {Record<FC.Piercing, Object>} Use singular when possible
+ * Use singular when possible
+ * @type {Record<FC.Piercing, {smart?: boolean, requirements?: (slave: FC.SlaveState) => boolean}>}
  */
 App.Data.Piercings = {
 	"ear": {
diff --git a/js/003-data/slaveSummaryData.js b/js/003-data/slaveSummaryData.js
index 4c2c3e49e426ac0529fe27a97c1a6bea2157d71a..465f67c7e32e73fd66cb580fb3be8a91025f811f 100644
--- a/js/003-data/slaveSummaryData.js
+++ b/js/003-data/slaveSummaryData.js
@@ -1,5 +1,5 @@
-// these ratings tables are consumed by App.UI.SlaveSummaryImpl.helpers. getNumericRating()
-// this function takes a value for rating and iterates a table (in the declaration order)
+// these ratings tables are consumed by App.Ratings.xxx()
+// those function takes a value for rating and iterates a table (in the declaration order)
 // until it finds a key greater or equal to the value; the found record is returned from the function
 // Briefly, each dictionary entry key -> value is read as "the highest rating that still suits -> value" or
 // "up to, including"
@@ -9,14 +9,19 @@ App.Data.SlaveSummary = {
 	long: {
 		body: {
 			age: {
-				17: "Underage.",
-				18: "Eighteen.",
-				19: "Nineteen.",
+				4: "Toddler.",
+				10: "Child.",
+				12: "Preteen.",
+				16: "Early teens.",
+				19: "Late teens.",
 				24: "Early twenties.",
 				29: "Late twenties.",
 				34: "Early thirties.",
 				39: "Late thirties.",
-				999: "Forties."
+				49: "Forties",
+				59: "Fifties",
+				69: "Sixties",
+				999: "Elderly."
 			},
 			face: { // face value + 100
 				4: {desc: "Very ugly", style: "red"},
@@ -90,7 +95,7 @@ App.Data.SlaveSummary = {
 						2: "Loose pussy.",
 						3: "High mileage."
 					},
-					4: {
+					99: {
 						3: "Cavernous pussy.",
 						4: "Blown out holes."
 					}
@@ -653,13 +658,19 @@ App.Data.SlaveSummary = {
 	short: {
 		body: {
 			age: {
-				18: "18",
-				19: "19",
+				4: "Toddl",
+				10: "Child",
+				12: "PTeen",
+				16: "EaTeen",
+				19: "LtTeen",
 				24: "Ea20s",
 				29: "Lt20s",
 				34: "Ea30s",
 				39: "Lt30s",
-				999: "40s"
+				49: "40s",
+				59: "50s",
+				69: "60s",
+				999: "Elder"
 			},
 			face: { // face value + 100
 				4: {desc: "Face---", style: "red"},
diff --git a/js/004-base/SurgeryEffect.js b/js/004-base/SurgeryEffect.js
index e0f299b9ba84bd71983fad36ac4970c473e8756f..09f00ffed574342f67adbec075d061c8d566c135 100644
--- a/js/004-base/SurgeryEffect.js
+++ b/js/004-base/SurgeryEffect.js
@@ -53,8 +53,8 @@ App.Medicine.Surgery.SimpleReaction = class {
 
 	/**
 	 * @typedef {object} reactionResult
-	 * @property {Array<Array<string|Node>>} longReaction can contain HTML, every array is a new paragraph. Shown when manually applied.
-	 * @property {Array<string|Node>} shortReaction can contain HTML. May be empty. Intended for use with RA.
+	 * @property {Array<Array<string|HTMLElement>>} longReaction can contain HTML, every array is a new paragraph. Shown when manually applied.
+	 * @property {Array<string|HTMLElement>} shortReaction can contain HTML. May be empty. Intended for use with RA.
 	 * @property {number} devotion 0 means no change
 	 * @property {number} trust 0 means no change
 	 */
diff --git a/js/004-base/SurgeryProcedure.js b/js/004-base/SurgeryProcedure.js
index 57fbd51cc91f2e23c3fe77ba894ef6aae310f625..dc5b65e44a22eb4d1538b5838739f0fa5ceec41d 100644
--- a/js/004-base/SurgeryProcedure.js
+++ b/js/004-base/SurgeryProcedure.js
@@ -16,6 +16,7 @@ App.Medicine.Surgery.Procedure = class {
 
 	// eslint-disable-next-line jsdoc/require-returns-check
 	/**
+	 * @abstract
 	 * @returns {string}
 	 */
 	get name() { throw new Error("Method 'name()' must be implemented."); }
@@ -27,6 +28,12 @@ App.Medicine.Surgery.Procedure = class {
 	 */
 	get description() { return ""; }
 
+	/**
+	 * Additional note to put at the bottom of the tooltip
+	 * @returns {string | DocumentFragment | HTMLElement}
+	 */
+	get note() { return null; }
+
 	/**
 	 * May die, but high player skill also reduces health impact.
 	 *
@@ -39,15 +46,33 @@ App.Medicine.Surgery.Procedure = class {
 
 	/**
 	 * The monetary cost of the surgery.
+	 * @returns {number}
+	 */
+	get cost() {
+		return Math.round(this._materialCost + this._workCost);
+	}
+
+	/**
+	 * Part of the surgery cost related to the required materials
+	 * @protected
+	 * @returns {number}
+	 */
+	get _materialCost() {
+		return 0;
+	}
+
+	/**
+	 * Part of the surgery cost related to the work efforts
 	 * This is the default cost. Subclasses should base their cost on this value if modifying it.
 	 * @example
-	 * get cost() {
+	 * get _workCost() {
 	 *     // Make the surgery 4 times more expensive
-	 *     return super.cost * 4;
+	 *     return super._workCost * 4;
 	 * }
+	 * @protected
 	 * @returns {number}
 	 */
-	get cost() {
+	get _workCost() {
 		// TODO phase out V.surgeryCost and replace with static calculation
 		return V.surgeryCost;
 	}
@@ -67,10 +92,22 @@ App.Medicine.Surgery.Procedure = class {
 
 	/**
 	 * If there are any entries, the procedure cannot be applied. The reasons are the array entries.
+	 * When overwriting always include disabled reasons of superclasses!
 	 *
 	 * @returns {Array<string>} May contain HTML
 	 */
-	get disabledReasons() { return []; }
+	get disabledReasons() {
+		const reasons = [];
+
+		/* disallow surgery for slaves on certain assignments */
+		if (this.originalSlave.assignment === "be your agent" ||
+			this.originalSlave.assignment === "live with your agent") {
+			const {his, him} = getPronouns(this.originalSlave);
+			reasons.push(`You must retrieve ${this.originalSlave.slaveName} from ${his} assignment before performing surgery on ${him}.`);
+		}
+
+		return reasons;
+	}
 
 	// eslint-disable-next-line jsdoc/require-returns-check
 	/**
diff --git a/js/dynamicJSLoading.js b/js/dynamicJSLoading.js
new file mode 100644
index 0000000000000000000000000000000000000000..3eb225f9d8c362df620aed8a4b0fcb209e760fa5
--- /dev/null
+++ b/js/dynamicJSLoading.js
@@ -0,0 +1,341 @@
+App.Loader = (function() {
+	/**
+	 * Remember the last loaded script.
+	 * @type {string}
+	 */
+	let lastScript = "";
+
+	/**
+	 * @param {string} name
+	 * @param {string} path Relative to the HTML file
+	 * @returns {HTMLScriptElement}
+	 */
+	function loadScript(name, path) {
+		lastScript = name;
+
+		const script = document.createElement("script");
+		script.setAttribute("src", `${path}`);
+		document.head.append(script);
+		return script;
+	}
+
+	/**
+	 * To make sure the scripts are loaded series, keep a queue of scripts to be loaded and only load the next once the
+	 * previous one is finished.
+	 *
+	 * @see nextScript
+	 *
+	 * @type {Array<()=>void>}
+	 */
+	const scriptQueue = [];
+
+	class Group {
+		/**
+		 * @param {string} path
+		 */
+		constructor(path) {
+			this._path = path;
+			this._scripts = [];
+
+			group.set(path, this);
+			scriptQueue.push(() => {
+				this._scripts.push(loadScript(path, path + "/index.js"));
+			});
+		}
+
+		/**
+		 * Loads a script as part of this group
+		 * @param {string} subPath relative to group path
+		 */
+		queueSubscript(subPath) {
+			scriptQueue.push(() => {
+				this._scripts.push(loadScript(subPath, this._path + "/" + subPath + ".js"));
+			});
+		}
+
+		/**
+		 * Removes all script elements belonging to this Group. Does not undo any changes these scripts did.
+		 */
+		unload() {
+			for (const script of this._scripts) {
+				document.head.removeChild(script);
+			}
+		}
+	}
+
+	/**
+	 * @type {Map<string, Group>}
+	 */
+	const group = new Map();
+
+	/**
+	 * Loads the group located at path
+	 *
+	 * @param {string} path
+	 */
+	function loadGroup(path) {
+		if (group.has(path)) {
+			group.get(path).unload();
+		}
+		new Group(path);
+	}
+
+	/**
+	 * Gives the group located at path
+	 *
+	 * @param {string} path
+	 * @returns {Group}
+	 */
+	function getGroup(path) {
+		return group.get(path);
+	}
+
+	function nextScript() {
+		if (scriptQueue.length > 0) {
+			scriptQueue.shift()();
+		}
+	}
+
+	return {
+		loadGroup: loadGroup,
+		getGroup: getGroup,
+		nextScript: nextScript,
+		executeTests: () => {
+			loadGroup("../tests");
+			nextScript();
+		},
+		get lastScript() {
+			return lastScript;
+		},
+		get hasNextScript() {
+			return scriptQueue.length > 0;
+		}
+	};
+})();
+
+
+/**
+ * Dedicated Modding API to abstract the loading mechanisms
+ */
+App.Modding = (function() {
+	let loadingDone = false;
+	/**
+	 * @type {Mod}
+	 */
+	let currentMod = null;
+
+	/**
+	 * @type {string[]}
+	 */
+	let modsToLoad = [];
+
+	/**
+	 * @type {Mod[]}
+	 */
+	const loadedMods = [];
+
+	class Mod {
+		/**
+		 * @param {string} directory where this mod is located relative to 'mods/'
+		 */
+		constructor(directory) {
+			this._path = "./mods/" + directory;
+			this.name = directory;
+			this.version = "0";
+			this.description = "";
+
+			currentMod = this;
+			loadedMods.push(this);
+
+			App.Loader.loadGroup(this._path);
+			App.Loader.nextScript();
+		}
+
+		/**
+		 * @returns {string}
+		 */
+		get path() {
+			return this._path;
+		}
+
+		/**
+		 * @param {string} path
+		 */
+		addSubscript(path) {
+			App.Loader.getGroup(this._path).queueSubscript(path);
+		}
+	}
+
+	/**
+	 * Loads the next subscript or mod
+	 */
+	function nextScript() {
+		if (App.Loader.hasNextScript) {
+			App.Loader.nextScript();
+		} else if (modsToLoad.length > 0) {
+			new Mod(modsToLoad.shift());
+		} else {
+			loadingDone = true;
+		}
+	}
+
+	/**
+	 * Load all mods
+	 */
+	function loadMods() {
+		modsToLoad = loadModList();
+		nextScript();
+	}
+
+	/**
+	 * @returns {string[]} modList
+	 */
+	function loadModList() {
+		return SugarCube.storage.get("modList") || [];
+	}
+
+	return {
+		internal: {
+			load: loadMods,
+			/** @returns {string[]} modList */
+			get modList() {
+				return loadModList();
+			},
+			/** @param {string[]} modList */
+			set modList(modList) {
+				SugarCube.storage.set("modList", modList);
+			},
+			get loadedMods() {
+				return loadedMods;
+			},
+			get done() {
+				return loadingDone;
+			}
+		},
+		scriptDone: nextScript,
+		get currentMod() {
+			return currentMod;
+		},
+	};
+})();
+
+App.UI.playerMods = function() {
+	let modList = loadModList();
+	const container = document.createElement("div");
+	container.append(makeModSettings());
+	return container;
+
+	function makeModSettings() {
+		const f = new DocumentFragment();
+		App.UI.DOM.appendNewElement("h2", f, "Player mods");
+		App.UI.DOM.appendNewElement("div", f, "Player mods are mods loaded from external files located at 'mods/'. If a mod does not exist loading will fail and never finish. Mods are save independent.");
+		if (!App.Modding.internal.done) {
+			f.append("Mods have not finished loading. ", App.UI.DOM.link("Refresh", () => {
+				modList = loadModList();
+				refresh();
+			}));
+		}
+		App.UI.DOM.appendNewElement("h3", f, "Currently loaded mods");
+		f.append(loadedList());
+		App.UI.DOM.appendNewElement("h3", f, "Edit mod list");
+		f.append(makeEditor());
+		return f;
+	}
+
+	/**
+	 * @returns {string[]}
+	 */
+	function loadModList() {
+		if (App.Status.storyReady) {
+			return App.Modding.internal.modList;
+		} else {
+			return [];
+		}
+	}
+
+	function loadedList() {
+		const loadedMods = App.Modding.internal.loadedMods;
+		const div = document.createElement("div");
+		div.classList.add("grid-3columns-auto");
+		for (const mod of loadedMods) {
+			App.UI.DOM.appendNewElement("div", div, mod.name);
+			App.UI.DOM.appendNewElement("div", div, mod.version);
+			App.UI.DOM.appendNewElement("div", div, mod.description);
+		}
+		return div;
+	}
+
+	function refresh() {
+		$(container).empty().append(makeModSettings());
+	}
+
+	function makeEditor() {
+		const div = document.createElement("div");
+		div.append("Add new mod. Input the exact name of the directory for the mod at 'mods/': ",
+			App.UI.DOM.makeTextBox("", name => {
+				modList.push(name);
+				refresh();
+			}));
+
+		App.UI.DOM.appendNewElement("div", div, "Mods are loaded from top to bottom.");
+
+		const listDiv = document.createElement("div");
+		for (let i = 0; i < modList.length; i++) {
+			const row = document.createElement("div");
+			row.append(up(i), " ", down(i), " ", remove(i), " ", modList[i]);
+			listDiv.append(row);
+		}
+		div.append(listDiv);
+
+		div.append(App.UI.DOM.link("Finalize (Will reload the game!)", () => {
+			App.Modding.internal.modList = modList;
+			window.location.reload();
+		}));
+		return div;
+	}
+
+	/**
+	 * @param {number} index
+	 * @returns {HTMLElement}
+	 */
+	function up(index) {
+		if (index === 0) {
+			return App.UI.DOM.makeElement("span", "Up", ["gray"]);
+		}
+		const button = App.UI.DOM.makeElement("a", "Up");
+		button.onclick = () => {
+			arraySwap(modList, index, index - 1);
+			refresh();
+		};
+		return button;
+	}
+
+	/**
+	 * @param {number} index
+	 * @returns {HTMLElement}
+	 */
+	function down(index) {
+		if (index === modList.length - 1) {
+			return App.UI.DOM.makeElement("span", "Down", ["gray"]);
+		}
+		const button = App.UI.DOM.makeElement("a", "Down");
+		button.onclick = () => {
+			arraySwap(modList, index, index + 1);
+			refresh();
+		};
+		return button;
+	}
+
+	/**
+	 * @param {number} index
+	 * @returns {HTMLElement}
+	 */
+	function remove(index) {
+		const button = App.UI.DOM.makeElement("a", "Remove");
+		button.onclick = () => {
+			modList.splice(index, 1);
+			refresh();
+		};
+		return button;
+	}
+};
diff --git a/js/medicine/surgery/assets/01-sizingImplants.js b/js/medicine/surgery/assets/01-sizingImplants.js
new file mode 100644
index 0000000000000000000000000000000000000000..ef25e28d60737b10124f7daa5f22fccfe2ba43ad
--- /dev/null
+++ b/js/medicine/surgery/assets/01-sizingImplants.js
@@ -0,0 +1,381 @@
+App.Medicine.Surgery.Procedures.SizingImplantProcedure = class extends App.Medicine.Surgery.Procedure {
+	/**
+	 * @param {FC.SlaveState} slave
+	 * @param {FC.SizingImplantTarget} target
+	 * @param {FC.SizingImplantType} implantType
+	 * @param {number} size
+	 */
+	constructor(slave, target, implantType, size) {
+		super(slave);
+		this._target = target;
+		this._implantType = implantType;
+		this._size = size;
+	}
+
+	get name() {
+		return `${capFirstChar(this._resolveDynamic(this._implantData.name, this._size))} implants`;
+	}
+
+	get changeValue() {
+		return this._size;
+	}
+
+	apply(cheat) {
+		this._slave[this._target] += this._size;
+		this._slave[`${this._target}Implant`] += this._size;
+		this._setSlaveImplantType(this._implantType);
+
+		if (this.changeValue >= 0) {
+			return this._assemble(this._doTargetGain());
+		} else {
+			if (this._slave[`${this._target}Implant`] < 1) {
+				this._slave[`${this._target}Implant`] = 0;
+				this._setSlaveImplantType("none");
+			}
+			return this._assemble(this._doTargetLoss());
+		}
+	}
+
+	_surgeryWorkPriceFactor() {
+		return V.surgeryCost * V.localEcon / 3e4;
+	}
+
+	/**
+	 * @param {FC.SizingImplantType} type
+	 */
+	_implantDataForType(type) {
+		return App.Data.Medicine.sizingImplants[this._target][type];
+	}
+
+	/**
+	 * @param {FC.SizingImplantType} type
+	 * @param {number} size
+	 */
+	_installationHealthCost(type, size) {
+		return this._implantDataForType(type).healthCostFactor.installation * size;
+	}
+
+	/**
+	 * @param {FC.InstalledSizingImplantType} type
+	 * @param {number} size
+	 */
+	_removalHealthCost(type, size) {
+		return type === "none" ? 0
+			: this._implantDataForType(type).healthCostFactor.removal * size;
+	}
+
+	/**
+	 * @param {FC.InstalledSizingImplantType} type
+	 * @param {number} size
+	 */
+	_installationWorkCost(type, size) {
+		return type === "none" ? 0
+			: this._implantDataForType(type).workCostFactor.installation * size * this._surgeryWorkPriceFactor();
+	}
+
+	/**
+	 * @param {FC.InstalledSizingImplantType} type
+	 * @param {number} size
+	 */
+	_removalWorkCost(type, size) {
+		return type === "none" ? 0
+			: this._implantDataForType(type).workCostFactor.removal * size * this._surgeryWorkPriceFactor();
+	}
+
+	get _implantData() {
+		return this._implantDataForType(this._implantType);
+	}
+
+	get _implantName() {
+		return this._resolveDynamic(this._implantData.name, this._size);
+	}
+
+	get _materialCost() {
+		return this._resolveDynamic(this._implantData.specificMaterialCost, this._size) * this._size;
+	}
+
+	/**
+	 * @param {*} amount Positive for fill, negative for drain
+	 */
+	_fillDrainMaterialCost(amount) {
+		const id = this._implantData;
+		return amount >= 0
+			? (id.fill ? this._implantData.fill.materialCostFactor * amount : 0)
+			: 0; // draining does not impose material cost as of now
+	}
+
+	/**
+	 * @template {string | number} T
+	 * @param {T | ((size: number) => T)} value
+	 * @param {number} size
+	 * @returns {T}
+	 */
+	_resolveDynamic(value, size) {
+		return typeof value !== "function" ? value : value(size);
+	}
+
+	get _targetName() {
+		switch (this._target) {
+			case "boobs":
+				return ["mammaries", "chest", "breasts"].random();
+			case "butt":
+				return ["buttocks", "posterior"].random();
+			case "lips":
+				return "lip";
+			default:
+				return this._target;
+		}
+	}
+
+	/**
+	 * Returns a string containign the name (depends on size) and possible volume of the implant
+	 * @param {FC.SizingImplantType} type
+	 * @param {number} volume
+	 */
+	_describeImplant(type, volume) {
+		let r = this._resolveDynamic(this._implantDataForType(type).name, volume);
+		const volumeDesc = this._volumeStr(volume);
+		if (volumeDesc) {
+			r += ` (${volumeDesc})`;
+		}
+		return r;
+	}
+
+	_setSlaveImplantType(implantType) {
+		if (this.originalSlave[`${this._target}ImplantType`] !== implantType) {
+			this._slave[`${this._target}ImplantType`] = implantType;
+		}
+	}
+
+	/**
+	 * @abstract
+	 * @returns {App.Medicine.Surgery.SimpleReaction}
+	 */
+	_doTargetGain() {
+		throw Error("Abstract method called");
+	}
+	/**
+	 * @abstract
+	 * @returns {App.Medicine.Surgery.SimpleReaction}
+	 */
+	_doTargetLoss() {
+		throw Error("Abstract method called");
+	}
+
+	/**
+	 * @abstract
+	 * @param {number} volume
+	 * @returns {string}
+	 */
+	_volumeStr(volume) {
+		throw Error("Abstract method called");
+	}
+
+	/**
+	 * @abstract
+	 * @param {number} volume
+	 * @returns {string}
+	 */
+	 _fleshExcessStr(volume) {
+		throw Error("Abstract method called");
+	}
+};
+
+App.Medicine.Surgery.Procedures.InstallSizingImplantProcedure = class extends App.Medicine.Surgery.Procedures.SizingImplantProcedure {
+	/**
+	 * @param {FC.SlaveState} slave
+	 * @param {FC.SizingImplantTarget} target
+	 * @param {FC.SizingImplantType} implantType
+	 * @param {number} size how big is the implant
+	 * @param {number} fleshExcess Excess flesh volume to remove for installing this implant
+	 */
+	constructor(slave, target, implantType, size, fleshExcess) {
+		super(slave, target, implantType, size);
+		this._fleshExcess = fleshExcess;
+	}
+
+	get description() {
+		const {his} = getPronouns(this._slave);
+		return `place ${this._describeImplant(this._implantType, this._size)} implants into ${his} ${this._targetName}`;
+	}
+
+	get note() {
+		if (this._fleshExcess > 0) {
+			const {his} = getPronouns(this._slave);
+			return App.UI.DOM.makeElement('span',
+				`Installation requires removing ${this._fleshExcessStr(this._fleshExcess)} of ${his} ${this._targetName} flesh.`, ["warning"]);
+		}
+		return null;
+	}
+
+	get healthCost() {
+		return this._installationHealthCost(this._implantType, this._size);
+	}
+
+	get _workCost() {
+		return super._workCost + super._installationWorkCost(this._implantType, this._size);
+	}
+};
+
+App.Medicine.Surgery.Procedures.ExistingImplantsProcedureBase = class extends App.Medicine.Surgery.Procedures.SizingImplantProcedure {
+	/**
+	 * @param {FC.SlaveState} slave
+	 * @param {FC.SizingImplantTarget} target
+	 * @param {number} size
+	 * @param {FC.SizingImplantType} [implantType]
+	 */
+	constructor(slave, target, size, implantType = null) {
+		const oldImplantInfo = App.Medicine.implantInfo(slave, target);
+		if (oldImplantInfo.type === "none") {
+			throw Error(`Slave has no ${target} implant to work on`);
+		}
+		super(slave, target, implantType || oldImplantInfo.type, size);
+		this._oldImplantInfo = oldImplantInfo;
+	}
+
+	/**
+	 * @protected
+	 */
+	get _oldImplantsDescription() {
+		return this._describeImplant(/** @type {FC.SizingImplantType}*/(this._oldImplantInfo.type), this._oldImplantInfo.volume);
+	}
+};
+
+App.Medicine.Surgery.Procedures.RemoveSizingImplantProcedure = class extends App.Medicine.Surgery.Procedures.ExistingImplantsProcedureBase {
+	/**
+	 * @param {FC.SlaveState} slave
+	 * @param {FC.SizingImplantTarget} target
+	 */
+	constructor(slave, target) {
+		super(slave, target, -slave[`${target}Implant`]);
+	}
+
+	get name() {
+		return `Remove ${this._targetName} implants`;
+	}
+
+	get description() {
+		const {his} = getPronouns(this._slave);
+		return `remove ${his} ${this._oldImplantsDescription} ${this._targetName} implants`;
+	}
+
+	get _materialCost() {
+		return 0;
+	}
+
+	get _workCost() {
+		return super._workCost + super._removalWorkCost(this._implantType, -this._size);
+	}
+
+	get healthCost() {
+		return this._removalHealthCost(this._implantType, -this._size);
+	}
+};
+
+App.Medicine.Surgery.Procedures.ReplaceSizingImplantProcedure = class extends App.Medicine.Surgery.Procedures.ExistingImplantsProcedureBase {
+	/**
+	 * @param {FC.SlaveState} slave
+	 * @param {FC.SizingImplantTarget} target
+	 * @param {FC.SizingImplantType} implantType
+	 * @param {number} size how big is the implant
+	 * @param {number} fleshExcess Excess flesh volume to remove for installing this implant
+	 */
+	constructor(slave, target, implantType, size, fleshExcess) {
+		super(slave, target, size, implantType);
+		this._fleshExcess = fleshExcess;
+	}
+
+	get description() {
+		const {his} = getPronouns(this._slave);
+		return `replace ${his} ${this._oldImplantsDescription} ${this._targetName} implants with ${this._describeImplant(this._implantType, this._size)} ones`;
+	}
+
+	get note() {
+		if (this._fleshExcess > 0) {
+			const {his} = getPronouns(this._slave);
+			return App.UI.DOM.makeElement('span',
+				`Installation of the new implant requires removing ${this._fleshExcessStr(this._fleshExcess)} of ${his} ${this._targetName} flesh.`, ["warning"]);
+		}
+		return null;
+	}
+
+	get healthCost() {
+		return this._removalHealthCost(this._oldImplantInfo.type, this._oldImplantInfo.volume) +
+			this._installationHealthCost(this._implantType, this._size);
+	}
+
+	get _workCost() {
+		const previousImplant = App.Medicine.implantInfo(this.originalSlave, this._target);
+		return super._workCost + super._removalWorkCost(previousImplant.type, previousImplant.volume) +
+			this._installationWorkCost(this._implantType, this._size);
+	}
+
+	get changeValue() {
+		return this._size - this._oldImplantInfo.volume;
+	}
+
+	apply(cheat) {
+		this._slave[this._target] -= this._oldImplantInfo.volume;
+		this._slave[`${this._target}Implant`] = 0;
+
+		return super.apply(cheat);
+	}
+};
+
+App.Medicine.Surgery.Procedures.FillSizingImplantProcedure = class extends  App.Medicine.Surgery.Procedures.ExistingImplantsProcedureBase {
+	/**
+	 * @param {FC.SlaveState} slave
+	 * @param {FC.SizingImplantTarget} target
+	 * @param {number} amount
+	 */
+	constructor(slave, target, amount) {
+		super(slave, target, amount);
+	}
+
+	get name() {
+		return `Add inert filler`;
+	}
+
+	get description() {
+		const {his} = getPronouns(this._slave);
+		const volumeStr = this._volumeStr(this._size);
+		return `add ${volumeStr ? `${volumeStr} of` : 'some'} inert filler to each of ${his} ${this._oldImplantsDescription} ${this._targetName} implants`;
+	}
+
+	get _materialCost() {
+		return this._fillDrainMaterialCost(this._size);
+	}
+
+	get healthCost() {
+		return this._implantData.fill.healthCost;
+	}
+};
+
+App.Medicine.Surgery.Procedures.DrainSizingImplantProcedure = class extends  App.Medicine.Surgery.Procedures.ExistingImplantsProcedureBase {
+	/**
+	 * @param {FC.SlaveState} slave
+	 * @param {FC.SizingImplantTarget} target
+	 * @param {number} amount
+	 */
+	constructor(slave, target, amount) {
+		super(slave, target, -amount);
+	}
+
+	get name() {
+		return `Drain inert filler`;
+	}
+
+	get description() {
+		const {his} = getPronouns(this._slave);
+		const volumeStr = this._volumeStr(this._size);
+		return `drain ${volumeStr ? `${volumeStr} of` : 'some'} inert filler from ${his} ${this._oldImplantsDescription} ${this._targetName} implants`;
+	}
+
+	get _materialCost() {
+		return 0;
+	}
+
+	get healthCost() {
+		return this._implantData.drain.healthCost;
+	}
+};
diff --git a/js/medicine/surgery/assets/boobs.js b/js/medicine/surgery/assets/boobs.js
index f873c09c957e949fe52de1ce365afc99fb09a9a0..99334fa8546ad43459c71beb6c5d40bfd2d12cca 100644
--- a/js/medicine/surgery/assets/boobs.js
+++ b/js/medicine/surgery/assets/boobs.js
@@ -143,11 +143,14 @@ App.Medicine.Surgery.Reactions.BoobsLoss = class extends App.Medicine.Surgery.Si
 	}
 };
 
-{
+/**
+ * @type {FC.Medicine.AssetSizingProcedureSet}
+ */
+App.Medicine.Surgery.Procedures.boobImplantsProcedure = function() {
 	/**
-	 * @param {App.Entity.SlaveState} slave
+	 * @param {FC.SlaveState} slave
 	 */
-	const applyBoobsGain = function(slave) {
+	const applyBoobsGain = (slave) => {
 		if (slave.areolae < 2 && Math.random() > 0.7) {
 			slave.areolae += 1;
 		}
@@ -172,9 +175,9 @@ App.Medicine.Surgery.Reactions.BoobsLoss = class extends App.Medicine.Surgery.Si
 	};
 
 	/**
-	 * @param {App.Entity.SlaveState} slave
+	 * @param {FC.SlaveState} slave
 	 */
-	const applyBoobsLoss = function(slave) {
+	const applyBoobsLoss = (slave) => {
 		if (slave.areolae > 2) {
 			slave.areolae -= 1;
 		}
@@ -190,196 +193,48 @@ App.Medicine.Surgery.Reactions.BoobsLoss = class extends App.Medicine.Surgery.Si
 		}
 	};
 
-	App.Medicine.Surgery.Procedures.InstallBoobImplants = class extends App.Medicine.Surgery.Procedure {
-		/**
-		 * @param {App.Entity.SlaveState} slave
-		 * @param {string} name
-		 * @param {FC.SizingImplantType} implantType
-		 * @param {number} size how big is the implant
-		 */
-		constructor(slave, name, implantType, size) {
-			super(slave);
-			this._size = size;
-			this._implantType = implantType;
-			this._name = name;
-		}
-
-		get name() {
-			return `${capFirstChar(this._name)} implants`;
-		}
-
-		get description() {
-			const {his} = getPronouns(this._slave);
-			return `place ${this._name}${V.showBoobCCs ? ` ${this._size}cc` : ''} implants into ${his} boobs`;
-		}
-
-		get healthCost() { return 10; }
-
-		get changeValue() { return this._size; }
-
-		apply(cheat) {
-			this._slave.boobs += this._size;
-			this._slave.boobsImplant = this._size;
-			this._slave.boobsImplantType = this._implantType;
-
-			applyBoobsGain(this._slave);
-
-			return this._assemble(new App.Medicine.Surgery.Reactions.BoobsGain());
-		}
-	};
-
-	App.Medicine.Surgery.Procedures.RemoveBoobImplants = class extends App.Medicine.Surgery.Procedure {
-		get name() {
-			return "Remove implants";
-		}
-
-		get description() {
-			const {his} = getPronouns(this._slave);
-			return `remove ${his} boob implants`;
-		}
-
-		get healthCost() { return 5; }
-
-		get changeValue() { return -this._slave.boobsImplant; }
-
-		apply(cheat) {
-			this._slave.boobs -= this._slave.boobsImplant;
-			this._slave.boobsImplant = 0;
-			this._slave.boobsImplantType = "none";
-
-			applyBoobsLoss(this._slave);
-
-			return this._assemble(new App.Medicine.Surgery.Reactions.BoobsLoss());
-		}
-	};
-
-
-	App.Medicine.Surgery.Procedures.ReplaceBoobImplants = class extends App.Medicine.Surgery.Procedure {
-		/**
-		 * @param {App.Entity.SlaveState} slave
-		 * @param {string} name
-		 * @param {FC.SizingImplantType} implantType
-		 * @param {number} size how big is the implant
-		 * @param {boolean} [advanced=false] advanced implants may be more expensive
-		 */
-		constructor(slave, name, implantType, size, advanced = false) {
-			super(slave);
-			this._size = size;
-			this._implantType = implantType;
-			this._name = name;
-			this._advanced = advanced;
-		}
-
-		get name() {
-			return `${capFirstChar(this._name)} implants${this._advanced && V.ImplantProductionUpgrade < 1 ? " (special order)" : ""}`;
-		}
-
-		get description() {
-			const {his} = getPronouns(this._slave);
-			const r = [];
-			r.push(`replace ${his} boob implants with ${this._name}`);
-			if (V.showBoobCCs) {
-				r.push(`(${this._size}cc)`);
-			}
-			r.push("ones");
-			if (this._advanced && V.ImplantProductionUpgrade < 1) {
-				r.push("(special order)");
+	/**
+	 * @template {FC.Medicine.SizingImplantProcedureConstructor} T
+	 * @param {T} Procedure
+	 * @param {ConstructorParameters<T>} args
+	 */
+	function makeBoobProcedure(Procedure, args) {
+		return new (class extends Procedure {
+			_doTargetGain() {
+				applyBoobsGain(this._slave);
+				return new App.Medicine.Surgery.Reactions.BoobsGain();
 			}
-			return r.join(" ");
-		}
-
-		get cost() { return super.cost + (this._advanced && V.ImplantProductionUpgrade < 1 ? 10000 : 0); }
-
-		get healthCost() { return 10; }
-
-		get changeValue() { return this._size - this.originalSlave.boobsImplant; }
-
-		apply(cheat) {
-			this._slave.boobs += this._size - this._slave.boobsImplant;
-			this._slave.boobsImplant = this._size;
-			this._slave.boobsImplantType = this._implantType;
 
-			if (this.changeValue >= 0) {
-				applyBoobsGain(this._slave);
-				return this._assemble(new App.Medicine.Surgery.Reactions.BoobsGain());
-			} else {
+			_doTargetLoss() {
 				applyBoobsLoss(this._slave);
-				return this._assemble(new App.Medicine.Surgery.Reactions.BoobsLoss());
+				return new App.Medicine.Surgery.Reactions.BoobsLoss();
 			}
-		}
-	};
-
-
-	App.Medicine.Surgery.Procedures.FillBoobImplants = class extends App.Medicine.Surgery.Procedure {
-		/**
-		 * @param {App.Entity.SlaveState} slave
-		 * @param {number} amount
-		 */
-		constructor(slave, amount) {
-			super(slave);
-			this._amount = amount;
-		}
-
-		get name() {
-			return `Add inert filler`;
-		}
 
-		get description() {
-			const {his} = getPronouns(this._slave);
-			return `add ${V.showBoobCCs ? `${this._amount}cc of` : 'some'} inert filler to each of ${his} boob implants`;
-		}
-
-		get healthCost() { return 10; }
-
-		get changeValue() { return this._amount; }
-
-		apply(cheat) {
-			this._slave.boobs += this._amount;
-			this._slave.boobsImplant += this._amount;
-
-			applyBoobsGain(this._slave);
-
-			return this._assemble(new App.Medicine.Surgery.Reactions.BoobsGain());
-		}
-	};
-
-	App.Medicine.Surgery.Procedures.DrainBoobImplants = class extends App.Medicine.Surgery.Procedure {
-		/**
-		 * @param {App.Entity.SlaveState} slave
-		 * @param {number} amount
-		 */
-		constructor(slave, amount) {
-			super(slave);
-			this._amount = amount;
-		}
-
-		get name() {
-			return `Drain inert filler`;
-		}
-
-		get description() {
-			const {his} = getPronouns(this._slave);
-			return `drain ${V.showBoobCCs ? `${this._amount}cc of` : 'some'} inert filler from ${his} boob implants`;
-		}
-
-		get healthCost() { return 5; }
-
-		get changeValue() { return -this._amount; }
-
-		apply(cheat) {
-			this._slave.boobs -= this._amount;
-			this._slave.boobsImplant -= this._amount;
-
-			applyBoobsLoss(this._slave);
+			/**
+			 * @param {number} volume
+			 * @returns {string}
+			 */
+			_volumeStr(volume) {
+				return V.showBoobCCs ? App.Utils.expandHTML(`${volume}&thinsp;cm³`) : '';
+			}
 
-			return this._assemble(new App.Medicine.Surgery.Reactions.BoobsLoss());
-		}
-	};
+			/**
+			 * @param {number} volume
+			 * @returns {string}
+			 */
+			_fleshExcessStr(volume) {
+				const percentsStr = `${Math.round(100. * volume / App.Medicine.fleshSize(this.originalSlave, "boobs"))}&thinsp;%`;
 
+				return V.showBoobCCs
+					? App.Utils.expandHTML(`${volume}&thinsp;cm³ (${percentsStr})`)
+					: App.Utils.expandHTML(percentsStr);
+			}
+		})(...args);
+	}
 
-	App.Medicine.Surgery.Procedures.ReduceBoobs = class extends App.Medicine.Surgery.Procedure {
+	class Reduce extends App.Medicine.Surgery.Procedure {
 		/**
-		 * @param {App.Entity.SlaveState} slave
+		 * @param {FC.SlaveState} slave
 		 * @param {string} procedureName
 		 * @param {number} amount
 		 */
@@ -409,5 +264,21 @@ App.Medicine.Surgery.Reactions.BoobsLoss = class extends App.Medicine.Surgery.Si
 
 			return this._assemble(new App.Medicine.Surgery.Reactions.BoobsLoss());
 		}
+	}
+
+	return {
+		install: (slave, type, size, fleshExcess) =>
+			makeBoobProcedure(App.Medicine.Surgery.Procedures.InstallSizingImplantProcedure, [slave, "boobs", type, size, fleshExcess]),
+		replace: (slave, type, size, fleshExcess) =>
+			makeBoobProcedure(App.Medicine.Surgery.Procedures.ReplaceSizingImplantProcedure, [slave, "boobs", type, size, fleshExcess]),
+		remove: (slave) =>
+			makeBoobProcedure(App.Medicine.Surgery.Procedures.RemoveSizingImplantProcedure, [slave, "boobs"]),
+
+		fill: (slave, amount) =>
+			makeBoobProcedure(App.Medicine.Surgery.Procedures.FillSizingImplantProcedure, [slave, "boobs", amount]),
+		drain: (slave, amount) =>
+			makeBoobProcedure(App.Medicine.Surgery.Procedures.DrainSizingImplantProcedure, [slave, "boobs", amount]),
+
+		reduce: (slave, name, amount) => new Reduce(slave, name, amount)
 	};
-}
+}();
diff --git a/js/medicine/surgery/assets/breastShapePreservation.js b/js/medicine/surgery/assets/breastShapePreservation.js
index 04beba000f2ff431434c0ec30a7ec926c89016ef..88a08430c494dfce7f4885733553a1e8dff8ed59 100644
--- a/js/medicine/surgery/assets/breastShapePreservation.js
+++ b/js/medicine/surgery/assets/breastShapePreservation.js
@@ -204,7 +204,7 @@ App.Medicine.Surgery.Procedures.BreastShapePreservation = class extends App.Medi
 		return "Implant a supportive mesh to preserve their shape";
 	}
 
-	get cost() {
+	get _workCost() {
 		return this.originalSlave.boobs / 100;
 	}
 
diff --git a/js/medicine/surgery/assets/butt.js b/js/medicine/surgery/assets/butt.js
index ce2673fd4190e1d9495b4aa3c408f50c621b201f..bb850556814b2b9c3d10430975c7dc734582f6b4 100644
--- a/js/medicine/surgery/assets/butt.js
+++ b/js/medicine/surgery/assets/butt.js
@@ -86,194 +86,87 @@ App.Medicine.Surgery.Reactions.ButtLoss = class extends App.Medicine.Surgery.Sim
 	}
 };
 
-App.Medicine.Surgery.Procedures.InstallButtImplants = class extends App.Medicine.Surgery.Procedure {
+/**
+ * @type {FC.Medicine.AssetSizingProcedureSet}
+ */
+App.Medicine.Surgery.Procedures.buttImplantsProcedure = function() {
 	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {string} name
-	 * @param {FC.SizingImplantType} implantType
-	 * @param {number} size how big is the implant
+	 * @template {FC.Medicine.SizingImplantProcedureConstructor} T
+	 * @param {T} Procedure
+	 * @param {ConstructorParameters<T>} args
 	 */
-	constructor(slave, name, implantType, size) {
-		super(slave);
-		this._size = size;
-		this._implantType = implantType;
-		this._name = name;
-	}
-
-	get name() {
-		return `${capFirstChar(this._name)} implants`;
-	}
-
-	get description() {
-		const {his} = getPronouns(this._slave);
-		return `place ${this._name} implants into ${his} butt`;
-	}
-
-	get healthCost() { return 10; }
-
-	get changeValue() { return this._size; }
-
-	apply(cheat) {
-		this._slave.butt += this._size;
-		this._slave.buttImplant = this._size;
-		this._slave.buttImplantType = this._implantType;
-		return this._assemble(new App.Medicine.Surgery.Reactions.ButtGain());
-	}
-};
-
-App.Medicine.Surgery.Procedures.RemoveButtImplants = class extends App.Medicine.Surgery.Procedure {
-	get name() {
-		return "Remove implants";
-	}
-
-	get description() {
-		const {his} = getPronouns(this._slave);
-		return `remove ${his} butt implants`;
-	}
-
-	get healthCost() { return 5; }
-
-	get changeValue() { return -this._slave.buttImplant; }
+	 function makeButtProcedure(Procedure, args) {
+		return new (class extends Procedure {
+			_doTargetGain() {
+				return new App.Medicine.Surgery.Reactions.ButtGain();
+			}
 
-	apply(cheat) {
-		this._slave.butt -= this._slave.buttImplant;
-		this._slave.buttImplant = 0;
-		this._slave.buttImplantType = "none";
-		return this._assemble(new App.Medicine.Surgery.Reactions.ButtLoss());
-	}
-};
+			_doTargetLoss() {
+				return new App.Medicine.Surgery.Reactions.ButtLoss();
+			}
 
-App.Medicine.Surgery.Procedures.ReplaceButtImplants = class extends App.Medicine.Surgery.Procedure {
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {string} name
-	 * @param {FC.SizingImplantType} implantType
-	 * @param {number} size how big is the implant
-	 * @param {boolean} [advanced=false] advanced implants may be more expensive
-	 */
-	constructor(slave, name, implantType, size, advanced = false) {
-		super(slave);
-		this._size = size;
-		this._implantType = implantType;
-		this._name = name;
-		this._advanced = advanced;
-	}
+			/**
+			 * @param {number} volume
+			 * @returns {string}
+			 */
+			_volumeStr(volume) {
+				return '';
+			}
 
-	get name() {
-		return `${capFirstChar(this._name)} implants${this._advanced && V.ImplantProductionUpgrade < 1 ? " (special order)" : ""}`;
-	}
+			/**
+			 * @param {number} volume
+			 * @returns {string}
+			 */
+			_fleshExcessStr(volume) {
+				return App.Utils.expandHTML(`${Math.round(100. * volume / App.Medicine.fleshSize(this.originalSlave, "butt"))}&thinsp;%`);
+			}
+		})(...args);
+	}
+
+	class Reduce extends App.Medicine.Surgery.Procedure {
+		/**
+		 * @param {App.Entity.SlaveState} slave
+		 * @param {string} procedureName
+		 * @param {number} amount
+		 */
+		constructor(slave, procedureName, amount) {
+			super(slave);
+			this._procedureName = capFirstChar(procedureName);
+			this._amount = amount;
+		}
 
-	get description() {
-		const {his} = getPronouns(this._slave);
-		return `replace ${his} butt implants with ${this._name} ones${this._advanced && V.ImplantProductionUpgrade < 1 ? " (special order)" : ""}`;
-	}
+		get name() {
+			return `${this._procedureName} butt`;
+		}
 
-	get cost() { return super.cost + (this._advanced && V.ImplantProductionUpgrade < 1 ? 10000 : 0); }
+		get description() {
+			const {his} = getPronouns(this._slave);
+			return `${this._procedureName} ${his} butt`;
+		}
 
-	get healthCost() { return 10; }
+		get healthCost() { return 5; }
 
-	get changeValue() { return this._size - this._slave.buttImplant; }
+		get changeValue() { return -this._amount; }
 
-	apply(cheat) {
-		this._slave.butt += this._size - this._slave.buttImplant;
-		this._slave.buttImplant = this._size;
-		this._slave.buttImplantType = this._implantType;
-		if (this.changeValue >= 0) {
-			return this._assemble(new App.Medicine.Surgery.Reactions.ButtGain());
-		} else {
+		apply(cheat) {
+			this._slave.butt -= this._amount;
 			return this._assemble(new App.Medicine.Surgery.Reactions.ButtLoss());
 		}
 	}
-};
 
+	return {
+		install: (slave, type, size, fleshExcess) =>
+			makeButtProcedure(App.Medicine.Surgery.Procedures.InstallSizingImplantProcedure, [slave, "butt", type, size, fleshExcess]),
+		replace: (slave, type, size, fleshExcess) =>
+			makeButtProcedure(App.Medicine.Surgery.Procedures.ReplaceSizingImplantProcedure, [slave, "butt", type, size, fleshExcess]),
+		remove: (slave) =>
+			makeButtProcedure(App.Medicine.Surgery.Procedures.RemoveSizingImplantProcedure, [slave, "butt"]),
 
-App.Medicine.Surgery.Procedures.FillButtImplants = class extends App.Medicine.Surgery.Procedure {
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {number} amount
-	 */
-	constructor(slave, amount) {
-		super(slave);
-		this._amount = amount;
-	}
+		fill: (slave, amount) =>
+			makeButtProcedure(App.Medicine.Surgery.Procedures.FillSizingImplantProcedure, [slave, "butt", amount]),
+		drain: (slave, amount) =>
+			makeButtProcedure(App.Medicine.Surgery.Procedures.DrainSizingImplantProcedure, [slave, "butt", amount]),
 
-	get name() {
-		return `Add inert filler`;
-	}
-
-	get description() {
-		const {his} = getPronouns(this._slave);
-		return `add some inert filler to each of ${his} butt implants`;
-	}
-
-	get healthCost() { return 10; }
-
-	get changeValue() { return this._amount; }
-
-	apply(cheat) {
-		this._slave.butt += this._amount;
-		this._slave.buttImplant += this._amount;
-		return this._assemble(new App.Medicine.Surgery.Reactions.ButtGain());
-	}
-};
-
-App.Medicine.Surgery.Procedures.DrainButtImplants = class extends App.Medicine.Surgery.Procedure {
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {number} amount
-	 */
-	constructor(slave, amount) {
-		super(slave);
-		this._amount = amount;
-	}
-
-	get name() {
-		return `Drain inert filler`;
-	}
-
-	get description() {
-		const {his} = getPronouns(this._slave);
-		return `drain some inert filler from ${his} butt implants`;
-	}
-
-	get healthCost() { return 5; }
-
-	get changeValue() { return -this._amount; }
-
-	apply(cheat) {
-		this._slave.butt -= this._amount;
-		this._slave.buttImplant -= this._amount;
-		return this._assemble(new App.Medicine.Surgery.Reactions.ButtLoss());
-	}
-};
-
-App.Medicine.Surgery.Procedures.ReduceButt = class extends App.Medicine.Surgery.Procedure {
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {string} procedureName
-	 * @param {number} amount
-	 */
-	constructor(slave, procedureName, amount) {
-		super(slave);
-		this._procedureName = capFirstChar(procedureName);
-		this._amount = amount;
-	}
-
-	get name() {
-		return `${this._procedureName} butt`;
-	}
-
-	get description() {
-		const {his} = getPronouns(this._slave);
-		return `${this._procedureName} ${his} butt`;
-	}
-
-	get healthCost() { return 5; }
-
-	get changeValue() { return -this._amount; }
-
-	apply(cheat) {
-		this._slave.butt -= this._amount;
-		return this._assemble(new App.Medicine.Surgery.Reactions.ButtLoss());
-	}
-};
+		reduce: (slave, name, amount) => new Reduce(slave, name, amount)
+	};
+}();
diff --git a/js/medicine/surgery/assets/fatGraft.js b/js/medicine/surgery/assets/fatGraft.js
index f9a8bc45a38300d9b4547143fdaef06b7125664b..c43e27e5a2c199402954fe815c0bf070102a3e0b 100644
--- a/js/medicine/surgery/assets/fatGraft.js
+++ b/js/medicine/surgery/assets/fatGraft.js
@@ -199,8 +199,8 @@ App.Medicine.Surgery.Procedures.FatGraft = class extends App.Medicine.Surgery.Pr
 		return "Finalize fat transfer";
 	}
 
-	get cost() {
-		return super.cost * 2;
+	get _workCost() {
+		return super._workCost * 2;
 	}
 
 	get healthCost() {
diff --git a/js/medicine/surgery/exotic/retrogradeVirusInjectionNCS.js b/js/medicine/surgery/exotic/retrogradeVirusInjectionNCS.js
index 3eb4be7684844038a27e33fc953c8d19458747d3..97d35eca6ad4fa0f46ce4e0b6ee678396d966b9c 100644
--- a/js/medicine/surgery/exotic/retrogradeVirusInjectionNCS.js
+++ b/js/medicine/surgery/exotic/retrogradeVirusInjectionNCS.js
@@ -168,14 +168,7 @@ App.Medicine.Surgery.Reactions.RetrogradeVirusInjectionNCS = class extends App.M
 			if (genitalChanges.length > 0) {
 				r.push(`${He} can ${sense} that ${his} junk is different now, it seems ${his}`);
 				if (genitalChanges.length > 2) {
-					for (let i = 0; i < genitalChanges.length; i++) {
-						if (i < genitalChanges.length - 1) {
-							r.push(`${genitalChanges[i]},`);
-						} else {
-							r.push(`and ${genitalChanges[i]}.`);
-						}
-					}
-					r.push(`have all become <span class="change negative">smaller.</span>`);
+					r.push(`${toSentence(genitalChanges)} have all become <span class="change negative">smaller.</span>`);
 				} else if (genitalChanges.length > 1) {
 					r.push(`${genitalChanges[0]}, and ${genitalChanges[1]} have both become <span class="change negative">smaller.</span>`);
 				} else {
@@ -188,8 +181,8 @@ App.Medicine.Surgery.Reactions.RetrogradeVirusInjectionNCS = class extends App.M
 					r.push(`also`);
 				}
 				r.push(`${sense} that ${his} body has some physical changes, it seems to ${him} that ${toSentence(physicalChanges)}`);
-				const reaction = ['comes as a bit of a surprise', 'comes as quite a shock', `confirms ${his} suspicions`, `doesn't seem to phase ${him}`, `${he} finds interesting`, `${he} can't get over`].random() + '.';
-				r.push(`which ${reaction}`);
+				const reaction = ['comes as a bit of a surprise', 'comes as quite a shock', `confirms ${his} suspicions`, `doesn't seem to phase ${him}`, `${he} finds interesting`, `${he} can't get over`].random();
+				r.push(`which ${reaction}.`);
 			}
 			if (statusChanges.length > 0) {
 				r.push(`${He} can feel some`);
@@ -197,9 +190,7 @@ App.Medicine.Surgery.Reactions.RetrogradeVirusInjectionNCS = class extends App.M
 					r.push(`other`);
 				}
 				r.push(`changes that are a little harder to describe.`);
-				for (let i = 0; i < statusChanges.length; i++) {
-					r.push(statusChanges[i]);
-				}
+				r.push(...statusChanges);
 			}
 		}
 
@@ -248,8 +239,8 @@ App.Medicine.Surgery.Procedures.RetrogradeVirusInjectionNCS = class extends App.
 		return 80;
 	}
 
-	get cost() {
-		return super.cost * 4;
+	get _workCost() {
+		return super._workCost * 4;
 	}
 
 	apply(cheat) {
diff --git a/js/medicine/surgery/exotic/treatment.js b/js/medicine/surgery/exotic/treatment.js
index 8a7b35d7a13401de81bc08dcd9700052903e24b0..31fd7b00ce1fd831d1acbb3c15ea61fedcd6de18 100644
--- a/js/medicine/surgery/exotic/treatment.js
+++ b/js/medicine/surgery/exotic/treatment.js
@@ -33,8 +33,8 @@ App.Medicine.Surgery.Procedures.ElasticityTreatment = class extends App.Medicine
 		return `this will alter ${his} genetic code to encourage ${his} body to stretch`;
 	}
 
-	get cost() {
-		return super.cost * 4;
+	get _workCost() {
+		return super._workCost * 4;
 	}
 
 	get healthCost() {
@@ -58,17 +58,49 @@ App.Medicine.Surgery.Procedures.ImmortalityTreatment = class extends App.Medicin
 		return `this will alter ${his} genetic code to reverse and prevent aging, effectively thwarting the rigors of old age`;
 	}
 
-	get cost() {
-		return super.cost * 4;
+	get _workCost() {
+		return super._workCost * 4;
 	}
 
 	get healthCost() {
 		return 40;
 	}
 
+	get note() {
+		return App.UI.DOM.makeElement("span", `Post operation, high levels of DNA toxicity may be identified within the patient. Placement within a modern and staffed Clinic is highly recommended.`, ["warning"]);
+	}
+
 	apply(cheat) {
 		this._slave.geneMods.immortality = 1;
 		this._slave.chem += 1000;
+		if (V.clinic) {
+			assignJob(this.originalSlave, Job.CLINIC);
+		}
+		return this._assemble(new App.Medicine.Surgery.Reactions.GeneTreatment());
+	}
+};
+
+App.Medicine.Surgery.Procedures.milkFlavoring = class extends App.Medicine.Surgery.Procedure {
+	get name() {
+		return "Bio-engineered milk flavoring";
+	}
+
+	get description() {
+		const {his} = getPronouns(this.originalSlave);
+		return `This will alter ${his} genetics to allow flavored milk`;
+	}
+
+	get cost() {
+		return super.cost * 1.5;
+	}
+
+	get healthCost() {
+		return 15;
+	}
+
+	apply(cheat) {
+		this._slave.milkFlavor = "natural";
+		this._slave.chem += 100;
 		return this._assemble(new App.Medicine.Surgery.Reactions.GeneTreatment());
 	}
 };
@@ -94,8 +126,8 @@ App.Medicine.Surgery.Procedures.RemoveGene = class extends App.Medicine.Surgery.
 		return `Applying a retro-virus treatment radically increases carcinogen buildup`;
 	}
 
-	get cost() {
-		return super.cost * 4;
+	get _workCost() {
+		return super._workCost * 4;
 	}
 
 	get healthCost() {
@@ -144,8 +176,8 @@ App.Medicine.Surgery.Procedures.AddGene = class extends App.Medicine.Surgery.Pro
 		return r.join(" ");
 	}
 
-	get cost() {
-		return super.cost * (this.activation ? 4 : 10);
+	get _workCost() {
+		return super._workCost * (this.activation ? 4 : 10);
 	}
 
 	get healthCost() {
diff --git a/js/medicine/surgery/extreme/fuckdoll.js b/js/medicine/surgery/extreme/fuckdoll.js
index 026265842337b99fc03ed386d9e19d505825cda8..900913f6882f5768703f80760a19d77c8f0c90b0 100644
--- a/js/medicine/surgery/extreme/fuckdoll.js
+++ b/js/medicine/surgery/extreme/fuckdoll.js
@@ -181,7 +181,7 @@ App.Medicine.Surgery.Procedures.Fuckdoll = class extends App.Medicine.Surgery.Pr
 		return "Encase in a Fuckdoll suit";
 	}
 
-	get cost() {
+	get _workCost() {
 		return 0;
 	}
 
diff --git a/js/medicine/surgery/extreme/fuckdollExtraction.js b/js/medicine/surgery/extreme/fuckdollExtraction.js
index dc966e070868c16cbb57b5b983caec732595e080..a7a6bf621498688217b37e18a377d10e8d075812 100644
--- a/js/medicine/surgery/extreme/fuckdollExtraction.js
+++ b/js/medicine/surgery/extreme/fuckdollExtraction.js
@@ -39,7 +39,7 @@ App.Medicine.Surgery.Procedures.FuckdollExtraction = class extends App.Medicine.
 		return `Extract ${him}`;
 	}
 
-	get cost() {
+	get _workCost() {
 		return 0;
 	}
 
diff --git a/js/medicine/surgery/face/lips.js b/js/medicine/surgery/face/lips.js
index 2ee1174da1dfe84d05c40276c27238a19d153d62..3efebb3a8e59af39919e0424994046015e9d9004 100644
--- a/js/medicine/surgery/face/lips.js
+++ b/js/medicine/surgery/face/lips.js
@@ -51,68 +51,95 @@ App.Medicine.Surgery.Reactions.Lips = class extends App.Medicine.Surgery.SimpleR
 	}
 };
 
-App.Medicine.Surgery.Procedures.IncreaseLipImplant = class extends App.Medicine.Surgery.Procedure {
-	get name() {
-		return "Replace with the next size up";
-	}
+/**
+ * @type {FC.Medicine.AssetSizingProcedureSet}
+ */
+App.Medicine.Surgery.Procedures.lipImplantProcedure = function() {
+	class Fill extends App.Medicine.Surgery.Procedures.FillSizingImplantProcedure {
+		get name() {
+			return "Replace with the next size up";
+		}
 
-	get healthCost() {
-		return 10;
+		get description() {
+			return '';
+		}
 	}
 
-	apply(cheat) {
-		this._slave.lipsImplant += 20;
-		this._slave.lips += 20;
-		return this._assemble(new App.Medicine.Surgery.Reactions.Lips());
-	}
-};
+	/**
+	 * @template {FC.Medicine.SizingImplantProcedureConstructor} T
+	 * @param {T} Procedure
+	 * @param {ConstructorParameters<T>} args
+	 */
+	function makeProcedure(Procedure, args) {
+		return new (class extends Procedure {
+			_doTargetGain() {
+				return new App.Medicine.Surgery.Reactions.Lips();
+			}
 
-App.Medicine.Surgery.Procedures.AddLipImplant = class extends App.Medicine.Surgery.Procedure {
-	get name() {
-		return "Lip implant";
-	}
+			_doTargetLoss() {
+				return new App.Medicine.Surgery.Reactions.Lips();
+			}
 
-	get healthCost() {
-		return 10;
-	}
+			/**
+			 * @param {number} volume
+			 * @returns {string}
+			 */
+			_volumeStr(volume) {
+				return '';
+			}
 
-	apply(cheat) {
-		this._slave.lipsImplant = 20;
-		this._slave.lips += 20;
-		return this._assemble(new App.Medicine.Surgery.Reactions.Lips());
-	}
-};
+			/**
+			 * @param {number} volume
+			 * @returns {string}
+			 */
+			_fleshExcessStr(volume) {
+				return App.Utils.expandHTML(`${Math.round(100. * volume / App.Medicine.fleshSize(this.originalSlave, "lips"))}&thinsp;%`);
+			}
 
-App.Medicine.Surgery.Procedures.RemoveLipImplant = class extends App.Medicine.Surgery.Procedure {
-	get name() {
-		return "Remove lip implants";
+			// overridden because slaves do not have the lipsImplantType property (yet?)
+			_setSlaveImplantType() {}
+		})(...args);
 	}
 
-	get healthCost() {
-		return 10;
-	}
+	class Reduce extends App.Medicine.Surgery.Procedure {
+		/**
+		 * @param {FC.SlaveState} slave
+		 * @param {string} name
+		 * @param {number} amount
+		 */
+		constructor(slave, name, amount) {
+			super(slave);
+			this._name = name;
+			this._amount = amount;
+		}
 
-	apply(cheat) {
-		this._slave.lips -= this._slave.lipsImplant;
-		this._slave.lipsImplant = 0;
-		if (this._slave.skill.oral > 10) {
-			this._slave.skill.oral -= 10;
+		get name() {
+			return `${this._name.toUpperFirst()} lips`;
 		}
-		return this._assemble(new App.Medicine.Surgery.Reactions.Lips());
-	}
-};
 
-App.Medicine.Surgery.Procedures.ReduceLips = class extends App.Medicine.Surgery.Procedure {
-	get name() {
-		return "Reduce lips";
-	}
+		get healthCost() {
+			return 10;
+		}
 
-	get healthCost() {
-		return 10;
+		apply(cheat) {
+			this._slave.lips -= this._amount;
+			return this._assemble(new App.Medicine.Surgery.Reactions.Lips());
+		}
 	}
 
-	apply(cheat) {
-		this._slave.lips -= 10;
-		return this._assemble(new App.Medicine.Surgery.Reactions.Lips());
-	}
-};
+	return {
+		install: (slave, type, size, fleshExcess) =>
+			makeProcedure(App.Medicine.Surgery.Procedures.InstallSizingImplantProcedure, [slave, "lips", type, size, fleshExcess]),
+		replace: (slave, type, size, fleshExcess) =>
+			makeProcedure(App.Medicine.Surgery.Procedures.ReplaceSizingImplantProcedure, [slave, "lips", type, size, fleshExcess]),
+		remove: (slave) =>
+			makeProcedure(App.Medicine.Surgery.Procedures.RemoveSizingImplantProcedure, [slave, "lips"]),
+
+		fill: (slave, amount) =>
+			makeProcedure(Fill, [slave, "lips", amount]),
+		drain: (slave, amount) =>
+			makeProcedure(App.Medicine.Surgery.Procedures.DrainSizingImplantProcedure, [slave, "lips", amount]),
+
+		reduce: (slave, name, amount) => new Reduce(slave, name, amount)
+	};
+}();
diff --git a/js/medicine/surgery/genitials/geld.js b/js/medicine/surgery/genitials/geld.js
index d2d9efdb28d63f6d959575d5eead7d596a687789..45f63cb509b4d079afe67efde4aa8c7d4898b0ba 100644
--- a/js/medicine/surgery/genitials/geld.js
+++ b/js/medicine/surgery/genitials/geld.js
@@ -47,6 +47,11 @@ App.Medicine.Surgery.Procedures.Geld = class extends App.Medicine.Surgery.Proced
 		this._slave.ballType = "human";
 		this._slave.scrotum = 0;
 		this._slave.vasectomy = 0;
+		if (this._slave.drugs === "testicle enhancement" ||
+			this._slave.drugs === "hyper testicle enhancement" ||
+			this._slave.drugs === "testicle atrophiers") {
+			this._slave.drugs = "no drugs";
+		}
 		return this._assemble(new App.Medicine.Surgery.Reactions.Geld());
 	}
 };
diff --git a/js/medicine/surgery/genitials/maleToFemale.js b/js/medicine/surgery/genitials/maleToFemale.js
index 9e168d9071beb020b03a8cc8129b3ebb4b3e0352..71c8ebd92b8fb20569e0769313b99b7668c42d08 100644
--- a/js/medicine/surgery/genitials/maleToFemale.js
+++ b/js/medicine/surgery/genitials/maleToFemale.js
@@ -51,18 +51,18 @@ App.Medicine.Surgery.Procedures.MaletoFemale = class extends App.Medicine.Surger
 	}
 
 	apply(cheat) {
-		this._slave.dick = 0;
-		this._slave.dickAccessory = "none";
-		this._slave.chastityPenis = 0;
-		this._slave.dickTat = 0;
-		this._slave.foreskin = 0;
+		surgeryAmp(this._slave, "dick");
 		this._slave.scrotum = 0;
 		this._slave.balls = 0;
 		this._slave.ballType = "human";
 		this._slave.vasectomy = 0;
 		this._slave.vagina = 0;
 		this._slave.preg = -2;
-		this._slave.skill.vaginal = 0;
+		if (this._slave.drugs === "testicle enhancement" ||
+			this._slave.drugs === "hyper testicle enhancement" ||
+			this._slave.drugs === "testicle atrophiers") {
+			this._slave.drugs = "no drugs";
+		}
 		return this._assemble(new App.Medicine.Surgery.Reactions.MaletoFemale());
 	}
 };
diff --git a/js/medicine/surgery/prosthetics/pLimbInterface.js b/js/medicine/surgery/prosthetics/pLimbInterface.js
index 1e11028f98a1f18536823bb780919797907a760c..c740e151839c95796f4a97c0e5890bd66db84d5d 100644
--- a/js/medicine/surgery/prosthetics/pLimbInterface.js
+++ b/js/medicine/surgery/prosthetics/pLimbInterface.js
@@ -186,7 +186,7 @@ App.Medicine.Surgery.Procedures.AdvancedPLimbInterface = class extends App.Medic
 	}
 
 	get disabledReasons() {
-		const r = [];
+		const r = super.disabledReasons;
 		const {He} = getPronouns(this.originalSlave);
 		if (this.originalSlave.PLimb === 3 && hasAnyProstheticLimbs(this.originalSlave)) {
 			r.push(`${He} still has limbs attached. Remove all limbs before downgrading.`);
@@ -219,7 +219,7 @@ App.Medicine.Surgery.Procedures.QuadrupedalPLimbInterface = class extends App.Me
 	}
 
 	get disabledReasons() {
-		const r = [];
+		const r = super.disabledReasons;
 		const {He} = getPronouns(this.originalSlave);
 		if ((this.originalSlave.PLimb === 1 || this.originalSlave.PLimb === 2) && hasAnyProstheticLimbs(this.originalSlave)) {
 			r.push(`${He} still has limbs attached. Remove all limbs before upgrading.`);
diff --git a/js/medicine/surgery/structural/amputation.js b/js/medicine/surgery/structural/amputation.js
index a371ddafbbb9ff41f50ba2c903b09594922e8fe2..b3e347a6b60a2b4b1eb6e52c4ab5a728569a0440 100644
--- a/js/medicine/surgery/structural/amputation.js
+++ b/js/medicine/surgery/structural/amputation.js
@@ -26,7 +26,7 @@ App.Medicine.Surgery.Reactions.Amputate = class extends App.Medicine.Surgery.Sim
 				}
 				r.push(`${his} limbless torso, ${he} squares ${his} shoulders and visibly resolves to carry on being a good slave as best ${he} can. Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span>`);
 			} else if (slave.devotion > 20) {
-				r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. Despite ${his} obedience, ${he} cries softly the whole time, shoulder and hip stumps moving occasionally as ${he} reflexively tries to stand — to walk — to touch ${himself} — to gesture — all things that ${he} will never do again. <span class="devotion dec">${He} will struggle greatly with ${his} medically created disability.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="fear inc">cripplingly afraid</span> of your total power over ${his} body.`);
+				r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. Despite ${his} obedience, ${he} cries softly the whole time, shoulder and hip stumps moving occasionally as ${he} reflexively tries to stand — to walk — to touch ${himself} — to gesture — all things that ${he} will never do again. <span class="devotion dec">${He} will struggle greatly with ${his} medically created disability.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="trust dec">cripplingly afraid</span> of your total power over ${his} body.`);
 				reaction.trust -= 20;
 				reaction.devotion -= 20;
 			} else {
@@ -42,7 +42,7 @@ App.Medicine.Surgery.Reactions.Amputate = class extends App.Medicine.Surgery.Sim
 				} else {
 					r.push(`stumps twitch pathetically with ${his} desperate efforts to move ${his} limbs, to prove there is something other than this.`);
 				}
-				r.push(`Anything other than this. <span class="devotion dec">The surgical invasion has filled ${him} with horror and anger.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="fear inc">terrified to the point of insanity</span> of your total power over ${his} body.`);
+				r.push(`Anything other than this. <span class="devotion dec">The surgical invasion has filled ${him} with horror and anger.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="trust dec">terrified to the point of insanity</span> of your total power over ${his} body.`);
 				reaction.trust -= 50;
 				reaction.devotion -= 50;
 			}
@@ -61,7 +61,7 @@ App.Medicine.Surgery.Reactions.Amputate = class extends App.Medicine.Surgery.Sim
 						}
 						r.push(`the two stumps that were once ${his} arms, ${he} squares ${his} shoulders and resolves to carry on being a good slave as best ${he} can. Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span>`);
 					} else if (slave.devotion > 20) {
-						r.push(`You're there to open the door for ${him} as ${he} exits the surgery. Despite ${his} obedience, ${he} cries softly the whole time, ${his} shoulder stumps occasionally moving as ${he} reflexively tries to grab at ${himself} and ${his} surroundings. <span class="devotion dec">${He} will struggle greatly with ${his} medically created disability.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="fear inc">extremely afraid</span> of your total power over ${his} body.`);
+						r.push(`You're there to open the door for ${him} as ${he} exits the surgery. Despite ${his} obedience, ${he} cries softly the whole time, ${his} shoulder stumps occasionally moving as ${he} reflexively tries to grab at ${himself} and ${his} surroundings. <span class="devotion dec">${He} will struggle greatly with ${his} medically created disability.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="trust dec">extremely afraid</span> of your total power over ${his} body.`);
 						reaction.trust -= 15;
 						reaction.devotion -= 15;
 					} else {
@@ -77,7 +77,7 @@ App.Medicine.Surgery.Reactions.Amputate = class extends App.Medicine.Surgery.Sim
 						} else {
 							r.push(`shoulder stumps twitch pathetically with ${his} desperate efforts to move ${his} arms, to prove there is something other than this.`);
 						}
-						r.push(`Anything other than this. <span class="devotion dec">The surgical invasion has filled ${him} with horror and anger.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="fear inc">utterly and entirely terrified</span> of your total power over ${his} body.`);
+						r.push(`Anything other than this. <span class="devotion dec">The surgical invasion has filled ${him} with horror and anger.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="trust dec">utterly and entirely terrified</span> of your total power over ${his} body.`);
 						reaction.trust -= 40;
 						reaction.devotion -= 40;
 					}
@@ -94,7 +94,7 @@ App.Medicine.Surgery.Reactions.Amputate = class extends App.Medicine.Surgery.Sim
 						}
 						r.push(`the stump that was once ${his} arm, ${he} squares ${his} shoulders and resolves to carry on being a good slave as best ${he} can. Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span>`);
 					} else if (slave.devotion > 20) {
-						r.push(`You're there to help ${him} with the door as ${he} exits the surgery. Despite ${his} obedience, ${he} cries softly the whole time, the stump at ${his} shoulder occasionally moving as ${he} reflexively tries to grab at ${himself} and ${his} surroundings. <span class="devotion dec">${He} will struggle greatly with ${his} medically created disability.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="fear inc">immensely afraid</span> of your total power over ${his} body.`);
+						r.push(`You're there to help ${him} with the door as ${he} exits the surgery. Despite ${his} obedience, ${he} cries softly the whole time, the stump at ${his} shoulder occasionally moving as ${he} reflexively tries to grab at ${himself} and ${his} surroundings. <span class="devotion dec">${He} will struggle greatly with ${his} medically created disability.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="trust dec">immensely afraid</span> of your total power over ${his} body.`);
 						reaction.trust -= 8;
 						reaction.devotion -= 8;
 					} else {
@@ -114,7 +114,7 @@ App.Medicine.Surgery.Reactions.Amputate = class extends App.Medicine.Surgery.Sim
 						} else {
 							r.push(`shoulder stump twitches pathetically with ${his} desperate efforts to move ${his} missing arm, to prove there is something other than this.`);
 						}
-						r.push(`Anything other than this. <span class="devotion dec">The surgical invasion has filled ${him} with horror and anger.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="fear inc">incredibly and intensely terrified</span> of your total power over ${his} body.`);
+						r.push(`Anything other than this. <span class="devotion dec">The surgical invasion has filled ${him} with horror and anger.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="trust dec">incredibly and intensely terrified</span> of your total power over ${his} body.`);
 						reaction.trust -= 20;
 						reaction.devotion -= 20;
 					}
@@ -132,7 +132,7 @@ App.Medicine.Surgery.Reactions.Amputate = class extends App.Medicine.Surgery.Sim
 						}
 						r.push(`the stump that was once ${his} leg, ${he} squares ${his} shoulders and resolves to carry on being a good slave as best ${he} can. Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span>`);
 					} else if (slave.devotion > 20) {
-						r.push(`Of course, ${he} could not walk out of the surgery by ${himself}; you had to walk alongside ${him}. Despite ${his} obedience, ${he} cries softly the whole time, the stump at ${his} hip occasionally moving as ${he} reflexively tries to use it somehow. <span class="devotion dec">${He} will struggle greatly with ${his} medically created disability.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="fear inc">immensely afraid</span> of your total power over ${his} body.`);
+						r.push(`Of course, ${he} could not walk out of the surgery by ${himself}; you had to walk alongside ${him}. Despite ${his} obedience, ${he} cries softly the whole time, the stump at ${his} hip occasionally moving as ${he} reflexively tries to use it somehow. <span class="devotion dec">${He} will struggle greatly with ${his} medically created disability.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="trust dec">immensely afraid</span> of your total power over ${his} body.`);
 						reaction.trust -= 5;
 						reaction.devotion -= 5;
 					} else {
@@ -152,7 +152,7 @@ App.Medicine.Surgery.Reactions.Amputate = class extends App.Medicine.Surgery.Sim
 						} else {
 							r.push(`leg stump twitches pathetically with ${his} desperate efforts to move ${his} missing leg, to prove there is something other than this.`);
 						}
-						r.push(`Anything other than this. <span class="devotion dec">The surgical invasion has filled ${him} with horror and anger.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="fear inc">incredibly and intensely terrified</span> of your total power over ${his} body.`);
+						r.push(`Anything other than this. <span class="devotion dec">The surgical invasion has filled ${him} with horror and anger.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="trust dec">incredibly and intensely terrified</span> of your total power over ${his} body.`);
 						reaction.trust -= 15;
 						reaction.devotion -= 15;
 					}
@@ -168,7 +168,7 @@ App.Medicine.Surgery.Reactions.Amputate = class extends App.Medicine.Surgery.Sim
 						}
 						r.push(`the two stumps that were once ${his} legs, ${he} squares ${his} shoulders and resolves to carry on being a good slave as best ${he} can. Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span>`);
 					} else if (slave.devotion > 20) {
-						r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. Despite ${his} obedience, ${he} cries softly the whole time, ${his} hip stumps occasionally moving as ${he} reflexively tries to stand up and walk around. <span class="devotion dec">${He} will struggle greatly with ${his} medically created disability.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="fear inc">extremely afraid</span> of your total power over ${his} body.`);
+						r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. Despite ${his} obedience, ${he} cries softly the whole time, ${his} hip stumps occasionally moving as ${he} reflexively tries to stand up and walk around. <span class="devotion dec">${He} will struggle greatly with ${his} medically created disability.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="trust dec">extremely afraid</span> of your total power over ${his} body.`);
 						reaction.trust -= 10;
 						reaction.devotion -= 10;
 					} else {
@@ -184,7 +184,7 @@ App.Medicine.Surgery.Reactions.Amputate = class extends App.Medicine.Surgery.Sim
 						} else {
 							r.push(`hip stumps twitch pathetically with ${his} desperate efforts to move ${his} legs, to prove there is something other than this.`);
 						}
-						r.push(`Anything other than this. <span class="devotion dec">The surgical invasion has filled ${him} with horror and anger.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="fear inc">utterly and entirely terrified</span> of your total power over ${his} body.`);
+						r.push(`Anything other than this. <span class="devotion dec">The surgical invasion has filled ${him} with horror and anger.</span> Since the surgery was invasive, <span class="health dec">${his} health has been greatly affected.</span> ${He} is <span class="trust dec">utterly and entirely terrified</span> of your total power over ${his} body.`);
 						reaction.trust -= 30;
 						reaction.devotion -= 30;
 					}
@@ -259,18 +259,19 @@ App.Medicine.Surgery.Procedures.Amputate = class extends App.Medicine.Surgery.Pr
 	}
 
 	get disabledReasons() {
+		const reasons = super.disabledReasons;
 		if (this.count === 0) {
-			return ["No limb selected"];
+			reasons.push("No limb selected");
 		}
-		return [];
+		return reasons;
 	}
 
 	get healthCost() {
 		return this.count * 10;
 	}
 
-	get cost() {
-		return super.cost * this.count;
+	get _workCost() {
+		return super._workCost * this.count;
 	}
 
 	apply(cheat) {
diff --git a/js/medicine/surgery/teeth/dental.js b/js/medicine/surgery/teeth/dental.js
index 410853c78bf622fb2c3e8b89f1956f350ba9f5b8..47b41f07ab1d37f5c7ac50bee0322fd3df337442 100644
--- a/js/medicine/surgery/teeth/dental.js
+++ b/js/medicine/surgery/teeth/dental.js
@@ -28,6 +28,6 @@ App.Medicine.Surgery.Procedures.DentalImplant = class extends App.Medicine.Surge
 
 	apply(cheat) {
 		this._slave.teeth = "normal";
-		return this._assemble(new App.Medicine.Surgery.Reactions.Template());
+		return this._assemble(new App.Medicine.Surgery.Reactions.DentalImplant());
 	}
 };
diff --git a/js/medicine/utility.js b/js/medicine/utility.js
new file mode 100644
index 0000000000000000000000000000000000000000..a7e2ba4d7cd20a6b08d4fb70db9883b0643661bb
--- /dev/null
+++ b/js/medicine/utility.js
@@ -0,0 +1,141 @@
+App.Medicine.pocketVolume = function() {
+	/**
+	 * @param {FC.HumanState} slave
+	 * @returns {number}
+	 */
+	function boobs(slave) {
+		/*
+		The breast is approximated by a spherical cap with the volume of slave.boobs.
+		The radius `a` of the cap is proportional to slave height and shoulders width
+		We assume that the skin has elasticity coefficient that depends on slave physical age.
+		Max pocket volume is therefore the volume of the cap with the same base but the
+		surface stretched by the skin elasticity coefficient
+		V = 1/6*πh(3a²+h²)
+		A = π(a²+h²)
+		*/
+		const a = 0.05 * slave.height + slave.shoulders * 1.1;
+		/* now the eq. for V we rewrite as
+		h³ + 3a³h -6/π*V = 0
+		and replace:
+		p = 3*a³, q = -6/π*V:
+		h³ + ph + q = 0
+		*/
+		const p = 3 * a * a;
+		const q = -6. / Math.PI * slave.boobs;
+		const Q = Math.pow(p / 3, 3) + Math.pow(q / 2, 2);
+		console.assert(Q > 0);
+		const h = Math.cbrt(-q / 2 + Math.sqrt(Q)) + Math.cbrt(-q / 2 - Math.sqrt(Q));
+
+		// now the current skin area:
+		const A = Math.PI * (a * a + h * h);
+
+		const skinStretchFactor = linearInterpolation(Math.max(slave.physicalAge, 13), 13, 1.5, 45, 1.15);
+
+		const hMax = Math.sqrt(A * skinStretchFactor / Math.PI - a * a);
+		const VMax = Math.PI / 6 * hMax * (3 * a * a + hMax * hMax);
+
+		return VMax;
+	}
+
+	/**
+	 * @param {FC.HumanState} slave
+	 * @returns {number}
+	 */
+	function butt(slave) {
+		return slave.butt + (slave.hips > 0 ? 2 : 1);
+	}
+
+	/**
+	 * @param {FC.HumanState} slave
+	 * @returns {number}
+	 */
+	function lips(slave) {
+		return slave.lips + 10;
+	}
+
+	return {
+		boobs,
+		butt,
+		lips
+	};
+}();
+
+/**
+ * @template {FC.SizingImplantTarget} T
+ * @param {FC.HumanState} slave
+ * @param {T} target
+ * @returns {FC.Medicine.ImplantInfo<T>}
+ */
+App.Medicine.implantInfo = function(slave, target) {
+	/**
+	 * @template {"boobs"|"butt"} Target
+	 * @param {Target} target
+	 * @returns FC.Medicine.ImplantInfo<Target>
+	 */
+	function boobsButt(target) {
+		return {
+			type: slave[`${target}ImplantType`],
+			volume: slave[`${target}Implant`]
+		};
+	}
+
+	switch (target) {
+		case "boobs":
+		case "butt":
+			return /** @type {FC.Medicine.ImplantInfo<T>} */(boobsButt(target));
+		case "lips":
+			return {
+				type: slave.lipsImplant > 0 ? "normal" : "none",
+				volume: slave.lipsImplant
+			};
+	}
+};
+
+/**
+ * @template {FC.SizingImplantTarget} T
+ * @param {T} target
+ * @returns {Array<FC.BodyPartImplantTypeMap[T]>}
+ */
+App.Medicine.implantTypesForTarget = function(target) {
+	return Object.keys(App.Data.Medicine.sizingImplants[target]);
+};
+
+/**
+ * Returns the size of the flesh part of the sizable body part
+ * @param {FC.SlaveState} slave
+ * @param {FC.SizableBodyPart} part
+ * @returns {number}
+ */
+App.Medicine.fleshSize = function(slave, part) {
+	switch (part) {
+		case "balls": return slave.balls;
+		case "boobs": return slave.boobs - slave.boobsImplant - slave.boobsMilk;
+		case "butt": return slave.butt - slave.buttImplant;
+		case "dick": return slave.dick;
+		case "lips": return slave.lips - slave.lipsImplant;
+	}
+};
+
+/**
+ * Returns the size of the flesh part of the sizable body part
+ * @param {FC.SlaveState} slave
+ * @param {FC.SizableBodyPart} part
+ * @returns {number}
+ */
+App.Medicine.assetSize = function(slave, part) {
+	return slave[part];
+};
+
+/**
+ * @param {FC.SizableBodyPart} part
+ * @returns {number}
+ */
+App.Medicine.maxAssetSize = function(part) {
+	switch (part) {
+		case "balls": return 125;
+		case "boobs": return 50000;
+		case "butt": return 20;
+		case "dick": return 31;
+		case "lips": return V.seeExtreme ? 96 : 86;
+	}
+};
diff --git a/js/medicine/z001-organFarm/2-reproductiveOrgans.js b/js/medicine/z001-organFarm/2-reproductiveOrgans.js
index 2a1e0856255a03e4e947c5051ded79a4bfcc311d..016ba16eb157c5173c17c0b59bd484bacbb5b529 100644
--- a/js/medicine/z001-organFarm/2-reproductiveOrgans.js
+++ b/js/medicine/z001-organFarm/2-reproductiveOrgans.js
@@ -100,9 +100,7 @@ App.Medicine.OrganFarm.OvariesImplantAction = class extends App.Medicine.OrganFa
 		implantError
 	}) {
 		super({
-			name: name,
-			//healthImpact: 20,
-			surgeryType: animal ? "addAnimalOvaries" : "addOvaries", autoImplant: autoImplant,
+			name: name, autoImplant: autoImplant,
 			surgeryProcedure: surgeryProcedure,
 			surgeryProcedureParams: surgeryProcedureParams,
 			canImplant: s => (!this.animal || V.animalTesticles > 0) && canImplant(s),
diff --git a/js/ratings.js b/js/ratings.js
new file mode 100644
index 0000000000000000000000000000000000000000..3e0671dfa503b6fc7b3d4ad638063f1e287b5aac
--- /dev/null
+++ b/js/ratings.js
@@ -0,0 +1,41 @@
+
+/**
+ * @template {PropertyKey} K
+ * @template {*} T
+ * @param {Partial<Record<K, T>>} dict
+ * @param {K} value
+ * @param {T} [defaultValue]
+ * @returns {T|null}
+ */
+App.Ratings.exact = function(dict, value, defaultValue = null) {
+	const res = dict[value];
+	return res ? res : defaultValue;
+};
+
+/**
+ * @template {*} T
+ * @param {Record<number, T>} ratings
+ * @param {number} value
+ * @returns {T|null}
+ */
+App.Ratings.numeric = function(ratings, value) {
+	for (const key in ratings) {
+		if (parseInt(key) >= value) {
+			return ratings[key];
+		}
+	}
+	return null;
+};
+
+/**
+ * @param {object} ratings
+ * @param {number[]} values
+ * @returns {*|null}
+ */
+App.Ratings.multiNumeric = function(ratings, values) {
+	const firstRating = App.Ratings.numeric(ratings, values[0]);
+	if (firstRating === null || typeof firstRating === "string" || firstRating.hasOwnProperty("desc")) {
+		return firstRating;
+	}
+	return App.Ratings.multiNumeric(firstRating, values.slice(1));
+};
diff --git a/js/rulesAssistant/01-stack.js b/js/rulesAssistant/01-stack.js
new file mode 100644
index 0000000000000000000000000000000000000000..b0924afc86c6eac6a45b5686edfea7041d96ad86
--- /dev/null
+++ b/js/rulesAssistant/01-stack.js
@@ -0,0 +1,56 @@
+App.RA.Activation.Stack = class Stack {
+	constructor() {
+		/**
+		 * @private
+		 * @type {number[]}
+		 */
+		this._numbers = [];
+		/**
+		 * @private
+		 * @type {string[]}
+		 */
+		this._strings = [];
+	}
+
+	/**
+	 * @param {boolean} v
+	 */
+	pushBoolean(v) {
+		this._numbers.push(v ? 1 : 0);
+	}
+
+	/**
+	 * @returns {FC.Bool}
+	 */
+	popAsBoolean() {
+		return this._numbers.pop() ? 1 : 0;
+	}
+
+	/**
+	 * @param {number} v
+	 */
+	pushNumber(v) {
+		this._numbers.push(v);
+	}
+
+	/**
+	 * @returns {number}
+	 */
+	popNumber() {
+		return this._numbers.pop();
+	}
+
+	/**
+	 * @param {string} v
+	 */
+	pushString(v) {
+		this._strings.push(v);
+	}
+
+	/**
+	 * @returns {string}
+	 */
+	popString() {
+		return this._strings.pop();
+	}
+};
diff --git a/js/rulesAssistant/conditionEditor.js b/js/rulesAssistant/conditionEditor.js
new file mode 100644
index 0000000000000000000000000000000000000000..88a6ac2ba08643609311ea0a8be4656789d9a5ac
--- /dev/null
+++ b/js/rulesAssistant/conditionEditor.js
@@ -0,0 +1,1322 @@
+App.RA.Activation.Editor = (function() {
+	/**
+	 * @type {HTMLDivElement}
+	 */
+	let editorNode = null;
+	/**
+	 * @type {Map<string, RulePart>}
+	 */
+	let rulePartMap = null;
+	/**
+	 * @type {RuleGroup}
+	 */
+	let currentRule = null;
+
+	/**
+	 * @param {FC.RA.PostFixRule} rule
+	 * @returns {HTMLDivElement}
+	 */
+	function editor(rule) {
+		rulePartMap = new Map();
+		currentRule = deserializeRule(rule);
+		editorNode = document.createElement("div");
+		editorNode.append(buildEditor());
+		return editorNode;
+	}
+
+	function refreshEditor() {
+		if (editorNode !== null) {
+			$(editorNode).empty().append(buildEditor());
+		}
+	}
+
+	/**
+	 * Save the rule, if it is valid.
+	 *
+	 * @param {(rule:FC.RA.PostFixRule)=>void} callback
+	 */
+	function saveEditor(callback) {
+		if (currentRule == null) {
+			return;
+		}
+		const error = currentRule.validate([]) === "error";
+		if (!error) {
+			callback(serializeRule(currentRule));
+		}
+	}
+
+	function resetEditor() {
+		rulePartMap = null;
+		currentRule = null;
+		editorNode = null;
+	}
+
+	/**
+	 * @returns {HTMLElement}
+	 */
+	function buildEditor() {
+		const outerDiv = document.createElement("div");
+		outerDiv.classList.add("rule-builder");
+
+		const ruleDiv = document.createElement("div");
+		ruleDiv.classList.add("condition-viewer");
+		const errors = [];
+		if (currentRule.validate(errors) === "error") {
+			ruleDiv.append("Condition has errors:");
+			for (const error of errors) {
+				ruleDiv.append(" ", error);
+			}
+			ruleDiv.append(" Changes have NOT been saved!");
+		} else {
+			ruleDiv.append("Condition saved.");
+		}
+		ruleDiv.append(" ", App.Encyclopedia.Dialog.linkDOM("Help", "RA Condition Editor"));
+		ruleDiv.append(currentRule.render());
+		outerDiv.append(ruleDiv);
+
+		outerDiv.append(buildPartBrowser());
+
+		return outerDiv;
+	}
+
+	/**
+	 * @returns {HTMLDivElement}
+	 */
+	function buildPartBrowser() {
+		const container = document.createElement("div");
+		App.UI.DOM.appendNewElement("h3", container, "Part Browser");
+		const div = document.createElement("div");
+		div.classList.add("rule-part-browser");
+		div.append(new RulePartProvider(() => new RuleGroup("and")).render());
+		div.append(new RulePartProvider(() => new RuleGroup("add")).render());
+		div.append(new RulePartProvider(() => new RuleNegate()).render());
+		div.append(new RulePartProvider(() => new RulePair("eq")).render());
+		div.append(new RulePartProvider(() => new RuleTernary()).render());
+		div.append(new RulePartProvider(() => new RuleMapCheck(App.RA.Activation.getterManager.booleanDefault)).render());
+		div.append(new RulePartProvider(() => new RuleMapCheck(App.RA.Activation.getterManager.numberDefault)).render());
+		div.append(new RulePartProvider(() => new RuleMapCheck(App.RA.Activation.getterManager.stringDefault)).render());
+		div.append(new RulePartProvider(() => new RuleMapCheck(App.RA.Activation.getterManager.assignmentDefault)).render());
+		div.append(new RulePartProvider(() => new RuleConstant(0)).render());
+		div.append(new RulePartProvider(() => new RuleBooleanConstant(true)).render());
+		div.append(new RulePartProvider(() => new RuleConstant("some text")).render());
+		div.append(new RulePartProvider(() => new RuleCustomCheck("bcontext => false")).render());
+		div.append(new RulePartTrash().render());
+		container.append(div);
+		return container;
+	}
+
+	/**
+	 * @abstract
+	 */
+	class RulePart {
+		constructor() {
+			this.id = generateNewID();
+			rulePartMap.set(this.id, this);
+
+			/**
+			 * @type {?RuleContainer}
+			 */
+			this.parent = null;
+
+			/**
+			 * @type {HTMLElement}
+			 * @protected
+			 */
+			this._dragElement = null;
+
+			/**
+			 * @type {boolean}
+			 * @private
+			 */
+			this._showValidationError = true;
+		}
+
+		/**
+		 * @abstract
+		 * @returns {HTMLElement}
+		 */
+		render() {
+			throw new Error("Method 'render()' must be implemented.");
+		}
+
+		/**
+		 * Validate the rule, gives the expected return type or "error".
+		 * @abstract
+		 * @param {Array<string>} errorList
+		 * @returns {"number"|"string"|"error"}
+		 */
+		validate(errorList) {
+			throw new Error("Method 'validate()' must be implemented.");
+		}
+
+		/**
+		 * Makes the element not draggable
+		 */
+		disableDragging() {
+			if (this._dragElement != null) {
+				this._dragElement.draggable = false;
+			}
+			if (this.parent != null) {
+				this.parent.disableDragging();
+			}
+		}
+
+		/**
+		 * Makes the element draggable again.
+		 */
+		enableDragging() {
+			if (this.parent != null) {
+				if (this._dragElement != null) {
+					this._dragElement.draggable = true;
+				}
+				this.parent.enableDragging();
+			}
+		}
+
+		/**
+		 * @protected
+		 * @param {HTMLElement} element
+		 */
+		_markValidationError(element) {
+			if (this._showValidationError && this.validate([]) === "error") {
+				element.classList.add("validation-error");
+			}
+		}
+
+		/**
+		 * @param {boolean} value
+		 */
+		set showValidationError(value) {
+			this._showValidationError = value;
+		}
+	}
+
+	/**
+	 * @abstract
+	 */
+	class RuleContainer extends RulePart {
+		/**
+		 * @abstract
+		 * @param {RulePart} rulePart
+		 */
+		removeChild(rulePart) {
+			throw new Error("Method 'removeChild()' must be implemented.");
+		}
+
+		/**
+		 * @abstract
+		 * @param {RuleContainer} maybeChild
+		 * @returns {boolean}
+		 */
+		isParent(maybeChild) {
+			throw new Error("Method 'isParent()' must be implemented.");
+		}
+
+		/**
+		 * @param {HTMLElement} element
+		 * @param {(child:RulePart)=>void} setChild
+		 * @protected
+		 */
+		_allowDroppingOn(element, setChild) {
+			element.ondragover = ev => {
+				if (canDrop(ev, this)) {
+					// show that it can be dropped
+					ev.preventDefault();
+				}
+				// stop containers further out from capturing the event.
+				ev.stopPropagation();
+			};
+			element.ondrop = ev => {
+				ev.preventDefault();
+				// stop groups further out from capturing the event.
+				ev.stopPropagation();
+				const rulePart = rulePartMap.get(ev.dataTransfer.getData("text/plain"));
+				setChild(rulePart);
+				refreshEditor();
+			};
+		}
+
+		/**
+		 * @param {HTMLElement} container
+		 * @param {?RulePart} child
+		 * @param {(child:RulePart)=>void} setChild
+		 * @protected
+		 */
+		_conditionalDropLocation(container, child, setChild) {
+			if (child == null) {
+				const span = document.createElement("span");
+				span.classList.add("rule-drop-location");
+				this._allowDroppingOn(span, setChild);
+				container.append(span);
+			} else {
+				container.append(child.render());
+			}
+		}
+	}
+
+	class RulePartProvider extends RuleContainer {
+		/**
+		 * @param {()=>RulePart} partFactory
+		 */
+		constructor(partFactory) {
+			super();
+			this._partFactory = partFactory;
+		}
+
+		render() {
+			const part = this._partFactory();
+			part.parent = this;
+			part.showValidationError = false;
+			const element = part.render();
+			part.showValidationError = true;
+			return element;
+		}
+
+		/**
+		 * @returns {"error"}
+		 */
+		validate(errorList) {
+			return "error";
+		}
+
+		removeChild(rulePart) {
+		}
+
+		isParent(maybeChild) {
+			return false;
+		}
+	}
+
+	class RulePartTrash extends RuleContainer {
+		render() {
+			const div = document.createElement("div");
+			div.classList.add("rule-trash");
+			div.ondragover = ev => {
+				// show that it can be dropped
+				ev.preventDefault();
+				// stop groups further out from capturing the event.
+				ev.stopPropagation();
+			};
+			div.ondrop = ev => {
+				ev.preventDefault();
+				// stop groups further out from capturing the event.
+				ev.stopPropagation();
+				const rulePartID = ev.dataTransfer.getData("text/plain");
+				const rulePart = rulePartMap.get(rulePartID);
+				rulePart.parent.removeChild(rulePart);
+				refreshEditor();
+			};
+			return div;
+		}
+
+		/**
+		 * @returns {"error"}
+		 */
+		validate(errorList) {
+			return "error";
+		}
+
+		removeChild(rulePart) {
+		}
+
+		isParent(maybeChild) {
+			return false;
+		}
+	}
+
+	/**
+	 * @typedef {"and"|"or"|"add"|"mul"|"max"|"min"} RuleGroupAggregators
+	 * @type {Map<RuleGroupAggregators, string>}
+	 */
+	const ruleGroupAggregators = new Map([
+		["and", "And"],
+		["or", "Or"],
+		["add", "Sum all"],
+		["mul", "Multiply all"],
+		["max", "Maximum"],
+		["min", "Minimum"],
+	]);
+
+	class RuleGroup extends RuleContainer {
+		/**
+		 * @param {RuleGroupAggregators} mode
+		 */
+		constructor(mode) {
+			super();
+			this.mode = mode;
+			/**
+			 * @type {RulePart[]}
+			 * @private
+			 */
+			this._children = [];
+		}
+
+		render() {
+			const div = document.createElement("div");
+			div.classList.add("rule-part");
+			div.append(ruleGroupAggregators.get(this.mode));
+			const button = App.UI.DOM.appendNewElement("button", div, "<->");
+			button.onclick = () => {
+				if (this.mode === "and") {
+					this.mode = "or";
+				} else if (this.mode === "or") {
+					this.mode = "and";
+				} else if (this.mode === "add") {
+					this.mode = "mul";
+				} else if (this.mode === "mul") {
+					this.mode = "max";
+				} else if (this.mode === "max") {
+					this.mode = "min";
+				} else {
+					this.mode = "add";
+				}
+				refreshEditor();
+			};
+			for (const rulePart of this._children) {
+				div.append(rulePart.render());
+			}
+			let span = document.createElement("span");
+			span.classList.add("rule-drop-location");
+			div.append(span);
+			// interactions
+			this._allowDroppingOn(div, (child => this.addChild(child)));
+			if (this.parent !== null) {
+				// if null, it's the outermost and that can't be draggable
+				makeDraggable(div, this);
+				this._dragElement = div;
+			}
+			this._markValidationError(div);
+			return div;
+		}
+
+		validate(errorList) {
+			if (this._children.length === 0) {
+				errorList.push("Condition group needs at least 1 condition.");
+				return "error";
+			}
+			const expectedType = "number";
+			for (const rulePart of this.children) {
+				if (rulePart.validate(errorList) !== expectedType) {
+					errorList.push("Condition group only accepts boolean and number conditions.");
+					return "error";
+				}
+			}
+			return expectedType;
+		}
+
+		/**
+		 * @param {RulePart} rulePart
+		 */
+		addChild(rulePart) {
+			if (rulePart.parent != null) {
+				rulePart.parent.removeChild(rulePart);
+			}
+			this._children.push(rulePart);
+			rulePart.parent = this;
+		}
+
+		/**
+		 * @override
+		 * @param {RulePart} rulePart
+		 */
+		removeChild(rulePart) {
+			this._children.delete(rulePart);
+			rulePart.parent = null;
+		}
+
+		/**
+		 * @override
+		 * @param {RuleContainer} maybeChild
+		 */
+		isParent(maybeChild) {
+			for (const child of this._children) {
+				if (isSameOrParent(child, maybeChild)) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		/**
+		 * @returns {ReadonlyArray<RulePart>}
+		 */
+		get children() {
+			return this._children;
+		}
+	}
+
+	class RuleNegate extends RuleContainer {
+		constructor() {
+			super();
+			/**
+			 * @type {?RulePart}
+			 * @private
+			 */
+			this._child = null;
+		}
+
+		render() {
+			const div = document.createElement("div");
+			div.classList.add("rule-part");
+			div.append("Not");
+
+			if (this.child == null) {
+				let span = document.createElement("span");
+				span.classList.add("rule-drop-location");
+				div.append(span);
+				this._allowDroppingOn(div, child => this.child = child);
+			} else {
+				div.append(this.child.render());
+				div.ondragover = ev => {
+					// stop groups further out from capturing the event.
+					ev.stopPropagation();
+				};
+			}
+
+			makeDraggable(div, this);
+			this._dragElement = div;
+			this._markValidationError(div);
+
+			return div;
+		}
+
+		validate(errorList) {
+			if (this._child == null) {
+				errorList.push("Negation needs a condition to negate.");
+				return "error";
+			}
+			if (this._child.validate(errorList) === "number") {
+				return "number";
+			} else {
+				errorList.push("Negation accepts only boolean and number conditions.");
+				return "error";
+			}
+		}
+
+		/**
+		 * @param {RulePart} rulePart
+		 */
+		set child(rulePart) {
+			if (rulePart.parent != null) {
+				rulePart.parent.removeChild(rulePart);
+			}
+			this._child = rulePart;
+			rulePart.parent = this;
+		}
+
+		/**
+		 * @returns {RulePart}
+		 */
+		get child() {
+			return this._child;
+		}
+
+		/**
+		 * @override
+		 * @param {RulePart} rulePart
+		 */
+		removeChild(rulePart) {
+			this._child = null;
+			rulePart.parent = null;
+		}
+
+		/**
+		 * @override
+		 * @param {RuleContainer} maybeChild
+		 */
+		isParent(maybeChild) {
+			if (this._child == null) {
+				return false;
+			}
+			return (isSameOrParent(this._child, maybeChild));
+		}
+	}
+
+	/**
+	 * @typedef {"sub" | "div" | "eq" | "neq" | "gt" | "gte" | "lt" | "lte"| "substr"} RulePairComparators
+	 * @typedef {object} RulePairComparatorDisplay
+	 * @property {string} key
+	 * @property {string} name
+	 * @type {RulePairComparatorDisplay[]}
+	 */
+	const rulePairComparators = [
+		{key: "eq", name: "="},
+		{key: "neq", name: "≠"},
+		{key: "lt", name: "<"},
+		{key: "gt", name: ">"},
+		{key: "lte", name: "⩽"},
+		{key: "gte", name: "⩾"},
+		{key: "sub", name: "-"},
+		{key: "div", name: "/"},
+		{key: "substr", name: "Contains"},
+	];
+
+	class RulePair extends RuleContainer {
+		/**
+		 * @param {RulePairComparators} mode
+		 */
+		constructor(mode) {
+			super();
+			this.mode = mode;
+			/**
+			 * @type {RulePart}
+			 */
+			this._child1 = null;
+			/**
+			 * @type {RulePart}
+			 */
+			this._child2 = null;
+		}
+
+		render() {
+			const div = document.createElement("div");
+			div.classList.add("rule-part");
+			// drag element
+			makeNotDraggable(div);
+			div.append(createDragElement(this));
+			// element 1
+			this._conditionalDropLocation(div, this._child1, child => this.child1 = child);
+
+			// operator
+			div.append(App.UI.DOM.makeSelect(rulePairComparators, this.mode, mode => {
+				// @ts-ignore
+				this.mode = mode;
+				refreshEditor();
+			}));
+
+			// element 2
+			this._conditionalDropLocation(div, this._child2, child => this.child2 = child);
+
+			this._markValidationError(div);
+			return div;
+		}
+
+		validate(errorList) {
+			if (this._child1 == null || this._child2 == null) {
+				errorList.push("Comparator conditions need a condition on both sides.");
+				return "error";
+			}
+			if (this.mode === "eq" || this.mode === "neq") {
+				const expectedType = this._child1.validate(errorList);
+				if (expectedType === this._child2.validate(errorList)) {
+					return "number";
+				} else {
+					errorList.push("Both sides need to return the same type.");
+					return "error";
+				}
+			} else if (this.mode === "substr") {
+				if (this._child1.validate(errorList) === "string" && this._child2.validate(errorList) === "string") {
+					return "number";
+				} else {
+					errorList.push("Both sides need to return string.");
+					return "error";
+				}
+			} else {
+				if (this._child1.validate(errorList) === "number" && this._child2.validate(errorList) === "number") {
+					return "number";
+				} else {
+					errorList.push("Both sides need to return number.");
+					return "error";
+				}
+			}
+		}
+
+		/**
+		 * @param {RulePart} child
+		 */
+		set child1(child) {
+			if (child.parent != null) {
+				child.parent.removeChild(child);
+			}
+			child.parent = this;
+			this._child1 = child;
+		}
+
+		/**
+		 * @returns {RulePart}
+		 */
+		get child1() {
+			return this._child1;
+		}
+
+		/**
+		 * @param {RulePart} child
+		 */
+		set child2(child) {
+			if (child.parent != null) {
+				child.parent.removeChild(child);
+			}
+			child.parent = this;
+			this._child2 = child;
+		}
+
+		/**
+		 * @returns {RulePart}
+		 */
+		get child2() {
+			return this._child2;
+		}
+
+		/**
+		 * @override
+		 * @param {RulePart} rulePart
+		 */
+		removeChild(rulePart) {
+			if (this._child1 === rulePart) {
+				this._child1 = null;
+			} else if (this._child2 === rulePart) {
+				this._child2 = null;
+			}
+			rulePart.parent = null;
+		}
+
+		/**
+		 * @override
+		 * @param {RuleContainer} maybeChild
+		 */
+		isParent(maybeChild) {
+			return isSameOrParent(this._child1, maybeChild) || isSameOrParent(this._child2, maybeChild);
+		}
+	}
+
+	class RuleTernary extends RuleContainer {
+		constructor() {
+			super();
+			/**
+			 * @type {RulePart}
+			 */
+			this._condition = null;
+			/**
+			 * @type {RulePart}
+			 */
+			this._ifTrue = null;
+			/**
+			 * @type {RulePart}
+			 */
+			this._ifFalse = null;
+		}
+
+		render() {
+			const div = document.createElement("div");
+			div.classList.add("rule-part");
+			// drag element
+			makeDraggable(div, this);
+			div.append(createDragElement(this));
+
+			// condition
+			App.UI.DOM.appendNewElement("span", div, "If", ["rule-left-margin"]);
+			this._conditionalDropLocation(div, this.condition, child => this.condition = child);
+			// ifTrue
+			div.append("Then");
+			this._conditionalDropLocation(div, this.ifTrue, child => this.ifTrue = child);
+			// ifFalse
+			div.append("Else");
+			this._conditionalDropLocation(div, this.ifFalse, child => this.ifFalse = child);
+
+			this._markValidationError(div);
+			return div;
+		}
+
+		validate(errorList) {
+			if (this._condition === null) {
+				errorList.push("Ternaries need a condition.");
+				return "error";
+			}
+			if (this._condition.validate(errorList) !== "number") {
+				errorList.push("Ternaries conditions accepts only booleans or numbers.");
+				return "error";
+			}
+			if (this._ifTrue == null || this._ifFalse == null) {
+				errorList.push("Ternaries need values on both sides.");
+				return "error";
+			}
+			const expectedType = this._ifTrue.validate(errorList);
+			if (expectedType === this._ifFalse.validate(errorList)) {
+				return "number";
+			} else {
+				errorList.push("Both sides need to return the same type.");
+				return "error";
+			}
+		}
+
+		/**
+		 * @param {RulePart} child
+		 */
+		set condition(child) {
+			if (child.parent != null) {
+				child.parent.removeChild(child);
+			}
+			child.parent = this;
+			this._condition = child;
+		}
+
+		/**
+		 * @returns {RulePart}
+		 */
+		get condition() {
+			return this._condition;
+		}
+
+		/**
+		 * @param {RulePart} child
+		 */
+		set ifTrue(child) {
+			if (child.parent != null) {
+				child.parent.removeChild(child);
+			}
+			child.parent = this;
+			this._ifTrue = child;
+		}
+
+		/**
+		 * @returns {RulePart}
+		 */
+		get ifTrue() {
+			return this._ifTrue;
+		}
+
+		/**
+		 * @param {RulePart} child
+		 */
+		set ifFalse(child) {
+			if (child.parent != null) {
+				child.parent.removeChild(child);
+			}
+			child.parent = this;
+			this._ifFalse = child;
+		}
+
+		/**
+		 * @returns {RulePart}
+		 */
+		get ifFalse() {
+			return this._ifFalse;
+		}
+
+		/**
+		 * @override
+		 * @param {RulePart} rulePart
+		 */
+		removeChild(rulePart) {
+			if (this._condition === rulePart) {
+				this._condition = null;
+			} else if (this._ifTrue === rulePart) {
+				this._ifTrue = null;
+			} else if (this._ifFalse === rulePart) {
+				this._ifFalse = null;
+			}
+			rulePart.parent = null;
+		}
+
+		/**
+		 * @override
+		 * @param {RuleContainer} maybeChild
+		 */
+		isParent(maybeChild) {
+			return isSameOrParent(this._condition, maybeChild) ||
+				isSameOrParent(this._ifTrue, maybeChild) ||
+				isSameOrParent(this._ifFalse, maybeChild);
+		}
+	}
+
+	class RuleBooleanConstant extends RulePart {
+		/**
+		 * @param {boolean} mode
+		 */
+		constructor(mode) {
+			super();
+			this.mode = mode;
+		}
+
+		render() {
+			const b = App.UI.DOM.makeElement("button", this.mode ? "Always" : "Never", ["rule-part"]);
+			b.onclick = () => {
+				this.mode = !this.mode;
+				refreshEditor();
+			};
+			makeDraggable(b, this);
+			return b;
+		}
+
+		/**
+		 * @returns {"number"}
+		 */
+		validate() {
+			return "number";
+		}
+	}
+
+	class RuleConstant extends RulePart {
+		/**
+		 * @param {number|string} value
+		 */
+		constructor(value) {
+			super();
+			this.value = value;
+			this._stringMode = typeof value === "string";
+		}
+
+		render() {
+			const div = App.UI.DOM.makeElement("div", createDragElement(this), ["rule-part"]);
+			div.append(this._stringMode ? " String" : " Number");
+			div.append(makeTextBoxDragSafe(App.UI.DOM.makeTextBox(this.value, (v) => {
+				this.value = v;
+				refreshEditor();
+			}, !this._stringMode), this));
+			return div;
+		}
+
+		/**
+		 * @returns {"number"|"string"}
+		 */
+		validate() {
+			return this._stringMode ? "string" : "number";
+		}
+	}
+
+	class RuleMapCheck extends RulePart {
+		/**
+		 * @param {string} key
+		 */
+		constructor(key) {
+			super();
+			/**
+			 * @type {"boolean"|"assignment"|"number"|"string"}
+			 */
+			this.mode = App.RA.Activation.getterManager.isBoolean(key) ? "boolean"
+				: App.RA.Activation.getterManager.isAssignment(key) ? "assignment"
+					: App.RA.Activation.getterManager.isNumber(key) ? "number"
+						: "string";
+			this.key = key;
+		}
+
+		render() {
+			// make container
+			const span = document.createElement("span");
+			span.classList.add("rule-part");
+			makeDraggable(span, this);
+
+			// fill container
+			// name
+			App.UI.DOM.appendNewElement("span", span, this.mode === "assignment" ? "Assignment" : "Slave", ["rule-right-margin"]);
+
+			// values
+			/**
+			 * @type {selectOption[]}
+			 */
+			const options = [];
+			this._getterMap.forEach((getter, key) => {
+				if (!getter.visible || getter.visible()) {
+					options.push({
+						key: key, name: getter.name, enabled: !getter.enabled || getter.enabled()
+					});
+				}
+			});
+			span.append(App.UI.DOM.makeSelect(options, this.key, key => {
+				this.key = key;
+				refreshEditor();
+			}));
+			return span;
+		}
+
+		validate() {
+			if (this.mode === "boolean" || this.mode === "assignment") {
+				return "number";
+			}
+			return this.mode;
+		}
+
+		/**
+		 * @returns {ReadonlyMap<string, Getter<*>>}
+		 * @private
+		 */
+		get _getterMap() {
+			return this.mode === "boolean" ? App.RA.Activation.getterManager.booleanGetters
+				: this.mode === "assignment" ? App.RA.Activation.getterManager.assignmentGetters
+					: this.mode === "number" ? App.RA.Activation.getterManager.numberGetters
+						: App.RA.Activation.getterManager.stringGetters;
+		}
+	}
+
+	class RuleCustomCheck extends RulePart {
+		/**
+		 * @param {string} check
+		 */
+		constructor(check) {
+			super();
+			this.check = check;
+			/**
+			 * @type {"boolean"|"number"|"string"}
+			 * @private
+			 */
+			this._expectedType = check.first() === "b" ? "boolean"
+				: check.first() === "n" ? "number"
+					: "string";
+		}
+
+		render() {
+			const outerDiv = App.UI.DOM.makeElement("div", null, ["rule-part"]);
+			const leftDiv = document.createElement("div");
+			leftDiv.classList.add("rule-custom-controls");
+
+			const upperDiv = document.createElement("div");
+			upperDiv.append(createDragElement(this), " Custom Getter");
+			leftDiv.append(upperDiv);
+
+			const lowerDiv = document.createElement("div");
+			lowerDiv.classList.add("rule-custom-mode");
+			lowerDiv.append("Mode:", this._makeToggleButton());
+			leftDiv.append(lowerDiv);
+
+			outerDiv.append(leftDiv);
+
+			const textArea = document.createElement("textarea");
+			textArea.append(this.check.slice(1));
+			textArea.onchange = ev => {
+				// @ts-ignore
+				this.check = this._expectedType.first() + ev.target.value;
+				refreshEditor();
+			};
+			outerDiv.append(makeTextBoxDragSafe(textArea, this));
+			this._markValidationError(outerDiv);
+			return outerDiv;
+		}
+
+		_makeToggleButton() {
+			const button = document.createElement("button");
+			button.append(capFirstChar(this._expectedType));
+			button.onclick = () => {
+				if (this._expectedType === "boolean") {
+					this._expectedType = "number";
+				} else if (this._expectedType === "number") {
+					this._expectedType = "string";
+				} else {
+					this._expectedType = "boolean";
+				}
+				this.check = this._expectedType.first() + this.check.slice(1);
+				refreshEditor();
+			};
+			return button;
+		}
+
+		validate(errorList) {
+			try {
+				runWithReadonlyProxy(() => this._validateRule(this.check.slice(1)));
+			} catch (e) {
+				errorList.push(e.message + ".");
+				return "error";
+			}
+			return this._expectedType === "boolean" ? "number" : this._expectedType;
+		}
+
+		_validateRule(check) {
+			const slave = createReadonlyProxy(V.slaves[0]);
+			const context = new App.RA.Activation.Context(slave);
+			(new Function("c", `return (${check})(c)`))(context);
+			return true;
+		}
+	}
+
+	/**
+	 * @param {HTMLInputElement|HTMLTextAreaElement} textBox
+	 * @param {RulePart} rulePart
+	 * @returns {HTMLSpanElement}
+	 */
+	function makeTextBoxDragSafe(textBox, rulePart) {
+		textBox.onfocus = () => rulePart.disableDragging();
+		textBox.onmouseover = () => rulePart.disableDragging();
+		textBox.onblur = () => rulePart.enableDragging();
+		textBox.onmouseout = () => rulePart.enableDragging();
+		return textBox;
+	}
+
+	/**
+	 * @param {RulePart} rulePart
+	 */
+	function createDragElement(rulePart) {
+		const element = document.createElement("div");
+		element.classList.add("rule-drag-element");
+		makeDraggable(element, rulePart);
+		return element;
+	}
+
+	/**
+	 * @param {HTMLElement} node
+	 * @param {RulePart} rulePart
+	 */
+	function makeDraggable(node, rulePart) {
+		node.draggable = true;
+		node.classList.add("rule-draggable");
+		node.ondragstart = ev => {
+			ev.stopPropagation();
+			editorNode.classList.add("part-dragging");
+			ev.dataTransfer.setData("text/plain", rulePart.id);
+		};
+		node.ondragend = _ => {
+			editorNode.classList.remove("part-dragging");
+		};
+	}
+
+	/**
+	 * @param {HTMLElement} node
+	 */
+	function makeNotDraggable(node) {
+		node.ondragstart = ev => {
+			ev.stopPropagation();
+		};
+	}
+
+	/**
+	 * @param {DragEvent} event
+	 * @param {RuleContainer} targetPart
+	 * @returns {boolean}
+	 * @private
+	 */
+	function canDrop(event, targetPart) {
+		const movedPartID = event.dataTransfer.getData("text/plain");
+		const movedPart = rulePartMap.get(movedPartID);
+		// if it can't have children, any place is valid
+		if (!(movedPart instanceof RuleContainer)) {
+			return true;
+		}
+		// don't allow dragging onto itself
+		if (movedPart === targetPart) {
+			return false;
+		}
+		// don't allow dragging onto children
+		return !movedPart.isParent(targetPart);
+	}
+
+	/**
+	 * @param {RulePart} parent
+	 * @param {RuleContainer} maybeChild
+	 * @returns {boolean}
+	 */
+	function isSameOrParent(parent, maybeChild) {
+		if (parent === maybeChild) {
+			return true;
+		}
+		return (parent instanceof RuleContainer) && parent.isParent(maybeChild);
+	}
+
+	/**
+	 * @param {FC.RA.PostFixRule} rule
+	 * @returns {RuleGroup}
+	 */
+	function deserializeRule(rule) {
+		let stack = new RuleFactoryStack();
+
+		/**
+		 * @param {"and"|"or"|"add"|"mul"|"max"|"min"} mode
+		 */
+		function makeGroup(mode) {
+			const length = stack.popNumber();
+			const group = new RuleGroup(mode);
+			const children = [];
+			for (let i = 0; i < length; i++) {
+				children.unshift(stack.popRulePart());
+			}
+			for (const child of children) {
+				group.addChild(child);
+			}
+			stack.pushRulePart(group);
+		}
+
+		/**
+		 * @param {"sub" | "div" | "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "substr"} mode
+		 */
+		function makePair(mode) {
+			const pair = new RulePair(mode);
+			pair.child2 = stack.popRulePart();
+			pair.child1 = stack.popRulePart();
+			stack.pushRulePart(pair);
+		}
+
+		function makeTernary() {
+			const ternary = new RuleTernary();
+			ternary.ifFalse = stack.popRulePart();
+			ternary.ifTrue = stack.popRulePart();
+			ternary.condition = stack.popRulePart();
+			stack.pushRulePart(ternary);
+		}
+
+		/**
+		 * @type {Map<string, function(): void>}
+		 */
+		const operators = new Map([
+			// and, or, +, * can take arbitrarily many arguments, so the first one describes the argument count
+			["and", () => makeGroup("and")],
+			["or", () => makeGroup("or")],
+			["add", () => makeGroup("add")],
+			["mul", () => makeGroup("mul")],
+			["max", () => makeGroup("max")],
+			["min", () => makeGroup("min")],
+			["sub", () => makePair("sub")],
+			["div", () => makePair("div")],
+			["eqstr", () => makePair("eq")],
+			["neqstr", () => makePair("neq")],
+			["eqnum", () => makePair("eq")],
+			["neqnum", () => makePair("neq")],
+			["gt", () => makePair("gt")],
+			["gte", () => makePair("gte")],
+			["lt", () => makePair("lt")],
+			["lte", () => makePair("lte")],
+			["substr", () => makePair("substr")],
+			["not", () => {
+				const negate = new RuleNegate();
+				negate.child = stack.popRulePart();
+				stack.pushRulePart(negate);
+			}],
+			["ternarystr", makeTernary],
+			["ternarynum", makeTernary],
+		]);
+
+		for (let i = 0; i < rule.length; i++) {
+			const rulePart = rule[i];
+			if (typeof rulePart === "string") {
+				const operation = operators.get(rulePart);
+				if (operation !== undefined) {
+					operation();
+				} else if (App.RA.Activation.getterManager.has(rulePart)) {
+					stack.pushRulePart(new RuleMapCheck(rulePart));
+				} else if (rulePart.startsWith("?")) {
+					stack.pushRulePart(new RuleCustomCheck(rulePart.slice(1)));
+				} else {
+					stack.pushRulePart(new RuleConstant(rulePart.slice(1)));
+				}
+			} else if (typeof rulePart === "number") {
+				// check if this is a length counter
+				const next = rule[i + 1];
+				if (["and", "or", "add", "mul"].includes(next)) {
+					stack.pushNumber(rulePart);
+				} else {
+					stack.pushRulePart(new RuleConstant(rulePart));
+				}
+			} else {
+				stack.pushRulePart(new RuleBooleanConstant(rulePart));
+			}
+		}
+
+		// @ts-ignore
+		return stack.popRulePart();
+	}
+
+	/**
+	 * Expects a valid RulePart structure
+	 *
+	 * @param {RuleGroup} rulePart
+	 * @returns {FC.RA.PostFixRule}
+	 */
+	function serializeRule(rulePart) {
+		/**
+		 * @type {FC.RA.PostFixRule}
+		 */
+		const rule = [];
+		_serializeRulePart(rulePart);
+		return rule;
+
+		/**
+		 * @param {RulePart} rulePart
+		 */
+		function _serializeRulePart(rulePart) {
+			if (rulePart instanceof RuleGroup) {
+				for (const ruleChild of rulePart.children) {
+					_serializeRulePart(ruleChild);
+				}
+				rule.push(rulePart.children.length, rulePart.mode);
+			} else if (rulePart instanceof RulePair) {
+				_serializeRulePart(rulePart.child1);
+				_serializeRulePart(rulePart.child2);
+				let mode = rulePart.mode;
+				if (rulePart.mode === "eq" || rulePart.mode === "neq") {
+					if (rulePart.child1.validate([]) === "string") {
+						mode += "str";
+					} else {
+						mode += "num";
+					}
+				}
+				rule.push(mode);
+			} else if (rulePart instanceof RuleBooleanConstant) {
+				rule.push(rulePart.mode);
+			} else if (rulePart instanceof RuleMapCheck) {
+				rule.push(rulePart.key);
+			} else if (rulePart instanceof RuleConstant) {
+				rule.push(typeof rulePart.value === "string" ? "!" + rulePart.value : rulePart.value);
+			} else if (rulePart instanceof RuleNegate) {
+				_serializeRulePart(rulePart.child);
+				rule.push("not");
+			} else if (rulePart instanceof RuleTernary) {
+				_serializeRulePart(rulePart.condition);
+				_serializeRulePart(rulePart.ifTrue);
+				_serializeRulePart(rulePart.ifFalse);
+				let mode = "ternary";
+				if (rulePart.ifTrue.validate([]) === "string") {
+					mode += "str";
+				} else {
+					mode += "num";
+				}
+				rule.push(mode);
+			} else if (rulePart instanceof RuleCustomCheck) {
+				rule.push("?" + rulePart.check);
+			}
+		}
+	}
+
+	class RuleFactoryStack extends App.RA.Activation.Stack {
+		constructor() {
+			super();
+			/**
+			 * @private
+			 * @type {RulePart[]}
+			 */
+			this._ruleParts = [];
+		}
+
+		/**
+		 * @param {RulePart} v
+		 */
+		pushRulePart(v) {
+			this._ruleParts.push(v);
+		}
+
+		/**
+		 * @returns {RulePart}
+		 */
+		popRulePart() {
+			return this._ruleParts.pop();
+		}
+	}
+
+	/**
+	 * @param {FC.RA.PostFixRule} rule
+	 */
+	function validate(rule) {
+		let mapExists = rulePartMap !== null;
+		if (!mapExists) {
+			rulePartMap = new Map();
+		}
+		const rulePart = deserializeRule(rule);
+		if (!(rulePart instanceof RuleGroup)) {
+			console.log("validation error", rule, rulePart, "Outermost is not RuleGroup!");
+		}
+		if (rulePart.mode !== "and" && rulePart.mode !== "or") {
+			console.log("validation error", rule, rulePart, "Outermost has to be \"and\" or \"or\" mode RuleGroup!");
+		}
+		const errors = [];
+		const result = rulePart.validate(errors);
+		if (result === "error") {
+			console.log("validation error", rule, rulePart, errors);
+		}
+		if (!mapExists) {
+			rulePartMap = null;
+		}
+		return result !== "error";
+	}
+
+	return {
+		build: editor,
+		save: saveEditor,
+		reset: resetEditor,
+		validateRule: validate,
+	};
+})();
diff --git a/js/rulesAssistant/conditionEvaluation.js b/js/rulesAssistant/conditionEvaluation.js
new file mode 100644
index 0000000000000000000000000000000000000000..3b4e493d3be02e445383bb638640abe472965337
--- /dev/null
+++ b/js/rulesAssistant/conditionEvaluation.js
@@ -0,0 +1,812 @@
+/* eslint-disable sonarjs/no-identical-expressions */
+
+App.RA.Activation.Context = class {
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	constructor(slave) {
+		this._slave = slave;
+	}
+
+	get slave() {
+		return this._slave;
+	}
+};
+
+/**
+ * @template {boolean|number|string} T
+ * @typedef {object} Getter
+ * @property {string} name
+ * @property {string} description Should include possible values if applicable.
+ * @property {string} [requirements] Plaintext description of requirements to use this getter.
+ * @property {()=>boolean} [enabled] Whether the getter can be used.
+ * @property {()=>boolean} [visible] Whether the getter should be shown. Mainly intended for disabled mods.
+ * @property {(s: App.RA.Activation.Context) =>T} val
+ */
+
+App.RA.Activation.getterManager = (function() {
+	class GetterManager {
+		constructor() {
+			/**
+			 * @private
+			 * @type {Map<string, Getter<boolean>>}
+			 */
+			this._booleanGetters = new Map();
+			/**
+			 * @private
+			 * @type {Map<string, Getter<boolean>>}
+			 */
+			this._assignmentGetters = new Map();
+			/**
+			 * @private
+			 * @type {Map<string, Getter<number>>}
+			 */
+			this._numberGetters = new Map();
+			/**
+			 * @private
+			 * @type {Map<string, Getter<string>>}
+			 */
+			this._stringGetters = new Map();
+		}
+
+		/**
+		 * @param {string} key
+		 * @private
+		 */
+		_validateKey(key) {
+			if (!/[a-zA-Z]/.test(key.first())) {
+				throw new Error(`Invalid Key: ${key}; The first character of a getter key has to be alphabetic`);
+			}
+		}
+
+		/**
+		 * @param {string} key
+		 * @param {Getter<boolean>} getter
+		 */
+		addBoolean(key, getter) {
+			this._validateKey(key);
+			this._booleanGetters.set(key, getter);
+		}
+
+		/**
+		 * @param {string} key
+		 * @param {Getter<boolean>} getter
+		 */
+		addAssignment(key, getter) {
+			this._validateKey(key);
+			this._assignmentGetters.set(key, getter);
+		}
+
+		/**
+		 * @param {string} key
+		 * @param {Getter<number>} getter
+		 */
+		addNumber(key, getter) {
+			this._validateKey(key);
+			this._numberGetters.set(key, getter);
+		}
+
+		/**
+		 * @param {string} key
+		 * @param {Getter<string>} getter
+		 */
+		addString(key, getter) {
+			this._validateKey(key);
+			this._stringGetters.set(key, getter);
+		}
+
+		/**
+		 * @param {string} key
+		 * @returns {boolean}
+		 */
+		has(key) {
+			return this._booleanGetters.has(key) || this._assignmentGetters.has(key) ||
+				this._numberGetters.has(key) || this._stringGetters.has(key);
+		}
+
+		/**
+		 * @param {string} key
+		 * @returns {boolean}
+		 */
+		isBoolean(key) {
+			return this._booleanGetters.has(key);
+		}
+
+		/**
+		 * @param {string} key
+		 * @returns {boolean}
+		 */
+		isAssignment(key) {
+			return this._assignmentGetters.has(key);
+		}
+
+		/**
+		 * @param {string} key
+		 * @returns {boolean}
+		 */
+		isNumber(key) {
+			return this._numberGetters.has(key);
+		}
+
+		/**
+		 * @param {string} key
+		 * @returns {boolean}
+		 */
+		isString(key) {
+			return this._stringGetters.has(key);
+		}
+
+		/**
+		 * @returns {ReadonlyMap<string, Getter<boolean>>}
+		 */
+		get booleanGetters() {
+			return this._booleanGetters;
+		}
+
+		/**
+		 * @returns {ReadonlyMap<string, Getter<boolean>>}
+		 */
+		get assignmentGetters() {
+			return this._assignmentGetters;
+		}
+
+		/**
+		 * @returns {ReadonlyMap<string, Getter<number>>}
+		 */
+		get numberGetters() {
+			return this._numberGetters;
+		}
+
+		/**
+		 * @returns {ReadonlyMap<string, Getter<string>>}
+		 */
+		get stringGetters() {
+			return this._stringGetters;
+		}
+
+		/**
+		 * @returns {string}
+		 */
+		get booleanDefault() {
+			return this._booleanGetters.keys().next().value;
+		}
+
+		/**
+		 * @returns {string}
+		 */
+		get assignmentDefault() {
+			return this._assignmentGetters.keys().next().value;
+		}
+
+		/**
+		 * @returns {string}
+		 */
+		get numberDefault() {
+			return this._numberGetters.keys().next().value;
+		}
+
+		/**
+		 * @returns {string}
+		 */
+		get stringDefault() {
+			return this._stringGetters.keys().next().value;
+		}
+
+		/**
+		 * @param {App.RA.Activation.Stack} stack
+		 * @param {App.RA.Activation.Context} context
+		 * @param {string} key
+		 * @returns {boolean} True, if a getter exists for the given key
+		 */
+		read(stack, context, key) {
+			let getterB = this._booleanGetters.get(key);
+			if (getterB !== undefined) {
+				stack.pushBoolean(getterB.val(context));
+				return true;
+			}
+			getterB = this._assignmentGetters.get(key);
+			if (getterB !== undefined) {
+				stack.pushBoolean(getterB.val(context));
+				return true;
+			}
+			const getterN = this._numberGetters.get(key);
+			if (getterN !== undefined) {
+				stack.pushNumber(getterN.val(context));
+				return true;
+			}
+			const getterS = this._stringGetters.get(key);
+			if (getterS !== undefined) {
+				stack.pushString(getterS.val(context));
+				return true;
+			}
+			return false;
+		}
+	}
+
+	return new GetterManager();
+})();
+
+App.RA.Activation.populateGetters = function() {
+	const gm = App.RA.Activation.getterManager;
+	// Note: The first value of each type being added is taken as the default.
+
+	// Booleans
+	gm.addBoolean("isfertile", {
+		name: "Is Fertile?", description: "Whether or not the slave is fertile.",
+		val: c => isFertile(c.slave)
+	});
+	gm.addBoolean("isamputee", {
+		name: "Is Amputee?", description: "Whether or not the slave has no limbs.",
+		val: c => isAmputee(c.slave)
+	});
+	gm.addBoolean("ispregnant", {
+		name: "Is Pregnant?", description: "Whether or not the slave is pregnant.",
+		val: c => c.slave.preg > 0
+	});
+	gm.addBoolean("isslim", {
+		name: "Is Slim?", description: "If the slave is considered slim or not by arcology standards.",
+		val: c => isSlim(c.slave)
+	});
+	gm.addBoolean("isstacked", {
+		name: "Is Stacked?", description: "If the slave is considered stacked (big T&A) or not.",
+		val: c => isStacked(c.slave)
+	});
+	gm.addBoolean("ismodded", {
+		name: "Is Modded?", description: "If the slave is considered heavily modded or not.",
+		val: c => SlaveStatsChecker.isModded(c.slave)
+	});
+	gm.addBoolean("isunmodded", {
+		name: "Is Unmodded?", description: "If the slave is (relatively) unmodded.",
+		val: c => SlaveStatsChecker.isModded(c.slave)
+	});
+	gm.addBoolean("canmove", {
+		name: "Can Move?", description: "Can the slave move at all?",
+		val: c => canMove(c.slave)
+	});
+	gm.addBoolean("canstand", {
+		name: "Can Stand?", description: "Can the slave stand independently?",
+		val: c => canStand(c.slave)
+	});
+	gm.addBoolean("canwalk", {
+		name: "Can Walk?", description: "Can the slave walk independently; if they can, they can move and stand too.",
+		val: c => canWalk(c.slave)
+	});
+	gm.addBoolean("hasinternalballs", {
+		name: "Has Internal Balls?", description: "If the slaves has internal balls. False, if the slave has no balls",
+		val: c => c.slave.balls > 0 && c.slave.scrotum === 0
+	});
+
+	// Assignments
+	// Penthouse Assignments
+	gm.addAssignment("rest", {
+		name: "Resting", description: "Resting in the penthouse.",
+		val: c => c.slave.assignment === Job.REST
+	});
+	gm.addAssignment("fucktoy", {
+		name: "Fucktoy", description: "Pleasing the master.",
+		val: c => c.slave.assignment === Job.FUCKTOY
+	});
+	gm.addAssignment("classes", {
+		name: "Taking classes", description: "Taking classes to better serve.",
+		val: c => c.slave.assignment === Job.CLASSES
+	});
+	gm.addAssignment("house", {
+		name: "Cleaning", description: "Cleaning the penthouse.",
+		val: c => c.slave.assignment === Job.HOUSE
+	});
+	gm.addAssignment("whore", {
+		name: "Whoring", description: "Whoring themself out.",
+		val: c => c.slave.assignment === Job.WHORE
+	});
+	gm.addAssignment("public", {
+		name: "Serving public", description: "Serving the public.",
+		val: c => c.slave.assignment === Job.PUBLIC
+	});
+	gm.addAssignment("subordinate", {
+		name: "Subordinate", description: "Subordinate to other slaves.",
+		val: c => c.slave.assignment === Job.SUBORDINATE
+	});
+	gm.addAssignment("milked", {
+		name: "Milked", description: "Getting milked.",
+		val: c => c.slave.assignment === Job.MILKED
+	});
+	gm.addAssignment("gloryhole", {
+		name: "Glory hole", description: "Working as a glory hole.",
+		val: c => c.slave.assignment === Job.GLORYHOLE
+	});
+	gm.addAssignment("confinement", {
+		name: "Confined", description: "Confined at the penthouse.",
+		val: c => c.slave.assignment === Job.CONFINEMENT
+	});
+	gm.addAssignment("choice", {
+		name: "Choose own", description: "Allowed to choose their own job.",
+		val: c => c.slave.assignment === Job.CHOICE
+	});
+	// Leadership Assignments
+	gm.addAssignment("bodyguard", {
+		name: "Bodyguard", description: "Serving as Bodyguard.",
+		requirements: "Armory is built.", enabled: () => App.Entity.facilities.armory.established,
+		val: c => c.slave.assignment === Job.BODYGUARD
+	});
+	gm.addAssignment("headgirl", {
+		name: "Head Girl", description: "Serving as Head Girl",
+		val: c => c.slave.assignment === Job.HEADGIRL
+	});
+	gm.addAssignment("recruiter", {
+		name: "Recruiter", description: "Recruiting new slaves.",
+		val: c => c.slave.assignment === Job.RECRUITER
+	});
+	gm.addAssignment("agent", {
+		name: "Agent", description: "Serving as an Agent in another arcology.",
+		val: c => c.slave.assignment === Job.AGENT
+	});
+	gm.addAssignment("agentpartner", {
+		name: "Agent partner", description: "Serving an agent living in another arcology.",
+		val: c => c.slave.assignment === Job.AGENTPARTNER
+	});
+	// Facility Assignments
+	gm.addAssignment("arcade", {
+		name: "Confined in arcade", description: "Confined in the arcade.",
+		requirements: "Arcade is built.", enabled: ()=>App.Entity.facilities.arcade.established,
+		val: c => c.slave.assignment === Job.ARCADE
+	});
+	gm.addAssignment("madam", {
+		name: "Madam", description: "Serving as Madam.",
+		requirements: "Brothel is built.", enabled: ()=>App.Entity.facilities.brothel.established,
+		val: c => c.slave.assignment === Job.MADAM
+	});
+	gm.addAssignment("brothel", {
+		name: "Brothel whoring?", description: "Working in the brothel.",
+		requirements: "Brothel is built.", enabled: ()=>App.Entity.facilities.brothel.established,
+		val: c => c.slave.assignment === Job.BROTHEL
+	});
+	gm.addAssignment("warden", {
+		name: "Wardeness", description: "Serving as Wardeness.",
+		requirements: "Cellblock is built.", enabled: ()=>App.Entity.facilities.cellblock.established,
+		val: c => c.slave.assignment === Job.WARDEN
+	});
+	gm.addAssignment("cellblock", {
+		name: "Confined in cellblock?", description: "Confined in the cellblock.",
+		requirements: "Cellblock is built.", enabled: ()=>App.Entity.facilities.cellblock.established,
+		val: c => c.slave.assignment === Job.CELLBLOCK
+	});
+	gm.addAssignment("dj", {
+		name: "DJ", description: "Serving as DJ.",
+		requirements: "Club is built.", enabled: ()=>App.Entity.facilities.club.established,
+		val: c => c.slave.assignment === Job.DJ
+	});
+	gm.addAssignment("club", {
+		name: "Serving club", description: "Serving in the club.",
+		requirements: "Club is built.", enabled: ()=>App.Entity.facilities.club.established,
+		val: c => c.slave.assignment === Job.CLUB
+	});
+	gm.addAssignment("nurse", {
+		name: "Nurse", description: "Serving as Nurse.",
+		requirements: "Clinic is built.", enabled: ()=>App.Entity.facilities.clinic.established,
+		val: c => c.slave.assignment === Job.NURSE
+	});
+	gm.addAssignment("clinic", {
+		name: "Getting treatment", description: "Getting treatment in the clinic.",
+		requirements: "Clinic is built.", enabled: ()=>App.Entity.facilities.clinic.established,
+		val: c => c.slave.assignment === Job.CLINIC
+	});
+	gm.addAssignment("milkmaid", {
+		name: "Milkmaid", description: "Serving as Milkmaid",
+		requirements: "Dairy is built.", enabled: ()=>App.Entity.facilities.dairy.established,
+		val: c => c.slave.assignment === Job.MILKMAID
+	});
+	gm.addAssignment("dairy", {
+		name: "Work dairy", description: "Working in the dairy",
+		requirements: "Dairy is built.", enabled: ()=>App.Entity.facilities.dairy.established,
+		val: c => c.slave.assignment === Job.DAIRY
+	});
+	gm.addAssignment("farmer", {
+		name: "Farmer", description: "Serving as Farmer",
+		requirements: "Farmyard is built.", enabled: ()=>App.Entity.facilities.farmyard.established,
+		val: c => c.slave.assignment === Job.FARMER
+	});
+	gm.addAssignment("farmyard", {
+		name: "Farmhand", description: "Working as a farmhand.",
+		requirements: "Farmyard is built.", enabled: ()=>App.Entity.facilities.farmyard.established,
+		val: c => c.slave.assignment === Job.FARMYARD
+	});
+	gm.addAssignment("headgirlsuite", {
+		name: "Head Girl Servant", description: "Living with the Head Girl.",
+		requirements: "Head Girl Suite is built.", enabled: ()=>App.Entity.facilities.headGirlSuite.established,
+		val: c => c.slave.assignment === Job.HEADGIRLSUITE
+	});
+	gm.addAssignment("concubine", {
+		name: "Concubine", description: "Serving as Concubine.",
+		requirements: "Master suite is built.", enabled: ()=>App.Entity.facilities.masterSuite.established,
+		val: c => c.slave.assignment === Job.CONCUBINE
+	});
+	gm.addAssignment("mastersuite", {
+		name: "Master suite servant", description: "Serving in the master suite.",
+		requirements: "Master suite is built.", enabled: ()=>App.Entity.facilities.masterSuite.established,
+		val: c => c.slave.assignment === Job.MASTERSUITE
+	});
+	gm.addAssignment("matron", {
+		name: "Matron", description: "Serving as Matron.",
+		requirements: "Nursery is built.", enabled: ()=>App.Entity.facilities.nursery.established,
+		visible: () => V.experimental.nursery > 0,
+		val: c => c.slave.assignment === Job.MATRON
+	});
+	gm.addAssignment("nursery", {
+		name: "Nanny", description: "Working as a nanny.",
+		requirements: "Nursery is built.", enabled: ()=>App.Entity.facilities.nursery.established,
+		visible: () => V.experimental.nursery > 0,
+		val: c => c.slave.assignment === Job.NURSERY
+	});
+	gm.addAssignment("teacher", {
+		name: "Schoolteacher", description: "Serving as Schoolteacher.",
+		requirements: "Schoolroom is built.", enabled: ()=>App.Entity.facilities.schoolroom.established,
+		val: c => c.slave.assignment === Job.TEACHER
+	});
+	gm.addAssignment("school", {
+		name: "Learning", description: "Learning in the schoolroom.",
+		requirements: "Schoolroom is built.", enabled: ()=>App.Entity.facilities.schoolroom.established,
+		val: c => c.slave.assignment === Job.SCHOOL
+	});
+	gm.addAssignment("steward", {
+		name: "Stewardess", description: "Serving as Stewardess.",
+		requirements: "Servants Quarters are built.",
+		enabled: ()=>App.Entity.facilities.servantsQuarters.established,
+		val: c => c.slave.assignment === Job.STEWARD
+	});
+	gm.addAssignment("quarter", {
+		name: "Servant", description: "Working as a servant in the Servants Quarters.",
+		requirements: "Servants Quarters are built.",
+		enabled: ()=>App.Entity.facilities.servantsQuarters.established,
+		val: c => c.slave.assignment === Job.QUARTER
+	});
+	gm.addAssignment("attendant", {
+		name: "Attendant", description: "Serving as Attendant.",
+		requirements: "Spa is built.", enabled: ()=>App.Entity.facilities.spa.established,
+		val: c => c.slave.assignment === Job.ATTENDANT
+	});
+	gm.addAssignment("spa", {
+		name: "Spa resting", description: "Resting in the spa.",
+		requirements: "Spa is built.", enabled: () => App.Entity.facilities.spa.established,
+		val: c => c.slave.assignment === Job.SPA
+	});
+
+	// Numbers
+	gm.addNumber("devotion", {
+		name: "Devotion",
+		description: "Very Hateful: (-∞, -95), Hateful: [-95, -50), Resistant: [-50, -20), Ambivalent: [-20, 20], " +
+			"Accepting: (20, 50], Devoted: (50, 95], Worshipful: (95, ∞)",
+		val: c => c.slave.devotion
+	});
+	gm.addNumber("trust", {
+		name: "Trust",
+		description: "Extremely terrified: (-∞, -95), Terrified: [-95, -50), Frightened: [-50, -20), " +
+			"Fearful: [-20, 20], Careful: (20, 50], Trusting: (50, 95], Total trust: (95, ∞)",
+		val: c => c.slave.trust
+	});
+	gm.addNumber("health", {
+		name: "Health",
+		description: "Death: (-∞, -100), Near Death: [-100, -90), Extremely Unhealthy: [-90, -50), " +
+			"Unhealthy: [-50, -20), Healthy: [-20, 20], Very Healthy: (20, 50], Extremely Healthy: (50, 90], " +
+			"Unnaturally Healthy: (90, ∞)",
+		val: c => c.slave.health.condition
+	});
+	gm.addNumber("fatigue", {
+		name: "Fatigue",
+		description: "Energetic: (-∞, 0], Rested: (0, 30], Tired: (30, 60], Fatigued: (60, 90], Exhausted: (90, ∞)",
+		val: c => c.slave.health.tired
+	});
+	gm.addNumber("illness", {
+		name: "Illness",
+		description: "0: Not ill, 1: A little under the weather, 2: Slightly ill, can be treated at the clinic, " +
+			"3: Ill, can be treated at the clinic, 4: Very ill, can be treated at the clinic, " +
+			"5: Terribly ill, can be treated at the clinic",
+		val: c => c.slave.health.illness
+	});
+	gm.addNumber("energy", {
+		name: "Sex drive",
+		description: "Frigid: (-∞, 20], Poor: (20, 40], Average: (40, 60], Powerful: (60, 80], " +
+			"Sex Addict: (80, 100), Nympho: 100",
+		val: c => c.slave.energy
+	});
+	gm.addNumber("weight", {
+		name: "Weight",
+		description: "Emaciated: (-∞, -95), Skinny: [-95, -30), Thin: [-30, -10), Average: [-10, 10], " +
+			"Plush: (10, 30], Overweight: (30, 95], Fat: (95, 130], Obese: (130, 160], Super Obese: (160, 190], " +
+			"Dangerously Obese: (190, ∞)",
+		val: c => c.slave.weight
+	});
+	gm.addNumber("height", {name: "Height", description: "Slave height in cm.", val: c => c.slave.height});
+	gm.addNumber("age", {name: "Age", description: "Real slave age", val: c => c.slave.actualAge});
+	gm.addNumber("physicalAge", {
+		name: "Body Age", description: "Age of the slave's body.",
+		val: c => c.slave.physicalAge
+	});
+	gm.addNumber("visualAge", {
+		name: "Visible Age", description: "How old the slave looks.",
+		val: c => c.slave.visualAge
+	});
+	gm.addNumber("muscles", {
+		name: "Muscles",
+		description: "Frail: (-∞, -96), Very weak: [-96, -31], Weak: [-31, -6), Soft: [-6, 5), Toned: [5, 30), " +
+			"Fit: [30, 50), Muscular: [50, 95), Hugely muscular: [95, ∞)",
+		val: c => c.slave.muscles
+	});
+	gm.addNumber("lactation", {
+		name: "Lactation", description: "0: None, 1: Natural, 2: Lactation implant",
+		val: c => c.slave.lactation
+	});
+	gm.addNumber("pregType", {
+		name: "Pregnancy Multiples", description: "Fetus count, known only after the 10th week of pregnancy",
+		val: c => c.slave.pregType
+	});
+	gm.addNumber("bellyImplant", {
+		name: "Belly Implant", description: "Volume in CCs. None: -1",
+		val: c => c.slave.bellyImplant
+	});
+	gm.addNumber("belly", {
+		name: "Belly Size", description: "Volume in CCs, any source",
+		val: c => c.slave.belly
+	});
+	gm.addNumber("intelligenceImplant", {
+		name: "Education",
+		description: "Education level. 0: uneducated, 15: educated, 30: advanced education, " +
+			"(0, 15): incomplete education.",
+		val: c => c.slave.intelligenceImplant
+	});
+	gm.addNumber("intelligence", {
+		name: "Intelligence", description: "From moronic to brilliant: [-100, 100]",
+		val: c => c.slave.intelligence
+	});
+	gm.addNumber("face", {
+		name: "Face", description: "Very Ugly: (-∞, -96), Ugly: [-96, -40), Unattractive: [-40, -10), " +
+			"Average: [-10, 10), Attractive: [10, 40), Beautiful: [40, 95), Very beautiful: [95, ∞)",
+		val: c => c.slave.face
+	});
+	gm.addNumber("beautyscore", {
+		name: "Beauty Score", description: "As seen in the slave description",
+		val: c => Beauty(c.slave)
+	});
+	gm.addNumber("sexscore", {
+		name: "Sexual Score", description: "As seen in the slave description",
+		val: c => FResult(c.slave)
+	});
+	gm.addNumber("accent", {
+		name: "Accent", description: "No accent: 0, Nice accent: 1, Bad accent: 2, Can't speak language: 3 and above",
+		val: c => c.slave.accent
+	});
+	gm.addNumber("waist", {
+		name: "Waist",
+		description: "Masculine waist: (95, ∞), Ugly waist: (40, 95], Unattractive waist: (10, 40], " +
+			"Average waist: [-10, 10], Feminine waist: [-40, -10), Wasp waist: [-95, -40), Absurdly narrow: (-∞, -95)",
+		val: c => c.slave.waist
+	});
+	gm.addNumber("chem", {
+		name: "Carcinogen Buildup",
+		description: "Side effects from drug use. If greater than 10 will have negative consequences.",
+		val: c => c.slave.chem
+	});
+	gm.addNumber("boobs", {
+		name: "Breasts",
+		description: "0-299: Flat, 300-399: A-cup, 400-499: B-cup, 500-649: C-cup, 650-799: D-cup, 00-999: DD-cup, " +
+			"1000-1199: F-cup, 1200-1399: G-cup, 1400-1599: H-cup, 1600-1799: I-cup, 1800-2049: J-cup, " +
+			"2050-2299: K-cup, 2300-2599: L-cup, 2600-2899: M-cup, 2900-3249: N-cup, 3250-3599: O-cup, " +
+			"3600-3949: P-cup, 3950-4299: Q-cup, 4300-4699: R-cup, 4700-5099: S-cup, 5100-10499: Massive",
+		val: c => c.slave.boobs
+	});
+	gm.addNumber("dick", {
+		name: "Dick",
+		description: "None: 0, Tiny: 1, Little: 2, Normal: 3, Big: 4, Huge: 5, Gigantic: 6, Massive: 7, Titanic: 8, " +
+			"Monstrous: 9, Inhuman: 10, Hypertrophied: 11+",
+		val: c => c.slave.dick
+	});
+	gm.addNumber("balls", {
+		name: "Balls",
+		description: "None: 0, Vestigial: 1, Small: 2, Average: 3, Large: 4, Massive: 5, Huge: 6, Gigantic: 7, " +
+			"Enormous: 8, Monstrous: 9, Hypertrophied: 11+",
+		val: c => c.slave.balls
+	});
+	gm.addNumber("lips", {
+		name: "Lips",
+		description: "Thin: (-∞, 10), Normal: [10, 20), Pretty: [20, 40), Plush: [40, 70), Huge (lisping): [70, 95), " +
+			"Facepussy (mute): [95, ∞)",
+		val: c => c.slave.lips
+	});
+	gm.addNumber("butt", {
+		name: "Butt",
+		description: "Flat: 0, Less flat: 1, Small: 2, Big: 3, Large: 4, Huge: 5, Enormous: 6, Gigantic: 7, " +
+			"Ridiculous: 8, Immense: 9-10, Inhuman: 11-20",
+		val: c => c.slave.butt
+	});
+	gm.addNumber("hips", {
+		name: "Hips",
+		description: "Very narrow: -2, Narrow: -1, Normal: 0, Wide hips: 1, Very wide hips: 2, Inhumanly wide hips: 3",
+		val: c => c.slave.hips
+	});
+	gm.addNumber("oralskill", {
+		name: "Oral Skill",
+		description: "Unskilled: (-∞, 10), Basic: [10, 30), Skilled: [30, 60), Expert: [60, 99), Master: [99, ∞)",
+		val: c => c.slave.skill.oral
+	});
+	gm.addNumber("analskill", {
+		name: "Anal Skill",
+		description: "Unskilled: (-∞, 10), Basic: [10, 30), Skilled: [30, 60), Expert: [60, 99), Master: [99, ∞)",
+		val: c => c.slave.skill.anal
+	});
+	gm.addNumber("vaginalskill", {
+		name: "Vaginal Skill",
+		description: "Unskilled: (-∞, 10), Basic: [10, 30), Skilled: [30, 60), Expert: [60, 99), Master: [99, ∞)",
+		val: c => c.slave.skill.vaginal
+	});
+	gm.addNumber("whoringskill", {
+		name: "Whoring Skill",
+		description: "Unskilled: (-∞, 10), Basic: [10, 30), Skilled: [30, 60), Expert: [60, 99), Master: [99, ∞)",
+		val: c => c.slave.skill.whoring
+	});
+	gm.addNumber("entertainmentskill", {
+		name: "Entertainment Skill",
+		description: "Unskilled: (-∞, 10), Basic: [10, 30), Skilled: [30, 60), Expert: [60, 99), Master: [99, ∞)",
+		val: c => c.slave.skill.entertainment
+	});
+	gm.addNumber("combatskill", {
+		name: "Combat Skill",
+		description: "Unskilled: (-∞, 10), Basic: [10, 30), Skilled: [30, 60), Expert: [60, 99), Master: [99, ∞)",
+		val: c => c.slave.skill.combat
+	});
+
+	// Strings
+	gm.addString("label", {name: "Label", description: "Assigned Label", val: c => c.slave.custom.label});
+	gm.addString("genes", {
+		name: "Sex", description: "Genetic sex: Male: XX, Female: XY",
+		val: c => c.slave.genes
+	});
+	gm.addString("fetish", {
+		name: "Fetish",
+		description: "One of 'buttslut', 'cumslut', 'masochist', 'sadist', 'dom', 'submissive', 'boobs', " +
+			"'pregnancy', 'none' (AKA vanilla)",
+		val: c => c.slave.fetish
+	});
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @param {FC.RA.PostFixRule} rule
+ * @returns {boolean} If the rule should be applied to the given slave
+ */
+App.RA.Activation.evaluate = function(slave, rule) {
+	const gm = App.RA.Activation.getterManager;
+	const context = new App.RA.Activation.Context(slave);
+	const stack = new App.RA.Activation.Stack();
+
+	/**
+	 * @type {Map<string, function(): void>}
+	 */
+	const operators = new Map([
+		// and, or, +, * can take arbitrarily many arguments, so the first one describes the argument count
+		["and", () => {
+			const length = stack.popNumber();
+			let value = 1;
+			for (let i = 0; i < length; i++) {
+				value &= stack.popAsBoolean();
+			}
+			stack.pushNumber(value);
+		}],
+		["or", () => {
+			const length = stack.popNumber();
+			let value = 0;
+			for (let i = 0; i < length; i++) {
+				value |= stack.popAsBoolean();
+			}
+			stack.pushNumber(value);
+		}],
+		["add", () => {
+			const length = stack.popNumber();
+			let value = 0;
+			for (let i = 0; i < length; i++) {
+				value += stack.popNumber();
+			}
+			stack.pushNumber(value);
+		}],
+		["mul", () => {
+			const length = stack.popNumber();
+			let value = 1;
+			for (let i = 0; i < length; i++) {
+				value *= stack.popNumber();
+			}
+			stack.pushNumber(value);
+		}],
+		["max", () => {
+			const length = stack.popNumber();
+			let value = stack.popNumber();
+			for (let i = 1; i < length; i++) {
+				value = Math.max(value, stack.popNumber());
+			}
+			stack.pushNumber(value);
+		}],
+		["min", () => {
+			const length = stack.popNumber();
+			let value = stack.popNumber();
+			for (let i = 1; i < length; i++) {
+				value = Math.min(value, stack.popNumber());
+			}
+			stack.pushNumber(value);
+		}],
+		["sub", () => {
+			const subtract = stack.popNumber();
+			stack.pushNumber(stack.popNumber() - subtract);
+		}],
+		["div", () => {
+			const divisor = stack.popNumber();
+			stack.pushNumber(stack.popNumber() / divisor);
+		}],
+		["eqstr", () => stack.pushBoolean(stack.popString() === stack.popString())],
+		["neqstr", () => stack.pushBoolean(stack.popString() !== stack.popString())],
+		["eqnum", () => stack.pushBoolean(stack.popNumber() === stack.popNumber())],
+		["neqnum", () => stack.pushBoolean(stack.popNumber() === stack.popNumber())],
+		["gt", () => stack.pushBoolean(stack.popNumber() < stack.popNumber())],
+		["gte", () => stack.pushBoolean(stack.popNumber() <= stack.popNumber())],
+		["lt", () => stack.pushBoolean(stack.popNumber() > stack.popNumber())],
+		["lte", () => stack.pushBoolean(stack.popNumber() >= stack.popNumber())],
+		["substr", () => {
+			const value = stack.popString();
+			stack.pushBoolean(stack.popString().includes(value));
+		}],
+		["not", () => stack.pushBoolean(stack.popNumber() === 0)],
+		["ternarystr", () => {
+			const ifFalse = stack.popString();
+			const ifTrue = stack.popString();
+			stack.pushString(stack.popNumber() ? ifTrue : ifFalse);
+		}],
+		["ternarynum", () => {
+			const ifFalse = stack.popNumber();
+			const ifTrue = stack.popNumber();
+			stack.pushNumber(stack.popNumber() ? ifTrue : ifFalse);
+		}],
+	]);
+
+	/**
+	 * Custom getters start with "?" and then "b", "n" or "s" depending on return type
+	 * @param {string} rulePart
+	 */
+	function evalCustom(rulePart) {
+		const expectedType = rulePart.charAt(1) === "b" ? "boolean"
+			: rulePart.charAt(1) === "n" ? "number"
+				: "string";
+		try {
+			// TODO: Can we cache the function (and is that useful)?
+			const value = (new Function("c", `return (${rulePart.slice(2)})(c)`))(context);
+			if (expectedType === "boolean") {
+				stack.pushNumber(value ? 1 : 0);
+			} else if (expectedType === "number") {
+				stack.pushNumber(value);
+			} else {
+				// no guarantee we are getting a string, and it's easy to ensure it is one.
+				stack.pushString(value.toString());
+			}
+		} catch (e) {
+			throw new Error(`Custom condition '${rulePart.slice(2)}' failed: '${e.message}'`);
+		}
+	}
+
+	for (const rulePart of rule) {
+		if (typeof rulePart === "string") {
+			const operation = operators.get(rulePart);
+			if (operation !== undefined) {
+				operation();
+			} else {
+				const result = gm.read(stack, context, rulePart);
+				if (!result) {
+					if (rulePart.startsWith("?")) {
+						evalCustom(rulePart);
+					} else {
+						stack.pushString(rulePart.slice(1));
+					}
+				}
+			}
+		} else if (typeof rulePart === "number") {
+			stack.pushNumber(rulePart);
+		} else {
+			stack.pushBoolean(rulePart);
+		}
+	}
+	return !!stack.popNumber();
+};
diff --git a/js/ui/select.js b/js/ui/select.js
new file mode 100644
index 0000000000000000000000000000000000000000..4eb0e69d4a075fc963ec377e59cc18e8eb8bc203
--- /dev/null
+++ b/js/ui/select.js
@@ -0,0 +1,45 @@
+/**
+ * @typedef {object} selectOption
+ * @property {string} key
+ * @property {string} name
+ * @property {boolean} [enabled]
+ */
+
+/**
+ * Creates a new dropdown with available and unavailable options.
+ * @param {Array<selectOption>} options A list of options to display
+ * @param {string} selected
+ * @param {function(string):void} onchange
+ *
+ * @returns {HTMLSelectElement}
+ */
+App.UI.DOM.makeSelect = function(options, selected, onchange) {
+	const select = document.createElement("select");
+	let matchFound = false;
+
+	for (const choice of options) {
+		const option = document.createElement("option");
+
+		option.text = choice.name;
+		option.value = choice.key;
+
+		if (selected === choice.key) {
+			option.selected = true;
+			matchFound = true;
+		}
+
+		if ("enabled" in choice && !choice.enabled) {
+			option.disabled = true;
+		}
+
+		select.append(option);
+	}
+
+	if (!matchFound) {
+		select.selectedIndex = -1;
+	}
+
+	select.onchange = () => onchange(select.value);
+
+	return select;
+};
diff --git a/js/utils.js b/js/utils.js
index cba532a786ec80d7fb222f96415fb680c4e7d7e4..4ee72ebf6bced819a356a55e31f26f4e3e07c9f9 100644
--- a/js/utils.js
+++ b/js/utils.js
@@ -240,6 +240,21 @@ App.Utils.escapeHtml = function(text) {
 	return text.replace(/[&<>"']/g, m => map[m]);
 };
 
+App.Utils.expandHTML = (function() {
+	const element = document.createElement("div");
+
+	/**
+	 * @param {string} s
+	 * @returns {string}
+	 */
+	function expand(s) {
+		element.innerHTML = s;
+		return element.textContent;
+	}
+
+	return expand;
+})();
+
 /**
  * Creates an object where the items are accessible via their ids.
  *
@@ -383,3 +398,17 @@ function median(arr = []) {
 
 	return arr.length % 2 === 0 ? (nums[mid] + nums[mid - 1]) / 2 : nums[mid];
 }
+
+/**
+ * Returns value for point x, computed assuming linear function defined
+ * via two points (x0,y0) and (x1,y1)
+ * @param {number} x
+ * @param {number} x0
+ * @param {number} y0
+ * @param {number} x1
+ * @param {number} y1
+ * @returns {number}
+ */
+function linearInterpolation(x, x0, y0, x1, y1) {
+	return y0 + (x - x0) * ((y1 - y0) / (x1 - x0));
+}
diff --git a/mods/example/index.js b/mods/example/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..67ff48ea01f56c20b7166fec46a0af68a0e403af
--- /dev/null
+++ b/mods/example/index.js
@@ -0,0 +1,24 @@
+// Always scope your code to not pollute the global namespace.
+{
+	// Get the mod so we can modify it:
+	const mod = App.Modding.currentMod;
+
+	// Set the name and version:
+	mod.name = "Example Mod";
+	mod.version = "1.0";
+	mod.description = "This is an example mod showing off the modding API and gives examples for moddable systems.";
+
+	// For bigger mods it can be useful to split the mod in multiple parts.
+	// These parts can then be loaded as subscripts.
+	// Subscripts will be loaded in series and only once this script is done.
+	mod.addSubscript("subscript");
+
+	// Usage examples for moddable systems
+	mod.addSubscript("rulesAssistantGetters");
+
+	// Write to console, so we can easily see that the mod has loaded:
+	console.log("Index Loading: Success!");
+
+	// Tell the modding system this file is done. Do this at the end of EVERY script file.
+	App.Modding.scriptDone();
+}
diff --git a/mods/example/rulesAssistantGetters.js b/mods/example/rulesAssistantGetters.js
new file mode 100644
index 0000000000000000000000000000000000000000..e72951818c0e7f4e9ce221d324d7629905062467
--- /dev/null
+++ b/mods/example/rulesAssistantGetters.js
@@ -0,0 +1,18 @@
+// Add a new boolean getter for use in the RA condition editor.
+// The first argument is a unique name for the getter. To ensure uniqueness with other mods it is recommended to
+// prefix the name with the mod name.
+// The second argument is an object describing the getter.
+// 'name' is the string shown in the RA condition editor when selecting.
+// 'description' should be a short description of the value the getter returns, with possible values if applicable.
+//      It will be displayed in the encyclopedia.
+// 'val' is the actual getter reading out the value and returning it. It operates on a 'context' object with the current
+//      slave as an attribute.
+// It is important that the getter always returns the data type that it is being added as, in this case 'string'.
+// 'addNumber()' and 'addBoolean()' also exist. The usage is the same.
+App.RA.Activation.getterManager.addString("example_slavename",
+	{name: "Slave Name", description: "The slave's name.", val: context => context.slave.slaveName}
+);
+
+console.log("Rule Assistant Getters loaded.");
+
+App.Modding.scriptDone();
diff --git a/mods/example/subscript.js b/mods/example/subscript.js
new file mode 100644
index 0000000000000000000000000000000000000000..98b9946a62ee900a8c75fbf2f40c967ef4593f96
--- /dev/null
+++ b/mods/example/subscript.js
@@ -0,0 +1,5 @@
+// Show the subscript loaded successfully:
+console.log("Subscript loaded!");
+
+// Tell the modding system this file is done. Do this at the end of EVERY script file.
+App.Modding.scriptDone();
diff --git a/mods/mods.md b/mods/mods.md
new file mode 100644
index 0000000000000000000000000000000000000000..e9eeb5db4b805293c088b72a73f9a1cfa205946d
--- /dev/null
+++ b/mods/mods.md
@@ -0,0 +1,16 @@
+# Player Mods
+
+Player mods are scripts that are loaded after loading the game itself.
+
+There is currently very limited support for these mods with few systems exposing an API for modding.
+
+To use the mods in this directory copy the `mods` directory directly next to the game HTML file like this:
+
+* `FC_pregmod.html`
+* `mods/`
+    * `example/`
+        * `index.js`
+        * ...
+    * ...
+
+The example mod explains the modding API itself and has examples for all moddable systems.
diff --git a/package.json b/package.json
index 247c5fc113474cffcf883df2f1d3ae427f91b1b8..8597ed95c2aef8be7a4022b1bcf317a0e1b8ce43 100644
--- a/package.json
+++ b/package.json
@@ -16,12 +16,12 @@
 		"@types/jquery": "^3.5.1",
 		"@types/lodash": "^4.14.159",
 		"@types/mousetrap": "^1.6.3",
-		"@types/twine-sugarcube": "^2.33.0",
-		"eslint": "^7.6.0",
-		"eslint-plugin-jsdoc": "^32.0.0",
-		"eslint-plugin-sonarjs": "^0.6.0",
-		"ts-essentials": "^7.0.0",
-		"typescript": "^4.2.0"
+		"@types/twine-sugarcube": "^2.36.1",
+		"eslint": "^8.0.0",
+		"eslint-plugin-jsdoc": "^37.0.0",
+		"eslint-plugin-sonarjs": "^0.11.0",
+		"ts-essentials": "^9.1.1",
+		"typescript": "^4.4.0"
 	},
 	"dependencies": {
 		"autoprefixer": "^10.0.0",
diff --git a/src/002-config/fc-version.js b/src/002-config/fc-version.js
index 4bc94576032df1113af44eb28f80c59227911a20..25140c6fcde42c71697a31c88221be8d60a675da 100644
--- a/src/002-config/fc-version.js
+++ b/src/002-config/fc-version.js
@@ -1,6 +1,6 @@
 App.Version = {
 	base: "0.10.7.1", // The vanilla version the mod is based off of, this should never be changed.
-	pmod: "4.0.0-alpha.12",
+	pmod: "4.0.0-alpha.14",
 	commitHash: null,
-	release: 1155 // When getting close to 2000, please remove the check located within the onLoad() function defined at line five of src/js/eventHandlers.js.
+	release: 1170, // When getting close to 2000, please remove the check located within the onLoad() function defined at line five of src/js/eventHandlers.js.
 };
diff --git a/src/002-config/start.tw b/src/002-config/start.tw
index f54f0b07e0aa821bd3663d1efa249ef8904d2505..17f8052078bcba506a88c403f4dceedf62ce7a09 100644
--- a/src/002-config/start.tw
+++ b/src/002-config/start.tw
@@ -2,7 +2,7 @@
 {
 	"ifid":"18DFC483-910E-4D3B-AC31-71AE10C5015A",
 	"format": "SugarCube",
-	"format-version": "2.35.0"
+	"format-version": "2.36.0"
 }
 
 :: Start [nobr]
diff --git a/src/004-base/arcologyBuilding.js b/src/004-base/arcologyBuilding.js
index 78b51ef79496929d2390ea16ce7845918b9dd429..c8dd4bb816267ff885a0ddb35dfca47ba44c09ce 100644
--- a/src/004-base/arcologyBuilding.js
+++ b/src/004-base/arcologyBuilding.js
@@ -241,23 +241,26 @@ App.Arcology.Cell.BaseCell = class extends App.Entity.Serializable {
 	 * @param {function(): void} action
 	 * @param {number} cost
 	 * @param {App.Arcology.Building} containingBuilding
-	 * @param {string} [note]
-	 * @param {Node} [domNote]
+	 * @param {string[]} [notes]
 	 * @returns {HTMLDivElement}
 	 * @protected
 	 */
-	_makeInternalUpgrade(name, action, cost, containingBuilding, note, domNote) {
-		const div = document.createElement("div");
-
-		div.append(App.Arcology.getCellLink(name, this.name, () => this.cellPassage(containingBuilding),
-			() => {
-				cashX(-cost, "capEx");
-				action();
-			}));
-
-		this._upgradeNote(div, cost, note, domNote);
-
-		return div;
+	_makeInternalUpgrade(name, action, cost, containingBuilding, notes) {
+		return makePurchase(name, cost, "capEx", {
+			notes,
+			handler: () => {
+				if (Dialog.isOpen()) {
+					Dialog.close();
+				}
+				if (action) {
+					action();
+					V.building.refresh();
+				}
+				Dialog.setup(this.name);
+				$(Dialog.body()).empty().append(this.cellPassage(containingBuilding));
+				Dialog.open();
+			},
+		});
 	}
 
 	/**
@@ -265,44 +268,25 @@ App.Arcology.Cell.BaseCell = class extends App.Entity.Serializable {
 	 * @param {function(): void} action
 	 * @param {number} cost
 	 * @param {string} passage
-	 * @param {string} [note]
-	 * @param {Node} [domNote]
+	 * @param {string[]} [notes]
 	 * @returns {HTMLDivElement}
 	 * @protected
 	 */
-	_makeExternalUpgrade(name, action, cost, passage, note, domNote) {
+	_makeExternalUpgrade(name, action, cost, passage, notes) {
 		const div = document.createElement("div");
 
-		div.append(App.UI.DOM.passageLink(name, passage,
-			() => {
-				cashX(-cost, "capEx");
+		div.append(makePurchase(name, cost, "capEx", {
+			notes,
+			handler: () => {
 				action();
 				Dialog.close();
-			}));
-
-		this._upgradeNote(div, cost, note, domNote);
+				Engine.play(passage);
+			}
+		}));
 
 		return div;
 	}
 
-	/**
-	 * @param {HTMLDivElement} div
-	 * @param {number} cost
-	 * @param {string} [note]
-	 * @param {Node} [domNote]
-	 * @private
-	 */
-	_upgradeNote(div, cost, note, domNote) {
-		if (cost > 0 || note === undefined) {
-			note = ` Costs ${cashFormat(cost)}${note !== undefined ? ` ${note}` : ""}.`;
-		}
-		App.UI.DOM.appendNewElement("span", div, note, "detail");
-
-		if (domNote !== undefined) {
-			div.append(domNote); // this only exists for the farmyard, remove once that is out of alpha
-		}
-	}
-
 	/**
 	 * @returns {boolean}
 	 */
diff --git a/src/004-base/facility.js b/src/004-base/facility.js
index 1063d5cd6f86106b971ba49353ce67f6236598ea..e5c54f0f8969a62f58c43e3185d1d34ab8abdeea 100644
--- a/src/004-base/facility.js
+++ b/src/004-base/facility.js
@@ -207,8 +207,7 @@ App.Entity.Facilities.ManagingJob = class extends App.Entity.Facilities.Job {
 	 * @returns {boolean}
 	 */
 	slaveHasExperience(slave) {
-		return (this.desc.skill !== null && slave.skill[this.desc.skill] >= V.masteredXP) ||
-			(typeof slave.career === 'string' && this.desc.careers.includes(slave.career));
+		return (this.desc.skill && slave.skill[this.desc.skill] >= V.masteredXP) || (this.desc.careers.includes(slave.career));
 	}
 
 	/** @returns {App.Entity.SlaveState} */
diff --git a/src/004-base/facilityFramework.js b/src/004-base/facilityFramework.js
index 1a216fbced1a1f30c225e38a01e7922172eb7911..e8351ab0f33a849c499d0c015a27f2c2bf1d2ec3 100644
--- a/src/004-base/facilityFramework.js
+++ b/src/004-base/facilityFramework.js
@@ -3,7 +3,7 @@
  *
  * Not to be confused with `App.Entity.Facilities.Facility`, which handles the logic.
  */
-App.Facilities.Facility = class {
+App.Facilities.Facility = class Facility {
 	/**
 	 * @param {App.Entity.Facilities.Facility} facility The instance form of the facility. Typically found in `App.Entity.facilities`.
 	 * @param {function():void} decommissionHandler
@@ -134,36 +134,51 @@ App.Facilities.Facility = class {
 	 */
 	_makeExpand() {
 		const div = document.createElement("div");
-
 		// TODO: rework once all facilities are objects
 		const capacity = typeof V[this.facility.desc.baseName] === 'object'
 			? V[this.facility.desc.baseName].capacity
 			: V[this.facility.desc.baseName];
+		const occupancy = this.facility.hostedSlaves;
 		const maximum = this.expand.maximum || Number.MAX_SAFE_INTEGER;
-		const amount = this.expand.amount || 5;
-		const cost = this.expand.cost || capacity * 1000 * V.upgradeMultiplierArcology;
+		const amount = this.expand.amount;
 		const desc = this.expand.desc ||
 			`${this.facility.nameCaps} can support ${this.facility.capacity} slaves. There ${this.facility.hostedSlaves === 1 ? `is` : `are`} currently ${numberWithPluralOne(this.facility.hostedSlaves, "slave")} here.`;
+		let cost = this.expand.cost || capacity * 1000 * V.upgradeMultiplierArcology;
 
 		div.append(desc);
-
 		if (!this.expand.unexpandable) {
+			if (this.expand.maximum) {
+				App.UI.DOM.appendNewElement("div", div, `${this.facility.nameCaps} can support a maximum of ${num(maximum)} slaves.`);
+			}
 			if (capacity < maximum) {
-				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link(`Expand ${this.facility.name}`, () => {
-					cashX(forceNeg(cost), "capEx");
-					if (typeof V[this.facility.desc.baseName] === 'object') {		// TODO: change this once all facilities are objects
-						V[this.facility.desc.baseName].capacity += amount;
-					} else {
-						V[this.facility.desc.baseName] += amount;
+				if (amount) {
+					App.UI.DOM.appendNewElement("div", div,
+						makePurchase(`Expand slave capacity.`, cost, "capEx", {
+							notes: [`increases the capacity of ${this.facility.name} by ${num(amount)}.`],
+							handler: () => { expandFacility(amount, cost); }
+						})
+					);
+				} else {
+					const link = document.createElement("span");
+					const baseCost = cost;
+					const array = [];
+					for (const expand of [10, 25, 50, 100].filter(s => capacity - occupancy >= s)) {
+						cost = baseCost * (expand / 5);
+						array.push(
+							App.UI.DOM.link(`x${expand}`, () => { expandFacility(expand, cost); }, [], '', `+${expand} slots will cost ${cashFormat(Math.trunc(cost))}`)
+						);
 					}
-					V.PC.skill.engineering += .1;
-
-					this.refresh();
-				}, [], '', `Costs ${cashFormat(cost)} and increases the capacity of ${this.facility.name} by ${amount}.`), ['indent']);
-			} else {
-				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.disabledLink(`Expand ${this.facility.name}`, [
-					`${this.facility.nameCaps} can support a maximum of ${maximum} slaves.`,
-				]), ['indent']);
+					link.append(App.UI.DOM.generateLinksStrip(array));
+
+					const linkArray = [];
+					App.UI.DOM.appendNewElement("div", div);
+					div.append(`Expanding ${this.facility.name} by ${num(5)} slots will cost ${cashFormat(Math.trunc(baseCost))}: `);
+					linkArray.push(App.UI.DOM.link(`x5`, () => { expandFacility(5, baseCost); }));
+					if (capacity - occupancy >= 10) {
+						linkArray.push(App.UI.DOM.linkReplace(`Additional options`, link));
+					}
+					div.append(App.UI.DOM.generateLinksStrip(linkArray));
+				}
 			}
 		}
 
@@ -171,6 +186,18 @@ App.Facilities.Facility = class {
 			App.UI.DOM.appendNewElement("div", div, this.expand.removeAll || removeFacilityWorkers(this.facility, this.expand.removeManager, this.expand.removeSlave), ['indent']);
 		}
 
+		const expandFacility = (num, price) => {
+			if (typeof V[this.facility.desc.baseName] === 'object') {		// TODO: change this once all facilities are objects
+				V[this.facility.desc.baseName].capacity += num;
+			} else {
+				V[this.facility.desc.baseName] += num;
+			}
+			V.PC.skill.engineering += 0.1;
+			cashX(-price, "capEx");
+
+			App.UI.reload();
+		};
+
 		return div;
 	}
 
@@ -198,7 +225,6 @@ App.Facilities.Facility = class {
 
 	/**
 	 * Allows rules to be set up in the facility.
-	 *
 	 * @private
 	 * @returns {HTMLDivElement}
 	 */
@@ -216,11 +242,9 @@ App.Facilities.Facility = class {
 					rule.options.forEach(o => {
 						if (!o.prereqs || o.prereqs.every(prereq => prereq())) {
 							option.addValue(o.link, o.value);
-
 							if (o.handler) {
 								option.addCallback(o.handler);
 							}
-
 							if (o.note) {
 								option.addComment(o.note);
 							}
@@ -437,7 +461,7 @@ App.Facilities.Facility = class {
 	/**
 	 * Allows for the addition of any custom nodes to the facility.
 	 *
-	 * @returns {HTMLDivElement[]}
+	 * @returns {Array<HTMLDivElement|DocumentFragment>}
 	 */
 	 get customNodes() {
 		return [];
diff --git a/src/005-passages/facilitiesPassages.js b/src/005-passages/facilitiesPassages.js
index 3d99f9e57c78f9bbb9cad4f47ace42bb97f808be..e8c1e26252d0fb8fd81b83b8da364aa5aeacc22c 100644
--- a/src/005-passages/facilitiesPassages.js
+++ b/src/005-passages/facilitiesPassages.js
@@ -9,6 +9,8 @@ new App.DomPassage("Clinic", () => { return new App.Facilities.Clinic.clinic().r
 
 new App.DomPassage("Club", () => { return new App.Facilities.Club.club().render(); }, ["jump-to-safe", "jump-from-safe"]);
 
+new App.DomPassage("Dairy", () => { return new App.Facilities.Dairy.dairy().render(); }, ["jump-to-safe", "jump-from-safe"]);
+
 new App.DomPassage("Farmyard", () => { return new App.Facilities.Farmyard.farmyard().render(); }, ["jump-to-safe", "jump-from-safe"]);
 
 new App.DomPassage("Head Girl Suite", () => { return new App.Facilities.HGSuite.headGirlSuite().render(); }, ["jump-to-safe", "jump-from-safe"]);
@@ -27,12 +29,12 @@ new App.DomPassage("Servants' Quarters", () => { return new App.Facilities.Serva
 
 new App.DomPassage("Spa", () => { return new App.Facilities.Spa.spa().render(); }, ["jump-to-safe", "jump-from-safe"]);
 
-new App.DomPassage("Transport Hub", () => { return App.SecExp.transportHub.GUI(); });
-new App.DomPassage("Weapons Manufacturing", () => { return App.SecExp.weapManu.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
-new App.DomPassage("securityHQ", () => { return App.SecExp.secHub.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
-new App.DomPassage("secBarracks", () => { return App.SecExp.barracks.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
-new App.DomPassage("riotControlCenter", () => { return App.SecExp.riotCenter.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
-new App.DomPassage("propagandaHub", () => { return App.SecExp.propHub.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
+new App.DomPassage("Transport Hub", () => { return App.Mods.SecExp.transportHub.GUI(); });
+new App.DomPassage("Weapons Manufacturing", () => { return App.Mods.SecExp.weapManu.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
+new App.DomPassage("securityHQ", () => { return App.Mods.SecExp.secHub.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
+new App.DomPassage("secBarracks", () => { return App.Mods.SecExp.barracks.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
+new App.DomPassage("riotControlCenter", () => { return App.Mods.SecExp.riotCenter.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
+new App.DomPassage("propagandaHub", () => { return App.Mods.SecExp.propHub.GUI(); }, ["jump-to-safe", "jump-from-safe"]);
 
 /* ### Slave Interact Facilities ### */
 new App.DomPassage("Wardrobe",
diff --git a/src/005-passages/interactPassages.js b/src/005-passages/interactPassages.js
index 9f1c9dd26839d4b68c851fadbbc815aa8b60d4d4..a25a8d7c9ae78b73bdbfd512d0a4d4df740e8617 100644
--- a/src/005-passages/interactPassages.js
+++ b/src/005-passages/interactPassages.js
@@ -142,7 +142,7 @@ new App.DomPassage("BreedingTest",
 	() => {
 		V.nextButton = "Confirm changes";
 		V.nextLink = "Slave Interact";
-		return App.UI.DOM.makeElement("div", eliteBreedingExam(getSlave(V.AS)));
+		return App.UI.DOM.makeElement("div", App.Interact.eliteBreedingExam(getSlave(V.AS)));
 	}
 );
 
@@ -180,30 +180,6 @@ new App.DomPassage("FAnimalImpreg",
 	}
 );
 
-new App.DomPassage("FSlaveSlaveDick",
-	() => {
-		V.nextLink = "Slave Interact";
-		V.nextButton = "Back";
-		return App.Interact.fSlaveSlaveDick(getSlave(V.AS));
-	}
-);
-
-new App.DomPassage("FSlaveSlaveVag",
-	() => {
-		V.nextLink = "Slave Interact";
-		V.nextButton = "Back";
-		return App.Interact.fSlaveSlaveVag(getSlave(V.AS));
-	}
-);
-
-new App.DomPassage("FSlaveSlaveAss",
-	() => {
-		V.nextLink = "Slave Interact";
-		V.nextButton = "Back";
-		return App.Interact.fSlaveSlaveAss(getSlave(V.AS));
-	}
-);
-
 new App.DomPassage("Matchmaking",
 	() => {
 		if (lastVisited("Child Interact") === 1) {
diff --git a/src/005-passages/managePassages.js b/src/005-passages/managePassages.js
index 11d6cd1110bab2c71c08515a1b5e4e30d9ecaa43..ce546fc095f99b5fd2c9247e1d3f4c72cfadb689 100644
--- a/src/005-passages/managePassages.js
+++ b/src/005-passages/managePassages.js
@@ -139,7 +139,7 @@ new App.DomPassage("The Black Market",
 		V.nextLink = "Main";
 		V.returnTo = "Main";
 		V.encyclopedia = "The Black Market";
-		return App.UI.theBlackMarket();
+		return App.UI.blackMarket();
 	}, ["jump-to-safe", "jump-from-safe"]
 );
 
@@ -222,6 +222,6 @@ new App.DomPassage("edicts",
 	() => {
 		V.nextButton = "Back";
 		V.nextLink = "Main";
-		return App.SecExp.edicts();
+		return App.Mods.SecExp.edicts();
 	}, ["jump-to-safe", "jump-from-safe"]
 );
diff --git a/src/Corporation/corporate.js b/src/Corporation/corporate.js
index 860035b7bc40dd63be6cd7dd9fc6f17ccfa36568..7e4e51fd9842af9551a143a712dd49dfd92c37ac 100644
--- a/src/Corporation/corporate.js
+++ b/src/Corporation/corporate.js
@@ -922,7 +922,7 @@ globalThis.corpBlacklistRace = function(race, blacklist) {
 	if (raceArray.length > 0 && blacklist === 1) {
 		raceArray.delete(race);
 	} else if (blacklist === 1) {
-		raceArray = Array.from(App.Data.misc.filterRaces.keys()).filter(x => x !== race);
+		raceArray = Array.from(App.Data.misc.filterRacesPublic.keys()).filter(x => x !== race);
 	} else {
 		raceArray.push(race);
 	}
diff --git a/src/Corporation/manageCorporation.js b/src/Corporation/manageCorporation.js
index 4f244d382b05e6b33f633f5869c9d44902d10e52..49831789f72dc08b36a85cfd1550423bd63587d8 100644
--- a/src/Corporation/manageCorporation.js
+++ b/src/Corporation/manageCorporation.js
@@ -614,7 +614,7 @@ App.Corporate.manage = function() {
 					// This used to be V.captureUpgradeRace, it is a general acquisition specialization
 
 					const links = [];
-					for (const [key, race] of App.Data.misc.filterRacesBase) {
+					for (const [key, race] of App.Data.misc.filterRacesPublic) {
 						if (V.arcologies[0].FSSubjugationistRace !== key || V.arcologies[0].FSSubjugationist === "unset") {
 							links.push(App.UI.DOM.link(race, () => {
 								V.corp.SpecRaces = corpBlacklistRace(key, 1);
@@ -629,7 +629,7 @@ App.Corporate.manage = function() {
 
 					if (V.corp.SpecToken >= 3) {
 						const links = [];
-						for (const [key, race] of App.Data.misc.filterRacesBase) {
+						for (const [key, race] of App.Data.misc.filterRacesPublic) {
 							if (V.arcologies[0].FSSupremacistRace !== key || V.arcologies[0].FSSupremacist === "unset") {
 								links.push(App.UI.DOM.link(race, () => {
 									V.corp.SpecRaces = corpBlacklistRace(key, 0);
@@ -1042,7 +1042,7 @@ App.Corporate.manage = function() {
 			p.append(`You have chosen the following specializations:`);
 			App.UI.DOM.appendNewElement("div", p, `You can choose to specialize further with additional tokens, specialize less, end the specialization or sometimes tweak them for free.`, "note");
 
-			if (V.corp.SpecRaces.length === 12) {
+			if (V.corp.SpecRaces.length === App.Data.misc.filterRacesPublic.size) {
 				V.corp.SpecRaces = [];
 			}
 			if (V.corp.SpecRaces.length > 0) {
@@ -2059,13 +2059,13 @@ App.Corporate.manage = function() {
 	function corpRaces() {
 		const el = new DocumentFragment();
 		App.UI.DOM.appendNewElement("div", el, `The corporation enslaves people of the following race${V.corp.SpecRaces.length === 1 ? `` : `s`}:`);
-		for (const [race, capRace] of App.Data.misc.filterRaces) {
+		for (const [race, capRace] of App.Data.misc.filterRacesPublic) {
 			const r = [];
 			if (V.corp.SpecRaces.includes(race)) {
 				r.push(capRace);
 				if (!(V.arcologies[0].FSSubjugationist !== "unset" && V.arcologies[0].FSSubjugationistRace !== race)) {
 					if (V.corp.SpecRaces.length > 1 && V.corp.SpecTimer === 0) {
-						const blacklistLength = App.Data.misc.filterRaces.size - V.corp.SpecRaces.length;
+						const blacklistLength = App.Data.misc.filterRacesPublic.size - V.corp.SpecRaces.length;
 						const needsToken = blacklistLength % 4 === 0;
 
 						if (!needsToken || V.corp.SpecToken > 0) {
@@ -2095,7 +2095,7 @@ App.Corporate.manage = function() {
 							"Whitelist",
 							() => {
 								V.corp.SpecRaces = corpBlacklistRace(race, 0);
-								const blacklistLength = App.Data.misc.filterRaces.size - V.corp.SpecRaces.length;
+								const blacklistLength = App.Data.misc.filterRacesPublic.size - V.corp.SpecRaces.length;
 								if (blacklistLength % 4 === 0) {
 									V.corp.SpecToken += 1;
 									V.corp.SpecTimer = 1;
diff --git a/src/Mods/Catmod/events/CMRESS/catLove.js b/src/Mods/Catmod/events/CMRESS/catLove.js
index afefe3a3aec46ae783cf901559cdfa89cdee093c..ca586f069982511903ccf5919776632385eb50e7 100644
--- a/src/Mods/Catmod/events/CMRESS/catLove.js
+++ b/src/Mods/Catmod/events/CMRESS/catLove.js
@@ -48,7 +48,7 @@ App.Events.CMRESSCatLove = class CMRESSCatLove extends App.Events.BaseEvent {
 			App.Events.addParagraph(node, t);
 
 			t = [];
-			t.push(`${He} holds the little sculpture out to you with wobbly hands, finding it hard to balance the unwieldy thing as you examine ${his} craftscatship. The sculpture is surprisingly pretty; one of the slaves around you is obviously supposed to be ${eventSlave.slaveName}, and they're all burshing up against you lovingly with individual expressions of happiness tediously moulded onto their faces.`);
+			t.push(`${He} holds the little sculpture out to you with wobbly hands, finding it hard to balance the unwieldy thing as you examine ${his} craftscatship. The sculpture is surprisingly pretty; one of the slaves around you is obviously supposed to be ${eventSlave.slaveName}, and they're all brushing up against you lovingly with individual expressions of happiness tediously moulded onto their faces.`);
 			if (canTalk(eventSlave)) {
 				t.push(
 					Spoken(eventSlave, `"I thought you might like a better gift, so I found some clay in the workshop and made this, ${title}."`),
diff --git a/src/Mods/Catmod/events/SoSBombing.js b/src/Mods/Catmod/events/SoSBombing.js
index 610efd9375005875b59cb6e2cba2e08f8e461427..4eb04e8343001f9ef17d4d3dde63c24617df9622 100644
--- a/src/Mods/Catmod/events/SoSBombing.js
+++ b/src/Mods/Catmod/events/SoSBombing.js
@@ -52,7 +52,7 @@ App.Events.RESosBombing = class RESosBombing extends App.Events.BaseEvent {
 		}
 
 		/**
-		 * @param {String} operationalCommand 
+		 * @param {String} operationalCommand
 		 * @returns {DocumentFragment}
 		 */
 		function raidOutcome(operationalCommand) {
diff --git a/src/Mods/Catmod/events/nonRandom/projectNBubbles.js b/src/Mods/Catmod/events/nonRandom/projectNBubbles.js
index e4942cf72d373fb23ec067c81c5d885700598b73..1fa6486698dd82d368f7c5a6aaca075f914582d7 100644
--- a/src/Mods/Catmod/events/nonRandom/projectNBubbles.js
+++ b/src/Mods/Catmod/events/nonRandom/projectNBubbles.js
@@ -25,14 +25,11 @@ App.Events.SEProjectNbubbles = class SEProjectNbubbles extends App.Events.BaseEv
 
 		function rename() {
 			const frag = new DocumentFragment();
-			let r = [];
-			r.push(
+			App.Events.addParagraph(frag, [
 				`You tell the waiting bioengineers that you'll be formally naming the growing catgirl `,
 				App.UI.DOM.makeTextBox(V.subjectDeltaName, (v) => V.subjectDeltaName = v),
 				`Nieskowitz nods, jots something down in a notepad, and then lets you know that he'll update you on the situation as it develops.`
-			);
-			r.push();
-			App.Events.addParagraph(frag, r);
+			]);
 			return frag;
 		}
 	}
diff --git a/src/Mods/Catmod/events/reRecruit/runawayCat.js b/src/Mods/Catmod/events/reRecruit/runawayCat.js
index fffebd00a924fc85cfd6aa80f43fb83db3d96d9a..5eb22633ad35d6dfde31d9e4c8d11fca8ecdeab1 100644
--- a/src/Mods/Catmod/events/reRecruit/runawayCat.js
+++ b/src/Mods/Catmod/events/reRecruit/runawayCat.js
@@ -66,7 +66,7 @@ App.Events.recRunawayCat = class recRunawayCat extends App.Events.BaseEvent {
 			const slave = GenerateNewSlave(null, {minAge: 16, maxAge: 22, race: "catgirl"});
 			slave.face = random(25, 75);
 			slave.origin = "$He was bioengineered by a rival arcology owner. After being mistreated, $he escaped and came to you for protection.";
-			slave.slaveName = setup.catSlaveNames.random();
+			slave.slaveName = App.Data.misc.catSlaveNames.random();
 			slave.birthName = slave.slaveName;
 			slave.weight = 10;
 			slave.muscles = 0;
diff --git a/src/Mods/Catmod/events/scheduled/vatcatboy.js b/src/Mods/Catmod/events/scheduled/vatcatboy.js
index 8f68775b6a28ed1b0b4c14a2c548ee4d1c9f14e3..a6c76a599b13f6022a88fcdaedbf7e5eb33bfbd4 100644
--- a/src/Mods/Catmod/events/scheduled/vatcatboy.js
+++ b/src/Mods/Catmod/events/scheduled/vatcatboy.js
@@ -13,7 +13,7 @@ App.Events.SEVatCatBoy = class SEVatCatBoy extends App.Events.BaseEvent {
 		slave.origin = "$He is a vat-grown catboy created by Dr. Nieskowitz and the science team in your genelab.";
 		slave.face = random(55, 95);
 		slave.faceShape = "feline";
-		slave.slaveName = setup.catSlaveNames.random();
+		slave.slaveName = App.Data.misc.catSlaveNames.random();
 		slave.birthName = slave.slaveName;
 		slave.slaveSurname = "";
 		slave.birthSurname = "";
diff --git a/src/Mods/Catmod/events/scheduled/vatcatgirl.js b/src/Mods/Catmod/events/scheduled/vatcatgirl.js
index 97127918aeccc8550f9dd198e6a45e91f5376fd6..92ccdaadc771ca52ede9205b7cb81870722de349 100644
--- a/src/Mods/Catmod/events/scheduled/vatcatgirl.js
+++ b/src/Mods/Catmod/events/scheduled/vatcatgirl.js
@@ -13,7 +13,7 @@ App.Events.SEVatCatGirl = class SEVatCatGirl extends App.Events.BaseEvent {
 		slave.origin = "$He is a vat-grown catgirl created by Dr. Nieskowitz and the science team in your genelab.";
 		slave.face = random(55, 95);
 		slave.faceShape = "feline";
-		slave.slaveName = setup.catSlaveNames.random();
+		slave.slaveName = App.Data.misc.catSlaveNames.random();
 		slave.birthName = slave.slaveName;
 		slave.slaveSurname = "";
 		slave.birthSurname = "";
diff --git a/src/Mods/DinnerParty/dinnerPartyExecution.tw b/src/Mods/DinnerParty/dinnerPartyExecution.tw
index a78bdb119d45e9bf6fb30c9259c754586490b4a7..4916d9cb4f7d376dda2a6b88241e9c9e41ab2c56 100644
--- a/src/Mods/DinnerParty/dinnerPartyExecution.tw
+++ b/src/Mods/DinnerParty/dinnerPartyExecution.tw
@@ -394,7 +394,7 @@
 		<<if _dinnerRating >= 20>>
 			<br><br>
 			You have earned the 20 stars required for the title of
-			<<set $MOD_DinnerPartyTitleAchievement 0 1>>
+			<<set $MOD_DinnerPartyTitleAchievement = 1>>
 			<<if $PC.title > 0>>
 				@@.yellow;Master of The Culinary Arts.@@
 			<<else>>
@@ -555,7 +555,7 @@
 		<<set _slave.trust = -2>>
 		<<set _slave.oldDevotion = -20>>
 		<<set _slave.origin = "$He was once an arcology owner like yourself, who made the mistake of insulting you.">>
-		<<set _slave.career = 0>>
+		<<set _slave.career = "a slave">>
 		<<set _slave.prestige = 3>>
 		<<set _slave.prestigeDesc = "You stormed $his arcology, killed $his guards, and enslaved $him in revenge for insulting you at a dinner party.">>
 		<<run setHealth(_slave, 20, random(5, 15), 0, 0, 0)>>
diff --git a/src/Mods/SecExp/buildings/buildingsBC.js b/src/Mods/SecExp/buildings/SecExpBuildingsBC.js
similarity index 99%
rename from src/Mods/SecExp/buildings/buildingsBC.js
rename to src/Mods/SecExp/buildings/SecExpBuildingsBC.js
index 04c537d687f6239138c10186fca41f9daf3936a9..d8555b4c68a438bb49b6149ba34f1e16addd6cb2 100644
--- a/src/Mods/SecExp/buildings/buildingsBC.js
+++ b/src/Mods/SecExp/buildings/SecExpBuildingsBC.js
@@ -1,4 +1,4 @@
-App.SecExp.BC = (function() {
+App.Mods.SecExp.BC = (function() {
 	return {
 		propHub,
 		riotCenter,
@@ -125,7 +125,7 @@ App.SecExp.BC = (function() {
 
 			V.SecExp.buildings.weapManu.upgrades = V.SecExp.buildings.weapManu.upgrades || {};
 			V.SecExp.buildings.weapManu.upgrades.completed = V.SecExp.buildings.weapManu.upgrades.completed || V.completedUpgrades || [];
-			if (!App.SecExp.weapManu.completed()) {
+			if (!App.Mods.SecExp.weapManu.completed()) {
 				V.SecExp.buildings.weapManu.upgrades.queue = V.SecExp.buildings.weapManu.upgrades.queue || [];
 				if (jsDef(V.currentUpgrade)) {
 					if (!jsDef(V.currentUpgrade.ID)) {
diff --git a/src/Mods/SecExp/buildings/propagandaHub.js b/src/Mods/SecExp/buildings/propagandaHub.js
index b3ef273756735fa241ed1c5b9618070ac7abbcbf..78cb7184f6498c294bc7fd8817a49337620ecaea 100644
--- a/src/Mods/SecExp/buildings/propagandaHub.js
+++ b/src/Mods/SecExp/buildings/propagandaHub.js
@@ -1,10 +1,10 @@
-App.SecExp.propHub = (function() {
+App.Mods.SecExp.propHub = (function() {
 	return {
-		Init,
+		init,
 		GUI
 	};
 
-	function Init() {
+	function init() {
 		V.SecExp.buildings.propHub = {
 			recruiterOffice: 0,
 			upgrades: {
diff --git a/src/Mods/SecExp/buildings/riotControlCenter.js b/src/Mods/SecExp/buildings/riotControlCenter.js
index 5db8db67e2c6c54dd2fd00b1c9a5cb09d6501cf7..9b0850b2d989be1383530f602f24cdff38d0782b 100644
--- a/src/Mods/SecExp/buildings/riotControlCenter.js
+++ b/src/Mods/SecExp/buildings/riotControlCenter.js
@@ -1,10 +1,10 @@
-App.SecExp.riotCenter = (function() {
+App.Mods.SecExp.riotCenter = (function() {
 	return {
-		Init,
+		init,
 		GUI
 	};
 
-	function Init() {
+	function init() {
 		V.SecExp.buildings.riotCenter = {
 			upgrades: {
 				freeMedia: 0,
@@ -201,7 +201,7 @@ App.SecExp.riotCenter = (function() {
 		if (V.SF.Toggle && V.SF.Active >= 1) {
 			if (V.SecExp.edicts.SFSupportLevel >= 4 && V.SF.Squad.Armoury >= 8 && !V.SecExp.rebellions.sfArmor) {
 				App.UI.DOM.appendNewElement("div", node);
-				const cost = Math.ceil(500000 * App.SF.env() * (1.15 + (V.SF.Squad.Armoury/10) ));
+				const cost = Math.ceil(500000 * App.Mods.SF.env() * (1.15 + (V.SF.Squad.Armoury/10) ));
 				App.UI.DOM.appendNewElement("span", node,
 					App.UI.DOM.link(
 						`Give the riot unit access to the combat armor suits of ${V.SF.Lower}.`,
@@ -211,7 +211,7 @@ App.SecExp.riotCenter = (function() {
 						}
 					)
 				);
-				App.UI.DOM.appendNewElement("span", node, `Costs ${cost}.`, "note");
+				App.UI.DOM.appendNewElement("span", node, `Costs ${cashFormat(cost)}.`, "note");
 			} else {
 				App.UI.DOM.appendNewElement("div", node, `You have given the riot unit access to the combat armor suits of ${V.SF.Lower}.`);
 			}
@@ -232,7 +232,10 @@ App.SecExp.riotCenter = (function() {
 			}
 			deploy.append("Spend: ", App.UI.DOM.generateLinksStrip(r));
 			return deploy;
-
+			/**
+			 * @param {string} cost 
+			 * @returns {HTMLSpanElement}
+			 */
 			function menu(cost) {
 				const text = document.createElement("span");
 				App.UI.DOM.appendNewElement("div", text, `Your ${cost} will be leveraged to suppress the rebels.`);
@@ -241,7 +244,7 @@ App.SecExp.riotCenter = (function() {
 						`Deploy the unit against ${type} rebel leaders`,
 						() => {
 							const price = forceNeg(1000 + 50 * V.SecExp.buildings.riotCenter.upgrades.rapidUnit);
-							(function() { cost === "reputation" ? repX(price, "war") : App.SecExp.authorityX(-price); })();
+							(function() { cost === "reputation" ? repX(price, "war") : App.Mods.SecExp.authorityX(-price); })();
 							const change = random(15) + random(1, 2) * V.SecExp.buildings.riotCenter.upgrades.rapidUnit;
 							V.SecExp.rebellions[type + "Progress"] = Math.clamp(V.SecExp.rebellions[type + "Progress"] - change, 0, 100);
 							V.SecExp.buildings.riotCenter.sentUnitCooldown = 3 - V.SecExp.buildings.riotCenter.upgrades.rapidUnitSpeed;
@@ -260,7 +263,7 @@ App.SecExp.riotCenter = (function() {
 					if (applyHacking) {
 						V.PC.skill.hacking++;
 					}
-					switch(type) {
+					switch (type) {
 						case "freeMedia":
 						case "rapidUnit":
 						case "rapidUnitSpeed":
diff --git a/src/Mods/SecExp/buildings/secBarracks.js b/src/Mods/SecExp/buildings/secBarracks.js
index 36fee0c922bbfcc3f92643d006db1417cdd2cd6f..8741fa04d33d0bf12c486420162b364e3be34f8c 100644
--- a/src/Mods/SecExp/buildings/secBarracks.js
+++ b/src/Mods/SecExp/buildings/secBarracks.js
@@ -1,10 +1,10 @@
-App.SecExp.barracks = (function() {
+App.Mods.SecExp.barracks = (function() {
 	return {
-		Init,
+		init,
 		GUI
 	};
 
-	function Init() {
+	function init() {
 		V.SecExp.buildings.barracks = {
 			size: 0,
 			luxury: 0,
@@ -23,7 +23,7 @@ App.SecExp.barracks = (function() {
 
 		node.append(`While this is a sore sight for many citizens of ${V.arcologies[0].name}, the barracks stand proud before you. `);
 		App.UI.DOM.appendNewElement("h1", node, "Upgrades", "underline");
-		switch(V.SecExp.buildings.barracks.size) {
+		switch (V.SecExp.buildings.barracks.size) {
 			case 0: r.push("The building is relatively small and able to house a limited number of units."); break;
 			case 1: r.push("The building has been expanded and can now house more units comfortably."); break;
 			case 2: r.push("The building has been further expanded and can now house a high number of units."); break;
@@ -81,7 +81,7 @@ App.SecExp.barracks = (function() {
 			App.UI.DOM.appendNewElement("div", node, `Costs ${cashFormat(cost)} and will increase the maximum number of units by 2`, "note");
 		} else {
 			const activeSF = V.SF.Toggle && V.SF.Active >= 1;
-			const sectionSF = activeSF && V.SF.Squad.Firebase > 5 && V.SecExp.edicts.SFSupportLevel >= 4 && App.SecExp.battle.maxUnits() === 18 && App.SecExp.battle.deploySpeed() <= 10;
+			const sectionSF = activeSF && V.SF.Squad.Firebase > 5 && V.SecExp.edicts.SFSupportLevel >= 4 && App.Mods.SecExp.battle.maxUnits() === 18 && App.Mods.SecExp.battle.deploySpeed() <= 10;
 			const reasons = [];
 			if (activeSF) {
 				if (V.SF.Squad.Firebase < 5) {
@@ -97,7 +97,7 @@ App.SecExp.barracks = (function() {
 				if (reasons.length > 0) {
 					App.UI.DOM.appendNewElement("div", node, `The Colonel says that ${capSF} may be able to provide assistance if; ${toSentence(reasons)}.`);
 				}
-				cost = Math.trunc( (750000 * (1.15 + (App.SF.upgrades.total() / 1000)) * (1.15 + (V.SF.Squad.Firebase / 10))) * App.SF.env() );
+				cost = Math.trunc( (750000 * (1.15 + (App.Mods.SF.upgrades.total() / 1000)) * (1.15 + (V.SF.Squad.Firebase / 10))) * App.Mods.SF.env() );
 				if (sectionSF) {
 					node.append(App.UI.DOM.link(`${capSF} will provide the security force their own section in the Firebase.`, () => {
 						V.SecExp.sectionInFirebase = 1;
@@ -113,7 +113,7 @@ App.SecExp.barracks = (function() {
 		}
 
 		if (V.SecExp.buildings.barracks.luxury < 4) {
-			switch(V.SecExp.buildings.barracks.luxury) {
+			switch (V.SecExp.buildings.barracks.luxury) {
 				case 0:
 					cost = Math.trunc(5000 * V.upgradeMultiplierTrade);
 					text = "Increase the quality of life of your soldiers by installing high tech furniture and appliances";
@@ -143,7 +143,7 @@ App.SecExp.barracks = (function() {
 		}
 
 		if (V.SecExp.buildings.barracks.training < 2) {
-			switch(V.SecExp.buildings.barracks.training) {
+			switch (V.SecExp.buildings.barracks.training) {
 				case 0:
 					cost = Math.trunc(10000 * V.upgradeMultiplierArcology);
 					text = "Add a training facility to the barracks";
@@ -165,7 +165,7 @@ App.SecExp.barracks = (function() {
 		}
 
 		if (V.SecExp.buildings.barracks.loyaltyMod < 2) {
-			switch(V.SecExp.buildings.barracks.loyaltyMod) {
+			switch (V.SecExp.buildings.barracks.loyaltyMod) {
 				case 0:
 					cost = Math.trunc(10000 * V.upgradeMultiplierArcology);
 					text = "Add an indoctrination facility to the barracks";
@@ -187,11 +187,11 @@ App.SecExp.barracks = (function() {
 		}
 
 		App.UI.DOM.appendNewElement("h1", node, "Units", "underline");
-		node.append(`${App.SecExp.battle.activeUnits()}/${App.SecExp.battle.maxUnits()} are active, totalling ${num(App.SecExp.unit.squads().reduce((acc, t) => acc += t.troops, 0))} troops `);
-		if (App.SecExp.battle.activeUnits() === 2 * App.SecExp.battle.deploySpeed()) {
+		node.append(`${App.Mods.SecExp.battle.activeUnits()}/${App.Mods.SecExp.battle.maxUnits()} are active, totalling ${num(App.Mods.SecExp.unit.squads().reduce((acc, t) => acc += t.troops, 0))} troops `);
+		if (App.Mods.SecExp.battle.activeUnits() === 2 * App.Mods.SecExp.battle.deploySpeed()) {
 			node.append(`and all can be deployed.`);
 		} else {
-			node.append(`however only ${2 * App.SecExp.battle.deploySpeed()} can be deployed.`);
+			node.append(`however only ${2 * App.Mods.SecExp.battle.deploySpeed()} can be deployed.`);
 		}
 		if (V.SecExp.buildings.barracks.luxury > 0) {
 			node.append(` The barracks provides ${V.SecExp.buildings.barracks.luxury * 5}% bonus morale when battle occurs.`);
@@ -204,13 +204,13 @@ App.SecExp.barracks = (function() {
 		options.addOption("Unit descriptions are", "unitDescriptions", V.SecExp.settings)
 			.addValue("Abbreviated", 1).on().addValue("Summarized", 0).off();
 		node.append(options.render());
-		if (App.SecExp.battle.activeUnits() >= App.SecExp.battle.maxUnits()) {
+		if (App.Mods.SecExp.battle.activeUnits() >= App.Mods.SecExp.battle.maxUnits()) {
 			App.UI.DOM.appendNewElement("div", node, "You have reached the maximum number of units. You'll have to disband one or enlarge the barracks before forming a new unit.");
 		}
-		node.append(App.SecExp.unit.replenishAll());
+		node.append(App.Mods.SecExp.unit.replenishAll());
 
 		const tabBar = new App.UI.Tabs.TabBar("SecExpBarracks");
-		for (const [unit, data] of App.SecExp.unit.list()) {
+		for (const [unit, data] of App.Mods.SecExp.unit.list()) {
 			if (data.unlock) {
 				tabBar.addTab(`${capFirstChar(data.name || unit)}: ${(V.SecExp.units[unit].squads.length)}`, unit, page(unit));
 			} else {
@@ -222,34 +222,34 @@ App.SecExp.barracks = (function() {
 
 		function page(u) {
 			const r = new DocumentFragment();
-			switch(u) {
+			switch (u) {
 				case "slaves":
-					App.UI.DOM.appendNewElement("div", r, `You are free to organize your menial slaves into fighting units. Currently you have ${num(V.menials)} slaves available, while ${num(App.SecExp.Manpower.employedSlave)} are already employed as soldiers. During all your battles you lost a total of ${num(V.SecExp.units.slaves.dead)}.`);
+					App.UI.DOM.appendNewElement("div", r, `You are free to organize your menial slaves into fighting units. Currently you have ${num(V.menials)} slaves available, while ${num(App.Mods.SecExp.Manpower.employedSlave)} are already employed as soldiers. During all your battles you lost a total of ${num(V.SecExp.units.slaves.dead)}.`);
 					break;
 				case "militia":
 					App.UI.DOM.appendNewElement("div", r, `You founded the ${V.arcologies[0].name} free militia. You are now able to organize your citizens into fighting units.`);
-					switch(V.SecExp.edicts.defense.militia) {
+					switch (V.SecExp.edicts.defense.militia) {
 						case 2:
-							App.UI.DOM.appendNewElement("div", r, `The militia is composed entirely of volunteers, your manpower is ${num(App.SecExp.militiaCap()*100)}% of the citizens population of your arcology.`);
+							App.UI.DOM.appendNewElement("div", r, `The militia is composed entirely of volunteers, your manpower is ${num(App.Mods.SecExp.militiaCap()*100)}% of the citizens population of your arcology.`);
 							break;
 						case 3:
-							App.UI.DOM.appendNewElement("div", r, `With the establishment of conscription, your available manpower has increased to now ${num(App.SecExp.militiaCap()*100)}% of the arcology's citizens population.`);
+							App.UI.DOM.appendNewElement("div", r, `With the establishment of conscription, your available manpower has increased to now ${num(App.Mods.SecExp.militiaCap()*100)}% of the arcology's citizens population.`);
 							break;
 						case 4:
-							App.UI.DOM.appendNewElement("div", r, `By establishing obligatory military service to obtain citizenship you have enlarged your manpower pool to be ${num(App.SecExp.militiaCap()*100)}% of the arcology's citizens population.`);
+							App.UI.DOM.appendNewElement("div", r, `By establishing obligatory military service to obtain citizenship you have enlarged your manpower pool to be ${num(App.Mods.SecExp.militiaCap()*100)}% of the arcology's citizens population.`);
 							break;
 						case 5:
-							App.UI.DOM.appendNewElement("div", r, `With the adoption of a militarized society, your available manpower has swelled to be ${num(App.SecExp.militiaCap()*100)}% of the arcology's citizens population.`);
+							App.UI.DOM.appendNewElement("div", r, `With the adoption of a militarized society, your available manpower has swelled to be ${num(App.Mods.SecExp.militiaCap()*100)}% of the arcology's citizens population.`);
 					}
-					App.UI.DOM.appendNewElement("div", r, `Your current total manpower is ${num(App.SecExp.Manpower.totalMilitia)}, of which ${num(App.SecExp.Manpower.employedMilitia)} is in active duty. You lost in total ${num(V.SecExp.units.militia.dead)} citizens, leaving you with ${num(V.SecExp.units.militia.free)} available citizens.`);
+					App.UI.DOM.appendNewElement("div", r, `Your current total manpower is ${num(App.Mods.SecExp.Manpower.totalMilitia)}, of which ${num(App.Mods.SecExp.Manpower.employedMilitia)} is in active duty. You lost in total ${num(V.SecExp.units.militia.dead)} citizens, leaving you with ${num(V.SecExp.units.militia.free)} available citizens.`);
 					break;
 				case "mercs":
 					App.UI.DOM.appendNewElement("div", r, `With the installation of a mercenary company in the arcology, many other are attracted to your free city, hoping to land a contract with you.`);
-					App.UI.DOM.appendNewElement("div", r, `You are able to organize them in units to use in the defense of the arcology. Excluding the defense force you set up, there are ${num(App.SecExp.Manpower.totalMerc)} mercenaries in your arcology, of which ${num(App.SecExp.Manpower.employedMerc)} actively employed and ${num(V.SecExp.units.mercs.free)} not yet under contract. In total ${num(V.SecExp.units.mercs.dead)} mercenaries have died defending your arcology.`);
+					App.UI.DOM.appendNewElement("div", r, `You are able to organize them in units to use in the defense of the arcology. Excluding the defense force you set up, there are ${num(App.Mods.SecExp.Manpower.totalMerc)} mercenaries in your arcology, of which ${num(App.Mods.SecExp.Manpower.employedMerc)} actively employed and ${num(V.SecExp.units.mercs.free)} not yet under contract. In total ${num(V.SecExp.units.mercs.dead)} mercenaries have died defending your arcology.`);
 					break;
 			}
 
-			App.UI.DOM.appendNewElement("div", r, App.SecExp.unit.barracksList(u));
+			App.UI.DOM.appendNewElement("div", r, App.Mods.SecExp.unit.barracksList(u));
 			return r;
 		}
 	}
diff --git a/src/Mods/SecExp/buildings/securityHQ.js b/src/Mods/SecExp/buildings/securityHQ.js
index 5709f81303164e5b877c7d296a705490aed4d1f0..ffce47fd8c47e3a2e4bc051b01e91b6836159c81 100644
--- a/src/Mods/SecExp/buildings/securityHQ.js
+++ b/src/Mods/SecExp/buildings/securityHQ.js
@@ -1,10 +1,10 @@
-App.SecExp.secHub = (function() {
+App.Mods.SecExp.secHub = (function() {
 	return {
-		Init,
+		init,
 		GUI
 	};
 
-	function Init() {
+	function init() {
 		V.SecExp.buildings.secHub = {
 			menials: 0,
 			coldstorage: 0,
@@ -51,8 +51,8 @@ App.SecExp.secHub = (function() {
 			App.UI.DOM.appendNewElement("div", node, "You lack the authority to access more advanced upgrades.", "red");
 		}
 
-		App.UI.DOM.appendNewElement("div", node, `You have ${num(V.SecExp.buildings.secHub.menials)} slaves working in the HQ. ${App.SecExp.Check.reqMenials()} are required and you have ${num(V.menials)} free menial slaves.`);
-		if (V.SecExp.buildings.secHub.menials < App.SecExp.Check.reqMenials()) {
+		App.UI.DOM.appendNewElement("div", node, `You have ${num(V.SecExp.buildings.secHub.menials)} slaves working in the HQ. ${App.Mods.SecExp.Check.reqMenials()} are required and you have ${num(V.menials)} free menial slaves.`);
+		if (V.SecExp.buildings.secHub.menials < App.Mods.SecExp.Check.reqMenials()) {
 			App.UI.DOM.appendNewElement("div", node, "You do not have enough slaves here. You will not receive the full benefit of the installed upgrades.");
 		} else {
 			App.UI.DOM.appendNewElement("div", node, "You have enough slaves to man all security systems.");
@@ -92,12 +92,12 @@ App.SecExp.secHub = (function() {
 				App.UI.DOM.link(
 					"Match the requirement",
 					() => {
-						if (V.menials >= App.SecExp.Check.reqMenials() - V.SecExp.buildings.secHub.menials) {
-							V.menials -= App.SecExp.Check.reqMenials() - V.SecExp.buildings.secHub.menials;
-							V.SecExp.buildings.secHub.menials = App.SecExp.Check.reqMenials();
-						} else if (App.SecExp.Check.reqMenials() < V.SecExp.buildings.secHub.menials) {
-							V.menials += App.SecExp.Check.reqMenials() - V.SecExp.buildings.secHub.menials;
-							V.SecExp.buildings.secHub.menials = App.SecExp.Check.reqMenials();
+						if (V.menials >= App.Mods.SecExp.Check.reqMenials() - V.SecExp.buildings.secHub.menials) {
+							V.menials -= App.Mods.SecExp.Check.reqMenials() - V.SecExp.buildings.secHub.menials;
+							V.SecExp.buildings.secHub.menials = App.Mods.SecExp.Check.reqMenials();
+						} else if (App.Mods.SecExp.Check.reqMenials() < V.SecExp.buildings.secHub.menials) {
+							V.menials += App.Mods.SecExp.Check.reqMenials() - V.SecExp.buildings.secHub.menials;
+							V.SecExp.buildings.secHub.menials = App.Mods.SecExp.Check.reqMenials();
 						} else {
 							V.SecExp.buildings.secHub.menials += V.menials;
 							V.menials = 0;
@@ -109,7 +109,7 @@ App.SecExp.secHub = (function() {
 		}
 
 		App.Events.addParagraph(node, []);
-		switch(App.SecExp.battle.recon()) {
+		switch (App.Mods.SecExp.battle.recon()) {
 			case 0:
 				App.UI.DOM.appendNewElement("div", node, "Your reconnaissance capabilities are very limited. Very little information will be available if the arcology is attacked.");
 				break;
@@ -123,7 +123,7 @@ App.SecExp.secHub = (function() {
 				App.UI.DOM.appendNewElement("div", node, "You have great reconnaissance capabilities. You'll have very accurate information on the enemy if the arcology is attacked.");
 		}
 
-		switch(App.SecExp.battle.deploySpeed()) {
+		switch (App.Mods.SecExp.battle.deploySpeed()) {
 			case 1:
 				App.UI.DOM.appendNewElement("div", node, "You have low readiness. You won't be able to mobilize many troops in time in case of an attack.");
 				break;
@@ -143,7 +143,7 @@ App.SecExp.secHub = (function() {
 		if (V.SecExp.core.authority > 12000) {
 			App.Events.addParagraph(node, []);
 			App.UI.DOM.appendNewElement("h2", node, `Cold Data Storage Facility:`);
-			if (App.SecExp.Check.reqMenials() <= 10) {
+			if (App.Mods.SecExp.Check.reqMenials() <= 10) {
 				App.UI.DOM.appendNewElement("div", node, "Personnel cannot be further reduced.");
 			} else {
 				r = [];
@@ -414,18 +414,18 @@ App.SecExp.secHub = (function() {
 			}
 			text.push("Considering the current upgrades the");
 			if (isSecurity) {
-				text.push(`resting level for security is ${Math.trunc(App.SecExp.Check.secRestPoint() * (Math.clamp(V.SecExp.buildings.secHub.menials, 0, App.SecExp.Check.reqMenials()) / App.SecExp.Check.reqMenials()))}, `);
-				text.push(`while the effective maximum level is ${Math.trunc(App.SecExp.Check.reqMenials() * (Math.clamp(V.SecExp.buildings.secHub.menials, 0, App.SecExp.Check.reqMenials()) / App.SecExp.Check.reqMenials()))}.`);
+				text.push(`resting level for security is ${Math.trunc(App.Mods.SecExp.Check.secRestPoint() * (Math.clamp(V.SecExp.buildings.secHub.menials, 0, App.Mods.SecExp.Check.reqMenials()) / App.Mods.SecExp.Check.reqMenials()))}, `);
+				text.push(`while the effective maximum level is ${Math.trunc(App.Mods.SecExp.Check.reqMenials() * (Math.clamp(V.SecExp.buildings.secHub.menials, 0, App.Mods.SecExp.Check.reqMenials()) / App.Mods.SecExp.Check.reqMenials()))}.`);
 			} else {
-				text.push(`maximum level of crime is ${App.SecExp.Check.crimeCap()}, `);
-				text.push(`while the effective maximum level is ${Math.trunc(Math.clamp(App.SecExp.Check.crimeCap() + (App.SecExp.Check.crimeCap() - App.SecExp.Check.crimeCap() * (V.SecExp.buildings.secHub.menials / App.SecExp.Check.reqMenials())), 0, 100))}.`);
+				text.push(`maximum level of crime is ${App.Mods.SecExp.Check.crimeCap()}, `);
+				text.push(`while the effective maximum level is ${Math.trunc(Math.clamp(App.Mods.SecExp.Check.crimeCap() + (App.Mods.SecExp.Check.crimeCap() - App.Mods.SecExp.Check.crimeCap() * (V.SecExp.buildings.secHub.menials / App.Mods.SecExp.Check.reqMenials())), 0, 100))}.`);
 			}
 			r.append(text.join(" "));
 
 			return r;
 		}
 		function checkStatus(value, authority) {
-			return V.SecExp.buildings.secHub.coldstorage === value && V.SecExp.core.authority >= authority && App.SecExp.Check.reqMenials() > 10;
+			return V.SecExp.buildings.secHub.coldstorage === value && V.SecExp.core.authority >= authority && App.Mods.SecExp.Check.reqMenials() > 10;
 		}
 		function makeLink(text, price, note, type, applyHacking=true) {
 			const r = new DocumentFragment();
@@ -435,7 +435,7 @@ App.SecExp.secHub = (function() {
 					if (applyHacking) {
 						V.PC.skill.hacking++;
 					}
-					switch(type) {
+					switch (type) {
 						case "coldstorage":
 							V.SecExp.buildings.secHub.coldstorage++;
 							break;
diff --git a/src/Mods/SecExp/buildings/transportHub.js b/src/Mods/SecExp/buildings/transportHub.js
index a6263d2bea5d9b94c0f8552e7869374738164854..5877c6d90c51dbcea5531d7d1f62bd8942c72e80 100644
--- a/src/Mods/SecExp/buildings/transportHub.js
+++ b/src/Mods/SecExp/buildings/transportHub.js
@@ -1,4 +1,4 @@
-App.SecExp.transportHub = (function() {
+App.Mods.SecExp.transportHub = (function() {
 	return {
 		Init,
 		GUI
diff --git a/src/Mods/SecExp/buildings/weaponsManufacturing.js b/src/Mods/SecExp/buildings/weaponsManufacturing.js
index 15f2c2f81823d49416ec22d1054c46de65d25178..6eba10ff2a83dcbfc24e178efb2aab5f41010f33 100644
--- a/src/Mods/SecExp/buildings/weaponsManufacturing.js
+++ b/src/Mods/SecExp/buildings/weaponsManufacturing.js
@@ -1,4 +1,4 @@
-App.SecExp.weapManu = (function() {
+App.Mods.SecExp.weapManu = (function() {
 	return {
 		Init,
 		baseTime,
@@ -34,7 +34,7 @@ App.SecExp.weapManu = (function() {
 	 * @returns {object}
 	 */
 	function current(upgradeID) {
-		switch(upgradeID) {
+		switch (upgradeID) {
 			case -3:
 				return {
 					dec: "advanced synthetic alloys", type: "hp",
@@ -181,13 +181,13 @@ App.SecExp.weapManu = (function() {
 			App.UI.DOM.appendNewElement("h2", div, `Menials`);
 			const unitCost = Math.trunc(1000 * V.upgradeMultiplierArcology * (V.SecExp.buildings.weapManu.space/100));
 			let text = [];
-			let links = [];
+			// let links = [];
 
 			// Transferring
 			if (V.SecExp.buildings.weapManu.menials > 0) {
 				text.push(`Assigned here ${V.SecExp.buildings.weapManu.menials === 1 ? `is` : `are`} ${numberWithPluralOne(V.SecExp.buildings.weapManu.menials, 'menial slave')}, working to produce as much equipment as they can.`);
 			}
-			text.push(`You ${V.menials ? `own ${num(V.menials)}` : `don't own any`} free menial slaves. This manufacturing complex is currently housing ${num(V.SecExp.buildings.weapManu.menials)}/${num(V.SecExp.buildings.weapManu.space)} menial slaves.`);
+			text.push(`You ${V.menials ? `own ${num(V.menials)}` : `don't own any`} free menial slaves. This manufacturing complex is currently housing ${num(V.SecExp.buildings.weapManu.menials)} out of ${num(V.SecExp.buildings.weapManu.space)} possible menial slaves.`);
 			div.append(text.join(' '));
 			text = [];
 
@@ -216,13 +216,14 @@ App.SecExp.weapManu = (function() {
 					}
 				}
 			}
-			if (V.SecExp.buildings.weapManu.menials) {
-				links.push(App.UI.DOM.link("Transfer out all menial slaves", () => {
-					V.menials += V.SecExp.buildings.weapManu.menials;
-					V.SecExp.buildings.weapManu.menials = 0;
-					App.UI.reload();
-				}));
-			}
+			// FIXME: this is unused
+			// if (V.SecExp.buildings.weapManu.menials) {
+			// 	links.push(App.UI.DOM.link("Transfer out all menial slaves", () => {
+			// 		V.menials += V.SecExp.buildings.weapManu.menials;
+			// 		V.SecExp.buildings.weapManu.menials = 0;
+			// 		App.UI.reload();
+			// 	}));
+			// }
 
 			// Housing
 			App.UI.DOM.appendNewElement("div", div, `There is enough room in the complex to build housing, enough to give an additional 100 workers a place to sleep and relax.`);
@@ -250,7 +251,7 @@ App.SecExp.weapManu = (function() {
 							link: `Invest in automating the complex`,
 							cost: 10000 * V.SecExp.buildings.weapManu.productivity,
 							handler: () => V.PC.skill.engineering += 0.1,
-							note: ` and will increase income in addition to speeding up upgrade production`,
+							notes: [`will increase income in addition to speeding up upgrade production`],
 						},
 						{
 							value: 2,
@@ -259,7 +260,7 @@ App.SecExp.weapManu = (function() {
 							link: `Invest in automating the complex`,
 							cost: 10000 * V.SecExp.buildings.weapManu.productivity,
 							handler: () => V.PC.skill.engineering += 0.1,
-							note: ` and will increase income in addition to speeding up upgrade production`,
+							notes: [`will increase income in addition to speeding up upgrade production`],
 						},
 						{
 							value: 3,
@@ -268,7 +269,7 @@ App.SecExp.weapManu = (function() {
 							link: `Invest in automating the complex`,
 							cost: 10000 * V.SecExp.buildings.weapManu.productivity,
 							handler: () => V.PC.skill.engineering += 0.1,
-							note: ` and will increase income in addition to speeding up upgrade production`,
+							notes: [`will increase income in addition to speeding up upgrade production`],
 						},
 						{
 							value: 4,
@@ -277,7 +278,7 @@ App.SecExp.weapManu = (function() {
 							link: `Invest in automating the complex`,
 							cost: 10000 * V.SecExp.buildings.weapManu.productivity,
 							handler: () => V.PC.skill.engineering += 0.1,
-							note: ` and will increase income in addition to speeding up upgrade production`,
+							notes: [`will increase income in addition to speeding up upgrade production`],
 						},
 						{
 							value: 5,
@@ -296,7 +297,7 @@ App.SecExp.weapManu = (function() {
 							link: `Invest in research and development`,
 							cost: 10000 * V.SecExp.buildings.weapManu.lab,
 							handler: () => V.PC.skill.engineering += 0.1,
-							note: ` and will increase income in addition to unlocking more advanced upgrades`,
+							notes: [`will increase income in addition to unlocking more advanced upgrades`],
 						},
 						{
 							value: 2,
@@ -305,7 +306,7 @@ App.SecExp.weapManu = (function() {
 							link: `Invest in research and development`,
 							cost: 10000 * V.SecExp.buildings.weapManu.lab,
 							handler: () => V.PC.skill.engineering += 0.1,
-							note: ` and will increase income in addition to unlocking more advanced upgrades`,
+							notes: [`will increase income in addition to unlocking more advanced upgrades`],
 						},
 						{
 							value: 3,
@@ -441,16 +442,16 @@ App.SecExp.weapManu = (function() {
 			}
 
 			App.UI.DOM.appendNewElement("h3", div, `Troops`);
-			if (V.SF.Toggle && V.SF.Active >= 1
-				&& (App.SecExp.getAppliedUpgrades('human').attack >= 4
-					|| App.SecExp.getAppliedUpgrades('human').hp >= 4
-					|| App.SecExp.getAppliedUpgrades('human').morale >= 40
-					|| App.SecExp.getAppliedUpgrades('human').defense >= 4)) {
+			if (V.SF.Toggle && V.SF.Active >= 1 &&
+				(App.Mods.SecExp.getAppliedUpgrades('human').attack >= 4 ||
+					App.Mods.SecExp.getAppliedUpgrades('human').hp >= 4 ||
+					App.Mods.SecExp.getAppliedUpgrades('human').morale >= 40 ||
+					App.Mods.SecExp.getAppliedUpgrades('human').defense >= 4)) {
 				div.append(`You have fully upgraded your human troops.`);
-			} else if (App.SecExp.getAppliedUpgrades('human').attack >= 2
-				|| App.SecExp.getAppliedUpgrades('human').hp >= 2
-				|| App.SecExp.getAppliedUpgrades('human').morale >= 20
-				|| App.SecExp.getAppliedUpgrades('human').defense >= 2) {
+			} else if (App.Mods.SecExp.getAppliedUpgrades('human').attack >= 2 ||
+				App.Mods.SecExp.getAppliedUpgrades('human').hp >= 2 ||
+				App.Mods.SecExp.getAppliedUpgrades('human').morale >= 20 ||
+				App.Mods.SecExp.getAppliedUpgrades('human').defense >= 2) {
 				if (V.SF.Toggle && V.SF.Active >= 1) {
 					const reasons = [];
 					if (V.SF.Squad.Drugs < 8) {
@@ -484,18 +485,18 @@ App.SecExp.weapManu = (function() {
 			}
 
 			if (V.SF.Toggle && V.SF.Active > 0) {
-				if (V.SecExp.buildings.weapManu.lab > 1
-					&& V.SecExp.edicts.SFSupportLevel > 1
-					&& V.SF.Squad.Firebase > 6) {
+				if (V.SecExp.buildings.weapManu.lab > 1 &&
+					V.SecExp.edicts.SFSupportLevel > 1 &&
+					V.SF.Squad.Firebase > 6) {
 					div.append(purchase(6));
 				}
-				if (V.SecExp.buildings.weapManu.lab > 1
-					&& V.SecExp.edicts.SFSupportLevel > 3
-					&& V.SF.Squad.Firebase > 7) {
+				if (V.SecExp.buildings.weapManu.lab > 1 &&
+					V.SecExp.edicts.SFSupportLevel > 3 &&
+					V.SF.Squad.Firebase > 7) {
 					div.append(purchase(7));
 				}
-				if (V.SecExp.buildings.weapManu.lab > 2
-					&& V.SecExp.edicts.SFSupportLevel > 4) {
+				if (V.SecExp.buildings.weapManu.lab > 2 &&
+					V.SecExp.edicts.SFSupportLevel > 4) {
 					div.append(purchase(8));
 				}
 			}
diff --git a/src/Mods/SecExp/events/conflictHandler.js b/src/Mods/SecExp/events/conflictHandler.js
index f546db5ae65db1d2c7a74b437da66a755bfe29a8..e66f523ae4e19e4414ce83cd7f189c17baeaab8e 100644
--- a/src/Mods/SecExp/events/conflictHandler.js
+++ b/src/Mods/SecExp/events/conflictHandler.js
@@ -84,7 +84,7 @@ App.Events.conflictHandler = function() {
 	if (inBattle && V.SecExp.war.result === 1 || V.SecExp.war.result === -1) { // bribery/surrender check
 		showProgress(`${V.SecExp.war.result === 1 ? 'Bribery' : 'Surrender'} chosen`);
 		if (inBattle && V.SecExp.war.result === 1) {
-			if (V.cash >= App.SecExp.battle.bribeCost()) { // if there's enough cash there's a 10% chance bribery fails. If there isn't there's instead a 50% chance it fails
+			if (V.cash >= App.Mods.SecExp.battle.bribeCost()) { // if there's enough cash there's a 10% chance bribery fails. If there isn't there's instead a 50% chance it fails
 				if (V.SecExp.war.attacker.type === "freedom fighters" && random(1, 100) <= 50 || random(1, 100) <= 10) {
 					V.SecExp.war.result = 0;
 				}
@@ -120,7 +120,7 @@ App.Events.conflictHandler = function() {
 			}
 		}
 
-		const commanderEffectiveness = App.SecExp.commanderEffectiveness("handler");
+		const commanderEffectiveness = App.Mods.SecExp.commanderEffectiveness("handler");
 		morale.slaves += commanderEffectiveness.slaveMod;
 		morale.militia += commanderEffectiveness.militiaMod;
 		morale.mercs += commanderEffectiveness.militiaMod;
@@ -271,17 +271,17 @@ App.Events.conflictHandler = function() {
 		}
 		if (V.SecExp.war.irregulars > 0) {
 			irregularMod = Math.trunc(irregularMod);
-			unitData = App.SecExp.getIrregularUnit("militia", V.SecExp.war.irregulars, V.SecExp.war.attacker.equip);
+			unitData = App.Mods.SecExp.getIrregularUnit("militia", V.SecExp.war.irregulars, V.SecExp.war.attacker.equip);
 			attack.irregulars = unitData.attack * irregularMod * 0.80;
 			defense.irregulars = unitData.defense * irregularMod * 0.80;
 			hp.irregulars = unitData.hp;
 		}
 	}
 
-	for (const type of Array.from(App.SecExp.unit.list().keys())) {
+	for (const type of Array.from(App.Mods.SecExp.unit.list().keys())) {
 		for (const unit of V.SecExp.units[type].squads) {
-			if (App.SecExp.unit.isDeployed(unit)) {
-				unitData = App.SecExp.getUnit(type, unit);
+			if (App.Mods.SecExp.unit.isDeployed(unit)) {
+				unitData = App.Mods.SecExp.getUnit(type, unit);
 				attack.base += unitData.attack * unitData.attack;
 				defense.base += unitData.defense * unitData.defense;
 				hp.base += unitData.hp;
@@ -290,7 +290,7 @@ App.Events.conflictHandler = function() {
 	}
 
 	if (activeSF && (inBattle && V.SecExp.war.deploySF || inRebellion)) {
-		unitData = App.SecExp.getUnit("SF");
+		unitData = App.Mods.SecExp.getUnit("SF");
 		attack.SF = unitData.attack;
 		defense.SF = unitData.defense;
 		hp.SF = unitData.hp;
@@ -313,23 +313,23 @@ App.Events.conflictHandler = function() {
 		morale.mercs = Math.clamp(morale.mercs, 0.5, 1.5);
 		morale.SF = Math.clamp(morale.SF, 0.5, 1.5);
 	}
-	const moraleTroopMod = App.SecExp.troopDiffAdjust().pc;
+	const moraleTroopMod = App.Mods.SecExp.troopDiffAdjust().pc;
 	const modifierSF = activeSF ? 1 : 0;
 
 	if (inBattle) {
-		morale.total = (App.SecExp.BaseDroneUnit.morale * App.SecExp.battle.deployedUnits('bots') + App.SecExp.BaseMilitiaUnit.morale * morale.militia * App.SecExp.battle.deployedUnits('militia') + App.SecExp.BaseSlaveUnit.morale * morale.slaves * App.SecExp.battle.deployedUnits('slaves') + App.SecExp.BaseMercUnit.morale * morale.mercs * App.SecExp.battle.deployedUnits('mercs') + App.SecExp.BaseSpecialForcesUnit.morale * V.SecExp.war.deploySF * morale.SF) / (App.SecExp.battle.deployedUnits('bots') + App.SecExp.battle.deployedUnits('militia') + App.SecExp.battle.deployedUnits('slaves') + App.SecExp.battle.deployedUnits('mercs') + V.SecExp.war.deploySF);
+		morale.total = (App.Mods.SecExp.BaseDroneUnit.morale * App.Mods.SecExp.battle.deployedUnits('bots') + App.Mods.SecExp.BaseMilitiaUnit.morale * morale.militia * App.Mods.SecExp.battle.deployedUnits('militia') + App.Mods.SecExp.BaseSlaveUnit.morale * morale.slaves * App.Mods.SecExp.battle.deployedUnits('slaves') + App.Mods.SecExp.BaseMercUnit.morale * morale.mercs * App.Mods.SecExp.battle.deployedUnits('mercs') + App.Mods.SecExp.BaseSpecialForcesUnit.morale * V.SecExp.war.deploySF * morale.SF) / (App.Mods.SecExp.battle.deployedUnits('bots') + App.Mods.SecExp.battle.deployedUnits('militia') + App.Mods.SecExp.battle.deployedUnits('slaves') + App.Mods.SecExp.battle.deployedUnits('mercs') + V.SecExp.war.deploySF);
 		if (V.SecExp.buildings.barracks) {
 			morale.total += morale.total * V.SecExp.buildings.barracks.luxury * 0.05;	// barracks bonus
 		}
 	} else {
-		morale.total = (App.SecExp.BaseDroneUnit.morale * App.SecExp.battle.deployedUnits('bots') + App.SecExp.BaseMilitiaUnit.morale * App.SecExp.battle.deployedUnits('militia') + App.SecExp.BaseSlaveUnit.morale * App.SecExp.battle.deployedUnits('slaves') + App.SecExp.BaseMercUnit.morale * App.SecExp.battle.deployedUnits('mercs') + App.SecExp.BaseSpecialForcesUnit.morale * modifierSF) / (App.SecExp.battle.deployedUnits('bots') + App.SecExp.battle.deployedUnits('militia') + App.SecExp.battle.deployedUnits('slaves') + App.SecExp.battle.deployedUnits('mercs') + modifierSF);
+		morale.total = (App.Mods.SecExp.BaseDroneUnit.morale * App.Mods.SecExp.battle.deployedUnits('bots') + App.Mods.SecExp.BaseMilitiaUnit.morale * App.Mods.SecExp.battle.deployedUnits('militia') + App.Mods.SecExp.BaseSlaveUnit.morale * App.Mods.SecExp.battle.deployedUnits('slaves') + App.Mods.SecExp.BaseMercUnit.morale * App.Mods.SecExp.battle.deployedUnits('mercs') + App.Mods.SecExp.BaseSpecialForcesUnit.morale * modifierSF) / (App.Mods.SecExp.battle.deployedUnits('bots') + App.Mods.SecExp.battle.deployedUnits('militia') + App.Mods.SecExp.battle.deployedUnits('slaves') + App.Mods.SecExp.battle.deployedUnits('mercs') + modifierSF);
 		morale.total += morale.total * (V.SecExp.buildings.barracks ? V.SecExp.buildings.barracks.luxury * 0.05 : 1);	// barracks bonus
 	}
 	morale.total *= moraleTroopMod;
 	if (inBattle) {
-		baseHp = (App.SecExp.BaseDroneUnit.hp * App.SecExp.battle.deployedUnits('bots') + App.SecExp.BaseMilitiaUnit.hp * App.SecExp.battle.deployedUnits('militia') + App.SecExp.BaseSlaveUnit.hp * App.SecExp.battle.deployedUnits('slaves') + App.SecExp.BaseMercUnit.hp * App.SecExp.battle.deployedUnits('mercs') + App.SecExp.BaseSpecialForcesUnit.hp * V.SecExp.war.deploySF) / (App.SecExp.battle.deployedUnits('bots') + App.SecExp.battle.deployedUnits('militia') + App.SecExp.battle.deployedUnits('slaves') + App.SecExp.battle.deployedUnits('mercs') + V.SecExp.war.deploySF);
+		baseHp = (App.Mods.SecExp.BaseDroneUnit.hp * App.Mods.SecExp.battle.deployedUnits('bots') + App.Mods.SecExp.BaseMilitiaUnit.hp * App.Mods.SecExp.battle.deployedUnits('militia') + App.Mods.SecExp.BaseSlaveUnit.hp * App.Mods.SecExp.battle.deployedUnits('slaves') + App.Mods.SecExp.BaseMercUnit.hp * App.Mods.SecExp.battle.deployedUnits('mercs') + App.Mods.SecExp.BaseSpecialForcesUnit.hp * V.SecExp.war.deploySF) / (App.Mods.SecExp.battle.deployedUnits('bots') + App.Mods.SecExp.battle.deployedUnits('militia') + App.Mods.SecExp.battle.deployedUnits('slaves') + App.Mods.SecExp.battle.deployedUnits('mercs') + V.SecExp.war.deploySF);
 	} else {
-		baseHp = (App.SecExp.BaseDroneUnit.hp * App.SecExp.battle.deployedUnits('bots') + App.SecExp.BaseMilitiaUnit.hp * App.SecExp.battle.deployedUnits('militia') + App.SecExp.BaseSlaveUnit.hp * App.SecExp.battle.deployedUnits('slaves') + App.SecExp.BaseMercUnit.hp * App.SecExp.battle.deployedUnits('mercs') + App.SecExp.BaseSpecialForcesUnit.hp * modifierSF) / (App.SecExp.battle.deployedUnits('bots') + App.SecExp.battle.deployedUnits('militia') + App.SecExp.battle.deployedUnits('slaves') + App.SecExp.battle.deployedUnits('mercs') + modifierSF);
+		baseHp = (App.Mods.SecExp.BaseDroneUnit.hp * App.Mods.SecExp.battle.deployedUnits('bots') + App.Mods.SecExp.BaseMilitiaUnit.hp * App.Mods.SecExp.battle.deployedUnits('militia') + App.Mods.SecExp.BaseSlaveUnit.hp * App.Mods.SecExp.battle.deployedUnits('slaves') + App.Mods.SecExp.BaseMercUnit.hp * App.Mods.SecExp.battle.deployedUnits('mercs') + App.Mods.SecExp.BaseSpecialForcesUnit.hp * modifierSF) / (App.Mods.SecExp.battle.deployedUnits('bots') + App.Mods.SecExp.battle.deployedUnits('militia') + App.Mods.SecExp.battle.deployedUnits('slaves') + App.Mods.SecExp.battle.deployedUnits('mercs') + modifierSF);
 	}
 
 	// calculates opposing army stats
@@ -353,22 +353,22 @@ App.Events.conflictHandler = function() {
 	if (inRebellion) {
 		if (V.SecExp.war.type.includes("Slave")) {
 			rebellingSlaves = 1;
-			unitData = App.SecExp.getIrregularUnit("slaves", V.SecExp.war.attacker.troops, V.SecExp.war.attacker.equip);
+			unitData = App.Mods.SecExp.getIrregularUnit("slaves", V.SecExp.war.attacker.troops, V.SecExp.war.attacker.equip);
 		} else {
 			rebellingMilitia = 1;
-			unitData = App.SecExp.getIrregularUnit("militia", V.SecExp.war.attacker.troops, V.SecExp.war.attacker.equip);
+			unitData = App.Mods.SecExp.getIrregularUnit("militia", V.SecExp.war.attacker.troops, V.SecExp.war.attacker.equip);
 		}
 		enemyAttack += unitData.attack * armyMod;
 		enemyDefense += unitData.defense * armyMod;
 		enemyHp += unitData.hp;
 
-		for (const [type] of Array.from(App.SecExp.unit.list()).slice(1)) {
+		for (const [type] of Array.from(App.Mods.SecExp.unit.list()).slice(1)) {
 			if (rebellingSlaves === 1 && type === "slaves" || rebellingMilitia === 1 && type === "militia") {
 				for (const unit of V.SecExp.units[type].squads) {
 					if (V.SecExp.war.rebellingID.includes(unit.ID)) {
 						V.SecExp.war.attacker.troops += unit.troops;
 						unit.loyalty = 0;
-						unitData = App.SecExp.getUnit(type, unit);
+						unitData = App.Mods.SecExp.getUnit(type, unit);
 						enemyAttack += unitData.attack;
 						enemyDefense += unitData.defense;
 						enemyHp += unitData.hp;
@@ -379,18 +379,18 @@ App.Events.conflictHandler = function() {
 	}
 
 	// calculates opposing army stats
-	const enemyMoraleTroopMod = App.SecExp.troopDiffAdjust().enemy;
+	const enemyMoraleTroopMod = App.Mods.SecExp.troopDiffAdjust().enemy;
 	if (inBattle) {
-		unitData = App.SecExp.getEnemyUnit(V.SecExp.war.attacker.type, V.SecExp.war.attacker.troops, V.SecExp.war.attacker.equip);
+		unitData = App.Mods.SecExp.getEnemyUnit(V.SecExp.war.attacker.type, V.SecExp.war.attacker.troops, V.SecExp.war.attacker.equip);
 		enemyAttack = unitData.attack * armyMod;
 		enemyDefense = unitData.defense * armyMod;
 		enemyMorale = unitData.morale * morale.enemy * enemyMoraleTroopMod;
 		enemyHp = unitData.hp;
 		enemyBaseHp = unitData.hp / V.SecExp.war.attacker.troops;
 	} else {
-		enemyMorale = 1.5 * (App.SecExp.BaseMilitiaUnit.morale * rebellingMilitia + App.SecExp.BaseSlaveUnit.morale * rebellingSlaves) / (rebellingMilitia + rebellingSlaves);
+		enemyMorale = 1.5 * (App.Mods.SecExp.BaseMilitiaUnit.morale * rebellingMilitia + App.Mods.SecExp.BaseSlaveUnit.morale * rebellingSlaves) / (rebellingMilitia + rebellingSlaves);
 		enemyMorale *= enemyMoraleTroopMod;
-		enemyBaseHp = (App.SecExp.BaseMilitiaUnit.hp * rebellingMilitia + App.SecExp.BaseSlaveUnit.hp * rebellingSlaves) / (rebellingMilitia + rebellingSlaves);
+		enemyBaseHp = (App.Mods.SecExp.BaseMilitiaUnit.hp * rebellingMilitia + App.Mods.SecExp.BaseSlaveUnit.hp * rebellingSlaves) / (rebellingMilitia + rebellingSlaves);
 	}
 	enemyMorale = Math.round(enemyMorale);
 
@@ -441,7 +441,7 @@ App.Events.conflictHandler = function() {
 		App.UI.DOM.appendNewElement("div", node, `Difficulty: ${difficultyText}. Modifier: x${V.SecExp.settings.difficulty}`);
 
 		App.UI.DOM.appendNewElement("div", node, `Army`, "underline");
-		App.UI.DOM.appendNewElement("div", node, `Deployed troops: ${num(App.SecExp.battle.troopCount())}`);
+		App.UI.DOM.appendNewElement("div", node, `Deployed troops: ${num(App.Mods.SecExp.battle.troopCount())}`);
 		App.UI.DOM.appendNewElement("div", node, `Attack: ${num(attack.total)}.`);
 		if (attack.SF) {
 			App.UI.DOM.appendNewElement("div", node, `Base: ${attack.base}`, "indent");
diff --git a/src/Mods/SecExp/events/conflictOptions.js b/src/Mods/SecExp/events/conflictOptions.js
index 34644dfb650dbeac2ec14f8ca80e472bb1d076aa..8296d64c40c343305b76566c6f9012716f627e07 100644
--- a/src/Mods/SecExp/events/conflictOptions.js
+++ b/src/Mods/SecExp/events/conflictOptions.js
@@ -24,7 +24,7 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 				if (V.SecExp.battles.victories + V.SecExp.battles.losses > 0) {
 					r.push(`The ominous message dominates the screens of your office, and ${V.assistant.name} quickly gathers all information available to prepare for battle.`);
 					if (V.SecExp.war.attacker.type === "raiders") {
-						if (App.SecExp.battle.recon() >= 1) {
+						if (App.Mods.SecExp.battle.recon() >= 1) {
 							r.push(`A disorganized horde of raiders is coming to your city. To such jackals your arcology surely looks like an appetizing morsel.`);
 							r.push(`Fortunately you knew of their coming, thanks to your recon systems.`);
 						} else {
@@ -35,7 +35,7 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 						App.UI.DOM.makeElement("span", `are roaming gangs of bandits, preying on the vulnerable supply lines of Free Cities and old world nations. They are rarely equipped with decent armaments and even more rarely have any formal military training, but they make up for that with high mobility and numbers.`);
 						r.push(div);
 					} else if (V.SecExp.war.attacker.type === "free city") {
-						if (App.SecExp.battle.recon() >= 1) {
+						if (App.Mods.SecExp.battle.recon() >= 1) {
 							r.push(`A menacing column of slavers and hired mercenaries is coming to your city. Another free city is ready to use their best tools to hit a dangerous competitor where it hurts.`);
 							r.push(`Fortunately you knew of their coming, thanks to your recon systems.`);
 						} else {
@@ -46,7 +46,7 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 						App.UI.DOM.makeElement("span", `are usually composed of mercenaries hired to take down sensible supplies or infrastructure in order to damage the enemies of their contractor. They have on average good equipment and training, together with decent mobility, making them a formidable force. Their biggest weakness however is their relatively low numbers.`);
 						r.push(div);
 					} else if (V.SecExp.war.attacker.type === "freedom fighters") {
-						if (App.SecExp.battle.recon() >= 1) {
+						if (App.Mods.SecExp.battle.recon() >= 1) {
 							r.push(`A dangerous looking army of guerrillas is gathering just outside the arcology. Fanatics and idealists armed with dead men's words and hope, set on erasing your fledgling empire.`);
 							r.push(`Fortunately you knew of their coming, thanks to your recon systems.`);
 						} else {
@@ -57,7 +57,7 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 						App.UI.DOM.makeElement("span", `are groups of individuals fighting to rid the planet of "evils" such as the Free Cities and their way of life. Lacking the strength to assault one directly they fight guerrilla style slowly starving to death their enemies. They are rarely well equipped, but with good training and mobility they are not a threat that can be taken lightly.`);
 						r.push(div);
 					} else if (V.SecExp.war.attacker.type === "old world") {
-						if (App.SecExp.battle.recon() >= 1) {
+						if (App.Mods.SecExp.battle.recon() >= 1) {
 							r.push(`A disciplined yet dusty, scruffy old world army is approaching the confines of your arcology. There's nothing better than a good war to unite the electorate and your arcology is just the perfect target.`);
 							r.push(`Fortunately you knew of their coming, thanks to your recon systems.`);
 						} else {
@@ -79,7 +79,7 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 					r.push(`Your assistant interrupted your rest to bring the grim news. You quickly rush to your console, where you can see the satellite images coming in of the force about to crash against your arcology. It's not the first time your armies fought for the survival of your empire, but this time it seems it will be a fight for life or death.`);
 				}
 				if (V.SecExp.war.attacker.type === "raiders") {
-					if (App.SecExp.battle.recon() >= 1) {
+					if (App.Mods.SecExp.battle.recon() >= 1) {
 						r.push(`A massive, disorganized horde of raiders is coming to your city. It seems a warlord of the wastelands amassed enough men to try and obtain a slice of territory of his own; if he's not defeated there won't be a tomorrow for the arcology.`);
 						r.push(`Fortunately you knew of their coming, thanks to your recon systems.`);
 					} else {
@@ -87,7 +87,7 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 					}
 					r.push(App.UI.DOM.makeElement("div", `Raiders are roaming gangs of bandits, preying on the vulnerable supply lines of Free Cities and old world nations. They are rarely equipped with decent armaments and even more rarely have any formal military training, but they make up for that with high mobility and numbers.`));
 				} else if (V.SecExp.war.attacker.type === "free city") {
-					if (App.SecExp.battle.recon() >= 1) {
+					if (App.Mods.SecExp.battle.recon() >= 1) {
 						r.push(`A massive, menacing column of slavers and hired mercenaries is coming to your city. The quantity of money invested in this assault is staggering; it seems you made some very powerful enemies. If they're not defeated your story will end this day.`);
 						r.push(`Fortunately you knew of their coming, thanks to your recon systems.`);
 					} else {
@@ -95,7 +95,7 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 					}
 					r.push(App.UI.DOM.makeElement("div", `Free City expeditions are usually composed of mercenaries hired to take down sensible supplies or infrastructure in order to damage the enemies of their contractor. They have, on average, good equipment and training, together with decent mobility, making them a formidable force. Their biggest weakness, however, is their relatively low numbers.`));
 				} else if (V.SecExp.war.attacker.type === "freedom fighters") {
-					if (App.SecExp.battle.recon() >= 1) {
+					if (App.Mods.SecExp.battle.recon() >= 1) {
 						r.push(`A massive, dangerous army of guerrillas is gathering just outside the arcology. A huge ocean of fanatics and idealists armed with dead men's words and hope, set on erasing your fledgling empire once and for all. And this time they won't stop until your body is burnt to a crisp.`);
 						r.push(`Fortunately you knew of their coming, thanks to your recon systems.`);
 					} else {
@@ -103,7 +103,7 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 					}
 					r.push(App.UI.DOM.makeElement("div", `Freedom Fighters are groups of individuals fighting to rid the planet of "evils" such as the Free Cities and their way of life. Lacking the strength to assault one directly, they fight guerrilla style, slowly starving to death their enemies. They are rarely well equipped, but with good training and mobility they are not a threat that can be taken lightly.`));
 				} else if (V.SecExp.war.attacker.type === "old world") {
-					if (App.SecExp.battle.recon() >= 1) {
+					if (App.Mods.SecExp.battle.recon() >= 1) {
 						r.push(`A massive, disciplined old world army is approaching the confines of your arcology. It seems one of the nations of the old world is determined to put your arcology to rest once and for all or die trying.`);
 						r.push(`Fortunately you knew of their coming, thanks to your recon systems.`);
 					} else {
@@ -143,11 +143,11 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 			} else {
 				r.push(App.UI.DOM.makeElement("span", `Error: failed to read terrain.`, "red"), `${V.SecExp.war.terrain} reads: ${V.SecExp.war.terrain}.`);
 			}
-			if (App.SecExp.battle.recon() === 3) {
+			if (App.Mods.SecExp.battle.recon() === 3) {
 				r.push(`Your recon capabilities are top notch. The information collected will be most likely correct or very close to be so:`);
-			} else if (App.SecExp.battle.recon() === 2) {
+			} else if (App.Mods.SecExp.battle.recon() === 2) {
 				r.push(`Your recon capabilities are decent. The information collected will be mostly close to the truth:`);
-			} else if (App.SecExp.battle.recon() === 1) {
+			} else if (App.Mods.SecExp.battle.recon() === 1) {
 				r.push(`Your recon capabilities are fairly low. The information collected will be quite inaccurate:`);
 			} else {
 				r.push(`Your recon capabilities are almost non-existent. The information collected will be wild guesses at best:`);
@@ -274,7 +274,7 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 			} else {
 				r.push(`Save current`);
 			}
-			if (App.SecExp.battle.deployedUnits() > 0) {
+			if (App.Mods.SecExp.battle.deployedUnits() > 0) {
 				linkArray.push(
 					App.UI.DOM.link(
 						`Clear current`,
@@ -305,9 +305,9 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 			node.append("Roster: ", App.UI.DOM.generateLinksStrip(linkArray));
 
 			// troop deployment
-			if (App.SecExp.battle.deployableUnits() > 0) {
+			if (App.Mods.SecExp.battle.deployableUnits() > 0) {
 				r.push(`With your current readiness level you can send an additional`);
-				r.push(App.UI.DOM.makeElement("span", String(App.SecExp.battle.deployableUnits()), "strong"));
+				r.push(App.UI.DOM.makeElement("span", String(App.Mods.SecExp.battle.deployableUnits()), "strong"));
 				r.push(`units.`);
 			}
 		} else {
@@ -337,7 +337,7 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 				App.Events.addParagraph(node, r);
 				r = [];
 				let rebelling = [];
-				for (const squad of App.SecExp.unit.squads("human")) {
+				for (const squad of App.Mods.SecExp.unit.squads("human")) {
 					if (squad.active === 1 && (V.SecExp.war.rebellingID.includes(squad.ID))) {
 						rebelling.push(squad.platoonName);
 					}
@@ -348,7 +348,7 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 			if (V.arcologyUpgrade.drones === 1) {
 				defending.push(`Your security drones`);
 			}
-			for (const squad of App.SecExp.unit.squads("human")) {
+			for (const squad of App.Mods.SecExp.unit.squads("human")) {
 				if (squad.active === 1 && (!V.SecExp.war.rebellingID.includes(squad.ID))) {
 					defending.push(squad.platoonName);
 				}
@@ -431,19 +431,19 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 			}
 		}
 
-		node.append(App.SecExp.unit.replenishAll());
+		node.append(App.Mods.SecExp.unit.replenishAll());
 		if (isBattle) {
-			if (App.SecExp.battle.deployableUnits() === 0) {
+			if (App.Mods.SecExp.battle.deployableUnits() === 0) {
 				App.UI.DOM.appendNewElement("div", node, `Unit roster full.`, "strong");
 			}
-			if (App.SecExp.unit.squads().length > 0) {
+			if (App.Mods.SecExp.unit.squads().length > 0) {
 				options = new App.UI.OptionsGroup();
 				options.addOption("Unit descriptions are", "unitDescriptions", V.SecExp.settings)
 					.addValueList([["Abbreviated", 1], ["Summarized", 0]]);
 				node.append(options.render());
 
 				const tabBar = new App.UI.Tabs.TabBar("SecExpAttackOptions");
-				for (const [u] of App.SecExp.unit.list()) {
+				for (const [u] of App.Mods.SecExp.unit.list()) {
 					if (V.SecExp.units[u].squads.length > 0) {
 						tabBar.addTab(capFirstChar(u), u, unitTab(u));
 					}
@@ -454,16 +454,16 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 
 		options = new App.UI.OptionsGroup();
 		option = options.addCustomOption(isBattle ? "Send your orders" : "Actions");
-		if (isBattle && App.SecExp.battle.deployedUnits() > 0 || !isBattle) {
+		if (isBattle && App.Mods.SecExp.battle.deployedUnits() > 0 || !isBattle) {
 			option.addButton(isBattle ? `Deploy troops` : `Proceed`, () => {
 				V.SecExp.war.result = 4; // Sets to a value outside accepted range (-3, 3) to avoid evaluation problems
 				V.SecExp.war.foughtThisWeek = 1;
 			}, `conflictHandler`);
-		} else if (isBattle && App.SecExp.battle.deployedUnits() === 0) {
+		} else if (isBattle && App.Mods.SecExp.battle.deployedUnits() === 0) {
 			App.UI.DOM.appendNewElement("div", node, `You need at least a unit in your roster to proceed to battle.`, "red");
 		}
 		if (isBattle) {
-			option.addButton(`Attempt to bribe (approximately ${cashFormat(Math.round(App.SecExp.battle.bribeCost() * (1 + either(-1, 1) * random(2) * 0.1)))})`, () => {
+			option.addButton(`Attempt to bribe (approximately ${cashFormat(Math.round(App.Mods.SecExp.battle.bribeCost() * (1 + either(-1, 1) * random(2) * 0.1)))})`, () => {
 				V.SecExp.war.result = 1;
 				V.SecExp.war.foughtThisWeek = 1;
 			}, `conflictHandler`);
@@ -482,7 +482,7 @@ App.Events.conflictOptions = class conflictOptions extends App.Events.BaseEvent
 		function unitTab(type) {
 			const frag = new DocumentFragment();
 			for (const u of V.SecExp.units[type].squads.filter(s => s.active === 1 && s.troops > 0)) {
-				App.UI.DOM.appendNewElement("div", frag, App.SecExp.unit.describe(u, true));
+				App.UI.DOM.appendNewElement("div", frag, App.Mods.SecExp.unit.describe(u, true));
 			}
 			return frag;
 		}
diff --git a/src/Mods/SecExp/events/conflictReport.js b/src/Mods/SecExp/events/conflictReport.js
index 1a8487476db1adb090c5cc6f70201fb4b1bc72e4..c09d4c15d40cf9753e3352eae440de6c57f6a37b 100644
--- a/src/Mods/SecExp/events/conflictReport.js
+++ b/src/Mods/SecExp/events/conflictReport.js
@@ -79,7 +79,7 @@ App.Events.conflictReport = function() {
 	}
 
 	if (V.SecExp.war.result !== 1 && V.SecExp.war.result !== 0 && V.SecExp.war.result !== -1) {
-		r.push(`Our defense forces, ${num(App.SecExp.battle.troopCount())} strong,`);
+		r.push(`Our defense forces, ${num(App.Mods.SecExp.battle.troopCount())} strong,`);
 		if (inBattle) {
 			r.push(`clashed with them`);
 			if (V.SecExp.war.terrain === "urban") {
@@ -119,7 +119,7 @@ App.Events.conflictReport = function() {
 		}
 		r.push(`${allKilled ? '' : 'themselves'}.`);
 		if (inRebellion) {
-			App.SecExp.slavesDamaged(V.SecExp.war.attacker.losses);
+			App.Mods.SecExp.slavesDamaged(V.SecExp.war.attacker.losses);
 		}
 
 		if (V.SecExp.war.result === 3) {
@@ -281,7 +281,7 @@ App.Events.conflictReport = function() {
 					V.lowerClass -= random(10, 30);
 				}
 				repX((result === 3 ? random(800, 1000) : random(600, 180)), "war");
-				App.SecExp.authorityX(result === 3 ? random(800, 1000) : random(600, 800));
+				App.Mods.SecExp.authorityX(result === 3 ? random(800, 1000) : random(600, 800));
 			} else {
 				if (result === 3) {
 					r.push("You were also able to capture");
@@ -307,16 +307,16 @@ App.Events.conflictReport = function() {
 				}
 				if (V.SecExp.war.attacker.type === "raiders") {
 					repX((result === 3 ? 4000 : 1000) * majorBattleMod, "war");
-					App.SecExp.authorityX((result === 3 ? 800 : 200) * majorBattleMod);
+					App.Mods.SecExp.authorityX((result === 3 ? 800 : 200) * majorBattleMod);
 				} else if (V.SecExp.war.attacker.type === "free city") {
 					repX((result === 3 ? 6000 : 1500) * majorBattleMod, "war");
-					App.SecExp.authorityX((result === 3 ? 1200 : 300) * majorBattleMod);
+					App.Mods.SecExp.authorityX((result === 3 ? 1200 : 300) * majorBattleMod);
 				} else if (V.SecExp.war.attacker.type === "freedom fighters") {
 					repX((result === 3 ? 7500 : 2000) * majorBattleMod, "war");
-					App.SecExp.authorityX((result === 3 ? 1500 : 450) * majorBattleMod);
+					App.Mods.SecExp.authorityX((result === 3 ? 1500 : 450) * majorBattleMod);
 				} else if (V.SecExp.war.attacker.type === "old world") {
 					repX((result === 3 ? 8000 : 2100) * majorBattleMod, "war");
-					App.SecExp.authorityX((result === 3 ? 1600 : 500) * majorBattleMod);
+					App.Mods.SecExp.authorityX((result === 3 ? 1600 : 500) * majorBattleMod);
 				}
 				r.push(`which once sold produced`);
 				if (V.SecExp.war.attacker.equip === 0) {
@@ -335,7 +335,7 @@ App.Events.conflictReport = function() {
 					r.push(`<span class="yellowgreen">${result === 3 ? 'wealth worthy of the mightiest warlord' : 'a great amount of cash'}.</span>`);
 					loot += (result === 3 ? 20000 : 10000) * majorBattleMod;
 				}
-				if (V.SecExp.edicts.defense.privilege.mercSoldier === 1 && App.SecExp.battle.deployedUnits('mercs') >= 1) {
+				if (V.SecExp.edicts.defense.privilege.mercSoldier === 1 && App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 					r.push(`Part of the loot is distributed to your mercenaries.`);
 					if (result === 3) {
 						captives = Math.trunc(captives * 0.6);
@@ -359,7 +359,7 @@ App.Events.conflictReport = function() {
 					}
 				} else {
 					V.lowerClass -= random(10) * majorBattleMod;
-					App.SecExp.slavesDamaged(random(20) * majorBattleMod);
+					App.Mods.SecExp.slavesDamaged(random(20) * majorBattleMod);
 				}
 				App.Events.addParagraph(node, r);
 				r = [];
@@ -371,13 +371,13 @@ App.Events.conflictReport = function() {
 					App.UI.DOM.appendNewElement("div", node, `After the battle most of the rebelling slaves managed to escape, while others remained in the arcology for days looting and hunting their former masters. The arcology will bear the scars of this day for a long time.`);
 					V.lowerClass -= (result === -3 ? random(50, 100) : random(40, 80));
 					lostSlaves = Math.trunc((V.SecExp.war.attacker.troops - V.SecExp.war.attacker.losses) * 0.8);
-					App.SecExp.slavesDamaged(lostSlaves);
+					App.Mods.SecExp.slavesDamaged(lostSlaves);
 				} else {
 					App.UI.DOM.appendNewElement("div", node, `After the battle most of the rebelling citizens remained in the arcology for days looting and hunting their former arcology. We will bear the scars of this day for a long time.`);
 					V.lowerClass -= Math.trunc((V.SecExp.war.attacker.troops - V.SecExp.war.attacker.losses) * 0.6);
 				}
 				repX((result === -3 ? random(-800, -1000) : random(-600, -800)), "war");
-				App.SecExp.authorityX(result === -3 ? random(-800, -1000) : random(-600, -800));
+				App.Mods.SecExp.authorityX(result === -3 ? random(-800, -1000) : random(-600, -800));
 			} else {
 				if (result === -3) {
 					App.UI.DOM.appendNewElement("div", node, " Obviously your troops were not able to capture anyone or anything.");
@@ -400,38 +400,38 @@ App.Events.conflictReport = function() {
 				r = [];
 				if (V.SecExp.war.attacker.type === "raiders") {
 					repX(forceNeg((result === -3 ? 400 : 40) * majorBattleMod), "war");
-					App.SecExp.authorityX((result === -3 ? -400 : -40) * majorBattleMod);
+					App.Mods.SecExp.authorityX((result === -3 ? -400 : -40) * majorBattleMod);
 				} else if (V.SecExp.war.attacker.type === "free city") {
 					repX(forceNeg((result === -3 ? 600 : 60) * majorBattleMod), "war");
-					App.SecExp.authorityX((result === -3 ? -600 : -60) * majorBattleMod);
+					App.Mods.SecExp.authorityX((result === -3 ? -600 : -60) * majorBattleMod);
 				} else if (V.SecExp.war.attacker.type === "freedom fighters") {
 					repX(forceNeg((result === -3 ? 750 : 75) * majorBattleMod), "war");
-					App.SecExp.authorityX((result === -3 ? -750 : -75) * majorBattleMod);
+					App.Mods.SecExp.authorityX((result === -3 ? -750 : -75) * majorBattleMod);
 				} else if (V.SecExp.war.attacker.type === "old world") {
 					repX(forceNeg((result === -3 ? 800 : 80) * majorBattleMod), "war");
-					App.SecExp.authorityX((result === -3 ? -800 : -80) * majorBattleMod);
+					App.Mods.SecExp.authorityX((result === -3 ? -800 : -80) * majorBattleMod);
 				}
 
 				cashX(forceNeg((result === -3 ? 5000 : 3000) * majorBattleMod), "war");
 				if (V.week <= 30) {
 					V.lowerClass -= random(result === -3 ? 100 : 50) * majorBattleMod;
-					App.SecExp.slavesDamaged(random(result === -3 ? 150 : 75) * majorBattleMod);
+					App.Mods.SecExp.slavesDamaged(random(result === -3 ? 150 : 75) * majorBattleMod);
 					V.arcologies[0].prosperity -= random(result === -3 ? 5 : 2) * majorBattleMod;
 				} else if (V.week <= 60) {
 					V.lowerClass -= random(result === -3 ? 120 : 60) * majorBattleMod;
-					App.SecExp.slavesDamaged(random(result === -3 ? 170 : 85) * majorBattleMod);
+					App.Mods.SecExp.slavesDamaged(random(result === -3 ? 170 : 85) * majorBattleMod);
 					V.arcologies[0].prosperity -= random(result === -3 ? 10 : 5) * majorBattleMod;
 				} else if (V.week <= 90) {
 					V.lowerClass -= random(result === -3 ? 140 : 70) * majorBattleMod;
-					App.SecExp.slavesDamaged(random(result === -3 ? 190 : 95) * majorBattleMod);
+					App.Mods.SecExp.slavesDamaged(random(result === -3 ? 190 : 95) * majorBattleMod);
 					V.arcologies[0].prosperity -= random(result === -3 ? 15 : 7) * majorBattleMod;
 				} else if (V.week <= 120) {
 					V.lowerClass -= random(result === -3 ? 160 : 80) * majorBattleMod;
-					App.SecExp.slavesDamaged(random(result === -3 ? 210 : 105) * majorBattleMod);
+					App.Mods.SecExp.slavesDamaged(random(result === -3 ? 210 : 105) * majorBattleMod);
 					V.arcologies[0].prosperity -= random(result === -3 ? 20 : 10) * majorBattleMod;
 				} else {
 					V.lowerClass -= random(result === -3 ? 180 : 90) * majorBattleMod;
-					App.SecExp.slavesDamaged(random(result === -3 ? 230 : 115) * majorBattleMod);
+					App.Mods.SecExp.slavesDamaged(random(result === -3 ? 230 : 115) * majorBattleMod);
 					V.arcologies[0].prosperity -= random(result === -3 ? 25 : 12) * majorBattleMod;
 				}
 			}
@@ -582,7 +582,7 @@ App.Events.conflictReport = function() {
 		V.NPCSlaves = Math.max(V.NPCSlaves, 0);
 
 		if (inBattle) { // tactics
-			App.Events.addParagraph(node, App.SecExp.commanderEffectiveness("report"));
+			App.Events.addParagraph(node, App.Mods.SecExp.commanderEffectiveness("report"));
 			r = [];
 
 			r.push(`${commanderIsPC ? 'You' : 'Your commander'}`);
@@ -884,8 +884,8 @@ App.Events.conflictReport = function() {
 		const lossesList = [];
 		if (hasLosses || V.SecExp.war.losses === 0) {
 			if (hasLosses) { // Generates a list of randomized losses, from which each unit picks one at random
-				averageLosses = Math.trunc(V.SecExp.war.losses / App.SecExp.battle.deployedUnits());
-				for (let i = 0; i < App.SecExp.battle.deployedUnits(); i++) {
+				averageLosses = Math.trunc(V.SecExp.war.losses / App.Mods.SecExp.battle.deployedUnits());
+				for (let i = 0; i < App.Mods.SecExp.battle.deployedUnits(); i++) {
 					let assignedLosses = Math.trunc(Math.clamp(averageLosses + random(-5, 5), 0, 100));
 					if (assignedLosses > V.SecExp.war.losses) {
 						assignedLosses = V.SecExp.war.losses;
@@ -966,10 +966,10 @@ App.Events.conflictReport = function() {
 			App.Events.addNode(node, r, "div");
 			r = [];
 		}
-		for (const type of App.SecExp.unit.list().keys()) {
-			if (App.SecExp.battle.deployedUnits(type) >= 1) {
+		for (const type of App.Mods.SecExp.unit.list().keys()) {
+			if (App.Mods.SecExp.battle.deployedUnits(type) >= 1) {
 				for (const unit of V.SecExp.units[type].squads) {
-					if (App.SecExp.unit.isDeployed(unit)) {
+					if (App.Mods.SecExp.unit.isDeployed(unit)) {
 						let r = [];
 						if (hasLosses) {
 							loss = lossesList.pluck();
@@ -1006,7 +1006,7 @@ App.Events.conflictReport = function() {
 		}
 
 		if (inRebellion) {
-			for (const unit of Array.from(App.SecExp.unit.list().keys()).slice(1)) {
+			for (const unit of Array.from(App.Mods.SecExp.unit.list().keys()).slice(1)) {
 				App.UI.DOM.appendNewElement("p", node, rebellingUnitsFate(unit, averageLosses));
 			}
 		} else {
@@ -1045,13 +1045,17 @@ App.Events.conflictReport = function() {
 					candidates = Math.min(captives, random(1, 3));
 					r.push(`${capFirstChar(num(candidates, true))} of them have the potential to be sex slaves.`);
 				}
+				App.Events.addParagraph(node, r);
+				r = [];
 
 				const sell = function() {
 					cashX((menialPrice * captives), "menialTransfer");
-					return `Captives sold`;
+					return `You have the all of the captives sold, gaining ${cashFormatColor(menialPrice * captives)}.`;
 				};
 				const keep = function() {
+					let t = [];
 					V.menials += (captives - candidates);
+					let names = [];
 					for (let i = 0; i < candidates; i++) {
 						const generateFemale = random(0, 99) < V.seeDicks;
 						let slave = GenerateNewSlave((generateFemale ? "XY" : "XX"), {minAge: 16, maxAge: 32, disableDisability: 1});
@@ -1060,19 +1064,26 @@ App.Events.conflictReport = function() {
 						slave.waist = (generateFemale ? random(10, 80) : random(-20, 20));
 						slave.skill.combat = 1;
 						slave.origin = `$He is an enslaved ${V.SecExp.war.attacker.type} soldier captured during a battle.`;
+						names.push(SlaveFullName(slave));
 						newSlave(slave); // skip New Slave Intro
 					}
-					return `Captives primarily added as menial slaves.`;
+					if (candidates > 0) {
+						t.push(`${toSentence(names)} ${names.length > 1 ? "have" : "has"} been added to your roster of sex slaves.`);
+					}
+					if (captives > candidates) {
+						t.push(`${capFirstChar(numberWithPluralOne(captives - candidates, "menial"))} slaves acquired.`);
+					}
+					return t;
 				};
 				const execute = function() {
-					App.SecExp.authorityX(100 * captives);
-					return `Captives executed`;
-				}
+					App.Mods.SecExp.authorityX(100 * captives);
+					return `You publicly execute the captives, earning the <span class="darkviolet">respect</span> of those who watched.`;
+				};
 
 				App.Events.addResponses(node, [
-					new App.Events.Result(`sell them all immediately`, sell),
-					new App.Events.Result(`keep them as primarily menial slaves`, keep),
-					new App.Events.Result(`execute them on the spot`, execute),
+					new App.Events.Result(`Sell them all immediately`, sell, `They are worth ${cashFormat(menialPrice * captives)}`),
+					new App.Events.Result(`Keep them as slaves`, keep, `${capFirstChar(numberWithPluralOne(captives - candidates, "menial"))} and ${numberWithPluralOne(candidates, "sex slave")}`),
+					new App.Events.Result(`Execute them on the spot`, execute, `Improves your authority`),
 				]);
 			}
 		}
@@ -1093,7 +1104,7 @@ App.Events.conflictReport = function() {
 				}
 				cashX(-1000, "war");
 				repX(random(-1000, -1200), "war");
-				App.SecExp.authorityX(random(-1000, -1200));
+				App.Mods.SecExp.authorityX(random(-1000, -1200));
 				if (V.week <= 30) {
 					arcologyEffects(100, 150, 5);
 				} else if (V.week <= 60) {
@@ -1107,21 +1118,21 @@ App.Events.conflictReport = function() {
 				}
 				V.lowerClass -= random(50, 100);
 				lostSlaves = Math.trunc((V.SecExp.war.attacker.troops - V.SecExp.war.attacker.losses) * 0.8);
-				App.SecExp.slavesDamaged(lostSlaves);
+				App.Mods.SecExp.slavesDamaged(lostSlaves);
 			} else {
 				r.push(`Rather than waste the lives of your men you decided to surrender, hoping your enemy will cause less damage if you indulge them. This is, however, a big hit to your status. Your <span class="red">reputation</span> and <span class="red">authority</span> are significantly impacted.`);
 				if (V.SecExp.war.attacker.type === "raiders") {
 					repX(forceNeg(600 * majorBattleMod), "war");
-					App.SecExp.authorityX(-600 * majorBattleMod);
+					App.Mods.SecExp.authorityX(-600 * majorBattleMod);
 				} else if (V.SecExp.war.attacker.type === "free city") {
 					repX(forceNeg(800 * majorBattleMod), "war");
-					App.SecExp.authorityX(-800 * majorBattleMod);
+					App.Mods.SecExp.authorityX(-800 * majorBattleMod);
 				} else if (V.SecExp.war.attacker.type === "freedom fighters") {
 					repX(forceNeg(1000 * majorBattleMod), "war");
-					App.SecExp.authorityX(-1000 * majorBattleMod);
+					App.Mods.SecExp.authorityX(-1000 * majorBattleMod);
 				} else if (V.SecExp.war.attacker.type === "old world") {
 					repX(forceNeg(1200 * majorBattleMod), "war");
-					App.SecExp.authorityX(-1200 * majorBattleMod);
+					App.Mods.SecExp.authorityX(-1200 * majorBattleMod);
 				}
 				App.Events.addParagraph(node, r);
 				r = [];
@@ -1130,23 +1141,23 @@ App.Events.conflictReport = function() {
 				cashX(forceNeg(1000 * majorBattleMod), "war");
 				if (V.week <= 30) {
 					V.lowerClass -= random(80) * majorBattleMod;
-					App.SecExp.slavesDamaged(random(120) * majorBattleMod);
+					App.Mods.SecExp.slavesDamaged(random(120) * majorBattleMod);
 					V.arcologies[0].prosperity -= random(5) * majorBattleMod;
 				} else if (V.week <= 60) {
 					V.lowerClass -= random(100) * majorBattleMod;
-					App.SecExp.slavesDamaged(random(140) * majorBattleMod);
+					App.Mods.SecExp.slavesDamaged(random(140) * majorBattleMod);
 					V.arcologies[0].prosperity -= random(10) * majorBattleMod;
 				} else if (V.week <= 90) {
 					V.lowerClass -= random(120) * majorBattleMod;
-					App.SecExp.slavesDamaged(random(160) * majorBattleMod);
+					App.Mods.SecExp.slavesDamaged(random(160) * majorBattleMod);
 					V.arcologies[0].prosperity -= random(15) * majorBattleMod;
 				} else if (V.week <= 120) {
 					V.lowerClass -= random(140) * majorBattleMod;
-					App.SecExp.slavesDamaged(random(180) * majorBattleMod);
+					App.Mods.SecExp.slavesDamaged(random(180) * majorBattleMod);
 					V.arcologies[0].prosperity -= random(20) * majorBattleMod;
 				} else {
 					V.lowerClass -= random(160) * majorBattleMod;
-					App.SecExp.slavesDamaged(random(200) * majorBattleMod);
+					App.Mods.SecExp.slavesDamaged(random(200) * majorBattleMod);
 					V.arcologies[0].prosperity -= random(25) * majorBattleMod;
 				}
 			}
@@ -1160,16 +1171,16 @@ App.Events.conflictReport = function() {
 			r.push(`There is no time to organize a defense and so the enemy walks into the arcology as if it was theirs. Your reputation and authority suffer a hit.`);
 			if (V.SecExp.war.attacker.type === "raiders") {
 				repX(forceNeg(400 * majorBattleMod), "war");
-				App.SecExp.authorityX(-400 * majorBattleMod);
+				App.Mods.SecExp.authorityX(-400 * majorBattleMod);
 			} else if (V.SecExp.war.attacker.type === "free city") {
 				repX(forceNeg(600 * majorBattleMod), "war");
-				App.SecExp.authorityX(-600 * majorBattleMod);
+				App.Mods.SecExp.authorityX(-600 * majorBattleMod);
 			} else if (V.SecExp.war.attacker.type === "freedom fighters") {
 				repX(forceNeg(750 * majorBattleMod), "war");
-				App.SecExp.authorityX(-750 * majorBattleMod);
+				App.Mods.SecExp.authorityX(-750 * majorBattleMod);
 			} else if (V.SecExp.war.attacker.type === "old world") {
 				repX(forceNeg(800 * majorBattleMod), "war");
-				App.SecExp.authorityX(-800 * majorBattleMod);
+				App.Mods.SecExp.authorityX(-800 * majorBattleMod);
 			}
 			App.Events.addParagraph(node, r);
 			r = [];
@@ -1178,23 +1189,23 @@ App.Events.conflictReport = function() {
 			cashX(-1000, "war");
 			if (V.week <= 30) {
 				V.lowerClass -= random(80) * majorBattleMod;
-				App.SecExp.slavesDamaged(random(120) * majorBattleMod);
+				App.Mods.SecExp.slavesDamaged(random(120) * majorBattleMod);
 				V.arcologies[0].prosperity -= random(5) * majorBattleMod;
 			} else if (V.week <= 60) {
 				V.lowerClass -= random(100) * majorBattleMod;
-				App.SecExp.slavesDamaged(random(140) * majorBattleMod);
+				App.Mods.SecExp.slavesDamaged(random(140) * majorBattleMod);
 				V.arcologies[0].prosperity -= random(10) * majorBattleMod;
 			} else if (V.week <= 90) {
 				V.lowerClass -= random(120) * majorBattleMod;
-				App.SecExp.slavesDamaged(random(160) * majorBattleMod);
+				App.Mods.SecExp.slavesDamaged(random(160) * majorBattleMod);
 				V.arcologies[0].prosperity -= random(15) * majorBattleMod;
 			} else if (V.week <= 120) {
 				V.lowerClass -= random(140) * majorBattleMod;
-				App.SecExp.slavesDamaged(random(180) * majorBattleMod);
+				App.Mods.SecExp.slavesDamaged(random(180) * majorBattleMod);
 				V.arcologies[0].prosperity -= random(20) * majorBattleMod;
 			} else {
 				V.lowerClass -= random(160) * majorBattleMod;
-				App.SecExp.slavesDamaged(random(200) * majorBattleMod);
+				App.Mods.SecExp.slavesDamaged(random(200) * majorBattleMod);
 				V.arcologies[0].prosperity -= random(25) * majorBattleMod;
 			}
 		} else if (result === 1) { // Battles only
@@ -1209,7 +1220,7 @@ App.Events.conflictReport = function() {
 			} else if (V.SecExp.war.attacker.type === "old world") {
 				repX(1250 * majorBattleMod, "war");
 			}
-			cashX(forceNeg(App.SecExp.battle.bribeCost()), "war");
+			cashX(forceNeg(App.Mods.SecExp.battle.bribeCost()), "war");
 		}
 	}
 
@@ -1232,7 +1243,7 @@ App.Events.conflictReport = function() {
  * @returns {DocumentFragment}
  */
 const casualtiesReport = function(type, loss, squad=null) {
-	const isSpecial = squad && Array.from(App.SecExp.unit.list().keys()).slice(1).includes(type);
+	const isSpecial = squad && Array.from(App.Mods.SecExp.unit.list().keys()).slice(1).includes(type);
 	const frag = new DocumentFragment();
 	const r = new SpacedTextAccumulator(frag);
 	if (loss <= 0) {
@@ -1247,7 +1258,7 @@ const casualtiesReport = function(type, loss, squad=null) {
 		r.push(`Catastrophic`);
 	}
 	r.push(`casualties suffered.`);
-	if (Array.from(App.SecExp.unit.list().keys()).includes(type)) {
+	if (Array.from(App.Mods.SecExp.unit.list().keys()).includes(type)) {
 		if (squad.troops <= 0) {
 			squad.active = 0;
 			r.push(`Unfortunately the losses they took were simply too great, their effective combatants are in so small number you can no longer call them a deployable unit.`);
@@ -1339,7 +1350,7 @@ const checkWoundStatus = function(target) {
 			healthDamage(V.PC, 60);
 			r.push(`A lucky shot managed to find its way to you, leaving a painful, but thankfully not lethal, wound.`);
 		} else {
-			const woundType = App.SecExp.inflictBattleWound(slave);
+			const woundType = App.Mods.SecExp.inflictBattleWound(slave);
 			const {his, him} = getPronouns(slave);
 			if (target === "Concubine") {
 				r.push(`Your Concubine was unfortunately caught in the crossfire.`);
@@ -1370,11 +1381,11 @@ const checkWoundStatus = function(target) {
  * @param {number} [value]
  * @param {number} [cost=2000]
  */
-	const setRepairTime = function(target, value, cost=2000) {
-		V.SecExp.rebellions.repairTime[target] = 3 + random(1) - value;
-		cashX(-cost, "war");
-		return IncreasePCSkills('engineering', 0.1);
-	};
+const setRepairTime = function(target, value, cost=2000) {
+	V.SecExp.rebellions.repairTime[target] = 3 + random(1) - value;
+	cashX(-cost, "war");
+	return IncreasePCSkills('engineering', 0.1);
+};
 /**
  * @param {number} [lowerClass]
  * @param {number} [slaves]
@@ -1383,7 +1394,7 @@ const checkWoundStatus = function(target) {
  */
 const arcologyEffects = function(lowerClass, slaves, prosperity) {
 	V.lowerClass -= random(lowerClass);
-	App.SecExp.slavesDamaged(random(slaves));
+	App.Mods.SecExp.slavesDamaged(random(slaves));
 	V.arcologies[0].prosperity -= random(prosperity);
 };
 /**
@@ -1397,14 +1408,14 @@ const rebellingUnitsFate = function(unit, averageLosses) {
 	const rebels = {ID: [], names: []};
 
 	const Dissolve = function() {
-		App.SecExp.unit.unitFree(unit).add(manpower);
+		App.Mods.SecExp.unit.unitFree(unit).add(manpower);
 		for (const u of V.SecExp.units[unit].squads.filter(s => s.active === 1)) {
 			u.loyalty = Math.clamp(u.loyalty - random(10, 40), 0, 100);
 		}
 		return `Units dissolved.`;
 	};
 	const Purge = function() {
-		App.SecExp.unit.unitFree(unit).add(manpower * 0.5);
+		App.Mods.SecExp.unit.unitFree(unit).add(manpower * 0.5);
 		return `Dissidents purged and units dissolved.`;
 	};
 	const Execute = function() {
diff --git a/src/Mods/SecExp/events/secExpSmilingMan0.js b/src/Mods/SecExp/events/secExpSmilingMan0.js
index 5d2a749bd1e9e32be95e3703bb82fab95994992d..cda9d50687c37470760be95fdb352dc026eaa702 100644
--- a/src/Mods/SecExp/events/secExpSmilingMan0.js
+++ b/src/Mods/SecExp/events/secExpSmilingMan0.js
@@ -1,7 +1,7 @@
 App.Events.secExpSmilingMan0 = class secExpSmilingMan0 extends App.Events.BaseEvent {
 	eventPrerequisites() {
 		return [
-			() => V.rivalOwner === 0,
+			() => V.rival.state <= 1 || V.rival.state > 2,
 			() => V.secExpEnabled > 0,
 			() => V.SecExp.smilingMan.progress === 0,
 			() => App.Events.effectiveWeek() >= 74,
diff --git a/src/Mods/SecExp/events/secExpSmilingMan1.js b/src/Mods/SecExp/events/secExpSmilingMan1.js
index 4197d1c030b4d603320e0af566d3fadb931c10ff..c51c512a248dba98c82ca715fc4d11ffe525ad0e 100644
--- a/src/Mods/SecExp/events/secExpSmilingMan1.js
+++ b/src/Mods/SecExp/events/secExpSmilingMan1.js
@@ -1,7 +1,7 @@
 App.Events.secExpSmilingMan1 = class secExpSmilingMan1 extends App.Events.BaseEvent {
 	eventPrerequisites() {
 		return [
-			() => V.rivalOwner === 0,
+			() => V.rival.state <= 1 || V.rival.state > 2,
 			() => V.secExpEnabled > 0,
 			() => V.SecExp.smilingMan.progress === 1,
 			() => App.Events.effectiveWeek() >= 77,
diff --git a/src/Mods/SecExp/events/secExpSmilingMan2.js b/src/Mods/SecExp/events/secExpSmilingMan2.js
index d6b439c9896ba07ce496019f79beb473fd112870..021d1cac5f5a64553ad54a15c939e0fc5e0e9bb8 100644
--- a/src/Mods/SecExp/events/secExpSmilingMan2.js
+++ b/src/Mods/SecExp/events/secExpSmilingMan2.js
@@ -1,7 +1,7 @@
 App.Events.secExpSmilingMan2 = class secExpSmilingMan2 extends App.Events.BaseEvent {
 	eventPrerequisites() {
 		return [
-			() => V.rivalOwner === 0,
+			() => V.rival.state <= 1 || V.rival.state > 2,
 			() => V.secExpEnabled > 0,
 			() => V.SecExp.smilingMan.progress === 2,
 			() => App.Events.effectiveWeek() >= 82,
diff --git a/src/Mods/SecExp/events/secExpSmilingMan3.js b/src/Mods/SecExp/events/secExpSmilingMan3.js
index bbb267162095edc8f860bd2e90e7bc7f57dbe8ed..c11f7de1eb9c274bc3ced369e4b5482fcdb42b24 100644
--- a/src/Mods/SecExp/events/secExpSmilingMan3.js
+++ b/src/Mods/SecExp/events/secExpSmilingMan3.js
@@ -1,7 +1,7 @@
 App.Events.secExpSmilingMan3 = class secExpSmilingMan3 extends App.Events.BaseEvent {
 	eventPrerequisites() {
 		return [
-			() => V.rivalOwner === 0,
+			() => V.rival.state <= 1 || V.rival.state > 2,
 			() => V.secExpEnabled > 0,
 			() => V.SecExp.smilingMan.progress === 3,
 		];
diff --git a/src/Mods/SecExp/js/Unit.js b/src/Mods/SecExp/js/Unit.js
index 1e1213d430b8946690c9f5cddda3d11c35213ba1..76b01e3197cfe0f0e1e0467353bf3b8db72d53ad 100644
--- a/src/Mods/SecExp/js/Unit.js
+++ b/src/Mods/SecExp/js/Unit.js
@@ -1,4 +1,4 @@
-App.SecExp.unit = (function() {
+App.Mods.SecExp.unit = (function() {
 	const equipUpgradeCost = 350;
 	const secBotsUpgradeCost = 450;
 	const secBotsCost = 500;
@@ -149,7 +149,7 @@ App.SecExp.unit = (function() {
 		let linkArray = [];
 
 		linkArray.push("Default unit name:", App.UI.DOM.makeTextBox(V.SecExp.units[type].defaultName, str => { V.SecExp.units[type].defaultName = str; App.UI.reload(); }));
-		if (unitFree(type).canUpgrade() && App.SecExp.battle.activeUnits() < App.SecExp.battle.maxUnits()) {
+		if (unitFree(type).canUpgrade() && App.Mods.SecExp.battle.activeUnits() < App.Mods.SecExp.battle.maxUnits()) {
 			linkArray.push(App.UI.DOM.link(`Form a new unit`, () => {
 				generate(type, true);
 				if (type === "bots") {
@@ -159,17 +159,16 @@ App.SecExp.unit = (function() {
 			}
 			));
 		}
-
-		linkArray.push(bulkUpgrade(V.SecExp.units[type].squads));
+		if (bulkUpgrade(V.SecExp.units[type].squads) !== "N/A") {
+			linkArray.push(bulkUpgrade(V.SecExp.units[type].squads));
+		}
 		App.UI.DOM.appendNewElement("div", list, App.UI.DOM.generateLinksStrip(linkArray));
-
 		if (type === "slaves") {
 			App.UI.DOM.appendNewElement("div", list, App.UI.market({menialWorkersOnly: true}));
 		}
 
 		for (const unit of V.SecExp.units[type].squads) {
 			linkArray = [];
-
 			App.UI.DOM.appendNewElement("div", unitDetail, describe(unit, false));
 			linkArray.push(App.UI.DOM.makeTextBox(unit.platoonName, str => { unit.platoonName = str; App.UI.reload(); }));
 			linkArray.push(App.UI.DOM.link(`Disband the unit`, () => {
@@ -215,11 +214,26 @@ App.SecExp.unit = (function() {
 					));
 				}
 			}
-			linkArray.push(bulkUpgrade(unit));
+			if (bulkUpgrade(unit) !== "N/A") {
+				linkArray.push(bulkUpgrade(unit));
+			}
+			if (V.peacekeepers.state === 3 && type !== "bots") {
+				const unitAdjust = Math.ceil((unit.troops / 10) + (unit.maxTroops / 10) + (unit.training / 10) + unit.equip + unit.commissars + unit.cyber + unit.medics + unit.SF);
+				const cost = forceNeg(25000 * (1.5 + unitAdjust));
+				linkArray.push(App.UI.DOM.link(`Send this unit to improve your relationship with General ${V.peacekeepers.generalName}. Costs ${cashFormat(cost)}.`, () => { 
+					V.peacekeepers.attitude += Math.ceil(unitAdjust / 5);
+					cashX(cost, "securityExpansion");
+					unitFree(type).add(unit.troops);
+					V.SecExp.units[type].squads.deleteAt(unit);
+					V.SecExp.battles.lastSelection.deleteAt(unit);
+					App.UI.reload();
+				}
+				));
+			}
 			App.UI.DOM.appendNewElement("div", unitDetail, App.UI.DOM.generateLinksStrip(linkArray));
 
 			if (V.SecExp.settings.showStats === 1) {
-				App.UI.DOM.appendNewElement("div", unitDetail, App.SecExp.getUnit(type, unit).printStats());
+				App.UI.DOM.appendNewElement("div", unitDetail, App.Mods.SecExp.getUnit(type, unit).printStats());
 			}
 
 			let options = new DocumentFragment();
@@ -363,7 +377,6 @@ App.SecExp.unit = (function() {
 			}
 			App.UI.DOM.appendNewElement("p", list, unitDetail);
 		}
-
 		return list;
 
 		/** Creates a bulk upgrade link for the unit that is passed.
@@ -371,8 +384,19 @@ App.SecExp.unit = (function() {
 		 */
 		function bulkUpgrade(unit) {
 			unit = Array.isArray(unit) ? unit : [unit];
-			let el = document.createElement("a");
-
+			const el = document.createElement("a");
+			const price = unit.map(getCost).reduce((acc, cur) => acc + cur, 0);
+			if (price !== 0) {
+				el.append(App.UI.DOM.link(`Bulk upgrade for ${cashFormat(price)}`, () => {
+					unit.map(upgradeUnit).reduce((acc, cur) => acc + cur, 0);
+					cashX(price, "securityExpansion");
+					App.UI.reload();
+				}
+				));
+				return el;
+			} else {
+				return "N/A";
+			}
 			/**
 			 * @param {FC.SecExp.PlayerHumanUnitData} x
 			 */
@@ -392,7 +416,6 @@ App.SecExp.unit = (function() {
 					}
 				}
 			}
-
 			/**
 			 * @param {FC.SecExp.PlayerHumanUnitData} x
 			 */
@@ -418,17 +441,6 @@ App.SecExp.unit = (function() {
 				}
 				return Math.ceil(cost * 1.1);
 			}
-
-			const price = unit.map(getCost).reduce((acc, cur) => acc + cur, 0);
-			if (price !== 0) {
-				el.append(App.UI.DOM.link(`Bulk upgrade for ${cashFormat(price)}`, () => {
-					unit.map(upgradeUnit).reduce((acc, cur) => acc + cur, 0);
-					cashX(price, "securityExpansion");
-					App.UI.reload();
-				}
-				));
-			}
-			return el;
 		}
 
 		/**
@@ -438,14 +450,14 @@ App.SecExp.unit = (function() {
 		function upgradeCost(upgrade, unit) {
 			let cost = 0;
 			const isBots = checkID(unit.ID) === "bots";
-			switch(upgrade) {
+			switch (upgrade) {
 				case "squadSize":
 					if (isBots) {
 						if (unit.maxTroops < 80) {
 							cost -= 5000;
 						} else if (V.SF.Toggle && V.SF.Active >= 1 && unit.maxTroops < 100 && V.SecExp.edicts.SFSupportLevel >= 1) {
 							cost -= 5000 + 10 * secBotsUpgradeCost * unit.equip;
-						}	
+						}
 					} else {
 						if (unit.maxTroops < 50) {
 							cost -= 5000 + 10 * equipUpgradeCost * (unit.equip + unit.commissars + unit.cyber + unit.SF);
@@ -477,7 +489,7 @@ App.SecExp.unit = (function() {
 	function replenishAll() {
 		let el = document.createElement("div");
 		let woundedUnit = new Map([]);
-		for (const squad of App.SecExp.unit.squads()) {
+		for (const squad of App.Mods.SecExp.unit.squads()) {
 			const unit = checkID(squad.ID);
 			if (squad.troops < squad.maxTroops && unitFree(unit).canUpgrade()) {
 				woundedUnit.set(unit);
@@ -511,11 +523,11 @@ App.SecExp.unit = (function() {
 	 */
 	function describe(input, inBattle) {
 		const brief = V.SecExp.settings.unitDescriptions;
-		const unitType = App.SecExp.unit.checkID(input.ID);
+		const unitType = App.Mods.SecExp.unit.checkID(input.ID);
 		let el = new DocumentFragment();
 
 		if (inBattle) {
-			const canDeploy = !isDeployed(input) && App.SecExp.battle.deployableUnits() > 0;
+			const canDeploy = !isDeployed(input) && App.Mods.SecExp.battle.deployableUnits() > 0;
 			el.append(App.UI.DOM.link(`(${canDeploy ? 'Deploy' : 'Recall'}) `, () => {
 				if (canDeploy) {
 					V.SecExp.war.deployed.push(input.ID);
@@ -528,7 +540,7 @@ App.SecExp.unit = (function() {
 			));
 		}
 
-		App.UI.DOM.appendNewElement("span", el, `${input.platoonName}`, "bold");
+		App.UI.DOM.appendNewElement("span", el, `${input.platoonName}`, ["bold"]);
 		App.UI.DOM.appendNewElement("span", el, `${!brief ? ``:`. `} `);
 		if (unitType !== "bots") {
 			if (brief === 0) {
@@ -646,7 +658,7 @@ App.SecExp.unit = (function() {
 				el.append(`Training: `);
 				if (input.training <= 33) {
 					el.append(`low. `);
-				} else if(input.training <= 66) {
+				} else if (input.training <= 66) {
 					el.append(`medium. `);
 				} else {
 					el.append(`high. `);
@@ -693,7 +705,7 @@ App.SecExp.unit = (function() {
 	 */
 	function squads(type = '') {
 		let array = Object.values(V.SecExp.units).map(s => s.squads).flatten();
-		switch(type) {
+		switch (type) {
 			case "human": return array.filter(s => checkID(s.ID) !== "bots");
 		}
 		return array;
@@ -740,7 +752,7 @@ App.SecExp.unit = (function() {
 		 * @returns {number}
 		 */
 		function print() {
-			switch(type) {
+			switch (type) {
 				case "slaves": return V.menials;
 				case "militia":
 				case "mercs":
@@ -752,7 +764,7 @@ App.SecExp.unit = (function() {
 		 * @returns {boolean}
 		 */
 		function canUpgrade() {
-			switch(type) {
+			switch (type) {
 				case "bots": return V.cash >= secBotsCost;
 				case "slaves": return V.menials > 0;
 				case "militia":
@@ -766,7 +778,7 @@ App.SecExp.unit = (function() {
 		 * @returns {void}
 		 */
 		function add(value) {
-			switch(type) {
+			switch (type) {
 				case "slaves": V.menials += value; break;
 				case "militia":
 				case "mercs":
@@ -779,7 +791,7 @@ App.SecExp.unit = (function() {
 		 * @returns {void}
 		 */
 		function remove(value) {
-			switch(type) {
+			switch (type) {
 				case "slaves": V.menials -= value; break;
 				case "militia":
 				case "mercs":
@@ -792,7 +804,7 @@ App.SecExp.unit = (function() {
 		 * @returns {void}
 		 */
 		function set(value) {
-			switch(type) {
+			switch (type) {
 				case "slaves": V.menials = value; break;
 				case "militia":
 				case "mercs":
@@ -834,20 +846,20 @@ App.SecExp.unit = (function() {
 /** Player unit factory - get a unit's data based on its type and the individual unit passed
  * @param {FC.SecExp.PlayerHumanUnitType} type - "bots", "militia", "slaves", "mercs", or "SF"
  * @param {FC.SecExp.PlayerHumanUnitData} [unit]
- * @returns {App.SecExp.Unit}
+ * @returns {App.Mods.SecExp.Unit}
  */
-App.SecExp.getUnit = function(type, unit=null) {
+App.Mods.SecExp.getUnit = function(type, unit=null) {
 	switch (type) {
 		case "SF":
-			return new App.SecExp.SFUnit();
+			return new App.Mods.SecExp.SFUnit();
 		case "bots":
-			return new App.SecExp.DroneUnit(unit, App.SecExp.BaseDroneUnit);
+			return new App.Mods.SecExp.DroneUnit(unit, App.Mods.SecExp.BaseDroneUnit);
 		case "militia":
-			return new App.SecExp.HumanUnit(unit, App.SecExp.BaseMilitiaUnit);
+			return new App.Mods.SecExp.HumanUnit(unit, App.Mods.SecExp.BaseMilitiaUnit);
 		case "slaves":
-			return new App.SecExp.HumanUnit(unit, App.SecExp.BaseSlaveUnit);
+			return new App.Mods.SecExp.HumanUnit(unit, App.Mods.SecExp.BaseSlaveUnit);
 		case "mercs":
-			return new App.SecExp.HumanUnit(unit, App.SecExp.BaseMercUnit);
+			return new App.Mods.SecExp.HumanUnit(unit, App.Mods.SecExp.BaseMercUnit);
 		default:
 			throw Error(`Unknown unit type: ${type}`);
 	}
@@ -857,34 +869,34 @@ App.SecExp.getUnit = function(type, unit=null) {
  * @param {FC.SecExp.EnemyUnitType} type - "raiders", "free city", "old world", or "freedom fighters"
  * @param {number} troops
  * @param {number} equipment
- * @returns {App.SecExp.Unit}
+ * @returns {App.Mods.SecExp.Unit}
  */
-App.SecExp.getEnemyUnit = function(type, troops, equipment) {
+App.Mods.SecExp.getEnemyUnit = function(type, troops, equipment) {
 	const baseUnitMap = new Map([
-		["raiders", App.SecExp.BaseRaiderUnit],
-		["free city", App.SecExp.BaseFreeCityUnit],
-		["old world", App.SecExp.BaseOldWorldUnit],
-		["freedom fighters", App.SecExp.BaseFreedomFighterUnit],
+		["raiders", App.Mods.SecExp.BaseRaiderUnit],
+		["free city", App.Mods.SecExp.BaseFreeCityUnit],
+		["old world", App.Mods.SecExp.BaseOldWorldUnit],
+		["freedom fighters", App.Mods.SecExp.BaseFreedomFighterUnit],
 	]);
 	const unitData = {
 		troops: troops,
 		maxTroops: troops,
 		equip: equipment
 	};
-	return new App.SecExp.EnemyUnit(unitData, baseUnitMap.get(type));
+	return new App.Mods.SecExp.EnemyUnit(unitData, baseUnitMap.get(type));
 };
 
 /** Irregular unit factory - get an irregular unit (without organization/upgrade bonuses) based on its type and basic data
  * @param {FC.SecExp.PlayerHumanUnitTypeModHuman} type - "militia", "slaves", or "mercs"
  * @param {number} troops
  * @param {number} equipment
- * @returns {App.SecExp.Unit}
+ * @returns {App.Mods.SecExp.Unit}
  */
-App.SecExp.getIrregularUnit = function(type, troops, equipment) {
+App.Mods.SecExp.getIrregularUnit = function(type, troops, equipment) {
 	const baseUnitMap = new Map([
-		["militia", App.SecExp.BaseMilitiaUnit],
-		["slaves", App.SecExp.BaseSlaveUnit],
-		["mercs", App.SecExp.BaseMercUnit],
+		["militia", App.Mods.SecExp.BaseMilitiaUnit],
+		["slaves", App.Mods.SecExp.BaseSlaveUnit],
+		["mercs", App.Mods.SecExp.BaseMercUnit],
 	]);
 	const unitData = {
 		troops: troops,
@@ -892,17 +904,17 @@ App.SecExp.getIrregularUnit = function(type, troops, equipment) {
 		equip: equipment
 	};
 
-	return new App.SecExp.IrregularUnit(unitData, baseUnitMap.get(type));
+	return new App.Mods.SecExp.IrregularUnit(unitData, baseUnitMap.get(type));
 };
 
 /** Equipment multiplier (static balance variable) */
-App.SecExp.equipMod = 0.15;
+App.Mods.SecExp.equipMod = 0.15;
 
 /** Turn a loyalty value into a corresponding bonus factor
  * @param {number} value range: [0-100]
  * @returns {number} bonus - range: [0.0-0.3], cap at input 67
  */
-App.SecExp.loyaltyValueToBonusFactor = function(value) {
+App.Mods.SecExp.loyaltyValueToBonusFactor = function(value) {
 	return Math.min(value * 3 / 670, 0.3);
 };
 
@@ -910,7 +922,7 @@ App.SecExp.loyaltyValueToBonusFactor = function(value) {
  * @param {number} value range: [0-100]
  * @returns {number} bonus - range: [0.0-0.5], cap at input 67
  */
-App.SecExp.trainingValueToBonusFactor = function(value) {
+App.Mods.SecExp.trainingValueToBonusFactor = function(value) {
 	return Math.min(value * 3 / 400, 0.5);
 };
 
@@ -918,7 +930,7 @@ App.SecExp.trainingValueToBonusFactor = function(value) {
  * @param {string} type - unit type to check.
  * @returns {object} bonus values after checking for completed upgrades.
  */
-App.SecExp.getAppliedUpgrades = function(type) {
+App.Mods.SecExp.getAppliedUpgrades = function(type) {
 	let hp = 0; let morale = 0; let def = 0; let attack = 0;
 	if (V.SecExp.buildings.weapManu) {
 		if (type === 'drone') {
@@ -969,7 +981,7 @@ App.SecExp.getAppliedUpgrades = function(type) {
 	};
 };
 
-App.SecExp.getEdictUpgradeVal = (function() {
+App.Mods.SecExp.getEdictUpgradeVal = (function() {
 	const data = {
 		militia: new Map([
 			["legionTradition", {defense: 2, morale: 5, hp: 1}],
@@ -1021,71 +1033,71 @@ App.SecExp.getEdictUpgradeVal = (function() {
  */
 
 /** @implements {BaseUnit} */
-App.SecExp.BaseMilitiaUnit = class BaseMilitiaUnit {
+App.Mods.SecExp.BaseMilitiaUnit = class BaseMilitiaUnit {
 	static get attack() {
-		return 7 + App.SecExp.getAppliedUpgrades('human').attack + App.SecExp.getEdictUpgradeVal("militia", "attack");
+		return 7 + App.Mods.SecExp.getAppliedUpgrades('human').attack + App.Mods.SecExp.getEdictUpgradeVal("militia", "attack");
 	}
 
 	static get defense() {
-		return 5 + App.SecExp.getAppliedUpgrades('human').defense + App.SecExp.getEdictUpgradeVal("militia", "defense");
+		return 5 + App.Mods.SecExp.getAppliedUpgrades('human').defense + App.Mods.SecExp.getEdictUpgradeVal("militia", "defense");
 	}
 
 	static get morale() {
-		return 140 + App.SecExp.getAppliedUpgrades('human').morale + App.SecExp.getEdictUpgradeVal("militia", "morale");
+		return 140 + App.Mods.SecExp.getAppliedUpgrades('human').morale + App.Mods.SecExp.getEdictUpgradeVal("militia", "morale");
 	}
 
 	static get hp() {
-		return 3 + App.SecExp.getAppliedUpgrades('human').hp + App.SecExp.getEdictUpgradeVal("militia", "hp");
+		return 3 + App.Mods.SecExp.getAppliedUpgrades('human').hp + App.Mods.SecExp.getEdictUpgradeVal("militia", "hp");
 	}
 };
 
 
 /** @implements {BaseUnit} */
-App.SecExp.BaseSlaveUnit = class BaseSlaveUnit {
+App.Mods.SecExp.BaseSlaveUnit = class BaseSlaveUnit {
 	static get attack() {
-		return 8 + App.SecExp.getAppliedUpgrades('human').attack + App.SecExp.getEdictUpgradeVal("slave", "attack");
+		return 8 + App.Mods.SecExp.getAppliedUpgrades('human').attack + App.Mods.SecExp.getEdictUpgradeVal("slave", "attack");
 	}
 
 	static get defense() {
-		return 3 + App.SecExp.getAppliedUpgrades('human').defense + App.SecExp.getEdictUpgradeVal("slave", "defense");
+		return 3 + App.Mods.SecExp.getAppliedUpgrades('human').defense + App.Mods.SecExp.getEdictUpgradeVal("slave", "defense");
 	}
 
 	static get morale() {
-		return 110 + App.SecExp.getAppliedUpgrades('human').morale + App.SecExp.getEdictUpgradeVal("slave", "morale");
+		return 110 + App.Mods.SecExp.getAppliedUpgrades('human').morale + App.Mods.SecExp.getEdictUpgradeVal("slave", "morale");
 	}
 
 	static get hp() {
-		return 3 + App.SecExp.getAppliedUpgrades('human').hp + App.SecExp.getEdictUpgradeVal("slave", "hp");
+		return 3 + App.Mods.SecExp.getAppliedUpgrades('human').hp + App.Mods.SecExp.getEdictUpgradeVal("slave", "hp");
 	}
 };
 
 /** @implements {BaseUnit} */
-App.SecExp.BaseMercUnit = class BaseMercUnit {
+App.Mods.SecExp.BaseMercUnit = class BaseMercUnit {
 	static get attack() {
-		return 8 + App.SecExp.getAppliedUpgrades('human').attack + App.SecExp.getEdictUpgradeVal("merc", "attack");
+		return 8 + App.Mods.SecExp.getAppliedUpgrades('human').attack + App.Mods.SecExp.getEdictUpgradeVal("merc", "attack");
 	}
 
 	static get defense() {
-		return 4 + App.SecExp.getAppliedUpgrades('human').defense + App.SecExp.getEdictUpgradeVal("merc", "defense");
+		return 4 + App.Mods.SecExp.getAppliedUpgrades('human').defense + App.Mods.SecExp.getEdictUpgradeVal("merc", "defense");
 	}
 
 	static get morale() {
-		return 125 + App.SecExp.getAppliedUpgrades('human').morale + App.SecExp.getEdictUpgradeVal("merc", "morale");
+		return 125 + App.Mods.SecExp.getAppliedUpgrades('human').morale + App.Mods.SecExp.getEdictUpgradeVal("merc", "morale");
 	}
 
 	static get hp() {
-		return 4 + App.SecExp.getAppliedUpgrades('human').hp + App.SecExp.getEdictUpgradeVal("merc", "hp");
+		return 4 + App.Mods.SecExp.getAppliedUpgrades('human').hp + App.Mods.SecExp.getEdictUpgradeVal("merc", "hp");
 	}
 };
 
 /** @implements {BaseUnit} */
-App.SecExp.BaseDroneUnit = class BaseDroneUnit {
+App.Mods.SecExp.BaseDroneUnit = class BaseDroneUnit {
 	static get attack() {
-		return 7 + App.SecExp.getAppliedUpgrades('drone').attack;
+		return 7 + App.Mods.SecExp.getAppliedUpgrades('drone').attack;
 	}
 
 	static get defense() {
-		return 3 + App.SecExp.getAppliedUpgrades('drone').defense;
+		return 3 + App.Mods.SecExp.getAppliedUpgrades('drone').defense;
 	}
 
 	static get morale() {
@@ -1093,12 +1105,12 @@ App.SecExp.BaseDroneUnit = class BaseDroneUnit {
 	}
 
 	static get hp() {
-		return 3 + App.SecExp.getAppliedUpgrades('drone').hp;
+		return 3 + App.Mods.SecExp.getAppliedUpgrades('drone').hp;
 	}
 };
 
 /** @implements {BaseUnit} */
-App.SecExp.BaseRaiderUnit = class BaseRaiderUnit {
+App.Mods.SecExp.BaseRaiderUnit = class BaseRaiderUnit {
 	static get attack() {
 		return 7 + (V.SecExp.buildings.weapManu ? V.SecExp.buildings.weapManu.sellTo.raiders : 0);
 	}
@@ -1117,7 +1129,7 @@ App.SecExp.BaseRaiderUnit = class BaseRaiderUnit {
 };
 
 /** @implements {BaseUnit} */
-App.SecExp.BaseFreeCityUnit = class BaseFreeCityUnit {
+App.Mods.SecExp.BaseFreeCityUnit = class BaseFreeCityUnit {
 	static get attack() {
 		return 6 + (V.SecExp.buildings.weapManu ? V.SecExp.buildings.weapManu.sellTo.FC : 0);
 	}
@@ -1136,7 +1148,7 @@ App.SecExp.BaseFreeCityUnit = class BaseFreeCityUnit {
 };
 
 /** @implements {BaseUnit} */
-App.SecExp.BaseOldWorldUnit = class BaseOldWorldUnit {
+App.Mods.SecExp.BaseOldWorldUnit = class BaseOldWorldUnit {
 	static get attack() {
 		return 8 + (V.SecExp.buildings.weapManu ? V.SecExp.buildings.weapManu.sellTo.oldWorld : 0);
 	}
@@ -1155,7 +1167,7 @@ App.SecExp.BaseOldWorldUnit = class BaseOldWorldUnit {
 };
 
 /** @implements {BaseUnit} */
-App.SecExp.BaseFreedomFighterUnit = class BaseFreedomFighterUnit {
+App.Mods.SecExp.BaseFreedomFighterUnit = class BaseFreedomFighterUnit {
 	static get attack() {
 		return 9 + (V.SecExp.buildings.weapManu ? V.SecExp.buildings.weapManu.sellTo.oldWorld : 0);
 	}
@@ -1174,26 +1186,26 @@ App.SecExp.BaseFreedomFighterUnit = class BaseFreedomFighterUnit {
 };
 
 /** @implements {BaseUnit} */
-App.SecExp.BaseSpecialForcesUnit = class BaseSpecialForcesUnit {
+App.Mods.SecExp.BaseSpecialForcesUnit = class BaseSpecialForcesUnit {
 	static get attack() {
-		return 8 + App.SecExp.getAppliedUpgrades('human').attack;
+		return 8 + App.Mods.SecExp.getAppliedUpgrades('human').attack;
 	}
 
 	static get defense() {
-		return 4 + App.SecExp.getAppliedUpgrades('human').defense;
+		return 4 + App.Mods.SecExp.getAppliedUpgrades('human').defense;
 	}
 
 	static get morale() {
-		return 140 + App.SecExp.getAppliedUpgrades('human').morale;
+		return 140 + App.Mods.SecExp.getAppliedUpgrades('human').morale;
 	}
 
 	static get hp() {
-		return 4 + App.SecExp.getAppliedUpgrades('human').hp;
+		return 4 + App.Mods.SecExp.getAppliedUpgrades('human').hp;
 	}
 };
 
 /** Unit base class */
-App.SecExp.Unit = class SecExpUnit {
+App.Mods.SecExp.Unit = class SecExpUnit {
 	/** @param {FC.SecExp.UnitData} data
 	 * @param {BaseUnit} baseUnit
 	 */
@@ -1233,7 +1245,7 @@ App.SecExp.Unit = class SecExpUnit {
 	}
 };
 
-App.SecExp.DroneUnit = class SecExpDroneUnit extends App.SecExp.Unit {
+App.Mods.SecExp.DroneUnit = class SecExpDroneUnit extends App.Mods.SecExp.Unit {
 	/** @param {FC.SecExp.PlayerUnitData} data
 	 * @param {BaseUnit} baseUnit
 	 */
@@ -1243,12 +1255,12 @@ App.SecExp.DroneUnit = class SecExpDroneUnit extends App.SecExp.Unit {
 	}
 
 	get attack() {
-		const equipmentFactor = this._data.equip * App.SecExp.equipMod;
+		const equipmentFactor = this._data.equip * App.Mods.SecExp.equipMod;
 		return this._baseUnit.attack * (1 + equipmentFactor);
 	}
 
 	get defense() {
-		const equipmentFactor = this._data.equip * App.SecExp.equipMod;
+		const equipmentFactor = this._data.equip * App.Mods.SecExp.equipMod;
 		return this._baseUnit.defense * (1 + equipmentFactor);
 	}
 
@@ -1267,7 +1279,7 @@ App.SecExp.DroneUnit = class SecExpDroneUnit extends App.SecExp.Unit {
 	}
 };
 
-App.SecExp.HumanUnit = class SecExpHumanUnit extends App.SecExp.Unit {
+App.Mods.SecExp.HumanUnit = class SecExpHumanUnit extends App.Mods.SecExp.Unit {
 	/** @param {FC.SecExp.PlayerHumanUnitData} data
 	 * @param {BaseUnit} baseUnit
 	 */
@@ -1277,17 +1289,17 @@ App.SecExp.HumanUnit = class SecExpHumanUnit extends App.SecExp.Unit {
 	}
 
 	get attack() {
-		const equipmentFactor = this._data.equip * App.SecExp.equipMod;
-		const experienceFactor = App.SecExp.trainingValueToBonusFactor(this._data.training);
-		const loyaltyFactor = App.SecExp.loyaltyValueToBonusFactor(this._data.loyalty);
+		const equipmentFactor = this._data.equip * App.Mods.SecExp.equipMod;
+		const experienceFactor = App.Mods.SecExp.trainingValueToBonusFactor(this._data.training);
+		const loyaltyFactor = App.Mods.SecExp.loyaltyValueToBonusFactor(this._data.loyalty);
 		const SFFactor = 0.20 * this._data.SF;
 		return this._baseUnit.attack * (1 + equipmentFactor + experienceFactor + loyaltyFactor + SFFactor) + this._data.cyber;
 	}
 
 	get defense() {
-		const equipmentFactor = this._data.equip * App.SecExp.equipMod;
-		const experienceFactor = App.SecExp.trainingValueToBonusFactor(this._data.training);
-		const loyaltyFactor = App.SecExp.loyaltyValueToBonusFactor(this._data.loyalty);
+		const equipmentFactor = this._data.equip * App.Mods.SecExp.equipMod;
+		const experienceFactor = App.Mods.SecExp.trainingValueToBonusFactor(this._data.training);
+		const loyaltyFactor = App.Mods.SecExp.loyaltyValueToBonusFactor(this._data.loyalty);
 		const SFFactor = 0.20 * this._data.SF;
 		return this._baseUnit.defense * (1 + equipmentFactor + experienceFactor + loyaltyFactor + SFFactor) + this._data.cyber;
 	}
@@ -1300,7 +1312,7 @@ App.SecExp.HumanUnit = class SecExpHumanUnit extends App.SecExp.Unit {
 
 	printStats() {
 		let r = new DocumentFragment();
-		this._descType = App.SecExp.unit.checkID(this._data.ID);
+		this._descType = App.Mods.SecExp.unit.checkID(this._data.ID);
 		App.UI.DOM.appendNewElement("div", r, `${this._descType} base attack: ${this._baseUnit.attack} (After modifiers: ${Math.trunc(this.attack)})`);
 		App.UI.DOM.appendNewElement("div", r, `${this._descType} base defense: ${this._baseUnit.defense} (After modifiers: ${Math.trunc(this.defense)})`);
 		if (this._data.equip > 0) {
@@ -1310,10 +1322,10 @@ App.SecExp.HumanUnit = class SecExpHumanUnit extends App.SecExp.Unit {
 			App.UI.DOM.appendNewElement("div", r, `Cyber enhancements bonus: +1`);
 		}
 		if (this._data.training > 0) {
-			App.UI.DOM.appendNewElement("div", r, `Experience bonus: +${Math.trunc(App.SecExp.trainingValueToBonusFactor(this._data.training)*100)}%`);
+			App.UI.DOM.appendNewElement("div", r, `Experience bonus: +${Math.trunc(App.Mods.SecExp.trainingValueToBonusFactor(this._data.training)*100)}%`);
 		}
 		if (this._data.loyalty > 0) {
-			App.UI.DOM.appendNewElement("div", r, `Loyalty bonus: +${Math.trunc(App.SecExp.loyaltyValueToBonusFactor(this._data.loyalty)*100)}%`);
+			App.UI.DOM.appendNewElement("div", r, `Loyalty bonus: +${Math.trunc(App.Mods.SecExp.loyaltyValueToBonusFactor(this._data.loyalty)*100)}%`);
 		}
 		if (this._data.SF > 0) {
 			App.UI.DOM.appendNewElement("div", r, `Special Force advisors bonus: +20%`);
@@ -1330,7 +1342,7 @@ App.SecExp.HumanUnit = class SecExpHumanUnit extends App.SecExp.Unit {
 	}
 };
 
-App.SecExp.troopsFromSF = function() {
+App.Mods.SecExp.troopsFromSF = function() {
 	if (V.SecExp.war.type.includes("Attack")) {
 		const transportMax = Math.trunc(125 * (V.SF.Squad.GunS + (V.terrain !== "oceanic" ? ((V.SF.Squad.AV + V.SF.Squad.TV)/2) : 0)));
 		return Math.min(transportMax, V.SF.ArmySize);
@@ -1339,9 +1351,9 @@ App.SecExp.troopsFromSF = function() {
 	}
 };
 
-App.SecExp.SFUnit = class SFUnit extends App.SecExp.Unit {
+App.Mods.SecExp.SFUnit = class SFUnit extends App.Mods.SecExp.Unit {
 	constructor() {
-		super(null, App.SecExp.BaseSpecialForcesUnit);
+		super(null, App.Mods.SecExp.BaseSpecialForcesUnit);
 		this._distancePenalty = (V.SecExp.war.type.includes("Attack")) ? 0.10 : 0.0;
 	}
 
@@ -1358,11 +1370,11 @@ App.SecExp.SFUnit = class SFUnit extends App.SecExp.Unit {
 	}
 
 	get hp() {
-		return this._baseUnit.hp * App.SecExp.troopsFromSF();
+		return this._baseUnit.hp * App.Mods.SecExp.troopsFromSF();
 	}
 };
 
-App.SecExp.EnemyUnit = class SecExpEnemyUnit extends App.SecExp.Unit {
+App.Mods.SecExp.EnemyUnit = class SecExpEnemyUnit extends App.Mods.SecExp.Unit {
 	/** @param {FC.SecExp.UnitData} data
 	 * @param {BaseUnit} baseUnit
 	 */
@@ -1371,12 +1383,12 @@ App.SecExp.EnemyUnit = class SecExpEnemyUnit extends App.SecExp.Unit {
 	}
 
 	get attack() {
-		const equipmentFactor = this._data.equip * App.SecExp.equipMod;
+		const equipmentFactor = this._data.equip * App.Mods.SecExp.equipMod;
 		return this._baseUnit.attack * (1 + equipmentFactor);
 	}
 
 	get defense() {
-		const equipmentFactor = this._data.equip * App.SecExp.equipMod;
+		const equipmentFactor = this._data.equip * App.Mods.SecExp.equipMod;
 		return this._baseUnit.defense * (1 + equipmentFactor);
 	}
 
@@ -1385,7 +1397,7 @@ App.SecExp.EnemyUnit = class SecExpEnemyUnit extends App.SecExp.Unit {
 	}
 };
 
-App.SecExp.IrregularUnit = class SecExpEnemyUnit extends App.SecExp.Unit {
+App.Mods.SecExp.IrregularUnit = class SecExpEnemyUnit extends App.Mods.SecExp.Unit {
 	/** @param {FC.SecExp.UnitData} data
 	 * @param {BaseUnit} baseUnit
 	 */
@@ -1394,25 +1406,25 @@ App.SecExp.IrregularUnit = class SecExpEnemyUnit extends App.SecExp.Unit {
 	}
 
 	get attack() {
-		const equipmentFactor = this._data.equip * App.SecExp.equipMod;
-		return (this._baseUnit.attack - App.SecExp.getAppliedUpgrades('human').attack) * (1 + equipmentFactor);
+		const equipmentFactor = this._data.equip * App.Mods.SecExp.equipMod;
+		return (this._baseUnit.attack - App.Mods.SecExp.getAppliedUpgrades('human').attack) * (1 + equipmentFactor);
 	}
 
 	get defense() {
-		const equipmentFactor = this._data.equip * App.SecExp.equipMod;
-		return (this._baseUnit.defense - App.SecExp.getAppliedUpgrades('human').defense) * (1 + equipmentFactor);
+		const equipmentFactor = this._data.equip * App.Mods.SecExp.equipMod;
+		return (this._baseUnit.defense - App.Mods.SecExp.getAppliedUpgrades('human').defense) * (1 + equipmentFactor);
 	}
 
 	get hp() {
-		return (this._baseUnit.hp - App.SecExp.getAppliedUpgrades('human').hp) * this._data.troops;
+		return (this._baseUnit.hp - App.Mods.SecExp.getAppliedUpgrades('human').hp) * this._data.troops;
 	}
 };
 
-App.SecExp.mercenaryAvgLoyalty = function() {
+App.Mods.SecExp.mercenaryAvgLoyalty = function() {
 	return _.mean(V.SecExp.units.mercs.squads.filter((u) => u.active === 1).map((u) => u.loyalty));
 };
 
-App.SecExp.Manpower = {
+App.Mods.SecExp.Manpower = {
 	get totalMilitia() {
 		return this.employedMilitia + this.freeMilitia;
 	},
diff --git a/src/Mods/SecExp/js/authorityReport.js b/src/Mods/SecExp/js/authorityReport.js
index 4a8b8f87d4a88b91262111408b4bdc3126a20ada..33db7ebaa4c97c75a1de3a947f605c8df48c09f4 100644
--- a/src/Mods/SecExp/js/authorityReport.js
+++ b/src/Mods/SecExp/js/authorityReport.js
@@ -1,4 +1,4 @@
-App.SecExp.authorityReport = function() {
+App.Mods.SecExp.authorityReport = function() {
 	let authGrowth = 0;
 	let r = V.useTabs === 0 ? [`<h2>Authority</h2>`] : [];
 	r.push(`<br>Your authority is`);
@@ -95,7 +95,7 @@ App.SecExp.authorityReport = function() {
 		authGrowth -= (5 * Math.trunc(V.arcologies[0].ownership / 10));
 	}
 
-	const activeUnits = App.SecExp.battle.activeUnits();
+	const activeUnits = App.Mods.SecExp.battle.activeUnits();
 	if (activeUnits >= 4) {
 		r.push(`Your military is`);
 		if (activeUnits >= 9) {
@@ -109,7 +109,7 @@ App.SecExp.authorityReport = function() {
 		authGrowth += (12 * activeUnits);
 	}
 
-	const SF = App.SecExp.assistanceSF('authority');
+	const SF = App.Mods.SecExp.assistanceSF('authority');
 	r.push(SF.text); authGrowth += SF.bonus;
 
 	const FSChattel = V.arcologies[0].FSChattelReligionist;
@@ -147,9 +147,9 @@ App.SecExp.authorityReport = function() {
 		}
 	}
 
-	if (App.SecExp.upkeep.edictsAuth() > 0) {
+	if (App.Mods.SecExp.upkeep.edictsAuth() > 0) {
 		r.push(`Some of your authority is spent maintaining your edicts.`);
-		authGrowth -= App.SecExp.upkeep.edictsAuth();
+		authGrowth -= App.Mods.SecExp.upkeep.edictsAuth();
 	}
 
 	if (authGrowth > 0) {
@@ -159,7 +159,7 @@ App.SecExp.authorityReport = function() {
 	} else {
 		r.push(`This week <span class="red">authority has decreased.</span>`);
 	}
-	App.SecExp.authorityX(authGrowth);
+	App.Mods.SecExp.authorityX(authGrowth);
 
 	if (V.SecExp.settings.rebellion.enabled === 1) {
 		const authorityEffects = function(group) {
@@ -453,7 +453,7 @@ App.SecExp.authorityReport = function() {
 			r.push(`<br><br><span class="red">Error: tension is outside accepted range.</span><br>`);
 		}
 
-		App.SecExp.generator.rebellion(); // rolls for rebellions
+		App.Mods.SecExp.generator.rebellion(); // rolls for rebellions
 	}
 	return App.Events.makeNode(r);
 };
diff --git a/src/Mods/SecExp/js/edicts.js b/src/Mods/SecExp/js/edicts.js
index ed9afedd862247dee463d65e415ba427d78d38d4..6562cb93aec7fcc561c49e34dfd6c857b8bc88e8 100644
--- a/src/Mods/SecExp/js/edicts.js
+++ b/src/Mods/SecExp/js/edicts.js
@@ -1,4 +1,4 @@
-App.SecExp.edicts = function() {
+App.Mods.SecExp.edicts = function() {
 	function genMenu(name, detail) {
 		const t = new DocumentFragment();
 		if (detail.implement.find(s => s.conditional) || detail.repeal && detail.repeal.find(s => s.conditional)) {
@@ -23,7 +23,7 @@ App.SecExp.edicts = function() {
 								() => {
 									if (detail.implement[i].conditional) {
 										cashX(-5000, "edicts");
-										App.SecExp.authorityX(-1000);
+										App.Mods.SecExp.authorityX(-1000);
 									}
 									current.set();
 									App.UI.reload();
@@ -644,7 +644,7 @@ App.SecExp.edicts = function() {
 						set: function() {
 							V.SecExp.edicts.defense.militia = 2;
 						},
-						note: `Will replenish militia manpower slowly and will cap at ${num(App.SecExp.militiaCap(2)*100)}% of the total citizens population.`
+						note: `Will replenish militia manpower slowly and will cap at ${num(App.Mods.SecExp.militiaCap(2)*100)}% of the total citizens population.`
 					},
 					{
 						text: `ensure every citizen is required to train in the militia and serve the arcology if the need arises.`,
@@ -652,7 +652,7 @@ App.SecExp.edicts = function() {
 						set: function() {
 							V.SecExp.edicts.defense.militia = 3;
 						},
-						note: `Will replenish militia manpower moderately fast and will cap at ${num(App.SecExp.militiaCap(3)*100)}% of the total citizens population, but has a high authority cost.`
+						note: `Will replenish militia manpower moderately fast and will cap at ${num(App.Mods.SecExp.militiaCap(3)*100)}% of the total citizens population, but has a high authority cost.`
 					},
 					{
 						text: `ensure every citizen is required to register and serve under the militia.`,
@@ -660,7 +660,7 @@ App.SecExp.edicts = function() {
 						set: function() {
 							V.SecExp.edicts.defense.militia = 4;
 						},
-						note: `Will quickly replenish militia manpower and will cap at ${num(App.SecExp.militiaCap(4)*100)}% of the total citizens population, but has a very high authority cost.`
+						note: `Will quickly replenish militia manpower and will cap at ${num(App.Mods.SecExp.militiaCap(4)*100)}% of the total citizens population, but has a very high authority cost.`
 					},
 					{
 						text: `ensure that very adult citizen is required to train and participate in the defense of the arcology.`,
@@ -668,7 +668,7 @@ App.SecExp.edicts = function() {
 						set: function() {
 							V.SecExp.edicts.defense.militia = 5;
 						},
-						note: `Will very quickly replenish militia manpower and will cap at ${num(App.SecExp.militiaCap(5)*100)}% of the total citizens population, but has an extremely high authority cost`
+						note: `Will very quickly replenish militia manpower and will cap at ${num(App.Mods.SecExp.militiaCap(5)*100)}% of the total citizens population, but has an extremely high authority cost`
 					},
 				]
 			}],
@@ -900,7 +900,7 @@ App.SecExp.edicts = function() {
 				implement: [
 					{
 						text: `${capSF} will provide the security HQ with advanced equipment.`,
-						conditional: V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.edicts.SFSupportLevel === 0 && App.SecExp.Check.reqMenials() > 5,
+						conditional: V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.edicts.SFSupportLevel === 0 && App.Mods.SecExp.Check.reqMenials() > 5,
 						set: function() {
 							V.SecExp.edicts.SFSupportLevel = 1;
 						},
@@ -908,7 +908,7 @@ App.SecExp.edicts = function() {
 					},
 					{
 						text: `${capSF} will provide the security HQ personnel with advanced training.`,
-						conditional: V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.edicts.SFSupportLevel === 1 && V.SF.Squad.Firebase >= 4 && App.SecExp.Check.reqMenials() > 5,
+						conditional: V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.edicts.SFSupportLevel === 1 && V.SF.Squad.Firebase >= 4 && App.Mods.SecExp.Check.reqMenials() > 5,
 						set: function() {
 							V.SecExp.edicts.SFSupportLevel = 2;
 						},
@@ -916,7 +916,7 @@ App.SecExp.edicts = function() {
 					},
 					{
 						text: `${capSF} will provide troops to the security department.`,
-						conditional: V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.edicts.SFSupportLevel === 2 && V.SF.Squad.Firebase >= 6 && App.SecExp.Check.reqMenials() > 5,
+						conditional: V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.edicts.SFSupportLevel === 2 && V.SF.Squad.Firebase >= 6 && App.Mods.SecExp.Check.reqMenials() > 5,
 						set: function() {
 							V.SecExp.edicts.SFSupportLevel = 3;
 						},
@@ -924,7 +924,7 @@ App.SecExp.edicts = function() {
 					},
 					{
 						text: `${capSF} will give the security department its full support.`,
-						conditional: V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.edicts.SFSupportLevel === 3 && V.SF.Squad.Firebase >= 6 && App.SecExp.Check.reqMenials() > 5,
+						conditional: V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.edicts.SFSupportLevel === 3 && V.SF.Squad.Firebase >= 6 && App.Mods.SecExp.Check.reqMenials() > 5,
 						set: function() {
 							V.SecExp.edicts.SFSupportLevel = 4;
 						},
@@ -932,7 +932,7 @@ App.SecExp.edicts = function() {
 					},
 					{
 						text: `${capSF} will assist the security department with installing a local version of their custom network.`,
-						conditional: V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.edicts.SFSupportLevel === 4 && V.SF.Squad.Firebase === 10 && App.SecExp.Check.reqMenials() > 5,
+						conditional: V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.edicts.SFSupportLevel === 4 && V.SF.Squad.Firebase === 10 && App.Mods.SecExp.Check.reqMenials() > 5,
 						set: function() {
 							V.SecExp.edicts.SFSupportLevel = 5;
 						},
diff --git a/src/Mods/SecExp/js/reportingRelatedFunctions.js b/src/Mods/SecExp/js/reportingRelatedFunctions.js
index a7224ac63b6379a6161a537a0d63bac9a0c93a93..60eb56328f6c808f77a9ac3b4490e65719da3eda 100644
--- a/src/Mods/SecExp/js/reportingRelatedFunctions.js
+++ b/src/Mods/SecExp/js/reportingRelatedFunctions.js
@@ -4,8 +4,8 @@
  * @param {string} [section=''] which sub section (if any) is this function being called from.
  * @returns {{text:string, bonus:number}}
  */
-App.SecExp.assistanceSF = function(report, section = '') {
-	const size = V.SF.Toggle && V.SF.Active >= 1 ? App.SF.upgrades.total() : 0;
+App.Mods.SecExp.assistanceSF = function(report, section = '') {
+	const size = V.SF.Toggle && V.SF.Active >= 1 ? App.Mods.SF.upgrades.total() : 0;
 	let r = ``; let bonus = 0;
 	if (size > 10) {
 		if (report === 'authority' || report === 'trade') {
@@ -28,7 +28,7 @@ App.SecExp.assistanceSF = function(report, section = '') {
  * @param {string} [focus] campaign option to check against.
  * @returns {{text:string, effect:number}}}
  */
-App.SecExp.propagandaEffects = function(focus) {
+App.Mods.SecExp.propagandaEffects = function(focus) {
 	let t = ``; let increase = 0;
 	if (V.secExpEnabled > 0 && V.SecExp.buildings.propHub && V.SecExp.buildings.propHub.upgrades.campaign >= 1 && V.SecExp.buildings.propHub.focus === focus) {
 		let campaign; let modifier;
@@ -85,14 +85,14 @@ App.SecExp.propagandaEffects = function(focus) {
 	return {text: t, effect: Math.round(increase)};
 };
 
-App.SecExp.slavesDamaged = function(adjustValue) {
+App.Mods.SecExp.slavesDamaged = function(adjustValue) {
 	V.NPCSlaves -= Math.trunc((V.NPCSlaves / V.ASlaves) * adjustValue);
 	V.menials -= Math.trunc((V.menials / V.ASlaves) * adjustValue);
 	V.fuckdolls -= Math.trunc((V.fuckdolls / V.ASlaves) * adjustValue);
 	V.menialBioreactors -= Math.trunc((V.menialBioreactors / V.ASlaves) * adjustValue);
 };
 
-App.SecExp.updateFacilityDamage = function(facility) {
+App.Mods.SecExp.updateFacilityDamage = function(facility) {
 	let text = ``;
 	let securityEffect = 0;
 	let crimeEffect = 0;
@@ -131,7 +131,7 @@ App.SecExp.updateFacilityDamage = function(facility) {
 /** Returns the how effective the selected commander is.
  * @param {string} passage if "handler" only numbers are returned else a string.
  */
-App.SecExp.commanderEffectiveness = function(passage) {
+App.Mods.SecExp.commanderEffectiveness = function(passage) {
 	const r = [];
 	const oldRep = V.rep;
 	const oldAuth = V.SecExp.core.authority;
@@ -257,7 +257,7 @@ App.SecExp.commanderEffectiveness = function(passage) {
 				}
 			} else {
 				r.push(`You decided to personally lead the defense of your arcology.`);
-				if (App.SecExp.battle.deployedUnits('militia') >= 1) {
+				if (App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 					if (oldRep <= 2500) {
 						if (oldRep > 1000) {
 							r.push(`You're not particularly popular between the inhabitants of your arcology, so your presence does little to reassure the volunteers.`);
@@ -294,7 +294,7 @@ App.SecExp.commanderEffectiveness = function(passage) {
 						}
 					}
 				}
-				if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
+				if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 					if (oldAuth <= 2500) {
 						if (oldAuth > 1000) {
 							r.push(`Your slave soldiers do not feel bound to you as much as they should, as your authority is far from absolute.`);
@@ -327,8 +327,8 @@ App.SecExp.commanderEffectiveness = function(passage) {
 						}
 					}
 				}
-				if (App.SecExp.battle.deployedUnits('mercs') >= 1) {
-					const mercLoyalty = App.SecExp.mercenaryAvgLoyalty();
+				if (App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
+					const mercLoyalty = App.Mods.SecExp.mercenaryAvgLoyalty();
 					if (mercLoyalty <= 25) {
 						if (mercLoyalty <= 10) {
 							r.push(`Your mercenaries barely bother to pretend being loyal; their battle performance is obviously barely passable.`);
@@ -417,7 +417,7 @@ App.SecExp.commanderEffectiveness = function(passage) {
 				}
 			} else {
 				r.push(`${V.assistant.name} lead the troops.`);
-				if (App.SecExp.battle.deployedUnits('mercs') >= 1 || App.SecExp.battle.deployedUnits('militia') >= 1 || App.SecExp.battle.deployedUnits('slaves') >= 1) {
+				if (App.Mods.SecExp.battle.deployedUnits('mercs') >= 1 || App.Mods.SecExp.battle.deployedUnits('militia') >= 1 || App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 					r.push(`No soldier trusts a computer to be their commander,`);
 					if (oldRep < 10000 && oldAuth < 10000) {
 						r.push(`no algorithm can substitute experience,`);
@@ -452,7 +452,7 @@ App.SecExp.commanderEffectiveness = function(passage) {
 		case "HeadGirl":
 			slave = S[commander];
 			/* eslint-disable no-case-declarations */
-			const CareerGivesBonus = App.Data.Careers.Leader[isBodyguard ? "bodyguard" : "HG"].includes(slave.career) || setup.secExCombatPrestige.includes(slave.prestigeDesc);
+			const CareerGivesBonus = App.Data.Careers.Leader[isBodyguard ? "bodyguard" : "HG"].includes(slave.career) || App.Data.misc.secExCombatPrestige.includes(slave.prestigeDesc);
 			const TotalIntelligence = slave.intelligence + slave.intelligenceImplant;
 
 			if (inHandler) {
@@ -568,7 +568,7 @@ App.SecExp.commanderEffectiveness = function(passage) {
 					his, he, him
 				} = getPronouns(slave);
 				r.push(`Your ${isBodyguard ? 'bodyguard' : 'Head Girl'} lead the troops.`);
-				if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
+				if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 					if (slave.devotion < -20) {
 						r.push(`${His} low devotion has a negative impact on the morale of your slave soldiers.`);
 					} else if (slave.devotion > 51) {
@@ -576,90 +576,90 @@ App.SecExp.commanderEffectiveness = function(passage) {
 					}
 				}
 				if (oldRep < 10000 && oldAuth < 10000 || slave.prestige < 1) {
-					if (App.SecExp.battle.deployedUnits('militia') >= 1) {
+					if (App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 						r.push(`Your volunteers`);
-						if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
+						if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 							r.push(`however`);
 						}
 						r.push(`are not enthusiastic to have a slave as a`);
-						if (V.SF.Toggle && V.SF.Active >= 1 && App.SecExp.battle.deployedUnits('mercs') === 1 && V.SecExp.war.deploySF) {
+						if (V.SF.Toggle && V.SF.Active >= 1 && App.Mods.SecExp.battle.deployedUnits('mercs') === 1 && V.SecExp.war.deploySF) {
 							r.push(`commander, and neither are your mercenaries or your soldiers.`);
-						} else if (App.SecExp.battle.deployedUnits('mercs') >= 1) {
+						} else if (App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 							r.push(`commander, and neither are your mercenaries.`);
 						} else if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 							r.push(`commander, and neither are your soldiers.`);
 						} else {
 							r.push(`commander.`);
 						}
-					} else if (V.SF.Toggle && V.SF.Active >= 1 && App.SecExp.battle.deployedUnits('mercs') === 1 && V.SecExp.war.deploySF) {
+					} else if (V.SF.Toggle && V.SF.Active >= 1 && App.Mods.SecExp.battle.deployedUnits('mercs') === 1 && V.SecExp.war.deploySF) {
 						r.push(`Your mercenaries and soldiers`);
-						if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
+						if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 							r.push(`however`);
 						}
 						r.push(`are not enthusiastic to have a slave as a commander.`);
-					} else if (App.SecExp.battle.deployedUnits('mercs') >= 1) {
+					} else if (App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 						r.push(`Your mercenaries`);
-						if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
+						if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 							r.push(`however`);
 						}
 						r.push(`are not enthusiastic to have a slave as a commander.`);
 					} else if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 						r.push(`Your soldiers`);
-						if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
+						if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 							r.push(`however`);
 						}
 						r.push(`are not enthusiastic to have a slave as a commander.`);
 					}
 				} else if (slave.prestige >= 2) {
-					if (App.SecExp.battle.deployedUnits('militia') >= 1) {
+					if (App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 						r.push(`Your`);
-						if (App.SecExp.battle.deployedUnits('mercs') === 1 && V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
+						if (App.Mods.SecExp.battle.deployedUnits('mercs') === 1 && V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 							r.push(`volunteers, your mercenaries and your soldiers are delighted to have such a prestigious individual as their commander, almost forgetting ${he} is a slave.`);
-						} else if (App.SecExp.battle.deployedUnits('mercs') >= 1) {
+						} else if (App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 							r.push(`volunteers and your mercenaries are delighted to have such a prestigious individual as their commander, almost forgetting ${he} is a slave.`);
 						} else if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 							r.push(`volunteers and your soldiers are delighted to have such a prestigious individual as their commander, almost forgetting ${he} is a slave.`);
 						} else {
 							r.push(`volunteers are delighted to have such a prestigious individual as their commander, almost forgetting ${he} is a slave.`);
 						}
-					} else if (App.SecExp.battle.deployedUnits('mercs') === 1 && V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
+					} else if (App.Mods.SecExp.battle.deployedUnits('mercs') === 1 && V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 						r.push(`Your mercenaries and soldiers are delighted to have such a prestigious individual as their commander, almost forgetting ${he} is a slave.`);
-					} else if (App.SecExp.battle.deployedUnits('mercs') >= 1) {
+					} else if (App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 						r.push(`Your mercenaries are delighted to have such a prestigious individual as their commander, almost forgetting ${he} is a slave.`);
 					} else if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 						r.push(`Your soldiers are delighted to have such a prestigious individual as their commander, almost forgetting ${he} is a slave.`);
 					}
 				} else {
-					if (App.SecExp.battle.deployedUnits('militia') >= 1) {
+					if (App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 						r.push(`Your volunteers`);
-						if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
+						if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 							r.push(`however`);
 						}
 						r.push(`are not enthusiastic to have a slave as a`);
-						if (App.SecExp.battle.deployedUnits('mercs') === 1 && V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
+						if (App.Mods.SecExp.battle.deployedUnits('mercs') === 1 && V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 							r.push(`commander, and neither are your mercenaries and soldiers, but they trust you enough not to question your decision.`);
-						} else if (App.SecExp.battle.deployedUnits('mercs') >= 1) {
+						} else if (App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 							r.push(`commander, and neither are your mercenaries, but they trust you enough not to question your decision.`);
 						} else if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 							r.push(`commander, and neither are your soldiers, but they trust you enough not to question your decision.`);
 						} else {
 							r.push(`commander, but they trust you enough not to question your decision.`);
 						}
-					} else if (App.SecExp.battle.deployedUnits('mercs') === 1 && V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
+					} else if (App.Mods.SecExp.battle.deployedUnits('mercs') === 1 && V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 						r.push(`Your mercenaries and soldiers`);
-						if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
+						if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 							r.push(`however,`);
 						}
 						r.push(`are not enthusiastic to have a slave as a commander, but they trust you enough not to question your decision.`);
-					} else if (App.SecExp.battle.deployedUnits('mercs') >= 1) {
+					} else if (App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 						r.push(`Your mercenaries`);
-						if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
+						if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 							r.push(`however,`);
 						}
 						r.push(`are not enthusiastic to have a slave as a commander, but they trust you enough not to question your decision.`);
 					} else if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 						r.push(`Your soldiers`);
-						if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
+						if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 							r.push(`however,`);
 						}
 						r.push(`are not enthusiastic to have a slave as a commander, but they trust you enough not to question your decision.`);
@@ -692,7 +692,7 @@ App.SecExp.commanderEffectiveness = function(passage) {
 				}
 				if (V.SecExp.war.leaderWounded) {
 					r.push(`Unfortunately, <span class="red">${he} sustained major injuries.</span>`);
-					const woundType = App.SecExp.inflictBattleWound(slave);
+					const woundType = App.Mods.SecExp.inflictBattleWound(slave);
 					if (woundType === "voice") {
 						r.push(`A stray bullet hit ${his} neck. While ${he} fortunately avoided fatal hemorrhaging, ${his} vocal cords were irreparably damaged.`);
 					} else if (woundType === "eyes") {
@@ -761,41 +761,41 @@ App.SecExp.commanderEffectiveness = function(passage) {
 			} else {
 				r.push(`One of your volunteers was the commander.`);
 				if (V.arcologies[0].FSDegradationist === "unset" && V.arcologies[0].FSPaternalist === "unset") {
-					if (App.SecExp.battle.deployedUnits('militia') >= 1) {
+					if (App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 						r.push(`Your volunteers are honored and pleased that one of their own is leading the defense force of the city.`);
 					}
-					if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
-						r.push(`Your slaves${(App.SecExp.battle.deployedUnits('militia') >= 1) ? `, however,` : ``}are not thrilled by the news.`);
+					if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
+						r.push(`Your slaves${(App.Mods.SecExp.battle.deployedUnits('militia') >= 1) ? `, however,` : ``}are not thrilled by the news.`);
 					}
 				} else if (V.arcologies[0].FSPaternalist !== "unset") {
-					if (App.SecExp.battle.deployedUnits('militia') >= 1) {
+					if (App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 						r.push(`Your volunteers are honored and pleased that one of their own is leading the defense force of the city.`);
 					}
-					if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
+					if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 						r.push(`Thanks to your paternalistic society, your slave soldiers trust your chosen citizen to treat them as more than cannon fodder.`);
 					}
 				} else if (V.arcologies[0].FSDegradationist !== "unset") {
-					if (App.SecExp.battle.deployedUnits('militia') >= 1) {
+					if (App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 						r.push(`Your volunteers are honored and pleased that one of their own is leading the defense force of the city.`);
 					}
-					if (App.SecExp.battle.deployedUnits('slaves') >= 1) {
+					if (App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 						r.push(`Because of your degradationist society,`);
-						if (App.SecExp.battle.deployedUnits('militia') >= 1) {
+						if (App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 							r.push(`however,`);
 						}
 						r.push(`your slave soldiers are deeply distrustful of the new leader.`);
 					}
 				}
-				if (V.arcologies[0].FSRomanRevivalist !== "unset" && App.SecExp.battle.deployedUnits('mercs') >= 1) {
+				if (V.arcologies[0].FSRomanRevivalist !== "unset" && App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 					r.push(`Since you decided to revive old Rome, many of your citizens took on themselves to educate themselves in martial matters, because of this your mercenaries feel safe enough in the hands of one of your volunteers.`);
-				} else if (V.arcologies[0].FSNeoImperialist !== "unset" && App.SecExp.battle.deployedUnits('mercs') >= 1) {
+				} else if (V.arcologies[0].FSNeoImperialist !== "unset" && App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 					r.push(`Since having instituted an Imperial society, your citizens have become adept at modern warfare and your hardened mercenaries feel far more comfortable with one of your Imperial Knights in command.`);
-				} else if (App.SecExp.battle.deployedUnits('mercs') >= 1) {
+				} else if (App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 					r.push(`Your mercenaries are not thrilled to be lead by a civilian without any formal martial training or education.`);
 				}
 				if (V.arcologies[0].FSRomanRevivalist !== "unset" && V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 					r.push(`Since you decided to revive old Rome, many of your citizens took on themselves to educate themselves in martial matters, because of this your soldiers feel safe enough in the hands of one of your volunteers.`);
-				} else if (V.arcologies[0].FSNeoImperialist !== "unset" && App.SecExp.battle.deployedUnits('mercs') >= 1) {
+				} else if (V.arcologies[0].FSNeoImperialist !== "unset" && App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 					r.push(`Since having instituted an Imperial society, your citizens have become adept at modern warfare and the line soldiers feel much more comfortable being commanded by one of your Imperial Knights.`);
 				} else if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 					r.push(`You soldiers are not thrilled to be lead by a civilian without any formal martial training or education.`);
@@ -819,18 +819,18 @@ App.SecExp.commanderEffectiveness = function(passage) {
 				tacChance += random(30) * 0.1;
 			} else {
 				r.push(`One of your mercenary officers took command.`);
-				if (App.SecExp.battle.deployedUnits('mercs') >= 1) {
+				if (App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 					r.push(`Your mercenaries of course approve of your decision.`);
 				}
 				if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 					r.push(`Your soldiers feel more confident going into battle with an experienced commander.`);
 				}
-				if (V.arcologies[0].FSRomanRevivalist !== "unset" && App.SecExp.battle.deployedUnits('militia') >= 1) {
+				if (V.arcologies[0].FSRomanRevivalist !== "unset" && App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 					r.push(`Since you decided to revive old Rome, your volunteers are more willing to trust one of your mercenaries as their leader.`);
-				} else if (App.SecExp.battle.deployedUnits('militia') >= 1) {
+				} else if (App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 					r.push(`Your volunteers are not enthusiastic at the prospect of being commanded around by a gun for hire.`);
 				}
-				if (V.arcologies[0].FSDegradationist !== "unset" && App.SecExp.battle.deployedUnits('slaves') >= 1) {
+				if (V.arcologies[0].FSDegradationist !== "unset" && App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 					r.push(`Because of your degradationist society, your slave soldiers are highly distrustful of the gun for hire you forced them to accept as leader.`);
 				}
 			}
@@ -852,20 +852,20 @@ App.SecExp.commanderEffectiveness = function(passage) {
 				tacChance += random(40) * 0.1;
 			} else {
 				r.push(`The Colonel was the commander.`);
-				if (App.SecExp.battle.deployedUnits('mercs') >= 1) {
+				if (App.Mods.SecExp.battle.deployedUnits('mercs') >= 1) {
 					r.push(`Your mercenaries approve of such decisions, as they feel more confident by having a good, experienced commander.`);
 				}
 				if (V.SF.Toggle && V.SF.Active >= 1 && V.SecExp.war.deploySF) {
 					r.push(`The soldiers of ${V.SF.Lower} obviously approved of your decision.`);
 				}
-				if (V.arcologies[0].FSRomanRevivalist !== "unset" && App.SecExp.battle.deployedUnits('militia') >= 1) {
+				if (V.arcologies[0].FSRomanRevivalist !== "unset" && App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 					r.push(`Since you decided to revive old Rome, your volunteers are more willing to trust one of your soldiers as their leader.`);
-				} else if (V.arcologies[0].FSNeoImperialist !== "unset" && App.SecExp.battle.deployedUnits('militia') >= 1) {
+				} else if (V.arcologies[0].FSNeoImperialist !== "unset" && App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 					r.push(`Under the strict hierarchy of your Imperial society, the militia is more willing to follow the Colonel's commands.`);
-				} else if (App.SecExp.battle.deployedUnits('militia') >= 1) {
+				} else if (App.Mods.SecExp.battle.deployedUnits('militia') >= 1) {
 					r.push(`Your volunteers are not enthusiastic at the prospect of being commanded around by an old style military officer.`);
 				}
-				if (V.arcologies[0].FSDegradationist !== "unset" && App.SecExp.battle.deployedUnits('slaves') >= 1) {
+				if (V.arcologies[0].FSDegradationist !== "unset" && App.Mods.SecExp.battle.deployedUnits('slaves') >= 1) {
 					r.push(`Because of your degradationist society, your slave soldiers are highly distrustful of the soldier you forced them to accept as leader.`);
 				}
 			}
@@ -891,7 +891,7 @@ App.SecExp.commanderEffectiveness = function(passage) {
 	}
 };
 
-App.SecExp.upkeep = (function() {
+App.Mods.SecExp.upkeep = (function() {
 	return {
 		cost,
 		edictsAuth
@@ -904,7 +904,7 @@ App.SecExp.upkeep = (function() {
 			secExpCost += edictsCash();
 			secExpCost += SF();
 			secExpCost += buildings();
-			for (const [unit, info] of Array.from(App.SecExp.unit.list()).slice(1)) {
+			for (const [unit, info] of Array.from(App.Mods.SecExp.unit.list()).slice(1)) {
 				secExpCost += V.SecExp.units[unit].squads.reduce((acc, s) => acc + s.troops * 10 * info.costMod * soldierMod, 0);
 			}
 		}
@@ -1016,10 +1016,10 @@ App.SecExp.upkeep = (function() {
  * @param {FC.SecExp.PlayerHumanUnitData} input the unit type to be checked.
  * @returns {HTMLDivElement}
  */
-App.SecExp.humanLoyaltyChanges = function(input) {
+App.Mods.SecExp.humanLoyaltyChanges = function(input) {
 	let loyaltyChange = 0;
 	let el = document.createElement("div");
-	const type = App.SecExp.unit.checkID(input.ID);
+	const type = App.Mods.SecExp.unit.checkID(input.ID);
 
 	el.append(`${input.platoonName}: `);
 	if (V.SecExp.buildings.barracks && V.SecExp.buildings.barracks.loyaltyMod >= 1) {
diff --git a/src/Mods/SecExp/js/secExp.js b/src/Mods/SecExp/js/secExp.js
index e182e2c3baf52ccc203661a5473efe4b00e55de5..06b51fd73ed41addbc2a333d89925841962ea0ce 100644
--- a/src/Mods/SecExp/js/secExp.js
+++ b/src/Mods/SecExp/js/secExp.js
@@ -1,8 +1,8 @@
-App.SecExp.troopDiffAdjust = function() {
+App.Mods.SecExp.troopDiffAdjust = function() {
 	let pc = 1.0;
 	let enemy = 1.0;
 	if (V.SecExp && V.SecExp.war) {
-		const diff = App.SecExp.battle.troopCount() / V.SecExp.war.attacker.troops;
+		const diff = App.Mods.SecExp.battle.troopCount() / V.SecExp.war.attacker.troops;
 		if (diff > 0) {
 			pc += diff;
 			enemy -= diff;
@@ -17,11 +17,11 @@ App.SecExp.troopDiffAdjust = function() {
 /** Takes the passed input and returns a clamped V.SecExp.core.authority
  * @param {number} input defaults to zero
  */
-App.SecExp.authorityX = function(input = 0) {
+App.Mods.SecExp.authorityX = function(input = 0) {
 	V.SecExp.core.authority = Math.trunc(Math.clamp(V.SecExp.core.authority + input, 0, 20000));
 };
 
-App.SecExp.generator = (function() {
+App.Mods.SecExp.generator = (function() {
 	return {
 		attack,
 		rebellion,
@@ -196,8 +196,8 @@ App.SecExp.generator = (function() {
 			V.SecExp.war.saveValid = 0;
 			V.SecExp.war.tacticsSuccessful = 0;
 			V.SecExp.war.chosenTactic = either("Bait and Bleed", "Blitzkrieg", "Choke Points", "Defense In Depth", "Guerrilla", "Human Wave", "Interior Lines", "Pincer Maneuver");
-			V.SecExp.war.estimatedMen = normalRandInt(troops, troops * (4 - App.SecExp.battle.recon()) * 0.05);
-			V.SecExp.war.expectedEquip = normalRandInt(equip, (4 - App.SecExp.battle.recon()) * 0.25);
+			V.SecExp.war.estimatedMen = normalRandInt(troops, troops * (4 - App.Mods.SecExp.battle.recon()) * 0.05);
+			V.SecExp.war.expectedEquip = normalRandInt(equip, (4 - App.Mods.SecExp.battle.recon()) * 0.25);
 			V.SecExp.war.deployed = [];
 		}
 	}
@@ -256,7 +256,7 @@ App.SecExp.generator = (function() {
 			V.SecExp.war.attacker.equip = Math.clamp(V.SecExp.edicts.weaponsLaw + random((isSlaveRebellion ? -2 : -1), 1), 0, 4);
 			V.SecExp.war.irregulars = Math.clamp(Math.trunc(V.ACitizens * irregularPercent * weekMod) + random(-100, 100), 50, V.ACitizens);
 			V.SecExp.war.engageRule = 0;
-			V.SecExp.war.rebellingID = App.SecExp.unit.squads("human").map(u => u.loyalty).filter(isDisloyal);
+			V.SecExp.war.rebellingID = App.Mods.SecExp.unit.squads("human").map(u => u.loyalty).filter(isDisloyal);
 		}
 	}
 })();
@@ -265,7 +265,7 @@ App.SecExp.generator = (function() {
  * Returns the raw percentage of society that can be drafted.
  * @returns {number}
  */
-App.SecExp.militiaCap = function(x = 0) {
+App.Mods.SecExp.militiaCap = function(x = 0) {
 	x = x || V.SecExp.edicts.defense.militia;
 	if (x === 2) {
 		return 0.02;
@@ -278,7 +278,7 @@ App.SecExp.militiaCap = function(x = 0) {
 	}
 };
 
-App.SecExp.initTrade = function() {
+App.Mods.SecExp.initTrade = function() {
 	if (V.SecExp.core.trade === 0 || !jsDef(V.SecExp.core.trade)) {
 		let init = jsRandom(20, 30);
 		if (V.terrain === "urban") {
@@ -295,7 +295,7 @@ App.SecExp.initTrade = function() {
 	}
 };
 
-App.SecExp.generalInit = function() {
+App.Mods.SecExp.generalInit = function() {
 	if (V.secExpEnabled === 0) {
 		return;
 	}
@@ -401,15 +401,15 @@ App.SecExp.generalInit = function() {
 		smilingMan: {progress: 0}
 	});
 
-	for (const [unit] of App.SecExp.unit.list()) {
-		App.SecExp.unit.gen(unit);
+	for (const [unit] of App.Mods.SecExp.unit.list()) {
+		App.Mods.SecExp.unit.gen(unit);
 	}
-	App.SecExp.initTrade();
+	App.Mods.SecExp.initTrade();
 };
 
-App.SecExp.battle = (function() {
+App.Mods.SecExp.battle = (function() {
 	"use strict";
-	const unitFunctions = App.SecExp.unit;
+	const unitFunctions = App.Mods.SecExp.unit;
 	return {
 		deployedUnits,
 		troopCount,
@@ -436,7 +436,7 @@ App.SecExp.battle = (function() {
 			count.militia++;
 		}
 
-		Array.from(unitFunctions.list().keys()).forEach((s) => count[s] += V.SecExp.units[s].squads.filter(u => App.SecExp.unit.isDeployed(u)).length);
+		Array.from(unitFunctions.list().keys()).forEach((s) => count[s] += V.SecExp.units[s].squads.filter(u => App.Mods.SecExp.unit.isDeployed(u)).length);
 		if (input === '') {
 			return Object.values(count).reduce((a, b) => a + b) + init;
 		} else {
@@ -451,7 +451,7 @@ App.SecExp.battle = (function() {
 		const inBattle = V.SecExp.war.type.includes("Attack");
 		let troops = 0;
 		if (V.SF.Toggle && V.SF.Active >= 1 && (inBattle && V.SecExp.war.deploySF || !inBattle)) {
-			troops += App.SecExp.troopsFromSF();
+			troops += App.Mods.SecExp.troopsFromSF();
 		}
 		if (!inBattle) {
 			troops += V.SecExp.war.irregulars;
@@ -488,7 +488,7 @@ App.SecExp.battle = (function() {
 	 * @returns {number}
 	 */
 	function deployableUnits() {
-		let init = 2 * App.SecExp.battle.deploySpeed();
+		let init = 2 * App.Mods.SecExp.battle.deploySpeed();
 		init -= unitFunctions.squads().filter(s => unitFunctions.isDeployed(s)).length;
 		return Math.max(0, init);
 	}
@@ -497,7 +497,7 @@ App.SecExp.battle = (function() {
 	 * @returns {number}
 	 */
 	function activeUnits() {
-		return V.secExpEnabled > 0 ? App.SecExp.unit.squads().filter(s => s.active).length : 0;
+		return V.secExpEnabled > 0 ? App.Mods.SecExp.unit.squads().filter(s => s.active).length : 0;
 	}
 
 	/** Get maximum active units
@@ -507,7 +507,7 @@ App.SecExp.battle = (function() {
 		let max = 0;
 		if (V.SecExp.buildings.barracks) {
 			max += 8 + (V.SecExp.buildings.barracks.size * 2);
-			if (App.SecExp.battle.deploySpeed() === 10) {
+			if (App.Mods.SecExp.battle.deploySpeed() === 10) {
 				max += 2;
 			}
 		}
@@ -544,7 +544,7 @@ App.SecExp.battle = (function() {
 	}
 })();
 
-App.SecExp.Check = (function() {
+App.Mods.SecExp.Check = (function() {
 	"use strict";
 	return {
 		secRestPoint,
@@ -648,7 +648,7 @@ App.SecExp.Check = (function() {
 	}
 })();
 
-App.SecExp.inflictBattleWound = (function() {
+App.Mods.SecExp.inflictBattleWound = (function() {
 	/** @typedef {object} Wound
 	 * @property {number} weight
 	 * @property {function(App.Entity.SlaveState):boolean} allowed
@@ -662,7 +662,7 @@ App.SecExp.inflictBattleWound = (function() {
 			effects: (s) => {
 				clampedDamage(s, 30);
 				eyeSurgery(s, "both", "blind");
-				App.Medicine.Modification.addScar(s, "damaged eyes", "While leading your army a splinter hit the eyes causing major damage.");
+				App.Medicine.Modification.addScar(s, "damaged eyes", "a scar from shrapnel obtained while leading your army");
 			}
 		},
 		voice: {
@@ -671,7 +671,7 @@ App.SecExp.inflictBattleWound = (function() {
 			effects: (s) => {
 				clampedDamage(s, 60);
 				s.voice = 0;
-				App.Medicine.Modification.addScar(s, "damaged throat", "While leading your army a splinter hit and destroyed vocal cords");
+				App.Medicine.Modification.addScar(s, "damaged throat", "a scar from shrapnel obtained while leading your army");
 			}
 		},
 		legs: {
@@ -681,7 +681,8 @@ App.SecExp.inflictBattleWound = (function() {
 				clampedDamage(s, 80);
 				removeLimbs(s, "left leg");
 				removeLimbs(s, "right leg");
-				App.Medicine.Modification.addScar(s, "arm blown off", "While leading your army a nearby explosion mangled both legs to the point of amputation.");
+				App.Medicine.Modification.addScar(s, "left buttock", "a scar from a battle wound leading to amputation");
+				App.Medicine.Modification.addScar(s, "right buttock", "a scar from a battle wound leading to amputation");
 			}
 		},
 		arm: {
@@ -689,8 +690,9 @@ App.SecExp.inflictBattleWound = (function() {
 			allowed: (s) => hasAnyNaturalArms(s),
 			effects: (s) => {
 				clampedDamage(s, 60);
-				removeLimbs(s, jsEither(["left arm", "right arm"]));
-				App.Medicine.Modification.addScar(s, "arm blown off", "While leading your army a nearby explosion mangled an arm to the point of amputation.");
+				const side = jsEither(["left", "right"]);
+				removeLimbs(s, side === "left" ? "left arm" : "right arm");
+				App.Medicine.Modification.addScar(s, `${side} shoulder`, "a scar from a battle wound leading to amputation");
 			}
 		},
 		flesh: {
@@ -698,7 +700,7 @@ App.SecExp.inflictBattleWound = (function() {
 			allowed: () => true,
 			effects: (s) => {
 				clampedDamage(s, 30);
-				App.Medicine.Modification.addScar(s, "flesh wound", "A stray shot during leading your army grazed the skin and destroyed nerve endings");
+				App.Medicine.Modification.addScar(s, either("left shoulder", "right shoulder", "back", "lower back", "belly", "left buttock", "right buttock"), "a scar from a stray shot while leading your army");
 			}
 		}
 		// TODO: add more wound types? destroy prosthetics?
diff --git a/src/Mods/SecExp/js/secExpBC.js b/src/Mods/SecExp/js/secExpBC.js
index 28c2fa0dad1b32aa396213853aa87e79038c2c4b..d645ae5fb31b41fc5096aae17709f9ca2bcf4cf8 100644
--- a/src/Mods/SecExp/js/secExpBC.js
+++ b/src/Mods/SecExp/js/secExpBC.js
@@ -1,5 +1,5 @@
 // @ts-nocheck
-App.SecExp.generalBC = function() {
+App.Mods.SecExp.generalBC = function() {
 	if (jsDef(V.secExp)) {
 		if (V.secExpEnabled !== 1) {
 			V.secExpEnabled = V.secExp;
@@ -88,8 +88,8 @@ App.SecExp.generalBC = function() {
 	V.SecExp.edicts.defense.privilege.slaveSoldier = V.SecExp.edicts.defense.privilege.slaveSoldier || V.slaveSoldier || 0;
 	V.SecExp.edicts.defense.privilege.mercSoldier = V.SecExp.edicts.defense.privilege.mercSoldier || V.mercSoldier || 0;
 
-	for (const [unit, data] of App.SecExp.unit.list()) {
-		App.SecExp.unit.gen(unit);
+	for (const [unit, data] of App.Mods.SecExp.unit.list()) {
+		App.Mods.SecExp.unit.gen(unit);
 		V.SecExp.units[unit].squads.forEach(u => {
 			if (unit === 'bots') {
 				u.active = Math.max(0, u.active) || V.arcologyUpgrade.drones > 0 ? 1 : 0;
@@ -119,7 +119,7 @@ App.SecExp.generalBC = function() {
 				u.platoonName = u.platoonName.replace('undefined', data.defaultName);
 			}
 
-			App.SecExp.unit.genID(u, unit);
+			App.Mods.SecExp.unit.genID(u, unit);
 			u.equip = u.equip || 0;
 			delete u.isDeployed;
 		});
@@ -167,7 +167,7 @@ App.SecExp.generalBC = function() {
 
 	delete V.SecExp.core.crimeCap;
 	V.SecExp.core.trade = V.SecExp.core.trade || V.trade || 0;
-	App.SecExp.initTrade();
+	App.Mods.SecExp.initTrade();
 
 	V.SecExp.core.authority = V.SecExp.core.authority || V.authority || 0;
 	V.SecExp.core.security = V.SecExp.core.security || V.security || 100;
@@ -291,12 +291,12 @@ App.SecExp.generalBC = function() {
 		V.SecExp.settings.showStats = V.showBattleStatistics;
 	}
 
-	App.SecExp.BC.propHub();
-	App.SecExp.BC.barracks();
-	App.SecExp.BC.secHub();
-	App.SecExp.BC.transportHub();
-	App.SecExp.BC.riotCenter();
-	App.SecExp.BC.weaponsManufacturing();
+	App.Mods.SecExp.BC.propHub();
+	App.Mods.SecExp.BC.barracks();
+	App.Mods.SecExp.BC.secHub();
+	App.Mods.SecExp.BC.transportHub();
+	App.Mods.SecExp.BC.riotCenter();
+	App.Mods.SecExp.BC.weaponsManufacturing();
 
 	V.SecExp.proclamation.cooldown = V.SecExp.proclamation.cooldown || V.proclamationsCooldown || 0;
 	V.SecExp.proclamation.currency = V.SecExp.proclamation.currency || V.proclamationCurrency || "";
diff --git a/src/Mods/SecExp/js/securityReport.js b/src/Mods/SecExp/js/securityReport.js
index 2391d984c2d48fea54829907b68e3750912c79e6..cdfd2a4253dbe1e6a48b9b9c6e977e0fe60161b3 100644
--- a/src/Mods/SecExp/js/securityReport.js
+++ b/src/Mods/SecExp/js/securityReport.js
@@ -1,5 +1,5 @@
 /** @returns {DocumentFragment} */
-App.SecExp.securityReport = function() {
+App.Mods.SecExp.securityReport = function() {
 	let immigration = 0;
 	let emigration = 0;
 	let secGrowth = 0;
@@ -9,7 +9,7 @@ App.SecExp.securityReport = function() {
 	} else {
 		emigration = V.oldACitizens - V.ACitizens; // takes into account citizens leaving and those getting enslaved
 	}
-	const activeUnits = App.SecExp.battle.activeUnits();
+	const activeUnits = App.Mods.SecExp.battle.activeUnits();
 	/** @type {(string|HTMLElement|DocumentFragment)[]} */
 	let r = V.useTabs === 0 ? ['<h2>Security</h2>'] : [];
 
@@ -52,6 +52,19 @@ App.SecExp.securityReport = function() {
 		r.push(`The extremely high number of residents makes their job a lot harder.`);
 		secGrowth -= 2;
 	}
+	if (V.SecExp.core.security == 3) {
+		r.push(`The completely free flow of weapons in your arcology makes security quite a bit more challenging.`);
+		secGrowth -= 1,5;
+	} else if (V.SecExp.core.security == 2) {
+		r.push(`The somewhat lax flow of weapons makes securing ${V.arcologies[0].name} moderately harder.`);
+		secGrowth -= 1;
+	} else if (V.SecExp.core.security == 1) {
+		r.push(`The restrictive nature of your weapon laws leaves few instances of violent crime that security has to deal with.`);
+		secGrowth = 0;
+	} else {
+		r.push(`Your complete ban on weapons makes securing your arcology significantly easier.`);
+		secGrowth += 1.5;
+	}
 	if (immigration >= 0 && emigration === 0) {
 		if (immigration < 50) {
 			r.push(`The limited number of immigrants that reached the arcology this week does not have any serious impact on the efficiency of current security measures.`);
@@ -166,7 +179,7 @@ App.SecExp.securityReport = function() {
 		secGrowth += 0.5 * random(1, 2);
 	}
 
-	const assistantDamaged = App.SecExp.updateFacilityDamage("assistant");
+	const assistantDamaged = App.Mods.SecExp.updateFacilityDamage("assistant");
 	r.push(assistantDamaged.text);
 	secGrowth -= assistantDamaged.security;
 	crimeGrowth += assistantDamaged.crime;
@@ -184,11 +197,11 @@ App.SecExp.securityReport = function() {
 		secGrowth *= 1+(V.SecExp.edicts.SFSupportLevel/10);
 	}
 
-	let secRest = App.SecExp.Check.secRestPoint() * (Math.clamp(V.SecExp.buildings.secHub ? V.SecExp.buildings.secHub.menials : 0, 0, App.SecExp.Check.reqMenials()) / App.SecExp.Check.reqMenials());
+	let secRest = App.Mods.SecExp.Check.secRestPoint() * (Math.clamp(V.SecExp.buildings.secHub ? V.SecExp.buildings.secHub.menials : 0, 0, App.Mods.SecExp.Check.reqMenials()) / App.Mods.SecExp.Check.reqMenials());
 	secRest = Math.max(20, secRest);
-	if (secRest < App.SecExp.Check.reqMenials() && V.SecExp.buildings.secHub) {
+	if (secRest < App.Mods.SecExp.Check.reqMenials() && V.SecExp.buildings.secHub) {
 		r.push(`The limited staff assigned to the HQ hampered the improvements to security achieved this week.`);
-	} else if (secRest < App.SecExp.Check.reqMenials()) {
+	} else if (secRest < App.Mods.SecExp.Check.reqMenials()) {
 		r.push(`The limited infrastructure available slowly erodes away the security level of the arcology.`);
 	}
 
@@ -306,9 +319,9 @@ App.SecExp.securityReport = function() {
 		crimeGrowth += 0.5 * random(1, 2);
 	}
 
-	const crimeCap = Math.trunc(Math.clamp(App.SecExp.Check.crimeCap() + (App.SecExp.Check.crimeCap() - App.SecExp.Check.crimeCap() * ((V.SecExp.buildings.secHub ? V.SecExp.buildings.secHub.menials : 0) / App.SecExp.Check.reqMenials())), 0, 100));
+	const crimeCap = Math.trunc(Math.clamp(App.Mods.SecExp.Check.crimeCap() + (App.Mods.SecExp.Check.crimeCap() - App.Mods.SecExp.Check.crimeCap() * ((V.SecExp.buildings.secHub ? V.SecExp.buildings.secHub.menials : 0) / App.Mods.SecExp.Check.reqMenials())), 0, 100));
 	if (V.SecExp.buildings.secHub) {
-		if (crimeCap > App.SecExp.Check.crimeCap()) {
+		if (crimeCap > App.Mods.SecExp.Check.crimeCap()) {
 			r.push(`The limited staff assigned to the HQ allows more space for criminals to act.`);
 		}
 		if (V.SecExp.buildings.secHub.coldstorage < 6) {
@@ -341,15 +354,15 @@ App.SecExp.securityReport = function() {
 			let recruitLimit = 0;
 			let adjst;
 
-			const SF = App.SecExp.assistanceSF('security', 'militia');
+			const SF = App.Mods.SecExp.assistanceSF('security', 'militia');
 			r.push(SF.text); recruitsMultiplier += SF.bonus;
 
-			const propagandaEffects = App.SecExp.propagandaEffects("recruitment");
+			const propagandaEffects = App.Mods.SecExp.propagandaEffects("recruitment");
 			r.push(propagandaEffects.text);
 			recruitsMultiplier *= (1 + propagandaEffects.effect);
 			if (V.SecExp.edicts.defense.militia === 2) {
 				r.push(`Your militia accepts only volunteering citizens, ready to defend their arcology.`);
-				recruitLimit = App.SecExp.militiaCap(); adjst = 0.0025;
+				recruitLimit = App.Mods.SecExp.militiaCap(); adjst = 0.0025;
 				if (V.rep >= 10000) {
 					r.push(`Many citizens volunteer just to fight for someone of your renown.`);
 					recruitLimit += adjst;
@@ -360,13 +373,13 @@ App.SecExp.securityReport = function() {
 				}
 			} else if (V.SecExp.edicts.defense.militia === 3) {
 				r.push(`Adult citizens are required to join the militia for a period of time.`);
-				recruitLimit = App.SecExp.militiaCap(); adjst = 0.005;
+				recruitLimit = App.Mods.SecExp.militiaCap(); adjst = 0.005;
 			} else if (V.SecExp.edicts.defense.militia === 4) {
 				r.push(`Adult citizens are required to register and serve in the militia whenever necessary.`);
-				recruitLimit = App.SecExp.militiaCap(); adjst = 0.01;
+				recruitLimit = App.Mods.SecExp.militiaCap(); adjst = 0.01;
 			} else if (V.SecExp.edicts.defense.militia === 5) {
 				r.push(`Every citizen is required to train and participate in the military activities of the arcology.`);
-				recruitLimit = App.SecExp.militiaCap(); adjst = 0.02;
+				recruitLimit = App.Mods.SecExp.militiaCap(); adjst = 0.02;
 			}
 			if (V.SecExp.edicts.defense.lowerRequirements === 1) {
 				r.push(`Your lax physical requirements to enter the militia allows for a greater number of citizens to join.`);
@@ -388,7 +401,7 @@ App.SecExp.securityReport = function() {
 				}
 			}
 
-			const recruits = Math.trunc((recruitLimit * V.ACitizens - App.SecExp.Manpower.totalMilitia) / 20 * recruitsMultiplier);
+			const recruits = Math.trunc((recruitLimit * V.ACitizens - App.Mods.SecExp.Manpower.totalMilitia) / 20 * recruitsMultiplier);
 			if (recruits > 0) {
 				V.SecExp.units.militia.free += recruits;
 				r.push(`This week ${recruits} citizens joined the militia.<br>`);
@@ -436,7 +449,7 @@ App.SecExp.securityReport = function() {
 				newMercs += random(1, 2);
 			}
 
-			const SF = App.SecExp.assistanceSF('security', 'mercs');
+			const SF = App.Mods.SecExp.assistanceSF('security', 'mercs');
 			r.push(SF.text); newMercs += SF.bonus;
 
 			if (V.SecExp.edicts.defense.discountMercenaries > 0) {
@@ -453,9 +466,9 @@ App.SecExp.securityReport = function() {
 			V.SecExp.units.mercs.free = Math.clamp(V.SecExp.units.mercs.free, 0, 2000);
 		}
 
-		if (activeUnits > 0 && App.SecExp.unit.squads("human").length > 0) { // loyalty and training
-			for (const squad of App.SecExp.unit.squads("human")) {
-				r.push(App.SecExp.humanLoyaltyChanges(squad));
+		if (activeUnits > 0 && App.Mods.SecExp.unit.squads("human").length > 0) { // loyalty and training
+			for (const squad of App.Mods.SecExp.unit.squads("human")) {
+				r.push(App.Mods.SecExp.humanLoyaltyChanges(squad));
 			}
 		}
 	}
@@ -479,13 +492,13 @@ App.SecExp.securityReport = function() {
 	}
 
 	if (V.SecExp.buildings.weapManu) {
-		if (App.SecExp.weapManu.completed()) {
+		if (App.Mods.SecExp.weapManu.completed()) {
 			delete V.SecExp.buildings.weapManu.upgrades.queue;
 		}
 		if (V.SecExp.buildings.weapManu.upgrades.queue) {
 			for (let item = 0; item < V.SecExp.buildings.weapManu.upgrades.queue.length; item++) {
 				const currentItem = V.SecExp.buildings.weapManu.upgrades.queue[item];
-				Object.assign(currentItem, App.SecExp.weapManu.current(currentItem.ID));
+				Object.assign(currentItem, App.Mods.SecExp.weapManu.current(currentItem.ID));
 				if (item === 0) {
 					currentItem.time--;
 					r.push(`<br>In the research lab, ${currentItem.dec}`);
@@ -515,8 +528,8 @@ App.SecExp.securityReport = function() {
 		}
 	}
 
-	if (V.SecExp.settings.battle.enabled > 0 && App.SecExp.unit.squads().length > 0) {
-		App.SecExp.generator.attack();
+	if (V.SecExp.settings.battle.enabled > 0 && App.Mods.SecExp.unit.squads().length > 0) {
+		App.Mods.SecExp.generator.attack();
 	}
 
 	const frag = new DocumentFragment();
diff --git a/src/Mods/SecExp/js/terrainAndTactics.js b/src/Mods/SecExp/js/terrainAndTactics.js
index ff23cfe943bedf7fcdb2072c94c3b6c7bfbca269..03cc7417d5f6f3af2da4e956f2395275277cb2d6 100644
--- a/src/Mods/SecExp/js/terrainAndTactics.js
+++ b/src/Mods/SecExp/js/terrainAndTactics.js
@@ -92,9 +92,9 @@ App.Data.SecExp.TerrainAndTactics = new Map([
 			tacChance: -0.25,
 		},
 		"Human Wave": {
-			atkMod: -0.15 * App.SecExp.troopDiffAdjust().enemy,
-			defMod: -0.15 * App.SecExp.troopDiffAdjust().enemy,
-			tacChance: -0.30 * App.SecExp.troopDiffAdjust().enemy,
+			atkMod: -0.15 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			defMod: -0.15 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			tacChance: -0.30 * App.Mods.SecExp.troopDiffAdjust().enemy,
 		},
 	}],
 	["rural", {
@@ -134,9 +134,9 @@ App.Data.SecExp.TerrainAndTactics = new Map([
 			tacChance: 0.25,
 		},
 		"Human Wave": {
-			atkMod: 0.20 * App.SecExp.troopDiffAdjust().enemy,
-			defMod: 0.05 * App.SecExp.troopDiffAdjust().enemy,
-			tacChance: 0.25 * App.SecExp.troopDiffAdjust().enemy,
+			atkMod: 0.20 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			defMod: 0.05 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			tacChance: 0.25 * App.Mods.SecExp.troopDiffAdjust().enemy,
 		},
 	}],
 	["hills", {
@@ -176,9 +176,9 @@ App.Data.SecExp.TerrainAndTactics = new Map([
 			tacChance: 0.25,
 		},
 		"Human Wave": {
-			atkMod: -0.15 * App.SecExp.troopDiffAdjust().enemy,
-			defMod: -0.15 * App.SecExp.troopDiffAdjust().enemy,
-			tacChance: -0.30 * App.SecExp.troopDiffAdjust().enemy,
+			atkMod: -0.15 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			defMod: -0.15 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			tacChance: -0.30 * App.Mods.SecExp.troopDiffAdjust().enemy,
 		},
 	}],
 	["coast", {
@@ -218,8 +218,8 @@ App.Data.SecExp.TerrainAndTactics = new Map([
 			tacChance: -0.10,
 		},
 		"Human Wave": {
-			atkMod: 0.05 * App.SecExp.troopDiffAdjust().enemy,
-			defMod: -0.05 * App.SecExp.troopDiffAdjust().enemy,
+			atkMod: 0.05 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			defMod: -0.05 * App.Mods.SecExp.troopDiffAdjust().enemy,
 		},
 	}],
 	["outskirts", {
@@ -259,8 +259,8 @@ App.Data.SecExp.TerrainAndTactics = new Map([
 			tacChance: 0.05,
 		},
 		"Human Wave": {
-			atkMod: 0.10 * App.SecExp.troopDiffAdjust().enemy,
-			defMod: -0.10 * App.SecExp.troopDiffAdjust().enemy,
+			atkMod: 0.10 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			defMod: -0.10 * App.Mods.SecExp.troopDiffAdjust().enemy,
 		},
 	}],
 	["mountains", {
@@ -300,9 +300,9 @@ App.Data.SecExp.TerrainAndTactics = new Map([
 			tacChance: -0.20,
 		},
 		"Human Wave": {
-			atkMod: -0.10 * App.SecExp.troopDiffAdjust().enemy,
-			defMod: -0.10 * App.SecExp.troopDiffAdjust().enemy,
-			tacChance: -0.20 * App.SecExp.troopDiffAdjust().enemy,
+			atkMod: -0.10 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			defMod: -0.10 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			tacChance: -0.20 * App.Mods.SecExp.troopDiffAdjust().enemy,
 		},
 	}],
 	["wasteland", {
@@ -342,9 +342,9 @@ App.Data.SecExp.TerrainAndTactics = new Map([
 			tacChance: 0.30,
 		},
 		"Human Wave": {
-			atkMod: 0.20 * App.SecExp.troopDiffAdjust().enemy,
-			defMod: 0.05 * App.SecExp.troopDiffAdjust().enemy,
-			tacChance: 0.25 * App.SecExp.troopDiffAdjust().enemy,
+			atkMod: 0.20 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			defMod: 0.05 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			tacChance: 0.25 * App.Mods.SecExp.troopDiffAdjust().enemy,
 		},
 	}],
 	["international waters", {
@@ -384,9 +384,9 @@ App.Data.SecExp.TerrainAndTactics = new Map([
 			tacChance: 0.25,
 		},
 		"Human Wave": {
-			atkMod: 0.20 * App.SecExp.troopDiffAdjust().enemy,
-			defMod: 0.05 * App.SecExp.troopDiffAdjust().enemy,
-			tacChance: 0.25 * App.SecExp.troopDiffAdjust().enemy,
+			atkMod: 0.20 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			defMod: 0.05 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			tacChance: 0.25 * App.Mods.SecExp.troopDiffAdjust().enemy,
 		},
 	}],
 	["an underwater cave", {
@@ -426,9 +426,9 @@ App.Data.SecExp.TerrainAndTactics = new Map([
 			tacChance: -0.30,
 		},
 		"Human Wave": {
-			atkMod: -0.20 * App.SecExp.troopDiffAdjust().enemy,
-			defMod: -0.05 * App.SecExp.troopDiffAdjust().enemy,
-			tacChance: -0.25 * App.SecExp.troopDiffAdjust().enemy,
+			atkMod: -0.20 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			defMod: -0.05 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			tacChance: -0.25 * App.Mods.SecExp.troopDiffAdjust().enemy,
 		},
 	}],
 	["a sunken ship", {
@@ -468,9 +468,9 @@ App.Data.SecExp.TerrainAndTactics = new Map([
 			tacChance: -0.30,
 		},
 		"Human Wave": {
-			atkMod: -0.20 * App.SecExp.troopDiffAdjust().enemy,
-			defMod: -0.05 * App.SecExp.troopDiffAdjust().enemy,
-			tacChance: -0.25 * App.SecExp.troopDiffAdjust().enemy,
+			atkMod: -0.20 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			defMod: -0.05 * App.Mods.SecExp.troopDiffAdjust().enemy,
+			tacChance: -0.25 * App.Mods.SecExp.troopDiffAdjust().enemy,
 		},
 	}],
 ]);
diff --git a/src/Mods/SecExp/js/tradeReport.js b/src/Mods/SecExp/js/tradeReport.js
index 56fae46f3fb04064f2a1022961291d2b30c75c88..ba97d228c01683a418593e2429e068b9fd39f3df 100644
--- a/src/Mods/SecExp/js/tradeReport.js
+++ b/src/Mods/SecExp/js/tradeReport.js
@@ -1,4 +1,4 @@
-App.SecExp.tradeReport = function() {
+App.Mods.SecExp.tradeReport = function() {
 	let r = [];
 	let tradeChange = 0;
 	let bonus = 0;
@@ -119,7 +119,7 @@ App.SecExp.tradeReport = function() {
 		}
 	}
 
-	const SF = App.SecExp.assistanceSF('trade');
+	const SF = App.Mods.SecExp.assistanceSF('trade');
 	r.push(SF.text); tradeChange += SF.bonus;
 
 	if (tradeChange > 0) {
diff --git a/src/Mods/SecExp/potentialToDo.txt b/src/Mods/SecExp/potentialToDo.txt
index b9ee3c599f43fccd867dae4d0accac4a98649b3b..67146f66eadf907043ce82daa957c15c0f589b24 100644
--- a/src/Mods/SecExp/potentialToDo.txt
+++ b/src/Mods/SecExp/potentialToDo.txt
@@ -2,11 +2,7 @@ Hexall90's last merged commit: 52dde0b3
 
 - Can other Arcologies assist with the attacks from your Arcology?
 	Like if you're being attacked by raiders they send some rapid-deployment forces and help you but when it's the Old world they wouldn't in fear of being criticize or something
-- Or sending your troops to help other arcologies to earn reputation, POW as menials and captured military assets for cash, to boost cultural exchange and economic development. Or choosing not to send troops (if rival) to lower its value and to preverse your cultural independance.
-- While at it something for barracks(general? commissar?) and riot center([Insert player title there]'s Will?? Big Sister? ) too would be nice
-- While at it decoupling of propaganda slave and recruiter when?
-- Would it be possible to add option for assigning hacker to security HQ that would work similarly to giving office for recruiter in propaganda hub? Preferably with smiling man slave giving extra bonuses there
-- Does having a large standing army give any bonus to authority/reputation growth?
+- Or sending your troops to help other arcologies to earn reputation, POW as menials and captured military assets for cash, to boost cultural exchange and economic development. Or choosing not to send troops (if rival) to lower its value and to preserve your cultural independence.
 
 	Fine, I'll Do It Myself
 	Pirates? Enemy navies? - 328279
@@ -23,10 +19,9 @@ Hexall90's last merged commit: 52dde0b3
 - Suggestion - Arcology Conquest - https://gitgud.io/pregmodfan/fc-pregmod/issues/760
 - And if I am a master tactician, maybe I could get an estimate how effective the various tactics could be?
 - Suggestion - Gradual Battle Frequency - https://gitgud.io/pregmodfan/fc-pregmod/issues/1245#note_82504
-- Option to send slaves into military unit to gain some nice scars and experience wold be nice (with retrieval).
+- Option to send slaves into military unit to gain some nice scars and experience would be nice (with retrieval).
 - So would be taking slaves from slave units as personal ones. The slave units would pretty much be menial slaves I'd imagine, not sex slaves.
 - If I think about it having a squad of personal slaves that you equip in whatever gear you want and send out to capture new slaves, raid caravans and cities and shit would be pretty sweet, I would even call it special forces but that's taken, also the combat skill is still a binary thing which makes the whole thing pointless.
 	How about to start off with option to send one or two of your combat trained slaves to assist the merc's when they are on a raid with the possibility of receiving battle wounds.
-- How about to start off with option to send one or two of your combat trained slaves to assist the merc's when they are on a raid with the possibility of receiving battle wounds.
 - If there are choices, they should be along the lines of "higher risk, higher reward" (defeating the enemy with fewer casualties and damage if it goes right, but suffering higher casualties and damage if it goes wrong), or things like accepting more/less military casualties for better/worse protection of economic assets (costing money/damaging economy) and civilians (costing reputation/damaging population).
-- The ability to send units to the general to increase relationship as an alternative to sending slaves.
\ No newline at end of file
+- Support Neo-Imperial Warhounds in battles.
diff --git a/src/Mods/SpecialForce/AfterActionReport.js b/src/Mods/SpecialForce/AfterActionReport.js
index 827f274f2f07a790675772adb548ab24cddcfc3a..d92788c12edb85abb3ccabd0309721fdf6d4fa2d 100644
--- a/src/Mods/SpecialForce/AfterActionReport.js
+++ b/src/Mods/SpecialForce/AfterActionReport.js
@@ -1,10 +1,10 @@
 /**
  * @returns {[DocumentFragment, number]}
  */
-App.SF.AAR = function() {
+App.Mods.SF.AAR = function() {
 	const endWeekCall = V.endweekFlag ? 1 : 0;
 	const S = V.SF.Squad;
-	const size = App.SF.upgrades.total();
+	const size = App.Mods.SF.upgrades.total();
 
 	let profit = 0;
 	let upkeep = 0;
@@ -13,7 +13,7 @@ App.SF.AAR = function() {
 	const node = new DocumentFragment();
 	if (V.SF.FS.Tension > 100 && endWeekCall > 0) {
 		if (V.SF.FS.BadOutcome === undefined) {
-			App.SF.fsIntegration.badOutcome();
+			App.Mods.SF.fsIntegration.badOutcome();
 		} else {
 			App.UI.DOM.appendNewElement("div", node, `This week your arcology lost a bit of prosperity and large amount of reputation, due to the looming threat that The Colonel and her forces may resurface.`);
 			V.arcologies[0].prosperity -= 25;
@@ -54,7 +54,7 @@ App.SF.AAR = function() {
 			Multiplier.troop += V.SF.ArmySize / 200;
 			upkeep += V.SF.ArmySize * 33 * 1/N0;
 			if (V.secExpEnabled > 0 && endWeekCall > 0) {
-				App.SecExp.authorityX((25 * (Math.ceil(V.SF.ArmySize / 200))) + size * 10);
+				App.Mods.SecExp.authorityX((25 * (Math.ceil(V.SF.ArmySize / 200))) + size * 10);
 			}
 		}
 
@@ -326,22 +326,18 @@ App.SF.AAR = function() {
 
 			App.UI.DOM.appendNewElement("span", node, ` ${FNG} new soldiers were recruited this week, and your reputation has`);
 			App.UI.DOM.appendNewElement("span", node, " increased through the improvement of trade security.", "green");
+
+			App.Events.addParagraph(node, ["As the leader of a military force, The Colonel has very limited free time during the week and is only able to issue orders or provide basic reports."]);
 			App.UI.DOM.appendNewElement("p", node, weeklyActions());
-			App.UI.DOM.appendNewElement("h3", node, `Operational choices:`);
 			App.UI.DOM.appendNewElement("div", node, weeklyOptions());
 
-			App.UI.DOM.appendNewElement("p", node, DeploymentFocus());
-			App.UI.DOM.appendNewElement("p", node, ROE());
-			App.UI.DOM.appendNewElement("p", node, Accountability());
-			App.Events.addParagraph(node, ["Force depravity affects trade."]);
-
 			if (V.SF.MercCon.CanAttend === 1) {
 				V.SF.MercCon.Income = 0;
 				V.SF.MercCon.Menials = 0;
 				const tradeShowAttendes = 200;
 				const menialGiftsPerAttendee = 5;
 				const menialGifts = Math.ceil(jsRandom(1, ((tradeShowAttendes * menialGiftsPerAttendee) / 10)));
-				const TSProfit = Math.ceil(500000 * (1 + (size / 1000)) * (1 + (V.arcologies[0].prosperity / 1000)) * App.SF.env());
+				const TSProfit = Math.ceil(500000 * (1 + (size / 1000)) * (1 + (V.arcologies[0].prosperity / 1000)) * App.Mods.SF.env());
 				const NewMercs = jsRandom(1, (tradeShowAttendes / 10));
 
 				V.SF.MercCon.Menials += menialGifts;
@@ -367,144 +363,6 @@ App.SF.AAR = function() {
 		return [node, upkeep];
 	}
 
-	function DeploymentFocus() {
-		const text = new DocumentFragment();
-		let focus = document.createElement("span");
-		App.UI.DOM.appendNewElement("span", focus, mapping());
-
-		App.UI.DOM.appendNewElement("span", text, "Deployment focus: ");
-		App.UI.DOM.appendNewElement("span", text, focus, "bold");
-
-		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Recruiting and Training",
-			() => {
-				V.SF.Target = "recruit";
-				App.UI.DOM.replace(focus, "Recruiting and Training");
-			}, [], "",
-			"Increases the amount of FNGs at the cost of revenue."
-		), "indent");
-
-		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Securing Trade Routes",
-			() => {
-				V.SF.Target = "secure";
-				App.UI.DOM.replace(focus, "Securing Trade Routes");
-			}, [], "",
-			"Increases trade and reputation at the cost of revenue."
-		), "indent");
-
-		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Raiding and Slaving",
-			() => {
-				V.SF.Target = "raiding";
-				App.UI.DOM.replace(focus, "Raiding and Slaving");
-			}, [], "",
-			"Increases revenue at the cost of less FNGs and increased force depravity."
-		), "indent");
-
-		return text;
-
-		function mapping() {
-			switch (V.SF.Target) {
-				case "recruit":
-					return "Recruiting and Training";
-				case "secure":
-					return "Securing Trade Routes";
-				case "raiding":
-					return "Raiding and Slaving";
-			}
-		}
-	}
-
-	function ROE() {
-		const text = new DocumentFragment();
-		let focus = document.createElement("span");
-		App.UI.DOM.appendNewElement("span", focus, mapping());
-
-		App.UI.DOM.appendNewElement("span", text, "Rules of Engagements: ");
-		App.UI.DOM.appendNewElement("span", text, focus, "bold");
-
-		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Hold Fire",
-			() => {
-				V.SF.ROE = "hold";
-				App.UI.DOM.replace(focus, mapping());
-			}, [], "",
-			"Reduces force depravity."
-		), "indent");
-
-		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("limited Fire",
-			() => {
-				V.SF.ROE = "limited";
-				App.UI.DOM.replace(focus, mapping());
-			}, [], "",
-			"Does not adjust force depravity."
-		), "indent");
-
-		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Free Fire",
-			() => {
-				V.SF.ROE = "free";
-				App.UI.DOM.replace(focus, mapping());
-			}, [], "",
-			"Increases force depravity."
-		), "indent");
-
-		return text;
-
-		function mapping() {
-			switch (V.SF.ROE) {
-				case "hold":
-					return "Hold Fire";
-				case "limited":
-					return "limited Fire";
-				case "free":
-					return "Free Fire";
-			}
-		}
-	}
-
-	function Accountability() {
-		const text = new DocumentFragment();
-		let focus = document.createElement("span");
-		App.UI.DOM.appendNewElement("span", focus, mapping());
-
-		App.UI.DOM.appendNewElement("span", text, "Rules of Engagements: ");
-		App.UI.DOM.appendNewElement("span", text, focus, "bold");
-
-		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Strict Accountability",
-			() => {
-				V.SF.Regs = "strict";
-				App.UI.DOM.replace(focus, mapping());
-			}, [], "",
-			"Reduces force depravity."
-		), "indent");
-
-		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Some Accountability",
-			() => {
-				V.SF.Regs = "some";
-				App.UI.DOM.replace(focus, mapping());
-			}, [], "",
-			"Does not adjust force depravity."
-		), "indent");
-
-		App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("No Accountability",
-			() => {
-				V.SF.Regs = "none";
-				App.UI.DOM.replace(focus, mapping());
-			}, [], "",
-			"Increases force depravity."
-		), "indent");
-
-		return text;
-
-		function mapping() {
-			switch (V.SF.Regs) {
-				case "strict":
-					return "Strict Accountability";
-				case "some":
-					return "Some Accountability";
-				case "none":
-					return "No Accountability";
-			}
-		}
-	}
-
 	function weeklyOptions() {
 		const choices = document.createElement("span");
 		App.UI.DOM.appendNewElement("div", choices, `The Colonel looks down a list on her tablet. "There's some things we can do to help you out, boss.`);
@@ -544,8 +402,8 @@ App.SF.AAR = function() {
 		function weeklyGift(input) {
 			let value;
 			let EnvProsp;
-			const env = App.SF.env();
-			const size = App.SF.upgrades.total();
+			const env = App.Mods.SF.env();
+			const size = App.Mods.SF.upgrades.total();
 
 			switch (input) {
 				case 1: // Request cash
@@ -582,7 +440,7 @@ App.SF.AAR = function() {
 					V.SF.FS.Tension -= colonelTalkTensionRuction;
 					const Env = {};
 					const text = document.createElement("span");
-					switch (App.SF.env()) {
+					switch (App.Mods.SF.env()) {
 						case 4:
 							Env.cash2 = 450;
 							Env.cash3 = 200;
diff --git a/src/Mods/SpecialForce/FireBase.js b/src/Mods/SpecialForce/FireBase.js
index 719baa8a965b6101492c83c8e6e2f80529bc3d3c..57917cf6ae781944786dd0a8db321dc6e1b8aaf4 100644
--- a/src/Mods/SpecialForce/FireBase.js
+++ b/src/Mods/SpecialForce/FireBase.js
@@ -1,12 +1,12 @@
 App.UI.FireBase = function() {
-	const max = App.SF.upgrades.max();
-	const size = App.SF.upgrades.total();
+	const max = App.Mods.SF.upgrades.max();
+	const size = App.Mods.SF.upgrades.total();
 	const isBrazen = V.SF.Colonel.Core === "brazen";
 	const node = document.createElement("span");
 	let r = [];
 
 	if (V.SF.FS.Tension > 100) {
-		node.append(App.SF.fsIntegration.badOutcome());
+		node.append(App.Mods.SF.fsIntegration.badOutcome());
 	} else {
 		if (V.cheatMode > 0 || V.debugMode > 0) {
 			App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink("Edit", "editSF"));
@@ -49,7 +49,7 @@ App.UI.FireBase = function() {
 		tabBar.addTab("Upgrades", "Upgrades", upgrades());
 	}
 	tabBar.addTab("Actions", "Actions", actions());
-	tabBar.addTab("Future Societies", "FS", App.SF.fsIntegration.menu());
+	tabBar.addTab("Future Societies", "FS", App.Mods.SF.fsIntegration.menu());
 	node.append(tabBar.render());
 	return node;
 
@@ -57,7 +57,7 @@ App.UI.FireBase = function() {
 		const cost = forceNeg(Math.ceil(10000 + ((0.03 - (size/max)/100) * V.SF.CreditsInvested)));
 		const node = document.createElement("span");
 		node.append(`Total upgrade progress:`);
-		$(node).wiki(App.SF.progress(size, max));
+		$(node).wiki(App.Mods.SF.progress(size, max));
 		node.append(`${size}/${max}(${(size/max).toFixed(2)*100}%)`);
 		if (size < 30) {
 			App.UI.DOM.appendNewElement("div", node, `${(30 - size)} more upgrades is needed until the next tier unlocks.`, "note");
@@ -74,7 +74,7 @@ App.UI.FireBase = function() {
 				))
 			);
 		} else if (size < 30 || size !== max) {
-			App.UI.DOM.appendNewElement("div", node, App.SF.upgrades.menu());
+			App.UI.DOM.appendNewElement("div", node, App.Mods.SF.upgrades.menu());
 		}
 		return node;
 	}
@@ -95,6 +95,12 @@ App.UI.FireBase = function() {
 			*/
 		const assignTroopsLink = (text, target, value) => App.UI.DOM.link(text, () => { V.SF.UC[target] = value; App.UI.reload(); });
 
+		App.UI.DOM.appendNewElement("h3", node, `Operational choices:`);
+		App.UI.DOM.appendNewElement("p", node, DeploymentFocus());
+		App.UI.DOM.appendNewElement("p", node, ROE());
+		App.UI.DOM.appendNewElement("p", node, Accountability());
+		App.Events.addParagraph(node, ["Force depravity is a measure of how cruel and indifferent solders of the force are. This affects trade, how the force is viewed and or acts during some situations. Lower values lead to more ideal outcomes."]);
+		
 		if (V.SF.MercCon.CanAttend === 0 || V.SF.MercCon.History >= 1 && repeatTrigger) {
 			r.push(`Her expression changes as something jogs her memory. "Before we begin, ${isBrazen ? `${properTitle()}` : 'boss'},`);
 			if (V.SF.MercCon.CanAttend === 0) {
@@ -162,7 +168,146 @@ App.UI.FireBase = function() {
 			);
 			App.UI.DOM.appendNewElement("span", node, assignTroopsLink(" Re-allocate the units", "Lock", 0));
 		}
+		App.UI.DOM.appendNewElement("div", node, "Any affects on your cultural goals and reputation are modified by the number of assigned troops.");
 
 		return node;
+
+		function DeploymentFocus() {
+			const text = new DocumentFragment();
+			let focus = document.createElement("span");
+			App.UI.DOM.appendNewElement("span", focus, mapping());
+	
+			App.UI.DOM.appendNewElement("span", text, "Deployment focus: ");
+			App.UI.DOM.appendNewElement("span", text, focus, "bold");
+	
+			App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Recruiting and Training",
+				() => {
+					V.SF.Target = "recruit";
+					App.UI.DOM.replace(focus, "Recruiting and Training");
+				}, [], "",
+				"Increases the amount of FNGs at the cost of revenue."
+			), "indent");
+	
+			App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Securing Trade Routes",
+				() => {
+					V.SF.Target = "secure";
+					App.UI.DOM.replace(focus, "Securing Trade Routes");
+				}, [], "",
+				"Increases trade and reputation at the cost of revenue."
+			), "indent");
+	
+			App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Raiding and Slaving",
+				() => {
+					V.SF.Target = "raiding";
+					App.UI.DOM.replace(focus, "Raiding and Slaving");
+				}, [], "",
+				"Increases revenue at the cost of less FNGs and increased force depravity."
+			), "indent");
+	
+			return text;
+	
+			function mapping() {
+				switch (V.SF.Target) {
+					case "recruit":
+						return "Recruiting and Training";
+					case "secure":
+						return "Securing Trade Routes";
+					case "raiding":
+						return "Raiding and Slaving";
+				}
+			}
+		}
+	
+		function ROE() {
+			const text = new DocumentFragment();
+			let focus = document.createElement("span");
+			App.UI.DOM.appendNewElement("span", focus, mapping());
+	
+			App.UI.DOM.appendNewElement("span", text, "Rules of Engagements: ");
+			App.UI.DOM.appendNewElement("span", text, focus, "bold");
+	
+			App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Hold Fire",
+				() => {
+					V.SF.ROE = "hold";
+					App.UI.DOM.replace(focus, mapping());
+				}, [], "",
+				"Reduces force depravity."
+			), "indent");
+	
+			App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("limited Fire",
+				() => {
+					V.SF.ROE = "limited";
+					App.UI.DOM.replace(focus, mapping());
+				}, [], "",
+				"Does not adjust force depravity."
+			), "indent");
+	
+			App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Free Fire",
+				() => {
+					V.SF.ROE = "free";
+					App.UI.DOM.replace(focus, mapping());
+				}, [], "",
+				"Increases force depravity."
+			), "indent");
+	
+			return text;
+	
+			function mapping() {
+				switch (V.SF.ROE) {
+					case "hold":
+						return "Hold Fire";
+					case "limited":
+						return "limited Fire";
+					case "free":
+						return "Free Fire";
+				}
+			}
+		}
+	
+		function Accountability() {
+			const text = new DocumentFragment();
+			let focus = document.createElement("span");
+			App.UI.DOM.appendNewElement("span", focus, mapping());
+	
+			App.UI.DOM.appendNewElement("span", text, "Rules of Engagements: ");
+			App.UI.DOM.appendNewElement("span", text, focus, "bold");
+	
+			App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Strict Accountability",
+				() => {
+					V.SF.Regs = "strict";
+					App.UI.DOM.replace(focus, mapping());
+				}, [], "",
+				"Reduces force depravity."
+			), "indent");
+	
+			App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("Some Accountability",
+				() => {
+					V.SF.Regs = "some";
+					App.UI.DOM.replace(focus, mapping());
+				}, [], "",
+				"Does not adjust force depravity."
+			), "indent");
+	
+			App.UI.DOM.appendNewElement("div", text, App.UI.DOM.link("No Accountability",
+				() => {
+					V.SF.Regs = "none";
+					App.UI.DOM.replace(focus, mapping());
+				}, [], "",
+				"Increases force depravity."
+			), "indent");
+	
+			return text;
+	
+			function mapping() {
+				switch (V.SF.Regs) {
+					case "strict":
+						return "Strict Accountability";
+					case "some":
+						return "Some Accountability";
+					case "none":
+						return "No Accountability";
+				}
+			}
+		}
 	}
 };
diff --git a/src/Mods/SpecialForce/FirebaseTour.js b/src/Mods/SpecialForce/FirebaseTour.js
index 8f2a767e561ba228ec46928d6c5fee39fbb0645e..59d3e5693983839e65b63421587858702bf09948 100644
--- a/src/Mods/SpecialForce/FirebaseTour.js
+++ b/src/Mods/SpecialForce/FirebaseTour.js
@@ -35,13 +35,13 @@ App.UI.firebaseTour = function() {
 	App.Events.addParagraph(node, r);
 	r = [];
 
-	node.append(App.SF.fsIntegration.flavourText(90));
+	node.append(App.Mods.SF.fsIntegration.flavourText(90));
 
 	r.push(
 		`You arrive at the firebase's common area, a nest of bars, pleasure dens, public spaces, and other facilities catering to the soldiers' needs and giving them somewhere to spend their free time, since they do not mingle with your citizens on the higher levels or exit the arcology except on deployment. It is well-occupied by the soldiers not currently tasked with duties, and they respectfully move out of your way as you approach, clearing a path for you to move forward.`,
-		App.SF.fsIntegration.flavourText(50),
-		App.SF.fsIntegration.flavourText(5),
-		App.SF.fsIntegration.flavourText(10),
+		App.Mods.SF.fsIntegration.flavourText(50),
+		App.Mods.SF.fsIntegration.flavourText(5),
+		App.Mods.SF.fsIntegration.flavourText(10),
 	);
 
 	r.push(`The amenities are staffed by menial slaves, captured by the soldiers on their excursions. They are`);
@@ -77,9 +77,9 @@ App.UI.firebaseTour = function() {
 	App.Events.addParagraph(node, r);
 	r = [];
 
-	node.append(App.SF.fsIntegration.flavourText(15));
-	node.append(App.SF.fsIntegration.flavourText(20));
-	node.append(App.SF.fsIntegration.flavourText(25));
+	node.append(App.Mods.SF.fsIntegration.flavourText(15));
+	node.append(App.Mods.SF.fsIntegration.flavourText(20));
+	node.append(App.Mods.SF.fsIntegration.flavourText(25));
 
 	App.Events.addParagraph(node, [
 		`In the middle of the common area is a pile of supply crates with a pavilion on top — The Colonel's personal throne and open quarters, the result of her preferring to live an extreme lifestyle amongst her soldiers rather than in her empty quarters on the upper levels. It's draped with the 'flag' of ${V.SF.Lower}, one of her inventions. Sprawled all around it is an immense quantity of alcohol, hard drugs, clothes, electronic devices, huge amounts of cash, jewels and precious metals looted from the outside world.`
@@ -93,90 +93,90 @@ App.UI.firebaseTour = function() {
 		r.push(`raises a hand in greeting and nods. She is sprawled on a couch, wearing only her combat suit tank top and fingerless gloves. She's holding a near-empty bottle of strong liquor in her hand and you can see a naked slave ${girlU} kneeling on the floor between her legs. The Colonel has her legs wrapped tightly around the ${girlU}'s head, forcing the ${girlU} to service her if ${heU} wants to breathe. The Colonel is close to her climax then suddenly tenses her lower body, thus gripping the ${girlU} even tighter, and throws her head back in ecstasy as she orgasms. She lets out a long breath before finally releasing the ${girlU}, giving ${himU} a hard smack and shouting at ${himU} to fuck off.`);
 		App.Events.addParagraph(node, r);
 		r = [];
-		r.push(`The Colonel finishes off her bottle, tossing it over her shoulder then leaning back on the couch and spreading her legs wide. You look down briefly, falling into your habits of inspection. Her pussy is completely devoid of hair with heavy labia with a very large and hard clit peeking out. Beads of moisture, the result of her excitation, are visible, and you can tell from long experience that she would be tight as a vise. You return your gaze to her face to find her smirking at you. "Like what you see, ${App.SF.ColonelStatus()}?" She waves her hand at the plaza around her, "So do they. But you're not here for pussy. You're here to talk business. So, what's up?"`);
+		r.push(`The Colonel finishes off her bottle, tossing it over her shoulder then leaning back on the couch and spreading her legs wide. You look down briefly, falling into your habits of inspection. Her pussy is completely devoid of hair with heavy labia with a very large and hard clit peeking out. Beads of moisture, the result of her excitation, are visible, and you can tell from long experience that she would be tight as a vise. You return your gaze to her face to find her smirking at you. "Like what you see, ${App.Mods.SF.ColonelStatus()}?" She waves her hand at the plaza around her, "So do they. But you're not here for pussy. You're here to talk business. So, what's up?"`);
 	} else if (random(0, 100) > 50) {
-		r.push(`is in no condition initially to greet you. She's naked except for one sock that gives you a very good view of her muscled, taut body laid out across the couch with her feet on the table. She is face-down in a drugged-out stupor in the middle of a wide variety of powders and pills. Perhaps sensing your approach, her head suddenly shoots up and looks at you with unfocused, bloodshot eyes. "Sorry, ${App.SF.ColonelStatus()}," she slurs, wiping her face and weakly holding up a hand. "Hold on a second, I need something to help me out here. Long fucking night." She struggles to sit on the couch and bending over the table, loudly snorts up some of the white powder on it. "Ahhh, fuck," she says, breathing heavily.`);
+		r.push(`is in no condition initially to greet you. She's naked except for one sock that gives you a very good view of her muscled, taut body laid out across the couch with her feet on the table. She is face-down in a drugged-out stupor in the middle of a wide variety of powders and pills. Perhaps sensing your approach, her head suddenly shoots up and looks at you with unfocused, bloodshot eyes. "Sorry, ${App.Mods.SF.ColonelStatus()}," she slurs, wiping her face and weakly holding up a hand. "Hold on a second, I need something to help me out here. Long fucking night." She struggles to sit on the couch and bending over the table, loudly snorts up some of the white powder on it. "Ahhh, fuck," she says, breathing heavily.`);
 		App.Events.addParagraph(node, r);
 		r = [];
-		r.push(`She shakes her head powerfully now looking at you, her eyes once again alert and piercing. "That's better," she says, leaning back on the couch and giving you another good view of her assets. "So, ${App.SF.ColonelStatus()}," she begins, "what brings you down here to our little clubhouse? I trust you're happy with how we've been handling things out there?" You nod. "Excellent", she laughs. "I have to say; it's nice to have a place like this while having some top-end gear and to be able to have fun out there without worrying about anyone coming back on us. Good fucking times." She laughs again. "So — I'm assuming you want something?"`);
+		r.push(`She shakes her head powerfully now looking at you, her eyes once again alert and piercing. "That's better," she says, leaning back on the couch and giving you another good view of her assets. "So, ${App.Mods.SF.ColonelStatus()}," she begins, "what brings you down here to our little clubhouse? I trust you're happy with how we've been handling things out there?" You nod. "Excellent", she laughs. "I have to say; it's nice to have a place like this while having some top-end gear and to be able to have fun out there without worrying about anyone coming back on us. Good fucking times." She laughs again. "So — I'm assuming you want something?"`);
 	} else if (random(0, 100) > 70 && V.SF.Depravity >= 1.5 && V.SF.Colonel.Core === "cruel") {
-		r.push(`is relaxing on her couch stark naked, greeting you with a raised hand. Between her tightly clenched legs is a slave ${girlU} being forced to eat her out. "Hey, ${App.SF.ColonelStatus()}, what's —" she breaks off as a flash of pain crosses her features. "Fucking bitch!" she exclaims, pulling her legs away and punching the slave ${girlU} in the face. She pushes the ${girlU} to the ground, straddling ${himU} then begins hitting. You hear one crunch after another as The Colonel's powerful blows shatter the ${girlU}'s face. She hisses from between clenched teeth, each word accompanied by a brutal punch. "How. Many. Fucking. Times. Have. I. Told. You. To. Watch. Your. Fucking. Teeth. On. My. Fucking. Clit!" She leans back, exhaling heavily. Before leaning back down to grip apply pressure onto the ${girlU}'s neck with her powerful hands. Wordlessly, she increases the pressure and soon the ${girlU} begins to turn blue as ${heU} struggles to draw breath. Eventually ${hisU} struggles weaken and then, finally, end.`);
+		r.push(`is relaxing on her couch stark naked, greeting you with a raised hand. Between her tightly clenched legs is a slave ${girlU} being forced to eat her out. "Hey, ${App.Mods.SF.ColonelStatus()}, what's —" she breaks off as a flash of pain crosses her features. "Fucking bitch!" she exclaims, pulling her legs away and punching the slave ${girlU} in the face. She pushes the ${girlU} to the ground, straddling ${himU} then begins hitting. You hear one crunch after another as The Colonel's powerful blows shatter the ${girlU}'s face. She hisses from between clenched teeth, each word accompanied by a brutal punch. "How. Many. Fucking. Times. Have. I. Told. You. To. Watch. Your. Fucking. Teeth. On. My. Fucking. Clit!" She leans back, exhaling heavily. Before leaning back down to grip apply pressure onto the ${girlU}'s neck with her powerful hands. Wordlessly, she increases the pressure and soon the ${girlU} begins to turn blue as ${heU} struggles to draw breath. Eventually ${hisU} struggles weaken and then, finally, end.`);
 		App.Events.addParagraph(node, r);
 		r = [];
-		r.push(`The Colonel relaxes her grip then wipes her brow, clearing away the sweat from her exertion. Finally rising from the ${girlU}'s body, relaxing back on the couch and putting her feet back up on the table. "Sorry about that ${App.SF.ColonelStatus()}," she says, shrugging. "So many of these bitches we pick up from the outside don't understand that they have to behave." Shaking her head in frustration, "Now I need to find another one. But that's not your problem — you're here to talk business. So, what's up?"`);
+		r.push(`The Colonel relaxes her grip then wipes her brow, clearing away the sweat from her exertion. Finally rising from the ${girlU}'s body, relaxing back on the couch and putting her feet back up on the table. "Sorry about that ${App.Mods.SF.ColonelStatus()}," she says, shrugging. "So many of these bitches we pick up from the outside don't understand that they have to behave." Shaking her head in frustration, "Now I need to find another one. But that's not your problem — you're here to talk business. So, what's up?"`);
 	} else {
-		r.push(`is topless while reviewing the particulars of her unit on a tablet as you approach. She raises a hand in greeting. "Hey ${App.SF.ColonelStatus()}," she says, noticing you looking at her chest. She laughs. "Nice, aren't they? But they're not for you or them." She throws a thumb at the plaza around her. "You're down here for a reason, though. What can I do for you?"`);
+		r.push(`is topless while reviewing the particulars of her unit on a tablet as you approach. She raises a hand in greeting. "Hey ${App.Mods.SF.ColonelStatus()}," she says, noticing you looking at her chest. She laughs. "Nice, aren't they? But they're not for you or them." She throws a thumb at the plaza around her. "You're down here for a reason, though. What can I do for you?"`);
 	}
 	App.Events.addParagraph(node, r);
 	r = [];
 
 	App.Events.addParagraph(node, [
-		App.SF.fsIntegration.flavourText(40),
-		App.SF.fsIntegration.flavourText(200),
-		App.SF.fsIntegration.flavourText(100),
+		App.Mods.SF.fsIntegration.flavourText(40),
+		App.Mods.SF.fsIntegration.flavourText(200),
+		App.Mods.SF.fsIntegration.flavourText(100),
 	]);
 
 	if (V.SF.Squad.Firebase === 10) {
-		App.Events.addParagraph(node, [`The quite hum of fans keeping the faster and much more efficient custom network operational can be heard throughout the firebase.`]);
+		App.Events.addParagraph(node, [`The quiet hum of fans keeping the faster and much more efficient custom network operational can be heard throughout the firebase.`]);
 	}
 
 	App.UI.DOM.appendNewElement("h3", node, `Current facilities status`);
 	App.Events.addParagraph(node, [
-		App.SF.UnitText('firebase'),
-		App.SF.UnitText('troop'),
-		App.SF.fsIntegration.flavourText(30),
-		App.SF.fsIntegration.flavourText(80),
-		App.SF.fsIntegration.flavourText(85),
-		App.SF.UnitText('Armoury'),
-		App.SF.fsIntegration.flavourText(35),
-		App.SF.UnitText('drugs'),
-		App.SF.fsIntegration.flavourText(45),
-		App.SF.UnitText('UAV'),
-		App.SF.fsIntegration.flavourText(55),
+		App.Mods.SF.UnitText('firebase'),
+		App.Mods.SF.UnitText('troop'),
+		App.Mods.SF.fsIntegration.flavourText(30),
+		App.Mods.SF.fsIntegration.flavourText(80),
+		App.Mods.SF.fsIntegration.flavourText(85),
+		App.Mods.SF.UnitText('Armoury'),
+		App.Mods.SF.fsIntegration.flavourText(35),
+		App.Mods.SF.UnitText('drugs'),
+		App.Mods.SF.fsIntegration.flavourText(45),
+		App.Mods.SF.UnitText('UAV'),
+		App.Mods.SF.fsIntegration.flavourText(55),
 	]);
 
 
-	if (App.SF.unlocked.garage()) {
+	if (App.Mods.SF.unlocked.garage()) {
 		App.UI.DOM.appendNewElement("h3", node, `Garage`);
 		if (V.SF.Squad.AV+V.SF.Squad.TV > 0) {
 			App.UI.DOM.appendNewElement("h3", node, `Vehicles`);
 			r.push(
-				App.SF.UnitText('AV'),
-				App.SF.UnitText('TV')
+				App.Mods.SF.UnitText('AV'),
+				App.Mods.SF.UnitText('TV')
 			);
 		}
 		r.push(
-			App.SF.UnitText('PGT'),
-			App.SF.fsIntegration.flavourText(60),
-			App.SF.fsIntegration.flavourText(65)
+			App.Mods.SF.UnitText('PGT'),
+			App.Mods.SF.fsIntegration.flavourText(60),
+			App.Mods.SF.fsIntegration.flavourText(65)
 		);
 	}
 	App.Events.addParagraph(node, r);
 	r = [];
 
-	if (App.SF.unlocked.hangar()) {
+	if (App.Mods.SF.unlocked.hangar()) {
 		App.UI.DOM.appendNewElement("h3", node, `Hangar`);
 		if (V.SF.Squad.AA+V.SF.Squad.TA > 0) {
 			App.UI.DOM.appendNewElement("h3", node, `Airforce`);
 			r.push(
-				App.SF.UnitText('AA'),
-				App.SF.UnitText('TA')
+				App.Mods.SF.UnitText('AA'),
+				App.Mods.SF.UnitText('TA')
 			);
 		}
 		r.push(
-			App.SF.UnitText('SP'),
-			App.SF.UnitText('GunS'),
-			App.SF.fsIntegration.flavourText(70),
-			App.SF.fsIntegration.flavourText(75),
+			App.Mods.SF.UnitText('SP'),
+			App.Mods.SF.UnitText('GunS'),
+			App.Mods.SF.fsIntegration.flavourText(70),
+			App.Mods.SF.fsIntegration.flavourText(75),
 		);
 	}
 	App.Events.addParagraph(node, r);
 	r = [];
 
-	if (App.SF.unlocked.launchBay()) {
+	if (App.Mods.SF.unlocked.launchBay()) {
 		App.UI.DOM.appendNewElement("h3", node, `Launch Bay`);
 		if (V.SF.Squad.Satellite > 0) {
-			r.push(App.SF.UnitText('sat'));
+			r.push(App.Mods.SF.UnitText('sat'));
 			const t = new DocumentFragment();
 			t.append("You ", App.UI.DOM.makeElement("span", `cannot`, "red"), " upgrade the satellite once it has been launched.");
 			const inOrbit = V.SF.SatLaunched === 1;
@@ -195,18 +195,18 @@ App.UI.firebaseTour = function() {
 			r.push(link);
 		}
 		r.push(
-			App.SF.UnitText('GR'),
-			App.SF.UnitText('ms')
+			App.Mods.SF.UnitText('GR'),
+			App.Mods.SF.UnitText('ms')
 		);
 		App.Events.addParagraph(node, r);
 	}
 
-	if (App.SF.unlocked.navalYard()) {
+	if (App.Mods.SF.unlocked.navalYard()) {
 		App.UI.DOM.appendNewElement("h3", node, `Naval Yard`);
 		App.Events.addParagraph(node, [
-			App.SF.UnitText('AC'),
-			App.SF.UnitText('Sub'),
-			App.SF.UnitText('HAT'),
+			App.Mods.SF.UnitText('AC'),
+			App.Mods.SF.UnitText('Sub'),
+			App.Mods.SF.UnitText('HAT'),
 		]);
 	}
 
diff --git a/src/Mods/SpecialForce/SpecialForce.js b/src/Mods/SpecialForce/SpecialForce.js
index b2e9376bcb054cc4942c5ce405af413ce0c3fcd0..2ab9c9a042b4b9cf9c459f687b1a843b3cdabf6b 100644
--- a/src/Mods/SpecialForce/SpecialForce.js
+++ b/src/Mods/SpecialForce/SpecialForce.js
@@ -1,5 +1,5 @@
 // T=SugarCube.State.temporary;
-App.SF.Init = function() {
+App.Mods.SF.Init = function() {
 	if (passage() === "Alpha disclaimer" || passage() === "New Game Plus") {
 		V.SF = {Active: -1, Toggle: 0};
 	}
@@ -39,18 +39,18 @@ App.SF.Init = function() {
 			}
 		});
 
-		for (const upgrade of App.SF.upgrades.list('all')) {
+		for (const upgrade of App.Mods.SF.upgrades.list('all')) {
 			V.SF.Squad[upgrade] = 0;
 		}
 
-		for (const currentFS of App.SF.fsIntegration.list().all) {
+		for (const currentFS of App.Mods.SF.fsIntegration.list().all) {
 			V.SF.FS[currentFS] = {lv: 0, gift: 0};
 		}
 	}
 	// V.arcologies[0].SFRaid = 1; V.arcologies[0].SFRaidTarget = -1;
 };
 
-App.SF.env = function() {
+App.Mods.SF.env = function() {
 	if (V.economy > 100) {
 		return 4;
 	} else if (V.economy > 67) {
@@ -60,11 +60,11 @@ App.SF.env = function() {
 	}
 };
 
-App.SF.SFC = function() {
+App.Mods.SF.SFC = function() {
 	return `The Colonel`;
 };
 
-App.SF.ColonelStatus = function() {
+App.Mods.SF.ColonelStatus = function() {
 	if (V.SF.Colonel.Status <= 19) {
 		return `boss`;
 	} else if (V.SF.Colonel.Status <= 39) {
@@ -74,12 +74,12 @@ App.SF.ColonelStatus = function() {
 	}
 };
 
-App.SF.totalNetWorth = function() {
+App.Mods.SF.totalNetWorth = function() {
 	let value = 0;
 	if (V.SF.Toggle && V.SF.Active >= 1) {
 		value += V.SF.CreditsInvested;
 		value += V.SF.MercCon.Revenue;
-		value -= App.SF.AAR()[1];
+		value -= App.Mods.SF.AAR()[1];
 	}
 	return value;
 };
diff --git a/src/Mods/SpecialForce/SpecialForceBC.js b/src/Mods/SpecialForce/SpecialForceBC.js
index a5665b4dcbed93dafcbaca50228e315b03054d5b..3fbbdeedd399154e81c127537d8fa352459bc998 100644
--- a/src/Mods/SpecialForce/SpecialForceBC.js
+++ b/src/Mods/SpecialForce/SpecialForceBC.js
@@ -1,6 +1,6 @@
 // @ts-nocheck
 /* no-usedOnce */
-App.SF.BC = function() {
+App.Mods.SF.BC = function() {
 	function InitClean() {
 		delete V.SFMODToggle;
 		delete V.securityForceActive;
@@ -189,14 +189,14 @@ App.SF.BC = function() {
 			};
 			UnitsClean();
 		} else {
-			App.SF.Init();
+			App.Mods.SF.Init();
 		}
 	} else if (typeof V.SF === "object") {
 		V.SF.FS = V.SF.FS || {};
 		V.SF.FS.Tension = V.SF.FS.Tension || -1;
 
 		if (V.SF.Toggle && V.SF.Active >= 1) {
-			for (const currentFS of App.SF.fsIntegration.list().all) {
+			for (const currentFS of App.Mods.SF.fsIntegration.list().all) {
 				if (typeof V.SF.FS[currentFS] === "number") {
 					V.SF.FS[currentFS] = {lv: V.SF.FS[currentFS]};
 				}
@@ -221,7 +221,7 @@ App.SF.BC = function() {
 			V.SF.ArmySize = V.SF.ArmySize || 40;
 
 			V.SF.Squad = V.SF.Squad || {};
-			for (const upgrade of App.SF.upgrades.list('all')) {
+			for (const upgrade of App.Mods.SF.upgrades.list('all')) {
 				V.SF.Squad[upgrade] = V.SF.Squad[upgrade] || 0;
 			}
 
@@ -319,7 +319,7 @@ App.SF.BC = function() {
 			if (V.SF.Depravity < 0) {
 				V.SF.Depravity = 0;
 			}
-		} // closes: V.SF.Toggle && V.SF.Active >= 1
+		}
 	}
 
 	delete V.Tour; delete V.SFColonel; delete V.SFUnit;
diff --git a/src/Mods/SpecialForce/SpecialForceFS.js b/src/Mods/SpecialForce/SpecialForceFS.js
index 6c1330d1615b4aa417133bffd6319c85563d57b4..e17f5490cb6ba18e63dff3bfe74477da0f743171 100644
--- a/src/Mods/SpecialForce/SpecialForceFS.js
+++ b/src/Mods/SpecialForce/SpecialForceFS.js
@@ -1,4 +1,4 @@
-App.SF.fsIntegration = (function() {
+App.Mods.SF.fsIntegration = (function() {
 	return {
 		list,
 		menu,
@@ -616,6 +616,7 @@ App.SF.fsIntegration = (function() {
 
 	function menu() {
 		const node = new DocumentFragment();
+		App.UI.DOM.appendNewElement("p", node, `Due to being located in the lower levels, occupying unneeded warehouse space that is not accessible to the general citizenry, the Special Force is quite isolated from the rest of ${V.arcologies[0].name}. As a result, the soldiers may roleplay with various Future Societies to reduce boredom, with no chance of influencing the arcology's broader society.`);
 		if (V.SF.FS.Tension === -1) {
 			App.UI.DOM.appendNewElement("span", node, `You bring up the topic of cultural development with The Colonel, and in doing so, you share your hopes that she might be willing to help you better acquaint the troops with your cultural mores. Her response was less than positive:`);
 			switch (V.SF.Colonel.Core) {
@@ -644,7 +645,7 @@ App.SF.fsIntegration = (function() {
 		} else if (V.SF.FS.Tension < 100) {
 			node.append(`You walk past The Colonel and move towards the common area to meet with an exclusive group of her very influential officers that are currently relaxing at their favorite table. These men and women are known for their competence, popularity, and authority within their respective divisions of ${V.SF.Lower}, they are hard to replace, and they are always looking to earn more coin; they are the perfect weak link for trickling your Future Society influences down into the Firebase. As the officers make room at their table for you to sit and join them for discussion, you spot The Colonel staring at you from afar, and she does not look happy with you. As you are her employer, she cannot stop you from speaking with her soldiers or moving around as you please, but she can tell that you are up to no good.`);
 			const confictingFSs = validityTester();
-			for (const currentFS of App.SF.fsIntegration.list().all) {
+			for (const currentFS of App.Mods.SF.fsIntegration.list().all) {
 				if (!confictingFSs.includes(V.SF.FS[currentFS]) && V.SF.FS[currentFS].lv < 100) {
 					$(node).wiki(createLink(currentFS));
 				}
@@ -741,7 +742,7 @@ App.SF.fsIntegration = (function() {
 			words = `Colonel's gift(s)`;
 		}
 		const divs = [];
-		for (const currentFS of App.SF.fsIntegration.list().all) {
+		for (const currentFS of App.Mods.SF.fsIntegration.list().all) {
 			if (textDisplay === 200 && V.SF.FS[currentFS].gift > 0) {
 				divs.push(selectedFSText(currentFS).gift);
 			}
diff --git a/src/Mods/SpecialForce/editSF.js b/src/Mods/SpecialForce/editSF.js
index b5ccc9167d5c987438547f4a2141fb5b6fb42db7..36c17ee412a47fff9d47c04009549873c899ad35 100644
--- a/src/Mods/SpecialForce/editSF.js
+++ b/src/Mods/SpecialForce/editSF.js
@@ -3,77 +3,77 @@ App.UI.editSF = function() {
 
 	for (let i in V.SF.Squad) {
 		const v = String([i]);
-		if (V.SF.Squad[i] > App.SF.upgrades.currentUnitMax(v)) {
-			V.SF.Squad[i] = App.SF.upgrades.currentUnitMax(v);
+		if (V.SF.Squad[i] > App.Mods.SF.upgrades.currentUnitMax(v)) {
+			V.SF.Squad[i] = App.Mods.SF.upgrades.currentUnitMax(v);
 		}
 	}
 
-	const max = App.SF.upgrades.max();
-	const T1 = App.SF.unlocked.secondTier();
-	const size = App.SF.upgrades.total();
+	const max = App.Mods.SF.upgrades.max();
+	const T1 = App.Mods.SF.unlocked.secondTier();
+	const size = App.Mods.SF.upgrades.total();
 
 	let options = new App.UI.OptionsGroup();
 
 	App.UI.DOM.appendNewElement("h2", node, `Upgrades: ${size}/${max} (${(100 * size / max).toFixed(2)}%)`);
 
 	options.addOption(`Firebase`, "Firebase", V.SF.Squad).showTextBox()
-		.addComment(`current max ${App.SF.upgrades.currentUnitMax('Firebase')}`);
+		.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('Firebase')}`);
 	options.addOption(`Armoury`, "Armoury", V.SF.Squad).showTextBox()
-		.addComment(`current max ${App.SF.upgrades.currentUnitMax('Armoury')}`);
+		.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('Armoury')}`);
 	options.addOption(`Drugs`, "Drugs", V.SF.Squad).showTextBox()
-		.addComment(`current max ${App.SF.upgrades.currentUnitMax('Drugs')}`);
+		.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('Drugs')}`);
 
 	if (V.SF.Squad.Firebase >= 2) {
 		options.addOption(`Drones`, "Drones", V.SF.Squad).showTextBox()
-			.addComment(`current max ${App.SF.upgrades.currentUnitMax('Drones')}`);
+			.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('Drones')}`);
 	}
 
-	if (App.SF.unlocked.garage()) {
+	if (App.Mods.SF.unlocked.garage()) {
 		options.addCustom(App.UI.DOM.makeElement("h2", `Garage`));
 		options.addOption(`Attack Vehicles`, "AV", V.SF.Squad).showTextBox()
-			.addComment(`current max ${App.SF.upgrades.currentUnitMax('AV')}`);
+			.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('AV')}`);
 		options.addOption(`Transport Vehicles`, "TV", V.SF.Squad).showTextBox()
-			.addComment(`current max ${App.SF.upgrades.currentUnitMax('TV')}`);
+			.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('TV')}`);
 		if (T1) {
 			options.addOption(`Prototype Goliath Tank`, "PGT", V.SF.Squad).showTextBox()
-				.addComment(`current max ${App.SF.upgrades.currentUnitMax('PGT')}`);
+				.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('PGT')}`);
 		}
 	}
 
-	if (App.SF.unlocked.hangar()) {
+	if (App.Mods.SF.unlocked.hangar()) {
 		options.addCustom(App.UI.DOM.makeElement("h2", `Hangar`));
 		options.addOption(`Attack Planes`, "AA", V.SF.Squad).showTextBox()
-			.addComment(`current max ${App.SF.upgrades.currentUnitMax('AA')}`);
+			.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('AA')}`);
 		options.addOption(`Transport Planes`, "TA", V.SF.Squad).showTextBox()
-			.addComment(`current max ${App.SF.upgrades.currentUnitMax('TA')}`);
+			.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('TA')}`);
 		if (T1) {
 			options.addOption(`Spaceplane`, "SpacePlane", V.SF.Squad).showTextBox()
-				.addComment(`current max ${App.SF.upgrades.currentUnitMax('SpacePlane')}`);
+				.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('SpacePlane')}`);
 			options.addOption(`Gunship`, "GunS", V.SF.Squad).showTextBox()
-				.addComment(`current max ${App.SF.upgrades.currentUnitMax('GunS')}`);
+				.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('GunS')}`);
 		}
 	}
 
-	if (App.SF.unlocked.launchBay()) {
+	if (App.Mods.SF.unlocked.launchBay()) {
 		options.addCustom(App.UI.DOM.makeElement("h2", `Launch Bay`));
 		options.addOption(`Satellite`, "Satellite", V.SF.Squad).showTextBox()
-			.addComment(`current max ${App.SF.upgrades.currentUnitMax('Satellite')}`);
+			.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('Satellite')}`);
 		if (V.terrain !== "oceanic") {
 			options.addOption(`Giant Robot`, "GiantRobot", V.SF.Squad).showTextBox()
-				.addComment(`current max ${App.SF.upgrades.currentUnitMax('GiantRobot')}`);
+				.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('GiantRobot')}`);
 				options.addOption(`Cruise Missile`, "MissileSilo", V.SF.Squad).showTextBox()
-				.addComment(`current max ${App.SF.upgrades.currentUnitMax('MissileSilo')}`);
+				.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('MissileSilo')}`);
 		}
 	}
 
-	if (App.SF.unlocked.navalYard()) {
+	if (App.Mods.SF.unlocked.navalYard()) {
 		options.addCustom(App.UI.DOM.makeElement("h2", `Naval Yard`));
 		options.addOption(`Aircraft Carrier`, "AircraftCarrier", V.SF.Squad).showTextBox()
-			.addComment(`current max ${App.SF.upgrades.currentUnitMax('AircraftCarrier')}`);
+			.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('AircraftCarrier')}`);
 		options.addOption(`Submarine`, "Sub", V.SF.Squad).showTextBox()
-			.addComment(`current max ${App.SF.upgrades.currentUnitMax('Sub')}`);
+			.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('Sub')}`);
 		options.addOption(`Amphibious Transport`, "HAT", V.SF.Squad).showTextBox()
-			.addComment(`current max ${App.SF.upgrades.currentUnitMax('HAT')}`);
+			.addComment(`current max ${App.Mods.SF.upgrades.currentUnitMax('HAT')}`);
 	}
 
 	node.append(options.render());
@@ -84,7 +84,7 @@ App.UI.editSF = function() {
 			App.UI.DOM.makeTextBox(V.SF.FS.Tension, (v) => {
 				V.SF.FS.Tension = v;
 				App.UI.reload();
-			})
+			}, true)
 		]);
 	}
 
diff --git a/src/Mods/SpecialForce/events/SpecialForceIntro.js b/src/Mods/SpecialForce/events/SpecialForceIntro.js
index f924391f3c2478fb4d80db1b3730efcd732aabae..d55aa2c0fcee297e76fc97eb21df5c89ae73c335 100644
--- a/src/Mods/SpecialForce/events/SpecialForceIntro.js
+++ b/src/Mods/SpecialForce/events/SpecialForceIntro.js
@@ -44,7 +44,7 @@ App.Events.SecurityForceProposal = class SecurityForceProposal extends App.Event
 		// TODO: write scenes and unlock sidebar, instead of going directly to passages.
 		function announce() {
 			V.SF.Active = 1;
-			App.SF.Init();
+			App.Mods.SF.Init();
 			cashX(forceNeg(price), "specialForcesCap");
 			App.UI.DOM.replace(node, stage0());
 			return ``;
diff --git a/src/Mods/SpecialForce/upgrades/SpecialForceUpgradeFunctions.js b/src/Mods/SpecialForce/upgrades/SpecialForceUpgradeFunctions.js
index 489d9b06b34b316afd8a9d65f49867cc4d12d5e5..43875fa95ecaf3b8ea5c431cd971fdf87f22971a 100644
--- a/src/Mods/SpecialForce/upgrades/SpecialForceUpgradeFunctions.js
+++ b/src/Mods/SpecialForce/upgrades/SpecialForceUpgradeFunctions.js
@@ -1,4 +1,4 @@
-App.SF.unlocked = (function() {
+App.Mods.SF.unlocked = (function() {
 	return {
 		secondTier,
 		garage,
@@ -29,7 +29,7 @@ App.SF.unlocked = (function() {
 	}
 })();
 
-App.SF.upgrades = (function() {
+App.Mods.SF.upgrades = (function() {
 	return {
 		total,
 		list,
@@ -44,7 +44,7 @@ App.SF.upgrades = (function() {
 
 	function list(completeView = '') {
 		let array = ['Armoury', 'Firebase', 'Drugs'];
-		const T1 = App.SF.unlocked.secondTier();
+		const T1 = App.Mods.SF.unlocked.secondTier();
 
 		if (V.SF.Squad.Firebase >= 2 || completeView === 'all') {
 			array.push('Drones');
@@ -66,9 +66,10 @@ App.SF.upgrades = (function() {
 
 		if (completeView === 'all' || T1) { // Launch Bay
 			array.push('Satellite');
-			if (V.terrain !== "oceanic" && V.terrain !== "marine") {
+			if (V.terrain !== "oceanic") {
 				array.push('GiantRobot', 'MissileSilo');
-			} else if (V.terrain === "oceanic" || V.terrain === "marine") { // Naval Yard
+			}
+			if (V.terrain === "oceanic" || V.terrain === "marine") { // Naval Yard
 				array.push('AircraftCarrier', 'Sub', 'HAT');
 			}
 		}
@@ -81,14 +82,13 @@ App.SF.upgrades = (function() {
 	}
 
 	function currentUnitMax(input) {
-		const T1 = App.SF.unlocked.secondTier();
+		const T1 = App.Mods.SF.unlocked.secondTier();
 
 		if (!T1) {
 			if (['Armoury', 'Firebase', 'Drugs', 'Drones', 'AV', 'TV', 'AA', 'TA'].includes(input)) {
 				return 5;
-			} else {
-				return 0;
 			}
+			return 0;
 		} else {
 			if (!['SpacePlane', 'GunS', 'Satellite', 'GiantRobot', 'MissileSilo', 'AircraftCarrier', 'Sub', 'HAT'].includes(input)) {
 				return 10;
@@ -116,20 +116,20 @@ App.SF.upgrades = (function() {
 			App.UI.DOM.appendNewElement("div", node, checkUnit("Drones"));
 		}
 
-		if (App.SF.unlocked.garage()) {
+		if (App.Mods.SF.unlocked.garage()) {
 			App.UI.DOM.appendNewElement("div", node, "Garage", "bold");
 			App.UI.DOM.appendNewElement("div", node, checkUnit("AV"));
 			App.UI.DOM.appendNewElement("div", node, checkUnit("TV"));
 			App.UI.DOM.appendNewElement("div", node, checkUnit("PGT"));
 		}
-		if (App.SF.unlocked.hangar()) {
+		if (App.Mods.SF.unlocked.hangar()) {
 			App.UI.DOM.appendNewElement("div", node, "Hangar", "bold");
 			App.UI.DOM.appendNewElement("div", node, checkUnit("AA"));
 			App.UI.DOM.appendNewElement("div", node, checkUnit("TA"));
 			App.UI.DOM.appendNewElement("div", node, checkUnit("SpacePlane"));
 			App.UI.DOM.appendNewElement("div", node, checkUnit("GunS"));
 		}
-		if (App.SF.unlocked.launchBay()) {
+		if (App.Mods.SF.unlocked.launchBay()) {
 			App.UI.DOM.appendNewElement("div", node, "Launch Bay", "bold");
 			App.UI.DOM.appendNewElement("div", node, checkUnit("Satellite"));
 			if (V.terrain !== "oceanic") {
@@ -137,7 +137,7 @@ App.SF.upgrades = (function() {
 				App.UI.DOM.appendNewElement("div", node, checkUnit("MissileSilo"));
 			}
 		}
-		if (App.SF.unlocked.navalYard()) {
+		if (App.Mods.SF.unlocked.navalYard()) {
 			App.UI.DOM.appendNewElement("div", node, "Naval Yard", "bold");
 			App.UI.DOM.appendNewElement("div", node, checkUnit("AircraftCarrier"));
 			App.UI.DOM.appendNewElement("div", node, checkUnit("Sub"));
@@ -155,7 +155,7 @@ App.SF.upgrades = (function() {
 		 */
 		function checkUnit(unit) {
 			const node = new DocumentFragment();
-			const max = App.SF.upgrades.currentUnitMax(unit);
+			const max = App.Mods.SF.upgrades.currentUnitMax(unit);
 			let cost;
 			let text = unit;
 			switch (unit) {
@@ -231,9 +231,9 @@ App.SF.upgrades = (function() {
 				const multiplier = [1, 2, 3, 4, 5];
 				if (V.cash >= price) {
 					node.append(`Upgrade ${text}, one level costs`);
-					App.UI.DOM.appendNewElement("span", node, ` ${cashFormat(cost)}. `, ["cash", "dec"]);
+					App.UI.DOM.appendNewElement("span", node, ` ${cashFormat(price)}. `, ["cash", "dec"]);
 					for (const number of multiplier) {
-						if (V.cash >= price * number) {
+						if (V.cash >= price * number && (max - V.SF.Squad[unit] >= number)) {
 							App.UI.DOM.appendNewElement("span", node, App.UI.DOM.link(` ,x${number}`, () => {
 								V.SF.Upgrade = 1;
 								V.SF.Squad[unit] += number;
@@ -246,10 +246,10 @@ App.SF.upgrades = (function() {
 				} else {
 					App.UI.DOM.appendNewElement("span", node, `Cannot afford to upgrade the ${text}.`, "note");
 				}
-				$(node).wiki(App.SF.progress(V.SF.Squad[unit]));
+				$(node).wiki(App.Mods.SF.progress(V.SF.Squad[unit]));
 			} else if (["PGT", "SpacePlane", "GunS", "Satellite", "GiantRobot", "MissileSilo", "AircraftCarrier", "Sub", "HAT"].includes(unit) && V.SF.Squad[unit] === max && V.PC.skill.warfare < 75) {
 				App.UI.DOM.appendNewElement("span", node, "Your warfare skill is not high enough unlock the next upgrade.", "note");
-				$(node).wiki(App.SF.progress(V.SF.Squad[unit]));
+				$(node).wiki(App.Mods.SF.progress(V.SF.Squad[unit]));
 			} else if (V.SF.Squad[unit] === max && max > 0) {
 				fullyUpgraded.push(text);
 			}
@@ -257,11 +257,11 @@ App.SF.upgrades = (function() {
 			/**
 			 * @param {number} cost
 			 * @returns {number}
-	*/
+			 */
 			function getPrice(cost) {
 				const upgradeDiv = 1.65;
 				const S = V.SF.Squad;
-				let value = (cost / upgradeDiv) * App.SF.env() * Math.pow(1.15, V.SF.Squad[unit] + 1);
+				let value = (cost / upgradeDiv) * App.Mods.SF.env() * Math.pow(1.15, V.SF.Squad[unit] + 1);
 				if ([S.AircraftCarrier, S.Drones, S.GiantRobot, S.GunS, S.MissileSilo, S.Satellite, S.SpacePlane, S.Sub].includes(unit)) {
 					value *= V.HackingSkillMultiplier;
 				}
@@ -275,13 +275,13 @@ App.SF.upgrades = (function() {
  * @param {number} [max]
  * @returns {string}
  */
-App.SF.progress = function(x, max) {
+App.Mods.SF.progress = function(x, max) {
 	let out = `⏐`;
 	let z;
 	let i;
 	if (max === undefined) {
 		x = Math.clamp(x, 0, 10);
-		if (App.SF.unlocked.secondTier() === false) {
+		if (App.Mods.SF.unlocked.secondTier() === false) {
 			z = 5 - x;
 			for (i = 0; i < x; i++) {
 				out += `█⏐`;
diff --git a/src/Mods/SpecialForce/upgrades/SpecialForceUpgradeText.js b/src/Mods/SpecialForce/upgrades/SpecialForceUpgradeText.js
index fd9c985aec371ba94ae4de118327e4883b5816df..f6b93308dc6ce6322b97842ea2bc78894516d35b 100644
--- a/src/Mods/SpecialForce/upgrades/SpecialForceUpgradeText.js
+++ b/src/Mods/SpecialForce/upgrades/SpecialForceUpgradeText.js
@@ -1,4 +1,4 @@
-App.SF.UnitText = function(input) {
+App.Mods.SF.UnitText = function(input) {
 	let text = ``;
 	const S = V.SF.Squad;
 	// Sorted by case
diff --git a/src/arcologyBuilding/ManageArcology.js b/src/arcologyBuilding/ManageArcology.js
index 1c90aa3291c092bf860ed9fcebc568460713e6c9..dbd355b89f976ef4665dbd9e45cca16932893c13 100644
--- a/src/arcologyBuilding/ManageArcology.js
+++ b/src/arcologyBuilding/ManageArcology.js
@@ -1,485 +1,750 @@
 App.UI.manageArcology = function() {
+	const frag = new DocumentFragment();
+
 	V.nextButton = "Back";
 	V.nextLink = "Main";
 	V.encyclopedia = "The X-Series Arcology";
-	let arcName = V.arcologies[0].name;
-	let r;
 
-	const asPercentage = (v) => Math.trunc((v / (V.ACitizens + V.ASlaves)) * 1000) / 10;
-	function arcUpgradeCost(basePrice, modifier = "") {
-		let cost = Math.trunc(basePrice * V.upgradeMultiplierArcology);
-		return cost * (["no subsidy", "light subsidy", "Heavy subsidy", "receiver subsidy", "propHub", "secHub"].includes(modifier) ? V.HackingSkillMultiplier : 1);
+	const arcologyName = V.arcologies[0].name;
+
+	frag.append(
+		description(),
+		ownership(),
+		construction(),
+		weather(),
+		sexualServices(),
+		language(),
+		upgrades(),
+		records(),
+	);
+
+	if (V.eventResults.foodCrisis) {
+		frag.append(
+			foodMarket()
+		);
 	}
-	function applyArcUpgrade(text, upgrade, basePrice, choice = "") {
-		return App.UI.DOM.link(text, () => {
-			if (["drones", "hydro", "apron", "grid"].includes(upgrade)) {
-				V.arcologyUpgrade[upgrade] = 1;
-				if (upgrade === "drones" && V.secExpEnabled > 0) {
-					App.SecExp.unit.gen("bots", true);
-				}
-			} else if (["weatherCladding", "antiWeatherFreeze", "disasterResponse"].includes(upgrade)) {
-				V[upgrade]++;
-			} else if (upgrade === "receiver") {
-				V.FCTV.receiver = 1;
-				V.FCTV.weekEnabled = V.week;
-				FCTV.initChannels();
-				if (["no subsidy", "heavy subsidy"].includes(choice)) {
-					repX((choice === "no subsidy" ? 500 : -1500), "capEx");
+
+	if (V.secExpEnabled) {
+		frag.append(
+			security(),
+			military(),
+		);
+	}
+
+	if (V.experimental.dinnerParty === 1 && V.seeExtreme === 1) {
+		frag.append(
+			events(),
+		);
+	}
+
+	return frag;
+
+	function description() {
+		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+
+		if (V.cheatMode === 1) {
+			App.UI.DOM.appendNewElement("div", div,
+				App.UI.DOM.passageLink(`Cheat Edit Arcology`, "MOD_Edit Arcology Cheat"),
+				["cheat-menu"]);
+		}
+
+		App.UI.DOM.appendNewElement("h1", div,
+			App.UI.DOM.link(`${V.arcologies[0].name}`, () => {
+				if (Dialog.isOpen()) {
+					Dialog.close();
 				}
-			} else if (upgrade === "SecExp") {
-				App.SecExp[choice].Init();
-			}
+				Dialog.setup("Rename");
 
-			V.PC.skill.engineering++;
-			if (upgrade === "receiver" || ["propHub", "secHub"].includes(choice)) {
-				V.PC.skill.hacking++;
-			}
-			cashX(forceNeg(arcUpgradeCost(basePrice, choice)), "capEx");
-			App.UI.reload();
-		});
+				const frag = new DocumentFragment();
+
+				frag.append(App.UI.DOM.makeTextBox(V.arcologies[0].name, str => { V.arcologies[0].name = str; App.UI.reload(); }));
+				$(Dialog.body()).empty().append(frag);
+				Dialog.open();
+			})
+			, ["white", "center"]
+		);
+
+		App.UI.DOM.appendNewElement("div", div, V.building.render());
+
+		if (V.seeArcology === 1) {
+			div.append(App.Desc.playerArcology(
+				App.UI.DOM.link(`Hide`, () => {
+					V.seeArcology = 0;
+					App.UI.reload();
+				})
+			));
+		}
+
+		return div;
 	}
 
-	function societalView(s, type) {
-		const classType = s === "top" ? "Millionaires" : `${capFirstChar(s)} Class`;
-		const calRent = (v) => Math.trunc(V.rent[v] * (1 + (5 - V.baseDifficulty) / 20) / 0.25) / 100;
-		const classStr = s + "Class";
-		function link(text, type, value, value2 = 0, value3 = 0) {
-			return App.UI.DOM.link(`${text}`, () => {
-				if (type !== "rent") {
-					V[type][classStr] = value;
-					if (type === "sexSupplyBarriers") {
-						repX(-1000, "subsidiesAndBarriers");
-					}
+	function ownership() {
+		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+
+		App.Arcology.updateOwnership();
+
+		App.UI.DOM.appendNewElement("h2", div, "Arcology Ownership");
+		div.append(ownershipReport(false));
+
+		if (FutureSocieties.availCredits() > 0) {
+			App.UI.DOM.appendNewElement("span", div, ` Society is ready to begin accepting a new societal direction.`, ['noteworthy']);
+		}
+
+		return div;
+	}
+
+	function construction() {
+		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+
+		App.UI.DOM.appendNewElement("h2", div, "Construction");
+
+		if (V.arcologyUpgrade.drones !== 1) {
+			App.UI.DOM.appendNewElement("div", div, `The first major upgrade needed is the installation of a drone security system so higher-class citizens will feel safe and protected should they choose to immigrate.`);
+			div.append(makePurchase(`Install drone security system`, 5000 * V.upgradeMultiplierArcology, "capEx", {
+				notes: [`increases upkeep`],
+				handler: () => {
+					V.arcologyUpgrade.drones = 1;
+					V.PC.skill.engineering++;
+				},
+			}));
+		} else {
+			App.UI.DOM.appendNewElement("div", div, `A drone-based security system has been installed throughout ${arcologyName}.`);
+
+			if (V.arcologyUpgrade.hydro !== 1) {
+				App.UI.DOM.appendNewElement("div", div, `The next major upgrade needed is the installation of a better water reclamation system so your residents will have access to cheaper water and hydroponically grown food.`);
+				div.append(makePurchase(`Upgrade water reclamation system`, 10000 * V.upgradeMultiplierArcology, "capEx", {
+					notes: [`increases upkeep`],
+					handler: () => {
+						V.arcologyUpgrade.hydro = 1;
+						V.PC.skill.engineering++;
+					},
+				}));
+			} else {
+				App.UI.DOM.appendNewElement("div", div, `Large pipes from the advanced water reclamation system can occasionally be seen snaking their way through the plumbing system.`);
+
+				if (V.arcologyUpgrade.apron !== 1) {
+					App.UI.DOM.appendNewElement("div", div, `The next major upgrade needed is the installation of a broader apron at the bottom of the arcology to increase its surface area and gather more solar energy. Right now, tenants that use a lot of power have to import it from outside.`);
+					div.append(makePurchase(`Install solar apron`, 20000 * V.upgradeMultiplierArcology, "capEx", {
+						notes: [`increases upkeep`],
+						handler: () => {
+							V.arcologyUpgrade.apron = 1;
+							V.PC.skill.engineering++;
+						},
+					}));
 				} else {
-					V.rent[classStr] = V.rentDefaults[classStr] * value;
-					if (s === "lower") {
-						V.rentEffectL = value2;
-					} else if (s === "middle") {
-						V.rentEffectM = value2;
-					} else if (s === "upper") {
-						V.rentEffectU = value2;
-					} else if (s === "top") {
-						V.rentEffectT = value2;
+					App.UI.DOM.appendNewElement("div", div, `Huge swathes of solar panels are installed on the outside of ${arcologyName}, covering nearly everything that isn't glass or an entrance.`);
+
+					if (V.arcologyUpgrade.grid !== 1) {
+						App.UI.DOM.appendNewElement("div", div, `The next major upgrade needed is an improvement of the arcology's electrical transmission lines to make efficient use of the additional power from the solar apron.`);
+						div.append(makePurchase(`Upgrade transmission lines`, 50000 * V.upgradeMultiplierArcology, "capEx", {
+							notes: [`increases upkeep`],
+							handler: () => {
+								V.arcologyUpgrade.grid = 1;
+								V.PC.skill.engineering++;
+							},
+						}));
+					} else {
+						App.UI.DOM.appendNewElement("div", div, `Thick cables as large as your forearm can be seen in the exposed ceilings of some parts of your arcology.`);
+						App.UI.DOM.appendNewElement("div", div, App.Arcology.upgrades(V.building));
 					}
-					V.whoreBudget[classStr] *= value3;
 				}
-				App.UI.reload();
-			});
+			}
 		}
 
-		let choices = [];
-		const node = new DocumentFragment();
-		if (type === "policies") {
-			if (V.sexSubsidies[classStr] === 0) {
-				node.append(`You can provide a minor subsidy for those selling sexual services to the ${classType}. `);
-				choices.push(link("Minor Subsidy", "sexSubsidies", 1));
-			} else if (V.sexSubsidies[classStr] === 1) {
-				node.append(`You are providing a minor subsidy for those selling sexual services to the ${classType}. `);
-				choices.push(link("Cancel Subsidy", "sexSubsidies", 0));
-				choices.push(link("Moderate Subsidy", "sexSubsidies", 2));
-			} else if (V.sexSubsidies[classStr] === 2) {
-				node.append(`You are providing a moderate subsidy for those selling sexual services to the ${classType}. `);
-				choices.push(link("Minor Subsidy", "sexSubsidies", 1));
-				choices.push(link("Substantial Subsidy", "sexSubsidies", 3));
-			} else if (V.sexSubsidies[classStr] === 3) {
-				node.append(`You are providing a substantial subsidy for those selling sexual services to the ${classType}. `);
-				choices.push(link("Moderate Subsidy", "sexSubsidies", 2));
-				choices.push(link("Gratuitous Subsidy", "sexSubsidies", 4));
+		const text = [];
+
+		if (V.weatherCladding === 0) {
+			text.push(`Extreme weather is becoming common worldwide. The arcology's exterior can be hardened to reduce damage in case of heavy weather, but this will reduce its beauty somewhat and will cost ${cashFormat(50000 * V.upgradeMultiplierArcology)}. Your citizens are`);
+
+			if (V.weatherAwareness === 0) {
+				text.push(`likely to disapprove of this measure as alarmism.`);
 			} else {
-				node.append(`You are providing a gratuitous subsidy for those selling sexual services to the ${classType}. `);
-				choices.push(link("Substantial Subsidy", "sexSubsidies", 3));
+				text.push(App.UI.DOM.makeElement("span", `concerned that this measure has not been taken already.`, ['noteworthy']));
 			}
-			App.UI.DOM.appendNewElement("span", node, "Upkeep is relative to the amount provided by other parties. ", "note");
-			App.UI.DOM.appendNewElement("span", node, App.UI.DOM.generateLinksStrip(choices));
-			App.UI.DOM.appendNewElement("div", node);
-
-			choices = [];
-			if (V.sexSupplyBarriers[classStr] === 0) {
-				node.append(
-					`Alternatively administrative "accidents" can happen if you are willing to spend ${num(1000)} reputation and pay a flat upkeep of`,
-					App.UI.DOM.makeElement("span", ` ${cashFormat(1000)}. `, "cash")
-				);
-				choices.push(link("Create Bureaucracy", "sexSupplyBarriers", 1));
-			} else if (V.sexSupplyBarriers[classStr] === 1) {
-				node.append(
-					`You have forced some unneeded bureaucracy, making things a little more difficult.
-					If you are willing to spend ${num(1000)} reputation you can change this policy.
-					Increasing the bureaucracy further will cost a flat upkeep of`,
-					App.UI.DOM.makeElement("span", ` ${cashFormat(5000)}. `, "cash")
-				);
-				choices.push(link("Abolish Bureaucracy", "sexSupplyBarriers", 0));
-				choices.push(link("Increase Bureaucracy", "sexSupplyBarriers", 2));
-			} else if (V.sexSupplyBarriers[classStr] === 2) {
-				node.append(
-					`You have forced considerable bureaucracy, making things a little more difficult.
-					If you are willing to spend ${num(1000)} reputation you can change this policy.
-					Increasing the bureaucracy further will cost a flat upkeep of`,
-					App.UI.DOM.makeElement("span", ` ${cashFormat(20000)}. `, "cash")
-				);
-				choices.push(link("Reduce Bureaucracy", "sexSupplyBarriers", 1));
-				choices.push(link("Increase Bureaucracy", "sexSupplyBarriers", 3));
-			} else if (V.sexSupplyBarriers[classStr] === 3) {
-				node.append(
-					`You have forced stifling bureaucracy, making things a little more difficult.
-					If you are willing to spend ${num(1000)} reputation you can change this policy.
-					Increasing the bureaucracy further will cost a flat upkeep of`,
-					App.UI.DOM.makeElement("span", ` ${cashFormat(60000)}. `, "cash")
-				);
-				choices.push(link("Reduce Bureaucracy", "sexSupplyBarriers", 2));
-				choices.push(link("Increase Bureaucracy", "sexSupplyBarriers", 4));
-			} else {
-				node.append(
-					`You have forced suffocating bureaucracy, making things a little more difficult.
-					If you are willing to spend ${num(1000)} reputation you can change this policy.`
+
+			App.Events.addNode(div, text, "div");
+
+			div.append(makePurchase(`Apply weather cladding`, 50000 * V.upgradeMultiplierArcology, "capEx", {
+				handler: () => {
+					V.weatherCladding++;
+					V.PC.skill.engineering++;
+				},
+			}));
+		} else {
+			text.push(`The arcology's exterior is jacketed with ${V.weatherCladding === 1 ? "unsightly but sturdy" : "gorgeously sculpted and fully functional"} weather cladding.`);
+
+			App.Events.addNode(div, text, "div");
+
+			if (V.weatherCladding === 1 && V.building.sections.length > 0) {
+				const cost = 3_500_000 * V.upgradeMultiplierArcology;
+
+				div.append(
+					`Your arcology is so prosperous that remodeling the cladding into something beautiful is within the realm of possibility. This massive project will cost ${cashFormat(cost)} and without a doubt render your arcology one of the wonders of the world.`,
+					makePurchase(`Remodel weather cladding`, cost, "capEx", {
+						handler: () => {
+							V.weatherCladding++;
+							V.PC.skill.engineering++;
+						},
+					})
 				);
-				choices.push(link("Reduce Bureaucracy", "sexSupplyBarriers", 3));
 			}
-		} else if (type === "rent") {
-			node.append(
-				`${classType} | ${num(V[classStr])} | ${asPercentage(V[classStr])}% | Rent: `,
-				App.UI.DOM.makeElement("span", `${cashFormat(calRent(classStr))} `, "cash")
+		}
+
+		if (V.FCTV.receiver > -1 && !V.FCTV.weekEnabled) {
+			App.UI.DOM.appendNewElement("div", div, "You have not installed an FCTV receiver.");
+
+			div.append(
+				`You can purchase a receiver and cover the cost yourself.`,
+				makePurchase(`No subsidy`, 25000 * V.upgradeMultiplierArcology, "capEx", {
+					handler: () => {
+						V.FCTV.receiver = 1;
+						V.FCTV.weekEnabled = V.week;
+						FCTV.initChannels();
+
+
+						repX(500, "capEx");
+					},
+				}),
+				`You can also have your citizens cover some of the cost, instead.`,
+				makePurchase(`Minor subsidy`, 20000 * V.upgradeMultiplierArcology, "capEx", {
+					handler: () => {
+						V.FCTV.receiver = 1;
+						V.FCTV.weekEnabled = V.week;
+						FCTV.initChannels();
+					},
+				}),
+				`You could also choose to have your citizens cover most of the cost.`,
+				makePurchase(`Major subsidy`, 15000 * V.upgradeMultiplierArcology, "capEx", {
+					notes: [`will upset your citizens`],
+					handler: () => {
+						V.FCTV.receiver = 1;
+						V.FCTV.weekEnabled = V.week;
+						FCTV.initChannels();
+
+						repX(-1500, "capEx");
+					},
+				}),
 			);
+		} else {
+			const text = [];
 
-			if (V.rent[classStr] > V.rentDefaults[classStr] * 1.5) {
-				node.append("Very High. ");
-				choices.push(link("Decrease", "rent", 1.5, 0.94, 9 / 8));
-			} else if (V.rent[classStr] > V.rentDefaults[classStr]) {
-				node.append("High. ");
-				choices.push(link("Increase", "rent", 2, 0.85, 8 / 9));
-				choices.push(link("Decrease", "rent", 1, 1, 10 / 9));
-			} else if (V.rent[classStr] > V.rentDefaults[classStr] * 0.5) {
-				node.append("Average. ");
-				choices.push(link("Increase", "rent", 1.5, 0.94, 9 / 8));
-				choices.push(link("Decrease", "rent", 0.5, 1.04, 11 / 10));
-			} else if (V.rent[classStr] > 0) {
-				node.append("Low. ");
-				choices.push(link("Increase", "rent", 1, 1, 10 / 11));
-				choices.push(link("Free Rent", "rent", 0, 1.1, 12 / 11));
-			} else {
-				node.append("Free. ");
-				choices.push(link("Increase", "rent", 0.5, 1.04, 11 / 12));
+			text.push(`You have installed the FCTV receiver and have access to the full range of FCTV's programs.`);
+
+			if (V.FCTV.receiver === 3) {
+				text.push(`High viewership rates amongst your citizens makes it easier to pursue your societal goals.`);
+			} else if (V.FCTV.receiver === 2) {
+				text.push(`Decent viewership rates amongst your citizens makes it somewhat easier to pursue your societal goals.`);
+			} else if (V.FCTV.receiver === 1) {
+				text.push(`Low viewership rates amongst your citizens limits the impact of FCTV on your societal goals.`);
 			}
+
+			App.UI.DOM.appendNewElement("div", div, text.join(' '));
 		}
-		if (type === "policies" && V.rep > 1000 || type === "rent") {
-			App.UI.DOM.appendNewElement("span", node, App.UI.DOM.generateLinksStrip(choices));
-		} else {
-			App.UI.DOM.appendNewElement("div", node, "You are not reputable enough.");
+
+		if (V.PC.skill.engineering >= 100 || V.PC.career === "arcology owner") {
+			const innerDiv = App.UI.DOM.appendNewElement("div", div, "Arcology upgrades are less expensive due to your ");
+
+			App.UI.DOM.appendNewElement("span", innerDiv, V.PC.career === "arcology owner" ? `experience in the Free Cities.` : `arcology engineering training.`, ["player", "skill"]);
 		}
-		return node;
-	}
 
-	const node = new DocumentFragment();
-	if (V.cheatMode === 1) {
-		App.UI.DOM.appendNewElement("div", node,
-			App.UI.DOM.passageLink("Cheat Edit Arcology", "MOD_Edit Arcology Cheat"),
-			["cheat-menu"]);
-	}
-	App.UI.DOM.appendNewElement("h1", node,
-		App.UI.DOM.link(`${arcName}`, () => {
-			if (Dialog.isOpen()) {
-				Dialog.close();
-			}
-			Dialog.setup("Rename");
-			const frag = new DocumentFragment();
-			frag.append(App.UI.DOM.makeTextBox(V.arcologies[0].name, str => { V.arcologies[0].name = str; App.UI.reload(); }));
-			$(Dialog.body()).empty().append(frag);
-			Dialog.open();
-		})
-		, ["white", "center"]
-	);
-	App.UI.DOM.appendNewElement("div", node, V.building.render());
-	if (V.seeArcology === 1) {
-		node.append(App.Desc.playerArcology(
-			App.UI.DOM.link("Hide", () => {
-				V.seeArcology = 0;
-				App.UI.reload();
-			})
-		));
+		return div;
 	}
 
-	App.UI.DOM.appendNewElement("h2", node, "Arcology Ownership");
-	App.Arcology.updateOwnership();
-	node.append(ownershipReport(false));
-	if (FutureSocieties.availCredits() > 0) {
-		App.UI.DOM.appendNewElement("span", node, ` Society is ready to begin accepting a new societal direction.`, "noteworthy");
-	}
+	function weather() {
+		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
 
-	App.UI.DOM.appendNewElement("h2", node, "Construction");
-	if (V.arcologyUpgrade.drones !== 1) {
-		App.UI.DOM.appendNewElement("div", node, `The first major upgrade needed is the installation of a drone security system so higher-class citizens will feel safe and protected should they choose to immigrate. This upgrade will cost ${cashFormat(arcUpgradeCost(5000))}.`, "note");
-		node.append(applyArcUpgrade("Install drone security system", "drones", 5000));
-	} else if (V.arcologyUpgrade.hydro !== 1) {
-		App.UI.DOM.appendNewElement("div", node, `The next major upgrade needed is the installation of a better water reclamation system so your residents will have access to cheaper water and hydroponically grown food. This upgrade will cost ${cashFormat(arcUpgradeCost(10000))}.`, "note");
-		node.append(applyArcUpgrade("Upgrade water reclamation system", "hydro", 10000));
-	} else if (V.arcologyUpgrade.apron !== 1) {
-		App.UI.DOM.appendNewElement("div", node, `The next major upgrade needed is the installation of a broader apron at the bottom of the arcology to increase its surface area and gather more solar energy. Right now, tenants that use a lot of power have to import it from outside. This upgrade will cost ${cashFormat(arcUpgradeCost(20000))}.`, "note");
-		node.append(applyArcUpgrade("Install solar apron", "apron", 20000));
-	} else if (V.arcologyUpgrade.grid !== 1) {
-		App.UI.DOM.appendNewElement("div", node, `The next major upgrade needed is an improvement of the arcology's electrical transmission lines to make efficient use of the additional power from the solar apron. This upgrade will cost ${cashFormat(arcUpgradeCost(50000))}.`, "note");
-		node.append(applyArcUpgrade("Upgrade transmission lines", "grid", 50000));
-	} else {
-		App.UI.DOM.appendNewElement("div", node, "The arcology's public areas are fully upgraded.");
-		App.UI.DOM.appendNewElement("div", node, App.Arcology.upgrades(V.building));
-	}
+		App.UI.DOM.appendNewElement("h2", div, "Weather");
 
-	r = [];
-	if (V.weatherCladding === 0) {
-		r.push(`Extreme weather is becoming common worldwide. The arcology's exterior can be hardened to reduce damage in case of heavy weather, but this will reduce its beauty somewhat and will cost ${cashFormat(arcUpgradeCost(50000))}. Your citizens are`);
-		if (V.weatherAwareness === 0) {
-			r.push("likely to disapprove of this measure as alarmism.");
-		} else {
-			r.push(App.UI.DOM.makeElement("span", `concerned that this measure has not been taken already.`, "noteworthy"));
-		}
-		r.push(App.UI.DOM.makeElement("div", applyArcUpgrade("Apply weather cladding", "weatherCladding", 50000)));
-	} else {
-		r.push(`The arcology's exterior is jacketed with ${V.weatherCladding === 1 ? "unsightly but sturdy" : "gorgeously sculpted and fully functional"} weather cladding.`);
-		if (V.weatherCladding === 1 && V.building.sections.length > 0) {
-			r.push(
-				`Your arcology is so prosperous that remodeling the cladding into something beautiful is within the realm of possibility. This massive project will cost ${cashFormat(arcUpgradeCost(3500000))} and without a doubt render your arcology one of the wonders of the world.`,
-				App.UI.DOM.makeElement("div", applyArcUpgrade("Remodel weather cladding", "weatherCladding", 3500000))
-			);
-		}
-	}
-	App.Events.addNode(node, r, "div");
-	App.UI.DOM.appendNewElement("div", node, "");
-
-	if (V.FCTV.receiver > -1 && !V.FCTV.weekEnabled) {
-		App.UI.DOM.appendNewElement("div", node, "You have not installed an FCTV receiver.");
-		node.append("Installing this receiver ", applyArcUpgrade("yourself", "receiver", 25000, "no subsidy"), ` will cost ${cashFormat(arcUpgradeCost(25000, "receiver subsidy"))}.`);
-		App.UI.DOM.appendNewElement("div", node, "");
-		node.append("You can have your ", applyArcUpgrade("citizens pay", "receiver", 20000, "light subsidy"), ` for the fiber optic upgrades, reducing the cost to ${cashFormat(arcUpgradeCost(20000, "receiver subsidy"))}.`);
-		App.UI.DOM.appendNewElement("div", node, "");
-		node.append("You can also have them ", applyArcUpgrade("heavily subsidize", "receiver", 10000, "Heavy subsidy"), ` installation. They will be upset about it, but it will only cost ${cashFormat(arcUpgradeCost(10000, "receiver subsidy"))}.`);
-	} else {
-		r = [];
-		r.push("You have installed the FCTV receiver and have access to the full range of FCTV's programs.");
-		if (V.FCTV.receiver === 3) {
-			r.push("High viewership rates amongst your citizens makes it easier to pursue your societal goals.");
-		} else if (V.FCTV.receiver === 2) {
-			r.push("Decent viewership rates amongst your citizens makes it somewhat easier to pursue your societal goals.");
-		} else if (V.FCTV.receiver === 1) {
-			r.push("Low viewership rates amongst your citizens limits the impact of FCTV on your societal goals.");
-		}
-		App.UI.DOM.appendNewElement("div", node, r.join(" "));
-	}
+		if (V.difficultySwitch === 1) {
+			if (V.econWeatherDamage > 0) {
+				div.append(
+					`The recent terrible weather has damaged the local infrastructure. It is `,
+					App.UI.DOM.makeElement("span", `reducing the local economy score by ${num(V.econWeatherDamage)}.`, ['warning'])
+				);
 
-	if (V.PC.skill.engineering >= 100 || V.PC.career === "arcology owner") {
-		const div = App.UI.DOM.appendNewElement("div", node, "Arcology upgrades are less expensive due to your ");
-		App.UI.DOM.appendNewElement("span", div, `${V.PC.career === "arcology owner" ? "experience in the Free Cities" : "arcology engineering training"}.`, ["player", "skill"]);
-	}
+				if (V.disasterResponse === 0) {
+					div.append(
+						` Locals will do their best to repair the damage on their own, but setting up a disaster response unit will improve the recovery of infrastructure critical for keeping goods, people and information flowing smoothly in and out of your arcology.`,
+						makePurchase(`Create a disaster response unit`, 50000 * V.upgradeMultiplierArcology, "capEx", {
+							notes: [`increases upkeep`],
+							handler: () => {
+								V.disasterResponse++;
+								V.PC.skill.engineering++;
+							}
+						}),
+					);
+				} else if (V.disasterResponse === 1) {
+					div.append(
+						` You are sending your disaster response unit to repair critical infrastructure. They are doing what they can.`,
+						makePurchase(`Purchase specialized all-weather equipment for the response unit`, 100_000 * V.upgradeMultiplierArcology, "capEx", {
+							notes: [`increases upkeep`],
+							handler: () => {
+								V.disasterResponse++;
+								V.PC.skill.engineering++;
+							}
+						}),
+					);
+				} else {
+					App.UI.DOM.appendNewElement("div", div, "Your highly capable disaster response unit is rapidly repairing the weather damage.");
+				}
+			} else if (V.disasterResponse > 0) {
+				App.UI.DOM.appendNewElement("div", div, "Your disaster response unit is idle. It will not cost you any upkeep this week.");
+			}
+		}
 
-	if (V.secExpEnabled === 0) {
 		if (V.weatherAwareness > 0) {
 			if (V.antiWeatherFreeze === 0) {
-				node.append("The extreme weather hurts your arcology's ability to function. Reinforcing your passenger terminals increase the weather range at which they can operate.");
-				App.UI.DOM.appendNewElement("div", node, "");
-				node.append(
-					applyArcUpgrade("Reinforcing", "antiWeatherFreeze", 50000),
-					` passenger terminals costs ${cashFormat(arcUpgradeCost(50000))} and increases upkeep.`
+				div.append(
+					`The extreme weather hurts your arcology's ability to function. Reinforcing your passenger terminals increase the weather range at which they can operate.`,
+					makePurchase(`Reinforce the passenger terminals`, 50000 * V.upgradeMultiplierArcology, "capEx", {
+						notes: [`increases upkeep`],
+						handler: () => {
+							V.antiWeatherFreeze++;
+							V.PC.skill.engineering++;
+						}
+					}),
 				);
 			} else if (V.antiWeatherFreeze === 1) {
-				node.append("You have reinforced your passenger terminals to function even during bad weather. You can invest into all-weather transportation to remain functional no matter what.");
-				App.UI.DOM.appendNewElement("div", node, "");
-				node.append(
-					applyArcUpgrade("Investing", "antiWeatherFreeze", 100000),
-					` in all-weather transportation costs ${cashFormat(arcUpgradeCost(100000))} and increases upkeep.`
+				div.append("You have reinforced your passenger terminals to function even during bad weather. You can invest in an all-weather transportation system that will remain operational, no matter the weather.");
+				div.append(
+					makePurchase(`Invest in a heavily-armored transportation system`, 100_000 * V.upgradeMultiplierArcology, "capEx", {
+						notes: [`increases upkeep`],
+						handler: () => {
+							V.antiWeatherFreeze++;
+							V.PC.skill.engineering++;
+						}
+					}),
 				);
 			} else if (V.antiWeatherFreeze === 2) {
-				App.UI.DOM.appendNewElement("div", node, "Your arcology's passenger terminals remain fully operational even during the most extreme weather.");
+				App.UI.DOM.appendNewElement("div", div, "Your arcology's passenger terminals remain fully operational during even the most extreme weather.");
 			}
-		}
-	} else {
-		App.UI.DOM.appendNewElement("h2", node, "Security");
-		if (!V.SecExp.buildings.propHub) {
-			node.append(applyArcUpgrade("Set up the propaganda Hub", "SecExp", 5000, "propHub"));
-			App.UI.DOM.appendNewElement("div", node, `Costs ${cashFormat(arcUpgradeCost(5000, "propHub"))}. Building specialized in the management of authority.`, ["detail", "indent"]);
 		} else {
-			node.append("The ", App.UI.DOM.passageLink("Propaganda Hub", "propagandaHub"), " is ready to manipulate reality on your command.");
+			div.append(`The weather outside the arcology is perfectly manageable, for the time being.`);
 		}
-		App.UI.DOM.appendNewElement("div", node, "");
 
-		if (!V.SecExp.buildings.secHub) {
-			node.append(applyArcUpgrade("Set up the security headquarters", "SecExp", 5000, "secHub"));
-			App.UI.DOM.appendNewElement("div", node, `Costs ${cashFormat(arcUpgradeCost(5000, "secHub"))}. Building specialized in the management of security and crime.`, ["detail", "indent"]);
-		} else {
-			node.append("The ", App.UI.DOM.passageLink("security HQ", "securityHQ"), " is constantly working to protect your arcology.");
+		return div;
+	}
+
+	function sexualServices() {
+		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+
+		const societyClasses = ["lower", "middle", "upper", "top"];
+
+		App.UI.DOM.appendNewElement("h2", div, "Sexual Service Policies");
+		App.UI.DOM.appendNewElement("div", div, "If so desired, your assistant can help you manipulate the business environment within your arcology.");
+		App.UI.DOM.appendNewElement("div", div, "Breakdown of sexual services supplied by outside parties per societal class.");
+
+		for (const s of societyClasses) {
+			const classType = s === "top" ? `millionaires` : `${s} class`;
+			App.UI.DOM.appendNewElement("div", div, `${capFirstChar(classType)}: ${V.NPCMarketShare[s + "Class"]/10}%`);
 		}
-		App.UI.DOM.appendNewElement("div", node);
+		App.UI.DOM.appendNewElement("div", div);
 
-		if (!V.SecExp.buildings.barracks) {
-			node.append(applyArcUpgrade("Set up the barracks", "SecExp", 5000, "barracks"));
-			App.UI.DOM.appendNewElement("div", node, `Costs ${cashFormat(arcUpgradeCost(5000))}. Building specialized in the management of armed forces.`, ["detail", "indent"]);
-		} else {
-			node.append("The ", App.UI.DOM.passageLink("barracks", "secBarracks"), " patiently await your orders.");
+		for (const s of societyClasses) {
+			App.UI.DOM.appendNewElement("div", div, societalView(s, "policies"));
 		}
-		App.UI.DOM.appendNewElement("div", node);
 
-		if (!V.SecExp.buildings.riotCenter && V.SecExp.settings.rebellion.enabled === 1) {
-			node.append(applyArcUpgrade("Set up the control center", "SecExp", 5000, "riotCenter"));
-			App.UI.DOM.appendNewElement("div", node, `Costs ${cashFormat(arcUpgradeCost(5000))}. Building specialized in the management and suppression of rebellions.`, ["detail", "indent"]);
-		} else if (V.SecExp.settings.rebellion.enabled === 1) {
-			node.append("The ", App.UI.DOM.passageLink("Riot Control Center", "riotControlCenter"), " stands ready for action.");
+		div.append(rent());
+
+		return div;
+
+		function rent() {
+			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+
+			const asPercentage = (v) => Math.trunc((v / (V.ACitizens + V.ASlaves)) * 1000) / 10;
+
+			App.UI.DOM.appendNewElement("h2", div, "Population and Rent");
+			App.UI.DOM.appendNewElement("div", div, `${arcologyName} is home to the following:`);
+
+			for (const s of societyClasses) {
+				App.UI.DOM.appendNewElement("div", div, societalView(s, "rent"));
+			}
+
+			App.UI.DOM.appendNewElement("div", div, `Slaves | ${num(V.ASlaves)} | ${asPercentage(V.ASlaves)}%`);
+
+			return div;
 		}
-	}
 
-	if (V.difficultySwitch === 1 && (V.econWeatherDamage > 0 || V.disasterResponse > 0)) {
-		App.UI.DOM.appendNewElement("h2", node, "Disaster Response");
-		if (V.econWeatherDamage > 0) {
-			node.append(
-				"The recent terrible weather has damaged the local infrastructure. It is ",
-				App.UI.DOM.makeElement("span", `reducing the local economy score by ${num(V.econWeatherDamage)}.`, "warning")
-			);
-			if (V.disasterResponse === 0) {
-				node.append(" Locals will do their best to repair the damage on their own, but setting up a disaster response unit will improve the recovery of infrastructure critical for keeping goods, people and information flowing smoothly in and out of your arcology.");
-				App.UI.DOM.appendNewElement("div", node);
-				node.append(
-					applyArcUpgrade(" Creating the unit", "disasterResponse", 50000),
-					` will cost ${cashFormat(arcUpgradeCost(50000))} and incur upkeep.`
-				);
-			} else if (V.disasterResponse === 1) {
-				node.append(" You are sending your disaster response unit to repair critical infrastructure. They are doing what they can.");
-				App.UI.DOM.appendNewElement("div", node);
-				node.append(
-					`The unit can be made more effective with an additional investment of ${cashFormat(arcUpgradeCost(100000))}. This will also increase upkeep.`,
-					applyArcUpgrade(" Improve the Disaster Response Unit", "disasterResponse", 100000),
+		function societalView(s, type) {
+			const frag = new DocumentFragment();
+
+			const classType = s === "top" ? "Millionaires" : `${capFirstChar(s)} Class`;
+			const calRent = (v) => Math.trunc(V.rent[v] * (1 + (5 - V.baseDifficulty) / 20) / 0.25) / 100;
+			const classStr = s + "Class";
+			function link(text, type, value, value2 = 0, value3 = 0) {
+				return App.UI.DOM.link(`${text}`, () => {
+					if (type !== "rent") {
+						V[type][classStr] = value;
+						if (type === "sexSupplyBarriers") {
+							repX(-1000, "subsidiesAndBarriers");
+						}
+					} else {
+						V.rent[classStr] = V.rentDefaults[classStr] * value;
+						if (s === "lower") {
+							V.rentEffectL = value2;
+						} else if (s === "middle") {
+							V.rentEffectM = value2;
+						} else if (s === "upper") {
+							V.rentEffectU = value2;
+						} else if (s === "top") {
+							V.rentEffectT = value2;
+						}
+						V.whoreBudget[classStr] *= value3;
+					}
+
+					App.UI.reload();
+				});
+			}
+
+			let choices = [];
+
+			if (type === "policies") {
+				if (V.sexSubsidies[classStr] === 0) {
+					frag.append(`You can provide a minor subsidy for those selling sexual services to the ${classType}. `);
+					choices.push(link(`Minor Subsidy`, "sexSubsidies", 1));
+				} else if (V.sexSubsidies[classStr] === 1) {
+					frag.append(`You are providing a minor subsidy for those selling sexual services to the ${classType}. `);
+					choices.push(link(`Cancel Subsidy`, "sexSubsidies", 0));
+					choices.push(link(`Moderate Subsidy`, "sexSubsidies", 2));
+				} else if (V.sexSubsidies[classStr] === 2) {
+					frag.append(`You are providing a moderate subsidy for those selling sexual services to the ${classType}. `);
+					choices.push(link(`Minor Subsidy`, "sexSubsidies", 1));
+					choices.push(link(`Substantial Subsidy`, "sexSubsidies", 3));
+				} else if (V.sexSubsidies[classStr] === 3) {
+					frag.append(`You are providing a substantial subsidy for those selling sexual services to the ${classType}. `);
+					choices.push(link(`Moderate Subsidy`, "sexSubsidies", 2));
+					choices.push(link(`Gratuitous Subsidy`, "sexSubsidies", 4));
+				} else {
+					frag.append(`You are providing a gratuitous subsidy for those selling sexual services to the ${classType}. `);
+					choices.push(link(`Substantial Subsidy`, "sexSubsidies", 3));
+				}
+
+				App.UI.DOM.appendNewElement("span", frag, "Upkeep is relative to the amount provided by other parties. ", ['note']);
+				App.UI.DOM.appendNewElement("span", frag, App.UI.DOM.generateLinksStrip(choices));
+				App.UI.DOM.appendNewElement("div", frag);
+
+				choices = [];
+				if (V.sexSupplyBarriers[classStr] === 0) {
+					frag.append(
+						`Alternatively administrative "accidents" can happen if you are willing to spend ${num(1000)} reputation and pay a flat upkeep of`,	// TODO: the actual effects of this aren't clear to the player
+						App.UI.DOM.makeElement("span", ` ${cashFormat(1000)}. `, ['cash'])
+					);
+					choices.push(link(`Create Bureaucracy`, "sexSupplyBarriers", 1));
+				} else if (V.sexSupplyBarriers[classStr] === 1) {
+					frag.append(
+						`You have forced some unneeded bureaucracy, making things a little more difficult.
+						If you are willing to spend ${num(1000)} reputation you can change this policy.
+						Increasing the bureaucracy further will cost a flat upkeep of`,
+						App.UI.DOM.makeElement("span", ` ${cashFormat(5000)}. `, ['cash'])
+					);
+					choices.push(link(`Abolish Bureaucracy`, "sexSupplyBarriers", 0));
+					choices.push(link(`Increase Bureaucracy`, "sexSupplyBarriers", 2));
+				} else if (V.sexSupplyBarriers[classStr] === 2) {
+					frag.append(
+						`You have forced considerable bureaucracy, making things a little more difficult.
+						If you are willing to spend ${num(1000)} reputation you can change this policy.
+						Increasing the bureaucracy further will cost a flat upkeep of`,
+						App.UI.DOM.makeElement("span", ` ${cashFormat(20000)}. `, ['cash'])
+					);
+					choices.push(link(`Reduce Bureaucracy`, "sexSupplyBarriers", 1));
+					choices.push(link(`Increase Bureaucracy`, "sexSupplyBarriers", 3));
+				} else if (V.sexSupplyBarriers[classStr] === 3) {
+					frag.append(
+						`You have forced stifling bureaucracy, making things a little more difficult.
+						If you are willing to spend ${num(1000)} reputation you can change this policy.
+						Increasing the bureaucracy further will cost a flat upkeep of`,
+						App.UI.DOM.makeElement("span", ` ${cashFormat(60000)}. `, ['cash'])
+					);
+					choices.push(link(`Reduce Bureaucracy`, "sexSupplyBarriers", 2));
+					choices.push(link(`Increase Bureaucracy`, "sexSupplyBarriers", 4));
+				} else {
+					frag.append(
+						`You have forced suffocating bureaucracy, making things a little more difficult.
+						If you are willing to spend ${num(1000)} reputation you can change this policy.`
+					);
+					choices.push(link(`Reduce Bureaucracy`, "sexSupplyBarriers", 3));
+				}
+			} else if (type === "rent") {
+				const asPercentage = (v) => Math.trunc((v / (V.ACitizens + V.ASlaves)) * 1000) / 10;
+
+				frag.append(
+					`${classType} | ${num(V[classStr])} | ${asPercentage(V[classStr])}% | Rent: `,
+					App.UI.DOM.makeElement("span", `${cashFormat(calRent(classStr))} `, ['cash'])
 				);
+
+				if (V.rent[classStr] > V.rentDefaults[classStr] * 1.5) {
+					frag.append(`Very High. `);
+					choices.push(link(`Decrease`, "rent", 1.5, 0.94, 9 / 8));
+				} else if (V.rent[classStr] > V.rentDefaults[classStr]) {
+					frag.append(`High. `);
+					choices.push(link(`Increase`, "rent", 2, 0.85, 8 / 9));
+					choices.push(link(`Decrease`, "rent", 1, 1, 10 / 9));
+				} else if (V.rent[classStr] > V.rentDefaults[classStr] * 0.5) {
+					frag.append(`Average. `);
+					choices.push(link(`Increase`, "rent", 1.5, 0.94, 9 / 8));
+					choices.push(link(`Decrease`, "rent", 0.5, 1.04, 11 / 10));
+				} else if (V.rent[classStr] > 0) {
+					frag.append(`Low. `);
+					choices.push(link(`Increase`, "rent", 1, 1, 10 / 11));
+					choices.push(link(`Free Rent`, "rent", 0, 1.1, 12 / 11));
+				} else {
+					frag.append(`Free. `);
+					choices.push(link(`Increase`, "rent", 0.5, 1.04, 11 / 12));
+				}
+			}
+
+			if (type === "policies" && V.rep > 1000 || type === "rent") {
+				App.UI.DOM.appendNewElement("span", frag, App.UI.DOM.generateLinksStrip(choices));
 			} else {
-				App.UI.DOM.appendNewElement("div", node, "Your highly capable disaster response unit is rapidly repairing the weather damage.");
+				App.UI.DOM.appendNewElement("div", frag, `You are not reputable enough.`);
 			}
-		} else if (V.disasterResponse > 0) {
-			App.UI.DOM.appendNewElement("div", node, "Your disaster response unit is idle. It will not cost you any upkeep this week.");
+
+			return frag;
 		}
 	}
-	if (V.mods.food.market) {
-		App.UI.DOM.appendNewElement("h2", node, "Food Management");
-		node.append(App.UI.foodMarket());
-	} else if (V.eventResults.foodCrisis) {
-		const div = document.createElement("div");
 
+	function language() {
+		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+
+		App.UI.DOM.appendNewElement("h2", div, "Language");
 		div.append(
-			`You can set up the food market for your citizens again, if you'd like.`,
-			App.UI.DOM.makeElement("div", App.UI.DOM.link(`Set it up`, () => {
-				V.mods.food.market = true;
-				repX(6500, "food");
-				App.UI.reload();
-			}), ['indent']),
+			`The lingua franca of the arcology is `,
+			App.UI.DOM.makeElement("span", `${V.language}.`, ["strong"]),
+			App.UI.DOM.makeElement("div", App.UI.DOM.link(`Language options`, () => {
+				V.seed = V.language;
+			}, [], "Change Language"), ['indent']),
 		);
 
-		node.append(div);
-	}
-	const SocietyClasses = ["lower", "middle", "upper", "top"];
-	App.UI.DOM.appendNewElement("h2", node, "Sexual Service Policies");
-	App.UI.DOM.appendNewElement("div", node, "If so desired, your assistant can help you manipulate the business environment within your arcology.");
-	App.UI.DOM.appendNewElement("div", node, "Breakdown of sexual services supplied by outside parties per societal class.");
-	for (const s of SocietyClasses) {
-		const classType = s === "top" ? "millionaires" : `${s} class`;
-		App.UI.DOM.appendNewElement("div", node, `${capFirstChar(classType)}: ${V.NPCMarketShare[s + "Class"]/10}%`);
-	}
-	App.UI.DOM.appendNewElement("p", node);
-	for (const s of SocietyClasses) {
-		App.UI.DOM.appendNewElement("p", node, societalView(s, "policies"));
+		return div;
 	}
 
-	App.UI.DOM.appendNewElement("h2", node, "Population and Rent");
-	App.UI.DOM.appendNewElement("div", node, `${arcName} is home to the following:`);
-	for (const s of SocietyClasses) {
-		App.UI.DOM.appendNewElement("div", node, societalView(s, "rent"));
-	}
-	App.UI.DOM.appendNewElement("div", node, `Slaves | ${num(V.ASlaves)} | ${asPercentage(V.ASlaves)}%`);
-
-	App.UI.DOM.appendNewElement("h2", node, "Language");
-	node.append("The lingua franca of the arcology is ", App.UI.DOM.makeElement("span", `${V.language}`, "strong"), ". ");
-	node.append(
-		App.UI.DOM.link("Language options", () => {
-			V.seed = V.language;
-		}, [], "Change Language")
-	);
+	function upgrades() {
+		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+
+		App.UI.DOM.appendNewElement("h2", div, "Special Arcology Upgrades");
 
-	App.UI.DOM.appendNewElement("h2", node, "Special Arcology Upgrades");
-	if (V.personalArms === 0 && V.mercenaries === 0 && V.assistant.personality <= 0) {
-		App.UI.DOM.makeElement("div", `${arcName} has no special upgrades.`, "note");
-	} else {
-		if (V.personalArms > 0) {
-			r = [];
-			r.push(`You own a prototype powered exoskeleton that mounts armor and a smart mortar system, and has rifles mounted into its forearms.`);
-			if (V.personalArms > 1) {
-				r.push(`Furthermore, your security drones can rearm with small-caliber guns if necessary.`);
+		if (V.personalArms === 0 && V.mercenaries === 0 && V.assistant.personality <= 0) {
+			div.append(`${arcologyName} has no special upgrades.`);
+		} else {
+			if (V.personalArms > 0) {
+				const text = [];
+
+				text.push(`You own a prototype powered exoskeleton that mounts armor and a smart mortar system, and has rifles mounted into its forearms.`);
+				if (V.personalArms > 1) {
+					text.push(`Furthermore, your security drones can rearm with small-caliber guns if necessary.`);
+				}
+
+				App.UI.DOM.appendNewElement("div", div, text.join(' '));
 			}
-			App.UI.DOM.appendNewElement("div", node, r.join(" "), "indent");
-		}
 
-		if (V.mercenaries > 0) {
-			r = [];
-			if (V.mercenaries.isBetween(1, 5)) {
-				r.push(`A ${V.mercenaries === 1 ? "squad" : "full platoon"} of mercenaries is permanently quartered in ${arcName}.`);
-			} else if (V.mercenaries >= 5) {
-				r.push(`You have permanently settled a full company of mercenaries in ${arcName} as your ${V.mercenariesTitle}.`);
+			if (V.mercenaries > 0) {
+				const text = [];
+
+				if (V.mercenaries.isBetween(1, 5)) {
+					text.push(`A ${V.mercenaries === 1 ? `squad` : `full platoon`} of mercenaries is permanently quartered in ${arcologyName}.`);
+				} else if (V.mercenaries >= 5) {
+					text.push(`You have permanently settled a full company of mercenaries in ${arcologyName} as your ${V.mercenariesTitle}.`);
+				}
+
+				text.push(`They are grim men and women${V.mercenaries < 5 ? `, heavily armed and armored` : ` who appreciate their luxurious life here and train hard to keep their skills with their prototype armor sharp`}.`);
+
+				App.UI.DOM.appendNewElement("div", div, text.join(' '));
 			}
-			r.push(`They are grim men and women${V.mercenaries < 5 ? ", heavily armed and armored" : " who appreciate their luxurious life here and train hard to keep their skills with their prototype armor sharp"}.`);
-			App.UI.DOM.appendNewElement("div", node, r.join(" "), "indent");
 		}
 
 		if (V.assistant.personality > 0) {
-			r = [];
+			const text = [];
+
 			const {hisA, heA} = getPronouns(assistant.pronouns().main).appendSuffix("A");
-			r.push(`${capFirstChar(V.assistant.name)} is using an alternative personality setting, speaking in a sultry, sexual voice, and talking as though the penthouse's sex toys are ${hisA} body.`);
+
+			text.push(`${capFirstChar(V.assistant.name)} is using an alternative personality setting, speaking in a sultry, sexual voice, and talking as though the penthouse's sex toys are ${hisA} body.`);
+
 			if (V.assistant.personality > 1) {
-				r.push(`${heA} also has charge of all smart piercings in the arcology, and is using ${hisA} adaptations to sexual duties to improve their effectiveness.`);
+				text.push(`${heA} also has charge of all smart piercings in the arcology, and is using ${hisA} adaptations to sexual duties to improve their effectiveness.`);
 			}
-			App.UI.DOM.appendNewElement("div", node, r.join(" "), "indent");
+
+			App.UI.DOM.appendNewElement("div", div, text.join(' '));
 		}
+
+		return div;
 	}
 
-	App.UI.DOM.appendNewElement("h2", node, "Slaves");
-	r = [];
-	r.push(`Your slaves have participated in approximately ${num(V.oralTotal + V.vaginalTotal+ V.analTotal)} sexual encounters: ${num(V.oralTotal)} primarily oral, ${num(V.vaginalTotal)} vanilla, ${num(V.mammaryTotal)} mammary, ${num(V.analTotal)} anal, and ${num(V.penetrativeTotal)} with the slave penetrating another. They have produced about ${num(V.milkTotal)} liters of marketable milk, ${V.seeDicks !== 0 ? `about ${num(V.cumTotal)} deciliters of marketable cum,` : ``} and have given birth ${num(V.birthsTotal)} times.`);
-	if (V.abortionsTotal > 0 && V.miscarriagesTotal > 0) {
-		r.push(`They have had a total of ${num(V.abortionsTotal)} abortions and ${num(V.miscarriagesTotal)} miscarriages.`);
-	} else if (V.abortionsTotal > 0) {
-		r.push(`They have had a total of ${num(V.abortionsTotal)} abortions.`);
-	} else if (V.miscarriagesTotal > 0) {
-		r.push(`They have had a total of ${num(V.miscarriagesTotal)} miscarriages.`);
+	function records() {
+		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+
+		App.UI.DOM.appendNewElement("h2", div, "Records");
+
+		const total = V.oralTotal + V.vaginalTotal + V.analTotal;
+		const text = [];
+
+		if (total > 0) {
+			text.push(`Your slaves have participated in approximately ${num(total)} sexual encounters: ${num(V.oralTotal)} primarily oral, ${num(V.vaginalTotal)} vanilla, ${num(V.mammaryTotal)} mammary, ${num(V.analTotal)} anal, and ${num(V.penetrativeTotal)} with the slave penetrating another.`);
+		} else {
+			text.push(`Your slaves haven't had any sexual encounters yet.`);
+		}
+
+		if (V.milkTotal > 0 || V.birthsTotal > 0 || (V.cumTotal > 0 && V.seeDicks !== 0)) {
+			text.push(`They have produced about ${num(V.milkTotal)} liters of marketable milk, ${V.seeDicks !== 0 ? `about ${num(V.cumTotal)} deciliters of marketable cum,` : ``} and have given birth ${num(V.birthsTotal)} times.`);
+		}
+
+		if (V.abortionsTotal > 0 && V.miscarriagesTotal > 0) {
+			text.push(`They have had a total of ${num(V.abortionsTotal)} abortions and ${num(V.miscarriagesTotal)} miscarriages.`);
+		} else if (V.abortionsTotal > 0) {
+			text.push(`They have had a total of ${num(V.abortionsTotal)} abortions.`);
+		} else if (V.miscarriagesTotal > 0) {
+			text.push(`They have had a total of ${num(V.miscarriagesTotal)} miscarriages.`);
+		}
+		if (V.fuckdollsSold > 0) { // FIXME: This never increases
+			text.push(`${V.fuckdollsSold} mindbroken arcade slaves have been converted into Fuckdolls and sold.`);
+		}
+
+		App.UI.DOM.appendNewElement("div", div, text.join(' '));
+
+		if (V.pitFightsTotal > 0 && V.pitKillsTotal > 0) {
+			App.UI.DOM.appendNewElement("div", div, `${arcologyName} has hosted ${numberWithPluralOne(V.pitFightsTotal, "pit fight")}, and ${numberWithPluralOne(V.pitKillsTotal, "slave")} slaves ${V.pitKillsTotal === 1 ? `has` : `have`} died in your pit.`);
+		} else if (V.pitFightsTotal > 0) {
+			App.UI.DOM.appendNewElement("div", div, `${arcologyName} has hosted ${numberWithPluralOne(V.pitFightsTotal, "pit fight")}.`);
+		}
+
+		return div;
 	}
-	if (V.fuckdollsSold > 0) { // TODO: This never increases.
-		r.push(`${V.fuckdollsSold} mindbroken arcade slaves have been converted into Fuckdolls and sold.`);
+
+	function foodMarket() {
+		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+
+		if (V.mods.food.enabled && V.mods.food.market) {
+			App.UI.DOM.appendNewElement("h2", div, "Food Management");
+			div.append(App.UI.foodMarket());
+		} else if (V.eventResults.foodCrisis) {
+			const price = V.PC.skill.trading >= 50 && ["capitalist", "entrepreneur", "business kid"].includes(V.PC.career) || V.PC.skill.trading >= 100 ? 112_500 : 150_000;
+
+			div.append(
+				`You can set up the food market for your citizens again, if you'd like.`,
+				makePurchase(`Set it up`, price, "capEx", {
+					handler: () => {
+						V.mods.food.market = true;
+						repX(6500, "food");
+						App.UI.reload();
+					}
+				}),
+			);
+		}
+
+		return div;
 	}
-	App.UI.DOM.appendNewElement("p", node, r.join(" "), "indent");
 
-	if (V.pitFightsTotal > 0 && V.pitKillsTotal > 0) {
-		App.UI.DOM.appendNewElement("p", node, `${arcName} has hosted ${numberWithPluralOne(V.pitFightsTotal, "pit fight")}, and ${numberWithPluralOne(V.pitKillsTotal, "slave")} slaves ${V.pitKillsTotal === 1 ? `has` : `have`} died in your pit.`, "indent");
-	} else if (V.pitFightsTotal > 0) {
-		App.UI.DOM.appendNewElement("p", node, `${arcName} has hosted ${numberWithPluralOne(V.pitFightsTotal, "pit fight")}.`, "indent");
+	function security() {
+		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+
+		App.UI.DOM.appendNewElement("h2", div, "Security");
+
+		const cost = 5000 * V.upgradeMultiplierArcology * V.HackingSkillMultiplier;
+
+		if (V.SecExp.buildings.propHub) {
+			const innerDiv = document.createElement("div");
+
+			innerDiv.append(`The `, App.UI.DOM.passageLink(`Propaganda Hub`, "propagandaHub"), ` is ready to manipulate reality on your command.`);
+
+			div.append(innerDiv);
+		} else {
+			App.UI.DOM.appendNewElement("div", div, `Building specialized in the management of authority.`, ["detail"]);
+			div.append(makePurchase(`Set up the propaganda hub`, cost, "capEx", {
+				notes: [`increases upkeep`],
+				handler: App.Mods.SecExp.propHub.init,
+			}));
+		}
+
+		if (V.SecExp.buildings.secHub) {
+			const innerDiv = document.createElement("div");
+
+			innerDiv.append(`The `, App.UI.DOM.passageLink(`security HQ`, "securityHQ"), ` is constantly working to protect your arcology.`);
+
+			div.append(innerDiv);
+		} else {
+			App.UI.DOM.appendNewElement("div", div, `Building specialized in the management of security and crime.`, ["detail"]);
+			div.append(makePurchase(`Set up the security headquarters`, cost, "capEx", {
+				notes: [`increases upkeep`],
+				handler: App.Mods.SecExp.secHub.init,
+			}));
+		}
+
+		if (V.SecExp.buildings.barracks) {
+			const innerDiv = document.createElement("div");
+
+			innerDiv.append(`The `, App.UI.DOM.passageLink(`barracks`, "secBarracks"), ` patiently await your orders.`);
+
+			div.append(innerDiv);
+		} else {
+			App.UI.DOM.appendNewElement("div", div, `Building specialized in the management of armed forces.`, ["detail"]);
+			div.append(makePurchase(`Set up the barracks`, cost, "capEx", {
+				notes: [`increases upkeep`],
+				handler: App.Mods.SecExp.barracks.init,
+			}));
+		}
+
+		if (V.SecExp.buildings.riotCenter && V.SecExp.settings.rebellion.enabled === 1) {
+			const innerDiv = document.createElement("div");
+
+			innerDiv.append(`The `, App.UI.DOM.passageLink(`Riot Control Center`, "riotControlCenter"), ` stands ready for action.`);
+
+			div.append(innerDiv);
+		} else if (V.SecExp.settings.rebellion.enabled === 1) {
+			App.UI.DOM.appendNewElement("div", div, `Building specialized in the management and suppression of rebellions.`, ["detail"]);
+			div.append(makePurchase(`Set up the control center`, cost, "capEx", {
+				notes: [`increases upkeep`],
+				handler: App.Mods.SecExp.riotCenter.init,
+			}));
+		}
+
+		return div;
 	}
 
-	if (V.secExpEnabled > 0) {
+	function military() {
+		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+
 		const victories = (x) => V.SecExp[x].victories;
 		const losses = (x) => V.SecExp[x].losses;
 		const count = (x) => victories(x) + losses(x);
 		const SF = V.SF.Toggle && V.SF.Active >= 1 ? V.SF.ArmySize : 0;
-		App.UI.DOM.appendNewElement("h2", node, "Military");
-		r = [];
+		const unitsLost = Array.from(App.Mods.SecExp.unit.list().keys()).slice(1).reduce((acc, cur) => acc + V.SecExp.units[cur].dead, 0);
+
+		App.UI.DOM.appendNewElement("h2", div, "Military");
+
+		const text = [];
+
+		text.push(`Your army counts ${num(App.Mods.SecExp.unit.squads("human").reduce((acc, s) => acc + s.troops, 0) + SF)} total soldiers${(V.SF.Toggle && V.SF.Active >= 1) ? ` of which ${num(V.SF.ArmySize)} under the special force command and the rest under your direct control` : ``}.`);
 
-		r.push(`Your army counts ${num(App.SecExp.unit.squads("human").reduce((acc, s) => acc + s.troops, 0) + SF)} total soldiers${(V.SF.Toggle && V.SF.Active >= 1) ? ` of which ${num(V.SF.ArmySize)} under the special force command and the rest under your direct control` : ``}.`);
 		if (V.SecExp.settings.battle.enabled === 1 && count('battles') > 0) {
-			r.push(`Your troops were involved in ${num(count('battles'))} battles of which ${num(V.SecExp.battles.major)} were major engagements.`);
-			r.push("You won");
+			text.push(`Your troops were involved in ${num(count('battles'))} battles, of which ${num(V.SecExp.battles.major)} were major engagements. You won`);
+
 			if (count('battles') === victories('battles')) {
-				r.push(`all of them.`);
+				text.push(`all of them.`);
 			} else if (count('battles') === losses('battles')) {
-				r.push(`none of them.`);
+				text.push(`none of them.`);
 			} else {
-				r.push(`${num(victories('battles'))} of them, while the enemy managed to gain the upper hand in the other ${num(losses('battles'))}.`);
+				text.push(`${num(victories('battles'))} of them, while the enemy managed to gain the upper hand in the other ${num(losses('battles'))}.`);
 			}
-			r.push(`You lost a total of ${num(Array.from(App.SecExp.unit.list().keys()).slice(1).reduce((acc, cur) => acc + V.SecExp.units[cur].dead, 0))} men, while scoring a total of ${num(V.SecExp.core.totalKills)} kills.`);
+
+			text.push(`You lost a total of ${num(unitsLost)} men, while scoring a total of ${num(V.SecExp.core.totalKills)} kills.`);
 		}
+
 		if (V.SecExp.settings.rebellion.enabled === 1 && count('rebellions') > 0) {
-			r.push(`Your arcology was involved in ${num(count('rebellions'))} rebellions. You won ${num(victories('rebellions'))} of them, while the rebels defeated your forces in ${num(losses('rebellions'))}.`);
+			text.push(`Your arcology was involved in ${numberWithPluralOne(count('rebellions'), "rebellion")}${count('rebellions') > 1
+				? `. You won ${num(victories('rebellions'))} of them, while the rebels defeated your forces in ${num(losses('rebellions'))}`
+				: `, which you ${victories('rebellions') === 1 ? `won` : `lost`}`
+			}.`);
 		}
-		App.UI.DOM.appendNewElement("p", node, r.join(" "), "indent");
+
+		App.UI.DOM.appendNewElement("div", div, text.join(' '));
+
+		return div;
 	}
 
-	if (V.experimental.dinnerParty === 1 && V.seeExtreme === 1) {
-		App.UI.DOM.appendNewElement("p", node, App.UI.DOM.passageLink("Host Dinner Party", "Dinner Party Preparations"), "indent");
+	function events() {
+		const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+
+		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.passageLink(`Host Dinner Party`, "Dinner Party Preparations"), ['indent']);
+
+		return div;
 	}
-	return node;
 };
diff --git a/src/arcologyBuilding/apartments.js b/src/arcologyBuilding/apartments.js
index a5bf336b73e7c71c4ea8633c968fd8dbfc1eb35b..2ea2c7ebb8a98c8f65a266cbd551698739ec4e64 100644
--- a/src/arcologyBuilding/apartments.js
+++ b/src/arcologyBuilding/apartments.js
@@ -93,19 +93,19 @@ App.Arcology.Cell.Apartment = class extends App.Arcology.Cell.BaseCell {
 
 		if (this.type !== 3) {
 			fragment.append(this._makeInternalUpgrade(
-				"Upgrade this sector of apartments for dense occupancy by as many citizens as possible.",
+				`Upgrade this sector of apartments for dense occupancy by as many citizens as possible`,
 				() => { this.type = 3; }, cost, containingBuilding));
 		}
 
 		if (this.type !== 1) {
 			fragment.append(this._makeInternalUpgrade(
-				"Improve this sector of apartments for occupancy by the Free Cities' wealthiest citizens.",
+				`Improve this sector of apartments for occupancy by the Free Cities' wealthiest citizens`,
 				() => { this.type = 1; }, cost, containingBuilding));
 		}
 
 		if (this.type !== 2) {
 			fragment.append(this._makeInternalUpgrade(
-				"Return this sector to standard, mixed housing.",
+				`Return this sector to standard, mixed housing`,
 				() => { this.type = 2; }, cost, containingBuilding));
 		}
 
diff --git a/src/arcologyBuilding/manufacturing.js b/src/arcologyBuilding/manufacturing.js
index d2d3f887750a35553c2a87e12bbd64cceac5a08b..bbff45144b68e4d0babd28d92b6cf1111cd6a121 100644
--- a/src/arcologyBuilding/manufacturing.js
+++ b/src/arcologyBuilding/manufacturing.js
@@ -70,7 +70,7 @@ App.Arcology.Cell.Manufacturing = class extends App.Arcology.Cell.BaseCell {
 			case "Weapon Manufacturing":
 				return App.UI.DOM.passageLink("Weapons Manufacturing", "Weapons Manufacturing");
 			default:
-				return App.UI.DOM.makeElement("span", `ERROR: invalid type: ${this.type}`, "error");
+				return App.UI.DOM.makeElement("span", `ERROR: invalid type: ${this.type}`, ["error"]);
 		}
 	}
 
@@ -194,49 +194,49 @@ App.Arcology.Cell.Manufacturing = class extends App.Arcology.Cell.BaseCell {
 
 			if (V.dairy === 0) {
 				fragment.append(thisCell._makeExternalUpgrade(
-					"Construct a dairy to milk slaves on an industrial scale",
+					`Construct a dairy to milk slaves on an industrial scale`,
 					() => {
 						V.dairy = 5;
 						thisCell.type = "Dairy";
-					}, cost, "Dairy", "and will incur upkeep costs"
+					}, cost, "Dairy", [`will incur upkeep costs`]
 				));
 			}
 
 			if (V.farmyard === 0) {
 				fragment.append(thisCell._makeExternalUpgrade(
-					"Construct a farming facility to grow food for your arcology and house animals",
+					`Construct a farming facility to grow food for your arcology and house animals`,
 					() => {
 						V.farmyard = 5;
 						thisCell.type = "Farmyard";
-					}, cost, "Farmyard", "and will incur upkeep costs"
+					}, cost, "Farmyard", [`will incur upkeep costs`]
 				));
 			}
 
 			if (V.mercenaries) {
 				if (V.barracks !== 1) {
 					fragment.append(thisCell._makeExternalUpgrade(
-						"Build an armory to properly house your mercenaries",
+						`Build a barracks to properly house your mercenaries`,
 						() => {
 							V.barracks = 1;
 							thisCell.type = "Barracks";
-						}, cost, "Barracks", "but will reduce mercenary upkeep"
+						}, cost, "Barracks", [`will reduce mercenary upkeep`]
 					));
 				}
 			}
 
 			if (V.secExpEnabled > 0 && !V.SecExp.buildings.weapManu) {
 				fragment.append(thisCell._makeExternalUpgrade(
-					"Convert this sector to weapons manufacturing",
+					`Convert this sector to weapons manufacturing`,
 					() => {
-						App.SecExp.weapManu.Init();
+						App.Mods.SecExp.weapManu.Init();
 						thisCell.type = "Weapon Manufacturing";
-					}, cost, "Weapons Manufacturing", "but will provide a weekly income and will unlock upgrades for our troops"
+					}, cost, "Weapons Manufacturing", [`will provide a weekly income`]
 				));
 			}
 
 			if (thisCell.type !== "Pens") {
 				fragment.append(thisCell._makeInternalUpgrade(
-					"Convert to pens to increase the number of menial slaves you can house",
+					`Convert to pens to increase the number of menial slaves you can house`,
 					() => {
 						thisCell.type = "Pens";
 					}, cost, containingBuilding
@@ -245,7 +245,7 @@ App.Arcology.Cell.Manufacturing = class extends App.Arcology.Cell.BaseCell {
 
 			if (thisCell.type !== "Sweatshops") {
 				fragment.append(thisCell._makeInternalUpgrade(
-					"Convert these facilities to use the labor of menial slaves",
+					`Convert these facilities to use the labor of menial slaves`,
 					() => {
 						thisCell.type = "Sweatshops";
 					}, cost, containingBuilding
@@ -254,7 +254,7 @@ App.Arcology.Cell.Manufacturing = class extends App.Arcology.Cell.BaseCell {
 
 			if (thisCell.type !== "Manufacturing") {
 				fragment.append(thisCell._makeInternalUpgrade(
-					"Return this sector to standard manufacturing",
+					`Return this sector to standard manufacturing`,
 					() => {
 						thisCell.type = "Manufacturing";
 					}, cost, containingBuilding
diff --git a/src/arcologyBuilding/markets.js b/src/arcologyBuilding/markets.js
index 402c9ffafca2973f65bf7aa85f311f57afce5ade..8ee82ef53fc1bb49d5ed1ea01db1730275aae0f9 100644
--- a/src/arcologyBuilding/markets.js
+++ b/src/arcologyBuilding/markets.js
@@ -65,7 +65,7 @@ App.Arcology.Cell.Market = class extends App.Arcology.Cell.BaseCell {
 					this._prepareCorporateMarket
 				);
 			default:
-				return App.UI.DOM.makeElement("span", "ERROR: invalid type: " + this.type, "error");
+				return App.UI.DOM.makeElement("span", "ERROR: invalid type: " + this.type, ["error"]);
 		}
 	}
 
@@ -93,17 +93,17 @@ App.Arcology.Cell.Market = class extends App.Arcology.Cell.BaseCell {
 		const cost = Math.trunc(10000 * V.upgradeMultiplierArcology);
 		if (V.arcade === 0) {
 			fragment.append(this._makeExternalUpgrade(
-				"Construct a sex arcade to present slaves' holes for public use",
+				`Construct a sex arcade to present slaves' holes for public use`,
 				() => {
 					this.type = "Arcade";
 					V.arcade = 10;
-				}, cost, "Arcade", "and will incur upkeep costs"
+				}, cost, "Arcade", [`will incur upkeep costs`]
 			));
 		}
 
 		if (!V.pit) {
 			fragment.append(this._makeExternalUpgrade(
-				"Build a pit to host proper slave fights",
+				`Build a pit to host proper slave fights`,
 				() => {
 					this.type = "Pit";
 					App.Facilities.Pit.init();
@@ -113,10 +113,10 @@ App.Arcology.Cell.Market = class extends App.Arcology.Cell.BaseCell {
 
 		if (V.secExpEnabled > 0 && !V.SecExp.buildings.transportHub) {
 			fragment.append(this._makeExternalUpgrade(
-				"Centralize and modernize the transport hub",
+				`Centralize and modernize the transport hub`,
 				() => {
 					this.type = "Transport Hub";
-					App.SecExp.transportHub.Init();
+					App.Mods.SecExp.transportHub.Init();
 				}, cost, "Transport Hub"
 			));
 		}
@@ -124,13 +124,13 @@ App.Arcology.Cell.Market = class extends App.Arcology.Cell.BaseCell {
 		const corpCost = Math.trunc(10000 * V.upgradeMultiplierArcology);
 		if (V.corp.Market === 0 && V.corp.Incorporated === 1) {
 			fragment.append(this._makeExternalUpgrade(
-				"Create a flagship slave market for your corporation here",
+				`Create a flagship slave market for your corporation here`,
 				() => {
 					this.type = "Corporate Market";
 					V.corp.Market = 1;
 					V.corp.Cash -= corpCost;
 					this._prepareCorporateMarket();
-				}, 0, "Market", ` Costs ${cashFormat(corpCost)} of the corporation's money`
+				}, 0, "Market", [`costs ${cashFormat(corpCost)} of the corporation's money`]
 			));
 		}
 
diff --git a/src/arcologyBuilding/penthouse.js b/src/arcologyBuilding/penthouse.js
index eb4a2de95c5cd8af3cc45737bbfb93ec18c8add4..dcebc2f01ab3c209806fcd8432d08322e93d7f1a 100644
--- a/src/arcologyBuilding/penthouse.js
+++ b/src/arcologyBuilding/penthouse.js
@@ -25,7 +25,7 @@ App.Arcology.Cell.Penthouse = class extends App.Arcology.Cell.BaseCell {
 		const fragment = document.createDocumentFragment();
 
 		const link = App.UI.DOM.passageLink("Penthouse", "Manage Penthouse");
-		const hotkey = App.UI.DOM.makeElement("span", App.UI.Hotkeys.hotkeys("Manage Penthouse"), "hotkey");
+		const hotkey = App.UI.DOM.makeElement("span", App.UI.Hotkeys.hotkeys("Manage Penthouse"), ["hotkey"]);
 		if (V.verticalizeArcologyLinks === 0) {
 			const div = document.createElement("div");
 			div.append(link, " ", hotkey);
@@ -69,7 +69,7 @@ App.Arcology.Cell.Penthouse = class extends App.Arcology.Cell.BaseCell {
 					(V.incubator.tanks.length + FetusGlobalReserveCount("incubator")), "empty tank")})`;
 
 				if (V.incubator.readySlaves > 0) {
-					wrapper.append(createFacilityDiv(link, App.UI.DOM.combineNodes(desc, App.UI.DOM.makeElement("span", "[!]", 								"noteworthy"))));
+					wrapper.append(createFacilityDiv(link, App.UI.DOM.combineNodes(desc, App.UI.DOM.makeElement("span", "[!]", ["noteworthy"]))));
 				} else {
 					wrapper.append(createFacilityDiv(link, desc));
 				}
diff --git a/src/arcologyBuilding/shops.js b/src/arcologyBuilding/shops.js
index 866362e4adbc68fd93428b6de35fc26889c7712e..1130c141be8e747ee7b56dbbb9e591be29f1f224 100644
--- a/src/arcologyBuilding/shops.js
+++ b/src/arcologyBuilding/shops.js
@@ -310,11 +310,11 @@ App.Arcology.Cell.Shop = class extends App.Arcology.Cell.BaseCell {
 				}
 				break;
 			default:
-				App.UI.DOM.appendNewElement("span", fragment, `ERROR: bad shop type: ${this.type}`, "error");
+				App.UI.DOM.appendNewElement("span", fragment, `ERROR: bad shop type: ${this.type}`, ["error"]);
 		}
 
 		if (this.owner === 1 && this.type === "Shops") {
-			fragment.append("You control this part of the arcology and all these businesses pay you rent.");
+			fragment.append(`You control this part of the arcology and all these businesses pay you rent.`);
 		}
 
 		return fragment;
@@ -331,21 +331,21 @@ App.Arcology.Cell.Shop = class extends App.Arcology.Cell.BaseCell {
 
 		if (V.brothel === 0) {
 			fragment.append(this._makeExternalUpgrade(
-				"Convert this sector of the promenade into a brothel.",
+				`Convert this sector of the promenade into a brothel`,
 				() => {
 					V.brothel = 5;
 					this.type = "Brothel";
-				}, cost, "Brothel", "and will incur upkeep costs"
+				}, cost, "Brothel", [`will incur upkeep costs`]
 			));
 		}
 
 		if (V.club === 0) {
 			fragment.append(this._makeExternalUpgrade(
-				"Build a club to serve as a focal point for public sluts.",
+				`Build a club to serve as a focal point for public sluts`,
 				() => {
 					V.club = 5;
 					this.type = "Club";
-				}, cost, "Club", "and will incur upkeep costs"
+				}, cost, "Club", [`will incur upkeep costs`]
 			));
 		}
 
diff --git a/src/art/artJS.js b/src/art/artJS.js
index c446fb9f40be347f4e449f86d1f829363efe6579..a476dacc99b162a7baf7be8d8b72161bbe30f47f 100644
--- a/src/art/artJS.js
+++ b/src/art/artJS.js
@@ -79,29 +79,34 @@ App.Art.SlaveArtBatch = class {
 			return App.Art.customArtElement(artSlave.custom.image, this._artSize);
 		}
 
-		const slaveData = this._slaveArtBatch.get(artSlave.ID);
-		if (slaveData) {
-			// perform "one of batch" rendering for supported formats
-			if (V.imageChoice === 1) { /* VECTOR ART BY NOX/DEEPMURK */
-				if (slaveData.displayClass) {
-					return App.Art.vectorArtElement(artSlave, this._artSize, slaveData.displayClass);
-				} else {
-					console.error(`Batch data unavailable for slave ID ${artSlave.ID}; ensure the slave ID is valid and preamble was written. Falling back to single-slave renderer.`);
-				}
-			} else if (V.imageChoice === 3) { /* VECTOR ART REVAMP*/
-				if (slaveData.displayClass) {
-					return App.Art.revampedVectorArtElement(artSlave, slaveData.displayClass);
-				} else {
-					console.error(`Batch data unavailable for slave ID ${artSlave.ID}; ensure the slave ID is valid and preamble was written. Falling back to single-slave renderer.`);
+		if (!V.seeCustomImagesOnly) {
+			const slaveData = this._slaveArtBatch.get(artSlave.ID);
+
+			if (slaveData) {
+				// perform "one of batch" rendering for supported formats
+				if (V.imageChoice === 1) { /* VECTOR ART BY NOX/DEEPMURK */
+					if (slaveData.displayClass) {
+						return App.Art.vectorArtElement(artSlave, this._artSize, slaveData.displayClass);
+					} else {
+						console.error(`Batch data unavailable for slave ID ${artSlave.ID}; ensure the slave ID is valid and preamble was written. Falling back to single-slave renderer.`);
+					}
+				} else if (V.imageChoice === 3) { /* VECTOR ART REVAMP*/
+					if (slaveData.displayClass) {
+						return App.Art.revampedVectorArtElement(artSlave, slaveData.displayClass);
+					} else {
+						console.error(`Batch data unavailable for slave ID ${artSlave.ID}; ensure the slave ID is valid and preamble was written. Falling back to single-slave renderer.`);
+					}
 				}
-			}
 
-			// or render directly for unsupported formats
+				// or render directly for unsupported formats
+				return App.Art.SlaveArtElement(artSlave, this._artSize, this._UIDisplay);
+			}
+			// definitely an error, but we can handle this...just redirect to the standard single-slave renderer
+			console.error(`Requested batch render of slave ID ${artSlave.ID} which was not present in the initialization vector. Falling back to single-slave renderer.`);
 			return App.Art.SlaveArtElement(artSlave, this._artSize, this._UIDisplay);
 		}
-		// definitely an error, but we can handle this...just redirect to the standard single-slave renderer
-		console.error(`Requested batch render of slave ID ${artSlave.ID} which was not present in the initialization vector. Falling back to single-slave renderer.`);
-		return App.Art.SlaveArtElement(artSlave, this._artSize, this._UIDisplay);
+
+		return new DocumentFragment();
 	}
 };
 
@@ -127,7 +132,7 @@ App.Art.SlaveArtElement = function(artSlave, artSize, UIDisplay) {
 		return App.Art.revampedVectorArtElement(artSlave);
 	} else if (imageChoice === 4) { /* Elohiem's Webgl */
 		return App.Art.webglArtElement(artSlave, artSize);
-	} else if (imageChoice === 0) { /* RENDERED IMAGES BY SHOKUSHU */
+	} else if (imageChoice === 5) { /* RENDERED IMAGES BY SHOKUSHU */
 		return App.Art.renderedArtElement(artSlave, artSize);
 	}
 };
diff --git a/src/art/assistantArt.js b/src/art/assistantArt.js
index 3a86b794378fd91b94028b61f3f16a7db51cd499..36b1339e1d90e1bd800b7cc02aa53902a4f5ce83 100644
--- a/src/art/assistantArt.js
+++ b/src/art/assistantArt.js
@@ -61,7 +61,7 @@ App.Art.assistantArt = function(size) {
 			default:
 				fileName = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARoAAAJaCAIAAAB/YR8cAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwAAADsABataJCQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4yMfEgaZUAACe5SURBVHja7d13eBR1wsBx/3tPDyF9S7Yn2U0vhISSntBCqCkkkIBIE4JAkI5yIqAgxYIUBURFxVPPhqe+3omeiNjOBhYsCFhAsb3SD/R4Jy4um93Z2dndWUiy388zz/u8F3Y3m9n5OmVnfnNJJgCFXMIsAMgJICeAnACQE0BOADkB5ASAnAByAsgJADkB5ASQE0BOAMgJICeAnACQE0BOADkB5ASAnAByAsgJADkB5ASQE0BOAMgJICeAnACQE0BOADkB5ASAnAByAsgJADkB5ASQE0BOAMgJICeAnACQE0BOADkB5ASAnAByAsgJICcA5ASQE0BOAMgJICeAnAByAkBOADkB5ASAnAByAsgJICcA5ASQE0BOAMgJICeAnAByAkBOADkB5ASAnAByAsgJICcA5ASQE0BOAMgJICeAnAByAkBOADkB5ASAnAByAsgJICcA5ASQE0BOAMgJICeAnAByAkBOADkB5ASQEwByAsgJICcA5ASQE0BOADkBICeAnAByAkBOADkB5ASQEwByAsgJICcA5ASQE0BOADkBICeAnAByAkBOADkB5ASQEwByAsgJICcA5ASQE0BOADkBICeAnAByAkBOADkB5ASQEwByAsgJICcA5ASQE0BOADkBICeAnAByAsgJADkB5ASQEy6iXmkLmQnkBCXEDxqXdjTbVsmcICcEql/CI30vOTsw6XFmBTkhUEJL9olZQU4ISK6twZFTr+iXmCHkBD+lWvOGW7515DQi4fs0Wz6zhZzgjy76yY6W7FMXwxRmCzkhoL0m54nZQk4gJ3LCRWxJvV00p37aHcwccoIPkg3lQ8KPieZUGXFc+FdmETlBrgzNRNGW7FNO2BpmETlBrkGqvRI5sQdFTpArPbFAuiVhykgqZEaRE7wrTprrNafSlGuZUeQE77y2xPYeOUHelp6xWmZOWZZaZhc5QcpQ63sycxqe/AGzi5zgUYZ+hMyW7FNn3dXMNHKCuELbbJ9yKg//mJlGTgjoIAQHJMgJXvTQLvcjp3zdSmYdOaGFVGtete5LP3IaavhaeC4zkJxwXlpsvR8t2ad0XQMzkJxwXpnhfr9z6mPewgwkJ/yxpaev9Lsl+yS8ArORnPD7qilyW4A5McgROV0IhqQsa+fWvqfu30GItnXEPMeal2LIIqe2TVO7SLNin6puaWt+k4G31MpzGhez5H7NvvG6m8ipbdOVNFyy+qx9Mg+eZupe0dreYUXsq4rkNNDwemv70wpNFXWmpq2XnLVP5foR5NS2CVt6+lu/chQVdedJ3fU7W9FBCFPF0Jj/KJJTrep0mrl/6/nTVul2bo066WjpYcPXOe39+7GQOBShGb7MkZPzZBrYFKTfmJyUIXO41i6W0Yq01Px9bsx/MuMHyfmlXRML0pMygvS31xqnOhJynhpjV3Aoor38nWI5CVPW6s8iZr6g/DpHO3yw+gs5jxSqq4j8RJGc5F/+9DfzoX5B2O5aGv7PhzI/FW1pa2icWxgqOSXVzvVUlH1KuOaR+IJBCubUvPVl/CbNWizn8f07/BxgS4WGW+X8ou62kkfNh4SFW8GcSuMH3RD/sKeK7NPGiD3k1H7oS0dI5yRM6o1nkpbvNhcPVSonYaozHZT1+MC+xu0edZfMN/Z4/GH78q1ITr3NQzfZ3n9OfUa6JWGqCo3rskLoa1zr0ve8FmWfwtcc01z3SkTVosBzEqbBnY7I2uqzFgvbh3601C1ppMx39UT4McfyHUhOo8IX3qre7vxq0tO9SbtDZZ8iM5TIzKnFKqvPBEPX8kByar4K3fKt3K2+qE/dg6mKPNGn04fuP69Tn+maKKuKbtbiv1m+dV7E/cgp31A+WD1BZkKhttdETnKnsNVHo2a9GEhO9ssoZK6jBsZ87v6FUlp0YyDrpS26L10WcV9zWha57fFOR/xoiZzaLWETzr+i7JNu4n26kgb/cmouSvaRCZetvuyoG4Uf1iS86/zDHimjZK6XtsQecF/EZeZUrmuYE3uvfxXZp1W6neTUPhkLqwPJyT4J+2CWklo/cvJpHeV+9lBx2D/Oj1mp3yzzT35Qu190Ka8weFmz9bHUbkh4N5CQ7FMvUw05sb3nfVKN3ejpt6RohklcPCtnHZWqrxzY8ReX2w3aX6G3dZ2cv7RrQtH9mn2elvL+xis8PXGWZlPgFYXgll4o5hQ2Yo2CRfmRU/MtbnNekbWOMlT16fSh89kVefolPa23yfxLb0l5XmIpl8hJwZamhK8lp3a9vdetX8Ta4xc3p+ZveLOeDeqfeVPyE9IL+gXI6anIEwXGfuTUzqnnbb/oOQlTfcqHwvonGH/gnKT1Xpf1C5DT7aF3l8QQvRq3NeRknxQvakHcX+Us6xcgp1BcrkIzp6gln7aSnAaHHU3rNFeRP6prQtEi0+Myl/Vg53Sfai85hQrDgCmtJCcF11Ebwj+Wv7hXez6JTpGc6kxN5BRCslZ/1npyCryoa40PKLUxFnhLj2TvDc2FKnRzipj5QqvKqXmrz9+ipsWtVnDfJvCclke9SE4ckLiYOUmvowqM/TxdP+v3t67Byyl0l6hQzilx5mNByilZXedfToM6HREtao3h9UFxY9x/frX+FsUX+gBbWpLyJDmFImvRkNaWk+gQX10TC55NPbIk+QmXn0+P2RCMdUiAOYlmT05s712cnPJVrqcCjrTNFg0gSJtkAb5sTgjfziPUc7r0undbW05p2uGelu9bVC87/3xT5CetLac1f34/pP/rHOI5xfQaL/f88b5XR9y4J9g5DdHsc79Z0/mh6jp/7vzzIdrGC5BTtWbKfaq9crf0VFeRU0gzLXxTTk5Rs5sP/iZ2KUgcOsdw+9dBysl9cK/1cW87L6+1xqmOf8q15T9iOhiknK7KXGA/c6JCfaXMF7zL8u9Q33cgp8iaxXJyMq8+5HzrAGNhtXnxW8rmVKP/yuV1hmgmSmcwxXib4jm5jC/ZFHmnzBccF7OEnCD3gIS2b6PMF/Qvpx7xM1xeZ93lu92X2isjFimyqyPzb+HrJnLycXtvUFOAxx78yGmY+ZDLkMjuI4zLGX1hY8Se4OW0qMOzMl9teNx0FiRyambLztff9pWCOaVa81xqcZ8ybGV1To8ZZHzD5UWuUt8sfllexHHny/Jq9JNdHjAj/B6lcrqp0/NyXmpD+Me58sZkJyf4w2XgIU/f1Tqqc3l6jjXvAQ+jpgjT5LA1zg9+IO1jlx0YL0t/wrs9jdV8RuTUZqSaKnKNUyu1+6VzSreVNMQfds+pt2aY/HVL37g6+w+n/TG6sqdn3dnxgyHaRj4dcmqrsiy1g1R7pc8kyra53ih6pvpu6Zy6JhW67GWNVy31tNP1eNjRmyNe4LMgp3axprLmpWqH58dskH/vTe9HpdPmOz++l7pO9OmbIj8ZopmYbyjnUyCnNmOg4fXa7vd3t45P9XbGWnHYP+xbgBKPGRw3JsBjCQ9d+sOt6u1lMi6g6m/OnptU8Y1x5k7deD5HcmoVCk3L7OucK2w/5huWJqtqJboS/kl4gMSrLU19Sk5OY6M93rnZ6+qo3JA1Pqb7a/qrTqvmnr1kijDdGNWTz5GcWoV0XYPrlUuqvV1Vft4uXu7wJskf+Pf62yIbjnSaZq/IMfEhklMrUmt7X/QIXvGf3vH1qnXHTc2kp8ny7jjoMEGd55KQY5piKOETJKdWpHOcxzMhqiJPVMS+Kv+leiSWem3pOuMDPqRu6f523GRPLf1gvTbfxgdITq2MnBPzsnVXp8q4wK7MULU16qTHc7c7fSjn/VSYOm+IGeypIsf0uqHFVRVXGPNGWwrt05i4wrHxxRLTPdpqr68fOhuTIZRT0qT1poVv2qeEpe+KTtal7yWv/EB0Sln5YcaqTzJXfeqY3G/53sv4gJyihpkPlcr4FqiPpdbTGT1dE4qcH7kitr97SDt1409GzZKzoFcZchxPXBheKjMPn6YNMYPIqV2JHbFCwXtniJ7Cl2EZUKs67ceAEGMvX/ak9QdhG8+9qKejT0nfAv2vcQ3u/+1/PGm0zAV9v3aq8xN3aMco3tLN6lD51iu0NvY6/GWXsjkJibr8iur4d/zLSUjliYTv3d9zb/NQ55Zc1kt3JdaJbkrJX9anx/VyPKvckHU8YrqyLe3qMJp9p3brsvnvKZnTLQecrylsPiARscjvnITpsbjvuttcD7KVxw97KvLEpqhPXX6+xTzc056JzGX9VPRsYbPQ8az5kSXKtrT78tAa1SjkckroUqRsUdE9x/lxQMJTTs3XX9h+HB252OU1C4z9XEYIWmWulNjRl7m4b1e3WHW8mzBV2ZaKEjiyFwr7URPuVWwFNflh15WJ5pVAcrJP7kU5u804SPq4mR9H2wZYcs6o5ynV0gPGOg6UhxDN8GWK5JS08Wdbdr4fKyjpnIRpUsc7RN/53epKr4eh5Szxv3RsarnpWK9US2sThobmQhXS3ztpr7pHkaLihkwPMKfZl24RPSbuMiyE4FbDIDnf6shZ6F+IaPDv6IX09EjCyJBdohi28t1gHDHP0jb6lJOQjadvbPs4jWI50tBD5pekvm7p1Vq6K9LSp1ETQ3lxCvWcEroUXb5gt+I5pdnyvY4V4fIUj7cJNI1yPGaUKU+pnDbrW2yPfZCswPHxz6IbQ+3YAzmJiJy1TbXhdCA5qedtd3nNEvMqBXJqefPzfsbOJyJnysnpk8iJEsv98YgZ/c3ZjgfXx3YNvKUv1JyTTk5/sPas9+34+NLPYssn6ctG2CdL3gD310zXNXia0mLr5eTkfvPz7eor5eSUb8scrs31NDl/1yTISEpx/tcJ6rx3/jTSp5b2a5uKrVksRaGS0wh9N68nTSf1GenTOkrfuFnBdyg6btH5JT4jQ2JD7rPoSQq+k7XhFT61dCC2SfoFhbXfCH13cmoPqo2571mbv508ZJ7t/Vhf7WKf1lHm0auUep851rw+2uFzdfe555SUlPTaa68J/9c9J2EXSFif5FkzlHobN0b19KmlL3XXSK+XakzntiTftzUJ/z85tUnCumi2rfwrfYs97H/mTvX6RMvYO3wqyjRimeJvfnnUi843Py8oKDh79qzwf+3/c6qx+aTvl6KVPx7t60lGRzpNq9R3kf5vmeg3vAWJWeTUBtiHQHjM2PB/ydeLLgE7u830upWvrVssf6svf9PB5Nwi0ddJtwwoi9zmPvWKfqmfdod9yvEw3kNPVW3aHzfDXbdunZDTXXfd5djVqVVli7/zhuUZqz6xT7l37Xef8m55IymnUPS5wiLuaaaJTt9a5ki3JMzn7+LmiH+DnLLgCfNI4ZMSPi9yaqX+GT78l45NXpeDrw3eR9NO6jtSTku2mtnup0Q4pNnyq2IPeLmhU/ix5N+HSUlOTi4uLhZ9nVOnTgk5nT59OitLZOErKjoXs6Fredjqo9JvOKFsuMRfPTwhf69qspyWDplnldg6S89Dl00DT2dmvBBRT06tyAR1j/cuG+XTVso3xhle11FJfUaqN54RuW/ahtMJS9/1YedN96V0UZ0vb94Bs1qthw8f3r9/f0NDQ0LCua9vhMZWrVp19g/r168XfmL/J+ExNTU1n3/++U8//WSzNR9mUfee4CX+3g0y3/PquKofbddJrJekny7MW2EO+3gdx5XC50hOF5Owa/umqdG/70mE/3b6sY4KX/yxpbjWpzeZbiuRc4ZESkrK7bffbs/mwIEDCxYsEFZWwg+Fxhw5/fjjj8JPCgsL58+fv2/fPvsPhU1B4YfCK7jfHNF50ozf5OvO5/S4Xu7zTdh+K03MDny9JDq9ZZ401NyNnC70YYYpBgWuzDkQO83r7zKPXtV8vOGOg7oRK+W8N1P3CvcfpuorB4cdlbof7u+3n+jatetvv/121onQz9mWXH4iPD4/v/m5wjan1PGS0beLvltN4TCJjVW7KkOOsJTb59iJyJle54AwVwP/aITPty2OBtPGcqoydHlFM/q7uLlKna/5UK73oU/1pSO8LnN2xoVvRK07ae0psjOQZqiSult78rlh+F9++eWzvnj77bftT0wc4HFLL3bCveLvtrBa+FfLmm9j5v5Ln18p/afVx3Ydby0dGJcr/bAtOeOV+mgOx8/doR0jfOLkFIzVUfFn0Y3BGBXEZewRXwmlud9tLa60TrQoT+uo/MxzBfbv3//XX3+V2ZLwyMrKcxmk9xkm2pJ1wjrRt20oqHJ5ZORNn1hKagP5mJ5KHR+MT+ez6EltZWXVBnJarq04aJoVpJDs09Gwa/z7r2D0nJcS7vzefSGOWf8fT0W5hFQe/nGm0x1iEhMTnXeWpP3www+O73abj5L3bQxb9JHz27BMfchTSxFrj4seZUlasTumzp9b3N7feUxQP6ND5lnuAzaRk1wj9N3mJQ8I6ifk30Bw1s55pt6jrNMf9XoYPb5smMiRCWO1sI6qMx3so3rZeXTY5OTk9PT0qqqqn376SWZOR48erampycjIcBzua04lv0rYeDOu+iZu5lMy10uiU+LQObHFcg9h35lef8E+pmtTBrTaU5ZaaU7vxE+5kCG9d9mo8TGyPiFLca2wpMo9TfauU8L+ifuLJBvKXUau7Ny58+bNm0+dOvXf//7Xp30n4fHCsx588MEuXbq4NO8yJowjNq/fTTlPxhvekDNb5oUVXsjPq/kjs04lJ+8u5EeyTzO13log512FVy1UX7s9fM0xP67dUA3zOPC/sDqaOHHia6+9Jn9/yZPffvvtrbfemjRpkvPJsq5/ReVCvwdsipj5gtfDFQWJWdelDrrAXZGTd/aTVoM0/Zz0F/mDGXj9blTOZOgqPm5jaWnp008/ffr0aV9XSqKrqTNnzjz33HNlZWUeP+yA/5AOf9kV02t8UqqXM25rLd0+Sp0V5LVTE2snn/adul+bMjAYn8TXhukrdQPkvAdhxaLMYBL5Az39ipSUFGE7bebMmV999ZXfLR06dGj27Nk5OTn273M9HjhZ+pkygzd526eqNua+brgqSCF9Ejnxal0h+05+Ehb9by2zg/HB7L58tPDBe30Dur/sFPaC/F81jXK9bYyw4aSbeJ+wUDrv3lit1pqamieffFJYycg/UL5169Zhw4YJz21x/NDcvyT23mrdl2nWYgWLilv7nf6KW6S/zxAW9CBV9F3cnFsNAzmyp8z3TlONpXtVVyv+IZ2MmvVvy6Qbo3pJvwFzj/7xlTP0t33l6yKoucr11J6kvudPBdSs2BdT2+KotM1mO3jwoMycDh8+7HygXJATfVOl5d810afsR+GHGr52PSyZU6y6ea8fLRkHThU9tuHsoGlmMELaq5rcZCrleyflVRm67NSN+z5hnrIf2HJthcw3YCmpFfbL/b640Na7QfSRjks8cnNzT548KTOnU6dO9ejxx2mjyUWiXxDXGr9JdxulWbVMblG663fK/3Q+ClPya9zvE659TT8+kG/YycmHlZVSH9tG1RCffrvwH2l96Qh942YvC+LE+1yf2Kve02VUmTXndqw3btzo02GJLVu22J9YnD7F0xlMdeZD7uso9fIvvFwWOahJWzTcpzlTlJD5YaexinwobWV11B5ycnjmz9VvxwW0BRjgF+2Rs7aJfg0VN3a1zPWS87GK1NRUl1XT6dOnXfpx+Ymwo5WWlpb5+71wJM4JHGr8xn0/StjUdP2i7M5TcTe97d9ZEQ4/Xub/J/JO/ORnO7ThEWTbx/VOebs6jPbjw9vV4crAf7uwstL2bWyxm3G16202TUU1Mev/43WYvmnTpjl3smLFiry8vGPHjjl+eOLEiYKCgiVLljgfrpgz59zVR17v0ea+jnJ+Dx1v+ED0S2eXQ51eZ0ilvot/9wcQPse2vii2q6txRW9IHvh9h0aZ8qdm9PN6MnV41ULt/B2qeS+7/Dy5e0/pzar/mdd8Vnh8fPyePXuOHj3697//vaamxmKx2I9MPP/8845ytm3bZr9S0Gw2V1ZWbt269ciRI3v37rVfbtg5dpJ0UXXZ/+vy3vT5lfoFr0XNelHiK1pbdn5C1UzHu02tuFJOUT/9ebLM0SZejBrRbpbA9jlWxFNxo35JuUFqHG3dcJnjld7d6dx5g2fU896Jn7K+Qz/pARJcGAqqEjf8JNFS5LoThvwq+0GI6dOnC2GYTCbnVygpKXHk5PIVrfBIIcKmpib7qCzJhvLKiOPSRTV02W6/tkrOWje657jYyQ8nbfy5xbHKjb/axt4up6gd2jG/aq4Vryj1hjeME+aFFTJWRNtQkJj1gLFO9LPcYpa7h704UmSUrGPh17ysGiXn6eYe/Tuu+sXX4WPd7d69W2jpo48+8vrI3OSa3l1m2KeyrGmlmU2uU8bUtBTvS7Cmfpn7nlWL6+Qn3ilnDoxJ7yU6/xnJqK2qMXXdnXSN47NcE18j84mrO5V73VYRNvcVHOPOYbg2Z7G2b4Pu3GXeY8aMEXIaN+7cfdmGaBu3XnJ2kHqC4r9XWE/KvweCzFE7x2b0ts+rD5Jn1Fq6te+FLVRGgb3CmDc1o+LWhKpA1ksexpy4ZoBFse9Ghpq7Oa4k/yTy3N0oUlNThZzsR/CaD6aHf2wf1PJOy7/7WGoVnEu6v+z06bvdhPFr5bxsY3LvUaa8UFjMGKNcxB0d+8o/JPV8ijJrCdGhjB3/Wlh4/iw197GXr4ler8h70OdXhq/27az5jjd8YM0pZpkhJ3GLIsp8ucRjilK3YBF9ffdTdSdql4veHGBU+EJF3oZ9AAmfpogb97DYkJMInwaI269tUvBXexgPcKbzvlmONe+vhq9Fc7r+0qeVeidCURFrjvtUVNiijxK6FLH8kFMLO3JnyB9UrNTaOdg5CZPzhdzl+hGe7qqmYE7NRRXX+bqOErb6WH7I6bznOvt/dsx2teuXwlWGHJ8uI/X0MOed+CJz/ycjjsvJqShtssS3T5Xa/c5X1xvKRipyHRTrKHI65+FuEwM598/9Vis7tGMCz+mDjmNdDsSXGark5FSWNU36+1zn+7VZO+fFrzusSFGXL9hNTqHumcxGZUcsyLdlfmuZE2BOH4eLD6nZ2zz0qcgTAebUy/Sg8+OjZr+oSE7Nl6VM2UJOIaooIXO/NtBxKWbb+rm87Jqwcl8LdPnXVWYv45xsbVmUrzkJU6q+xa9QKqfmISWu3xWaW32hntMX6skBtnQk9Qb3U2b8WKG1HA7B+3dZfSy1zjkt/PMzvubUM+pF56fYZvxNwaI6LfyQnELLY4mjA7/Q7Q2j66Ivess9+TntibhK5vsX9qMcW32LOjzra07Vui+dn2ItGqK5+1cFiwrBIxOhm9OmtBHKDEoaXuR2EGKs3zntVV3t0y3Qhf0ov3Pq63Qra7v02/YomFMIrqNCNKeH45Vp6WjYNe6XGPh39MI+xojou+2RWPqk9Yebkh73WFTUSf9y6q9rMRRExLh7lc0p1IoKxZw2JCs2oPa/Yq5weXH55866PHG0pdDT6AiPxX1nXwXNT79H9AHFlgGFpgo/cqqN+U+q0xOje45TPCfRodHIqZ2431Ab1BF937c1KTgacHdbiaOlcxt11kdl7VbJy0mYesTPcH6iaeGbwSjK/YJ/cmrzVsdVBXWA7IFxuWfU8xTMyaUl+zQvZaOCObkckLhs8t+DkVPz0E7ybt9ITm1Df3O2giH90rHJ/UyILebhMs/3+2e4lyuCu1mLHzEd9HSG3g3xD0s/XdiE66vePiT8mJyiMkwtLqn885RnLp/6nMskZHbppKdFJ0NBVSZCbu0Ul1irylZqEh3kQLqi06q5r2jGjIvu5vUCXqGlx+MPe2rJPs1K9X7pXrKhPDPiupqEd8elS3U12PQmJZBT67JM00/iJgOzbf0qTHLPQH/Yw1UYLtPc5A0yXzAjqbAsbb6nnGqiTqaaKvgEyam1EFY4QjPuq6P3rFNvjOrp00s1xq6Q05IwPaM6XWwZ4NOLF3V6flTmp+5F5cVs4EMkp9ZihL6b6z3hLfVeh+bzRGZO9yTu8u/1c01NA1V7pb/SBTldNJv1546/f2uZ02CTuvtQH+3wGaqNWyUX3/tUe+XkNDb6Jk+v0Dz6l2Gk1yH1KmJfrY46ee7u8S2/CAY5XTT2lqYYiiUOM/Q0Vq8zvemIQeLVao1T5eQk8Qr2A+VDDV/nxa6QfufCXlOh+m7hwQMNr/M5klNrl2vLH2ae9oB2v0QMXRMLfN3eG5NyrfPjhR66JY10yckx9en0YZa2kc+CnC6EXqaaO3Q779C/5nVaEf2ST688LW71EwnfS69bFnV5cLP6C9cnRq+XzsmlwOYhyNVnuidfIZrTuW9s49/x6c1r6pclLt/lmJJXfpB++x7x6bY98WXDWJDIyYddf2G6Q7dTqZe1P+bm1KdEt9x6a4bJ39ITOnE0Yy9K+qyIvISZMkcq9+m8BxYkcsq8MmKR/JwW+DJgkNceFmRtdvxPYT3m/Nwca979mn2enjup4x2OR2ZYBtSqTp+/TYb6TI61vixjjvSZEFcm/Zzj+UiGg3blfvk5RQ+9iZxC3VrjG/JzUnClt8z2jPP/FLYJc1uuMcbFLBF94lMRx/MN5eePcBjud6+lPvtlr+cWFYf9w+ufED7jnz6MErH4LXIKaQNjxstvqSp2UpC2Ie1TnalJzivcrt3hstfk3yQnJ1+391S9riKn0LXqT+/IXNYfi/vOee1RZqi6RfXyJN1KBXNyPyAxS7PJ/WHCr3Y8oLtmmd85lUa8IGcWxU7w4ZrCy+a/R04chPA+2dcJwi7NEG3jxog99h/e1nJFEWBOLqlk/j5O5d+jTzk/4L6Yzx3/mmrNq9Z96XdOLkOvuKyO9BWTNYXNB+s0PUdzQIKcvCtLGCx/Qe9tqG2MXfGQ/ivnHyqek/uRQ+dvfrc2fzN7/kKptNh6v1vympN90s7fYc0tjb3lgPycbMWV5BSKbkx8zI8lPqg5NXerGebpdR7K/NT55yW6+4Kdkx9T8uwnyIktvdaSU7Xuak+vs7zll8iBtBS8nEJ5ey90c6qw1rfOnNwPx49ImCn68zRD1cCOv7TCnCJnbSOn0CJsOLWVnHJt+c+mHlls+5v7rxCKaoU5dV7zOTmFEGGHPvCWgpTTqj+JnFm3KvbVgeYrRX+LUNSgTkcUzKnD9bsUGLpo4FRyChWboj5tnTlND9vUNUFkIOJ8Q3laksdLP1L1lYM1+5TKSSgh8Jxibv6cnDgIcTFzmqHa6PdflGYt9nkFpd4u+lKWPqMVGQmMnELCyph/tcKcJmqXB/h3Ceso37b6gpyT5rpXyKmdKzD283Q/zIuY01zdfYr8db4dmQhyThFrjxu79SOn9qwqdpJSLTUfNoh9NfCc1nbYpfDfmP1Aa8hJmMJHriWn9uye6M+UamlO7L2FksPTyXmRuzp9KHrswZPe1nXZkYu9F5X+tN856UoaFBxLmZzarZ7G6sAruidxV3m8rAu55bQk8fQMU43LNRSp2uH2EnI6rfb62+syX/QvJ7u40jrbsvcDz8lUVENO7dOt6u0BtlTpywAmgayXhL2gyojjwpRiPL/7kWucen5YPPNQr8f6qmIP+J2Tnba8McCcYue/Sk7tk38JPRF+bGXMv5T9dXdHfiLxxHRbiWOhz3Y6hU96qH5RlRJFycjJIXrOS2Grj7K9R04B5TRE2+h8Jbkiv25jxB7p/aVa4zeOhX5A9GfnVk0xS1zHFo8+lW6s9rqOqtF/JZpTRaxv6w1D13JNn4nkRE7NNsTLvfD2yYjjq2JfHR11YzDqfaTDz6X6Son10lDD1y7Lfdrv1xQOMb8l53YyHo5nHgg8J4eI6kXa+Tsi1hyXmVPisl3k1K6U6xrkhPSo+VAfS23wVob3/LGqEZWqrxQNplzzSlp0o8ReUFYH73fLHNb9EaVycrAU15ruOChrD6p8Ejm1H6MS50iHtNj2t4HmK3OsecHbttys/qKbtVji2IOnqy2GhB8rvew96cN0ckb5ctmPCjwngbVznqn3KOv0R718AbX4Y3Jq/3tNj2Tv9XVgV/9+qfuwKi4tBXgtoGObUJrzfpQiOTmLmvVi5zWfh/IeVEjkNF61VLSlYeZpF6bh+zX7JNZLggGX/1/gOVVGHE8z95d/ZELxnOxMg5pEc9LWLyenNk/Yftui+9KxZD8ddXKt8Y0LuUp8vNMR6Yf11+0MvCVhqlWd9pqT8zoqSDmdPxJ4w+tRd5505GS4/Wthy5Cc2s9BiFmaTUXyFjgFcyrztg2mVE7yb3ErrKOqdV8GOyeBuUd/9fi7HUXpS0eQU9s2RrPowdgDV2mWXfhffat6e5lB1l3NFcnJ5/V29IUbUlw9/Gbtyv2xdTeSU9uWYshS9nhdMFyUnC4wYUvPkJRFTgi6nlEvBthSb79OgwI5tUOevsCVP6XqK5mN5IRzehkf8D8ny0PMQHLCeYEMOJ6ua2AGkhOctveseZ5O/fbydZPxm1RrHjOQnNBCXuwKP3IqNNzKrCMniGh/x8fJCRcvp7CPfGqpX8QeZho5QVzn2Ek+5ZTtdvcakBPOq7W9L7Ol+pQPmV3kBCkZphqZOWUpd+EwyCnUD0gwo8gJ3pUkz/PaUmnKtcwocoJ36YkFXnPKSCpkRpETlNneYxaRE+Tq0mm1REu5YWuYReQEuZIN5ZURxz0NseI8cDnICd6Va15RZDBkkBM87kFlhS9kzpATlMmJ2UJO8OuAhH6y6+DJhinMFnKCP1KtefVx3zlaGpHwfZotn9lCTvBTWeQ2R059VC8zQ8gJyuxBMSvICYGqsD4qtDQo+QlmBTkhUFkJg4dpfs2NG8OsICcosYJK2chBCHICyAkAOQHkBJATAHICyAkgJ4CcAJATQE4AOQEgJ4CcAHICyAkAOQHkBJATAHICyAkgJ4CcAJATQE4AOQHkBICcAHICyAkAOQHkBJATQE4AyAkgJ4CcAJATQE4AOQHkBICcAHICyAkAOQHkBJATQE4AyAkgJ4CcAJATQE4AOQHkBICcAHICyAkAOQHkBJATQE4AyAkgJ4CcAJATQE4AOQHkBICcAHICyAkAOQHkBJATQE4AyAkgJ4CcAHICQE4AOQHkBICcAHICyAkgJwDkBJATQE4AyAkgJ4CcAHICQE4AOQHkBICcAHICyAkgJwDkBJATQE4AyAkgJ4CcAHICQE4AOQHkBICcAHICyAkgJwDkBJATQE4AyAkgJ4CcAHICQE4AOQHkBJATswAgJ4CcAHICQE4AOQHkBJATAHICyAkgJwDkBJATQE4AOQEgJ4CcAHICQE4AOQHkBJATAHICyAkgJwDkBJATQE4AOQEgJ4CcAHICQE4AOQHkBJATAHICyAkgJwDkBJATQE4AOQEgJ4CcAHICQE4AOQHkBJATAHICyAkgJ4CcAJATQE4AOQEgJ4CcAHICyAkAOQHkBJATAHICyAkgJ4CcAJATQE4AOQEgJ4CcAHICyAkAOQHkBJATAHICyAkgJ4CcAJATQE4AOQEgJ4CcAHICyAkAOQHkBJATAHICyAkgJ4CcAJATQE4AOQEgJ4CcAHICyAkAOQHkBJATQE4AyAkgJ4CcAJATQE4AOQHkBICcAHICyAkAOQHkBJATQE4AyAkgJ6B9+X8k88OTKA8XwgAAAABJRU5ErkJggg==";
 		}
-	} else if (V.imageChoice === 0) {
+	} else if (V.imageChoice === 5) {
 		fileName += "resources/renders/assistant ";
 		switch (V.assistant.appearance) {
 			case "monstergirl":
diff --git a/src/art/webgl/art.js b/src/art/webgl/art.js
index 5e5ae1a41f157f7353cefc211800773008ca6ae6..ba23fdb80a5d670bffcc7299cd16c0d640b58a89 100644
--- a/src/art/webgl/art.js
+++ b/src/art/webgl/art.js
@@ -1104,8 +1104,9 @@ App.Art.applySurfaces = function(slave, scene, p) {
 	}
 
 	function applyScars(slave, location, area, layers) {
-		for (let kind in slave.scar[location]) {
-			for (let i = 0; i < slave.scar[location][kind]; i++) {
+		const scars = App.Medicine.Modification.scarRecord(slave);
+		for (let kind in scars[location]) {
+			for (let i = 0; i < scars[location][kind]; i++) {
 				let matId = location + kind + i;
 				if (App.Art.getMaterialById(scene, matId) == null)	{
 					generateDecalScar(location, area, matId, kind);
@@ -1143,7 +1144,8 @@ App.Art.applySurfaces = function(slave, scene, p) {
 	}
 
 	function applyBrands(slave, location, center, layers) {
-		let text = slave.brand[location];
+		const brands = App.Medicine.Modification.brandRecord(slave);
+		let text = brands[location];
 
 		switch (text) {
 			case "your initials":
@@ -1239,14 +1241,15 @@ App.Art.applySurfaces = function(slave, scene, p) {
 		}
 	}
 
-	for (let location in slave.scar) {
+	for (let location in App.Medicine.Modification.scarRecord(slave)) {
 		let [area,, layer] = getDecalArea(location);
 		if (layer !== null) {
 			applyScars(slave, location, area, layer);
 		}
 	}
 
-	for (let location in slave.brand) {
+	const brands = App.Medicine.Modification.brandRecord(slave);
+	for (let location in brands) {
 		let [, center, layer] = getDecalArea(location);
 		if (layer !== null) {
 			applyBrands(slave, location, center, layer);
@@ -1786,7 +1789,8 @@ App.Art.applyMaterials = function(slave, scene, p) {
 
 	let torso = App.Art.getMatIdsBySurface(scene, "Torso")[0];
 
-	if (slave.scar.hasOwnProperty("belly") && slave.scar.belly["c-section"] > 0) {
+	const scars = App.Medicine.Modification.scarRecord(slave);
+	if (scars.hasOwnProperty("belly") && scars.belly["c-section"] > 0) {
 		materials.push([torso, "map_Kn", "base/Victoria8_Torso_CNM_1002_3.jpg"]);
 	} else {
 		materials.push([torso, "map_Kn", "base/Victoria8_Torso_NM_1002_3.jpg"]);
diff --git a/src/budget/costsBudget.js b/src/budget/costsBudget.js
index 0a7f9e508bfa9eea70ad19145d448ca6dc21c63f..03bb29fb5c79d997c79a694dc99c317ee74fc144 100644
--- a/src/budget/costsBudget.js
+++ b/src/budget/costsBudget.js
@@ -3,62 +3,84 @@
  * @returns {DocumentFragment}
  */
 App.Budget.costs = function() {
-	const f = new DocumentFragment();
+	const frag = new DocumentFragment();
 
-	f.append(
+	App.UI.DOM.appendNewElement("h1", frag, `Budget`);
+
+	frag.append(
 		intro(),
+		loans(),
 		netWorth(),
 	);
 	if (V.difficultySwitch === 1) {
-		f.append(economy());
+		frag.append(economy());
 	}
-	f.append(settings());
+	frag.append(settings());
 
 	// Table of Totals
 	if (!V.lastWeeksCashIncome) {
-		App.UI.DOM.appendNewElement("p", f, "Financial data currently unavailable.");
+		App.UI.DOM.appendNewElement("p", frag, "Financial data currently unavailable.");
 	} else {
-		App.UI.DOM.appendNewElement("p", f, App.Budget.table("cash"));
+		App.UI.DOM.appendNewElement("p", frag, App.Budget.table("cash"));
 	}
 
-	errors(f);
-	return f;
+	errors(frag);
+	return frag;
+
+	/**
+	 * @returns {DocumentFragment}
+	 */
+	function loans() {
+		const frag = new DocumentFragment();
+
+		frag.append(App.Budget.loans());
+
+		return frag;
+	}
 
 	/**
 	 * @returns {HTMLParagraphElement}
 	 */
 	function intro() {
-		return App.UI.DOM.makeElement("p", `Here you can view many of the financial details of your arcology, ${properTitle()}. Proper cash flow is critical to the success of your long term goals. Find expensive waste here and you can change the right policies or sell off slackers. Find your next profit center and invest in new equipment, advertising, or flesh to maximize your assets.`, "scene-intro");
+		return App.UI.DOM.makeElement("p", `Here you can view many of the financial details of your arcology, ${properTitle()}. Proper cash flow is critical to the success of your long term goals. Find expensive waste here and you can change the right policies or sell off slackers. Find your next profit center and invest in new equipment, advertising, or flesh to maximize your assets.`, ["scene-intro"]);
 	}
 
 	/**
-	 * @returns {HTMLParagraphElement}
+	 * @returns {DocumentFragment}
 	 */
 	function netWorth() {
-		const p = document.createElement("p");
+		const frag = new DocumentFragment();
 
-		p.append(`You have a total net worth of ${cashFormat(Math.trunc(App.Utils.totalNetWorth()))}.`);
+		frag.append(
+			App.UI.DOM.makeElement("h2", `Net worth`),
+			`You have a total net worth of ${cashFormat(Math.trunc(App.Utils.totalNetWorth()))}.`
+		);
 
 		if (V.debugMode) {
-			App.UI.DOM.appendNewElement("div", p, App.UI.DOM.link(`Recalculate net worth`, () => {
+			App.UI.DOM.appendNewElement("div", frag, App.UI.DOM.link(`Recalculate net worth`, () => {
 				App.UI.reload();
 			}), ['indent']);
 		}
 
-		return p;
+		return frag;
 	}
 
 	/**
-	 * @returns {HTMLParagraphElement}
+	 * @returns {DocumentFragment}
 	 */
 	function economy() {
+		const frag = new DocumentFragment();
+
+		App.UI.DOM.appendNewElement("h2", frag, `Economy`);
+
 		const p = document.createElement("p");
-		App.UI.DOM.appendNewElement("div", p, `The Local Economy score effects some prices in your ecology. The lower the score, the higher the prices. The base score is 100.`, "scene-intro");
+
+		App.UI.DOM.appendNewElement("div", p, `The Local Economy score effects some prices in your ecology. The lower the score, the higher the prices. The base score is 100.`, ["scene-intro"]);
 
 		const grid = document.createElement("div");
 		grid.className = "grid-2columns-auto";
 
-		App.UI.DOM.appendNewElement("div", grid, "Global Economy", "cash");
+		App.UI.DOM.appendNewElement("div", grid, "Global Economy", ["cash"]);
 		if (V.cheatMode && V.cheatModeM) {
 			const div = document.createElement("div");
 			div.append(App.UI.DOM.makeTextBox(V.economy, v => {
@@ -70,7 +92,7 @@ App.Budget.costs = function() {
 			App.UI.DOM.appendNewElement("div", grid, String(V.economy));
 		}
 
-		App.UI.DOM.appendNewElement("div", grid, "Local Economy", "cash");
+		App.UI.DOM.appendNewElement("div", grid, "Local Economy", ["cash"]);
 		if (V.cheatMode && V.cheatModeM) {
 			const div = document.createElement("div");
 			div.append(App.UI.DOM.makeTextBox(V.localEcon, v => {
@@ -97,7 +119,9 @@ App.Budget.costs = function() {
 		}
 		$(p).append(...App.Events.spaceSentences(r));
 
-		return p;
+		frag.append(p);
+
+		return frag;
 	}
 
 	/**
@@ -105,7 +129,7 @@ App.Budget.costs = function() {
 	 */
 	function settings() {
 		const p = document.createElement("p");
-		App.UI.DOM.appendNewElement("div", p, "Your weekly costs are as follows:", "detail");
+		App.UI.DOM.appendNewElement("div", p, "Your weekly costs are as follows:", ["detail"]);
 
 		let options = new App.UI.OptionsGroup();
 		options.addOption("", "costsBudget", V.showAllEntries)
@@ -123,9 +147,9 @@ App.Budget.costs = function() {
 			const p = document.createElement("p");
 			p.append(App.UI.DOM.passageLink("Reset", "Costs Budget",
 				() => { V.lastWeeksCashErrors = []; }));
-			App.UI.DOM.appendNewElement("div", p, "Errors:", "error");
+			App.UI.DOM.appendNewElement("div", p, "Errors:", ["error"]);
 			for (const error of V.lastWeeksCashErrors) {
-				App.UI.DOM.appendNewElement("div", p, error, "error");
+				App.UI.DOM.appendNewElement("div", p, error, ["error"]);
 			}
 			container.append(p);
 		}
diff --git a/src/budget/loans.js b/src/budget/loans.js
new file mode 100644
index 0000000000000000000000000000000000000000..5234f2eac176ad7b628c4a5e82b8cc14aed5e7b4
--- /dev/null
+++ b/src/budget/loans.js
@@ -0,0 +1,182 @@
+App.Budget.loans = function() {
+	/** @typedef {('bank'|'shark')} Lender */
+
+	const frag = new DocumentFragment();
+
+	const loan = (/** @type {Lender} */ name) => V.loans.find(loan => loan.name === name);
+
+	App.UI.DOM.appendNewElement("h2", frag, `Loans`);
+
+	if (V.loans.length) {
+		frag.append(pay());
+	}
+
+	frag.append(
+		bank(),
+		loanshark(),
+	);
+
+	return frag;
+
+	function pay() {
+		const div = document.createElement("div");
+		const links = [];
+		const text = [];
+
+		text.push(`You can pay off a loan here.`);
+
+		if (loan('bank')) {
+			const bank = loan('bank');
+			if (V.cash > bank.full) {
+				links.push(App.UI.DOM.link(`Pay off your bank loan`, () => {
+					cashX(forceNeg(bank.full), "loan");
+					V.loans.delete(bank);
+
+					App.UI.reload();
+				}, [], '', `You have a remaining balance of ${cashFormat(Math.trunc(bank.full))}.`));
+			} else {
+				links.push(App.UI.DOM.disabledLink(`Pay off your bank loan`, [
+					`You lack the necessary funds to pay off this loan`,
+				]));
+			}
+		}
+		if (loan('shark')) {
+			const shark = loan('shark');
+			if (V.cash > shark.full) {
+				links.push(App.UI.DOM.link(`Pay off the loanshark`, () => {
+					cashX(forceNeg(shark.full), "loan");
+					V.loans.delete(shark);
+
+					App.UI.reload();
+				}, [], '', `You have ${years(loan('shark').deadline - V.week || 1)} until the shark comes to collect.`));
+			} else {
+				links.push(App.UI.DOM.disabledLink(`Pay off the loanshark`, [
+					`You lack the necessary funds to pay off this loan`,
+				]));
+			}
+		}
+
+		div.append(text.join(' '));
+		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
+
+		return div;
+	}
+
+	function bank() {
+		const div = document.createElement("div");
+		const values = [10000, 100000, 1000000];
+		const disabledReasons = [];
+		const links = [];
+		const text = [];
+
+		let allowed = true;
+
+		text.push(`You can take out a loan from one of the credit unions in the Free City, if you have the reputation for them to trust you.`);
+
+		if (V.rep < 10000) {
+			disabledReasons.push(`You need at least ${num(10000)} reputation to take a loan from this lender.`);
+			allowed = false;
+		}
+		if (loan('bank')) {
+			disabledReasons.push(`You have already taken out a loan from this lender.`);
+			allowed = false;
+		}
+
+		if (allowed) {
+			values.map(val => links.push(App.UI.DOM.link(cashFormat(val), () => {
+				const term = Math.max(val / 50000, 4);
+				const apr = Math.max(Math.abs((V.rep - 20000) / 500), 5);
+				const interest = val * (term / 52) * (apr / 100);
+				const full = val + interest;
+				V.loans.push({
+					name: 'bank',
+					principal: val,
+					deadline: V.week + term,
+					installments: term,
+					apr,
+					interest,
+					full,
+				});
+				cashX(val, "loan");
+
+				App.UI.reload();
+			}, [], '', terms('bank', val))));
+		} else {
+			values.map(val => links.push(App.UI.DOM.disabledLink(cashFormat(val), disabledReasons)));
+		}
+
+		div.append(text.join(' '));
+		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
+
+		return div;
+	}
+
+	function loanshark() {
+		const div = document.createElement("div");
+		const values = [10000, 100000, 1000000];
+		const disabledReasons = [];
+		const links = [];
+		const text = [];
+
+		let allowed = true;
+
+		text.push(`If you're not quite reputable enough, you can also borrow money from one of the local loansharks in the area.`);
+
+		if (V.rep < 2000) {
+			disabledReasons.push(`You need at least ${num(2000)} reputation to take a loan from this lender.`);
+			allowed = false;
+		}
+		if (loan('shark')) {
+			disabledReasons.push(`You have already taken out a loan from this lender.`);
+			allowed = false;
+		}
+
+		if (allowed) {
+			values.map(val => links.push(App.UI.DOM.link(cashFormat(val), () => {
+				const term = Math.max(val / 50000, 4);
+				const apr = Math.max(Math.abs((V.rep - 20000) / 500), 5);
+				const interest = (val * (term / 52) * (apr / 100)) * 3;
+				const full = val + interest;
+				V.loans.push({
+					name: 'shark',
+					principal: val,
+					deadline: V.week + (Math.max(val / 50000, 4)),
+					installments: 1,
+					apr,
+					interest,
+					full,
+				});
+				cashX(val, "loan");
+
+				App.UI.reload();
+			}, [], '', terms('shark', val))));
+		} else {
+			values.map(val => links.push(App.UI.DOM.disabledLink(cashFormat(val), disabledReasons)));
+		}
+
+		div.append(text.join(' '));
+		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['indent']);
+
+		return div;
+	}
+
+	/**
+	 * @param {Lender} lender
+	 * @param {number} amount
+	 */
+	function terms(lender, amount) {
+		const term = Math.max(amount / 50000, 4);
+		const apr = Math.max(Math.abs((V.rep - 20000) / 500), 5);
+		const interest = amount * (term / 52) * (apr / 100);
+		const full = amount + interest;
+		const text = [];
+
+		if (lender === 'bank') {
+			text.push(`You will pay about ${cashFormat(Math.trunc(full / term))} per week for ${num(term)} weeks until you have paid off the entire balance. If for any reason you lack the credits, sectors of ${V.arcologies[0].name} will be used in lieu of payment. You will end up paying back about ${cashFormat(Math.trunc(full))} after interest.`);
+		} else {
+			text.push(`You will have ${num(term)} weeks to pay off the full amount, after which the lender will send his men to collect – forcibly, if necessary. You will end up paying back about ${cashFormat(Math.trunc(amount + (interest * 3)))} after interest.`);
+		}
+
+		return text.join(' ');
+	}
+};
diff --git a/src/cheats/cheatEditArcology.js b/src/cheats/cheatEditArcology.js
index 9f2c6640eabfc41ce47ba93c87060d45511440b3..aebc9076f1adaf19bce5a4a2e73b8017de83a079 100644
--- a/src/cheats/cheatEditArcology.js
+++ b/src/cheats/cheatEditArcology.js
@@ -15,6 +15,29 @@ App.UI.Cheat.arcology = function(num) {
 		el.append(tabBar.render());
 	}
 
+	if(num === 0) {
+		if(arc.FSMaturityPreferentialist !== "unset") {
+			if(V.idealAge < 30) {
+				V.idealAge = 30;
+			}
+			if(V.targetIdealAge < 30) {
+				V.targetIdealAge = 30;
+			}
+			V.policies.idealAge = 1;
+		} 
+		else if(arc.FSYouthPreferentialist !== "unset") {
+			if(V.idealAge >= 30) {
+				V.idealAge = 29;
+			} 
+			if(V.targetIdealAge >= 30) {
+				V.targetIdealAge = 29;
+			}
+			if(V.targetIdealAge !== 18) {
+				V.policies.idealAge = 1;
+			} 
+		} 
+	}
+
 	return el;
 
 	function cheat() {
diff --git a/src/cheats/cheatEditSlave.js b/src/cheats/cheatEditSlave.js
index be194260918c04568d4093bfbad0f79bf8503cbb..7bcc1eba3e51358f83322c52ce39e200381413e3 100644
--- a/src/cheats/cheatEditSlave.js
+++ b/src/cheats/cheatEditSlave.js
@@ -57,6 +57,7 @@ App.UI.SlaveInteract.cheatEditSlave = function(slave) {
 			"Apply cheat edits",
 			() => {
 				SlaveDatatypeCleanup(V.tempSlave);
+				normalizeRelationship();
 				V.slaves[V.slaveIndices[slave.ID]] = V.tempSlave;
 				ibc.recalculate_coeff_id(slave.ID);
 				delete V.tempSlave;
@@ -67,6 +68,46 @@ App.UI.SlaveInteract.cheatEditSlave = function(slave) {
 		return el;
 	}
 
+	function normalizeRelationship() {
+		if (V.tempSlave.relationship !== slave.relationship || V.tempSlave.relationshipTarget !== slave.relationshipTarget) {
+			if (slave.relationship > 0 && V.tempSlave.relationship <= 0) {
+				// broke relationship
+				const friend = getSlave(slave.relationshipTarget);
+				if (friend) {
+					friend.relationship = 0;
+					friend.relationshipTarget = 0;
+				}
+				V.tempSlave.relationshipTarget = 0;
+			} else if (V.tempSlave.relationship > 0 && V.tempSlave.relationshipTarget !== slave.relationshipTarget) {
+				// new relationship target
+				const oldFriend = slave.relationship > 0 ? getSlave(slave.relationshipTarget) : null;
+				if (oldFriend) {
+					// first break this slave's existing relationship, if she had one
+					oldFriend.relationship = 0;
+					oldFriend.relationshipTarget = 0;
+				}
+				const newFriend = getSlave(V.tempSlave.relationshipTarget);
+				if (newFriend) {
+					// then break the target's existing relationship, if she had one
+					const newFriendFriend = newFriend.relationship > 0 ? getSlave(newFriend.relationshipTarget) : null;
+					if (newFriendFriend) {
+						newFriendFriend.relationship = 0;
+						newFriendFriend.relationshipTarget = 0;
+					}
+					// then make the new relationship bilateral
+					newFriend.relationship = V.tempSlave.relationship;
+					newFriend.relationshipTarget = V.tempSlave.ID;
+				}
+			} else if (V.tempSlave.relationship > 0) {
+				// same target, new relationship level
+				const friend = getSlave(slave.relationshipTarget);
+				if (friend) {
+					friend.relationship = V.tempSlave.relationship;
+				}
+			}
+		}
+	}
+
 	function extreme() {
 		const el = new DocumentFragment();
 		const options = new App.UI.OptionsGroup();
diff --git a/src/personalAssistant/assistantBC.js b/src/data/backwardsCompatibility/assistantBC.js
similarity index 100%
rename from src/personalAssistant/assistantBC.js
rename to src/data/backwardsCompatibility/assistantBC.js
diff --git a/src/data/backwardsCompatibility/backwardsCompatibility.js b/src/data/backwardsCompatibility/backwardsCompatibility.js
index 3222c9940ca5eba01b2b5f06986b077c8494acf7..d661272f9ebc9389193d576fd44f3db9c3b56848 100644
--- a/src/data/backwardsCompatibility/backwardsCompatibility.js
+++ b/src/data/backwardsCompatibility/backwardsCompatibility.js
@@ -130,6 +130,66 @@ App.Update.backwardsCompatibility = function() {
 };
 
 App.Update.globalVariables = function(node) {
+	V.rival = V.rival || {};
+	V.rival.FS = V.rival.FS || {};
+
+	if (V.slaves.find(s => s.origin.includes("You were acquainted with $him before you were an arcology owner") && s.newGamePlus === 0)) {
+		V.rival.hostageState = 2;
+		V.hostage = 0;
+		delete V.hostageWife;
+	}
+	if (V.hostageAnnounced && !V.slaves.find(s => s.origin.includes("You were acquainted with $him before you were an arcology owner") && s.newGamePlus === 0)) {
+		V.rival.hostageState = 1;
+	}
+	V.rival.hostageState = V.rival.hostageState || 0;	
+
+	V.rival.state = V.rival.state || 0;
+	V.rival.prosperity = V.rival.prosperity || 0;
+	V.rival.power = V.rivalryPower || V.rival.power || 0;
+	V.rival.duration = V.rivalryDuration || V.rival.duration || 0;
+	V.rival.FS.name = V.rivalryFS || V.rival.FS.name || "";
+	if (V.rivalRace) {
+		V.rival.race = V.rivalRace;
+	}
+	if (V.rivalryFSRace) {
+		V.rival.FS.race = V.rivalryFSRace;
+	}
+	if (V.rivalryFSAdopted) {
+		V.rival.FS.adopted = 1;
+	}
+	if (V.rivalOwner > 0) {
+		V.rival.prosperity = V.rivalOwner;
+	}
+	if (V.rivalOwner > 0 && V.rivalSet === 0) {
+		V.rival.state = 1;
+	} else if (V.rivalSet === 1) {
+		V.rival.state = 2;
+	}
+	if (V.rivalOwner === -1) {
+		V.rival.state = 3;
+	}
+	if (V.rivalOwnerEnslaved) {
+		V.rival.state = 5;
+	}
+	if (V.rivalGender) {
+		V.rival.gender = V.rivalGender;
+	}
+
+	if (typeof V.peacekeepers.state === "undefined") {
+		V.peacekeepers = V.peacekeepers || {};
+		delete V.peacekeepers.independent;
+		if (V.peacekeepersGone) {
+			V.peacekeepers.state = 0;
+		} else if (!peacekeepersCanBeEstablished()) {
+			V.peacekeepers.state = 1;
+		} else if (!V.peacekeepersFate) {
+			V.peacekeepers.state = 2;
+		} else {
+			V.peacekeepers.state = 3;
+		}
+		V.peacekeepers.tastes = V.peacekeepers.tastes || "";
+	}
+
 	if (typeof V.incubator === "number") {
 		if (V.incubator > 0) {
 			const storage = V.incubator;
@@ -299,14 +359,14 @@ App.Update.globalVariables = function(node) {
 		if (typeof V.trainingRegimen !== "undefined" && typeof V.personalAttention === "number") {
 			V.personalAttention = {
 				task: PersonalAttention.TRAINING,
-				slaves: [{ID: V.personalAttention, objective: App.personalAttention.update(V.trainingRegimen)}]
+				slaves: [{ID: V.personalAttention, objective: App.PersonalAttention.update(V.trainingRegimen)}]
 			};
 		}
 		if (V.personalAttention.task === undefined) {
 			if (typeof V.personalAttention === "string") {
 				V.personalAttention = {task: V.personalAttention};
 			} else if (Array.isArray(V.personalAttention)) {
-				V.personalAttention.forEach(s => { s.objective = App.personalAttention.update(s.trainingRegimen); delete s.trainingRegimen; });
+				V.personalAttention.forEach(s => { s.objective = App.PersonalAttention.update(s.trainingRegimen); delete s.trainingRegimen; });
 				V.personalAttention = {
 					task: PersonalAttention.TRAINING,
 					slaves: V.personalAttention
@@ -376,8 +436,8 @@ App.Update.globalVariables = function(node) {
 	// Pit
 	App.Facilities.Pit.BC();
 
-	App.SecExp.generalBC();
-	App.SF.BC();
+	App.Mods.SecExp.generalBC();
+	App.Mods.SF.BC();
 
 	// FS
 	{
@@ -451,6 +511,9 @@ App.Update.globalVariables = function(node) {
 				V.arcologies[bci].FSHedonisticDecadenceResearch = 0;
 			}
 		}
+		if ( V.arcologies[0].FSRestart !== "unset" && V.playerBredTube) {
+			V.playerBred = 2;
+		}
 	}
 
 	// Arcologies
@@ -837,7 +900,6 @@ App.Update.globalVariables = function(node) {
 			}
 			if (V.arcologies[0].FSArabianRevivalist !== "unset" && !Number.isFinite(V.arcologies[0].FSArabianRevivalist)) {
 				V.arcologies[0].FSArabianRevivalist = 10;
-				App.UI.DOM.appendNewElement("div", node, ``);
 				App.UI.DOM.appendNewElement("div", node, `Fixed NaN FS value for FSArabianRevivalist`);
 			}
 			if (V.arcologies[0].FSEdoRevivalist !== "unset" && !Number.isFinite(V.arcologies[0].FSEdoRevivalist)) {
@@ -889,9 +951,6 @@ App.Update.globalVariables = function(node) {
 		if (V.week > 11 && V.assistant.personality === 0) {
 			V.assistant.personality = -1;
 		}
-		if (V.week > 29 && V.eventResults.aid === 0) {
-			V.eventResults.aid = -1;
-		}
 		App.Update.FCTV();
 		if (jQuery.isEmptyObject(V.arcologyUpgrade)) {
 			V.arcologyUpgrade = {
@@ -1625,6 +1684,8 @@ App.Update.arcologyLocation = function(node) {
 };
 
 App.Update.oldVersions = function(node) {
+	V.slaves.filter(s => s.career === 0).forEach(s => s.career = "a slave");
+	V.slaves.filter(s => s.origin === 0).forEach(s => s.origin = "");
 	if (V.releaseID === 1021 || V.releaseID === 1020 || V.releaseID === 1019 || V.releaseID === 2022) {
 		V.releaseID = 1022;
 	}
diff --git a/src/data/backwardsCompatibility/datatypeCleanup.js b/src/data/backwardsCompatibility/datatypeCleanup.js
index 1d01e17a14a333f5a0df44054655b40696f224a0..c13a5d635e2d7332d00551346e9b4d2b95ba89fc 100644
--- a/src/data/backwardsCompatibility/datatypeCleanup.js
+++ b/src/data/backwardsCompatibility/datatypeCleanup.js
@@ -19,8 +19,10 @@ App.Entity.Utils.SlaveDataSchemeCleanup = (function() {
 		migrateSkills(slave);
 		migrateCounters(slave);
 		migrateCustomProperties(slave);
-		migrateBrand(slave);
-		migrateScars(slave);
+		if (V.releaseID < 1161) {
+			migrateBrand(slave);
+			migrateScars(slave);
+		}
 		migrateHealth(slave);
 		App.Entity.Utils.migratePronouns(slave);
 
@@ -2142,6 +2144,167 @@ App.Entity.Utils.RARuleDatatypeCleanup = function() {
 			}
 			delete cond.specialSlaves;
 		}
+
+		if (cond.function !== undefined) {
+			try {
+				if (typeof cond.function === "boolean") {
+					cond.activation = [cond.function, 1, "and"];
+				} else if (cond.function === "custom") {
+					cond.activation = ["?bc=>(" + cond.data + ")(c.slave)", 1, "and"];
+				} else if (cond.function === "belongs") {
+					switch (cond.data.attribute) {
+						case "amp":
+							cond.activation = cond.data.value[0] === 1
+								? ["isamputee", 1, "and"]
+								: ["isamputee", "not", 1, "and"];
+							break;
+						case "genes":
+							cond.activation = ["genes", "!" + cond.data.value[0], "eqstr", 1, "and"];
+							break;
+						case "fetish":
+							cond.activation = [];
+							// eslint-disable-next-line no-case-declarations
+							let count = 0;
+							for (const fetish of cond.data.value) {
+								count++;
+								cond.activation.push("fetish", "!" + fetish, "eqstr");
+							}
+							cond.activation.push(count, "or", 1, "and");
+					}
+				} else if (cond.function === "between") {
+					let count = convertBetween();
+					if (count === 0) {
+						count++;
+						cond.activation = [false];
+						console.log("no match", JSON.parse(JSON.stringify(cond)));
+					}
+					cond.activation.push(count, "and");
+				}
+
+				if (!App.RA.Activation.Editor.validateRule(cond.activation)) {
+					cond.activation = [false, 1, "and"];
+				}
+			} catch (e) {
+				console.log("condition broke", e.message, JSON.parse(JSON.stringify(cond)));
+				cond.activation = [false, 1, "and"];
+			} finally {
+				delete cond.function;
+				delete cond.data;
+			}
+
+			// assignments
+			try {
+				if (cond.assignment.length > 0) {
+					const rule = [];
+					for (const assignment of cond.assignment) {
+						rule.push(assigmentToKey(assignment));
+					}
+					rule.push(rule.length, "or");
+
+					if (!App.RA.Activation.Editor.validateRule(rule)) {
+						rule = [false, 1, "or"];
+					}
+
+					cond.activation.pop();
+					const length = cond.activation.pop();
+					cond.activation.push(...rule);
+					cond.activation.push(length + 1, "and");
+					if (!App.RA.Activation.Editor.validateRule(cond.activation)) {
+						cond.activation = [false, 1, "and"];
+					}
+				}
+			} catch (e) {
+				console.log("assignments broke", e.message, JSON.parse(JSON.stringify(cond)));
+			} finally {
+				delete cond.assignment;
+			}
+		}
+
+		function convertBetween() {
+			const values = {
+				"devotion": "devotion",
+				"trust": "trust",
+				"health.condition": "health",
+				"health.tired": "fatigue",
+				"energy": "energy",
+				"height": "height",
+				"weight": "weight",
+				"actualAge": "age",
+				"physicalAge": "physicalAge",
+				"visualAge": "visualAge",
+				"muscles": "muscles",
+				"pregType": "pregType",
+				"bellyImplant": "bellyImplant",
+				"belly": "belly",
+				"intelligenceImplant": "intelligenceImplant",
+				"intelligence": "intelligence",
+				"accent": "accent",
+				"waist": "waist",
+				"chem": "chem",
+				"lactation": "lactation",
+			};
+			if (values.hasOwnProperty(cond.data.attribute)) {
+				return addBetween(values[cond.data.attribute]);
+			}
+			return 0;
+		}
+
+		function addBetween(key) {
+			let count = 0;
+			if (cond.data.value[0] !== null) {
+				cond.activation.push(key, cond.data.value[0], "gte");
+				count++;
+			}
+			if (cond.data.value[1] !== null) {
+				cond.activation.push(key, cond.data.value[1], "lte");
+				count++;
+			}
+			return count;
+		}
+
+		function assigmentToKey(assignment) {
+			const jobs = {
+				[Job.REST]: "rest",
+				[Job.CHOICE]: "choice",
+				[Job.FUCKTOY]: "fucktoy",
+				[Job.CLASSES]: "classes",
+				[Job.HOUSE]: "house",
+				[Job.WHORE]: "whore",
+				[Job.PUBLIC]: "public",
+				[Job.SUBORDINATE]: "subordinate",
+				[Job.MILKED]: "milked",
+				[Job.GLORYHOLE]: "gloryhole",
+				[Job.CONFINEMENT]: "confinement",
+				[Job.BODYGUARD]: "bodyguard",
+				[Job.RECRUITER]: "recruiter",
+				[Job.HEADGIRL]: "headgirl",
+				[Job.ARCADE]: "arcade",
+				[Job.MADAM]: "madam",
+				[Job.BROTHEL]: "brothel",
+				[Job.WARDEN]: "warden",
+				[Job.CELLBLOCK]: "cellblock",
+				[Job.DJ]: "dj",
+				[Job.CLUB]: "club",
+				[Job.NURSE]: "nurse",
+				[Job.CLINIC]: "clinic",
+				[Job.MILKMAID]: "milkmaid",
+				[Job.DAIRY]: "dairy",
+				[Job.FARMER]: "farmer",
+				[Job.FARMYARD]: "farmyard",
+				[Job.HEADGIRLSUITE]: "headgirlsuite",
+				[Job.CONCUBINE]: "concubine",
+				[Job.MASTERSUITE]: "mastersuite",
+				[Job.MATRON]: "matron",
+				[Job.NURSERY]: "nursery",
+				[Job.TEACHER]: "teacher",
+				[Job.SCHOOL]: "school",
+				[Job.STEWARD]: "steward",
+				[Job.QUARTER]: "quarter",
+				[Job.ATTENDANT]: "attendant",
+				[Job.SPA]: "spa"
+			};
+			return jobs[assignment];
+		}
 	}
 
 	/** @param {object} o */
@@ -2294,6 +2457,27 @@ App.Entity.Utils.RARuleDatatypeCleanup = function() {
 			}
 		}
 
+		/**
+		 * Converts numeric target to range.
+		 * Conversion is valid only for integer targets
+		 * @param {FC.RA.NumericTarget} tgt
+		 * @returns {FC.NumericRange}
+		 */
+		function targetToRange(tgt) {
+			switch (tgt.cond) {
+				case '==':
+					return App.Utils.makeRange(tgt.val, tgt.val);
+				case "<=":
+					return App.Utils.makeRange(Number.NEGATIVE_INFINITY, tgt.val);
+				case "<":
+					return App.Utils.makeRange(Number.NEGATIVE_INFINITY, tgt.val - 1);
+				case ">=":
+					return App.Utils.makeRange(tgt.val, Number.POSITIVE_INFINITY);
+				case ">":
+					return App.Utils.makeRange(tgt.val + 1, Number.POSITIVE_INFINITY);
+			}
+		}
+
 		if (!([true, false, null].includes(set.preg))) {
 			set.preg = (set.preg === -1);
 		}
@@ -2316,7 +2500,7 @@ App.Entity.Utils.RARuleDatatypeCleanup = function() {
 
 		// moving numeric diets to the 'weight' attribute
 		if (typeof set.diet === 'number') {
-			set.weight = App.RA.makeRange(set.diet, set.diet);
+			set.weight = App.Utils.makeRange(set.diet, set.diet);
 			set.diet = null;
 		}
 
@@ -2405,6 +2589,12 @@ App.Entity.Utils.RARuleDatatypeCleanup = function() {
 				}
 			}
 		}
+
+		for (const n of ["boobs", "butt", "lips"]) {
+			if (set.surgery[n] && typeof set.surgery[n].cond !== "undefined") {
+				set.surgery[n] = targetToRange(set.surgery[n]);
+			}
+		}
 	}
 }();
 
diff --git a/src/facilities/farmyard/farmyardBC.js b/src/data/backwardsCompatibility/farmyardBC.js
similarity index 57%
rename from src/facilities/farmyard/farmyardBC.js
rename to src/data/backwardsCompatibility/farmyardBC.js
index aa708d187d7847ff1d25d3780ae63f69d7be779c..0774ab9ee51c51b108accff12f0851ab787761d2 100644
--- a/src/facilities/farmyard/farmyardBC.js
+++ b/src/data/backwardsCompatibility/farmyardBC.js
@@ -32,15 +32,34 @@ App.Facilities.Farmyard.BC = function() {
 		delete V.feline;
 	}
 
+	if (V.animals.canine.some(animal => typeof animal !== "string")) {
+		V.animals.canine = V.animals.canine.filter(animal => typeof animal === "string");
+		V.active.canine = V.animals.canine || null;
+	}
+	if (V.animals.hooved.some(animal => typeof animal !== "string")) {
+		V.animals.hooved = V.animals.hooved.filter(animal => typeof animal === "string");
+		V.active.hooved = V.animals.hooved || null;
+	}
+	if (V.animals.feline.some(animal => typeof animal !== "string")) {
+		V.animals.feline = V.animals.feline.filter(animal => typeof animal === "string");
+		V.active.feline = V.animals.feline || null;
+	}
+
 	if (V.active.canine && typeof V.active.canine !== "string") {
 		V.active.canine = V.active.canine.name;
 	}
-
 	if (V.active.hooved && typeof V.active.hooved !== "string") {
 		V.active.hooved = V.active.hooved.name;
 	}
-
 	if (V.active.feline && typeof V.active.feline !== "string") {
 		V.active.feline = V.active.feline.name;
 	}
+
+	if (V.farmyardShowgirls) {
+		delete V.farmyardShowgirls;
+	}
+
+	if (V.farmyardFarmers) {
+		delete V.farmyardFarmers;
+	}
 };
diff --git a/src/facilities/pit/pitBC.js b/src/data/backwardsCompatibility/pitBC.js
similarity index 88%
rename from src/facilities/pit/pitBC.js
rename to src/data/backwardsCompatibility/pitBC.js
index 1811a0f6a5295feec11abb20e3d12a138c579ea2..eeb2d3437cc48a0e0133c64c63fa5225751ef549 100644
--- a/src/facilities/pit/pitBC.js
+++ b/src/data/backwardsCompatibility/pitBC.js
@@ -32,10 +32,10 @@ App.Facilities.Pit.BC = function() {
 		V.pit.fought = V.pit.fought || V.pitFought || false;
 
 		V.pit.slavesFighting = V.pit.slavesFighting || [];
+		V.pit.decoration = V.pit.decoration || "standard";
 	}
 
-	if (V.slaveFightingBG) {
-		V.pit.slaveFightingBodyguard = V.slaveFightingBG;
-		delete V.slaveFightingBG;
+	if (V.slaveFightingBG && V.pit) {
+			V.pit.slaveFightingBodyguard = V.slaveFightingBG;
 	}
 };
diff --git a/src/data/backwardsCompatibility/policiesBC.js b/src/data/backwardsCompatibility/policiesBC.js
index af28db08ccd7df11a64bc1ea017a14a3784a9805..3143dead083184a99bfb780f95dc95c043f9c31d 100644
--- a/src/data/backwardsCompatibility/policiesBC.js
+++ b/src/data/backwardsCompatibility/policiesBC.js
@@ -13,13 +13,11 @@ App.Update.policies = function() {
 		}
 	}
 
-	if (V.policies.gumjobFetishism == null) {
-		V.policies.gumjobFetishism = 0;
-	}
-
-	if (V.policies.gumjobFetishismSMR == null) {
-		V.policies.gumjobFetishismSMR = 0;
-	}
+	App.Update.setNonexistentProperties(V.policies, {
+		gumjobFetishism: 0,
+		gumjobFetishismSMR: 0,
+		idealAge: 0
+	});	
 
 	// Spelling fixes:
 	V.policies.sexualOpenness = V.policies.sexualOpenness || V.policies.sexualOpeness || 0;
diff --git a/src/data/backwardsCompatibility/updateCustomSlaveOrder.js b/src/data/backwardsCompatibility/updateCustomSlaveOrder.js
index d58dec2814789d7140d19aade73beb4e0b25f707..fb3c0ac2b4d7b38061a3bebee205764b7c5a4266 100644
--- a/src/data/backwardsCompatibility/updateCustomSlaveOrder.js
+++ b/src/data/backwardsCompatibility/updateCustomSlaveOrder.js
@@ -6,7 +6,7 @@ App.Update.CustomSlaveOrder = function(customSlaveOrder) {
 		if (jsDef(customSlaveOrder.amp) && customSlaveOrder.amp === 1) {
 			customSlaveOrder.leg = {left: null, right: null};
 		} else {
-			customSlaveOrder.leg = {left: new App.Entity.LimbState(), right: new App.Entity.LimbState()};
+			customSlaveOrder.leg = {left: new App.Entity.LegState(), right: new App.Entity.LegState()};
 		}
 	}
 
@@ -14,7 +14,7 @@ App.Update.CustomSlaveOrder = function(customSlaveOrder) {
 		if (jsDef(customSlaveOrder.amp) && customSlaveOrder.amp === 1) {
 			customSlaveOrder.arm = {left: null, right: null};
 		} else {
-			customSlaveOrder.arm = {left: new App.Entity.LimbState(), right: new App.Entity.LimbState()};
+			customSlaveOrder.arm = {left: new App.Entity.LegState(), right: new App.Entity.LegState()};
 		}
 	}
 
diff --git a/src/data/backwardsCompatibility/updateSlaveObject.js b/src/data/backwardsCompatibility/updateSlaveObject.js
index 067747223df29d49b5a40c3f44be1c43685b464f..a88e58b40abfceda1f25b300e454fd9fe0c58759 100644
--- a/src/data/backwardsCompatibility/updateSlaveObject.js
+++ b/src/data/backwardsCompatibility/updateSlaveObject.js
@@ -4,6 +4,8 @@
  * @param {boolean} [genepool=false]
  */
 App.Update.Slave = function(slave, genepool = false) {
+	slave.career = slave.career || "a slave";
+	slave.origin = slave.origin || "";
 	const quirks = {};
 	App.Data.geneticQuirks.forEach((value, q) => quirks[q] = 0);
 	slave.geneticQuirks = Object.assign(clone(quirks), slave.geneticQuirks);
@@ -26,6 +28,7 @@ App.Update.Slave = function(slave, genepool = false) {
 		hEffect: "none",
 		hEffectColor: "none",
 		tailEffect: "none",
+		tailEffectColor: "none",
 		appendagesEffect: "none",
 		appendagesEffectColor: "none",
 		daughters: 0,
@@ -97,11 +100,12 @@ App.Update.Slave = function(slave, genepool = false) {
 		}
 	}
 	if (slave.genetics !== undefined) { delete slave.genetics; }
-	slave.geneMods = Object.assign({NCS: 0, rapidCellGrowth: 0, immortality: 0}, slave.geneMods);
+	slave.geneMods = Object.assign({NCS: 0, rapidCellGrowth: 0, immortality: 0, bioEngineeredMilkFlavoring: 0}, slave.geneMods);
 	if (slave.inducedNCS !== undefined) {
 		slave.geneMods.NCS = slave.inducedNCS;
 		delete slave.inducedNCS;
 	}
+	if (slave.milkFlavor === undefined) {slave.milkFlavor = "none"}
 	if (slave.PCSlutContacts !== undefined) { delete slave.PCSlutContacts; }
 	if (slave.superfetation !== undefined) { delete slave.superfetation; }
 	if (slave.lactationDuration === undefined) {
@@ -113,7 +117,7 @@ App.Update.Slave = function(slave, genepool = false) {
 	}
 
 	if (slave.reservedChildren !== undefined) { delete slave.reservedChildren; }
-	if (slave.origin !== undefined && slave.origin !== 0) { slave.origin = pronounReplacer(slave.origin); }
+	if (slave.origin !== undefined && slave.origin !== "") { slave.origin = pronounReplacer(slave.origin); }
 	if (slave.custom !== undefined) {
 		if (slave.custom.desc !== undefined && slave.custom.desc !== "") {
 			slave.custom.desc = pronounReplacer(slave.custom.desc);
@@ -926,4 +930,36 @@ App.Update.Slave = function(slave, genepool = false) {
 	slave.womb.forEach(f => {
 		f.genetics.geneticQuirks = Object.assign(clone(quirks), f.genetics.geneticQuirks);
 	});
+
+	if (V.releaseID < 1161 && !genepool) {
+		// transfer scars from body to limbs if needed.
+		const scars = slave.scar;
+		const brands = slave.brand;
+		slave.scar = {};
+		slave.brand = {};
+		if (slave.leg.left) {
+			slave.leg.left.scar = {};
+			slave.leg.left.brand = {};
+		}
+		if (slave.leg.right) {
+			slave.leg.right.scar = {};
+			slave.leg.right.brand = {};
+		}
+		if (slave.arm.left) {
+			slave.arm.left.scar = {};
+			slave.arm.left.brand = {};
+		}
+		if (slave.arm.right) {
+			slave.arm.right.scar = {};
+			slave.arm.right.brand = {};
+		}
+		for (const location in scars) {
+			for (const design in scars[location]) {
+				App.Medicine.Modification.addScar(slave, location, design, scars[location][design]);
+			}
+		}
+		for (const location in brands) {
+			App.Medicine.Modification.addBrand(slave, location, scars[location]);
+		}
+	}
 };
diff --git a/src/data/newGamePlus.js b/src/data/newGamePlus.js
index 12995cee6e95ab065388041c199600d58c1b4cf1..85b0a7877f5a6e445ad34f040bc3077658bde23f 100644
--- a/src/data/newGamePlus.js
+++ b/src/data/newGamePlus.js
@@ -220,10 +220,23 @@ App.Data.NewGamePlus = (function() {
 		}
 	}
 
+	function updateMods() {
+		if (V.mods.food.enabled) {
+			V.mods.food.amount = 0;
+			V.mods.food.lastWeek = 0;
+			V.mods.food.market = false;
+			V.mods.food.produced = 0;
+			V.mods.food.rations = 0;
+			V.mods.food.total = 0;
+			V.mods.food.warned = false;
+		}
+	}
+
 	function doNGPSetup() {
 		slaveLoopInit();
 		PCInit();
 		resetFamilyCounters();
+		updateMods();
 		V.ngpParams = {};
 	}
 
diff --git a/src/debugging/debugJS.js b/src/debugging/debugJS.js
index 9e7c48e295ee64db09ab703d1a710d207cf83def..d9710c3f99882b6b59834f05bb30984f600bb173 100644
--- a/src/debugging/debugJS.js
+++ b/src/debugging/debugJS.js
@@ -106,18 +106,15 @@ App.Debug.dumpGameState = function() {
 		a.click();
 	}
 
-	// we will replace SugarCube onSave handler
-	let oldHandler = SugarCube.Config.saves.onSave;
+	const handler = (save) => {
+		downloadToFile(JSON.stringify(save, null, 2), save.id + ".json", "text/plain");
+	};
+
+	Save.onSave.add(handler);
 	try {
-		SugarCube.Config.saves.onSave = function(save, details) {
-			if (oldHandler) {
-				oldHandler(save, details);
-			}
-			downloadToFile(JSON.stringify(save, null, 2), save.id + ".json", "text/plain");
-		};
 		SugarCube.Save.serialize();
 	} finally {
-		SugarCube.Config.saves.onSave = oldHandler;
+		Save.onSave.delete(handler);
 	}
 };
 
diff --git a/src/descriptions/arcologyDescription.js b/src/descriptions/arcologyDescription.js
index 0287dc0caa5a8073cf13e5fb824a58ff2bc9db8b..332409c6f9f6ca46ca0e51e1aed01093272c4b95 100644
--- a/src/descriptions/arcologyDescription.js
+++ b/src/descriptions/arcologyDescription.js
@@ -436,6 +436,12 @@ App.Desc.playerArcology = function(lastElement) {
 						buffer.push(`${t} a trap's tight ass.`);
 					}
 				}
+
+				const slaves = App.Entity.facilities.brothel.employees();
+
+				if (slaves.length > 5 && slaves.every(slave => slave.face > 40)) {
+					buffer.push(`${V.arcologies[0].name} is known for its beautiful whores.`);
+				}
 			}
 			if (V.clubAdsSpending > 0) {
 				buffer.push(`Music videos set in ${V.clubName} are also shown frequently.`);
@@ -829,7 +835,7 @@ App.Desc.playerArcology = function(lastElement) {
 			buffer.push(`Giggles and moans are drifting out of a hallway off the plaza.`);
 		}
 		if (A.FSRestartDecoration >= 80) {
-			buffer.push(`The sound of a fertile slave being viciously beaten can be heard from a side hall.`);
+			buffer.push(`The sound of a fertile slave being ${A.FSPaternalist > 20 ? `viciously beaten` : `"reeducated"`} can be heard from a side hall.`);
 		}
 		if (A.FSYouthPreferentialistDecoration >= 80) {
 			buffer.push(`The squeals of a young slave taking cock in a tight hole are coming from somewhere off the plaza.`);
@@ -994,7 +1000,7 @@ App.Desc.playerArcology = function(lastElement) {
 		const frag = document.createDocumentFragment();
 
 		if (V.plot) {
-			if (V.peacekeepers === 0) {
+			if (V.peacekeepers.state <= 1) {
 				if (V.invasionVictory) {
 					frag.append(`The area previously occupied by the little old world country whose collapse led to a failed invasion of the Free City is a lawless wilderness.`);
 				} else if (V.week > 29) {
diff --git a/src/descriptions/officeDescription.js b/src/descriptions/officeDescription.js
index e634df1f25df84b83cee9fab0c7caa01318e97fe..3880380a73ba6581702d33243dc38097b297db79 100644
--- a/src/descriptions/officeDescription.js
+++ b/src/descriptions/officeDescription.js
@@ -633,7 +633,7 @@ App.Desc.officeDescription = function(lastElement) {
 						r.push(`Cloth napkins skillfully folded into ${napkinMap.size === 1 ? "a single shape" : "various shapes"} by your slaves.`);
 						// Make a fragment for each napkin type that we have, including the slaves that made that type
 						for (const [shape, slaves] of napkinMap) {
-							r.push(App.UI.DOM.combineNodes(slaveSentence(slaves), ` ${slaves.length === 1 ? "" : "each "}made ${shape}.`, ));
+							r.push(App.UI.DOM.combineNodes(slaveSentence(slaves), ` ${slaves.length === 1 ? "" : "each "}made ${shape}.`,));
 						}
 						App.Events.addNode(el, r);
 					}
@@ -641,6 +641,11 @@ App.Desc.officeDescription = function(lastElement) {
 				} else {
 					return null;
 				}
+			case "a poster for the movie that was made about the love between one of your mercenaries and": {
+				const el = document.createElement("span");
+				el.append("A poster for the movie that was made about the love between one of your mercenaries and ", slaveSentence(array), ".");
+				return el;
+			}
 			// should never have plurals
 			case "a collection of diplomas from expensive schools":
 			case "a framed low denomination piece of paper money from your native country":
@@ -678,13 +683,20 @@ App.Desc.officeDescription = function(lastElement) {
 				}
 				return App.UI.DOM.makeElement("span", capFirstChar(desc));
 		}
+
+		/**
+		 * @param slaveArray
+		 * @returns {DocumentFragment}
+		 */
 		function slaveSentence(slaveArray) {
 			const nameArray = [];
 			for (const obj of slaveArray) {
 				if (obj.id && getSlave(obj.id)) {
 					nameArray.push(App.UI.DOM.link(
 						getSlave(obj.id).slaveName,
-						() => { V.AS = obj.id; },
+						() => {
+							V.AS = obj.id;
+						},
 						[],
 						"Slave Interact"
 					));
diff --git a/src/endWeek/economics/arcmgmt.js b/src/endWeek/economics/arcmgmt.js
index a52cdb25d9fd7b8012546aeb05853d8d71c6c7bb..e2e7247001659102dac73424fd68c47d18d91995 100644
--- a/src/endWeek/economics/arcmgmt.js
+++ b/src/endWeek/economics/arcmgmt.js
@@ -1,6 +1,6 @@
 App.EndWeek.arcManagement = function() {
 	const el = new DocumentFragment();
-	const secExpImmigrationBonus = App.SecExp.propagandaEffects("immigration");
+	const secExpImmigrationBonus = App.Mods.SecExp.propagandaEffects("immigration");
 	let r;
 	let enslaved;
 	let rentMultiplier;
@@ -94,7 +94,7 @@ App.EndWeek.arcManagement = function() {
 
 	V.ASlaves = V.NPCSlaves + V.menials + V.fuckdolls + V.menialBioreactors;
 	if (V.secExpEnabled > 0) {
-		V.ASlaves += (V.SecExp.buildings.secHub ? V.SecExp.buildings.secHub.menials : 0) + App.SecExp.Manpower.employedSlave;
+		V.ASlaves += (V.SecExp.buildings.secHub ? V.SecExp.buildings.secHub.menials : 0) + App.Mods.SecExp.Manpower.employedSlave;
 	}
 	V.ACitizens = V.lowerClass + V.middleClass + V.upperClass + V.topClass;
 	const percOfPop = (n) => Math.trunc((n / (V.ACitizens + V.ASlaves)) * 1000) / 10;
@@ -196,6 +196,37 @@ App.EndWeek.arcManagement = function() {
 	if (V.arcologies[0].FSHedonisticDecadenceSMR === 1) {
 		r.push(`The arcology must import a very large quantity of fattening food to plump up its slaves.`);
 	}
+	r.push(`Polling finds the most attractive age to be ${V.idealAge}.`);
+	if (V.policies.idealAge) {
+		if (V.targetIdealAge !== V.idealAge) {
+			r.push(`You use your wealth and personal influence to try and shift it to ${V.targetIdealAge}`);
+			V.idealAgeAdoption += V.rep / 100;
+			if (V.idealAgeAdoption > 100) {
+				const adoptionModifier = Math.floor(V.idealAgeAdoption / 100);
+				if (V.targetIdealAge > V.idealAge) {
+					V.idealAge = Math.clamp(Math.floor(V.idealAge + adoptionModifier), V.idealAge, V.targetIdealAge);
+				} else {
+					V.idealAge = Math.clamp(Math.floor(V.idealAge - adoptionModifier), V.idealAge, V.targetIdealAge);
+				}
+				if (adoptionModifier > 1) {
+					r.push(`and, with your peerless reputation, ${V.idealAge === V.targetIdealAge ? `find it <span class="green">accepted wholeheartedly` : `<span class="green">quickly gain support`}.</span>`);
+				} else if (V.idealAge === V.targetIdealAge) {
+					// TODO:
+				} else {
+					r.push(`, but tastes don't change quickly, so it ends up at ${V.idealAge}.`);
+				}
+				V.idealAgeAdoption = V.idealAgeAdoption - (100 * adoptionModifier);
+			} else {
+				if (V.idealAgeAdoption <= 0) {
+					r.push(r.pop() + `; unfortunately, your efforts <span class="red">have no effect</span> on what others find sexually appealing, and so it remains where it is.`);
+				} else {
+					r.push(`and make <span class="yellow">some progress</span> in doing so, but for now, society's tastes do not change.`);
+				}
+			}
+		} else {
+			V.policies.idealAge = 0;
+		}
+	}
 
 	if (V.ACitizens > V.ASlaves * 2) { /* This will need to go away Eventually*/
 		r.push(`Since most citizens do not own sex slaves, <span class="yellowgreen">demand for sexual services is intense.</span>`);
@@ -607,11 +638,11 @@ App.EndWeek.arcManagement = function() {
 					delete V.SecExp.smilingMan.globalCrisisWeeks;
 				}
 			}
-			const reactorDamaged = App.SecExp.updateFacilityDamage("reactor");
+			const reactorDamaged = App.Mods.SecExp.updateFacilityDamage("reactor");
 			r.push(reactorDamaged.text);
 			AWeekGrowth -= reactorDamaged.growth;
 
-			const secExpTrade = App.SecExp.tradeReport();
+			const secExpTrade = App.Mods.SecExp.tradeReport();
 			r.push(secExpTrade.text);
 			AWeekGrowth += secExpTrade.bonus;
 			App.Events.addParagraph(el, r);
@@ -1460,7 +1491,7 @@ App.EndWeek.arcManagement = function() {
 				transportHub += V.SecExp.buildings.transportHub.airport / 10 + V.SecExp.buildings.transportHub.surfaceTransport / 10;
 			}
 			crime = (100 - V.SecExp.core.crimeLow) / 100 + 0.2;
-			const waterwayDamaged = App.SecExp.updateFacilityDamage("waterway");
+			const waterwayDamaged = App.Mods.SecExp.updateFacilityDamage("waterway");
 			appendDiv(waterwayDamaged.text);
 		}
 		const terrainFactors = {
@@ -1484,8 +1515,8 @@ App.EndWeek.arcManagement = function() {
 				V.visitors = normalRandInt(50, 2);
 			}
 			appendDiv(`<span class="green">${num(V.visitors)} traders and tourists</span> visited your arcology this week.`);
-			appendDiv(App.SecExp.propagandaEffects("enslavement").text);
-			enslaved += App.SecExp.propagandaEffects("enslavement").effect;
+			appendDiv(App.Mods.SecExp.propagandaEffects("enslavement").text);
+			enslaved += App.Mods.SecExp.propagandaEffects("enslavement").effect;
 		}
 
 		/* Slaves getting retired - happens even when frozen */
diff --git a/src/endWeek/economics/economics.js b/src/endWeek/economics/economics.js
index 7f6deadd27aeaf292d9ccd41a93f4daede624d40..1bf6ae3d620fe531bbe3512a7e1959a40e784399 100644
--- a/src/endWeek/economics/economics.js
+++ b/src/endWeek/economics/economics.js
@@ -5,7 +5,7 @@ App.EndWeek.economics = function() {
 	if (V.cash > -10000) {
 		V.debtWarned = 0;
 	}
-	if (V.mods.food.market &&
+	if (V.mods.food.enabled && V.mods.food.market &&
 		(V.mods.food.amount > App.Facilities.Farmyard.foodConsumption() ||
 		V.cash > App.Facilities.Farmyard.foodConsumption() * V.mods.food.cost)) {
 		V.mods.food.warned = false;
@@ -48,12 +48,12 @@ App.EndWeek.economics = function() {
 		["authority", {
 			name: "Authority",
 			get requirements() { return V.secExpEnabled > 0; },
-			get report() { return App.SecExp.authorityReport(); }
+			get report() { return App.Mods.SecExp.authorityReport(); }
 		}],
 		["securityReport", {
 			name: "Security",
 			get requirements() { return V.secExpEnabled > 0; },
-			get report() { return App.SecExp.securityReport(); }
+			get report() { return App.Mods.SecExp.securityReport(); }
 		}],
 		["reputation", {
 			name: "Reputation",
diff --git a/src/endWeek/economics/fsDevelopments.js b/src/endWeek/economics/fsDevelopments.js
index 57584da363449990683d04a429038c9d90e5b7be..8a9609099e1bb2a8e096f8772e20f43385434384 100644
--- a/src/endWeek/economics/fsDevelopments.js
+++ b/src/endWeek/economics/fsDevelopments.js
@@ -72,7 +72,7 @@ App.EndWeek.FSDevelopments = function() {
 		}
 	}
 
-	const propagandaEffects = App.SecExp.propagandaEffects("social engineering");
+	const propagandaEffects = App.Mods.SecExp.propagandaEffects("social engineering");
 	r.push(propagandaEffects.text);
 	broadProgress += propagandaEffects.effect;
 
diff --git a/src/endWeek/economics/neighborsDevelopment.js b/src/endWeek/economics/neighborsDevelopment.js
index 1d801ee963c1c82f25e754267b301b905ba5d9e8..3c9c401295eda4fcb8261e7a7966e613688d60e5 100644
--- a/src/endWeek/economics/neighborsDevelopment.js
+++ b/src/endWeek/economics/neighborsDevelopment.js
@@ -82,7 +82,7 @@ App.EndWeek.neighborsDevelopment = function() {
 		} else {
 			millions = `m`;
 		}
-		r.push(`has an estimated GSP of <span class="yellowgreen">${cashFormat(prosperity)}${millions},</span>`);
+		r.push(`has an estimated GSP of <span class="yellowgreen">${prosperity > 0 ? `${cashFormat(prosperity)}` : `less than ${num(1)} `}${millions},</span>`);
 		if (arc.rival === 1 && arc.government !== "an individual") {
 			r.push(`but it is undergoing some internal turmoil. <span class="red">Resentment that has been quietly building among the arcology's elite turns into open rebellion!</span>`);
 			if (arc.PCminority > 0) {
@@ -330,7 +330,7 @@ App.EndWeek.neighborsDevelopment = function() {
 					redHanded = 1;
 					repX(forceNeg(random(100, 200)), "war");
 					if (V.secExpEnabled > 0) {
-						App.SecExp.authorityX(random(-100, -500) * V.arcologies[0].CyberEconomic);
+						App.Mods.SecExp.authorityX(random(-100, -500) * V.arcologies[0].CyberEconomic);
 						V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow + random(10, 25), 0, 100);
 					}
 					V.arcologies[0].prosperity = Math.clamp(V.arcologies[0].prosperity, 1, V.AProsperityCap);
@@ -377,7 +377,7 @@ App.EndWeek.neighborsDevelopment = function() {
 					redHanded = 1;
 					repX(forceNeg(random(100, 200)), "war");
 					if (V.secExpEnabled > 0) {
-						App.SecExp.authorityX(random(-100, -500) * V.arcologies[0].CyberReputation);
+						App.Mods.SecExp.authorityX(random(-100, -500) * V.arcologies[0].CyberReputation);
 						V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow + random(10, 25), 0, 100);
 					}
 					V.arcologies[0].prosperity = Math.clamp(V.arcologies[0].prosperity, 1, 300);
@@ -1439,6 +1439,9 @@ App.EndWeek.neighborsDevelopment = function() {
 					const dipFSes = FutureSocieties.diplomaticFSes(arc, arc2);
 					for (const sharedFS of dipFSes.shared) {
 						if (arc2[sharedFS] > 60) {
+							if (sharedFS === "FSNull") {
+								continue; // Multiculturalism is not affected by influence.
+							}
 							arc[sharedFS] += Math.trunc((arc2[sharedFS] - 60) / 4) + appliedInfluenceBonus;
 							if (arc[sharedFS] > V.FSLockinLevel) {
 								alignment += 1;
@@ -1454,6 +1457,9 @@ App.EndWeek.neighborsDevelopment = function() {
 					}
 					for (const [arcFS, arc2FS] of dipFSes.conflicting) {
 						if (arc2[arc2FS] > 60) {
+							if (arcFS === "FSNull") {
+								continue; // Multiculturalism is not affected by influence.
+							}
 							arc[arcFS] -= Math.trunc((arc2[arc2FS] - 60) / 4) + appliedInfluenceBonus;
 							if (arcFS === "FSSubjugationist" && arc2FS === "FSSupremacist") {
 								attacking.push("opposing Subjugationism");
@@ -1534,9 +1540,8 @@ App.EndWeek.neighborsDevelopment = function() {
 		App.Events.addParagraph(el, r);
 	}
 
-	/* PEACEKEEPERS */
-
-	if (V.plot && V.peacekeepers !== 0) {
+	// PEACEKEEPERS
+	if (V.plot && V.peacekeepers.state >= 2) {
 		let prisoners;
 		let r = [];
 		if (V.peacekeepers.strength >= 50) {
@@ -1554,14 +1559,11 @@ App.EndWeek.neighborsDevelopment = function() {
 			r.push(`<span class="yellow">The peacekeeping force led by General ${V.peacekeepers.generalName} in the troubled area near the Free City has been withdrawn.</span>`);
 			if (V.peacekeepers.undermining) {
 				r.push(`Your misinformation campaign against it in the old world media was successful. Before long, everyone in the Free City is confident that you're somehow responsible, <span class="green">greatly improving your reputation.</span>`);
-				V.peacekeepers = 0;
-				V.peacekeepersGone = 1;
 				repX(2000, "peacekeepers");
 			} else {
 				r.push(`The cost was ultimately too high. The time when old world countries could afford to waste billions on military adventurism is gone. It will not return.`);
-				V.peacekeepers = 0;
-				V.peacekeepersGone = 1;
 			}
+			V.peacekeepers.state = 0;
 		} else {
 			r.push(`There's a peacekeeping force led by General ${V.peacekeepers.generalName} in the troubled area near the Free City.`);
 			if (V.peacekeepers.undermining) {
@@ -1647,10 +1649,10 @@ App.EndWeek.neighborsDevelopment = function() {
 
 			if (arc.rival === 1) {
 				if (arc.government === "an individual") {
-					if (V.rivalryFSAdopted === 0) {
-						V.rivalryFSAdopted = 1;
+					if (!V.rival.FS.adopted) {
+						V.rival.FS.adopted = 1;
 						const desc = "Its owner is";
-						switch (V.rivalryFS) {
+						switch (V.rival.FS.name) {
 							case "Racial Subjugationism":
 								r.push(`${desc} preoccupied by belief in the superiority of the ${V.arcologies[0].FSSubjugationistRace} race, leading the arcology to <span class="yellow">adopt ${V.arcologies[0].FSSubjugationistRace} Supremacy.</span>`);
 								adoptRivalFS("FSSupremacist");
@@ -1711,7 +1713,7 @@ App.EndWeek.neighborsDevelopment = function() {
 								return;
 							case "Petite Admiration":
 								r.push(`${desc} convinced that tall equals beauty, leading the arcology to <span class="yellow">adopt Statuesque Glorification.</span>`);
-								adoptRivalFS("FSSlaveProfessionalism");
+								adoptRivalFS("FSStatuesqueGlorification");
 								return;
 							case "Statuesque Glorification":
 								r.push(`${desc} enamored by those shorter than them, leading the arcology to <span class="yellow">adopt Petite Admiration.</span>`);
@@ -1775,7 +1777,7 @@ App.EndWeek.neighborsDevelopment = function() {
 								adoptRivalFS("FSRomanRevivalist");
 								return;
 							default:
-								V.rivalryFSAdopted = 0;
+								delete V.rival.FS.adopted;
 						}
 					} else { // RIVAL ADOPTION
 						let desc = "Its owner is";
diff --git a/src/endWeek/economics/persBusiness.js b/src/endWeek/economics/persBusiness.js
index 0f2ecaf2095b9a9d753ce99b8e1f46e5a6a398a6..50dbd9cff67f3d7118ea1eb07e157f62540f94e6 100644
--- a/src/endWeek/economics/persBusiness.js
+++ b/src/endWeek/economics/persBusiness.js
@@ -46,7 +46,7 @@ App.EndWeek.personalBusiness = function() {
 			}
 		}
 	}
-	if (V.mods.food.market) {
+	if (V.mods.food.enabled && V.mods.food.market) {
 		if (V.mods.food.amount < App.Facilities.Farmyard.foodConsumption() && V.cash < (App.Facilities.Farmyard.foodConsumption() * V.mods.food.cost)) {
 			r.push(`<span class="red">WARNING: your arcology will starve in the coming week unless action is taken.</span>`);
 			if (V.mods.food.warned) {
@@ -56,7 +56,7 @@ App.EndWeek.personalBusiness = function() {
 				V.mods.food.warned = true;
 				r.push(
 					`Immediately purchase more food or acquire enough capital to purchase the required amount.`,
-					`You can also renege on your deal to provide a marketplace for food, but your citizens may hate you for it,`,
+					`You can also renege on your deal to provide a marketplace for food, but your citizens may hate you for it.`,
 				);
 			}
 		}
@@ -532,7 +532,7 @@ App.EndWeek.personalBusiness = function() {
 				V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow - 25, 0, 100);
 			}
 			if (V.SecExp.proclamation.currency === "authority") {
-				App.SecExp.authorityX(-2000);
+				App.Mods.SecExp.authorityX(-2000);
 			} else if (V.SecExp.proclamation.currency === "reputation") {
 				repX(Math.clamp(V.rep - 2000, 0, 20000), "personalBusiness");
 			} else {
@@ -803,7 +803,7 @@ App.EndWeek.personalBusiness = function() {
 					if (V.secExpEnabled > 0) {
 						X = 1;
 						r.push(`<span class="red">authority,</span>`);
-						App.SecExp.authorityX(random(-100, -500));
+						App.Mods.SecExp.authorityX(random(-100, -500));
 						r.push(`<span class="red">crime rate</span>`);
 						V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow + random(10, 25), 0, 100);
 						r.push(`and`);
@@ -873,10 +873,13 @@ App.EndWeek.personalBusiness = function() {
 			}
 		}
 	}
-	if (V.mods.food.enabled && V.mods.food.market && V.mods.food.amount < App.Facilities.Farmyard.foodConsumption()) {
-		const foodCost = (App.Facilities.Farmyard.foodConsumption() - V.mods.food.amount) * V.mods.food.cost;
-		r.push(`You also spent ${cashFormat(Math.trunc(foodCost))} this week buying enough food to keep your citizens fed, as you promised.`);
-		cashX(forceNeg(foodCost), "food");
+	if (V.mods.food.enabled && V.mods.food.market) {
+		if (V.mods.food.amount < App.Facilities.Farmyard.foodConsumption()) {
+			const foodCost = (App.Facilities.Farmyard.foodConsumption() - V.mods.food.amount) * V.mods.food.cost;
+			r.push(`You also spent ${cashFormat(Math.trunc(foodCost))} this week buying enough food to keep your citizens fed, as you promised.`);
+			cashX(forceNeg(foodCost), "food");
+		}
+		V.mods.food.amount -= App.Facilities.Farmyard.foodConsumption();
 	}
 	App.Events.addParagraph(el, r);
 	r = [];
@@ -900,7 +903,7 @@ App.EndWeek.personalBusiness = function() {
 				r.push(`You are selling the data collected by your security department, which earns a discreet sum of <span class="yellowgreen">${cashFormat(dataGain)}.</span>`);
 				cashX(dataGain, "personalBusiness");
 				r.push(`Many of your citizens are not enthusiastic of this however, <span class="red">damaging your authority.</span>`);
-				App.SecExp.authorityX(-50);
+				App.Mods.SecExp.authorityX(-50);
 			}
 		}
 
@@ -911,7 +914,7 @@ App.EndWeek.personalBusiness = function() {
 			cashX(blackMarket, "personalBusiness");
 		}
 
-		const arcDamaged = App.SecExp.updateFacilityDamage("arc");
+		const arcDamaged = App.Mods.SecExp.updateFacilityDamage("arc");
 		r.push(arcDamaged.text);
 
 		App.Events.addParagraph(el, r);
@@ -950,7 +953,7 @@ App.EndWeek.personalBusiness = function() {
 				r.push(`A share of our weapons production is sold to other Free Cities.`);
 				income += Math.round(V.week / 3 * price * 10 * factoryMod);
 			}
-			if (V.peacekeepers !== 0 && V.peacekeepers.strength >= 50) {
+			if (V.peacekeepers.state === 3 && V.peacekeepers.strength >= 50) {
 				r.push(`The peacekeeping force is always in need of new armaments and is happy to be supplied by their ally.`);
 				income += Math.round(V.peacekeepers.strength * price * 10 * factoryMod);
 			}
@@ -979,6 +982,60 @@ App.EndWeek.personalBusiness = function() {
 	}
 	r = [];
 	r.push(`Routine upkeep of your demesne costs <span class="yellow">${cashFormat(V.costs)}.</span>`);
+	if (V.loans.length) {
+		const loan = (/** @type {'bank'|'shark'} */ name) => V.loans.find(loan => loan.name === name);
+
+		if (V.loans.some(loan => loan.name === 'bank')) {
+			const bank = loan('bank');
+			const full = bank.full;
+			const installment = full / bank.installments;
+			const sellable = V.building.findCells(cell => cell.canBeSold());
+
+			if (V.cash > installment) {
+				r.push(`You paid the credit union your weekly payment of <span class="yellow">${cashFormat(Math.trunc(installment))}</span> this week.`);
+			} else {
+				if (sellable) {
+					r.push(`You were unable to afford your weekly payment of ${cashFormat(Math.trunc(installment))} to the credit union this week. As a result, one sector of your arcology has been repossessed and sold as per your signed contract.`);
+
+					sellable.pluck().owner = 0;
+				} else {
+					// not technically possible, but just in case
+					// Probably needs to be written better. Draw attention to the fact that the player is a minority shareholder in the arcology and thus should not be in control anyway.
+					r.push(`You were unable to afford your weekly payment of ${cashFormat(Math.trunc(installment))} this week, and since you somehow have not been ousted over not owning any sectors for the credit union to repossess, your debt was instead put on auction and summarily purchased by another slaveholder.`);
+
+					V.gameover = "debt";
+					V.nextLink = "Gameover";
+				}
+			}
+
+			cashX(forceNeg(installment), "loan");
+			loan('bank').full -= installment;
+			loan('bank').installments--;
+
+			if (loan('bank').full > 0) {
+				r.push(`You now have ${years(loan('bank').installments)} to pay off your remaining balance of ${cashFormat(Math.trunc(loan('bank').full))}.`);
+			} else {
+				r.push(`Congratulations! You have paid off your full balance.`);
+			}
+
+			if (loan('bank').full <= 0) {
+				V.loans.delete(loan('bank'));
+			}
+		}
+		if (V.loans.some(loan => loan.name === 'shark')) {
+			const bank = V.loans.some(loan => loan.name === 'bank');
+			const term = loan('shark').deadline - V.week;
+			const full = loan('shark').full;
+
+			r.push(`You ${bank ? `also ` : ``}still owe the local loanshark <span class="yellow">${cashFormat(Math.trunc(full))}.</span> You have ${years(term)} to pay the full amount.`);
+
+			if (term === 1) {
+				r.push(`The shark will send his men next week to collect on your loan if you don't pay during the week. <span class="red">Make sure you have his money ready.</span>`);
+			} else if (term === 0) {
+				r.push(`The shark will be sending his men this week to collect his money. <span class="red">Make sure you have it ready.</span>`);
+			}
+		}
+	}
 	if (V.plot === 1) {
 		if (V.week > 10) {
 			if (V.weatherToday.severity - V.weatherCladding > 2) {
@@ -1203,7 +1260,7 @@ App.EndWeek.personalBusiness = function() {
 	App.Events.addParagraph(el, r);
 
 	if (V.SF.Toggle && V.SF.Active >= 1) {
-		el.append(App.SF.AAR()[0]);
+		el.append(App.Mods.SF.AAR()[0]);
 	}
 	return el;
 };
diff --git a/src/endWeek/economics/reputation.js b/src/endWeek/economics/reputation.js
index 7263d0cb7e4b8f02f910476eed227828238627ce..de6e1493a4ca0e41a0a756c893cd8154ba4436f8 100644
--- a/src/endWeek/economics/reputation.js
+++ b/src/endWeek/economics/reputation.js
@@ -315,33 +315,38 @@ App.EndWeek.reputation = function() {
 			r.push(`The grim statue of the Smiling Man outside your arcology <span class="green">reminds the world of who managed to eliminate such a threat.</span>`);
 			repX(100, "architecture");
 		}
-
 		if (V.SecExp.edicts.weaponsLaw === 3) {
 			r.push(`The absence of any kind of restriction on weaponry within your arcology is <span class="green">welcomed by your citizens</span> as sign of your respect for the ideals the Free Cities stand for.`);
 			repX(20, "edicts");
 		}
+		if (V.SecExp.buildings.propHub && V.SecExp.buildings.propHub.upgrades.fakeNews > 0) {
+			r.push(`The authenticity department produces and distributes copious amounts of plausible enough news and reports, <span class="green">increasing your reputation.</span>`);
+			repX(10 * V.SecExp.buildings.propHub.upgrades.fakeNews, "policies");
+		}
+		const activeUnits = App.Mods.SecExp.battle.activeUnits();
+		if (activeUnits >= 4) {
+			r.push(`Your military is`);
+			if (activeUnits >= 9) {
+				r.push(`<span class="green">massive; commanding so many troops greatly</span>`);
+			} else if (activeUnits >= 7) {
+				r.push(`<span class="green">huge; commanding such a number of soldiers</span>`);
+			} else if (activeUnits >= 4) {
+				r.push(`<span class="green">at a decent size; commanding a small army</span>`);
+			}
+			r.push(`increases your reputation.`);
+			repX(12 * activeUnits, "securityExpansion");
+		}
 	}
 
 	if (V.SF.Toggle && V.SF.Active >= 1 && V.SF.UC.Assign > 0) {
 		const sfArray = [];
-		sfArray.push(`Assigning a`);
-		if (V.SF.UC.Assign === 1) {
-			sfArray.push(`small`);
-		} else {
-			sfArray.push(`large`);
-		}
+		sfArray.push(`Assigning a ${V.SF.UC.Assign === 1 ? 'small' : 'large'}`);
 		sfArray.push(`portion of ${V.SF.Lower} to <span class="green">undercover work, slightly boosts your reputation.</span>`);
 		App.Events.addNode(el, sfArray, "div");
-		let value;
-		if (V.SF.UC.Assign === 1) {
-			value = V.SF.ArmySize * 0.05;
-		} else {
-			value = V.SF.ArmySize * 0.25;
-		}
-		repX(value, "specialForces");
+		repX(V.SF.ArmySize * (V.SF.UC.Assign === 1 ? 0.05 : 0.25), "specialForces");
 	} else if (V.SF.FS.BadOutcome === "ISOLATION") {
 		r.push(App.UI.DOM.makeElement("div", `Your citizens are <span class="red">very displeased</span> that you are hosting a legion of heavily armed squatters in your basement.`));
-		repX(forceNeg(V.SF.ArmySize + App.SF.upgrades.total()), "specialForces");
+		repX(forceNeg(V.SF.ArmySize + App.Mods.SF.upgrades.total()), "specialForces");
 	}
 
 	if (V.arcologies[0].FSSupremacist !== "unset") {
@@ -904,11 +909,6 @@ App.EndWeek.reputation = function() {
 		repX(500, "policies");
 	}
 
-	if (V.secExpEnabled > 0 && V.SecExp.buildings.propHub && V.SecExp.buildings.propHub.upgrades.fakeNews > 0) {
-		r.push(`The authenticity department produces and distributes copious amounts of plausible enough news and reports, <span class="green">increasing your reputation.</span>`);
-		repX(10 * V.SecExp.buildings.propHub.upgrades.fakeNews, "policies");
-	}
-
 	App.Events.addParagraph(el, r);
 	r = [];
 	const repGain = hashSum(V.lastWeeksRepIncome);
diff --git a/src/endWeek/endWeek.js b/src/endWeek/endWeek.js
index 8e627d3daa1624bca6a1ed5b472ed3368c36613a..f83ea91958a48027201993b0dd5e6e414e844a0e 100644
--- a/src/endWeek/endWeek.js
+++ b/src/endWeek/endWeek.js
@@ -181,9 +181,8 @@ globalThis.endWeek = (function() {
 	}
 
 	function food() {
-		if (V.mods.food.market) {
+		if (V.mods.food.enabled && V.mods.food.market) {
 			V.mods.food.amount += App.Facilities.Farmyard.foodProduction();
-			V.mods.food.amount -= App.Facilities.Farmyard.foodConsumption();
 		}
 	}
 
diff --git a/src/endWeek/events/expire.js b/src/endWeek/events/expire.js
index f9173555ddecc0a6927faeffddd901e81adecf4c..ae4c1c1eabd32e598a5b11a53528cd0de57d273e 100644
--- a/src/endWeek/events/expire.js
+++ b/src/endWeek/events/expire.js
@@ -56,7 +56,7 @@ App.Events.SEExpiration = class SEExpiration extends App.Events.BaseEvent {
 				App.UI.DOM.appendNewElement("div", el, artRenderer.render(slave), ["imageRef", "tinyImg"]);
 			}
 
-			r.push(`${slave.slaveName}'s indentured servitude is ending this week, meaning that your arcology is gaining a citizen.`);
+			r.push(App.UI.DOM.combineNodes(App.UI.DOM.slaveDescriptionDialog(slave, slave.slaveName), `'s indentured servitude is ending this week, meaning that your arcology is gaining a citizen.`));
 			V.lowerClass += 1;
 
 			let seed = 0;
diff --git a/src/endWeek/minorInjuryResponse.js b/src/endWeek/minorInjuryResponse.js
index e5884279ca8b44a104efef4b2ff880d4adf40d28..79774938bd528d94e7efa5cda7c092d49fd65aa1 100644
--- a/src/endWeek/minorInjuryResponse.js
+++ b/src/endWeek/minorInjuryResponse.js
@@ -10,7 +10,7 @@ globalThis.minorInjuryResponse = function(slave) {
 	return responseWithTracking(trackedCategory());
 
 	/**
-	 * @returns {string}
+	 * @returns {keyof App.Data.Records.LastWeeksCash}
 	 */
 	function trackedCategory() {
 		switch (slave.assignment) {
@@ -27,12 +27,12 @@ globalThis.minorInjuryResponse = function(slave) {
 			case Job.CLUB:
 				return "slaveAssignmentClub";
 			default:
-				return "slaveAssignmentUndefined";
+				throw new Error(`Minor injury response requested for unexpected assignment ${slave.assignment}`);
 		}
 	}
 
 	/**
-	 * @param {string} category
+	 * @param {keyof App.Data.Records.LastWeeksCash} category
 	 * @returns {string}
 	 */
 	function responseWithTracking(category) {
diff --git a/src/endWeek/nextWeek/nextWeek.js b/src/endWeek/nextWeek/nextWeek.js
index c22693fb2bf7f73989599e137592598a4b9f9c25..4688cc0b74bf00f402e40c0577c02c1c5a0e3673 100644
--- a/src/endWeek/nextWeek/nextWeek.js
+++ b/src/endWeek/nextWeek/nextWeek.js
@@ -5,10 +5,10 @@ App.EndWeek.nextWeek = function() {
 	V.upgradeMultiplierTrade = upgradeMultiplier('trading');
 
 	const rival = V.arcologies.find(function(s) { return s.direction !== 0 && s.rival === 1; });
-	if (rival && V.rivalOwner !== 0) {
-		V.rivalOwner = rival.prosperity;
+	if (rival && V.rival.prosperity !== 0) {
+		V.rival.prosperity = rival.prosperity;
 	} else if (!rival) {
-		V.rivalSet = 0;
+		V.rival.state = 1;
 	}
 
 	if (V.playerAging !== 0) {
@@ -21,8 +21,47 @@ App.EndWeek.nextWeek = function() {
 			if (V.playerAging === 2) {
 				V.PC.physicalAge++;
 				V.PC.actualAge++;
-				V.PC.visualAge++;
-				V.PC.ovaryAge++;
+				if (V.PC.geneMods.NCS === 1 || (V.PC.geneticQuirks.neoteny >= 2 && V.PC.geneticQuirks.progeria !== 2)) {
+					/* Induced NCS completely takes over visual aging. Additionally, because of the neoteny aspects of NCS, ovaries don't age quite as fast. */
+					/* Unsurprisingly, actual neoteny has the same effect as long as progeria isn't in play. */
+					V.PC.ovaryAge += either(0.5, 0.6, 0.7, 0.7, 0.8, 0.9, 1.0);
+				} else {
+					V.PC.visualAge++;
+					V.PC.ovaryAge += either(0.8, 0.9, 0.9, 1.0, 1.0, 1.0, 1.1);
+				}
+				if (V.PC.physicalAge <= 18 && V.loliGrow > 0) {
+					// this is temporary to make physDev not wig out!
+					if (V.PC.genes === "XX") {
+						if (V.PC.pubertyXX === 1) {
+							if (V.PC.pubertyXY === 1) {
+								V.PC.hormoneBalance = 20;
+							} else {
+								V.PC.hormoneBalance = 60;
+							}
+						} else {
+							if (V.PC.pubertyXY === 1) {
+								V.PC.hormoneBalance = -20;
+							} else {
+								V.PC.hormoneBalance = 20;
+							}
+						}
+					} else if (V.PC.genes === "XY") {
+						if (V.PC.pubertyXX === 1) {
+							if (V.PC.pubertyXY === 1) {
+								V.PC.hormoneBalance = 20;
+							} else {
+								V.PC.hormoneBalance = 40;
+							}
+						} else {
+							if (V.PC.pubertyXY === 1) {
+								V.PC.hormoneBalance = -40;
+							} else {
+								V.PC.hormoneBalance = 20;
+							}
+						}
+					}
+					App.EndWeek.Shared.physicalDevelopment(V.PC, true);
+				}
 				agePCEffects();
 			}
 		}
@@ -90,7 +129,7 @@ App.EndWeek.nextWeek = function() {
 			V.localEcon = 20;
 		}
 
-		if (V.mods.food.market) {
+		if (V.mods.food.enabled && V.mods.food.market) {
 			if (V.localEcon > 100) {
 				V.mods.food.cost = Math.max(5 / (1 + (Math.trunc(1000 - 100000 / V.localEcon) / 10) / 100), 3.125);
 			} else if (V.localEcon === 100) {
diff --git a/src/endWeek/player/playerReportUtils.js b/src/endWeek/player/playerReportUtils.js
new file mode 100644
index 0000000000000000000000000000000000000000..91f17062db26afb587286b3cecd6fb1d79e7eab7
--- /dev/null
+++ b/src/endWeek/player/playerReportUtils.js
@@ -0,0 +1,120 @@
+App.EndWeek.Player.bustUp = function(PC, oldCupSize) {
+	let outcome = "";
+
+	if (oldCupSize >= 10000) {
+		// do nothing
+	} else if (oldCupSize >= 9000) {
+		if (PC.boobs >= 10000) {
+			// wip
+		}
+	} else if (oldCupSize >= 8500) {
+		if (PC.boobs >= 9000) {
+			// wip
+		}
+	} else if (oldCupSize >= 8000) {
+		if (PC.boobs >= 8500) {
+			// wip
+		}
+	} else if (oldCupSize >= 7500) {
+		if (PC.boobs >= 8000) {
+			// wip
+		}
+	} else if (oldCupSize >= 7000) {
+		if (PC.boobs >= 7500) {
+			// wip
+		}
+	} else if (oldCupSize >= 6500) {
+		if (PC.boobs >= 7000) {
+			// wip
+		}
+	} else if (oldCupSize >= 5500) {
+		if (PC.boobs >= 6500) {
+			// wip
+		}
+	} else if (oldCupSize >= 5100) {
+		if (PC.boobs >= 5500) {
+			// wip
+		}
+	} else if (oldCupSize >= 4700) {
+		if (PC.boobs >= 5100) {
+			// wip
+		}
+	} else if (oldCupSize >= 4300) {
+		if (PC.boobs >= 4700) {
+			// wip
+		}
+	} else if (oldCupSize >= 3950) {
+		if (PC.boobs >= 4300) {
+			// wip
+		}
+	} else if (oldCupSize >= 3600) {
+		if (PC.boobs >= 3950) {
+			// wip
+		}
+	} else if (oldCupSize >= 3250) {
+		if (PC.boobs >= 3600) {
+			// wip
+		}
+	} else if (oldCupSize >= 2900) {
+		if (PC.boobs >= 3250) {
+			// wip
+		}
+	} else if (oldCupSize >= 2600) {
+		if (PC.boobs >= 2900) {
+			// wip
+		}
+	} else if (oldCupSize >= 2300) {
+		if (PC.boobs >= 2600) {
+			// wip
+		}
+	} else if (oldCupSize >= 2050) {
+		if (PC.boobs >= 2300) {
+			// wip
+		}
+	} else if (oldCupSize >= 1800) {
+		if (PC.boobs >= 2050) {
+			// wip
+		}
+	} else if (oldCupSize >= 1600) {
+		if (PC.boobs >= 1800) {
+			// wip
+		}
+	} else if (oldCupSize >= 1400) {
+		if (PC.boobs >= 1600) {
+			// wip
+		}
+	} else if (oldCupSize >= 1200) {
+		if (PC.boobs >= 1400) {
+			outcome = `Your desk is steadily starting to disappear; <span class="change positive">H-cups will do that.</span>`;
+		}
+	} else if (oldCupSize >= 1000) {
+		if (PC.boobs >= 1200) {
+			outcome = `Nothing fits comfortably now; your tailor says <span class="change positive">it's your G-cup knockers.</span> Your back agrees.`;
+		}
+	} else if (oldCupSize >= 800) {
+		if (PC.boobs >= 1000) {
+			outcome = `You popped your bra when you put it on; <span class="change positive">time to order some F-cups.</span>`;
+		}
+	} else if (oldCupSize >= 650) {
+		if (PC.boobs >= 800) {
+			outcome = `Their prominence, and a quick measuring, reveals <span class="change positive">you now sport DDs.</span>`;
+		}
+	} else if (oldCupSize >= 500) {
+		if (PC.boobs >= 650) {
+			outcome = `They're big, sensitive, <span class="change positive">and now a D-cup.</span>`;
+		}
+	} else if (oldCupSize >= 400) {
+		if (PC.boobs >= 500) {
+			outcome = `They spill dramatically out of your bra now, which means <span class="change positive">you've graduated to a C-cup.</span>`;
+		}
+	} else if (oldCupSize >= 300) {
+		if (PC.boobs >= 400) {
+			outcome = `A quick measuring after your top started to feel too constricting reveals <span class="change positive">you are now a B-cup!</span>`;
+		}
+	} else {
+		if (PC.boobs >= 300) {
+			outcome = `They've gotten so big that <span class="change positive">you can now fill an A-cup bra.</span>`;
+		}
+	}
+	return outcome;
+};
diff --git a/src/endWeek/player/prDiet.js b/src/endWeek/player/prDiet.js
index 5832a9d3fd9a2d0e09f6812dfdacbe9fc729ffe0..b6e618042deaadf32545d9bad9d2129449228b28 100644
--- a/src/endWeek/player/prDiet.js
+++ b/src/endWeek/player/prDiet.js
@@ -43,7 +43,7 @@ App.EndWeek.Player.diet = function(PC = V.PC) {
 				PC.weight = Math.max(PC.weight, -100);
 				sharedAssetLoss(weightLoss);
 				if (PC.weight < -95) {
-					r.push(`You can not physically lose any more weight, so you will <span class="noteworthy">resume a normal diet</span> starting next week.`);
+					r.push(`You cannot physically lose any more weight, so you will <span class="noteworthy">resume a normal diet</span> starting next week.`);
 					PC.diet = "healthy";
 				}
 				break;
@@ -113,7 +113,7 @@ App.EndWeek.Player.diet = function(PC = V.PC) {
 				PC.weight = Math.max(PC.weight, -100);
 				sharedAssetLoss(weightLoss);
 				if (PC.weight < -95) {
-					r.push(`You can not physically lose any more weight, so you will <span class="noteworthy">resume a normal diet</span> starting next week.`);
+					r.push(`You cannot physically lose any more weight, so you will <span class="noteworthy">resume a normal diet</span> starting next week.`);
 					PC.diet = "healthy";
 				}
 				break;
@@ -472,7 +472,7 @@ App.EndWeek.Player.diet = function(PC = V.PC) {
 				break;
 			case "cleansing": // chem reduce and health plus
 				if (!canSmell(PC) && !canTaste(PC)) {
-					r.push(`<span class="health inc">You feel spectacular</span> on this health focused diet, even if you find other people try to avoid and that your slaves hold their breath when in your presence.`);
+					r.push(`<span class="health inc">You feel spectacular</span> on this health focused diet, even if you find other people try to avoid you, and that your slaves hold their breath when in your presence.`);
 				} else if (!canSmell(PC) || !canTaste(PC)) {
 					r.push(`Your specialized diet ${canTaste(PC) ? "tastes" : "smells"} awful, but leaves you <span class="health inc">feeling well</span> once you get over it.`);
 				} else {
@@ -612,10 +612,10 @@ App.EndWeek.Player.diet = function(PC = V.PC) {
 			if ((PC.geneMods.NCS === 0 && random(1, 100) > 90) || (PC.geneMods.NCS === 1 && random(1, 100) > 45)) {
 				if ((PC.geneMods.NCS === 0 && boobSize >= 200) || (PC.geneMods.NCS === 1 && boobSize > 100)) {
 					if (PC.geneMods.NCS === 0) {
-						r.push(`All the excercise <span class="change negative">cuts a little fat from your chest.</span>`);
+						r.push(`All the exercise <span class="change negative">cuts a little fat from your chest.</span>`);
 						PC.boobs -= 50;
 					} else {
-						r.push(`All the excercise <span class="change negative">cuts some fat off your chest.</span>`);
+						r.push(`All the exercise <span class="change negative">cuts some fat off your chest.</span>`);
 						PC.boobs -= 100;
 					}
 				} else if (buttSize > 1 && (PC.geneticQuirks.rearLipedema !== 2 || (buttSize > 10 && random(1, 100) > 80))) {
@@ -699,10 +699,10 @@ App.EndWeek.Player.diet = function(PC = V.PC) {
 			if ((PC.geneMods.NCS === 0 && random(1, 100) > 90) || (PC.geneMods.NCS === 1 && random(1, 100) > 45)) {
 				if ((PC.geneMods.NCS === 0 && boobSize >= 200) || (PC.geneMods.NCS === 1 && boobSize > 100) && gigantomastiaMod !== 3) {
 					if (PC.geneMods.NCS === 0) {
-						r.push(`All the excercise <span class="change negative">cuts a little fat from your chest.</span>`);
+						r.push(`All the exercise <span class="change negative">cuts a little fat from your chest.</span>`);
 						PC.boobs -= 50;
 					} else {
-						r.push(`All the excercise <span class="change negative">cuts some fat off your chest.</span>`);
+						r.push(`All the exercise <span class="change negative">cuts some fat off your chest.</span>`);
 						PC.boobs -= 100;
 					}
 				} else if (buttSize > 1 && (PC.geneticQuirks.rearLipedema !== 2 || (buttSize > 10 && random(1, 100) > 80))) {
@@ -739,10 +739,10 @@ App.EndWeek.Player.diet = function(PC = V.PC) {
 			}
 			if (((PC.geneMods.NCS === 0 && boobSize >= 200) || (PC.geneMods.NCS === 1 && (boobSize > 100))) && gigantomastiaMod !== 3) {
 				if (PC.geneMods.NCS === 0) {
-					r.push(`All the excercise <span class="change negative">cuts a little fat from your chest.</span>`);
+					r.push(`All the exercise <span class="change negative">cuts a little fat from your chest.</span>`);
 					PC.boobs -= 50;
 				} else {
-					r.push(`All the excercise <span class="change negative">cuts some fat off your chest.</span>`);
+					r.push(`All the exercise <span class="change negative">cuts some fat off your chest.</span>`);
 					PC.boobs -= 100;
 				}
 			}
diff --git a/src/endWeek/player/prHormones.js b/src/endWeek/player/prHormones.js
new file mode 100644
index 0000000000000000000000000000000000000000..7c6d7811917be33dbfef98c6a04c79d0d39d232d
--- /dev/null
+++ b/src/endWeek/player/prHormones.js
@@ -0,0 +1,903 @@
+App.EndWeek.Player.hormones = function(PC = V.PC) {
+	const r = [];
+
+	const gigantomastiaMod = PC.geneticQuirks.gigantomastia === 2 ? (PC.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
+	const rearLipedemaMod = PC.geneticQuirks.rearLipedema === 2 ? 1 : 0;
+	const boobSize = PC.boobs - PC.boobsImplant - PC.boobsMilk;
+	const buttSize = PC.butt - PC.buttImplant;
+	const selfManufactured = false; // Once a means to buy the recipes is added, this will become a ternary.
+	const hormonePower = selfManufactured ? V.hormoneUpgradePower : 1; // Prescribed ones are better to match their base price.
+	let normBreasts;
+	let normButt;
+	const faceValue = PC.face - PC.faceImplant;
+	const effects = [];
+	let faceShape = 0;
+	let faceInc = 0;
+
+	hormoneBalance();
+	if (V.hormoneUpgradeMood === 0 || !selfManufactured) {
+		moodConflict();
+	}
+	if (PC.physicalAge >= 18 || V.loliGrow === 0 || PC.geneMods.NCS === 1) {
+		hormonesEffects();
+	}
+
+	return r.join(" ");
+
+	function hormoneBalance() {
+		if (PC.hormoneBalance <= -400) {
+			r.push(`You are overflowing with masculine hormones`);
+			if (PC.hormones === 1) {
+				r.push(`and taking female ones in an attempt to balance things out.`);
+			} else if (PC.hormones === -1) {
+				r.push(r.pop() + `, supported through your continued use of artificial ones.`);
+			} else {
+				r.push(r.pop() + `, but lack the means to maintain such a state and will slowly regress to a more normal balance over time.`);
+			}
+		} else if (PC.hormoneBalance <= -300) {
+			r.push(`Your system is completely flooded with male hormones`);
+		} else if (PC.hormoneBalance <= -200) {
+			r.push(`Your body is awash with masculine hormones`);
+		} else if (PC.hormoneBalance <= -100) {
+			r.push(`Your hormone balance is overly masculine.`);
+		} else if (PC.hormoneBalance < -20) {
+			r.push(`You have a masculine hormone balance`);
+			if (PC.hormones === 1) {
+				r.push(r.pop() + `, but are taking female ones in an attempt to become feminine.`);
+			} else if (PC.hormones === -1) {
+				r.push(`being supplemented by your use of artificial hormones.`);
+			} else {
+				r.push(r.pop() + `.`);
+			}
+		} else if (PC.hormoneBalance >= 400) {
+			r.push(`You are overflowing with feminine hormones`);
+			if (PC.hormones === -1) {
+				r.push(`and taking male ones in an attempt to balance things out.`);
+			} else if (PC.hormones === 1) {
+				r.push(r.pop() + `, supported through your continued use of artificial ones.`);
+			} else {
+				r.push(r.pop() + `, but lack the means to maintain such a state and will slowly regress to a more normal balance over time.`);
+			}
+		} else if (PC.hormoneBalance >= 300) {
+			r.push(`Your system is completely flooded with female hormones`);
+		} else if (PC.hormoneBalance >= 200) {
+			r.push(`Your body is awash with feminine hormones`);
+		} else if (PC.hormoneBalance >= 100) {
+			r.push(`Your hormone balance is overly feminine.`);
+		} else if (PC.hormoneBalance > 20) {
+			r.push(`You have a feminine hormone balance`);
+			if (PC.hormones === -1) {
+				r.push(r.pop() + `, but are taking male ones in an attempt to become more masculine.`);
+			} else if (PC.hormones === 1) {
+				r.push(`being supplemented by your use of artificial hormones.`);
+			} else {
+				r.push(r.pop() + `.`);
+			}
+		} else {
+			r.push(`Your hormone balance is very androgynous`);
+			if (PC.hormones === 1) {
+				r.push(r.pop() + `, but are taking male hormones in an attempt to become more masculine.`);
+			} else if (PC.hormones === -1) {
+				r.push(r.pop() + `, but are taking female hormones in an attempt to become more feminine.`);
+			} else {
+				r.push(r.pop() + `.`);
+			}
+		}
+		if (PC.hormoneBalance > -400 && PC.hormoneBalance <= -100) {
+			if (PC.hormones === 1) {
+				r.push(r.pop() + `, but you are taking female ones in an attempt to balance things out.`);
+			} else if (PC.hormones === -1) {
+				r.push(`and further bolstered by your use of artificial ones.`);
+			} else {
+				r.push(r.pop() + `, but will slowly regress to a more normal balance unless supplemented.`);
+			}
+		} else if (PC.hormoneBalance < 400 && PC.hormoneBalance >= 100) {
+			if (PC.hormones === -1) {
+				r.push(r.pop() + `, but you are taking male ones in an attempt to balance things out.`);
+			} else if (PC.hormones === 1) {
+				r.push(`and further bolstered by your use of artificial ones.`);
+			} else {
+				r.push(r.pop() + `, but will slowly regress to a more normal balance unless supplemented.`);
+			}
+		}
+	}
+
+	function moodConflict() {
+		if ((PC.hormoneBalance > 20 && PC.genes === "XY" && PC.balls !== 0 && PC.ballType !== "sterile") || (PC.hormoneBalance < -20 && PC.genes === "XX" && (PC.ovaries !== 0 || PC.mpreg !== 0))) {
+			r.push(`Your altered hormonal balance conflicts with your natural hormones, causing occasional moodiness.`);
+			if (PC.energy > 10) {
+				r.push(`These clashing hormones also have the frustrating effect of <span class="libido dec">disrupting your sex drive.</span>`);
+				PC.energy--;
+			}
+		}
+	}
+
+	function hormonesEffects() {
+		if (Math.abs(PC.hormoneBalance) >= 50) {
+			if (PC.hormoneBalance > 30 && PC.geneMods.NCS !== 1) {
+				/* 'Expected' breast size based on weight for feminine-bodied player. Masculine-bodied takes a small hit. */
+				normBreasts = Math.trunc((100 + (PC.weight + 100) * 5 + 2 * PC.lactationAdaptation) * (0.85 + PC.hormoneBalance / 400) * gigantomastiaMod / Math.max(PC.title * 1.25,  1));
+				normButt = ((PC.weight + 100) * 0.025 * (0.9 + PC.hormoneBalance / 600) * (rearLipedemaMod / 2 + 1) / Math.max(PC.title * 1.10,  1));
+			}
+
+			if (PC.hormoneBalance >= 350) {
+				if (PC.geneMods.NCS === 1) {
+					if ((PC.shoulders + Math.abs(PC.shouldersImplant)) > -1 && PC.shoulders > -2 && random(1, 100) < (40 + (20 * hormonePower))) {
+						effects.push(`<span class="change positive">shoulders to narrow`);
+						PC.shoulders--;
+					}
+				} else if (PC.physicalAge < 25) {
+					if (PC.shoulders + Math.abs(PC.shouldersImplant) > -1 && PC.shoulders > -2 && random(1, 100) < 20 + (10 * hormonePower)) {
+						effects.push(`<span class="change positive">shoulders to narrow`);
+						PC.shoulders--;
+					}
+					if (PC.geneMods.NCS === 0 && PC.hips - (Math.abs(PC.hipsImplant)) < 1 && PC.hips < 2 && random(1, 100) <= 20 + (10 * hormonePower)) {
+						effects.push(`<span class="change positive">hips to widen`);
+						PC.hips++;
+					}
+				}
+
+				if (PC.faceImplant < 5) {
+					if (PC.faceShape === "masculine") {
+						faceShape = "androgynous";
+					} else if (PC.faceShape === "androgynous" && PC.geneticQuirks.androgyny !== 2) {
+						faceShape = "normal";
+					} else if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.faceShape === "normal") {
+						faceShape = "cute";
+					}
+				}
+				if (faceValue < 50 && PC.face < 75) {
+					effects.push(`<span class="change positive">facial structure to soften`);
+					faceInc = 1 + hormonePower;
+					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+						faceInc *= 2;
+					}
+					faceIncreaseAction(PC, faceInc);
+				}
+
+				if (PC.voice.isBetween(0, 3)) {
+					effects.push(`<span class="change positive">voice to heighten`);
+					PC.voice++;
+				}
+
+				if (PC.muscles > 10 && PC.diet !== "muscle building" && PC.drugs !== "steroids" && (PC.geneticQuirks.mGain !== 2 || PC.geneticQuirks.mLoss === 2)) {
+					effects.push(`<span class="change negative">muscles to lose mass`);
+					PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
+					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+						PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
+					}
+				}
+				if (PC.waist > -30) {
+					effects.push(`<span class="change positive">waist to narrow`);
+					PC.waist -= 2 + hormonePower;
+				}
+
+				if (PC.geneMods.NCS === 0) {
+					if (boobSize < 0.9 * normBreasts) {
+						/* Grow to 90% of normBreasts */
+						effects.push(`<span class="change positive">breasts to slightly grow`);
+						PC.boobs += 25;
+					}
+					if (PC.nipples === "tiny") {
+						effects.push(`<span class="change positive">tiny nipples to enlarge`);
+						PC.nipples = "cute";
+					}
+					if (buttSize < Math.trunc(4.5 * normButt) / 5) {
+						/* 90% of normButt, rounded down to the next increment of .2 */
+						effects.push(`<span class="change positive">butt to swell`);
+						PC.butt += 0.2;
+					}
+				}
+				if (PC.vagina > -1 && PC.ovaries !== 0 && PC.vaginaLube < 2) {
+					effects.push(`<span class="change positive">pussy to produce more lubricant`);
+					PC.vaginaLube++;
+				}
+
+				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
+					if (PC.dick > 1) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.dick > 2) {
+							effects.push(`<span class="change negative">dick to greatly shrink`);
+							PC.dick -= 1;
+						} else {
+							effects.push(`<span class="change negative">dick to shrink`);
+						}
+						PC.dick--;
+					}
+					if (PC.balls > 1) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.balls > 2) {
+							effects.push(`<span class="change negative">testicles to heavily atrophy`);
+							PC.balls -= 1;
+						} else {
+							effects.push(`<span class="change negative">testicles to atrophy`);
+						}
+						PC.balls--;
+					}
+					if (PC.clit > 0) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.clit > 1) {
+							effects.push(`<span class="change negative">clit to greatly shrink`);
+							PC.clit -= 1;
+						} else {
+							effects.push(`<span class="change negative">clit to shrink`);
+						}
+						PC.clit--;
+					}
+				}
+			} else if (PC.hormoneBalance >= 300) {
+				if (PC.faceImplant < 5) {
+					if (PC.faceShape === "masculine") {
+						faceShape = "androgynous";
+					} else if (PC.faceShape === "androgynous" && PC.geneticQuirks.androgyny !== 2) {
+						faceShape = "normal";
+					} else if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.faceShape === "normal") {
+						faceShape = "cute";
+					}
+				}
+				if (faceValue < 30 && PC.face < 60) {
+					effects.push(`<span class="change positive">facial structure to soften`);
+					faceInc = 1 + hormonePower;
+					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+						faceInc *= 2;
+					}
+					faceIncreaseAction(PC, faceInc);
+				}
+
+				if (PC.voice.isBetween(0, 3)) {
+					effects.push(`<span class="change positive">voice to heighten`);
+					PC.voice++;
+				}
+
+				if (PC.muscles > 30 && PC.diet !== "muscle building" && PC.drugs !== "steroids" && (PC.geneticQuirks.mGain !== 2 || PC.geneticQuirks.mLoss === 2)) {
+					effects.push(`<span class="change negative">muscles to lose mass`);
+					PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
+					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+						PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
+					}
+				}
+				if (PC.waist > -10) {
+					effects.push(`<span class="change positive">waist to narrow`);
+					PC.waist -= 2 + hormonePower;
+				}
+
+				if (PC.geneMods.NCS === 0) {
+					if (boobSize < 0.8 * normBreasts) {
+						/* Grow to 80% of expected */
+						effects.push(`<span class="change positive">breasts to slightly grow`);
+						PC.boobs += 25;
+					}
+					if (PC.nipples === "tiny") {
+						effects.push(`<span class="change positive">tiny nipples to enlarge`);
+						PC.nipples = "cute";
+					}
+					if (buttSize < Math.trunc(4 * normButt) / 5) {
+						/* 80% of normButt, rounded down to the next increment of .2 */
+						effects.push(`<span class="change positive">butt to swell`);
+						PC.butt += 0.2;
+					}
+				}
+				if (PC.vagina > -1 && PC.ovaries !== 0 && PC.vaginaLube < 2) {
+					effects.push(`<span class="change positive">pussy to produce more lubricant`);
+					PC.vaginaLube++;
+				}
+
+				if (V.hormoneUpgradeShrinkage === 0) {
+					if (PC.dick > 1) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.dick > 2) {
+							effects.push(`<span class="change negative">dick to greatly shrink`);
+							PC.dick -= 1;
+						} else {
+							effects.push(`<span class="change negative">dick to shrink`);
+						}
+						PC.dick--;
+					}
+					if (PC.balls > 1) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.balls > 2) {
+							effects.push(`<span class="change negative">testicles to heavily atrophy`);
+							PC.balls -= 1;
+						} else {
+							effects.push(`<span class="change negative">testicles to atrophy`);
+						}
+						PC.balls--;
+					}
+					if (PC.clit > 0) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.clit > 1) {
+							effects.push(`<span class="change negative">clit to greatly shrink`);
+							PC.clit -= 1;
+						} else {
+							effects.push(`<span class="change negative">clit to shrink`);
+						}
+						PC.clit--;
+					}
+				}
+			} else if (PC.hormoneBalance >= 250) {
+				if (PC.faceImplant < 5) {
+					if (PC.faceShape === "masculine") {
+						faceShape = "androgynous";
+					} else if (PC.faceShape === "androgynous" && PC.geneticQuirks.androgyny !== 2) {
+						faceShape = "normal";
+					} else if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.faceShape === "normal") {
+						faceShape = "cute";
+					}
+				}
+				if (faceValue < 10 && PC.face < 30) {
+					effects.push(`<span class="change positive">facial structure to soften`);
+					faceInc = 1 + hormonePower;
+					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+						faceInc *= 2;
+					}
+					faceIncreaseAction(PC, faceInc);
+				}
+
+				if (PC.voice.isBetween(0, 2)) {
+					effects.push(`<span class="change positive">voice to heighten`);
+					PC.voice++;
+				}
+
+				if (PC.muscles > 30 && PC.diet !== "muscle building" && PC.drugs !== "steroids" && (PC.geneticQuirks.mGain !== 2 || PC.geneticQuirks.mLoss === 2)) {
+					effects.push(`<span class="change negative">muscles to lose mass`);
+					PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
+					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+						PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
+					}
+				}
+				if (PC.waist > 0) {
+					effects.push(`<span class="change positive">waist to narrow`);
+					PC.waist -= 2 + hormonePower;
+				}
+
+				if (PC.geneMods.NCS === 0) {
+					if (boobSize < 0.7 * normBreasts) {
+						/* Grow to 70% of expected */
+						effects.push(`<span class="change positive">breasts to slightly grow`);
+						PC.boobs += 25;
+					}
+					if (PC.nipples === "tiny") {
+						effects.push(`<span class="change positive">tiny nipples to enlarge`);
+						PC.nipples = "cute";
+					}
+					if (buttSize < Math.trunc(3.5 * normButt) / 5) {
+						/* 70% of normButt, rounded down to the next increment of .2 */
+						effects.push(`<span class="change positive">butt to swell`);
+						PC.butt += 0.2;
+					}
+				}
+				if (PC.vagina > -1 && PC.ovaries !== 0 && PC.vaginaLube < 1) {
+					effects.push(`<span class="change positive">pussy to produce more lubricant`);
+					PC.vaginaLube++;
+				}
+
+				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
+					if (PC.dick > 2) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">dick to greatly shrink`);
+							PC.dick -= 1;
+						} else {
+							effects.push(`<span class="change negative">dick to shrink`);
+						}
+						PC.dick--;
+					}
+					if (PC.balls > 2) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">testicles to heavily atrophy`);
+							PC.balls -= 1;
+						} else {
+							effects.push(`<span class="change negative">testicles to atrophy`);
+						}
+						PC.balls--;
+					}
+					if (PC.clit > 1) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">clit to greatly shrink`);
+							PC.clit -= 1;
+						} else {
+							effects.push(`<span class="change negative">clit to shrink`);
+						}
+						PC.clit--;
+					}
+				}
+			} else if (PC.hormoneBalance >= 200) {
+				if (PC.faceImplant < 5) {
+					if (PC.faceShape === "masculine") {
+						faceShape = "androgynous";
+					} else if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.faceShape === "androgynous" && PC.geneticQuirks.androgyny !== 2) {
+						faceShape = "normal";
+					}
+				}
+				if (faceValue < 0 && PC.face < 0) {
+					r.push(`<span class="change positive">facial structure to soften`);
+					faceInc = 1 + hormonePower;
+					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+						faceInc *= 2;
+					}
+					faceIncreaseAction(PC, faceInc);
+				}
+
+				if (PC.voice.isBetween(0, 2)) {
+					r.push(`<span class="change positive">voice to heighten`);
+					PC.voice++;
+				}
+
+				if (PC.muscles > 30 && PC.diet !== "muscle building" && PC.drugs !== "steroids" && (PC.geneticQuirks.mGain !== 2 || PC.geneticQuirks.mLoss === 2)) {
+					r.push(`<span class="change negative">muscles to lose mass`);
+					PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
+					if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+						PC.muscles -= 2 + hormonePower + PC.geneticQuirks.mLoss;
+					}
+				}
+				if (PC.waist > 10) {
+					r.push(`<span class="change positive">waist to narrow`);
+					PC.waist -= 2 + hormonePower;
+				}
+
+				if (PC.geneMods.NCS === 0) {
+					if (boobSize < 0.6 * normBreasts) {
+						/* Grow to 60% of expected */
+						effects.push(`<span class="change positive">breasts to slightly grow`);
+						PC.boobs += 25;
+					}
+					if (PC.nipples === "tiny") {
+						effects.push(`<span class="change positive">tiny nipples to enlarge`);
+						PC.nipples = "cute";
+					}
+					if (buttSize < Math.trunc(3 * normButt) / 5) {
+						/* 60% of normButt, rounded down to the next increment of .2 */
+						effects.push(`<span class="change positive">butt to swell`);
+						PC.butt += 0.2;
+					}
+				}
+				if (PC.vagina > -1 && PC.ovaries !== 0 && PC.vaginaLube < 1) {
+					effects.push(`<span class="change positive">pussy to produce more lubricant`);
+					PC.vaginaLube++;
+				}
+
+				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
+					if (PC.dick > 3) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">dick to greatly shrink`);
+							PC.dick -= 1;
+						} else {
+							effects.push(`<span class="change negative">dick to shrink`);
+							PC.dick--;
+						}
+					}
+					if (PC.balls > 3) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">testicles to heavily atrophy`);
+							PC.balls -= 1;
+						} else {
+							effects.push(`<span class="change negative">testicles to atrophy`);
+						}
+						PC.balls--;
+					}
+					if (PC.clit > 2) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">clit to greatly shrink`);
+							PC.clit -= 1;
+						} else {
+							effects.push(`<span class="change negative">clit to shrink`);
+						}
+						PC.clit--;
+					}
+				}
+			} else if (PC.hormoneBalance >= 100) {
+				if (PC.faceImplant < 5) {
+					if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && PC.faceShape === "masculine") {
+						faceShape = "androgynous";
+					}
+				}
+
+				if (PC.geneMods.NCS === 0) {
+					if (boobSize < 0.5 * normBreasts) {
+						/* Grow to 50% of expected */
+						r.push(`<span class="change positive">breasts to slightly grow`);
+						PC.boobs += 25;
+					}
+				}
+			} else if (PC.hormoneBalance >= 50) {
+				// possible attraction stuff here
+			} else if (PC.hormoneBalance <= -350) {
+				if (PC.geneMods.NCS === 1) {
+					if (PC.hips + Math.abs(PC.hipsImplant) > -1 && PC.hips > -2 && (random(1, 100) <= 20 + (10 * hormonePower))) {
+						effects.push(`<span class="change positive">hips to narrow`);
+						PC.hips--;
+					}
+				} else if (PC.physicalAge < 25) {
+					if ((PC.shoulders - (Math.abs(PC.shouldersImplant)) < 1) && (PC.shoulders < 2) && (random(1, 100) < 20 + (10 * hormonePower))) {
+						effects.push(`<span class="change positive">shoulders to widen`);
+						PC.shoulders++;
+					}
+					if ((PC.hips + (Math.abs(PC.hipsImplant)) > -1) && (PC.hips > -2) && (random(1, 100) <= 20 + (10 * hormonePower))) {
+						effects.push(`<span class="change positive">hips to narrow`);
+						PC.hips--;
+					}
+				}
+
+				if (PC.geneMods.NCS === 0) {
+					if (PC.faceImplant < 5) {
+						if (PC.geneticQuirks.androgyny !== 2) {
+							if (PC.faceShape === "androgynous") {
+								faceShape = "masculine";
+							} else if (PC.faceShape !== "masculine") {
+								faceShape = "androgynous";
+							}
+						}
+					}
+					if (faceValue.isBetween(0, 100)) {
+						effects.push(`<span class="change positive">facial structure to harden`);
+						faceDec = 1 + hormonePower;
+						PC.face = Math.clamp(PC.face - faceDec, -100, 100);
+					}
+					if (PC.voice > 1) {
+						effects.push(`<span class="change positive">voice to deepen`);
+						PC.voice--;
+					}
+				}
+
+				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
+					if (buttSize > 1 && rearLipedemaMod !== 2) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && buttSize > 2) {
+							effects.push(`<span class="change negative">butt to greatly diminish`);
+							PC.butt--;
+						} else {
+							effects.push(`<span class="change negative">butt to diminish`);
+						}
+						PC.butt--;
+					}
+					if (boobSize > 100 * gigantomastiaMod && gigantomastiaMod !== 3) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && boobSize > 200) {
+							effects.push(`<span class="change negative">breasts to shrink`);
+							PC.boobs -= 10 + (15 * hormonePower);
+						} else {
+							effects.push(`<span class="change negative">breasts to slightly shrink`);
+						}
+						PC.boobs -= 10 + (15 * hormonePower);
+					}
+				}
+				if (PC.geneMods.NCS === 1 && PC.nipples === "tiny") {
+					/* nothing, just don't advance to cute */
+				} else if (PC.nipples !== "tiny" && PC.nipples !== "fuckable" && PC.nipples !== "flat") {
+					effects.push(`<span class="change positive">nipples to become more masculine`);
+					PC.nipples = "tiny";
+				}
+
+				if (PC.geneMods.NCS === 0) {
+					if (PC.dick.isBetween(0, 5)) {
+						effects.push(`<span class="change positive">dick to swell`);
+						PC.dick++;
+					}
+					if (PC.balls.isBetween(0, 5)) {
+						effects.push(`<span class="change positive">balls to grow`);
+						PC.balls++;
+					}
+
+					if (PC.clit < 5 && PC.dick === 0 && PC.vagina >= 0) {
+						effects.push(`<span class="change positive">clit to swell`);
+						PC.clit++;
+					}
+					if (PC.vagina > -1 && PC.vaginaLube > 0) {
+						effects.push(`<span class="change negative">vagina to dry out`);
+						PC.vaginaLube--;
+					}
+
+					if (PC.muscles <= 50 && PC.diet !== "slimming") {
+						effects.push(`<span class="change negative">muscles to gain mass`);
+						PC.muscles += 2 + hormonePower + PC.geneticQuirks.mGain;
+					}
+					if (PC.waist < 80) {
+						effects.push(`<span class="change positive">waist to broaden`);
+						PC.waist += 2 + hormonePower;
+					}
+				}
+			} else if (PC.hormoneBalance <= -300) {
+				if (PC.geneMods.NCS === 0) {
+					if (PC.faceImplant < 5) {
+						if (PC.geneticQuirks.androgyny !== 2) {
+							if (PC.faceShape === "androgynous") {
+								faceShape = "masculine";
+							} else if (PC.faceShape !== "masculine") {
+								faceShape = "androgynous";
+							}
+						}
+					}
+
+					if (PC.voice > 1) {
+						effects.push(`<span class="change positive">voice to deepen`);
+						PC.voice--;
+					}
+				}
+
+				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
+					if (buttSize > 1 && rearLipedemaMod !== 2) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50 && buttSize > 2) {
+							effects.push(`<span class="change negative">butt to greatly diminish`);
+							PC.butt--;
+						} else {
+							effects.push(`<span class="change negative">butt to diminish`);
+						}
+						PC.butt--;
+					}
+					if (boobSize > 300 * gigantomastiaMod && gigantomastiaMod !== 3) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">breasts to shrink`);
+							PC.boobs -= 10 + (15 * hormonePower);
+						} else {
+							effects.push(`<span class="change negative">breasts to slightly shrink`);
+						}
+						PC.boobs -= 10 + (15 * hormonePower);
+					}
+				}
+				if (PC.geneMods.NCS === 1 && PC.nipples === "tiny") {
+					/* nothing, just don't advance to cute */
+				} else if (PC.nipples !== "tiny" && PC.nipples !== "fuckable" && PC.nipples !== "flat") {
+					effects.push(`<span class="change positive">nipples to become more masculine`);
+					PC.nipples = "tiny";
+				}
+
+				if (PC.geneMods.NCS === 0) {
+					if (PC.dick.isBetween(0, 5)) {
+						effects.push(`<span class="change positive">dick to swell`);
+						PC.dick++;
+					}
+					if (PC.balls.isBetween(0, 5) && PC.ballType !== "sterile") {
+						effects.push(`<span class="change positive">balls to grow`);
+						PC.balls++;
+					}
+
+					if (PC.clit < 4 && PC.dick === 0 && PC.vagina >= 0) {
+						effects.push(`<span class="change positive">clit to swell`);
+						PC.clit++;
+					}
+					if (PC.vagina > -1 && PC.vaginaLube > 0) {
+						effects.push(`<span class="change negative">vagina to dry out`);
+						PC.vaginaLube--;
+					}
+
+					if (PC.muscles <= 50 && PC.diet !== "slimming") {
+						effects.push(`<span class="change negative">muscles to gain mass`);
+						PC.muscles += 2 + hormonePower + PC.geneticQuirks.mGain;
+					}
+					if (PC.waist < 40) {
+						effects.push(`<span class="change positive">waist to broaden`);
+						PC.waist += 2 + hormonePower;
+					}
+				}
+			} else if (PC.hormoneBalance <= -250) {
+				if (PC.geneMods.NCS === 0) {
+					if (PC.faceImplant < 5) {
+						if (PC.faceShape !== "masculine" && PC.faceShape !== "androgynous") {
+							faceShape = "androgynous";
+						}
+					}
+
+					if (PC.voice > 1) {
+						effects.push(`<span class="change positive">voice to deepen`);
+						PC.voice--;
+					}
+				}
+
+				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
+					if (buttSize > 2 && rearLipedemaMod !== 2) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">butt to greatly diminish`);
+							PC.butt--;
+						} else {
+							effects.push(`<span class="change negative">butt to diminish`);
+						}
+						PC.butt--;
+					}
+					if (boobSize > 400 * gigantomastiaMod && gigantomastiaMod !== 3) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">breasts to shrink`);
+							PC.boobs -= 10 + (15 * hormonePower);
+						} else {
+							effects.push(`<span class="change negative">breasts to slightly shrink`);
+						}
+						PC.boobs -= 10 + (15 * hormonePower);
+					}
+				}
+				if (PC.geneMods.NCS === 1 && PC.nipples === "tiny") {
+					/* nothing, just don't advance to cute */
+				} else if (PC.nipples !== "tiny" && PC.nipples !== "fuckable" && PC.nipples !== "flat") {
+					effects.push(`<span class="change positive">nipples to become more masculine`);
+					PC.nipples = "tiny";
+				}
+
+				if (PC.geneMods.NCS === 0) {
+					if (PC.dick.isBetween(0, 4)) {
+						effects.push(`<span class="change positive">dick to swell`);
+						PC.dick++;
+					}
+					if (PC.balls.isBetween(0, 4) && PC.ballType !== "sterile") {
+						effects.push(`<span class="change positive">balls to grow`);
+						PC.balls++;
+					}
+
+					if (PC.clit < 3 && PC.dick === 0 && PC.vagina >= 0) {
+						effects.push(`<span class="change positive">clit to swell`);
+						PC.clit++;
+					}
+					if (PC.vagina > -1 && PC.vaginaLube > 0) {
+						effects.push(`<span class="change negative">vagina to dry out`);
+						PC.vaginaLube--;
+					}
+
+					if (PC.muscles <= 35 && PC.diet !== "slimming") {
+						effects.push(`<span class="change negative">muscles to gain mass`);
+						PC.muscles += 2 + hormonePower + PC.geneticQuirks.mGain;
+					}
+					if (PC.waist < 25) {
+						effects.push(`<span class="change positive">waist to broaden`);
+						PC.waist += 2 + hormonePower;
+					}
+				}
+			} else if (PC.hormoneBalance <= -200) {
+				if (PC.geneMods.NCS === 0) {
+					if (PC.faceImplant < 5) {
+						if (PC.faceShape !== "masculine" && PC.faceShape !== "androgynous") {
+							faceShape = "androgynous";
+						}
+					}
+
+					if (PC.voice > 2) {
+						effects.push(`<span class="change positive">voice to deepen`);
+						PC.voice--;
+					}
+				}
+
+				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
+					if (buttSize > 3 && rearLipedemaMod !== 2) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">butt to greatly diminish`);
+							PC.butt--;
+						} else {
+							effects.push(`<span class="change negative">butt to diminish`);
+						}
+						PC.butt--;
+					}
+					if (boobSize > 600 * gigantomastiaMod && gigantomastiaMod !== 3) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">breasts to shrink`);
+							PC.boobs -= 10 + (15 * hormonePower);
+						} else {
+							effects.push(`<span class="change negative">breasts to slightly shrink`);
+						}
+						PC.boobs -= 10 + (15 * hormonePower);
+					}
+				}
+				if (PC.nipples === "huge" || PC.nipples === "puffy") {
+					effects.push(`<span class="change positive">nipples to become more masculine`);
+					PC.nipples = "cute";
+				}
+
+				if (PC.geneMods.NCS === 0) {
+					if (PC.dick.isBetween(0, 3)) {
+						effects.push(`<span class="change positive">dick to swell`);
+						PC.dick++;
+					}
+					if (PC.balls.isBetween(0, 3) && PC.ballType !== "sterile") {
+						effects.push(`<span class="change positive">balls to grow`);
+						PC.balls++;
+					}
+
+					if (PC.clit < 2 && PC.dick === 0 && PC.vagina >= 0) {
+						effects.push(`<span class="change positive">clit to swell`);
+						PC.clit++;
+					}
+					if (PC.vagina > -1 && PC.vaginaLube > 0) {
+						effects.push(`<span class="change negative">vagina to dry out`);
+						PC.vaginaLube--;
+					}
+
+					if (PC.muscles <= 15 && PC.diet !== "slimming") {
+						effects.push(`<span class="change negative">muscles to gain mass`);
+						PC.muscles += 2 + hormonePower + PC.geneticQuirks.mGain;
+					}
+					if (PC.waist < 9) {
+						effects.push(`<span class="change positive">waist to broaden`);
+						PC.waist += 2 + hormonePower;
+					}
+				}
+			} else if (PC.hormoneBalance <= -100) {
+				if (PC.geneMods.NCS === 0) {
+					if (PC.voice > 2) {
+						effects.push(`<span class="change positive">voice to deepen`);
+						PC.voice--;
+					}
+				}
+
+				if (V.hormoneUpgradeShrinkage === 0 || !selfManufactured) {
+					if (buttSize > 4 && rearLipedemaMod !== 2) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">butt to greatly diminish`);
+							PC.butt--;
+						} else {
+							effects.push(`<span class="change negative">butt to diminish`);
+						}
+						PC.butt--;
+					}
+					if (boobSize > 800 * gigantomastiaMod && gigantomastiaMod !== 3) {
+						if (PC.geneMods.NCS === 1 && random(1, 100) > 50) {
+							effects.push(`<span class="change negative">breasts to shrink`);
+							PC.boobs -= 10 + (15 * hormonePower);
+						} else {
+							effects.push(`<span class="change negative">breasts to slightly shrink`);
+						}
+						PC.boobs -= 10 + (15 * hormonePower);
+					}
+				}
+
+				if (PC.geneMods.NCS === 0) {
+					if (PC.muscles < 0 && PC.diet !== "slimming") {
+						effects.push(`<span class="change negative">muscles to gain mass`);
+						PC.muscles += 2 + hormonePower + PC.geneticQuirks.mGain;
+					}
+
+					if (PC.waist < 0) {
+						effects.push(`<span class="change positive">waist to broaden`);
+						PC.waist += 2 + hormonePower;
+					}
+
+					if (PC.dick.isBetween(0, 2)) {
+						effects.push(`<span class="change positive">dick to grow`);
+						PC.dick++;
+					}
+					if (PC.balls.isBetween(0, 2)) {
+						effects.push(`<span class="change positive">balls to drop`);
+						PC.balls++;
+					}
+
+					if (PC.clit < 1 && PC.dick === 0) {
+						effects.push(`<span class="change positive">clit to swell`);
+						PC.clit++;
+					}
+					if (PC.vagina > -1 && PC.vaginaLube > 1) {
+						effects.push(`<span class="change negative">vagina to dry out`);
+						PC.vaginaLube--;
+					}
+				}
+			} else if (PC.hormoneBalance <= -50) {
+				// possible attraction stuff here
+			}
+		}
+
+		if (effects.length > 0) {
+			r.push(`Hormonal effects cause your`);
+			r.push(effectsListToText(effectsList));
+			r.push(`${r.pop()}.</span>`);
+		}
+		if (faceShape !== 0) {
+			if (effecs.length > 0) {
+				r.push(`More importantly, they cause`);
+			} else {
+				r.push(`Hormonal effects cause`);
+			}
+			if (PC.faceShape === "masculine" && faceShape === "androgynous") {
+				r.push(`<span class="change positive">your face to soften into a state of`);
+				if (PC.geneMods.NCS === 1) {
+					r.push(`childlike`);
+				}
+				r.push(`androgyny.</span>`);
+			} else if (PC.faceShape === "androgynous" && faceShape === "normal") {
+				r.push(`<span class="change positive">your face to soften into`);
+				if (PC.geneMods.NCS === 1) {
+					r.push(`childlike normalcy.</span>`);
+				} else {
+					r.push(`femininity.</span>`);
+				}
+			} else if (PC.faceShape === "androgynous" && faceShape === "masculine") {
+				r.push(`<span class="change negative">your face to harden into masculinity.</span>`);
+			} else if (PC.faceShape === "normal" && faceShape === "cute") {
+				r.push(`<span class="change positive">your face to soften into a state of sheer cuteness.</span>`);
+			} else if (PC.faceShape !== "masculine" && PC.faceShape !== "androgynous" && faceShape === "androgynous") {
+				r.push(`<span class="change negative">your face to harden into a state of androgyny.</span>`);
+			}
+			PC.faceShape = faceShape;
+		}
+		if ((faceValue >= 50 || PC.face >= 75) && faceInc !== 0) {
+			r.push(`Your face is has become quite beautiful, though hormonal treatments <span class="noteworthy">are unlikely to be able to improve it further.</span>`);
+		}
+	}
+
+	function effectsListToText(effectsList) {
+		return effectsList.reduce((res, ch, i, arr) => res + (i === arr.length - 1 ? '</span> and ' : ',</span> ') + ch);
+	}
+};
diff --git a/src/endWeek/player/prInflation.js b/src/endWeek/player/prInflation.js
index 29960dfcbb81754ce7614d2486a31e1ef029e0d1..d467536b04356e1777d790aa34dabc5819d37d1f 100644
--- a/src/endWeek/player/prInflation.js
+++ b/src/endWeek/player/prInflation.js
@@ -169,7 +169,7 @@ App.EndWeek.Player.inflation = function(PC = V.PC) {
 			case "food":
 				r.push(`You gorge yourself whenever you feel your gut`);
 				if (PC.inflation === 3) {
-					r.push(`isn't stuffed to bursting with with food to sate your predilections. ${stateTerm}`);
+					r.push(`isn't stuffed to bursting with enough food to sate your predilections. ${stateTerm}`);
 					healthDamage(PC, 10);
 				} else if (PC.inflation === 2) {
 					r.push(`isn't stuffed with enough food`);
@@ -179,7 +179,7 @@ App.EndWeek.Player.inflation = function(PC = V.PC) {
 					} else {
 						r.push(`to bulge prominently ahead of you to sate your predilections.`);
 					}
-					r.push(`You're so full, the your distended belly groans angrily as it struggles to digest all you've eaten.`);
+					r.push(`You're so full, your distended belly groans angrily as it struggles to digest all that you've eaten.`);
 				} else if (PC.inflation === 1) {
 					r.push(`isn't stuffed with enough food to be noticeably distended to sate your predilections. ${stateTerm}`);
 				}
@@ -206,7 +206,7 @@ App.EndWeek.Player.inflation = function(PC = V.PC) {
 			}
 		} else if (PC.inflationType === "food") {
 			if (PC.weight < 200) {
-				r.push(`It should surprise noone that you <span class="lime">rapidly gain weight</span> with all the binge eating.`);
+				r.push(`It should surprise nobody that you <span class="lime">rapidly gain weight</span> with all the binge eating.`);
 				PC.weight += 4;
 				if (PC.weightDirection === 1) {
 					PC.weight += 2;
diff --git a/src/endWeek/player/prLongTermMentalEffects.js b/src/endWeek/player/prLongTermMentalEffects.js
new file mode 100644
index 0000000000000000000000000000000000000000..516235f9f3f4d7025bba508251663dd26b323311
--- /dev/null
+++ b/src/endWeek/player/prLongTermMentalEffects.js
@@ -0,0 +1,20 @@
+App.EndWeek.Player.longTermMentalEffects = function(PC = V.PC) {
+	// just dissolve this
+	const r = [];
+
+	asexualOvariesBurnout();
+
+	return r.join(" ");
+
+	function asexualOvariesBurnout() { // This block needs to be reflected in PC.need generation.
+		if (PC.ovaImplant === "asexual" && isFertile(PC) && (PC.preg === 0 || (PC.preg >= 0 && PC.geneticQuirks.superfetation === 2))) {
+			r.push(`The frequent climaxes brought about by your ovarian modification's internal ejaculations keep you sexually sated.`);
+			if (PC.energy >= 10) {
+				r.push(`However, the constant self-gratification <span class="libido dec">leaves sex less satisfying.</span>`);
+				PC.energy -= 10;
+			}
+			PC.need = 0;
+		}
+	}
+
+};
diff --git a/src/endWeek/player/prPregnancy.js b/src/endWeek/player/prPregnancy.js
new file mode 100644
index 0000000000000000000000000000000000000000..89b44674acf009ea0ac57c374b0b1870834dffdb
--- /dev/null
+++ b/src/endWeek/player/prPregnancy.js
@@ -0,0 +1,534 @@
+App.EndWeek.Player.pregnancy = function(PC = V.PC) {
+	const r = [];
+
+	const gigantomastiaMod = PC.geneticQuirks.gigantomastia === 2 ? (PC.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
+	const rearQuirk = PC.geneticQuirks.rearLipedema === 2 ? 2 : 0;
+	const uterineHypersensitivityMod = PC.geneticQuirks.uterineHypersensitivity === 2 ? 2 : 1;
+	const boobSize = PC.boobs - PC.boobsImplant - PC.boobsMilk;
+	const oldBoobs = PC.boobs;
+	const buttSize = PC.butt - PC.buttImplant;
+	const hipSize = PC.hips - PC.hipsImplant;
+	const child = (PC.pregType > 1 ? "children" : "child");
+
+	if (PC.preg > 0) {
+		pregnancyEffects();
+	}
+	if (V.seePreg !== 0) {
+		preconception();
+		pregnancySanityCheck();
+	}
+
+	return r.join(" ");
+
+	function pregnancyEffects() {
+		pregnancyDiscovery();
+		pregnancyLibido();
+		fetalAdjustment();
+		if (PC.preg >= PC.pregData.normalBirth / 4) {
+			pregnancyAdjustments();
+			laborText();
+			pregnancyPhysicalEffects();
+		}
+		if (PC.pregType === 0) { // Catch for strange cases - now with checking.
+			failSafe();
+		}
+	}
+
+	function pregnancyDiscovery() {
+		// Add passive discovery to this once periods are added
+		if (PC.bellyFluid > 2000) {
+			if (PC.inflation > 1) {
+				r.push(`While trying to inflate yourself with ${PC.inflationType}, you discover that you can't hold more <span class="noteworthy">two liters</span> without feeling seriously ill.`);
+				PC.inflation = 1;
+			} else {
+				r.push(`While pleasuring yourself by inflating with ${PC.inflationType}, you're forced to stop due to a sudden bout of extreme nausea.`);
+				PC.bellyFluid = 2000;
+			}
+			SetBellySize(PC);
+			if (PC.pregKnown === 0) {
+				r.push(`It turns out <span class="pregnancy">you're`);
+				if (PC.preg > PC.pregData.normalBirth / 4) {
+					r.push(`pregnant and have been for some time.</span>`);
+				} else {
+					r.push(`pregnant.</span>`);
+				}
+			} else {
+				r.push(`Unfortunately, this will likely be the case for the duration of your pregnancy; at least you'll still steadily swell, if a little slowly for your taste.`);
+			}
+		}
+	}
+
+	function pregnancyLibido() {
+		// .need needs to consider this
+		// drop .energy on birth for uterine hypersensitivity
+		if (PC.geneticQuirks.uterineHypersensitivity === 2 && V.geneticMappingUpgrade >= 1) {
+			if (PC.preg >= PC.pregData.normalBirth) {
+				r.push(`You're full-term and overwhelmed with arousal. Your uterine hypersensitivity combined with a full womb and upcoming birth confers a <span class="libido inc">huge improvement to your sexual appetite.</span>`);
+				PC.energy += 7;
+			} else if (PC.preg > PC.pregData.normalBirth / 1.33) {
+				r.push(`Being hugely pregnant with uterine hypersensitivity confers an <span class="libido inc">improvement to your sexual appetite</span> as your womb steadily stretches.`);
+				PC.energy += 5;
+			} else if (PC.preg > PC.pregData.normalBirth / 2) {
+				r.push(`Being pregnant with uterine hypersensitivity confers a <span class="libido inc">slow improvement to your sexual appetite</span> as your womb grows ever fuller.`);
+				PC.energy += 3;
+			} else if (PC.preg > PC.pregData.normalBirth / 4) {
+				r.push(`You eagerly anticipate the growth of your pregnancy, producing <span class="libido inc">a very slow improvement to your sexual appetite.</span>`);
+				PC.energy += 1;
+			} else if (PC.preg <= PC.pregData.normalBirth / 4 && PC.preg > PC.pregData.normalBirth / 13.33) {
+				if (PC.counter.birthsTotal > 0) {
+					r.push(`The rigors of early pregnancy are easily tolerable when you can only quiver in anticipation of what's to come.`);
+				} else {
+					r.push(`The rigors of early pregnancy <span class="libido dec">slightly reduce your sexual appetite.</span>`);
+					PC.energy -= 1;
+				}
+			}
+		} else if (PC.geneticQuirks.uterineHypersensitivity === 2) {
+			if (PC.preg >= PC.pregData.normalBirth) {
+				r.push(`You're full-term and overwhelmed with arousal. The sensation of your womb stretched so full ${PC.counter.birthsTotal > 0 ? "and the anticipation of another orgasmic birth " : ""}<span class="libido inc">sends your sexual appetite skyrocketing.</span>`);
+				PC.energy += 7;
+			} else if (PC.preg > PC.pregData.normalBirth / 1.33) {
+				r.push(`The feeling of your womb steadily expanding drives you wild, <span class="libido inc">improving your sexual appetite.</span>`);
+				PC.energy += 5;
+			} else if (PC.preg > PC.pregData.normalBirth / 2) {
+				r.push(`The life growing in your womb leaves you feeling especially energetic, granting a <span class="libido inc">slow improvement to your sexual appetite.</span>`);
+				PC.energy += 3;
+			} else if (PC.preg > PC.pregData.normalBirth / 4) {
+				r.push(`You feel a rush from your growing pregnancy, granting a <span class="libido inc">very slow improvement to your sexual appetite.</span>`);
+				PC.energy += 1;
+			} else if (PC.preg <= PC.pregData.normalBirth / 4 && PC.preg > PC.pregData.normalBirth / 13.33) {
+				if (PC.counter.birthsTotal > 0) {
+					r.push(`The rigors of early pregnancy are easily tolerable when you can only quiver in anticipation of what's to come.`);
+				} else {
+					r.push(`The rigors of early pregnancy <span class="libido dec">slightly reduce your sexual appetite.</span>`);
+					PC.energy -= 1;
+				}
+			}
+		} else if (PC.pregMood === 2) {
+			if (PC.preg <= PC.pregData.normalBirth / 4 && PC.preg > PC.pregData.normalBirth / 13.33) {
+				r.push(`The rigors of early pregnancy <span class="libido dec">take their toll on your sexual appetite.</span>`);
+				PC.energy -= 3;
+			} else if (PC.preg >= PC.pregData.normalBirth) {
+				r.push(`You are full-term and <span class="libido inc">horny as hell.</span> Your hormones are out of control, driving you to fuck like a beast in heat despite your condition.`);
+				PC.energy += 4;
+			} else if (PC.preg > PC.pregData.normalBirth / 1.33) {
+				r.push(`With your pregnancy hormones raging, you <span class="libido inc">find your thoughts focusing on sex</span> more than usual.`);
+				PC.energy += 2;
+			} else if (PC.preg > PC.pregData.normalBirth / 2) {
+				r.push(`As your pregnancy grows, so does your desire for sex.`);
+			}
+		// } else if (PC.pregMood === 4) { unattractive
+		} else if (PC.energy >= 90) {
+			if (PC.preg <= PC.pregData.normalBirth / 4 && PC.preg > PC.pregData.normalBirth / 13.33) {
+				r.push(`The rigors of early pregnancy <span class="libido dec">take their toll on your sexual appetite.</span>`);
+				PC.energy -= 3;
+			} else if (PC.preg >= PC.pregData.normalBirth) {
+				r.push(`You are full-term and <span class="libido inc">horny as hell.</span> Between your hormones and already high libido, you're acting like you haven't had a good fuck in nine months.`);
+				PC.energy += 2;
+			} else if (PC.preg > PC.pregData.normalBirth / 1.33) {
+				r.push(`Your advanced pregnancy, combined with your already high libido, leaves you aching to be filled throughout the day.`);
+			} else if (PC.preg > PC.pregData.normalBirth / 2) {
+				r.push(`Your growing pregnancy, combined with your already high libido, has you always itching for some sex.`);
+			}
+		// } else if (PC.pregMood === 3) { frigid
+		// } else if (PC.pregMood === 5) { hotnhorny
+		} else if (PC.energy > 60) {
+			if (PC.preg <= PC.pregData.normalBirth / 4 && PC.preg > PC.pregData.normalBirth / 13.33) {
+				r.push(`The rigors of early pregnancy <span class="libido dec">take their toll on your sexual appetite.</span>`);
+				PC.energy -= 3;
+			} else if (PC.preg >= PC.pregData.normalBirth) {
+				r.push(`You are full-term and suffering from an <span class="libido inc">unquenchable need to be filled.</span>`);
+				PC.energy += 4;
+			} else if (PC.preg > PC.pregData.normalBirth / 1.33) {
+				r.push(`Your advanced pregnancy comes with a hugely increased libido, <span class="libido inc">greatly increasing your sexual drive.</span>`);
+				PC.energy += 3;
+			} else if (PC.preg > PC.pregData.normalBirth / 2) {
+				r.push(`Your growing pregnancy comes with an increased libido, <span class="libido inc">spurring your sexual appetite.</span>`);
+				PC.energy += 2;
+			}
+		} else if (PC.energy > 40) {
+			if (PC.preg <= PC.pregData.normalBirth / 4 && PC.preg > PC.pregData.normalBirth / 13.33) {
+				r.push(`The rigors of early pregnancy <span class="libido dec">slightly reduce your sexual appetite.</span>`);
+				PC.energy -= 1;
+			} else if (PC.preg >= PC.pregData.normalBirth) {
+				r.push(`You are full-term and <span class="libido inc">feeling rather frisky.</span>`);
+				PC.energy += 2;
+			} else if (PC.preg > PC.pregData.normalBirth / 1.33) {
+				r.push(`As your pregnancy grows, so does that<span class="libido inc">tingling feeling</span> in your crotch.`);
+				PC.energy += 1;
+			}
+		} else {
+			if (PC.preg <= PC.pregData.normalBirth / 4 && PC.preg > PC.pregData.normalBirth / 13.33) {
+				r.push(`The rigors of early pregnancy <span class="libido dec">take their toll on your sexual appetite.</span>`);
+				PC.energy -= 3;
+			} else if (PC.preg >= PC.pregData.normalBirth) {
+				r.push(`You are full-term and feeling way too full for sex, <span class="libido dec">greatly suppressing your sexual appetite.</span>`);
+				PC.energy -= 3;
+			} else if (PC.preg > PC.pregData.normalBirth / 1.33) {
+				r.push(`Your advanced pregnancy <span class="libido dec">greatly hinders your sexual appetite.</span>`);
+				PC.energy -= 2;
+			} else if (PC.preg > PC.pregData.normalBirth / 2) {
+				r.push(`Your growing pregnancy <span class="libido dec">suppresses your sexual appetite slightly.</span>`);
+				PC.energy -= 1;
+			}
+		}
+	}
+
+	function fetalAdjustment() {
+		const oldCount = PC.pregType;
+		if (PC.preg <= 2 && PC.broodmother === 0) {
+			fetalSplit(PC, 1000);
+			WombCleanYYFetuses(PC);
+		}
+		if (V.pregnancyMonitoringUpgrade === 1 && PC.pregKnown) {
+			if (oldCount < PC.pregType) {
+				r.push(`While exploring your new pregnancy with the monitoring tools, you get quite the surprise; <span class="pregnancy">you are more pregnant than previously thought!</span>`);
+			} else if (oldCount > PC.pregType) {
+				r.push(`While exploring your new pregnancy with the monitoring tools, you make an unfortunate discovery; <span class="change negative">some of your fertilized ova have not made it.</span>`);
+				if (PC.pregType === 0) {
+					r.push(`Since there are now none present in your womb, <span class="noteworthy">you are technically no longer pregnant.</span>`);
+					TerminatePregnancy(PC);
+				}
+			}
+		} else if (oldCount > PC.pregType && PC.pregType === 0) {
+			TerminatePregnancy(PC);
+		}
+	}
+
+	function pregnancyAdjustments() {
+		if (PC.geneticQuirks.gigantomastia === 3 && random(1, 200) < PC.hormoneBalance) {
+			PC.geneticQuirks.gigantomastia = 2;
+		}
+		if (PC.geneticQuirks.macromastia === 3 && random(1, 200) < PC.hormoneBalance) {
+			PC.geneticQuirks.macromastia = 2;
+		}
+		if (PC.geneticQuirks.galactorrhea === 2 && random(1, 100) < PC.hormoneBalance && PC.lactation === 0) {
+			PC.inappropriateLactation = 1;
+		}
+		// MOVE THIS
+		/*
+		if (PC.preg > PC.pregData.normalBirth / 2) {
+			if (PC.belly >= 300000) {
+				PC.need *= 0.5;
+			} else if (PC.belly >= 120000) {
+				PC.need *= 0.7;
+			} else if (PC.belly >= 60000) {
+				PC.need *= 0.9;
+			} else {
+				PC.need *= 1.5;
+			}
+		}
+		*/
+	}
+
+	function laborText() {
+		const childIs = (PC.pregType > 1 ? "children are" : "child is");
+		if (isInduced(PC)) {
+			r.push(`Your child${PC.pregType > 1 ? "ren stir" : "stirs"} restlessly as ${PC.pregType > 1 ? "they prepare" : "it prepares"} to enter the world. You experience several`);
+			if (PC.geneticQuirks.uterineHypersensitivity === 2) {
+				r.push(`${PC.counter.birthsTotal > 0 ? "overwhelmingly" : "unexpectedly"} orgasmic`);
+			}
+			r.push(`contractions, so it's best to stay put until it's time.`);
+		} else if (PC.pregControl === "labor suppressors") {
+			r.push(`Your ${childIs} far calmer that one would expect for their stage of development; it is unlikely you will give birth soon, despite being overdue.`);
+		} else {
+			if (PC.preg > PC.pregData.normalBirth + 1) {
+				r.push(`You are constantly beset by your squirming`);
+				if (PC.geneticQuirks.uterineHypersensitivity === 2) {
+					r.push(`${child} and uncontrollable orgasms.`);
+				} else {
+					r.push(`${child}.`);
+				}
+				r.push(`They're overdue, so your water could break at any moment, but for now they aren't quite ready to leave their home.`);
+			} else if (PC.preg > PC.pregData.normalBirth - 1 && PC.preg > PC.pregData.minLiveBirth) {
+				r.push(`You are constantly beset by your squirming`);
+				if (PC.geneticQuirks.uterineHypersensitivity === 2) {
+					r.push(`${child} and uncontrollable orgasms.`);
+				} else {
+					r.push(`${child}.`);
+				}
+				r.push(`Given their liveliness, and how far along you are, it is likely that you will go into labor at any time now.`);
+			} else if (PC.preg > PC.pregData.normalBirth - 2 && PC.preg > PC.pregData.minLiveBirth) {
+				r.push(`You often have to pause and soothe your kicking`);
+				if (PC.geneticQuirks.uterineHypersensitivity === 2) {
+					r.push(`${child}, to spontaneously orgasm,`);
+				} else {
+					r.push(`${child}`);
+				}
+				r.push(`or to catch your breath. With how far along you are, it's possible you may go into labor any day now.`);
+			} else if (PC.preg > PC.pregData.normalBirth - 3 && PC.preg > PC.pregData.minLiveBirth) {
+				r.push(`You often have to pause to soothe your kicking`);
+				if (PC.geneticQuirks.uterineHypersensitivity === 2) {
+					r.push(`${child} or to spontaneously orgasm.`);
+				} else {
+					r.push(`${child}.`);
+				}
+				r.push(`You are far enough along that you could enter labor early.`);
+			}
+		}
+	}
+
+	function pregnancyPhysicalEffects() {
+		let boobTarget;
+		if (PC.geneMods.NCS === 1) {
+			// NCS: always working against secondary sexual characteristics even in pregnancies.
+			boobTarget = 0;
+		} else if (PC.geneticQuirks.androgyny === 2) {
+			boobTarget = 400;
+		} else if (PC.physicalAge >= 18) {
+			if (PC.pregType >= 50) {
+				boobTarget = 10000;
+			} else if (PC.pregType >= 30) {
+				boobTarget = 5000;
+			} else if (PC.pregType >= 10) {
+				boobTarget = 2000;
+			} else if (PC.pregType >= 2) {
+				boobTarget = 1000;
+			} else {
+				boobTarget = 800;
+			}
+		} else if (PC.physicalAge >= 13) {
+			if (PC.pregType >= 50) {
+				boobTarget = 5000;
+			} else if (PC.pregType >= 30) {
+				boobTarget = 3200;
+			} else if (PC.pregType >= 10) {
+				boobTarget = 1800;
+			} else if (PC.pregType >= 2) {
+				boobTarget = 1000;
+			} else {
+				boobTarget = 700;
+			}
+		} else if (PC.physicalAge >= 8) {
+			if (PC.pregType >= 50) {
+				boobTarget = 1800;
+			} else if (PC.pregType >= 30) {
+				boobTarget = 1400;
+			} else if (PC.pregType >= 10) {
+				boobTarget = 1000;
+			} else if (PC.pregType >= 2) {
+				boobTarget = 800;
+			} else {
+				boobTarget = 600;
+			}
+		} else {
+			if (PC.pregType >= 50) {
+				boobTarget = 1000;
+			} else if (PC.pregType >= 30) {
+				boobTarget = 800;
+			} else if (PC.pregType >= 10) {
+				boobTarget = 600;
+			} else {
+				boobTarget = 400;
+			}
+		}
+		boobTarget *= gigantomastiaMod;
+		if (PC.geneMods.NCS === 0) {
+			if (PC.pregType >= 30) {
+				if (PC.weight <= 65) {
+					r.push(`With the amount of food you eat to sustain your brood, <span class="change positive">you put on a little baby weight.</span>`);
+					PC.weight += 1;
+				}
+				if (random(1, 100) > 60) {
+					if (boobSize < boobTarget) {
+						boobsUpText(100);
+						if (PC.boobShape !== "saggy" && PC.preg > PC.pregData.normalBirth / 1.25 && (PC.boobsImplant / PC.boobs < 0.5) && PC.breastMesh !== 1 && PC.drugs !== "sag-B-gone") {
+							r.push(`Your immensely engorged <span class="change negative">mammaries begin to sag</span> as your body continues its motherly transformation in anticipation of breastfeeding.`);
+							PC.boobShape = "saggy";
+						}
+					}
+					if (PC.geneticQuirks.androgyny !== 2) {
+						if (hipSize < 2) {
+							r.push(`Your hips <span class="change positive">widen</span> in preparation for the upcoming births.`);
+							PC.hips += 1;
+						}
+						if (buttSize < 14 + (rearQuirk * 3)) {
+							r.push(`Your butt <span class="change positive">swells with added fat</span> from your ripening body.`);
+							PC.butt += 1;
+						}
+					}
+				}
+			} else if (PC.pregType >= 10) {
+				if (random(1, 100) > 80 && boobSize < boobTarget) {
+					boobsUpText(50);
+					if (PC.boobShape !== "saggy" && (PC.boobsImplant / PC.boobs < 0.5) && PC.breastMesh !== 1 && PC.drugs !== "sag-B-gone") {
+						if (PC.preg > random(PC.pregData.normalBirth / 1.25, PC.pregData.normalBirth * 2.05)) {
+							r.push(`Your swollen <span class="change negative">mammaries begin to sag</span> as your body continues its motherly transformation in anticipation of breastfeeding.`);
+							PC.boobShape = "saggy";
+						}
+					}
+				}
+			} else if (boobSize < boobTarget) {
+				if (random(1, 100) > 80) {
+					boobsUpText(25);
+					if (PC.boobShape !== "saggy" && PC.preg > random(PC.pregData.normalBirth / 1.25, PC.pregData.normalBirth * 2.5) && (PC.boobsImplant / PC.boobs < 0.5) && PC.breastMesh !== 1 && PC.drugs !== "sag-B-gone") {
+						r.push(`Your <span class="change negative">mammaries begin to sag</span> as your body continues its motherly transformation in anticipation of breastfeeding.`);
+						PC.boobShape = "saggy";
+					}
+				}
+			}
+			if (PC.preg > PC.pregData.normalBirth / 1.25 && PC.physicalAge >= 18 && PC.hips === 1 && PC.hipsImplant === 0 && random(1, 100) > 90 / uterineHypersensitivityMod) {
+				r.push(`Your hips <span class="change positive">widen</span> to better support your gravidity.`);
+				PC.hips += 1;
+			} else if (PC.preg > PC.pregData.normalBirth / 1.42 && PC.physicalAge >= 16 && PC.hips === 0 && PC.hipsImplant === 0 && random(1, 100) > 70 / uterineHypersensitivityMod) {
+				r.push(`Your hips <span class="change positive">widen</span> to better support your gravidity.`);
+				PC.hips += 1;
+			}
+			if (PC.preg > PC.pregData.normalBirth / 1.42 && PC.physicalAge >= 12 && buttSize < (4 + (rearQuirk * 3)) && PC.weight >= -30 && random(1, 100) > 70) {
+				r.push(`Your butt <span class="change positive">gets a little bigger</span> as your body ripens.`);
+				PC.butt += 1;
+			}
+		}
+		if (PC.preg === PC.pregData.normalBirth / 2.66) { // change me when nipple color gets hardset
+			if (PC.pregKnown === 0) {
+				r.push(`Your areolae have gotten dark. Some cursory tests reveal <span class="pregnant">you are about fifteen weeks pregnant.</span> How did that manage to slip past you?`);
+				PC.pregKnown = 1;
+			} else {
+				r.push(`Your areolae have gotten dark. Just another step along your pregnancy.`);
+			}
+		} else if (PC.bellyPreg >= 1500) {
+			if (PC.preg > PC.pregData.normalBirth / 2 && PC.lactation === 0) {
+				if (PC.preg > random(PC.pregData.normalBirth / 2.22, PC.pregData.normalBirth / 1.33) && PC.health.condition >= -20 && PC.weight > -30) {
+					r.push(`A moist sensation on your breasts draws your attention; <span class="lime">your milk has come in.</span>`);
+					PC.lactation = 1;
+				}
+			}
+			if (PC.lactation === 1) { // If natural lactation, constantly refresh it.
+				PC.lactationDuration = 2;
+			}
+		}
+	}
+
+	function boobsUpText(bustUp) {
+		if (PC.boobs >= 90000) {
+			r.push(`It's nearly impossible to tell if your inhuman breasts have gotten larger from your pregnancy, but your nipples sitting <span class="lime">further out of reach than ever</span> sure confirms they are.`);
+		} else if (PC.boobs >= 25000) {
+			r.push(`It's nearly impossible to tell if your obscene breasts are getting larger from your pregnancy, but as your nipples <span class="lime">slowly become harder to reach, you can't deny their growth.</span>`);
+		} else if (PC.boobs >= 15000) {
+			r.push(`It may be difficult to gauge growth in breasts as enormous as yours, but your back can sure feel <span class="lime">the extra weight on your chest</span> caused by your pregnancy.`);
+		} else if (PC.boobs >= 7500) {
+			r.push(`It may be difficult to gauge growth in breasts as large as yours, but you can still feel <span class="lime">the extra weight on your chest</span> caused by your pregnancy.`);
+		} else if (PC.boobs >= 3950) {
+			r.push(`Like the cow you are, your udders <span class="lime">have gotten even larger</span> with your pregnancy.`);
+		} else if (PC.boobs >= 1400) {
+			r.push(`Unsurprisingly, your cow tits <span class="lime">have swollen even larger</span> with your pregnancy.`);
+		} else if (PC.boobs >= 1200) {
+			r.push(`Your already huge breasts have <span class="lime">grown even heavier</span> with your pregnancy.`);
+		} else if (PC.boobs >= 1000) {
+			r.push(`Your already large breasts have <span class="lime">grown even larger</span> with your pregnancy.`);
+		} else if (PC.boobs >= 800) {
+			r.push(`Your breasts have <span class="lime">grown a bit larger</span> to feed your coming ${child}.`);
+		} else if (PC.boobs >= 650) {
+			r.push(`Your breasts have <span class="lime">grown a bit larger</span> to feed your coming ${child}.`);
+		} else if (PC.boobs >= 500) {
+			r.push(`Your breasts have <span class="lime">grown a bit larger</span> to feed your coming ${child}.`);
+		} else if (PC.boobs >= 400) {
+			r.push(`Your breasts have <span class="lime">gotten heavier</span> alongside your pregnancy.`);
+		} else if (PC.boobs >= 300) {
+			r.push(`Your breasts have <span class="lime">swollen</span> alongside your pregnancy.`);
+		} else {
+			r.push(`Your chest <span class="lime">has filled out slightly</span> with your pregnancy.`);
+		}
+		PC.boobs += bustUp;
+		r.push(App.EndWeek.Player.bustUp(PC, oldBoobs));
+	}
+
+	function failSafe() {
+		PC.pregType = setPregType(PC);
+		WombImpregnate(PC, PC.pregType, PC.pregSource, PC.preg);
+	}
+
+	function preconception() {
+		if (isFertile(PC)) { // && PC.pregMood === 5
+			needToBreed();
+		}
+		if (canGetPregnant(PC)) {
+			impregnation();
+		}
+		if (PC.ovaImplant === "asexual" && isFertile(PC) && (PC.preg === 0 || (PC.preg >= 0 && PC.geneticQuirks.superfetation === 2))) {
+			autoImpregnation();
+		}
+	}
+
+	function needToBreed() {
+		// Empty for now. Will be used for "breeder" .pregMood.
+	}
+
+	function impregnation() {
+		if (PC.vagina === 0 || (PC.anus === 0 && PC.mpreg > 0)) {
+			// You aren't putting out.
+		} else if (random(1, 100) > (70 - (V.reproductionFormula * 10))) {
+			/** @type {Map<FC.Assignment, number>} */
+			const assignmentWeight = new Map([
+				[Job.CONCUBINE, 7],
+				[Job.MASTERSUITE, 4],
+				[Job.FUCKTOY, 3],
+				[Job.HOUSE, 1],
+				[Job.QUARTER, 1],
+				[Job.MILKED, 1],
+				[Job.BODYGUARD, 1],
+				[Job.HEADGIRL, 1],
+				[Job.RECRUITER, 1],
+				[Job.MATRON, 1],
+				[Job.NURSERY, 1],
+				[Job.ATTENDANT, 1],
+				[Job.STEWARD, 1],
+				[Job.TEACHER, 1]
+			]);
+			const undesirableRace = (s) => (V.arcologies[0].FSSupremacist !== "unset" && (s.race !== V.arcologies[0].FSSupremacistRace)) ||
+				(V.arcologies[0].FSSubjugationist !== "unset" && (s.race === V.arcologies[0].FSSubjugationistRace));
+			const raceIsAcceptable = (s) => !undesirableRace(s) ||
+				(s.relationship === -3) ||
+				[Job.CONCUBINE, Job.MASTERSUITE, Job.FUCKTOY].includes(s.assignment);
+			const score = (/** @type {App.Entity.SlaveState} */s) => {
+				let weight = (assignmentWeight.get(s.assignment) || 0);
+				if (s.relationship === -3 && isSlaveAvailable(s)) { // assumes player will seek relations with slavewife if available
+					weight += 3;
+				}
+				if (onBedRest(PC) && weight < 3) {
+					weight = 0;
+				}
+				return weight;
+			};
+
+			let dadHash;
+			if (V.policies.sexualOpenness === 1) {
+				dadHash = V.slaves.filter(s => canImpreg(V.PC, s) && canAchieveErection(s) && s.devotion > 20 && raceIsAcceptable);
+			} else {
+				dadHash = V.slaves.filter(s => canImpreg(V.PC, s) && s.toyHole === "dick");
+			}
+			dadHash.reduce((acc, cur) => Object.assign(acc, {[cur.ID]: score(cur)}), {});
+			const chosenDadID = hashChoice(dadHash);
+			if (chosenDadID) {
+				knockMeUp(PC, 100, 2, chosenDadID);
+			}
+		}
+	}
+
+	function autoImpregnation() {
+		knockMeUp(PC, 100, 2, PC.ID);
+		if (PC.geneticQuirks.superfetation === 2 && PC.pregKnown === 1) {
+			if (V.geneticMappingUpgrade === 0 && PC.counter.birthsTotal === 0) {
+				r.push(`You are wracked with frequent spontaneous orgasms from your asexual reproduction modifications despite already being pregnant.`);
+			} else {
+				r.push(`Your asexual reproduction modifications don't care that you've already got a bun in the oven, a fact made clear as they force you into adding <span class="pregnant">yet another child into your increasingly crowded womb.</span> At this rate, you will spend the rest of your fertile years as a constantly pregnant broodmother.`);
+			}
+		} else {
+			r.push(`Your asexual reproduction modifications leaves you writhing in constant orgasm for a short time. You are only released once you've <span class="pregnant">thoroughly impregnated yourself.</span>`);
+			PC.pregKnown = 1;
+		}
+	}
+
+	function pregnancySanityCheck() { // PREGNANCY TYPE SANITY CHECK (not for pregnancies started above)
+		if (PC.preg <= 0) {
+			if (PC.pregType !== 0) {
+				WombFlush(PC);
+			}
+		} else if (PC.preg > 0 && PC.pregType === 0) {
+			PC.pregType = setPregType(PC);
+			WombImpregnate(PC, PC.pregType, PC.pregSource, 1);
+		}
+		if (PC.readyOva !== 0) {
+			PC.readyOva = 0;
+		}
+	}
+};
diff --git a/src/endWeek/reports/cellblockReport.js b/src/endWeek/reports/cellblockReport.js
index de18e36d06188d72bf7a3e550c22588fbd236e43..cb063ff01ffec5dcbd7cfc7df7304ae87ad3bfb5 100644
--- a/src/endWeek/reports/cellblockReport.js
+++ b/src/endWeek/reports/cellblockReport.js
@@ -15,7 +15,7 @@ App.EndWeek.cellblockReport = function() {
 	let confinedResults;
 
 	const cellblockNameCaps = capFirstChar(V.cellblockName);
-	V.flSex = App.EndWeek.getFLSex(App.Entity.facilities.cellblock);/* FIXME: should be local, passed as a parameter to saRules */
+	App.EndWeek.saVars.flSex = App.EndWeek.getFLSex(App.Entity.facilities.cellblock);
 
 	if (S.Wardeness) {
 		const {
diff --git a/src/endWeek/reports/clinicReport.js b/src/endWeek/reports/clinicReport.js
index 707c7c35d0caa4273f11a0b1957d3bc592cc08f9..372ece308e4dccb679166b1048fcdc0ac22f79eb 100644
--- a/src/endWeek/reports/clinicReport.js
+++ b/src/endWeek/reports/clinicReport.js
@@ -4,7 +4,7 @@ App.EndWeek.clinicReport = function() {
 	const slaves = App.Utils.sortedEmployees(App.Entity.facilities.clinic);
 	let devBonus = (V.clinicDecoration !== "standard") ? 1 : 0;
 	let healthBonus = 0;
-	V.flSex = App.EndWeek.getFLSex(App.Entity.facilities.clinic); // FIXME: should be local, passed as a parameter to saRules
+	App.EndWeek.saVars.flSex = App.EndWeek.getFLSex(App.Entity.facilities.clinic);
 
 	function nurseText() {
 		let r = [];
@@ -385,6 +385,12 @@ App.EndWeek.clinicReport = function() {
 						r.push(`so ${he} has returned to rest.`);
 					}
 				} else {
+					// This needs to be set here or else it freaks out and returns errors. It also can't be defaulted without hiding issues, so we set something here.
+					if (slave.assignment === Job.WHORE || slave.assignment === Job.BROTHEL) {
+						slave.sexAmount = Math.trunc(Beauty(slave) / 5);
+						slave.sexQuality = FResult(slave);
+						slave.effectiveWhoreClass = effectiveWhoreClass(slave);
+					}
 					r.push(`so ${he} goes back to ${slave.assignment}.`);
 				}
 			} else {
diff --git a/src/endWeek/reports/dairyReport.js b/src/endWeek/reports/dairyReport.js
index aa6836514e5bba1877d4c12f58fbcd5dba9f4bdc..844e4eec9fb5a0ede49687a6b27ff3f45fdfc1a3 100644
--- a/src/endWeek/reports/dairyReport.js
+++ b/src/endWeek/reports/dairyReport.js
@@ -375,7 +375,7 @@ App.EndWeek.dairyReport = function() {
 		/* Perform facility based rule changes */
 
 		// Set diet
-		if (V.dairySlimMaintain === 0) {
+		if (V.dairySlimMaintain === 0 || V.dairySlimMaintainUpgrade === 0) {
 			if (V.dairyWeightSetting === 0) {
 				if (slave.weight <= 30) {
 					slave.diet = "fattening";
@@ -714,12 +714,12 @@ App.EndWeek.dairyReport = function() {
 
 		// Stimulators
 		if (V.dairyStimulatorsUpgrade === 1 && V.dairyStimulatorsSetting > 0) {
-			if (V.dairyStimulatorsSetting > 1 && slave.anus < 4) {
+			if (V.seeStretching === 1 && V.dairyStimulatorsSetting > 1 && slave.anus < 4) {
 				slave.anus++;
 				if (slave.anus >= 4) {
 					anusesStretched++;
 				}
-			} else if (slave.anus < 3) {
+			} else if (V.seeStretching === 1 && slave.anus < 3) {
 				slave.anus++;
 			}
 			if (slave.health.condition < 60) {
@@ -1003,12 +1003,12 @@ App.EndWeek.dairyReport = function() {
 						cashValue = 25;
 					}
 					cashX(cashValue, "slaveAssignmentDairy", slave);
-					if (V.dairyPregSetting > 1 && slave.vagina < 4) {
+					if (V.seeStretching === 1 && V.dairyPregSetting > 1 && slave.vagina < 4) {
 						slave.vagina++;
 						if (slave.vagina === 4) {
 							vaginasStretched++;
 						}
-					} else if (slave.vagina < 3) {
+					} else if (V.seeStretching === 1 && slave.vagina < 3) {
 						slave.vagina++;
 					}
 				}
diff --git a/src/endWeek/reports/farmyardReport.js b/src/endWeek/reports/farmyardReport.js
index e5291a00744f1ac5f7985a615badf1cd39da37db..d3ee19f721ff34fbc465be2d0c2ef0ef3d8fd560 100644
--- a/src/endWeek/reports/farmyardReport.js
+++ b/src/endWeek/reports/farmyardReport.js
@@ -9,6 +9,7 @@ App.EndWeek.farmyardReport = function farmyardReport() {
 	let foodWeek = 0;
 
 	const statsSpan = document.createElement("span");
+	frag.append(statsSpan);
 
 	// Statistics gathering
 	V.facility = V.facility || {};
@@ -22,10 +23,10 @@ App.EndWeek.farmyardReport = function farmyardReport() {
 	V.mods.food.amount += foodWeek;
 
 	if (Farmer) {
-		const farmerEffects = App.UI.DOM.appendNewElement("p", frag, '', "indent");
+		const farmerEffects = App.UI.DOM.appendNewElement("p", frag, null, ["indent"]);
 
 		if (V.showEWD) {
-			const farmerEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
+			const farmerEntry = App.UI.DOM.appendNewElement("div", frag, null, ["slave-report"]);
 			const artSpan = App.UI.DOM.appendNewElement("span", farmerEntry);
 			App.SlaveAssignment.appendSlaveLinks(farmerEntry, Farmer);
 			$(farmerEntry).append(`<span class="slave-name">${SlaveFullName(Farmer)}</span> is serving as the Farmer.`);
@@ -42,7 +43,7 @@ App.EndWeek.farmyardReport = function farmyardReport() {
 	}
 
 	if (slaves) {
-		const intro = App.UI.DOM.appendNewElement("p", frag, '', "indent");
+		const intro = App.UI.DOM.appendNewElement("p", frag, null, ["indent"]);
 
 		$(intro).append(farmhandCount(slaves.length));
 
@@ -50,7 +51,7 @@ App.EndWeek.farmyardReport = function farmyardReport() {
 			slave.devotion += devBonus;
 
 			if (V.showEWD) {
-				const slaveEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
+				const slaveEntry = App.UI.DOM.appendNewElement("div", frag, null, ["slave-report"]);
 				const artSpan = App.UI.DOM.appendNewElement("span", slaveEntry);
 				App.SlaveAssignment.appendSlaveLinks(slaveEntry, slave);
 				$(slaveEntry).append(`<span class="slave-name">${SlaveFullName(slave)}</span> `);
@@ -70,7 +71,7 @@ App.EndWeek.farmyardReport = function farmyardReport() {
 
 				profits += farmhandProfit(slave);
 
-				const farmhandContent = App.UI.DOM.appendNewElement("div", slaveEntry, '', "indent");
+				const farmhandContent = App.UI.DOM.appendNewElement("div", slaveEntry, null, ["indent"]);
 
 				$(farmhandContent).append(App.SlaveAssignment.workTheFarm(slave));
 				slaveEntry.append(App.SlaveAssignment.standardSlaveReport(slave, false));
@@ -190,18 +191,20 @@ App.EndWeek.farmyardReport = function farmyardReport() {
 	}
 
 	function farmerText() {
-		let r = [];
-
-		r.push(farmerIntro(Farmer));
-		r.push(farmerRelationshipPC(Farmer));
-		r.push(farmerFetishEffects(Farmer, farmerFetish(Farmer)));
-		r.push(farmerSkill(Farmer));
-		r.push(farmerExperience(Farmer));
-		r.push(farmerTiredness(Farmer));
-		r.push(farmerIntelligence(Farmer));
-		r.push(farmerSmell(Farmer));
-		r.push(farmerRelationshipSlaves(Farmer));
-		r.push(farmerContracts(Farmer));
+		const r = [];
+
+		r.push(
+			farmerIntro(Farmer),
+			farmerRelationshipPC(Farmer),
+			farmerFetishEffects(Farmer, farmerFetish(Farmer)),
+			farmerSkill(Farmer),
+			farmerExperience(Farmer),
+			farmerTiredness(Farmer),
+			farmerIntelligence(Farmer),
+			farmerSmell(Farmer),
+			farmerRelationshipSlaves(Farmer),
+			farmerContracts(Farmer)
+		);
 
 		return r.join(' ');
 	}
@@ -236,7 +239,7 @@ App.EndWeek.farmyardReport = function farmyardReport() {
 	function farmerSkill(slave) {
 		const {he, his, His} = getPronouns(slave);
 
-		let r = [];
+		const r = [];
 
 		if (slave.skill.farmer <= 10) {
 			r.push(`Though ${slave.slaveName} does ${his} best to manage the farmyard, with ${his} lack of skill ${he} can do little.`);
@@ -281,7 +284,7 @@ App.EndWeek.farmyardReport = function farmyardReport() {
 	function farmerRelationshipSlaves(Farmer) {
 		const {he, his, He} = getPronouns(Farmer);
 
-		let r = [];
+		const r = [];
 
 		for (const slave of slaves) {
 			if (Farmer.rivalryTarget === slave.ID) {
@@ -315,15 +318,16 @@ App.EndWeek.farmyardReport = function farmyardReport() {
 	function farmerContracts(slave) {
 		const {he, his, himself} = getPronouns(slave);
 
-		let r = [];
-		let seed = Math.trunc(App.Facilities.Farmyard.farmShowsIncome(slave));
+		const r = [];
+		const seed = Math.trunc(App.Facilities.Farmyard.farmShowsIncome(slave));
 
-		if (V.farmyardShows && !V.farmyardShowgirls) {
-			r.push(`<p class="indent">Since ${he} doesn't have enough showgirls to entertain your arcology's citizens, ${he} puts on shows with your animals on ${his} own, earning <span class="cash">${cashFormat(seed)}.</span></p>`);
-		} else if (!V.farmyardFarmers) {
-			r.push(`<p class="indent">Since ${V.farmyardName} doesn't have anyone tending to the crops, ${he} looks after them ${himself}, earning <span class="cash">${cashFormat(seed)}.</span></p>`);
+		if (!App.Entity.facilities.farmyard.employeesIDs()) {
+			if (V.farmyardShows > 0) {
+				r.push(`<p class="indent">Since ${he} doesn't have enough showgirls to entertain your arcology's citizens, ${he} puts on shows with your animals on ${his} own, earning <span class="cash">${cashFormat(seed)}.</span></p>`);
+			} else {
+				r.push(`<p class="indent">Since ${V.farmyardName} doesn't have anyone tending to the crops, ${he} looks after them ${himself}, earning <span class="cash">${cashFormat(seed)}.</span></p>`);
+			}
 		}
-
 		return r;
 	}
 
@@ -458,10 +462,12 @@ App.EndWeek.farmyardReport = function farmyardReport() {
 		if (V.farmyardDecoration !== 'standard') {
 			text.push(`${capFirstChar(V.farmyardName)}'s customer's enjoyed`);
 
-			if (V.seeBestiality && V.policies.bestialityOpenness && (V.animals.canine.length || V.animals.hooved.length || V.animals.feline.length)) {
-				text.push(`<span class="reputation inc">watching farmhands fuck animals in ${V.farmyardDecoration} surroundings.</span>`);
-			} else if (V.farmyardShows) {
-				text.push(`<span class="reputation inc">watching farmhands put on shows in ${V.farmyardDecoration} surroundings.</span>`);
+			if (V.farmyardShows > 0) {
+				if (V.seeBestiality && V.policies.bestialityOpenness && (V.animals.canine.length || V.animals.hooved.length || V.animals.feline.length)) {
+					text.push(`<span class="reputation inc">watching farmhands fuck animals in ${V.farmyardDecoration} surroundings.</span>`);
+				} else {
+					text.push(`<span class="reputation inc">watching farmhands put on shows in ${V.farmyardDecoration} surroundings.</span>`);
+				}
 			} else {
 				text.push(`<span class="reputation inc">partaking of ${V.farmyardName}'s fine produce in its ${V.farmyardDecoration} décor.</span>`);
 			}
diff --git a/src/endWeek/reports/incubatorReport.js b/src/endWeek/reports/incubatorReport.js
index 37258b84c679a8d73ae9618305cb8af981b3a3e3..e06b0b3897194534376e697bb7fa40099e613f65 100644
--- a/src/endWeek/reports/incubatorReport.js
+++ b/src/endWeek/reports/incubatorReport.js
@@ -157,7 +157,7 @@ App.EndWeek.incubatorReport = function() {
 		r = [];
 		if (V.incubator.upgrade.growthStims === 1 && V.incubator.setting.growthStims !== 0) {
 			let heightLimit = Math.clamp((Height.mean(tank) * 1.25), 0, 274);
-			let heightLimitAge = Height.forAge(tank.height, tank);
+			let heightLimitAge = Height.mean(tank);
 			if (tank.geneticQuirks.dwarfism === 2 && tank.geneticQuirks.gigantism !== 2) {
 				heightLimit = Math.clamp((Height.mean(tank) * 0.95), 0, 160);
 			} else if (tank.geneticQuirks.gigantism === 2 && tank.geneticQuirks.dwarfism !== 2) {
@@ -167,11 +167,13 @@ App.EndWeek.incubatorReport = function() {
 				/* NCS should block physical growth beyond that of a toddler, but some players might like
 				 * a little more or less. So using V.minimumSlaveAge or 8, whichever is lesser.	*/
 				const limitAge = Math.min(8, V.minimumSlaveAge);
-				heightLimitAge = Height.forAge(tank.height, limitAge, tank.genes);
-				heightLimit = heightLimitAge;
-			} else if (tank.geneticQuirks.neoteny === 2 && tank.actualAge > 12) {
-				heightLimitAge = Height.forAge(tank.height, 12, tank.genes);
-				heightLimit = heightLimitAge;
+				/* Generate new average height for slave of age limitAge */
+				heightLimitAge = Height.mean(tank.nationality, tank.race, tank.genes, limitHeight);
+				heightLimit = heightLimitAge; /* TODO: Add some variation, right now all NCS slaves will be the exact same height */
+			} else if (tank.geneticQuirks.neoteny === 2 && tank.physicalAge > 12) {
+				/* Generate new average height for slave of age 12 */
+				heightLimitAge = Height.mean(tank.nationality, tank.race, tank.genes, 12);
+				heightLimit = Math.clamp((heightLimitAge * 1.25), 0, 274);
 			}
 			if (tank.height >= heightLimit) {
 				r.push(`The monitoring system detects ${his} body is not able to support further increases in height, so it carefully regulates stimulant injections to <span class="yellow">maintain ${his} current stature.</span>`);
diff --git a/src/endWeek/reports/masterSuiteReport.js b/src/endWeek/reports/masterSuiteReport.js
index b91600b45ffd490dac590c6e7ab557bbf6f4e90d..3b47eb3727e82ebeb78276cb16c3d1de98e1e97a 100644
--- a/src/endWeek/reports/masterSuiteReport.js
+++ b/src/endWeek/reports/masterSuiteReport.js
@@ -339,7 +339,10 @@ App.EndWeek.masterSuiteReport = function() {
 				const milkDiv = App.UI.DOM.appendNewElement("div", smallFrag, `When ${his} breasts begin to feel full and you aren't around, ${he} avails ${himself} to the penthouse milkers and gives ${milkingResults.milk} liters of milk over the week, which is sold for `, "indent");
 				App.UI.DOM.appendNewElement("span", milkDiv, `${cashFormat(milkingResults.milkSale)}.`, ["cash", "inc"]);
 			}
-			smallFrag.append(App.SlaveAssignment.standardSlaveReport(slave, false));
+			App.Events.addNode(smallFrag, [
+				App.SlaveAssignment.choosesOwnClothes(slave),
+				...App.SlaveAssignment.individualSlaveReport(slave),
+			], "div", "indent");
 		} else {
 			// discard return values silently
 			App.SlaveAssignment.choosesOwnJob(slave);
@@ -347,8 +350,12 @@ App.EndWeek.masterSuiteReport = function() {
 			if (V.servantMilkers === 1 && slave.lactation > 0 && slave.fuckdoll === 0 && slave.fetish !== "mindbroken" && canMove(slave) && slave.intelligence + slave.intelligenceImplant >= -90) {
 				App.SlaveAssignment.getMilked(slave, 0.25);
 			}
-			App.SlaveAssignment.standardSlaveReport(slave, true);
+			App.SlaveAssignment.choosesOwnClothes(slave);
+			App.SlaveAssignment.individualSlaveReport(slave);
 		}
+		smallFrag.append(App.PersonalAttention.slaveReport(slave));
+		App.Events.addNode(smallFrag, [App.SlaveAssignment.devotion(slave)], "div", "indent");
+
 		if (slave.health.condition < 80) {
 			if (V.masterSuiteUpgradeLuxury === 1) {
 				improveCondition(slave, 20);
diff --git a/src/endWeek/reports/nurseryReport.js b/src/endWeek/reports/nurseryReport.js
index 66bda83d85b7a45bdadfc4e5f65af73a82a21849..f97a9a47fcdd065ed615e83cdf67db6e19cf30e7 100644
--- a/src/endWeek/reports/nurseryReport.js
+++ b/src/endWeek/reports/nurseryReport.js
@@ -11,7 +11,7 @@ App.Facilities.Nursery.nurseryReport = function nurseryReport() {
 
 	let matronBonus = 0;
 
-	V.flSex = App.EndWeek.getFLSex(App.Entity.facilities.nursery); // FIXME: should be local, passed as a parameter to saRules
+	App.EndWeek.saVars.flSex = App.EndWeek.getFLSex(App.Entity.facilities.nursery);
 
 	function matronChanges() {
 		if (S.Matron) {
diff --git a/src/endWeek/reports/penthouseReport.js b/src/endWeek/reports/penthouseReport.js
index 0e0c031c1360c65e524ab1be1311d737692c2967..f2dc91c5624554929312c3bf835cb573c66e2dd7 100644
--- a/src/endWeek/reports/penthouseReport.js
+++ b/src/endWeek/reports/penthouseReport.js
@@ -61,7 +61,7 @@ App.EndWeek.penthouseReport = function() {
 		const el = new DocumentFragment();
 		const {
 			He, His,
-			he, him
+			he, him,
 		} = getPronouns(slave);
 		let r = [];
 		let milkResults;
@@ -151,7 +151,6 @@ App.EndWeek.penthouseReport = function() {
 			}
 			r.push(`and ${he} gives ${milkResults.milk} liters of milk over the week, which is sold for <span class="yellowgreen">${cashFormat(milkResults.milkSale)}.</span>`);
 		}
-
 		App.Events.addNode(el, r);
 
 		if (V.showEWD !== 0) {
@@ -168,20 +167,15 @@ App.EndWeek.penthouseReport = function() {
 			App.SlaveAssignment.individualSlaveReport(slave);
 		}
 
-		r = [];
-		if (V.PC.health.shortDamage < 30 && V.personalAttention.task === PersonalAttention.TRAINING && V.personalAttention.slaves.some(s => s.ID === slave.ID)) {
-			r.push(App.personalAttention.slaveReport(slave));
-		}
-
+		el.append(App.PersonalAttention.slaveReport(slave));
 		if (HGTrainSlavesIDs.length > 0) {
 			const trainee = HGTrainSlavesIDs.find(trainee => slave.ID === trainee.ID);
 			if (trainee) {
-				r.push(HGApplication(slave, trainee.training));
+				el.append(HGApplication(slave, trainee.training));
 			}
 		}
 
-		r.push(`<div class="indent">${App.SlaveAssignment.devotion(slave)}</div>`);
-		App.Events.addNode(el, r);
+		App.Events.addNode(el, [App.SlaveAssignment.devotion(slave)], "div", "indent");
 		return el;
 	}
 
@@ -190,10 +184,10 @@ App.EndWeek.penthouseReport = function() {
 	 * @param {string} headGirlsTraining
 	 */
 	function HGApplication(slave, headGirlsTraining) {
-		const el = document.createElement("span");
+		const el = new DocumentFragment();
 		const {
 			He, His,
-			he, his, him, himself, girl
+			he, his, him, himself, girl,
 		} = getPronouns(S.HeadGirl);
 		const {he2, His2, his2, him2, himself2, girl2} = getPronouns(slave).appendSuffix("2");
 		let r = [];
diff --git a/src/endWeek/reports/personalAttention.js b/src/endWeek/reports/personalAttention.js
index 4d84837928244417216c6954a4568e8f8bf9b171..cf2cf452a4d2c150944527e7ecd1baa751e34df7 100644
--- a/src/endWeek/reports/personalAttention.js
+++ b/src/endWeek/reports/personalAttention.js
@@ -1,21 +1,35 @@
 /**
  * @param {App.Entity.SlaveState} slave
- * @returns {HTMLElement}
+ * @returns {DocumentFragment}
  */
-App.personalAttention.slaveReport = function(slave) {
-	let pa;
-	const el = document.createElement("p");
-	el.classList.add("indent");
+App.PersonalAttention.slaveReport = function(slave) {
+	const el = new DocumentFragment();
 	if (V.personalAttention.task !== PersonalAttention.TRAINING) {
-		throw Error(`Personal attention requested for slave ${SlaveFullName(slave)} but is set to "${V.personalAttention.task}"`);
+		return el; // not training any slaves this week
 	}
-	pa = V.personalAttention.slaves.find((s) => s.ID === slave.ID);
+	const pa = V.personalAttention.slaves.find((s) => s.ID === slave.ID);
+	if (!pa) {
+		return el; // not training this slave this week
+	}
+
+	// trying to train this slave this week
 	const {
 		He, His,
-		he, his, him, himself, wife, girl, hers
+		he, his, him, himself, wife, girl, hers,
 	} = getPronouns(slave);
 	const {womenP} = getPronouns(V.PC).appendSuffix("P");
 	let r = [];
+
+	if (V.PC.health.shortDamage >= 30) {
+		// too badly injured to train this week
+		r.push(`You planned to ${pa.objective === "health" ? "care for" : "train"}`);
+		r.push(App.UI.DOM.makeElement("span", slave.slaveName, ["slave-name"]));
+		r.push(`this week, but you're not feeling up to it.`);
+		App.Events.addNode(el, r, "div", "indent");
+		return el;
+	}
+
+	// actually training this slave
 	let currentSlaveValue = slave.training < 100 ? 0.2 : 0.5;
 	let coloredText;
 	let trainingEfficiency;
@@ -23,11 +37,11 @@ App.personalAttention.slaveReport = function(slave) {
 	let analTrainingEfficiency;
 	let seed;
 	if (pa.objective === "health") {
-		r.push(App.UI.DOM.makeElement("span", `You care for`, "bold"));
+		r.push(App.UI.DOM.makeElement("span", `You care for`, ["bold"]));
 	} else {
-		r.push(App.UI.DOM.makeElement("span", `You train`, "bold"));
+		r.push(App.UI.DOM.makeElement("span", `You train`, ["bold"]));
 	}
-	r.push(App.UI.DOM.makeElement("span", slave.slaveName, "slave-name"));
+	r.push(App.UI.DOM.makeElement("span", slave.slaveName, ["slave-name"]));
 	r.push(`when ${he} isn't otherwise occupied.`);
 	slave.training = Math.clamp(slave.training, 0, 100);
 	slave.training += 80 - (slave.intelligence + slave.intelligenceImplant) / 5 + ((slave.devotion + slave.trust) / 10);
@@ -39,7 +53,7 @@ App.personalAttention.slaveReport = function(slave) {
 			slave.devotion += 6;
 			if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === "submissive") {
 				r.push(`Since ${slave.slaveName} is a submissive, you`);
-				r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["hotpink"]));
 				r.push(`by indulging ${his} need to be dominated. Already smiling to ${himself}, ${he} changes into bondage gear that`);
 				if (canSee(slave)) {
 					r.push(`blinds ${him},`);
@@ -66,12 +80,12 @@ App.personalAttention.slaveReport = function(slave) {
 				r.push(`Thus attired, ${he} is forced to serve you in whatever petty ways occur to you. ${He} holds your tablet for you on ${his} upthrust ass as you work, holds a thin beverage glass for you in ${his} upturned mouth when you eat, and lies still so you can use ${his} tits as a pillow whenever you recline. ${He} loves it.`);
 			} else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === "cumslut" && V.PC.dick !== 0) {
 				r.push(`Since ${slave.slaveName} has an unusual taste for oral sex and cum, you`);
-				r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["hotpink"]));
 				r.push(`by indulging ${him}. You allow ${him} to spend ${his} free time following you around. ${He} is permitted to act as your private cum receptacle. If you use another slave, you usually pull out and give ${his} smiling face a facial. When you come inside another slave instead, ${slave.slaveName} is allowed to get your cum anyway, regardless of whether that requires the other slave to spit it into ${his} mouth or ${slave.slaveName} to suck it out of the other slave's vagina or rectum. Either way, ${he} rubs ${his} stomach happily after ${he}'s swallowed it down.`);
 				seX(slave, "oral", V.PC, "penetrative", 20);
 			} else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === "boobs") {
 				r.push(`Since ${slave.slaveName} has an unusual taste for having ${his} tits fondled, you`);
-				r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["hotpink"]));
 				r.push(`by indulging ${him}. You keep ${him} near you as a sort of living stress ball. Whenever you have a free hand, whether you're conducting business or buttfucking another slave, you reach over and play with ${him}. ${He} sometimes masturbates while you massage ${his} breasts and`);
 				if (slave.nipples === "fuckable") {
 					r.push(`finger`);
@@ -82,7 +96,7 @@ App.personalAttention.slaveReport = function(slave) {
 				seX(slave, "mammary", V.PC, "penetrative", 10);
 			} else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === "pregnancy") {
 				r.push(`Since ${slave.slaveName} has an unusual taste for big pregnant bellies, you`);
-				r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["hotpink"]));
 				r.push(`by indulging ${him}. You`);
 				if (isItemAccessible.entry("a small empathy belly", "bellyAccessory") && slave.belly < 1500 && slave.weight < 130) {
 					r.push(`strap an enormous sympathy belly onto ${him} and`);
@@ -98,13 +112,13 @@ App.personalAttention.slaveReport = function(slave) {
 					)
 			) {
 				r.push(`Since ${slave.slaveName} has an unusual sexuality, you`);
-				r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["hotpink"]));
 				r.push(`by indulging ${his} perversions. Since ${he}'s an absolute slut for humiliation, you let ${him} whore around inside the special camera room whenever possible. When you're going out and feel like putting on a show, you bring ${him} on a leash and fuck ${him} in public. ${He} comes harder than ever when you push ${his} naked body up against the wall of a crowded public arcology elevator and molest ${him}.`);
 				seX(slave, "oral", V.PC, "penetrative", 4);
 				r.push(VCheck.Both(slave, 4, 2));
 			} else if (slave.fetishKnown === 1 && slave.fetishStrength > 60 && slave.fetish === "humiliation") {
 				r.push(`Since ${slave.slaveName} has an unusual sexuality, you`);
-				r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `build ${his} devotion to you`, ["hotpink"]));
 				r.push(`by indulging ${his} perversions. Since ${he}'s an absolute slut for humiliation, you let ${him} whore around inside the special camera room whenever possible. When you're going out and feel like putting on a show, you`);
 				if (hasBothLegs(slave)) {
 					r.push(`bring ${him} on a leash and have ${him} service you in public. ${He} comes harder than ever when you push ${him} down on ${his} knees in a crowded public arcology elevator and facefuck ${him} while ${he}`);
@@ -126,9 +140,9 @@ App.personalAttention.slaveReport = function(slave) {
 			} else if ((slave.anus === 3) && (slave.vagina === 3) && slave.geneMods.rapidCellGrowth !== 1) {
 				r.push(`${slave.slaveName} is a stretched-out, well-traveled slut. Some like their holes loose, but most prefer cunts and butts that don't make sloppy noises when fucked. So, you spend some quality care time with ${him}, carefully massaging ${his} abused holes with oils and lotions. ${He} comes, of course, but ${his} pussy and asshole do benefit from the treatment. You allow ${him} to service you with ${his} mouth to avoid spoiling your work right away. Afterward, ${he}`);
 				if (hasAnyArms(slave)) {
-					r.push(App.UI.DOM.makeElement("span", `hugs you and gives you a kiss.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `hugs you and gives you a kiss.`, ["hotpink"]));
 				} else {
-					r.push(App.UI.DOM.makeElement("span", `gives you a kiss and tries to hug you,`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `gives you a kiss and tries to hug you,`, ["hotpink"]));
 					r.push(`but without arms, all ${he} manages is a sort of nuzzle.`);
 				}
 				slave.vagina--;
@@ -136,7 +150,7 @@ App.personalAttention.slaveReport = function(slave) {
 				seX(slave, "oral", V.PC, "penetrative", 5);
 			} else if (slave.vagina === 0) {
 				r.push(`${slave.slaveName}'s accustomed to the slave life, so the experience is almost novel for ${him} and ${he} is`);
-				r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["hotpink"]));
 				r.push(`${He} isn't used to being kissed, teased and massaged. ${He}'s almost disappointed when it becomes clear that you don't mean to take ${his} virginity. You gently stimulate ${his}`);
 				if (slave.dick) {
 					r.push(`dick`);
@@ -145,22 +159,33 @@ App.personalAttention.slaveReport = function(slave) {
 				} else {
 					r.push(`nipples`);
 				}
-				r.push(`while ${he} sucks you off, bringing ${him} to a moaning climax as you cum in ${his} mouth.`);
-				seX(slave, "oral", V.PC, "penetrative", 5);
+				if (slave.rules.release.master) {
+					r.push(`while ${he} sucks you off, bringing ${him} to a moaning climax as you cum in ${his} mouth.`);
+					seX(slave, "oral", V.PC, "penetrative", 5);
+				} else {
+					r.push(`as you play with ${his} body, subconsciously causing ${him} to become more accustomed to your presence.`);
+				}
 			} else if (slave.anus === 0 && slave.vagina < 0) {
-				r.push(`You haven't decided to take ${slave.slaveName}'s anus yet, so you let ${him} suck you off and play with ${himself} while ${he} does. You stroke ${his} hair, play with ${his} tits, and generally pamper ${him} while ${he} orally services you. ${He}'s accustomed to the slave life, so the experience of affection is novel for ${him} and ${he} is`);
-				r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, "hotpink"));
-				r.push(`${He} isn't used to being kissed, teased and massaged. ${He}'s almost disappointed when it becomes clear that you don't mean to take ${his} virgin hole.`);
-				seX(slave, "oral", V.PC, "penetrative", 5);
+				// TODO: not sure if the PC has to have either a dick or a vagina... can PCs be nulls?
+				if (slave.rules.release.master) {
+					r.push(`You haven't decided to take ${slave.slaveName}'s anus yet, so you have ${him} ${V.PC.dick > 0 ? `suck you off` : `eat you out`} and allow ${him} to play with ${himself} while ${he} does. You stroke ${his} hair, play with ${his} tits, and generally pamper ${him} while ${he} orally services you. ${He}'s accustomed to the slave life, so the experience of affection is novel for ${him} and ${he} is`);
+					r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["hotpink"]));
+					r.push(`${He} isn't used to being kissed, teased and massaged. ${He}'s almost disappointed when it becomes clear that you don't mean to take ${his} virgin hole.`);
+					seX(slave, "oral", V.PC, "penetrative", 5);
+				} else {
+					r.push(`You haven't decided to take ${slave.slaveName}'s anus yet, so you have ${him} ${V.PC.dick > 0 ? `jerk you off` : `play with your pussy`} and allow ${him} to play with ${himself} while ${he} does. You stroke ${his} hair, play with ${his} tits, and generally pamper ${him} while ${he} services you. ${He}'s accustomed to the slave life, so the experience of affection is novel for ${him} and ${he} is`);
+					r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["hotpink"]));
+					r.push(`${He} isn't used to being kissed, teased and massaged. ${He}'s almost disappointed when it becomes clear that you don't mean to take ${his} virgin hole.`);
+				}
 			} else if (slave.anus === 0 && slave.vagina > 0 && canDoVaginal(slave)) {
 				r.push(`You fuck ${slave.slaveName}, of course, but you do it slowly and lovingly, and keep well clear of ${his} still-virgin asshole in the process. ${He}'s accustomed to the slave life, so the experience is almost novel for ${him} and ${he} is affectingly`);
-				r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["hotpink"]));
 				r.push(`${He} isn't used to being kissed, teased and massaged before ${he} takes cock. Slaves are usually used without regard to their orgasm, so ${he}'s also surprised and gratified when you make meticulous efforts to delay your own orgasm so it can coincide with ${his} own. ${He}'s a puddle on the sheets under your hands.`);
 				seX(slave, "oral", V.PC, "penetrative", 4);
 				r.push(VCheck.Vaginal(slave, 4));
 			} else if (slave.anus === 0) {
 				r.push(`${slave.slaveName}'s accustomed to the slave life, so the experience is almost novel for ${him} and ${he} is`);
-				r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["hotpink"]));
 				r.push(`${He} isn't used to being kissed, teased and massaged. ${He}'s almost disappointed when it becomes clear that you don't mean to take ${his} anal virginity. You gently stimulate ${his}`);
 				if (slave.dick) {
 					r.push(`dick`);
@@ -173,7 +198,7 @@ App.personalAttention.slaveReport = function(slave) {
 				seX(slave, "oral", V.PC, "penetrative", 5);
 			} else {
 				r.push(`You fuck ${slave.slaveName}, of course, but you do it slowly and lovingly. ${He}'s accustomed to the slave life, so the experience is almost novel for ${him} and ${he} is affectingly`);
-				r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `touched by the affection.`, ["hotpink"]));
 				r.push(`${He} isn't used to being kissed, teased and massaged before ${he} takes cock. Slaves are usually used without regard to their orgasm, so ${he}'s also surprised and gratified when you make meticulous efforts to delay your own orgasm so it can coincide with ${his} own. ${He}'s a puddle on the sheets under your hands.`);
 				seX(slave, "oral", V.PC, "penetrative", 4);
 				if (slave.vagina === 0) {
@@ -186,7 +211,7 @@ App.personalAttention.slaveReport = function(slave) {
 				r.push(`Your`);
 				r.push(App.UI.DOM.makeElement("span", `slave training experience`, ["skill", "player"]));
 				r.push(`allows you to`);
-				r.push(App.UI.DOM.makeElement("span", `bend ${him} to your will`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `bend ${him} to your will`, ["hotpink"]));
 				r.push(`more quickly without provoking resistance.`);
 				slave.devotion += 1;
 			}
@@ -293,7 +318,7 @@ App.personalAttention.slaveReport = function(slave) {
 					slave.training = 0;
 					r.push(`By the end of the week,`);
 					r.push(App.UI.DOM.makeElement("span", `you resolve ${his} flaw into something special.`, "green"));
-					r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, ["hotpink"]));
 					SoftenBehavioralFlaw(slave);
 					slave.devotion += 4;
 				}
@@ -450,7 +475,7 @@ App.personalAttention.slaveReport = function(slave) {
 					slave.training = 0;
 					r.push(`By the end of the week,`);
 					r.push(App.UI.DOM.makeElement("span", `you resolve ${his} flaw into something special.`, "green"));
-					r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, ["hotpink"]));
 					SoftenSexualFlaw(slave);
 					slave.devotion += 4;
 				}
@@ -1027,7 +1052,7 @@ App.personalAttention.slaveReport = function(slave) {
 				slave.training = 0;
 				r.push(`By the end of the week,`);
 				r.push(App.UI.DOM.makeElement("span", `you break ${him} of ${his} bad habits.`, "green"));
-				r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, ["hotpink"]));
 				slave.behavioralFlaw = "none";
 				slave.devotion += 4;
 			}
@@ -1266,7 +1291,7 @@ App.personalAttention.slaveReport = function(slave) {
 				slave.training = 0;
 				r.push(`By the end of the week,`);
 				r.push(App.UI.DOM.makeElement("span", `you break ${him} of ${his} bad habits.`, "green"));
-				r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, "hotpink"));
+				r.push(App.UI.DOM.makeElement("span", `${His} obedience has increased.`, ["hotpink"]));
 				slave.sexualFlaw = "none";
 				slave.devotion += 4;
 			}
@@ -1363,7 +1388,7 @@ App.personalAttention.slaveReport = function(slave) {
 						r.push(`clits.`);
 					}
 					r.push(`Finding ${his} mammary fixation with you has`);
-					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, ["hotpink"]));
 					slave.devotion += 4;
 				} else if (slave.fetish === "buttslut") {
 					if (slave.vagina >= 0) {
@@ -1372,7 +1397,7 @@ App.personalAttention.slaveReport = function(slave) {
 						r.push(`When you move from fondling ${his} mouth to ${his} asshole,`);
 					}
 					r.push(`you've barely touched ${his} butt before ${he} comes explosively. After some experimentation, it becomes clear that ${his} g-spot might as well be located up ${his} ass. Finding ${his} anal fixation with you has`);
-					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, ["hotpink"]));
 					slave.devotion += 4;
 				} else if (slave.energy > 95) {
 					r.push(`${He} shows no real reaction when you move your fingers from hole to hole, because ${he} seems to react with arousal to fingers in any of them.`);
@@ -1382,7 +1407,7 @@ App.personalAttention.slaveReport = function(slave) {
 				r.push(`Next, you demand extreme submission from ${him}. You make ${him} change into bondage gear that blinds ${him}, restricts ${his} movement, forces ${him} to present ${his} breasts uncomfortably, and holds vibrators against ${him}. Thus attired, ${he} is forced to serve you in whatever petty ways occur to you.`);
 				if (slave.fetish === "submissive") {
 					r.push(`During the first hour of this treatment, ${he} cums hard against the vibrators. ${He}'s a natural submissive! Discovering this about ${himself} under your hands has`);
-					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, ["hotpink"]));
 					slave.devotion += 4;
 				} else if (slave.energy > 95) {
 					r.push(`${He} complies, showing the same enthusiasm for this as for other sex.`);
@@ -1392,19 +1417,19 @@ App.personalAttention.slaveReport = function(slave) {
 				r.push(`Before you let ${him} out of the extreme bondage, you rain a series of light blows across ${his} nipples and buttocks.`);
 				if (slave.fetish === "masochist") {
 					r.push(`${He} almost orgasms at the stinging pain. ${He}'s a masochist! This discovery has`);
-					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, ["hotpink"]));
 					slave.devotion += 4;
 				} else if (slave.energy > 95) {
 					r.push(`${He} enjoys the pain play, but ${he} seems to enjoy everything you try.`);
 				} else {
 					r.push(`${He} struggles and tries to avoid the blows.`);
 				}
-				App.Events.addParagraph(el, r);
+				App.Events.addNode(el, r, "div", "indent");
 				r = [];
 				r.push(`The next day, ${he} continues to accompany you. Whenever cum is involved in your day's affairs in any way, you require ${him} to clean it up with ${his} mouth.`);
 				if (slave.fetish === "cumslut") {
 					r.push(`${He} enjoys this treatment. ${He}'s a cumslut! Discovering this about ${himself} under your hands has`);
-					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, ["hotpink"]));
 					slave.devotion += 4;
 				} else if (slave.energy > 95) {
 					r.push(`${He} enjoys using ${his} mouth, but no more than other kinds of sexual activity.`);
@@ -1415,7 +1440,7 @@ App.personalAttention.slaveReport = function(slave) {
 				r.push(`You carefully watch ${his} reaction as you let ${him} spend a short time relaxing with a pregnant slave.`);
 				if (slave.fetish === "pregnancy") {
 					r.push(`${He}'s fascinated. ${He} fetishizes fertility! Discovering this with you has`);
-					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, ["hotpink"]));
 					slave.devotion += 4;
 				} else if (slave.energy > 95) {
 					r.push(`${He} spends most of the rest ogling the pregnant slave's boobs.`);
@@ -1425,7 +1450,7 @@ App.personalAttention.slaveReport = function(slave) {
 				r.push(`You restrain the pregnant slave and administer a brief beating across ${hisU} bare buttocks, ensuring that you cause enough pain to produce a few tears, a bit of begging, and some struggling.`);
 				if (slave.fetish === "sadist") {
 					r.push(`${He}'s almost painfully aroused. ${He}'s titillated by the idea of causing pain! Discovering this about ${himself} under your direction has`);
-					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, ["hotpink"]));
 					slave.devotion += 4;
 				} else if (slave.energy > 95) {
 					r.push(`${He} enjoys watching the poor pregnant slave wriggle, but ${he}'s watching ${hisU} butt rather than the beating.`);
@@ -1443,7 +1468,7 @@ App.personalAttention.slaveReport = function(slave) {
 				r.push(`Before letting the poor pregnant slave go, you require ${slave.slaveName} to add a blindfold to the restraints.`);
 				if (slave.fetish === "dom") {
 					r.push(`${He} seems to really enjoy blindfolding the poor ${girlU}, reassuring ${himU} as ${he} does. ${He}'s a natural sexual top! Discovering this about ${himself} under your direction has`);
-					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, ["hotpink"]));
 					slave.devotion += 4;
 				} else if (slave.energy > 95) {
 					r.push(`${He} enjoys getting closer to the slave, mostly so ${he} can give ${hisU} pregnant pussy a thorough grope.`);
@@ -1453,11 +1478,11 @@ App.personalAttention.slaveReport = function(slave) {
 				r.push(`Lastly, you place ${him} in a special room in your penthouse filled with live video equipment. They get to see ${him} groped, deepthroated, facialed, teased, and tortured.`);
 				if (slave.fetish === "humiliation") {
 					r.push(`The more viewers ${he} gets, the harder ${he} comes. ${He}'s a slut for humiliation! Discovering this about ${himself} under your hands has`);
-					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `increased ${his} devotion to you.`, ["hotpink"]));
 					slave.devotion += 4;
 				} else if (slave.energy > 95) {
 					r.push(`${He} enjoys showing off sexually, but focuses on the sex first. ${He} got off on everything, and is clearly a nympho. Discovering this about ${himself} under your hands has`);
-					r.push(App.UI.DOM.makeElement("span", `greatly increased ${his} devotion to you.`, "hotpink"));
+					r.push(App.UI.DOM.makeElement("span", `greatly increased ${his} devotion to you.`, ["hotpink"]));
 					slave.devotion += 9;
 				} else {
 					r.push(`${He} gets through it, but ${he} doesn't seem to enjoy`);
@@ -1925,7 +1950,7 @@ App.personalAttention.slaveReport = function(slave) {
 	}
 	r.push(IncreasePCSkills('slaving', currentSlaveValue));
 	V.PC.skill.slaving = Math.clamp(V.PC.skill.slaving, -100, 100);
-	App.Events.addParagraph(el, r);
+	App.Events.addNode(el, r, "div", "indent");
 	return el;
 
 	/**
@@ -1976,11 +2001,10 @@ App.personalAttention.slaveReport = function(slave) {
 	}
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 * @returns {HTMLParagraphElement}
+	 * @returns {HTMLElement}
 	 */
 	function basicTrainingDefaulter(slave) {
-		const el = document.createElement("p");
-		el.classList.add("indent");
+		const el = App.UI.DOM.makeElement("div", "", ["indent"]);
 		const {He, His, his, he} = getPronouns(slave);
 		if (slave.devotion > 20 && slave.behavioralFlaw !== "none" && slave.behavioralQuirk === "none") {
 			el.append(`Since ${he}'s obedient, `);
diff --git a/src/endWeek/reports/schoolroomReport.js b/src/endWeek/reports/schoolroomReport.js
index 14b66df8f9889e2bf1816f2c8ca2aa118237f303..5c64a0174d5d0b4cd95f2383d6651de44d45bd42 100644
--- a/src/endWeek/reports/schoolroomReport.js
+++ b/src/endWeek/reports/schoolroomReport.js
@@ -3,7 +3,7 @@ App.EndWeek.schoolroomReport = function() {
 
 	const slaves = App.Utils.sortedEmployees(App.Entity.facilities.schoolroom);
 	const devBonus = (V.schoolroomDecoration !== "standard") ? 1 : 0;
-	V.flSex = App.EndWeek.getFLSex(App.Entity.facilities.schoolroom); // FIXME: should be local, passed as a parameter to saRules
+	App.EndWeek.saVars.flSex = App.EndWeek.getFLSex(App.Entity.facilities.schoolroom);
 
 	function schoolteacherText() {
 		let r = [];
@@ -211,6 +211,12 @@ App.EndWeek.schoolroomReport = function() {
 						r.push(`so ${he} has returned to rest.`);
 					}
 				} else {
+					// This needs to be set here or else it freaks out and returns errors. It also can't be defaulted without hiding issues, so we set something here.
+					if (slave.assignment === Job.WHORE || slave.assignment === Job.BROTHEL) {
+						slave.sexAmount = Math.trunc(Beauty(slave) / 5);
+						slave.sexQuality = FResult(slave);
+						slave.effectiveWhoreClass = effectiveWhoreClass(slave);
+					}
 					r.push(`so ${he} goes back to ${slave.assignment}.`);
 				}
 			} else {
diff --git a/src/endWeek/reports/spaReport.js b/src/endWeek/reports/spaReport.js
index 0b1327e032675039452e45052b43355250f39ba1..bdb0208d91da6eca08a6d6108060bff044101fa2 100644
--- a/src/endWeek/reports/spaReport.js
+++ b/src/endWeek/reports/spaReport.js
@@ -11,7 +11,7 @@ App.EndWeek.spaReport = function() {
 	let restedSlave;
 	let devBonus = (V.spaDecoration !== "standard") ? 1 : 0;
 
-	V.flSex = App.EndWeek.getFLSex(App.Entity.facilities.spa); /* FIXME: should be local, passed as a parameter to saRules */
+	App.EndWeek.saVars.flSex = App.EndWeek.getFLSex(App.Entity.facilities.spa);
 
 	if (S.Attendant) {
 		let idleBonus = 0;
diff --git a/src/endWeek/saAgent.js b/src/endWeek/saAgent.js
index 33f08bc3775e98a3b98a916f7a926cd8970ce908..df50161b1a48ece0fc61aeed2533a64e01f0b8d0 100644
--- a/src/endWeek/saAgent.js
+++ b/src/endWeek/saAgent.js
@@ -294,8 +294,8 @@ App.SlaveAssignment.agent = function(slave) {
 					slave.lactationDuration = 2;
 				}
 			}
-		} // closes .preg >= 10
-	} // END PREG EFFECTS
+		}
+	}
 
 	if (slave.belly >= 1000000) {
 		if (slave.bellySag < 50) {
diff --git a/src/endWeek/saBeYourHeadGirl.js b/src/endWeek/saBeYourHeadGirl.js
index 2e83eb5c3fdc779ae896718e7dd068011c4d5442..49e340b920d501efa27692e74ce264bef505afd1 100644
--- a/src/endWeek/saBeYourHeadGirl.js
+++ b/src/endWeek/saBeYourHeadGirl.js
@@ -1,50 +1,33 @@
-App.SlaveAssignment.beYourHeadGirl = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.beYourHeadGirl = function saBeYourHeadGirl(slave) {
+	/** @type {string[]} */
+	const r = [];
 
-	let r;
+	const arcology = V.arcologies[0];
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let He;
-	let His;
+	const {
+		he, him, his, himself, He, His,
+	} = getPronouns(slave);
 
-	let fetishChange;
-	let arcology;
-
-	return saBeYourHeadGirl;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {string}
-	 */
-	function saBeYourHeadGirl(slave) {
-		r = [];
-		fetishChange = fetishChangeChance(slave);
-		arcology = V.arcologies[0];
-
-		({
-			he, him, his, himself, He, His,
-		} = getPronouns(slave));
-
-		updateHGState(slave);
-		jobPreface(slave);
-		theHGLife(slave);
-		if (V.personalAttention.task === PersonalAttention.SUPPORTHG) {
-			playerHelpsHG(slave);
-		}
-		if (V.HGFormality === 0) {
-			HGFormality(slave);
-		}
-		jobEffects(slave);
-		if (slave.prestige === 0) {
-			prestigeGain(slave);
-		}
-		cleanupVars(slave);
-
-		return r.join(" ");
+	updateHGState(slave);
+	jobPreface(slave);
+	theHGLife(slave);
+	if (V.personalAttention.task === PersonalAttention.SUPPORTHG) {
+		playerHelpsHG(slave);
 	}
+	if (V.HGFormality === 0) {
+		HGFormality(slave);
+	}
+	jobEffects(slave);
+	if (slave.prestige === 0) {
+		prestigeGain(slave);
+	}
+	cleanupVars(slave);
+
+	return r.join(" ");
 
 	/**
 	 * @param {FC.ReportSlave} slave
@@ -221,7 +204,7 @@ App.SlaveAssignment.beYourHeadGirl = (function() {
 					r.push(`Having all the slaves look up to and obey ${him} advances ${his} <span class="lightcoral">dominant tendencies.</span>`);
 					slave.fetishStrength += 4;
 				}
-			} else if (fetishChange > jsRandom(0, 100)) {
+			} else if (fetishChangeChance(slave) > jsRandom(0, 100)) {
 				r.push(`Having all the slaves look up to and obey ${him} affects ${his} sexuality, turning ${him} into a <span class="lightcoral">bit of a dominatrix.</span>`);
 				slave.fetish = "dom";
 				slave.fetishStrength = 20;
@@ -234,7 +217,7 @@ App.SlaveAssignment.beYourHeadGirl = (function() {
 			if (slave.fetish === "dom") {
 				r.push(`Having all the slaves look up to and obey ${him} clearly excites ${him}; <span class="lightcoral">${he}'s a natural dom!</span>`);
 				slave.fetishKnown = 1;
-			} else if (fetishChange > jsRandom(0, 100)) {
+			} else if (fetishChangeChance(slave) > jsRandom(0, 100)) {
 				r.push(`Having all the slaves look up to and obey ${him} affects ${his} sexuality, turning ${him} into a <span class="lightcoral">bit of a dominatrix.</span>`);
 				slave.fetish = "dom";
 				slave.fetishStrength = 20;
@@ -287,4 +270,4 @@ App.SlaveAssignment.beYourHeadGirl = (function() {
 		}
 		slave.health.tired = Math.clamp(slave.health.tired, 0, 1000);
 	}
-})();
+};
diff --git a/src/endWeek/saChoosesOwnClothes.js b/src/endWeek/saChoosesOwnClothes.js
index 11d97190eb16c7d70ce3dca608449cc4cab30923..55f8dc495f09e111b55d8b7f092ce704c50d9644 100644
--- a/src/endWeek/saChoosesOwnClothes.js
+++ b/src/endWeek/saChoosesOwnClothes.js
@@ -1,88 +1,78 @@
-App.SlaveAssignment.choosesOwnClothes = (function() {
-	"use strict";
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.choosesOwnClothes = function saChoosesOwnClothes(slave) {
+	if (slave.choosesOwnClothes !== 1) {
+		return "";
+	}
 
-	let player;
-	let r;
-	let He;
-	let His;
-	let he;
-	let him;
-	let his;
-	let himself;
+	let r = "";
+	const player = V.PC;
+	const {
+		He, His, he, him, his, himself,
+	} = getPronouns(slave);
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @returns {string}
-	 */
-	function saChoosesOwnClothes(slave) {
-		player = V.PC;
-		r = "";
-		if (slave.choosesOwnClothes !== 1) { return r; }
-		({
-			He, His, he, him, his, himself,
-		} = getPronouns(slave));
+	if (slave.fetish === "mindbroken") {
+		const corsetChoice = todaysCorset(slave);
+		const clothingChoice = todaysOutfit(slave);
+		slave.bellyAccessory = corsetChoice.bellyAccessory;
+		slave.clothes = clothingChoice.clothes;
+		r += `${He} is fundamentally broken, but still follows some faint memories of standing within the wardrobe. `;
+		if (hasAnyLegs(slave)) {
+			const shoeChoice = todaysShoes(slave);
+			r += `${shoeChoice.text} `;
+			slave.shoes = shoeChoice.shoes;
+		}
+		r += `${corsetChoice.text} Faced with so many choices and no thought on the matter; ${clothingChoice.text}`;
+	} else if (slave.devotion <= 20) {
+		const clothingChoice = todaysOutfit(slave);
+		slave.clothes = clothingChoice.clothes;
+		r += `${clothingChoice.text} `;
+		if (hasAnyLegs(slave)) {
+			const shoeChoice = todaysShoes(slave);
+			r += `${shoeChoice.text} `;
+			slave.shoes = shoeChoice.shoes;
+		}
+		r += `Allowing ${him} permission to dress as ${he} sees fit <span class="devotion dec">increases ${his} independence.</span>`;
+		slave.devotion -= 5;
+	} else {
+		const neckChoice = todaysCollar(slave);
+		const corsetChoice = todaysCorset(slave);
+		const clothingChoice = todaysOutfit(slave);
+		slave.collar = neckChoice.collar;
+		slave.bellyAccessory = corsetChoice.bellyAccessory;
+		slave.clothes = clothingChoice.clothes;
+		r += `${He} <span class="devotion inc">loves</span> being able to dress ${himself}, ${neckChoice.text} ${corsetChoice.text} ${clothingChoice.text} `;
+		slave.devotion += 1;
 
-		if (slave.fetish === "mindbroken") {
-			const corsetChoice = todaysCorset(slave);
-			const clothingChoice = todaysOutfit(slave);
-			slave.bellyAccessory = corsetChoice.bellyAccessory;
-			slave.clothes = clothingChoice.clothes;
-			r += `${He} is fundamentally broken, but still follows some faint memories of standing within the wardrobe. `;
-			if (hasAnyLegs(slave)) {
-				const shoeChoice = todaysShoes(slave);
-				r += `${shoeChoice.text} `;
-				slave.shoes = shoeChoice.shoes;
-			}
-			r += `${corsetChoice.text} Faced with so many choices and no thought on the matter; ${clothingChoice.text}`;
-		} else if (slave.devotion <= 20) {
-			const clothingChoice = todaysOutfit(slave);
-			slave.clothes = clothingChoice.clothes;
-			r += `${clothingChoice.text} `;
-			if (hasAnyLegs(slave)) {
-				const shoeChoice = todaysShoes(slave);
-				r += `${shoeChoice.text} `;
-				slave.shoes = shoeChoice.shoes;
+		if (V.arcologies[0].FSRestart !== "unset" && slave.choosesOwnChastity === 1) {
+			if (slave.vagina > -1 && slave.breedingMark === 1 && slave.chastityVagina === 1) {
+				r += `${He} unfastens ${his} chastity belt knowing full well ${his} role in life is to carry ${his} ${getWrittenTitle(slave)}'s children. `;
+				slave.chastityVagina = 0;
+			} else if (slave.vagina > -1 && slave.ovaries === 1 && slave.preg === 0 && slave.chastityVagina !== 1) {
+				r += `${He} also affixes a chastity belt over ${his} vagina to discourage use of ${his} reproductive organ. `;
+				slave.chastityVagina = 1;
+			} else if (slave.vagina > -1 && (slave.ovaries === 0 || slave.preg < -1) && slave.chastityVagina === 1) {
+				r += `${He} removes ${his} chastity belt since no matter how hard someone tries, ${he} can never become pregnant. `;
+				slave.chastityVagina = 0;
 			}
-			r += `Allowing ${him} permission to dress as ${he} sees fit <span class="devotion dec">increases ${his} independence.</span>`;
-			slave.devotion -= 5;
-		} else {
-			const neckChoice = todaysCollar(slave);
-			const corsetChoice = todaysCorset(slave);
-			const clothingChoice = todaysOutfit(slave);
-			slave.collar = neckChoice.collar;
-			slave.bellyAccessory = corsetChoice.bellyAccessory;
-			slave.clothes = clothingChoice.clothes;
-			r += `${He} <span class="devotion inc">loves</span> being able to dress ${himself}, ${neckChoice.text} ${corsetChoice.text} ${clothingChoice.text} `;
-			slave.devotion += 1;
-
-			if (V.arcologies[0].FSRestart !== "unset" && slave.choosesOwnChastity === 1) {
-				if (slave.vagina > -1 && slave.breedingMark === 1 && slave.chastityVagina === 1) {
-					r += `${He} unfastens ${his} chastity belt knowing full well ${his} role in life is to carry ${his} ${getWrittenTitle(slave)}'s children. `;
-					slave.chastityVagina = 0;
-				} else if (slave.vagina > -1 && slave.ovaries === 1 && slave.preg === 0 && slave.chastityVagina !== 1) {
-					r += `${He} also affixes a chastity belt over ${his} vagina to discourage use of ${his} reproductive organ. `;
-					slave.chastityVagina = 1;
-				} else if (slave.vagina > -1 && (slave.ovaries === 0 || slave.preg < -1) && slave.chastityVagina === 1) {
-					r += `${He} removes ${his} chastity belt since no matter how hard someone tries, ${he} can never become pregnant. `;
-					slave.chastityVagina = 0;
-				}
-				if (slave.dick > 0 && slave.balls > 0 && slave.chastityPenis !== 1) {
-					r += `${He} also affixes a chastity cage onto ${his} dick to discourage use of ${his} reproductive organ. `;
-					slave.chastityPenis = 1;
-				} else if (slave.dick > 0 && slave.balls === 0 && slave.chastityPenis === 1) {
-					r += `${He} removes ${his} chastity cage since even if ${he} could get erect, ${he} only shoots blanks. `;
-					slave.chastityPenis = 0;
-				}
+			if (slave.dick > 0 && slave.balls > 0 && slave.chastityPenis !== 1) {
+				r += `${He} also affixes a chastity cage onto ${his} dick to discourage use of ${his} reproductive organ. `;
+				slave.chastityPenis = 1;
+			} else if (slave.dick > 0 && slave.balls === 0 && slave.chastityPenis === 1) {
+				r += `${He} removes ${his} chastity cage since even if ${he} could get erect, ${he} only shoots blanks. `;
+				slave.chastityPenis = 0;
 			}
+		}
 
-			if (hasAnyLegs(slave)) {
-				const shoeChoice = todaysShoes(slave);
-				r += `${shoeChoice.text}`;
-				slave.shoes = shoeChoice.shoes;
-			}
+		if (hasAnyLegs(slave)) {
+			const shoeChoice = todaysShoes(slave);
+			r += `${shoeChoice.text}`;
+			slave.shoes = shoeChoice.shoes;
 		}
-		return r;
 	}
+	return r;
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
@@ -937,7 +927,7 @@ App.SlaveAssignment.choosesOwnClothes = (function() {
 				/* pregnancy */
 				if (slave.belly >= 5000) {
 					wardrobeTastes.push({text: `and wears pretty lingerie to show off ${his} merchandise while giving ${his} protruding belly plenty of room to hang free.`, clothes: "attractive lingerie"});
-					wardrobeTastes.push({text: `and wears only panties. Something so easy to slip on is appreciable with such a big belly in the way.`, clothes: "panties"});
+					wardrobeTastes.push({text: `and wears only panties. ${He} appreciates something so easy to slip on, with such a big belly in the way.`, clothes: "panties"});
 					if (isItemAccessible.entry("kitty lingerie") === true) {
 						wardrobeTastes.push({text: `and wears cute lingerie to show off ${his} merchandise while giving ${his} protruding belly plenty of room to hang free.`, clothes: "kitty lingerie"});
 					}
@@ -1071,7 +1061,7 @@ App.SlaveAssignment.choosesOwnClothes = (function() {
 			//
 		} else {
 			if (V.arcologies[0].FSRepopulationFocus > 0 && slave.pregKnown === 1) {
-				neck.push({text: `dons a digital display around ${his} neck that shows off ${his} pregnancy in support of your Repopulation efforts.`, collar: "preg biometrics"});
+				neck.push({text: `dons a digital display around ${his} neck that shows off ${his} pregnancy in support of your Repopulation efforts,`, collar: "preg biometrics"});
 			} else {
 				if (V.arcologies[0].FSEgyptianRevivalist > 0) {
 					neck.push({text: `dons a wesekh to support your ancient Egyptian pretensions,`, collar: "ancient Egyptian"});
@@ -1101,6 +1091,7 @@ App.SlaveAssignment.choosesOwnClothes = (function() {
 	function todaysCorset(slave) {
 		/** @type {Array<{text: string, bellyAccessory: FC.BellyAccessory}>} */
 		const belly = [];
+		/** @type {FC.BellyAccessory[]} */
 		const empathyBellies = [];
 		for (const [key, object] of App.Data.bellyAccessory) {
 			if (object.hasOwnProperty("empathyBelly")) {
@@ -1148,13 +1139,13 @@ App.SlaveAssignment.choosesOwnClothes = (function() {
 			} else if (empathyBellies.includes(slave.bellyAccessory) && slave.sexualFlaw === "breeder") {
 				belly.push({text: `pulls ${his} fake belly off, disgusted by it,`, bellyAccessory: "none"});
 			} else if (slave.belly < 8000 && slave.bellyAccessory === "a support band") {
-				belly.push({text: `removes ${his} support band since ${he} no longer needs it,`, bellyAccessory: "none"});
+				belly.push({
+					text: `removes ${his} support band since ${he} no longer needs it,`, bellyAccessory: "none"
+				});
 			} else {
 				belly.push({text: "", bellyAccessory: slave.bellyAccessory}); /* compatibility for no output, will likely get deprecated in the future as content is added*/
 			}
 		}
 		return jsEither(belly);
 	}
-
-	return saChoosesOwnClothes;
-})();
+};
diff --git a/src/endWeek/saChoosesOwnJob.js b/src/endWeek/saChoosesOwnJob.js
index 29a2986f389bb0223febd4070dad3357e17c2452..7a314efa96b7c548d8182a095cc3824e2ad1fbd1 100644
--- a/src/endWeek/saChoosesOwnJob.js
+++ b/src/endWeek/saChoosesOwnJob.js
@@ -1,75 +1,94 @@
-App.SlaveAssignment.choosesOwnJob = (function() {
-	"use strict";
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.choosesOwnJob = function saChoosesOwnJob(slave) {
+	/** @type {string[]} */
+	const r = [];
 
-	let r;
+	const arcology = V.arcologies[0];
+	const clinicL = App.Entity.facilities.clinic.employeesIDs().size;
+	const schoolL = App.Entity.facilities.schoolroom.employeesIDs().size;
+	const servQL = App.Entity.facilities.servantsQuarters.employeesIDs().size;
+	const nurseryL = App.Entity.facilities.nursery.employeesIDs().size;
+	const brothelL = App.Entity.facilities.brothel.employeesIDs().size;
+	const clubL = App.Entity.facilities.club.employeesIDs().size;
+	const masterSL = App.Entity.facilities.masterSuite.employeesIDs().size;
+	const spaL = App.Entity.facilities.spa.employeesIDs().size;
+	const dairyL = App.Entity.facilities.dairy.employeesIDs().size;
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let girl;
-	let He;
+	const {
+		He, he, him, his, himself, girl,
+	} = getPronouns(slave);
 
-	let clinicL;
-	let schoolL;
-	let servQL;
-	let nurseryL;
-	let brothelL;
-	let clubL;
-	let masterSL;
-	let spaL;
-	let dairyL;
-	let arcology;
+	/*
+	"I suspect something might be awry with that too" - Pregmodder - 2021-09-26
+	*/
+	if (slave.choosesOwnAssignment === 0 || slave.fuckdoll > 0 || slave.fetish === "mindbroken") {
+		// nothing to do
+	} else if (slave.choosesOwnAssignment === 2) {
+		// second pass happens visibly during weekly report for the location where this slave decided to go (or stay)
+		// display text but don't change assignment (already done)
+		r.push(V.choosesOwnAssignmentText[slave.ID]);
+		delete V.choosesOwnAssignmentText[slave.ID];
+		slave.choosesOwnAssignment = 1;
+		// continue cycle for next week
+	} else {
+		// first pass happens silently before all reports: give stats bonus, construct decision string for display during second pass, actually change assignment
+		slave.devotion++;
+		slave.trust++;
+		V.choosesOwnAssignmentText[slave.ID] = jobSelection(slave);
+	}
+
+	return r.join(" ");
 
-	return saChoosesOwnJob;
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 * @returns {string}
+	 * @returns {Array<string>}
 	 */
-	function saChoosesOwnJob(slave) {
-		r = [];
-
-		clinicL = App.Entity.facilities.clinic.employeesIDs().size;
-		schoolL = App.Entity.facilities.schoolroom.employeesIDs().size;
-		servQL = App.Entity.facilities.servantsQuarters.employeesIDs().size;
-		nurseryL = App.Entity.facilities.nursery.employeesIDs().size;
-		brothelL = App.Entity.facilities.brothel.employeesIDs().size;
-		clubL = App.Entity.facilities.club.employeesIDs().size;
-		masterSL = App.Entity.facilities.masterSuite.employeesIDs().size;
-		spaL = App.Entity.facilities.spa.employeesIDs().size;
-		dairyL = App.Entity.facilities.dairy.employeesIDs().size;
-
-		arcology = V.arcologies[0];
+	function assignPublicService(slave) {
+		slave.sexAmount = 10;
+		if (V.universalRulesAssignsSelfFacility === 1 && V.club > clubL) {
+			return [`in ${V.clubName}.</span>`, assignJob(slave, "serve in the club")];
+		} else {
+			return [`on the streets.</span>`, assignJob(slave, "serve the public")];
+		}
+	}
 
-		({
-			He, he, him, his, himself, girl,
-		} = getPronouns(slave));
-		/*
-		"I suspect something might be awry with that too" - Pregmodder - 2021-09-26
-		*/
-		if (slave.choosesOwnAssignment === 0 || slave.fuckdoll > 0 || slave.fetish === "mindbroken") {
-			// nothing to do
-		} else if (slave.choosesOwnAssignment === 2) {
-			// second pass happens visibly during weekly report for the location where this slave decided to go (or stay)
-			// display text but don't change assignment (already done)
-			r.push(V.choosesOwnAssignmentText[slave.ID]);
-			delete V.choosesOwnAssignmentText[slave.ID];
-			slave.choosesOwnAssignment = 1;
-			// continue cycle for next week
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @returns {Array<string>}
+	 */
+	function assignFucktoy(slave) {
+		if (V.universalRulesAssignsSelfFacility === 1 && V.masterSuite > masterSL) {
+			r.push(`so ${he} <span class="job change">heads straight to ${V.masterSuiteName}.</span>`);
+			r.push(assignJob(slave, "serve in the master suite"));
 		} else {
-			// first pass happens silently before all reports: give stats bonus, construct decision string for display during second pass, actually change assignment
-			slave.devotion++;
-			slave.trust++;
-			V.choosesOwnAssignmentText[slave.ID] = jobSelection(slave);
+			r.push(`so ${he} cheerfully <span class="job change">designates ${himself} one of your fucktoys.</span>`);
+			r.push(assignJob(slave, "please you"));
 		}
+		return r;
+	}
 
-		return r.join(" ");
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @returns {Array<string>}
+	 */
+	function assignServant(slave) {
+		const r = [`so ${he} <span class="job change">decides to work`];
+		if (V.universalRulesAssignsSelfFacility === 1 && V.servantsQuarters > servQL) {
+			r.push(`from ${V.servantsQuartersName}</span> to make your penthouse as clean and homelike as possible.`);
+			r.push(assignJob(slave, "work as a servant"));
+		} else {
+			r.push(`as a servant</span> to make your penthouse as clean and homelike as possible.`);
+			r.push(assignJob(slave, "be a servant"));
+		}
+		return r;
 	}
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
 	 */
 	function jobSelection(slave) {
 		let choice = [];
@@ -158,14 +177,7 @@ App.SlaveAssignment.choosesOwnJob = (function() {
 				}
 			} else {
 				choice.push(`so ${he} eagerly <span class="job change">decides to slut around`);
-				if (V.universalRulesAssignsSelfFacility === 1 && V.club > clubL) {
-					choice.push(`in ${V.clubName}.</span>`);
-					choice.push(assignJob(slave, "serve in the club"));
-				} else {
-					choice.push(`on the streets.</span>`);
-					choice.push(assignJob(slave, "serve the public"));
-				}
-				slave.sexAmount = 10;
+				choice.push(...assignPublicService(slave));
 			}
 		} else if (slave.relationship === -2) {
 			choice.push(`is emotionally bonded to you,`);
@@ -181,32 +193,12 @@ App.SlaveAssignment.choosesOwnJob = (function() {
 				slave.sexAmount = 10;
 			} else if (slave.behavioralQuirk === "advocate") {
 				choice.push(`and an advocate for slavery, so ${he} <span class="job change">decides to burnish your reputation by slutting it up`);
-				if (V.universalRulesAssignsSelfFacility === 1 && V.club > clubL) {
-					choice.push(`in ${V.clubName}.</span>`);
-					choice.push(assignJob(slave, "serve in the club"));
-				} else {
-					choice.push(`on the streets.</span>`);
-					choice.push(assignJob(slave, "serve the public"));
-				}
-				slave.sexAmount = 10;
+				choice.push(...assignPublicService(slave));
 			} else if (slave.energy > 60) {
 				choice.push(`and ${he} thinks of little but sex with you,`);
-				if (V.universalRulesAssignsSelfFacility === 1 && V.masterSuite > masterSL) {
-					choice.push(`so ${he} <span class="job change">heads straight to ${V.masterSuiteName}.</span>`);
-					choice.push(assignJob(slave, "serve in the master suite"));
-				} else {
-					choice.push(`so ${he} cheerfully <span class="job change">designates ${himself} one of your fucktoys.</span>`);
-					choice.push(assignJob(slave, "please you"));
-				}
+				choice.push(...assignFucktoy(slave));
 			} else if (canSee(slave) && canWalk(slave)) {
-				choice.push(`so ${he} <span class="job change">decides to work`);
-				if (V.universalRulesAssignsSelfFacility === 1 && V.servantsQuarters > servQL) {
-					choice.push(`from ${V.servantsQuartersName}</span> to make your penthouse as clean and homelike as possible.`);
-					choice.push(assignJob(slave, "work as a servant"));
-				} else {
-					choice.push(`as a servant</span> to make your penthouse as clean and homelike as possible.`);
-					choice.push(assignJob(slave, "be a servant"));
-				}
+				choice.push(...assignServant(slave));
 			} else {
 				choice.push(`but unable to do much on ${his} own,`);
 				if (V.universalRulesAssignsSelfFacility === 1 && V.masterSuite > masterSL) {
@@ -228,22 +220,9 @@ App.SlaveAssignment.choosesOwnJob = (function() {
 			if (slave.devotion > 50) {
 				if (slave.energy > 60) {
 					choice.push(`and ${he} thinks of little but sex with you,`);
-					if (V.universalRulesAssignsSelfFacility === 1 && V.masterSuite > masterSL) {
-						choice.push(`so ${he} <span class="job change">heads straight to ${V.masterSuiteName}.</span>`);
-						choice.push(assignJob(slave, "serve in the master suite"));
-					} else {
-						choice.push(`so ${he} cheerfully <span class="job change">designates ${himself} one of your fucktoys.</span>`);
-						choice.push(assignJob(slave, "please you"));
-					}
+					choice.push(...assignFucktoy(slave));
 				} else if (canSee(slave) && canWalk(slave)) {
-					choice.push(`so ${he} <span class="job change">decides to work`);
-					if (V.universalRulesAssignsSelfFacility === 1 && V.servantsQuarters > servQL) {
-						choice.push(`from ${V.servantsQuartersName}</span> to make your penthouse as clean and homelike as possible.`);
-						choice.push(assignJob(slave, "work as a servant"));
-					} else {
-						choice.push(`as a servant</span> to make your penthouse as clean and homelike as possible.`);
-						choice.push(assignJob(slave, "be a servant"));
-					}
+					choice.push(...assignServant(slave));
 				} else {
 					choice.push(`but unable to do much on ${his} own`);
 					if (V.universalRulesAssignsSelfFacility === 1 && V.masterSuite > masterSL) {
@@ -260,22 +239,9 @@ App.SlaveAssignment.choosesOwnJob = (function() {
 			} else {
 				if (slave.energy > 60) {
 					choice.push(`and ${he} thinks of little but sex,`);
-					if (V.universalRulesAssignsSelfFacility === 1 && V.masterSuite > masterSL) {
-						choice.push(`so ${he} <span class="job change">heads straight to ${V.masterSuiteName}.</span>`);
-						choice.push(assignJob(slave, "serve in the master suite"));
-					} else {
-						choice.push(`so ${he} cheerfully <span class="job change">designates ${himself} one of your fucktoys.</span>`);
-						choice.push(assignJob(slave, "please you"));
-					}
+					choice.push(...assignFucktoy(slave));
 				} else if (canSee(slave) && canWalk(slave)) {
-					choice.push(`so ${he} <span class="job change">decides to work`);
-					if (V.universalRulesAssignsSelfFacility === 1 && V.servantsQuarters > servQL) {
-						choice.push(`from ${V.servantsQuartersName}</span> to make your penthouse as clean and homelike as possible.`);
-						choice.push(assignJob(slave, "work as a servant"));
-					} else {
-						choice.push(`as a servant</span> to make your penthouse as clean and homelike as possible.`);
-						choice.push(assignJob(slave, "be a servant"));
-					}
+					choice.push(...assignServant(slave));
 				} else {
 					choice.push(`but unable to do much on ${his} own, so ${he} <span class="job change">designates ${himself} one of your fucktoys</span> to get more intimate with you.`);
 					choice.push(assignJob(slave, "please you"));
@@ -593,4 +559,4 @@ App.SlaveAssignment.choosesOwnJob = (function() {
 
 		return choice.join(" ");
 	}
-})();
+};
diff --git a/src/endWeek/saClothes.js b/src/endWeek/saClothes.js
index af6c41d459aa1291ac9b4e77733187d167b1aa42..edaca0092b6e0e7f584412eddd16181b1f7389d5 100644
--- a/src/endWeek/saClothes.js
+++ b/src/endWeek/saClothes.js
@@ -1,60 +1,46 @@
-App.SlaveAssignment.clothes = (function() {
-	"use strict";
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.clothes = function saClothes(slave) {
+	/** @type {string[]} */
+	const r = [];
 
-	let r;
-	let arcology;
+	const arcology = V.arcologies[0];
 
-	let he;
-	let him;
-	let his;
-	let He;
-	let His;
+	const {
+		He, His, he, him, his, hers
+	} = getPronouns(slave);
 
-	return saClothes;
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @returns {string}
-	 */
-	function saClothes(slave) {
-		r = [];
-
-		arcology = V.arcologies[0];
-
-		({
-			He, His, he, him, his,
-		} = getPronouns(slave));
-
-		updateAccessories(slave);
-		if (slave.fuckdoll === 0 && slave.fetish !== "mindbroken") {
-			clothingEffects(slave);
-		}
-		if (slave.collar !== "none") {
-			collarEffects(slave);
-		}
-		if (slave.faceAccessory !== "none") {
-			maskEffects(slave);
-		}
-		if (slave.mouthAccessory !== "none") {
-			mouthEffects(slave);
-		}
-		chastityEffects(slave);
-		if (slave.bellyAccessory !== "none") {
-			bellyAccessories(slave);
-		}
-		if (hasAnyLegs(slave)) {
-			legAccessories(slave);
-		}
-		if (slave.vagina >= 0) {
-			vaginaAccessories(slave);
-		}
-		if (slave.buttplug !== "none") {
-			analAccessories(slave);
-		}
-
-		return r.join(" ");
+	updateAccessories(slave);
+	if (slave.fuckdoll === 0 && slave.fetish !== "mindbroken") {
+		clothingEffects(slave);
+	}
+	if (slave.collar !== "none") {
+		collarEffects(slave);
+	}
+	if (slave.faceAccessory !== "none") {
+		maskEffects(slave);
+	}
+	if (slave.mouthAccessory !== "none") {
+		mouthEffects(slave);
+	}
+	chastityEffects(slave);
+	if (slave.bellyAccessory !== "none") {
+		bellyAccessories(slave);
+	}
+	if (hasAnyLegs(slave)) {
+		legAccessories(slave);
+	}
+	if (slave.vagina >= 0) {
+		vaginaAccessories(slave);
+	}
+	if (slave.buttplug !== "none") {
+		analAccessories(slave);
 	}
 
+	return r.join(" ");
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 *
@@ -82,6 +68,56 @@ App.SlaveAssignment.clothes = (function() {
 		}
 	}
 
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function chainMakesMasochist(slave) {
+		if (slave.fetish === "masochist" && slave.fetishKnown === 0) {
+			r.push(`${His} chains pinch and constrict ${him} whenever ${he}'s used. ${He} seems to get off on the discomfort; ${he}'s a <span class="lightcoral">natural masochist.</span>`);
+			slave.fetishKnown = 1;
+		} else if (slave.fetish === "none" || slave.fetishKnown === 0) {
+			if (fetishChangeChance(slave) > jsRandom(0, 100)) {
+				r.push(`${His} chains pinch and constrict ${him} whenever ${he}'s used. ${He} learns to come in spite of, and then <span class="lightcoral">because of the discomfort.</span>`);
+				slave.fetish = "masochist";
+				slave.fetishKnown = 1;
+				slave.fetishStrength = 10;
+			}
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function harshMakesMasochist(slave) {
+		if (slave.fetish === "masochist" && slave.fetishKnown === 0) {
+			r.push(`${His} outfit pinches and constricts ${him} whenever ${he}'s used. ${He} seems to get off on the discomfort; ${he}'s a <span class="lightcoral">natural masochist.</span>`);
+			slave.fetishKnown = 1;
+		} else if (slave.fetish === "none" || slave.fetishKnown === 0) {
+			if (fetishChangeChance(slave) > jsRandom(0, 100)) {
+				r.push(`${His} outfit pinches and constricts ${him} whenever ${he}'s used. ${He} learns to come in spite of, and then <span class="lightcoral">because of the discomfort.</span>`);
+				slave.fetish = "masochist";
+				slave.fetishKnown = 1;
+				slave.fetishStrength = 10;
+			}
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function humiliationLikesExposed(slave) {
+		if (slave.fetishKnown === 0) {
+			r.push(`${He} pretends to be embarrassed by ${his} extremely revealing clothing but seems to get off on it. <span class="lightcoral">${He}'s into humiliation.</span>`);
+			slave.fetishKnown = 1;
+		} else if (slave.fetishStrength > 60) {
+			r.push(`${He} pretends to be embarrassed by ${his} extremely revealing clothing but <span class="hotpink">openly gets off on it.</span>`);
+			slave.devotion += 2;
+		} else {
+			r.push(`${He} pretends to be embarrassed by ${his} extremely revealing clothing but <span class="hotpink">secretly gets off on it.</span>`);
+			slave.devotion += 1;
+		}
+	}
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 *
@@ -177,29 +213,9 @@ App.SlaveAssignment.clothes = (function() {
 							r.push(`The chains ${he}'s wearing keep ${him} <span class="hotpink">servile</span> and <span class="gold">afraid.</span>`);
 							slave.devotion += 1;
 							slave.trust -= 1;
-							if (slave.fetish === "masochist" && slave.fetishKnown === 0) {
-								r.push(`${His} chains pinch and constrict ${him} whenever ${he}'s used. ${He} seems to get off on the discomfort; ${he}'s a <span class="lightcoral">natural masochist.</span>`);
-								slave.fetishKnown = 1;
-							} else if (slave.fetish === "none" || slave.fetishKnown === 0) {
-								if (fetishChangeChance(slave) > jsRandom(0, 100)) {
-									r.push(`${His} chains pinch and constrict ${him} whenever ${he}'s used. ${He} learns to come in spite of, and then <span class="lightcoral">because of the discomfort.</span>`);
-									slave.fetish = "masochist";
-									slave.fetishKnown = 1;
-									slave.fetishStrength = 10;
-								}
-							}
+							chainMakesMasochist(slave);
 						} else {
-							if (slave.fetish === "masochist" && slave.fetishKnown === 0) {
-								r.push(`${His} chains pinch and constrict ${him} whenever ${he}'s used. ${He} seems to get off on the discomfort; ${he}'s a <span class="lightcoral">natural masochist.</span>`);
-								slave.fetishKnown = 1;
-							} else if (slave.fetish === "none" || slave.fetishKnown === 0) {
-								if (fetishChangeChance(slave) > jsRandom(0, 100)) {
-									r.push(`${His} chains pinch and constrict ${him} whenever ${he}'s used. ${He} learns to come in spite of, and then <span class="lightcoral">because of the discomfort.</span>`);
-									slave.fetish = "masochist";
-									slave.fetishKnown = 1;
-									slave.fetishStrength = 10;
-								}
-							}
+							chainMakesMasochist(slave);
 						}
 						break;
 					case "restrictive latex":
@@ -264,29 +280,9 @@ App.SlaveAssignment.clothes = (function() {
 							r.push(`The outfit ${he}'s wearing keeps ${him} <span class="hotpink">servile</span> and <span class="gold">afraid.</span>`);
 							slave.devotion += 1;
 							slave.trust -= 1;
-							if (slave.fetish === "masochist" && slave.fetishKnown === 0) {
-								r.push(`${His} outfit pinches and constricts ${him} whenever ${he}'s used. ${He} seems to get off on the discomfort; ${he}'s a <span class="lightcoral">natural masochist.</span>`);
-								slave.fetishKnown = 1;
-							} else if (slave.fetish === "none" || slave.fetishKnown === 0) {
-								if (fetishChangeChance(slave) > jsRandom(0, 100)) {
-									r.push(`${His} outfit pinches and constricts ${him} whenever ${he}'s used. ${He} learns to come in spite of, and then <span class="lightcoral">because of the discomfort.</span>`);
-									slave.fetish = "masochist";
-									slave.fetishKnown = 1;
-									slave.fetishStrength = 10;
-								}
-							}
+							harshMakesMasochist(slave);
 						} else {
-							if (slave.fetish === "masochist" && slave.fetishKnown === 0) {
-								r.push(`${His} outfit pinches and constricts ${him} whenever ${he}'s used. ${He} seems to get off on the discomfort; ${he}'s a <span class="lightcoral">natural masochist.</span>`);
-								slave.fetishKnown = 1;
-							} else if (slave.fetish === "none" || slave.fetishKnown === 0) {
-								if (fetishChangeChance(slave) > jsRandom(0, 100)) {
-									r.push(`${His} outfit pinches and constricts ${him} whenever ${he}'s used. ${He} learns to come in spite of, and then <span class="lightcoral">because of the discomfort.</span>`);
-									slave.fetish = "masochist";
-									slave.fetishKnown = 1;
-									slave.fetishStrength = 10;
-								}
-							}
+							harshMakesMasochist(slave);
 						}
 				}
 			} else { // nice
@@ -301,16 +297,7 @@ App.SlaveAssignment.clothes = (function() {
 								slave.devotion += 1;
 							}
 						} else if (slave.fetish === "humiliation") {
-							if (slave.fetishKnown === 0) {
-								r.push(`${He} pretends to be embarrassed by ${his} extremely revealing clothing but seems to get off on it. <span class="lightcoral">${He}'s into humiliation.</span>`);
-								slave.fetishKnown = 1;
-							} else if (slave.fetishStrength > 60) {
-								r.push(`${He} pretends to be embarrassed by ${his} extremely revealing clothing but <span class="hotpink">openly gets off on it.</span>`);
-								slave.devotion += 2;
-							} else {
-								r.push(`${He} pretends to be embarrassed by ${his} extremely revealing clothing but <span class="hotpink">secretly gets off on it.</span>`);
-								slave.devotion += 1;
-							}
+							humiliationLikesExposed(slave);
 						} else if (slave.fetish === "pregnancy" && (slave.bellyPreg >= 1500 || slave.bellyImplant >= 1500)) {
 							if (slave.fetishKnown === 0) {
 								r.push(`${He} pretends to be embarrassed over only having an apron to cover ${his} gravid swell but seems to get off on it. <span class="lightcoral">${He}'s a pregnancy fetishist.</span>`);
@@ -365,16 +352,7 @@ App.SlaveAssignment.clothes = (function() {
 								slave.devotion += 1;
 							}
 						} else if (slave.fetish === "humiliation" && getExposure(slave) === 3) {
-							if (slave.fetishKnown === 0) {
-								r.push(`${He} pretends to be embarrassed by ${his} extremely revealing clothing but seems to get off on it. <span class="lightcoral">${He}'s into humiliation.</span>`);
-								slave.fetishKnown = 1;
-							} else if (slave.fetishStrength > 60) {
-								r.push(`${He} pretends to be embarrassed by ${his} extremely revealing clothing but <span class="hotpink">openly gets off on it.</span>`);
-								slave.devotion += 2;
-							} else {
-								r.push(`${He} pretends to be embarrassed by ${his} extremely revealing clothing but <span class="hotpink">secretly gets off on it.</span>`);
-								slave.devotion += 1;
-							}
+							humiliationLikesExposed(slave);
 						} else if (slave.dick > 0) {
 							/* males have trouble with outfit block */ /* return to with crotch description overhaul */
 							switch (slave.clothes) {
@@ -908,7 +886,12 @@ App.SlaveAssignment.clothes = (function() {
 						slave.devotion += 1;
 						slave.trust -= 1;
 					}
-					r.push(`They're so high they're a bit <span class="health dec">unhealthy</span> for ${his} legs.`);
+					r.push(`They're so high they're a bit <span class="health dec">unhealthy</span> for`);
+					if (hasBothLegs(slave)) {
+						r.push(`${his} legs.`);
+					} else {
+						r.push(`${him}.`);
+					}
 					healthDamage(slave, 2);
 				}
 			} else {
@@ -975,11 +958,11 @@ App.SlaveAssignment.clothes = (function() {
 				}
 			} else if (dildo.width === 2) {
 				if (slave.vagina < 3) {
-					if (jsRandom(1, 4) === 1) {
+					if (V.seeStretching === 1 && jsRandom(1, 4) === 1) {
 						r.push(`Constantly wearing a large dildo in ${his} pussy <span class="lime">stretches it out.</span>`);
 						slave.vagina += 1;
 					} else {
-						r.push(`The large dildo ${he}'s required to wear is a stretch for ${his} cunt, but pussies are resilient and ${he}rs isn't seriously affected.`);
+						r.push(`The large dildo ${he}'s required to wear is a stretch for ${his} cunt, but pussies are resilient and ${hers} isn't seriously affected.`);
 					}
 				} else {
 					r.push(`${His} pussy accommodates the large dildo ${he}'s required to wear.`);
@@ -1027,21 +1010,43 @@ App.SlaveAssignment.clothes = (function() {
 									r.push(`${He} thinks of the massive dildo stretching out ${his} womanhood as <span class="lime">preparation for the biggest cocks,</span> and <span class="hotpink">looks forward</span> to take anything — dicks, hands, truly anything — inside ${his} newly capacious cunt.`);
 									slave.devotion += 4;
 								} else if (slave.fetish === "masochist" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-									r.push(`${He} gets off on the agony of having ${his} cunt <span class="lime">permanently stretched</span> by a huge dildo. The terrible combination of pain and pleasure <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
+									r.push(`${He} gets off on the agony of having ${his} cunt`);
+									if (V.seeStretching === 1) {
+										r.push(`<span class="lime">permanently stretched</span>`);
+									} else {
+										r.push(`stretched`);
+									}
+									r.push(`by a huge dildo. The terrible combination of pain and pleasure <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
 									slave.devotion += 5;
 									slave.trust -= 5;
 								} else if (slave.fetish === "submissive" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-									r.push(`${He} submits to the agony of having ${his} cunt <span class="lime">permanently stretched</span> by a huge dildo. Having ${his} hole ruined at your whim <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
+									r.push(`${He} submits to the agony of having ${his} cunt`);
+									if (V.seeStretching === 1) {
+										r.push(`<span class="lime">permanently stretched</span>`);
+									} else {
+										r.push(`stretched`);
+									}
+									r.push(`by a huge dildo. Having ${his} hole ruined at your whim <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
 									slave.devotion += 5;
 									slave.trust -= 5;
 								} else {
-									r.push(`The agony of having ${his} cunt <span class="lime">permanently stretched</span> by a huge dildo fills ${him} with <span class="mediumorchid">resentment</span> and <span class="gold">fear.</span>`);
+									r.push(`The agony of having ${his} cunt`);
+									if (V.seeStretching === 1) {
+										r.push(`<span class="lime">permanently stretched</span>`);
+									} else {
+										r.push(`stretched`);
+									}
+									r.push(`by a huge dildo fills ${him} with <span class="mediumorchid">resentment</span> and <span class="gold">fear.</span>`);
 									slave.devotion -= 5;
 									slave.trust -= 5;
 								}
 							}
 						}
-						slave.vagina += 1;
+						if (V.seeStretching === 1) {
+							slave.vagina += 1;
+						} else {
+							r.push(`The large dildo ${he}'s required to wear is a stretch for ${his} cunt, but pussies are resilient and ${hers} isn't seriously affected.`);
+						}
 					} else {
 						r.push(`${His} cavernous pussy accommodates the huge dildo ${he}'s required to wear.`);
 					}
@@ -1053,21 +1058,43 @@ App.SlaveAssignment.clothes = (function() {
 									r.push(`${He} thinks of the massive dildo stretching out ${his} womanhood and stomach as <span class="lime">preparation for the biggest cocks,</span> and <span class="hotpink">looks forward</span> to take anything — dicks, hands, arms, truly anything — inside ${his} newly capacious cunt.`);
 									slave.devotion += 4;
 								} else if (slave.fetish === "masochist" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-									r.push(`${He} gets off on the agony of having ${his} cunt <span class="lime">permanently stretched</span> and ${his} cervix penetrated by a huge dildo. The terrible combination of pain and pleasure <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
+									r.push(`${He} gets off on the agony of having ${his} cunt`);
+									if (V.seeStretching === 1) {
+										r.push(`<span class="lime">permanently stretched</span>`);
+									} else {
+										r.push(`stretched`);
+									}
+									r.push(`and ${his} cervix penetrated by a huge dildo. The terrible combination of pain and pleasure <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
 									slave.devotion += 5;
 									slave.trust -= 5;
 								} else if (slave.fetish === "submissive" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-									r.push(`${He} submits to the agony of having ${his} cunt <span class="lime">permanently stretched</span> and ${his} cervix penetrated by a huge dildo. Having ${his} hole and cervix ruined at your whim <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
+									r.push(`${He} submits to the agony of having ${his} cunt`);
+									if (V.seeStretching === 1) {
+										r.push(`<span class="lime">permanently stretched</span>`);
+									} else {
+										r.push(`stretched`);
+									}
+									r.push(`and ${his} cervix penetrated by a huge dildo. Having ${his} hole and cervix ruined at your whim <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
 									slave.devotion += 5;
 									slave.trust -= 5;
 								} else {
-									r.push(`The agony of having ${his} cunt <span class="lime">permanently stretched</span> and ${his} cervix penetrated by a huge dildo fills ${him} with <span class="mediumorchid">resentment</span> and <span class="gold">fear.</span>`);
+									r.push(`The agony of having ${his} cunt`);
+									if (V.seeStretching === 1) {
+										r.push(`<span class="lime">permanently stretched</span>`);
+									} else {
+										r.push(`stretched`);
+									}
+									r.push(`and ${his} cervix penetrated by a huge dildo fills ${him} with <span class="mediumorchid">resentment</span> and <span class="gold">fear.</span>`);
 									slave.devotion -= 5;
 									slave.trust -= 5;
 								}
 							}
 						}
-						slave.vagina += 1;
+						if (V.seeStretching === 1) {
+							slave.vagina += 1;
+						} else {
+							r.push(`The large dildo ${he}'s required to wear is a stretch for ${his} cunt, but pussies are resilient and ${hers} isn't seriously affected.`);
+						}
 					} else {
 						r.push(`${His} cavernous pussy accommodates the huge dildo ${he}'s required to wear.`);
 					}
@@ -1118,9 +1145,34 @@ App.SlaveAssignment.clothes = (function() {
 		}
 	}
 
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function smallButtPlugEffects(slave) {
+		if (slave.sexualFlaw === "hates anal" && jsRandom(1, 100) > 50) {
+			r.push(`It <span class="green">gets ${him} habituated to having ${his} asshole filled.</span>`);
+			slave.sexualFlaw = "none";
+		}
+		if (slave.sexualQuirk === "size queen" && plugLength(slave) > 1) {
+			r.push(`The overly long plug delving the depths of ${his} rear <span class="hotpink">gets ${him} off,</span> since ${he}'s a size queen.`);
+			slave.devotion += 2;
+		}
+	}
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function largeButtPlugEffect(slave) {
+		r.push(`${His} anus accommodates the large plug ${he}'s required to wear.`);
+		if (slave.fetish === "buttslut" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
+			r.push(`In fact, ${he} <span class="hotpink">regularly orgasms</span> even in non-sexual situations as the plug is <span class="libido inc">constantly stimulating</span> ${his} rear-end.`);
+			slave.devotion += 1;
+			slave.energy += 1;
+		}
+	}
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
 	 */
 	function analAccessories(slave) {
 		const plugDiameter = plugWidth(slave);
@@ -1135,14 +1187,7 @@ App.SlaveAssignment.clothes = (function() {
 						r.push(`${His} asshole is used to being penetrated and wearing ${his} tailed buttplug doesn't affect it, though it still serves as <span class="gold">a constant degrading reminder of ${his} submission.</span>`);
 						slave.trust -= 2;
 					}
-					if (slave.sexualFlaw === "hates anal" && jsRandom(1, 100) > 50) {
-						r.push(`It <span class="green">gets ${him} habituated to having ${his} asshole filled.</span>`);
-						slave.sexualFlaw = "none";
-					}
-					if (slave.sexualQuirk === "size queen" && plugLength(slave) > 1) {
-						r.push(`The overly long plug delving the depths of ${his} rear <span class="hotpink">gets ${him} off,</span> since ${he}'s a size queen.`);
-						slave.devotion += 2;
-					}
+					smallButtPlugEffects(slave);
 				}
 			} else {
 				if (slave.fuckdoll === 0 && slave.fetish !== "mindbroken") {
@@ -1152,14 +1197,7 @@ App.SlaveAssignment.clothes = (function() {
 					} else {
 						r.push(`${His} asshole is used to being penetrated and wearing ${his} buttplug doesn't affect it.`);
 					}
-					if (slave.sexualFlaw === "hates anal" && jsRandom(1, 100) > 50) {
-						r.push(`It <span class="green">gets ${him} habituated to having ${his} asshole filled.</span>`);
-						slave.sexualFlaw = "none";
-					}
-					if (slave.sexualQuirk === "size queen" && plugLength(slave) > 1) {
-						r.push(`The overly long plug delving the depths of ${his} rear <span class="hotpink">gets ${him} off,</span> since ${he}'s a size queen.`);
-						slave.devotion += 2;
-					}
+					smallButtPlugEffects(slave);
 				}
 			}
 		} else if (plugDiameter === 2) {
@@ -1183,19 +1221,14 @@ App.SlaveAssignment.clothes = (function() {
 					}
 				}
 				if (slave.anus < 3) {
-					if (slave.anus < 1 || jsRandom(1, 2) === 1) {
+					if (V.seeStretching === 1 && (slave.anus < 1 || jsRandom(1, 2) === 1)) {
 						r.push(`Constantly wearing a large tailed plug up ${his} ass <span class="lime">loosens ${his} sphincter.</span>`);
 						slave.anus += 1;
 					} else {
 						r.push(`The large tailed plug ${he}'s required to wear up ${his} ass stretches it to the limit, but on the rare occasions when the plug is removed, ${his} rear hole still tightens up.`);
 					}
 				} else {
-					r.push(`${His} anus accommodates the large plug ${he}'s required to wear.`);
-					if (slave.fetish === "buttslut" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-						r.push(`In fact, ${he} <span class="hotpink">regularly orgasms</span> even in non-sexual situations as the plug is <span class="libido inc">constantly stimulating</span> ${his} rear-end.`);
-						slave.devotion += 1;
-						slave.energy += 1;
-					}
+					largeButtPlugEffect(slave);
 				}
 			} else {
 				if (slave.fuckdoll === 0 && slave.fetish !== "mindbroken") {
@@ -1215,19 +1248,14 @@ App.SlaveAssignment.clothes = (function() {
 					}
 				}
 				if (slave.anus < 3) {
-					if (slave.anus < 1 || jsRandom(1, 2) === 1) {
+					if (V.seeStretching === 1 && (slave.anus < 1 || jsRandom(1, 2) === 1)) {
 						r.push(`Constantly wearing a large plug up ${his} ass <span class="lime">loosens ${his} sphincter.</span>`);
 						slave.anus += 1;
 					} else {
 						r.push(`The large plug ${he}'s required to wear up ${his} ass stretches it to the limit, but on the rare occasions when the plug is removed, ${his} rear hole still tightens up.`);
 					}
 				} else {
-					r.push(`${His} anus accommodates the large plug ${he}'s required to wear.`);
-					if (slave.fetish === "buttslut" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-						r.push(`In fact, ${he} <span class="hotpink">regularly orgasms</span> even in non-sexual situations as the plug is <span class="libido inc">constantly stimulating</span> ${his} rear-end.`);
-						slave.devotion += 1;
-						slave.energy += 1;
-					}
+					largeButtPlugEffect(slave);
 				}
 			}
 		} else if (plugDiameter === 3) {
@@ -1239,20 +1267,42 @@ App.SlaveAssignment.clothes = (function() {
 							slave.devotion += 4;
 							slave.trust -= 5;
 						} else if (slave.fetish === "masochist" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-							r.push(`${He} gets off on the agony of having ${his} anal sphincter <span class="lime">permanently gaped</span> by a huge tailed buttplug, but can't ignore the tail hanging from the back of the plug. The terrible combination of anal pleasure and degradation <span class="hotpink">breaks ${his} will</span> and fills ${him} with <span class="gold">humiliation.</span>`);
+							r.push(`${He} gets off on the agony of having ${his} anal sphincter`);
+							if (V.seeStretching === 1) {
+								r.push(`<span class="lime">permanently gaped</span>`);
+							} else {
+								r.push(`stretched`);
+							}
+							r.push(`by a huge tailed buttplug, but can't ignore the tail hanging from the back of the plug. The terrible combination of anal pleasure and degradation <span class="hotpink">breaks ${his} will</span> and fills ${him} with <span class="gold">humiliation.</span>`);
 							slave.devotion += 5;
 							slave.trust -= 7;
 						} else if (slave.fetish === "submissive" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-							r.push(`${He} submits to the agony of having ${his} anal sphincter <span class="lime">permanently gaped</span> by a huge tailed buttplug and the shame of having a tail dangle from the back of the plug. Having ${his} hole ruined at your whim and in such a degrading fashion <span class="hotpink">breaks ${his} will</span> and fills ${him} with <span class="gold">humiliation.</span>`);
+							r.push(`${He} submits to the agony of having ${his} anal sphincter`);
+							if (V.seeStretching === 1) {
+								r.push(`<span class="lime">permanently gaped</span>`);
+							} else {
+								r.push(`stretched`);
+							}
+							r.push(`by a huge tailed buttplug and the shame of having a tail dangle from the back of the plug. Having ${his} hole ruined at your whim and in such a degrading fashion <span class="hotpink">breaks ${his} will</span> and fills ${him} with <span class="gold">humiliation.</span>`);
 							slave.devotion += 5;
 							slave.trust -= 7;
 						} else {
-							r.push(`The agony of having ${his} anal sphincter <span class="lime">permanently gaped</span> by a huge tailed buttplug fills ${him} with <span class="mediumorchid">resentment</span> and <span class="gold">humiliation.</span>`);
+							r.push(`The agony of having ${his} anal sphincter`);
+							if (V.seeStretching === 1) {
+								r.push(`<span class="lime">permanently gaped</span>`);
+							} else {
+								r.push(`stretched`);
+							}
+							r.push(`by a huge tailed buttplug fills ${him} with <span class="mediumorchid">resentment</span> and <span class="gold">humiliation.</span>`);
 							slave.devotion -= 5;
 							slave.trust -= 5;
 						}
 					}
-					slave.anus += 1;
+					if (V.seeStretching === 1) {
+						slave.anus += 1;
+					} else {
+						r.push(`On the rare occasions when the plug is removed, ${his} rear hole still tightens up.`);
+					}
 				} else {
 					r.push(`${His} gaping anus accommodates the huge tailed plug ${he}'s required to wear, serving little purpose other than to remind ${him} of ${his} <span class="gold">humiliation.</span>`);
 					if (slave.fetish === "buttslut" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
@@ -1268,20 +1318,42 @@ App.SlaveAssignment.clothes = (function() {
 							r.push(`${He} thinks of the horribly huge plug ${he} has wear in ${his} butt as <span class="lime">preparation for the biggest cocks,</span> and <span class="hotpink">looks forward</span> to being able to safely take unlubricated anal from them.`);
 							slave.devotion += 4;
 						} else if (slave.fetish === "masochist" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-							r.push(`${He} gets off on the agony of having ${his} anal sphincter <span class="lime">permanently gaped</span> by a huge buttplug. The terrible combination of pain and pleasure <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
+							r.push(`${He} gets off on the agony of having ${his} anal sphincter`);
+							if (V.seeStretching === 1) {
+								r.push(`<span class="lime">permanently gaped</span>`);
+							} else {
+								r.push(`stretched`);
+							}
+							r.push(`by a huge buttplug. The terrible combination of pain and pleasure <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
 							slave.devotion += 5;
 							slave.trust -= 5;
 						} else if (slave.fetish === "submissive" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-							r.push(`${He} submits to the agony of having ${his} anal sphincter <span class="lime">permanently gaped</span> by a huge buttplug. Having ${his} hole ruined at your whim <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
+							r.push(`${He} submits to the agony of having ${his} anal sphincter`);
+							if (V.seeStretching === 1) {
+								r.push(`<span class="lime">permanently gaped</span>`);
+							} else {
+								r.push(`stretched`);
+							}
+							r.push(`by a huge buttplug. Having ${his} hole ruined at your whim <span class="hotpink">breaks ${his} will</span> but fills ${him} with <span class="gold">fear.</span>`);
 							slave.devotion += 5;
 							slave.trust -= 5;
 						} else {
-							r.push(`The agony of having ${his} anal sphincter <span class="lime">permanently gaped</span> by a huge buttplug fills ${him} with <span class="mediumorchid">resentment</span> and <span class="gold">fear.</span>`);
+							r.push(`The agony of having ${his} anal sphincter`);
+							if (V.seeStretching === 1) {
+								r.push(`<span class="lime">permanently gaped</span>`);
+							} else {
+								r.push(`stretched`);
+							}
+							r.push(`by a huge buttplug fills ${him} with <span class="mediumorchid">resentment</span> and <span class="gold">fear.</span>`);
 							slave.devotion -= 5;
 							slave.trust -= 5;
 						}
 					}
-					slave.anus += 1;
+					if (V.seeStretching === 1) {
+						slave.anus += 1;
+					} else {
+						r.push(`On the rare occasions when the plug is removed, ${his} rear hole still tightens up.`);
+					}
 				} else {
 					r.push(`${His} gaping anus accommodates the huge plug ${he}'s required to wear.`);
 					if (slave.fetish === "buttslut" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
@@ -1320,4 +1392,4 @@ App.SlaveAssignment.clothes = (function() {
 			}
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saDevotion.js b/src/endWeek/saDevotion.js
index 84bc5475295e208952a4559b3407483fea56eb68..5582875272dd5b5fcf740e65a0baee2aa4ea95ad 100644
--- a/src/endWeek/saDevotion.js
+++ b/src/endWeek/saDevotion.js
@@ -1,64 +1,47 @@
-App.SlaveAssignment.devotion = (function() {
-	"use strict";
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.devotion = function saDevotion(slave) {
+	/** @type {string[]} */
+	const r = [];
 
-	let r;
+	const PC = V.PC;
 
-	let He;
-	let His;
-	let he;
-	let him;
-	let his;
-	let himself;
-	let playerPronouns;
-	let PC;
-	let gettingPersonalAttention;
+	const {
+		He, His, he, him, his, himself
+	} = getPronouns(slave);
+	const playerPronouns = getPronouns(V.PC);
 
-	return saDevotion;
+	const gettingPersonalAttention = V.personalAttention.task === PersonalAttention.TRAINING && V.personalAttention.slaves.some((s) => s.ID === slave.ID);
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @returns {string}
-	 */
-	function saDevotion(slave) {
-		r = [];
-
-		PC = V.PC;
-
-		({
-			He, His, he, him, his, himself
-		} = getPronouns(slave));
-		playerPronouns = getPronouns(PC);
-
-		gettingPersonalAttention = V.personalAttention.task === PersonalAttention.TRAINING && V.personalAttention.slaves.some((s) => s.ID === slave.ID);
-
-		if (slave.fetish === "mindbroken") {
-			mindbreakDevotion(slave);
-		} else if (slave.fuckdoll !== 0) {
-			fuckdollDevotion(slave);
-		} else {
-			hostageDevotion(slave);
-			playerPregnancyThoughts(slave);
-			if (slave.devotion <= 95) {
-				slaveryResistance(slave);
-			}
-			FSImpacts(slave);
-			if (slave.bodySwap > 0 && slave.origBodyOwnerID > 0) {
-				bodySwapThoughts(slave);
-			}
-			retirementThoughts(slave);
-			if (assignmentVisible(slave) && V.personalAttention.task === PersonalAttention.SEX) {
-				sexualAttentionThoughts(slave);
-			}
-			collectiveSpirit(slave);
-			statCrossovers(slave);
-			statRebounding(slave);
-			devotionReport(slave);
-			finalChanges(slave);
+	if (slave.fetish === "mindbroken") {
+		mindbreakDevotion(slave);
+	} else if (slave.fuckdoll !== 0) {
+		fuckdollDevotion(slave);
+	} else {
+		hostageDevotion(slave);
+		playerPregnancyThoughts(slave);
+		if (slave.devotion <= 95) {
+			slaveryResistance(slave);
 		}
-
-		return r.join(" ");
+		FSImpacts(slave);
+		if (slave.bodySwap > 0 && slave.origBodyOwnerID > 0) {
+			bodySwapThoughts(slave);
+		}
+		retirementThoughts(slave);
+		if (assignmentVisible(slave) && V.personalAttention.task === PersonalAttention.SEX) {
+			sexualAttentionThoughts(slave);
+		}
+		collectiveSpirit(slave);
+		statCrossovers(slave);
+		statRebounding(slave);
+		devotionReport(slave);
+		finalChanges(slave);
 	}
 
+	return r.join(" ");
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 *
@@ -110,18 +93,18 @@ App.SlaveAssignment.devotion = (function() {
 	 *
 	 */
 	function hostageDevotion(slave) {
-		if (slave.origin === "You were acquainted with $him before you were an arcology owner; your rival tried to use $him to manipulate you, but you rescued $him." && slave.newGamePlus === 0 && V.rivalryFS !== "Slave Professionalism" && V.rivalryFS !== "Intellectual Dependency") {
-			if (V.rivalryDuration <= 10 || V.rivalryFS === "Racial Supremacism" || V.rivalryFS === "Paternalism") {
+		if (slave.origin === "You were acquainted with $him before you were an arcology owner; your rival tried to use $him to manipulate you, but you rescued $him." && slave.newGamePlus === 0 && V.rival.FS.name !== "Slave Professionalism" && V.rival.FS.name !== "Intellectual Dependency") {
+			if (V.rival.duration <= 10 || V.rival.FS.name === "Racial Supremacism" || V.rival.FS.name === "Paternalism") {
 				r.push(`You <span class="trust inc">saved ${slave.slaveName} from a living nightmare</span> under your rival's rule. ${He} <span class="devotion inc">tries ${his} best to adapt to ${his} savior's wishes.</span>`);
 				slave.devotion += 10;
 				slave.trust += 10;
 			/* TODO: Setup setter code block. Already defined within js/003-Data/gameVariableData.js
-			} else if (V.hostageGiveIn === 1) {
+			} else if (V.rival.hostageState === 3) {
 				r.push(`Since you are <span class="trust inc">indulging</span> ${slave.slaveName}'s desires, ${he} <span class="devotion inc">likes you more.</span>`);
 				slave.devotion += 5;
 				slave.trust += 5;
 			*/
-			} else if (V.rivalryDuration > 20 && slave.devotion < 5) {
+			} else if (V.rival.duration > 20 && slave.devotion < 5) {
 				if (gettingPersonalAttention) {
 					r.push(`You took everything from ${slave.slaveName} and <span class="devotion dec">${he} hates you for it.</span> Since you won't give ${him} what ${he} wants, ${he} <span class="trust dec">refuses to trust you.</span> Since you are putting such a personal touch into ${his} care, ${he} can't find it in ${him} to rebel as strongly.`);
 					slave.devotion -= 5;
@@ -131,7 +114,7 @@ App.SlaveAssignment.devotion = (function() {
 					slave.devotion -= 25;
 					slave.trust -= 25;
 				}
-			} else if (V.rivalryDuration > 10 && slave.devotion < 5) {
+			} else if (V.rival.duration > 10 && slave.devotion < 5) {
 				if (gettingPersonalAttention) {
 					r.push(`${He} is <span class="trust dec">horrified by you.</span> Your rival taught ${him} a great deal about slave life in your arcology and indulged ${his} deepest fantasies. ${slave.slaveName} considers being your pet <span class="devotion dec">a fate worse than death.</span> Since you are putting such a personal touch into ${his} care, maybe you aren't the monster ${he} thought you were. ${He} can't find it in ${him} to hate and fear you as much.`);
 					slave.devotion -= 3;
@@ -328,7 +311,122 @@ App.SlaveAssignment.devotion = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
+	 */
+	function retirementToCitizenIsSoonThoughts(slave) {
+		r.push(`${He} knows that it's less than a year until ${his} retirement from sexual slavery into citizenship.`);
+		if (slave.devotion > 95) {
+			r.push(`Since ${he} loves you, ${he} has mixed feelings about the prospect, but ${he} prefers to think of it as your way of looking after ${him}. It's ${his} favorite subject, and ${his} strong feelings about it`);
+			if (V.arcologies[0].FSPaternalist !== "unset") {
+				r.push(`advances paternalistic ideals and <span class="reputation inc">improves your reputation.</span>`);
+				FutureSocieties.Change("Paternalist", 2);
+			} else {
+				r.push(`<span class="reputation inc">improves your reputation.</span>`);
+				repX(V.FSSingleSlaveRep * 2, "retirement", slave);
+			}
+		} else if (slave.devotion >= -20) {
+			r.push(`The prospect of manumission <span class="devotion inc">encourages ${him} to submit to slavery</span> and <span class="trust inc">encourages ${him} to be optimistic.</span>`);
+			slave.devotion += 2;
+			slave.trust += 2;
+		} else {
+			r.push(`The prospect of manumission encourages ${him} to <span class="trust inc">tolerate anything.</span>`);
+			slave.trust += 2;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function retirementToCitizenThoughts(slave) {
+		r.push(`${His} retirement from sexual slavery into citizenship is on the horizon.`);
+		if (slave.devotion > 95) {
+			r.push(`Since ${he} loves you, ${he} has mixed feelings about the prospect, but ${he} prefers to think of it as your way of looking after ${him}. This`);
+			if (V.arcologies[0].FSPaternalist !== "unset") {
+				r.push(`advances paternalistic ideals and <span class="reputation inc">improves your reputation.</span>`);
+				FutureSocieties.Change("Paternalist", 2);
+			} else {
+				r.push(`<span class="reputation inc">improves your reputation.</span>`);
+				repX(V.FSSingleSlaveRep, "retirement", slave);
+			}
+		} else if (slave.devotion >= -20) {
+			r.push(`The prospect of manumission <span class="devotion inc">cheers ${him} up</span> and <span class="trust inc">makes ${him} optimistic.</span>`);
+			slave.devotion += 1;
+			slave.trust += 1;
+		} else {
+			r.push(`The prospect of manumission works to make the indignities of slavery <span class="trust inc">weigh lightly</span> on ${him}.`);
+			slave.trust += 1;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function cruelRetirementIsSoonThoughts(slave) {
+		if (slave.devotion > 95) {
+			r.push(`Since ${he} loves you, ${he} desperately tries not to think about it, though ${he} occasionally bursts into tears without provocation.`);
+		} else if (slave.devotion > 20) {
+			r.push(`To put it mildly, <span class="trust dec">${he} is terrified.</span>`);
+			slave.trust -= 3;
+		} else {
+			r.push(`${He} is filled with <span class="trust dec">terror</span> and <span class="devotion dec">horror.</span>`);
+			slave.devotion -= 3;
+			slave.trust -= 3;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function cruelRetirementThoughts(slave) {
+		if (slave.devotion > 95) {
+			r.push(`Since ${he} loves you, ${he} tries not to think about it, though ${he} occasionally seems preoccupied.`);
+		} else if (slave.devotion > 20) {
+			r.push(`The prospect <span class="trust dec">scares ${him}.</span>`);
+			slave.trust -= 2;
+		} else {
+			r.push(`The prospect <span class="trust dec">scares</span> and <span class="devotion dec">disgusts ${him}.</span>`);
+			slave.devotion -= 2;
+			slave.trust -= 2;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function retirementByFateThoughts(slave) {
+		const relevantAge = V.policies.retirement.physicalAgePolicy === 0 ? slave.actualAge : slave.physicalAge;
+		const expectedTime = V.retirementAge - relevantAge;
+
+		if (expectedTime > 5) {
+			return;
+		}
+
+		if (V.policies.retirement.fate === "citizen") {
+			if (expectedTime < 2) {
+				retirementToCitizenIsSoonThoughts(slave);
+			} else {
+				retirementToCitizenThoughts(slave);
+			}
+		} else if (V.policies.retirement.fate === "bioreactor") {
+			if (expectedTime < 2) {
+				r.push(`${He} knows that it's less than a year until ${his} permanent inclusion in the arcology's milk production systems.`);
+				cruelRetirementIsSoonThoughts(slave);
+			} else {
+				r.push(`${He} knows that ${his} permanent inclusion in the arcology's milk production systems is not far off.`);
+				cruelRetirementThoughts(slave);
+			}
+		} else if (V.policies.retirement.fate === "arcade") {
+			if (expectedTime < 2) {
+				r.push(`${He} knows that it's less than a year until ${he} is to be permanently encased in a bodysuit with holes for nothing but dick.`);
+				cruelRetirementIsSoonThoughts(slave);
+			} else {
+				r.push(`${He} knows that ${his} ultimate fate as a Fuckdoll is not far off.`);
+				cruelRetirementThoughts(slave);
+			}
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
 	 */
 	function retirementThoughts(slave) {
 		if (slave.indenture > -1) {
@@ -367,195 +465,7 @@ App.SlaveAssignment.devotion = (function() {
 				}
 			}
 		} else if (V.seeAge === 1) {
-			if (slave.actualAge >= V.retirementAge - 5 && V.policies.retirement.physicalAgePolicy === 0) {
-				if (V.policies.retirement.fate === "citizen") {
-					if (slave.actualAge >= V.retirementAge - 1) {
-						r.push(`${He} knows that it's less than a year until ${his} retirement from sexual slavery into citizenship.`);
-						if (slave.devotion > 95) {
-							r.push(`Since ${he} loves you, ${he} has mixed feelings about the prospect, but ${he} prefers to think of it as your way of looking after ${him}. It's ${his} favorite subject, and ${his} strong feelings about it`);
-							if (V.arcologies[0].FSPaternalist !== "unset") {
-								r.push(`advances paternalistic ideals and <span class="reputation inc">improves your reputation.</span>`);
-								FutureSocieties.Change("Paternalist", 2);
-							} else {
-								r.push(`<span class="reputation inc">improves your reputation.</span>`);
-								repX(V.FSSingleSlaveRep * 2, "retirement", slave);
-							}
-						} else if (slave.devotion >= -20) {
-							r.push(`The prospect of manumission <span class="devotion inc">encourages ${him} to submit to slavery</span> and <span class="trust inc">encourages ${him} to be optimistic.</span>`);
-							slave.devotion += 2;
-							slave.trust += 2;
-						} else {
-							r.push(`The prospect of manumission encourages ${him} to <span class="trust inc">tolerate anything.</span>`);
-							slave.trust += 2;
-						}
-					} else {
-						r.push(`${His} retirement from sexual slavery into citizenship is on the horizon.`);
-						if (slave.devotion > 95) {
-							r.push(`Since ${he} loves you, ${he} has mixed feelings about the prospect, but ${he} prefers to think of it as your way of looking after ${him}. This`);
-							if (V.arcologies[0].FSPaternalist !== "unset") {
-								r.push(`advances paternalistic ideals and <span class="reputation inc">improves your reputation.</span>`);
-								FutureSocieties.Change("Paternalist", 2);
-							} else {
-								r.push(`<span class="reputation inc">improves your reputation.</span>`);
-								repX(V.FSSingleSlaveRep, "retirement", slave);
-							}
-						} else if (slave.devotion >= -20) {
-							r.push(`The prospect of manumission <span class="devotion inc">cheers ${him} up</span> and <span class="trust inc">makes ${him} optimistic.</span>`);
-							slave.devotion += 1;
-							slave.trust += 1;
-						} else {
-							r.push(`The prospect of manumission works to make the indignities of slavery <span class="trust inc">weigh lightly</span> on ${him}.`);
-							slave.trust += 1;
-						}
-					}
-				} else if (V.policies.retirement.fate === "bioreactor") {
-					if (slave.actualAge >= V.retirementAge - 1) {
-						r.push(`${He} knows that it's less than a year until ${his} permanent inclusion in the arcology's milk production systems.`);
-						if (slave.devotion > 95) {
-							r.push(`Since ${he} loves you, ${he} desperately tries not to think about it, though ${he} occasionally bursts into tears without provocation.`);
-						} else if (slave.devotion > 20) {
-							r.push(`To put it mildly, <span class="trust dec">${he} is terrified.</span>`);
-							slave.trust -= 3;
-						} else {
-							r.push(`${He} is filled with <span class="trust dec">terror</span> and <span class="devotion dec">horror.</span>`);
-							slave.devotion -= 3;
-							slave.trust -= 3;
-						}
-					} else {
-						r.push(`${He} knows that ${his} permanent inclusion in the arcology's milk production systems is not far off.`);
-						if (slave.devotion > 95) {
-							r.push(`Since ${he} loves you, ${he} tries not to think about it, though ${he} occasionally seems preoccupied.`);
-						} else if (slave.devotion > 20) {
-							r.push(`The prospect <span class="trust dec">scares ${him}.</span>`);
-							slave.trust -= 2;
-						} else {
-							r.push(`The prospect <span class="trust dec">scares</span> and <span class="devotion dec">disgusts ${him}.</span>`);
-							slave.devotion -= 2;
-							slave.trust -= 2;
-						}
-					}
-				} else if (V.policies.retirement.fate === "arcade") {
-					if (slave.actualAge >= V.retirementAge - 1) {
-						r.push(`${He} knows that it's less than a year until ${he} is to be permanently encased in a bodysuit with holes for nothing but dick.`);
-						if (slave.devotion > 95) {
-							r.push(`Since ${he} loves you, ${he} desperately tries not to think about it, though ${he} occasionally bursts into tears without provocation.`);
-						} else if (slave.devotion > 20) {
-							r.push(`To put it mildly, <span class="trust dec">${he} is terrified.</span>`);
-							slave.trust -= 3;
-						} else {
-							r.push(`${He} is filled with <span class="trust dec">terror</span> and <span class="devotion dec">horror.</span>`);
-							slave.devotion -= 3;
-							slave.trust -= 3;
-						}
-					} else {
-						r.push(`${He} knows that ${his} ultimate fate as a Fuckdoll is not far off.`);
-						if (slave.devotion > 95) {
-							r.push(`Since ${he} loves you, ${he} tries not to think about it, though ${he} occasionally seems preoccupied.`);
-						} else if (slave.devotion > 20) {
-							r.push(`The prospect <span class="trust dec">scares ${him}.</span>`);
-							slave.trust -= 2;
-						} else {
-							r.push(`The prospect <span class="trust dec">scares</span> and <span class="devotion dec">disgusts ${him}.</span>`);
-							slave.devotion -= 2;
-							slave.trust -= 2;
-						}
-					}
-				}
-			} else if (slave.physicalAge >= V.retirementAge - 5 && V.policies.retirement.physicalAgePolicy) {
-				if (V.policies.retirement.fate === "citizen") {
-					if (slave.physicalAge >= V.retirementAge - 1) {
-						r.push(`${He} knows that it's less than a year until ${his} retirement from sexual slavery into citizenship.`);
-						if (slave.devotion > 95) {
-							r.push(`Since ${he} loves you, ${he} has mixed feelings about the prospect, but ${he} prefers to think of it as your way of looking after ${him}. It's ${his} favorite subject, and ${his} strong feelings about it`);
-							if (V.arcologies[0].FSPaternalist !== "unset") {
-								r.push(`advances paternalistic ideals and <span class="reputation inc">improves your reputation.</span>`);
-								FutureSocieties.Change("Paternalist", 2);
-							} else {
-								r.push(`<span class="reputation inc">improves your reputation.</span>`);
-								repX(V.FSSingleSlaveRep * 2, "retirement", slave);
-							}
-						} else if (slave.devotion >= -20) {
-							r.push(`The prospect of manumission <span class="devotion inc">encourages ${him} to submit to slavery</span> and <span class="trust inc">encourages ${him} to be optimistic.</span>`);
-							slave.devotion += 2;
-							slave.trust += 2;
-						} else {
-							r.push(`The prospect of manumission encourages ${him} to <span class="trust inc">tolerate anything.</span>`);
-							slave.trust += 2;
-						}
-					} else {
-						r.push(`${His} retirement from sexual slavery into citizenship is on the horizon.`);
-						if (slave.devotion > 95) {
-							r.push(`Since ${he} loves you, ${he} has mixed feelings about the prospect, but ${he} prefers to think of it as your way of looking after ${him}. This`);
-							if (V.arcologies[0].FSPaternalist !== "unset") {
-								r.push(`advances paternalistic ideals and <span class="reputation inc">improves your reputation.</span>`);
-								FutureSocieties.Change("Paternalist", 2);
-							} else {
-								r.push(`<span class="reputation inc">improves your reputation.</span>`);
-								repX(V.FSSingleSlaveRep, "retirement", slave);
-							}
-						} else if (slave.devotion >= -20) {
-							r.push(`The prospect of manumission <span class="devotion inc">cheers ${him} up</span> and <span class="trust inc">makes ${him} optimistic.</span>`);
-							slave.devotion += 1;
-							slave.trust += 1;
-						} else {
-							r.push(`The prospect of manumission works to make the indignities of slavery <span class="trust inc">weigh lightly</span> on ${him}.`);
-							slave.trust += 1;
-						}
-					}
-				} else if (V.policies.retirement.fate === "bioreactor") {
-					if (slave.physicalAge >= V.retirementAge - 1) {
-						r.push(`${He} knows that it's less than a year until ${his} permanent inclusion in the arcology's milk production systems.`);
-						if (slave.devotion > 95) {
-							r.push(`Since ${he} loves you, ${he} desperately tries not to think about it, though ${he} occasionally bursts into tears without provocation.`);
-						} else if (slave.devotion > 20) {
-							r.push(`To put it mildly, <span class="trust dec">${he} is terrified.</span>`);
-							slave.trust -= 3;
-						} else {
-							r.push(`${He} is filled with <span class="trust dec">terror</span> and <span class="devotion dec">horror.</span>`);
-							slave.devotion -= 3;
-							slave.trust -= 3;
-						}
-					} else {
-						r.push(`${He} knows that ${his} permanent inclusion in the arcology's milk production systems is not far off.`);
-						if (slave.devotion > 95) {
-							r.push(`Since ${he} loves you, ${he} tries not to think about it, though ${he} occasionally seems preoccupied.`);
-						} else if (slave.devotion > 20) {
-							r.push(`The prospect <span class="trust dec">scares ${him}.</span>`);
-							slave.trust -= 2;
-						} else {
-							r.push(`The prospect <span class="trust dec">scares</span> and <span class="devotion dec">disgusts ${him}.</span>`);
-							slave.devotion -= 2;
-							slave.trust -= 2;
-						}
-					}
-				} else if (V.policies.retirement.fate === "arcade") {
-					if (slave.physicalAge >= V.retirementAge - 1) {
-						r.push(`${He} knows that it's less than a year until ${he} is to be permanently encased in a bodysuit with holes for nothing but dick.`);
-						if (slave.devotion > 95) {
-							r.push(`Since ${he} loves you, ${he} desperately tries not to think about it, though ${he} occasionally bursts into tears without provocation.`);
-						} else if (slave.devotion > 20) {
-							r.push(`To put it mildly, <span class="trust dec">${he} is terrified.</span>`);
-							slave.trust -= 3;
-						} else {
-							r.push(`${He} is filled with <span class="trust dec">terror</span> and <span class="devotion dec">horror.</span>`);
-							slave.devotion -= 3;
-							slave.trust -= 3;
-						}
-					} else {
-						r.push(`${He} knows that ${his} ultimate fate as a Fuckdoll is not far off.`);
-						if (slave.devotion > 95) {
-							r.push(`Since ${he} loves you, ${he} tries not to think about it, though ${he} occasionally seems preoccupied.`);
-						} else if (slave.devotion > 20) {
-							r.push(`The prospect <span class="trust dec">scares ${him}.</span>`);
-							slave.trust -= 2;
-						} else {
-							r.push(`The prospect <span class="trust dec">scares</span> and <span class="devotion dec">disgusts ${him}.</span>`);
-							slave.devotion -= 2;
-							slave.trust -= 2;
-						}
-					}
-				}
-			}
+			retirementByFateThoughts(slave);
 			if (V.policies.retirement.fate === "citizen") {
 				if (slave.devotion <= 95 || slave.trust <= 95) {
 					if (V.policies.retirement.sex > 0) {
@@ -1130,4 +1040,4 @@ App.SlaveAssignment.devotion = (function() {
 			slave.rudeTitle = 0;
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saDiet.js b/src/endWeek/saDiet.js
index 1711dd12e8aede1ed9dc4009959af75741576d87..a6fc4a50cf315bfc8e9df705ca10dabcf11808e1 100644
--- a/src/endWeek/saDiet.js
+++ b/src/endWeek/saDiet.js
@@ -1,68 +1,47 @@
-App.SlaveAssignment.diet = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.diet = function saDiet(slave) {
+	/** @type {string[]} */
+	const r = [];
 
-	let r;
+	const gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
+	const rearQuirk = slave.geneticQuirks.rearLipedema === 2 ? 2 : 0;
+	const boobSize = slave.boobs - slave.boobsImplant - slave.boobsMilk;
+	const buttSize = slave.butt - slave.buttImplant;
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let He;
-	let His;
-
-	let weightGain;
-	let weightLoss;
 	let growthGoal;
 	let roll;
 	let target;
-	let gigantomastiaMod;
-	let rearQuirk;
-	let boobSize;
-	let buttSize;
-
-	return saDiet;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {string}
-	 */
-	function saDiet(slave) {
-		r = [];
 
-		weightGain = -1; // -1 used in cockFeeder()
-		weightLoss = 0;
-		gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
-		rearQuirk = slave.geneticQuirks.rearLipedema === 2 ? 2 : 0;
-		boobSize = slave.boobs - slave.boobsImplant - slave.boobsMilk;
-		buttSize = slave.butt - slave.buttImplant;
+	let weightGain = -1; // -1 used in cockFeeder()
 
-		({
-			he, him, his, himself, He, His
-		} = getPronouns(slave));
+	const {
+		he, him, his, himself, He, His
+	} = getPronouns(slave);
 
-		if (V.feeder === 1) {
-			feederUsed(slave);
+	if (V.feeder === 1) {
+		feederUsed(slave);
+	}
+	foodEffects(slave);
+	geneticQuirkEffects(slave);
+	if (slave.fuckdoll === 0 && slave.fetish !== "mindbroken") {
+		if (slave.dietCum > 0) {
+			cumDiet(slave);
 		}
-		foodEffects(slave);
-		geneticQuirkEffects(slave);
-		if (slave.fuckdoll === 0 && slave.fetish !== "mindbroken") {
-			if (slave.dietCum > 0) {
-				cumDiet(slave);
-			}
-			if (V.cockFeeder === 1) {
-				cockFeeder(slave);
-			}
-			if (V.revealFoodEffects === 1) {
-				slaveFoodEffects(slave);
-			}
+		if (V.cockFeeder === 1) {
+			cockFeeder(slave);
+		}
+		if (V.revealFoodEffects === 1) {
+			slaveFoodEffects(slave);
 		}
-
-		return r.join(" ");
 	}
 
+	return r.join(" ");
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
 	 */
 	function feederUsed(slave) {
 		if (slave.diet !== "healthy") {
@@ -71,1338 +50,1381 @@ App.SlaveAssignment.diet = (function() {
 	}
 
 	/**
-	 * @param {FC.ReportSlave} slave
-	 *
+	 * @param {App.Entity.SlaveState} slave
 	 */
-	function foodEffects(slave) {
-		let weightShift;
-		let superFetKnown;
+	function cumIncreasesCumslut(slave) {
+		if (slave.fetishStrength < 95) {
+			if (slave.dietCum === 2) {
+				r.push(`The high concentration of cum in ${his} food <span class="fetish inc">further`);
+				if (slave.fetishStrength < 60) {
+					r.push(`habituates`);
+				} else {
+					r.push(`endears`);
+				}
+				r.push(`${him} to the taste.</span>`);
+				slave.fetishStrength += 2;
+			} else if (slave.dietCum === 1) {
+				r.push(`Having cum added to ${his} food makes ${him}`);
+				if (slave.fetishStrength < 60) {
+					r.push(`<span class="fetish inc">even more used to the taste of it.</span>`);
+				} else {
+					r.push(`<span class="fetish inc">love the taste of it even more.</span>`);
+				}
+				slave.fetishStrength += 1;
+			}
+		}
+	}
 
-		switch (slave.diet) {
-			case "restricted": // weight loss
-				weightLoss = 5;
-				if (slave.fuckdoll > 0) {
-					r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s being <span class="change positive">slimmed down.</span>`);
-					if (slave.weightDirection === -1) {
-						slave.weight -= 12;
-					} else if (slave.weightDirection === 1) {
-						slave.weight -= 6;
+	/**
+	 * Weight loss
+	 * @param {FC.ReportSlave} slave
+	 */
+	function restrictedDiet(slave) {
+		let weightLoss = 5;
+		if (slave.fuckdoll > 0) {
+			r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s being <span class="change positive">slimmed down.</span>`);
+			if (slave.weightDirection === -1) {
+				slave.weight -= 12;
+			} else if (slave.weightDirection === 1) {
+				slave.weight -= 6;
+			} else {
+				slave.weight -= 9;
+			}
+		} else {
+			if (slave.fetish !== "mindbroken") {
+				if (slave.behavioralFlaw === "anorexic") {
+					if (slave.devotion >= -20) {
+						r.push(`As an anorexic, <span class="devotion inc">${he} derives perverse enjoyment from being underfed.</span>`);
+						slave.devotion += 1;
 					} else {
-						slave.weight -= 9;
-					}
-				} else {
-					if (slave.fetish !== "mindbroken") {
-						if (slave.behavioralFlaw === "anorexic") {
-							if (slave.devotion >= -20) {
-								r.push(`As an anorexic, <span class="devotion inc">${he} derives perverse enjoyment from being underfed.</span>`);
-								slave.devotion += 1;
-							} else {
-								r.push(`As an anorexic, ${he} accepts being underfed.`);
-							}
-						} else if (slave.behavioralFlaw === "gluttonous") {
-							r.push(`As a stress glutton, <span class="trust dec">being underfed makes ${him} terribly anxious.</span>`);
-							slave.trust -= 5;
-						} else if (slave.behavioralQuirk === "fitness") {
-							r.push(`As a fitness fanatic, <span class="devotion inc">${he} enjoys slimming down.</span>`);
-							slave.devotion += 1;
-						} else if (slave.devotion <= 20) {
-							r.push(`<span class="devotion dec">${He} resents being underfed.</span>`);
-							slave.devotion -= 4;
-						}
-						if (slave.devotion <= 20) {
-							if (slave.dietCum > 0) {
-								if (slave.sexualFlaw !== "cum addict") {
-									if (slave.fetish !== "cumslut") {
-										if (slave.dietCum === 2) {
-											if (V.cockFeeder === 0) {
-												if (random(1, 100) > 50) {
-													r.push(`${His} <span class="devotion dec">disgusting diet</span> is little more than human ejaculate infused with nutritional supplements, and ${he}'s unable to hold most of it down.`);
-													weightLoss = 8;
-													slave.devotion -= 4;
-												} else {
-													r.push(`Despite ${his} food being filled with large amounts of thick, human ejaculate, ${he} manages to choke down enough that ${he} doesn't get sick from malnourishment.`);
-													weightLoss = 6;
-													slave.devotion -= 2;
-												}
-											} else {
-												r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, helping ${him} get ${his} prescribed servings so that ${his} weight loss is safe and consistent. However, the unmistakable taste of cum ${he} burps up afterward <span class="devotion dec">nauseates</span> and <span class="trust dec">unnerves</span> ${him}.`);
-												weightLoss = 5;
-												slave.devotion -= 3;
-												slave.trust -= 1;
-											}
-										} else if (slave.dietCum === 1) {
-											if (V.cockFeeder === 0) {
-												if (random(1, 100) < 20) {
-													r.push(`${He} is <span class="devotion dec">troubled</span> by the use of human ejaculate as a food additive, and ${he} has a problem keeping all of ${his} food down.`);
-													weightLoss = 7;
-													slave.devotion -= 2;
-												} else {
-													r.push(`Despite having human ejaculate added to ${his} food, ${he} manages to choke it down this week, <span class="devotion dec">but it's a struggle.</span>`);
-													weightLoss = 5;
-													slave.devotion -= 2;
-												}
-											} else {
-												r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, helping ${him} get ${his} prescribed servings so that ${his} weight loss is safe and consistent. However, the thought of being force-fed food with ejaculate in it <span class="devotion dec">disturbs ${him}.</span>`);
-												weightLoss = 5;
-												slave.devotion -= 3;
-											}
-										}
-									} else {
-										r.push(`${He}`);
-										if (slave.fetishKnown === 0) {
-											r.push(`clearly <span class="fetish gain">obviously likes cum,</span>`);
-											slave.fetishKnown = 1;
-										} else if (slave.fetishStrength < 20) {
-											r.push(`is developing a taste for cum,`);
-										} else if (slave.fetishStrength < 60) {
-											r.push(`is used to eating cum,`);
+						r.push(`As an anorexic, ${he} accepts being underfed.`);
+					}
+				} else if (slave.behavioralFlaw === "gluttonous") {
+					r.push(`As a stress glutton, <span class="trust dec">being underfed makes ${him} terribly anxious.</span>`);
+					slave.trust -= 5;
+				} else if (slave.behavioralQuirk === "fitness") {
+					r.push(`As a fitness fanatic, <span class="devotion inc">${he} enjoys slimming down.</span>`);
+					slave.devotion += 1;
+				} else if (slave.devotion <= 20) {
+					r.push(`<span class="devotion dec">${He} resents being underfed.</span>`);
+					slave.devotion -= 4;
+				}
+				if (slave.devotion <= 20) {
+					if (slave.dietCum > 0) {
+						if (slave.sexualFlaw !== "cum addict") {
+							if (slave.fetish !== "cumslut") {
+								if (slave.dietCum === 2) {
+									if (V.cockFeeder === 0) {
+										if (random(1, 100) > 50) {
+											r.push(`${His} <span class="devotion dec">disgusting diet</span> is little more than human ejaculate infused with nutritional supplements, and ${he}'s unable to hold most of it down.`);
+											weightLoss = 8;
+											slave.devotion -= 4;
 										} else {
-											r.push(`loves eating cum,`);
-										}
-										r.push(`so ${he}`);
-										if (slave.behavioralFlaw === "gluttonous") {
-											r.push(`desperately`);
+											r.push(`Despite ${his} food being filled with large amounts of thick, human ejaculate, ${he} manages to choke down enough that ${he} doesn't get sick from malnourishment.`);
+											weightLoss = 6;
+											slave.devotion -= 2;
 										}
-										r.push(`sucks down every drop of the`);
-										if (slave.dietCum === 2) {
-											r.push(`nutritionally supplemented human ejaculate`);
+									} else {
+										r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, helping ${him} get ${his} prescribed servings so that ${his} weight loss is safe and consistent. However, the unmistakable taste of cum ${he} burps up afterward <span class="devotion dec">nauseates</span> and <span class="trust dec">unnerves</span> ${him}.`);
+										weightLoss = 5;
+										slave.devotion -= 3;
+										slave.trust -= 1;
+									}
+								} else if (slave.dietCum === 1) {
+									if (V.cockFeeder === 0) {
+										if (random(1, 100) < 20) {
+											r.push(`${He} is <span class="devotion dec">troubled</span> by the use of human ejaculate as a food additive, and ${he} has a problem keeping all of ${his} food down.`);
+											weightLoss = 7;
+											slave.devotion -= 2;
 										} else {
-											r.push(`cum supplemented food`);
-										}
-										r.push(`${he}'s given to eat, especially because ${his} servings are small.`);
-										if (slave.fetishStrength < 95) {
-											if (slave.dietCum === 2) {
-												r.push(`The high concentration of cum in ${his} food <span class="fetish inc">further`);
-												if (slave.fetishStrength < 60) {
-													r.push(`habituates`);
-												} else {
-													r.push(`endears`);
-												}
-												r.push(`${him} to the taste.</span>`);
-												slave.fetishStrength += 2;
-											} else if (slave.dietCum === 1) {
-												r.push(`Having cum added to ${his} food makes ${him}`);
-												if (slave.fetishStrength < 60) {
-													r.push(`<span class="fetish inc">even more used to the taste of it.</span>`);
-												} else {
-													r.push(`<span class="fetish inc">love the taste of it even more.</span>`);
-												}
-												slave.fetishStrength += 1;
-											}
+											r.push(`Despite having human ejaculate added to ${his} food, ${he} manages to choke it down this week, <span class="devotion dec">but it's a struggle.</span>`);
+											weightLoss = 5;
+											slave.devotion -= 2;
 										}
+									} else {
+										r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, helping ${him} get ${his} prescribed servings so that ${his} weight loss is safe and consistent. However, the thought of being force-fed food with ejaculate in it <span class="devotion dec">disturbs ${him}.</span>`);
+										weightLoss = 5;
+										slave.devotion -= 3;
 									}
 								}
-							}
-						} else { // For Devotion Higher than 20
-							if (slave.sexualFlaw === "cum addict") {
+							} else {
+								r.push(`${He}`);
+								if (slave.fetishKnown === 0) {
+									r.push(`clearly <span class="fetish gain">obviously likes cum,</span>`);
+									slave.fetishKnown = 1;
+								} else if (slave.fetishStrength < 20) {
+									r.push(`is developing a taste for cum,`);
+								} else if (slave.fetishStrength < 60) {
+									r.push(`is used to eating cum,`);
+								} else {
+									r.push(`loves eating cum,`);
+								}
+								r.push(`so ${he}`);
+								if (slave.behavioralFlaw === "gluttonous") {
+									r.push(`desperately`);
+								}
+								r.push(`sucks down every drop of the`);
 								if (slave.dietCum === 2) {
-									if (slave.behavioralFlaw !== "anorexic") {
-										r.push(`Despite wanting more to eat, the`);
-									} else {
-										r.push(`The`);
-									}
-									r.push(`cum addict is relieved to have such high concentrations of cum in ${his} diet.`);
-								} else if (slave.dietCum === 1) {
-									r.push(`Although ${his} food is supplemented with ejaculate, ${he} is so addicted to cum that restricting the amount ${he} can eat <span class="devotion dec">upsets ${him}.</span>`);
-									slave.devotion -= 1;
+									r.push(`nutritionally supplemented human ejaculate`);
+								} else {
+									r.push(`cum supplemented food`);
 								}
+								r.push(`${he}'s given to eat, especially because ${his} servings are small.`);
+								cumIncreasesCumslut(slave);
 							}
 						}
 					}
-					if (weightLoss === 8) {
-						r.push(`${His} <span class="change positive">weight loss</span> this week is so dramatic as to be dangerous, and <span class="health dec">${his} health suffers because of it.</span> <span class="trust dec">Your disregard for ${his} well-being scares ${him}.</span>`);
-						healthDamage(slave, 4);
-						slave.trust -= 2;
-					} else if (weightLoss === 7) {
-						r.push(`Distaste for ${his} food caused ${him} to <span class="change positive">lose weight</span> a bit too quickly, and by the end of the week ${he} looks <span class="trust dec">a little unsettled</span> and <span class="health dec">slightly malnourished.</span>`);
-						healthDamage(slave, 1);
-						slave.trust -= 1;
-					} else if (weightLoss === 6) {
-						r.push(`Due to ${his} distaste for ${his} diet, ${he} <span class="change positive">loses a bit more weight than ${he} was supposed to this week,</span> making ${him} <span class="trust dec">a little anxious.</span>`);
-						slave.trust -= 1;
-					} else if (weightLoss === 5) {
-						r.push(`${He} <span class="change positive">loses weight.</span>`);
-					}
-					weightLoss += V.feeder * 2;
-					if (slave.weightDirection === -1) {
-						slave.weight -= (weightLoss + 3);
-					} else if (slave.weightDirection === 1) {
-						slave.weight -= (weightLoss - 3) - (V.feeder);
-					} else {
-						slave.weight -= weightLoss;
-					}
-				}
-				slave.weight = Math.max(slave.weight, -100);
-				if (slave.hormoneBalance > 30 && slave.geneMods.NCS !== 0) { // 'Expected' breast size based on weight for feminine-bodied slaves
-					growthGoal = Math.trunc((100 + ((slave.weight + 100) * 5) + (2 * slave.lactationAdaptation)) * (0.85 + (slave.hormoneBalance / 400)) * gigantomastiaMod);
-					roll = 300;
-					target = Math.trunc(Math.clamp((weightLoss * 20) + (boobSize - growthGoal) / 5, 0, 270));
-				} else { // For masculine and childish-bodied slaves
-					growthGoal = ((slave.weight + 100) * 2 + slave.lactationAdaptation) * gigantomastiaMod;
-					roll = 75;
-					target = Math.trunc(Math.clamp(weightLoss * 2 + (boobSize - growthGoal) / 20, 0, 68));
-				}
-				if (random(1, roll) <= target && (gigantomastiaMod !== 3 && boobSize >= 100)) {
-					if (random(1, 2) === 1) {
-						r.push(`<span class="change negative">${His} breasts get smaller.</span>`);
-						slave.boobs -= 100;
-					} else {
-						r.push(`<span class="change negative">${His} breasts get a little smaller.</span>`);
-						slave.boobs -= 50 * (1 + slave.geneMods.NCS);
+				} else { // For Devotion Higher than 20
+					if (slave.sexualFlaw === "cum addict") {
+						if (slave.dietCum === 2) {
+							if (slave.behavioralFlaw !== "anorexic") {
+								r.push(`Despite wanting more to eat, the`);
+							} else {
+								r.push(`The`);
+							}
+							r.push(`cum addict is relieved to have such high concentrations of cum in ${his} diet.`);
+						} else if (slave.dietCum === 1) {
+							r.push(`Although ${his} food is supplemented with ejaculate, ${he} is so addicted to cum that restricting the amount ${he} can eat <span class="devotion dec">upsets ${him}.</span>`);
+							slave.devotion -= 1;
+						}
 					}
 				}
-				if (slave.hormoneBalance > 30) { // 'Expected' butt size based on weight for feminine-bodied slaves, scaled up by 1000
-					growthGoal = Math.trunc((slave.weight + 100) * 25 * (0.9 + slave.hormoneBalance / 600) * (rearQuirk / 2 + 1));
-					roll = 40000;
-					target = Math.trunc(Math.clamp(weightLoss * 1000 + (buttSize * 1000 - growthGoal) * 2, 0, 36000));
-				} else { // For masculine- and childish-bodied slaves, likewise scaled up
-					growthGoal = Math.trunc((slave.weight + 100) * 12.5) * (rearQuirk / 2 + 1);
-					roll = 80000;
-					target = Math.trunc(Math.clamp(weightLoss * 1000 + (buttSize * 1000 - growthGoal) * 4, 0, 72000));
-				}
-				if (random(1, roll) <= target && buttSize > 0) {
-					if (slave.geneMods.NCS === 1 && buttSize > 2) {
-						r.push(`<span class="change negative">${His} butt gets smaller.</span>`);
-						slave.butt -= 2;
+			}
+			if (weightLoss === 8) {
+				r.push(`${His} <span class="change positive">weight loss</span> this week is so dramatic as to be dangerous, and <span class="health dec">${his} health suffers because of it.</span> <span class="trust dec">Your disregard for ${his} well-being scares ${him}.</span>`);
+				healthDamage(slave, 4);
+				slave.trust -= 2;
+			} else if (weightLoss === 7) {
+				r.push(`Distaste for ${his} food caused ${him} to <span class="change positive">lose weight</span> a bit too quickly, and by the end of the week ${he} looks <span class="trust dec">a little unsettled</span> and <span class="health dec">slightly malnourished.</span>`);
+				healthDamage(slave, 1);
+				slave.trust -= 1;
+			} else if (weightLoss === 6) {
+				r.push(`Due to ${his} distaste for ${his} diet, ${he} <span class="change positive">loses a bit more weight than ${he} was supposed to this week,</span> making ${him} <span class="trust dec">a little anxious.</span>`);
+				slave.trust -= 1;
+			} else if (weightLoss === 5) {
+				r.push(`${He} <span class="change positive">loses weight.</span>`);
+			}
+			weightLoss += V.feeder * 2;
+			if (slave.weightDirection === -1) {
+				slave.weight -= (weightLoss + 3);
+			} else if (slave.weightDirection === 1) {
+				slave.weight -= (weightLoss - 3) - (V.feeder);
+			} else {
+				slave.weight -= weightLoss;
+			}
+		}
+		slave.weight = Math.max(slave.weight, -100);
+		if (slave.hormoneBalance > 30 && slave.geneMods.NCS !== 0) { // 'Expected' breast size based on weight for feminine-bodied slaves
+			growthGoal = Math.trunc((100 + ((slave.weight + 100) * 5) + (2 * slave.lactationAdaptation)) * (0.85 + (slave.hormoneBalance / 400)) * gigantomastiaMod);
+			roll = 300;
+			target = Math.trunc(Math.clamp((weightLoss * 20) + (boobSize - growthGoal) / 5, 0, 270));
+		} else { // For masculine and childish-bodied slaves
+			growthGoal = ((slave.weight + 100) * 2 + slave.lactationAdaptation) * gigantomastiaMod;
+			roll = 75;
+			target = Math.trunc(Math.clamp(weightLoss * 2 + (boobSize - growthGoal) / 20, 0, 68));
+		}
+		if (random(1, roll) <= target && (gigantomastiaMod !== 3 && boobSize >= 100)) {
+			if (random(1, 2) === 1) {
+				r.push(`<span class="change negative">${His} breasts get smaller.</span>`);
+				slave.boobs -= 100;
+			} else {
+				r.push(`<span class="change negative">${His} breasts get a little smaller.</span>`);
+				slave.boobs -= 50 * (1 + slave.geneMods.NCS);
+			}
+		}
+		if (slave.hormoneBalance > 30) { // 'Expected' butt size based on weight for feminine-bodied slaves, scaled up by 1000
+			growthGoal = Math.trunc((slave.weight + 100) * 25 * (0.9 + slave.hormoneBalance / 600) * (rearQuirk / 2 + 1));
+			roll = 40000;
+			target = Math.trunc(Math.clamp(weightLoss * 1000 + (buttSize * 1000 - growthGoal) * 2, 0, 36000));
+		} else { // For masculine- and childish-bodied slaves, likewise scaled up
+			growthGoal = Math.trunc((slave.weight + 100) * 12.5) * (rearQuirk / 2 + 1);
+			roll = 80000;
+			target = Math.trunc(Math.clamp(weightLoss * 1000 + (buttSize * 1000 - growthGoal) * 4, 0, 72000));
+		}
+		if (random(1, roll) <= target && buttSize > 0) {
+			if (slave.geneMods.NCS === 1 && buttSize > 2) {
+				r.push(`<span class="change negative">${His} butt gets smaller.</span>`);
+				slave.butt -= 2;
+			} else {
+				r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
+				slave.butt -= 1;
+			}
+		}
+		if (slave.weight < -95) {
+			r.push(`${He} is now quite skinny, so ${his} diet <span class="noteworthy">has defaulted to maintenance of this weight.</span>`);
+			slave.diet = "healthy";
+		}
+	}
+
+	/**
+	 * Weight gain
+	 * @param {FC.ReportSlave} slave
+	 */
+	function fatteningDiet(slave) {
+		weightGain = 5;
+		if (slave.fuckdoll > 0) {
+			r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s being <span class="change positive">fattened up.</span>`);
+			if (slave.weightDirection === 1) {
+				slave.weight += 12;
+			} else if (slave.weightDirection === -1) {
+				slave.weight += 6;
+			} else {
+				slave.weight += 9;
+			}
+			weightGainShared(slave);
+		} else {
+			if (slave.fetish !== "mindbroken") {
+				if (slave.behavioralFlaw === "anorexic") {
+					r.push(`Suffering from anorexia, <span class="devotion dec">${he} is intensely resentful of being overfed.</span>`);
+					slave.devotion -= 5;
+				} else if (slave.behavioralFlaw === "gluttonous") {
+					r.push(`As a glutton,`);
+					if (slave.devotion >= -20) {
+						r.push(`<span class="devotion inc">${he} derives almost sexual pleasure from being overfed.</span>`);
+						slave.devotion += 4;
 					} else {
-						r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
-						slave.butt -= 1;
+						r.push(`${he} accepts being overfed.`);
 					}
+				} else if (App.Data.Careers.General.grateful.includes(slave.career) && slave.weight < 100) {
+					r.push(`<span class="trust inc">${He} appreciates having a belly full of food.</span>`);
+					slave.trust += 1;
+				} else if (slave.devotion <= 20) {
+					r.push(`<span class="devotion dec">${He} resents being overfed.</span>`);
+					slave.devotion -= 4;
 				}
-				if (slave.weight < -95) {
-					r.push(`${He} is now quite skinny, so ${his} diet <span class="noteworthy">has defaulted to maintenance of this weight.</span>`);
-					slave.diet = "healthy";
-				}
-				break;
-			case "fattening": // weight gain
-				weightGain = 5;
-				if (slave.fuckdoll > 0) {
-					r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s being <span class="change positive">fattened up.</span>`);
-					if (slave.weightDirection === 1) {
-						slave.weight += 12;
-					} else if (slave.weightDirection === -1) {
-						slave.weight += 6;
-					} else {
-						slave.weight += 9;
-					}
-					weightGainShared(slave);
-				} else {
-					if (slave.fetish !== "mindbroken") {
-						if (slave.behavioralFlaw === "anorexic") {
-							r.push(`Suffering from anorexia, <span class="devotion dec">${he} is intensely resentful of being overfed.</span>`);
-							slave.devotion -= 5;
-						} else if (slave.behavioralFlaw === "gluttonous") {
-							r.push(`As a glutton,`);
-							if (slave.devotion >= -20) {
-								r.push(`<span class="devotion inc">${he} derives almost sexual pleasure from being overfed.</span>`);
-								slave.devotion += 4;
-							} else {
-								r.push(`${he} accepts being overfed.`);
-							}
-						} else if (App.Data.Careers.General.grateful.includes(slave.career) && slave.weight < 100) {
-							r.push(`<span class="trust inc">${He} appreciates having a belly full of food.</span>`);
-							slave.trust += 1;
-						} else if (slave.devotion <= 20) {
-							r.push(`<span class="devotion dec">${He} resents being overfed.</span>`);
-							slave.devotion -= 4;
-						}
-						if (slave.devotion <= 20) {
-							if (slave.dietCum > 0) {
-								if (slave.sexualFlaw !== "cum addict") {
-									if (slave.fetish !== "cumslut") {
-										if (slave.dietCum === 2) {
-											if (V.cockFeeder === 0) {
-												if (random(1, 100) > 50) {
-													r.push(`<span class="devotion dec">${He} is disgusted</span> that ${he} is forced to drink large amounts of human ejaculate for sustenance.`);
-													if (slave.sexualFlaw === "hates oral") {
-														r.push(`This is <span class="devotion dec">exacerbated</span> by ${his} hatred of oral sex.`);
-														slave.devotion -= 1;
-													}
-													r.push(`${He} has trouble holding ${his} food down.`);
-													weightGain = 0;
-													slave.devotion -= 4;
-												} else {
-													r.push(`Despite ${his} food being filled with large amounts of human ejaculate, ${he} manages to keep some of it down, but <span class="devotion dec">${he} hates you for it.</span>`);
-													weightGain = 2;
-													slave.devotion -= 2;
-												}
-											} else {
-												if (random(1, 100) < 30) {
-													r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, helping ${him} get the extra calories ${he}'s been prescribed, but the <span class="devotion dec">ejaculate based food is so heavy in ${his} tummy</span> that ${he} loses a tiny bit of ${his} intake to post-meal nausea.`);
-													weightGain = 4;
-													slave.devotion -= 4;
-												} else {
-													r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, ensuring that ${he} gets all of ${his} prescribed calories, and <span class="devotion dec">despite some intense nausea afterwards,</span> ${he}'s able to keep ${his} heavy cum diet down.`);
-													slave.devotion -= 4;
-												}
-											}
-										} else if (slave.dietCum === 1) {
-											if (V.cockFeeder === 0) {
-												if (random(1, 100) < 15) {
-													r.push(`${He} hates being forced to eat food that is supplemented with cum as ${his} primary source of`);
-													if (slave.sexualFlaw === "hates oral") {
-														r.push(`nourishment, and ${his} hatred of oral sex makes it even worse.`);
-													} else {
-														r.push(`nourishment.`);
-													}
-													r.push(`<span class="trust dec">${He} is so disgusted</span> that ${he} has trouble keeping most of ${his} food down.`);
-													weightGain = 0;
-													slave.devotion -= 4;
-												} else {
-													r.push(`Despite ${his} food`);
-													if (canTaste(slave)) {
-														r.push(`tasting`);
-													} else if (canSmell(slave)) {
-														r.push(`smelling`);
-													} else {
-														r.push(`reminding ${him}`);
-													}
-													r.push(`strongly of cum, ${he} manages to choke down most of it this week, <span class="devotion dec">but ${he} resents being a cum-fed whore.</span>`);
-													weightGain = 3;
-													slave.devotion -= 2;
-												}
-											} else {
-												r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, helping ${him} get ${his} prescribed calories, even though <span class="devotion dec">${he} hates the idea of being force-fed cum.</span>`);
-												slave.devotion -= 2;
+				if (slave.devotion <= 20) {
+					if (slave.dietCum > 0) {
+						if (slave.sexualFlaw !== "cum addict") {
+							if (slave.fetish !== "cumslut") {
+								if (slave.dietCum === 2) {
+									if (V.cockFeeder === 0) {
+										if (random(1, 100) > 50) {
+											r.push(`<span class="devotion dec">${He} is disgusted</span> that ${he} is forced to drink large amounts of human ejaculate for sustenance.`);
+											if (slave.sexualFlaw === "hates oral") {
+												r.push(`This is <span class="devotion dec">exacerbated</span> by ${his} hatred of oral sex.`);
+												slave.devotion -= 1;
 											}
+											r.push(`${He} has trouble holding ${his} food down.`);
+											weightGain = 0;
+											slave.devotion -= 4;
+										} else {
+											r.push(`Despite ${his} food being filled with large amounts of human ejaculate, ${he} manages to keep some of it down, but <span class="devotion dec">${he} hates you for it.</span>`);
+											weightGain = 2;
+											slave.devotion -= 2;
 										}
 									} else {
-										if (slave.behavioralFlaw === "anorexic") {
-											r.push(`Despite ${his} predilection to starve ${himself}, ${he}`);
+										if (random(1, 100) < 30) {
+											r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, helping ${him} get the extra calories ${he}'s been prescribed, but the <span class="devotion dec">ejaculate based food is so heavy in ${his} tummy</span> that ${he} loses a tiny bit of ${his} intake to post-meal nausea.`);
+											weightGain = 4;
+											slave.devotion -= 4;
 										} else {
-											r.push(`${He}`);
-										}
-										if (slave.fetishKnown === 0) {
-											r.push(`apparently <span class="fetish gain">enjoys the taste of cum</span> enough that ${he}`);
-											slave.fetishKnown = 1;
-										} else if (slave.fetishStrength > 60) {
-											r.push(`loves cum so much that ${he}`);
-										}
-										r.push(`can't help but suck down every drop of the nutrition infused human ejaculate ${he}'s given to eat.`);
-										if (slave.fetishStrength < 95) {
-											if (slave.dietCum === 2) {
-												r.push(`The high concentration of cum in ${his} food <span class="fetish inc">further`);
-												if (slave.fetishStrength < 60) {
-													r.push(`habituates`);
-												} else {
-													r.push(`endears`);
-												}
-												r.push(`${him} to the taste.</span>`);
-												slave.fetishStrength += 1;
-											} else if (slave.dietCum === 1) {
-												r.push(`Having cum added to ${his} food makes ${him}`);
-												if (slave.fetishStrength < 60) {
-													r.push(`<span class="fetish inc">even more used to the taste of it.</span>`);
-												} else {
-													r.push(`<span class="fetish inc">love the taste of it even more.</span>`);
-												}
-												slave.fetishStrength += 1;
-											}
+											r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, ensuring that ${he} gets all of ${his} prescribed calories, and <span class="devotion dec">despite some intense nausea afterwards,</span> ${he}'s able to keep ${his} heavy cum diet down.`);
+											slave.devotion -= 4;
 										}
 									}
-								} else {
-									if (slave.dietCum === 2) {
-										r.push(`${He} hates ${himself} for it, but the cum addict is <span class="devotion inc">grateful</span> to have so much ejaculate in ${his} diet, especially because ${he}'s given extra food this week.`);
-										slave.devotion += 1;
-									} else if (slave.dietCum === 1) {
-										r.push(`The cum addict <span class="trust dec">anxiously</span> slurps up every drop of ${his} cum-supplemented food this week. ${He} eats all the extra food ${he}'s given and is <span class="devotion inc">disturbed</span> by ${his} insatiable hunger for more.`);
-										slave.devotion -= 1;
-										slave.trust -= 1;
-									}
-								}
-							}
-							if (slave.dietMilk > 0) {
-								if (slave.sexualFlaw !== "breast growth") {
-									if (slave.fetish !== "pregnancy") {
-										if (slave.dietMilk === 2) {
-											if (V.cockFeeder === 0) {
-												r.push(`Despite ${his} food being based on huge quantities of breast milk, ${he} manages to keep most of it down, but <span class="devotion dec">${he} hates you for it.</span>`);
-												weightGain = 2;
-												slave.devotion -= 2;
+								} else if (slave.dietCum === 1) {
+									if (V.cockFeeder === 0) {
+										if (random(1, 100) < 15) {
+											r.push(`${He} hates being forced to eat food that is supplemented with cum as ${his} primary source of`);
+											if (slave.sexualFlaw === "hates oral") {
+												r.push(`nourishment, and ${his} hatred of oral sex makes it even worse.`);
 											} else {
-												r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, ensuring that ${he} gets all of ${his} prescribed calories, and <span class="devotion dec">despite some intense nausea afterwards,</span> ${he}'s able to keep ${his} heavy milk diet down.`);
-												slave.devotion -= 4;
+												r.push(`nourishment.`);
 											}
-										} else if (slave.dietMilk === 1) {
-											if (V.cockFeeder === 0) {
-												r.push(`Despite ${his} food`);
-												if (canTaste(slave)) {
-													r.push(`tasting`);
-												} else if (canSmell(slave)) {
-													r.push(`smelling`);
-												} else {
-													r.push(`reminding ${him}`);
-												}
-												r.push(`strongly of human breast milk, ${he} manages to choke down most of it this week, <span class="devotion dec">but ${he} resents being a milk-fed whore.</span>`);
-												weightGain = 3;
-												slave.devotion -= 2;
+											r.push(`<span class="trust dec">${He} is so disgusted</span> that ${he} has trouble keeping most of ${his} food down.`);
+											weightGain = 0;
+											slave.devotion -= 4;
+										} else {
+											r.push(`Despite ${his} food`);
+											if (canTaste(slave)) {
+												r.push(`tasting`);
+											} else if (canSmell(slave)) {
+												r.push(`smelling`);
 											} else {
-												r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, helping ${him} get ${his} prescribed calories, even though <span class="devotion dec">${he} hates the idea of being force-fed human milk.</span>`);
-												slave.devotion -= 2;
+												r.push(`reminding ${him}`);
 											}
+											r.push(`strongly of cum, ${he} manages to choke down most of it this week, <span class="devotion dec">but ${he} resents being a cum-fed whore.</span>`);
+											weightGain = 3;
+											slave.devotion -= 2;
 										}
 									} else {
-										if (slave.behavioralFlaw === "anorexic") {
-											r.push(`Despite ${his} predilection to starve ${himself}, ${he}`);
-										} else {
-											r.push(`${He}`);
-										}
-										if (slave.fetishKnown === 0) {
-											r.push(`apparently fetishizes some aspect of lactation enough that ${he}`);
-										} else if (slave.fetishStrength > 60) {
-											r.push(`loves breast milk so much that ${he}`);
-										}
-										r.push(`can't help but suck down every drop of the nutrition infused human milk ${he}'s given to eat.`);
-										if (slave.fetishStrength < 95 && slave.fetishKnown === 1) {
-											if (slave.dietMilk === 2) {
-												r.push(`The high concentration of milk in ${his} food <span class="fetish inc">further`);
-												if (slave.fetishStrength < 60) {
-													r.push(`habituates`);
-												} else {
-													r.push(`endears`);
-												}
-												r.push(`${him} to the corruption of normal pregnancy and motherhood.</span>`);
-												slave.fetishStrength += 1;
-											} else if (slave.dietMilk === 1) {
-												r.push(`Having milk added to ${his} food makes ${him}`);
-												if (slave.fetishStrength < 60) {
-													r.push(`<span class="fetish inc">accept perversion of normal pregnancy.</span>`);
-												} else {
-													r.push(`<span class="fetish inc">even hornier for anything related to pregnancy.</span>`);
-												}
-												slave.fetishStrength += 1;
-											}
-										}
+										r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, helping ${him} get ${his} prescribed calories, even though <span class="devotion dec">${he} hates the idea of being force-fed cum.</span>`);
+										slave.devotion -= 2;
 									}
+								}
+							} else {
+								if (slave.behavioralFlaw === "anorexic") {
+									r.push(`Despite ${his} predilection to starve ${himself}, ${he}`);
 								} else {
-									if (slave.dietMilk === 2) {
-										r.push(`${He} hates ${himself} for it, but the breast growth fanatic is <span class="devotion inc">grateful</span> to have so much mother's milk in ${his} diet, especially because ${he}'s given extra food this week.`);
-										slave.devotion += 1;
-									} else if (slave.dietMilk === 1) {
-										r.push(`The breast growth fanatic <span class="trust dec">anxiously</span> slurps up every drop of ${his} milk-supplemented food this week. ${He} eats all the extra food ${he}'s given and is <span class="devotion dec">disturbed</span> by ${his} insatiable hunger for more mother's milk.`);
-										slave.devotion -= 1;
-										slave.trust -= 1;
-									}
+									r.push(`${He}`);
 								}
+								if (slave.fetishKnown === 0) {
+									r.push(`apparently <span class="fetish gain">enjoys the taste of cum</span> enough that ${he}`);
+									slave.fetishKnown = 1;
+								} else if (slave.fetishStrength > 60) {
+									r.push(`loves cum so much that ${he}`);
+								}
+								r.push(`can't help but suck down every drop of the nutrition infused human ejaculate ${he}'s given to eat.`);
+								cumIncreasesCumslut(slave);
 							}
-						} else { // For Devotion Higher than 20 See Below for more diet effects for this condition
-							if (slave.sexualFlaw === "cum addict") {
-								if (slave.dietCum === 2) {
-									r.push(`${His} diet is almost pure human ejaculate with nutritional`);
-									if (slave.behavioralFlaw === "anorexic") {
-										r.push(`additives. Despite ${his} desire to remain thin, ${his} cum addiction is even more powerful.`);
+						} else {
+							if (slave.dietCum === 2) {
+								r.push(`${He} hates ${himself} for it, but the cum addict is <span class="devotion inc">grateful</span> to have so much ejaculate in ${his} diet, especially because ${he}'s given extra food this week.`);
+								slave.devotion += 1;
+							} else if (slave.dietCum === 1) {
+								r.push(`The cum addict <span class="trust dec">anxiously</span> slurps up every drop of ${his} cum-supplemented food this week. ${He} eats all the extra food ${he}'s given and is <span class="devotion inc">disturbed</span> by ${his} insatiable hunger for more.`);
+								slave.devotion -= 1;
+								slave.trust -= 1;
+							}
+						}
+					}
+					if (slave.dietMilk > 0) {
+						if (slave.sexualFlaw !== "breast growth") {
+							if (slave.fetish !== "pregnancy") {
+								if (slave.dietMilk === 2) {
+									if (V.cockFeeder === 0) {
+										r.push(`Despite ${his} food being based on huge quantities of breast milk, ${he} manages to keep most of it down, but <span class="devotion dec">${he} hates you for it.</span>`);
+										weightGain = 2;
+										slave.devotion -= 2;
 									} else {
-										r.push(`additives — the perfect food for a cum addict.`);
+										r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, ensuring that ${he} gets all of ${his} prescribed calories, and <span class="devotion dec">despite some intense nausea afterwards,</span> ${he}'s able to keep ${his} heavy milk diet down.`);
+										slave.devotion -= 4;
 									}
-									r.push(`${He} gets extra food this week. ${He} makes a sloppy mess at feeding time, getting cum all over ${himself}, and ${he} is unashamed of ${his} pathological need to be your cum-fed slut. <span class="devotion inc">${He}'s a happy little cum-piggy.</span> The only drawback is that some of ${his} food ends up on ${him}, rather than in ${him}.`);
-									slave.devotion += 3;
-									weightGain = 4;
-								} else if (slave.dietCum === 1) {
-									r.push(`${His} food is infused with ejaculate,`);
-									if (slave.behavioralFlaw === "anorexic") {
-										r.push(`and ${his} cum addiction trumps ${his} desire to remain thin. ${He}`);
+								} else if (slave.dietMilk === 1) {
+									if (V.cockFeeder === 0) {
+										r.push(`Despite ${his} food`);
+										if (canTaste(slave)) {
+											r.push(`tasting`);
+										} else if (canSmell(slave)) {
+											r.push(`smelling`);
+										} else {
+											r.push(`reminding ${him}`);
+										}
+										r.push(`strongly of human breast milk, ${he} manages to choke down most of it this week, <span class="devotion dec">but ${he} resents being a milk-fed whore.</span>`);
+										weightGain = 3;
+										slave.devotion -= 2;
 									} else {
-										r.push(`${he}`);
+										r.push(`The phallic feeders inject ${his} food directly into ${his} stomach, helping ${him} get ${his} prescribed calories, even though <span class="devotion dec">${he} hates the idea of being force-fed human milk.</span>`);
+										slave.devotion -= 2;
 									}
-									r.push(`is <span class="devotion inc">thrilled to get extra this week.</span> ${He} gobbles down every last drop like the happy`);
-									if (slave.weight < 0) {
-										r.push(`little`);
-									} else {
-										r.push(`chubby`);
+								}
+							} else {
+								if (slave.behavioralFlaw === "anorexic") {
+									r.push(`Despite ${his} predilection to starve ${himself}, ${he}`);
+								} else {
+									r.push(`${He}`);
+								}
+								if (slave.fetishKnown === 0) {
+									r.push(`apparently fetishizes some aspect of lactation enough that ${he}`);
+								} else if (slave.fetishStrength > 60) {
+									r.push(`loves breast milk so much that ${he}`);
+								}
+								r.push(`can't help but suck down every drop of the nutrition infused human milk ${he}'s given to eat.`);
+								if (slave.fetishStrength < 95 && slave.fetishKnown === 1) {
+									if (slave.dietMilk === 2) {
+										r.push(`The high concentration of milk in ${his} food <span class="fetish inc">further`);
+										if (slave.fetishStrength < 60) {
+											r.push(`habituates`);
+										} else {
+											r.push(`endears`);
+										}
+										r.push(`${him} to the corruption of normal pregnancy and motherhood.</span>`);
+										slave.fetishStrength += 1;
+									} else if (slave.dietMilk === 1) {
+										r.push(`Having milk added to ${his} food makes ${him}`);
+										if (slave.fetishStrength < 60) {
+											r.push(`<span class="fetish inc">accept perversion of normal pregnancy.</span>`);
+										} else {
+											r.push(`<span class="fetish inc">even hornier for anything related to pregnancy.</span>`);
+										}
+										slave.fetishStrength += 1;
 									}
-									r.push(`cum addict ${he} is.`);
-									slave.devotion += 2;
 								}
 							}
-						}
-					}
-					if (weightGain > 0) {
-						if (weightGain === 5) {
-							r.push(`${He} gains weight.`);
-						} else if (weightGain >= 3) {
-							r.push(`${He} gains some weight.`);
-						} else if (weightGain >= 1) {
-							r.push(`${He} gains a little weight, but ${his} progress was severely limited by what ${he} was forced to eat, <span class="trust dec">making for an anxious week for ${him}.</span>`);
-							slave.trust -= 1;
-						}
-						weightGain += V.feeder * 2;
-						if (slave.weightDirection === -1) {
-							slave.weight += Math.max((weightGain - 3) - (V.feeder), 1);
-						} else if (slave.weightDirection === 1) {
-							slave.weight += weightGain + 3;
 						} else {
-							slave.weight += weightGain;
+							if (slave.dietMilk === 2) {
+								r.push(`${He} hates ${himself} for it, but the breast growth fanatic is <span class="devotion inc">grateful</span> to have so much mother's milk in ${his} diet, especially because ${he}'s given extra food this week.`);
+								slave.devotion += 1;
+							} else if (slave.dietMilk === 1) {
+								r.push(`The breast growth fanatic <span class="trust dec">anxiously</span> slurps up every drop of ${his} milk-supplemented food this week. ${He} eats all the extra food ${he}'s given and is <span class="devotion dec">disturbed</span> by ${his} insatiable hunger for more mother's milk.`);
+								slave.devotion -= 1;
+								slave.trust -= 1;
+							}
 						}
-						weightGainShared(slave);
-						if (slave.geneticQuirks.galactorrhea === 2 && random(1, 100) < slave.hormoneBalance && slave.lactation === 0) {
-							slave.inappropriateLactation = 1;
+					}
+				} else { // For Devotion Higher than 20 See Below for more diet effects for this condition
+					if (slave.sexualFlaw === "cum addict") {
+						if (slave.dietCum === 2) {
+							r.push(`${His} diet is almost pure human ejaculate with nutritional`);
+							if (slave.behavioralFlaw === "anorexic") {
+								r.push(`additives. Despite ${his} desire to remain thin, ${his} cum addiction is even more powerful.`);
+							} else {
+								r.push(`additives — the perfect food for a cum addict.`);
+							}
+							r.push(`${He} gets extra food this week. ${He} makes a sloppy mess at feeding time, getting cum all over ${himself}, and ${he} is unashamed of ${his} pathological need to be your cum-fed slut. <span class="devotion inc">${He}'s a happy little cum-piggy.</span> The only drawback is that some of ${his} food ends up on ${him}, rather than in ${him}.`);
+							slave.devotion += 3;
+							weightGain = 4;
+						} else if (slave.dietCum === 1) {
+							r.push(`${His} food is infused with ejaculate,`);
+							if (slave.behavioralFlaw === "anorexic") {
+								r.push(`and ${his} cum addiction trumps ${his} desire to remain thin. ${He}`);
+							} else {
+								r.push(`${he}`);
+							}
+							r.push(`is <span class="devotion inc">thrilled to get extra this week.</span> ${He} gobbles down every last drop like the happy`);
+							if (slave.weight < 0) {
+								r.push(`little`);
+							} else {
+								r.push(`chubby`);
+							}
+							r.push(`cum addict ${he} is.`);
+							slave.devotion += 2;
 						}
-					} else if (slave.weightDirection === 1) {
-						r.push(`${He} gains a little weight this week despite ${his} dietary troubles.`);
-						slave.weight += 1;
-					} else {
-						r.push(`${He} doesn't gain any weight this week.`);
 					}
 				}
-				slave.weight = Math.min(slave.weight, 200);
-				break;
-			case "corrective": // normalizes weight towards 0
-				weightShift = 0;
-				if (slave.weight < -10) {
-					weightShift = V.feeder + 1;
-					r.push(`By carefully adjusting ${his} intake, ${he} slowly puts on weight without realizing it.`);
-				} else if (slave.weight > 10) {
-					weightShift = -(V.feeder + 1);
-					r.push(`By carefully adjusting ${his} intake, ${he} slowly loses on weight without realizing it.`);
+			}
+			if (weightGain > 0) {
+				if (weightGain === 5) {
+					r.push(`${He} gains weight.`);
+				} else if (weightGain >= 3) {
+					r.push(`${He} gains some weight.`);
+				} else if (weightGain >= 1) {
+					r.push(`${He} gains a little weight, but ${his} progress was severely limited by what ${he} was forced to eat, <span class="trust dec">making for an anxious week for ${him}.</span>`);
+					slave.trust -= 1;
 				}
+				weightGain += V.feeder * 2;
 				if (slave.weightDirection === -1) {
-					slave.weight += (weightShift - random(0, 1));
+					slave.weight += Math.max((weightGain - 3) - (V.feeder), 1);
 				} else if (slave.weightDirection === 1) {
-					slave.weight += (weightShift + random(0, 1));
+					slave.weight += weightGain + 3;
 				} else {
-					slave.weight += weightShift;
-				}
-				if (weightShift < 0) {
-					if (slave.hormoneBalance > 30 && slave.geneMods.NCS !== 0) { // 'Expected' breast size based on weight for feminine-bodied slaves
-						growthGoal = Math.trunc((100 + (slave.weight + 100) * 5 + 2 * slave.lactationAdaptation) * (0.85 + slave.hormoneBalance / 400) * gigantomastiaMod);
-						roll = 600;
-						target = Math.trunc(Math.clamp(weightShift * 20 + (boobSize - growthGoal) / 5, 0, 270));
-					} else { // For masculine- and childish-bodied slaves
-						growthGoal = ((slave.weight + 100) * 2 + slave.lactationAdaptation) * gigantomastiaMod;
-						roll = 200;
-						target = Math.trunc(Math.clamp(weightShift * 2 + (boobSize - growthGoal) / 20, 0, 68));
-					}
-					if (random(1, roll) <= target && gigantomastiaMod !== 3 && boobSize >= 100) {
-						if (random(1, 2) === 1) {
-							r.push(`<span class="change negative">${His} breasts get smaller.</span>`);
-							slave.boobs -= 20;
-						} else {
-							r.push(`<span class="change negative">${His} breasts get a little smaller.</span>`);
-							slave.boobs -= 10 * (1 + slave.geneMods.NCS);
-						}
-					}
-					if (slave.hormoneBalance > 30) { // 'Expected' butt size based on weight for feminine-bodied slaves, scaled up by 1000 */
-						growthGoal = Math.trunc((slave.weight + 100) * 25 * (0.9 + slave.hormoneBalance / 600) * (rearQuirk / 2 + 1));
-						roll = 60000;
-						target = Math.trunc(Math.clamp(weightShift * 1000 + (buttSize * 1000 - growthGoal) * 2, 0, 36000));
-					} else { // For masculine- and childish-bodied slaves, likewise scaled up
-						growthGoal = Math.trunc((slave.weight + 100) * 12.5) * (rearQuirk / 2 + 1);
-						roll = 100000;
-						target = Math.trunc(Math.clamp(weightShift * 1000 + (buttSize * 1000 - growthGoal) * 4, 0, 72000));
-					}
-					if (random(1, roll) <= target && buttSize > 0) {
-						r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
-						slave.butt -= 1;
-						// FIXME: identical branches
-						// if (slave.geneMods.NCS === 1 && buttSize > 2) {
-						// 	r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
-						// 	slave.butt -= 1;
-						// } else {
-						// 	// TODO: write this
-						// 	r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
-						// 	slave.butt -= 1;
-						// }
-					}
-				} else if (weightShift > 0) {
-					if (slave.hormoneBalance > 30 && slave.geneMods.NCS !== 1) { // 'Expected' breast size based on weight for feminine-bodied slaves */
-						growthGoal = Math.trunc((100 + (slave.weight + 100) * 5 + 2 * slave.lactationAdaptation) * (0.85 + slave.hormoneBalance / 400) * gigantomastiaMod);
-						roll = 600;
-						target = Math.trunc(Math.clamp(weightShift * 20 - (boobSize - growthGoal) / 5, 0, 270));
-					} else { // For masculine- and childish-bodied slaves */
-						growthGoal = ((slave.weight + 100) * 2 + slave.lactationAdaptation) * gigantomastiaMod;
-						roll = 200;
-						target = Math.trunc(Math.clamp(weightShift * 2 - (boobSize - growthGoal) / 20, 0, 68));
-					}
-					if (slave.geneMods.NCS === 1) {
-						roll *= 2;
-					}
-					if (random(1, roll) <= target) {
-						if (random(1, 2) === 1) {
-							r.push(`<span class="change positive">${His} breasts get bigger.</span>`);
-							slave.boobs += 40 / (1 + slave.geneMods.NCS);
-						} else {
-							r.push(`<span class="change positive">${His} breasts get a little bigger.</span>`);
-							slave.boobs += 20 / (1 + slave.geneMods.NCS);
-						}
-					}
-					if (slave.hormoneBalance > 30) { // 'Expected' butt size based on weight for feminine-bodied slaves, scaled up by 1000
-						growthGoal = Math.trunc((slave.weight + 100) * 25 * (0.9 + slave.hormoneBalance / 600) * (rearQuirk / 2 + 1));
-						roll = 60000;
-						target = Math.trunc(Math.clamp(weightShift * 1000 - (buttSize * 1000 - growthGoal) * 2, 0, 36000));
-					} else { // For masculine- and childish-bodied slaves, likewise scaled up
-						growthGoal = Math.trunc((slave.weight + 100) * 12.5) * (rearQuirk / 2 + 1);
-						roll = 100000;
-						target = Math.trunc(Math.clamp(weightShift * 1000 - (buttSize * 1000 - growthGoal) * 4, 0, 72000));
-					}
-					if (slave.geneMods.NCS === 1) {
-						roll *= 2;
-					}
-					if (random(1, roll) <= target) {
-						r.push(`<span class="change positive">${His} butt gets a little bigger.</span>`);
-						slave.butt += 1;
-					}
+					slave.weight += weightGain;
 				}
-				if (slave.weight >= -10 && slave.weight <= 10) {
-					r.push(`${He} is now a healthy weight, so ${his} diet <span class="noteworthy">has defaulted to keeping it this way.</span>`);
-					slave.diet = "healthy";
+				weightGainShared(slave);
+				if (slave.geneticQuirks.galactorrhea === 2 && random(1, 100) < slave.hormoneBalance && slave.lactation === 0) {
+					slave.inappropriateLactation = 1;
 				}
-				break;
-			case "muscle building": // Muscle Gain
-				if (slave.fuckdoll > 0) {
-					r.push(`Fuckdoll suits can force their inhabitants to`);
-					if (hasAnyArms(slave)) {
-						r.push(`lift weights`);
+			} else if (slave.weightDirection === 1) {
+				r.push(`${He} gains a little weight this week despite ${his} dietary troubles.`);
+				slave.weight += 1;
+			} else {
+				r.push(`${He} doesn't gain any weight this week.`);
+			}
+		}
+		slave.weight = Math.min(slave.weight, 200);
+	}
+
+	/**
+	 * Normalize weight towards 0
+	 * @param {FC.ReportSlave} slave
+	 */
+	function correctiveDiet(slave) {
+		let weightShift = 0;
+		if (slave.weight < -10) {
+			weightShift = V.feeder + 1;
+			r.push(`By carefully adjusting ${his} intake, ${he} slowly puts on weight without realizing it.`);
+		} else if (slave.weight > 10) {
+			weightShift = -(V.feeder + 1);
+			r.push(`By carefully adjusting ${his} intake, ${he} slowly loses on weight without realizing it.`);
+		}
+		if (slave.weightDirection === -1) {
+			slave.weight += (weightShift - random(0, 1));
+		} else if (slave.weightDirection === 1) {
+			slave.weight += (weightShift + random(0, 1));
+		} else {
+			slave.weight += weightShift;
+		}
+		if (weightShift < 0) {
+			if (slave.hormoneBalance > 30 && slave.geneMods.NCS !== 0) { // 'Expected' breast size based on weight for feminine-bodied slaves
+				growthGoal = Math.trunc((100 + (slave.weight + 100) * 5 + 2 * slave.lactationAdaptation) * (0.85 + slave.hormoneBalance / 400) * gigantomastiaMod);
+				roll = 600;
+				target = Math.trunc(Math.clamp(weightShift * 20 + (boobSize - growthGoal) / 5, 0, 270));
+			} else { // For masculine- and childish-bodied slaves
+				growthGoal = ((slave.weight + 100) * 2 + slave.lactationAdaptation) * gigantomastiaMod;
+				roll = 200;
+				target = Math.trunc(Math.clamp(weightShift * 2 + (boobSize - growthGoal) / 20, 0, 68));
+			}
+			if (random(1, roll) <= target && gigantomastiaMod !== 3 && boobSize >= 100) {
+				if (random(1, 2) === 1) {
+					r.push(`<span class="change negative">${His} breasts get smaller.</span>`);
+					slave.boobs -= 20;
+				} else {
+					r.push(`<span class="change negative">${His} breasts get a little smaller.</span>`);
+					slave.boobs -= 10 * (1 + slave.geneMods.NCS);
+				}
+			}
+			if (slave.hormoneBalance > 30) { // 'Expected' butt size based on weight for feminine-bodied slaves, scaled up by 1000 */
+				growthGoal = Math.trunc((slave.weight + 100) * 25 * (0.9 + slave.hormoneBalance / 600) * (rearQuirk / 2 + 1));
+				roll = 60000;
+				target = Math.trunc(Math.clamp(weightShift * 1000 + (buttSize * 1000 - growthGoal) * 2, 0, 36000));
+			} else { // For masculine- and childish-bodied slaves, likewise scaled up
+				growthGoal = Math.trunc((slave.weight + 100) * 12.5) * (rearQuirk / 2 + 1);
+				roll = 100000;
+				target = Math.trunc(Math.clamp(weightShift * 1000 + (buttSize * 1000 - growthGoal) * 4, 0, 72000));
+			}
+			if (random(1, roll) <= target && buttSize > 0) {
+				r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
+				slave.butt -= 1;
+				// FIXME: identical branches
+				// if (slave.geneMods.NCS === 1 && buttSize > 2) {
+				// 	r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
+				// 	slave.butt -= 1;
+				// } else {
+				// 	// TODO: write this
+				// 	r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
+				// 	slave.butt -= 1;
+				// }
+			}
+		} else if (weightShift > 0) {
+			if (slave.hormoneBalance > 30 && slave.geneMods.NCS !== 1) { // 'Expected' breast size based on weight for feminine-bodied slaves */
+				growthGoal = Math.trunc((100 + (slave.weight + 100) * 5 + 2 * slave.lactationAdaptation) * (0.85 + slave.hormoneBalance / 400) * gigantomastiaMod);
+				roll = 600;
+				target = Math.trunc(Math.clamp(weightShift * 20 - (boobSize - growthGoal) / 5, 0, 270));
+			} else { // For masculine- and childish-bodied slaves */
+				growthGoal = ((slave.weight + 100) * 2 + slave.lactationAdaptation) * gigantomastiaMod;
+				roll = 200;
+				target = Math.trunc(Math.clamp(weightShift * 2 - (boobSize - growthGoal) / 20, 0, 68));
+			}
+			if (slave.geneMods.NCS === 1) {
+				roll *= 2;
+			}
+			if (random(1, roll) <= target) {
+				if (random(1, 2) === 1) {
+					r.push(`<span class="change positive">${His} breasts get bigger.</span>`);
+					slave.boobs += 40 / (1 + slave.geneMods.NCS);
+				} else {
+					r.push(`<span class="change positive">${His} breasts get a little bigger.</span>`);
+					slave.boobs += 20 / (1 + slave.geneMods.NCS);
+				}
+			}
+			if (slave.hormoneBalance > 30) { // 'Expected' butt size based on weight for feminine-bodied slaves, scaled up by 1000
+				growthGoal = Math.trunc((slave.weight + 100) * 25 * (0.9 + slave.hormoneBalance / 600) * (rearQuirk / 2 + 1));
+				roll = 60000;
+				target = Math.trunc(Math.clamp(weightShift * 1000 - (buttSize * 1000 - growthGoal) * 2, 0, 36000));
+			} else { // For masculine- and childish-bodied slaves, likewise scaled up
+				growthGoal = Math.trunc((slave.weight + 100) * 12.5) * (rearQuirk / 2 + 1);
+				roll = 100000;
+				target = Math.trunc(Math.clamp(weightShift * 1000 - (buttSize * 1000 - growthGoal) * 4, 0, 72000));
+			}
+			if (slave.geneMods.NCS === 1) {
+				roll *= 2;
+			}
+			if (random(1, roll) <= target) {
+				r.push(`<span class="change positive">${His} butt gets a little bigger.</span>`);
+				slave.butt += 1;
+			}
+		}
+		if (slave.weight >= -10 && slave.weight <= 10) {
+			r.push(`${He} is now a healthy weight, so ${his} diet <span class="noteworthy">has defaulted to keeping it this way.</span>`);
+			slave.diet = "healthy";
+		}
+	}
+
+	/**
+	 * Reduce fat by exercising - Fuckdoll variant
+	 * @param {FC.ReportSlave} slave
+	 */
+	function burnFatFuckdoll(slave) {
+		if (random(1, 100) > 90) {
+			if (boobSize >= 200 * gigantomastiaMod && gigantomastiaMod !== 3) {
+				r.push(`<span class="change negative">${His} breasts get a little smaller.</span>`);
+				slave.boobs -= 50;
+			} else if (buttSize > 1 && (slave.geneticQuirks.rearLipedema !== 2 || (buttSize > 10 && random(1, 100) > 80))) {
+				r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
+				slave.butt -= 1;
+			}
+		}
+		if (slave.weight > 10 && slave.weightDirection !== 1) {
+			r.push(`${His} workouts have also <span class="change positive">burned off some excess fat.</span>`);
+			slave.weight -= 2;
+			if (slave.weightDirection === -1) {
+				slave.weight -= 2;
+			}
+		}
+	}
+
+	/**
+	 * Reduce fat by exercising - Slave variant
+	 * @param {FC.ReportSlave} slave
+	 */
+	function burnFatSlave(slave,) {
+		if ((slave.geneMods.NCS === 0 && random(1, 100) > 90) ||
+			(slave.geneMods.NCS === 1 && random(1, 100) > 45)) {
+			if ((slave.geneMods.NCS === 0 && boobSize >= 200) ||
+				(slave.geneMods.NCS === 1 && boobSize > 100) && gigantomastiaMod !== 3) {
+				if (slave.geneMods.NCS === 0) {
+					r.push(`<span class="change negative">${His} breasts get a little smaller.</span>`);
+					slave.boobs -= 50;
+				} else {
+					r.push(`<span class="change negative">${His} breasts get smaller.</span>`);
+					slave.boobs -= 100;
+				}
+			} else if (buttSize > 1 && (slave.geneticQuirks.rearLipedema !== 2 || (buttSize > 10 && random(1, 100) > 80))) {
+				if (slave.geneMods.NCS === 0 || buttSize === 1) {
+					r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
+					slave.butt -= 1;
+				} else {
+					r.push(`<span class="change negative">${His} butt gets smaller.</span>`);
+					slave.butt -= 2;
+				}
+			}
+		}
+		if (random(1, 100) > 80) {
+			r.push(`${His} workout successes have <span class="health inc">improved ${his} health.</span>`);
+			improveCondition(slave, 10);
+		}
+		if (slave.weight > 10 && slave.weightDirection !== 1) {
+			r.push(`${His} workouts have also <span class="change positive">burned off some excess fat.</span>`);
+			slave.weight -= 2;
+			if (slave.weightDirection === -1) {
+				slave.weight -= 2;
+			}
+		}
+	}
+
+	/**
+	 * Muscle Gain
+	 * @param {FC.ReportSlave} slave
+	 */
+	function muscleBuildingDiet(slave) {
+		if (slave.fuckdoll > 0) {
+			r.push(`Fuckdoll suits can force their inhabitants to`);
+			if (hasAnyArms(slave)) {
+				r.push(`lift weights`);
+			} else {
+				r.push(`exercise`);
+			}
+			r.push(`until they drop.`);
+			if (slave.geneticQuirks.mGain === 2) {
+				r.push(`${He} <span class="change positive">explosively builds`);
+				if (V.geneticMappingUpgrade >= 1) {
+					r.push(`muscle</span> aided by ${his} myotonic hypertrophy.`);
+				} else {
+					r.push(`muscle.</span>`);
+				}
+				slave.muscles += 15;
+			} else if (slave.geneticQuirks.mLoss === 2) {
+				r.push(`${He} <span class="change positive">slowly gains`);
+				if (V.geneticMappingUpgrade >= 1) {
+					r.push(`muscle</span> due to ${his} myotonic dystrophy.`);
+				} else {
+					r.push(`muscle.</span>`);
+				}
+				slave.muscles += 4;
+			} else {
+				r.push(`${He} <span class="change positive">quickly gains muscle.</span>`);
+				slave.muscles += 9;
+			}
+			slave.muscles = Math.clamp(slave.muscles, -100, 100);
+			burnFatFuckdoll(slave);
+			if (slave.muscles === 100) {
+				r.push(`${He} has plateaued at a state of <span class="lime">perfect musculature.</span>`);
+				slave.diet = "healthy";
+			}
+			r.push(`The stress of forced exercise is trivial compared to everything else ${he} experiences, and ${he}'s unaffected mentally.`);
+		} else {
+			if (isAmputee(slave)) {
+				r.push(`${He} is no longer capable of working out in any plausible way. ${His} special diet <span class="noteworthy">has ended.</span>`);
+				slave.diet = "healthy";
+			} else {
+				if (slave.geneticQuirks.mGain === 2) {
+					r.push(`${His} heavy workouts focus on lifting,`);
+					if (V.geneticMappingUpgrade >= 1) {
+						r.push(`and with ${his} myotonic hypertrophy,`);
 					} else {
-						r.push(`exercise`);
-					}
-					r.push(`until they drop.`);
-					if (slave.geneticQuirks.mGain === 2) {
-						r.push(`${He} <span class="change positive">explosively builds`);
-						if (V.geneticMappingUpgrade >= 1) {
-							r.push(`muscle</span> aided by ${his} myotonic hypertrophy.`);
-						} else {
-							r.push(`muscle.</span>`);
-						}
-						slave.muscles += 15;
-					} else if (slave.geneticQuirks.mLoss === 2) {
-						r.push(`${He} <span class="change positive">slowly gains`);
-						if (V.geneticMappingUpgrade >= 1) {
-							r.push(`muscle</span> due to ${his} myotonic dystrophy.`);
-						} else {
-							r.push(`muscle.</span>`);
-						}
-						slave.muscles += 4;
+						r.push(`and despite run-of-the-mill routines,`);
+					}
+					r.push(`${he} <span class="change positive">gains muscle rapidly.</span>`);
+					slave.muscles += 10;
+				} else if (slave.drugs === "steroids") {
+					r.push(`${His} heavy workouts focus on lifting, and since ${he}'s on so much gear, ${he} <span class="change positive">gains muscle rapidly.</span>`);
+					slave.muscles += 8 + slave.geneticQuirks.mGain;
+				} else if (slave.geneticQuirks.mLoss === 2) {
+					r.push(`${His} heavy workouts focus on lifting,`);
+					if (V.geneticMappingUpgrade >= 1) {
+						r.push(`but with ${his} myotonic dystrophy,`);
 					} else {
-						r.push(`${He} <span class="change positive">quickly gains muscle.</span>`);
-						slave.muscles += 9;
-					}
-					if (random(1, 100) > 90) {
-						if (boobSize >= 200 * gigantomastiaMod && gigantomastiaMod !== 3) {
-							r.push(`<span class="change negative">${His} breasts get a little smaller.</span>`);
-							slave.boobs -= 50;
-						} else if (buttSize > 1 && (slave.geneticQuirks.rearLipedema !== 2 || (buttSize > 10 && random(1, 100) > 80))) {
-							r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
-							slave.butt -= 1;
-						}
-					}
-					if (slave.weight > 10 && slave.weightDirection !== 1) {
-						r.push(`${His} workouts have also <span class="change positive">burned off some excess fat.</span>`);
-						slave.weight -= 2;
-						if (slave.weightDirection === -1) {
-							slave.weight -= 2;
-						}
-					}
-					slave.muscles = Math.clamp(slave.muscles, -100, 100);
-					if (slave.muscles >= 100) {
-						r.push(`${He} has plateaued at a state of <span class="lime">perfect musculature.</span>`);
-						slave.diet = "healthy";
-					}
-					r.push(`The stress of forced exercise is trivial compared to everything else ${he} experiences, and ${he}'s unaffected mentally.`);
+						r.push(`but despite ${his} efforts,`);
+					}
+					r.push(`${he} barely <span class="change positive">gains muscle.</span>`);
+					slave.muscles += 2;
+				} else if (slave.balls > 0 && slave.ballType !== "sterile" && slave.hormoneBalance >= 100) {
+					r.push(`${His} heavy workouts focus on lifting, but with natural testosterone and artificial female hormones clashing in ${his} system, ${he} only <span class="change positive">slowly gains muscle.</span>`);
+					slave.muscles += 3 + slave.geneticQuirks.mGain;
+				} else if (slave.balls > 0 && slave.ballType !== "sterile" && slave.hormoneBalance <= -100) {
+					r.push(`${His} heavy workouts focus on lifting, and with natural testosterone and artificial male hormones in ${his} system, ${he} <span class="change positive">gains muscle rapidly.</span>`);
+					slave.muscles += 8;
+				} else if (slave.balls > 0 && slave.ballType !== "sterile") {
+					r.push(`${His} heavy workouts focus on lifting, and with natural testosterone in ${his} system, ${he} <span class="change positive">gains muscle.</span>`);
+					slave.muscles += 5 + slave.geneticQuirks.mGain;
+				} else if (slave.balls > 0) {
+					r.push(`${His} heavy workouts focus on lifting, but with ${his} useless balls making little testosterone for ${his} system, ${he} only <span class="change positive">slowly gains muscle.</span>`);
+					slave.muscles += 2 + slave.geneticQuirks.mGain;
+				} else if (slave.hormoneBalance <= -100) {
+					r.push(`${His} heavy workouts focus on lifting, and with artificial testosterone in ${his} system, ${he} <span class="change positive">gains muscle.</span>`);
+					slave.muscles += 5 + slave.geneticQuirks.mGain;
+				} else if (slave.hormoneBalance >= 100) {
+					r.push(`${His} heavy workouts focus on lifting, but with lots of female hormones in ${his} system, ${he} barely <span class="change positive">gains muscle.</span>`);
+					slave.muscles += 2 + slave.geneticQuirks.mGain;
 				} else {
-					if (isAmputee(slave)) {
-						r.push(`${He} is no longer capable of working out in any plausible way. ${His} special diet <span class="noteworthy">has ended.</span>`);
-						slave.diet = "healthy";
-					} else {
-						if (slave.geneticQuirks.mGain === 2) {
-							r.push(`${His} heavy workouts focus on lifting,`);
-							if (V.geneticMappingUpgrade >= 1) {
-								r.push(`and with ${his} myotonic hypertrophy,`);
-							} else {
-								r.push(`and despite run-of-the-mill routines,`);
-							}
-							r.push(`${he} <span class="change positive">gains muscle rapidly.</span>`);
-							slave.muscles += 10;
-						} else if (slave.drugs === "steroids") {
-							r.push(`${His} heavy workouts focus on lifting, and since ${he}'s on so much gear, ${he} <span class="change positive">gains muscle rapidly.</span>`);
-							slave.muscles += 8 + slave.geneticQuirks.mGain;
-						} else if (slave.geneticQuirks.mLoss === 2) {
-							r.push(`${His} heavy workouts focus on lifting,`);
-							if (V.geneticMappingUpgrade >= 1) {
-								r.push(`but with ${his} myotonic dystrophy,`);
-							} else {
-								r.push(`but despite ${his} efforts,`);
-							}
-							r.push(`${he} barely <span class="change positive">gains muscle.</span>`);
-							slave.muscles += 2;
-						} else if (slave.balls > 0 && slave.ballType !== "sterile" && slave.hormoneBalance >= 100) {
-							r.push(`${His} heavy workouts focus on lifting, but with natural testosterone and artificial female hormones clashing in ${his} system, ${he} only <span class="change positive">slowly gains muscle.</span>`);
-							slave.muscles += 3 + slave.geneticQuirks.mGain;
-						} else if (slave.balls > 0 && slave.ballType !== "sterile" && slave.hormoneBalance <= -100) {
-							r.push(`${His} heavy workouts focus on lifting, and with natural testosterone and artificial male hormones in ${his} system, ${he} <span class="change positive">gains muscle rapidly.</span>`);
-							slave.muscles += 8;
-						} else if (slave.balls > 0 && slave.ballType !== "sterile") {
-							r.push(`${His} heavy workouts focus on lifting, and with natural testosterone in ${his} system, ${he} <span class="change positive">gains muscle.</span>`);
-							slave.muscles += 5 + slave.geneticQuirks.mGain;
-						} else if (slave.balls > 0) {
-							r.push(`${His} heavy workouts focus on lifting, but with ${his} useless balls making little testosterone for ${his} system, ${he} only <span class="change positive">slowly gains muscle.</span>`);
-							slave.muscles += 2 + slave.geneticQuirks.mGain;
-						} else if (slave.hormoneBalance <= -100) {
-							r.push(`${His} heavy workouts focus on lifting, and with artificial testosterone in ${his} system, ${he} <span class="change positive">gains muscle.</span>`);
-							slave.muscles += 5 + slave.geneticQuirks.mGain;
-						} else if (slave.hormoneBalance >= 100) {
-							r.push(`${His} heavy workouts focus on lifting, but with lots of female hormones in ${his} system, ${he} barely <span class="change positive">gains muscle.</span>`);
-							slave.muscles += 2 + slave.geneticQuirks.mGain;
-						} else {
-							r.push(`${His} heavy workouts focus on lifting, and ${he} <span class="change positive">slowly gains muscle.</span>`);
-							slave.muscles += 3 + slave.geneticQuirks.mGain;
-						}
-						if (slave.behavioralQuirk === "fitness") {
-							r.push(`${He} attacks lifting with real enthusiasm, further increasing ${his} mass.`);
-							slave.muscles += 2 + slave.geneticQuirks.mGain;
-						}
-						if ((slave.geneMods.NCS === 0 && random(1, 100) > 90) || (slave.geneMods.NCS === 1 && random(1, 100) > 45)) {
-							if ((slave.geneMods.NCS === 0 && boobSize >= 200) || (slave.geneMods.NCS === 1 && boobSize > 100)) {
-								if (slave.geneMods.NCS === 0) {
-									r.push(`<span class="change negative">${His} breasts get a little smaller.</span>`);
-									slave.boobs -= 50;
-								} else {
-									r.push(`<span class="change negative">${His} breasts get smaller.</span>`);
-									slave.boobs -= 100;
-								}
-							} else if (buttSize > 1 && (slave.geneticQuirks.rearLipedema !== 2 || (buttSize > 10 && random(1, 100) > 80))) {
-								if (slave.geneMods.NCS === 0 || buttSize === 1) {
-									r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
-									slave.butt -= 1;
-								} else {
-									r.push(`<span class="change negative">${His} butt gets smaller.</span>`);
-									slave.butt -= 2;
-								}
-							}
-						}
-						if (random(1, 100) > 80) {
-							r.push(`${His} workout successes have <span class="health inc">improved ${his} health.</span>`);
-							improveCondition(slave, 10);
-						}
-						if (slave.weight > 10 && slave.weightDirection !== 1) {
-							r.push(`${His} workouts have also <span class="change positive">burned off some excess fat.</span>`);
-							slave.weight -= 2;
-							if (slave.weightDirection === -1) {
-								slave.weight -= 2;
-							}
-						}
-						slave.muscles = Math.clamp(slave.muscles, -100, 100);
-						if (slave.muscles >= 100) {
-							r.push(`${He} has plateaued at a state of <span class="lime">goddess-like musculature.</span>`);
-							slave.diet = "healthy";
-						}
-					}
+					r.push(`${His} heavy workouts focus on lifting, and ${he} <span class="change positive">slowly gains muscle.</span>`);
+					slave.muscles += 3 + slave.geneticQuirks.mGain;
 				}
-				break;
-			case "slimming": // Muscle Loss
-				if (slave.fuckdoll > 0) {
-					r.push(`Fuckdoll suits can force their inhabitants to exercise until they drop.`);
-					if (slave.geneticQuirks.mLoss === 2) {
-						r.push(`${He} <span class="change positive">rapidly sheds`);
-						if (V.geneticMappingUpgrade >= 1) {
-							r.push(`muscle</span> aided by ${his} myotonic dystrophy.`);
-						} else {
-							r.push(`muscle.</span>`);
-						}
-						slave.muscles = Math.clamp(slave.muscles - 15, -100, 100);
-					} else if (slave.geneticQuirks.mGain === 2) {
-						r.push(`${He} <span class="change positive">slowly loses`);
-						if (V.geneticMappingUpgrade >= 1) {
-							r.push(`musculature</span> due to ${his} myotonic hypertrophy steadily trying to put it back.`);
-						} else {
-							r.push(`musculature.</span>`);
-						}
-						slave.muscles -= 4;
-					} else {
-						r.push(`${He} <span class="change positive">loses musculature.</span>`);
-						slave.muscles -= 9;
-					}
-					if (random(1, 100) > 90) {
-						if (boobSize >= 200 * gigantomastiaMod && gigantomastiaMod !== 3) {
-							r.push(`<span class="change negative">${His} breasts get a little smaller.</span>`);
-							slave.boobs -= 50;
-						} else if (buttSize > 1 && (slave.geneticQuirks.rearLipedema !== 2 || (buttSize > 10 && random(1, 100) > 80))) {
-							r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
-							slave.butt -= 1;
-						}
-					}
-					if (slave.weight > 10 && slave.weightDirection !== 1) {
-						r.push(`${His} workouts have also <span class="change positive">burned off some excess fat.</span>`);
-						slave.weight -= 2;
-						if (slave.weightDirection === -1) {
-							slave.weight -= 2;
-						}
-					}
-					slave.muscles = Math.clamp(slave.muscles, -100, 100);
-					if (slave.muscles <= 0) {
-						r.push(`${He} has finally <span class="lime">lost all visible musculature.</span>`);
-						slave.diet = "healthy";
-					}
-					r.push(`The stress of forced exercise is trivial compared to everything else ${he} experiences, and ${he}'s unaffected mentally.`);
+				if (slave.behavioralQuirk === "fitness") {
+					r.push(`${He} attacks lifting with real enthusiasm, further increasing ${his} mass.`);
+					slave.muscles += 2 + slave.geneticQuirks.mGain;
+				}
+				burnFatSlave(slave);
+				slave.muscles = Math.clamp(slave.muscles, -100, 100);
+				if (slave.muscles >= 100) {
+					r.push(`${He} has plateaued at a state of <span class="lime">goddess-like musculature.</span>`);
+					slave.diet = "healthy";
+				}
+			}
+		}
+	}
+
+	/**
+	 * Muscle Loss
+	 * @param {FC.ReportSlave} slave
+	 */
+	function slimmingDiet(slave) {
+		if (slave.fuckdoll > 0) {
+			r.push(`Fuckdoll suits can force their inhabitants to exercise until they drop.`);
+			if (slave.geneticQuirks.mLoss === 2) {
+				r.push(`${He} <span class="change positive">rapidly sheds`);
+				if (V.geneticMappingUpgrade >= 1) {
+					r.push(`muscle</span> aided by ${his} myotonic dystrophy.`);
 				} else {
-					if (!canWalk(slave)) {
-						r.push(`${He} is no longer capable of actively working out. ${His} special diet <span class="noteworthy">has ended.</span>`);
-						slave.diet = "healthy";
-					} else if (slave.muscles > 0) {
-						if (slave.geneticQuirks.mLoss === 2) {
-							r.push(`${His} long workouts focus on cardio,`);
-							if (V.geneticMappingUpgrade >= 1) {
-								r.push(`and with ${his} myotonic dystrophy,`);
-							} else {
-								r.push(`and despite run-of-the-mill routines,`);
-							}
-							r.push(`${he} <span class="change positive">rapidly loses musculature.</span>`);
-							slave.muscles -= 10;
-						} else if (slave.geneticQuirks.mGain === 2) {
-							r.push(`${His} long workouts focus on cardio,`);
-							if (V.geneticMappingUpgrade >= 1) {
-								r.push(`but with ${his} myotonic hypertrophy,`);
-							} else {
-								r.push(`but despite ${his} best efforts,`);
-							}
-							r.push(`${he} <span class="change positive">loses mass slowly.</span>`);
-							slave.muscles -= 2;
-						} else if (slave.drugs === "steroids") {
-							r.push(`${His} long workouts focus on cardio, but since ${he}'s still shooting gear, ${he} <span class="change positive">loses mass slowly.</span>`);
-							slave.muscles -= 3 + slave.geneticQuirks.mLoss;
-						} else if (slave.balls > 0 && slave.ballType !== "sterile" && slave.hormoneBalance <= -100) {
-							r.push(`${His} long workouts focus on cardio, but since ${he}'s got so much natural and artificial testosterone, ${he} <span class="change positive">loses mass slowly.</span>`);
-							slave.muscles -= 3 + slave.geneticQuirks.mLoss;
-						} else if (slave.balls > 0 && slave.ballType !== "sterile" && slave.hormoneBalance >= 100) {
-							r.push(`${His} long workouts focus on cardio, and with the natural testosterone in ${his} system counteracted by hormone treatment, ${he} <span class="change positive">loses musculature.</span>`);
-							slave.muscles -= 5 + slave.geneticQuirks.mLoss;
-						} else if (slave.balls > 0 && slave.ballType !== "sterile") {
-							r.push(`${His} long workouts focus on cardio, but with some natural testosterone in ${his} system, ${he} <span class="change positive">loses muscle slowly.</span>`);
-							slave.muscles -= 3 + slave.geneticQuirks.mLoss;
-						} else if (slave.balls > 0) {
-							r.push(`${His} long workouts focus on cardio, and with ${his} useless balls not producing much testosterone, ${he} <span class="change positive">loses musculature.</span>`);
-							slave.muscles -= 5 + slave.geneticQuirks.mLoss;
-						} else if (slave.hormoneBalance >= 100) {
-							r.push(`${His} long workouts focus on cardio, and with female hormone treatment, ${he} <span class="change positive">loses musculature rapidly.</span>`);
-							slave.muscles -= 8 + slave.geneticQuirks.mLoss;
-						} else if (slave.hormoneBalance <= -100) {
-							r.push(`${His} long workouts focus on cardio, but under male hormone treatment, ${he} <span class="change positive">loses muscle slowly.</span>`);
-							slave.muscles -= 3 + slave.geneticQuirks.mLoss;
-						} else {
-							r.push(`${His} long workouts focus on cardio, and ${he} <span class="change positive">loses musculature.</span>`);
-							slave.muscles -= 5 + slave.geneticQuirks.mLoss;
-						}
-						if (slave.behavioralQuirk === "fitness") {
-							r.push(`${He} approaches endurance work with real enthusiasm, quickly slimming ${him} down.`);
-							slave.muscles -= 2 + slave.geneticQuirks.mLoss;
-						}
-						if ((slave.geneMods.NCS === 0 && random(1, 100) > 90) || (slave.geneMods.NCS === 1 && random(1, 100) > 45)) {
-							if ((slave.geneMods.NCS === 0 && boobSize >= 200) || (slave.geneMods.NCS === 1 && boobSize > 100) && gigantomastiaMod !== 3) {
-								if (slave.geneMods.NCS === 0) {
-									r.push(`<span class="change negative">${His} breasts get a little smaller.</span>`);
-									slave.boobs -= 50;
-								} else {
-									r.push(`<span class="change negative">${His} breasts get smaller.</span>`);
-									slave.boobs -= 100;
-								}
-							} else if (buttSize > 1 && (slave.geneticQuirks.rearLipedema !== 2 || (buttSize > 10 && random(1, 100) > 80))) {
-								if (slave.geneMods.NCS === 0 || buttSize === 1) {
-									r.push(`<span class="change negative">${His} butt gets a little smaller.</span>`);
-									slave.butt -= 1;
-								} else {
-									r.push(`<span class="change negative">${His} butt gets smaller.</span>`);
-									slave.butt -= 2;
-								}
-							}
-						}
-						if (random(1, 100) > 80) {
-							r.push(`${His} workout successes have <span class="health inc">improved ${his} health.</span>`);
-							improveCondition(slave, 10);
-						}
-						if (slave.weight > 10 && slave.weightDirection !== 1) {
-							r.push(`${His} workouts have also <span class="change positive">burned off some excess fat.</span>`);
-							slave.weight -= 2;
-							if (slave.weightDirection === -1) {
-								slave.weight -= 2;
-							}
-						}
-						slave.muscles = Math.clamp(slave.muscles, 0, 100);
-						if (slave.muscles <= 0) {
-							r.push(`${He} has finally <span class="orange">lost all visible musculature.</span>`);
-							slave.diet = "healthy";
-						}
-					} else {
-						r.push(`${His} long workouts focus on cardio to keep ${his} body lithe.`);
-						if (slave.behavioralQuirk === "fitness") {
-							r.push(`${He} <span class="devotion inc">enjoys</span> the time ${he}'s given to work out.`);
-							slave.devotion += 2;
-						}
-						if (slave.muscles < -10) {
-							r.push(`Since ${he} is rather weak, ${his} routine slowly tones ${his} soft muscles.`);
-							slave.muscles++;
-						}
-						if (((slave.geneMods.NCS === 0 && boobSize >= 200) || (slave.geneMods.NCS === 1 && (boobSize > 100))) && gigantomastiaMod !== 3) {
-							if (slave.geneMods.NCS === 0) {
-								r.push(`<span class="change negative">${His} breasts get a little smaller.</span>`);
-								slave.boobs -= 50;
-							} else {
-								r.push(`<span class="change negative">${His} breasts get smaller.</span>`);
-								slave.boobs -= 100;
-							}
-						}
-						if (random(1, 100) > 50) {
-							if (buttSize > 1 && (slave.geneticQuirks.rearLipedema !== 2 || (buttSize > 10 && random(1, 100) > 80))) {
-								r.push(`<span class="change negative">${His} butt loses a little mass.</span>`);
-								slave.butt -= 1;
-							}
-						}
-						if (random(1, 100) > 50 && slave.health.condition <= 90 && slave.health.condition >= -20) {
-							r.push(`${His} workout successes have <span class="health inc">improved ${his} health.</span>`);
-							improveCondition(slave, 5);
-						}
-						if (slave.weight > 10 && slave.weightDirection !== 1) {
-							r.push(`${His} workouts have also <span class="change positive">burned off some excess fat.</span>`);
-							slave.weight -= 2;
-							if (slave.weightDirection === -1) {
-								slave.weight -= 2;
-							}
-						}
-					}
+					r.push(`muscle.</span>`);
 				}
-				break;
-			case "cum production":
-				if (slave.fuckdoll > 0) {
-					r.push(`Fuckdoll suits have easily attached reservoirs to catch excess cum.`);
-					if (slave.geneMods.NCS === 0 && slave.balls < 6 && random(1, 100) > 90) {
-						r.push(`${His} <span class="fetish gain">balls swell</span> to better accommodate ${his} increased cum production.`);
-						slave.balls += 1;
-					} else if (slave.geneMods.NCS === 1 && slave.balls < 3 && random(1, 100) > 95) {
-						r.push(`${He}'s <span class="fetish gain">balls grow slightly</span> to better accommodate ${his} increased cum production.`);
-						slave.balls += 1;
-					}
+				slave.muscles = Math.clamp(slave.muscles - 15, -100, 100);
+			} else if (slave.geneticQuirks.mGain === 2) {
+				r.push(`${He} <span class="change positive">slowly loses`);
+				if (V.geneticMappingUpgrade >= 1) {
+					r.push(`musculature</span> due to ${his} myotonic hypertrophy steadily trying to put it back.`);
 				} else {
-					if (slave.fetish !== "mindbroken") {
-						if (slave.attrXX < 80) {
-							r.push(`${He} finds ${himself} <span class="improvement">fantasizing about fucking girls</span> in ${his} free time.`);
-							slave.attrXX += 2;
-						}
-						if (slave.fetishKnown === 1) {
-							if (slave.fetishStrength < 95 && slave.fetish === "pregnancy") {
-								r.push(`${His} thoughts frequently drift towards <span class="fetish inc">bellies swelling with ${his} children</span> whenever ${he} has sex or pleasures ${himself}.`);
-								slave.fetishStrength += 1;
-							} else if (slave.energy < 90 && slave.fetish === "pregnancy") {
-								r.push(`${His} eagerness for sex <span class="libido inc">grows stronger</span> the more ${his} aching nuts yearn to inseminate a fertile womb.`);
-								slave.energy += 1;
-							}
-						}
-						if (slave.fetishStrength <= 65) {
-							if (slave.fetish !== "pregnancy") {
-								if (fetishChangeChance(slave) > random(0, 100)) {
-									r.push(`${He} begins to find the thought of filling a fertile womb with sperm <span class="fetish gain">irresistible.</span>`);
-									slave.fetish = "pregnancy";
-									slave.fetishStrength = 10;
-									slave.fetishKnown = 1;
-								}
-							}
-						}
-					}
-					if (slave.geneMods.NCS === 0 && slave.balls < 6 && random(1, 100) > 90) {
-						r.push(`${His} <span class="change positive">balls swell</span> to better accommodate ${his} increased cum production.`);
-						slave.balls += 1;
-					} else if (slave.geneMods.NCS === 1 && slave.balls < 3 && random(1, 100) > 95) {
-						r.push(`${His} <span class="change positive">balls grow slightly</span> to better accommodate ${his} increased cum production.`);
-						slave.balls += 1;
-					}
+					r.push(`musculature.</span>`);
 				}
-				break;
-			case "XX": // Female Hormones
-				if (slave.fuckdoll > 0) {
-					r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s being <span class="lime">feminized.</span>`);
+				slave.muscles -= 4;
+			} else {
+				r.push(`${He} <span class="change positive">loses musculature.</span>`);
+				slave.muscles -= 9;
+			}
+			slave.muscles = Math.clamp(slave.muscles, -100, 100);
+			burnFatFuckdoll(slave);
+			if (slave.muscles <= 0) {
+				r.push(`${He} has finally <span class="lime">lost all visible musculature.</span>`);
+				slave.diet = "healthy";
+			}
+			r.push(`The stress of forced exercise is trivial compared to everything else ${he} experiences, and ${he}'s unaffected mentally.`);
+		} else {
+			if (!canWalk(slave)) {
+				r.push(`${He} is no longer capable of actively working out. ${His} special diet <span class="noteworthy">has ended.</span>`);
+				slave.diet = "healthy";
+			} else if (slave.muscles > 0) {
+				if (slave.geneticQuirks.mLoss === 2) {
+					r.push(`${His} long workouts focus on cardio,`);
+					if (V.geneticMappingUpgrade >= 1) {
+						r.push(`and with ${his} myotonic dystrophy,`);
+					} else {
+						r.push(`and despite run-of-the-mill routines,`);
+					}
+					r.push(`${he} <span class="change positive">rapidly loses musculature.</span>`);
+					slave.muscles -= 10;
+				} else if (slave.geneticQuirks.mGain === 2) {
+					r.push(`${His} long workouts focus on cardio,`);
+					if (V.geneticMappingUpgrade >= 1) {
+						r.push(`but with ${his} myotonic hypertrophy,`);
+					} else {
+						r.push(`but despite ${his} best efforts,`);
+					}
+					r.push(`${he} <span class="change positive">loses mass slowly.</span>`);
+					slave.muscles -= 2;
+				} else if (slave.drugs === "steroids") {
+					r.push(`${His} long workouts focus on cardio, but since ${he}'s still shooting gear, ${he} <span class="change positive">loses mass slowly.</span>`);
+					slave.muscles -= 3 + slave.geneticQuirks.mLoss;
+				} else if (slave.balls > 0 && slave.ballType !== "sterile" && slave.hormoneBalance <= -100) {
+					r.push(`${His} long workouts focus on cardio, but since ${he}'s got so much natural and artificial testosterone, ${he} <span class="change positive">loses mass slowly.</span>`);
+					slave.muscles -= 3 + slave.geneticQuirks.mLoss;
+				} else if (slave.balls > 0 && slave.ballType !== "sterile" && slave.hormoneBalance >= 100) {
+					r.push(`${His} long workouts focus on cardio, and with the natural testosterone in ${his} system counteracted by hormone treatment, ${he} <span class="change positive">loses musculature.</span>`);
+					slave.muscles -= 5 + slave.geneticQuirks.mLoss;
+				} else if (slave.balls > 0 && slave.ballType !== "sterile") {
+					r.push(`${His} long workouts focus on cardio, but with some natural testosterone in ${his} system, ${he} <span class="change positive">loses muscle slowly.</span>`);
+					slave.muscles -= 3 + slave.geneticQuirks.mLoss;
+				} else if (slave.balls > 0) {
+					r.push(`${His} long workouts focus on cardio, and with ${his} useless balls not producing much testosterone, ${he} <span class="change positive">loses musculature.</span>`);
+					slave.muscles -= 5 + slave.geneticQuirks.mLoss;
+				} else if (slave.hormoneBalance >= 100) {
+					r.push(`${His} long workouts focus on cardio, and with female hormone treatment, ${he} <span class="change positive">loses musculature rapidly.</span>`);
+					slave.muscles -= 8 + slave.geneticQuirks.mLoss;
+				} else if (slave.hormoneBalance <= -100) {
+					r.push(`${His} long workouts focus on cardio, but under male hormone treatment, ${he} <span class="change positive">loses muscle slowly.</span>`);
+					slave.muscles -= 3 + slave.geneticQuirks.mLoss;
 				} else {
-					if (slave.behavioralQuirk === "insecure") {
-						if (slave.balls > 0) {
-							r.push(`Despite some doubts lurking at the back of ${his} mind, your insistence that ${he} will be prettier if ${he} was more feminine <span class="devotion inc">lets ${him} enjoy</span> the estrogen rich food given to ${him}.`);
-							slave.devotion += 1;
-						} else if (slave.ovaries === 1 || slave.mpreg === 1) {
-							r.push(`Despite some doubts lurking at the back of ${his} mind, your insistence that ${he} will be prettier if ${he} was more fertile <span class="devotion inc">lets ${him} enjoy</span> the estrogen rich food given to ${him}.`);
-							slave.devotion += 1;
-						}
-					}
+					r.push(`${His} long workouts focus on cardio, and ${he} <span class="change positive">loses musculature.</span>`);
+					slave.muscles -= 5 + slave.geneticQuirks.mLoss;
 				}
-				if ((slave.ovaries === 1 || slave.mpreg === 1) && slave.balls > 0) { // herm
-					if (slave.weight < 30 && slave.weightDirection !== -1) {
-						r.push(`Hormonal changes encourage ${his} body to <span class="change positive">grow softer.</span>`);
-						slave.weight += 1;
-						if (slave.weightDirection === 1) {
-							slave.weight += 2;
-						}
-					}
-					if (slave.geneMods.NCS === 0 && slave.boobs < 500 * gigantomastiaMod) {
-						r.push(`${His} breasts <span class="change positive">grow slightly</span> from the estrogen.`);
-						slave.boobs += 10;
-					}
-					if (slave.geneMods.NCS === 0 && slave.butt < 4 && random(1, 100) > (75 - (rearQuirk * 20))) {
-						r.push(`${His} rear <span class="change positive">rounds out</span> to fit ${his} developing femininity.`);
-						slave.butt += 1;
-					}
-					if (slave.waist > -20) {
-						r.push(`Hormonal changes <span class="change positive">slim ${his} waist.</span>`);
-						slave.waist--;
-					}
-					if (slave.dick > 1 && (((slave.geneMods.NCS === 0) && (random(1, 100) > 95)) || ((slave.geneMods.NCS === 1) && (random(1, 100) > 43)))) {
-						if (slave.geneMods.NCS === 1 && slave.dick > 2) {
-							r.push(`${His} dick <span class="change negative">shrinks down</span> due to ${his} body chemistry.`);
-							slave.dick -= 1;
-						} else {
-							r.push(`${His} dick <span class="change negative">shrinks slightly</span> due to ${his} body chemistry.`);
-						}
-						slave.dick -= 1;
-					}
-					if (slave.balls > 1 && (((slave.geneMods.NCS === 0) && (random(1, 100) > 95)) || ((slave.geneMods.NCS === 1) && (random(1, 100) > 43)))) {
-						if (slave.geneMods.NCS === 1 && slave.balls > 2) {
-							r.push(`${His} balls <span class="change negative">shrink down</span> due to ${his} body chemistry.`);
-							slave.balls -= 1;
-						} else {
-							r.push(`${His} balls <span class="change negative">shrivel</span> due to ${his} body chemistry.`);
-						}
-						slave.balls -= 1;
-					}
-				} else if (slave.ovaries === 1 || slave.mpreg === 1) { // female
-					if (slave.weight < 40 && slave.weightDirection !== 1) {
-						r.push(`Hormonal changes encourage ${his} body to <span class="change positive">grow softer.</span>`);
-						slave.weight += 1;
-						if (slave.weightDirection === 1) {
-							slave.weight += 2;
-						}
-					}
-					if (slave.geneMods.NCS === 0 && slave.boobs < 600 * gigantomastiaMod) {
-						r.push(`${His} breasts <span class="change positive">grow slightly</span> from the estrogen.`);
-						slave.boobs += 10;
-					}
-					if (slave.waist > -30) {
-						r.push(`Hormonal changes <span class="change positive">slim ${his} waist.</span>`);
-						slave.waist--;
-					}
-					if (slave.geneMods.NCS === 0 && slave.butt < 5 && random(1, 100) > (75 - (rearQuirk * 20))) {
-						r.push(`${His} rear <span class="change positive">rounds out</span> to fit ${his} developing femininity.`);
-						slave.butt += 1;
-					}
-				} else if (slave.balls > 0) { // male
-					if (slave.weight < 20 && slave.weightDirection !== 1) {
-						r.push(`Hormonal changes encourage ${his} body to <span class="change positive">grow softer.</span>`);
-						slave.weight += 1;
-						if (slave.weightDirection === 1) {
-							slave.weight += 2;
-						}
-					}
-					if (slave.geneMods.NCS === 0 && slave.boobs < 400 * gigantomastiaMod) {
-						r.push(`${His} breasts <span class="change positive">grow slightly</span> from the estrogen.`);
-						slave.boobs += 10;
-					}
-					if (slave.waist > -10) {
-						r.push(`Hormonal changes <span class="change positive">slim ${his} waist.</span>`);
-						slave.waist--;
-					}
-					if (slave.geneMods.NCS === 0 && slave.butt < 3 && random(1, 100) > (75 - (rearQuirk * 20))) {
-						r.push(`${His} rear <span class="change positive">rounds out</span> to fit ${his} developing femininity.`);
-						slave.butt += 1;
-					}
-					if (slave.dick > 1 && (((slave.geneMods.NCS === 0) && (random(1, 100) > 99)) || ((slave.geneMods.NCS === 1) && (random(1, 100) > 48)))) {
-						if (slave.geneMods.NCS === 1 && slave.dick > 2) {
-							r.push(`${His} dick <span class="change negative">shrinks down</span> due to ${his} body chemistry.`);
-							slave.dick -= 1;
-						} else {
-							r.push(`${His} dick <span class="change negative">shrinks slightly</span> due to ${his} body chemistry.`);
-						}
-						slave.dick -= 1;
-					}
-					if (slave.balls > 1 && (((slave.geneMods.NCS === 0) && (random(1, 100) > 99)) || ((slave.geneMods.NCS === 1) && (random(1, 100) > 48)))) {
-						if (slave.geneMods.NCS === 1 && slave.balls > 2) {
-							r.push(`${His} balls <span class="change negative">shrink down</span> due to ${his} body chemistry.`);
-							slave.balls -= 1;
-						} else {
-							r.push(`${His} balls <span class="change negative">shrivel</span> due to ${his} body chemistry.`);
-						}
-						slave.balls -= 1;
+				if (slave.behavioralQuirk === "fitness") {
+					r.push(`${He} approaches endurance work with real enthusiasm, quickly slimming ${him} down.`);
+					slave.muscles -= 2 + slave.geneticQuirks.mLoss;
+				}
+				burnFatSlave(slave);
+				slave.muscles = Math.clamp(slave.muscles, 0, 100);
+				if (slave.muscles <= 0) {
+					r.push(`${He} has finally <span class="orange">lost all visible musculature.</span>`);
+					slave.diet = "healthy";
+				}
+			} else {
+				r.push(`${His} long workouts focus on cardio to keep ${his} body lithe.`);
+				if (slave.behavioralQuirk === "fitness") {
+					r.push(`${He} <span class="devotion inc">enjoys</span> the time ${he}'s given to work out.`);
+					slave.devotion += 2;
+				}
+				if (slave.muscles < -10) {
+					r.push(`Since ${he} is rather weak, ${his} routine slowly tones ${his} soft muscles.`);
+					slave.muscles++;
+				}
+				if (((slave.geneMods.NCS === 0 && boobSize >= 200) || (slave.geneMods.NCS === 1 && (boobSize > 100))) && gigantomastiaMod !== 3) {
+					if (slave.geneMods.NCS === 0) {
+						r.push(`<span class="change negative">${His} breasts get a little smaller.</span>`);
+						slave.boobs -= 50;
+					} else {
+						r.push(`<span class="change negative">${His} breasts get smaller.</span>`);
+						slave.boobs -= 100;
 					}
 				}
-				if (slave.fuckdoll === 0) {
-					if (slave.fetish !== "mindbroken") {
-						if (slave.attrXY < 100) {
-							r.push(`${He} begins to find men <span class="change positive">a little more attractive</span> thanks to the female hormones.`);
-							slave.attrXY += 1;
-						}
-					}
-					if (slave.energy < 70) {
-						r.push(`Hormones leave ${him} feeling <span class="change positive">a little more frisky</span> towards others.`);
-						slave.energy += 1;
+				if (random(1, 100) > 50) {
+					if (buttSize > 1 && (slave.geneticQuirks.rearLipedema !== 2 || (buttSize > 10 && random(1, 100) > 80))) {
+						r.push(`<span class="change negative">${His} butt loses a little mass.</span>`);
+						slave.butt -= 1;
 					}
 				}
-				if (slave.geneticQuirks.galactorrhea === 2 && random(1, 100) < slave.hormoneBalance && slave.lactation === 0) {
-					slave.inappropriateLactation = 1;
+				if (random(1, 100) > 50 && slave.health.condition <= 90 && slave.health.condition >= -20) {
+					r.push(`${His} workout successes have <span class="health inc">improved ${his} health.</span>`);
+					improveCondition(slave, 5);
 				}
-				break;
-			case "XY": // Male Hormones
-				if (slave.fuckdoll > 0) {
-					r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s becoming <span class="lime">masculine.</span>`);
-				} else {
-					if (slave.behavioralQuirk === "insecure") {
-						if (slave.balls > 0) {
-							r.push(`Despite some doubts lurking at the back of ${his} mind, your insistence that ${he} will be handsomer if ${he} was more masculine <span class="devotion inc">lets ${him} enjoy</span> the testosterone rich food given to ${him}.`);
-							slave.devotion += 1;
-						} else if (slave.ovaries === 1 || slave.mpreg === 1) {
-							r.push(`Despite some doubts lurking at the back of ${his} mind, your insistence that ${he} will be handsomer if ${he} was less feminine <span class="devotion inc">lets ${him} enjoy</span> the testosterone rich food given to ${him}.`);
-							slave.devotion += 1;
-						}
+				if (slave.weight > 10 && slave.weightDirection !== 1) {
+					r.push(`${His} workouts have also <span class="change positive">burned off some excess fat.</span>`);
+					slave.weight -= 2;
+					if (slave.weightDirection === -1) {
+						slave.weight -= 2;
 					}
 				}
-				if ((slave.ovaries === 1 || slave.mpreg === 1) && slave.balls > 0) { // herm
-					if (slave.muscles < 30) {
-						r.push(`Hormonal changes encourage ${his} body to <span class="change positive">gain muscle.</span>`);
-						slave.muscles += 1 + slave.geneticQuirks.mGain;
-					}
-					if (slave.geneMods.NCS === 0 && slave.dick < 4 && random(1, 100) > 95) {
-						r.push(`${His} dick <span class="change positive">grows slightly</span> due to the male hormones in ${his} diet.`);
-						slave.dick += 1;
-					}
-					if (slave.geneMods.NCS === 0 && slave.balls < 3 && random(1, 100) > 95) {
-						r.push(`${His} balls <span class="change positive">swell</span> due to the male hormones in ${his} diet.`);
-						slave.balls += 1;
-					}
-					if ((slave.geneMods.NCS === 0 && boobSize > 400) || (slave.geneMods.NCS === 1 && boobSize > 200) && gigantomastiaMod !== 3) {
-						r.push(`${His} breasts <span class="change negative">lose some mass</span> from the lack of estrogen in ${his} diet.`);
-						slave.boobs -= 10;
-						if (slave.geneMods.NCS === 1) {
-							slave.boobs -= 10;
-						}
-					}
-					if (slave.waist < 15) {
-						r.push(`Hormonal changes <span class="change negative">thicken ${his} waist.</span>`);
-						slave.waist++;
-					}
-				} else if (slave.ovaries === 1 || slave.mpreg === 1) { // female
-					if (slave.muscles < 15) {
-						r.push(`Hormonal changes encourage ${his} body to <span class="change positive">gain muscle.</span>`);
-						slave.muscles += 1 + slave.geneticQuirks.mGain;
-					}
-					if ((slave.geneMods.NCS === 0 && boobSize > 500) || (slave.geneMods.NCS === 1 && boobSize > 200) && gigantomastiaMod !== 3) {
-						r.push(`${His} breasts <span class="change negative">lose some mass</span> from the lack of estrogen in ${his} diet.`);
-						slave.boobs -= 10;
-						if (slave.geneMods.NCS === 1) {
-							slave.boobs -= 10;
-						}
-					}
-					if (slave.waist < 0) {
-						r.push(`Hormonal changes <span class="change negative">thicken ${his} waist.</span>`);
-						slave.waist++;
-					}
-				} else if (slave.balls > 0) { // male
-					if (slave.muscles < 60) {
-						r.push(`Hormonal changes encourage ${his} body to <span class="change positive">gain muscle.</span>`);
-						slave.muscles += 1 + slave.geneticQuirks.mGain;
-					}
-					if (slave.geneMods.NCS === 0 && slave.dick < 4 && random(1, 100) > 95) {
-						r.push(`${His} dick <span class="change positive">grows slightly</span> due to the male hormones in ${his} diet.`);
-						slave.dick += 1;
-					}
-					if (slave.waist < 30) {
-						r.push(`Hormonal changes <span class="change negative">thicken ${his} waist.</span>`);
-						slave.waist++;
-					}
-					if (slave.geneMods.NCS === 0 && slave.balls < 3 && random(1, 100) > 95) {
-						r.push(`${His} balls <span class="change positive">swell</span> due to the male hormones in ${his} diet.`);
-						slave.balls += 1;
-					}
-					if (boobSize > 300 && gigantomastiaMod !== 3) {
-						r.push(`${His} breasts <span class="change negative">lose some mass</span> to better suit ${his} body chemistry.`);
-						slave.boobs -= 10;
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.ReportSlave} slave
+	 */
+	function cumProductionDiet(slave) {
+		if (slave.fuckdoll > 0) {
+			r.push(`Fuckdoll suits have easily attached reservoirs to catch excess cum.`);
+			if (slave.geneMods.NCS === 0 && slave.balls < 6 && random(1, 100) > 90) {
+				r.push(`${His} <span class="fetish gain">balls swell</span> to better accommodate ${his} increased cum production.`);
+				slave.balls += 1;
+			} else if (slave.geneMods.NCS === 1 && slave.balls < 3 && random(1, 100) > 95) {
+				r.push(`${He}'s <span class="fetish gain">balls grow slightly</span> to better accommodate ${his} increased cum production.`);
+				slave.balls += 1;
+			}
+		} else {
+			if (slave.fetish !== "mindbroken") {
+				if (slave.attrXX < 80) {
+					r.push(`${He} finds ${himself} <span class="improvement">fantasizing about fucking girls</span> in ${his} free time.`);
+					slave.attrXX += 2;
+				}
+				if (slave.fetishKnown === 1) {
+					if (slave.fetishStrength < 95 && slave.fetish === "pregnancy") {
+						r.push(`${His} thoughts frequently drift towards <span class="fetish inc">bellies swelling with ${his} children</span> whenever ${he} has sex or pleasures ${himself}.`);
+						slave.fetishStrength += 1;
+					} else if (slave.energy < 90 && slave.fetish === "pregnancy") {
+						r.push(`${His} eagerness for sex <span class="libido inc">grows stronger</span> the more ${his} aching nuts yearn to inseminate a fertile womb.`);
+						slave.energy += 1;
 					}
 				}
-				if (slave.fuckdoll === 0) {
-					if (slave.fetish !== "mindbroken") {
-						if (slave.attrXX < 100) {
-							r.push(`${He} begins to find women <span class="change positive">a little more attractive</span> thanks to the male hormones.`);
-							slave.attrXX += 1;
+				if (slave.fetishStrength <= 65) {
+					if (slave.fetish !== "pregnancy") {
+						if (fetishChangeChance(slave) > random(0, 100)) {
+							r.push(`${He} begins to find the thought of filling a fertile womb with sperm <span class="fetish gain">irresistible.</span>`);
+							slave.fetish = "pregnancy";
+							slave.fetishStrength = 10;
+							slave.fetishKnown = 1;
 						}
 					}
-					if (slave.energy < 70) {
-						r.push(`Hormones leave ${him} feeling <span class="change positive">a little more frisky</span> towards others.`);
-						slave.energy += 1;
-					}
 				}
-				break;
-			case "XXY": // Futa Hormones
-				if (slave.fuckdoll > 0) {
-					r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s becoming <span class="change positive">masculine.</span>`);
+			}
+			if (slave.geneMods.NCS === 0 && slave.balls < 6 && random(1, 100) > 90) {
+				r.push(`${His} <span class="change positive">balls swell</span> to better accommodate ${his} increased cum production.`);
+				slave.balls += 1;
+			} else if (slave.geneMods.NCS === 1 && slave.balls < 3 && random(1, 100) > 95) {
+				r.push(`${His} <span class="change positive">balls grow slightly</span> to better accommodate ${his} increased cum production.`);
+				slave.balls += 1;
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.ReportSlave} slave
+	 */
+	function femaleHormonesDiet(slave) {
+		if (slave.fuckdoll > 0) {
+			r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s being <span class="lime">feminized.</span>`);
+		} else {
+			if (slave.behavioralQuirk === "insecure") {
+				if (slave.balls > 0) {
+					r.push(`Despite some doubts lurking at the back of ${his} mind, your insistence that ${he} will be prettier if ${he} was more feminine <span class="devotion inc">lets ${him} enjoy</span> the estrogen rich food given to ${him}.`);
+					slave.devotion += 1;
+				} else if (slave.ovaries === 1 || slave.mpreg === 1) {
+					r.push(`Despite some doubts lurking at the back of ${his} mind, your insistence that ${he} will be prettier if ${he} was more fertile <span class="devotion inc">lets ${him} enjoy</span> the estrogen rich food given to ${him}.`);
+					slave.devotion += 1;
+				}
+			}
+		}
+		if ((slave.ovaries === 1 || slave.mpreg === 1) && slave.balls > 0) { // herm
+			if (slave.weight < 30 && slave.weightDirection !== -1) {
+				r.push(`Hormonal changes encourage ${his} body to <span class="change positive">grow softer.</span>`);
+				slave.weight += 1;
+				if (slave.weightDirection === 1) {
+					slave.weight += 2;
+				}
+			}
+			if (slave.geneMods.NCS === 0 && slave.boobs < 500 * gigantomastiaMod) {
+				r.push(`${His} breasts <span class="change positive">grow slightly</span> from the estrogen.`);
+				slave.boobs += 10;
+			}
+			if (slave.geneMods.NCS === 0 && slave.butt < 4 && random(1, 100) > (75 - (rearQuirk * 20))) {
+				r.push(`${His} rear <span class="change positive">rounds out</span> to fit ${his} developing femininity.`);
+				slave.butt += 1;
+			}
+			if (slave.waist > -20) {
+				r.push(`Hormonal changes <span class="change positive">slim ${his} waist.</span>`);
+				slave.waist--;
+			}
+			if (slave.dick > 1 && (((slave.geneMods.NCS === 0) && (random(1, 100) > 95)) || ((slave.geneMods.NCS === 1) && (random(1, 100) > 43)))) {
+				if (slave.geneMods.NCS === 1 && slave.dick > 2) {
+					r.push(`${His} dick <span class="change negative">shrinks down</span> due to ${his} body chemistry.`);
+					slave.dick -= 1;
 				} else {
-					if (slave.behavioralQuirk === "insecure") {
-						r.push(`Despite some doubts lurking at the back of ${his} mind, your insistence that ${he} will be gorgeous if ${he} embraced both halves of ${his} sexuality <span class="devotion inc">lets ${him} enjoy</span> ${his} special diet.`);
-						slave.devotion += 1;
-					}
+					r.push(`${His} dick <span class="change negative">shrinks slightly</span> due to ${his} body chemistry.`);
 				}
-				if (slave.muscles < 90) {
-					r.push(`Hormonal changes encourage ${his} body to <span class="change positive">gain muscle.</span>`);
-					slave.muscles += 1 + slave.geneticQuirks.mGain;
+				slave.dick -= 1;
+			}
+			if (slave.balls > 1 && (((slave.geneMods.NCS === 0) && (random(1, 100) > 95)) || ((slave.geneMods.NCS === 1) && (random(1, 100) > 43)))) {
+				if (slave.geneMods.NCS === 1 && slave.balls > 2) {
+					r.push(`${His} balls <span class="change negative">shrink down</span> due to ${his} body chemistry.`);
+					slave.balls -= 1;
+				} else {
+					r.push(`${His} balls <span class="change negative">shrivel</span> due to ${his} body chemistry.`);
 				}
-				if (slave.weight < 50 && slave.weightDirection !== -1) {
-					r.push(`Hormonal changes encourage ${his} body to <span class="change positive">grow softer.</span>`);
-					slave.weight += 1;
-					if (slave.weightDirection === 1) {
-						slave.weight += 2;
-					}
+				slave.balls -= 1;
+			}
+		} else if (slave.ovaries === 1 || slave.mpreg === 1) { // female
+			if (slave.weight < 40 && slave.weightDirection !== 1) {
+				r.push(`Hormonal changes encourage ${his} body to <span class="change positive">grow softer.</span>`);
+				slave.weight += 1;
+				if (slave.weightDirection === 1) {
+					slave.weight += 2;
 				}
-				if (slave.geneMods.NCS === 0 && slave.boobs < 800 * gigantomastiaMod) {
-					r.push(`${His} breasts <span class="change positive">grow slightly</span> to fit ${his} developing femininity.`);
-					slave.boobs += 10;
-				}
-				if (slave.geneMods.NCS === 0 && slave.butt < 5 && random(1, 100) > (75 - (rearQuirk * 20))) {
-					r.push(`${His} rear <span class="change positive">rounds out</span> to fit ${his} developing femininity.`);
-					slave.butt += 1;
-				}
-				if (slave.geneMods.NCS === 0 && slave.dick < 5 && random(1, 100) > 90) {
-					r.push(`${His} dick <span class="change positive">grows slightly</span> to fit ${his} developing masculinity.`);
-					slave.dick += 1;
-				}
-				if (slave.geneMods.NCS === 0 && slave.balls < 5 && random(1, 100) > 90) {
-					r.push(`${His} balls <span class="change positive">swell</span> to fit ${his} developing masculinity.`);
-					slave.balls += 1;
-				}
-				if (slave.waist < 0) {
-					r.push(`Hormonal changes <span class="change negative">thicken ${his} waist.</span>`);
-					slave.waist++;
-				} else if (slave.waist > 0) {
-					r.push(`Hormonal changes <span class="change positive">thin ${his} waist.</span>`);
-					slave.waist--;
-				}
-				if (slave.fuckdoll === 0) {
-					if (slave.fetish !== "mindbroken") {
-						if (slave.attrXX < 100) {
-							r.push(`${He} begins to find women <span class="change positive">a little more attractive</span> thanks to ${his} specialized hormones.`);
-							slave.attrXX += 1;
-						}
-						if (slave.attrXY < 100) {
-							r.push(`${He} begins to find men <span class="change positive">a little more attractive</span> thanks to ${his} specialized hormones.`);
-							slave.attrXY += 1;
-						}
-					}
-					if (slave.energy < 90) {
-						r.push(`Hormones leave ${him} feeling <span class="change positive">a little more frisky</span> towards others.`);
-						slave.energy += 1;
-					}
+			}
+			if (slave.geneMods.NCS === 0 && slave.boobs < 600 * gigantomastiaMod) {
+				r.push(`${His} breasts <span class="change positive">grow slightly</span> from the estrogen.`);
+				slave.boobs += 10;
+			}
+			if (slave.waist > -30) {
+				r.push(`Hormonal changes <span class="change positive">slim ${his} waist.</span>`);
+				slave.waist--;
+			}
+			if (slave.geneMods.NCS === 0 && slave.butt < 5 && random(1, 100) > (75 - (rearQuirk * 20))) {
+				r.push(`${His} rear <span class="change positive">rounds out</span> to fit ${his} developing femininity.`);
+				slave.butt += 1;
+			}
+		} else if (slave.balls > 0) { // male
+			if (slave.weight < 20 && slave.weightDirection !== 1) {
+				r.push(`Hormonal changes encourage ${his} body to <span class="change positive">grow softer.</span>`);
+				slave.weight += 1;
+				if (slave.weightDirection === 1) {
+					slave.weight += 2;
 				}
-				if (slave.geneticQuirks.galactorrhea === 2 && random(1, 100) < slave.hormoneBalance && slave.lactation === 0) {
-					slave.inappropriateLactation = 1;
+			}
+			if (slave.geneMods.NCS === 0 && slave.boobs < 400 * gigantomastiaMod) {
+				r.push(`${His} breasts <span class="change positive">grow slightly</span> from the estrogen.`);
+				slave.boobs += 10;
+			}
+			if (slave.waist > -10) {
+				r.push(`Hormonal changes <span class="change positive">slim ${his} waist.</span>`);
+				slave.waist--;
+			}
+			if (slave.geneMods.NCS === 0 && slave.butt < 3 && random(1, 100) > (75 - (rearQuirk * 20))) {
+				r.push(`${His} rear <span class="change positive">rounds out</span> to fit ${his} developing femininity.`);
+				slave.butt += 1;
+			}
+			if (slave.dick > 1 && (((slave.geneMods.NCS === 0) && (random(1, 100) > 99)) || ((slave.geneMods.NCS === 1) && (random(1, 100) > 48)))) {
+				if (slave.geneMods.NCS === 1 && slave.dick > 2) {
+					r.push(`${His} dick <span class="change negative">shrinks down</span> due to ${his} body chemistry.`);
+					slave.dick -= 1;
+				} else {
+					r.push(`${His} dick <span class="change negative">shrinks slightly</span> due to ${his} body chemistry.`);
 				}
-				break;
-			case "cleansing": // chem reduce and health plus
-				if (slave.fuckdoll > 0) {
-					r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s <span class="health inc">becoming healthier.</span>`);
-				} else if (slave.fetish === "mindbroken") {
-					r.push(`${His} diet tastes and smells awful, but such things are lost on ${his} broken mind. ${His} body <span class="health inc">appreciates</span> it, however.`);
-				} else if (!canSmell(slave) && !canTaste(slave)) {
-					r.push(`${His} diet tastes and smells awful, but ${he} is incapable of recognizing it, allowing ${him} to feel nothing but its <span class="health inc">significant restorative effect.</span> ${He} <span class="trust inc">trusts you more</span> since you seem to care about ${his} health.`);
-					slave.trust++;
-				} else if (!canSmell(slave) || !canTaste(slave)) {
-					r.push(`${His} diet <span class="mediumorchid">tastes and smells awful,</span> but ${he} is thankfully only partially aware of this, allowing ${him} to appreciate its <span class="health inc">significant restorative effect</span> a bit more. ${He} <span class="trust inc">trusts you more</span> since you seem to care about ${his} health.`);
-					slave.devotion -= 1;
-					slave.trust++;
-				} else if (slave.sexualFlaw === "self hating") {
-					r.push(`${His} diet <span class="devotion inc">tastes and smells awful,</span> the perfect meal for such a wretched creature as ${himself}. ${He} knows you are <span class="health inc">preserving ${his} health</span> but doesn't understand why you'd waste time and credits on ${him}.`);
-					slave.devotion += 2;
+				slave.dick -= 1;
+			}
+			if (slave.balls > 1 && (((slave.geneMods.NCS === 0) && (random(1, 100) > 99)) || ((slave.geneMods.NCS === 1) && (random(1, 100) > 48)))) {
+				if (slave.geneMods.NCS === 1 && slave.balls > 2) {
+					r.push(`${His} balls <span class="change negative">shrink down</span> due to ${his} body chemistry.`);
+					slave.balls -= 1;
 				} else {
-					r.push(`${His} diet <span class="devotion desc">tastes and smells awful</span> but ${he} actively <span class="health inc">feels better</span> the more ${he} eats. ${He} <span class="trust inc">trusts you more</span> since you seem to care about ${his} health.`);
-					slave.devotion -= 2;
-					slave.trust++;
+					r.push(`${His} balls <span class="change negative">shrivel</span> due to ${his} body chemistry.`);
+				}
+				slave.balls -= 1;
+			}
+		}
+		if (slave.fuckdoll === 0) {
+			if (slave.fetish !== "mindbroken") {
+				if (slave.attrXY < 100) {
+					r.push(`${He} begins to find men <span class="change positive">a little more attractive</span> thanks to the female hormones.`);
+					slave.attrXY += 1;
+				}
+			}
+			if (slave.energy < 70) {
+				r.push(`Hormones leave ${him} feeling <span class="change positive">a little more frisky</span> towards others.`);
+				slave.energy += 1;
+			}
+		}
+		if (slave.geneticQuirks.galactorrhea === 2 && random(1, 100) < slave.hormoneBalance && slave.lactation === 0) {
+			slave.inappropriateLactation = 1;
+		}
+	}
+
+	/**
+	 * @param {FC.ReportSlave} slave
+	 */
+	function maleHormonesDiet(slave) {
+		if (slave.fuckdoll > 0) {
+			r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s becoming <span class="lime">masculine.</span>`);
+		} else {
+			if (slave.behavioralQuirk === "insecure") {
+				if (slave.balls > 0) {
+					r.push(`Despite some doubts lurking at the back of ${his} mind, your insistence that ${he} will be handsomer if ${he} was more masculine <span class="devotion inc">lets ${him} enjoy</span> the testosterone rich food given to ${him}.`);
+					slave.devotion += 1;
+				} else if (slave.ovaries === 1 || slave.mpreg === 1) {
+					r.push(`Despite some doubts lurking at the back of ${his} mind, your insistence that ${he} will be handsomer if ${he} was less feminine <span class="devotion inc">lets ${him} enjoy</span> the testosterone rich food given to ${him}.`);
+					slave.devotion += 1;
+				}
+			}
+		}
+		if ((slave.ovaries === 1 || slave.mpreg === 1) && slave.balls > 0) { // herm
+			if (slave.muscles < 30) {
+				r.push(`Hormonal changes encourage ${his} body to <span class="change positive">gain muscle.</span>`);
+				slave.muscles += 1 + slave.geneticQuirks.mGain;
+			}
+			if (slave.geneMods.NCS === 0 && slave.dick < 4 && random(1, 100) > 95) {
+				r.push(`${His} dick <span class="change positive">grows slightly</span> due to the male hormones in ${his} diet.`);
+				slave.dick += 1;
+			}
+			if (slave.geneMods.NCS === 0 && slave.balls < 3 && random(1, 100) > 95) {
+				r.push(`${His} balls <span class="change positive">swell</span> due to the male hormones in ${his} diet.`);
+				slave.balls += 1;
+			}
+			if ((slave.geneMods.NCS === 0 && boobSize > 400) || (slave.geneMods.NCS === 1 && boobSize > 200) && gigantomastiaMod !== 3) {
+				r.push(`${His} breasts <span class="change negative">lose some mass</span> from the lack of estrogen in ${his} diet.`);
+				slave.boobs -= 10;
+				if (slave.geneMods.NCS === 1) {
+					slave.boobs -= 10;
+				}
+			}
+			if (slave.waist < 15) {
+				r.push(`Hormonal changes <span class="change negative">thicken ${his} waist.</span>`);
+				slave.waist++;
+			}
+		} else if (slave.ovaries === 1 || slave.mpreg === 1) { // female
+			if (slave.muscles < 15) {
+				r.push(`Hormonal changes encourage ${his} body to <span class="change positive">gain muscle.</span>`);
+				slave.muscles += 1 + slave.geneticQuirks.mGain;
+			}
+			if ((slave.geneMods.NCS === 0 && boobSize > 500) || (slave.geneMods.NCS === 1 && boobSize > 200) && gigantomastiaMod !== 3) {
+				r.push(`${His} breasts <span class="change negative">lose some mass</span> from the lack of estrogen in ${his} diet.`);
+				slave.boobs -= 10;
+				if (slave.geneMods.NCS === 1) {
+					slave.boobs -= 10;
+				}
+			}
+			if (slave.waist < 0) {
+				r.push(`Hormonal changes <span class="change negative">thicken ${his} waist.</span>`);
+				slave.waist++;
+			}
+		} else if (slave.balls > 0) { // male
+			if (slave.muscles < 60) {
+				r.push(`Hormonal changes encourage ${his} body to <span class="change positive">gain muscle.</span>`);
+				slave.muscles += 1 + slave.geneticQuirks.mGain;
+			}
+			if (slave.geneMods.NCS === 0 && slave.dick < 4 && random(1, 100) > 95) {
+				r.push(`${His} dick <span class="change positive">grows slightly</span> due to the male hormones in ${his} diet.`);
+				slave.dick += 1;
+			}
+			if (slave.waist < 30) {
+				r.push(`Hormonal changes <span class="change negative">thicken ${his} waist.</span>`);
+				slave.waist++;
+			}
+			if (slave.geneMods.NCS === 0 && slave.balls < 3 && random(1, 100) > 95) {
+				r.push(`${His} balls <span class="change positive">swell</span> due to the male hormones in ${his} diet.`);
+				slave.balls += 1;
+			}
+			if (boobSize > 300 && gigantomastiaMod !== 3) {
+				r.push(`${His} breasts <span class="change negative">lose some mass</span> to better suit ${his} body chemistry.`);
+				slave.boobs -= 10;
+			}
+		}
+		if (slave.fuckdoll === 0) {
+			if (slave.fetish !== "mindbroken") {
+				if (slave.attrXX < 100) {
+					r.push(`${He} begins to find women <span class="change positive">a little more attractive</span> thanks to the male hormones.`);
+					slave.attrXX += 1;
 				}
-				if (slave.health.condition <= 90) {
-					improveCondition(slave, 2);
+			}
+			if (slave.energy < 70) {
+				r.push(`Hormones leave ${him} feeling <span class="change positive">a little more frisky</span> towards others.`);
+				slave.energy += 1;
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.ReportSlave} slave
+	 */
+	function futaHormonesDiet(slave) {
+		if (slave.fuckdoll > 0) {
+			r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s becoming <span class="change positive">masculine.</span>`);
+		} else {
+			if (slave.behavioralQuirk === "insecure") {
+				r.push(`Despite some doubts lurking at the back of ${his} mind, your insistence that ${he} will be gorgeous if ${he} embraced both halves of ${his} sexuality <span class="devotion inc">lets ${him} enjoy</span> ${his} special diet.`);
+				slave.devotion += 1;
+			}
+		}
+		if (slave.muscles < 90) {
+			r.push(`Hormonal changes encourage ${his} body to <span class="change positive">gain muscle.</span>`);
+			slave.muscles += 1 + slave.geneticQuirks.mGain;
+		}
+		if (slave.weight < 50 && slave.weightDirection !== -1) {
+			r.push(`Hormonal changes encourage ${his} body to <span class="change positive">grow softer.</span>`);
+			slave.weight += 1;
+			if (slave.weightDirection === 1) {
+				slave.weight += 2;
+			}
+		}
+		if (slave.geneMods.NCS === 0 && slave.boobs < 800 * gigantomastiaMod) {
+			r.push(`${His} breasts <span class="change positive">grow slightly</span> to fit ${his} developing femininity.`);
+			slave.boobs += 10;
+		}
+		if (slave.geneMods.NCS === 0 && slave.butt < 5 && random(1, 100) > (75 - (rearQuirk * 20))) {
+			r.push(`${His} rear <span class="change positive">rounds out</span> to fit ${his} developing femininity.`);
+			slave.butt += 1;
+		}
+		if (slave.geneMods.NCS === 0 && slave.dick < 5 && random(1, 100) > 90) {
+			r.push(`${His} dick <span class="change positive">grows slightly</span> to fit ${his} developing masculinity.`);
+			slave.dick += 1;
+		}
+		if (slave.geneMods.NCS === 0 && slave.balls < 5 && random(1, 100) > 90) {
+			r.push(`${His} balls <span class="change positive">swell</span> to fit ${his} developing masculinity.`);
+			slave.balls += 1;
+		}
+		if (slave.waist < 0) {
+			r.push(`Hormonal changes <span class="change negative">thicken ${his} waist.</span>`);
+			slave.waist++;
+		} else if (slave.waist > 0) {
+			r.push(`Hormonal changes <span class="change positive">thin ${his} waist.</span>`);
+			slave.waist--;
+		}
+		if (slave.fuckdoll === 0) {
+			if (slave.fetish !== "mindbroken") {
+				if (slave.attrXX < 100) {
+					r.push(`${He} begins to find women <span class="change positive">a little more attractive</span> thanks to ${his} specialized hormones.`);
+					slave.attrXX += 1;
 				}
-				if (slave.chem > 2) {
-					slave.chem -= 2;
+				if (slave.attrXY < 100) {
+					r.push(`${He} begins to find men <span class="change positive">a little more attractive</span> thanks to ${his} specialized hormones.`);
+					slave.attrXY += 1;
 				}
-				if (slave.health.condition > 90 && slave.chem < 10) {
+			}
+			if (slave.energy < 90) {
+				r.push(`Hormones leave ${him} feeling <span class="change positive">a little more frisky</span> towards others.`);
+				slave.energy += 1;
+			}
+		}
+		if (slave.geneticQuirks.galactorrhea === 2 && random(1, 100) < slave.hormoneBalance && slave.lactation === 0) {
+			slave.inappropriateLactation = 1;
+		}
+	}
+
+	/**
+	 * Reduce .chem and increase health
+	 * @param {FC.ReportSlave} slave
+	 */
+	function cleansingDiet(slave) {
+		if (slave.fuckdoll > 0) {
+			r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s <span class="health inc">becoming healthier.</span>`);
+		} else if (slave.fetish === "mindbroken") {
+			r.push(`${His} diet tastes and smells awful, but such things are lost on ${his} broken mind. ${His} body <span class="health inc">appreciates</span> it, however.`);
+		} else if (!canSmell(slave) && !canTaste(slave)) {
+			r.push(`${His} diet tastes and smells awful, but ${he} is incapable of recognizing it, allowing ${him} to feel nothing but its <span class="health inc">significant restorative effect.</span> ${He} <span class="trust inc">trusts you more</span> since you seem to care about ${his} health.`);
+			slave.trust++;
+		} else if (!canSmell(slave) || !canTaste(slave)) {
+			r.push(`${His} diet <span class="devotion dec">tastes and smells awful,</span> but ${he} is thankfully only partially aware of this, allowing ${him} to appreciate its <span class="health inc">significant restorative effect</span> a bit more. ${He} <span class="trust inc">trusts you more</span> since you seem to care about ${his} health.`);
+			slave.devotion -= 1;
+			slave.trust++;
+		} else if (slave.sexualFlaw === "self hating") {
+			r.push(`${His} diet <span class="devotion inc">tastes and smells awful,</span> the perfect meal for such a wretched creature as ${himself}. ${He} knows you are <span class="health inc">preserving ${his} health</span> but doesn't understand why you'd waste time and credits on ${him}.`);
+			slave.devotion += 2;
+		} else {
+			r.push(`${His} diet <span class="devotion desc">tastes and smells awful</span> but ${he} actively <span class="health inc">feels better</span> the more ${he} eats. ${He} <span class="trust inc">trusts you more</span> since you seem to care about ${his} health.`);
+			slave.devotion -= 2;
+			slave.trust++;
+		}
+		if (slave.health.condition <= 90) {
+			improveCondition(slave, 2);
+		}
+		if (slave.chem > 2) {
+			slave.chem -= 2;
+		}
+		if (slave.health.condition > 90 && slave.chem < 10) {
+			if (slave.fuckdoll > 0) {
+				r.push(`${He} can't get any healthier. <span class="noteworthy">${His} cleansing diet has been ended.</span>`);
+			} else {
+				r.push(`${His} health, all things considered, cannot get much better. <span class="noteworthy">${His} cleansing diet has ended.</span>`);
+			}
+			slave.diet = "healthy";
+		}
+	}
+
+	/**
+	 * Increases Fertility
+	 * + ovum and small boosts to energy and attrXY
+	 * @param {FC.ReportSlave} slave
+	 */
+	function fertilityDiet(slave) {
+		const superFetKnown = (slave.geneticQuirks.superfetation === 2 && V.geneticMappingUpgrade >= 1);
+		if (slave.fuckdoll > 0) {
+			r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s being <span class="change positive">prepared to carry multiples.</span>`);
+		}
+		if (!isFertile(slave) || (slave.preg !== 0)) {
+			if (!superFetKnown) {
+				if (slave.pregKnown === 0 && slave.preg > 0) {
 					if (slave.fuckdoll > 0) {
-						r.push(`${He} can't get any healthier. <span class="noteworthy">${His} cleansing diet has been ended.</span>`);
+						r.push(`${His} suit alerts you to the diet not working due to <span class="pregnant">pregnancy.</span>`);
 					} else {
-						r.push(`${His} health, all things considered, cannot get much better. <span class="noteworthy">${His} cleansing diet has ended.</span>`);
+						r.push(`The diet is not properly working; tests reveal the reason is a <span class="pregnant">new pregnancy.</span>`);
 					}
+					slave.pregKnown = 1;
+					r.push(`<span class="noteworthy">${His} fertility diet has been ended.</span>`);
 					slave.diet = "healthy";
-				}
-				break;
-			case "fertility": // + ovum and small boosts to energy and attrXY
-				superFetKnown = (slave.geneticQuirks.superfetation === 2 && V.geneticMappingUpgrade >= 1);
-				if (slave.fuckdoll > 0) {
-					r.push(`The ports in Fuckdoll suits allow total dietary control, and ${he}'s barely aware ${he}'s being <span class="change positive">prepared to carry multiples.</span>`);
-				}
-				if (!isFertile(slave) || (slave.preg !== 0)) {
-					if (!superFetKnown) {
-						if (slave.pregKnown === 0 && slave.preg > 0) {
-							if (slave.fuckdoll > 0) {
-								r.push(`${His} suit alerts you to the diet not working due to <span class="pregnant">pregnancy.</span>`);
-							} else {
-								r.push(`The diet is not properly working; tests reveal the reason is a <span class="pregnant">new pregnancy.</span>`);
-							}
-							slave.pregKnown = 1;
-							r.push(`<span class="noteworthy">${His} fertility diet has been ended.</span>`);
-							slave.diet = "healthy";
-						} else {
-							if (slave.fuckdoll > 0) {
-								r.push(`${He} is no longer able to be impregnated.`);
-							} else {
-								r.push(`${He} is no longer able to get pregnant, for one reason or another.`);
-							}
-							r.push(`<span class="noteworthy">${His} fertility diet has been ended.</span>`);
-							slave.diet = "healthy";
-						}
-					}
-				}
-				if (slave.diet === "fertility" && slave.fuckdoll === 0) {
-					if (slave.fetish === "mindbroken") {
-						r.push(`${He} doesn't really notice that <span class="change positive">${his} body is being prepared to`);
-						if (superFetKnown) {
-							r.push(`develop additional pregnancies`);
-						} else {
-							r.push(`carry multiples`);
-						}
-						r.push(`</span> by ${his} diet.`);
-						if (slave.energy < 45 && slave.energy > 20) {
-							r.push(`${He} begins craving <span class="libido inc">sex for the sole purpose of reproduction,</span> even if ${he} doesn't comprehend it.`);
-							slave.energy++;
-						}
-					} else if (slave.sexualFlaw === "breeder") {
-						r.push(`${His} diet is <span class="change positive">prepping ${him} to`);
-						if (superFetKnown) {
-							r.push(`develop additional pregnancies,`);
-						} else {
-							r.push(`carry multiple fetuses,`);
-						}
-						r.push(`</span> and ${he} feels it. ${He}`);
-						if (slave.bellyPreg >= 1000) {
-							r.push(`<span class="devotion inc">eagerly awaits to find just how pregnant ${he} can become.</span>`);
-						} else {
-							r.push(`<span class="devotion inc">eagerly awaits to swell with children.</span>`);
-						}
-						slave.devotion += 2;
-						if (slave.attrXY < 70) {
-							r.push(`${He} certainly notices <span class="improvement">how much more attractive men are.</span>`);
-							slave.attrXY += 2;
-						}
-						if (slave.energy < 45 && slave.energy > 20) {
-							r.push(`${He} begins craving <span class="libido inc">penetrative sex and hot loads left inside ${him}</span> as well.`);
-							slave.energy++;
-						}
+				} else {
+					if (slave.fuckdoll > 0) {
+						r.push(`${He} is no longer able to be impregnated.`);
 					} else {
-						r.push(`${He} doesn't really notice that <span class="change positive">${his} body is being prepared to`);
-						if (superFetKnown) {
-							r.push(`develop additional pregnancies`);
-						} else {
-							r.push(`carry multiples`);
-						}
-						r.push(`</span> by ${his} diet, other than the slight`);
-						if (slave.bellyPreg >= 1000) {
-							r.push(`tingling in ${his} swollen belly.`);
-						} else {
-							r.push(`tingle in ${his} lower belly.`);
-						}
-						if (slave.attrXY < 70) {
-							r.push(`${He} certainly notices <span class="improvement">how much more attractive men are,</span> however.`);
-							slave.attrXY += 2;
-						}
-						if (slave.energy < 45 && slave.energy > 20) {
-							r.push(`${He} begins craving <span class="libido inc">penetrative sex and hot loads left inside ${him}</span> as well.`);
-							slave.energy++;
-						}
+						r.push(`${He} is no longer able to get pregnant, for one reason or another.`);
 					}
+					r.push(`<span class="noteworthy">${His} fertility diet has been ended.</span>`);
+					slave.diet = "healthy";
+				}
+			}
+		}
+		if (slave.diet === "fertility" && slave.fuckdoll === 0) {
+			if (slave.fetish === "mindbroken") {
+				r.push(`${He} doesn't really notice that <span class="change positive">${his} body is being prepared to`);
+				if (superFetKnown) {
+					r.push(`develop additional pregnancies`);
+				} else {
+					r.push(`carry multiples`);
+				}
+				r.push(`</span> by ${his} diet.`);
+				if (slave.energy < 45 && slave.energy > 20) {
+					r.push(`${He} begins craving <span class="libido inc">sex for the sole purpose of reproduction,</span> even if ${he} doesn't comprehend it.`);
+					slave.energy++;
+				}
+			} else if (slave.sexualFlaw === "breeder") {
+				r.push(`${His} diet is <span class="change positive">prepping ${him} to`);
+				if (superFetKnown) {
+					r.push(`develop additional pregnancies,`);
+				} else {
+					r.push(`carry multiple fetuses,`);
+				}
+				r.push(`</span> and ${he} feels it. ${He}`);
+				if (slave.bellyPreg >= 1000) {
+					r.push(`<span class="devotion inc">eagerly awaits to find just how pregnant ${he} can become.</span>`);
+				} else {
+					r.push(`<span class="devotion inc">eagerly awaits to swell with children.</span>`);
+				}
+				slave.devotion += 2;
+				if (slave.attrXY < 70) {
+					r.push(`${He} certainly notices <span class="improvement">how much more attractive men are.</span>`);
+					slave.attrXY += 2;
+				}
+				if (slave.energy < 45 && slave.energy > 20) {
+					r.push(`${He} begins craving <span class="libido inc">penetrative sex and hot loads left inside ${him}</span> as well.`);
+					slave.energy++;
+				}
+			} else {
+				r.push(`${He} doesn't really notice that <span class="change positive">${his} body is being prepared to`);
+				if (superFetKnown) {
+					r.push(`develop additional pregnancies`);
+				} else {
+					r.push(`carry multiples`);
+				}
+				r.push(`</span> by ${his} diet, other than the slight`);
+				if (slave.bellyPreg >= 1000) {
+					r.push(`tingling in ${his} swollen belly.`);
+				} else {
+					r.push(`tingle in ${his} lower belly.`);
+				}
+				if (slave.attrXY < 70) {
+					r.push(`${He} certainly notices <span class="improvement">how much more attractive men are,</span> however.`);
+					slave.attrXY += 2;
 				}
+				if (slave.energy < 45 && slave.energy > 20) {
+					r.push(`${He} begins craving <span class="libido inc">penetrative sex and hot loads left inside ${him}</span> as well.`);
+					slave.energy++;
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.ReportSlave} slave
+	 */
+	function foodEffects(slave) {
+		switch (slave.diet) {
+			case "restricted": // weight loss
+				restrictedDiet(slave);
+				break;
+			case "fattening": // weight gain
+				fatteningDiet(slave);
+				break;
+			case "corrective": // normalizes weight towards 0
+				correctiveDiet(slave);
+				break;
+			case "muscle building": // Muscle Gain
+				muscleBuildingDiet(slave);
+				break;
+			case "slimming": // Muscle Loss
+				slimmingDiet(slave);
+				break;
+			case "cum production":
+				cumProductionDiet(slave);
+				break;
+			case "XX":
+				femaleHormonesDiet(slave);
+				break;
+			case "XY":
+				maleHormonesDiet(slave);
+				break;
+			case "XXY":
+				futaHormonesDiet(slave);
+				break;
+			case "cleansing": // chem reduce and health plus
+				cleansingDiet(slave);
+				break;
+			case "fertility":
+				fertilityDiet(slave);
 				break;
 		}
 	}
@@ -1500,7 +1522,36 @@ App.SlaveAssignment.diet = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
+	 * @returns {string}
+	 */
+	function ejaculateDescription(slave) {
+		if (slave.fetish === "masochist") {
+			return `ejaculate of an abusive lover`;
+		} else if (slave.fetish === "boobs") {
+			return `fresh milk from a pretty dairy cow`;
+		} else if (slave.fetish === "submissive") {
+			return `ejaculate of a dominant partner`;
+		} else if (slave.fetish === "pregnancy") {
+			if (slave.ovaries === 1 || slave.mpreg === 1) {
+				return `ejaculate of ${his} future baby's father`;
+			} else {
+				return `key to someday siring a child.`;
+			}
+		} else if (slave.fetish === "sadist") {
+			return `ejaculate of a painslut ${he} recently milked`;
+		} else if (slave.fetish === "buttslut") {
+			return `ejaculate of a cock that just came from ${his} butt`;
+		} else if (slave.fetish === "dom") {
+			return `ejaculate of a weak-minded submissive`;
+		} else if (slave.fetish === "humiliation") {
+			return `ejaculate of a publicly used slut`;
+		} else {
+			return `ejaculate of a gentle lover`;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
 	 */
 	function cumDiet(slave) {
 		if (slave.devotion > 20) { // Diet effects for Devotion over 20 — For ALL cum diets
@@ -1567,29 +1618,7 @@ App.SlaveAssignment.diet = (function() {
 									slave.energy += 1;
 								} else {
 									r.push(`${His} high sex drive helps ${him} pretend ${his} heavy cum-based diet is the`);
-									if (slave.fetish === "masochist") {
-										r.push(`ejaculate of an abusive lover`);
-									} else if (slave.fetish === "boobs") {
-										r.push(`fresh milk from a pretty dairy cow`);
-									} else if (slave.fetish === "submissive") {
-										r.push(`ejaculate of a dominant partner`);
-									} else if (slave.fetish === "pregnancy") {
-										if (slave.ovaries === 1 || slave.mpreg === 1) {
-											r.push(`ejaculate of ${his} future baby's father`);
-										} else {
-											r.push(`key to someday siring a child.`);
-										}
-									} else if (slave.fetish === "sadist") {
-										r.push(`ejaculate of a painslut ${he} recently milked`);
-									} else if (slave.fetish === "buttslut") {
-										r.push(`ejaculate of a cock that just came from ${his} butt`);
-									} else if (slave.fetish === "dom") {
-										r.push(`ejaculate of a weak-minded submissive`);
-									} else if (slave.fetish === "humiliation") {
-										r.push(`ejaculate of a publicly used slut`);
-									} else {
-										r.push(`ejaculate of a gentle lover`);
-									}
+									r.push(ejaculateDescription(slave));
 									r.push(`— helping ${him} keep ${his} <span class="devotion dec">unpleasant</span> food down.`);
 									slave.devotion -= 1;
 								}
@@ -1599,29 +1628,7 @@ App.SlaveAssignment.diet = (function() {
 									slave.energy += 2;
 								} else {
 									r.push(`${His} high sex drive helps ${him} pretend ${his} cum-supplemented diet is the`);
-									if (slave.fetish === "masochist") {
-										r.push(`ejaculate of an abusive lover`);
-									} else if (slave.fetish === "boobs") {
-										r.push(`fresh milk from a pretty dairy cow`);
-									} else if (slave.fetish === "submissive") {
-										r.push(`ejaculate of a dominant partner`);
-									} else if (slave.fetish === "pregnancy") {
-										if (slave.ovaries === 1 || slave.mpreg === 1) {
-											r.push(`ejaculate of ${his} future baby's father`);
-										} else {
-											r.push(`key to someday siring a child.`);
-										}
-									} else if (slave.fetish === "sadist") {
-										r.push(`ejaculate of a painslut ${he} recently milked`);
-									} else if (slave.fetish === "buttslut") {
-										r.push(`ejaculate of a cock that just came from ${his} butt`);
-									} else if (slave.fetish === "dom") {
-										r.push(`ejaculate of a weak-minded submissive`);
-									} else if (slave.fetish === "humiliation") {
-										r.push(`ejaculate of a publicly used slut`);
-									} else {
-										r.push(`ejaculate of a gentle lover`);
-									}
+									r.push(ejaculateDescription(slave));
 									r.push(`— helping ${him} swallow ${his} food without complaint.`);
 								}
 							}
@@ -1701,4 +1708,4 @@ App.SlaveAssignment.diet = (function() {
 			slave.devotion--;
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saDrugs.js b/src/endWeek/saDrugs.js
index 99eec5cc452937a3646bbd9c72e32be1aa0f8da8..4d318157ab68b5454414d7fafca66d7f7fa3d7be 100644
--- a/src/endWeek/saDrugs.js
+++ b/src/endWeek/saDrugs.js
@@ -1,66 +1,86 @@
-App.SlaveAssignment.drugs = (function() {
-	"use strict";
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.drugs = function saDrugs(slave) {
+	let r = "";
 
-	let r;
+	const intensive = (slave.drugs === "intensive breast injections" || slave.drugs === "intensive butt injections" ||
+		slave.drugs === "intensive penis enhancement" || slave.drugs === "intensive testicle enhancement") ? 1 : 0;
+	const gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
+	const rearLipedemaMod = slave.geneticQuirks.rearLipedema === 2 ? 1 : 0;
+	const boobSize = slave.boobs - slave.boobsImplant - slave.boobsMilk;
+	const buttSize = slave.butt - slave.buttImplant;
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let He;
-	let His;
+	const {
+		he, him, his, himself, He, His
+	} = getPronouns(slave);
 
-	let intensive;
-	let gigantomastiaMod;
-	let rearLipedemaMod;
-	let growth;
-	let shrinkage;
-	let boobSize;
-	let buttSize;
+	if (slave.drugs !== "no drugs") {
+		drugEffects(slave);
+	}
+	if (slave.pregControl !== "none" && slave.pregKnown === 1) {
+		pregnancyDrugEffects(slave);
+	}
+	if (slave.curatives > 1) {
+		curativeEffects(slave);
+	}
+	if (slave.aphrodisiacs > 0) {
+		aphrodisiacEffects(slave);
+	}
+	healthAndWellness(slave);
+	if (slave.drugs !== "no drugs") {
+		drugExpiry(slave);
+	}
 
-	return saDrugs;
+	return r;
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 * @returns {string}
 	 */
-	function saDrugs(slave) {
-		r = ``;
-		gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
-		rearLipedemaMod = slave.geneticQuirks.rearLipedema === 2 ? 1 : 0;
-		boobSize = slave.boobs - slave.boobsImplant - slave.boobsMilk;
-		buttSize = slave.butt - slave.buttImplant;
-
-		({
-			he, him, his, himself, He, His
-		} = getPronouns(slave));
-
-		if (slave.drugs !== "no drugs") {
-			drugEffects(slave);
-		}
-		if (slave.pregControl !== "none" && slave.pregKnown === 1) {
-			pregnancyDrugEffects(slave);
-		}
-		if (slave.curatives > 1) {
-			curativeEffects(slave);
-		}
-		if (slave.aphrodisiacs > 0) {
-			aphrodisiacEffects(slave);
-		}
-		healthAndWellness(slave);
-		if (slave.drugs !== "no drugs") {
-			drugExpiry(slave);
+	function galactorrheaTriggerCheck(slave) {
+		if (slave.geneticQuirks.galactorrhea === 2 && slave.lactation === 0 && random(1, 100) <= slave.hormoneBalance) {
+			slave.lactation = 1;
+			slave.lactationDuration = 2;
+			if (V.geneticMappingUpgrade >= 1) {
+				return ` The sudden surge of hormones has unsurprisingly <span class="lime">triggered ${his} galactorrhea.</span>`;
+			} else {
+				return ` Hormonal effects have caused ${him} to <span class="lime">begin lactating.</span>`;
+			}
 		}
+		return "";
+	}
 
-		return r;
+	/**
+	 * Decreases butt growth if NCS is active.
+	 *
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {number} growth without NCS applied
+	 * @returns {number}
+	 */
+	function ncsFightsButtGrowth(slave, growth) {
+		if (slave.geneMods.NCS === 1) {
+			growth = Math.trunc(growth / 2.2);
+			r += ` ${His} <span class="orange">NCS</span> kicks in fighting the butt growth, `;
+			if (growth > 1) {
+				r += `converting the excess fat into sexual energy.`;
+			} else {
+				r += `but has no effect.`;
+			}
+			slave.energy += growth;
+		}
+		return growth;
 	}
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
 	 */
 	function drugEffects(slave) {
-		intensive = (slave.drugs === "intensive breast injections" || slave.drugs === "intensive butt injections" || slave.drugs === "intensive penis enhancement" || slave.drugs === "intensive testicle enhancement") ? 1 : 0;
+		let dietInfluence;
+		let growth;
+		let shrinkage;
+
 		r += ` `;
 		switch (slave.drugs) {
 			case "hormone enhancers":
@@ -72,8 +92,10 @@ App.SlaveAssignment.drugs = (function() {
 					slave.drugs = "no drugs";
 				} else if (slave.chastityPenis === 1) {
 					r += `A tight cage around a dick forced hard are a bad mix so <span class="yellow">${his} drug regimen has been ended.</span>`;
+					slave.drugs = "no drugs";
 				} else if (slave.health.condition <= -50) {
 					r += `${He} is too unwell to risk further health complications from priapism. <span class="yellow">${His} drug regimen has been ended.</span>`;
+					slave.drugs = "no drugs";
 				} else if (slave.dick > 10) {
 					r += `${His} dick is so enormous that attempts to force an erection would kill ${him}. <span class="yellow">${His} drug regimen has been mercifully ended.</span>`;
 					slave.drugs = "no drugs";
@@ -463,15 +485,7 @@ App.SlaveAssignment.drugs = (function() {
 				if (slave.geneticQuirks.macromastia === 3 && jsRandom(1, 300) < slave.hormoneBalance) {
 					slave.geneticQuirks.macromastia = 2;
 				}
-				if (slave.geneticQuirks.galactorrhea === 2 && slave.lactation === 0 && random(1, 100) <= slave.hormoneBalance) {
-					if (V.geneticMappingUpgrade >= 1) {
-						r += ` The sudden surge of hormones has unsurprisingly <span class="lime">triggered ${his} galactorrhea.</span>`;
-					} else {
-						r += ` Hormonal effects have caused ${him} to <span class="lime">begin lactating.</span>`;
-					}
-					slave.lactation = 1;
-					slave.lactationDuration = 2;
-				}
+				r += galactorrheaTriggerCheck(slave);
 				break;
 			case "nipple enhancers": {
 				let nippleThreshold = ((60 - (V.injectionUpgrade * 15)) / (1 + slave.geneMods.NCS));
@@ -541,74 +555,53 @@ App.SlaveAssignment.drugs = (function() {
 					r += ` advanced`;
 				}
 				r += ` growth hormones, right into ${his} buttocks;</span>`;
+				dietInfluence = false;
 				if (slave.diet === "fattening") {
 					r += ` all the food ${he}'s required to consume fuels growth, `;
-					if (slave.health.condition > -20) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
+					dietInfluence = true;
 					growth += 2;
 				} else if (slave.diet === "restricted") {
 					r += ` ${his} restricted diet means ${his} body has few resources to grow on, `;
-					if (slave.health.condition > -20) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
+					dietInfluence = true;
 					growth -= 2;
 				} else if (slave.weight > 130) {
 					r += ` the generous diet ${he} eats to maintain ${his} fat body helps support growth, `;
-					if (slave.health.condition > -20) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
+					dietInfluence = true;
 					growth += 3;
 				} else if (slave.weight > 30) {
 					r += ` the generous diet ${he} eats to maintain ${his} fat body helps support growth, `;
-					if (slave.health.condition > -20) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
+					dietInfluence = true;
 					growth++;
 				} else if (slave.weight <= -30) {
 					r += ` the diet ${he} is required to maintain to keep slim impedes growth, `;
+					dietInfluence = true;
+					growth--;
+				}
+				if (dietInfluence) {
 					if (slave.health.condition > -20) {
 						r += `and`;
 					} else {
 						r += `but`;
 					}
-					growth--;
 				}
 				if (slave.health.condition > 80) {
 					r += ` ${his} perfect health supports growth extremely well, `;
-					if (slave.butt < 6) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
 					growth++;
 				} else if (slave.health.condition > -20) {
 					r += ` ${his} health supports growth, `;
-					if (slave.butt < 6) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
 				} else {
 					r += ` ${his} poor health does not support steady growth, `;
-					if (slave.butt < 6) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
 					growth--;
 				}
+				if (slave.butt < 6) {
+					r += `and`;
+				} else {
+					r += `but`;
+				}
 				r += ` ${his}`;
 				if (slave.butt < 2) {
 					r += ` modest rear tends to grow quickly.`;
+					growth += 3;
 				} else if (slave.butt < 4) {
 					r += ` big behind tends to grow readily.`;
 					growth += 2;
@@ -627,16 +620,7 @@ App.SlaveAssignment.drugs = (function() {
 					}
 				}
 				growth *= 0.2;
-				if (slave.geneMods.NCS === 1) {
-					growth = Math.trunc(growth / 2.2);
-					r += ` ${His} <span class="orange">NCS</span> kicks in fighting the butt growth, `;
-					if (growth > 1) {
-						r += `converting the excess fat into sexual energy.`;
-					} else {
-						r += `but has no effect.`;
-					}
-					slave.energy += growth;
-				}
+				growth = ncsFightsButtGrowth(slave, growth);
 				slave.butt += Math.clamp(growth, 0, 2 + rearLipedemaMod);
 				if (slave.geneMods.rapidCellGrowth !== 1) {
 					if (intensive) {
@@ -674,71 +658,49 @@ App.SlaveAssignment.drugs = (function() {
 					r += ` advanced`;
 				}
 				r += ` hyper growth hormones, right into ${his} buttocks;</span>`;
+				dietInfluence = false;
 				if (slave.diet === "fattening") {
 					r += ` all the food ${he}'s required to consume fuels growth, `;
-					if (slave.health.condition > -20) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
+					dietInfluence = true;
 					growth += 0.2;
 				} else if (slave.diet === "restricted") {
 					r += ` ${his} restricted diet means ${his} body has few resources to grow on, `;
-					if (slave.health.condition > -20) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
+					dietInfluence = true;
 					growth -= 0.2;
 				} else if (slave.weight > 130) {
 					r += ` the enormous diet ${he} eats to maintain ${his} hugely fat body helps support growth, `;
-					if (slave.health.condition > -20) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
+					dietInfluence = true;
 					growth += 0.2;
 				} else if (slave.weight > 30) {
 					r += ` the generous diet ${he} eats to maintain ${his} fat body helps support growth, `;
-					if (slave.health.condition > -20) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
+					dietInfluence = true;
 					growth += 0.1;
 				} else if (slave.weight <= -30) {
 					r += ` the diet ${he} is required to maintain to keep slim impedes growth, `;
+					dietInfluence = true;
+					growth -= 0.1;
+				}
+				if (dietInfluence) {
 					if (slave.health.condition > -20) {
 						r += `and`;
 					} else {
 						r += `but`;
 					}
-					growth -= 0.1;
 				}
 				if (slave.health.condition > 80) {
 					r += ` ${his} perfect health supports growth extremely well, `;
-					if (slave.butt < 10) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
 					growth += 0.5;
 				} else if (slave.health.condition > -20) {
 					r += ` ${his} health supports growth reasonably well, `;
-					if (slave.butt < 10) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
 				} else {
 					r += ` ${his} poor health does not support steady growth, `;
-					if (slave.butt < 10) {
-						r += `and`;
-					} else {
-						r += `but`;
-					}
 					growth -= 0.1;
 				}
+				if (slave.butt < 10) {
+					r += `and`;
+				} else {
+					r += `but`;
+				}
 				r += ` ${his} `;
 				if (slave.butt < 6) {
 					r += `modest rear tends to grow quickly.`;
@@ -761,16 +723,7 @@ App.SlaveAssignment.drugs = (function() {
 						r += ` The drugs seem to have an added effect on ${him}.`;
 					}
 				}
-				if (slave.geneMods.NCS === 1) {
-					growth = Math.trunc(growth / 2.2);
-					r += ` ${His} <span class="orange">NCS</span> kicks in fighting the butt growth, `;
-					if (growth > 1) {
-						r += `converting the excess fat into sexual energy.`;
-					} else {
-						r += `but has no effect.`;
-					}
-					slave.energy += growth;
-				}
+				growth = ncsFightsButtGrowth(slave, growth);
 				if (growth > 1 || slave.geneMods.NCS === 1) {
 					slave.butt += growth;
 				} else {
@@ -974,14 +927,15 @@ App.SlaveAssignment.drugs = (function() {
 							ageMod = 0.5;
 						}
 					}
-					// evaluate against slave expected height...
-					let heightDiff = slave.height / Height.forAge(slave.height, slave);
-					// if ${he} is taller than the expected height the growth is reduced, if shorter accelerated proportionally to the distance from the expected height
-					if (heightDiff >= 1) {
-						heightDiff = 1 - heightDiff;
+					// evaluate against slave expected height, with neoteny slaves comparing against expected height for 12 year olds...
+					let heightDiff
+					if (slave.geneticQuirks.neoteny === 2 && slave.physicalAge > 12) {
+						heightDiff = (slave.height - slave.heightImplant * 10) / Height.mean(slave.nationality, slave.race, slave.genes, 12);
 					} else {
-						heightDiff--;
+						heightDiff = (slave.height - slave.heightImplant * 10) / Height.mean(slave);
 					}
+					// if ${he} is taller than the expected height the growth is reduced, if shorter accelerated proportionally to the distance from the expected height
+					heightDiff = 1 - heightDiff;
 					// ...and calculates final value
 					growth = (growth + growth * heightDiff) * ageMod;
 					if (slave.geneMods.NCS === 0) {
@@ -1046,15 +1000,7 @@ App.SlaveAssignment.drugs = (function() {
 					if (slave.energy > 5) {
 						slave.energy -= 5;
 					}
-					if (slave.geneticQuirks.galactorrhea === 2 && slave.lactation === 0 && random(1, 100) <= slave.hormoneBalance) {
-						if (V.geneticMappingUpgrade >= 1) {
-							r += ` The sudden surge of hormones has unsurprisingly <span class="lime">triggered ${his} galactorrhea.</span>`;
-						} else {
-							r += ` Hormonal effects have caused ${him} to <span class="lime">begin lactating.</span>`;
-						}
-						slave.lactation = 1;
-						slave.lactationDuration = 2;
-					}
+					r += galactorrheaTriggerCheck(slave);
 				}
 				break;
 			case "penis enhancement":
@@ -1254,15 +1200,7 @@ App.SlaveAssignment.drugs = (function() {
 						slave.lactationDuration = 1;
 					}
 				}
-				if (slave.geneticQuirks.galactorrhea === 2 && slave.lactation === 0 && random(1, 100) <= slave.hormoneBalance) {
-					if (V.geneticMappingUpgrade >= 1) {
-						r += ` The sudden surge of hormones has unsurprisingly <span class="lime">triggered ${his} galactorrhea.</span>`;
-					} else {
-						r += ` Hormonal effects have caused ${him} to <span class="lime">begin lactating.</span>`;
-					}
-					slave.lactation = 1;
-					slave.lactationDuration = 2;
-				}
+				r += galactorrheaTriggerCheck(slave);
 				if (slave.attrXY < 100 && jsRandom(0, 10) < slave.health.condition) {
 					r += ` The hormonal changes produced by the fertility drugs cause ${him} to begin <span class="improvement">finding men more attractive.</span>`;
 					slave.attrXY += jsRandom(5, 10);
@@ -1308,15 +1246,7 @@ App.SlaveAssignment.drugs = (function() {
 						slave.lactationDuration = 1;
 					}
 				}
-				if (slave.geneticQuirks.galactorrhea === 2 && slave.lactation === 0 && random(1, 100) <= slave.hormoneBalance) {
-					if (V.geneticMappingUpgrade >= 1) {
-						r += ` The sudden surge of hormones has unsurprisingly <span class="lime">triggered ${his} galactorrhea.</span>`;
-					} else {
-						r += ` Hormonal effects have caused ${him} to <span class="lime">begin lactating.</span>`;
-					}
-					slave.lactation = 1;
-					slave.lactationDuration = 2;
-				}
+				r += galactorrheaTriggerCheck(slave);
 				break;
 			case "appetite suppressors":
 				if (slave.weight <= -95) {
@@ -1538,13 +1468,15 @@ App.SlaveAssignment.drugs = (function() {
 					slave.boobs -= 100 * factor;
 				} else if (V.geneticMappingUpgrade >= 1) {
 					r += ` breasts to no avail; ${his} body refuses to allow ${his} breasts to shrink, and as such, <span class="yellow">${his} drug regimen has been ended.</span>`;
+					slave.drugs = "no drugs";
 				} else {
 					r += ` breasts to no avail; <span class="yellow">${his} drug regimen has been ended.</span>`;
+					slave.drugs = "no drugs";
 				}
 				break;
 			case "butt redistributors":
 				r += ` ${He} receives <span class="lime">direct injections of fat redistributors right into ${his} buttocks,</span> causing ${his} body to begin moving fatty tissue from it to ${his} core`;
-				if (slave.geneMods.NCS === 1 && rearLipedemaMod !== 2) {
+				if (slave.geneMods.NCS === 1 && rearLipedemaMod === 0) {
 					r += `; ${his} <span class="orange">NCS</span> amplifies the effectiveness`;
 				}
 				r += `.`;
@@ -1554,7 +1486,7 @@ App.SlaveAssignment.drugs = (function() {
 				} else if (slave.weight >= 200) {
 					r += ` ${He} is now so immensely obese ${his} health is greatly at risk; <span class="yellow">${his} drug regimen has been ended.</span>`;
 					slave.drugs = "no drugs";
-				} else if (rearLipedemaMod === 2) {
+				} else if (rearLipedemaMod === 1) {
 					r += ` ${His} <span class="orange">waistline swells slightly,</span> but <span class="lime">${his} butt barely loses any mass</span>`;
 					if (V.geneticMappingUpgrade >= 1) {
 						r += ` due to ${his} rear lipedema putting it right back.`;
@@ -1918,7 +1850,7 @@ App.SlaveAssignment.drugs = (function() {
 							r += ` ${He} <span class="hotpink">secretly enjoys</span> being assraped by a machine twice a day.`;
 							slave.devotion += 1;
 						}
-						if (slave.anus === 1) {
+						if (V.seeStretching === 1 && slave.anus === 1) {
 							if (jsRandom(1, 100) > 70) {
 								r += ` The regular machine anal <span class="lime">stretches out ${his} tight asshole.</span>`;
 								slave.anus += 1;
@@ -1987,7 +1919,7 @@ App.SlaveAssignment.drugs = (function() {
 					slave.drugs = "no drugs";
 				} else if (slave.clit >= 5 && slave.dick === 0) {
 					r += ` ${His} clit is now so huge that further drug enhancement will not increase its size. <span class="yellow">${His} drug regimen has been ended.</span>`;
-					slave.clit = Math.clamp(slave.clit, 0, 5);
+					slave.clit = /** @type {FC.ClitType} */ (Math.clamp(slave.clit, 0, 5));
 					slave.drugs = "no drugs";
 				}
 				break;
@@ -2019,4 +1951,4 @@ App.SlaveAssignment.drugs = (function() {
 			slave.pregControl = "none";
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saGetMilked.js b/src/endWeek/saGetMilked.js
index 4bcd2505bdeeaf209694497a7d5e6681e6b4061a..2e0dac00c92f25c80a1071bbc4f57536a5e08111 100644
--- a/src/endWeek/saGetMilked.js
+++ b/src/endWeek/saGetMilked.js
@@ -1,10 +1,4 @@
-App.SlaveAssignment.getMilked = (function() {
-	"use strict";
-
-	let arcology;
-	let vignetteCash;
-	let vignetteRep;
-
+{
 	class MilkingResults {
 		constructor() {
 			/** full description of milking */
@@ -29,38 +23,26 @@ App.SlaveAssignment.getMilked = (function() {
 		}
 	}
 
-	/** @type {MilkingResults} */
-	let r;
-
-	// could probably move these back or something
-	let hormones;
-	let cumHormones;
-	let implantEffect;
-
-	let he;
-	let him;
-	let his;
-	let He;
-	let His;
-
-	return saGetMilked;
-
 	/**
-	 * @param {App.Entity.SlaveState} slave
+	 * @param {FC.ReportSlave} slave
 	 * @param {number} [multiplier=1.0]
 	 * @param {boolean} [preview=false] are we trying to preview milking income, or may we make changes to the slave?
 	 * @returns {MilkingResults}
 	 */
-	function saGetMilked(slave, multiplier = 1.0, preview = false) {
-		arcology = V.arcologies[0];
-		r = new MilkingResults();
-		vignetteCash = 0;
-		vignetteRep = 0;
+	App.SlaveAssignment.getMilked = function saGetMilked(slave, multiplier = 1.0, preview = false) {
+		const r = new MilkingResults();
+		const arcology = V.arcologies[0];
+		const {
+			he, him, his, He, His
+		} = getPronouns(slave);
+
+		// could probably move these back or something
+		let implantEffect;
+
+		let vignetteCash = 0;
+		let vignetteRep = 0;
 
 		if (!preview) {
-			({
-				he, him, his, He, His
-			} = getPronouns(slave));
 			jobPreface(slave);
 		}
 
@@ -100,789 +82,789 @@ App.SlaveAssignment.getMilked = (function() {
 			}
 		}
 		return r;
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function recordTotals(slave) {
-		actX(slave, "milk", r.milk);
-		actX(slave, "cum", r.cum);
-	}
-
-	/**
-	 * @param {object} incomeStats getSlaveStatisticData return value - FIXME should be a named type
-	 */
-	function recordFacilityStatistics(incomeStats) {
-		incomeStats.milk = r.milk;
-		incomeStats.cum = r.cum;
-		incomeStats.fluid = r.fluid;
-		incomeStats.income = r.cash + vignetteCash;
-		incomeStats.rep = vignetteRep;
-	}
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function jobPreface(slave) {
-		r.text += `gets milked this week.`;
-		if (V.dairy > 0 && V.dairyRestraintsSetting < 2) {
-			if ((V.universalRulesFacilityWork === 1 && slave.assignment === window.Job.MILKED && V.dairySpots > 0) || (slave.assignment === window.Job.DAIRY)) {
-				if (slave.assignment === window.Job.MILKED) {
-					r.text += ` Since there's extra space in ${V.dairyName}, ${he} spends most of ${his} milkings there.`;
-					V.dairySpots -= 1; // Would this need to be pulled for statistics gathering?
-				}
-				if (V.MilkmaidID !== 0) {
-					r.text += ` While there, ${he} gets the benefit of ${S.Milkmaid.slaveName}'s `;
-					if (S.Milkmaid.physicalAge < 21) {
-						r.text += `youthful energy`;
-					} else {
-						r.text += `care`;
-					}
-					if (S.Milkmaid.skill.oral >= 100) {
-						r.text += ` and talented tongue`;
-					}
-					r.text += `.`;
-					if (slave.devotion < V.milkmaidDevotionThreshold) {
-						slave.devotion += V.milkmaidDevotionBonus;
-					}
-					if (slave.trust < V.milkmaidTrustThreshold) {
-						slave.trust += V.milkmaidTrustBonus;
+		/**
+		 * @param {App.Entity.SlaveState} slave
+		 */
+		function recordTotals(slave) {
+			actX(slave, "milk", r.milk);
+			actX(slave, "cum", r.cum);
+		}
+
+		/**
+		 * @param {FC.SlaveStatisticData} incomeStats
+		 */
+		function recordFacilityStatistics(incomeStats) {
+			incomeStats.milk = r.milk;
+			incomeStats.cum = r.cum;
+			incomeStats.fluid = r.fluid;
+			incomeStats.income = r.cash + vignetteCash;
+			incomeStats.rep = vignetteRep;
+		}
+
+		/**
+		 * @param {App.Entity.SlaveState} slave
+		 */
+		function jobPreface(slave) {
+			r.text += `gets milked this week.`;
+			if (V.dairy > 0 && V.dairyRestraintsSetting < 2) {
+				if ((V.universalRulesFacilityWork === 1 && slave.assignment === window.Job.MILKED && V.dairySpots > 0) || (slave.assignment === window.Job.DAIRY)) {
+					if (slave.assignment === window.Job.MILKED) {
+						r.text += ` Since there's extra space in ${V.dairyName}, ${he} spends most of ${his} milkings there.`;
+						V.dairySpots -= 1; // Would this need to be pulled for statistics gathering?
 					}
-					if (slave.health.condition < 100) {
-						improveCondition(slave, V.milkmaidHealthBonus);
+					if (V.MilkmaidID !== 0) {
+						r.text += ` While there, ${he} gets the benefit of ${S.Milkmaid.slaveName}'s `;
+						if (S.Milkmaid.physicalAge < 21) {
+							r.text += `youthful energy`;
+						} else {
+							r.text += `care`;
+						}
+						if (S.Milkmaid.skill.oral >= 100) {
+							r.text += ` and talented tongue`;
+						}
+						r.text += `.`;
+						if (slave.devotion < V.milkmaidDevotionThreshold) {
+							slave.devotion += V.milkmaidDevotionBonus;
+						}
+						if (slave.trust < V.milkmaidTrustThreshold) {
+							slave.trust += V.milkmaidTrustBonus;
+						}
+						if (slave.health.condition < 100) {
+							improveCondition(slave, V.milkmaidHealthBonus);
+						}
 					}
 				}
 			}
 		}
-	}
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {number} multiplier
-	 * @param {boolean} preview
-	 */
-	function harvestMilk(slave, multiplier, preview) {
-		r.milk = milkAmount(slave);
-
-		r.text += ` ${He} produces from ${his} ${jsEither(["boobs", "breasts", "mammaries", "tits", "udders"])}, which have a combined volume of ${(slave.boobs * 2)} CCs; `;
-		if (slave.lactation === 1) {
-			r.text += `${he} is lactating naturally and produces `;
-			if (implantEffect >= 0.90) {
-				r.text += `a weak trickle of milk.`;
-			} else if (implantEffect >= 0.75) {
-				r.text += `a weak stream of milk.`;
-			} else {
-				r.text += `a healthy stream of milk.`;
-			}
-			// I want to increase lactationAdaptation for normal milk too. Since it is locked to integers, I would need something like .ageAdjust it seems.
-		} else if (slave.lactation === 2) {
-			r.text += `${he} is on lactation drugs and produces `;
-			if (implantEffect >= 0.90) {
-				r.text += `a steady flow of milk.`;
-			} else if (implantEffect >= 0.75) {
-				r.text += `strong bursts of milk.`;
-			} else {
-				r.text += `a river of milk.`;
-			}
-			if (!preview) {
-				if (slave.lactationAdaptation < 100) {
-					r.text += ` ${His} udders are forced to adapt to this unnatural productivity.`;
-					slave.lactationAdaptation += 1;
+		/**
+		 * @param {App.Entity.SlaveState} slave
+		 * @param {number} multiplier
+		 * @param {boolean} preview
+		 */
+		function harvestMilk(slave, multiplier, preview) {
+			r.milk = milkAmount(slave);
+
+			r.text += ` ${He} produces from ${his} ${jsEither(["boobs", "breasts", "mammaries", "tits", "udders"])}, which have a combined volume of ${(slave.boobs * 2)} CCs; `;
+			if (slave.lactation === 1) {
+				r.text += `${he} is lactating naturally and produces `;
+				if (implantEffect >= 0.90) {
+					r.text += `a weak trickle of milk.`;
+				} else if (implantEffect >= 0.75) {
+					r.text += `a weak stream of milk.`;
+				} else {
+					r.text += `a healthy stream of milk.`;
 				}
-				if (slave.curatives === 0 && slave.inflationType !== "curative") {
-					r.text += ` The stress of extreme milk production <span class="health dec">damages ${his} health.</span>`;
-					healthDamage(slave, 3);
+				// I want to increase lactationAdaptation for normal milk too. Since it is locked to integers, I would need something like .ageAdjust it seems.
+			} else if (slave.lactation === 2) {
+				r.text += `${he} is on lactation drugs and produces `;
+				if (implantEffect >= 0.90) {
+					r.text += `a steady flow of milk.`;
+				} else if (implantEffect >= 0.75) {
+					r.text += `strong bursts of milk.`;
+				} else {
+					r.text += `a river of milk.`;
+				}
+				if (!preview) {
+					if (slave.lactationAdaptation < 100) {
+						r.text += ` ${His} udders are forced to adapt to this unnatural productivity.`;
+						slave.lactationAdaptation += 1;
+					}
+					if (slave.curatives === 0 && slave.inflationType !== "curative") {
+						r.text += ` The stress of extreme milk production <span class="health dec">damages ${his} health.</span>`;
+						healthDamage(slave, 3);
+					}
 				}
 			}
-		}
 
-		if (slave.boobsMilk > 0) {
-			r.text += ` ${He} was in need of a good milking, too.`;
-		}
+			if (slave.boobsMilk > 0) {
+				r.text += ` ${He} was in need of a good milking, too.`;
+			}
 
-		if (slave.devotion > 50) {
-			r.text += ` ${He}'s such a happy cow that ${his} mental state has a positive impact on ${his} production.`;
-		} else if (slave.devotion < -50) {
-			r.text += ` ${He}'s such an unhappy cow that ${his} mental state has a negative impact on ${his} production.`;
-		}
+			if (slave.devotion > 50) {
+				r.text += ` ${He}'s such a happy cow that ${his} mental state has a positive impact on ${his} production.`;
+			} else if (slave.devotion < -50) {
+				r.text += ` ${He}'s such an unhappy cow that ${his} mental state has a negative impact on ${his} production.`;
+			}
 
-		if (slave.boobsImplant > 0) {
-			implantEffect = (slave.boobsImplant / slave.boobs);
-		}
-		if (slave.boobsImplant > 0) {
-			r.text += ` However, ${his} `;
-			if (implantEffect >= 0.90) {
-				r.text += `breast implants are ill-suited for`;
-			} else if (implantEffect >= 0.75) {
-				r.text += `breasts are almost entirely implant, greatly restricting ${his}`;
-			} else if (implantEffect >= 0.60) {
-				r.text += `breasts are mostly implant, restricting ${his}`;
-			} else if (implantEffect >= 0.45) {
-				r.text += `implants make up a considerable amount of ${his} breasts and greatly impede`;
-			} else if (implantEffect >= 0.30) {
-				r.text += `breast implants take up enough space to impede`;
-			} else if (implantEffect >= 0.10) {
-				r.text += `breast implants slightly impede`;
-			} else {
-				r.text += `breast implants cause a minor decrease in`;
+			if (slave.boobsImplant > 0) {
+				implantEffect = (slave.boobsImplant / slave.boobs);
 			}
-			r.text += ` milk production`;
-			if (implantEffect >= 0.90) {
-				r.text += `, given the lack of actual breast flesh`;
+			if (slave.boobsImplant > 0) {
+				r.text += ` However, ${his} `;
+				if (implantEffect >= 0.90) {
+					r.text += `breast implants are ill-suited for`;
+				} else if (implantEffect >= 0.75) {
+					r.text += `breasts are almost entirely implant, greatly restricting ${his}`;
+				} else if (implantEffect >= 0.60) {
+					r.text += `breasts are mostly implant, restricting ${his}`;
+				} else if (implantEffect >= 0.45) {
+					r.text += `implants make up a considerable amount of ${his} breasts and greatly impede`;
+				} else if (implantEffect >= 0.30) {
+					r.text += `breast implants take up enough space to impede`;
+				} else if (implantEffect >= 0.10) {
+					r.text += `breast implants slightly impede`;
+				} else {
+					r.text += `breast implants cause a minor decrease in`;
+				}
+				r.text += ` milk production`;
+				if (implantEffect >= 0.90) {
+					r.text += `, given the lack of actual breast flesh`;
+				}
+				r.text += `.`;
 			}
-			r.text += `.`;
-		}
 
-		hormones = (slave.hormoneBalance / 100);
-		if (slave.balls !== 0) {
-			hormones -= 1;
-		}
-		if (slave.ovaries !== 0 || slave.mpreg !== 0) {
-			hormones += 1;
-		}
-		if (hormones > 1) {
-			r.text += ` ${His} internal chemistry is perfectly suited to milk production.`;
-		} else if (hormones > 0) {
-			r.text += ` ${His} hormonal balance favors milk production.`;
-		} else if (hormones < 0) {
-			r.text += ` ${His} hormonal balance impedes milk production.`;
-		} else if (hormones < -1) {
-			r.text += ` ${His} internal chemistry is poorly suited to milk production.`;
-		}
-
-		if (!preview && slave.lactationAdaptation < 100 && slave.assignment === Job.MILKED || slave.assignment === Job.DAIRY) {
-			r.text += ` Living as a cow helps ${his} body and mind adapt to producing milk.`;
-			slave.lactationAdaptation += 1;
-		}
+			let hormones = (slave.hormoneBalance / 100);
+			if (slave.balls !== 0) {
+				hormones -= 1;
+			}
+			if (slave.ovaries !== 0 || slave.mpreg !== 0) {
+				hormones += 1;
+			}
+			if (hormones > 1) {
+				r.text += ` ${His} internal chemistry is perfectly suited to milk production.`;
+			} else if (hormones > 0) {
+				r.text += ` ${His} hormonal balance favors milk production.`;
+			} else if (hormones < 0) {
+				r.text += ` ${His} hormonal balance impedes milk production.`;
+			} else if (hormones < -1) {
+				r.text += ` ${His} internal chemistry is poorly suited to milk production.`;
+			}
 
-		if (!preview && slave.preg > (slave.pregData.normalBirth / 8) && slave.pregKnown === 1) {
-			r.text += ` ${His} pregnancy helps ${his} body produce more milk naturally`;
-			if (slave.lactationAdaptation < 100) {
-				r.text += `, and also helps it adapt to milk production`;
+			if (!preview && slave.lactationAdaptation < 100 && slave.assignment === Job.MILKED || slave.assignment === Job.DAIRY) {
+				r.text += ` Living as a cow helps ${his} body and mind adapt to producing milk.`;
 				slave.lactationAdaptation += 1;
 			}
-			r.text += `.`;
-		}
 
-		if (slave.health.condition > 50) {
-			r.text += ` ${His} shining health helps ${him} really produce.`;
-		} else if (slave.health.condition < -50) {
-			r.text += ` ${His} poor health impedes milk production.`;
-		}
+			if (!preview && slave.preg > (slave.pregData.normalBirth / 8) && slave.pregKnown === 1) {
+				r.text += ` ${His} pregnancy helps ${his} body produce more milk naturally`;
+				if (slave.lactationAdaptation < 100) {
+					r.text += `, and also helps it adapt to milk production`;
+					slave.lactationAdaptation += 1;
+				}
+				r.text += `.`;
+			}
 
-		if (slave.weight > 10) {
-			r.text += ` ${His} extra weight supports ${his} productivity.`;
-		} else if (slave.weight < -10) {
-			r.text += ` ${His} thinness hinders ${his} productivity.`;
-		}
+			if (slave.health.condition > 50) {
+				r.text += ` ${His} shining health helps ${him} really produce.`;
+			} else if (slave.health.condition < -50) {
+				r.text += ` ${His} poor health impedes milk production.`;
+			}
 
-		if (slave.lactationAdaptation > 10) {
-			if (slave.lactationAdaptation > 50) {
-				r.text += ` ${His} body has adapted heavily to milk production, making ${him} extremely productive.`;
-			} else {
-				r.text += ` ${His} body has gotten used to producing milk, making ${him} very productive.`;
+			if (slave.weight > 10) {
+				r.text += ` ${His} extra weight supports ${his} productivity.`;
+			} else if (slave.weight < -10) {
+				r.text += ` ${His} thinness hinders ${his} productivity.`;
+			}
+
+			if (slave.lactationAdaptation > 10) {
+				if (slave.lactationAdaptation > 50) {
+					r.text += ` ${His} body has adapted heavily to milk production, making ${him} extremely productive.`;
+				} else {
+					r.text += ` ${His} body has gotten used to producing milk, making ${him} very productive.`;
+				}
 			}
-		}
 
-		if (V.dairySlimMaintainUpgrade === 1) {
-			if (V.dairySlimMaintain === 1) {
-				if (slave.boobs <= 700) {
-					if (arcology.FSSlimnessEnthusiast > 80) {
-						r.text += ` Your arcology's milkers are optimized to extract maximum output from small breasted slaves, which substantially increases ${his} otherwise modest productivity.`;
-						r.milk *= 1.5;
-					} else if (arcology.FSSlimnessEnthusiast > 20) {
-						r.text += ` Your arcology's milkers have been carefully modified to more readily accommodate slaves with tiny breasts, which slightly mitigates ${his} less than ideal physiology for milk production.`;
-						r.milk *= 1.1;
+			if (V.dairySlimMaintainUpgrade === 1) {
+				if (V.dairySlimMaintain === 1) {
+					if (slave.boobs <= 700) {
+						if (arcology.FSSlimnessEnthusiast > 80) {
+							r.text += ` Your arcology's milkers are optimized to extract maximum output from small breasted slaves, which substantially increases ${his} otherwise modest productivity.`;
+							r.milk *= 1.5;
+						} else if (arcology.FSSlimnessEnthusiast > 20) {
+							r.text += ` Your arcology's milkers have been carefully modified to more readily accommodate slaves with tiny breasts, which slightly mitigates ${his} less than ideal physiology for milk production.`;
+							r.milk *= 1.1;
+						}
 					}
 				}
 			}
-		}
 
-		if (slave.assignment === Job.DAIRY) { // FIXME: no text for this block???
-			if (V.dairyFeedersUpgrade === 1) {
-				if (V.dairyFeedersSetting > 0) {
-					r.milk += (r.milk * (0.1 * (V.dairyFeedersUpgrade + V.dairyRestraintsSetting + ((50 - slave.physicalAge) / 20))));
-					if (slave.chem > 360) {
-						r.milk *= 0.6;
-					} else if (slave.chem > 100) {
-						r.milk *= ((600 - slave.chem) / 600);
+			if (slave.assignment === Job.DAIRY) { // FIXME: no text for this block???
+				if (V.dairyFeedersUpgrade === 1) {
+					if (V.dairyFeedersSetting > 0) {
+						r.milk += (r.milk * (0.1 * (V.dairyFeedersUpgrade + V.dairyRestraintsSetting + ((50 - slave.physicalAge) / 20))));
+						if (slave.chem > 360) {
+							r.milk *= 0.6;
+						} else if (slave.chem > 100) {
+							r.milk *= ((600 - slave.chem) / 600);
+						}
 					}
 				}
 			}
-		}
 
-		r.milk *= multiplier;
-		r.milk = Math.max(Math.trunc(r.milk), 1);
-
-		r.text += ` As a result, ${he} produces ${numberWithPluralOne(r.milk, "liter")} of milk over the week.`;
-
-		// make sure milkSale is set here
-		if (arcology.FSPastoralistLaw === 1) {
-			r.milkSale = (r.milk * (8 + Math.trunc(arcology.FSPastoralist / 30)));
-			r.text += ` Since breast milk is ${arcology.name}'s only legal dairy product, ${he} can scarcely be milked fast enough, and ${he} makes <span class="cash inc">${cashFormat(r.milkSale)}.</span>`;
-		} else if (arcology.FSPastoralist !== "unset") {
-			r.milkSale = (r.milk * (6 + Math.trunc(arcology.FSPastoralist / 30)));
-			r.text += ` Since milk is fast becoming a major part of the ${arcology.name}'s dietary culture, ${his} milk is in demand, and ${he} makes <span class="cash inc">${cashFormat(r.milkSale)}.</span>`;
-		} else if (arcology.FSRepopulationFocusLaw === 1) {
-			r.milkSale = (r.milk * (6 + Math.trunc(arcology.FSRepopulationFocus / 50)));
-			r.text += ` Since the number of hungry babies outweighs the supply of available breasts in ${arcology.name}, ${his} milk is in demand, and ${he} makes <span class="cash inc">${cashFormat(r.milkSale)}.</span>`;
-		} else {
-			r.milkSale = (r.milk * 6);
-			r.text += ` ${His} milk is sold for <span class="cash inc">${cashFormat(r.milkSale)}.</span>`;
+			r.milk *= multiplier;
+			r.milk = Math.max(Math.trunc(r.milk), 1);
+
+			r.text += ` As a result, ${he} produces ${numberWithPluralOne(r.milk, "liter")} of milk over the week.`;
+
+			// make sure milkSale is set here
+			if (arcology.FSPastoralistLaw === 1) {
+				r.milkSale = (r.milk * (8 + Math.trunc(arcology.FSPastoralist / 30)));
+				r.text += ` Since breast milk is ${arcology.name}'s only legal dairy product, ${he} can scarcely be milked fast enough, and ${he} makes <span class="cash inc">${cashFormat(r.milkSale)}.</span>`;
+			} else if (arcology.FSPastoralist !== "unset") {
+				r.milkSale = (r.milk * (6 + Math.trunc(arcology.FSPastoralist / 30)));
+				r.text += ` Since milk is fast becoming a major part of the ${arcology.name}'s dietary culture, ${his} milk is in demand, and ${he} makes <span class="cash inc">${cashFormat(r.milkSale)}.</span>`;
+			} else if (arcology.FSRepopulationFocusLaw === 1) {
+				r.milkSale = (r.milk * (6 + Math.trunc(arcology.FSRepopulationFocus / 50)));
+				r.text += ` Since the number of hungry babies outweighs the supply of available breasts in ${arcology.name}, ${his} milk is in demand, and ${he} makes <span class="cash inc">${cashFormat(r.milkSale)}.</span>`;
+			} else {
+				r.milkSale = (r.milk * 6);
+				r.text += ` ${His} milk is sold for <span class="cash inc">${cashFormat(r.milkSale)}.</span>`;
+			}
 		}
-	}
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function milkingEffects(slave) {
-		if (slave.fetishKnown) {
-			if (slave.fetish === "boobs" || slave.energy > 95) {
-				r.text += ` Getting constantly milked is as good as sex, as far as ${he}'s concerned. <span class="devotion inc">${He} is happy</span> to have ${his} breasts receive so much attention.`;
-				slave.devotion += 1;
-				if (slave.need > 0) {
-					slave.need = 0;
+		/**
+		 * @param {App.Entity.SlaveState} slave
+		 */
+		function milkingEffects(slave) {
+			if (slave.fetishKnown) {
+				if (slave.fetish === "boobs" || slave.energy > 95) {
+					r.text += ` Getting constantly milked is as good as sex, as far as ${he}'s concerned. <span class="devotion inc">${He} is happy</span> to have ${his} breasts receive so much attention.`;
+					slave.devotion += 1;
+					if (slave.need > 0) {
+						slave.need = 0;
+					}
 				}
 			}
-		}
 
-		if (slave.career === "a dairy cow" && slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
-			r.text += ` ${He} feels like <span class="devotion inc">${he} was made to be milked,</span> <span class="trust inc">not that ${he}'d complain about such a good feeling.</span>`;
-			slave.devotion++;
-			slave.trust++;
-			if (slave.need > 0) {
-				slave.need = 0;
+			if (slave.career === "a dairy cow" && slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
+				r.text += ` ${He} feels like <span class="devotion inc">${he} was made to be milked,</span> <span class="trust inc">not that ${he}'d complain about such a good feeling.</span>`;
+				slave.devotion++;
+				slave.trust++;
+				if (slave.need > 0) {
+					slave.need = 0;
+				}
 			}
-		}
 
-		if (slave.nipples !== "huge") {
-			if (slave.nipples === "inverted") {
-				if (slave.fetish === "masochist" && slave.fetishKnown === 1) {
-					r.text += ` Having the milkers constantly haul ${his} inverted nipples out is <span class="devotion inc">extremely uncomfortable; ${he} loves it.</span>`;
-					slave.devotion += 3;
-				} else {
-					r.text += ` Having the milkers constantly haul ${his} inverted nipples out is <span class="devotion dec">extremely uncomfortable.</span>`;
-					slave.devotion -= 3;
-				}
-				if (jsRandom(1, 100) > 50) {
-					r.text += ` The constant suction <span class="change positive">permanently protrudes them,</span> and `;
-					if (jsRandom(1, 2) === 1) {
-						r.text += `it turns out they're absolutely massive.`;
-						slave.nipples = "huge";
+			if (slave.nipples !== "huge") {
+				if (slave.nipples === "inverted") {
+					if (slave.fetish === "masochist" && slave.fetishKnown === 1) {
+						r.text += ` Having the milkers constantly haul ${his} inverted nipples out is <span class="devotion inc">extremely uncomfortable; ${he} loves it.</span>`;
+						slave.devotion += 3;
 					} else {
-						r.text += `it turns out they're nice and puffy.`;
-						slave.nipples = "puffy";
+						r.text += ` Having the milkers constantly haul ${his} inverted nipples out is <span class="devotion dec">extremely uncomfortable.</span>`;
+						slave.devotion -= 3;
 					}
-				}
-			} else if (slave.nipples === "partially inverted") {
-				if (slave.fetish === "masochist" && slave.fetishKnown === 1) {
-					r.text += ` Having the milkers constantly haul ${his} inverted nipples out is <span class="devotion inc">quite uncomfortable; ${he} loves it.</span>`;
-					slave.devotion += 1;
-				} else {
-					r.text += ` Having the milkers constantly haul ${his} inverted nipples out is <span class="devotion dec">quite uncomfortable.</span>`;
-					slave.devotion -= 1;
-				}
-				if (jsRandom(1, 100) > 30) {
-					r.text += ` The constant suction <span class="change positive">permanently protrudes them,</span> and `;
-					if (jsRandom(1, 2) === 1) {
-						r.text += `it turns out they're pretty cute.`;
-						slave.nipples = "cute";
+					if (jsRandom(1, 100) > 50) {
+						r.text += ` The constant suction <span class="change positive">permanently protrudes them,</span> and `;
+						if (jsRandom(1, 2) === 1) {
+							r.text += `it turns out they're absolutely massive.`;
+							slave.nipples = "huge";
+						} else {
+							r.text += `it turns out they're nice and puffy.`;
+							slave.nipples = "puffy";
+						}
+					}
+				} else if (slave.nipples === "partially inverted") {
+					if (slave.fetish === "masochist" && slave.fetishKnown === 1) {
+						r.text += ` Having the milkers constantly haul ${his} inverted nipples out is <span class="devotion inc">quite uncomfortable; ${he} loves it.</span>`;
+						slave.devotion += 1;
 					} else {
-						r.text += `it turns out they're nice and puffy.`;
-						slave.nipples = "puffy";
+						r.text += ` Having the milkers constantly haul ${his} inverted nipples out is <span class="devotion dec">quite uncomfortable.</span>`;
+						slave.devotion -= 1;
 					}
+					if (jsRandom(1, 100) > 30) {
+						r.text += ` The constant suction <span class="change positive">permanently protrudes them,</span> and `;
+						if (jsRandom(1, 2) === 1) {
+							r.text += `it turns out they're pretty cute.`;
+							slave.nipples = "cute";
+						} else {
+							r.text += `it turns out they're nice and puffy.`;
+							slave.nipples = "puffy";
+						}
+					}
+				} else if (slave.nipples === "puffy" && jsRandom(1, 100) > 90) {
+					r.text += ` Producing this river of milk <span class="change positive">enlarges ${his} nipples:</span> they're now enormous.`;
+					slave.nipples = "huge";
+				} else if (slave.nipples === "cute" && jsRandom(1, 100) > 80) {
+					r.text += ` Producing this river of milk <span class="change positive">makes ${his} nipples nice and puffy.</span>`;
+					slave.nipples = "puffy";
+				} else if (slave.nipples === "tiny") {
+					r.text += ` Producing this river of milk <span class="change positive">makes ${his} nipples grow to a nice size.</span>`;
+					slave.nipples = "cute";
+				} else if (slave.nipples === "flat") {
+					r.text += ` Producing this river of milk <span class="change positive">forces ${his} nipples to grow to a more suitable size.</span>`;
+					slave.nipples = "huge";
+				} else if (slave.areolae < 4 && jsRandom(1, 100) > (30 + (slave.areolae * 20))) {
+					if (slave.nipples === "fuckable") {
+						r.text += ` The constant suction around of ${his} nipples as their depths are drained of milk`;
+					} else {
+						r.text += ` Producing this river of milk`;
+					}
+					r.text += ` <span class="change positive">broadens ${his} areolae.</span>`;
+					slave.areolae += 1;
 				}
-			} else if (slave.nipples === "puffy" && jsRandom(1, 100) > 90) {
-				r.text += ` Producing this river of milk <span class="change positive">enlarges ${his} nipples:</span> they're now enormous.`;
-				slave.nipples = "huge";
-			} else if (slave.nipples === "cute" && jsRandom(1, 100) > 80) {
-				r.text += ` Producing this river of milk <span class="change positive">makes ${his} nipples nice and puffy.</span>`;
-				slave.nipples = "puffy";
-			} else if (slave.nipples === "tiny") {
-				r.text += ` Producing this river of milk <span class="change positive">makes ${his} nipples grow to a nice size.</span>`;
-				slave.nipples = "cute";
-			} else if (slave.nipples === "flat") {
-				r.text += ` Producing this river of milk <span class="change positive">forces ${his} nipples to grow to a more suitable size.</span>`;
-				slave.nipples = "huge";
-			} else if (slave.areolae < 4 && jsRandom(1, 100) > (30 + (slave.areolae * 20))) {
-				if (slave.nipples === "fuckable") {
-					r.text += ` The constant suction around of ${his} nipples as their depths are drained of milk`;
-				} else {
-					r.text += ` Producing this river of milk`;
-				}
-				r.text += ` <span class="change positive">broadens ${his} areolae.</span>`;
-				slave.areolae += 1;
+			}
+			slave.lactationDuration = 2;
+			if (slave.boobsMilk > 0) {
+				slave.boobs -= slave.boobsMilk;
+				slave.boobsMilk = 0;
 			}
 		}
-		slave.lactationDuration = 2;
-		if (slave.boobsMilk > 0) {
-			slave.boobs -= slave.boobsMilk;
-			slave.boobsMilk = 0;
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {number} multiplier
-	 */
-	function harvestCum(slave, multiplier) {
-		let qualityMultiplier = 1.0;
-		r.cum = cumAmount(slave);
 
-		if (slave.lactation > 0) {
-			r.text += ` ${His} `;
-		} else {
-			r.text += ` ${slave.slaveName}'s `;
-		}
+		/**
+		 * @param {App.Entity.SlaveState} slave
+		 * @param {number} multiplier
+		 */
+		function harvestCum(slave, multiplier) {
+			let qualityMultiplier = 1.0;
+			r.cum = cumAmount(slave);
 
-		if (slave.dick > 0) {
-			if (slave.dick > 6) {
-				r.text += `inhuman`;
-			} else if (slave.dick > 5) {
-				r.text += `massive`;
-			} else if (slave.dick > 4) {
-				r.text += `big`;
-			} else if (slave.dick > 3) {
-				r.text += `sizable`;
-			} else if (slave.dick > 2) {
-				r.text += `moderate`;
-			} else if (slave.dick > 1) {
-				r.text += `little`;
+			if (slave.lactation > 0) {
+				r.text += ` ${His} `;
+			} else {
+				r.text += ` ${slave.slaveName}'s `;
+			}
+
+			if (slave.dick > 0) {
+				if (slave.dick > 6) {
+					r.text += `inhuman`;
+				} else if (slave.dick > 5) {
+					r.text += `massive`;
+				} else if (slave.dick > 4) {
+					r.text += `big`;
+				} else if (slave.dick > 3) {
+					r.text += `sizable`;
+				} else if (slave.dick > 2) {
+					r.text += `moderate`;
+				} else if (slave.dick > 1) {
+					r.text += `little`;
+				} else {
+					r.text += `tiny`;
+				}
+				r.text += ` prick is`;
+				if (slave.lactation > 0) {
+					r.text += ` also`;
+				}
+				r.text += ` machine-milked`;
 			} else {
-				r.text += `tiny`;
+				r.text += `butt is machine-fucked`;
 			}
-			r.text += ` prick is`;
-			if (slave.lactation > 0) {
-				r.text += ` also`;
+			r.text += ` to extract the cum from ${his} `;
+			if (slave.scrotum === 0) {
+				r.text += `invisible`;
+			} else {
+				if (slave.balls > 10) {
+					r.text += `hypertrophied`;
+				} else if (slave.balls >= 10) {
+					r.text += `inhuman`;
+				} else if (slave.balls >= 9) {
+					r.text += `titanic`;
+				} else if (slave.balls >= 8) {
+					r.text += `gigantic`;
+				} else if (slave.balls >= 7) {
+					r.text += `monstrous`;
+				} else if (slave.balls >= 6) {
+					r.text += `pendulous`;
+				} else if (slave.balls >= 5) {
+					r.text += `huge`;
+				} else if (slave.balls >= 4) {
+					r.text += `big`;
+				} else if (slave.balls >= 3) {
+					r.text += `average`;
+				} else {
+					r.text += `pathetic`;
+				}
 			}
-			r.text += ` machine-milked`;
-		} else {
-			r.text += `butt is machine-fucked`;
-		}
-		r.text += ` to extract the cum from ${his} `;
-		if (slave.scrotum === 0) {
-			r.text += `invisible`;
-		} else {
-			if (slave.balls > 10) {
-				r.text += `hypertrophied`;
-			} else if (slave.balls >= 10) {
-				r.text += `inhuman`;
-			} else if (slave.balls >= 9) {
-				r.text += `titanic`;
-			} else if (slave.balls >= 8) {
-				r.text += `gigantic`;
-			} else if (slave.balls >= 7) {
-				r.text += `monstrous`;
-			} else if (slave.balls >= 6) {
-				r.text += `pendulous`;
-			} else if (slave.balls >= 5) {
-				r.text += `huge`;
-			} else if (slave.balls >= 4) {
-				r.text += `big`;
-			} else if (slave.balls >= 3) {
-				r.text += `average`;
+			if (slave.drugs === "testicle enhancement") {
+				r.text += ` balls, relieving them of the excessive cum production caused by the testicle enhancement drugs.`;
+			} else if (slave.drugs === "hyper testicle enhancement") {
+				r.text += ` balls, relieving them of the excessive cum production caused by the hyper testicle enhancement drugs.`;
 			} else {
-				r.text += `pathetic`;
+				r.text += ` balls.`;
 			}
-		}
-		if (slave.drugs === "testicle enhancement") {
-			r.text += ` balls, relieving them of the excessive cum production caused by the testicle enhancement drugs.`;
-		} else if (slave.drugs === "hyper testicle enhancement") {
-			r.text += ` balls, relieving them of the excessive cum production caused by the hyper testicle enhancement drugs.`;
-		} else {
-			r.text += ` balls.`;
-		}
 
-		if (slave.diet === "cum production") {
-			r.text += ` ${His} diet is designed for cum production.`;
-		}
+			if (slave.diet === "cum production") {
+				r.text += ` ${His} diet is designed for cum production.`;
+			}
 
-		cumHormones = (slave.hormoneBalance / 50);
-		if (cumHormones < -1) {
-			r.text += ` ${His} internal chemistry is perfectly suited to cum production.`;
-		} else if (cumHormones < 0) {
-			r.text += ` ${His} hormonal balance favors cum production.`;
-		} else if (cumHormones > 0) {
-			r.text += ` ${His} hormonal balance impedes cum production.`;
-		} else if (cumHormones > 1) {
-			r.text += ` ${His} internal chemistry is poorly suited to cum production.`;
-		}
+			const cumHormones = (slave.hormoneBalance / 50);
+			if (cumHormones < -1) {
+				r.text += ` ${His} internal chemistry is perfectly suited to cum production.`;
+			} else if (cumHormones < 0) {
+				r.text += ` ${His} hormonal balance favors cum production.`;
+			} else if (cumHormones > 0) {
+				r.text += ` ${His} hormonal balance impedes cum production.`;
+			} else if (cumHormones > 1) {
+				r.text += ` ${His} internal chemistry is poorly suited to cum production.`;
+			}
 
-		if (slave.scrotum === 0) {
-			r.text += ` ${He} does produce cum despite ${his} apparent ballslessness, but less than ${he} would if they weren't hidden inside ${him}.`;
-		}
+			if (slave.scrotum === 0) {
+				r.text += ` ${He} does produce cum despite ${his} apparent ballslessness, but less than ${he} would if they weren't hidden inside ${him}.`;
+			}
 
-		if (slave.prostate > 0) {
-			if (slave.prostate > 2) {
-				r.text += ` ${His} heavily altered prostate greatly increases the volume of ${his} ejaculations and promotes excessive, watery semen production. This dilute ejaculate <span class="cash dec">sells poorly</span> compared to normal cum.`;
-			} else if (slave.prostate > 1) {
-				r.text += ` ${His} hyperactive prostate increases the volume of ${his} ejaculations and promotes good semen production.`;
+			if (slave.prostate > 0) {
+				if (slave.prostate > 2) {
+					r.text += ` ${His} heavily altered prostate greatly increases the volume of ${his} ejaculations and promotes excessive, watery semen production. This dilute ejaculate <span class="cash dec">sells poorly</span> compared to normal cum.`;
+				} else if (slave.prostate > 1) {
+					r.text += ` ${His} hyperactive prostate increases the volume of ${his} ejaculations and promotes good semen production.`;
+				}
+			} else {
+				r.text += ` ${His} lack of a prostate reduces the health and volume of ${his} ejaculations.`;
+				qualityMultiplier *= 0.5;
 			}
-		} else {
-			r.text += ` ${His} lack of a prostate reduces the health and volume of ${his} ejaculations.`;
-			qualityMultiplier *= 0.5;
-		}
 
-		if (slave.devotion > 50) {
-			r.text += ` ${He}'s so happy that ${his} mental state has a positive impact on ${his} semen production.`;
-		} else if (slave.devotion < -50) {
-			r.text += ` ${He}'s so unhappy that ${his} mental state has a negative impact on ${his} semen production.`;
-		}
+			if (slave.devotion > 50) {
+				r.text += ` ${He}'s so happy that ${his} mental state has a positive impact on ${his} semen production.`;
+			} else if (slave.devotion < -50) {
+				r.text += ` ${He}'s so unhappy that ${his} mental state has a negative impact on ${his} semen production.`;
+			}
 
-		if (slave.health.condition > 50) {
-			r.text += ` ${His} shining health helps ${him} really produce.`;
-		} else if (slave.health.condition < -50) {
-			r.text += ` ${His} poor health impedes semen production.`;
-		}
+			if (slave.health.condition > 50) {
+				r.text += ` ${His} shining health helps ${him} really produce.`;
+			} else if (slave.health.condition < -50) {
+				r.text += ` ${His} poor health impedes semen production.`;
+			}
 
-		if (slave.vasectomy === 1) {
-			r.text += ` ${His} cum lacks the primary ingredient, sperm, thanks to ${his} vasectomy, <span class="cash dec">considerably lowering the value</span> of ${his} ejaculate.`;
-			qualityMultiplier *= 0.2;
-		} else if (slave.ballType === "sterile") {
-			r.text += ` ${His} cum lacks vigor entirely, thanks to ${his} chemical castration, <span class="cash dec">considerably lowering the value</span> of ${his} ejaculate.`;
-			qualityMultiplier *= 0.2;
-		}
+			if (slave.vasectomy === 1) {
+				r.text += ` ${His} cum lacks the primary ingredient, sperm, thanks to ${his} vasectomy, <span class="cash dec">considerably lowering the value</span> of ${his} ejaculate.`;
+				qualityMultiplier *= 0.2;
+			} else if (slave.ballType === "sterile") {
+				r.text += ` ${His} cum lacks vigor entirely, thanks to ${his} chemical castration, <span class="cash dec">considerably lowering the value</span> of ${his} ejaculate.`;
+				qualityMultiplier *= 0.2;
+			}
 
-		if (slave.assignment === Job.DAIRY) {
-			if (V.dairyStimulatorsUpgrade === 1) { // FIXME: no text for this block?
-				if (V.dairyStimulatorsSetting > 0) {
-					r.cum += (r.cum * (0.2 * (V.dairyStimulatorsSetting + V.dairyRestraintsSetting + Math.trunc((50 - slave.physicalAge) / 20))));
-				}
-				if (slave.chem > 360) {
-					r.cum *= 0.6;
-				} else if (slave.chem > 100) {
-					r.cum *= ((600 - slave.chem) / 600);
-				}
-			} else if (V.MilkmaidID !== 0) {
-				if (S.Milkmaid.dick > 4 && canAchieveErection(S.Milkmaid)) {
-					const milkmaidPronouns = getPronouns(S.Milkmaid);
-					r.text += ` ${S.Milkmaid.slaveName} sometimes stands in for the machines, which is a polite way of saying ${milkmaidPronouns.he} sometimes fucks ${slave.slaveName}'s ass to help ${him} cum.`;
-					r.cum *= 1.2;
+			if (slave.assignment === Job.DAIRY) {
+				if (V.dairyStimulatorsUpgrade === 1) { // FIXME: no text for this block?
+					if (V.dairyStimulatorsSetting > 0) {
+						r.cum += (r.cum * (0.2 * (V.dairyStimulatorsSetting + V.dairyRestraintsSetting + Math.trunc((50 - slave.physicalAge) / 20))));
+					}
+					if (slave.chem > 360) {
+						r.cum *= 0.6;
+					} else if (slave.chem > 100) {
+						r.cum *= ((600 - slave.chem) / 600);
+					}
+				} else if (V.MilkmaidID !== 0) {
+					if (S.Milkmaid.dick > 4 && canAchieveErection(S.Milkmaid)) {
+						const milkmaidPronouns = getPronouns(S.Milkmaid);
+						r.text += ` ${S.Milkmaid.slaveName} sometimes stands in for the machines, which is a polite way of saying ${milkmaidPronouns.he} sometimes fucks ${slave.slaveName}'s ass to help ${him} cum.`;
+						r.cum *= 1.2;
+					}
 				}
 			}
-		}
 
-		r.cum *= multiplier;
-		r.cum = Math.max(Math.trunc(r.cum), 1);
-		r.text += ` ${He} produces ${numberWithPluralOne(r.cum, "deciliter")} of cum over the week;`;
-
-		if (arcology.FSPastoralist === "unset") {
-			r.cumSale = Math.max(Math.trunc((r.cum * jsRandom(15, 25) * qualityMultiplier)), 1);
-			r.text += ` the fresh ejaculate is sold for <span class="cash inc">${cashFormat(r.cumSale)}.</span>`;
-		} else if (arcology.FSPastoralistLaw === 1) {
-			r.cumSale = Math.max(Math.trunc((r.cum * (jsRandom(20, 40)) * qualityMultiplier)), 1);
-			r.text += ` the fresh ejaculate, which is in extremely high demand as one of ${arcology.name}'s few legal sources of animal protein, is sold for <span class="cash inc">${cashFormat(r.cumSale)}.</span>`;
-		} else {
-			r.cumSale = Math.max(Math.trunc((r.cum * (jsRandom(10, 20) + Math.trunc(arcology.FSPastoralist / 10)) * qualityMultiplier)), 1);
-			r.text += ` the fresh ejaculate, which is in high demand given the new cultural preference for slave products, is sold for <span class="cash inc">${cashFormat(r.cumSale)}.</span>`;
-		}
-	}
+			r.cum *= multiplier;
+			r.cum = Math.max(Math.trunc(r.cum), 1);
+			r.text += ` ${He} produces ${numberWithPluralOne(r.cum, "deciliter")} of cum over the week;`;
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function cumEffects(slave) {
-		if (slave.energy > 95) {
-			r.text += ` Getting ${his} dick constantly milked is almost as good as getting constant blowjobs as far as ${he}'s concerned. <span class="devotion inc">${He} is happy</span> to have ${his} member receive so much attention.`;
-			slave.devotion += 1;
+			if (arcology.FSPastoralist === "unset") {
+				r.cumSale = Math.max(Math.trunc((r.cum * jsRandom(15, 25) * qualityMultiplier)), 1);
+				r.text += ` the fresh ejaculate is sold for <span class="cash inc">${cashFormat(r.cumSale)}.</span>`;
+			} else if (arcology.FSPastoralistLaw === 1) {
+				r.cumSale = Math.max(Math.trunc((r.cum * (jsRandom(20, 40)) * qualityMultiplier)), 1);
+				r.text += ` the fresh ejaculate, which is in extremely high demand as one of ${arcology.name}'s few legal sources of animal protein, is sold for <span class="cash inc">${cashFormat(r.cumSale)}.</span>`;
+			} else {
+				r.cumSale = Math.max(Math.trunc((r.cum * (jsRandom(10, 20) + Math.trunc(arcology.FSPastoralist / 10)) * qualityMultiplier)), 1);
+				r.text += ` the fresh ejaculate, which is in high demand given the new cultural preference for slave products, is sold for <span class="cash inc">${cashFormat(r.cumSale)}.</span>`;
+			}
 		}
 
-		if (slave.need > 0) {
-			r.text += ` ${His} cock and balls are milked so thoroughly that ${he}'s involuntarily sexually sated, regardless of ${his} feelings and tastes.`;
-			slave.need = 0;
-		}
+		/**
+		 * @param {App.Entity.SlaveState} slave
+		 */
+		function cumEffects(slave) {
+			if (slave.energy > 95) {
+				r.text += ` Getting ${his} dick constantly milked is almost as good as getting constant blowjobs as far as ${he}'s concerned. <span class="devotion inc">${He} is happy</span> to have ${his} member receive so much attention.`;
+				slave.devotion += 1;
+			}
 
-		if (!canAchieveErection(slave)) {
-			r.text += ` Since ${he} cannot maintain an erection, ${he} requires <span class="trust dec">painful</span> and <span class="devotion dec">degrading</span> anal electrostimulation to produce.`;
-			slave.devotion -= 2;
-			slave.trust -= 2;
-			if (slave.anus === 0) {
-				r.text += ` The electrostimulator <span class="virginity loss">breaks in ${his} virgin asshole.</span>`;
-				slave.anus = 1;
-			}
-		} else if (slave.devotion <= 20) {
-			r.text += ` Since ${he}'s unaroused by ${his} situation, ${he} requires <span class="trust dec">painful</span> and <span class="devotion dec">degrading</span> anal electrostimulation to produce.`;
-			slave.devotion -= 2;
-			slave.trust -= 2;
-			if (slave.anus === 0) {
-				r.text += ` The electrostimulator <span class="virginity loss">breaks in ${his} virgin asshole.</span>`;
-				slave.anus = 1;
+			if (slave.need > 0) {
+				r.text += ` ${His} cock and balls are milked so thoroughly that ${he}'s involuntarily sexually sated, regardless of ${his} feelings and tastes.`;
+				slave.need = 0;
 			}
-		}
 
-		if (slave.balls < 3 && slave.ballType !== "sterile") {
-			if (slave.balls < 2) {
-				if (jsRandom(1, 100) > (70 + (slave.geneMods.NCS * 15))) {
-					r.text += ` Constant semen production and continual emptying and refilling <span class="change positive">increases the size of ${his} tiny testicles.</span>`;
-					slave.balls += 1;
+			if (!canAchieveErection(slave)) {
+				r.text += ` Since ${he} cannot maintain an erection, ${he} requires <span class="trust dec">painful</span> and <span class="devotion dec">degrading</span> anal electrostimulation to produce.`;
+				slave.devotion -= 2;
+				slave.trust -= 2;
+				if (slave.anus === 0) {
+					r.text += ` The electrostimulator <span class="virginity loss">breaks in ${his} virgin asshole.</span>`;
+					slave.anus = 1;
+				}
+			} else if (slave.devotion <= 20) {
+				r.text += ` Since ${he}'s unaroused by ${his} situation, ${he} requires <span class="trust dec">painful</span> and <span class="devotion dec">degrading</span> anal electrostimulation to produce.`;
+				slave.devotion -= 2;
+				slave.trust -= 2;
+				if (slave.anus === 0) {
+					r.text += ` The electrostimulator <span class="virginity loss">breaks in ${his} virgin asshole.</span>`;
+					slave.anus = 1;
 				}
-			} else if (jsRandom(1, 100) > (90 + (slave.geneMods.NCS * 5))) {
-				r.text += ` Constant semen production and continual emptying and refilling <span class="change positive">increases the size of ${his} small testicles.</span>`;
-				slave.balls += 1;
 			}
-		}
-	}
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {number} multiplier
-	 */
-	function harvestGirlCum(slave, multiplier) {
-		r.fluid = girlCumAmount(slave) * multiplier;
-		r.text += ` ${His} female prostate fluid is considered an exotic delicacy.`;
-		if (slave.vagina >= 0) {
-			if (slave.vaginaLube === 2) {
-				r.text += ` ${His} excessive vaginal secretions bolster the mix.`;
-			} else if (slave.vaginaLube === 1) {
-				r.text += ` ${His} natural vaginal secretions add to the mix.`;
-			}
-		}
-		if (slave.energy > 10) {
-			if (slave.health.condition > 50) {
-				if (slave.energy > 90) {
-					r.text += ` As a nympho, ${he} has no trouble orgasming almost constantly.`;
+			if (slave.balls < 3 && slave.ballType !== "sterile") {
+				if (slave.balls < 2) {
+					if (jsRandom(1, 100) > (70 + (slave.geneMods.NCS * 15))) {
+						r.text += ` Constant semen production and continual emptying and refilling <span class="change positive">increases the size of ${his} tiny testicles.</span>`;
+						slave.balls += 1;
+					}
+				} else if (jsRandom(1, 100) > (90 + (slave.geneMods.NCS * 5))) {
+					r.text += ` Constant semen production and continual emptying and refilling <span class="change positive">increases the size of ${his} small testicles.</span>`;
+					slave.balls += 1;
 				}
-				r.text += ` ${His} shining health keeps ${his} juices flowing.`;
-			} else if (slave.health.condition < -50) {
-				r.text += ` ${He} is so unwell, ${he} produces less than normal.`;
 			}
-		} else {
-			/* slave.energy <= 10 */
-			r.text += ` Unfortunately, ${he} is frigid and rarely reaches orgasm in spite of the intense automatic stimulation.`;
-		}
-
-		r.fluidSale = (r.fluid * jsRandom(40, 50));
-		r.text += ` ${capFirstChar(numberWithPluralOne(r.fluid, "deciliter"))} of uncommon ejaculate is gathered during ${his} milkings.`;
-		if (arcology.FSPastoralist !== "unset" && arcology.FSPastoralist > 30) {
-			r.fluidSale = (Math.trunc(r.fluidSale * (1 + (arcology.FSPastoralist - 30) / 140))); /* fully accepted pastoralism gives +50% on the price*/
-			r.text += ` Because of your arcology's cultural preferences, it comes with extra value.`;
 		}
-		r.text += ` It is sold for <span class="cash inc">${cashFormat(r.fluidSale)}.</span>`;
-	}
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function physicalEffects(slave) {
-		if (r.milk + r.cum + r.fluid > 0) {
-			if (slave.health.illness > 0 || slave.health.tired > 60) {
-				r.text += ` ${His} production was reduced this week due to<span class="cash dec">`;
-				if (slave.health.illness === 1) {
-					r.text += ` malaise`;
-				} else if (slave.health.illness === 2) {
-					r.text += ` minor illness`;
-				} else if (slave.health.illness === 3) {
-					r.text += ` sickness`;
-				} else if (slave.health.illness === 4) {
-					r.text += ` severe sickness`;
-				} else if (slave.health.illness === 5) {
-					r.text += ` terrible illness`;
-				}
-				if (slave.health.illness > 0 && slave.health.tired > 60) {
-					r.text += ` and`;
-				}
-				if (slave.health.tired > 90) {
-					r.text += ` exhaustion`;
-				} else if (slave.health.tired > 60) {
-					r.text += ` fatigue`;
-				}
-				r.text += `.</span>`;
+		/**
+		 * @param {App.Entity.SlaveState} slave
+		 * @param {number} multiplier
+		 */
+		function harvestGirlCum(slave, multiplier) {
+			r.fluid = girlCumAmount(slave) * multiplier;
+			r.text += ` ${His} female prostate fluid is considered an exotic delicacy.`;
+			if (slave.vagina >= 0) {
+				if (slave.vaginaLube === 2) {
+					r.text += ` ${His} excessive vaginal secretions bolster the mix.`;
+				} else if (slave.vaginaLube === 1) {
+					r.text += ` ${His} natural vaginal secretions add to the mix.`;
+				}
 			}
-			if (slave.assignment === Job.DAIRY) {
-				if (V.dairyRestraintsSetting > 1) {
-					r.text += ` The milking machine is merciless in its extraction of fluids from ${him}, but ${his} body is supplied with chemical stimulants to keep fatigue from setting in.`;
-				} else if (V.dairyRestraintsSetting > 0) {
-					if (slaveResting(slave)) {
-						r.text += ` Resting doesn't stop ${him} from being thoroughly milked, but it does free ${him} from some of the associated chores, allowing ${him} time <span class="health inc">to snooze</span> in ${his} harness post harvesting.`;
-					} else if (slave.health.tired + 9 >= 90 && !willWorkToDeath(slave)) {
-						r.text += ` ${He} attempts to skip out on milkings due to ${his} exhaustion, but can do little to avoid being dragged and strapped in to the milkers by `;
-						if (V.MilkmaidID !== 0) {
-							r.text += `${S.Milkmaid.slaveName}.`;
+			if (slave.energy > 10) {
+				if (slave.health.condition > 50) {
+					if (slave.energy > 90) {
+						r.text += ` As a nympho, ${he} has no trouble orgasming almost constantly.`;
+					}
+					r.text += ` ${His} shining health keeps ${his} juices flowing.`;
+				} else if (slave.health.condition < -50) {
+					r.text += ` ${He} is so unwell, ${he} produces less than normal.`;
+				}
+			} else {
+				/* slave.energy <= 10 */
+				r.text += ` Unfortunately, ${he} is frigid and rarely reaches orgasm in spite of the intense automatic stimulation.`;
+			}
+
+			r.fluidSale = (r.fluid * jsRandom(40, 50));
+			r.text += ` ${capFirstChar(numberWithPluralOne(r.fluid, "deciliter"))} of uncommon ejaculate is gathered during ${his} milkings.`;
+			if (arcology.FSPastoralist !== "unset" && arcology.FSPastoralist > 30) {
+				r.fluidSale = (Math.trunc(r.fluidSale * (1 + (arcology.FSPastoralist - 30) / 140))); /* fully accepted pastoralism gives +50% on the price*/
+				r.text += ` Because of your arcology's cultural preferences, it comes with extra value.`;
+			}
+			r.text += ` It is sold for <span class="cash inc">${cashFormat(r.fluidSale)}.</span>`;
+		}
+
+		/**
+		 * @param {FC.ReportSlave} slave
+		 */
+		function physicalEffects(slave) {
+			if (r.milk + r.cum + r.fluid > 0) {
+				if (slave.health.illness > 0 || slave.health.tired > 60) {
+					r.text += ` ${His} production was reduced this week due to<span class="cash dec">`;
+					if (slave.health.illness === 1) {
+						r.text += ` malaise`;
+					} else if (slave.health.illness === 2) {
+						r.text += ` minor illness`;
+					} else if (slave.health.illness === 3) {
+						r.text += ` sickness`;
+					} else if (slave.health.illness === 4) {
+						r.text += ` severe sickness`;
+					} else if (slave.health.illness === 5) {
+						r.text += ` terrible illness`;
+					}
+					if (slave.health.illness > 0 && slave.health.tired > 60) {
+						r.text += ` and`;
+					}
+					if (slave.health.tired > 90) {
+						r.text += ` exhaustion`;
+					} else if (slave.health.tired > 60) {
+						r.text += ` fatigue`;
+					}
+					r.text += `.</span>`;
+				}
+				if (slave.assignment === Job.DAIRY) {
+					if (V.dairyRestraintsSetting > 1) {
+						r.text += ` The milking machine is merciless in its extraction of fluids from ${him}, but ${his} body is supplied with chemical stimulants to keep fatigue from setting in.`;
+					} else if (V.dairyRestraintsSetting > 0) {
+						if (slaveResting(slave)) {
+							r.text += ` Resting doesn't stop ${him} from being thoroughly milked, but it does free ${him} from some of the associated chores, allowing ${him} time <span class="health inc">to snooze</span> in ${his} harness post harvesting.`;
+						} else if (slave.health.tired + 9 >= 90 && !willWorkToDeath(slave)) {
+							r.text += ` ${He} attempts to skip out on milkings due to ${his} exhaustion, but can do little to avoid being dragged and strapped in to the milkers by `;
+							if (V.MilkmaidID !== 0) {
+								r.text += `${S.Milkmaid.slaveName}.`;
+							} else {
+								r.text += `force.`;
+							}
+							r.text += ` ${He} quickly learns <span class="devotion inc">submission is the only choice</span> lest ${he} remain locked to the machine.`;
+							slave.devotion += 2;
 						} else {
-							r.text += `force.`;
+							if (slave.devotion > 20) {
+								r.text += ` All that is expected from ${him} is to submit to the machine's manipulations. It can get a little tiring by the end of the day, `;
+								if (V.dairyFeedersSetting + V.dairyStimulatorsSetting + V.dairyPregSetting > 0) {
+									r.text += `<span class="red">moreso given the dairy's settings,</span> `;
+								}
+								r.text += `but it is mostly manageable.`;
+							} else {
+								r.text += ` Spending so much time strapped to a machine and being forcibly drained is not only <span class="red">exhausting, `;
+								if (V.dairyFeedersSetting + V.dairyStimulatorsSetting + V.dairyPregSetting > 0) {
+									r.text += `especially given the dairy's settings, `;
+								}
+								r.text += `</span> but also haunts ${him} even after ${he} is released from the session.`;
+							}
 						}
-						r.text += ` ${He} quickly learns <span class="devotion inc">submission is the only choice</span> lest ${he} remain locked to the machine.`;
-						slave.devotion += 2;
 					} else {
-						if (slave.devotion > 20) {
-							r.text += ` All that is expected from ${him} is to submit to the machine's manipulations. It can get a little tiring by the end of the day, `;
-							if (V.dairyFeedersSetting + V.dairyStimulatorsSetting + V.dairyPregSetting > 0) {
-								r.text += `<span class="red">moreso given the dairy's settings,</span> `;
+						if (slaveResting(slave)) {
+							r.text += ` Resting doesn't stop ${him} from being thoroughly milked, but it does free ${him} from some of the associated chores, allowing ${him} time <span class="health inc">to catch some extra sleep</span> in ${his} stall.`;
+						} else if (slave.health.tired + 9 >= 90 && !willWorkToDeath(slave)) {
+							r.text += ` ${He} attempts to skip out on milkings due to ${his} exhaustion, but can do little to avoid being dragged and hooked up to the milkers by `;
+							if (V.MilkmaidID !== 0) {
+								r.text += `${S.Milkmaid.slaveName}.`;
+							} else {
+								r.text += `force.`;
 							}
-							r.text += `but it is mostly manageable.`;
+							r.text += ` ${He} quickly learns <span class="devotion inc">submitting to such a carefree life</span> is much easier than rebelling against it.`;
+							slave.devotion += 2;
 						} else {
-							r.text += ` Spending so much time strapped to a machine and being forcibly drained is not only <span class="red">exhausting, `;
-							if (V.dairyFeedersSetting + V.dairyStimulatorsSetting + V.dairyPregSetting > 0) {
-								r.text += `especially given the dairy's settings, `;
+							if (slave.devotion > 20) {
+								r.text += ` Being a free range cow is one of <span class="health inc">the most laid-back assignments</span> available. All that is required of ${him} is that ${he} lie back and get milked.`;
+							} else {
+								r.text += ` Being a free range cow can be one of the most laid-back assignments available, but ${he} fails to realize that and instead chooses to <span class="red">waste energy</span> struggling against the inevitable.`;
 							}
-							r.text += `</span> but also haunts ${him} even after ${he} is released from the session.`;
 						}
 					}
-				} else {
+					tired(slave);
+				} else if (slave.assignment === Job.MILKED) {
 					if (slaveResting(slave)) {
-						r.text += ` Resting doesn't stop ${him} from being thoroughly milked, but it does free ${him} from some of the associated chores, allowing ${him} time <span class="health inc">to catch some extra sleep</span> in ${his} stall.`;
-					} else if (slave.health.tired + 9 >= 90 && !willWorkToDeath(slave)) {
+						r.text += ` While less is required of ${him} during ${his} <span class="health inc">mandatory rest periods,</span> ${he} still needs to frequently visit the milkers, reducing the overall effectiveness of ${his} breaks.`;
+					} else if (slave.health.tired + 8 >= 90 && !willWorkToDeath(slave)) {
 						r.text += ` ${He} attempts to skip out on milkings due to ${his} exhaustion, but can do little to avoid being dragged and hooked up to the milkers by `;
-						if (V.MilkmaidID !== 0) {
+						if (V.dairy > 0 && V.universalRulesFacilityWork === 1 && V.dairySpots > 0 && V.MilkmaidID !== 0 && V.dairyRestraintsSetting < 2) {
 							r.text += `${S.Milkmaid.slaveName}.`;
 						} else {
 							r.text += `force.`;
 						}
-						r.text += ` ${He} quickly learns <span class="devotion inc">submitting to such a carefree life</span> is much easier than rebelling against it.`;
-						slave.devotion += 2;
+						r.text += ` ${His} <span class="devotion dec">protests</span> quickly fall silent as ${he} realizes struggling takes more energy than letting it happen.`;
+						slave.devotion -= 2;
 					} else {
+						r.text += ` ${His} assignment doesn't expect much from ${him}, `;
 						if (slave.devotion > 20) {
-							r.text += ` Being a free range cow is one of <span class="health inc">the most laid-back assignments</span> available. All that is required of ${him} is that ${he} lie back and get milked.`;
+							r.text += `giving ${him} plenty of time to relax throughout the day.`;
 						} else {
-							r.text += ` Being a free range cow can be one of the most laid-back assignments available, but ${he} fails to realize that and instead chooses to <span class="red">waste energy</span> struggling against the inevitable.`;
+							r.text += `but ${he} complicates things, <span Class="red">wasting energy</span> ${he} should be conserving for ${his} other responsibilities.`;
 						}
 					}
-				}
-				tired(slave);
-			} else if (slave.assignment === Job.MILKED) {
-				if (slaveResting(slave)) {
-					r.text += ` While less is required of ${him} during ${his} <span class="health inc">mandatory rest periods,</span> ${he} still needs to frequently visit the milkers, reducing the overall effectiveness of ${his} breaks.`;
-				} else if (slave.health.tired + 8 >= 90 && !willWorkToDeath(slave)) {
-					r.text += ` ${He} attempts to skip out on milkings due to ${his} exhaustion, but can do little to avoid being dragged and hooked up to the milkers by `;
-					if (V.dairy > 0 && V.universalRulesFacilityWork === 1 && V.dairySpots > 0 && V.MilkmaidID !== 0 && V.dairyRestraintsSetting < 2) {
-						r.text += `${S.Milkmaid.slaveName}.`;
-					} else {
-						r.text += `force.`;
-					}
-					r.text += ` ${His} <span class="devotion dec">protests</span> quickly fall silent as ${he} realizes struggling takes more energy than letting it happen.`;
-					slave.devotion -= 2;
+					tired(slave);
 				} else {
-					r.text += ` ${His} assignment doesn't expect much from ${him}, `;
-					if (slave.devotion > 20) {
-						r.text += `giving ${him} plenty of time to relax throughout the day.`;
-					} else {
-						r.text += `but ${he} complicates things, <span Class="red">wasting energy</span> ${he} should be conserving for ${his} other responsibilities.`;
-					}
+					r.text += ` Having to visit the milkers and cleaning up afterwards takes some time out of ${his} breaks.`;
+					slave.health.tired += 2;
 				}
-				tired(slave);
-			} else {
-				r.text += ` Having to visit the milkers and cleaning up afterwards takes some time out of ${his} breaks.`;
-				slave.health.tired += 2;
 			}
 		}
-	}
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function mentalEffects(slave) {
-		if (slave.assignment === window.Job.MILKED || (slave.assignment === window.Job.DAIRY && V.dairyRestraintsSetting < 2)) {
-			if (slave.behavioralQuirk === "fitness") {
-				r.text += ` ${slave.slaveName} <span class="devotion inc">privately enjoys</span> the focus on ${his} health and fitness that comes with being a cow.`;
-				slave.devotion += 1;
+		/**
+		 * @param {App.Entity.SlaveState} slave
+		 */
+		function mentalEffects(slave) {
+			if (slave.assignment === window.Job.MILKED || (slave.assignment === window.Job.DAIRY && V.dairyRestraintsSetting < 2)) {
+				if (slave.behavioralQuirk === "fitness") {
+					r.text += ` ${slave.slaveName} <span class="devotion inc">privately enjoys</span> the focus on ${his} health and fitness that comes with being a cow.`;
+					slave.devotion += 1;
+				}
 			}
 		}
-	}
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function assignmentVignette(slave) {
-		const vignette = GetVignette(slave);
-		const FuckResult = FResult(slave); // Got to be something better than this
-		r.text += ` <span class="story-label">This week</span> ${vignette.text} `;
-		if (vignette.type === "cash") {
-			const cashVign = Math.trunc(FuckResult * vignette.effect);
-			if (vignette.effect > 0) {
-				r.text += `<span class="cash inc">making you an extra ${cashFormat(cashVign)}.</span>`;
-			} else if (vignette.effect < 0) {
-				r.text += `<span class="cash dec">losing you ${cashFormat(Math.abs(cashVign))}.</span>`;
-			} else {
-				r.text += `an incident without lasting effect.`;
-			}
-			if (slave.assignment === window.Job.MILKED) {
+		/**
+		 * @param {App.Entity.SlaveState} slave
+		 */
+		function assignmentVignette(slave) {
+			const vignette = GetVignette(slave);
+			const FuckResult = FResult(slave); // Got to be something better than this
+			r.text += ` <span class="story-label">This week</span> ${vignette.text} `;
+			if (vignette.type === "cash") {
+				const cashVign = Math.trunc(FuckResult * vignette.effect);
 				if (vignette.effect > 0) {
-					cashX(cashVign, "slaveAssignmentMilkedVign", slave);
+					r.text += `<span class="cash inc">making you an extra ${cashFormat(cashVign)}.</span>`;
 				} else if (vignette.effect < 0) {
-					cashX(forceNeg(cashVign), "slaveAssignmentMilkedVign", slave);
+					r.text += `<span class="cash dec">losing you ${cashFormat(Math.abs(cashVign))}.</span>`;
+				} else {
+					r.text += `an incident without lasting effect.`;
 				}
-			} else if (slave.assignment === window.Job.DAIRY) {
+				if (slave.assignment === window.Job.MILKED) {
+					if (vignette.effect > 0) {
+						cashX(cashVign, "slaveAssignmentMilkedVign", slave);
+					} else if (vignette.effect < 0) {
+						cashX(forceNeg(cashVign), "slaveAssignmentMilkedVign", slave);
+					}
+				} else if (slave.assignment === window.Job.DAIRY) {
+					if (vignette.effect > 0) {
+						cashX(cashVign, "slaveAssignmentDairyVign", slave);
+					} else if (vignette.effect < 0) {
+						cashX(forceNeg(cashVign), "slaveAssignmentDairyVign", slave);
+					}
+				} else {
+					cashX(cashVign, "slaveAssignmentExtraMilkVign", slave);
+				}
+				vignetteCash += cashVign;
+			} else if (vignette.type === "devotion") {
 				if (vignette.effect > 0) {
-					cashX(cashVign, "slaveAssignmentDairyVign", slave);
+					if (slave.devotion > 50) {
+						r.text += `<span class="devotion inc">increasing ${his} devotion to you.</span>`;
+					} else if (slave.devotion >= -20) {
+						r.text += `<span class="devotion inc">increasing ${his} acceptance of you.</span>`;
+					} else if (slave.devotion >= -50) {
+						r.text += `<span class="devotion inc">reducing ${his} dislike of you.</span>`;
+					} else {
+						r.text += `<span class="devotion inc">reducing ${his} hatred of you.</span>`;
+					}
 				} else if (vignette.effect < 0) {
-					cashX(forceNeg(cashVign), "slaveAssignmentDairyVign", slave);
-				}
-			} else {
-				cashX(cashVign, "slaveAssignmentExtraMilkVign", slave);
-			}
-			vignetteCash += cashVign;
-		} else if (vignette.type === "devotion") {
-			if (vignette.effect > 0) {
-				if (slave.devotion > 50) {
-					r.text += `<span class="devotion inc">increasing ${his} devotion to you.</span>`;
-				} else if (slave.devotion >= -20) {
-					r.text += `<span class="devotion inc">increasing ${his} acceptance of you.</span>`;
-				} else if (slave.devotion >= -50) {
-					r.text += `<span class="devotion inc">reducing ${his} dislike of you.</span>`;
-				} else {
-					r.text += `<span class="devotion inc">reducing ${his} hatred of you.</span>`;
-				}
-			} else if (vignette.effect < 0) {
-				if (slave.devotion > 50) {
-					r.text += `<span class="devotion dec">reducing ${his} devotion to you.</span>`;
-				} else if (slave.devotion >= -20) {
-					r.text += `<span class="devotion dec">reducing ${his} acceptance of you.</span>`;
-				} else if (slave.devotion >= -50) {
-					r.text += `<span class="devotion dec">increasing ${his} dislike of you.</span>`;
+					if (slave.devotion > 50) {
+						r.text += `<span class="devotion dec">reducing ${his} devotion to you.</span>`;
+					} else if (slave.devotion >= -20) {
+						r.text += `<span class="devotion dec">reducing ${his} acceptance of you.</span>`;
+					} else if (slave.devotion >= -50) {
+						r.text += `<span class="devotion dec">increasing ${his} dislike of you.</span>`;
+					} else {
+						r.text += `<span class="devotion dec">increasing ${his} hatred of you.</span>`;
+					}
 				} else {
-					r.text += `<span class="devotion dec">increasing ${his} hatred of you.</span>`;
+					r.text += `an incident without lasting effect.`;
 				}
-			} else {
-				r.text += `an incident without lasting effect.`;
-			}
-			slave.devotion += vignette.effect;
-		} else if (vignette.type === "trust") {
-			if (vignette.effect > 0) {
-				if (slave.trust > 20) {
-					r.text += `<span class="trust inc">increasing ${his} trust in you.</span>`;
-				} else if (slave.trust >= -50) {
-					r.text += `<span class="trust inc">reducing ${his} fear of you.</span>`;
+				slave.devotion += vignette.effect;
+			} else if (vignette.type === "trust") {
+				if (vignette.effect > 0) {
+					if (slave.trust > 20) {
+						r.text += `<span class="trust inc">increasing ${his} trust in you.</span>`;
+					} else if (slave.trust >= -50) {
+						r.text += `<span class="trust inc">reducing ${his} fear of you.</span>`;
+					} else {
+						r.text += `<span class="trust inc">reducing ${his} terror of you.</span>`;
+					}
+				} else if (vignette.effect < 0) {
+					if (slave.trust > 20) {
+						r.text += `<span class="trust dec">reducing ${his} trust in you.</span>`;
+					} else if (slave.trust >= -20) {
+						r.text += `<span class="trust dec">increasing ${his} fear of you.</span>`;
+					} else {
+						r.text += `<span class="trust dec">increasing ${his} terror of you.</span>`;
+					}
 				} else {
-					r.text += `<span class="trust inc">reducing ${his} terror of you.</span>`;
+					r.text += `an incident without lasting effect.`;
 				}
-			} else if (vignette.effect < 0) {
-				if (slave.trust > 20) {
-					r.text += `<span class="trust dec">reducing ${his} trust in you.</span>`;
-				} else if (slave.trust >= -20) {
-					r.text += `<span class="trust dec">increasing ${his} fear of you.</span>`;
+				slave.trust += vignette.effect;
+			} else if (vignette.type === "health") {
+				if (vignette.effect > 0) {
+					r.text += `<span class="health inc">improving ${his} health.</span>`;
+				} else if (vignette.effect < 0) {
+					r.text += `<span class="health dec">affecting ${his} health.</span>`;
 				} else {
-					r.text += `<span class="trust dec">increasing ${his} terror of you.</span>`;
+					r.text += `an incident without lasting effect.`;
 				}
+				improveCondition(slave, 2 * vignette.effect);
 			} else {
-				r.text += `an incident without lasting effect.`;
-			}
-			slave.trust += vignette.effect;
-		} else if (vignette.type === "health") {
-			if (vignette.effect > 0) {
-				r.text += `<span class="health inc">improving ${his} health.</span>`;
-			} else if (vignette.effect < 0) {
-				r.text += `<span class="health dec">affecting ${his} health.</span>`;
-			} else {
-				r.text += `an incident without lasting effect.`;
-			}
-			improveCondition(slave, 2 * vignette.effect);
-		} else {
-			if (vignette.effect > 0) {
-				r.text += `<span class="reputation inc">gaining you a bit of reputation.</span>`;
-			} else if (vignette.effect < 0) {
-				r.text += `<span class="reputation dec">losing you a bit of reputation.</span>`;
-			} else {
-				r.text += `an incident without lasting effect.`;
+				if (vignette.effect > 0) {
+					r.text += `<span class="reputation inc">gaining you a bit of reputation.</span>`;
+				} else if (vignette.effect < 0) {
+					r.text += `<span class="reputation dec">losing you a bit of reputation.</span>`;
+				} else {
+					r.text += `an incident without lasting effect.`;
+				}
+				repX(Math.trunc(FuckResult * vignette.effect * 0.1), "vignette", slave);
+				vignetteRep += Math.trunc(FuckResult * vignette.effect * 0.1);
 			}
-			repX(Math.trunc(FuckResult * vignette.effect * 0.1), "vignette", slave);
-			vignetteRep += Math.trunc(FuckResult * vignette.effect * 0.1);
 		}
-	}
 
-	// FACILITY DECORATION IMPACTS
-	function applyFSDecoration() {
-		const fsGain = 0.0001 * (r.milk + (5 * r.cum));
-		FutureSocieties.DecorationBonus(V.dairyDecoration, fsGain);
-	}
-})();
+		// FACILITY DECORATION IMPACTS
+		function applyFSDecoration() {
+			const fsGain = 0.0001 * (r.milk + (5 * r.cum));
+			FutureSocieties.DecorationBonus(V.dairyDecoration, fsGain);
+		}
+	};
+}
diff --git a/src/endWeek/saGuardYou.js b/src/endWeek/saGuardYou.js
index ad736912cc1278acc7d47d9bb6f65c39646ab11a..48c40fa5bf082a280e922dfd594f9dd419abb6a8 100644
--- a/src/endWeek/saGuardYou.js
+++ b/src/endWeek/saGuardYou.js
@@ -1,48 +1,25 @@
-App.SlaveAssignment.guardYou = (function() {
-	"use strict";
-
-	let r;
-
-	let he;
-	let him;
-	let his;
-	let He;
-	let His;
-
-	let BGImpressiveness;
-
-	// Used for selecting a successor
-	let successorCandidates;
-	let combatSkilled;
-	let flawedTrainee;
-	let candidate;
-
-	return saGuardYou;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {string}
-	 */
-	function saGuardYou(slave) {
-		r = [];
-
-		({
-			he, him, his, He, His
-		} = getPronouns(slave));
-
-		BGImpressiveness = deadliness(slave);
-
-		updateBGState(slave);
-		jobPreface(slave);
-		publicImpression(slave);
-		jobEffects(slave);
-		if (V.bodyguardTrains === 1) {
-			trainReplacements(slave);
-		}
-
-		return r.join(" ");
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.guardYou = function saGuardYou(slave) {
+	/** @type {string[]} */
+	const r = [];
+
+	const {
+		he, him, his, He, His
+	} = getPronouns(slave);
+
+	updateBGState(slave);
+	jobPreface(slave);
+	publicImpression(slave);
+	jobEffects(slave);
+	if (V.bodyguardTrains === 1) {
+		trainReplacements(slave);
 	}
 
+	return r.join(" ");
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 *
@@ -232,19 +209,20 @@ App.SlaveAssignment.guardYou = (function() {
 		}
 
 		r.push(`${His} constant presence is`);
-		if (BGImpressiveness > 6) {
+		const impressiveness = deadliness(slave);
+		if (impressiveness > 6) {
 			r.push(`extremely intimidating, <span class="green">adding much to your reputation.</span>`);
 			if (slave.career === "an arcology owner") {
 				r.push(`You've made a one-time rival arcology owner into a deadly and loyal protector, a feat of slaveownership that's <span class="green">internationally famous.</span>`);
-				repX(BGImpressiveness * 50, "bodyguard", slave);
+				repX(impressiveness * 50, "bodyguard", slave);
 			}
-		} else if (BGImpressiveness > 3) {
+		} else if (impressiveness > 3) {
 			r.push(`intimidating, <span class="green">adding to your reputation.</span>`);
 		} else {
 			r.push(`hardly intimidating, <span class="yellow">barely adding to your reputation.</span>`);
 		}
 
-		repX(BGImpressiveness * 50, "bodyguard", slave);
+		repX(impressiveness * 50, "bodyguard", slave);
 	}
 
 	/**
@@ -272,13 +250,13 @@ App.SlaveAssignment.guardYou = (function() {
 	 */
 	function trainReplacements(slave) {
 		if (slave.devotion > 95 && slave.trust > 50 && slave.skill.combat > 0 && slave.intelligence + slave.intelligenceImplant > 15) {
-			successorCandidates = V.slaves.filter(function(s) { return (assignmentVisible(s) || s.assignment === Job.CONCUBINE || s.assignment === Job.WARDEN || s.assignment === Job.HEADGIRL || s.assignment === Job.QUARTER || s.assignment === Job.MASTERSUITE) && bodyguardSuccessorEligible(s); });
-			combatSkilled = successorCandidates.filter(function(s) { return s.skill.combat > 0; });
+			const successorCandidates = V.slaves.filter(function(s) { return (assignmentVisible(s) || s.assignment === Job.CONCUBINE || s.assignment === Job.WARDEN || s.assignment === Job.HEADGIRL || s.assignment === Job.QUARTER || s.assignment === Job.MASTERSUITE) && bodyguardSuccessorEligible(s); });
+			const combatSkilled = successorCandidates.filter(function(s) { return s.skill.combat > 0; });
 
 			r.push(`${He}'s confident in ${his} martial skills, but smart enough to know that${slave.geneMods.immortality > 0 ? `, while technically immortal, ${he} isn't invincible` : ` ${he} isn't immortal`}, and devoted enough to worry about who will protect you should ${he} die.`);
 			if (combatSkilled.length < 2) {
-				candidate = null;
-				flawedTrainee = 0;
+				let candidate = null;
+				let flawedTrainee = 0;
 				if (slave.relationship > 1) {
 					candidate = getSlave(slave.relationshipTarget);
 					if (candidate !== undefined && candidate.skill.combat === 0 && bodyguardSuccessorEligible(candidate)) {
@@ -341,4 +319,4 @@ App.SlaveAssignment.guardYou = (function() {
 			}
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saHormonesEffects.js b/src/endWeek/saHormonesEffects.js
index 333d848c6fb4f02d40195399535c916f5c365f28..11feec09c6bd73852c269140fed18e2deb2c3310 100644
--- a/src/endWeek/saHormonesEffects.js
+++ b/src/endWeek/saHormonesEffects.js
@@ -1,56 +1,33 @@
-App.SlaveAssignment.hormonesEffects = (function() {
-	"use strict";
-
-	let r;
-
-	let he;
-	let him;
-	let his;
-	let He;
-	let His;
-
-	let gigantomastiaMod;
-	let rearLipedemaMod;
-	let boobSize;
-	let buttSize;
-	let normBreasts;
-	let normButt;
-	let faceValue;
-	let faceInc;
-	let faceDec;
-
-	return saHormonesEffects;
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @returns {string}
-	 */
-	function saHormonesEffects(slave) {
-		r = [];
-		gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
-		rearLipedemaMod = slave.geneticQuirks.rearLipedema === 2 ? 1 : 0;
-		boobSize = slave.boobs - slave.boobsImplant - slave.boobsMilk;
-		buttSize = slave.butt - slave.buttImplant;
-		faceValue = slave.face - slave.faceImplant;
-
-		({
-			he, him, his, He, His,
-		} = getPronouns(slave));
-
-		hormoneBalance(slave);
-		if (V.hormoneUpgradeMood === 0) {
-			moodConflict(slave);
-		}
-		if (slave.physicalAge >= 18 || V.loliGrow === 0 || slave.geneMods.NCS === 1) {
-			hormonesEffects(slave);
-		}
-		if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
-			hormoneReactions(slave);
-		}
-
-		return r.join(" ");
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.hormonesEffects = function saHormonesEffects(slave) {
+	/** @type {string[]} */
+	const r = [];
+	const gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
+	const rearLipedemaMod = slave.geneticQuirks.rearLipedema === 2 ? 1 : 0;
+	const boobSize = slave.boobs - slave.boobsImplant - slave.boobsMilk;
+	const buttSize = slave.butt - slave.buttImplant;
+	const faceValue = slave.face - slave.faceImplant;
+
+	const {
+		he, him, his, He, His,
+	} = getPronouns(slave);
+
+	hormoneBalance(slave);
+	if (V.hormoneUpgradeMood === 0) {
+		moodConflict(slave);
+	}
+	if (slave.physicalAge >= 18 || V.loliGrow === 0 || slave.geneMods.NCS === 1) {
+		hormonesEffects(slave);
+	}
+	if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
+		hormoneReactions(slave);
 	}
 
+	return r.join(" ");
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 *
@@ -86,11 +63,18 @@ App.SlaveAssignment.hormonesEffects = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
 	 */
 	function moodConflict(slave) {
+		let conflict = false;
 		if (slave.hormoneBalance > 20 && slave.genes === "XY" && slave.balls !== 0 && slave.ballType !== "sterile") {
 			r.push(`${His} feminine hormonal balance conflicts with ${his} natural hormones,`);
+			conflict = true;
+		} else if (slave.hormoneBalance < -20 && slave.genes === "XX" && (slave.ovaries !== 0 || slave.mpreg !== 0)) {
+			r.push(`${His} masculine hormonal balance conflicts with ${his} natural hormones,`);
+			conflict = true;
+		}
+
+		if (conflict) {
 			if (slave.devotion > 50) {
 				r.push(`but ${he}'s a good enough slave to suppress the occasional moodiness.`);
 			} else {
@@ -111,36 +95,228 @@ App.SlaveAssignment.hormonesEffects = (function() {
 				}
 			}
 		}
-		if (slave.hormoneBalance < -20 && slave.genes === "XX" && (slave.ovaries !== 0 || slave.mpreg !== 0)) {
-			r.push(`${His} masculine hormonal balance conflicts with ${his} natural hormones,`);
-			if (slave.devotion > 50) {
-				r.push(`but ${he}'s a good enough slave to suppress the occasional moodiness.`);
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function softenFaceShape(slave) {
+		if (slave.faceImplant < 5) {
+			if (slave.faceShape === "masculine") {
+				r.push(`Hormonal effects cause <span class="orange">${his} face to soften into`);
+				if (slave.geneMods.NCS === 1) {
+					r.push(`childlike`);
+				}
+				r.push(`androgyny.</span>`);
+				slave.faceShape = "androgynous";
+			} else if (slave.faceShape === "androgynous" && slave.geneticQuirks.androgyny !== 2) {
+				r.push(`Hormonal effects cause <span class="lime">${his} face to soften into`);
+				if (slave.geneMods.NCS === 1) {
+					r.push(`childlike normalcy.</span>`);
+				} else {
+					r.push(`femininity.</span>`);
+				}
+				slave.faceShape = "normal";
+			} else if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.faceShape === "normal") {
+				r.push(`Hormonal effects cause <span class="lime">${his} face to soften into childlike cuteness.</span>`);
+				slave.faceShape = "cute";
+			}
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function softenFace(slave) {
+		r.push(`Hormonal effects cause <span class="lime">${his} facial structure to soften and become ${slave.face >= 0 ? "more attractive" : "less unattractive"}.</span>`);
+		let faceInc = 1 + V.hormoneUpgradePower;
+		if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
+			faceInc *= 2;
+		}
+		faceIncrease(slave, faceInc);
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {number} maxVoice
+	 */
+	function raiseVoice(slave, maxVoice) {
+		if (slave.voice < maxVoice && slave.voice > 0) {
+			r.push(`Hormonal effects cause <span class="lime">${his} voice to become higher and more`);
+			if (slave.geneMods.NCS === 1) {
+				r.push(`childlike.</span>`);
 			} else {
-				r.push(`causing <span class="mediumorchid">occasional moodiness.</span>`);
-				slave.devotion -= 1;
+				r.push(`feminine.</span>`);
 			}
-			if (slave.energy > 10) {
-				r.push(`It also has the unfortunate consequence of <span class="libido dec">damaging ${his} libido.</span>`);
-				slave.energy--;
+			slave.voice++;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {number} minimumMuscles
+	 */
+	function softenMuscles(slave, minimumMuscles) {
+		if (slave.muscles > minimumMuscles && slave.diet !== "muscle building" && slave.drugs !== "steroids" && (slave.geneticQuirks.mGain !== 2 || slave.geneticQuirks.mLoss === 2)) {
+			r.push(`Hormonal effects <span class="orange">reduce ${his} musculature.</span>`);
+			slave.muscles -= 2 + V.hormoneUpgradePower + slave.geneticQuirks.mLoss;
+			if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
+				slave.muscles -= 2 + V.hormoneUpgradePower + slave.geneticQuirks.mLoss;
 			}
-			if (slave.attrXX > 50 || slave.attrXY > 50) {
-				r.push(`Even more troubling, ${his} sexual confusion <span class="red">leaves ${him} finding others less attractive.</span>`);
-				if (slave.attrXX > 50) {
-					slave.attrXX--;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {number} maxWetness
+	 */
+	function increaseWetness(slave, maxWetness) {
+		if (slave.vagina > -1 && slave.ovaries !== 0 && slave.vaginaLube < maxWetness) {
+			r.push(`Hormonal effects cause <span class="lime">${his} vagina to produce more copious natural lubricant.</span>`);
+			slave.vaginaLube++;
+		}
+	}
+
+	/**
+	 * Atrophy genitals because of too much female hormones
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function atrophyGenitals(slave) {
+		if (V.hormoneUpgradeShrinkage === 0) {
+			if (slave.dick > 1) {
+				if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.dick > 2) {
+					r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} dick to atrophy a lot.</span>`);
+					slave.dick--;
+				} else {
+					r.push(`Hormonal effects cause <span class="orange">${his} dick to atrophy.</span>`);
 				}
-				if (slave.attrXY > 50) {
-					slave.attrXY--;
+				slave.dick--;
+			}
+			if (slave.balls > 1) {
+				if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.balls > 2) {
+					r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} testicles to atrophy a lot.</span>`);
+					slave.balls--;
+				} else {
+					r.push(`Hormonal effects cause <span class="orange">${his} testicles to atrophy.</span>`);
 				}
+				slave.balls--;
+			}
+			if (slave.clit > 0) {
+				if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.clit > 1) {
+					r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} clit to shrink down greatly.</span>`);
+					slave.clit--;
+				} else {
+					r.push(`Hormonal effects cause <span class="orange">${his} clit to shrink significantly.</span>`);
+				}
+				slave.clit--;
 			}
 		}
 	}
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
+	 */
+	function mentalEffectsFemale(slave) {
+		if (slave.devotion <= 20) {
+			r.push(`Hormonal effects make ${him} a bit more <span class="hotpink">docile.</span>`);
+			slave.devotion++;
+		}
+		if (slave.trust <= 20) {
+			r.push(`Hormonal effects make ${him} a bit more <span class="mediumaquamarine">trusting.</span>`);
+			slave.trust++;
+		}
+		if (slave.attrXY < 100) {
+			r.push(`Hormonal effects cause ${him} to become <span class="green">more attracted to men.</span>`);
+			slave.attrXY += 2 + V.hormoneUpgradePower;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function hardenFaceShape(slave) {
+		if (slave.faceImplant < 5) {
+			if (slave.geneticQuirks.androgyny !== 2) {
+				if (slave.faceShape === "androgynous") {
+					r.push(`Hormonal effects cause <span class="orange">${his} face to harden into masculinity.</span>`);
+					slave.faceShape = "masculine";
+				} else if (slave.faceShape !== "masculine") {
+					r.push(`Hormonal effects cause <span class="orange">${his} face to harden into androgyny.</span>`);
+					slave.faceShape = "androgynous";
+				}
+			}
+		}
+	}
+
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function hardenFace(slave) {
+		if (faceValue.isBetween(0, 100)) {
+			r.push(`Hormonal effects cause <span class="orange">${his} facial structure to harden and become less attractive.</span>`);
+			const faceDec = 1 + V.hormoneUpgradePower;
+			slave.face = Math.clamp(slave.face - faceDec, -100, 100);
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {number} minVoice
+	 */
+	function lowerVoice(slave, minVoice) {
+		if (slave.voice > minVoice) {
+			r.push(`Hormonal effects cause <span class="orange">${his} voice to become deeper and less feminine.</span>`);
+			slave.voice--;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function shrinkButt(slave) {
+		if (buttSize > 1 && rearLipedemaMod === 0) {
+			if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && buttSize > 2) {
+				r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} butt to decrease a lot.</span>`);
+				slave.butt -= 1;
+			} else {
+				r.push(`Hormonal effects cause <span class="orange">the natural size of ${his} butt to decrease.</span>`);
+			}
+			slave.butt--;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function shrinkBoobs(slave) {
+		if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
+			r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} tits to shrink a lot.</span>`);
+			slave.boobs -= 10 + (15 * V.hormoneUpgradePower);
+		} else {
+			r.push(`Hormonal effects cause <span class="orange">the natural size of ${his} tits to shrink.</span>`);
+		}
+		slave.boobs -= 10 + (15 * V.hormoneUpgradePower);
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {number} minWetness
+	 */
+	function lowerWetness(slave, minWetness) {
+		if (slave.vagina > -1 && slave.vaginaLube > 0) {
+			r.push(`Hormonal effects cause <span class="orange">${his} vagina to produce less natural lubricant.</span>`);
+			slave.vaginaLube--;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
 	 */
 	function hormonesEffects(slave) {
 		if (Math.abs(slave.hormoneBalance) >= 50) {
+			let normBreasts = 0;
+			let normButt = 0;
 			if (slave.hormoneBalance > 30 && slave.geneMods.NCS !== 1) {
 				/* 'Expected' breast size based on weight for feminine-bodied slaves */
 				normBreasts = Math.trunc((100 + (slave.weight + 100) * 5 + 2 * slave.lactationAdaptation) * (0.85 + slave.hormoneBalance / 400) * gigantomastiaMod);
@@ -164,56 +340,17 @@ App.SlaveAssignment.hormonesEffects = (function() {
 					}
 				}
 
-				if (slave.faceImplant < 5) {
-					if (slave.faceShape === "masculine") {
-						r.push(`Hormonal effects cause <span class="orange">${his} face to soften into`);
-						if (slave.geneMods.NCS === 1) {
-							r.push(`childlike`);
-						}
-						r.push(`androgyny.</span>`);
-						slave.faceShape = "androgynous";
-					} else if (slave.faceShape === "androgynous" && slave.geneticQuirks.androgyny !== 2) {
-						r.push(`Hormonal effects cause <span class="lime">${his} face to soften into`);
-						if (slave.geneMods.NCS === 1) {
-							r.push(`childlike normalcy.</span>`);
-						} else {
-							r.push(`femininity.</span>`);
-						}
-						slave.faceShape = "normal";
-					} else if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.faceShape === "normal") {
-						r.push(`Hormonal effects cause <span class="lime">${his} face to soften into childlike cuteness.</span>`);
-						slave.faceShape = "cute";
-					}
-				}
+				softenFaceShape(slave);
 				if (faceValue < 50 && slave.face < 75) {
-					r.push(`Hormonal effects cause <span class="lime">${his} facial structure to soften and become ${slave.face >= 0 ? "more attractive" : "less unattractive"}.</span>`);
-					faceInc = 1 + V.hormoneUpgradePower;
-					if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
-						faceInc *= 2;
-					}
-					faceIncrease(slave, faceInc);
+					softenFace(slave);
 					if (faceValue >= 50 || slave.face >= 75) {
 						r.push(`${His} face is now quite beautiful; hormonal treatments alone <span class="yellow">cannot improve it further.</span>`);
 					}
 				}
 
-				if (slave.voice < 3 && slave.voice > 0) {
-					r.push(`Hormonal effects cause <span class="lime">${his} voice to become higher and more`);
-					if (slave.geneMods.NCS === 1) {
-						r.push(`childlike.</span>`);
-					} else {
-						r.push(`feminine.</span>`);
-					}
-					slave.voice++;
-				}
+				raiseVoice(slave, 3);
+				softenMuscles(slave, 10);
 
-				if (slave.muscles > 10 && slave.diet !== "muscle building" && slave.drugs !== "steroids" && (slave.geneticQuirks.mGain !== 2 || slave.geneticQuirks.mLoss === 2)) {
-					r.push(`Hormonal effects <span class="orange">reduce ${his} musculature.</span>`);
-					slave.muscles -= 2 + V.hormoneUpgradePower + slave.geneticQuirks.mLoss;
-					if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
-						slave.muscles -= 2 + V.hormoneUpgradePower + slave.geneticQuirks.mLoss;
-					}
-				}
 				if (slave.waist > -30) {
 					r.push(`Hormonal effects cause ${his} <span class="lime">waist to narrow.</span>`);
 					slave.waist -= 2 + V.hormoneUpgradePower;
@@ -237,101 +374,20 @@ App.SlaveAssignment.hormonesEffects = (function() {
 				} else {
 					r.push(`${His} <span class="orange">NCS</span> blocks asset growth despite the fact that ${his} body is swimming in hormones.`);
 				}
-				if (slave.vagina > -1 && slave.ovaries !== 0 && slave.vaginaLube < 2) {
-					r.push(`Hormonal effects cause <span class="lime">${his} vagina to produce more copious natural lubricant.</span>`);
-					slave.vaginaLube++;
-				}
+				increaseWetness(slave, 2);
 
-				if (V.hormoneUpgradeShrinkage === 0) {
-					if (slave.dick > 1) {
-						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.dick > 2) {
-							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} dick to atrophy a lot.</span>`);
-							slave.dick -= 1;
-						} else {
-							r.push(`Hormonal effects cause <span class="orange">${his} dick to atrophy.</span>`);
-						}
-						slave.dick--;
-					}
-					if (slave.balls > 1) {
-						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.balls > 2) {
-							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} testicles to atrophy a lot.</span>`);
-							slave.balls -= 1;
-						} else {
-							r.push(`Hormonal effects cause <span class="orange">${his} testicles to atrophy.</span>`);
-						}
-						slave.balls--;
-					}
-					if (slave.clit > 0) {
-						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.clit > 1) {
-							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} clit to shrink down greatly.</span>`);
-							slave.clit -= 1;
-						} else {
-							r.push(`Hormonal effects cause <span class="orange">${his} clit to shrink significantly.</span>`);
-						}
-						slave.clit--;
-					}
-				}
+				atrophyGenitals(slave);
 
-				if (slave.devotion <= 20) {
-					r.push(`Hormonal effects make ${him} a bit more <span class="hotpink">docile.</span>`);
-					slave.devotion++;
-				}
-				if (slave.trust <= 20) {
-					r.push(`Hormonal effects make ${him} a bit more <span class="mediumaquamarine">trusting.</span>`);
-					slave.trust++;
-				}
-				if (slave.attrXY < 100) {
-					r.push(`Hormonal effects cause ${him} to become <span class="green">more attracted to men.</span>`);
-					slave.attrXY += 2 + V.hormoneUpgradePower;
-				}
+				mentalEffectsFemale(slave);
 			} else if (slave.hormoneBalance >= 300) {
-				if (slave.faceImplant < 5) {
-					if (slave.faceShape === "masculine") {
-						r.push(`Hormonal effects cause <span class="orange">${his} face to soften into`);
-						if (slave.geneMods.NCS === 1) {
-							r.push(`childlike`);
-						}
-						r.push(`androgyny.</span>`);
-						slave.faceShape = "androgynous";
-					} else if (slave.faceShape === "androgynous" && slave.geneticQuirks.androgyny !== 2) {
-						r.push(`Hormonal effects cause <span class="lime">${his} face to soften into`);
-						if (slave.geneMods.NCS === 1) {
-							r.push(`childlike normalcy.</span>`);
-						} else {
-							r.push(`femininity.</span>`);
-						}
-						slave.faceShape = "normal";
-					} else if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.faceShape === "normal") {
-						r.push(`Hormonal effects cause <span class="lime">${his} face to soften into childlike cuteness.</span>`);
-						slave.faceShape = "cute";
-					}
-				}
+				softenFaceShape(slave);
 				if (faceValue < 30 && slave.face < 60) {
-					r.push(`Hormonal effects cause <span class="lime">${his} facial structure to soften and become ${slave.face >= 0 ? "more attractive" : "less unattractive"}.</span>`);
-					faceInc = 1 + V.hormoneUpgradePower;
-					if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
-						faceInc *= 2;
-					}
-					faceIncrease(slave, faceInc);
+					softenFace(slave);
 				}
 
-				if (slave.voice < 3 && slave.voice > 0) {
-					r.push(`Hormonal effects cause <span class="lime">${his} voice to become higher and more`);
-					if (slave.geneMods.NCS === 1) {
-						r.push(`childlike.</span>`);
-					} else {
-						r.push(`feminine.</span>`);
-					}
-					slave.voice++;
-				}
+				raiseVoice(slave, 3);
+				softenMuscles(slave, 30);
 
-				if (slave.muscles > 30 && slave.diet !== "muscle building" && slave.drugs !== "steroids" && (slave.geneticQuirks.mGain !== 2 || slave.geneticQuirks.mLoss === 2)) {
-					r.push(`Hormonal effects <span class="orange">reduce ${his} musculature.</span>`);
-					slave.muscles -= 2 + V.hormoneUpgradePower + slave.geneticQuirks.mLoss;
-					if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
-						slave.muscles -= 2 + V.hormoneUpgradePower + slave.geneticQuirks.mLoss;
-					}
-				}
 				if (slave.waist > -10) {
 					r.push(`Hormonal effects cause ${his} <span class="lime">waist to narrow.</span>`);
 					slave.waist -= 2 + V.hormoneUpgradePower;
@@ -353,101 +409,20 @@ App.SlaveAssignment.hormonesEffects = (function() {
 						slave.butt += 0.2;
 					}
 				}
-				if (slave.vagina > -1 && slave.ovaries !== 0 && slave.vaginaLube < 2) {
-					r.push(`Hormonal effects cause <span class="lime">${his} vagina to produce more copious natural lubricant.</span>`);
-					slave.vaginaLube++;
-				}
+				increaseWetness(slave, 2);
 
-				if (V.hormoneUpgradeShrinkage === 0) {
-					if (slave.dick > 1) {
-						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.dick > 2) {
-							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} dick to atrophy a lot.</span>`);
-							slave.dick -= 1;
-						} else {
-							r.push(`Hormonal effects cause <span class="orange">${his} dick to atrophy.</span>`);
-						}
-						slave.dick--;
-					}
-					if (slave.balls > 1) {
-						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.balls > 2) {
-							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} testicles to atrophy a lot.</span>`);
-							slave.balls -= 1;
-						} else {
-							r.push(`Hormonal effects cause <span class="orange">${his} testicles to atrophy.</span>`);
-						}
-						slave.balls--;
-					}
-					if (slave.clit > 0) {
-						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.clit > 1) {
-							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} clit to shrink down greatly.</span>`);
-							slave.clit -= 1;
-						} else {
-							r.push(`Hormonal effects cause <span class="orange">${his} clit to shrink significantly.</span>`);
-						}
-						slave.clit--;
-					}
-				}
+				atrophyGenitals(slave);
 
-				if (slave.devotion <= 20) {
-					r.push(`Hormonal effects make ${him} a bit more <span class="hotpink">docile.</span>`);
-					slave.devotion++;
-				}
-				if (slave.trust <= 20) {
-					r.push(`Hormonal effects make ${him} a bit more <span class="mediumaquamarine">trusting.</span>`);
-					slave.trust++;
-				}
-				if (slave.attrXY < 100) {
-					r.push(`Hormonal effects cause ${him} to become <span class="green">more attracted to men.</span>`);
-					slave.attrXY += 2 + V.hormoneUpgradePower;
-				}
+				mentalEffectsFemale(slave);
 			} else if (slave.hormoneBalance >= 250) {
-				if (slave.faceImplant < 5) {
-					if (slave.faceShape === "masculine") {
-						r.push(`Hormonal effects cause <span class="orange">${his} face to soften into`);
-						if (slave.geneMods.NCS === 1) {
-							r.push(`childlike`);
-						}
-						r.push(`androgyny.</span>`);
-						slave.faceShape = "androgynous";
-					} else if (slave.faceShape === "androgynous" && slave.geneticQuirks.androgyny !== 2) {
-						r.push(`Hormonal effects cause <span class="lime">${his} face to soften into`);
-						if (slave.geneMods.NCS === 1) {
-							r.push(`childlike normalcy.</span>`);
-						} else {
-							r.push(`femininity.</span>`);
-						}
-						slave.faceShape = "normal";
-					} else if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && slave.faceShape === "normal") {
-						r.push(`Hormonal effects cause <span class="lime">${his} face to soften into childlike cuteness.</span>`);
-						slave.faceShape = "cute";
-					}
-				}
+				softenFaceShape(slave);
 				if (faceValue < 10 && slave.face < 30) {
-					r.push(`Hormonal effects cause <span class="lime">${his} facial structure to soften and become ${slave.face >= 0 ? "more attractive" : "less unattractive"}.</span>`);
-					faceInc = 1 + V.hormoneUpgradePower;
-					if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
-						faceInc *= 2;
-					}
-					faceIncrease(slave, faceInc);
+					softenFace(slave);
 				}
 
-				if (slave.voice < 2 && slave.voice > 0) {
-					r.push(`Hormonal effects cause <span class="lime">${his} voice to become higher and more`);
-					if (slave.geneMods.NCS === 1) {
-						r.push(`childlike.</span>`);
-					} else {
-						r.push(`feminine.</span>`);
-					}
-					slave.voice++;
-				}
+				raiseVoice(slave, 2);
+				softenMuscles(slave, 30);
 
-				if (slave.muscles > 30 && slave.diet !== "muscle building" && slave.drugs !== "steroids" && (slave.geneticQuirks.mGain !== 2 || slave.geneticQuirks.mLoss === 2)) {
-					r.push(`Hormonal effects <span class="orange">reduce ${his} musculature.</span>`);
-					slave.muscles -= 2 + V.hormoneUpgradePower + slave.geneticQuirks.mLoss;
-					if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
-						slave.muscles -= 2 + V.hormoneUpgradePower + slave.geneticQuirks.mLoss;
-					}
-				}
 				if (slave.waist > 0) {
 					r.push(`Hormonal effects cause ${his} <span class="lime">waist to narrow.</span>`);
 					slave.waist -= 2 + V.hormoneUpgradePower;
@@ -469,10 +444,7 @@ App.SlaveAssignment.hormonesEffects = (function() {
 						slave.butt += 0.2;
 					}
 				}
-				if (slave.vagina > -1 && slave.ovaries !== 0 && slave.vaginaLube < 1) {
-					r.push(`Hormonal effects cause <span class="lime">${his} vagina to produce more copious natural lubricant.</span>`);
-					slave.vaginaLube++;
-				}
+				increaseWetness(slave, 1);
 
 				if (V.hormoneUpgradeShrinkage === 0) {
 					if (slave.dick > 2) {
@@ -537,30 +509,16 @@ App.SlaveAssignment.hormonesEffects = (function() {
 				}
 				if (faceValue < 0 && slave.face < 0) {
 					r.push(`Hormonal effects cause <span class="lime">${his} facial structure to soften and become less unattractive.</span>`);
-					faceInc = 1 + V.hormoneUpgradePower;
+					let faceInc = 1 + V.hormoneUpgradePower;
 					if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
 						faceInc *= 2;
 					}
 					faceIncrease(slave, faceInc);
 				}
 
-				if (slave.voice < 2 && slave.voice > 0) {
-					r.push(`Hormonal effects cause <span class="lime">${his} voice to become higher and more`);
-					if (slave.geneMods.NCS === 1) {
-						r.push(`childlike.</span>`);
-					} else {
-						r.push(`feminine.</span>`);
-					}
-					slave.voice++;
-				}
+				raiseVoice(slave, 2);
+				softenMuscles(slave, 30);
 
-				if (slave.muscles > 30 && slave.diet !== "muscle building" && slave.drugs !== "steroids" && (slave.geneticQuirks.mGain !== 2 || slave.geneticQuirks.mLoss === 2)) {
-					r.push(`Hormonal effects <span class="orange">reduce ${his} musculature.</span>`);
-					slave.muscles -= 2 + V.hormoneUpgradePower + slave.geneticQuirks.mLoss;
-					if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
-						slave.muscles -= 2 + V.hormoneUpgradePower + slave.geneticQuirks.mLoss;
-					}
-				}
 				if (slave.waist > 10) {
 					r.push(`Hormonal effects cause ${his} <span class="lime">waist to narrow.</span>`);
 					slave.waist -= 2 + V.hormoneUpgradePower;
@@ -582,10 +540,7 @@ App.SlaveAssignment.hormonesEffects = (function() {
 						slave.butt += 0.2;
 					}
 				}
-				if (slave.vagina > -1 && slave.ovaries !== 0 && slave.vaginaLube < 1) {
-					r.push(`Hormonal effects cause <span class="lime">${his} vagina to produce more copious natural lubricant.</span>`);
-					slave.vaginaLube++;
-				}
+				increaseWetness(slave, 1);
 
 				if (V.hormoneUpgradeShrinkage === 0) {
 					if (slave.dick > 3) {
@@ -684,38 +639,13 @@ App.SlaveAssignment.hormonesEffects = (function() {
 				}
 
 				if (slave.geneMods.NCS === 0) {
-					if (slave.faceImplant < 5) {
-						if (slave.geneticQuirks.androgyny !== 2) {
-							if (slave.faceShape === "androgynous") {
-								r.push(`Hormonal effects cause <span class="orange">${his} face to harden into masculinity.</span>`);
-								slave.faceShape = "masculine";
-							} else if (slave.faceShape !== "masculine") {
-								r.push(`Hormonal effects cause <span class="orange">${his} face to harden into androgyny.</span>`);
-								slave.faceShape = "androgynous";
-							}
-						}
-					}
-					if (faceValue.isBetween(0, 100)) {
-						r.push(`Hormonal effects cause <span class="orange">${his} facial structure to harden and become less attractive.</span>`);
-						faceDec = 1 + V.hormoneUpgradePower;
-						slave.face = Math.clamp(slave.face - faceDec, -100, 100);
-					}
-					if (slave.voice > 1) {
-						r.push(`Hormonal effects cause <span class="orange">${his} voice to become deeper and less feminine.</span>`);
-						slave.voice--;
-					}
+					hardenFaceShape(slave);
+					hardenFace(slave);
+					lowerVoice(slave, 1);
 				}
 
 				if (V.hormoneUpgradeShrinkage === 0) {
-					if (buttSize > 1 && rearLipedemaMod !== 2) {
-						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && buttSize > 2) {
-							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} butt to decrease a lot.</span>`);
-							slave.butt -= 1;
-						} else {
-							r.push(`Hormonal effects cause <span class="orange">the natural size of ${his} butt to decrease.</span>`);
-						}
-						slave.butt--;
-					}
+					shrinkButt(slave);
 					if (boobSize > 100 * gigantomastiaMod && gigantomastiaMod !== 3) {
 						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && boobSize > 200) {
 							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} tits to shrink a lot.</span>`);
@@ -747,10 +677,7 @@ App.SlaveAssignment.hormonesEffects = (function() {
 						r.push(`Hormonal effects cause <span class="lime">${his} clit to grow significantly.</span>`);
 						slave.clit++;
 					}
-					if (slave.vagina > -1 && slave.vaginaLube > 0) {
-						r.push(`Hormonal effects cause <span class="orange">${his} vagina to produce less natural lubricant.</span>`);
-						slave.vaginaLube--;
-					}
+					lowerWetness(slave, 0);
 
 					if (slave.muscles <= 50 && slave.diet !== "slimming") {
 						r.push(`Hormonal effects <span class="lime">build up ${his} musculature.</span>`);
@@ -773,47 +700,15 @@ App.SlaveAssignment.hormonesEffects = (function() {
 				}
 			} else if (slave.hormoneBalance <= -300) {
 				if (slave.geneMods.NCS === 0) {
-					if (slave.faceImplant < 5) {
-						if (slave.geneticQuirks.androgyny !== 2) {
-							if (slave.faceShape === "androgynous") {
-								r.push(`Hormonal effects cause <span class="orange">${his} face to harden into masculinity.</span>`);
-								slave.faceShape = "masculine";
-							} else if (slave.faceShape !== "masculine") {
-								r.push(`Hormonal effects cause <span class="orange">${his} face to harden into androgyny.</span>`);
-								slave.faceShape = "androgynous";
-							}
-						}
-					}
-					if (faceValue.isBetween(0, 100)) {
-						r.push(`Hormonal effects cause <span class="orange">${his} facial structure to harden and become less attractive.</span>`);
-						faceDec = 1 + V.hormoneUpgradePower;
-						slave.face = Math.clamp(slave.face - faceDec, -100, 100);
-					}
-
-					if (slave.voice > 1) {
-						r.push(`Hormonal effects cause <span class="orange">${his} voice to become deeper and less feminine.</span>`);
-						slave.voice--;
-					}
+					hardenFaceShape(slave);
+					hardenFace(slave);
+					lowerVoice(slave, 1);
 				}
 
 				if (V.hormoneUpgradeShrinkage === 0) {
-					if (buttSize > 1 && rearLipedemaMod !== 2) {
-						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50 && buttSize > 2) {
-							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} butt to decrease a lot.</span>`);
-							slave.butt -= 1;
-						} else {
-							r.push(`Hormonal effects cause <span class="orange">the natural size of ${his} butt to decrease.</span>`);
-						}
-						slave.butt--;
-					}
+					shrinkButt(slave);
 					if (boobSize > 300 * gigantomastiaMod && gigantomastiaMod !== 3) {
-						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
-							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} tits to shrink a lot.</span>`);
-							slave.boobs -= 10 + (15 * V.hormoneUpgradePower);
-						} else {
-							r.push(`Hormonal effects cause <span class="orange">the natural size of ${his} tits to shrink.</span>`);
-						}
-						slave.boobs -= 10 + (15 * V.hormoneUpgradePower);
+						shrinkBoobs(slave);
 					}
 				}
 				if (slave.geneMods.NCS === 1 && slave.nipples === "tiny") {
@@ -837,10 +732,7 @@ App.SlaveAssignment.hormonesEffects = (function() {
 						r.push(`Hormonal effects cause <span class="lime">${his} clit to grow significantly.</span>`);
 						slave.clit++;
 					}
-					if (slave.vagina > -1 && slave.vaginaLube > 0) {
-						r.push(`Hormonal effects cause <span class="orange">${his} vagina to produce less natural lubricant.</span>`);
-						slave.vaginaLube--;
-					}
+					lowerWetness(slave, 0);
 
 					if (slave.muscles <= 50 && slave.diet !== "slimming") {
 						r.push(`Hormonal effects <span class="lime">build up ${his} musculature.</span>`);
@@ -871,18 +763,15 @@ App.SlaveAssignment.hormonesEffects = (function() {
 					}
 					if (faceValue.isBetween(20, 100)) {
 						r.push(`Hormonal effects cause <span class="orange">${his} facial structure to harden and become less attractive.</span>`);
-						faceDec = 1 + V.hormoneUpgradePower;
+						const faceDec = 1 + V.hormoneUpgradePower;
 						slave.face = Math.clamp(slave.face - faceDec, -100, 100);
 					}
 
-					if (slave.voice > 1) {
-						r.push(`Hormonal effects cause <span class="orange">${his} voice to become deeper and less feminine.</span>`);
-						slave.voice--;
-					}
+					lowerVoice(slave, 1);
 				}
 
 				if (V.hormoneUpgradeShrinkage === 0) {
-					if (buttSize > 2 && rearLipedemaMod !== 2) {
+					if (buttSize > 2 && rearLipedemaMod === 0) {
 						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
 							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} butt to decrease a lot.</span>`);
 							slave.butt -= 1;
@@ -892,13 +781,7 @@ App.SlaveAssignment.hormonesEffects = (function() {
 						slave.butt--;
 					}
 					if (boobSize > 400 * gigantomastiaMod && gigantomastiaMod !== 3) {
-						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
-							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} tits to shrink a lot.</span>`);
-							slave.boobs -= 10 + (15 * V.hormoneUpgradePower);
-						} else {
-							r.push(`Hormonal effects cause <span class="orange">the natural size of ${his} tits to shrink.</span>`);
-						}
-						slave.boobs -= 10 + (15 * V.hormoneUpgradePower);
+						shrinkBoobs(slave);
 					}
 				}
 				if (slave.geneMods.NCS === 1 && slave.nipples === "tiny") {
@@ -922,10 +805,7 @@ App.SlaveAssignment.hormonesEffects = (function() {
 						r.push(`Hormonal effects cause <span class="lime">${his} clit to grow significantly.</span>`);
 						slave.clit++;
 					}
-					if (slave.vagina > -1 && slave.vaginaLube > 0) {
-						r.push(`Hormonal effects cause <span class="orange">${his} vagina to produce less natural lubricant.</span>`);
-						slave.vaginaLube--;
-					}
+					lowerWetness(slave, 0);
 
 					if (slave.muscles <= 35 && slave.diet !== "slimming") {
 						r.push(`Hormonal effects <span class="lime">build up ${his} musculature.</span>`);
@@ -956,18 +836,15 @@ App.SlaveAssignment.hormonesEffects = (function() {
 					}
 					if (faceValue.isBetween(40, 100)) {
 						r.push(`Hormonal effects cause <span class="orange">${his} facial structure to harden and become less attractive.</span>`);
-						faceDec = 1 + V.hormoneUpgradePower;
+						const faceDec = 1 + V.hormoneUpgradePower;
 						slave.face = Math.clamp(slave.face - faceDec, -100, 100);
 					}
 
-					if (slave.voice > 2) {
-						r.push(`Hormonal effects cause <span class="orange">${his} voice to become deeper and less feminine.</span>`);
-						slave.voice--;
-					}
+					lowerVoice(slave, 2);
 				}
 
 				if (V.hormoneUpgradeShrinkage === 0) {
-					if (buttSize > 3 && rearLipedemaMod !== 2) {
+					if (buttSize > 3 && rearLipedemaMod === 0) {
 						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
 							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} butt to decrease a lot.</span>`);
 							slave.butt -= 1;
@@ -977,13 +854,7 @@ App.SlaveAssignment.hormonesEffects = (function() {
 						slave.butt--;
 					}
 					if (boobSize > 600 * gigantomastiaMod && gigantomastiaMod !== 3) {
-						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
-							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} tits to shrink a lot.</span>`);
-							slave.boobs -= 10 + (15 * V.hormoneUpgradePower);
-						} else {
-							r.push(`Hormonal effects cause <span class="orange">the natural size of ${his} tits to shrink.</span>`);
-						}
-						slave.boobs -= 10 + (15 * V.hormoneUpgradePower);
+						shrinkBoobs(slave);
 					}
 				}
 				if (slave.nipples === "huge" || slave.nipples === "puffy") {
@@ -1005,10 +876,7 @@ App.SlaveAssignment.hormonesEffects = (function() {
 						r.push(`Hormonal effects cause <span class="lime">${his} clit to grow significantly.</span>`);
 						slave.clit++;
 					}
-					if (slave.vagina > -1 && slave.vaginaLube > 0) {
-						r.push(`Hormonal effects cause <span class="orange">${his} vagina to produce less natural lubricant.</span>`);
-						slave.vaginaLube--;
-					}
+					lowerWetness(slave, 0);
 
 					if (slave.muscles <= 15 && slave.diet !== "slimming") {
 						r.push(`Hormonal effects <span class="lime">build up ${his} musculature.</span>`);
@@ -1033,18 +901,15 @@ App.SlaveAssignment.hormonesEffects = (function() {
 				if (slave.geneMods.NCS === 0) {
 					if (faceValue.isBetween(60, 100)) {
 						r.push(`Hormonal effects cause <span class="orange">${his} facial structure to harden and become less attractive.</span>`);
-						faceDec = 1 + V.hormoneUpgradePower;
+						const faceDec = 1 + V.hormoneUpgradePower;
 						slave.face = Math.clamp(slave.face - faceDec, -100, 100);
 					}
 
-					if (slave.voice > 2) {
-						r.push(`Hormonal effects cause <span class="orange">${his} voice to become deeper and less feminine.</span>`);
-						slave.voice--;
-					}
+					lowerVoice(slave, 2);
 				}
 
 				if (V.hormoneUpgradeShrinkage === 0) {
-					if (buttSize > 4 && rearLipedemaMod !== 2) {
+					if (buttSize > 4 && rearLipedemaMod === 0) {
 						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
 							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} butt to decrease a lot.</span>`);
 							slave.butt -= 1;
@@ -1054,13 +919,7 @@ App.SlaveAssignment.hormonesEffects = (function() {
 						slave.butt--;
 					}
 					if (boobSize > 800 * gigantomastiaMod && gigantomastiaMod !== 3) {
-						if (slave.geneMods.NCS === 1 && jsRandom(1, 100) > 50) {
-							r.push(`Hormonal effects work with ${his} <span class="orange">NCS</span> and cause <span class="orange">${his} tits to shrink a lot.</span>`);
-							slave.boobs -= 10 + (15 * V.hormoneUpgradePower);
-						} else {
-							r.push(`Hormonal effects cause <span class="orange">the natural size of ${his} tits to shrink.</span>`);
-						}
-						slave.boobs -= 10 + (15 * V.hormoneUpgradePower);
+						shrinkBoobs(slave);
 					}
 				}
 
@@ -1088,10 +947,7 @@ App.SlaveAssignment.hormonesEffects = (function() {
 						r.push(`Hormonal effects cause <span class="lime">${his} clit to grow significantly.</span>`);
 						slave.clit++;
 					}
-					if (slave.vagina > -1 && slave.vaginaLube > 1) {
-						r.push(`Hormonal effects cause <span class="orange">${his} vagina to produce less natural lubricant.</span>`);
-						slave.vaginaLube--;
-					}
+					lowerWetness(slave, 1);
 				}
 
 				if (slave.attrXX < 80) {
@@ -1145,4 +1001,4 @@ App.SlaveAssignment.hormonesEffects = (function() {
 			}
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saInflation.js b/src/endWeek/saInflation.js
index a8e0ead941d3e08c010c792b5d96553cb3a60ed2..848d627fc1fceaa15fa0be58117cd68cc71f1e36 100644
--- a/src/endWeek/saInflation.js
+++ b/src/endWeek/saInflation.js
@@ -1,62 +1,40 @@
-App.SlaveAssignment.inflation = (function() {
-	"use strict";
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.inflation = function saInflation(slave) {
+	/** @type {string[]} */
+	const r = [];
 
-	let r;
+	const gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
+	const rearLipedemaMod = slave.geneticQuirks.rearLipedema === 2 ? 2 : 0;
+	const rearLipedemaDivider = rearLipedemaMod === 0 ? 1 : rearLipedemaMod;
+	const dairyL = App.Entity.facilities.dairy.employeesIDs().size;
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let He;
-	let His;
-
-	let gigantomastiaMod;
-	let rearLipedemaMod;
-	let rearLipedemaDivider;
-	let distensionTerm;
-	let dairyL;
-	let dupeTextFlag;
 	let cow;
-	let harvest;
-
-	return saInflation;
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @returns {string}
-	 */
-	function saInflation(slave) {
-		r = [];
-		gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
-		rearLipedemaMod = slave.geneticQuirks.rearLipedema === 2 ? 2 : 0;
-		rearLipedemaDivider = rearLipedemaMod === 0 ? 1 : rearLipedemaMod;
-		dairyL = App.Entity.facilities.dairy.employeesIDs().size;
-		dupeTextFlag = 0;
-
-		if (slave.inflationMethod === 3) {
-			cow = slave.inflationType === "milk" ? getSlave(slave.milkSource) : getSlave(slave.cumSource);
-		}
-
-		({
-			he, him, his, himself, He, His,
-		} = getPronouns(slave));
+	if (slave.inflationMethod === 3) {
+		cow = slave.inflationType === "milk" ? getSlave(slave.milkSource) : getSlave(slave.cumSource);
+	}
 
-		inflationCancellation(slave);
-		if (slave.inflation > 0) {
-			fillUp(slave);
-		}
-		if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
-			mentalEffects(slave);
-		}
-		if (slave.inflationType === "milk" || slave.inflationType === "food") {
-			foodMeansFat(slave);
-		}
-		if (slave.cervixImplant >= 2) {
-			cervixImplantFluidConversion(slave);
-		}
+	const {
+		he, him, his, himself, He, His,
+	} = getPronouns(slave);
 
-		return r.join(" ");
+	inflationCancellation(slave);
+	if (slave.inflation > 0) {
+		fillUp(slave);
+	}
+	if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
+		mentalEffects(slave);
+	}
+	if (slave.inflationType === "milk" || slave.inflationType === "food") {
+		foodMeansFat(slave);
 	}
+	if (slave.cervixImplant >= 2) {
+		cervixImplantFluidConversion(slave);
+	}
+
+	return r.join(" ");
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
@@ -96,7 +74,7 @@ App.SlaveAssignment.inflation = (function() {
 				SetBellySize(slave);
 			}
 		} else if ((slave.inflationType === "milk" || slave.inflationType === "cum") && slave.inflationMethod === 3) {
-			harvest = (slave.inflationType === "milk") ? Math.trunc(milkAmount(cow) / 14) : Math.trunc(cumAmount(cow) / 70);
+			const harvest = (slave.inflationType === "milk") ? Math.trunc(milkAmount(cow) / 14) : Math.trunc(cumAmount(cow) / 70);
 			if (slave.inflation === 3 && harvest < 8) {
 				r.push(`${cow.slaveName} is having trouble producing the requested amount of ${slave.inflationType}`);
 				if (harvest < 2) {
@@ -120,9 +98,108 @@ App.SlaveAssignment.inflation = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
+	 */
+	function gluttonousReaction(slave) {
+		if (slave.inflationMethod === 1 || slave.inflationMethod === 3) {
+			if (slave.inflation === 3) {
+				r.push(`full belly <span class="mediumaquamarine">contently,</span> anticipating ${his} next gorging.`);
+				slave.devotion += 5;
+				slave.trust += 5;
+			} else if (slave.inflation === 2) {
+				r.push(`taut belly <span class="mediumaquamarine">contently,</span> anticipating ${his} next feeding.`);
+				slave.devotion += 4;
+				slave.trust += 4;
+			} else if (slave.inflation === 1) {
+				r.push(`sloshing belly <span class="mediumaquamarine">contently,</span> anticipating ${his} next meal.`);
+				slave.devotion += 3;
+				slave.trust += 3;
+			}
+		} else {
+			if (slave.inflation === 3) {
+				r.push(`taut`);
+				slave.devotion += 4;
+				slave.trust += 4;
+			} else if (slave.inflation === 2) {
+				r.push(`full`);
+				slave.devotion += 3;
+				slave.trust += 3;
+			} else if (slave.inflation === 1) {
+				r.push(`sloshing`);
+				slave.devotion += 1;
+				slave.trust += 1;
+			}
+			r.push(`belly <span class="mediumaquamarine">contently,</span> though ${he} wishes ${he} could have swallowed it instead.`);
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function milkInflationMethod(slave) {
+		if (slave.inflationMethod === 1) {
+			r.push(`sucks from the dairy tap until ${his} stomach is`);
+		} else if (slave.inflationMethod === 2) {
+			r.push(`fills ${his} rectum from the dairy tap until ${his} stomach is`);
+		} else if (slave.inflationMethod === 3) {
+			r.push(`suckles from ${cow.slaveName} until ${his} stomach is`);
+			cow.lactationDuration = 2;
+			cow.boobs -= cow.boobsMilk;
+			cow.boobsMilk = 0;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function cumInflationMethod(slave) {
+		if (slave.inflationMethod === 1) {
+			r.push(`sucks from the dairy tap until ${his} stomach is`);
+		} else if (slave.inflationMethod === 2) {
+			r.push(`fills ${his} rectum from the dairy tap until ${his} stomach is`);
+		} else if (slave.inflationMethod === 3) {
+			r.push(`sucks ${cow.slaveName}'s ${(cow.dick > 0) ? `cock` : `cum hole`} until ${his} stomach is`);
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function anorexicBloatSize(slave) {
+		if (slave.inflation === 3) {
+			r.push(`<span class="health dec">painfully bloated</span> with nearly two gallons`);
+			healthDamage(slave, 10);
+			slave.devotion -= 8;
+			slave.trust -= 8;
+		} else if (slave.inflation === 2) {
+			r.push(`bloated with nearly four liters`);
+			slave.devotion -= 5;
+			slave.trust -= 5;
+		} else if (slave.inflation === 1) {
+			r.push(`bloated with nearly two liters`);
+			slave.devotion -= 3;
+			slave.trust -= 3;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function milkOrCumSize(slave) {
+		if (slave.inflation === 3) {
+			r.push(`${He} keeps ${himself} <span class="health dec">painfully full</span> for you.`);
+			healthDamage(slave, 10);
+		} else if (slave.inflation === 2) {
+			r.push(`${He} is full enough to be distended but not enough to grow taut.`);
+		} else if (slave.inflation === 1) {
+			r.push(`${He} is full enough to be swollen but not enough to visibly jiggle.`);
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
 	 */
 	function fillUp(slave) {
+		let distensionTerm;
 		if (slave.inflation === 3) {
 			distensionTerm = `leaving ${him} looking ready to burst`;
 		} else if (slave.inflation === 2) {
@@ -252,14 +329,15 @@ App.SlaveAssignment.inflation = (function() {
 				if (slave.geneMods.rapidCellGrowth === 1) {
 					r.push(`Unfortunately for ${him}, ${his} body shows no interest in tightening up after the elasticity treatment ${he} underwent.`);
 				} else {
+					let dupeTextFlag = false;
 					if (slave.anus > 1) {
 						r.push(`The solution slowly tightens ${his} anus while inside ${his} bowels.`);
 						if (slave.inflation === 3) {
 							r.push(`Being filled to ${his} limit with the solution does not make it tighten any better or faster; it's just perverted.`);
-							dupeTextFlag = 1;
+							dupeTextFlag = true;
 						} else if (slave.inflation === 2) {
 							r.push(`Being overfilled with the solution does not make it tighten any better or faster; it's just perverted.`);
-							dupeTextFlag = 1;
+							dupeTextFlag = true;
 						}
 						if (jsRandom(1, 100) > 60) {
 							r.push(`By week's end, <span class="lime">${his} butthole has tightened nicely.</span>`);
@@ -270,7 +348,7 @@ App.SlaveAssignment.inflation = (function() {
 					}
 					if (slave.vagina > 1) {
 						r.push(`As ${his} body slowly absorbs the solution, its benefits begin to affect ${his} pussy.`);
-						if (dupeTextFlag !== 1) {
+						if (!dupeTextFlag) {
 							if (slave.inflation === 3) {
 								r.push(`Being filled to ${his} limit with the solution does not make it tighten any better or faster; it's just perverted.`);
 							} else if (slave.inflation === 2) {
@@ -324,43 +402,12 @@ App.SlaveAssignment.inflation = (function() {
 				r.push(`Throughout the week, ${he}`);
 				if (slave.behavioralFlaw === "anorexic") {
 					r.push(`<span class="mediumorchid">reluctantly</span>`);
-					if (slave.inflationMethod === 1) {
-						r.push(`sucks from the dairy tap until ${his} stomach is`);
-					} else if (slave.inflationMethod === 2) {
-						r.push(`fills ${his} rectum from the dairy tap until ${his} stomach is`);
-					} else if (slave.inflationMethod === 3) {
-						r.push(`suckles from ${cow.slaveName} until ${his} stomach is`);
-						cow.lactationDuration = 2;
-						cow.boobs -= cow.boobsMilk;
-						cow.boobsMilk = 0;
-					}
-					if (slave.inflation === 3) {
-						r.push(`<span class="health dec">painfully bloated</span> with nearly two gallons`);
-						healthDamage(slave, 10);
-						slave.devotion -= 8;
-						slave.trust -= 8;
-					} else if (slave.inflation === 2) {
-						r.push(`bloated with nearly four liters`);
-						slave.devotion -= 5;
-						slave.trust -= 5;
-					} else if (slave.inflation === 1) {
-						r.push(`bloated with nearly two liters`);
-						slave.devotion -= 3;
-						slave.trust -= 3;
-					}
+					milkInflationMethod(slave);
+					anorexicBloatSize(slave);
 					r.push(`of milk, ${distensionTerm}. ${He} struggles to keep ${his} fatty, liquid meal down, <span class="gold">fearing</span> punishment otherwise.`);
 				} else if (slave.behavioralFlaw === "gluttonous") {
 					r.push(`<span class="hotpink">${slave.inflationMethod === 2 ? `happily` : `eagerly`}</span>`);
-					if (slave.inflationMethod === 1) {
-						r.push(`sucks from the dairy tap until ${his} stomach is`);
-					} else if (slave.inflationMethod === 2) {
-						r.push(`fills ${his} rectum from the dairy tap until ${his} stomach is`);
-					} else if (slave.inflationMethod === 3) {
-						r.push(`sucks from ${cow.slaveName} until ${his} stomach is`);
-						cow.lactationDuration = 2;
-						cow.boobs -= cow.boobsMilk;
-						cow.boobsMilk = 0;
-					}
+					milkInflationMethod(slave);
 					if (slave.inflation === 3) {
 						r.push(`<span class="health dec">painfully bloated</span> with nearly two gallons`);
 						healthDamage(slave, 10);
@@ -370,36 +417,7 @@ App.SlaveAssignment.inflation = (function() {
 						r.push(`bloated with nearly two liters`);
 					}
 					r.push(`of milk, ${distensionTerm}. ${He} rubs ${his}`);
-					if (slave.inflationMethod === 1 || slave.inflationMethod === 3) {
-						if (slave.inflation === 3) {
-							r.push(`full belly <span class="mediumaquamarine">contently,</span> anticipating ${his} next gorging.`);
-							slave.devotion += 5;
-							slave.trust += 5;
-						} else if (slave.inflation === 2) {
-							r.push(`taut belly <span class="mediumaquamarine">contently,</span> anticipating ${his} next feeding.`);
-							slave.devotion += 4;
-							slave.trust += 4;
-						} else if (slave.inflation === 1) {
-							r.push(`sloshing belly <span class="mediumaquamarine">contently,</span> anticipating ${his} next meal.`);
-							slave.devotion += 3;
-							slave.trust += 3;
-						}
-					} else {
-						if (slave.inflation === 3) {
-							r.push(`taut`);
-							slave.devotion += 4;
-							slave.trust += 4;
-						} else if (slave.inflation === 2) {
-							r.push(`full`);
-							slave.devotion += 3;
-							slave.trust += 3;
-						} else if (slave.inflation === 1) {
-							r.push(`sloshing`);
-							slave.devotion += 1;
-							slave.trust += 1;
-						}
-						r.push(`belly <span class="mediumaquamarine">contently,</span> though ${he} wishes ${he} could have swallowed it instead.`);
-					}
+					gluttonousReaction(slave);
 				} else {
 					r.push(`makes sure to`);
 					if (slave.inflationMethod === 1) {
@@ -424,14 +442,7 @@ App.SlaveAssignment.inflation = (function() {
 					} else {
 						r.push(`${distensionTerm}.`);
 					}
-					if (slave.inflation === 3) {
-						r.push(`${He} keeps ${himself} <span class="health dec">painfully full</span> for you.`);
-						healthDamage(slave, 10);
-					} else if (slave.inflation === 2) {
-						r.push(`${He} is full enough to be distended but not enough to grow taut.`);
-					} else if (slave.inflation === 1) {
-						r.push(`${He} is full enough to be swollen but not enough to visibly jiggle.`);
-					}
+					milkOrCumSize(slave);
 				}
 				break;
 
@@ -439,27 +450,8 @@ App.SlaveAssignment.inflation = (function() {
 				r.push(`Throughout the week, ${he}`);
 				if (slave.behavioralFlaw === "anorexic") {
 					r.push(`<span class="mediumorchid">reluctantly</span>`);
-					if (slave.inflationMethod === 1) {
-						r.push(`sucks from the dairy tap until ${his} stomach is`);
-					} else if (slave.inflationMethod === 2) {
-						r.push(`fills ${his} rectum from the dairy tap until ${his} stomach is`);
-					} else if (slave.inflationMethod === 3) {
-						r.push(`sucks ${cow.slaveName}'s ${(cow.dick > 0) ? `cock` : `cum hole`} until ${his} stomach is`);
-					}
-					if (slave.inflation === 3) {
-						r.push(`<span class="health dec">painfully bloated</span> with nearly two gallons`);
-						healthDamage(slave, 10);
-						slave.devotion -= 8;
-						slave.trust -= 8;
-					} else if (slave.inflation === 2) {
-						r.push(`bloated with nearly four liters`);
-						slave.devotion -= 5;
-						slave.trust -= 5;
-					} else if (slave.inflation === 1) {
-						r.push(`bloated with nearly two liters`);
-						slave.devotion -= 3;
-						slave.trust -= 3;
-					}
+					cumInflationMethod(slave);
+					anorexicBloatSize(slave);
 					r.push(`of cum, ${distensionTerm}.`);
 					if (slave.inflationMethod === 1 || slave.inflationMethod === 3) {
 						r.push(`${He} struggles to keep ${his} liquid meal down, <span class="gold">fearing</span> punishment otherwise.`);
@@ -468,13 +460,7 @@ App.SlaveAssignment.inflation = (function() {
 					}
 				} else if (slave.behavioralFlaw === "gluttonous") {
 					r.push(`<span class="hotpink">${slave.inflationMethod === 2 ? `happily` : `eagerly`}</span>`);
-					if (slave.inflationMethod === 1) {
-						r.push(`sucks from the dairy tap until ${his} stomach is`);
-					} else if (slave.inflationMethod === 2) {
-						r.push(`fills ${his} rectum from the dairy tap until ${his} stomach is`);
-					} else if (slave.inflationMethod === 3) {
-						r.push(`sucks ${cow.slaveName}'s ${(cow.dick > 0) ? `cock` : `cum hole`} until ${his} stomach is`);
-					}
+					cumInflationMethod(slave);
 					if (slave.inflation === 3) {
 						r.push(`<span class="health dec">painfully bloated</span> with nearly two gallons`);
 						healthDamage(slave, 10);
@@ -484,36 +470,7 @@ App.SlaveAssignment.inflation = (function() {
 						r.push(`bloated with nearly two liters`);
 					}
 					r.push(`of cum, ${distensionTerm}. ${He} rubs ${his}`);
-					if (slave.inflationMethod === 1 || slave.inflationMethod === 3) {
-						if (slave.inflation === 3) {
-							r.push(`full belly <span class="mediumaquamarine">contently,</span> anticipating ${his} next gorging.`);
-							slave.devotion += 5;
-							slave.trust += 5;
-						} else if (slave.inflation === 2) {
-							r.push(`taut belly <span class="mediumaquamarine">contently,</span> anticipating ${his} next feeding.`);
-							slave.devotion += 4;
-							slave.trust += 4;
-						} else if (slave.inflation === 1) {
-							r.push(`sloshing belly <span class="mediumaquamarine">contently,</span> anticipating ${his} next meal.`);
-							slave.devotion += 3;
-							slave.trust += 3;
-						}
-					} else {
-						if (slave.inflation === 3) {
-							r.push(`taut`);
-							slave.devotion += 4;
-							slave.trust += 4;
-						} else if (slave.inflation === 2) {
-							r.push(`full`);
-							slave.devotion += 3;
-							slave.trust += 3;
-						} else if (slave.inflation === 1) {
-							r.push(`sloshing`);
-							slave.devotion += 1;
-							slave.trust += 1;
-						}
-						r.push(`belly <span class="mediumaquamarine">contently,</span> though ${he} wishes ${he} could have swallowed it instead.`);
-					}
+					gluttonousReaction(slave);
 				} else {
 					r.push(`makes sure to`);
 					if (slave.inflationMethod === 1) {
@@ -535,14 +492,7 @@ App.SlaveAssignment.inflation = (function() {
 					} else {
 						r.push(`${distensionTerm}.`);
 					}
-					if (slave.inflation === 3) {
-						r.push(`${He} keeps ${himself} <span class="health dec">painfully full</span> for you.`);
-						healthDamage(slave, 10);
-					} else if (slave.inflation === 2) {
-						r.push(`${He} is full enough to be distended but not enough to grow taut.`);
-					} else if (slave.inflation === 1) {
-						r.push(`${He} is full enough to be swollen but not enough to visibly jiggle.`);
-					}
+					milkOrCumSize(slave);
 				}
 				break;
 
@@ -665,4 +615,4 @@ App.SlaveAssignment.inflation = (function() {
 			slave.bellyImplant += 200;
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saLiveWithHG.js b/src/endWeek/saLiveWithHG.js
index 3b67c0d602b39974e418326c85ce984c6c16d5d7..345ff4354e7797bbbf3bde040cae776eb167e2f8 100644
--- a/src/endWeek/saLiveWithHG.js
+++ b/src/endWeek/saLiveWithHG.js
@@ -1,106 +1,62 @@
-App.SlaveAssignment.liveWithHG = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {DocumentFragment}
+ */
+App.SlaveAssignment.liveWithHG = function saliveWithHG(slave) {
+	const el = new DocumentFragment();
+	/** @type {string[]} */
+	const r = [];
 
-	/* Major forced feminization. Needs serious reworking to support male slaves. Instead base off HG's attr stat? */
+	const {
+		he, him, his, himself, girl, He, wife
+	} = getPronouns(slave);
+	const {
+		he2, him2, his2, himself2, He2, His2, wife2
+	} = getPronouns(S.HeadGirl).appendSuffix("2");
 
-	let r;
+	const arcology = V.arcologies[0];
 
-	let arcology;
-	let he;
-	let him;
-	let his;
-	let himself;
-	let girl;
-	let He;
-	let wife;
+	let oralUse = 0;
+	let analUse = 0;
+	let vaginalUse = 0;
+	let mammaryUse = 0;
+	let penetrativeUse = 0;
+	let cervixPump = 0;
 
-	let he2;
-	let him2;
-	let his2;
-	let himself2;
-	let He2;
-	let His2;
-	let wife2;
+	// these three get set first, but we save the output for later
+	const dietText = HGSetsDiet(slave, S.HeadGirl);
+	const hormoneText = V.HGSuiteHormones !== 0 ? HGSetsHormones(slave, S.HeadGirl) : [];
+	const drugText = HGSetsDrugs(slave, S.HeadGirl);
 
-	let diet;
-	let hormones;
-
-	let oralUse;
-	let analUse;
-	let vaginalUse;
-	let mammaryUse;
-	let penetrativeUse;
-	let cervixPump;
-
-	return saliveWithHG;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {DocumentFragment}
-	 */
-	function saliveWithHG(slave) {
-		const el = new DocumentFragment();
-		r = [];
-
-		({
-			he, him, his, himself, girl, He, wife
-		} = getPronouns(slave));
-		({
-			he2, him2, his2, himself2, He2, His2, wife2
-		} = getPronouns(S.HeadGirl).appendSuffix("2"));
-
-		arcology = V.arcologies[0];
-
-		// These get swapped prior to their text, so remember them.
-		diet = slave.diet;
-		hormones = slave.hormones;
-
-		oralUse = 0;
-		analUse = 0;
-		vaginalUse = 0;
-		mammaryUse = 0;
-		penetrativeUse = 0;
-		cervixPump = 0;
-
-		HGSetsDiet(slave, S.HeadGirl);
-		if (V.HGSuiteHormones !== 0) {
-			HGSetsHormones(slave, S.HeadGirl);
-		}
-		HGSetsDrugs(slave, S.HeadGirl);
-		HGSetsLivingConditions(slave, S.HeadGirl);
-		slaveAssistsHG(slave, S.HeadGirl);
-		HGSlaveTreatment(slave, S.HeadGirl);
-		slaveHGRelations(slave, S.HeadGirl);
-		HGTrainsSlave(slave, S.HeadGirl);
-		if (canPenetrate(S.HeadGirl)) {
-			HGStretchesHoles(slave, S.HeadGirl);
-		}
-		if (V.seePreg !== 0) {
-			HGManagesPregnancy(slave, S.HeadGirl);
-		}
-		if (slave.devotion > 50) {
-			HGCausesFetish(slave, S.HeadGirl);
-		}
-		HGSexualSatiation(slave, S.HeadGirl);
-		HGManagesTiredness(slave, S.HeadGirl);
-		HGDressesSlave(slave, S.HeadGirl);
-		if (S.HeadGirl.energy > 95) {
-			narcissistHG(slave, S.HeadGirl);
-		}
-		HGSetsDietText(slave, S.HeadGirl);
-		if (V.HGSuiteHormones !== 0) {
-			HGSetsHormonesText(slave, S.HeadGirl);
-		}
-		HGSetsDrugsText(slave, S.HeadGirl);
-		if (V.HGSuiteSurgery !== 0) {
-			HGArrangesSurgery(slave, S.HeadGirl);
-		}
-		HGEnjoyment(slave, S.HeadGirl);
-		slaveReport(slave);
-
-		App.Events.addNode(el, r);
-		return el;
+	HGSetsLivingConditions(slave, S.HeadGirl);
+	slaveAssistsHG(slave, S.HeadGirl);
+	HGSlaveTreatment(slave, S.HeadGirl);
+	slaveHGRelations(slave, S.HeadGirl);
+	HGTrainsSlave(slave, S.HeadGirl);
+	if (canPenetrate(S.HeadGirl)) {
+		HGStretchesHoles(slave, S.HeadGirl);
+	}
+	if (V.seePreg !== 0) {
+		HGManagesPregnancy(slave, S.HeadGirl);
+	}
+	if (slave.devotion > 50) {
+		HGCausesFetish(slave, S.HeadGirl);
 	}
+	HGSexualSatiation(slave, S.HeadGirl);
+	HGManagesTiredness(slave, S.HeadGirl);
+	HGDressesSlave(slave, S.HeadGirl);
+	if (S.HeadGirl.energy > 95) {
+		narcissistHG(slave, S.HeadGirl);
+	}
+	r.push(...dietText, ...hormoneText, ...drugText);
+	if (V.HGSuiteSurgery !== 0 && slave.indentureRestrictions < 1) {
+		HGArrangesSurgery(slave, S.HeadGirl);
+	}
+	HGEnjoyment(slave, S.HeadGirl);
+	App.Events.addNode(el, r);
+
+	slaveReport(slave, el);
+	return el;
 
 	function getHGTastes() {
 		if (arcology.FSSlimnessEnthusiast !== "unset") {
@@ -122,94 +78,189 @@ App.SlaveAssignment.liveWithHG = (function() {
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 * @param {App.Entity.SlaveState} HG
+	 * @returns {string[]}
 	 */
 	function HGSetsDiet(slave, HG) {
+		const t = [];
 		if ((arcology.FSRepopulationFocusPregPolicy === 1 || (arcology.FSRestart === "unset" && HG.fetish === "pregnancy")) && canImpreg(slave, HG) && V.dietFertility === 1) {
+			t.push(`${HG.slaveName} thinks ${slave.slaveName} could do with a bigger bump`);
+			if (arcology.FSRepopulationFocusPregPolicy) {
+				t.push(`since pregnant ${girl}s are all the rage in your arcology`);
+			}
 			if (slave.diet !== "fertility") {
+				t.push(`and assigns ${him} a diet to promote ovulation.`);
 				slave.diet = "fertility";
+			} else {
+				t.push(`and keeps ${him} on ${his} fertility diet.`);
 			}
 		} else if ((slave.weight < 100 && arcology.FSHedonisticDecadence >= 20) || (slave.weight < -10)) {
+			t.push(`${HG.slaveName} thinks ${slave.slaveName} could use a little extra weight`);
+			if (arcology.FSHedonisticDecadence >= 20) {
+				t.push(`since plump ${girl}s are all the rage in your arcology`);
+			}
 			if (slave.diet !== "fattening") {
+				t.push(`and assigns ${him} a diet to fatten ${him} up.`);
 				slave.diet = "fattening";
+			} else {
+				t.push(`and keeps ${him} on ${his} fattening diet.`);
 			}
 		} else if (slave.weight > 30 && arcology.FSHedonisticDecadence === "unset") {
+			t.push(`${HG.slaveName} thinks ${slave.slaveName} is a little too porky`);
 			if (slave.diet !== "restricted") {
+				t.push(`and puts ${him} on a diet.`);
 				slave.diet = "restricted";
+			} else {
+				t.push(`and keeps ${him} on ${his} diet.`);
 			}
 		} else if (((slave.muscles <= 95 && ((arcology.FSPhysicalIdealist > 0 && arcology.FSPhysicalIdealistLaw === 0) || (HG.fetish === "submissive" || HG.fetish === "masochist"))) || (slave.muscles <= 45 && (arcology.FSPhysicalIdealist !== "unset" && arcology.FSPhysicalIdealistLaw === 1)) || slave.muscles <= 5) && !isAmputee(slave)) {
+			t.push(`${HG.slaveName} thinks ${slave.slaveName}`);
+			if (HG.fetish === "submissive" && HG.fetishKnown === 1) {
+				t.push(`could use bigger muscles to better dominate ${him2} with in bed`);
+			} else if (HG.fetish === "masochist" && HG.fetishKnown === 1) {
+				t.push(`could use bigger muscles to better spank ${him2}`);
+			} else if (arcology.FSPhysicalIdealist !== "unset") {
+				t.push(`could use bigger muscles to support your societal goals`);
+			} else {
+				t.push(`could use a bit of muscle`);
+			}
 			if (slave.diet !== "muscle building") {
+				t.push(`and makes ${him} work out hard.`);
 				slave.diet = "muscle building";
+			} else {
+				t.push(`and keeps ${him} working out.`);
 			}
 		} else if (slave.balls > 0 && HG.fetish === "cumslut" && V.cumProDiet === 1) {
+			t.push(`${HG.slaveName}`);
+			if (HG.fetishKnown === 1) {
+				t.push(`loves cum,`);
+			} else {
+				t.push(`seems amused by cumshots,`);
+			}
+			t.push(`so ${he2}`);
 			if (slave.diet !== "cum production") {
+				t.push(`puts`);
 				slave.diet = "cum production";
+			} else {
+				t.push(`keeps`);
 			}
+			t.push(`${slave.slaveName} on a diet designed to make ${him} cum harder and stronger.`);
 		} else {
+			t.push(`${HG.slaveName} thinks ${slave.slaveName} is fine as is`);
 			if (slave.diet !== "healthy") {
+				t.push(`and puts ${him} on a normal diet.`);
 				slave.diet = "healthy";
+			} else {
+				t.push(`and keeps ${him} on ${his} healthy diet.`);
 			}
 		}
+		return t;
 	}
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 * @param {App.Entity.SlaveState} HG
+	 * @returns {string[]}
 	 */
 	function HGSetsHormones(slave, HG) {
+		const t = [];
 		// Room for expansion
-		if (slave.hormones !== 2) {
+		if (slave.indentureRestrictions > 1) {
+			t.push(`${HG.slaveName} puts ${slave.slaveName} on female hormones, since ${he2} expects ${him} to act as the submissive, feminine partner.`);
+			slave.hormones = 1;
+		} else {
+			t.push(`${HG.slaveName} puts ${slave.slaveName} on intensive female hormones, since ${he2} expects ${him} to act as the submissive, feminine partner.`);
 			slave.hormones = 2;
 		}
+		return t;
 	}
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 * @param {App.Entity.SlaveState} HG
+	 * @returns {string[]}
 	 */
 	function HGSetsDrugs(slave, HG) {
+		const t = [];
 		if (V.HGSuiteDrugs !== 0) {
 			if (slave.health.condition < 60) {
+				t.push(`${HG.slaveName} gives ${slave.slaveName} curatives, since ${he2} wants a shiningly healthy living partner.`);
 				slave.curatives = 2;
 			}
-			if (slave.lips <= 20) {
-				slave.drugs = "lip injections";
-			} else if (arcology.FSSlaveProfessionalismResearch === 1 && V.HGSuiteEquality !== 0 && canImproveIntelligence(slave)) {
-				slave.drugs = "psychostimulants";
-			} else if (HG.fetish === "buttslut" && arcology.FSAssetExpansionistResearch === 1 && slave.butt < 18) {
-				slave.drugs = "hyper butt injections";
-			} else if (HG.fetish === "buttslut" && arcology.FSAssetExpansionistResearch === 1 && slave.butt < 8) {
-				slave.drugs = "butt injections";
-			} else if (HG.fetish === "cumslut" && arcology.FSAssetExpansionistResearch === 1 && slave.balls < 100 && slave.balls > 0 && slave.dick > 0) {
-				slave.drugs = "hyper testicle enhancement";
-			} else if (HG.fetish === "cumslut" && slave.balls < 10 && slave.balls > 0 && slave.dick > 0) {
-				slave.drugs = "testicle enhancement";
-			} else if ((HG.fetish === "masochist" || HG.fetish === "submissive") && canImproveHeight(slave) && V.growthStim === 1) {
-				slave.drugs = "growth stimulants";
-			} else if (HG.fetish === "boobs" && slave.boobs < 15000) {
-				if (arcology.FSAssetExpansionistResearch === 1) {
-					slave.drugs = "hyper breast injections";
-				} else {
-					slave.drugs = "breast injections";
-				}
-			} else if (canImpreg(slave, HG) && arcology.FSRestart === "unset" && (getHGTastes() === 4 || HG.fetish === "pregnancy" || arcology.FSRepopulationFocusPregPolicy === 1)) {
-				slave.drugs = "fertility drugs";
-			} else if (getHGTastes() > 1) {
-				// need to consider things here
-				if (slave.lips <= 70) {
+			// default state, unless the HG decides she needs (and can have) something else
+			slave.drugs = "no drugs";
+			if (slave.indentureRestrictions < 2) {
+				if (slave.lips <= 20) {
+					t.push(`${HG.slaveName} gives ${slave.slaveName} lip injections, since ${he2} wants to get oral from plump, luscious lips.`);
 					slave.drugs = "lip injections";
-				} else if (slave.boobs > (125 * Math.pow(slave.butt, 2))) {
+				} else if (arcology.FSSlaveProfessionalismResearch === 1 && V.HGSuiteEquality !== 0 && canImproveIntelligence(slave)) {
+					t.push(`${HG.slaveName} gives ${slave.slaveName} psychostimulants, since ${him} being smarter will benefit them both when ${he} is in charge.`);
+					slave.drugs = "psychostimulants";
+				} else if (HG.fetish === "buttslut" && arcology.FSAssetExpansionistResearch === 1 && slave.butt < 18) {
+					t.push(`${HG.slaveName} gives ${slave.slaveName} hyper ass injections, since ${he2} never once thought it possible to fuck an ass as big as ${his} is.`);
+					slave.drugs = "hyper butt injections";
+				} else if (HG.fetish === "buttslut" && arcology.FSAssetExpansionistResearch === 1 && slave.butt < 8) {
+					t.push(`${HG.slaveName} gives ${slave.slaveName} ass injections, since ${he2} likes comfortable padding as ${he2} fucks a butt.`);
 					slave.drugs = "butt injections";
-				} else {
-					slave.drugs = "breast injections";
+				} else if (HG.fetish === "cumslut" && arcology.FSAssetExpansionistResearch === 1 && slave.balls < 100 && slave.balls > 0 && slave.dick > 0) {
+					t.push(`${HG.slaveName} gives ${slave.slaveName} hyper testicle injections, since ${he2}`);
+					if (HG.fetishKnown === 1) {
+						t.push(`wants to swim in a river of cum.`);
+					} else {
+						t.push(`enjoys seeing how large of a load ${slave.slaveName} can blow.`);
+					}
+					slave.drugs = "hyper testicle enhancement";
+				} else if (HG.fetish === "cumslut" && slave.balls < 10 && slave.balls > 0 && slave.dick > 0) {
+					t.push(`${HG.slaveName} gives ${slave.slaveName} testicle injections, since ${he2} wants ${slave.slaveName} shooting bigger loads.`);
+					slave.drugs = "testicle enhancement";
+				} else if ((HG.fetish === "masochist" || HG.fetish === "submissive") && canImproveHeight(slave)) {
+					t.push(`${HG.slaveName}`);
+					if (HG.fetishKnown === 1) {
+						t.push(`has a subconscious need to be hurt by the biggest, strongest ${girl} possible,`);
+					} else {
+						t.push(`feels that ${slave.slaveName} is too short,`);
+					}
+					t.push(`so ${he2} gives ${slave.slaveName} injections of growth stimulants to make ${him} grow taller.`);
+					slave.drugs = "growth stimulants";
+				} else if (HG.fetish === "boobs" && slave.boobs < 15000) {
+					t.push(`${HG.slaveName} gives ${slave.slaveName}`);
+					if (arcology.FSAssetExpansionistResearch === 1) {
+						slave.drugs = "hyper breast injections";
+					} else {
+						slave.drugs = "breast injections";
+					}
+					t.push(`${slave.drugs},`);
+					if (HG.fetishKnown === 1) {
+						t.push(`since as far as ${he2}'s concerned there's no such thing as too much boob.`);
+					} else {
+						t.push(`eager to see just how much boob ${slave.slaveName} can handle.`);
+					}
+				} else if (canImpreg(slave, HG) && arcology.FSRestart === "unset" && (getHGTastes() === 4 || HG.fetish === "pregnancy")) {
+					t.push(`${HG.slaveName} gives ${slave.slaveName} fertility enhancers, since ${he2} wants to see ${slave.slaveName} heavy with child.`);
+					slave.drugs = "fertility drugs";
+				} else if (arcology.FSRepopulationFocusPregPolicy === 1 && canImpreg(slave, HG)) {
+					t.push(`${HG.slaveName} gives ${slave.slaveName} fertility enhancers, since pregnancy is popular and ${he2} wants ${slave.slaveName} to look hot.`);
+					slave.drugs = "fertility drugs";
+				} else if (getHGTastes() > 1) {
+					// need to consider things here
+					if (slave.lips <= 70) {
+						t.push(`${HG.slaveName} gives ${slave.slaveName} lip injections, since ${he2} thinks ${slave.slaveName} should have lips so big ${he} can barely speak.`);
+						slave.drugs = "lip injections";
+					} else if (slave.boobs > (125 * Math.pow(slave.butt, 2))) {
+						t.push(`${HG.slaveName} gives ${slave.slaveName} ass injections, since ${he2} loves curves and thinks ${slave.slaveName}'s butt needs the most work.`);
+						slave.drugs = "butt injections";
+					} else {
+						t.push(`${HG.slaveName} gives ${slave.slaveName} boob injections, since ${he2} loves curves and thinks ${slave.slaveName}'s tits need the most work.`);
+						slave.drugs = "breast injections";
+					}
 				}
-			} else {
-				slave.drugs = "no drugs";
 			}
 		} else {
-			if (slave.health.condition < 100) {
+			if (slave.health.condition < 90) {
+				t.push(`${HG.slaveName} gives ${slave.slaveName} curatives, since ${his2} assistant could be healthier.`);
 				slave.curatives = 2;
 			}
 		}
+		return t;
 	}
 
 	/**
@@ -491,23 +542,25 @@ App.SlaveAssignment.liveWithHG = (function() {
 				r.push(`${HG.slaveName} <span class="devotion inc">loves</span> <span class="virginity loss">taking</span> ${slave.slaveName}'s virginity, and spends much of the week ogling ${his2} conquest complacently.`);
 				slave.vagina = 1;
 				HG.devotion += 4;
-			} else if (slave.vagina === 1) {
-				if (HG.dick > 4 && HG.energy > 95) {
-					r.push(`${HG.slaveName} has such a ferocious sex drive and such a big dick that ${his2} constant pounding of ${slave.slaveName} <span class="change positive">loosens</span> the poor ${girl}'s pussy.`);
-					slave.vagina += 1;
-				} else if (HG.dick > 5) {
-					r.push(`Serving ${HG.slaveName}'s monster cock <span class="change positive">loosens</span> ${slave.slaveName}'s pussy.`);
-					slave.vagina += 1;
-				}
-			} else if (slave.vagina === 2) {
-				if (HG.dick > 5 && HG.energy > 95) {
-					r.push(`${HG.slaveName} has such a ferocious sex drive and such a monster cock that ${his2} constant pounding of ${slave.slaveName} <span class="change positive">loosens</span> the poor ${girl}'s pussy.`);
-					slave.vagina += 1;
-				}
-			} else if (slave.vagina === 3) {
-				if (HG.dick > 5 && HG.energy > 95 && random(1, 100) > 80) {
-					r.push(`${HG.slaveName} has such a ferocious sex drive and such a monster cock that ${his2} constant pounding of ${slave.slaveName}'s loose pussy inevitably leaves it <span class="change positive">gaping.</span>`);
-					slave.vagina += 1;
+			} else if (V.seeStretching === 1) {
+				if (slave.vagina === 1) {
+					if (HG.dick > 4 && HG.energy > 95) {
+						r.push(`${HG.slaveName} has such a ferocious sex drive and such a big dick that ${his2} constant pounding of ${slave.slaveName} <span class="change positive">loosens</span> the poor ${girl}'s pussy.`);
+						slave.vagina += 1;
+					} else if (HG.dick > 5) {
+						r.push(`Serving ${HG.slaveName}'s monster cock <span class="change positive">loosens</span> ${slave.slaveName}'s pussy.`);
+						slave.vagina += 1;
+					}
+				} else if (slave.vagina === 2) {
+					if (HG.dick > 5 && HG.energy > 95) {
+						r.push(`${HG.slaveName} has such a ferocious sex drive and such a monster cock that ${his2} constant pounding of ${slave.slaveName} <span class="change positive">loosens</span> the poor ${girl}'s pussy.`);
+						slave.vagina += 1;
+					}
+				} else if (slave.vagina === 3) {
+					if (HG.dick > 5 && HG.energy > 95 && random(1, 100) > 80) {
+						r.push(`${HG.slaveName} has such a ferocious sex drive and such a monster cock that ${his2} constant pounding of ${slave.slaveName}'s loose pussy inevitably leaves it <span class="change positive">gaping.</span>`);
+						slave.vagina += 1;
+					}
 				}
 			}
 		}
@@ -516,23 +569,25 @@ App.SlaveAssignment.liveWithHG = (function() {
 				r.push(`${HG.slaveName} <span class="devotion inc">relishes</span> <span class="virginity loss">taking</span> ${slave.slaveName}'s anal virginity, and spends much of the week groping ${his2} conquest's rear end possessively.`);
 				slave.anus = 1;
 				HG.devotion += 4;
-			} else if (slave.anus === 1) {
-				if (HG.dick > 4 && HG.energy > 95) {
-					r.push(`${HG.slaveName} uses ${slave.slaveName}'s anus to vent ${his2} sexual addiction. Constant assrape from such a huge dick <span class="change positive">loosens</span> ${his} sphincter.`);
-					slave.anus += 1;
-				} else if (HG.dick > 5) {
-					r.push(`Taking ${HG.slaveName}'s monster cock up the butt <span class="change positive">loosens</span> ${slave.slaveName}'s anal sphincter.`);
-					slave.anus += 1;
-				}
-			} else if (slave.anus === 2) {
-				if (HG.dick > 5 && HG.energy > 95) {
-					r.push(`${HG.slaveName} uses ${slave.slaveName}'s anus to vent ${his2} sexual addiction. Constant assrape from the Head Girl's monster cock <span class="change positive">loosens</span> ${his} sphincter.`);
-					slave.anus += 1;
-				}
-			} else if (slave.anus === 3) {
-				if (HG.dick > 5 && HG.energy > 95 && random(1, 100) > 80) {
-					r.push(`${HG.slaveName} uses ${slave.slaveName}'s loose anus to vent ${his2} sexual addiction. Constant assrape from the Head Girl's monster cock eventually leaves it <span class="change positive">gaping.</span>`);
-					slave.anus += 1;
+			} else if (V.seeStretching === 1) {
+				if (slave.anus === 1) {
+					if (HG.dick > 4 && HG.energy > 95) {
+						r.push(`${HG.slaveName} uses ${slave.slaveName}'s anus to vent ${his2} sexual addiction. Constant assrape from such a huge dick <span class="change positive">loosens</span> ${his} sphincter.`);
+						slave.anus += 1;
+					} else if (HG.dick > 5) {
+						r.push(`Taking ${HG.slaveName}'s monster cock up the butt <span class="change positive">loosens</span> ${slave.slaveName}'s anal sphincter.`);
+						slave.anus += 1;
+					}
+				} else if (slave.anus === 2) {
+					if (HG.dick > 5 && HG.energy > 95) {
+						r.push(`${HG.slaveName} uses ${slave.slaveName}'s anus to vent ${his2} sexual addiction. Constant assrape from the Head Girl's monster cock <span class="change positive">loosens</span> ${his} sphincter.`);
+						slave.anus += 1;
+					}
+				} else if (slave.anus === 3) {
+					if (HG.dick > 5 && HG.energy > 95 && random(1, 100) > 80) {
+						r.push(`${HG.slaveName} uses ${slave.slaveName}'s loose anus to vent ${his2} sexual addiction. Constant assrape from the Head Girl's monster cock eventually leaves it <span class="change positive">gaping.</span>`);
+						slave.anus += 1;
+					}
 				}
 			}
 		}
@@ -729,8 +784,8 @@ App.SlaveAssignment.liveWithHG = (function() {
 			if (HG.attrXY > 85 && slave.attrXY > 65 && slave.attrXY <= 85) { // needs male slave support
 				r.push(`${slave.slaveName} and ${HG.slaveName} have so much fun debating which male citizens, dickgirls and slave boys are cutest (typically followed by`);
 				if (canDoAnal(slave) || canDoVaginal(slave)) {
-					r.push(`${HG.slaveName} banging ${his2} girltoy`);
-					if (canPenetrate(HG)) {
+					r.push(`${HG.slaveName} banging ${his2} ${girl}toy`);
+					if (!canPenetrate(HG)) {
 						r.push(`with a strap-on)`);
 					} else {
 						r.push(`senseless)`);
@@ -749,6 +804,43 @@ App.SlaveAssignment.liveWithHG = (function() {
 		}
 	}
 
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {App.Entity.SlaveState} HG
+	 */
+	function mediumUse(slave, HG) {
+		oralUse += 4;
+		if (canDoAnal(slave)) {
+			analUse += 3;
+			if (canImpreg(slave, HG)) {
+				r.push(knockMeUp(slave, 3, 1, V.HeadGirlID));
+			}
+		} else if (slave.boobs >= 500) {
+			mammaryUse += 3;
+		} else {
+			oralUse += 3;
+		}
+		if (slave.vagina > 0 && canDoVaginal(slave)) {
+			vaginalUse += 3;
+			if (canImpreg(slave, HG)) {
+				r.push(knockMeUp(slave, 3, 0, V.HeadGirlID));
+			}
+		} else if (canDoAnal(slave)) {
+			analUse += 3;
+			if (canImpreg(slave, HG)) {
+				r.push(knockMeUp(slave, 3, 1, V.HeadGirlID));
+			}
+		} else {
+			oralUse += 3;
+		}
+		seX(slave, canDoVaginal(slave)
+			? "vaginal"
+			: canDoAnal(slave)
+				? "anal"
+				: "oral",
+		HG, "penetrative", 10);
+	}
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 * @param {App.Entity.SlaveState} HG
@@ -786,36 +878,15 @@ App.SlaveAssignment.liveWithHG = (function() {
 			} else {
 				oralUse += 5;
 			}
-			HG.counter.penetrative += 15;
-			V.penetrativeTotal += 15;
+			seX(slave, canDoVaginal(slave)
+				? "vaginal"
+				: canDoAnal(slave)
+					? "anal"
+					: "oral",
+			HG, "penetrative", 15);
 		} else if (HG.fetish === "submissive" && HG.fetishKnown === 1) {
 			r.push(`${HG.slaveName} walks a fine line with ${slave.slaveName}. They work out a sexual life in which ${HG.slaveName} is in charge, but ${slave.slaveName} takes the sexual lead: ${slave.slaveName} serves ${his} superior by taking ${him2} firmly.`);
-			oralUse += 4;
-			if (canDoAnal(slave)) {
-				analUse += 3;
-				if (canImpreg(slave, HG)) {
-					r.push(knockMeUp(slave, 3, 1, V.HeadGirlID));
-				}
-			} else if (slave.boobs >= 500) {
-				mammaryUse += 3;
-			} else {
-				oralUse += 3;
-			}
-			if (slave.vagina > 0 && canDoVaginal(slave)) {
-				vaginalUse += 3;
-				if (canImpreg(slave, HG)) {
-					r.push(knockMeUp(slave, 3, 0, V.HeadGirlID));
-				}
-			} else if (canDoAnal(slave)) {
-				analUse += 3;
-				if (canImpreg(slave, HG)) {
-					r.push(knockMeUp(slave, 3, 1, V.HeadGirlID));
-				}
-			} else {
-				oralUse += 3;
-			}
-			HG.counter.penetrative += 10;
-			V.penetrativeTotal += 10;
+			mediumUse(slave, HG);
 		} else if (HG.fetish === "dom" && HG.fetishKnown === 1) {
 			r.push(`${slave.slaveName} serves ${HG.slaveName} as ${his2} sexual and moral inferior, taking the Head Girl's`);
 			if (canPenetrate(HG)) {
@@ -824,32 +895,7 @@ App.SlaveAssignment.liveWithHG = (function() {
 				r.push(`strap-on`);
 			}
 			r.push(`in all ${his} holes. Though it isn't necessary with such an obedient partner, ${slave.slaveName} is often tied up for use.`);
-			oralUse += 4;
-			if (canDoAnal(slave)) {
-				analUse += 3;
-				if (canImpreg(slave, HG)) {
-					r.push(knockMeUp(slave, 3, 1, V.HeadGirlID));
-				}
-			} else if (slave.boobs >= 500) {
-				mammaryUse += 3;
-			} else {
-				oralUse += 3;
-			}
-			if (slave.vagina > 0 && canDoVaginal(slave)) {
-				vaginalUse += 3;
-				if (canImpreg(slave, HG)) {
-					r.push(knockMeUp(slave, 3, 0, V.HeadGirlID));
-				}
-			} else if (canDoAnal(slave)) {
-				analUse += 3;
-				if (canImpreg(slave, HG)) {
-					r.push(knockMeUp(slave, 3, 1, V.HeadGirlID));
-				}
-			} else {
-				oralUse += 3;
-			}
-			HG.counter.penetrative += 10;
-			V.penetrativeTotal += 10;
+			mediumUse(slave, HG);
 		} else if (HG.fetish === "humiliation" && HG.fetishKnown === 1) { // swap for exhibitionism in the future
 			r.push(`${HG.slaveName} is such an exhibitionist that ${slave.slaveName} finds ${himself} taking ${HG.slaveName}'s`);
 			if (canPenetrate(HG)) {
@@ -858,38 +904,12 @@ App.SlaveAssignment.liveWithHG = (function() {
 				r.push(`strap-on`);
 			}
 			r.push(`in public quite often.`);
-			oralUse += 4;
-			if (canDoAnal(slave)) {
-				analUse += 3;
-				if (canImpreg(slave, HG)) {
-					r.push(knockMeUp(slave, 3, 1, V.HeadGirlID));
-				}
-			} else if (slave.boobs >= 500) {
-				mammaryUse += 3;
-			} else {
-				oralUse += 3;
-			}
-			if (slave.vagina > 0 && canDoVaginal(slave)) {
-				vaginalUse += 3;
-				if (canImpreg(slave, HG)) {
-					r.push(knockMeUp(slave, 3, 0, V.HeadGirlID));
-				}
-			} else if (canDoAnal(slave)) {
-				analUse += 3;
-				if (canImpreg(slave, HG)) {
-					r.push(knockMeUp(slave, 3, 1, V.HeadGirlID));
-				}
-			} else {
-				oralUse += 3;
-			}
-			HG.counter.penetrative += 10;
-			V.penetrativeTotal += 10;
+			mediumUse(slave, HG);
 		} else if (HG.fetish === "boobs" && HG.fetishKnown === 1) {
 			r.push(`${HG.slaveName} is such a boob fetishist that ${slave.slaveName} sometimes wonders whether ${HG.slaveName} thinks there are four clits in the suite: the four nipples between the two of them.`);
 			oralUse += 4;
 			mammaryUse += 6;
-			HG.counter.mammary += 10;
-			V.mammaryTotal += 10;
+			seX(slave, "mammary", HG, "penetrative", 10);
 		} else if (HG.fetish === "buttslut" && HG.fetishKnown === 1) {
 			r.push(`${HG.slaveName} takes a dominant sexual role with ${slave.slaveName}; ${he2} indulges ${his2}`);
 			if (canDoAnal(slave)) {
@@ -900,19 +920,15 @@ App.SlaveAssignment.liveWithHG = (function() {
 			r.push(`while wearing a vibrating plug ${himself2}.`);
 			if (canDoAnal(slave)) {
 				analUse += 10;
-				HG.counter.penetrative += 10;
-				V.penetrativeTotal += 10;
+				seX(slave, "anal", HG, "penetrative", 10);
 				if (canImpreg(slave, HG)) {
 					r.push(knockMeUp(slave, 10, 1, V.HeadGirlID));
 				}
 			}
 		} else if (HG.fetish === "cumslut" && HG.fetishKnown === 1) {
 			r.push(`${HG.slaveName} takes a dominant sexual role with ${slave.slaveName}; ${he2} indulges ${his2} oral fixation with constant oral sex. ${He2} certainly applies ${his2} mouth to ${slave.slaveName} when ${he2} gets the chance, but ${slave.slaveName} does most of the sucking.`);
-			oralUse += 20;
-			HG.counter.oral += 10;
-			V.oralTotal += 10;
-			HG.counter.penetrative += 10;
-			V.penetrativeTotal += 10;
+			seX(slave, "oral", HG, "penetrative", 20);
+			seX(HG, "oral", slave, "penetrative", 10);
 		} else if (HG.fetish === "masochist" && HG.fetishKnown === 1) {
 			r.push(`${HG.slaveName} carefully structures ${his2} sexual games with ${slave.slaveName} to gratify ${his2} deep need to be physically hurt during sex without damaging ${his2} leadership. Usually, ${slave.slaveName} tortures ${HG.slaveName} until ${he2}'s quite sated, and then takes a rough`);
 			if (canDoAnal(slave)) {
@@ -935,8 +951,12 @@ App.SlaveAssignment.liveWithHG = (function() {
 			} else {
 				oralUse += 10;
 			}
-			HG.counter.penetrative += 10;
-			V.penetrativeTotal += 10;
+			seX(slave, canDoVaginal(slave)
+				? "vaginal"
+				: canDoAnal(slave)
+					? "anal"
+					: "oral",
+			HG, "penetrative", 10);
 		} else if (HG.fetish === "sadist" && HG.fetishKnown === 1) {
 			r.push(`${slave.slaveName} serves ${HG.slaveName} as ${his2} sexual punching bag, taking the Head Girl's`);
 			if (canPenetrate(HG)) {
@@ -945,32 +965,7 @@ App.SlaveAssignment.liveWithHG = (function() {
 				r.push(`strap-on`);
 			}
 			r.push(`roughly in all ${his} holes whenever ${he2} needs to sate ${his2} sadistic urges.`);
-			oralUse += 4;
-			if (canDoAnal(slave)) {
-				analUse += 3;
-				if (canImpreg(slave, HG)) {
-					r.push(knockMeUp(slave, 3, 1, V.HeadGirlID));
-				}
-			} else if (slave.boobs >= 500) {
-				mammaryUse += 3;
-			} else {
-				oralUse += 3;
-			}
-			if (slave.vagina > 0 && canDoVaginal(slave)) {
-				vaginalUse += 3;
-				if (canImpreg(slave, HG)) {
-					r.push(knockMeUp(slave, 3, 0, V.HeadGirlID));
-				}
-			} else if (canDoAnal(slave)) {
-				analUse += 3;
-				if (canImpreg(slave, HG)) {
-					r.push(knockMeUp(slave, 3, 1, V.HeadGirlID));
-				}
-			} else {
-				oralUse += 3;
-			}
-			HG.counter.penetrative += 10;
-			V.penetrativeTotal += 10;
+			mediumUse(slave, HG);
 		} else if (HG.attrXX > 65) {
 			r.push(`${HG.slaveName} expects ${slave.slaveName} to be girlish sexually, and ${slave.slaveName} spends a lot of time`);
 			if (hasBothLegs(slave)) {
@@ -1002,8 +997,12 @@ App.SlaveAssignment.liveWithHG = (function() {
 			} else {
 				oralUse++;
 			}
-			HG.counter.penetrative += 8;
-			V.penetrativeTotal += 8;
+			seX(slave, canDoVaginal(slave)
+				? "vaginal"
+				: canDoAnal(slave)
+					? "anal"
+					: "oral",
+			HG, "penetrative", 8);
 		} else {
 			r.push(`${HG.slaveName} takes a dominant sexual role with ${slave.slaveName}, mostly getting`);
 			if (canPenetrate(HG) && (canDoVaginal(slave) || canDoAnal(slave))) {
@@ -1035,25 +1034,18 @@ App.SlaveAssignment.liveWithHG = (function() {
 					r.push(knockMeUp(slave, 3, 1, V.HeadGirlID));
 				}
 			} else if (slave.boobs >= 300) {
-				mammaryUse += 3;
+				mammaryUse += 3;	// FIXME: 'mammaryUse' is assigned a value but never used.
 			} else {
 				oralUse += 3;
 			}
-			HG.counter.penetrative += 10;
-			V.penetrativeTotal += 10;
+			seX(slave, canDoVaginal(slave)
+				? "vaginal"
+				: canDoAnal(slave)
+					? "anal"
+					: "oral",
+			HG, "penetrative", 15);
 		}
 
-		slave.counter.oral += oralUse;
-		V.oralTotal += oralUse;
-		slave.counter.anal += analUse;
-		V.analTotal += analUse;
-		slave.counter.vaginal += vaginalUse;
-		V.vaginalTotal += vaginalUse;
-		slave.counter.mammary += mammaryUse;
-		V.mammaryTotal += mammaryUse;
-		slave.counter.penetrative += penetrativeUse;
-		V.penetrativeTotal += penetrativeUse;
-
 		if (slave.cervixImplant === 1 || slave.cervixImplant === 3) {
 			cervixPump += 20 * vaginalUse;
 		}
@@ -1139,14 +1131,14 @@ App.SlaveAssignment.liveWithHG = (function() {
 	 * @param {App.Entity.SlaveState} HG
 	 */
 	function HGDressesSlave(slave, HG) {
-		if (HG.fetishKnown === 1) {
-			if (HG.energy > 95) {
-				r.push(`${HG.slaveName} keeps ${slave.slaveName} naked so ${he2} doesn't have to waste any time tearing ${his} clothes off.`);
-				slave.clothes = "no clothing";
-			} else if (slave.devotion <= 20) {
-				r.push(`${HG.slaveName} keeps ${slave.slaveName} in a torturous habit since ${he} still clings to ${his} dignity and remains defiant.`);
-				slave.clothes = "a penitent nuns habit";
-			} else if (HG.fetish === "submissive") {
+		if (HG.energy > 95) {
+			r.push(`${HG.slaveName} keeps ${slave.slaveName} naked so ${he2} doesn't have to waste any time tearing ${his} clothes off.`);
+			slave.clothes = "no clothing";
+		} else if (slave.devotion <= 20) {
+			r.push(`${HG.slaveName} keeps ${slave.slaveName} in a torturous habit since ${he} still clings to ${his} dignity and remains defiant.`);
+			slave.clothes = "a penitent nuns habit";
+		} else if (HG.fetishKnown === 1) {
+			if (HG.fetish === "submissive") {
 				r.push(`${HG.slaveName} keeps ${slave.slaveName} dressed up in slutty power clothing, since ${he2}'s attracted to competence.`);
 				slave.clothes = "slutty business attire";
 			} else if (HG.fetish === "masochist") {
@@ -1181,14 +1173,16 @@ App.SlaveAssignment.liveWithHG = (function() {
 			} else if (HG.fetish === "buttslut") {
 				r.push(`${HG.slaveName} keeps ${slave.slaveName} wearing nothing but slutty bangles, since ${he2} likes dressing ${him} up but wants that butt bare.`);
 				slave.clothes = "slutty jewelry";
-			} else if (HG.fetish === "pregnancy" && isItemAccessible.entry("a huge empathy belly", "bellyAccessory", slave) === true) {
-				r.push(`${HG.slaveName} keeps ${slave.slaveName} wearing an empathy belly, since ${he2} likes ${his2} ${girl}s with a bun in the oven.`);
-				slave.bellyAccessory = "a large empathy belly";
-			} else if (HG.fetish === "pregnancy" && slave.preg > 0 && slave.pregKnown === 1 && slave.pregSource === V.HeadGirlID) {
-				r.push(`${HG.slaveName} keeps the pregnant ${slave.slaveName} dressed as a slutty maid, since ${he2} wants ${him} to look motherly yet fuckable while ${he2} fantasizes about fucking ${him} pregnant again.`);
-				slave.clothes = "a slutty maid outfit";
 			} else if (HG.fetish === "pregnancy") {
-				r.push(`${HG.slaveName} keeps ${slave.slaveName} dressed as a slutty maid, since ${he2} wants ${him} to look motherly yet fuckable while ${he2} fantasizes about putting a bun in ${his} oven.`);
+				if (isItemAccessible.entry("a huge empathy belly", "bellyAccessory", slave) === true) {
+					r.push(`${HG.slaveName} keeps ${slave.slaveName} wearing an empathy belly, since ${he2} likes ${his2} ${girl}s with a bun in the oven.`);
+					slave.bellyAccessory = "a large empathy belly";
+				}
+				if (slave.preg > 0 && slave.pregKnown === 1 && slave.pregSource === V.HeadGirlID) {
+					r.push(`${HG.slaveName} keeps the pregnant ${slave.slaveName} dressed as a slutty maid, since ${he2} wants ${him} to look motherly yet fuckable while ${he2} fantasizes about fucking ${him} pregnant again.`);
+				} else {
+					r.push(`${HG.slaveName} keeps ${slave.slaveName} dressed as a slutty maid, since ${he2} wants ${him} to look motherly yet fuckable while ${he2} fantasizes about putting a bun in ${his} oven.`);
+				}
 				slave.clothes = "a slutty maid outfit";
 			} else if (HG.attrXX > 85) {
 				r.push(`${HG.slaveName} keeps ${slave.slaveName} wearing nice lingerie, since girls and girliness turn ${him2} on.`);
@@ -1298,154 +1292,6 @@ App.SlaveAssignment.liveWithHG = (function() {
 		}
 	}
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {App.Entity.SlaveState} HG
-	 */
-	function HGSetsDietText(slave, HG) {
-		if ((arcology.FSRepopulationFocusPregPolicy === 1 || (arcology.FSRestart === "unset" && HG.fetish === "pregnancy")) && canImpreg(slave, HG) && V.dietFertility === 1) {
-			r.push(`${HG.slaveName} thinks ${slave.slaveName} could do with a bigger bump`);
-			if (arcology.FSRepopulationFocusPregPolicy) {
-				r.push(`since pregnant ${girl}s are all the rage in your arcology`);
-			}
-			if (diet !== "fertility") {
-				r.push(`and assigns ${him} a diet to promote ovulation.`);
-			} else {
-				r.push(`and keeps ${him} on ${his} fertility diet.`);
-			}
-		} else if ((slave.weight < 100 && arcology.FSHedonisticDecadence >= 20) || (slave.weight < -10)) {
-			r.push(`${HG.slaveName} thinks ${slave.slaveName} could use a little extra weight`);
-			if (arcology.FSHedonisticDecadence >= 20) {
-				r.push(`since plump ${girl}s are all the rage in your arcology`);
-			}
-			if (diet !== "fattening") {
-				r.push(`and assigns ${him} a diet to fatten ${him} up.`);
-			} else {
-				r.push(`and keeps ${him} on ${his} fattening diet.`);
-			}
-		} else if (slave.weight > 30 && arcology.FSHedonisticDecadence === "unset") {
-			r.push(`${HG.slaveName} thinks ${slave.slaveName} is a little too porky`);
-			if (diet !== "restricted") {
-				r.push(`and puts ${him} on a diet.`);
-			} else {
-				r.push(`and keeps ${him} on ${his} diet.`);
-			}
-		} else if (((slave.muscles <= 95 && ((arcology.FSPhysicalIdealist > 0 && arcology.FSPhysicalIdealistLaw === 0) || (HG.fetish === "submissive" || HG.fetish === "masochist"))) || (slave.muscles <= 45 && (arcology.FSPhysicalIdealist !== "unset" && arcology.FSPhysicalIdealistLaw === 1)) || slave.muscles <= 5) && !isAmputee(slave)) {
-			r.push(`${HG.slaveName} thinks ${slave.slaveName}`);
-			if (HG.fetish === "submissive" && HG.fetishKnown === 1) {
-				r.push(`could use bigger muscles to better dominate ${him2} with in bed`);
-			} else if (HG.fetish === "masochist" && HG.fetishKnown === 1) {
-				r.push(`could use bigger muscles to better spank ${him2}`);
-			} else if (arcology.FSPhysicalIdealist !== "unset") {
-				r.push(`could use bigger muscles to support your societal goals`);
-			} else {
-				r.push(`could use a bit of muscle`);
-			}
-			if (diet !== "muscle building") {
-				r.push(`and makes ${him} work out hard.`);
-			} else {
-				r.push(`and keeps ${him} working out.`);
-			}
-		} else if (slave.balls > 0 && HG.fetish === "cumslut" && V.cumProDiet === 1) {
-			r.push(`${HG.slaveName}`);
-			if (HG.fetishKnown === 1) {
-				r.push(`loves cum,`);
-			} else {
-				r.push(`seems amused by cumshots,`);
-			}
-			r.push(`so ${he2}`);
-			if (diet !== "cum production") {
-				r.push(`puts`);
-			} else {
-				r.push(`keeps`);
-			}
-			r.push(`${slave.slaveName} on a diet designed to make ${him} cum harder and stronger.`);
-		} else {
-			r.push(`${HG.slaveName} thinks ${slave.slaveName} is fine as is`);
-			if (diet !== "healthy") {
-				r.push(`and puts ${him} on a normal diet.`);
-			} else {
-				r.push(`and keeps ${him} on ${his} healthy diet.`);
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {App.Entity.SlaveState} HG
-	 */
-	function HGSetsHormonesText(slave, HG) {
-		// room for expansion
-		if (hormones !== 2) {
-			r.push(`${HG.slaveName} puts ${slave.slaveName} on intensive female hormones, since ${he2} expects ${him} to act as the submissive, feminine partner.`);
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {App.Entity.SlaveState} HG
-	 */
-	function HGSetsDrugsText(slave, HG) {
-		if (V.HGSuiteDrugs !== 0) {
-			if (slave.health.condition < 60) {
-				r.push(`${HG.slaveName} gives ${slave.slaveName} curatives, since ${he2} wants a shiningly healthy living partner.`);
-			}
-			if (slave.lips <= 20) {
-				r.push(`${HG.slaveName} gives ${slave.slaveName} lip injections, since ${he2} wants to get oral from plump, luscious lips.`);
-			} else if (arcology.FSSlaveProfessionalismResearch === 1 && V.HGSuiteEquality !== 0 && canImproveIntelligence(slave)) {
-				r.push(`${HG.slaveName} gives ${slave.slaveName} psychostimulants, since ${him} being smarter will benefit them both when ${he} is in charge.`);
-			} else if (HG.fetish === "buttslut" && arcology.FSAssetExpansionistResearch === 1 && slave.butt < 18) {
-				r.push(`${HG.slaveName} gives ${slave.slaveName} hyper ass injections, since ${he2} never once thought it possible to fuck an ass as big as ${his} is.`);
-			} else if (HG.fetish === "buttslut" && arcology.FSAssetExpansionistResearch === 1 && slave.butt < 8) {
-				r.push(`${HG.slaveName} gives ${slave.slaveName} ass injections, since ${he2} likes comfortable padding as ${he2} fucks a butt.`);
-			} else if (HG.fetish === "cumslut" && arcology.FSAssetExpansionistResearch === 1 && slave.balls < 100 && slave.balls > 0 && slave.dick > 0) {
-				r.push(`${HG.slaveName} gives ${slave.slaveName} hyper testicle injections, since ${he2}`);
-				if (HG.fetishKnown === 1) {
-					r.push(`wants to swim in a river of cum.`);
-				} else {
-					r.push(`enjoys seeing how large of a load ${slave.slaveName} can blow.`);
-				}
-			} else if (HG.fetish === "cumslut" && slave.balls < 10 && slave.balls > 0 && slave.dick > 0) {
-				r.push(`${HG.slaveName} gives ${slave.slaveName} testicle injections, since ${he2} wants ${slave.slaveName} shooting bigger loads.`);
-			} else if ((HG.fetish === "masochist" || HG.fetish === "submissive") && canImproveHeight(slave)) {
-				r.push(`${HG.slaveName}`);
-				if (HG.fetishKnown === 1) {
-					r.push(`has a subconscious need to be hurt by the biggest, strongest ${girl} possible,`);
-				} else {
-					r.push(`feels that ${slave.slaveName} is too short,`);
-				}
-				r.push(`so ${he2} gives ${slave.slaveName} injections of growth stimulants to make ${him} grow taller.`);
-			} else if (HG.fetish === "boobs" && slave.boobs < 15000) {
-				r.push(`${HG.slaveName} gives ${slave.slaveName}`);
-				if (arcology.FSAssetExpansionistResearch === 1) {
-					r.push(`hyper`);
-				}
-				r.push(`tit injections,`);
-				if (HG.fetishKnown === 1) {
-					r.push(`since as far as ${he2}'s concerned there's no such thing as too much boob.`);
-				} else {
-					r.push(`eager to see just how much boob ${slave.slaveName} can handle.`);
-				}
-			} else if (canImpreg(slave, HG) && arcology.FSRestart === "unset" && (getHGTastes() === 4 || HG.fetish === "pregnancy")) {
-				r.push(`${HG.slaveName} gives ${slave.slaveName} fertility enhancers, since ${he2} wants to see ${slave.slaveName} heavy with child.`);
-			} else if (arcology.FSRepopulationFocusPregPolicy === 1 && canImpreg(slave, HG)) {
-				r.push(`${HG.slaveName} gives ${slave.slaveName} fertility enhancers, since pregnancy is popular and ${he2} wants ${slave.slaveName} to look hot.`);
-			} else if (getHGTastes() > 1) {
-				if (slave.lips <= 70) {
-					r.push(`${HG.slaveName} gives ${slave.slaveName} lip injections, since ${he2} thinks ${slave.slaveName} should have lips so big ${he} can barely speak.`);
-				} else if (slave.boobs > (125 * Math.pow(slave.butt, 2))) {
-					r.push(`${HG.slaveName} gives ${slave.slaveName} ass injections, since ${he2} loves curves and thinks ${slave.slaveName}'s butt needs the most work.`);
-				} else {
-					r.push(`${HG.slaveName} gives ${slave.slaveName} boob injections, since ${he2} loves curves and thinks ${slave.slaveName}'s tits need the most work.`);
-				}
-			}
-		} else {
-			if (slave.health.condition < 100) {
-				r.push(`${HG.slaveName} gives ${slave.slaveName} curatives, since ${his2} assistant could be healthier.`);
-			}
-		}
-	}
-
 	/** Allow the HG to set RA surgery rules based on her tastes, for immediate application
 	 * @returns {FC.RA.RuleSurgerySettings}
 	 */
@@ -1456,56 +1302,56 @@ App.SlaveAssignment.liveWithHG = (function() {
 				thisSurgery.lactation = 0;
 				thisSurgery.cosmetic = 1;
 				thisSurgery.faceShape = "cute";
-				thisSurgery.lips = App.RA.makeTarget('==', 10);
+				thisSurgery.lips = App.Utils.makeRange(10, 10);
 				thisSurgery.hips = 0;
 				thisSurgery.hipsImplant = 0;
-				thisSurgery.butt = App.RA.makeTarget('==', 0);
+				thisSurgery.butt = App.Utils.makeRange(0, 0);
 				thisSurgery.accent = 0;
 				thisSurgery.shoulders = 0;
 				thisSurgery.shouldersImplant = 0;
-				thisSurgery.boobs = App.RA.makeTarget('==', 0);
+				thisSurgery.boobs = App.Utils.makeRange(0, 0);
 				thisSurgery.holes = 0;
 				break;
 			case 2:
 				thisSurgery.lactation = 0;
 				thisSurgery.cosmetic = 1;
 				thisSurgery.faceShape = "cute";
-				thisSurgery.lips = App.RA.makeTarget('==', 60);
+				thisSurgery.lips = App.Utils.makeRange(60, 60);
 				thisSurgery.hips = 0;
 				thisSurgery.hipsImplant = 0;
-				thisSurgery.butt = App.RA.makeTarget('==', 4);
+				thisSurgery.butt = App.Utils.makeRange(4, 4);
 				thisSurgery.accent = 0;
 				thisSurgery.shoulders = 0;
 				thisSurgery.shouldersImplant = 0;
-				thisSurgery.boobs = App.RA.makeTarget('==', 1200);
+				thisSurgery.boobs = App.Utils.makeRange(1200, 1200);
 				thisSurgery.holes = 0;
 				break;
 			case 3:
 				thisSurgery.lactation = 0;
 				thisSurgery.cosmetic = 1;
 				thisSurgery.faceShape = "cute";
-				thisSurgery.lips = App.RA.makeTarget('==', 95);
+				thisSurgery.lips = App.Utils.makeRange(95, 95);
 				thisSurgery.hips = 0;
 				thisSurgery.hipsImplant = 0;
-				thisSurgery.butt = App.RA.makeTarget('==', 8);
+				thisSurgery.butt = App.Utils.makeRange(8, 8);
 				thisSurgery.accent = 0;
 				thisSurgery.shoulders = 0;
 				thisSurgery.shouldersImplant = 0;
-				thisSurgery.boobs = App.RA.makeTarget('==', 10000);
+				thisSurgery.boobs = App.Utils.makeRange(10000, 10000);
 				thisSurgery.holes = 2;
 				break;
 			case 4:
 				thisSurgery.lactation = 1;
 				thisSurgery.cosmetic = 1;
 				thisSurgery.faceShape = "cute";
-				thisSurgery.lips = App.RA.makeTarget('==', 10);
+				thisSurgery.lips = App.Utils.makeRange(10, 10);
 				thisSurgery.hips = 3;
 				thisSurgery.hipsImplant = 0;
-				thisSurgery.butt = App.RA.makeTarget('==', 0);
+				thisSurgery.butt = App.Utils.makeRange(0, 0);
 				thisSurgery.accent = 0;
 				thisSurgery.shoulders = 0;
 				thisSurgery.shouldersImplant = 0;
-				thisSurgery.boobs = App.RA.makeTarget('==', 0);
+				thisSurgery.boobs = App.Utils.makeRange(0, 0);
 				thisSurgery.holes = 0;
 				break;
 			default:
@@ -1565,7 +1411,7 @@ App.SlaveAssignment.liveWithHG = (function() {
 						surgeryDamage(slave, 20);
 					}
 				}
-				if (slave.devotion < -90 && slave.fetish !== "mindbroken") {
+				if (slave.devotion < -90) {
 					r.push(`${HG.slaveName} tires of ${slave.slaveName}'s protests that ${HG.slaveName} is a monster for hurting ${him} this way and ${his} complaints that ${he} deserves better. ${HG.slaveName} decides that it'll be just as much fun and a lot less trouble to mistreat ${slave.slaveName} once ${he}'s mindbroken, and sends ${him} in for <span class="mindbreak">chemical lobotomization.</span>`);
 					applyMindbroken(slave);
 					surgeryDamage(slave, 20);
@@ -1644,20 +1490,17 @@ App.SlaveAssignment.liveWithHG = (function() {
 
 	/**
 	 * @param {FC.ReportSlave} slave
-	 *
+	 * @param {DocumentFragment} el
 	 */
-	function slaveReport(slave) {
+	function slaveReport(slave, el) {
 		if (V.showEWD === 0) {
 			/* App.SlaveAssignment.choosesOwnClothes(slave) */
 			App.SlaveAssignment.individualSlaveReport(slave);
 			App.SlaveAssignment.devotion(slave);
 		} else {
 			/* App.SlaveAssignment.choosesOwnClothes(slave) */
-			const content = App.UI.DOM.makeElement("div", '', "indent");
-			$(content).append(
-				...App.Events.spaceSentences(App.SlaveAssignment.individualSlaveReport(slave)),
-				`<div class="indent">${App.SlaveAssignment.devotion(slave)}</div>`);
-			r.push(content);
+			App.Events.addNode(el, App.SlaveAssignment.individualSlaveReport(slave), "div", "indent");
+			App.Events.addNode(el, [App.SlaveAssignment.devotion(slave)], "div", "indent");
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saLongTermEffects.js b/src/endWeek/saLongTermEffects.js
index 9fda2639937a261d20efdc35c9b6846193e169a9..4887fe53fe2b55f68fa093d19e8f82724c6b7211 100644
--- a/src/endWeek/saLongTermEffects.js
+++ b/src/endWeek/saLongTermEffects.js
@@ -1,117 +1,97 @@
-App.SlaveAssignment.longTermEffects = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {DocumentFragment}
+ */
+App.SlaveAssignment.longTermEffects = function saLongTermEffects(slave) {
+	const r = [];
 
-	let r;
+	const gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
+	const rearQuirk = slave.geneticQuirks.rearLipedema === 2 ? 2 : 0;
+	const uterineHypersensitivityMod = slave.geneticQuirks.uterineHypersensitivity === 2 ? 2 : 1;
+	const oldEnergy = slave.energy;
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let He;
-	let His;
+	const {
+		he, him, his, himself, He, His,
+	} = getPronouns(slave);
 
-	let gigantomastiaMod;
-	let rearQuirk;
-	let uterineHypersensitivityMod;
-	let effect;
-
-	return saLongTermEffects;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {DocumentFragment}
-	 */
-	function saLongTermEffects(slave) {
-		r = [];
-
-		gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
-		rearQuirk = slave.geneticQuirks.rearLipedema === 2 ? 2 : 0;
-		uterineHypersensitivityMod = slave.geneticQuirks.uterineHypersensitivity === 2 ? 2 : 1;
-		const oldEnergy = slave.energy;
-
-		({
-			he, him, his, himself, He, His,
-		} = getPronouns(slave));
-
-		if (slave.fuckdoll > 0) {
-			fuckdollConversion(slave);
-		}
-		if (assignmentVisible(slave) && (slave.assignment !== "live with your Head Girl" || V.HGSuiteSurgery === 0)) {
-			if (hasSurgeryRule(slave, V.defaultRules) && slave.useRulesAssistant === 1 && slave.indentureRestrictions < 2 && V.cash > 0) {
-				r.push(rulesAutosurgery(slave));
-			}
-		}
-		r.push(App.SlaveAssignment.clothes(slave));
-		r.push(App.SlaveAssignment.longTermMentalEffects(slave));
-		piercingEffects(slave);
-		if (slave.lactation >= 2 || (slave.lactation > 0 && slave.lactationAdaptation >= 100)) {
-			heavyLactationEffects(slave);
-		}
-		implantEffects(slave);
-		if (slave.diet === "muscle building") { // Why is this here? Probably something to do with hormones.
-			muscleBuildingEffects(slave);
-		}
-		if (slave.aphrodisiacs > random(0, 2)) {
-			aphrodisiacEffects(slave);
-		}
-		hormoneBalance(slave); // includes App.SlaveAssignment.hormonesEffects()
-		if (slave.pubertyXX === 0 || slave.pubertyXY === 0) {
-			puberty(slave);
-		}
-		r.push(App.SlaveAssignment.pregnancy(slave));
-		if (slave.bellyFluid >= 1500) {
-			r.push(App.SlaveAssignment.inflation(slave));
-			inflationEffects(slave);
+	if (slave.fuckdoll > 0) {
+		fuckdollConversion(slave);
+	}
+	if (assignmentVisible(slave) && (slave.assignment !== "live with your Head Girl" || V.HGSuiteSurgery === 0)) {
+		if (hasSurgeryRule(slave, V.defaultRules) && slave.useRulesAssistant === 1 && slave.indentureRestrictions < 2 && V.cash > 0) {
+			r.push(rulesAutosurgery(slave));
 		}
-		bellySagging(slave);
-		bellyImplantStuff(slave);
-		if (slave.fetish !== "mindbroken") {
-			mindbreak(slave);
-			if (slave.fuckdoll === 0) {
-				mentalTension(slave);
-				if (!canTalk(slave)) {
-					noTalkingFixesFlaws(slave);
-				}
-				if (slave.breedingMark === 1 && V.propOutcome === 1) {
-					breedingMark(slave);
-				}
-				solidSlaveFoodEffects(slave);
+	}
+	r.push(App.SlaveAssignment.clothes(slave));
+	r.push(App.SlaveAssignment.longTermMentalEffects(slave));
+	piercingEffects(slave);
+	if (slave.lactation >= 2 || (slave.lactation > 0 && slave.lactationAdaptation >= 100)) {
+		heavyLactationEffects(slave);
+	}
+	implantEffects(slave);
+	if (slave.diet === "muscle building") { // Why is this here? Probably something to do with hormones.
+		muscleBuildingEffects(slave);
+	}
+	if (slave.aphrodisiacs > random(0, 2)) {
+		aphrodisiacEffects(slave);
+	}
+	hormoneBalance(slave); // includes App.SlaveAssignment.hormonesEffects()
+	if (slave.pubertyXX === 0 || slave.pubertyXY === 0) {
+		puberty(slave);
+	}
+	r.push(App.SlaveAssignment.pregnancy(slave));
+	if (slave.bellyFluid >= 1500) {
+		r.push(App.SlaveAssignment.inflation(slave));
+		inflationEffects(slave);
+	}
+	bellySagging(slave);
+	bellyImplantStuff(slave);
+	if (slave.fetish !== "mindbroken") {
+		mindbreak(slave);
+		if (slave.fuckdoll === 0) {
+			mentalTension(slave);
+			if (!canTalk(slave)) {
+				noTalkingFixesFlaws(slave);
 			}
-		}
-		r.push(App.SlaveAssignment.saSocialEffects(slave));
-		if (slave.fuckdoll === 0) { // swap to fuckdoll suit in the future
-			brandEffects(slave);
-			if (slave.fetish !== "mindbroken") {
-				disabilityEffects(slave);
+			if (slave.breedingMark === 1 && V.propOutcome === 1) {
+				breedingMark(slave);
 			}
+			solidSlaveFoodEffects(slave);
 		}
-		r.push(App.SlaveAssignment.longTermPhysicalEffects(slave));
-		anaphrodisiacEffects(slave, oldEnergy); // must come after all .energy gains!
-		if (slave.accent > 0 && slave.fetish !== "mindbroken") {
-			languageLearning(slave);
-		}
-		if (slave.prestige > 0) {
-			prestige(slave);
-		}
-		pornEffects(slave);
-		age(slave);
-		if (V.arcologies[0].FSRestart !== "unset") {
-			pregnancyCheck(slave);
-		}
-		if (slave.preg > slave.pregData.normalBirth / 8) {
-			mainLaborTriggers(slave);
-		}
-		endWeekHealthDamage(slave); // contained in healthFunctions.js
-		slaveDeath(slave);
-		if ((slave.hStyle !== "shaved" && slave.hStyle !== "buzzcut" && slave.hStyle !== "trimmed" && slave.hStyle !== "pixie cut" && slave.hStyle !== "bob cut") && slave.bald !== 1 && slave.haircuts === 0) {
-			hairGrowth(slave);
+	}
+	r.push(App.SlaveAssignment.saSocialEffects(slave));
+	if (slave.fuckdoll === 0) { // swap to fuckdoll suit in the future
+		brandEffects(slave);
+		if (slave.fetish !== "mindbroken") {
+			disabilityEffects(slave);
 		}
-
-		const frag = document.createDocumentFragment();
-		$(frag).append(...App.Events.spaceSentences(r));
-		return frag;
+	}
+	r.push(App.SlaveAssignment.longTermPhysicalEffects(slave));
+	anaphrodisiacEffects(slave, oldEnergy); // must come after all .energy gains!
+	if (slave.accent > 0 && slave.fetish !== "mindbroken") {
+		languageLearning(slave);
+	}
+	if (slave.prestige > 0) {
+		prestige(slave);
+	}
+	pornEffects(slave);
+	age(slave);
+	if (V.arcologies[0].FSRestart !== "unset") {
+		pregnancyCheck(slave);
+	}
+	if (slave.preg > slave.pregData.normalBirth / 8) {
+		mainLaborTriggers(slave);
+	}
+	endWeekHealthDamage(slave); // contained in healthFunctions.js
+	slaveDeath(slave);
+	if ((slave.hStyle !== "shaved" && slave.hStyle !== "buzzcut" && slave.hStyle !== "trimmed" && slave.hStyle !== "pixie cut" && slave.hStyle !== "bob cut") && slave.bald !== 1 && slave.haircuts === 0) {
+		hairGrowth(slave);
 	}
 
+	const frag = document.createDocumentFragment();
+	$(frag).append(...App.Events.spaceSentences(r));
+	return frag;
+
 	/**
 	 * Calculate current total base of the slave's boobs, since it'll be changing throughout the passage
 	 * @param {App.Entity.SlaveState} slave
@@ -178,7 +158,13 @@ App.SlaveAssignment.longTermEffects = (function() {
 						r.push(`legs.`);
 					}
 				} else {
-					r.push(`${He} practices balance in the heels integral to the suit, and learns to stand and bend at the waist, all the way down, while keeping ${his} legs straight, putting ${his} face hole and ${his}`);
+					r.push(`${He} practices balance in the heels integral to the suit, and learns to stand and bend at the waist, all the way down, while keeping ${his}`);
+					if (!hasBothLegs(slave)) {
+						r.push(`leg`);
+					} else {
+						r.push(`legs`);
+					}
+					r.push(`straight, putting ${his} face hole and ${his}`);
 					if (slave.vagina > -1) {
 						r.push(`lower holes`);
 					} else {
@@ -444,7 +430,7 @@ App.SlaveAssignment.longTermEffects = (function() {
 			r.push(`${His} string implants absorb fluid, <span class="change positive">slowly swelling ${his} breasts.</span>`);
 			slave.boobsImplant += 50;
 			slave.boobs += 50;
-			effect = random(1, 10);
+			const effect = random(1, 10);
 			if (slave.boobs > 50000) {
 				r.push(`Since they are as large as ${his} body can handle, some serum is drained from them.`);
 				slave.boobs -= 100;
@@ -514,7 +500,7 @@ App.SlaveAssignment.longTermEffects = (function() {
 				slave.butt -= 1;
 				slave.buttImplant -= 1;
 			}
-			effect = random(1, 8);
+			const effect = random(1, 8);
 			if (slave.buttImplant > 7 && effect >= 2) {
 				r.push(`As they grow they <span class="health dec">greatly irritate</span> the tissue of ${his} cheeks.`);
 				healthDamage(slave, 20);
@@ -545,7 +531,6 @@ App.SlaveAssignment.longTermEffects = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
 	 */
 	function muscleBuildingEffects(slave) {
 		if (slave.muscles > 30) {
@@ -564,7 +549,6 @@ App.SlaveAssignment.longTermEffects = (function() {
 
 	/**
 	 * @param {FC.ReportSlave} slave
-	 *
 	 */
 	function aphrodisiacEffects(slave) {
 		let Effects = [];
@@ -578,7 +562,7 @@ App.SlaveAssignment.longTermEffects = (function() {
 			if (slave.clit > 0 && slave.geneticQuirks.wellHung !== 2) {
 				Effects.push("ClitSmaller");
 			}
-			if (slave.voice < 3 && slave.voice > 0) {
+			if (slave.voice.isBetween(0, 3)) {
 				Effects.push("VoiceHigher");
 			}
 			if (slave.vagina > -1 && slave.ovaries !== 0 && slave.vaginaLube < 2) {
@@ -1571,7 +1555,7 @@ App.SlaveAssignment.longTermEffects = (function() {
 		if (slave.behavioralFlaw === "none") {
 			if (slave.trust < -20 && slave.devotion <= 50) {
 				if (random(1, 100) > 100 + slave.trust) {
-					effect = random(1, 4);
+					const effect = random(1, 4);
 					r.push(`Being so afraid so constantly drives ${him} to find solace in`);
 					if (attention && ["build devotion", "health", "soften behavioral flaw", "soften sexual flaw", "learn skills"].includes(attention.objective)) {
 						r.push(`your attention. Relying on you for <span class="devotion inc">emotional support</span> strengthens ${his} <span class="trust inc">bond</span> with ${getWrittenTitle(slave)}.`);
@@ -1596,7 +1580,7 @@ App.SlaveAssignment.longTermEffects = (function() {
 		if (slave.sexualFlaw === "none") {
 			if (slave.devotion < -20) {
 				if (random(1, 500) > 500 + slave.devotion) {
-					effect = random(1, 6);
+					const effect = random(1, 6);
 					r.push(`Being so angry at ${his} life as a sex slave has`);
 					if (attention && ["build devotion", "health", "soften behavioral flaw", "soften sexual flaw", "learn skills"].includes(attention.objective)) {
 						r.push(`forced ${him} to face ${his} problems with you. Lending ${him} support makes it <span class="devotion inc">a little more tolerable.</span>`);
@@ -1893,9 +1877,10 @@ App.SlaveAssignment.longTermEffects = (function() {
 	 *
 	 */
 	function brandEffects(slave) {
-		if (!jQuery.isEmptyObject(slave.brand)) {
+		const brands = App.Medicine.Modification.brandRecord(slave);
+		if (!jQuery.isEmptyObject(brands)) {
 			if ([Job.PUBLIC, Job.WHORE, Job.BROTHEL, Job.CLUB].includes(slave.assignment)) {
-				r.push(`Since ${he} is in public, your brand against the ${slave.skin} skin of ${his} ${Object.keys(slave.brand)[0]} <span class="reputation inc">slightly increases your reputation</span> as a slaveowner.`);
+				r.push(`Since ${he} is in public, your brand against the ${slave.skin} skin of ${his} ${Object.keys(brands)[0]} <span class="reputation inc">slightly increases your reputation</span> as a slaveowner.`);
 				repX(5, "futureSocieties", slave);
 				switch (slave.assignment) {
 					case "work in the brothel":
@@ -2589,4 +2574,4 @@ App.SlaveAssignment.longTermEffects = (function() {
 			slave.energy = oldEnergy + maxEnergyGain;
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saLongTermMentalEffects.js b/src/endWeek/saLongTermMentalEffects.js
index 98d7e84fa1c57ae6a91f734cbde19575456eca75..82923894e546a7d27f22c365550c38c00e7333de 100644
--- a/src/endWeek/saLongTermMentalEffects.js
+++ b/src/endWeek/saLongTermMentalEffects.js
@@ -1,69 +1,49 @@
-App.SlaveAssignment.longTermMentalEffects = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.longTermMentalEffects = function saLongTermMentalEffects(slave) {
+	const r = [];
 
-	let r;
+	const {
+		he, him, his, himself, girl, He, His,
+	} = getPronouns(slave);
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let girl;
-	let He;
-	let His;
-
-	let boobSize;
-
-	return saLongTermMentalEffects;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {string}
-	 */
-	function saLongTermMentalEffects(slave) {
-		r = [];
-
-		boobSize = slave.boobs - slave.boobsImplant - slave.boobsMilk;
-
-		({
-			he, him, his, himself, girl, He, His,
-		} = getPronouns(slave));
-
-		if (slave.fetish === "mindbroken") {
-			applyMindbroken(slave);
-		} else if (slave.fuckdoll === 0) {
-			asexualOvariesBurnout(slave);
-			sexualAttraction(slave);
-			if (slave.behavioralQuirk !== "none") {
-				behavioralQuirkEffects(slave);
-			}
-			if (slave.sexualQuirk !== "none") {
-				sexualQuirkEffects(slave);
-			}
-			if (slave.fetishKnown === 1) {
-				fetishEffects(slave);
-			}
-			if (slave.behavioralFlaw !== "none") { // Moved out of .fetishKnown for the devout block to be more prominent.
-				behavioralFlawEffects(slave);
-			}
-			if (slave.sexualFlaw !== "none") {
-				sexualFlawEffects(slave);
-				paraphiliaImpacts(slave);
-			}
-			if (slave.energy > 95) {
-				nymphoDevotionGain(slave);
-			}
-			careerEffects(slave);
+	if (slave.fetish === "mindbroken") {
+		applyMindbroken(slave);
+	} else if (slave.fuckdoll === 0) {
+		asexualOvariesBurnout(slave);
+		sexualAttraction(slave);
+		if (slave.behavioralQuirk !== "none") {
+			behavioralQuirkEffects(slave);
 		}
-		r.push(App.SlaveAssignment.saSmartPiercingEffects(slave));
-		if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
-			organicFetishDevelopments(slave);
-			if (slave.fetishKnown !== 0 && slave.fetish !== "none") {
-				paraphiliaAcquisition(slave);
-			}
+		if (slave.sexualQuirk !== "none") {
+			sexualQuirkEffects(slave);
 		}
-
-		return r.join(" ");
+		if (slave.fetishKnown === 1) {
+			fetishEffects(slave);
+		}
+		if (slave.behavioralFlaw !== "none") { // Moved out of .fetishKnown for the devout block to be more prominent.
+			behavioralFlawEffects(slave);
+		}
+		if (slave.sexualFlaw !== "none") {
+			sexualFlawEffects(slave);
+			paraphiliaImpacts(slave);
+		}
+		if (slave.energy > 95) {
+			nymphoDevotionGain(slave);
+		}
+		careerEffects(slave);
 	}
+	r.push(App.SlaveAssignment.saSmartPiercingEffects(slave));
+	if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
+		organicFetishDevelopments(slave);
+		if (slave.fetishKnown !== 0 && slave.fetish !== "none") {
+			paraphiliaAcquisition(slave);
+		}
+	}
+
+	return r.join(" ");
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
@@ -222,7 +202,7 @@ App.SlaveAssignment.longTermMentalEffects = (function() {
 					slave.attrXY += 3;
 				} else if (slave.fetish === "pregnancy") {
 					if (slave.fetishKnown === 1) {
-						t.push(`${His} fantasies about pregnancy have become quite vivid; ${he} loves hot cum jetting into ${him}. ${He}'s now <span class="positive">more attracted to men.</span>`);
+						t.push(`${His} fantasies about pregnancy have become quite vivid; ${he} loves ${slave.counter.vaginal === 0 ? `the idea of` : ``} hot cum jetting into ${him}. ${He}'s now <span class="positive">more attracted to men.</span>`);
 					}
 					slave.attrXY += 3;
 				}
@@ -595,29 +575,33 @@ App.SlaveAssignment.longTermMentalEffects = (function() {
 							}
 							break;
 						case "adores men":
-							if (slave.fetish !== "pregnancy" && (slave.ovaries === 1 || slave.mpreg === 1)) {
-								r.push(`${His} appreciation of men has turned into a fantasy about getting knocked up. <span class="fetish gain">${He}'s a pregnancy fetishist!</span>`);
-								slave.fetish = "pregnancy";
-								slave.fetishKnown = 1;
-								slave.fetishStrength = 65;
-							} else if (slave.fetish !== "cumslut") {
-								r.push(`${His} appreciation of men has turned into a fetish for cocks, balls and, more importantly, what comes out of them. <span class="fetish gain">${He}'s now a cum fetishist!</span>`);
-								slave.fetish = "cumslut";
-								slave.fetishKnown = 1;
-								slave.fetishStrength = 65;
+							if (slave.fetish !== "pregnancy" && slave.fetish !== "cumslut") {
+								if (slave.ovaries === 1 || slave.mpreg === 1) {
+									r.push(`${His} appreciation of men has turned into a fantasy about getting knocked up. <span class="fetish gain">${He}'s a pregnancy fetishist!</span>`);
+									slave.fetish = "pregnancy";
+									slave.fetishKnown = 1;
+									slave.fetishStrength = 65;
+								} else {
+									r.push(`${His} appreciation of men has turned into a fetish for cocks, balls and, more importantly, what comes out of them. <span class="fetish gain">${He}'s now a cum fetishist!</span>`);
+									slave.fetish = "cumslut";
+									slave.fetishKnown = 1;
+									slave.fetishStrength = 65;
+								}
 							}
 							break;
 						case "adores women":
-							if (slave.fetish !== "pregnancy" && canPenetrate(slave)) {
-								r.push(`${His} appreciation of women has turned into a fantasy about knocking them up. <span class="fetish gain">${He}'s an impregnation fetishist!</span>`);
-								slave.fetish = "pregnancy";
-								slave.fetishKnown = 1;
-								slave.fetishStrength = 65;
-							} else if (slave.fetish !== "boobs") {
-								r.push(`${His} appreciation of women has turned into a fetish for breasts. <span class="fetish gain">${He}'s a boob fetishist!</span>`);
-								slave.fetish = "boobs";
-								slave.fetishKnown = 1;
-								slave.fetishStrength = 65;
+							if (slave.fetish !== "pregnancy" && slave.fetish !== "boobs") {
+								if (canPenetrate(slave)) {
+									r.push(`${His} appreciation of women has turned into a fantasy about knocking them up. <span class="fetish gain">${He}'s an impregnation fetishist!</span>`);
+									slave.fetish = "pregnancy";
+									slave.fetishKnown = 1;
+									slave.fetishStrength = 65;
+								} else {
+									r.push(`${His} appreciation of women has turned into a fetish for breasts. <span class="fetish gain">${He}'s a boob fetishist!</span>`);
+									slave.fetish = "boobs";
+									slave.fetishKnown = 1;
+									slave.fetishStrength = 65;
+								}
 							}
 							break;
 						case "insecure":
@@ -1879,7 +1863,7 @@ App.SlaveAssignment.longTermMentalEffects = (function() {
 				}
 			}
 		}
-		if (!slave.piercing.genitals.smart || slave.clitSetting === "off" || slave.clitSetting === "none" || slave.clitSetting === "all" || slave.clitSetting === "men" || slave.clitSetting === "women") {
+		if (!slave.piercing.genitals.smart || ["off", "none", "all", "men", "women", "anti-men", "anti-women"].includes(slave.clitSetting)) {
 			if (canDoAnal(slave)) {
 				if (slave.vagina > -1 && !canDoVaginal(slave)) {
 					if (slave.fetishStrength <= 95) {
@@ -2072,6 +2056,7 @@ App.SlaveAssignment.longTermMentalEffects = (function() {
 					break;
 				case "boobs":
 					if (slave.sexualFlaw !== "breast growth") {
+						const boobSize = slave.boobs - slave.boobsImplant - slave.boobsMilk;
 						if (slave.drugs === "breast injections" || slave.drugs === "intensive breast injections") {
 							r.push(`${He} loves ${his} tits, and feeling them respond to drug injections starts to hold more fascination for ${him} than mere sex. <span class="paraphilia gain">${His} sexual identity is now dominated by ${his} swelling boobs.</span>`);
 							slave.sexualFlaw = "breast growth";
@@ -2224,4 +2209,4 @@ App.SlaveAssignment.longTermMentalEffects = (function() {
 			}
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saLongTermPhysicalEffects.js b/src/endWeek/saLongTermPhysicalEffects.js
index a5953a4509acde1d92ba3f62f16d906a8a75891f..909726a5b943c9a387df4cf9cc93675ecb4a91c4 100644
--- a/src/endWeek/saLongTermPhysicalEffects.js
+++ b/src/endWeek/saLongTermPhysicalEffects.js
@@ -1,97 +1,71 @@
-App.SlaveAssignment.longTermPhysicalEffects = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.longTermPhysicalEffects = function saLongTermPhysicalEffects(slave) {
+	const r = [];
 
-	let r;
+	const gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
+	const boobSize = slave.boobs - slave.boobsImplant - slave.boobsMilk;
+	const buttSize = slave.butt - slave.buttImplant;
+	const totalInt = slave.intelligence + slave.intelligenceImplant;
 
-	let he;
-	let him;
-	let his;
-	let hers;
-	let himself;
-	let girl;
-	let He;
-	let His;
+	const {
+		he, him, his, hers, himself, girl, He, His,
+	} = getPronouns(slave);
 
-	let gigantomastiaMod;
-	let rearQuirk;
-	let boobSize;
-	let buttSize;
-	let faceValue;
-	let slaveInt;
-
-	return saLongTermPhysicalEffects;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {string}
-	 */
-	function saLongTermPhysicalEffects(slave) {
-		r = [];
-
-		gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
-		rearQuirk = slave.geneticQuirks.rearLipedema === 2 ? 2 : 0;
-		boobSize = slave.boobs - slave.boobsImplant - slave.boobsMilk;
-		buttSize = slave.butt - slave.buttImplant;
-		faceValue = slave.face - slave.faceImplant;
-		slaveInt = slave.intelligence + slave.intelligenceImplant;
-
-		({
-			he, him, his, hers, himself, girl, He, His,
-		} = getPronouns(slave));
-
-		if (slave.fuckdoll > 0) {
-			fuckdollEffects(slave); // Moved up to follow the disability block that proceeds this function in LTE
-		}
-		teeth(slave);
-		if (V.weightAffectsAssets !== 0) {
-			weightAffectsAssets(slave);
-		}
-		if (slave.anus > 0 || slave.vagina > 2) {
-			holeRelaxation(slave);
-		}
-		malenessAdjustments(slave);
-		if ((slave.balls === 0 || slave.ballType === "sterile") && slave.ovaries === 0 && slave.mpreg === 0) {
-			noHormoneProduction(slave);
-		}
-		if (slave.vagina === -1 && slave.dick === 0) {
-			nullSexualFrustration(slave);
-		}
-		if (slave.fuckdoll === 0) {
-			adjustSexualAppetite(slave);
-		}
-		sexualSatisfaction(slave);
-		healthEffects(slave);
-		ageEffects(slave);
-		if (slave.geneMods.NCS === 1) {
-			NCSEffects(slave);
-		}
-		geneticQuirkEffects(slave);
-		boobsEffects(slave); // Moved up from middle of the mobility and oversized asset set of text.
-		bellyEffects(slave); // Moved up from middle of the mobility and oversized asset set of text.
-		if (slave.fuckdoll === 0) {
-			mobility(slave);
-			hugeBreasts(slave);
-			if (slave.fetish !== "mindbroken" && isSlaveAvailable(slave)) {
-				boobAccessibility(slave);
-			}
-		}
-		hugeBelly(slave);
-		if (slave.fuckdoll === 0) {
-			if (slave.fetish !== "mindbroken" && isSlaveAvailable(slave)) {
-				bellyAccessibility(slave);
-				hugeDick(slave);
-				dickAccessibility(slave);
-				hugeBalls(slave);
-				ballsAccessibility(slave);
-				hugeHips(slave);
-				hugeButt(slave);
-				buttAccessibility(slave);
-			}
-		}
-		healthBlips(slave);
-
-		return r.join(" ");
+	if (slave.fuckdoll > 0) {
+		fuckdollEffects(slave); // Moved up to follow the disability block that proceeds this function in LTE
+	}
+	teeth(slave);
+	if (V.weightAffectsAssets !== 0) {
+		weightAffectsAssets(slave);
 	}
+	if (slave.anus > 0 || slave.vagina > 2) {
+		holeRelaxation(slave);
+	}
+	malenessAdjustments(slave);
+	if ((slave.balls === 0 || slave.ballType === "sterile") && slave.ovaries === 0 && slave.mpreg === 0) {
+		noHormoneProduction(slave);
+	}
+	if (slave.vagina === -1 && slave.dick === 0) {
+		nullSexualFrustration(slave);
+	}
+	if (slave.fuckdoll === 0) {
+		adjustSexualAppetite(slave);
+	}
+	sexualSatisfaction(slave);
+	healthEffects(slave);
+	ageEffects(slave);
+	if (slave.geneMods.NCS === 1) {
+		NCSEffects(slave);
+	}
+	geneticQuirkEffects(slave);
+	boobsEffects(slave); // Moved up from middle of the mobility and oversized asset set of text.
+	bellyEffects(slave); // Moved up from middle of the mobility and oversized asset set of text.
+	if (slave.fuckdoll === 0) {
+		mobility(slave);
+		hugeBreasts(slave);
+		if (slave.fetish !== "mindbroken" && isSlaveAvailable(slave)) {
+			boobAccessibility(slave);
+		}
+	}
+	hugeBelly(slave);
+	if (slave.fuckdoll === 0) {
+		if (slave.fetish !== "mindbroken" && isSlaveAvailable(slave)) {
+			bellyAccessibility(slave);
+			hugeDick(slave);
+			dickAccessibility(slave);
+			hugeBalls(slave);
+			ballsAccessibility(slave);
+			hugeHips(slave);
+			hugeButt(slave);
+			buttAccessibility(slave);
+		}
+	}
+	healthBlips(slave);
+
+	return r.join(" ");
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
@@ -135,7 +109,7 @@ App.SlaveAssignment.longTermPhysicalEffects = (function() {
 			if (slave.fuckdoll === 0 && slave.fetish !== "mindbroken") {
 				if (slave.devotion <= 20) {
 					r.push(`${His} mouth full of orthodontia is quite uncomfortable,`);
-					if (slaveInt > 15) {
+					if (totalInt > 15) {
 						r.push(`but ${he} has the presence of mind to know that it's for ${his} own good, and ${he} doesn't blame you for it.`);
 					} else {
 						r.push(`and ${he}'s stupid enough to <span class="devotion dec">blame you</span> for the discomfort.`);
@@ -161,6 +135,7 @@ App.SlaveAssignment.longTermPhysicalEffects = (function() {
 					slave.teeth = "fangs";
 					r.push(`${His} baby teeth have fully grown into a pretty but intimidatingly sharp set of feline fangs.`);
 				} else {
+					const faceValue = slave.face - slave.faceImplant;
 					const crookedTeethGen = ((faceValue + 100) / 10);
 					if (random(0, crookedTeethGen) < 5) {
 						r.push(`Unfortunately,`);
@@ -186,13 +161,14 @@ App.SlaveAssignment.longTermPhysicalEffects = (function() {
 	 *
 	 */
 	function weightAffectsAssets(slave) {
-		let normBreasts;
-		let normButt;
-		let adj1;
-		let adj2;
-		let adj3;
 		if (slave.weight <= 10) {
 			if (slave.diet !== "fattening") {
+				const rearQuirk = slave.geneticQuirks.rearLipedema === 2 ? 2 : 0;
+				let normBreasts;
+				let normButt;
+				let adj1;
+				let adj2;
+				let adj3;
 				if (slave.hormoneBalance > 30 && slave.geneMods.NCS !== 1) { // 'Expected' breast size based on weight for feminine-bodied slaves
 					normBreasts = Math.trunc((100 + (slave.weight + 100) * 5 + 2 * slave.lactationAdaptation) * (0.85 + slave.hormoneBalance / 400) * gigantomastiaMod);
 					normButt = ((slave.weight + 100) * .025 * ( 0.9 + slave.hormoneBalance / 600) * ( rearQuirk / 2 + 1));
@@ -1425,7 +1401,7 @@ App.SlaveAssignment.longTermPhysicalEffects = (function() {
 							}
 						}
 						if (slave.counter.births > 100 && slave.devotion <= 20 && slave.trust <= 20) {
-							r.push(`Being constantly pregnant and giving birth to over a hundred offspring has taken its toll on ${slave.slaveName}'s mind. Feeling that ${he} is nothing more than a breeder has destroyed any hopes that ${he} had. ${slave.slaveName} has become <span class="mindbreak">completely broken,</span> leaving ${him} nothing more than a baby filled sack.`);
+							r.push(`Being constantly pregnant and giving birth to over a hundred offspring has taken its toll on ${slave.slaveName}'s mind. Feeling that ${he} is nothing more than a breeder has destroyed any hopes that ${he} had. ${slave.slaveName} has become <span class="mindbreak">completely broken,</span> leaving ${him} nothing more than a baby-filled sack.`);
 							slave.fetish = "mindbroken";
 							slave.sexualFlaw = "none";
 							slave.behavioralFlaw = "none";
@@ -2191,7 +2167,7 @@ App.SlaveAssignment.longTermPhysicalEffects = (function() {
 						r.push(`breath`);
 					}
 					r.push(`feels like it may be ${his} last. ${He} is <span class="trust dec">terrified</span> that at any moment ${his} body may fail causing ${him} to burst.`);
-					if (slave.pregControl === "slow gestation" && slaveInt >= -50) {
+					if (slave.pregControl === "slow gestation" && totalInt >= -50) {
 						r.push(`${His} slowed gestation rate gives ${his} body more time to adapt to ${his} gravidity, but given ${his} situation, it just means more suffering.`);
 						slave.devotion -= 15;
 						slave.trust -= 20;
@@ -2250,7 +2226,7 @@ App.SlaveAssignment.longTermPhysicalEffects = (function() {
 					} else {
 						r.push(`will become of ${him}.`);
 					}
-					if (slave.pregControl === "slow gestation" && slaveInt >= -50) {
+					if (slave.pregControl === "slow gestation" && totalInt >= -50) {
 						r.push(`${His} slowed gestation rate gives ${his} body more time to adapt to ${his} gravidity, but given ${his} situation, it isn't very comforting.`);
 						slave.devotion -= 7;
 						slave.trust -= 10;
@@ -2303,7 +2279,7 @@ App.SlaveAssignment.longTermPhysicalEffects = (function() {
 					} else {
 						r.push(`whenever ${he} is forced to move.`);
 					}
-					if (slave.pregControl === "slow gestation" && slaveInt >= -50) {
+					if (slave.pregControl === "slow gestation" && totalInt >= -50) {
 						r.push(`${His} slowed gestation rate gives ${his} body more time to adapt to ${his} gravidity, easing some of ${his} worries.`);
 						slave.devotion -= 3;
 					} else {
@@ -2343,7 +2319,7 @@ App.SlaveAssignment.longTermPhysicalEffects = (function() {
 					r.push(`Such discomforts are meaningless to ${his} broken mind.`);
 				} else {
 					r.push(`${He} is in constant <span class="devotion dec">discomfort</span> and can't wait for these children to be born.`);
-					if (slave.pregControl === "slow gestation" && slaveInt >= -50) {
+					if (slave.pregControl === "slow gestation" && totalInt >= -50) {
 						r.push(`${His} slowed gestation rate gives ${his} body more time to adapt to ${his} gravidity, easing some of ${his} worries.`);
 						slave.devotion -= 1;
 					} else {
@@ -2869,10 +2845,10 @@ App.SlaveAssignment.longTermPhysicalEffects = (function() {
 				r.push(`${His} butt has gotten absolutely enormous.`);
 				if (V.arcologies[0].FSAssetExpansionist !== "unset" && (slave.behavioralFlaw === "arrogant" || slave.behavioralQuirk === "confident")) {
 					if (slave.behavioralFlaw === "arrogant") {
-						r.push(`Your arcology glorifies asses as large as ${his}, <span class="trust inc">inflating ${his} ego</span> almost as large as ${his} rear.`);
+						r.push(`Your arcology glorifies asses as large as ${hers}, <span class="trust inc">inflating ${his} ego</span> almost as large as ${his} rear.`);
 						slave.trust += 2;
 					} else if (slave.behavioralQuirk === "confident") {
-						r.push(`Your arcology glorifies asses as large as ${his}, so the minor annoyances don't seem so bad.`);
+						r.push(`Your arcology glorifies asses as large as ${hers}, so the minor annoyances don't seem so bad.`);
 					}
 				} else if (slave.devotion <= 50) {
 					r.push(`${He} finds it a <span class="devotion dec">massive nuisance</span> to live with.`);
@@ -3006,4 +2982,4 @@ App.SlaveAssignment.longTermPhysicalEffects = (function() {
 			}
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saPleaseYou.js b/src/endWeek/saPleaseYou.js
index 395bcf4fd1c33baa416e91481a28375f98a83e8d..b5417ed2236bea804e81217369cc3028caec384e 100644
--- a/src/endWeek/saPleaseYou.js
+++ b/src/endWeek/saPleaseYou.js
@@ -1,91 +1,64 @@
-App.SlaveAssignment.pleaseYou = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.pleaseYou = function saPleaseYou(slave) {
+	/** @type {string[]} */
+	const r = [];
 
-	let r;
+	const {
+		he, him, his, himself, girl, He, His, wife
+	} = getPronouns(slave);
+	const playerPronouns = getPronouns(V.PC);
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let girl;
-	let He;
-	let His;
-	let wife;
-	let playerPronouns;
+	const fetishChange = fetishChangeChance(slave);
+	const arcology = V.arcologies[0];
+	const fuckSlavesCount = fuckSlavesLength();
+	const trainingEfficiency = 5 + Math.trunc(slave.devotion / 30) + ((slave.intelligence + slave.intelligenceImplant) / 32);
+	const canFuck = slave.rules.release.master !== 0;
 
-	let fetishChange;
-	let arcology;
-	let trainingEfficiency;
+	let oralUse = 0;
+	let analUse = 0;
+	let vaginalUse = 0;
+	let mammaryUse = 0;
+	let penetrativeUse = 0;
+	let cervixPump = 0;
+	let acts = 0;
 
-	let oralUse;
-	let analUse;
-	let vaginalUse;
-	let mammaryUse;
-	let penetrativeUse;
-	let cervixPump;
-	let acts;
-	let demand;
-
-	let fuckSlavesCount;
-
-	return saPleaseYou;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {string}
-	 */
-	function saPleaseYou(slave) {
-		r = [];
-		fetishChange = fetishChangeChance(slave);
-		arcology = V.arcologies[0];
-		fuckSlavesCount = fuckSlavesLength();
-
-		oralUse = 0;
-		analUse = 0;
-		vaginalUse = 0;
-		mammaryUse = 0;
-		penetrativeUse = 0;
-		cervixPump = 0;
-		acts = 0;
-
-		trainingEfficiency = 5 + Math.trunc(slave.devotion / 30) + ((slave.intelligence+slave.intelligenceImplant) / 32);
-
-		({
-			he, him, his, himself, girl, He, His, wife
-		} = getPronouns(slave));
-		playerPronouns = getPronouns(V.PC);
-
-		jobPreface(slave);
-		checkHoleAvailability(slave);
-		switch (slave.toyHole) {
-			case "pussy":
-				useVagina(slave);
-				break;
-			case "ass":
-				useAnus(slave);
-				break;
-			case "mouth":
-				useMouth(slave);
-				break;
-			case "boobs":
-				useBoobs(slave);
-				break;
-			case "dick":
-				useDick(slave);
-				break;
-			default:
-				useAllHoles(slave);
-		}
-		physicalEffects(slave);
-		const familyMult = familyBonus(slave);
-		addRep(slave, familyMult);
-		if (slave.fuckdoll === 0 && slave.fetish !== "mindbroken") {
-			mentalEffects(slave);
-		}
+	jobPreface(slave);
+	checkHoleAvailability(slave);
+	if (!canFuck) {
+		return useNone();
+	}
 
-		return r.join(" ");
+	switch (slave.toyHole) {
+		case "pussy":
+			useVagina(slave);
+			break;
+		case "ass":
+			useAnus(slave);
+			break;
+		case "mouth":
+			useMouth(slave);
+			break;
+		case "boobs":
+			useBoobs(slave);
+			break;
+		case "dick":
+			useDick(slave);
+			break;
+		default:
+			useAllHoles(slave);
+	}
+	physicalEffects(slave);
+	const familyMult = familyBonus(slave);
+	addRep(slave, familyMult);
+	if (slave.fuckdoll === 0 && slave.fetish !== "mindbroken") {
+		mentalEffects(slave);
 	}
 
+	return r.join(" ");
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 *
@@ -114,17 +87,38 @@ App.SlaveAssignment.pleaseYou = (function() {
 		}
 	}
 
+	function useNone() {
+		r.push(`Since you've decided not to fuck ${him}, ${he} has to`);
+
+		if (slave.devotion > 20) {
+			r.push(`be content with simply keeping you company${slave.assignment === Job.MASTERSUITE ? ` and warming your bed` : ``} for now.`);
+		} else if (slave.devotion > -50) {
+			r.push(`keep you company${slave.assignment === Job.MASTERSUITE ? ` and warm your bed at night` : ``}, a job ${he} doesn't mind too much.`);
+		} else {
+			r.push(`keep you company${slave.assignment === Job.MASTERSUITE ? ` and warm your bed at night` : ``}, a job ${he} loathes. Still, it could be worse – you could decide you want to fuck ${him} after all.`);
+		}
+
+		physicalEffects(slave);
+		const familyMult = familyBonus(slave);
+		addRep(slave, familyMult);
+		if (slave.fuckdoll === 0 && slave.fetish !== "mindbroken") {
+			mentalEffects(slave);
+		}
+
+		return r.join(' ');
+	}
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 *
 	 */
 	function useVagina(slave) {
 		if (fuckSlavesCount <= V.PC.sexualEnergy / 2) {
-			vaginalUse = jsRandom(21, 40);
+			vaginalUse = random(21, 40);
 		} else if (fuckSlavesCount <= V.PC.sexualEnergy) {
-			vaginalUse = jsRandom(7, 14);
+			vaginalUse = random(7, 14);
 		} else {
-			vaginalUse = jsRandom(3, 7);
+			vaginalUse = random(3, 7);
 		}
 		if (slave.assignment === Job.FUCKTOY) {
 			vaginalUse = Math.ceil(vaginalUse * restEffects(slave, 11));
@@ -233,7 +227,7 @@ App.SlaveAssignment.pleaseYou = (function() {
 							r.push(`${he} <span class="hotpink">seems to enjoy</span> being your fucktoy.`);
 						}
 						slave.devotion += 2;
-					} else if (fetishChange > jsRandom(0, 100)) {
+					} else if (fetishChange > random(0, 100)) {
 						slave.fetish = "submissive";
 						slave.fetishKnown = 1;
 						slave.fetishStrength = 10;
@@ -269,8 +263,7 @@ App.SlaveAssignment.pleaseYou = (function() {
 				knockMeUp(slave, vaginalUse, 0, -1);
 			}
 		}
-		slave.counter.vaginal += vaginalUse;
-		V.vaginalTotal += vaginalUse;
+		seX(slave, "vaginal", V.PC, "penetrative", vaginalUse);
 	}
 
 	/**
@@ -279,11 +272,11 @@ App.SlaveAssignment.pleaseYou = (function() {
 	 */
 	function useAnus(slave) {
 		if (fuckSlavesCount <= V.PC.sexualEnergy / 2) {
-			analUse = jsRandom(21, 40);
+			analUse = random(21, 40);
 		} else if (fuckSlavesCount <= V.PC.sexualEnergy) {
-			analUse = jsRandom(7, 14);
+			analUse = random(7, 14);
 		} else {
-			analUse = jsRandom(3, 7);
+			analUse = random(3, 7);
 		}
 		if (slave.assignment === Job.FUCKTOY) {
 			analUse = Math.ceil(analUse * restEffects(slave, 11));
@@ -393,7 +386,7 @@ App.SlaveAssignment.pleaseYou = (function() {
 						r.push(`${He} <span class="hotpink">seems to enjoy</span> anal sex more than the usual slave.`);
 					}
 					slave.devotion += 2;
-				} else if (fetishChange > jsRandom(0, 100)) {
+				} else if (fetishChange > random(0, 100)) {
 					slave.fetishKnown = 1;
 					slave.fetishStrength = 10;
 					slave.fetish = "buttslut";
@@ -422,8 +415,7 @@ App.SlaveAssignment.pleaseYou = (function() {
 				knockMeUp(slave, analUse, 1, -1);
 			}
 		}
-		slave.counter.anal += analUse;
-		V.analTotal += analUse;
+		seX(slave, "anal", V.PC, "penetrative", analUse);
 	}
 
 	/**
@@ -432,11 +424,11 @@ App.SlaveAssignment.pleaseYou = (function() {
 	 */
 	function useMouth(slave) {
 		if (fuckSlavesCount <= V.PC.sexualEnergy / 2) {
-			oralUse = jsRandom(21, 40);
+			oralUse = random(21, 40);
 		} else if (fuckSlavesCount <= V.PC.sexualEnergy) {
-			oralUse = jsRandom(7, 14);
+			oralUse = random(7, 14);
 		} else {
-			oralUse = jsRandom(3, 7);
+			oralUse = random(3, 7);
 		}
 		if (slave.assignment === Job.FUCKTOY) {
 			oralUse = Math.ceil(oralUse * restEffects(slave, 11));
@@ -642,7 +634,7 @@ App.SlaveAssignment.pleaseYou = (function() {
 						r.push(`${He} <span class="hotpink">seems to enjoy</span> ${his} role as a cum receptacle more than you'd expect.`);
 					}
 					slave.devotion += 2;
-				} else if (fetishChange > jsRandom(0, 100)) {
+				} else if (fetishChange > random(0, 100)) {
 					slave.fetishKnown = 1;
 					slave.fetishStrength = 10;
 					slave.fetish = "cumslut";
@@ -655,8 +647,6 @@ App.SlaveAssignment.pleaseYou = (function() {
 					r.push(`learning that giving <span class="lightcoral">blowjobs is a lot of fun.</span>`);
 				}
 			}
-			slave.counter.oral += oralUse;
-			V.oralTotal += oralUse;
 		} else {
 			r.push(`You keep ${him} with you all week, using ${him} as your personal sex toy`);
 			if (oralUse >= 14) {
@@ -673,9 +663,8 @@ App.SlaveAssignment.pleaseYou = (function() {
 				r.push(`stands`);
 			}
 			r.push(`nearby, waiting silently for your order to open ${his} mouth.`);
-			slave.counter.oral += oralUse;
-			V.oralTotal += oralUse;
 		}
+		seX(slave, "oral", V.PC, V.PC.dick > 0 ? "penetrative" : "vaginal", oralUse);
 	}
 
 	/**
@@ -684,11 +673,11 @@ App.SlaveAssignment.pleaseYou = (function() {
 	 */
 	function useBoobs(slave) {
 		if (fuckSlavesCount <= V.PC.sexualEnergy / 2) {
-			mammaryUse = jsRandom(21, 40);
+			mammaryUse = random(21, 40);
 		} else if (fuckSlavesCount <= V.PC.sexualEnergy) {
-			mammaryUse = jsRandom(7, 14);
+			mammaryUse = random(7, 14);
 		} else {
-			mammaryUse = jsRandom(3, 7);
+			mammaryUse = random(3, 7);
 		}
 		if (slave.assignment === Job.FUCKTOY) {
 			mammaryUse = Math.ceil(mammaryUse * restEffects(slave, 11));
@@ -853,7 +842,7 @@ App.SlaveAssignment.pleaseYou = (function() {
 						r.push(`fondled more than the average ${girl}.`);
 					}
 					slave.devotion += 2;
-				} else if (fetishChange > jsRandom(0, 100)) {
+				} else if (fetishChange > random(0, 100)) {
 					slave.fetishKnown = 1;
 					slave.fetishStrength = 10;
 					slave.fetish = "boobs";
@@ -893,8 +882,7 @@ App.SlaveAssignment.pleaseYou = (function() {
 		} else {
 			r.push(induceLactation(slave, 2));
 		}
-		slave.counter.mammary += mammaryUse;
-		V.mammaryTotal += mammaryUse;
+		seX(slave, "mammary", V.PC, "penetrative", mammaryUse);
 	}
 
 	/**
@@ -903,11 +891,11 @@ App.SlaveAssignment.pleaseYou = (function() {
 	 */
 	function useDick(slave) {
 		if (fuckSlavesCount <= V.PC.sexualEnergy / 2) {
-			penetrativeUse = jsRandom(21, 40);
+			penetrativeUse = random(21, 40);
 		} else if (fuckSlavesCount <= V.PC.sexualEnergy) {
-			penetrativeUse = jsRandom(7, 14);
+			penetrativeUse = random(7, 14);
 		} else {
-			penetrativeUse = jsRandom(3, 7);
+			penetrativeUse = random(3, 7);
 		}
 		if (slave.assignment === Job.FUCKTOY) {
 			penetrativeUse = Math.ceil(penetrativeUse * restEffects(slave, 11));
@@ -1155,8 +1143,7 @@ App.SlaveAssignment.pleaseYou = (function() {
 				slave.behavioralFlaw = "none";
 			}
 		}
-		slave.counter.penetrative += penetrativeUse;
-		V.penetrativeTotal += penetrativeUse;
+		seX(slave, "penetrative", V.PC, canDoVaginal(V.PC) ? "vaginal" : "anal", penetrativeUse);
 		if (canImpreg(V.PC, slave)) {
 			r.push(knockMeUp(V.PC, penetrativeUse, 0, slave.ID));
 		}
@@ -1168,7 +1155,26 @@ App.SlaveAssignment.pleaseYou = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
+	 */
+	function playerFuckAmountDescription(slave) {
+		r.push(`You have the sexual energy to fuck ${him}`);
+		if (fuckSlavesCount <= V.PC.sexualEnergy / 2) {
+			r.push(`several times a day; constant,`);
+			slave.devotion += 3;
+			slave.trust += 3;
+		} else if (fuckSlavesCount <= V.PC.sexualEnergy) {
+			r.push(`at least once a day; regular,`);
+			slave.devotion += 2;
+			slave.trust += 2;
+		} else {
+			r.push(`on occasion;`);
+			slave.devotion += 1;
+			slave.trust += 1;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
 	 */
 	function useAllHoles(slave) {
 		if (slave.fuckdoll > 0) {
@@ -1290,40 +1296,14 @@ App.SlaveAssignment.pleaseYou = (function() {
 			} else {
 				r.push(`${He} comes indecently hard whenever ${his} beloved ${getWrittenTitle(slave)} uses ${his} body.`);
 			}
-			r.push(`You have the sexual energy to fuck ${him}`);
-			if (fuckSlavesCount <= V.PC.sexualEnergy / 2) {
-				r.push(`several times a day; constant,`);
-				slave.devotion += 3;
-				slave.trust += 3;
-			} else if (fuckSlavesCount <= V.PC.sexualEnergy) {
-				r.push(`at least once a day; regular,`);
-				slave.devotion += 2;
-				slave.trust += 2;
-			} else {
-				r.push(`on occasion;`);
-				slave.devotion += 1;
-				slave.trust += 1;
-			}
+			playerFuckAmountDescription(slave);
 			r.push(`loving sex with you draws ${him} <span class="hotpink">closer to you</span> and encourages ${him} to <span class="mediumaquamarine">trust you.</span>`);
 		} else if (slave.devotion > 20) {
 			r.push(`Whenever you feel the need, you use whichever of ${his} available holes that appears most appealing at the moment, since ${he}'s up for anything.`);
 			if (slave.dick !== 0 && canAchieveErection(slave) && !slave.chastityPenis) {
 				r.push(`By the end of the week ${he} gets a hard-on when you use ${him}.`);
 			}
-			r.push(`You have the sexual energy to fuck ${him}`);
-			if (fuckSlavesCount <= V.PC.sexualEnergy / 2) {
-				r.push(`several times a day; constant,`);
-				slave.devotion += 3;
-				slave.trust += 3;
-			} else if (fuckSlavesCount <= V.PC.sexualEnergy) {
-				r.push(`at least once a day; regular,`);
-				slave.devotion += 2;
-				slave.trust += 2;
-			} else {
-				r.push(`on occasion;`);
-				slave.devotion += 1;
-				slave.trust += 1;
-			}
+			playerFuckAmountDescription(slave);
 			r.push(`enjoyable sex with you draws ${him} <span class="hotpink">closer to you</span> and encourages ${him} to <span class="mediumaquamarine">trust you.</span>`);
 		} else if (slave.trust < -20) {
 			r.push(`${He} is afraid of you and does ${his} best to offer you ${his}`);
@@ -1394,11 +1374,11 @@ App.SlaveAssignment.pleaseYou = (function() {
 		}
 
 		if (fuckSlavesCount <= V.PC.sexualEnergy / 2) {
-			acts = jsRandom(21, 40);
+			acts = random(21, 40);
 		} else if (fuckSlavesCount <= V.PC.sexualEnergy) {
-			acts = jsRandom(7, 14);
+			acts = random(7, 14);
 		} else {
-			acts = jsRandom(3, 7);
+			acts = random(3, 7);
 		}
 		if (slave.assignment === Job.FUCKTOY) {
 			acts = Math.ceil(acts * restEffects(slave, 11));
@@ -1412,23 +1392,15 @@ App.SlaveAssignment.pleaseYou = (function() {
 		if (canDoVaginal(slave) && slave.vagina > 0) {
 			vaginalUse = 1;
 		}
-		mammaryUse = jsRandom(0, 1);
+		mammaryUse = random(0, 1);
 		if (slave.nipples === "fuckable") {
 			mammaryUse = 1;
 		}
-		demand = oralUse + analUse + vaginalUse + mammaryUse;
+		const demand = oralUse + analUse + vaginalUse + mammaryUse;
 		oralUse = Math.trunc((oralUse / demand) * acts);
 		analUse = Math.trunc((analUse / demand) * acts);
 		vaginalUse = Math.trunc((vaginalUse / demand) * acts);
 		mammaryUse = Math.trunc((mammaryUse / demand) * acts);
-		slave.counter.oral += oralUse;
-		V.oralTotal += oralUse;
-		slave.counter.anal += analUse;
-		V.analTotal += analUse;
-		slave.counter.vaginal += vaginalUse;
-		V.vaginalTotal += vaginalUse;
-		slave.counter.mammary += mammaryUse;
-		V.mammaryTotal += mammaryUse;
 
 		if (slave.fuckdoll === 0) {
 			if (slave.fetish !== "mindbroken") {
@@ -1458,6 +1430,11 @@ App.SlaveAssignment.pleaseYou = (function() {
 				slave.boobsMilk = 0;
 			}
 		}
+
+		seX(slave, "vaginal", V.PC, "penetrative", vaginalUse);
+		seX(slave, "anal", V.PC, "penetrative", analUse);
+		seX(slave, "oral", V.PC, V.PC.dick > 0 ? "penetrative" : "vaginal", oralUse);
+		seX(slave, "mammary", V.PC, "penetrative", mammaryUse);
 	}
 
 	/**
@@ -1497,13 +1474,17 @@ App.SlaveAssignment.pleaseYou = (function() {
 			} else if (slave.health.tired > 60) {
 				r.push(`fatigued,`);
 			}
-			if (slave.health.illness !== 0) {
-				r.push(`</span> making ${him} rather unappealing to use.`);
+			if (!canFuck) {
+				r.push(`though the fact that ${his} job isn't very strenuous helps.`);
 			} else {
-				r.push(`</span> making ${him} less enjoyable to fuck.`);
+				if (slave.health.illness !== 0) {
+					r.push(`</span> making ${him} rather unappealing to use.`);
+				} else {
+					r.push(`</span> making ${him} less enjoyable to fuck.`);
+				}
 			}
 		}
-		if (slave.health.condition < 0 && jsRandom(1, 100) > 50) {
+		if (slave.health.condition < 0 && random(1, 100) > 50) {
 			r.push(`Under your personal supervision, <span class="health inc">${his} health improves.</span>`);
 			improveCondition(slave, 10);
 		}
@@ -1630,7 +1611,7 @@ App.SlaveAssignment.pleaseYou = (function() {
 		const isFucktoy = (s) => [Job.CONCUBINE, Job.MASTERSUITE, Job.FUCKTOY].includes(s.assignment);
 
 		if (areRelated(V.PC, slave)) {
-			r.push(`Keeping your own ${relativeTerm(V.PC, slave)} as a personal fucktoy leaves quite a public impression.`);
+			r.push(`Keeping your own ${relativeTerm(V.PC, slave)} as a personal ${canFuck ? `fucktoy` : `bedwarmer`} leaves quite a public impression.`);
 			multiplier += 0.01; // 1% base
 			if (V.arcologies[0].FSEgyptianRevivalist !== "unset" || V.arcologies[0].FSEgyptianRevivalistIncestPolicy === 1) {
 				multiplier += 0.04; // 5% if such behavior aligns with your societal goals
@@ -1720,7 +1701,9 @@ App.SlaveAssignment.pleaseYou = (function() {
 		repX(Math.trunc(( Beauty(slave) * FResult(slave) ) * multiplier / 4), "fucktoy", slave);
 
 		r.push(`Keeping ${him} as nothing but your personal`);
-		if (slave.toyHole === "pussy") {
+		if (!canFuck) {
+			r.push(`bedwarmer and arm candy`);
+		} else if (slave.toyHole === "pussy") {
 			r.push(`pussy toy`);
 		} else if (slave.toyHole === "ass") {
 			r.push(`anal toy`);
@@ -1776,20 +1759,20 @@ App.SlaveAssignment.pleaseYou = (function() {
 	 */
 	function mentalEffects(slave) {
 		if (slave.behavioralQuirk === "confident") {
-			r.push(`${slave.slaveName} <span class="mediumaquamarine">confidently enjoys</span> the prestige within the slave hierarchy that comes with being your fucktoy.`);
+			r.push(`${slave.slaveName} <span class="mediumaquamarine">confidently enjoys</span> the prestige within the slave hierarchy that comes with being your ${canFuck ? `fucktoy` : `arm candy`}.`);
 			slave.trust += 1;
 		} else if (slave.behavioralQuirk === "insecure") {
-			r.push(`${slave.slaveName} <span class="mediumaquamarine">constantly reassures ${himself}</span> that ${he} must be pretty, since you keep ${him} as a fucktoy.`);
+			r.push(`${slave.slaveName} <span class="mediumaquamarine">constantly reassures ${himself}</span> that ${he} must be pretty, since you keep ${him} as ${canFuck ? `a fucktoy` : `arm candy`}.`);
 			slave.trust += 1;
 		}
 		if (slave.behavioralQuirk === "adores men") {
 			if (V.PC.dick !== 0) {
-				r.push(`${slave.slaveName} <span class="hotpink">adores your company,</span> and is happy to spend time with you, even when you don't have your cock in ${him}.`);
+				r.push(`${slave.slaveName} <span class="hotpink">adores your company,</span> and is happy to spend time with you, even ${canFuck ? `when` : `if`} you don't have your cock in ${him}.`);
 				slave.devotion += 1;
 			}
 		} else if (slave.behavioralQuirk === "adores women") {
 			if (V.PC.vagina !== -1) {
-				r.push(`${slave.slaveName} <span class="hotpink">adores your company,</span> and is happy to spend time with you, even when you aren't fucking.`);
+				r.push(`${slave.slaveName} <span class="hotpink">adores your company,</span> and is happy to spend time with you, even ${canFuck ? `when` : `if`} you aren't fucking.`);
 				slave.devotion += 1;
 			}
 		} else if (slave.sexualQuirk === "romantic") {
@@ -1806,11 +1789,11 @@ App.SlaveAssignment.pleaseYou = (function() {
 				r.push(`Being tasked with servicing a lusty pregnant ${playerPronouns.woman} <span class="lightcoral">strengthens ${his} pregnancy fetish.</span>`);
 				slave.fetishStrength += 4;
 			}
-		} else if (fetishChange > jsRandom(0, 100) && (V.PC.preg >= 20 || (V.PC.preg >= 16 && V.PC.career === "escort"))) {
+		} else if (fetishChange > random(0, 100) && (V.PC.preg >= 20 || (V.PC.preg >= 16 && V.PC.career === "escort"))) {
 			r.push(`At first ${he} found the prospect of being used by ${his} increasingly pregnant ${getWrittenTitle(slave)} a turn off, but being so close to your gravid form serves to be more erotic than ${he} anticipated. Soon ${he} finds ${himself} aroused less from the prospect of sex and more <span class="lightcoral">the chance to be near your child laden belly.</span>`);
 			slave.fetish = "pregnancy";
 			slave.fetishKnown = 1;
 			slave.fetishStrength = 10;
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saPorn.js b/src/endWeek/saPorn.js
index 0e301e3407e633ba178debff9ce765859941b841..246dd03b18271fc20704997010d1b765182c4464 100644
--- a/src/endWeek/saPorn.js
+++ b/src/endWeek/saPorn.js
@@ -1,90 +1,78 @@
-App.SlaveAssignment.porn = (function() {
-	"use strict";
-
-	let r;
-	let he;
-	let him;
-	let his;
-	let himself;
-	let He;
-	let His;
-	let decayRate;
-	let viewership;
-	let viewerSoaking;
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.porn = function saPorn(slave) {
+	const {
+		he, him, his, himself, He, His
+	} = getPronouns(slave);
 
-	return saPorn;
+	let r = ` `;
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @returns {string}
-	 */
-	function saPorn(slave) {
-		({
-			he, him, his, himself, He, His
-		} = getPronouns(slave));
+	const oldFame = slave.porn.viewerCount;
 
-		r = ` `;
+	let decayRate;
+	let viewership;
+	let viewerSoaking;
 
-		let oldFame = slave.porn.viewerCount;
+	if (V.studio === 1 && slave.porn.feed === 1) {
+		viewerSoaking = 0;
 
-		if (V.studio === 1 && slave.porn.feed === 1) {
-			viewerSoaking = 0;
+		calcBaseViewership(slave);
 
-			calcBaseViewership(slave);
+		r += `The studio regularly releases clips of ${his} daily affairs. `;
+		if (V.cheatMode === 1) {
+			r += `(Decay: ${decayRate} Viewership: ${viewership} Last week's fame: ${oldFame}) `;
+		}
 
-			r += `The studio regularly releases clips of ${his} daily affairs. `;
-			if (V.cheatMode === 1) {
-				r += `(Decay: ${decayRate} Viewership: ${viewership} Last week's fame: ${oldFame}) `;
+		prestigeCommentary(slave);
+		faceCommentary(slave);
+		hack();
+
+		allGenreViews(slave);
+		updateViewerCount(slave);
+		if (oldFame > slave.porn.viewerCount) {
+			r += `Overall, ${his} online fame <span class="red">dropped</span> this week. `;
+		} else if (oldFame < slave.porn.viewerCount) {
+			r += `Overall, ${his} online fame <span class="green">rose</span> this week. `;
+			if (oldFame < 100 && slave.porn.viewerCount >= 100 && V.studioFeed === 1) {
+				r += `${He} <span class="yellow">has accrued enough views to determine prospective porn genres.</span> `;
 			}
+		} else if (slave.porn.viewerCount !== 0) {
+			r += `Surprisingly, ${his} online fame <span class="yellow">remained consistent</span> this week despite how fickle watchers can be. `;
+		} else {
+			r += `${He} went <span class="red">completely overlooked</span> this week and failed to gain any hits at all. `;
+		}
 
-			prestigeCommentary(slave);
-			faceCommentary(slave);
-			hack();
-
-			allGenreViews(slave);
-			updateViewerCount(slave);
-			if (oldFame > slave.porn.viewerCount) {
-				r += `Overall, ${his} online fame <span class="red">dropped</span> this week. `;
-			} else if (oldFame < slave.porn.viewerCount) {
-				r += `Overall, ${his} online fame <span class="green">rose</span> this week. `;
-				if (oldFame < 100 && slave.porn.viewerCount >= 100 && V.studioFeed === 1) {
-					r += `${He} <span class="yellow">has accrued enough views to determine prospective porn genres.</span> `;
-				}
-			} else if (slave.porn.viewerCount !== 0) {
-				r += `Surprisingly, ${his} online fame <span class="yellow">remained consistent</span> this week despite how fickle watchers can be. `;
-			} else {
-				r += `${He} went <span class="red">completely overlooked</span> this week and failed to gain any hits at all. `;
+		if (slave.porn.viewerCount > 0) {
+			let donations = Math.floor(slave.porn.viewerCount / jsRandom(10, 15 + viewerSoaking));
+			if (donations > 0) {
+				r += `Fans donated a total of <span class="cash inc">${cashFormat(donations)}</span> to ${his} account this week. `;
+				cashX(donations, "porn", slave);
 			}
+		}
+		if (slave.porn.spending > 0) {
+			cashX(forceNeg(slave.porn.spending / V.PCSlutContacts), "porn", slave);
+		}
 
-			if (slave.porn.viewerCount > 0) {
-				let donations = Math.floor(slave.porn.viewerCount / jsRandom(10, 15 + viewerSoaking));
-				if (donations > 0) {
-					r += `Fans donated a total of <span class="cash inc">${cashFormat(donations)}</span> to ${his} account this week. `;
-					cashX(donations, "porn", slave);
-				}
-			}
-			if (slave.porn.spending > 0) {
-				cashX(forceNeg(slave.porn.spending / V.PCSlutContacts), "porn", slave);
-			}
+		prestigeGen(slave);
+	} else { /* popularity decay from lack of new content */
+		if (slave.porn.prestige > 1) { // 500k
+			decayRate = 5000;
+		} else if (slave.porn.prestige > 0) { // 10k
+			decayRate = 500;
+		} else {
+			decayRate = 30;
+		}
 
-			prestigeGen(slave);
-		} else { /* popularity decay from lack of new content */
-			if (slave.porn.prestige > 1) { // 500k
-				decayRate = 5000;
-			} else if (slave.porn.prestige > 0) { // 10k
-				decayRate = 500;
-			} else {
-				decayRate = 30;
-			}
+		genreDecay(slave);
+		updateViewerCount(slave);
 
-			genreDecay(slave);
-			updateViewerCount(slave);
+		prestigeDecay(slave);
+	}
 
-			prestigeDecay(slave);
-		}
+	return r;
 
-		return r;
-	}
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
@@ -378,4 +366,4 @@ App.SlaveAssignment.porn = (function() {
 			}
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saPregnancy.js b/src/endWeek/saPregnancy.js
index ff59538e4f944fc12e47d72c011f43d255036708..27fb4cbede5f774f05e7e14dd15a3800758d6cc3 100644
--- a/src/endWeek/saPregnancy.js
+++ b/src/endWeek/saPregnancy.js
@@ -1,55 +1,29 @@
-App.SlaveAssignment.pregnancy = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.pregnancy = function saPregnancy(slave) {
+	/** @type {string[]} */
+	const r = [];
 
-	let r;
+	const gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
+	const rearQuirk = slave.geneticQuirks.rearLipedema === 2 ? 2 : 0;
+	const uterineHypersensitivityMod = slave.geneticQuirks.uterineHypersensitivity === 2 ? 2 : 1;
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let girl;
-	let He;
-	let His;
-	let wife;
+	const {
+		he, him, his, himself, girl, He, His, wife
+	} = getPronouns(slave);
 
-	let gigantomastiaMod;
-	let rearQuirk;
-	let uterineHypersensitivityMod;
-	let boobSize;
-	let buttSize;
-	let hipSize;
-
-	return saPregnancy;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {string}
-	 */
-	function saPregnancy(slave) {
-		r = [];
-
-		gigantomastiaMod = slave.geneticQuirks.gigantomastia === 2 ? (slave.geneticQuirks.macromastia === 2 ? 3 : 2) : 1;
-		rearQuirk = slave.geneticQuirks.rearLipedema === 2 ? 2 : 0;
-		uterineHypersensitivityMod = slave.geneticQuirks.uterineHypersensitivity === 2 ? 2 : 1;
-		boobSize = slave.boobs - slave.boobsImplant - slave.boobsMilk;
-		buttSize = slave.butt - slave.buttImplant;
-		hipSize = slave.hips - slave.hipsImplant;
-
-		({
-			he, him, his, himself, girl, He, His, wife
-		} = getPronouns(slave));
-
-		if (slave.preg > 0) {
-			pregnancyEffects(slave);
-		}
-		if (V.seePreg !== 0) {
-			preconception(slave);
-			pregnancySanityCheck(slave);
-		}
-
-		return r.join(" ");
+	if (slave.preg > 0) {
+		pregnancyEffects(slave);
+	}
+	if (V.seePreg !== 0) {
+		preconception(slave);
+		pregnancySanityCheck(slave);
 	}
 
+	return r.join(" ");
+
 	/**
 	 * @param {FC.ReportSlave} slave
 	 *
@@ -107,9 +81,21 @@ App.SlaveAssignment.pregnancy = (function() {
 		}
 	}
 
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function slowLibidoIncrease(slave) {
+		if (slave.preg > slave.pregData.normalBirth / 4) {
+			r.push(`${His} new pregnancy excites ${him} and produces <span class="libido inc">very slow improvement in ${his} sexual appetite.</span>`);
+			slave.energy += 1;
+		} else if (slave.preg <= slave.pregData.normalBirth / 4 && slave.preg > slave.pregData.normalBirth / 13.33) {
+			r.push(`The rigors of early pregnancy do not seem to decrease ${his} sex drive. If anything, it seems to be exciting ${him}.`);
+		}
+	}
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
 	 */
 	function pregnancyLibido(slave) {
 		if (slave.geneticQuirks.uterineHypersensitivity === 2 && V.geneticMappingUpgrade >= 1) {
@@ -122,11 +108,8 @@ App.SlaveAssignment.pregnancy = (function() {
 			} else if (slave.preg > slave.pregData.normalBirth / 2) {
 				r.push(`Being pregnant with uterine hypersensitivity confers a <span class="libido inc">slow improvement in ${his} sexual appetite.</span>`);
 				slave.energy += 3;
-			} else if (slave.preg > slave.pregData.normalBirth / 4) {
-				r.push(`${His} new pregnancy excites ${him} and produces <span class="libido inc">very slow improvement in ${his} sexual appetite.</span>`);
-				slave.energy += 1;
-			} else if (slave.preg <= slave.pregData.normalBirth / 4 && slave.preg > slave.pregData.normalBirth / 13.33) {
-				r.push(`The rigors of early pregnancy do not seem to decrease ${his} sex drive. If anything, it seems to be exciting ${him}.`);
+			} else {
+				slowLibidoIncrease(slave);
 			}
 		} else if (slave.fetish === "pregnancy" && slave.fetishKnown === 1) {
 			if (slave.preg >= slave.pregData.normalBirth) {
@@ -138,11 +121,8 @@ App.SlaveAssignment.pregnancy = (function() {
 			} else if (slave.preg > slave.pregData.normalBirth / 2) {
 				r.push(`Being a pregnancy fetishist and pregnant confers a <span class="libido inc">slow improvement in ${his} sexual appetite.</span>`);
 				slave.energy += 2;
-			} else if (slave.preg > slave.pregData.normalBirth / 4) {
-				r.push(`${His} new pregnancy excites ${him} and produces <span class="libido inc">very slow improvement in ${his} sexual appetite.</span>`);
-				slave.energy += 1;
-			} else if (slave.preg <= slave.pregData.normalBirth / 4 && slave.preg > slave.pregData.normalBirth / 13.33) {
-				r.push(`The rigors of early pregnancy do not seem to decrease ${his} sex drive. If anything, it seems to be exciting ${him}.`);
+			} else {
+				slowLibidoIncrease(slave);
 			}
 		} else if (slave.fetish === "pregnancy") {
 			if (slave.preg >= slave.pregData.normalBirth) {
@@ -154,11 +134,8 @@ App.SlaveAssignment.pregnancy = (function() {
 			} else if (slave.preg > slave.pregData.normalBirth / 2) {
 				r.push(`Being pregnant confers a <span class="libido inc">slow improvement in ${his} sexual appetite.</span>`);
 				slave.energy += 2;
-			} else if (slave.preg > slave.pregData.normalBirth / 4) {
-				r.push(`${His} new pregnancy excites ${him} and produces <span class="libido inc">very slow improvement in ${his} sexual appetite.</span>`);
-				slave.energy += 1;
-			} else if (slave.preg <= slave.pregData.normalBirth / 4 && slave.preg > slave.pregData.normalBirth / 13.33) {
-				r.push(`The rigors of early pregnancy do not seem to decrease ${his} sex drive. If anything, it seems to be exciting ${him}.`);
+			} else {
+				slowLibidoIncrease(slave);
 			}
 			if (slave.preg > slave.pregData.normalBirth / 13.33) {
 				if (slave.fetish === "pregnancy") {
@@ -176,11 +153,8 @@ App.SlaveAssignment.pregnancy = (function() {
 			} else if (slave.preg > slave.pregData.normalBirth / 2) {
 				r.push(`Being pregnant confers a <span class="libido inc">slow improvement in ${his} sexual appetite.</span>`);
 				slave.energy += 3;
-			} else if (slave.preg > slave.pregData.normalBirth / 4) {
-				r.push(`${His} new pregnancy excites ${him} and produces <span class="libido inc">very slow improvement in ${his} sexual appetite.</span>`);
-				slave.energy += 1;
-			} else if (slave.preg <= slave.pregData.normalBirth / 4 && slave.preg > slave.pregData.normalBirth / 13.33) {
-				r.push(`The rigors of early pregnancy do not seem to decrease ${his} sex drive. If anything, it seems to be exciting ${him}.`);
+			} else {
+				slowLibidoIncrease(slave);
 			}
 		} else { // not pregnancy fetish
 			if (slave.energy < 41) {
@@ -508,7 +482,7 @@ App.SlaveAssignment.pregnancy = (function() {
 				break;
 		}
 		if (isInduced(slave)) {
-			r.push(`${His} child${slave.pregType > 1 ? "ren visibly shift" : "visibly shifts"} within ${his} womb as ${slave.pregType > 1 ? "they prepare" : "it prepares"} to enter the world. ${He} experiences several`);
+			r.push(`${His} child${slave.pregType > 1 ? "ren visibly shift" : " visibly shifts"} within ${his} womb as ${slave.pregType > 1 ? "they prepare" : "it prepares"} to enter the world. ${He} experiences several`);
 			if (slave.geneticQuirks.uterineHypersensitivity === 2) {
 				r.push(`unexpected orgasms,`);
 			} else {
@@ -695,6 +669,9 @@ App.SlaveAssignment.pregnancy = (function() {
 		}
 		boobTarget *= gigantomastiaMod;
 		if (slave.geneMods.NCS === 0) {
+			const boobSize = slave.boobs - slave.boobsImplant - slave.boobsMilk;
+			const buttSize = slave.butt - slave.buttImplant;
+			const hipSize = slave.hips - slave.hipsImplant;
 			if (slave.pregType >= 30 && (((slave.assignment === "be your Concubine" || slave.assignment === "serve in the master suite") && V.masterSuitePregnancySlaveLuxuries === 1) || slave.diet === "high caloric")) {
 				if (slave.weight <= 65) {
 					r.push(`${He} has <span class="change positive">gained weight</span> in order to better sustain ${himself} and ${his} children.`);
@@ -845,7 +822,52 @@ App.SlaveAssignment.pregnancy = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
+	 */
+	function addRapeFlaw(slave) {
+		if (slave.sexualFlaw === "none") {
+			r.push(`This unpleasant interlude leaves ${him} <span class="flaw gain">hating penetration</span> of ${his} violated`);
+			if (slave.mpreg === 1) {
+				r.push(`anus.`);
+				slave.sexualFlaw = "hates anal";
+			} else {
+				r.push(`pussy.`);
+				slave.sexualFlaw = "hates penetration";
+			}
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @returns {boolean}
+	 */
+	function pcCanKnockUpSlave(slave) {
+		return canImpreg(slave, V.PC) &&
+			(
+				(slave.toyHole === "all her holes" && slave.mpreg !== 1 && slave.vagina > 0) ||
+				(slave.toyHole === "all her holes" && slave.mpreg === 1 && slave.anus > 0) ||
+				(slave.toyHole === "pussy" && slave.mpreg !== 1) ||
+				(slave.toyHole === "ass" && slave.mpreg === 1)
+			);
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function pcDoKnockUpSlave(slave) {
+		if (slave.pregKnown === 0) {
+			r.push(`You frequently avail yourself to ${his} fertile`);
+			if (slave.mpreg === 1) {
+				r.push(`ass.`);
+			} else {
+				r.push(`pussy.`);
+			}
+			r.push(`It's no surprise when <span class="pregnant">${he} ends up pregnant with your child.</span>`);
+		}
+		knockMeUp(slave, 100, 2, -1);
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
 	 */
 	function impregnation(slave) {
 		const conceptionSeed = random(1, 100);
@@ -916,8 +938,7 @@ App.SlaveAssignment.pregnancy = (function() {
 			// Skip virgins.
 		} else if (V.HeadGirlID !== 0 && slave.ID !== V.HeadGirlID && V.universalRulesImpregnation === "HG" && canPenetrate(S.HeadGirl) && slave.pregKnown === 0) {
 			const {
-				// eslint-disable-next-line no-unused-vars
-				He2, he2, His2, his2, hers2, him2, himself2, girl2
+				he2, His2, his2, him2,
 			} = getPronouns(S.HeadGirl).appendSuffix('2');
 			if (slave.HGExclude === 1) {
 				r.push(`It's ${S.HeadGirl.slaveName}'s responsibility to impregnate fertile slaves, but your Head Girl is forbidden from impregnating ${slave.slaveName}.`);
@@ -967,16 +988,7 @@ App.SlaveAssignment.pregnancy = (function() {
 							r.push(`${slave.slaveName} tries to resist ${him2}, so ${S.HeadGirl.slaveName} is forced to <span class="devotion dec">rape the poor ${girl}</span> pregnant, regularly ejaculating inside ${him} until <span class="pregnant">conception</span> is confirmed.`);
 							slave.devotion -= 4;
 						}
-						if (slave.sexualFlaw === "none") {
-							r.push(`This unpleasant interlude leaves ${him} <span class="flaw gain">hating penetration</span> of ${his} violated`);
-							if (slave.mpreg === 1) {
-								r.push(`anus.`);
-								slave.sexualFlaw = "hates anal";
-							} else {
-								r.push(`pussy.`);
-								slave.sexualFlaw = "hates penetration";
-							}
-						}
+						addRapeFlaw(slave);
 					} else if (slave.devotion <= 20) {
 						if ((S.HeadGirl.fetish === "sadist" || S.HeadGirl.fetish === "dom") && S.HeadGirl.fetishStrength > 60) {
 							r.push(`${His2} interest is piqued, however, when it becomes clear that ${slave.slaveName}, though fearfully obedient, is not happy with being bred. ${S.HeadGirl.slaveName} <span class="devotion inc">enthusiastically</span> ensures that ${his2} victim <span class="devotion dec">does not enjoy</span> a week of being <span class="pregnant">raped pregnant.</span>`);
@@ -986,16 +998,7 @@ App.SlaveAssignment.pregnancy = (function() {
 							r.push(`${slave.slaveName}, though fearfully obedient, is not happy with being bred, but ${S.HeadGirl.slaveName} <span class="devotion dec">rapes the poor ${girl}</span> pregnant anyway, regularly ejaculating inside ${him} until <span class="pregnant">conception</span> is confirmed.`);
 							slave.devotion -= 2;
 						}
-						if (slave.sexualFlaw === "none") {
-							r.push(`This unpleasant interlude leaves ${him} <span class="flaw gain">hating penetration</span> of ${his} violated`);
-							if (slave.mpreg === 1) {
-								r.push(`anus.`);
-								slave.sexualFlaw = "hates anal";
-							} else {
-								r.push(`pussy.`);
-								slave.sexualFlaw = "hates penetration";
-							}
-						}
+						addRapeFlaw(slave);
 					} else if (slave.devotion < 75) {
 						if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
 							if (slave.fetishKnown === 1) {
@@ -1049,8 +1052,7 @@ App.SlaveAssignment.pregnancy = (function() {
 			}
 		} else if (Stud && slave.ID !== V.StudID && V.universalRulesImpregnation === "Stud" && slave.pregKnown === 0) {
 			const {
-				// eslint-disable-next-line no-unused-vars
-				He2, he2, His2, his2, hers2, him2, himself2, girl2
+				He2, he2, his2, him2, himself2,
 			} = getPronouns(Stud).appendSuffix('2');
 			if ((slave.StudExclude === 1 || slave.breedingMark === 1) && (Stud.career !== "a breeding bull" || Stud.fetish !== "mindbroken" || !canMove(Stud))) {
 				r.push(`It's ${Stud.slaveName}'s role to provide sperm for fertile slaves, but ${slave.slaveName} is not included on the list.`);
@@ -1569,16 +1571,7 @@ App.SlaveAssignment.pregnancy = (function() {
 					}
 				}
 				if (rapeAddsFlaw) {
-					if (slave.sexualFlaw === "none") {
-						r.push(`This unpleasant interlude leaves ${him} <span class="flaw gain">hating penetration</span> of ${his} violated`);
-						if (slave.mpreg === 1) {
-							r.push(`anus.`);
-							slave.sexualFlaw = "hates anal";
-						} else {
-							r.push(`pussy.`);
-							slave.sexualFlaw = "hates penetration";
-						}
-					}
+					addRapeFlaw(slave);
 				}
 				App.EndWeek.saVars.StudCum -= 1;
 				knockMeUp(slave, 100, 2, V.StudID);
@@ -1625,17 +1618,8 @@ App.SlaveAssignment.pregnancy = (function() {
 					}
 					break;
 				case "serve in the master suite":
-					if (canImpreg(slave, V.PC) && ((slave.toyHole === "all her holes" && slave.mpreg !== 1 && slave.vagina > 0) || (slave.toyHole === "all her holes" && slave.mpreg === 1 && slave.anus > 0) || (slave.toyHole === "pussy" && slave.mpreg !== 1) || (slave.mpreg === 1 && slave.toyHole === "ass"))) {
-						if (slave.pregKnown === 0) {
-							r.push(`You frequently avail yourself to ${his} fertile`);
-							if (slave.mpreg === 1) {
-								r.push(`ass.`);
-							} else {
-								r.push(`pussy.`);
-							}
-							r.push(`It's no surprise when <span class="pregnant">${he} ends up pregnant with your child.</span>`);
-						}
-						knockMeUp(slave, 100, 2, -1);
+					if (pcCanKnockUpSlave(slave)) {
+						pcDoKnockUpSlave(slave);
 					} else { // look for a random father among master suite slaves
 						const msSlaves = V.slaves.filter((s) => s.assignment === "serve in the master suite").shuffle();
 						for (const msSlave of msSlaves) {
@@ -1657,17 +1641,8 @@ App.SlaveAssignment.pregnancy = (function() {
 					}
 					break;
 				case "please you":
-					if (canImpreg(slave, V.PC) && ((slave.toyHole === "all her holes" && slave.mpreg !== 1 && slave.vagina > 0) || (slave.toyHole === "all her holes" && slave.mpreg === 1 && slave.anus > 0) || (slave.toyHole === "pussy" && slave.mpreg !== 1) || (slave.mpreg === 1 && slave.toyHole === "ass"))) {
-						if (slave.pregKnown === 0) {
-							r.push(`You frequently avail yourself to ${his} fertile`);
-							if (slave.mpreg === 1) {
-								r.push(`ass.`);
-							} else {
-								r.push(`pussy.`);
-							}
-							r.push(`It's no surprise when <span class="pregnant">${he} ends up pregnant with your child.</span>`);
-						}
-						knockMeUp(slave, 100, 2, -1);
+					if (pcCanKnockUpSlave(slave)) {
+						pcDoKnockUpSlave(slave);
 					}
 					break;
 				case "serve in the club":
@@ -1819,4 +1794,4 @@ App.SlaveAssignment.pregnancy = (function() {
 			slave.readyOva = 0;
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saRecruitGirls.js b/src/endWeek/saRecruitGirls.js
index 499ca81dc6e2cc0c938a11c8ffe30d90ae1d248f..21a2a1c507c0a955c48e04d28d24f6b7608c2ae8 100644
--- a/src/endWeek/saRecruitGirls.js
+++ b/src/endWeek/saRecruitGirls.js
@@ -1,55 +1,33 @@
-App.SlaveAssignment.recruitGirls = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.recruitGirls = function recruitGirls(slave) {
+	/** @type {string[]} */
+	let r = [];
 
-	let r;
+	const arcology = V.arcologies[0];
+	const targetArcology = V.arcologies.find((s) => s.direction === arcology.influenceTarget);
+	const totalInt = slave.intelligence + slave.intelligenceImplant;
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let girl;
-	let woman;
-	let women;
-	let He;
-	let His;
+	const {
+		he, him, his, himself, girl, woman, women, He, His,
+	} = getPronouns(slave);
 
-	let idleTarget;
-	let arcology;
-	let targetArcology;
-	let slaveInt;
-
-	return recruitGirls;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {string}
-	 */
-	function recruitGirls(slave) {
-		r = [];
-
-		arcology = V.arcologies[0];
-		targetArcology = V.arcologies.find((s) => s.direction === arcology.influenceTarget);
-		slaveInt = slave.intelligence + slave.intelligenceImplant;
-
-		({
-			he, him, his, himself, girl, woman, women, He, His,
-		} = getPronouns(slave));
-
-		calcIdleTarget();
-		physicalAdjustments(slave);
-		if (slave.health.tired > 80) {
-			tooTired(slave);
-		} else if (V.recruiterTarget === "other arcologies") {
-			influenceNeighbor(slave);
-		} else if (V.slaves.length < idleTarget) {
-			recruiting(slave);
-		} else {
-			idlePublicity(slave);
-		}
-
-		return r.join(" ");
+	const idleTarget = calcIdleTarget();
+	physicalAdjustments(slave);
+	if (slave.health.tired > 80) {
+		tooTired(slave);
+	} else if (V.recruiterTarget === "other arcologies") {
+		influenceNeighbor(slave);
+	} else if (V.slaves.length < idleTarget) {
+		recruiting(slave);
+	} else {
+		idlePublicity(slave);
 	}
 
+	return r.join(" ");
+
 	/** Get club ads bonus for Edo Revivalist recruitment
 	 * @returns {number}
 	 */
@@ -69,13 +47,16 @@ App.SlaveAssignment.recruitGirls = (function() {
 		return seed;
 	}
 
+	/**
+	 * @returns {number}
+	 */
 	function calcIdleTarget() {
 		if (V.recruiterIdleRule === "number") {
-			idleTarget = V.recruiterIdleNumber;
+			return V.recruiterIdleNumber;
 		} else if (V.recruiterIdleRule === "facility") {
-			idleTarget = App.Utils.recruiterFacilitySpace();
+			return App.Utils.recruiterFacilitySpace();
 		} else {
-			idleTarget = Infinity;
+			return Infinity;
 		}
 	}
 
@@ -313,7 +294,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 			} else if (arcology.FSSlaveProfessionalism !== "unset") {
 				if (targetArcology.FSSlaveProfessionalism !== "unset") {
 					r.push(`${He} advances Slave Professionalism there by demonstrating new techniques for the local slaves to`);
-					if (slaveInt > 95) {
+					if (totalInt > 95) {
 						r.push(`learn, which ${he}'s perfect for, since ${he}'s brilliant enough to pass ${his} knowledge to anyone willing to listen.`);
 						targetArcology.FSSlaveProfessionalism++;
 					} else {
@@ -322,7 +303,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 					targetArcology.FSSlaveProfessionalism += influence;
 				} else if (targetArcology.FSIntellectualDependency !== "unset") {
 					r.push(`${He} challenges Intellectual Dependency there by demonstrating new techniques for the local slaves to`);
-					if (slaveInt > 95) {
+					if (totalInt > 95) {
 						r.push(`learn, which ${he}'s perfect for, since ${he}'s brilliant enough to pass ${his} knowledge to anyone willing to listen.`);
 						targetArcology.FSIntellectualDependency--;
 					} else {
@@ -635,7 +616,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 			if (arcology.FSChattelReligionist !== "unset") {
 				if (targetArcology.FSChattelReligionist !== "unset") {
 					r.push(`${He} advances Chattel Religionism there by constant public worship, both sexual and`);
-					if (slave.devotion > 95 && slaveInt > 95) {
+					if (slave.devotion > 95 && totalInt > 95) {
 						r.push(`traditional, and by composing ${his} own series of devotionals to your sexual prowess and attractiveness.`);
 						targetArcology.FSChattelReligionist++;
 					} else {
@@ -647,7 +628,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 			if (arcology.FSRomanRevivalist !== "unset") {
 				if (targetArcology.FSRomanRevivalist !== "unset") {
 					r.push(`${He} advances Roman Revivalism there by taking an active part in the daily round of public Roman`);
-					if (canTalk(slave) && slaveInt > 95) {
+					if (canTalk(slave) && totalInt > 95) {
 						r.push(`life, which ${he}'s perfect for, since ${he} has the intelligence to hold ${his} own in discourse with citizens.`);
 						targetArcology.FSRomanRevivalist++;
 					} else {
@@ -658,7 +639,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 			} else if (arcology.FSNeoImperialist !== "unset") {
 				if (targetArcology.FSNeoImperialist !== "unset") {
 					r.push(`${He} advances Neo-Imperialism there by measuring out grace and allure with the arcology's`);
-					if (canTalk(slave) && slaveInt > 95) {
+					if (canTalk(slave) && totalInt > 95) {
 						r.push(`elites, elegantly convincing them with ${his} cutting wit on the favorite topic of any wealthy patrician - their own societal importance.`);
 						targetArcology.FSNeoImperialist++;
 					} else {
@@ -713,7 +694,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 			} else if (arcology.FSChineseRevivalist !== "unset") {
 				if (targetArcology.FSChineseRevivalist !== "unset") {
 					r.push(`${He} advances Chinese Revivalism there by helping citizens improve the feng shui of their slave`);
-					if (slaveInt > 110) {
+					if (totalInt > 110) {
 						r.push(`arrangements, which ${he}'s perfect for, since ${he} has the intelligence and education to make real contributions.`);
 						targetArcology.FSChineseRevivalist++;
 					} else {
@@ -771,11 +752,11 @@ App.SlaveAssignment.recruitGirls = (function() {
 			V.recruiterProgress += 1;
 		}
 		if (slave.skill.recruiter < V.masteredXP) {
-			const skillIncrease = random(1, Math.ceil((slaveInt) / 15) + 8);
+			const skillIncrease = random(1, Math.ceil((totalInt) / 15) + 8);
 			r.push(slaveSkillIncrease('recruiter', slave, skillIncrease));
 		}
 
-		if (slaveInt > 50) {
+		if (totalInt > 50) {
 			r.push(`${His} intelligence enables ${him} to cleverly entrap potential slaves.`);
 			V.recruiterProgress += 1;
 		}
@@ -797,7 +778,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 		}
 
 		if (slave.bellyPreg >= 300000) {
-			r.push(`${His} massive overfilled womb is detrimental to ${his} efforts to recruit slaves. It instills a fear of being turned into nothing more than a baby filled sack.`);
+			r.push(`${His} massive overfilled womb is detrimental to ${his} efforts to recruit slaves. It instills a fear of being turned into nothing more than a baby-filled sack.`);
 			V.recruiterProgress -= 3;
 		}
 
@@ -887,7 +868,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 
 		let FSmatch = 0; // FSmatch means recruiter's appearance displays FS ideas
 		let FSdefend = 0; // FSdefend is intelligence-based advocation for your FS
-		const FSIntMod = Math.floor(slaveInt / 32);
+		const FSIntMod = Math.floor(totalInt / 32);
 		let seed = 0;
 		const modScore = SlaveStatsChecker.modScore(slave);
 
@@ -901,8 +882,8 @@ App.SlaveAssignment.recruitGirls = (function() {
 
 		seed -= (6 - (6 * slave.skill.entertainment / 100));
 		seed -= (3 - (3 * slave.face / 100));
-		if (slaveInt < -15) {
-			seed = Math.min(seed, slaveInt / 10);
+		if (totalInt < -15) {
+			seed = Math.min(seed, totalInt / 10);
 		}
 		if (seed < 0) {
 			// catches overload from very high entertainment
@@ -910,7 +891,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 		}
 		V.recruiterProgress = Math.max(V.recruiterProgress, 0);
 
-		if (slaveInt > 15) {
+		if (totalInt > 15) {
 			if (slave.skill.entertainment >= 100) {
 				r.push(`${His} mastery of flirting and conversation continues to seduce them,`);
 				if (slave.face > 95) {
@@ -967,7 +948,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 		} else {
 			pushEWM(`More than a few sign up to watch ${his} feeds, but unsubscribe due to ${his} amateur presentation.`);
 		}
-		if (slaveInt > 15) {
+		if (totalInt > 15) {
 			pushEWM(`${He} offers thoughtful commentaries on trending topics.`);
 			seed += FSIntMod;
 		} else {
@@ -993,7 +974,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 		}
 
 		if (arcology.FSSupremacist !== "unset") {
-			if (slaveInt > 50) {
+			if (totalInt > 50) {
 				seed += 2;
 				FSdefend++;
 				arcology.FSSupremacist += 0.01 * V.FSSingleSlaveRep * FSIntMod;
@@ -1010,7 +991,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 			}
 		}
 		if (arcology.FSSubjugationist !== "unset") {
-			if (slaveInt > 50) {
+			if (totalInt > 50) {
 				seed += 2;
 				FSdefend++;
 				arcology.FSSubjugationist += 0.01 * V.FSSingleSlaveRep * FSIntMod;
@@ -1100,7 +1081,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 				pushFS(`${His} praise of your good works lacks the special touch of personal affection, so it doesn't impress much.`);
 			}
 		} else if (arcology.FSDegradationist !== "unset") {
-			if (slaveInt > 50) {
+			if (totalInt > 50) {
 				pushFS(`Ordinarily you would punish a slave who displays independent thinking, but when ${slave.slaveName}`);
 				if (modScore.total > 15 || (modScore.piercing > 8 && modScore.tat > 5)) {
 					pushFS(`goes public in all ${his} garish, modded glory to defend the legal right of slaveowners to use their property however they please, ${he}'s earned a brief reprieve.`);
@@ -1127,7 +1108,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 		if (arcology.FSIntellectualDependency !== "unset") {
 			if (arcology.FSIntellectualDependencyLawBeauty === 1 && bimboScore(slave) >= 6) {
 				if (slave.energy > 95) {
-					if (slaveInt < -50) {
+					if (totalInt < -50) {
 						pushFS(`${His} week was spent competing with other bimbos and generally being a delight to onlookers when the competition inevitably turns sexual.`);
 						seed += 3;
 					} else {
@@ -1141,7 +1122,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 				}
 				seed += 1;
 			} else if (slave.energy > 95) {
-				if (slaveInt < -50) {
+				if (totalInt < -50) {
 					pushFS(`${His} week was spent wandering aimlessly throughout the arcology, delighting anyone able to spend time with ${him} with ${his} simple ways.`);
 					seed += 3;
 				} else {
@@ -1155,8 +1136,8 @@ App.SlaveAssignment.recruitGirls = (function() {
 			}
 		} else if (arcology.FSSlaveProfessionalism !== "unset") {
 			if (slave.accent <= 1) {
-				if (slaveInt > 50) {
-					if (slaveInt > 95) {
+				if (totalInt > 50) {
+					if (totalInt > 95) {
 						if (slave.skill.entertainment + slave.skill.whoring + slave.skill.oral + slave.skill.anal + slave.skill.vaginal >= 400) {
 							pushFS(`Each week ${he} hosts ${his} own seminar demonstrating new and exciting sexual techniques, some even of ${his} own creation.`);
 							seed += 1;
@@ -1276,7 +1257,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 		}
 		if (arcology.FSRepopulationFocus !== "unset") {
 			if (slave.preg > slave.pregData.normalBirth / 1.33) {
-				pushFS(`${He} makes a habit of allowing the public to fondle and enjoy the movements within ${his} baby filled belly.`);
+				pushFS(`${He} makes a habit of allowing the public to fondle and enjoy the movements within ${his} baby-filled belly.`);
 				if (slave.pregType >= 30) {
 					seed += 5;
 				} else if (slave.pregType >= 10) {
@@ -1305,7 +1286,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 			} else {
 				pushFS(`${His} efforts would have more impact if ${his} womb wasn't so empty. Disappointing to any who would want to see ${him} pregnant.`);
 			}
-			if (slaveInt > 50) {
+			if (totalInt > 50) {
 				pushFS(`${He} is smart enough to not only repeat your repopulationist goals, but to expand upon them.`);
 				FSdefend++;
 				arcology.FSRepopulationFocus += 0.01 * V.FSSingleSlaveRep;
@@ -1437,7 +1418,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 		}
 		const clothes = App.Data.clothes.get(slave.clothes);
 		if (arcology.FSChattelReligionist !== "unset") {
-			if (slaveInt > 15 && (slave.devotion > 95 || slave.trust > 95)) {
+			if (totalInt > 15 && (slave.devotion > 95 || slave.trust > 95)) {
 				if (clothes.fs && clothes.fs.loves && clothes.fs.loves.has("FSChattelReligionist")) {
 					pushFS(`Clad in ${his} holy garb, ${slave.slaveName} preaches to the atrium with a powerful appeal to the new morality, in which ${his} absolute faith in your revelations is unmistakable.`);
 					seed += 1;
@@ -1456,7 +1437,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 				seed += 1;
 				FSdefend++;
 				arcology.FSChattelReligionist += 0.01 * V.FSSingleSlaveRep * FSIntMod;
-			} else if (slaveInt > 15) {
+			} else if (totalInt > 15) {
 				pushFS(`${His} lecture on the new religious morality is thorough, and also devastatingly boring: all bullet point scriptures and little emotion that would sway unenlightened hearts.`);
 			} else if (slave.devotion > 95 || slave.trust > 95) {
 				pushFS(`Although ${he} wears ${his} faith in you on ${his} metaphorical sleeve, ${he} can't muster the intellectual arguments to counter the shrill voices of backward old world religions.`);
@@ -1598,7 +1579,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 				pushFS(`${He} makes a short video essay about your elaborate master suite, but there's no sex going on while ${he} films.`);
 			}
 		} else if (arcology.FSChineseRevivalist !== "unset") {
-			if (slaveInt > 15 && V.HeadGirlID !== 0 && V.BodyguardID !== 0 && V.HGSuite > 0) {
+			if (totalInt > 15 && V.HeadGirlID !== 0 && V.BodyguardID !== 0 && V.HGSuite > 0) {
 				if ((S.HeadGirl.skill.entertainment / 30) + (S.HeadGirl.intelligenceImplant / 10) + S.HeadGirl.prestige >= 4) {
 					if (S.Bodyguard.prestige >= 1) {
 						pushFS(`${He} deferentially chronicles the administration of your Imperial household by Head Girl ${S.HeadGirl.slaveName} and Bodyguard ${S.Bodyguard.slaveName}. The piece explains points of Chinese Revivalist protocol where new slaves or visitors to the Forbidden Penthouse might inadvertently stumble.`);
@@ -1616,7 +1597,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 				arcology.FSChineseRevivalist += 0.03 * V.FSSingleSlaveRep;
 			} else if (V.HeadGirlID === 0 || V.BodyguardID === 0) {
 				pushFS(`${He} can't document the benefits of your Imperial Chinese administration because of unfilled posts in its leadership.`);
-			} else if (slaveInt <= 15) {
+			} else if (totalInt <= 15) {
 				pushFS(`Your household is a well-run model for the arcology at large, but your recruiter doesn't completely understand its intricate Revivalist protocols and can't explain it for the masses.`);
 			} else {
 				pushFS(`${He} never considers promoting your household's Revivalist protocols, since you don't value your Head Girl enough to accord ${him} a separate apartment inside your walls.`);
@@ -1649,7 +1630,7 @@ App.SlaveAssignment.recruitGirls = (function() {
 					pushFS(`${He} is willing to take part in bloodletting, but you can't allow ${him} to do so in ${his} poor health.`);
 				}
 			}
-			if (slaveInt > 15) {
+			if (totalInt > 15) {
 				pushFS(`${He} puts ${his} mind to work as ${he} joins citizens in their prayers to each deity.`);
 				FSdefend++;
 				seed += 1;
@@ -1683,4 +1664,4 @@ App.SlaveAssignment.recruitGirls = (function() {
 		// concatenate the FS match/defend strings *after* the summary
 		r = r.concat(FSstrings);
 	}
-})();
+};
diff --git a/src/endWeek/saRelationships.js b/src/endWeek/saRelationships.js
index 706cd45fcf941827c23002fab89c766872e4d5dd..252c5c85f3964836da9dc60b8e2616891a3b5d29 100644
--- a/src/endWeek/saRelationships.js
+++ b/src/endWeek/saRelationships.js
@@ -1,55 +1,35 @@
-App.SlaveAssignment.relationships = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.relationships = function saRelationships(slave) {
+	/** @type {string[]} */
+	const r = [];
 
-	let r;
+	const {
+		he, him, his, himself, He, His, wife, woman
+	} = getPronouns(slave);
+	const playerPronouns = getPronouns(V.PC);
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let He;
-	let His;
-	let wife;
-	let woman;
-	let playerPronouns;
-
-	let PC;
-
-	return saRelationships;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {string}
-	 */
-	function saRelationships(slave) {
-		r = [];
-
-		PC = V.PC;
-		({
-			he, him, his, himself, He, His, wife, woman
-		} = getPronouns(slave));
-		playerPronouns = getPronouns(PC);
-
-		if (slave.fuckdoll === 0) {
-			if (slave.relationship === 0 && slave.fetish !== "mindbroken") {
-				generateRelationship(slave);
-			} else if (slave.relationship !== 0) {
-				if (slave.relationship > 0) {
-					sanityCheck(slave);
-				}
-				existingRelationship(slave);
-				if (slave.relationship > 2) {
-					consummateRelationship(slave);
-				}
-			}
-			if (slave.fetish !== "mindbroken" && totalRelatives(slave) > 0) {
-				familyFeelings(slave);
+	if (slave.fuckdoll === 0) {
+		if (slave.relationship > 0) {
+			sanityCheck(slave);
+		}
+		if (slave.relationship === 0 && slave.fetish !== "mindbroken") {
+			generateRelationship(slave);
+		} else if (slave.relationship !== 0) {
+			existingRelationship(slave);
+			if (slave.relationship > 2) {
+				consummateRelationship(slave);
 			}
 		}
-
-		return r.join(" ");
+		if (slave.fetish !== "mindbroken" && totalRelatives(slave) > 0) {
+			familyFeelings(slave);
+		}
 	}
 
+	return r.join(" ");
+
 	/** Can this slave possibly be a friend?
 	 * @param {FC.ReportSlave} slave
 	 * @param {App.Entity.SlaveState} potentialFriend
@@ -82,7 +62,40 @@ App.SlaveAssignment.relationships = (function() {
 
 	/**
 	 * @param {FC.ReportSlave} slave
-	 *
+	 */
+	function bondEmotionally(slave) {
+		r.push(`and persistently interprets sex in the most romantic possible terms, ${he} has decided that ${he} wants to be yours in ${his} heart as well as ${his}`);
+		if (slave.vagina > 0) {
+			r.push(`pussy.`);
+		} else if (slave.anus > 0) {
+			r.push(`butthole.`);
+		} else {
+			r.push(`mouth.`);
+		}
+		r.push(`<span class="relationship">${He}'s become emotionally bonded to you!</span>`);
+		slave.relationship = -2;
+	}
+
+	/**
+	 * @param {FC.ReportSlave} slave
+	 * @param {FC.SlaveState} friend
+	 */
+	function forcedApartReaction(slave, friend) {
+		if (slave.devotion <= 50 && friend.devotion <= 50) {
+			r.push(`${slave.slaveName} and ${friend.slaveName} both <span class="devotion dec">resent</span> this.`);
+			slave.devotion -= 2;
+			friend.devotion -= 2;
+		} else if (slave.devotion <= 50) {
+			r.push(`${slave.slaveName} <span class="devotion dec">resents</span> this.`);
+			slave.devotion -= 2;
+		} else if (friend.devotion <= 50) {
+			r.push(`${friend.slaveName} <span class="devotion dec">resents</span> this.`);
+			friend.devotion -= 2;
+		}
+	}
+
+	/**
+	 * @param {FC.ReportSlave} slave
 	 */
 	function generateRelationship(slave) {
 		let randomSeed;
@@ -90,16 +103,7 @@ App.SlaveAssignment.relationships = (function() {
 		if (slave.devotion + slave.trust > 175 && random(1, 3) === 1) { // player + emotional slut
 			r.push(`${slave.slaveName} is quite devoted to you, and trusts both you and ${his} place as a slave. Since ${he} does not have a strong relationship with another slave,`);
 			if (slave.sexualQuirk === "romantic") {
-				r.push(`and persistently interprets sex in the most romantic possible terms, ${he} has decided that ${he} wants to be yours in ${his} heart as well as ${his}`);
-				if (slave.vagina > 0) {
-					r.push(`pussy.`);
-				} else if (slave.anus > 0) {
-					r.push(`butthole.`);
-				} else {
-					r.push(`mouth.`);
-				}
-				r.push(`<span class="relationship">${He}'s become emotionally bonded to you!</span>`);
-				slave.relationship = -2;
+				bondEmotionally(slave);
 			} else if (slave.assignment === Job.CONCUBINE) {
 				r.push(`and is your concubine, ${he} almost inevitably comes to view you as much as a lover as an owner. <span class="relationship">${He}'s become emotionally bonded to you!</span>`);
 				slave.relationship = -2;
@@ -109,7 +113,7 @@ App.SlaveAssignment.relationships = (function() {
 			} else if (slave.assignment === Job.FUCKTOY || slave.assignment === Job.MASTERSUITE) {
 				r.push(`and spends ${his} days worshipping your`);
 				if (V.PC.dick !== 0) {
-					r.push(`cock${PC.vagina !== -1 ? " and" : ","}`);
+					r.push(`cock${V.PC.vagina !== -1 ? " and" : ","}`);
 				}
 				if (V.PC.vagina !== -1) {
 					r.push(`cunt,`);
@@ -132,7 +136,7 @@ App.SlaveAssignment.relationships = (function() {
 				r.push(`${slave.slaveName} greets ${potentialFriend.slaveName} with joy. It's not clear whether they ever knew each other during their lives as Futanari Sisters, but it seems that they believe themselves to be in a relationship by simple virtue of having been Sisters. In any case, ${slave.slaveName} and ${potentialFriend.slaveName} <span class="relationship">become inseparable lovers</span> instantly, as though there's no possibility they would do anything else. They're even surprised when other slaves ask them about it; it's as though they're unaware that other possibilities even exist.`);
 				startFriendship(slave, potentialFriend, 4);
 			}
-		} else if (slave.origin === "You were acquainted with $him before you were an arcology owner; your rival tried to use $him to manipulate you, but you rescued $him." && V.rivalryDuration > 20 && !["Intellectual Dependency", "Paternalism", "Racial Supremacism", "Slave Professionalism"].includes(V.rivalryFS) && slave.newGamePlus === 0) {
+		} else if (slave.origin === "You were acquainted with $him before you were an arcology owner; your rival tried to use $him to manipulate you, but you rescued $him." && V.rival.duration > 20 && !["Intellectual Dependency", "Paternalism", "Racial Supremacism", "Slave Professionalism"].includes(V.rival.FS.name) && slave.newGamePlus === 0) {
 			const potentialFriend = V.slaves.find((s) => (s.prestigeDesc === "You bankrupted and enslaved $him in revenge for $his part in the attack on your arcology by the Daughters of Liberty." && s.fuckdoll === 0 && s.fetish !== "mindbroken" && s.newGamePlus === 0));
 			if (potentialFriend !== undefined) {
 				r.push(`${slave.slaveName} greets ${potentialFriend.slaveName} with joy, happy to see a familiar face again. Without any regard to you, <span class="relationship">they continue their prior relationship.</span>`);
@@ -393,7 +397,7 @@ App.SlaveAssignment.relationships = (function() {
 				}
 			}
 		} else if (slave.relationship === -2) {
-			incestReactions(slave, PC);
+			incestReactions(slave, V.PC);
 			if (slave.devotion + slave.trust < 150) {
 				if (slave.devotion < 75 && random(1, 100) > 50) {
 					r.push(`${He} is no longer as devoted to you as ${he} once was, and has <span class="relationship dec">begun to look elsewhere for emotional support.</span>`);
@@ -419,7 +423,7 @@ App.SlaveAssignment.relationships = (function() {
 					slave.trust++;
 			}
 		} else if (slave.relationship === -3) {
-			incestReactions(slave, PC);
+			incestReactions(slave, V.PC);
 			if (slave.fetish === "mindbroken") {
 				switch (slave.assignment) {
 					case Job.HOUSE:
@@ -575,17 +579,7 @@ App.SlaveAssignment.relationships = (function() {
 					slave.relationship = 0;
 					slave.relationshipTarget = 0;
 				}
-				if (slave.devotion <= 50 && friend.devotion <= 50) {
-					r.push(`${slave.slaveName} and ${friend.slaveName} both <span class="devotion dec">resent</span> this.`);
-					slave.devotion -= 2;
-					friend.devotion -= 2;
-				} else if (slave.devotion <= 50) {
-					r.push(`${slave.slaveName} <span class="devotion dec">resents</span> this.`);
-					slave.devotion -= 2;
-				} else if (friend.devotion <= 50) {
-					r.push(`${friend.slaveName} <span class="devotion dec">resents</span> this.`);
-					friend.devotion -= 2;
-				}
+				forcedApartReaction(slave, friend);
 			}
 		} else if (slave.rules.relationship === "just friends" && slave.relationship !== 5 && slave.relationship > 2) {
 			if (disobedience(friend) > random(0, 100)) {
@@ -600,17 +594,7 @@ App.SlaveAssignment.relationships = (function() {
 				r.push(`<span class="relationship dec">forced to keep their hands to themselves.</span>`);
 				friend.relationship = 2;
 				slave.relationship = 2;
-				if (slave.devotion <= 50 && friend.devotion <= 50) {
-					r.push(`${slave.slaveName} and ${friend.slaveName} both <span class="devotion dec">resent</span> this.`);
-					slave.devotion -= 2;
-					friend.devotion -= 2;
-				} else if (slave.devotion <= 50) {
-					r.push(`${slave.slaveName} <span class="devotion dec">resents</span> this.`);
-					slave.devotion -= 2;
-				} else if (friend.devotion <= 50) {
-					r.push(`${friend.slaveName} <span class="devotion dec">resents</span> this.`);
-					friend.devotion -= 2;
-				}
+				forcedApartReaction(slave, friend);
 			}
 		} else {
 			let seed = 0;
@@ -621,16 +605,7 @@ App.SlaveAssignment.relationships = (function() {
 					if (slave.devotion + slave.trust > 170 && random(1, 100) > 95) { // 5% chance to abandon friend to ebond/eslut
 						r.push(`${He}'s very devoted to you, and strongly trusts both you and ${his} place as a slave. Since ${he} is just friends with ${friend.slaveName},`);
 						if (slave.sexualQuirk === "romantic") {
-							r.push(`and persistently interprets sex in the most romantic possible terms, ${he} has decided that ${he} wants to be yours in ${his} heart as well as ${his}`);
-							if (slave.vagina > 0) {
-								r.push(`pussy.`);
-							} else if (slave.anus > 0) {
-								r.push(`butthole.`);
-							} else {
-								r.push(`mouth.`);
-							}
-							r.push(`<span class="relationship">${He}'s become emotionally bonded to you!</span>`);
-							slave.relationship = -2;
+							bondEmotionally(slave);
 						} else if (slave.energy > 90) {
 							r.push(`and is a total sex addict, ${he} begins to think of sex as ${his} only meaningful emotional connection with people. <span class="relationship">${He}'s become an emotional slut!</span>`);
 							slave.relationship = -1;
@@ -878,7 +853,7 @@ App.SlaveAssignment.relationships = (function() {
 
 	/**
 	 * @param {FC.ReportSlave} slave
-	 * @param {App.Entity.SlaveState} relative
+	 * @param {Relative} relative
 	 */
 	function incestReactions(slave, relative) {
 		if (areRelated(slave, relative)) {
@@ -991,11 +966,11 @@ App.SlaveAssignment.relationships = (function() {
 			if (slave.sexualQuirk === "size queen" && canPenetrate(lover)) {
 				if (lover.dick > 5) {
 					r.push(`${He}'s <span class="devotion inc">very happy</span> with ${his} romantic status, since it means ${he} regularly gets monster cock.`);
-					if (canDoAnal(slave) && slave.anus.isBetween(0, 3)) {
+					if (V.seeStretching === 1 && canDoAnal(slave) && slave.anus.isBetween(0, 3)) {
 						r.push(`${He}'s such a size queen that ${he} takes it up ${his} ass as often as ${he} can bear it, despite ${his} poor anus not being used to such abuse. This <span class="lime">stretches out ${his} sphincter.</span>`);
 						slave.anus++;
 					}
-					if (canDoVaginal(slave) && slave.vagina.isBetween(0, 3)) {
+					if (V.seeStretching === 1 && canDoVaginal(slave) && slave.vagina.isBetween(0, 3)) {
 						r.push(`It's a little big for what ${his} pussy can handle, <span class="lime">but ${he} gets used to it.</span>`);
 						slave.vagina++;
 					}
@@ -1004,11 +979,11 @@ App.SlaveAssignment.relationships = (function() {
 					lover.devotion += 2;
 				} else if (lover.dick > 4) {
 					r.push(`${He} <span class="devotion inc">quite likes</span> being in a sexual relationship with a slave who has such an impressive dick.`);
-					if (canDoAnal(slave) && slave.anus.isBetween(0, 2)) {
+					if (V.seeStretching === 1 && canDoAnal(slave) && slave.anus.isBetween(0, 2)) {
 						r.push(`${He}'s such a size queen that ${he} takes it up ${his} ass as often as ${he} can bear it, despite ${his} tight butt not being used to such abuse. This <span class="lime">stretches out ${his} sphincter.</span>`);
 						slave.anus++;
 					}
-					if (canDoVaginal(slave) && slave.vagina.isBetween(0, 2)) {
+					if (V.seeStretching === 1 && canDoVaginal(slave) && slave.vagina.isBetween(0, 2)) {
 						r.push(`It's a little big for what ${his} tight pussy can handle, <span class="lime">but ${he} gets used to it.</span>`);
 						slave.vagina++;
 					}
@@ -1343,4 +1318,4 @@ App.SlaveAssignment.relationships = (function() {
 			}
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saReleaseRules.js b/src/endWeek/saReleaseRules.js
index 40cdebabe9f8cd1db366cd1cf2be45a4acc6ad95..2ac87bfadec6a76331bef0c663309fb0598a757a 100644
--- a/src/endWeek/saReleaseRules.js
+++ b/src/endWeek/saReleaseRules.js
@@ -3,6 +3,7 @@
  * @returns {DocumentFragment}
  */
 App.SlaveAssignment.nonAssignmentRelease = function(slave) {
+	/** @type {Array<string|DocumentFragment>} */
 	let r = [];
 	const release = slave.rules.release;
 	const {he, his, him, himself} = getPronouns(slave);
diff --git a/src/endWeek/saRewardAndPunishment.js b/src/endWeek/saRewardAndPunishment.js
index fb431b7348422267e49642e18ec5d2e2b9d76f0c..dce20eff661c3152d0e7ec6909050553013c49be 100644
--- a/src/endWeek/saRewardAndPunishment.js
+++ b/src/endWeek/saRewardAndPunishment.js
@@ -1,256 +1,253 @@
-App.SlaveAssignment.rewardAndPunishment = (function() {
-	/** @type {App.Entity.SlaveState} */
-	let slave;
-	let He;
-	let he;
-	let His;
-	let his;
-	let him;
-	let himself;
+/** Administer rewards and punishments for the slave
+ * @param {App.Entity.SlaveState} forSlave
+ * @returns {string}
+ */
+App.SlaveAssignment.rewardAndPunishment = function rewardAndPunish(forSlave) {
+	/** @type {string[]} */
+	const r = [];
+
+	const slave = forSlave;
+	const {He, he, His, his, him, himself} = getPronouns(slave);
+
 	let rewards = 0;
 	let punishments = 0;
 	let combinedText = false;
 
-	const rewardFuncs = {
-		relaxation: function() {
-			let r = [];
-			r.push(`${He}'s given free time, which ${he}`);
-			if (slave.assignment === Job.CLINIC) {
-				r.push(`spends with the amenities present in ${V.clinicName} for recovering slaves to pass the time.`);
-			} else if (slave.assignment === Job.ATTENDANT) {
-				r.push(`usually spends soaking in a hot bath or enjoying the amenities ${his} facility has to offer.`);
-			} else if (slave.assignment === Job.CONCUBINE) {
-				if (V.spa !== 0) {
-					r.push(`usually sets aside to spend with you in ${V.spaName}.`);
-				} else {
-					r.push(`usually spends relaxing with you.`);
-				}
-			} else if (V.spa !== 0) {
-				const where = (slave.assignment !== Job.SPA) ? V.spaName : `a private bath`;
-				const attendant = S.Attendant ? `, enjoying ${S.Attendant.slaveName}'s care` : ``;
-				r.push(`usually spends in ${where}${attendant}.`);
-			} else if (slave.assignment === Job.MASTERSUITE) {
-				r.push(`usually spends relaxing on ${his} favorite pillow.`);
-			} else if (slave.assignment === Job.HEADGIRLSUITE) {
-				r.push(`usually spends relaxing in your Head Girl's private room.`);
-			} else if (slave.rules.living === "luxurious") {
-				let roomActivity = '';
-				if (slave.assignment === Job.NURSE) {
-					roomActivity = ` amusing ${himself} with the amenities for recovering slaves`;
-				} else if (slave.assignment === Job.WARDEN && App.Entity.facilities.cellblock.employeesIDs().size > 0) {
-					roomActivity = ` teaching a disobedient slave how to properly use their mouth`;
-				} else if (slave.assignment === Job.TEACHER && App.Entity.facilities.schoolroom.employeesIDs().size > 0) {
-					roomActivity = ` giving private lessons to a student`;
-				} else if (slave.assignment === Job.STEWARD && App.Entity.facilities.servantsQuarters.employeesIDs().size > 0) {
-					roomActivity = ` while enjoying some service from ${his} underlings`;
-				} else if (slave.assignment === Job.MILKMAID && App.Entity.facilities.dairy.employeesIDs().size > 0) {
-					roomActivity = ` with the softest cow available`;
-				} else if (slave.assignment === Job.FARMER && App.Entity.facilities.farmyard.employeesIDs().size > 0) {
-					roomActivity = ` with the softest cow available`; // FIXME: needs improvement
-				} else if (canSee(slave) && (slave.intelligence + slave.intelligenceImplant > 50)) {
-					roomActivity = ` reading books`;
-				} else if (canSee(slave) && canHear(slave)) {
-					roomActivity = ` watching television`;
-				} else if (canSee(slave)) {
-					roomActivity = ` reading magazines`;
-				} else if (canHear(slave)) {
-					roomActivity = ` listening to music`;
-				}
-				r.push(`usually spends relaxing in ${his} private room${roomActivity}.`);
-			} else if (slave.assignment === Job.SCHOOL) {
-				r.push(`usually spends relaxing in ${his} dorm room.`);
+	if (slave.assignment === Job.CLINIC && random(-200, 200) < slave.health.health) {
+		r.push(`${He} does not feel up to doing much, so ${he} needs neither rewards nor punishments this week.`);
+	} else {
+		const you = (slave.assignment !== Job.HEADGIRLSUITE) ? `you` : `you and ${S.HeadGirl.slaveName}`;
+		if (slave.devotion > 50) {
+			r.push(`${He} does ${his} best for ${you}, so ${he} frequently deserves a reward and never needs to be punished.`);
+			punishments = 0;
+			rewards = 3;
+		} else if (slave.devotion > 20) {
+			r.push(`${He}'s obedient out of acceptance of ${his} place, so ${he} often deserves a reward and rarely needs to be punished.`);
+			punishments = 1;
+			rewards = 2;
+		} else if (slave.devotion >= -20) {
+			if (slave.trust < -20) {
+				r.push(`${He}'s obedient out of fear, so ${he} only rarely deserves a reward and sometimes needs to be punished.`);
+				punishments = 1;
+				rewards = 1;
 			} else {
-				r.push(`usually spends relaxing in the slave quarters.`);
+				r.push(`${He}'s too trusting for obedience and often needs to be punished.`);
+				punishments = 2;
+				rewards = 0;
 			}
-			if (slave.relationship > 0) {
-				r.push(`${He} often asks to save these breaks so ${he} can spend them with ${his} ${relationshipTerm(slave)}.`);
+		} else {
+			if (slave.trust < -50) {
+				r.push(`${He}'s only obedient out of terror, so ${he} sometimes needs to be punished.`);
+				punishments = 1;
+				rewards = 0;
+			} else {
+				r.push(`${He} hates ${you} too much to obey, so ${he} needs constant punishment.`);
+				punishments = 3;
+				rewards = 0;
 			}
-			r.push(`These breaks are <span class="health inc">good for ${him}.</span>`);
-			improveCondition(slave, rewards);
-			return r;
-		},
+		}
+	}
 
-		drugs: function() {
-			let r = [];
-			r.push(`${He}'s <span class="hotpink">rewarded</span> with hits of mild recreational drugs, which <span class="health dec">isn't healthy,</span> but helps bind ${him} to you strongly.`);
-			if ([Job.CLUB, Job.PUBLIC].includes(slave.assignment)) {
-				r.push(`${His} patrons don't complain either.`);
-			}
-			healthDamage(slave, rewards);
-			slave.devotion += rewards * 2;
-			return r;
-		},
+	combinedText = (slave.rules.reward === slave.rules.punishment) && rewards > 0 && punishments > 0;
+	if (rewards > 0) {
+		r.push(...reward(slave, slave.rules.reward));
+	}
+	if (punishments > 0) {
+		r.push(...punish(slave, slave.rules.punishment));
+	}
+	return r.join(' ');
 
-		orgasm: function() {
-			let r = [];
-			r.push(`${He}'s <span class="hotpink">rewarded</span> with`);
-			if (slave.piercing.genitals.smart) {
-				r.push(`sustained orgasm from ${his}`);
-				if (slave.dick === 0) {
-					r.push(`clit`);
+	/**
+	 * @param {FC.SlaveState} slave
+	 * @param {"relaxation" | "drugs" | "orgasm" | "situational" | "confinement"} type
+	 * @returns {string[]}
+	 */
+	function reward(slave, type) {
+		/** @type {string[]} */
+		const r = [];
+		switch (type) {
+			case "relaxation":
+				r.push(`${He}'s given free time, which ${he}`);
+				if (slave.assignment === Job.CLINIC) {
+					r.push(`spends with the amenities present in ${V.clinicName} for recovering slaves to pass the time.`);
+				} else if (slave.assignment === Job.ATTENDANT) {
+					r.push(`usually spends soaking in a hot bath or enjoying the amenities ${his} facility has to offer.`);
+				} else if (slave.assignment === Job.CONCUBINE) {
+					if (V.spa !== 0) {
+						r.push(`usually sets aside to spend with you in ${V.spaName}.`);
+					} else {
+						r.push(`usually spends relaxing with you.`);
+					}
+				} else if (V.spa !== 0) {
+					const where = (slave.assignment !== Job.SPA) ? V.spaName : `a private bath`;
+					const attendant = S.Attendant ? `, enjoying ${S.Attendant.slaveName}'s care` : ``;
+					r.push(`usually spends in ${where}${attendant}.`);
+				} else if (slave.assignment === Job.MASTERSUITE) {
+					r.push(`usually spends relaxing on ${his} favorite pillow.`);
+				} else if (slave.assignment === Job.HEADGIRLSUITE) {
+					r.push(`usually spends relaxing in your Head Girl's private room.`);
+				} else if (slave.rules.living === "luxurious") {
+					let roomActivity = '';
+					if (slave.assignment === Job.NURSE) {
+						roomActivity = ` amusing ${himself} with the amenities for recovering slaves`;
+					} else if (slave.assignment === Job.WARDEN && App.Entity.facilities.cellblock.employeesIDs().size > 0) {
+						roomActivity = ` teaching a disobedient slave how to properly use their mouth`;
+					} else if (slave.assignment === Job.TEACHER && App.Entity.facilities.schoolroom.employeesIDs().size > 0) {
+						roomActivity = ` giving private lessons to a student`;
+					} else if (slave.assignment === Job.STEWARD && App.Entity.facilities.servantsQuarters.employeesIDs().size > 0) {
+						roomActivity = ` while enjoying some service from ${his} underlings`;
+					} else if (slave.assignment === Job.MILKMAID && App.Entity.facilities.dairy.employeesIDs().size > 0) {
+						roomActivity = ` with the softest cow available`;
+					} else if (slave.assignment === Job.FARMER && App.Entity.facilities.farmyard.employeesIDs().size > 0) {
+						roomActivity = ` with the softest cow available`; // FIXME: needs improvement
+					} else if (canSee(slave) && (slave.intelligence + slave.intelligenceImplant > 50)) {
+						roomActivity = ` reading books`;
+					} else if (canSee(slave) && canHear(slave)) {
+						roomActivity = ` watching television`;
+					} else if (canSee(slave)) {
+						roomActivity = ` reading magazines`;
+					} else if (canHear(slave)) {
+						roomActivity = ` listening to music`;
+					}
+					r.push(`usually spends relaxing in ${his} private room${roomActivity}.`);
+				} else if (slave.assignment === Job.SCHOOL) {
+					r.push(`usually spends relaxing in ${his} dorm room.`);
 				} else {
-					r.push(`dick`);
+					r.push(`usually spends relaxing in the slave quarters.`);
 				}
-				r.push(`piercing,`);
-				if (slave.assignment === Job.CLUB) {
-					r.push(`often on stage during a dance,`);
+				if (slave.relationship > 0) {
+					r.push(`${He} often asks to save these breaks so ${he} can spend them with ${his} ${relationshipTerm(slave)}.`);
 				}
-			} else if ([Job.CONCUBINE, Job.MASTERSUITE, Job.FUCKTOY].includes(slave.assignment)) {
-				r.push(`immediate sex with you,`);
-			} else if (slave.rules.release.slaves === 1) {
-				r.push(`immediate sex with any nearby slave,`);
-			} else {
-				r.push(`a quick climax from a vibrator,`);
-			}
-			r.push(`<span class="libido inc">boosting ${his} libido.</span>`);
-			if (slave.energy < 98) {
-				slave.energy += rewards;
-			}
-			slave.need -= (rewards * 10);
-			slave.devotion += rewards;
-			return r;
-		},
+				r.push(`These breaks are <span class="health inc">good for ${him}.</span>`);
+				improveCondition(slave, rewards);
+				return r;
 
-		situational: function() {
-			let r = [];
-			r.push(`${He}'s <span class="hotpink">rewarded</span>`);
-			if (combinedText) {
-				r.push(`and <span class="gold">punished</span>`);
-			}
-			r.push(`situationally, letting ${him} develop normally.`);
-			slave.devotion += rewards;
-			return r;
-		}
-	};
+			case "drugs":
+				r.push(`${He}'s <span class="hotpink">rewarded</span> with hits of mild recreational drugs, which <span class="health dec">isn't healthy,</span> but helps bind ${him} to you strongly.`);
+				if ([Job.CLUB, Job.PUBLIC].includes(slave.assignment)) {
+					r.push(`${His} patrons don't complain either.`);
+				}
+				healthDamage(slave, rewards);
+				slave.devotion += rewards * 2;
+				return r;
 
-	const punishFuncs = {
-		confinement: function() {
-			let r = [];
-			r.push(`When ${he} disobeys,`);
-			if (slave.assignment === Job.CLINIC) {
-				r.push(`${he} spends ${his} time <span class="gold">strapped</span> to ${his} bed until ${he} behaves.`);
-			} else if (slave.assignment === Job.DAIRY) {
-				r.push(`${he} spends ${his} time <span class="gold">getting milked in a cramped dark stall</span> until ${he} behaves.`);
-			} else if (V.cellblock !== 0) {
-				if (slave.assignment === Job.CELLBLOCK) {
-					r.push(`${he} <span class="gold">spends ${his} day in solitary.</span>`);
-				} else if (slave.assignment === Job.SCHOOL) {
-					r.push(`${he} <span class="gold">is assigned detention after school in ${V.cellblockName}</span>${S.Wardeness ? `, where ${he} can experience ${S.Wardeness.slaveName}'s teaching methods` : ``}.`);
-				} else if (slave.assignment === Job.QUARTER) {
-					r.push(`${he} <span class="gold">spends ${his} day (and night) cleaning the cells in ${V.cellblockName}</span>${S.Wardeness ? `, where ${he} can experience ${S.Wardeness.slaveName}'s tender mercies` : ``}.`);
+			case "orgasm":
+				r.push(`${He}'s <span class="hotpink">rewarded</span> with`);
+				if (slave.piercing.genitals.smart) {
+					r.push(`sustained orgasm from ${his}`);
+					if (slave.dick === 0) {
+						r.push(`clit`);
+					} else {
+						r.push(`dick`);
+					}
+					r.push(`piercing,`);
+					if (slave.assignment === Job.CLUB) {
+						r.push(`often on stage during a dance,`);
+					}
+				} else if ([Job.CONCUBINE, Job.MASTERSUITE, Job.FUCKTOY].includes(slave.assignment)) {
+					if (slave.rules.release.master) {
+						r.push(`immediate sex with you,`);
+						seX(slave, canDoVaginal(slave) ? "vaginal" : "anal", V.PC);
+					} else {
+						r.push(`an orgasm directly from the hand of ${his} ${getWrittenTitle(slave)},`);
+					}
+				} else if (slave.rules.release.slaves === 1) {
+					r.push(`immediate sex with any nearby slave,`);
+					seX(slave, canDoVaginal(slave) ? "vaginal" : "anal", "slaves");
 				} else {
-					r.push(`${he} <span class="gold">spends ${his} off hours in ${V.cellblockName}</span>${S.Wardeness ? `, where ${he} can experience ${S.Wardeness.slaveName}'s tender mercies` : ``}.`);
+					r.push(`a quick climax from a vibrator,`);
 				}
-			} else {
-				r.push(`${he} spends ${his} off hours <span class="gold">shut up in a box</span> until ${he} behaves.`);
-			}
-			slave.trust -= punishments;
-			return r;
-		},
-
-		whipping: function() {
-			let r = [];
-			r.push(`When ${he} disobeys, ${he}'s`);
-			if (slave.assignment === Job.SCHOOL) {
-				r.push(`dragged to the front of the class and`);
-			}
-			r.push(`<span class="gold">whipped,</span> not hard enough to mark ${him}${slave.assignment === Job.CLINIC ? `or complicate ${his} stay` : ``}, but hard enough to <span class="health dec">hurt,</span> breaking ${him} quickly.`);
-			healthDamage(slave, punishments);
-			slave.trust -= 2 * punishments;
-			return r;
-		},
-
-		chastity: function() {
-			let r = [];
-			r.push(`When ${he} disobeys,`);
-			if (slave.assignment === Job.BROTHEL) {
-				r.push(`${he} finds ${his} next client is into <span class="gold">orgasm denial,</span>`);
-			} else if (slave.assignment === Job.CLUB) {
-				r.push(`${he} finds ${his} next dance to be both extremely sexual and <span class="gold">completely unsatisfying,</span>`);
-			} else if (slave.assignment === Job.CELLBLOCK) {
-				r.push(`${he}'s given a hit of mild aphrodisiacs and <span class="gold">left to squirm without release,</span>`);
-			} else if (slave.assignment === Job.SCHOOL) {
-				r.push(`${he}'s dragged to the front of the class for a lesson on edging. ${He} is kept <span class="gold">just shy of orgasm</span> for the rest of the day,`);
-			} else if (slave.assignment === Job.QUARTER) {
-				r.push(`${he} finds ${himself} cleaning up around an ongoing orgy, yet <span class="gold">forbidden from getting off,</span>`);
-			} else if (slave.assignment === Job.DAIRY) {
-				r.push(`${he} finds ${his} <span class="gold">milkings fewer and farther between,</span>`);
-			} else {
-				r.push(`${he}'s <span class="gold">denied</span> ${his} next orgasm,`);
-			}
-			r.push(`<span class="libido dec">reducing ${his} libido</span> but breaking ${him} to <span class="hotpink">sexual obedience.</span>`);
-			if (slave.energy > 2) {
-				slave.energy -= 2 * punishments;
-			}
-			slave.devotion += punishments;
-			slave.trust -= punishments;
-			return r;
-		},
+				r.push(`<span class="libido inc">boosting ${his} libido.</span>`);
+				if (slave.energy < 98) {
+					slave.energy += rewards;
+				}
+				slave.need -= (rewards * 10);
+				slave.devotion += rewards;
+				return r;
 
-		situational: function() {
-			let r = [];
-			if (!combinedText) {
-				r.push(`When ${he} disobeys, ${he}'s <span class="gold">punished</span> situationally, letting ${him} develop normally.`);
-			}
-			slave.trust -= punishments;
-			return r;
+			case "situational":
+				r.push(`${He}'s <span class="hotpink">rewarded</span>`);
+				if (combinedText) {
+					r.push(`and <span class="gold">punished</span>`);
+				}
+				r.push(`situationally, letting ${him} develop normally.`);
+				slave.devotion += rewards;
+				return r;
 		}
-	};
+	}
 
-	/** Administer rewards and punishments for the slave
-	 * @param {App.Entity.SlaveState} forSlave
-	 * @returns {string}
+	/**
+	 * @param {FC.SlaveState} slave
+	 * @param {"confinement" | "whipping" | "chastity" | "situational"} type
+	 * @returns {string[]}
 	 */
-	function rewardAndPunish(forSlave) {
-		let r = [];
+	function punish(slave, type) {
+		/** @type {string[]} */
+		const r = [];
+		switch (type) {
+			case "confinement":
+				r.push(`When ${he} disobeys,`);
+				if (slave.assignment === Job.CLINIC) {
+					r.push(`${he} spends ${his} time <span class="gold">strapped</span> to ${his} bed until ${he} behaves.`);
+				} else if (slave.assignment === Job.DAIRY) {
+					r.push(`${he} spends ${his} time <span class="gold">getting milked in a cramped dark stall</span> until ${he} behaves.`);
+				} else if (V.cellblock !== 0) {
+					if (slave.assignment === Job.CELLBLOCK) {
+						r.push(`${he} <span class="gold">spends ${his} day in solitary.</span>`);
+					} else if (slave.assignment === Job.SCHOOL) {
+						r.push(`${he} <span class="gold">is assigned detention after school in ${V.cellblockName}</span>${S.Wardeness ? `, where ${he} can experience ${S.Wardeness.slaveName}'s teaching methods` : ``}.`);
+					} else if (slave.assignment === Job.QUARTER) {
+						r.push(`${he} <span class="gold">spends ${his} day (and night) cleaning the cells in ${V.cellblockName}</span>${S.Wardeness ? `, where ${he} can experience ${S.Wardeness.slaveName}'s tender mercies` : ``}.`);
+					} else {
+						r.push(`${he} <span class="gold">spends ${his} off hours in ${V.cellblockName}</span>${S.Wardeness ? `, where ${he} can experience ${S.Wardeness.slaveName}'s tender mercies` : ``}.`);
+					}
+				} else {
+					r.push(`${he} spends ${his} off hours <span class="gold">shut up in a box</span> until ${he} behaves.`);
+				}
+				slave.trust -= punishments;
+				return r;
 
-		slave = forSlave;
-		({He, he, His, his, him, himself} = getPronouns(slave));
+			case "whipping":
+				r.push(`When ${he} disobeys, ${he}'s`);
+				if (slave.assignment === Job.SCHOOL) {
+					r.push(`dragged to the front of the class and`);
+				}
+				r.push(`<span class="gold">whipped,</span> not hard enough to mark ${him}${slave.assignment === Job.CLINIC ? `or complicate ${his} stay` : ``}, but hard enough to <span class="health dec">hurt,</span> breaking ${him} quickly.`);
+				healthDamage(slave, punishments);
+				slave.trust -= 2 * punishments;
+				return r;
 
-		if (slave.assignment === Job.CLINIC && random(-200, 200) < slave.health.health) {
-			r.push(`${He} does not feel up to doing much, so ${he} needs neither rewards nor punishments this week.`);
-		} else {
-			const you = (slave.assignment !== Job.HEADGIRLSUITE) ? `you` : `you and ${S.HeadGirl.slaveName}`;
-			if (slave.devotion > 50) {
-				r.push(`${He} does ${his} best for ${you}, so ${he} frequently deserves a reward and never needs to be punished.`);
-				punishments = 0;
-				rewards = 3;
-			} else if (slave.devotion > 20) {
-				r.push(`${He}'s obedient out of acceptance of ${his} place, so ${he} often deserves a reward and rarely needs to be punished.`);
-				punishments = 1;
-				rewards = 2;
-			} else if (slave.devotion >= -20) {
-				if (slave.trust < -20) {
-					r.push(`${He}'s obedient out of fear, so ${he} only rarely deserves a reward and sometimes needs to be punished.`);
-					punishments = 1;
-					rewards = 1;
+			case "chastity":
+				r.push(`When ${he} disobeys,`);
+				if (slave.assignment === Job.BROTHEL) {
+					r.push(`${he} finds ${his} next client is into <span class="gold">orgasm denial,</span>`);
+				} else if (slave.assignment === Job.CLUB) {
+					r.push(`${he} finds ${his} next dance to be both extremely sexual and <span class="gold">completely unsatisfying,</span>`);
+				} else if (slave.assignment === Job.CELLBLOCK) {
+					r.push(`${he}'s given a hit of mild aphrodisiacs and <span class="gold">left to squirm without release,</span>`);
+				} else if (slave.assignment === Job.SCHOOL) {
+					r.push(`${he}'s dragged to the front of the class for a lesson on edging. ${He} is kept <span class="gold">just shy of orgasm</span> for the rest of the day,`);
+				} else if (slave.assignment === Job.QUARTER) {
+					r.push(`${he} finds ${himself} cleaning up around an ongoing orgy, yet <span class="gold">forbidden from getting off,</span>`);
+				} else if (slave.assignment === Job.DAIRY) {
+					r.push(`${he} finds ${his} <span class="gold">milkings fewer and farther between,</span>`);
 				} else {
-					r.push(`${He}'s too trusting for obedience and often needs to be punished.`);
-					punishments = 2;
-					rewards = 0;
+					r.push(`${he}'s <span class="gold">denied</span> ${his} next orgasm,`);
 				}
-			} else {
-				if (slave.trust < -50) {
-					r.push(`${He}'s only obedient out of terror, so ${he} sometimes needs to be punished.`);
-					punishments = 1;
-					rewards = 0;
-				} else {
-					r.push(`${He} hates ${you} too much to obey, so ${he} needs constant punishment.`);
-					punishments = 3;
-					rewards = 0;
+				r.push(`<span class="libido dec">reducing ${his} libido</span> but breaking ${him} to <span class="hotpink">sexual obedience.</span>`);
+				if (slave.energy > 2) {
+					slave.energy -= 2 * punishments;
 				}
-			}
-		}
+				slave.devotion += punishments;
+				slave.trust -= punishments;
+				return r;
 
-		combinedText = (slave.rules.reward === slave.rules.punishment) && rewards > 0 && punishments > 0;
-		if (rewards > 0) {
-			r.push(...rewardFuncs[slave.rules.reward]());
-		}
-		if (punishments > 0) {
-			r.push(...punishFuncs[slave.rules.punishment]());
+			case "situational":
+				if (!combinedText) {
+					r.push(`When ${he} disobeys, ${he}'s <span class="gold">punished</span> situationally, letting ${him} develop normally.`);
+				}
+				slave.trust -= punishments;
+				return r;
 		}
-		return r.join(' ');
 	}
-
-	return rewardAndPunish;
-})();
+};
diff --git a/src/endWeek/saRivalries.js b/src/endWeek/saRivalries.js
index a29b5291c5ad4068d95fb85fb66da0c356370f72..c12986b7cb64042c0653b7d2eba9c1056d8e2f8e 100644
--- a/src/endWeek/saRivalries.js
+++ b/src/endWeek/saRivalries.js
@@ -1,40 +1,30 @@
-App.SlaveAssignment.rivalries = (function() {
-	"use strict";
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.rivalries = function saRivalries(slave) {
+	/** @type {string[]} */
+	const r = [];
 
-	let r;
+	let changed = false;
 
-	let he;
-	let him;
-	let his;
+	const {
+		he, him, his
+	} = getPronouns(slave);
 
-	let changed;
-
-	return saRivalries;
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @returns {string}
-	 */
-	function saRivalries(slave) {
-		r = [];
-
-		({
-			he, him, his
-		} = getPronouns(slave));
-
-		if (canStartRivalry(slave)) {
-			if (isSlaveAvailable(slave) && slave.assignment !== Job.CONFINEMENT) {
-				generateRivalry(slave);
-			}
-		} else if (slave.rivalry) {
-			existingRivalry(slave);
-		}
-		if (slave.rivalry) {
-			rivalryValidation(slave);
+	if (canStartRivalry(slave)) {
+		if (isSlaveAvailable(slave) && slave.assignment !== Job.CONFINEMENT) {
+			generateRivalry(slave);
 		}
-
-		return r.join(" ");
+	} else if (slave.rivalry) {
+		existingRivalry(slave);
 	}
+	if (slave.rivalry) {
+		rivalryValidation(slave);
+	}
+
+	return r.join(" ");
+
 
 	/** Can this slave possibly get a new rival?
 	 * @param {App.Entity.SlaveState} slave
@@ -352,4 +342,4 @@ App.SlaveAssignment.rivalries = (function() {
 			slave.rivalryTarget = 0;
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saRules.js b/src/endWeek/saRules.js
index ca1ba60d12aec6feb0ac0fe401abfe94cf9b261b..f76ffc75a756a6dae7191a9f1ae1d13e9043099d 100644
--- a/src/endWeek/saRules.js
+++ b/src/endWeek/saRules.js
@@ -30,7 +30,7 @@ App.SlaveAssignment.rules = function(slave) {
 					} else if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off, not that ${he} gets a choice.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (slave.devotion <= 20) {
 							r.push(`gets off at work despite ${his} reluctance, <span class="hotpink">habituating ${him} to being a fuckhole.</span>`);
 							slave.devotion += 1;
@@ -63,7 +63,7 @@ App.SlaveAssignment.rules = function(slave) {
 					if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (App.Utils.hasNonassignmentSex(slave)) {
 							r.push(`gets off at work as well as during ${his} rest time.`);
 						} else if (release.masturbation === 0) {
@@ -125,7 +125,7 @@ App.SlaveAssignment.rules = function(slave) {
 					} else if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off, not that ${his} clients care.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (slave.devotion <= 20) {
 							r.push(`gets off at work despite ${his} reluctance, <span class="hotpink">habituating ${him} to sexual slavery.</span>`);
 							slave.devotion += 1;
@@ -298,7 +298,7 @@ App.SlaveAssignment.rules = function(slave) {
 					if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (App.Utils.hasNonassignmentSex(slave)) {
 							r.push(`gets off at work as well as during ${his} rest time.`);
 						} else if (release.masturbation === 0) {
@@ -360,7 +360,7 @@ App.SlaveAssignment.rules = function(slave) {
 					} else if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off, not that ${his} spectators care.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (slave.devotion <= 20) {
 							r.push(`gets off at work despite ${his} reluctance, <span class="hotpink">habituating ${him} to sexual slavery.</span>`);
 							slave.devotion += 1;
@@ -488,11 +488,11 @@ App.SlaveAssignment.rules = function(slave) {
 					r.push(App.SlaveAssignment.rewardAndPunishment(slave));
 					break;
 				case "be the Nurse":
-					slave.need -= (V.flSex.size * 3);
+					slave.need -= App.EndWeek.saVars.flSex.size * 3;
 					if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (App.Utils.hasNonassignmentSex(slave)) {
 							r.push(`gets off at work as well as during ${his} rest time.`);
 						} else if (release.masturbation === 0) {
@@ -824,11 +824,11 @@ App.SlaveAssignment.rules = function(slave) {
 					r.push(App.SlaveAssignment.rewardAndPunishment(slave));
 					break;
 				case "be the Wardeness":
-					slave.need -= (V.flSex.size * 5);
+					slave.need -= App.EndWeek.saVars.flSex.size * 5;
 					if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						r.push(`gets off at work, so ${he} doesn't feel the need for release that often.`);
 						slave.need -= 20;
 					} else {
@@ -877,7 +877,7 @@ App.SlaveAssignment.rules = function(slave) {
 					break;
 				case "be confined in the cellblock":
 					wardenFunTimes = 0;
-					if (V.flSex.has(slave.ID)) {
+					if (App.EndWeek.saVars.flSex.has(slave.ID)) {
 						wardenFunTimes = random(0, 5);
 						slave.need -= (10 * wardenFunTimes);
 					}
@@ -914,7 +914,7 @@ App.SlaveAssignment.rules = function(slave) {
 								}
 							}
 						}
-						if (slave.need < slave.needCap * 0.5) {
+						if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 							if (slave.devotion <= 20) {
 								r.push(`gets off despite ${his} reluctance, <span class="hotpink">habituating ${him} to sexual slavery.</span>`);
 								slave.devotion += 1;
@@ -1003,11 +1003,11 @@ App.SlaveAssignment.rules = function(slave) {
 					r.push(App.SlaveAssignment.rewardAndPunishment(slave));
 					break;
 				case "be the Attendant":
-					slave.need -= (V.flSex.size * 3);
+					slave.need -= App.EndWeek.saVars.flSex.size * 3;
 					if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (App.Utils.hasNonassignmentSex(slave)) {
 							r.push(`gets off at work as well as during ${his} rest time.`);
 						} else if (release.masturbation === 0) {
@@ -1070,7 +1070,7 @@ App.SlaveAssignment.rules = function(slave) {
 					} else if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off.`);
 						slave.need = 0;
-					} else if (V.flSex.has(slave.ID)) {
+					} else if (App.EndWeek.saVars.flSex.has(slave.ID)) {
 						r.push(`is routinely relieved of any built up tension by ${S.Attendant.slaveName} and ${his}`);
 						if (canPenetrate(slave) && S.Attendant.boobs >= 500) {
 							r.push(`luscious breasts.`);
@@ -1210,11 +1210,11 @@ App.SlaveAssignment.rules = function(slave) {
 					r.push(App.SlaveAssignment.rewardAndPunishment(slave));
 					break;
 				case "be the Matron":
-					slave.need -= (V.flSex.size * 3);
+					slave.need -= App.EndWeek.saVars.flSex.size * 3;
 					if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (release.masturbation === 0) {
 							r.push(`gets off while relieving ${his} charges, so being forbidden from masturbation doesn't really bother ${him}.`);
 						} else {
@@ -1274,7 +1274,7 @@ App.SlaveAssignment.rules = function(slave) {
 					} else if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off.`);
 						slave.need = 0;
-					} else if (V.flSex.has(slave.ID)) {
+					} else if (App.EndWeek.saVars.flSex.has(slave.ID)) {
 						r.push(`is routinely relieved of any built up tension by ${S.Matron.slaveName} and ${his}`);
 						if (canPenetrate(slave) && S.Matron.boobs >= 500) {
 							r.push(`luscious breasts.`);
@@ -1404,11 +1404,11 @@ App.SlaveAssignment.rules = function(slave) {
 					r.push(App.SlaveAssignment.rewardAndPunishment(slave));
 					break;
 				case "be the Schoolteacher":
-					slave.need -= (V.flSex.size * 10);
+					slave.need -= App.EndWeek.saVars.flSex.size * 10;
 					if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (release.masturbation === 0) {
 							r.push(`gets off with ${his} students, so being forbidden from masturbation doesn't really bother ${him}.`);
 						} else {
@@ -1466,7 +1466,7 @@ App.SlaveAssignment.rules = function(slave) {
 					r.push(App.SlaveAssignment.rewardAndPunishment(slave));
 					break;
 				case "learn in the schoolroom":
-					if (V.flSex.has(slave.ID)) {
+					if (App.EndWeek.saVars.flSex.has(slave.ID)) {
 						slave.need -= 30;
 						seX(slave, "oral", S.Schoolteacher, "oral", 7);
 						if (canPenetrate(S.Schoolteacher) && slave.boobs > 500) {
@@ -1512,7 +1512,7 @@ App.SlaveAssignment.rules = function(slave) {
 					} else if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (slave.devotion <= 20) {
 							r.push(`gets off during class despite ${his} reluctance, <span class="hotpink">habituating ${him} to sexual slavery.</span>`);
 							slave.devotion += 1;
@@ -1571,7 +1571,7 @@ App.SlaveAssignment.rules = function(slave) {
 					if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (release.masturbation === 0) {
 							r.push(`gets off while performing ${his} duties, so being forbidden from masturbation doesn't really bother ${him}.`);
 							slave.need -= 20;
@@ -1633,7 +1633,7 @@ App.SlaveAssignment.rules = function(slave) {
 					} else if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (slave.devotion <= 20) {
 							r.push(`gets off at work despite ${his} reluctance, <span class="hotpink">habituating ${him} to sexual slavery.</span>`);
 							slave.devotion += 1;
@@ -1830,7 +1830,7 @@ App.SlaveAssignment.rules = function(slave) {
 					if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (release.masturbation === 0) {
 							r.push(`gets off while performing ${his} duties, so being forbidden from masturbation doesn't really bother ${him}.`);
 						} else {
@@ -1900,7 +1900,7 @@ App.SlaveAssignment.rules = function(slave) {
 						} else if (slave.energy <= 20) {
 							r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 							slave.need = 0;
-						} else if (slave.need < slave.needCap * 0.5) {
+						} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 							if (slave.devotion <= 20) {
 								r.push(`gets off from being milked despite ${his} reluctance, <span class="hotpink">habituating ${him} to sexual slavery.</span>`);
 								slave.devotion += 1;
@@ -2128,7 +2128,7 @@ App.SlaveAssignment.rules = function(slave) {
 					if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (release.masturbation === 0) {
 							r.push(`gets off while performing ${his} duties, so being forbidden from masturbation doesn't really bother ${him}.`);
 							slave.need -= 20;
@@ -2189,7 +2189,7 @@ App.SlaveAssignment.rules = function(slave) {
 					} else if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (slave.devotion <= 20) {
 							r.push(`gets off from working as a farmhand despite ${his} reluctance, <span class="hotpink">habituating ${him} to sexual slavery.</span>`);
 							slave.devotion += 1;
@@ -2395,7 +2395,7 @@ App.SlaveAssignment.rules = function(slave) {
 					} else if (V.masterSuiteUpgradeLuxury === 2 && L.masterSuite > 3) {
 						r.push(`never goes unsatisfied with all the action in the fuckpit.`);
 						slave.need -= 80;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (slave.devotion <= 20) {
 							r.push(`gets off regularly despite ${his} reluctance, <span class="hotpink">habituating ${him} to sexual slavery.</span>`);
 							slave.devotion += 1;
@@ -2472,7 +2472,7 @@ App.SlaveAssignment.rules = function(slave) {
 					} else if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off, though it doesn't stop ${S.HeadGirl.slaveName}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (slave.devotion <= 20) {
 							r.push(`gets off with ${S.HeadGirl.slaveName} despite ${his} reluctance, <span class="hotpink">habituating ${him} to sexual slavery.</span>`);
 							slave.devotion += 1;
@@ -2538,7 +2538,7 @@ App.SlaveAssignment.rules = function(slave) {
 					} else if (slave.energy <= 20) {
 						r.push(`is frigid and has little interest in getting off${(App.Utils.releaseRestricted(slave)) ? `, making the rule restricting ${his} sexual outlets superfluous` : ``}.`);
 						slave.need = 0;
-					} else if (slave.need < slave.needCap * 0.5) {
+					} else if (slave.need < App.EndWeek.saVars.needCapPerSlave[slave.ID] * 0.5) {
 						if (slave.devotion <= 20) {
 							r.push(`gets off at work despite ${his} reluctance, <span class="hotpink">habituating ${him} to sexual slavery.</span>`);
 							slave.devotion += 1;
diff --git a/src/endWeek/saRulesFunctions.js b/src/endWeek/saRulesFunctions.js
index ab06cf112cce4a25d5f89d5f5739d8ba7567f982..165ca14d7fd92dceb7fe4234c7dc0d5c6e1a8fcb 100644
--- a/src/endWeek/saRulesFunctions.js
+++ b/src/endWeek/saRulesFunctions.js
@@ -191,82 +191,84 @@ App.EndWeek.Rules.playerDiscoversFetish = function(slave) {
 	const el = new DocumentFragment();
 	const {he, him, his} = getPronouns(slave);
 	if (slave.fetishKnown === 0) {
-		if (App.EndWeek.saVars.freeSexualEnergy > 0) {
-			if (App.EndWeek.saVars.freeSexualEnergy > random(0, 5)) {
-				slave.fetishKnown = 1;
-				el.append(`You discover that ${he} really likes it when you `);
-				switch (slave.fetish) {
-					case "submissive":
-						el.append(`hold ${him} down and fuck ${him}; `);
-						App.UI.DOM.appendNewElement("span", el, `${he}'s a submissive!`, "lightcoral");
-						break;
-					case "cumslut":
-						if (V.PC.dick !== 0) {
-							el.append(`cum in ${his} mouth; `);
-							App.UI.DOM.appendNewElement("span", el, `${he}'s a cumslut!`, "lightcoral");
-						} else {
-							el.append(`use your strap-on in ${his} mouth; `);
-							App.UI.DOM.appendNewElement("span", el, `${he}'s a cumslut!`, "lightcoral");
-						}
-						break;
-					case "humiliation":
-						el.append(`use ${him} in public; `);
-						App.UI.DOM.appendNewElement("span", el, `${he}'s a humiliation fetishist!`, "lightcoral");
-						break;
-					case "buttslut":
-						if (canDoAnal(slave)) {
-							el.append(`fuck ${his} butt `);
-						} else {
-							el.append(`tease ${his} anus `);
-						}
-						App.UI.DOM.appendNewElement("span", el, `${he}'s an anal slut!`, "lightcoral");
-						break;
-					case "boobs":
-						el.append(`fondle ${his} breasts; `);
-						App.UI.DOM.appendNewElement("span", el, `${he}'s a boob fetishist!`, "lightcoral");
-						break;
-					case "sadist":
-						el.append(`let ${him} help you abuse other slaves; `);
-						App.UI.DOM.appendNewElement("span", el, `${he}'s a sadist!`, "lightcoral");
-						break;
-					case "masochist":
-						el.append(`hurt ${him}; `);
-						App.UI.DOM.appendNewElement("span", el, `${he}'s a masochist!`, "lightcoral");
-						break;
-					case "dom":
-						el.append(`let ${him} help you use other slaves; `);
-						App.UI.DOM.appendNewElement("span", el, `${he}'s dominant!`, "lightcoral");
-						break;
-					case "pregnancy":
-						if (V.PC.dick !== 0) {
-							if (slave.mpreg === 0) {
-								el.append(`come `);
-								if (canDoVaginal(slave)) {
-									el.append(`inside `);
-								} else {
-									el.append(`on `);
-								}
-								el.append(`${him}; `);
-								App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, "lightcoral");
+		if (App.EndWeek.saVars.freeSexualEnergy > random(0, 5)) {
+			slave.fetishKnown = 1;
+			el.append(`You discover that ${he} really likes it when you `);
+			switch (slave.fetish) {
+				case "submissive":
+					el.append(`hold ${him} down and fuck ${him}; `);
+					App.UI.DOM.appendNewElement("span", el, `${he}'s a submissive!`, ["lightcoral"]);
+					break;
+				case "cumslut":
+					if (V.PC.dick !== 0) {
+						el.append(`cum in ${his} mouth; `);
+						App.UI.DOM.appendNewElement("span", el, `${he}'s a cumslut!`, ["lightcoral"]);
+					} else {
+						el.append(`use your strap-on in ${his} mouth; `);
+						App.UI.DOM.appendNewElement("span", el, `${he}'s a cumslut!`, ["lightcoral"]);
+					}
+					break;
+				case "humiliation":
+					el.append(`use ${him} in public; `);
+					App.UI.DOM.appendNewElement("span", el, `${he}'s a humiliation fetishist!`, ["lightcoral"]);
+					break;
+				case "buttslut":
+					if (canDoAnal(slave)) {
+						el.append(`fuck ${his} butt `);
+					} else {
+						el.append(`tease ${his} anus `);
+					}
+					App.UI.DOM.appendNewElement("span", el, `${he}'s an anal slut!`, ["lightcoral"]);
+					break;
+				case "boobs":
+					el.append(`fondle ${his} breasts; `);
+					App.UI.DOM.appendNewElement("span", el, `${he}'s a boob fetishist!`, ["lightcoral"]);
+					break;
+				case "sadist":
+					el.append(`let ${him} help you abuse other slaves; `);
+					App.UI.DOM.appendNewElement("span", el, `${he}'s a sadist!`, ["lightcoral"]);
+					break;
+				case "masochist":
+					el.append(`hurt ${him}; `);
+					App.UI.DOM.appendNewElement("span", el, `${he}'s a masochist!`, ["lightcoral"]);
+					break;
+				case "dom":
+					el.append(`let ${him} help you use other slaves; `);
+					App.UI.DOM.appendNewElement("span", el, `${he}'s dominant!`, ["lightcoral"]);
+					break;
+				case "pregnancy":
+					if (V.PC.dick !== 0) {
+						if (slave.mpreg === 0) {
+							el.append(`come `);
+							if (canDoVaginal(slave)) {
+								el.append(`inside `);
 							} else {
-								el.append(`come `);
-								if (canDoAnal(slave)) {
-									el.append(`inside `);
-								} else {
-									el.append(`on `);
-								}
-								el.append(`${him}; `);
-								App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, "lightcoral");
+								el.append(`on `);
 							}
+							el.append(`${him}; `);
+							App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, ["lightcoral"]);
 						} else {
-							el.append(`talk dirty and call ${him} a mother; `);
-							App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, "lightcoral");
+							el.append(`come `);
+							if (canDoAnal(slave)) {
+								el.append(`inside `);
+							} else {
+								el.append(`on `);
+							}
+							el.append(`${him}; `);
+							App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, ["lightcoral"]);
 						}
-						break;
-					default:
+					} else {
+						el.append(`talk dirty and call ${him} a mother; `);
+						App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, ["lightcoral"]);
+					}
+					break;
+				default:
+					if (canDoVaginal(slave) && slave.vagina === 0) {
+						el.append(`touch ${him}; `);
+					} else {
 						el.append(`fuck ${him}; `);
-						App.UI.DOM.appendNewElement("span", el, `${he}'s got a normal sexuality.`, "lightcoral");
-				}
+					}
+					App.UI.DOM.appendNewElement("span", el, `${he}'s got a normal sexuality.`, ["lightcoral"]);
 			}
 		}
 	}
@@ -466,24 +468,24 @@ App.EndWeek.Rules.masturbationDiscoversFetish = function(slave) {
 		el.append(`However, you start to notice a trend in ${his} fantasies,`);
 		if (slave.fetish === "submissive") {
 			el.append(`${he} likes to tie ${himself} up and boss ${himself} around; `);
-			App.UI.DOM.appendNewElement("span", el, `${he}'s a submissive!`, "lightcoral");
+			App.UI.DOM.appendNewElement("span", el, `${he}'s a submissive!`, ["lightcoral"]);
 		} else if (slave.fetish === "cumslut") {
 			if (slave.dick > 0) {
 				el.append(`${he} often eats ${his} own cum when ${he}'s finished; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a cumslut!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a cumslut!`, ["lightcoral"]);
 			} else {
 				el.append(`${he} likes to have something, anything, in ${his} mouth while ${he} masturbates; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a cumslut!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a cumslut!`, ["lightcoral"]);
 			}
 		} else if (slave.fetish === "humiliation") {
 			el.append(`${he} tends to masturbate in places where others can walk in on ${him}; `);
-			App.UI.DOM.appendNewElement("span", el, `${he}'s a humiliation fetishist!`, "lightcoral");
+			App.UI.DOM.appendNewElement("span", el, `${he}'s a humiliation fetishist!`, ["lightcoral"]);
 		} else if (slave.fetish === "buttslut") {
 			el.append(`${he} always pays special attention to ${his} butthole; `);
-			App.UI.DOM.appendNewElement("span", el, `${he}'s an anal slut!`, "lightcoral");
+			App.UI.DOM.appendNewElement("span", el, `${he}'s an anal slut!`, ["lightcoral"]);
 		} else if (slave.fetish === "boobs") {
 			el.append(`${he} always has a hand to ${his} nipples; `);
-			App.UI.DOM.appendNewElement("span", el, `${he}'s a boob fetishist!`, "lightcoral");
+			App.UI.DOM.appendNewElement("span", el, `${he}'s a boob fetishist!`, ["lightcoral"]);
 			if (slave.lactation > 0) {
 				slave.lactationDuration = 2;
 				slave.boobs -= slave.boobsMilk;
@@ -493,21 +495,21 @@ App.EndWeek.Rules.masturbationDiscoversFetish = function(slave) {
 			}
 		} else if (slave.fetish === "sadist") {
 			el.append(`${he} tends to threaten ${his} toys; `);
-			App.UI.DOM.appendNewElement("span", el, `${he}'s a sadist!`, "lightcoral");
+			App.UI.DOM.appendNewElement("span", el, `${he}'s a sadist!`, ["lightcoral"]);
 		} else if (slave.fetish === "masochist") {
 			el.append(`${he} often to abuses ${himself}; `);
-			App.UI.DOM.appendNewElement("span", el, `${he}'s a masochist!`, "lightcoral");
+			App.UI.DOM.appendNewElement("span", el, `${he}'s a masochist!`, ["lightcoral"]);
 		} else if (slave.fetish === "dom") {
 			el.append(`${he} sometimes bosses ${his} toys around; `);
-			App.UI.DOM.appendNewElement("span", el, `${he}'s dominant!`, "lightcoral");
+			App.UI.DOM.appendNewElement("span", el, `${he}'s dominant!`, ["lightcoral"]);
 		} else if (slave.fetish === "pregnancy") {
 			el.append(`${he} frequently pretends to either get pregnant, be pregnant, or get someone else pregnant; `);
-			App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, "lightcoral");
+			App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, ["lightcoral"]);
 		} else if (slave.energy > 95) {
 			el.append(`${he}'s always horny; `);
-			App.UI.DOM.appendNewElement("span", el, `${he}'s a nympho!`, "lightcoral");
+			App.UI.DOM.appendNewElement("span", el, `${he}'s a nympho!`, ["lightcoral"]);
 		} else {
-			App.UI.DOM.appendNewElement("span", el, `they are incredibly mundane.`, "lightcoral");
+			App.UI.DOM.appendNewElement("span", el, `they are incredibly mundane.`, ["lightcoral"]);
 		}
 	}
 	return el;
@@ -623,7 +625,7 @@ App.EndWeek.Rules.rapeFetish = function(slave) {
 	if (slave.fetishKnown === 1 && slave.fetishStrength > 60) {
 		if (slave.fetish === "submissive") {
 			el.append(`plead that ${who} fuck ${him}. `);
-			if (App.EndWeek.saVars.averageDick > 4) {
+			if (V.seeStretching === 1 && App.EndWeek.saVars.averageDick > 4) {
 				if (slave.anus.isBetween(0, 3) && canDoAnal(slave)) {
 					if ((slave.anus * 40) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 						App.UI.DOM.appendNewElement("span", el, `${His} asshole is loosened `, "lime");
@@ -682,7 +684,7 @@ App.EndWeek.Rules.rapeFetish = function(slave) {
 			}
 		} else if (slave.fetish === "buttslut" && canDoAnal(slave)) {
 			el.append(`demand that ${who} penetrate ${his} anus. `);
-			if (App.EndWeek.saVars.averageDick > 4) {
+			if (V.seeStretching === 1 && App.EndWeek.saVars.averageDick > 4) {
 				if (slave.anus.isBetween(0, 3) && canDoAnal(slave)) {
 					if ((slave.anus * 30) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 						el.append(`Since most of the slaves ${he} demands anal sex from are extremely hung, `);
@@ -779,7 +781,7 @@ App.EndWeek.Rules.rapeFetish = function(slave) {
 			}
 		} else if (slave.fetish === "masochist") {
 			el.append(`demand that ${who} hurt ${him}. `);
-			if (App.EndWeek.saVars.averageDick > 4) {
+			if (V.seeStretching === 1 && App.EndWeek.saVars.averageDick > 4) {
 				if (slave.anus.isBetween(0, 3) && canDoAnal(slave)) {
 					if ((slave.anus * 30) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 						App.UI.DOM.appendNewElement("span", el, `${His} asshole is loosened `, "lime");
@@ -835,7 +837,7 @@ App.EndWeek.Rules.rapeFetish = function(slave) {
 			el.append(`demand that ${who} indulge ${his} pregnancy fetish. `);
 			if (App.EndWeek.saVars.averageDick > 5) {
 				if (slave.mpreg === 0) {
-					if (slave.vagina.isBetween(0, 3) && canDoVaginal(slave)) {
+					if (V.seeStretching === 1 && slave.vagina.isBetween(0, 3) && canDoVaginal(slave)) {
 						if ((slave.vagina * 40) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 							el.append(`Since ${he} constantly demands to be fucked deeply to get ${his} womb filled with cum, `);
 							App.UI.DOM.appendNewElement("span", el, `${his} cunt gets stretched out.`, "lime");
@@ -844,7 +846,7 @@ App.EndWeek.Rules.rapeFetish = function(slave) {
 						}
 					}
 				} else {
-					if (slave.anus.isBetween(0, 3) && canDoAnal(slave)) {
+					if (V.seeStretching === 1 && slave.anus.isBetween(0, 3) && canDoAnal(slave)) {
 						if ((slave.anus * 40) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 							el.append(`Since ${he} constantly demands to be fucked deeply to get ${his} womb filled with cum, `);
 							App.UI.DOM.appendNewElement("span", el, `${his} ass gets stretched out.`, "lime");
@@ -859,7 +861,7 @@ App.EndWeek.Rules.rapeFetish = function(slave) {
 			}
 		} else if (slave.energy > 95) {
 			el.append(`demand that ${who} satisfy ${his} formidable appetites. `);
-			if (App.EndWeek.saVars.averageDick > 4) {
+			if (V.seeStretching === 1 && App.EndWeek.saVars.averageDick > 4) {
 				if (slave.anus.isBetween(0, 3) && canDoAnal(slave)) {
 					if ((slave.anus * 30) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 						App.UI.DOM.appendNewElement("span", el, `${His} asshole is loosened `, "lime");
@@ -915,7 +917,7 @@ App.EndWeek.Rules.consentFetish = function(slave) {
 	if (slave.fetishKnown === 1 && slave.fetishStrength > 60) {
 		if (slave.fetish === "submissive") {
 			el.append(`usually pairing off with a more dominant slave. `);
-			if (App.EndWeek.saVars.averageDick > 4) {
+			if (V.seeStretching === 1 && App.EndWeek.saVars.averageDick > 4) {
 				if (slave.anus.isBetween(0, 3) && canDoAnal(slave)) {
 					if ((slave.anus * 40) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 						App.UI.DOM.appendNewElement("span", el, `${His} asshole is loosened `, "lime");
@@ -959,7 +961,7 @@ App.EndWeek.Rules.consentFetish = function(slave) {
 				el.append(`tease ${his} virgin anus `);
 			}
 			el.append(`in return. `);
-			if (App.EndWeek.saVars.averageDick > 4) {
+			if (V.seeStretching === 1 && App.EndWeek.saVars.averageDick > 4) {
 				if (slave.anus.isBetween(0, 3) && canDoAnal(slave)) {
 					if ((slave.anus * 30) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 						el.append(`Since most of the slaves ${he} enjoys anal sex with are extremely hung, `);
@@ -986,7 +988,7 @@ App.EndWeek.Rules.consentFetish = function(slave) {
 			}
 		} else if (slave.fetish === "masochist") {
 			el.append(`usually pairing off with an abusive slave. `);
-			if (App.EndWeek.saVars.averageDick > 4) {
+			if (V.seeStretching === 1 && App.EndWeek.saVars.averageDick > 4) {
 				if (slave.anus.isBetween(0, 3) && canDoAnal(slave)) {
 					if ((slave.anus * 30) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 						App.UI.DOM.appendNewElement("span", el, `${His} asshole is loosened, `, "lime");
@@ -1016,7 +1018,7 @@ App.EndWeek.Rules.consentFetish = function(slave) {
 		} else if (slave.fetish === "pregnancy") {
 			el.append(`doing ${his} best to pair off with any pregnant slaves. `);
 			if (slave.mpreg === 0) {
-				if (App.EndWeek.saVars.averageDick > 5) {
+				if (V.seeStretching === 1 && App.EndWeek.saVars.averageDick > 5) {
 					if (slave.vagina.isBetween(0, 3) && canDoVaginal(slave)) {
 						if ((slave.vagina * 40) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 							el.append(`${He} also takes cock whenever ${he} can, begging to be fucked deeply to get ${his} womb filled with cum, so `);
@@ -1027,7 +1029,7 @@ App.EndWeek.Rules.consentFetish = function(slave) {
 					}
 				}
 			} else {
-				if (App.EndWeek.saVars.averageDick > 5) {
+				if (V.seeStretching === 1 && App.EndWeek.saVars.averageDick > 5) {
 					if (slave.anus.isBetween(0, 3) && canDoAnal(slave)) {
 						if ((slave.anus * 40) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 							el.append(`${He} also takes cock whenever ${he} can, begging to be fucked deeply to get ${his} womb filled with cum, so `);
@@ -1044,7 +1046,7 @@ App.EndWeek.Rules.consentFetish = function(slave) {
 			}
 		} else if (slave.energy > 95) {
 			el.append(`and has to give out a lot of favors to get enough attention for ${himself}. `);
-			if (App.EndWeek.saVars.averageDick > 4) {
+			if (V.seeStretching === 1 && App.EndWeek.saVars.averageDick > 4) {
 				if (slave.anus.isBetween(0, 3) && canDoAnal(slave)) {
 					if ((slave.anus * 30) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 						App.UI.DOM.appendNewElement("span", el, `${His} asshole is loosened `, "lime");
@@ -1100,13 +1102,13 @@ App.EndWeek.Rules.consentDiscoversFetish = function(slave) {
 			el.append(`However, one of ${his} partners `);
 			if (slave.fetish === "submissive") {
 				el.append(`holds ${him} down, and ${he} loves it; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a submissive!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a submissive!`, ["lightcoral"]);
 			} else if (slave.fetish === "cumslut") {
 				el.append(`finally has to push ${him} away to get ${him} to stop sucking; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a cumslut!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a cumslut!`, ["lightcoral"]);
 			} else if (slave.fetish === "humiliation") {
 				el.append(`fucks ${him} in public, and ${he} loves it; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a humiliation fetishist!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a humiliation fetishist!`, ["lightcoral"]);
 			} else if (slave.fetish === "buttslut") {
 				if (slave.anus > 0) {
 					if (canDoAnal(slave)) {
@@ -1118,10 +1120,10 @@ App.EndWeek.Rules.consentDiscoversFetish = function(slave) {
 				} else {
 					el.append(`teases ${his} virgin anus, and ${he} loves it;`);
 				}
-				App.UI.DOM.appendNewElement("span", el, `${he}'s an anal slut!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s an anal slut!`, ["lightcoral"]);
 			} else if (slave.fetish === "boobs") {
 				el.append(`fondles ${his} breasts, and ${he} loves it; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a boob fetishist!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a boob fetishist!`, ["lightcoral"]);
 				if (slave.lactation > 0) {
 					slave.lactationDuration = 2;
 					slave.boobs -= slave.boobsMilk;
@@ -1131,22 +1133,22 @@ App.EndWeek.Rules.consentDiscoversFetish = function(slave) {
 				}
 			} else if (slave.fetish === "sadist") {
 				el.append(`asks ${slave.slaveName} to hit ${him}, which ${slave.slaveName} enjoys doing; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a sadist!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a sadist!`, ["lightcoral"]);
 			} else if (slave.fetish === "masochist") {
 				el.append(`hits ${slave.slaveName} while fucking ${him}, which only makes ${him} hornier; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a masochist!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a masochist!`, ["lightcoral"]);
 			} else if (slave.fetish === "dom") {
 				el.append(`asks ${slave.slaveName} to make them ${slave.slaveName}'s bitch, which ${slave.slaveName} manages like a natural; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s dominant!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s dominant!`, ["lightcoral"]);
 			} else if (slave.fetish === "pregnancy") {
 				el.append(`pretends to get ${him} pregnant, which ${he} really enjoys; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, ["lightcoral"]);
 			} else if (slave.energy > 95) {
 				el.append(`discovers that ${he} cannot be satisfied; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a nympho!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a nympho!`, ["lightcoral"]);
 			} else {
 				el.append(`discovers that ${he} isn't terribly exciting; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s got a normal sexuality.`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s got a normal sexuality.`, ["lightcoral"]);
 			}
 		}
 	}
@@ -1168,13 +1170,13 @@ App.EndWeek.Rules.rapeDiscoversFetish = function(slave) {
 			el.append(`You discover that ${he} really likes it when the other slaves `);
 			if (slave.fetish === "submissive") {
 				el.append(`hold ${him} down and fuck ${him}; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a submissive!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a submissive!`, ["lightcoral"]);
 			} else if (slave.fetish === "cumslut") {
 				el.append(`cum in ${his} mouth; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a cumslut!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a cumslut!`, ["lightcoral"]);
 			} else if (slave.fetish === "humiliation") {
 				el.append(`use ${him} in public; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a humiliation fetishist!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a humiliation fetishist!`, ["lightcoral"]);
 			} else if (slave.fetish === "buttslut") {
 				if (slave.anus > 0) {
 					if (canDoAnal(slave)) {
@@ -1185,10 +1187,10 @@ App.EndWeek.Rules.rapeDiscoversFetish = function(slave) {
 				} else {
 					el.append(`tease ${his} virgin anus;`);
 				}
-				App.UI.DOM.appendNewElement("span", el, `${he}'s an anal slut!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s an anal slut!`, ["lightcoral"]);
 			} else if (slave.fetish === "boobs") {
 				el.append(`fondle ${his} breasts; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a boob fetishist!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a boob fetishist!`, ["lightcoral"]);
 				if (slave.lactation > 0) {
 					slave.lactationDuration = 2;
 					slave.boobs -= slave.boobsMilk;
@@ -1198,13 +1200,13 @@ App.EndWeek.Rules.rapeDiscoversFetish = function(slave) {
 				}
 			} else if (slave.fetish === "sadist") {
 				el.append(`let ${him} abuse them; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a sadist!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a sadist!`, ["lightcoral"]);
 			} else if (slave.fetish === "masochist") {
 				el.append(`hurt ${him}; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s a masochist!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s a masochist!`, ["lightcoral"]);
 			} else if (slave.fetish === "dom") {
 				el.append(`let ${him} dominate them; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s dominant!`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s dominant!`, ["lightcoral"]);
 			} else if (slave.fetish === "pregnancy") {
 				if (slave.mpreg === 0) {
 					el.append(`come `);
@@ -1214,7 +1216,7 @@ App.EndWeek.Rules.rapeDiscoversFetish = function(slave) {
 						el.append(`on `);
 					}
 					el.append(`${him}; `);
-					App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, "lightcoral");
+					App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, ["lightcoral"]);
 				} else {
 					el.append(`come `);
 					if (canDoAnal(slave)) {
@@ -1223,11 +1225,11 @@ App.EndWeek.Rules.rapeDiscoversFetish = function(slave) {
 						el.append(`on `);
 					}
 					el.append(`${him}; `);
-					App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, "lightcoral");
+					App.UI.DOM.appendNewElement("span", el, `${he}'s a pregnancy fetishist!`, ["lightcoral"]);
 				}
 			} else {
 				el.append(`fuck ${him}; `);
-				App.UI.DOM.appendNewElement("span", el, `${he}'s got a normal sexuality.`, "lightcoral");
+				App.UI.DOM.appendNewElement("span", el, `${he}'s got a normal sexuality.`, ["lightcoral"]);
 			}
 		}
 	}
diff --git a/src/endWeek/saServant.js b/src/endWeek/saServant.js
index ef1f299fcec6923e1dec4774a0f7d1283f5af966..968505b33ce52ce512c8dfa1e3faabf6975dc9f5 100644
--- a/src/endWeek/saServant.js
+++ b/src/endWeek/saServant.js
@@ -1,60 +1,33 @@
-App.SlaveAssignment.servant = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @param {number} [stewardessBonus=0] - bonus from facility leader effects
+ * @returns {string}
+ */
+App.SlaveAssignment.servant = function saServant(slave, stewardessBonus = 0) {
+	/** @type {string[]} */
+	const r = [];
 
-	let r;
+	const {
+		he, him, his, himself, He, His, wife
+	} = getPronouns(slave);
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let He;
-	let His;
-	let wife;
+	let cash = 0;
 
-	let cash;
-	let oralUse;
-	let stewardessBonus;
-
-	return saServant;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @param {number} [bonus=0] - bonus from facility leader effects
-	 * @returns {string}
-	 */
-	function saServant(slave, bonus = 0) {
-		r = [];
-		stewardessBonus = bonus;
-
-		({
-			he, him, his, himself, He, His, wife
-		} = getPronouns(slave));
-
-		cash = 0;
-		oralUse = jsRandom(5, 10);
-		if (V.policies.gumjobFetishism === 1) {
-			if (slave.teeth !== "removable") {
-				oralUse = Math.trunc(oralUse / 2);
-			} else {
-				oralUse = Math.trunc(oralUse * 1.5);
-			}
+	jobPreface(slave);
+	if (V.servantsQuarters > 0) {
+		if ((V.universalRulesFacilityWork === 1 && slave.assignment === window.Job.HOUSE && V.servantsQuartersSpots > 0) || (slave.assignment === window.Job.QUARTER)) {
+			facilityEffects(slave);
 		}
+	}
+	jobReaction(slave);
+	jobEffects(slave);
+	physicalEffects(slave);
+	if (V.showVignettes === 1 && (slave.assignment === window.Job.QUARTER || slave.assignment === window.Job.HOUSE)) {
+		assignmentVignette(slave);
+	}
 
-		jobPreface(slave);
-		if (V.servantsQuarters > 0) {
-			if ((V.universalRulesFacilityWork === 1 && slave.assignment === window.Job.HOUSE && V.servantsQuartersSpots > 0) || (slave.assignment === window.Job.QUARTER)) {
-				facilityEffects(slave);
-			}
-		}
-		jobReaction(slave);
-		jobEffects(slave);
-		physicalEffects(slave);
-		if (V.showVignettes === 1 && (slave.assignment === window.Job.QUARTER || slave.assignment === window.Job.HOUSE)) {
-			assignmentVignette(slave);
-		}
+	return r.join(" ");
 
-		return r.join(" ");
-	}
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
@@ -133,15 +106,29 @@ App.SlaveAssignment.servant = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
 	 */
-	function jobEffects(slave) {
+	function doOralUse(slave) {
 		// TODO: this flat unchecked oral sex is a bit problematic
 		// who is she serving and why aren't they benefiting?
 		// is the current number of servants correct to accomplish this task?
 		// why can't the player prevent this on-assignment sex while still getting the other benefits of having a servant?
+		let oralUse = jsRandom(5, 10);
+		if (V.policies.gumjobFetishism === 1) {
+			if (slave.teeth !== "removable") {
+				oralUse = Math.trunc(oralUse / 2);
+			} else {
+				oralUse = Math.trunc(oralUse * 1.5);
+			}
+		}
 		oralUse = Math.ceil(oralUse * restEffects(slave, 11));
 		actX(slave, "oral", oralUse);
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	function jobEffects(slave) {
+		doOralUse(slave);
 
 		if (slave.relationship === -2) {
 			r.push(`${He} does ${his} best to perfect your domesticity due to ${his} emotional bond to you.`);
@@ -193,7 +180,6 @@ App.SlaveAssignment.servant = (function() {
 
 	/**
 	 * @param {FC.ReportSlave} slave
-	 *
 	 */
 	function physicalEffects(slave) {
 		if (slave.health.illness > 0 || slave.health.tired > 60) {
@@ -377,4 +363,4 @@ App.SlaveAssignment.servant = (function() {
 			repX((modifier * vignette.effect * 0.1), "vignette", slave);
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saServeThePublic.js b/src/endWeek/saServeThePublic.js
index 5da7e14dd04dde848ff202fac43fd95856430684..ab9180f36cb3f4ee6618210960c109ccc9f5ba57 100644
--- a/src/endWeek/saServeThePublic.js
+++ b/src/endWeek/saServeThePublic.js
@@ -1,85 +1,66 @@
-App.SlaveAssignment.serveThePublic = (function() {
-	"use strict";
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.serveThePublic = function saServeThePublic(slave) {
+	const {
+		he, him, his, hers, himself, girl, He, His, loli
+	} = getPronouns(slave);
+	const arcology = V.arcologies[0];
+	let r = ` `;
 
-	let incomeStats;
-	let r;
-	let arcology;
+	let cervixPump = 0;
 
-	let cervixPump;
-	let he;
-	let him;
-	let his;
-	let hers;
-	let himself;
-	let girl;
-	let loli;
-	let He;
-	let His;
-
-	// if the following are set outside this file, they must be set in it too!
 	let oralUse;
 	let analUse;
 	let vaginalUse;
 	let mammaryUse;
 	let penetrativeUse;
 
-	return saServeThePublic;
+	const incomeStats = gatherStatistics(slave);
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @returns {string}
-	 */
-	function saServeThePublic(slave) {
-		arcology = V.arcologies[0];
-		r = ` `;
-		({
-			he, him, his, hers, himself, girl, He, His, loli
-		} = getPronouns(slave));
+	if (slave.assignment === Job.CLUB) {
+		// By being at the end, every slave after the first will get a bonus. By moving it up, the first can enjoy it too. slaveJobValues() checks Edo Revivalist, so here we are.
+		applyFSDecoration(slave);
+	}
+	addRep(slave);
+	sexCounts(slave);
+	jobPreface(slave);
+	bonusMultiplierText(slave);
+	usageCountDescriptions(slave);
+	if (V.seeAge === 1) {
+		comingOfAge(slave);
+	}
+	mentalEffects(slave);
+	physicalEffects(slave);
+	slaveSkills(slave);
+	if (V.showEWM === 1) {
+		publicReactions(slave);
+	}
+	if (slave.sexualFlaw === "none") {
+		addFlaw(slave);
+	}
+	sexualSatiation(slave);
+	if (V.showVignettes === 1) {
+		assignmentVignette(slave);
+	}
 
-		gatherStatistics(slave);
-		if (slave.assignment === Job.CLUB) {
-			// By being at the end, every slave after the first will get a bonus. By moving it up, the first can enjoy it too. slaveJobValues() checks Edo Revivalist, so here we are.
-			applyFSDecoration(slave);
-		}
-		addRep(slave);
-		sexCounts(slave);
-		jobPreface(slave);
-		bonusMultiplierText(slave);
-		usageCountDescriptions(slave);
-		if (V.seeAge === 1) {
-			comingOfAge(slave);
-		}
-		mentalEffects(slave);
-		physicalEffects(slave);
-		slaveSkills(slave);
-		if (V.showEWM === 1) {
-			publicReactions(slave);
-		}
-		if (slave.sexualFlaw === "none") {
-			addFlaw(slave);
-		}
-		sexualSatiation(slave);
-		if (V.showVignettes === 1) {
-			assignmentVignette(slave);
-		}
+	return r;
 
-		return r;
-	}
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
+	 * @returns {Object}
 	 */
 	function gatherStatistics(slave) {
-		/* Statistics gathering */
 		const facility = (slave.assignment === Job.CLUB || slave.assignment === Job.DJ) ? V.facility.club : undefined;
-		incomeStats = getSlaveStatisticData(slave, facility);
+		const incomeStats = getSlaveStatisticData(slave, facility);
 		incomeStats.customers = slave.sexAmount;
+		return incomeStats;
 	}
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
 	 */
 	function jobPreface(slave) {
 		if (slave.devotion > 95 || slave.energy > 95) {
@@ -422,7 +403,7 @@ App.SlaveAssignment.serveThePublic = (function() {
 					slave.trust -= 10;
 					slave.vagina = 1;
 				}
-			} else if (slave.vagina < 3) {
+			} else if (V.seeStretching === 1 && slave.vagina < 3) {
 				if (jsRandom(1, 100) > ((170 - slave.sexAmount) + (slave.vagina * 10) + (slave.skill.vaginal / 3))) {
 					r += ` <span class="change positive">${His} pussy gets loosened by the intense use.</span>`;
 					slave.vagina += 1;
@@ -446,7 +427,7 @@ App.SlaveAssignment.serveThePublic = (function() {
 					slave.trust -= 5;
 					slave.anus = 2;
 				}
-			} else if (slave.anus < 3) {
+			} else if (V.seeStretching === 1 && slave.anus < 3) {
 				if (slave.vagina < 0) {
 					if (jsRandom(1, 100) > ((150 - slave.sexAmount) + (slave.anus * 10) + (slave.skill.anal / 6))) {
 						r += ` <span class="change positive">${His} asshole sees constant use in place of a pussy and loosens.</span>`;
@@ -1343,7 +1324,6 @@ App.SlaveAssignment.serveThePublic = (function() {
 		seX(slave, "mammary", "public", "penetrative", mammaryUse);
 		seX(slave, "penetrative", "public", "penetrative", penetrativeUse);
 
-		cervixPump = 0;
 		if (slave.cervixImplant === 1 || slave.cervixImplant === 3) {
 			cervixPump += (20 * vaginalUse);
 		}
@@ -1548,4 +1528,4 @@ App.SlaveAssignment.serveThePublic = (function() {
 			}
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saServeYourOtherSlaves.js b/src/endWeek/saServeYourOtherSlaves.js
index 341cbca7e933b82fcc7fd80ccf04e359e8ea321f..c49c80cc2d5e8696205f3c967979305e3e347b98 100644
--- a/src/endWeek/saServeYourOtherSlaves.js
+++ b/src/endWeek/saServeYourOtherSlaves.js
@@ -1,93 +1,55 @@
-App.SlaveAssignment.serveYourOtherSlaves = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.serveYourOtherSlaves = function saServeYourOtherSlaves(slave) {
+	/** @type {string[]} */
+	const r = [];
 
-	let r;
+	const {
+		he, him, his, himself, girl, He, His,
+	} = getPronouns(slave);
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let girl;
-	let He;
-	let His;
-
-	let he2;
-	let him2;
-	let his2;
-	let himself2;
+	const fetishChange = fetishChangeChance(slave);
 
+	/** @type {string} */
 	let jobType;
-	let fetishChange;
-
-	let oralUse;
-	let analUse;
-	let vaginalUse;
-	let mammaryUse;
-	let penetrativeUse;
-	let fuckCount;
-	let cervixPump;
-
 	/** @type {App.Entity.SlaveState} */
 	let domSlave;
 	let domName;
-	/** @type {FC.Race|""} */
-	let domRace;
-
 	let domFetishKnown;
 	let domSlaveUsedFetish;
-	let subSlaveLikedFetish;
 	let subHatesDom;
 
-	let subName;
-	/** @type {FC.Race|""} */
-	let subRace;
-	let hands;
+	let oralUse = 0;
+	let analUse = 0;
+	let vaginalUse = 0;
+	let mammaryUse = 0;
+	let penetrativeUse = 0;
+	let cervixPump = 0;
+	let fuckCount = 0;
 
-	return saServeYourOtherSlaves;
+	const subName = slave.slaveName;
+	let subSlaveLikedFetish = 0;
 
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {string}
-	 */
-	function saServeYourOtherSlaves(slave) {
-		r = [];
-		fetishChange = fetishChangeChance(slave);
-
-		({
-			he, him, his, himself, girl, He, His,
-		} = getPronouns(slave));
-
-		oralUse = 0;
-		analUse = 0;
-		vaginalUse = 0;
-		mammaryUse = 0;
-		penetrativeUse = 0;
-		cervixPump = 0;
-		fuckCount = 0;
-
-		subName = slave.slaveName;
-		subSlaveLikedFetish = 0;
-		hands = hasBothArms(slave) ? "hands" : "hand";
-
-		validateJob(slave);
-		if (jobType === "stud") {
-			studLife(slave);
-		} else if (jobType === "cumdump") {
-			cumdumpLife(slave);
-		} else if (jobType === "sub") {
-			subLife(slave);
-		}
-		sexualSatiation(slave);
-		physicalEffects(slave);
-		mentalEffects(slave);
-		slaveSkills(slave);
-
-		return r.join(" ");
+	validateJob(slave);
+	if (jobType === "stud") {
+		studLife(slave);
+	} else if (jobType === "cumdump") {
+		cumdumpLife(slave);
+	} else if (jobType === "sub") {
+		subLife(slave);
 	}
+	sexualSatiation(slave);
+	physicalEffects(slave);
+	mentalEffects(slave);
+	slaveSkills(slave);
+
+	return r.join(" ");
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 * */
+	 */
 	function validateJob(slave) {
 		if (slave.subTarget === -1) {
 			jobType = "stud";
@@ -111,7 +73,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 * */
+	 */
 	function studLife(slave) {
 		if (slave.fuckdoll > 0) {
 			r.push(`is positioned as a sperm dispenser for fertile slaves to ride or milk at their discretion.`);
@@ -191,7 +153,30 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 * */
+	 */
+	function cumdumpHeavyUseDevotion(slave) {
+		if (slave.sexualFlaw === "self hating") {
+			r.push(`With so many other slaves taking advantage of ${his} body, ${his} life's purpose of <span class="hotpink">being nothing more than a piece of meat</span> has come true.`);
+			slave.devotion += 5;
+		} else if (slave.sexualFlaw === "attention whore") {
+			r.push(`With little competition for ${his} body and so many slaves eager to use ${him}, ${his} dreams of being the center of attention are <span class="hotpink">have come true.</span>`);
+			if (slave.weight < 10 && slave.belly < 100) {
+				if (canDoVaginal(slave) && slave.vagina > 0 && canDoAnal(slave) && slave.anus > 0) {
+					r.push(`${He} ends each day cradling ${his} cum swollen stomach, marveling at the "attention" bestowed upon ${him}.`);
+				} else if ((canDoVaginal(slave) && slave.vagina > 0) || (canDoAnal(slave) && slave.anus > 0)) {
+					r.push(`By the end of the day, ${his} stomach has a noticeable bulge to it from all the "attention" bestowed upon ${him}.`);
+				}
+			}
+			slave.devotion += 5;
+		} else if (slave.energy > 95) {
+			r.push(`With so many other slaves using ${his} body, ${his} <span class="hotpink">burning libido is finally sated.</span>`);
+			slave.devotion += 2;
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
 	function cumdumpLife(slave) {
 		if (slave.devotion <= 20) {
 			if (slave.trust >= -20) {
@@ -255,23 +240,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 				r.push(`With ${his} servicing sisters, ${his} workload is reasonable and ${he} isn't overworked.`);
 			} else if (load > 0.2) {
 				r.push(`While ${he} may have support in servicing your stock, ${he} is <span class="health dec">overwhelmed by their collective need.</span>`);
-				if (slave.sexualFlaw === "self hating") {
-					r.push(`With so many other slaves taking advantage of ${his} body, ${his} life's purpose of <span class="hotpink">being nothing more than a piece of meat</span> has come true.`);
-					slave.devotion += 5;
-				} else if (slave.sexualFlaw === "attention whore") {
-					r.push(`With little competition for ${his} body and so many slaves eager to use ${him}, ${his} dreams of being the center of attention are <span class="hotpink">have come true.</span>`);
-					if (slave.weight < 10 && slave.belly < 100) {
-						if (canDoVaginal(slave) && slave.vagina > 0 && canDoAnal(slave) && slave.anus > 0) {
-							r.push(`${He} ends each day cradling ${his} cum swollen stomach, marveling at the "attention" bestowed upon ${him}.`);
-						} else if ((canDoVaginal(slave) && slave.vagina > 0) || (canDoAnal(slave) && slave.anus > 0)) {
-							r.push(`By the end of the day, ${his} stomach has a noticeable bulge to it from all the "attention" bestowed upon ${him}.`);
-						}
-					}
-					slave.devotion += 5;
-				} else if (slave.energy > 95) {
-					r.push(`With so many other slaves using ${his} body, ${his} <span class="hotpink">burning libido is finally sated.</span>`);
-					slave.devotion += 2;
-				}
+				cumdumpHeavyUseDevotion(slave);
 			} else {
 				r.push(`Since`);
 				if (subSlaves.length === 1) {
@@ -281,56 +250,94 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 				}
 				r.push(`servicing your stock, ${he} is used to the <span class="health dec">point of exhaustion.</span>`);
 				healthDamage(slave, 10);
-				if (App.EndWeek.saVars.averageDick > 5) {
+				if (V.seeStretching === 1 && App.EndWeek.saVars.averageDick > 5) {
 					if (canDoVaginal(slave) && slave.vagina.isBetween(0, 4)) {
-						if ((slave.vagina * 40) - (App.EndWeek.saVars.averageDick * 5) < jsRandom(1, 100)) {
+						if ((slave.vagina * 40) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 							r.push(`So many huge dicks pistoning in and out of ${his} pussy <span class="lime">loosen ${him} up.</span>`);
 							slave.vagina++;
 							actX(slave, "vaginal", 3);
 						}
 					}
 					if (canDoAnal(slave) && slave.anus.isBetween(0, 4)) {
-						if ((slave.anus * 40) - (App.EndWeek.saVars.averageDick * 5) < jsRandom(1, 100)) {
+						if ((slave.anus * 40) - (App.EndWeek.saVars.averageDick * 5) < random(1, 100)) {
 							r.push(`<span class="lime">${His} asshole is loosened</span> after being pounded by so many giant cocks.`);
 							slave.anus++;
 							actX(slave, "anal", 3);
 						}
 					}
 				}
-				if (slave.sexualFlaw === "self hating") {
-					r.push(`With so many other slaves taking advantage of ${his} body, ${his} life's purpose of <span class="hotpink">being nothing more than a piece of meat</span> has come true.`);
-					slave.devotion += 5;
-				} else if (slave.sexualFlaw === "attention whore") {
-					r.push(`With little competition for ${his} body and so many slaves eager to use ${him}, ${his} dreams of being the center of attention are <span class="hotpink">have come true.</span>`);
-					if (slave.weight < 10 && slave.belly < 100) {
-						if (canDoVaginal(slave) && slave.vagina > 0 && canDoAnal(slave) && slave.anus > 0) {
-							r.push(`${He} ends each day cradling ${his} cum swollen stomach, marveling at the "attention" bestowed upon ${him}.`);
-						} else if ((canDoVaginal(slave) && slave.vagina > 0) || (canDoAnal(slave) && slave.anus > 0)) {
-							r.push(`By the end of the day, ${his} stomach has a noticeable bulge to it from all the "attention" bestowed upon ${him}.`);
-						}
-					}
-					slave.devotion += 5;
-				} else if (slave.energy > 95) {
-					r.push(`With so many other slaves using ${his} body, ${his} <span class="hotpink">burning libido is finally sated.</span>`);
-					slave.devotion += 2;
-				}
+				cumdumpHeavyUseDevotion(slave);
 			}
 		} else {
 			r.push(`Since you have so few slaves in need of release, ${he} sees little action.`);
 		}
 		// service the fraction of the eligible slave population that's not served by another subslave between 1 and 5 times per day
-		fuckCount = Math.ceil((jsRandom(7, 35) / App.EndWeek.saVars.subSlaveRatio) * healthPenalty(slave));
+		fuckCount = Math.ceil((random(7, 35) / App.EndWeek.saVars.subSlaveRatio) * healthPenalty(slave));
 		SimpleSexAct.Slave(slave, fuckCount);
 	}
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 * */
+	 */
+	function addFuckCount(slave) {
+		if (canPenetrate(domSlave)) {
+			fuckCount = random(15, 25);
+			r.push(SimpleSexAct.Slaves(slave, domSlave, fuckCount));
+		} else if (canPenetrate(slave) && ((canDoVaginal(domSlave) && domSlave.vagina > 0) || (canDoAnal(domSlave) && domSlave.anus > 0))) {
+			/* yes, that means she rides her */
+			penetrativeUse = random(15, 25);
+			r.push(SimpleSexAct.Slaves(domSlave, slave, fuckCount));
+		} else {
+			fuckCount = random(15, 25);
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {App.Entity.SlaveState} domSlave
+	 */
+	function knockUpAnal(slave, domSlave) {
+		seX(domSlave, "anal", slave, "penetrative", penetrativeUse);
+		if (canImpreg(domSlave, slave)) {
+			knockMeUp(domSlave, 30, 1, slave.ID);
+			if (domSlave.pregKnown === 1) {
+				const {he2, his2} = getPronouns(domSlave).appendSuffix('2');
+				r.push(`With so many potent deposits into ${his2} fertile rear, it comes as little surprise when <span class="lime">${he2} ends up pregnant with ${subName}'s child.</span>`);
+			}
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {App.Entity.SlaveState} domSlave
+	 */
+	function stimulateSlaveProstate(slave, domSlave) {
+		const {he2, his2} = getPronouns(domSlave).appendSuffix('2');
+		r.push(`${domName} has ${his2} own private semen dispenser. ${domName} sometimes gets tired of having to work hard for cum, so ${he2} spends the week`);
+		if (hasAnyArms(domSlave)) {
+			r.push(`stimulating poor ${subName}'s`);
+		} else {
+			r.push(`ordering ${subName} to stimulate ${his} own`);
+		}
+		if (slave.prostate) {
+			r.push(`prostate`);
+		} else {
+			r.push(`balls`);
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
 	function subLife(slave) {
-		({
+		const {
 			he2, him2, his2, himself2,
-		} = getPronouns(domSlave).appendSuffix('2'));
+		} = getPronouns(domSlave).appendSuffix('2');
 
+		/** @type {FC.Race|""} */
+		let domRace;
+		/** @type {FC.Race|""} */
+		let subRace;
 		if (V.seeRace === 1) {
 			domRace = domSlave.race;
 			subRace = slave.race;
@@ -356,6 +363,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 			}
 		}
 
+		const hands = hasBothArms(slave) ? "hands" : "hand";
 		if (domSlave.fetishStrength > 60 && domSlave.fetish === "buttslut") {
 			domSlaveUsedFetish = 1;
 			if (canPenetrate(slave) && canDoAnal(domSlave) && (domSlave.anus !== 0)) {
@@ -394,17 +402,9 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 					}
 					r.push(`so ${he2} can ride that ${subRace} dick with ${his2} ${domRace} butt. <span class="hotpink">${domName} enjoys a week of constant butt loving.</span>`);
 				}
-				penetrativeUse = jsRandom(9, 12);
-				slave.counter.penetrative += penetrativeUse;
-				V.penetrativeTotal += penetrativeUse;
-				domSlave.counter.anal += penetrativeUse;
-				V.analTotal += penetrativeUse;
-				if (canImpreg(domSlave, slave)) {
-					knockMeUp(domSlave, 30, 1, slave.ID);
-					if (domSlave.pregKnown === 1) {
-						r.push(`With so many potent deposits into ${his2} fertile rear, it comes as little surprise when <span class="lime">${he2} ends up pregnant with ${subName}'s child.</span>`);
-					}
-				}
+				penetrativeUse = random(9, 12);
+				seX(domSlave, "anal", slave, "penetrative", penetrativeUse);
+				knockUpAnal(slave, domSlave);
 			} else if (canDoAnal(domSlave)) {
 				if (slave.devotion < -20) {
 					if (domFetishKnown) {
@@ -431,11 +431,8 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 					}
 					r.push(`${subName} lavishes attention on ${his2} butt. ${He} spends the week servicing ${domName}'s insatiable ${domRace} ass with ${his} ${subRace} mouth. <span class="hotpink">${domName} enjoys having an enthusiastic anal playmate.</span>`);
 				}
-				oralUse = jsRandom(9, 12);
-				domSlave.counter.anal += oralUse;
-				V.analTotal += oralUse;
-				slave.counter.oral += oralUse;
-				V.oralTotal += oralUse;
+				oralUse = random(9, 12);
+				seX(slave, "oral", domSlave, "anal", oralUse);
 			} else {
 				if (slave.devotion < -20) {
 					if (domFetishKnown) {
@@ -509,12 +506,11 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 			}
 			r.push(`${subName} to fuck ${him2}; when ${subName} asks how, ${domName} tells ${him} to take charge.`);
 			if (canPenetrate(slave)) {
-				penetrativeUse = jsRandom(9, 12);
+				penetrativeUse = random(9, 12);
 				if (isAmputee(slave)) {
 					if (canDoVaginal(domSlave) && domSlave.vagina !== 0) {
 						r.push(`${domName} finds ${himself2} under the weight of ${subName}'s limbless body and ${his2} ${domRace} slit accommodating an eager ${subRace} cock. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top for ${his} efforts. ${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind</span> being expected to fuck a willing pussy.`);
-						domSlave.counter.vaginal += penetrativeUse;
-						V.vaginalTotal += penetrativeUse;
+						seX(domSlave, "vaginal", slave, "penetrative", penetrativeUse);
 						if (canImpreg(domSlave, slave)) {
 							knockMeUp(domSlave, 30, 0, slave.ID);
 							if (domSlave.pregKnown === 1) {
@@ -523,24 +519,15 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 						}
 					} else if (canDoAnal(domSlave) && domSlave.anus !== 0) {
 						r.push(`${domName} finds ${himself2} under the weight of ${subName}'s limbless body and ${his2} ${domRace} ass accommodating an eager ${subRace} cock. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top for ${his} efforts. ${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind</span> being expected to fuck a willing asshole.`);
-						domSlave.counter.anal += penetrativeUse;
-						V.analTotal += penetrativeUse;
-						if (canImpreg(domSlave, slave)) {
-							knockMeUp(domSlave, 30, 1, slave.ID);
-							if (domSlave.pregKnown === 1) {
-								r.push(`With so many potent deposits into ${his2} fertile rear, it comes as little surprise when <span class="lime">${he2} ends up pregnant with ${subName}'s child.</span>`);
-							}
-						}
+						knockUpAnal(slave, domSlave);
 					} else {
 						r.push(`${domName} finds ${his2} head under the weight of ${subName}'s limbless body and ${his2} ${domRace} face accommodating an eager ${subRace} cock. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top for ${his} efforts. ${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind</span> being expected to fuck a willing asshole.`);
-						domSlave.counter.oral += penetrativeUse;
-						V.oralTotal += penetrativeUse;
+						seX(domSlave, "oral", slave, "penetrative", penetrativeUse);
 					}
 				} else {
 					if (canDoVaginal(domSlave) && domSlave.vagina !== 0) {
 						r.push(`${domName} finds ${himself2} with ${his2} face pushed firmly into ${his2} bedsheets and ${his2} ${domRace} slit accommodating ${subName}'s eager ${subRace} cock. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top. ${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind</span> being expected to fuck a willing pussy.`);
-						domSlave.counter.vaginal += penetrativeUse;
-						V.vaginalTotal += penetrativeUse;
+						seX(domSlave, "vaginal", slave, "penetrative", penetrativeUse);
 						if (canImpreg(domSlave, slave)) {
 							r.push(knockMeUp(domSlave, 30, 0, slave.ID));
 							if (domSlave.pregKnown === 1) {
@@ -549,8 +536,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 						}
 					} else if (canDoAnal(domSlave) && domSlave.anus !== 0) {
 						r.push(`${domName} finds ${himself2} with ${his2} face pushed firmly into ${his2} bedsheets and ${his2} ${domRace} ass accommodating ${subName}'s eager ${subRace} cock. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top. ${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind</span> being expected to fuck a willing asshole.`);
-						domSlave.counter.anal += penetrativeUse;
-						V.analTotal += penetrativeUse;
+						seX(domSlave, "anal", slave, "penetrative", penetrativeUse);
 						if (canImpreg(domSlave, slave)) {
 							r.push(knockMeUp(domSlave, 30, 1, slave.ID));
 							if (domSlave.pregKnown === 1) {
@@ -559,12 +545,9 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 						}
 					} else {
 						r.push(`${domName} finds ${himself2} with ${his2} face pushed firmly into ${subName}'s crotch and ${his2} ${domRace} face accommodating an eager ${subRace} cock. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top. ${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind</span> being expected to fuck a willing asshole.`);
-						domSlave.counter.oral += penetrativeUse;
-						V.oralTotal += penetrativeUse;
+						seX(domSlave, "oral", slave, "penetrative", penetrativeUse);
 					}
 				}
-				slave.counter.penetrative += oralUse;
-				V.penetrativeTotal += oralUse;
 			} else if (slave.clit > 2) {
 				if (isAmputee(slave)) {
 					r.push(`${domName} finds ${himself2} pinned by the weight of ${subName}'s limbless body and ${his} quickly hardening ${subRace} clit being pushed eagerly into ${his2} ${domRace} mouth. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top for ${his} efforts.`);
@@ -572,27 +555,18 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 					r.push(`${domName} finds ${himself2} with ${his2} back pushed firmly into ${his2} bedsheets and ${subName}'s quickly hardening clit being pushed eagerly into ${his2} mouth. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top.`);
 				}
 				r.push(`${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind</span> constant oral attention.`);
-				penetrativeUse = jsRandom(9, 12);
-				domSlave.counter.oral += penetrativeUse;
-				V.oralTotal += penetrativeUse;
-				slave.counter.penetrative += penetrativeUse;
-				V.penetrativeTotal += penetrativeUse;
+				penetrativeUse = random(9, 12);
+				seX(domSlave, "oral", slave, "penetrative", penetrativeUse);
 			} else {
 				if (isAmputee(slave)) {
 					if (canDoVaginal(domSlave)) {
 						r.push(`${domName} finds ${himself2} under the weight of ${subName}'s limbless body and ${his2} ${domRace} slit molested by an eager tongue. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top for ${his} efforts. ${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind</span> being expected to torment a willing pussy.`);
-						oralUse = jsRandom(9, 12);
-						domSlave.counter.vaginal += oralUse;
-						V.vaginalTotal += oralUse;
-						slave.counter.vaginal += penetrativeUse;
-						V.vaginalTotal += penetrativeUse;
+						oralUse = random(9, 12);
+						seX(domSlave, "vaginal", slave, "vaginal", oralUse);
 					} else if (!(domSlave.chastityPenis) && domSlave.dick > 0) {
 						r.push(`${domName} finds ${himself2} under the weight of ${subName}'s limbless body with the tight embrace of ${subRace} lips around ${his2} ${domRace} cock. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top for ${his} efforts. ${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind</span> being expected to torment a willing dick.`);
-						oralUse = jsRandom(9, 12);
-						domSlave.counter.penetrative += oralUse;
-						V.penetrativeTotal += oralUse;
-						slave.counter.oral += penetrativeUse;
-						V.oralTotal += penetrativeUse;
+						oralUse = random(9, 12);
+						seX(slave, "oral", domSlave, "penetrative", oralUse);
 					} else {
 						r.push(`${domName} finds ${himself2} under the weight of ${subName}'s limbless body and`);
 						if (domSlave.boobs >= 300) {
@@ -601,23 +575,18 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 							r.push(`${his2} ${nippleColor(domSlave)} nipples`);
 						}
 						r.push(`under attack by an eager mouth. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top for ${his} efforts. ${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind</span> being expected to play with a willing chest.`);
-						oralUse = jsRandom(9, 12);
-						domSlave.counter.mammary += oralUse;
-						V.mammaryTotal += oralUse;
-						slave.counter.oral += penetrativeUse;
-						V.oralTotal += penetrativeUse;
+						oralUse = random(9, 12);
+						seX(slave, "oral", domSlave, "mammary", oralUse);
 					}
 				} else {
 					if (canDoVaginal(domSlave) && domSlave.vagina !== 0) {
 						r.push(`${domName} finds ${himself2} with ${his2} face pushed firmly into ${his2} bedsheets and ${his2} ${domRace} slit accommodating ${subName}'s thrusting ${subRace} fingers. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top. ${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind the fun.</span>`);
-						fuckCount = jsRandom(9, 12);
-						domSlave.counter.vaginal += fuckCount;
-						V.vaginalTotal += fuckCount;
+						fuckCount = random(9, 12);
+						seX(domSlave, "vaginal", slave, "penetrative", fuckCount);
 					} else if (canDoAnal(domSlave) && domSlave.anus !== 0) {
 						r.push(`${domName} finds ${himself2} with ${his2} face pushed firmly into ${his2} bedsheets and ${his2} ${domRace} ass accommodating ${subName}'s thrusting ${subRace} fingers. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top. ${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind the fun.</span>`);
-						fuckCount = jsRandom(9, 12);
-						domSlave.counter.anal += fuckCount;
-						V.analTotal += fuckCount;
+						fuckCount = random(9, 12);
+						seX(domSlave, "anal", slave, "penetrative", fuckCount);
 					} else {
 						r.push(`${domName} finds ${himself2} pushed firmly into ${his2} bedsheets and ${his2}`);
 						if (domSlave.boobs >= 300) {
@@ -626,9 +595,8 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 							r.push(`${nippleColor(domSlave)} nipples`);
 						}
 						r.push(`being roughly handled by ${subName}'s ${subRace} fingers. Afterward, ${domName} lavishes kisses on ${his2} satisfactory top. ${domName} <span class="hotpink">enjoys a week of constant submission,</span> and even though ${he}'s technically being used, ${subName} <span class="hotpink">doesn't mind the fun.</span>`);
-						fuckCount = jsRandom(9, 12);
-						domSlave.counter.mammary += fuckCount;
-						V.mammaryTotal += fuckCount;
+						fuckCount = random(9, 12);
+						seX(domSlave, "mammary", slave, "penetrative", fuckCount);
 					}
 				}
 			}
@@ -740,11 +708,8 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 					domSlave.fetishKnown = 1;
 				}
 				r.push(`${subName} spends the week getting to use ${his} dick for a change. ${subName}'s ${subRace} body thrusting into ${domName}'s supple ${domRace} breasts is a frequent sight as ${domName} takes ${his2} pleasure. <span class="hotpink">${domName} enjoys being able to use ${subName}.</span>`);
-				penetrativeUse = jsRandom(9, 12);
-				domSlave.counter.mammary += penetrativeUse;
-				V.mammaryTotal += penetrativeUse;
-				slave.counter.penetrative += penetrativeUse;
-				V.penetrativeTotal += penetrativeUse;
+				penetrativeUse = random(9, 12);
+				seX(domSlave, "mammary", slave, "penetrative", penetrativeUse);
 			} else if (domSlave.lactation > 0) {
 				if (domFetishKnown) {
 					r.push(`Since ${domName} loves giving milk,`);
@@ -821,9 +786,8 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 				domSlave.boobs -= domSlave.boobsMilk;
 				domSlave.boobsMilk = 0;
 			}
-			oralUse = jsRandom(9, 12);
-			domSlave.counter.mammary += oralUse;
-			V.mammaryTotal += oralUse;
+			oralUse = random(9, 12);
+			seX(domSlave, "mammary", slave, "penetrative", oralUse);
 			if (slave.need && slave.fetish === "boobs") {
 				if (slave.fetishKnown) {
 					r.push(`${subName} needs this kind of play to be truly sexually satisfied; this week,`);
@@ -844,17 +808,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 					r.push(`${domName}, it turns out, <span class="lightcoral">really likes cum,</span> and ${subName} has a dick, so`);
 					domSlave.fetishKnown = 1;
 				}
-				r.push(`${domName} has ${his2} own private semen dispenser. ${domName} sometimes gets tired of having to work hard for cum, so ${he2} spends the week`);
-				if (hasAnyArms(domSlave)) {
-					r.push(`stimulating poor ${subName}'s`);
-				} else {
-					r.push(`ordering ${subName} to stimulate ${his} own`);
-				}
-				if (slave.prostate) {
-					r.push(`prostate`);
-				} else {
-					r.push(`balls`);
-				}
+				stimulateSlaveProstate(slave, domSlave);
 				r.push(`to force ${him} to climax so ${domName} can wrap ${his2} ${domRace} lips around ${subName}'s ${subRace} dickhead to suck down ${his2} cum. <span class="hotpink">${domName} enjoys having a servile dick on demand.</span>`);
 			} else if (slave.dick > 0 && !canAchieveErection(slave)) {
 				if (domFetishKnown) {
@@ -871,17 +825,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 					r.push(`${domName}, it turns out, <span class="lightcoral">really likes cum,</span> and ${subName} has balls, so`);
 					domSlave.fetishKnown = 1;
 				}
-				r.push(`${domName} has ${his2} own private semen dispenser. ${domName} sometimes gets tired of having to work hard for cum, so ${he2} spends the week`);
-				if (hasAnyArms(domSlave)) {
-					r.push(`stimulating poor ${subName}'s`);
-				} else {
-					r.push(`ordering ${subName} to stimulate ${his} own`);
-				}
-				if (slave.prostate) {
-					r.push(`prostate`);
-				} else {
-					r.push(`balls`);
-				}
+				stimulateSlaveProstate(slave, domSlave);
 				r.push(`to force ${him} to climax so ${domName} can plant ${his2} ${domRace} lips overs ${subName}'s ${subRace}`);
 				if (slave.vagina >= 0) {
 					r.push(`urethra`);
@@ -890,9 +834,8 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 				}
 				r.push(`to catch ${his} cum. <span class="hotpink">${domName} enjoys having ${his2} little sperm fountain.</span>`);
 			}
-			penetrativeUse = jsRandom(9, 12);
-			domSlave.counter.oral += penetrativeUse;
-			V.oralTotal += penetrativeUse;
+			penetrativeUse = random(9, 12);
+			seX(domSlave, "oral", slave, "penetrative", penetrativeUse);
 		} else if (domSlave.fetishStrength > 60 && domSlave.fetish === "humiliation" && hasAnyLegs(slave)) {
 			domSlaveUsedFetish = 1;
 			if (domFetishKnown) {
@@ -970,10 +913,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 					}
 				}
 				penetrativeUse = 7;
-				domSlave.counter.oral += penetrativeUse;
-				V.oralTotal += penetrativeUse;
-				slave.counter.penetrative += penetrativeUse;
-				V.penetrativeTotal += penetrativeUse;
+				seX(domSlave, "oral", slave, "penetrative", penetrativeUse);
 			} else if (slave.scrotum > 0) {
 				r.push(`while ${his}`);
 				if (slave.balls === 0) {
@@ -1011,23 +951,18 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 					}
 				}
 				fuckCount = 7;
-				domSlave.counter.oral += fuckCount;
-				V.oralTotal += fuckCount;
+				seX(domSlave, "oral", slave, "penetrative", fuckCount);
 			} else if (canDoVaginal(slave)) {
 				r.push(`while ${his} pussy is being invaded by drops of slave food and the tongue pursuing them.`);
 				if (slave.clit > 2) {
 					r.push(`${subName} practically throws ${his} cup when ${domName} sucks the entire length of ${his} clit into ${his2} mouth.`);
 				}
 				fuckCount = 7;
-				domSlave.counter.oral += fuckCount;
-				V.oralTotal += fuckCount;
-				slave.counter.penetrative += fuckCount;
-				V.vaginalTotal += fuckCount;
+				seX(domSlave, "oral", slave, "penetrative", fuckCount);
 			} else {
 				r.push(`with an eager tongue roaming ${his} thighs, pubic mound, and taint trying to lap up the slave food before it slips away.`);
 				fuckCount = 7;
-				domSlave.counter.oral += fuckCount;
-				V.oralTotal += fuckCount;
+				seX(domSlave, "oral", slave, "penetrative", fuckCount);
 			}
 			r.push(`The lewdness emanating from beneath the table is not lost on the other diners, <span class="hotpink">much to ${domName}'s enjoyment.</span>`);
 			if (slave.need && slave.fetish === "humiliation") {
@@ -1053,19 +988,13 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 				}
 				r.push(`mounts ${his} fertile ${slave.mpreg > 0 ? "ass" : ""}pussy and lets loose the first of many loads. ${subName} spends the week being thoroughly bred until ${domName}'s potent sperm <span class="hotpink">achieves ${his2} goal,</span> and then a bit more for good measure.`);
 				r.push(knockMeUp(slave, 100, 2, domSlave.ID));
-				fuckCount = jsRandom(10, 16);
+				fuckCount = random(10, 16);
 				if (slave.mpreg > 0) {
 					analUse = fuckCount;
-					domSlave.counter.penetrative += fuckCount;
-					V.penetrativeTotal += fuckCount;
-					slave.counter.anal += fuckCount;
-					V.analTotal += fuckCount;
+					seX(slave, "anal", domSlave, "penetrative", fuckCount);
 				} else {
 					vaginalUse = fuckCount;
-					domSlave.counter.penetrative += fuckCount;
-					V.penetrativeTotal += fuckCount;
-					slave.counter.vaginal += fuckCount;
-					V.vaginalTotal += fuckCount;
+					seX(slave, "vaginal", domSlave, "penetrative", fuckCount);
 				}
 			} else if (domSlave.pregKnown === 1 || slave.belly > 10000 || slave.bellyPreg >= 1500) {
 				if (domSlave.pregKnown === 1) {
@@ -1126,7 +1055,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 					}
 				} else {
 					if (domFetishKnown) {
-						r.push(`Since ${domName} loves pregnant ${girl}s,`);
+						r.push(`${domName} loves pregnant ${girl}s,`);
 					} else {
 						r.push(`${domName}, it turns out, <span class="lightcoral">really likes pregnant ${girl}s,</span>`);
 						domSlave.fetishKnown = 1;
@@ -1139,16 +1068,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 					} else {
 						r.push(`${domName}'s ${domRace} body against ${subName}'s enthusiastic ${subRace} ${bellyAdjective(slave)} belly is a frequent sight as the two of them share pleasure. <span class="hotpink">${domName} enjoys having a pregnant plaything.</span>`);
 					}
-					if (canPenetrate(domSlave)) {
-						fuckCount = jsRandom(15, 25);
-						r.push(SimpleSexAct.Slaves(slave, domSlave, fuckCount));
-					} else if (canPenetrate(slave) && ((canDoVaginal(domSlave) && domSlave.vagina > 0) || (canDoAnal(domSlave) && domSlave.anus > 0))) {
-						/* yes, that means she rides her */
-						penetrativeUse = jsRandom(15, 25);
-						r.push(SimpleSexAct.Slaves(domSlave, slave, fuckCount));
-					} else {
-						fuckCount = jsRandom(15, 25);
-					}
+					addFuckCount(slave);
 				}
 			} else if (canImpreg(domSlave, slave)) {
 				if (domFetishKnown) {
@@ -1170,17 +1090,9 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 				}
 				r.push(`${domName} spends the week extracting loads from ${subName} until ${his} potent sperm <span class="hotpink">slakes the burning need in ${his2} loins.</span>`);
 				r.push(knockMeUp(domSlave, 100, 2, slave.ID));
-				fuckCount = jsRandom(10, 16);
+				fuckCount = random(10, 16);
 				penetrativeUse = fuckCount;
-				slave.counter.penetrative += fuckCount;
-				V.penetrativeTotal += fuckCount;
-				if (domSlave.mpreg > 0) {
-					domSlave.counter.anal += fuckCount;
-					V.analTotal += fuckCount;
-				} else {
-					domSlave.counter.vaginal += fuckCount;
-					V.vaginalTotal += fuckCount;
-				}
+				seX(domSlave, domSlave.mpreg ? "anal" : "vaginal", slave, "penetrative", fuckCount);
 			} else {
 				if (domFetishKnown) {
 					r.push(`${domName} adores pregnancy, and`);
@@ -1232,16 +1144,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 				} else {
 					r.push(`${domName}'s ${domRace} body intertwined with ${subName}'s enthusiastic ${subRace} form is a frequent sight as the two of them share pleasure. <span class="hotpink">${domName} enjoys spending time with a partner willing to indulge ${his2} fantasies.</span>`);
 				}
-				if (canPenetrate(domSlave)) {
-					fuckCount = jsRandom(15, 25);
-					r.push(SimpleSexAct.Slaves(slave, domSlave, fuckCount));
-				} else if (canPenetrate(slave) && ((canDoVaginal(domSlave) && domSlave.vagina > 0) || (canDoAnal(domSlave) && domSlave.anus > 0))) {
-					/* yes, that means she rides her */
-					penetrativeUse = jsRandom(15, 25);
-					r.push(SimpleSexAct.Slaves(domSlave, slave, fuckCount));
-				} else {
-					fuckCount = jsRandom(15, 25);
-				}
+				addFuckCount(slave);
 			}
 			if (slave.need && slave.fetish === "pregnancy") {
 				if (slave.fetishKnown) {
@@ -1257,16 +1160,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 			} else {
 				r.push(`Since ${domName} loves to fuck, ${subName} spends the week getting fucked. ${domName}'s ${domRace} body atop ${subName}'s enthusiastic ${subRace} form is a frequent sight as the two of them share pleasure. <span class="hotpink">${domName} enjoys having an extra outlet for ${his2} sexual needs.</span>`);
 			}
-			if (canPenetrate(domSlave)) {
-				fuckCount = jsRandom(15, 25);
-				r.push(SimpleSexAct.Slaves(slave, domSlave, fuckCount));
-			} else if (canPenetrate(slave) && ((canDoVaginal(domSlave) && domSlave.vagina > 0) || (canDoAnal(domSlave) && domSlave.anus > 0))) {
-				/* yes, that means she rides her */
-				penetrativeUse = jsRandom(15, 25);
-				r.push(SimpleSexAct.Slaves(domSlave, slave, fuckCount));
-			} else {
-				fuckCount = jsRandom(15, 25);
-			}
+			addFuckCount(slave);
 		} else if (domSlave.dick > 0 && canPenetrate(domSlave)) {
 			if (slave.devotion < -20) {
 				r.push(`${domName} doesn't get to use ${his2} still-functional cock as much as ${he2} would like; it often stands stiff and untended while ${he2}'s being used. Not this week: ${subName} spends the week with ${domName}'s ${domRace} dick thrusting in and out of ${his} ${subRace} body, whenever ${he2} feels like forcing it into ${subName}'s unwilling holes. <span class="hotpink">${domName} loves having someone to fuck whenever ${he2} wants.</span>`);
@@ -1275,7 +1169,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 			} else {
 				r.push(`${domName} doesn't get to use ${his2} still-functional cock as much as ${he2} would like; it often stands stiff and untended while ${he2}'s being used. Not this week: ${subName} spends the week with ${domName}'s ${domRace} dick thrusting in and out of ${his} ${subRace} body, whenever ${he2} feels like having an enthusiastic fuck. <span class="hotpink">${domName} loves having someone to tend to ${his2} prick at last.</span>`);
 			}
-			fuckCount = jsRandom(9, 12);
+			fuckCount = random(9, 12);
 			r.push(SimpleSexAct.Slaves(slave, domSlave, fuckCount));
 		} else if (hasAnyArms(domSlave) && domSlave.attrXX > 85 && slave.dick === 0 && slave.vagina > -1) { // feminine check
 			if (slave.devotion < -20) {
@@ -1304,10 +1198,10 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 				r.push(`They rove across ${his} ${subRace} body, knowing just where to touch and where to press. <span class="hotpink">${domName} enjoys having a compliant ${girl} friend,</span> and they spend as much time together as they can.`);
 			}
 			if (canPenetrate(domSlave)) {
-				fuckCount = jsRandom(9, 12);
+				fuckCount = random(9, 12);
 				r.push(SimpleSexAct.Slaves(slave, domSlave, fuckCount));
 			} else {
-				fuckCount = jsRandom(9, 12);
+				fuckCount = random(9, 12);
 			}
 		} else if (slave.dick > 0 && hasAnyArms(domSlave) && domSlave.attrXY > 85) {
 			if (canPenetrate(slave)) {
@@ -1335,15 +1229,15 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 					r.push(`Since ${domName} loves cocks, even soft ones, ${subName} finds ${himself} being sucked, groped, and played with until ${he} comes. ${He} spends the week enjoying with ${domName}'s little games. <span class="hotpink">${domName} enjoys having a nice dick right at hand,</span> even if it's only good as a soft, dripping toy.`);
 				}
 			}
-			fuckCount = jsRandom(9, 12);
+			fuckCount = random(9, 12);
 			r.push(SimpleSexAct.Slaves(domSlave, slave, fuckCount));
 		} else if (isAmputee(slave)) {
 			r.push(`${domName} doesn't have any special desires, so ${he2} simply uses the helpless ${subName} for comfort and convenience. ${subName} finds ${his} helpless ${subRace} torso being used as a bath toy, a bedwarmer, and for sexual convenience. <span class="hotpink">${domName} enjoys the ease and companionship.</span>`);
-			fuckCount = jsRandom(9, 12);
+			fuckCount = random(9, 12);
 			r.push(SimpleSexAct.Slaves(slave, domSlave, fuckCount));
 		} else {
 			r.push(`${domName} doesn't have any special desires ${subName} can satisfy, so ${he2} simply uses ${subName} for comfort and convenience. ${subName} washes ${his} superior's ${domRace} body thoroughly and uses ${his} own ${subRace} body to warm ${domName}'s bed at night. <span class="hotpink">${domName} enjoys the ease and companionship.</span>`);
-			fuckCount = jsRandom(9, 12);
+			fuckCount = random(9, 12);
 			r.push(SimpleSexAct.Slaves(slave, domSlave, fuckCount));
 		}
 		domSlave.devotion += 4;
@@ -1351,7 +1245,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 * */
+	 */
 	function sexualSatiation(slave) {
 		/* This is here because SimpleSexAct.Slaves doesn't update analUse, etc. and that is needed to calculate cervixPump and .need clearing */
 		oralUse = slave.counter.oral - oralUse;
@@ -1370,7 +1264,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 					slave.fetishStrength++;
 				}
 			}
-			if (fetishChange > jsRandom(0, 99) && !subSlaveLikedFetish) {
+			if (fetishChange > random(0, 99) && !subSlaveLikedFetish) {
 				r.push(`${His} work starts to pervade ${his} fantasies; <span class="lightcoral">${he}'s developed a pregnancy fetish.</span>`);
 				slave.fetish = "pregnancy";
 				slave.fetishStrength = 65;
@@ -1462,7 +1356,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 				if (slave.fetishStrength < 100) {
 					slave.fetishStrength++;
 				}
-			} else if (fetishChange > jsRandom(0, 100) && slave.fetish !== "masochist" && slave.fetish !== "submissive" && App.EndWeek.saVars.subSlaveRatio.isBetween(0, 0.8)) {
+			} else if (fetishChange > random(0, 100) && slave.fetish !== "masochist" && slave.fetish !== "submissive" && App.EndWeek.saVars.subSlaveRatio.isBetween(0, 0.8)) {
 				r.push(`Being used as much as ${he} is starts to take a toll on ${him} sexuality; <span class="lightcoral">${he} begins to enjoy being your chattel's fucktoy.</span>`);
 				slave.fetish = "submissive";
 				slave.fetishStrength = 65;
@@ -1479,7 +1373,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 				}
 			}
 			slave.need -= ((penetrativeUse + vaginalUse + analUse) * 5);
-			if (domSlaveUsedFetish && !subSlaveLikedFetish && fetishChange > jsRandom(70, 100)) {
+			if (domSlaveUsedFetish && !subSlaveLikedFetish && fetishChange > random(70, 100)) {
 				// If subslave is uncertain of her fetish, allow her to take one based off her dom.
 				switch (domSlave.fetish) {
 					case "buttslut":
@@ -1644,7 +1538,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 
 	/**
 	 * @param {FC.ReportSlave} slave
-	 * */
+	 */
 	function physicalEffects(slave) {
 		if (slave.health.illness > 0 || slave.health.tired > 60) {
 			if (jobType === "sub") {
@@ -1723,6 +1617,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 			}
 			tiredFucks(slave);
 		} else if (jobType === "sub") {
+			const {him2, his2} = getPronouns(domSlave).appendSuffix('2');
 			if (slaveResting(slave)) {
 				r.push(`${domName} only uses ${subName} sexually <span class="health inc">out of respect for ${his} rest rules.</span>`);
 			} else if (slave.relationshipTarget === domSlave.ID && slave.health.tired > 60) {
@@ -1786,11 +1681,11 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 * */
+	 */
 	function mentalEffects(slave) {
 		if (jobType === "stud") {
 			if (slave.behavioralFlaw === "hates women") {
-				if (slave.devotion > 20 && jsRandom(1, 100) > 70) {
+				if (slave.devotion > 20 && random(1, 100) > 70) {
 					r.push(`Spending so much time in close proximity to pussies <span class="green">reconciles ${him} to sex with girls.</span>`);
 					slave.behavioralFlaw = "none";
 				}
@@ -1798,7 +1693,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 		} else if (jobType === "cumdump") {
 			if (App.EndWeek.saVars.subSlaveRatio <= 0.8) {
 				if (slave.sexualFlaw === "repressed") {
-					if (slave.devotion > 20 && jsRandom(1, 100) > (100 - fuckCount)) {
+					if (slave.devotion > 20 && random(1, 100) > (100 - fuckCount)) {
 						r.push(`After being brought to orgasm so many times, <span class="green">${he} begins to enjoy having sex.</span>`);
 						slave.sexualFlaw = "none";
 					}
@@ -1831,7 +1726,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 			if (!subHatesDom) {
 				if (slave.relationship === 0) {
 					if (slave.rivalryTarget !== domSlave.ID && slave.devotion >= 10 && domSlave.relationship === 0) {
-						if (jsRandom(1, 100) > 50) {
+						if (random(1, 100) > 50) {
 							r.push(`${subName} and ${domName} enjoy spending time together and <span class="lightgreen">strike up a friendship.</span>`);
 							domSlave.relationship = 1;
 							domSlave.relationshipTarget = slave.ID;
@@ -1873,7 +1768,7 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 			}
 
 			if (slave.rivalry === 0) {
-				if (slave.relationshipTarget !== domSlave.ID && slave.devotion <= 50 && domSlave.rivalry === 0 && jsRandom(1, 100) > 50 - (subHatesDom * 20)) {
+				if (slave.relationshipTarget !== domSlave.ID && slave.devotion <= 50 && domSlave.rivalry === 0 && random(1, 100) > 50 - (subHatesDom * 20)) {
 					r.push(`${subName} resents ${domName} for using ${him} and the two <span class="lightsalmon">start to dislike each other.</span>`);
 					domSlave.rivalry = 1;
 					domSlave.rivalryTarget = slave.ID;
@@ -1902,33 +1797,35 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 * */
+	 * @param {"oral"|"vaginal"|"anal"} skillName
+	 * @param {number} skillValue
+	 */
+	function increaseSkillFromCumdump(slave, skillName, skillValue) {
+		if (skillValue < 30) {
+			r.push(slaveSkillIncrease(skillName, slave, (Math.floor((oralUse / 2) + Math.floor((slave.intelligence + slave.intelligenceImplant) / 32)))));
+		} else if (skillValue < 100) {
+			r.push(slaveSkillIncrease(skillName, slave, (Math.floor((oralUse / 4) + Math.floor((slave.intelligence + slave.intelligenceImplant) / 32)))));
+		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 */
 	function slaveSkills(slave) {
 		if (jobType === "stud") {
 			// Penetrative skill goes here.
 		} else if (jobType === "cumdump") {
 			if (oralUse > 0) {
-				if (slave.skill.oral < 30) {
-					r.push(slaveSkillIncrease('oral', slave, (Math.floor((oralUse / 2) + Math.floor((slave.intelligence + slave.intelligenceImplant) / 32)))));
-				} else if (slave.skill.oral < 100) {
-					r.push(slaveSkillIncrease('oral', slave, (Math.floor((oralUse / 4) + Math.floor((slave.intelligence + slave.intelligenceImplant) / 32)))));
-				}
+				increaseSkillFromCumdump(slave, "oral", slave.skill.oral);
 			}
 			if (vaginalUse > 0) {
-				if (slave.skill.vaginal < 30) {
-					r.push(slaveSkillIncrease('vaginal', slave, (Math.floor((vaginalUse / 2) + Math.floor((slave.intelligence + slave.intelligenceImplant) / 32)))));
-				} else if (slave.skill.vaginal < 100) {
-					r.push(slaveSkillIncrease('vaginal', slave, (Math.floor((vaginalUse / 4) + Math.floor((slave.intelligence + slave.intelligenceImplant) / 32)))));
-				}
+				increaseSkillFromCumdump(slave, "vaginal", slave.skill.vaginal);
 			}
 			if (analUse > 0) {
-				if (slave.skill.anal < 30) {
-					r.push(slaveSkillIncrease('anal', slave, (Math.floor((analUse / 2) + Math.floor((slave.intelligence + slave.intelligenceImplant) / 32)))));
-				} else if (slave.skill.anal < 100) {
-					r.push(slaveSkillIncrease('anal', slave, (Math.floor((analUse / 4) + Math.floor((slave.intelligence + slave.intelligenceImplant) / 32)))));
-				}
+				increaseSkillFromCumdump(slave, "anal", slave.skill.anal);
 			}
 		} else if (jobType === "sub") {
+			const {his2} = getPronouns(domSlave).appendSuffix('2');
 			if ((slave.rivalry === 0 || slave.rivalryTarget !== domSlave.ID) && slave.devotion > 20 && domSlave.devotion > 20) {
 				if (oralUse > 0) {
 					if (slave.skill.oral < domSlave.skill.oral) {
@@ -1957,4 +1854,4 @@ App.SlaveAssignment.serveYourOtherSlaves = (function() {
 			}
 		}
 	}
-})();
+};
diff --git a/src/endWeek/saSharedVariables.js b/src/endWeek/saSharedVariables.js
index d7c8156666437c5807e15d26be4805dbe3fc966b..3bd4691282a027cf9f6cf3ee829f53d6654e3e15 100644
--- a/src/endWeek/saSharedVariables.js
+++ b/src/endWeek/saSharedVariables.js
@@ -32,6 +32,12 @@ App.EndWeek.SASharedVariables = class {
 		this.subSlaveMap = new Map();
 		/** Slave art manager */
 		this.slaveArt = null;
+		/** Need cap per slave. Array indices are the slave IDs (resulting in a sparse array, but that's ok, because we never save this array) */
+		this.needCapPerSlave = [];
+		/** Which employees the leader of the currently processed facility is having sex with this week
+		 *  @see App.EndWeek.getFLSex
+		 */
+		this.flSex = 0;
 	}
 
 	/** Compute shared subslave ratio (subslaves per ordinary slave) */
diff --git a/src/endWeek/saSocialEffects.js b/src/endWeek/saSocialEffects.js
index d7ac64c90c783fdeb9faa1e6787fa6ed4a81973a..8e9e302993b5e60e35062daa8c74daa067ca5b2e 100644
--- a/src/endWeek/saSocialEffects.js
+++ b/src/endWeek/saSocialEffects.js
@@ -50,7 +50,7 @@ App.SlaveAssignment.saSocialEffects = function(slave) {
 						if (dad) {
 							if (slave.race !== dad.race && V.arcologies[0].FSSupremacistRace === "mixed race") {
 								t.push(new SocialEffect("Supremacist", 2, "Mixed race breeding",
-									`Society <span class="lightgreen">approves</span> of your using slave breeders like ${slave.slaveName} to propagate the ${V.arcologies[0].FSSupremacistRace} civilization.`));
+									`Society <span class="green">approves</span> of your using slave breeders like ${slave.slaveName} to propagate the ${V.arcologies[0].FSSupremacistRace} civilization.`));
 							} else if (slave.race !== dad.race) {
 								t.push(new SocialEffect("Supremacist", -2, "Miscegenation",
 									`Society <span class="red">strongly disapproves</span> of your allowing a pure ${V.arcologies[0].FSSupremacistRace} slave to be miscegenated by ${dad.slaveName}.`));
@@ -484,10 +484,11 @@ App.SlaveAssignment.saSocialEffects = function(slave) {
 			}
 		}
 
-		if (!(jQuery.isEmptyObject(slave.scar))) {
+		const scars = App.Medicine.Modification.scarRecord(slave);
+		if (!(jQuery.isEmptyObject(scars))) {
 			let hasScar = 0;
-			for (const scarPlace in slave.scar) {
-				for (const scarType in slave.scar[scarPlace]) {
+			for (const scarPlace in scars) {
+				for (const scarType in scars[scarPlace]) {
 					// exotic scars don't count
 					if (scarType !== "exotic") {
 						if (V.arcologies[0].FSDegradationist !== "unset") {
diff --git a/src/endWeek/saStayConfined.js b/src/endWeek/saStayConfined.js
index 9135eb59eed6d3ec419d9b9e7a04fe45bd027103..4c131c7d30d355cef66578ff1bf80ba312ccbca7 100644
--- a/src/endWeek/saStayConfined.js
+++ b/src/endWeek/saStayConfined.js
@@ -5,7 +5,7 @@
  */
 
 /**
- * @param {App.Entity.SlaveState} slave
+ * @param {FC.ReportSlave} slave
  * @returns {confinedResults}
  */
 App.SlaveAssignment.stayConfined = function(slave) {
diff --git a/src/endWeek/saTakeClasses.js b/src/endWeek/saTakeClasses.js
index 105069708dd0344f1854df148eddcadcb6b1fadf..ad1aaa51571b4ce03b438b82e42dda31c60163bf 100644
--- a/src/endWeek/saTakeClasses.js
+++ b/src/endWeek/saTakeClasses.js
@@ -1,52 +1,36 @@
-App.SlaveAssignment.takeClasses = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.takeClasses = function saTakeClasses(slave) {
+	const {
+		he, him, his, himself, He, His,
+	} = getPronouns(slave);
 
-	let r;
+	let r = ` `;
 
-	let he;
-	let him;
-	let his;
-	let himself;
-	let He;
-	let His;
+	let learning = 1;
+	let teaching = 0;
 
-	let learning;
-	let teaching;
-
-	return saTakeClasses;
-
-	/**
-	 * @param {FC.ReportSlave} slave
-	 * @returns {string}
-	 */
-	function saTakeClasses(slave) {
-		r = ` `;
-		learning = 1;
-		teaching = 0;
-		({
-			he, him, his, himself, He, His,
-		} = getPronouns(slave));
-
-		jobPreface(slave);
-		if (slave.fetish !== "mindbroken") {
-			learningDisability(slave);
-			jobHealthImpact(slave);
-			learningProgress(slave);
-			if (slave.lactation > 0) {
-				lactationBreak(slave);
-			}
-			skillLessons(slave);
-			generalLessons(slave);
-			if (slave.accent > 1 && slave.voice !== 0) {
-				speechLessons(slave);
-			}
-			if (needsTutoring(slave)) {
-				tutorLessons(slave);
-			}
-			graduation(slave);
+	jobPreface(slave);
+	if (slave.fetish !== "mindbroken") {
+		learningDisability(slave);
+		jobHealthImpact(slave);
+		learningProgress(slave);
+		if (slave.lactation > 0) {
+			lactationBreak(slave);
+		}
+		skillLessons(slave);
+		generalLessons(slave);
+		if (slave.accent > 1 && slave.voice !== 0) {
+			speechLessons(slave);
 		}
-		return r;
+		if (needsTutoring(slave)) {
+			tutorLessons(slave);
+		}
+		graduation(slave);
 	}
+	return r;
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
@@ -301,20 +285,27 @@ App.SlaveAssignment.takeClasses = (function() {
 		}
 	}
 
+	/**
+	 * @param {FC.SlaveState} slave
+	 * @returns {number}
+	 */
+	function lessonSkillIncrease(slave) {
+		if (V.schoolroomRemodelBimbo !== 1 || slave.assignment !== Job.SCHOOL) {
+			return (10 + Math.floor((slave.intelligence + slave.intelligenceImplant) / 32));
+		} else {
+			return (10 + (Math.abs(Math.floor((slave.intelligence + slave.intelligenceImplant) / 32))));
+		}
+	}
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 *
 	 */
 	function skillLessons(slave) {
 		let undevoted = 0; // forces an obedience lesson to replace the first skill lesson
-		let skillIncrease = 0;
+		const skillIncrease = lessonSkillIncrease(slave);
 		let lessons;
 		const set = new Set();
-		if (V.schoolroomRemodelBimbo !== 1 || slave.assignment !== Job.SCHOOL) {
-			skillIncrease = (10 + Math.floor((slave.intelligence + slave.intelligenceImplant) / 32));
-		} else {
-			skillIncrease = (10 + (Math.abs(Math.floor((slave.intelligence + slave.intelligenceImplant) / 32))));
-		}
 		for (lessons = 0; lessons < Math.max(1, learning); lessons++) {
 			if (slave.devotion <= 20 && undevoted === 0) {
 				set.add(`Since ${he} is wanting in basic obedience, ${he} suffers through courses on <span class="devotion inc">${his} place</span> in the Free Cities world.`);
@@ -493,256 +484,244 @@ App.SlaveAssignment.takeClasses = (function() {
 	 *
 	 */
 	function tutorLessons(slave) {
-		let cost = 7500;
-		let skillIncrease = 0;
-
-		if (V.schoolroomRemodelBimbo !== 1 || slave.assignment !== Job.SCHOOL) {
-			skillIncrease = (10 + Math.floor((slave.intelligence + slave.intelligenceImplant) / 32));
-		} else {
-			skillIncrease = (10 + (Math.abs(Math.floor((slave.intelligence + slave.intelligenceImplant) / 32))));
-		}
-		if (V.cash > cost) {
-			cashX(forceNeg(cost), "slaveAssignmentClasses", slave);
-			switch (tutorForSlave(slave)) {
-				case "HeadGirl":
-					if (App.Data.Careers.Leader.HG.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to be a Head Girl, surprising no one.`;
-						slave.skill.headGirl = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective Head Girl.`;
-						if (slave.skill.headGirl <= 20) {
-							r += ` ${He} is so unskilled that the tutor teaches ${him} the basics. ${He} learns how to make slaves obey ${him} and how to treat minor injuries.`;
-						} else if (slave.skill.headGirl <= 60) {
-							r += ` ${He} has some experience teaching others. The tutor has ${him} practice teaching slaves how to please their master, and has ${him} attend lectures on slave psychology.`;
-						} else if (slave.skill.headGirl <= 120) {
-							r += ` The tutor arranges for ${him} to work at different places throughout the week, from treating emergencies or diagnosing patients in the hospital to breaking resistant slaves for a slave school. ${He} is truly becoming a jack-of-all trades.`;
-						} else if (slave.skill.headGirl <= 200) {
-							r += ` Now that ${he} has mastered individual skills, ${he} is taught to assist you in running the arcology as a whole. ${He} learns how the security systems work, and how to make every slave perform at their best.`;
-						}
-						r += ` ${slaveSkillIncrease('headGirl', slave, skillIncrease)}`;
+		const skillIncrease = lessonSkillIncrease(slave);
+		switch (tutorForSlave(slave)) {
+			case "HeadGirl":
+				if (App.Data.Careers.Leader.HG.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to be a Head Girl, surprising no one.`;
+					slave.skill.headGirl = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective Head Girl.`;
+					if (slave.skill.headGirl <= 20) {
+						r += ` ${He} is so unskilled that the tutor teaches ${him} the basics. ${He} learns how to make slaves obey ${him} and how to treat minor injuries.`;
+					} else if (slave.skill.headGirl <= 60) {
+						r += ` ${He} has some experience teaching others. The tutor has ${him} practice teaching slaves how to please their master, and has ${him} attend lectures on slave psychology.`;
+					} else if (slave.skill.headGirl <= 120) {
+						r += ` The tutor arranges for ${him} to work at different places throughout the week, from treating emergencies or diagnosing patients in the hospital to breaking resistant slaves for a slave school. ${He} is truly becoming a jack-of-all trades.`;
+					} else if (slave.skill.headGirl <= 200) {
+						r += ` Now that ${he} has mastered individual skills, ${he} is taught to assist you in running the arcology as a whole. ${He} learns how the security systems work, and how to make every slave perform at their best.`;
 					}
-					break;
-				case "Recruiter":
-					if (App.Data.Careers.Leader.recruiter.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to be a recruiter, surprising no one.`;
-						slave.skill.recruiter = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective recruiter.`;
-						if (slave.skill.recruiter <= 20) {
-							r += ` The tutor starts teaching ${him} the basics. ${He} is given lessons on conversing, pronunciation, style and fashion.`;
-						} else if (slave.skill.recruiter <= 60) {
-							r += ` Having been taught the basics by ${his} tutor, ${he} is no longer awkward in conversation. But ${he} has a long way to go, the tutor teaches ${him} how to carry ${himself} and how to interpret others' non-verbal cues.`;
-						} else if (slave.skill.recruiter <= 120) {
-							r += ` The tutor has ${him} practice convincing others. ${He} watches online lectures on slave psychology, and applies it in practice by convincing others to make unfavorable deals.`;
-						} else if (slave.skill.recruiter <= 200) {
-							r += ` Every move ${he} makes is practiced and calculated, yet looks entirely natural. He has ${him} continue attending lectures on psychology, and sends ${him} out to convince free citizens to let themselves get voluntarily enslaved.`;
-						}
-						r += ` ${slaveSkillIncrease('recruiter', slave, skillIncrease)}`;
+					r += ` ${slaveSkillIncrease('headGirl', slave, skillIncrease)}`;
+				}
+				break;
+			case "Recruiter":
+				if (App.Data.Careers.Leader.recruiter.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to be a recruiter, surprising no one.`;
+					slave.skill.recruiter = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective recruiter.`;
+					if (slave.skill.recruiter <= 20) {
+						r += ` The tutor starts teaching ${him} the basics. ${He} is given lessons on conversing, pronunciation, style and fashion.`;
+					} else if (slave.skill.recruiter <= 60) {
+						r += ` Having been taught the basics by ${his} tutor, ${he} is no longer awkward in conversation. But ${he} has a long way to go, the tutor teaches ${him} how to carry ${himself} and how to interpret others' non-verbal cues.`;
+					} else if (slave.skill.recruiter <= 120) {
+						r += ` The tutor has ${him} practice convincing others. ${He} watches online lectures on slave psychology, and applies it in practice by convincing others to make unfavorable deals.`;
+					} else if (slave.skill.recruiter <= 200) {
+						r += ` Every move ${he} makes is practiced and calculated, yet looks entirely natural. He has ${him} continue attending lectures on psychology, and sends ${him} out to convince free citizens to let themselves get voluntarily enslaved.`;
 					}
-					break;
-				case "Bodyguard":
-					if (App.Data.Careers.Leader.bodyguard.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to be a bodyguard, surprising no one.`;
-						slave.skill.bodyguard = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective bodyguard.`;
-						if (slave.skill.bodyguard <= 20) {
-							r += ` ${He} undergoes a personalized boot camp in form of physical exercises, to make sure ${he} has the basic skills required for further security training.`;
-						} else if (slave.skill.bodyguard <= 60) {
-							r += ` The tutor trains ${him} in using and maintaining firearms, and forces ${him} through repetitive dry fire training in order to instill discipline.`;
-						} else if (slave.skill.bodyguard <= 120) {
-							r += ` During the week ${he} attends skirmish-scale wargames, and joins routine security patrols around the arcology.`;
-						} else if (slave.skill.bodyguard <= 200) {
-							r += `${He} receives versatile training on tactics and different weapons, culminating at the end of the week with a live fire exercise.`;
-						}
-						r += ` ${slaveSkillIncrease('bodyguard', slave, skillIncrease)}`;
+					r += ` ${slaveSkillIncrease('recruiter', slave, skillIncrease)}`;
+				}
+				break;
+			case "Bodyguard":
+				if (App.Data.Careers.Leader.bodyguard.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to be a bodyguard, surprising no one.`;
+					slave.skill.bodyguard = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective bodyguard.`;
+					if (slave.skill.bodyguard <= 20) {
+						r += ` ${He} undergoes a personalized boot camp in form of physical exercises, to make sure ${he} has the basic skills required for further security training.`;
+					} else if (slave.skill.bodyguard <= 60) {
+						r += ` The tutor trains ${him} in using and maintaining firearms, and forces ${him} through repetitive dry fire training in order to instill discipline.`;
+					} else if (slave.skill.bodyguard <= 120) {
+						r += ` During the week ${he} attends skirmish-scale wargames, and joins routine security patrols around the arcology.`;
+					} else if (slave.skill.bodyguard <= 200) {
+						r += `${He} receives versatile training on tactics and different weapons, culminating at the end of the week with a live fire exercise.`;
 					}
-					break;
-				case "Madam":
-					if (App.Data.Careers.Leader.madam.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to run a brothel, surprising no one.`;
-						slave.skill.madam = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective brothel madam.`;
-						if (slave.skill.madam <= 20) {
-							r += ` The tutor teaches ${him} the basics of whoring. To make sure the customer pays before they're serviced, how to take care of hygiene and how to take care of whores' health.`;
-						} else if (slave.skill.madam <= 60) {
-							r += ` Having been taught the basics, the lessons shift to learning how to best please a customer. ${He} is taught to converse and how to respond to a customer's desires.`;
-						} else if (slave.skill.madam <= 120) {
-							r += ` Now that ${he} is a masterful whore, the tutor teaches ${him} how to discipline ${his} subordinate whores. ${He} attends online lectures on marketing.`;
-						} else if (slave.skill.madam <= 200) {
-							r += ` ${He} is becoming a master at extracting maximum value from the assets ${he} commands, and is learning how to run the brothel effectively.`;
-						}
-						r += ` ${slaveSkillIncrease('madam', slave, skillIncrease)}`;
+					r += ` ${slaveSkillIncrease('bodyguard', slave, skillIncrease)}`;
+				}
+				break;
+			case "Madam":
+				if (App.Data.Careers.Leader.madam.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to run a brothel, surprising no one.`;
+					slave.skill.madam = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective brothel madam.`;
+					if (slave.skill.madam <= 20) {
+						r += ` The tutor teaches ${him} the basics of whoring. To make sure the customer pays before they're serviced, how to take care of hygiene and how to take care of whores' health.`;
+					} else if (slave.skill.madam <= 60) {
+						r += ` Having been taught the basics, the lessons shift to learning how to best please a customer. ${He} is taught to converse and how to respond to a customer's desires.`;
+					} else if (slave.skill.madam <= 120) {
+						r += ` Now that ${he} is a masterful whore, the tutor teaches ${him} how to discipline ${his} subordinate whores. ${He} attends online lectures on marketing.`;
+					} else if (slave.skill.madam <= 200) {
+						r += ` ${He} is becoming a master at extracting maximum value from the assets ${he} commands, and is learning how to run the brothel effectively.`;
 					}
-					break;
-				case "DJ":
-					if (App.Data.Careers.Leader.DJ.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to DJ a club, surprising no one.`;
-						slave.skill.DJ = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective club manager and DJ.`;
-						if (slave.skill.DJ <= 20) {
-							r += ` The Club is crucial for your reputation, and the DJ is in charge of the club, so classes are quite demanding. ${He} is absolutely unskilled so the tutor is teaches ${him} the very basics. ${He} is undergoing military-like drills in dancing and composure.`;
-						} else if (slave.skill.DJ <= 60) {
-							r += ` ${He} is still quite inexperienced, although ${he} is at least not awkward in conversation anymore. ${His} classes are heavily focused on slut etiquette, dancing and composure, but ${his} moves are still stiff and unsure.`;
-						} else if (slave.skill.DJ <= 120) {
-							r += ` ${He} is already a skilled entertainer, yet ${his} DJ training continues. ${His} training is now more focused on putting ${him} in charge of the whole club facility, which serves to increase public opinion of ${his} owner. ${He} is taught how to make guests feel welcome, and how to manage ${his} employees. `;
-						} else if (slave.skill.DJ <= 200) {
-							r += ` Every movement and gesture of ${him} must engage the crowd. ${He} is so well-trained that ${his} sultry and inviting composure seems entirely natural. ${He} is also taught how to look after subordinate club sluts, to make sure they perform at their best and give the guests an unforgettable experience.`;
-						}
-						r += ` ${slaveSkillIncrease('DJ', slave, skillIncrease)}`;
+					r += ` ${slaveSkillIncrease('madam', slave, skillIncrease)}`;
+				}
+				break;
+			case "DJ":
+				if (App.Data.Careers.Leader.DJ.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to DJ a club, surprising no one.`;
+					slave.skill.DJ = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective club manager and DJ.`;
+					if (slave.skill.DJ <= 20) {
+						r += ` The Club is crucial for your reputation, and the DJ is in charge of the club, so classes are quite demanding. ${He} is absolutely unskilled so the tutor is teaches ${him} the very basics. ${He} is undergoing military-like drills in dancing and composure.`;
+					} else if (slave.skill.DJ <= 60) {
+						r += ` ${He} is still quite inexperienced, although ${he} is at least not awkward in conversation anymore. ${His} classes are heavily focused on slut etiquette, dancing and composure, but ${his} moves are still stiff and unsure.`;
+					} else if (slave.skill.DJ <= 120) {
+						r += ` ${He} is already a skilled entertainer, yet ${his} DJ training continues. ${His} training is now more focused on putting ${him} in charge of the whole club facility, which serves to increase public opinion of ${his} owner. ${He} is taught how to make guests feel welcome, and how to manage ${his} employees. `;
+					} else if (slave.skill.DJ <= 200) {
+						r += ` Every movement and gesture of ${him} must engage the crowd. ${He} is so well-trained that ${his} sultry and inviting composure seems entirely natural. ${He} is also taught how to look after subordinate club sluts, to make sure they perform at their best and give the guests an unforgettable experience.`;
 					}
-					break;
-				case "Nurse":
-					if (App.Data.Careers.Leader.nurse.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to run a clinic, surprising no one.`;
-						slave.skill.nurse = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective clinical nurse.`;
-						if (slave.skill.nurse <= 20) {
-							r += ` ${He} is taught bedside manner, first aid and elementary physiology as basis for further medical tutoring.`;
-						} else if (slave.skill.nurse <= 60) {
-							r += ` During the week ${he} follows tutored instructions on doing common medical tests, preliminary diagnosis and the safe administering of drugs.`;
-						} else if (slave.skill.nurse <= 120) {
-							r += ` ${He} is busy watching lectures on physiology, pathology, biochemistry and other medical subjects under the supervision of a tutor.`;
-						} else if (slave.skill.nurse <= 200) {
-							r += ` In addition to many, lengthy lectures on medicine, ${he} studies emergency care and basic surgery in supervised simulations.`;
-						}
-						r += ` ${slaveSkillIncrease('nurse', slave, skillIncrease)}`;
+					r += ` ${slaveSkillIncrease('DJ', slave, skillIncrease)}`;
+				}
+				break;
+			case "Nurse":
+				if (App.Data.Careers.Leader.nurse.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to run a clinic, surprising no one.`;
+					slave.skill.nurse = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective clinical nurse.`;
+					if (slave.skill.nurse <= 20) {
+						r += ` ${He} is taught bedside manner, first aid and elementary physiology as basis for further medical tutoring.`;
+					} else if (slave.skill.nurse <= 60) {
+						r += ` During the week ${he} follows tutored instructions on doing common medical tests, preliminary diagnosis and the safe administering of drugs.`;
+					} else if (slave.skill.nurse <= 120) {
+						r += ` ${He} is busy watching lectures on physiology, pathology, biochemistry and other medical subjects under the supervision of a tutor.`;
+					} else if (slave.skill.nurse <= 200) {
+						r += ` In addition to many, lengthy lectures on medicine, ${he} studies emergency care and basic surgery in supervised simulations.`;
 					}
-					break;
-				case "Teacher":
-					if (App.Data.Careers.Leader.schoolteacher.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to teach classes, surprising no one.`;
-						slave.skill.teacher = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective teacher.`;
-						if (slave.skill.teacher <= 20) {
-							r += ` ${He} is so inept that the tutor has to teach ${him} the very basics before ${he} can progress any further. ${He} is given grammar and arithmetic lessons.`;
-						} else if (slave.skill.teacher <= 60) {
-							r += ` Now that ${he} has some understanding of the basics, the tutor has ${him} attend more advanced lectures on grammar, mathematics and pronunciation.`;
-						} else if (slave.skill.teacher <= 120) {
-							r += ` Having mastered basic skills, ${he} is now being taught how to teach others. The tutor sends ${him} to work at a local slave school.`;
-						} else if (slave.skill.teacher <= 200) {
-							r += ` ${He} now knows how to teach others, and is now taught how to teach students who do not speak the language, are disabled, be it physically or mentally or simply unwilling to learn.`;
-						}
-						r += ` ${slaveSkillIncrease('teacher', slave, skillIncrease)}`;
+					r += ` ${slaveSkillIncrease('nurse', slave, skillIncrease)}`;
+				}
+				break;
+			case "Teacher":
+				if (App.Data.Careers.Leader.schoolteacher.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to teach classes, surprising no one.`;
+					slave.skill.teacher = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective teacher.`;
+					if (slave.skill.teacher <= 20) {
+						r += ` ${He} is so inept that the tutor has to teach ${him} the very basics before ${he} can progress any further. ${He} is given grammar and arithmetic lessons.`;
+					} else if (slave.skill.teacher <= 60) {
+						r += ` Now that ${he} has some understanding of the basics, the tutor has ${him} attend more advanced lectures on grammar, mathematics and pronunciation.`;
+					} else if (slave.skill.teacher <= 120) {
+						r += ` Having mastered basic skills, ${he} is now being taught how to teach others. The tutor sends ${him} to work at a local slave school.`;
+					} else if (slave.skill.teacher <= 200) {
+						r += ` ${He} now knows how to teach others, and is now taught how to teach students who do not speak the language, are disabled, be it physically or mentally or simply unwilling to learn.`;
 					}
-					break;
-				case "Attendant":
-					if (App.Data.Careers.Leader.attendant.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to manage a spa, surprising no one.`;
-						slave.skill.attendant = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective spa attendant.`;
-						if (slave.skill.attendant <= 20) {
-							r += ` This week, a tutor has ${him} wait on poolside clients while offering back-rubs, an exercise instilling, more than anything, calm patience.`;
-						} else if (slave.skill.attendant <= 60) {
-							r += ` ${He} practices massaging techniques with a tutor until ${his} hands are sore and then suffers through hours of listening to people's problems on an online helpline.`;
-						} else if (slave.skill.attendant <= 120) {
-							r += ` A tutor teaches ${him} relaxing physical therapies. Additionally ${he} attends a course on applied psychology concentrated on mental well-being and stress management.`;
-						} else if (slave.skill.attendant <= 200) {
-							r += ` ${He} spends the week watching lectures of psychiatry and physiotherapy, before attending a practical exam arranged by ${his} tutor.`;
-						}
-						r += ` ${slaveSkillIncrease('attendant', slave, skillIncrease)}`;
+					r += ` ${slaveSkillIncrease('teacher', slave, skillIncrease)}`;
+				}
+				break;
+			case "Attendant":
+				if (App.Data.Careers.Leader.attendant.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to manage a spa, surprising no one.`;
+					slave.skill.attendant = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective spa attendant.`;
+					if (slave.skill.attendant <= 20) {
+						r += ` This week, a tutor has ${him} wait on poolside clients while offering back-rubs, an exercise instilling, more than anything, calm patience.`;
+					} else if (slave.skill.attendant <= 60) {
+						r += ` ${He} practices massaging techniques with a tutor until ${his} hands are sore and then suffers through hours of listening to people's problems on an online helpline.`;
+					} else if (slave.skill.attendant <= 120) {
+						r += ` A tutor teaches ${him} relaxing physical therapies. Additionally ${he} attends a course on applied psychology concentrated on mental well-being and stress management.`;
+					} else if (slave.skill.attendant <= 200) {
+						r += ` ${He} spends the week watching lectures of psychiatry and physiotherapy, before attending a practical exam arranged by ${his} tutor.`;
 					}
-					break;
-				case "Matron":
-					if (App.Data.Careers.Leader.matron.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to run a nursery, surprising no one.`;
-						slave.skill.matron = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective nursery matron.`;
-						if (slave.skill.matron <= 20) {
-							r += ` The tutor teaches ${him} how to care for a body during pregnancy. To eat well, rest, and avoid strenuous activity.`;
-						} else if (slave.skill.matron <= 60) {
-							r += ` ${He} learns how to best prepare a body for a baby's birth. And how to take care of the baby after it has been born.`;
-						} else if (slave.skill.matron <= 120) {
-							r += ` The tutor has ${him} serve as a midwife at a local hospital. ${He} also attends lectures on child development and child psychology.`;
-						} else if (slave.skill.matron <= 200) {
-							r += ` ${He} continues attending lectures, but at the same time the tutor teaches ${him} how to take care of others while they are pregnant. ${He}'s quickly learning how to best rear children.`;
-						}
-						r += ` ${slaveSkillIncrease('matron', slave, skillIncrease)}`;
+					r += ` ${slaveSkillIncrease('attendant', slave, skillIncrease)}`;
+				}
+				break;
+			case "Matron":
+				if (App.Data.Careers.Leader.matron.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to run a nursery, surprising no one.`;
+					slave.skill.matron = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective nursery matron.`;
+					if (slave.skill.matron <= 20) {
+						r += ` The tutor teaches ${him} how to care for a body during pregnancy. To eat well, rest, and avoid strenuous activity.`;
+					} else if (slave.skill.matron <= 60) {
+						r += ` ${He} learns how to best prepare a body for a baby's birth. And how to take care of the baby after it has been born.`;
+					} else if (slave.skill.matron <= 120) {
+						r += ` The tutor has ${him} serve as a midwife at a local hospital. ${He} also attends lectures on child development and child psychology.`;
+					} else if (slave.skill.matron <= 200) {
+						r += ` ${He} continues attending lectures, but at the same time the tutor teaches ${him} how to take care of others while they are pregnant. ${He}'s quickly learning how to best rear children.`;
 					}
-					break;
-				case "Stewardess":
-					if (App.Data.Careers.Leader.stewardess.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to oversee servants, surprising no one.`;
-						slave.skill.stewardess = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective stewardess.`;
-						if (slave.skill.stewardess <= 20) {
-							r += ` ${He} has no skill as a servant, so the tutor teaches ${him} the basics. What to clean, how to clean and using which products.`;
-						} else if (slave.skill.stewardess <= 60) {
-							r += ` Having been taught the basics, ${his} studies continue by following cleaning crews to various parts of your arcologies to get practical experience as well as become familiar with the cleaning routines of all sectors.`;
-						} else if (slave.skill.stewardess <= 120) {
-							r += ` The tutor has ${him} attend lectures on slave breaking and management, to prepare ${him} for running a facility. ${He} keeps working with the cleaning crews, but now takes command during outings.`;
-						} else if (slave.skill.stewardess <= 200) {
-							r += ` ${He} is familiar with every nook and cranny of your arcology. ${He} no longer accompanies your cleaning crews, instead ${he} organizes their deployments. ${He} is becoming an adept manager.`;
-						}
-						r += ` ${slaveSkillIncrease('stewardess', slave, skillIncrease)}`;
+					r += ` ${slaveSkillIncrease('matron', slave, skillIncrease)}`;
+				}
+				break;
+			case "Stewardess":
+				if (App.Data.Careers.Leader.stewardess.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to oversee servants, surprising no one.`;
+					slave.skill.stewardess = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective stewardess.`;
+					if (slave.skill.stewardess <= 20) {
+						r += ` ${He} has no skill as a servant, so the tutor teaches ${him} the basics. What to clean, how to clean and using which products.`;
+					} else if (slave.skill.stewardess <= 60) {
+						r += ` Having been taught the basics, ${his} studies continue by following cleaning crews to various parts of your arcologies to get practical experience as well as become familiar with the cleaning routines of all sectors.`;
+					} else if (slave.skill.stewardess <= 120) {
+						r += ` The tutor has ${him} attend lectures on slave breaking and management, to prepare ${him} for running a facility. ${He} keeps working with the cleaning crews, but now takes command during outings.`;
+					} else if (slave.skill.stewardess <= 200) {
+						r += ` ${He} is familiar with every nook and cranny of your arcology. ${He} no longer accompanies your cleaning crews, instead ${he} organizes their deployments. ${He} is becoming an adept manager.`;
 					}
-					break;
-				case "Milkmaid":
-					if (App.Data.Careers.Leader.milkmaid.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to run a free range dairy, surprising no one.`;
-						slave.skill.milkmaid = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective milkmaid.`;
-						if (slave.skill.milkmaid <= 20) {
-							r += ` The tutor teaches ${him} the basics. ${He} is taught what to eat to maximize fluid production, as well as how to milk udders.`;
-						} else if (slave.skill.milkmaid <= 60) {
-							r += ` Having been taught the basics, the tutor has ${him} work at a farm milking cows. ${He} also attends online lectures on nutrition and health.`;
-						} else if (slave.skill.milkmaid <= 120) {
-							r += ` Having been taught how to milk and how to take care of ones body to produce as much fluid as possible, ${his} training shifts to teach ${him} leadership skills.`;
-						} else if (slave.skill.milkmaid <= 200) {
-							r += ` ${He} is becoming an adept leader, who knows how to squeeze every last drop of milk and cum out of ${his} cows. The tutor believes ${he} will soon be able to run ${his} facility on ${his} own.`;
-						}
-						r += ` ${slaveSkillIncrease('milkmaid', slave, skillIncrease)}`;
+					r += ` ${slaveSkillIncrease('stewardess', slave, skillIncrease)}`;
+				}
+				break;
+			case "Milkmaid":
+				if (App.Data.Careers.Leader.milkmaid.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to run a free range dairy, surprising no one.`;
+					slave.skill.milkmaid = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective milkmaid.`;
+					if (slave.skill.milkmaid <= 20) {
+						r += ` The tutor teaches ${him} the basics. ${He} is taught what to eat to maximize fluid production, as well as how to milk udders.`;
+					} else if (slave.skill.milkmaid <= 60) {
+						r += ` Having been taught the basics, the tutor has ${him} work at a farm milking cows. ${He} also attends online lectures on nutrition and health.`;
+					} else if (slave.skill.milkmaid <= 120) {
+						r += ` Having been taught how to milk and how to take care of ones body to produce as much fluid as possible, ${his} training shifts to teach ${him} leadership skills.`;
+					} else if (slave.skill.milkmaid <= 200) {
+						r += ` ${He} is becoming an adept leader, who knows how to squeeze every last drop of milk and cum out of ${his} cows. The tutor believes ${he} will soon be able to run ${his} facility on ${his} own.`;
 					}
-					break;
-				case "Farmer":
-					if (App.Data.Careers.Leader.farmer.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to run a farm, surprising no one.`;
-						slave.skill.farmer = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective farmer.`;
-						if (slave.skill.farmer <= 20) {
-							r += ` The tutor has ${him} working on a farm, nothing beats practical learning. ${He} learns how to grow cops and how to care for farm animals.`;
-						} else if (slave.skill.farmer <= 60) {
-							r += ` Having become familiar with farming, the tutor now has ${him} attend lectures on the science behind it. ${His} knowledge greatly increases due to this.`;
-						} else if (slave.skill.farmer <= 120) {
-							r += ` ${He} oversees a group of farmhands as they care for the animals and plow the fields. Having mastered farming, ${he}'s now training ${his} leadership skills.`;
-						} else if (slave.skill.farmer <= 200) {
-							r += ` The tutor has ${him} lead an entire farm. ${He} manages every aspect, and does so admirably. ${He} is also introduced to a different side of slave farming, the "shows". It doesn't take long before ${he}'s overseeing those too.`;
-						}
-						r += ` ${slaveSkillIncrease('farmer', slave, skillIncrease)}`;
+					r += ` ${slaveSkillIncrease('milkmaid', slave, skillIncrease)}`;
+				}
+				break;
+			case "Farmer":
+				if (App.Data.Careers.Leader.farmer.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to run a farm, surprising no one.`;
+					slave.skill.farmer = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective farmer.`;
+					if (slave.skill.farmer <= 20) {
+						r += ` The tutor has ${him} working on a farm, nothing beats practical learning. ${He} learns how to grow cops and how to care for farm animals.`;
+					} else if (slave.skill.farmer <= 60) {
+						r += ` Having become familiar with farming, the tutor now has ${him} attend lectures on the science behind it. ${His} knowledge greatly increases due to this.`;
+					} else if (slave.skill.farmer <= 120) {
+						r += ` ${He} oversees a group of farmhands as they care for the animals and plow the fields. Having mastered farming, ${he}'s now training ${his} leadership skills.`;
+					} else if (slave.skill.farmer <= 200) {
+						r += ` The tutor has ${him} lead an entire farm. ${He} manages every aspect, and does so admirably. ${He} is also introduced to a different side of slave farming, the "shows". It doesn't take long before ${he}'s overseeing those too.`;
 					}
-					break;
-				case "Wardeness":
-					if (App.Data.Careers.Leader.wardeness.includes(slave.career)) {
-						r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to oversee a cellblock, surprising no one.`;
-						slave.skill.wardeness = 200;
-					} else {
-						r += ` ${He} spends time with a tutor training to be an effective cellblock wardeness.`;
-						if (slave.skill.wardeness <= 20) {
-							r += ` A tutor takes ${him} through basic self-defense and the safe use of prison equipment.`;
-						} else if (slave.skill.wardeness <= 60) {
-							r += ` ${He} practices wrestling holds with a tutor, who also shows ${him} how to tie up resisting victims.`;
-						} else if (slave.skill.wardeness <= 120) {
-							r += ` The correctional psychology lectures ${he} watches this week are unburdened by ethics. ${He} learns how to handle prisoners more effectively.`;
-						} else if (slave.skill.wardeness <= 200) {
-							r += ` ${He} gets to study enhanced interrogation techniques from an experienced tutor, with ample demonstrations on live subjects, including ${himself}.`;
-						}
-						r += ` ${slaveSkillIncrease('wardeness', slave, skillIncrease)}`;
+					r += ` ${slaveSkillIncrease('farmer', slave, skillIncrease)}`;
+				}
+				break;
+			case "Wardeness":
+				if (App.Data.Careers.Leader.wardeness.includes(slave.career)) {
+					r += ` ${He} shows up the tutor by utilizing applicable skills from ${his} prior life as ${slave.career}. The service <span class="cash dec">will not offer a refund,</span> but does recognize ${him} as qualified to oversee a cellblock, surprising no one.`;
+					slave.skill.wardeness = 200;
+				} else {
+					r += ` ${He} spends time with a tutor training to be an effective cellblock wardeness.`;
+					if (slave.skill.wardeness <= 20) {
+						r += ` A tutor takes ${him} through basic self-defense and the safe use of prison equipment.`;
+					} else if (slave.skill.wardeness <= 60) {
+						r += ` ${He} practices wrestling holds with a tutor, who also shows ${him} how to tie up resisting victims.`;
+					} else if (slave.skill.wardeness <= 120) {
+						r += ` The correctional psychology lectures ${he} watches this week are unburdened by ethics. ${He} learns how to handle prisoners more effectively.`;
+					} else if (slave.skill.wardeness <= 200) {
+						r += ` ${He} gets to study enhanced interrogation techniques from an experienced tutor, with ample demonstrations on live subjects, including ${himself}.`;
 					}
-					break;
-				default:
-					r += `tutorLessons ERROR unknown skill`;
-			}
-		} else {
-			r += `You did not have enough credits for private tutoring.`;
+					r += ` ${slaveSkillIncrease('wardeness', slave, skillIncrease)}`;
+				}
+				break;
+			default:
+				r += `tutorLessons ERROR unknown skill`;
 		}
 	}
 
@@ -751,42 +730,55 @@ App.SlaveAssignment.takeClasses = (function() {
 	 *
 	 */
 	function graduation(slave) {
-		if (slave.intelligenceImplant >= 15 && slave.assignment === Job.CLASSES) {
-			if ((slave.voice === 0) || (slave.accent <= 1) || (V.schoolroomUpgradeLanguage === 0 && slave.accent <= 2)) {
-				if ((slave.skill.oral > 30) || (V.schoolroomUpgradeSkills === 0 && slave.skill.oral > 10)) {
-					if ((slave.skill.whoring > 30) || (V.schoolroomUpgradeSkills === 0 && slave.skill.whoring > 10)) {
-						if ((slave.skill.entertainment > 30) || (V.schoolroomUpgradeSkills === 0 && slave.skill.entertainment > 10)) {
-							if ((slave.skill.anal > 30) || (V.schoolroomUpgradeSkills === 0 && slave.skill.anal > 10)) {
-								if ((slave.skill.vaginal > 30) || (V.schoolroomUpgradeSkills === 0 && slave.skill.vaginal > 10) || (slave.vagina < 0)) {
-									if (!needsTutoring(slave)) {
-										r += ` ${He} can learn little from further classes, <span class="noteworthy">`;
-										if (V.assignmentRecords[slave.ID]) {
-											let oldJob = V.assignmentRecords[slave.ID];
-											assignJobSafely(slave, oldJob);
-											if (slave.choosesOwnAssignment === 1) {
-												r += ` so ${he} takes a break before choosing another task.`;
-											// @ts-ignore
-											} else if (slave.assignment === Job.REST) {
-												if (oldJob !== Job.REST) {
-													r += ` and since ${he} was unable to return to ${his} old job (${oldJob}), ${his} assignment has defaulted to rest.`;
-												} else {
-													r += ` so ${he} has returned to resting.`;
-												}
-											} else {
-												r += ` so ${he} goes back to ${oldJob}.`;
-											}
-										} else {
-											r += ` so ${his} assignment has defaulted to rest.`;
-											removeJob(slave, slave.assignment);
-										}
-										r += `</span>`;
-									}
-								}
-							}
-						}
-					}
+		// can't graduate a slave not in the classroom
+		if (slave.assignment !== Job.CLASSES) {
+			return;
+		}
+
+		// check if the slave has something left to learn
+		if (slave.intelligenceImplant < 15) {
+			return;
+		}
+		if (slave.voice > 0 && slave.accent > 1 && (slave.accent > 2 || V.schoolroomUpgradeLanguage > 0)) {
+			return;
+		}
+		if (slave.skill.oral <= 10 || slave.skill.whoring <= 10 ||
+			slave.skill.entertainment <= 10 || slave.skill.anal <= 10 ||
+			(V.schoolroomUpgradeSkills > 0 &&
+				(
+					slave.skill.oral <= 30 || slave.skill.whoring <= 30 ||
+					slave.skill.entertainment <= 30 || slave.skill.anal <= 30
+				))) {
+			return;
+		}
+		if (slave.vagina >= 0 && (slave.skill.vaginal <= 10 || (V.schoolroomUpgradeSkills > 0 && slave.skill.vaginal <= 30))) {
+			return;
+		}
+		if (needsTutoring(slave)) {
+			return;
+		}
+
+		// Throw the slave out
+		r += ` ${He} can learn little from further classes, <span class="noteworthy">`;
+		if (V.assignmentRecords[slave.ID]) {
+			let oldJob = V.assignmentRecords[slave.ID];
+			assignJobSafely(slave, oldJob);
+			if (slave.choosesOwnAssignment === 1) {
+				r += ` so ${he} takes a break before choosing another task.`;
+				// @ts-ignore
+			} else if (slave.assignment === Job.REST) {
+				if (oldJob !== Job.REST) {
+					r += ` and since ${he} was unable to return to ${his} old job (${oldJob}), ${his} assignment has defaulted to rest.`;
+				} else {
+					r += ` so ${he} has returned to resting.`;
 				}
+			} else {
+				r += ` so ${he} goes back to ${oldJob}.`;
 			}
+		} else {
+			r += ` so ${his} assignment has defaulted to rest.`;
+			removeJob(slave, slave.assignment);
 		}
+		r += `</span>`;
 	}
-})();
+};
diff --git a/src/endWeek/saWhore.js b/src/endWeek/saWhore.js
index 50ce837c429289f084b3a53a3684f589015fc253..5879da42cdea33905e7980cf6f1985f9bf23658d 100644
--- a/src/endWeek/saWhore.js
+++ b/src/endWeek/saWhore.js
@@ -496,7 +496,7 @@ App.SlaveAssignment.whore = (function() {
 					slave.trust -= 10;
 					slave.vagina = 1;
 				}
-			} else if (slave.vagina < 3) {
+			} else if (V.seeStretching === 1 && slave.vagina < 3) {
 				if (jsRandom(1, 100) > ((170 - beauty) + (slave.vagina * 10) + (slave.skill.vaginal / 3))) {
 					r += ` <span class="change positive">${His} pussy gets loosened by the intense use.</span>`;
 					slave.vagina += 1;
@@ -520,7 +520,7 @@ App.SlaveAssignment.whore = (function() {
 					slave.trust -= 5;
 					slave.anus = 2;
 				}
-			} else if (slave.anus < 3) {
+			} else if (V.seeStretching === 1 && slave.anus < 3) {
 				if (slave.vagina < 0) {
 					if (jsRandom(1, 100) > ((150 - beauty) + (slave.anus * 10) + (slave.skill.anal / 6))) {
 						r += ` <span class="change positive">${His} asshole sees constant use in place of a pussy and loosens.</span>`;
@@ -1581,7 +1581,7 @@ App.SlaveAssignment.whore = (function() {
 			} else {
 				r += `an incident without lasting effect.`;
 			}
-			slave.devotion += (1 * vignette.effect);
+			slave.devotion += vignette.effect;
 		} else if (vignette.type === "trust") {
 			if (vignette.effect > 0) {
 				if (slave.trust > 20) {
@@ -1602,7 +1602,7 @@ App.SlaveAssignment.whore = (function() {
 			} else {
 				r += `an incident without lasting effect.`;
 			}
-			slave.trust += (1 * vignette.effect);
+			slave.trust += vignette.effect;
 		} else if (vignette.type === "health") {
 			if (vignette.effect > 0) {
 				r += `<span class="health inc">improving ${his} health.</span>`;
diff --git a/src/endWeek/saWorkAGloryHole.js b/src/endWeek/saWorkAGloryHole.js
index 16e1bc0cf32481fca023b57ff5e26a5be32f5a4e..f1610d7e139b7a531dd3ec54bd15b80cfc7430a6 100644
--- a/src/endWeek/saWorkAGloryHole.js
+++ b/src/endWeek/saWorkAGloryHole.js
@@ -1,57 +1,37 @@
-App.SlaveAssignment.workAGloryHole = (function() {
-	"use strict";
+/**
+ * @param {FC.ReportSlave} slave
+ * @returns {string}
+ */
+App.SlaveAssignment.workAGloryHole = function saWorkAGloryHole(slave) {
+	const {
+		he, him, his, He, His
+	} = getPronouns(slave);
+	const beauty = slave.sexAmount; /* This gets calculated during slaveAssignmentReport and stored on the slave for later use */
+	const FResult = V.arcadePrice; /* This gets calculated during slaveAssignmentReport after we know the total 'arcade' sex slave supply */
 
-	let incomeStats;
-	let r;
-	let beauty;
-	let FResult;
-	/* eslint-disable no-unused-vars*/
-	let he;
-	let him;
-	let his;
-	let hers;
-	let himself;
-	let boy;
-	let He;
-	let His;
-	/* eslint-enable */
+	let r = ``;
 
-	return saWorkAGloryHole;
+	const incomeStats = gatherStatistics(slave);
+	jobPreface(slave);
+	physicalEffects(slave);
+	mentalEffects(slave);
+	jobBody(slave);
+	applyFSDecoration(slave);
+	sexCounts(slave);
+	profitReport(slave);
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @returns {string}
-	 */
-	function saWorkAGloryHole(slave) {
-		r = ``;
-		({
-			// eslint-disable-next-line no-unused-vars
-			he, him, his, hers, himself, boy, He, His
-		} = getPronouns(slave));
-		beauty = slave.sexAmount; /* This gets calculated during slaveAssignmentReport and stored on the slave for later use */
-		FResult = V.arcadePrice; /* This gets calculated during slaveAssignmentReport after we know the total 'arcade' sex slave supply */
-
-		gatherStatistics(slave);
-		jobPreface(slave);
-		physicalEffects(slave);
-		mentalEffects(slave);
-		jobBody(slave);
-		applyFSDecoration(slave);
-		sexCounts(slave);
-		profitReport(slave);
-
-		return r;
-	}
+	return r;
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 *
+	 * @returns {Object}
 	 */
 	function gatherStatistics(slave) {
 		/* Statistics gathering */
 		const facility = slave.assignment === window.Job.ARCADE ? V.facility.arcade : undefined;
-		incomeStats = getSlaveStatisticData(slave, facility);
+		let incomeStats = getSlaveStatisticData(slave, facility);
 		incomeStats.customers = beauty;
+		return incomeStats;
 	}
 
 	/**
@@ -92,8 +72,7 @@ App.SlaveAssignment.workAGloryHole = (function() {
 	}
 
 	/**
-	 * @param {App.Entity.SlaveState} slave
-	 *
+	 * @param {FC.ReportSlave} slave
 	 */
 	function physicalEffects(slave) {
 		// check usage counts for these — more fucks should be more damaging
@@ -193,7 +172,7 @@ App.SlaveAssignment.workAGloryHole = (function() {
 			slave.devotion -= 10;
 			slave.trust -= 10;
 			slave.vagina = 1;
-		} else if (slave.vagina < 3 && canDoVaginal(slave) && jsRandom(1, 100) > ((310 - beauty) + (slave.vagina * 10))) {
+		} else if (V.seeStretching === 1 && slave.vagina < 3 && canDoVaginal(slave) && jsRandom(1, 100) > ((310 - beauty) + (slave.vagina * 10))) {
 			r += ` <span class="lime">${His} pussy gets stretched out by the use.</span>`;
 			slave.vagina += 1;
 		}
@@ -215,7 +194,7 @@ App.SlaveAssignment.workAGloryHole = (function() {
 			slave.devotion -= 5;
 			slave.trust -= 5;
 			slave.anus = 1;
-		} else if (slave.anus < 3 && canDoAnal(slave) && jsRandom(1, 100) > ((290 - beauty) + (slave.anus * 10))) {
+		} else if (V.seeStretching === 1 && slave.anus < 3 && canDoAnal(slave) && jsRandom(1, 100) > ((290 - beauty) + (slave.anus * 10))) {
 			r += ` <span class="lime">${His} asshole sees constant use and loosens.</span>`;
 			slave.anus += 1;
 		}
@@ -442,4 +421,4 @@ App.SlaveAssignment.workAGloryHole = (function() {
 
 		incomeStats.income += cash;
 	}
-})();
+};
diff --git a/src/endWeek/saWorkTheFarm.js b/src/endWeek/saWorkTheFarm.js
index fdf51492543f2963640b70ca96a7f9558a4386ed..bc5d56aa3274bf1c5226ebed6ef9f5d9bb784814 100644
--- a/src/endWeek/saWorkTheFarm.js
+++ b/src/endWeek/saWorkTheFarm.js
@@ -5,45 +5,39 @@
 App.SlaveAssignment.workTheFarm = function(slave) {
 	const frag = document.createDocumentFragment();
 
-	const {he, him, his, He, His} = getPronouns(slave);
+	const {he, him, his, He} = getPronouns(slave);
 	const incomeStats = getSlaveStatisticData(slave, V.facility.farmyard);
 
 	const sexualQuirks = ["perverted", "unflinching"];
 	const behavioralQuirks = ["sinful"];
 	const fetishes = ["humiliation", "masochist"];
 
-	const slaveApproves = sexualQuirks.includes(slave.sexualQuirk) || behavioralQuirks.includes(slave.behavioralQuirk) ||fetishes.includes(slave.fetish);
+	const slaveApproves = sexualQuirks.includes(slave.sexualQuirk) ||
+		behavioralQuirks.includes(slave.behavioralQuirk) ||
+		fetishes.includes(slave.fetish);
 
 	const foodAmount = Math.trunc(App.Facilities.Farmyard.foodAmount(slave));
 
-	const intro = `${He} works as a farmhand this week.`;
+	const intro = `${He} works in ${V.farmyardName} this week.`;
 
-	foodProduction();
-
-	fullReport(slave);
+	fullReport();
 
 	return frag;
 
-	function fullReport(slave) {
+	function fullReport() {
 		const text = new SpacedTextAccumulator(frag);
 
 		text.push(
 			intro,
-			devotion(slave),
-			muscles(slave),
-			weight(slave),
-			health(slave),
-			sight(slave),
-			hearing(slave),
-			shows(),
 
-			slaveShows(slave),
-			longTermEffects(slave),
-			results(slave),
+			food(),
+			shows(),
+			longTermEffects(),
+			results(),
 			slaveVignettes(),
 		);
 
-		return text.toParagraph();
+		return text.toChildren();
 	}
 
 	// function farmer(slave) {
@@ -55,117 +49,8 @@ App.SlaveAssignment.workTheFarm = function(slave) {
 	// 	}
 	// }
 
-	function devotion(slave) {
-		if (slave.devotion > 50) {
-			return `${He}'s so devoted to you that ${he} works harder and produces more food.`;
-		} else if (slave.devotion < -50) {
-			return `${He}'s so resistant that ${he} doesn't work as hard, and thus produces less food.`;
-		} else {
-			return `${He} doesn't feel particularly compelled to work hard or slack off and produces an average amount of food.`;
-		}
-	}
-
-	function health(slave) {
-		const text = [];
-
-		text.push(
-			healthCondition(slave),
-			healthIllness(slave),
-		);
-
-		return text.join(' ');
-	}
-
-	function healthCondition(slave) {
-		if (slave.health.condition > 50) {
-			return `${His} shining health helps ${him} work harder and longer.`;
-		} else if (slave.health.condition < -50) {
-			return `${His} poor health impedes ${his} ability to work efficiently.`;
-		}
-	}
-
-	function healthIllness(slave) {
-		const text = [];
-		let health = ``;
-		let exhaustion = ``;
-
-		if (slave.health.illness > 0 || slave.health.tired > 60) {
-			if (slave.health.illness === 1) {
-				health = `feeling under the weather`;
-			} else if (slave.health.illness === 2) {
-				health = `a minor illness`;
-			} else if (slave.health.illness === 3) {
-				health = `being sick`;
-			} else if (slave.health.illness === 4) {
-				health = `being very sick`;
-			} else if (slave.health.illness === 5) {
-				health = `a terrible illness`;
-			}
-
-			if (slave.health.tired > 90) {
-				exhaustion = `exhaustion`;
-			} else if (slave.health.tired > 60) {
-				exhaustion = `being tired`;
-			}
-
-			text.push(`${He} performed worse this week due to <span class="health dec">${health}${slave.health.illness > 0 && slave.health.tired > 60 ? ` and ` : ``}${exhaustion}.</span>`);
-
-			text.push(tired(slave));
-		}
-
-		return text;
-	}
-
-	function tired(slave) {
-		if (slaveResting(slave)) {
-			return `${He} spends reduced hours working the soil in order to <span class="health dec">offset ${his} lack of rest.</span>`;
-		} else if (slave.health.tired + 20 >= 90 && !willWorkToDeath(slave)) {
-			return `${He} attempts to refuse work due to ${his} exhaustion, but can do little to stop it or the resulting <span class="trust dec">severe punishment.</span> ${He} <span class="devotion dec">purposefully underperforms,</span> choosing ${his} overall well-being over the consequences, <span class="health dec">greatly reducing yields.</span>`;
-		} else {
-			return `Hours of manual labor quickly add up, leaving ${him} <span class="health dec">physically drained</span> by the end of the day.`;
-		}
-	}
-
-	function muscles(slave) {
-		if (slave.muscles > 50) {
-			return `${His} muscular form helps ${him} work better, increasing ${his} productivity.`;
-		} else if (slave.muscles < -50) {
-			return `${He} is so weak that ${he} is not able to work effectively.`;
-		}
-	}
-
-	function weight(slave) {
-		if (slave.weight > 95) {
-			return `${He} is so overweight that ${he} has to stop every few minutes to catch ${his} breath, and so ${his} productivity suffers. `;
-		}
-	}
-
-	function sight(slave) {
-		if (!canSee(slave)) {
-			return `${His} blindness makes it extremely difficult for ${him} to work, severely limiting ${his} production.`;
-		} else if (!canSeePerfectly(slave)) {
-			return `${His} nearsightedness makes it harder for ${him} to work as hard as ${he} otherwise would.`;
-		}
-	}
-
-	function hearing(slave) {
-		if (slave.hears === -1) {
-			return `${He} is hard-of-hearing, which gets in the way of ${his} work whenever ${he} misses directions${S.Farmer ? ` from ${S.Farmer.slaveName}` : ``}.`;
-		} else if (slave.hears < -1) {
-			return `${He} is deaf, which gets in the way of ${his} work whenever ${he} misses directions${S.Farmer ? ` from ${S.Farmer.slaveName}` : ``}.`;
-		}
-	}
-
-	function shows() {
-		if (V.farmyardShows) {
-			return `Since ${he} also has to put on shows for your citizens, ${he} can only work on food production for half of ${his} shift, cutting down on the amount of food ${he} would have otherwise produced.`;
-		}
-	}
-
-	// Food Production
-
-	function foodProduction() {
-		if (V.mods.food.market) {
+	function food() {
+		if (V.mods.food.market && V.farmyardShows < 2) {
 			const fsGain = 0.0001 * foodAmount;
 
 			FutureSocieties.DecorationBonus(V.farmyardDecoration, fsGain);
@@ -173,21 +58,22 @@ App.SlaveAssignment.workTheFarm = function(slave) {
 			V.mods.food.produced += foodAmount;
 			V.mods.food.total += foodAmount;
 			incomeStats.food += foodAmount;
+
+			return App.Facilities.Farmyard.produceFood(slave);
 		}
 	}
 
-	// Shows
+	function shows() {
+		if (V.farmyardShows > 0) {
+			cashX(App.Facilities.Farmyard.farmShowsIncome(slave), "slaveAssignmentFarmyard", slave);
 
-	function slaveShows(slave) {
-		if (V.farmyardShows) {
 			return App.Facilities.Farmyard.putOnShows(slave);
 		}
 	}
 
-	// Long-Term Effects
-
-	function longTermEffects(slave) {
-		if (V.farmyardShows) {
+	function longTermEffects() {
+		// TODO: rewrite these
+		if (V.farmyardShows > 0) {
 			if (V.seeBestiality) {
 				if (slave.fetishKnown && slaveApproves) {
 					slave.devotion += 1;
@@ -209,16 +95,16 @@ App.SlaveAssignment.workTheFarm = function(slave) {
 		}
 	}
 
-	function results(slave) {
+	function results() {
 		const text = [];
 
 		text.push(`All said and done,`);
 
-		if (V.mods.food.market) {
+		if (V.mods.food.market && V.farmyardShows < 2) {
 			text.push(`${he} produces <span class="chocolate">${massFormat(foodAmount)}</span> of food`);
 		}
 
-		if (V.farmyardShows) {
+		if (V.farmyardShows > 0) {
 			if (V.mods.food.market) {
 				text.push(`and`);
 			} else {
diff --git a/src/endWeek/shared/physicalDevelopment.js b/src/endWeek/shared/physicalDevelopment.js
new file mode 100644
index 0000000000000000000000000000000000000000..5af501c23e4aefd17eef1b2c401fc2310e3a2f81
--- /dev/null
+++ b/src/endWeek/shared/physicalDevelopment.js
@@ -0,0 +1,3745 @@
+App.EndWeek.Shared.physicalDevelopment = function(actor, player = false) {
+	let gigantomastiaMod;
+	let uterineHypersensitivityMod;
+	const rearQuirk = actor.geneticQuirks.rearLipedema === 2 ? 2 : 0;
+	const rearQuirkDivider = rearQuirk === 0 ? 1 : rearQuirk;
+	const dickMod = (actor.geneticQuirks.wellHung === 2 ? 2 : 1);
+	let physicalAgeSwap;
+	const tallerPC = (player && actor.height >= Height.mean(actor) + 5);
+
+	if (actor.geneticQuirks.progeria === 2) {
+		// since progeria increases .physicalAge, we need to work around it.
+		// nothing other than the incubator drastically desyncs it, and progeria actors do not live through incubation, so this should be fine.
+		physicalAgeSwap = actor.actualAge;
+	} else {
+		physicalAgeSwap = actor.physicalAge;
+	}
+	if (actor.geneMods.NCS !== 1) {
+		/* NCS completely blocks all natural physical growth: no height increases. It also blocks all hormonal secondary sexual * characteristics. So, on the female side: no boobs, no butt, no hips, and no labia. And on the male side: no dick, no clit, no balls, no scrotum, no shoulders. */
+		/* so this is a big old NO-OP to skip the physical development. */
+		if (actor.geneticQuirks.androgyny === 2) { /* takes a mix of both to create a very androgynous slave */
+			if (actor.geneticQuirks.dwarfism === 2 && actor.geneticQuirks.gigantism !== 2) {
+				increaseHeightDwarf(actor);
+			} else if (actor.geneticQuirks.gigantism === 2) {
+				increaseHeightGiant(actor);
+			} else if (actor.geneticQuirks.neoteny === 2) {
+				increaseHeightNeoteny(actor);
+			} else {
+				increaseHeightXX(actor);
+			}
+			if (actor.geneticQuirks.neoteny !== 2) {
+				if (actor.boobs - actor.boobsImplant <= 300) {
+					increaseBoobsXX(actor);
+				}
+				if (actor.dick.isBetween(0, 3) || actor.geneticQuirks.wellHung === 2) {
+					increaseDick(actor);
+				}
+				if (actor.balls.isBetween(0, 3)) {
+					increaseBalls(actor);
+				}
+				if (actor.vagina > 0 && actor.ovaries > 0 && physicalAgeSwap > actor.pubertyAgeXX) {
+					increaseWetness(actor);
+				}
+				if (actor.waist < 10) {
+					increaseWaistXY(actor);
+				}
+				if (actor.hips - actor.hipsImplant < 0) {
+					increaseHipsXX(actor);
+				}
+				if (actor.butt - actor.buttImplant < 3) {
+					increaseButtXX(actor);
+				}
+			}
+			increasePregAdaptationXX(actor);
+		} else if (actor.genes === "XX") { /* loli becoming a woman */
+			if (actor.geneticQuirks.dwarfism === 2 && actor.geneticQuirks.gigantism !== 2) {
+				increaseHeightDwarf(actor);
+			} else if (actor.geneticQuirks.gigantism === 2) {
+				increaseHeightGiant(actor);
+			} else if (actor.geneticQuirks.neoteny === 2) {
+				increaseHeightNeoteny(actor);
+			} else {
+				increaseHeightXX(actor);
+			}
+			if (physicalAgeSwap === 13 || (physicalAgeSwap > 13 && (actor.hormoneBalance >= 100 || actor.hormoneBalance <= -100))) {
+				increaseFaceXX(actor);
+				if (actor.voice > 0) {
+					increaseVoiceXX(actor);
+				}
+			}
+			if (actor.geneticQuirks.neoteny !== 2) {
+				increaseBoobsXX(actor);
+				if (actor.clit > 0) {
+					increaseClit(actor);
+				}
+				if (actor.vagina > 0 && actor.ovaries > 0 && physicalAgeSwap > actor.pubertyAgeXX) {
+					increaseWetness(actor);
+				}
+				increaseWaistXX(actor);
+				increaseHipsXX(actor);
+				increaseButtXX(actor);
+			}
+			increasePregAdaptationXX(actor);
+		} else {
+			/* shota becoming a man */
+			if (actor.geneticQuirks.dwarfism === 2 && actor.geneticQuirks.gigantism !== 2) {
+				increaseHeightDwarf(actor);
+			} else if (actor.geneticQuirks.gigantism === 2) {
+				increaseHeightGiant(actor);
+			} else if (actor.geneticQuirks.neoteny === 2) {
+				increaseHeightNeoteny(actor);
+			} else {
+				increaseHeightXY(actor);
+			}
+			if (physicalAgeSwap === 13 || (physicalAgeSwap > 13 && (actor.hormoneBalance >= 100 || actor.hormoneBalance <= -100))) {
+				increaseFaceXY(actor);
+				if (actor.voice > 1) {
+					increaseVoiceXY(actor);
+				}
+			}
+			if (actor.geneticQuirks.neoteny !== 2) {
+				increaseBoobsXY(actor);
+				if (actor.dick > 0) {
+					increaseDick(actor);
+				}
+				if (actor.balls > 0) {
+					increaseBalls(actor);
+				}
+				increaseWaistXY(actor);
+				increaseHipsXY(actor);
+				increaseButtXY(actor);
+			}
+			increasePregAdaptationXY(actor);
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseHeightXX(actor) {
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 91) {
+					actor.height += jsEither([8, 8, 9, 9]);
+				} else if (actor.height <= 101) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 101) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 109) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 109) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 116) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 116) {
+					actor.height += jsEither([5, 5, 6, 6]);
+				} else if (actor.height <= 124) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 124) {
+					actor.height += jsEither([7, 7, 8, 8]);
+				} else if (actor.height <= 131) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 131) {
+					actor.height += jsEither([5, 5, 6, 6]);
+				} else if (actor.height <= 137) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 137) {
+					actor.height += jsEither([4, 4, 5, 5]);
+				} else if (actor.height <= 144) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 144) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 156) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 156) {
+					actor.height += jsEither([5, 5, 6, 6]);
+				} else if (actor.height <= 163) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 163) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 168) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 168) {
+					actor.height += jsEither([5, 5, 6, 6]);
+				} else if (actor.height <= 171) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 171) {
+					actor.height += jsEither([4, 4, 5, 5]);
+				} else if (actor.height <= 173) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 0, 1, 1]);
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 0, 1, 1]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 0, 1, 1]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 0, 1, 1]);
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 91) {
+					actor.height += jsEither([8, 8, 9, 9, 9]);
+				} else if (actor.height <= 101) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 101) {
+					actor.height += jsEither([6, 6, 7, 7, 7]);
+				} else if (actor.height <= 109) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 109) {
+					actor.height += jsEither([6, 6, 7, 7, 7]);
+				} else if (actor.height <= 116) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 116) {
+					actor.height += jsEither([5, 5, 6, 6, 6]);
+				} else if (actor.height <= 124) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 124) {
+					actor.height += jsEither([7, 7, 8, 8, 8]);
+				} else if (actor.height <= 131) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 131) {
+					actor.height += jsEither([5, 5, 6, 6, 6]);
+				} else if (actor.height <= 137) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 137) {
+					actor.height += jsEither([4, 4, 5, 5, 5]);
+				} else if (actor.height <= 144) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 144) {
+					actor.height += jsEither([6, 6, 7, 7, 7]);
+				} else if (actor.height <= 156) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 156) {
+					actor.height += jsEither([5, 5, 6, 6, 6]);
+				} else if (actor.height <= 163) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 163) {
+					actor.height += jsEither([6, 6, 7, 7, 7]);
+				} else if (actor.height <= 168) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 168) {
+					actor.height += jsEither([5, 5, 6, 6, 6]);
+				} else if (actor.height <= 171) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 171) {
+					actor.height += jsEither([4, 4, 5, 5, 5]);
+				} else if (actor.height <= 173) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 0, 1, 1, 1]);
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 0, 1, 1, 1]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 0, 1, 1, 1]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 0, 1, 1, 1]);
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 91) {
+					actor.height += jsEither([9, 9, 9, 10, 10]);
+				} else if (actor.height <= 101) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 101) {
+					actor.height += jsEither([7, 7, 7, 8, 8]);
+				} else if (actor.height <= 109) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 109) {
+					actor.height += jsEither([7, 7, 7, 8, 8]);
+				} else if (actor.height <= 116) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 116) {
+					actor.height += jsEither([6, 6, 6, 7, 7]);
+				} else if (actor.height <= 124) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 124) {
+					actor.height += jsEither([8, 8, 8, 9, 9]);
+				} else if (actor.height <= 131) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 131) {
+					actor.height += jsEither([6, 6, 6, 7, 7]);
+				} else if (actor.height <= 137) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 137) {
+					actor.height += jsEither([5, 5, 5, 6, 6]);
+				} else if (actor.height <= 144) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 144) {
+					actor.height += jsEither([7, 7, 7, 8, 8]);
+				} else if (actor.height <= 156) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 156) {
+					actor.height += jsEither([6, 6, 6, 7, 7]);
+				} else if (actor.height <= 163) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 163) {
+					actor.height += jsEither([7, 7, 7, 8, 8]);
+				} else if (actor.height <= 168) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 168) {
+					actor.height += jsEither([6, 6, 6, 7, 7]);
+				} else if (actor.height <= 171) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 171) {
+					actor.height += jsEither([5, 5, 5, 6, 6]);
+				} else if (actor.height <= 173) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([1, 1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([1, 1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([1, 1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([1, 1, 1, 2, 2]);
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 91) {
+					actor.height += jsEither([8, 9, 9, 10, 10]);
+				} else if (actor.height <= 101) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 101) {
+					actor.height += jsEither([6, 7, 7, 8, 8]);
+				} else if (actor.height <= 109) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 109) {
+					actor.height += jsEither([6, 7, 7, 8, 8]);
+				} else if (actor.height <= 116) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 116) {
+					actor.height += jsEither([5, 6, 6, 7, 7]);
+				} else if (actor.height <= 124) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 124) {
+					actor.height += jsEither([7, 8, 8, 9, 9]);
+				} else if (actor.height <= 131) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 131) {
+					actor.height += jsEither([5, 6, 6, 7, 7]);
+				} else if (actor.height <= 137) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 137) {
+					actor.height += jsEither([4, 5, 5, 6, 6]);
+				} else if (actor.height <= 144) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 144) {
+					actor.height += jsEither([6, 7, 7, 8, 8]);
+				} else if (actor.height <= 156) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 156) {
+					actor.height += jsEither([5, 6, 6, 7, 7]);
+				} else if (actor.height <= 163) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 163) {
+					actor.height += jsEither([6, 7, 7, 8, 8]);
+				} else if (actor.height <= 168) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 168) {
+					actor.height += jsEither([5, 6, 6, 7, 7]);
+				} else if (actor.height <= 171) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 171) {
+					actor.height += jsEither([4, 5, 5, 6, 6]);
+				} else if (actor.height <= 173) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 1, 1, 2, 2]);
+				}
+			}
+		} else {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 91) {
+					actor.height += jsEither([8, 8, 9, 9, 9, 10]);
+				} else if (actor.height <= 101) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 101) {
+					actor.height += jsEither([6, 6, 7, 7, 8, 8]);
+				} else if (actor.height <= 109) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 109) {
+					actor.height += jsEither([6, 6, 7, 7, 7, 8]);
+				} else if (actor.height <= 116) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 116) {
+					actor.height += jsEither([5, 5, 6, 6, 6, 7]);
+				} else if (actor.height <= 124) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 124) {
+					actor.height += jsEither([7, 7, 8, 8, 8, 9]);
+				} else if (actor.height <= 131) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 131) {
+					actor.height += jsEither([5, 5, 6, 6, 6, 7]);
+				} else if (actor.height <= 137) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 137) {
+					actor.height += jsEither([4, 4, 5, 5, 5, 6]);
+				} else if (actor.height <= 144) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 144) {
+					actor.height += jsEither([6, 6, 7, 7, 7, 8]);
+				} else if (actor.height <= 156) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 156) {
+					actor.height += jsEither([5, 5, 6, 6, 6, 7]);
+				} else if (actor.height <= 163) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 163) {
+					actor.height += jsEither([6, 6, 7, 7, 7, 8]);
+				} else if (actor.height <= 168) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 168) {
+					actor.height += jsEither([5, 5, 6, 6, 6, 7]);
+				} else if (actor.height <= 171) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 171) {
+					actor.height += jsEither([4, 4, 5, 5, 5, 6]);
+				} else if (actor.height <= 173) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 0, 1, 1, 1, 2]);
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 0, 1, 1, 1, 2]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 0, 1, 1, 1, 2]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 174) {
+					actor.height += jsEither([0, 0, 1, 1, 1, 2]);
+				}
+			}
+		}
+		// experiment - Let's see if this keeps players on average above average height or if it makes them too tall in the long run.
+		if (tallerPC) {
+			actor.height += random(0, 3);
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseHeightXY(actor) {
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 93) {
+					actor.height += jsEither([9, 9, 10, 10]);
+				} else if (actor.height <= 103) {
+					actor.height += 6;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 103) {
+					actor.height += jsEither([7, 7, 8, 8]);
+				} else if (actor.height <= 110) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 110) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 117) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 117) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 124) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 124) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 131) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 131) {
+					actor.height += jsEither([5, 5, 6, 6]);
+				} else if (actor.height <= 137) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 137) {
+					actor.height += jsEither([4, 4, 5, 5]);
+				} else if (actor.height <= 144) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 144) {
+					actor.height += jsEither([5, 5, 6, 6]);
+				} else if (actor.height <= 150) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 150) {
+					actor.height += jsEither([5, 5, 6, 6]);
+				} else if (actor.height <= 156) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 156) {
+					actor.height += jsEither([5, 5, 6, 6]);
+				} else if (actor.height <= 162) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 162) {
+					actor.height += jsEither([7, 7, 8, 8]);
+				} else if (actor.height <= 170) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 170) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 177) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 177) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 184) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 184) {
+					actor.height += jsEither([2, 2, 3, 3]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 185) {
+					actor.height += jsEither([1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 186) {
+					actor.height += jsEither([0, 0, 1, 1]);
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 93) {
+					actor.height += jsEither([9, 9, 9, 10, 10]);
+				} else if (actor.height <= 103) {
+					actor.height += 6;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 103) {
+					actor.height += jsEither([7, 7, 8, 8, 8]);
+				} else if (actor.height <= 110) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 110) {
+					actor.height += jsEither([6, 6, 7, 7, 7]);
+				} else if (actor.height <= 117) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 117) {
+					actor.height += jsEither([6, 6, 7, 7, 7]);
+				} else if (actor.height <= 124) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 124) {
+					actor.height += jsEither([6, 6, 7, 7, 7]);
+				} else if (actor.height <= 131) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 131) {
+					actor.height += jsEither([5, 5, 6, 6, 6]);
+				} else if (actor.height <= 137) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 137) {
+					actor.height += jsEither([4, 4, 5, 5, 5]);
+				} else if (actor.height <= 144) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 144) {
+					actor.height += jsEither([5, 5, 6, 6, 6]);
+				} else if (actor.height <= 150) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 150) {
+					actor.height += jsEither([5, 5, 6, 6, 6]);
+				} else if (actor.height <= 156) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 156) {
+					actor.height += jsEither([5, 5, 6, 6, 6]);
+				} else if (actor.height <= 162) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 162) {
+					actor.height += jsEither([7, 7, 8, 8, 8]);
+				} else if (actor.height <= 170) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 170) {
+					actor.height += jsEither([6, 6, 7, 7, 7]);
+				} else if (actor.height <= 177) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 177) {
+					actor.height += jsEither([6, 6, 7, 7, 7]);
+				} else if (actor.height <= 184) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 184) {
+					actor.height += jsEither([2, 2, 3, 3, 3]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 185) {
+					actor.height += jsEither([1, 1, 2, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 186) {
+					actor.height += jsEither([0, 0, 1, 1, 1]);
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 93) {
+					actor.height += jsEither([10, 10, 11, 11]);
+				} else if (actor.height <= 103) {
+					actor.height += 6;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 103) {
+					actor.height += jsEither([8, 8, 9, 9]);
+				} else if (actor.height <= 110) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 110) {
+					actor.height += jsEither([7, 7, 8, 8]);
+				} else if (actor.height <= 117) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 117) {
+					actor.height += jsEither([7, 7, 8, 8]);
+				} else if (actor.height <= 124) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 124) {
+					actor.height += jsEither([7, 7, 8, 8]);
+				} else if (actor.height <= 131) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 131) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 137) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 137) {
+					actor.height += jsEither([5, 5, 6, 6]);
+				} else if (actor.height <= 144) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 144) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 150) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 150) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 156) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 156) {
+					actor.height += jsEither([6, 6, 7, 7]);
+				} else if (actor.height <= 162) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 162) {
+					actor.height += jsEither([8, 8, 9, 9]);
+				} else if (actor.height <= 170) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 170) {
+					actor.height += jsEither([7, 7, 8, 8]);
+				} else if (actor.height <= 177) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 177) {
+					actor.height += jsEither([7, 7, 8, 8]);
+				} else if (actor.height <= 184) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 184) {
+					actor.height += jsEither([3, 3, 4, 4]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 185) {
+					actor.height += jsEither([2, 2, 3, 3]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 186) {
+					actor.height += jsEither([1, 1, 2, 2]);
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 93) {
+					actor.height += jsEither([10, 10, 10, 11, 11]);
+				} else if (actor.height <= 103) {
+					actor.height += 6;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 103) {
+					actor.height += jsEither([8, 8, 8, 9, 9]);
+				} else if (actor.height <= 110) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 110) {
+					actor.height += jsEither([7, 7, 7, 8, 8]);
+				} else if (actor.height <= 117) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 117) {
+					actor.height += jsEither([7, 7, 7, 8, 8]);
+				} else if (actor.height <= 124) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 124) {
+					actor.height += jsEither([7, 7, 7, 8, 8]);
+				} else if (actor.height <= 131) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 131) {
+					actor.height += jsEither([6, 6, 6, 7, 7]);
+				} else if (actor.height <= 137) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 137) {
+					actor.height += jsEither([5, 5, 5, 6, 6]);
+				} else if (actor.height <= 144) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 144) {
+					actor.height += jsEither([6, 6, 6, 7, 7]);
+				} else if (actor.height <= 150) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 150) {
+					actor.height += jsEither([6, 6, 6, 7, 7]);
+				} else if (actor.height <= 156) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 156) {
+					actor.height += jsEither([6, 6, 6, 7, 7]);
+				} else if (actor.height <= 162) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 162) {
+					actor.height += jsEither([8, 8, 8, 9, 9]);
+				} else if (actor.height <= 170) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 170) {
+					actor.height += jsEither([7, 7, 7, 8, 8]);
+				} else if (actor.height <= 177) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 177) {
+					actor.height += jsEither([7, 7, 7, 8, 8]);
+				} else if (actor.height <= 184) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 184) {
+					actor.height += jsEither([3, 3, 3, 4, 4]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 185) {
+					actor.height += jsEither([2, 2, 2, 3, 3]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 186) {
+					actor.height += jsEither([1, 1, 1, 2, 2]);
+				}
+			}
+		} else {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 93) {
+					actor.height += jsEither([9, 9, 10, 10, 10, 11]);
+				} else if (actor.height <= 103) {
+					actor.height += 6;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 103) {
+					actor.height += jsEither([7, 7, 8, 8, 9, 9]);
+				} else if (actor.height <= 110) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 110) {
+					actor.height += jsEither([6, 6, 7, 7, 8, 8]);
+				} else if (actor.height <= 117) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 117) {
+					actor.height += jsEither([6, 6, 7, 7, 8, 8]);
+				} else if (actor.height <= 124) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 124) {
+					actor.height += jsEither([6, 6, 7, 7, 8, 8]);
+				} else if (actor.height <= 131) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 131) {
+					actor.height += jsEither([5, 5, 6, 6, 7, 7]);
+				} else if (actor.height <= 137) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 137) {
+					actor.height += jsEither([4, 4, 5, 5, 5, 6]);
+				} else if (actor.height <= 144) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 144) {
+					actor.height += jsEither([5, 5, 6, 6, 7, 7]);
+				} else if (actor.height <= 150) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 150) {
+					actor.height += jsEither([5, 5, 6, 6, 6, 7]);
+				} else if (actor.height <= 156) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 156) {
+					actor.height += jsEither([5, 5, 6, 6, 7, 7]);
+				} else if (actor.height <= 162) {
+					actor.height += 3;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 162) {
+					actor.height += jsEither([7, 7, 8, 8, 9, 9]);
+				} else if (actor.height <= 170) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 170) {
+					actor.height += jsEither([6, 6, 7, 7, 8, 8]);
+				} else if (actor.height <= 177) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 177) {
+					actor.height += jsEither([6, 6, 7, 7, 8, 8]);
+				} else if (actor.height <= 184) {
+					actor.height += 4;
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 184) {
+					actor.height += jsEither([2, 2, 3, 3, 4, 4]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 185) {
+					actor.height += jsEither([1, 1, 2, 2, 3, 3]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 186) {
+					actor.height += jsEither([0, 0, 1, 1, 2, 2]);
+				}
+			}
+		}
+		// experiment - Let's see if this keeps players on average above average height or if it makes them too tall in the long run.
+		if (tallerPC) {
+			actor.height += random(0, 3);
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseHeightDwarf(actor) {
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 80) {
+					actor.height += jsEither([1, 1, 2, 2]);
+				} else if (actor.height <= 84) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 84) {
+					actor.height += jsEither([4, 4, 5, 5]);
+				} else if (actor.height <= 90) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 90) {
+					actor.height += jsEither([8, 8, 9, 9]);
+				} else if (actor.height <= 100) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 100) {
+					actor.height += jsEither([3, 3, 4, 4]);
+				} else if (actor.height <= 105) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 105) {
+					actor.height += jsEither([2, 2, 3, 3]);
+				} else if (actor.height <= 109) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 109) {
+					actor.height += jsEither([3, 3, 4, 4]);
+				} else if (actor.height <= 114) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 114) {
+					actor.height += jsEither([2, 2, 3, 3]);
+				} else if (actor.height <= 118) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 118) {
+					actor.height += jsEither([2, 2, 3, 3]);
+				} else if (actor.height <= 122) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 122) {
+					actor.height += jsEither([3, 3, 4, 4]);
+				} else if (actor.height <= 127) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 127) {
+					actor.height += jsEither([3, 3, 4, 4]);
+				} else if (actor.height <= 132) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 132) {
+					actor.height += jsEither([1, 1, 2, 2]);
+				} else if (actor.height <= 135) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 135) {
+					actor.height += jsEither([1, 1, 2, 2]);
+				} else if (actor.height <= 138) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 138) {
+					actor.height += jsEither([1, 1, 2, 2]);
+				} else if (actor.height <= 141) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([0, 0, 1, 1]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([0, 0, 1, 1]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([0, 0, 1, 1]);
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 80) {
+					actor.height += jsEither([1, 1, 2, 2, 2]);
+				} else if (actor.height <= 84) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 84) {
+					actor.height += jsEither([4, 4, 5, 5, 5]);
+				} else if (actor.height <= 90) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 90) {
+					actor.height += jsEither([8, 8, 9, 9, 9]);
+				} else if (actor.height <= 100) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 100) {
+					actor.height += jsEither([3, 3, 4, 4, 4]);
+				} else if (actor.height <= 105) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 105) {
+					actor.height += jsEither([2, 2, 3, 3, 3]);
+				} else if (actor.height <= 109) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 109) {
+					actor.height += jsEither([3, 3, 4, 4, 4]);
+				} else if (actor.height <= 114) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 114) {
+					actor.height += jsEither([2, 2, 3, 3, 3]);
+				} else if (actor.height <= 118) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 118) {
+					actor.height += jsEither([2, 2, 3, 3, 3]);
+				} else if (actor.height <= 122) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 122) {
+					actor.height += jsEither([3, 3, 4, 4, 4]);
+				} else if (actor.height <= 127) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 127) {
+					actor.height += jsEither([3, 3, 4, 4, 4]);
+				} else if (actor.height <= 132) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 132) {
+					actor.height += jsEither([1, 1, 2, 2, 2]);
+				} else if (actor.height <= 135) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 135) {
+					actor.height += jsEither([1, 1, 2, 2, 2]);
+				} else if (actor.height <= 138) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 138) {
+					actor.height += jsEither([1, 1, 2, 2, 2]);
+				} else if (actor.height <= 141) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([0, 0, 1, 1, 1]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([0, 0, 1, 1, 1]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([0, 0, 1, 1, 1]);
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 80) {
+					actor.height += jsEither([2, 2, 3, 3]);
+				} else if (actor.height <= 84) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 84) {
+					actor.height += jsEither([5, 5, 6, 6]);
+				} else if (actor.height <= 90) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 90) {
+					actor.height += jsEither([9, 9, 10, 10]);
+				} else if (actor.height <= 100) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 100) {
+					actor.height += jsEither([4, 4, 5, 5]);
+				} else if (actor.height <= 105) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 105) {
+					actor.height += jsEither([3, 3, 4, 4]);
+				} else if (actor.height <= 109) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 109) {
+					actor.height += jsEither([4, 4, 5, 5]);
+				} else if (actor.height <= 114) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 114) {
+					actor.height += jsEither([3, 3, 4, 4]);
+				} else if (actor.height <= 118) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 118) {
+					actor.height += jsEither([3, 3, 4, 4]);
+				} else if (actor.height <= 122) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 122) {
+					actor.height += jsEither([4, 4, 5, 5]);
+				} else if (actor.height <= 127) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 127) {
+					actor.height += jsEither([4, 4, 5, 5]);
+				} else if (actor.height <= 132) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 132) {
+					actor.height += jsEither([2, 2, 3, 3]);
+				} else if (actor.height <= 135) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 135) {
+					actor.height += jsEither([2, 2, 3, 3]);
+				} else if (actor.height <= 138) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 138) {
+					actor.height += jsEither([2, 2, 3, 3]);
+				} else if (actor.height <= 141) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([1, 1, 2, 2]);
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 80) {
+					actor.height += jsEither([2, 2, 2, 3, 3]);
+				} else if (actor.height <= 84) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 84) {
+					actor.height += jsEither([5, 5, 5, 6, 6]);
+				} else if (actor.height <= 90) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 90) {
+					actor.height += jsEither([9, 9, 9, 10, 10]);
+				} else if (actor.height <= 100) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 100) {
+					actor.height += jsEither([4, 4, 4, 5, 5]);
+				} else if (actor.height <= 105) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 105) {
+					actor.height += jsEither([3, 3, 3, 4, 4]);
+				} else if (actor.height <= 109) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 109) {
+					actor.height += jsEither([4, 4, 4, 5, 5]);
+				} else if (actor.height <= 114) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 114) {
+					actor.height += jsEither([3, 3, 3, 4, 4]);
+				} else if (actor.height <= 118) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 118) {
+					actor.height += jsEither([3, 3, 3, 4, 4]);
+				} else if (actor.height <= 122) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 122) {
+					actor.height += jsEither([4, 4, 4, 5, 5]);
+				} else if (actor.height <= 127) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 127) {
+					actor.height += jsEither([4, 4, 4, 5, 5]);
+				} else if (actor.height <= 132) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 132) {
+					actor.height += jsEither([2, 2, 2, 3, 3]);
+				} else if (actor.height <= 135) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 135) {
+					actor.height += jsEither([2, 2, 2, 3, 3]);
+				} else if (actor.height <= 138) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 138) {
+					actor.height += jsEither([2, 2, 2, 3, 3]);
+				} else if (actor.height <= 141) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([1, 1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([1, 1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([1, 1, 1, 2, 2]);
+				}
+			}
+		} else {
+			if (physicalAgeSwap === 3) {
+				if (actor.height <= 80) {
+					actor.height += jsEither([1, 1, 2, 2, 3, 3]);
+				} else if (actor.height <= 84) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 4) {
+				if (actor.height <= 84) {
+					actor.height += jsEither([4, 4, 5, 5, 6, 6]);
+				} else if (actor.height <= 90) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 5) {
+				if (actor.height <= 90) {
+					actor.height += jsEither([8, 8, 9, 9, 10, 10]);
+				} else if (actor.height <= 100) {
+					actor.height += 5;
+				}
+			} else if (physicalAgeSwap === 6) {
+				if (actor.height <= 100) {
+					actor.height += jsEither([3, 3, 4, 4, 5, 5]);
+				} else if (actor.height <= 105) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 7) {
+				if (actor.height <= 105) {
+					actor.height += jsEither([2, 2, 3, 3, 4, 4]);
+				} else if (actor.height <= 109) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 8) {
+				if (actor.height <= 109) {
+					actor.height += jsEither([3, 3, 4, 4, 5, 5]);
+				} else if (actor.height <= 114) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.height <= 114) {
+					actor.height += jsEither([2, 2, 3, 3, 4, 4]);
+				} else if (actor.height <= 118) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.height <= 118) {
+					actor.height += jsEither([2, 2, 3, 3, 4, 4]);
+				} else if (actor.height <= 122) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.height <= 122) {
+					actor.height += jsEither([3, 3, 4, 4, 5, 5]);
+				} else if (actor.height <= 127) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.height <= 127) {
+					actor.height += jsEither([3, 3, 4, 4, 5, 5]);
+				} else if (actor.height <= 132) {
+					actor.height += 2;
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.height <= 132) {
+					actor.height += jsEither([1, 1, 2, 2, 3, 3]);
+				} else if (actor.height <= 135) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.height <= 135) {
+					actor.height += jsEither([1, 1, 2, 2, 3, 3]);
+				} else if (actor.height <= 138) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.height <= 138) {
+					actor.height += jsEither([1, 1, 2, 2, 3, 3]);
+				} else if (actor.height <= 141) {
+					actor.height += 1;
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([0, 0, 1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([0, 0, 1, 1, 2, 2]);
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.height <= 143) {
+					actor.height += jsEither([0, 0, 1, 1, 2, 2]);
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseHeightGiant(actor) {
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap < 16) {
+				if (actor.height <= 270) {
+					actor.height += random(5, 12);
+				}
+			} else {
+				if (actor.height <= 270) {
+					actor.height += random(3, 7);
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap < 16) {
+				if (actor.height <= 270) {
+					actor.height += random(7, 15);
+				}
+			} else {
+				if (actor.height <= 270) {
+					actor.height += random(5, 7);
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap < 16) {
+				if (actor.height <= 270) {
+					actor.height += random(10, 25);
+				}
+			} else {
+				if (actor.height <= 270) {
+					actor.height += random(7, 13);
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap < 16) {
+				if (actor.height <= 270) {
+					actor.height += random(7, 22);
+				}
+			} else {
+				if (actor.height <= 270) {
+					actor.height += random(7, 12);
+				}
+			}
+		} else {
+			if (physicalAgeSwap < 16) {
+				if (actor.height <= 270) {
+					actor.height += random(7, 20);
+				}
+			} else {
+				if (actor.height <= 270) {
+					actor.height += random(5, 10);
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseHeightNeoteny(actor) {
+		if (physicalAgeSwap <= 12) {
+			if (actor.height <= 120) {
+				actor.height += jsEither([0, 0, 1, 1, 2, 2]);
+			}
+		} else if (physicalAgeSwap === 13) {
+			if (actor.height <= 120) {
+				actor.height += jsEither([0, 0, 1, 1, 2, 2]);
+			}
+		} else if (physicalAgeSwap === 14) {
+			if (actor.height <= 120) {
+				actor.height += jsEither([0, 0, 1, 1, 2, 2]);
+			}
+		} else if (physicalAgeSwap === 15) {
+			if (actor.height <= 120) {
+				actor.height += jsEither([0, 0, 1, 1, 2, 2]);
+			}
+		} else if (physicalAgeSwap === 16) {
+			if (actor.height <= 130) {
+				actor.height += jsEither([0, 0, 1, 1, 2, 2]);
+			}
+		} else if (physicalAgeSwap === 17) {
+			if (actor.height <= 130) {
+				actor.height += jsEither([0, 0, 1, 1, 2, 2]);
+			}
+		} else if (physicalAgeSwap === 18) {
+			if (actor.height <= 130) {
+				actor.height += jsEither([0, 0, 1, 1, 2, 2]);
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseBoobsXX(actor) {
+		if (actor.geneticQuirks.gigantomastia === 2 && actor.geneticQuirks.macromastia === 2) {
+			gigantomastiaMod = 3;
+		} else if (actor.geneticQuirks.gigantomastia === 2) {
+			gigantomastiaMod = 2;
+		} else if (actor.geneticQuirks.macromastia === 2) {
+			gigantomastiaMod = 1.5;
+		} else if (actor.geneticQuirks.gigantomastia === 3) {
+			gigantomastiaMod = 1.2;
+		} else if (actor.geneticQuirks.macromastia === 3) {
+			gigantomastiaMod = 1.1;
+		} else {
+			gigantomastiaMod = 1;
+		}
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap === 8) {
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 9) {
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 10) {
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 11) {
+				if (actor.boobs < (600 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			} else if (physicalAgeSwap === 12) {
+				if (actor.boobs < (700 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			} else if (physicalAgeSwap === 13) {
+				if (actor.boobs < (1000 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			} else if (physicalAgeSwap === 14) {
+				if (actor.boobs < (800 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			} else if (physicalAgeSwap === 15) {
+				if (actor.boobs < (900 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			} else if (physicalAgeSwap === 16) {
+				if (actor.boobs < (1200 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			} else if (physicalAgeSwap === 17) {
+				if (actor.boobs < (1600 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			} else if (physicalAgeSwap === 18) {
+				if (actor.boobs < (2000 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap === 8) {
+				actor.boobs += 25;
+			} else if (physicalAgeSwap === 9) {
+				actor.boobs += 25;
+			} else if (physicalAgeSwap === 10) {
+				actor.boobs += 25;
+			} else if (physicalAgeSwap === 11) {
+				if (actor.boobs < (500 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 12) {
+				if (actor.boobs < (600 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 13) {
+				if (actor.boobs < (900 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 14) {
+				if (actor.boobs < (700 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 15) {
+				if (actor.boobs < (800 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 16) {
+				if (actor.boobs < (1000 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 17) {
+				if (actor.boobs < (1200 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 18) {
+				if (actor.boobs < (1600 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap >= 11) {
+				if (actor.boobs > 200 && gigantomastiaMod !== 3) {
+					actor.boobs -= 100;
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap >= 11) {
+				if (actor.boobs > 200 && gigantomastiaMod !== 3) {
+					actor.boobs -= 50;
+				}
+			}
+		} else {
+			if (physicalAgeSwap === 11) {
+				if (actor.boobs < (300 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.boobs < (300 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.boobs < (400 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.boobs < (500 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.boobs < (500 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.boobs < (800 * gigantomastiaMod)) {
+					if (random(1, 100) > (50 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.boobs < (800 * gigantomastiaMod)) {
+					if (random(1, 100) > (60 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.boobs < (800 * gigantomastiaMod)) {
+					if (random(1, 100) > (70 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseBoobsXY(actor) {
+		if (actor.geneticQuirks.gigantomastia === 2 && actor.geneticQuirks.macromastia === 2) {
+			gigantomastiaMod = 3;
+		} else if (actor.geneticQuirks.gigantomastia === 2) {
+			gigantomastiaMod = 2;
+		} else if (actor.geneticQuirks.macromastia === 2) {
+			gigantomastiaMod = 1.5;
+		} else if (actor.geneticQuirks.gigantomastia === 3) {
+			gigantomastiaMod = 1.2;
+		} else if (actor.geneticQuirks.macromastia === 3) {
+			gigantomastiaMod = 1.1;
+		} else {
+			gigantomastiaMod = 1;
+		}
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap === 8) {
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 9) {
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 10) {
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 11) {
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 12) {
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 13) {
+				if (actor.boobs < (1000 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 14) {
+				if (actor.boobs < (800 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			} else if (physicalAgeSwap === 15) {
+				if (actor.boobs < (900 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			} else if (physicalAgeSwap === 16) {
+				if (actor.boobs < (1200 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			} else if (physicalAgeSwap === 17) {
+				if (actor.boobs < (1600 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			} else if (physicalAgeSwap === 18) {
+				if (actor.boobs < (2000 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 100;
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap === 8) {
+				actor.boobs += 25;
+			} else if (physicalAgeSwap === 9) {
+				actor.boobs += 25;
+			} else if (physicalAgeSwap === 10) {
+				actor.boobs += 25;
+			} else if (physicalAgeSwap === 11) {
+				actor.boobs += 25;
+			} else if (physicalAgeSwap === 12) {
+				actor.boobs += 25;
+			} else if (physicalAgeSwap === 13) {
+				if (actor.boobs < (900 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 25;
+			} else if (physicalAgeSwap === 14) {
+				if (actor.boobs < (700 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 15) {
+				if (actor.boobs < (800 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 16) {
+				if (actor.boobs < (1000 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 17) {
+				if (actor.boobs < (1200 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			} else if (physicalAgeSwap === 18) {
+				if (actor.boobs < (1600 * gigantomastiaMod)) {
+					if (random(1, 100) > (40 / gigantomastiaMod)) {
+						actor.boobs += 100;
+					}
+				}
+				actor.boobs += 50;
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap >= 11) {
+				if (actor.boobs > 200 && gigantomastiaMod !== 3) {
+					actor.boobs -= 100;
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap >= 11) {
+				if (actor.boobs > 200 && gigantomastiaMod !== 3) {
+					actor.boobs -= 50;
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseHipsXX(actor) {
+		if (actor.geneticQuirks.uterineHypersensitivity === 2) {
+			uterineHypersensitivityMod = 1.5;
+		} else if (actor.geneticQuirks.uterineHypersensitivity === 1) {
+			uterineHypersensitivityMod = 1.2;
+		} else {
+			uterineHypersensitivityMod = 1;
+		}
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap === 8) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 90 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 90 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 90 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap === 8) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 95 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 95 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 95 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap === 8) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 99 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 95 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 95 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 95 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap === 8) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 95 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 90 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 90 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 90 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			}
+		} else {
+			if (physicalAgeSwap === 8) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 90 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 60 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 60 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 60 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 60 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseHipsXY(actor) {
+		if (actor.geneticQuirks.uterineHypersensitivity === 2) {
+			uterineHypersensitivityMod = 1.3;
+		} else if (actor.geneticQuirks.uterineHypersensitivity === 1) {
+			uterineHypersensitivityMod = 1.15;
+		} else {
+			uterineHypersensitivityMod = 1;
+		}
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap === 8) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 90 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 90 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 90 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap === 8) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 95 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 95 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 95 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap === 14) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 99 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap === 14) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 95 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			}
+		} else {
+			if (physicalAgeSwap === 14) {
+				if (actor.hips < 2) {
+					if (random(1, 100) > 60 / uterineHypersensitivityMod) {
+						actor.hips++;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseButtXX(actor) {
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap === 8) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (80 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (80 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (80 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (20 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.butt < (4 + rearQuirk)) {
+					if (random(1, 100) > (20 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.butt < (4 + rearQuirk)) {
+					if (random(1, 100) > (20 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap === 8) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (90 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (90 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (90 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (40 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.butt < (4 + rearQuirk)) {
+					if (random(1, 100) > (40 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.butt < (4 + rearQuirk)) {
+					if (random(1, 100) > (40 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap === 8) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (90 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (95 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (95 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (95 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap === 8) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (80 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (90 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (90 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (90 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			}
+		} else {
+			if (physicalAgeSwap === 8) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (60 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (60 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (60 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (60 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseButtXY(actor) {
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap === 8) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (80 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (80 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (80 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (20 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.butt < (4 + rearQuirk)) {
+					if (random(1, 100) > (20 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.butt < (4 + rearQuirk)) {
+					if (random(1, 100) > (20 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap === 8) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (90 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (90 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (90 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (40 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.butt < (4 + rearQuirk)) {
+					if (random(1, 100) > (40 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap === 8) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (90 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap === 8) {
+				if (actor.butt < (3 + rearQuirk)) {
+					if (random(1, 100) > (80 / rearQuirkDivider)) {
+						actor.butt++;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseDick(actor) {
+		if (actor.hormoneBalance >= 200) {
+			//
+		} else if (actor.hormoneBalance >= 100) {
+			//
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap === 8) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (70 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.dick < 6 && dickMod === 2) {
+					if (random(1, 100) > 70) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (70 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (70 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (70 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (50 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (20 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (20 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (70 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (70 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (70 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap === 8) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (90 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.dick < 6 && dickMod === 2) {
+					if (random(1, 100) > 70) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (90 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (90 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (90 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (70 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (40 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (40 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (90 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (90 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (90 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			}
+		} else {
+			if (physicalAgeSwap === 9) {
+				if (actor.dick < 6 && dickMod === 2) {
+					if (random(1, 100) > 70) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.dick < 6 && dickMod === 2) {
+					if (random(1, 100) > 70) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.dick < 6 && dickMod === 2) {
+					if (random(1, 100) > 70) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.dick < 6 && dickMod === 2) {
+					if (random(1, 100) > 70) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (50 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (50 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.dick < 6) {
+					if (random(1, 100) > (50 / dickMod)) {
+						actor.dick++;
+						if (actor.foreskin > 0) {
+							actor.foreskin++;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseBalls(actor) {
+		if (actor.hormoneBalance >= 200) {
+			//
+		} else if (actor.hormoneBalance >= 100) {
+			//
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap === 8) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 10) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 70) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 70) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 70) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 50) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 20) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 20) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 70) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 70) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 70) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap === 8) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 30) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 90) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 90) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 90) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 70) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 40) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 40) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 90) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 90) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 90) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			}
+		} else {
+			if (physicalAgeSwap === 8) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 50) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 50) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 50) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.balls < 6) {
+					if (random(1, 100) > 50) {
+						actor.balls++;
+						if (actor.scrotum > 0) {
+							actor.scrotum++;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseClit(actor) {
+		if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap === 8) {
+				if (actor.clit < 4) {
+					if (random(1, 100) > 70) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.clit < 4) {
+					if (random(1, 100) > 70) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.clit < 4) {
+					if (random(1, 100) > 70) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.clit < 4) {
+					if (random(1, 100) > 50) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.clit < 4) {
+					if (random(1, 100) > 50) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.clit < 4) {
+					if (random(1, 100) > 50) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.clit < 4) {
+					if (random(1, 100) > 50) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.clit < 4) {
+					if (random(1, 100) > 50) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.clit < 4) {
+					if (random(1, 100) > 50) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.clit < 4) {
+					if (random(1, 100) > 50) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.clit < 4) {
+					if (random(1, 100) > 50) {
+						actor.clit++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap === 8) {
+				if (actor.clit.isBetween(0, 4)) {
+					if (random(1, 100) > 90) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 9) {
+				if (actor.clit.isBetween(0, 4)) {
+					if (random(1, 100) > 90) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 10) {
+				if (actor.clit.isBetween(0, 4)) {
+					if (random(1, 100) > 90) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 11) {
+				if (actor.clit.isBetween(0, 4)) {
+					if (random(1, 100) > 70) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 12) {
+				if (actor.clit.isBetween(0, 4)) {
+					if (random(1, 100) > 70) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 13) {
+				if (actor.clit.isBetween(0, 4)) {
+					if (random(1, 100) > 70) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 14) {
+				if (actor.clit.isBetween(0, 4)) {
+					if (random(1, 100) > 70) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 15) {
+				if (actor.clit.isBetween(0, 4)) {
+					if (random(1, 100) > 70) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 16) {
+				if (actor.clit.isBetween(0, 4)) {
+					if (random(1, 100) > 70) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 17) {
+				if (actor.clit.isBetween(0, 4)) {
+					if (random(1, 100) > 70) {
+						actor.clit++;
+					}
+				}
+			} else if (physicalAgeSwap === 18) {
+				if (actor.clit.isBetween(0, 4)) {
+					if (random(1, 100) > 70) {
+						actor.clit++;
+					}
+				}
+			}
+		}
+		if (physicalAgeSwap >= 11 && actor.geneticQuirks.wellHung === 2 && actor.clit < 5 && random(1, 100) > 60) {
+			actor.clit++;
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseWetness(actor) {
+		if (actor.geneticQuirks.uterineHypersensitivity === 2) {
+			uterineHypersensitivityMod = 1.5;
+		} else if (actor.geneticQuirks.uterineHypersensitivity === 1) {
+			uterineHypersensitivityMod = 1.2;
+		} else {
+			uterineHypersensitivityMod = 1;
+		}
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap === 8 || physicalAgeSwap === 9) {
+				if (actor.vaginaLube < 1) {
+					if (random(1, 100) > 90 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				}
+			} else if (physicalAgeSwap <= 12) {
+				if (actor.vaginaLube < 1) {
+					if (random(1, 100) > 60 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				} else if (actor.vaginaLube < 2) {
+					if (random(1, 100) > 80 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				}
+			} else if (physicalAgeSwap <= 15) {
+				if (actor.vaginaLube < 1) {
+					if (random(1, 100) > 30 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				} else if (actor.vaginaLube < 2) {
+					if (random(1, 100) > 50 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				}
+			} else if (physicalAgeSwap <= 18) {
+				if (actor.vaginaLube < 1) {
+					if (random(1, 100) > 10 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				} else if (actor.vaginaLube < 2) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap > 9 && physicalAgeSwap <= 12) {
+				if (actor.vaginaLube < 1) {
+					if (random(1, 100) > 70 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				}
+			} else if (physicalAgeSwap <= 15) {
+				if (actor.vaginaLube < 1) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				} else if (actor.vaginaLube < 2) {
+					if (random(1, 100) > 70 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				}
+			} else if (physicalAgeSwap <= 18) {
+				if (actor.vaginaLube < 1) {
+					if (random(1, 100) > 20 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				} else if (actor.vaginaLube < 2) {
+					if (random(1, 100) > 40 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance >= -20) {
+			if (physicalAgeSwap > 15 && physicalAgeSwap <= 18) {
+				if (actor.vaginaLube < 1) {
+					if (random(1, 100) > 50 / uterineHypersensitivityMod) {
+						actor.vaginaLube++;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseWaistXX(actor) {
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap >= 12) {
+				if (actor.waist > -60) {
+					if (random(1, 100) > 20) {
+						actor.waist -= 5;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap >= 12) {
+				if (actor.waist > -30) {
+					if (random(1, 100) > 20) {
+						actor.waist -= 5;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap >= 12) {
+				if (actor.waist < 60) {
+					if (random(1, 100) > 20) {
+						actor.waist += 5;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap >= 12) {
+				if (actor.waist < 30) {
+					if (random(1, 100) > 20) {
+						actor.waist += 5;
+					}
+				}
+			}
+		} else {
+			if (physicalAgeSwap >= 12) {
+				if (actor.waist > -20) {
+					if (random(1, 100) > 60) {
+						actor.waist -= 5;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseWaistXY(actor) {
+		if (actor.hormoneBalance >= 200) {
+			if (physicalAgeSwap >= 12) {
+				if (actor.waist > -30) {
+					if (random(1, 100) > 20) {
+						actor.waist -= 5;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (physicalAgeSwap >= 12) {
+				if (actor.waist > -15) {
+					if (random(1, 100) > 20) {
+						actor.waist -= 5;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (physicalAgeSwap >= 12) {
+				if (actor.waist < 90) {
+					if (random(1, 100) > 20) {
+						actor.waist += 5;
+					}
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (physicalAgeSwap >= 12) {
+				if (actor.waist < 60) {
+					if (random(1, 100) > 20) {
+						actor.waist += 5;
+					}
+				}
+			}
+		} else {
+			if (physicalAgeSwap >= 12) {
+				if (actor.waist < 20) {
+					if (random(1, 100) > 60) {
+						actor.waist += 5;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseFaceXX(actor) {
+		if (actor.hormoneBalance >= 200) {
+			if (actor.face > 60) {
+				if (random(1, 100) > 80) {
+					actor.face += 5;
+				}
+			} else if (actor.face <= 60) {
+				if (random(1, 100) > 30) {
+					actor.face += 10;
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (actor.face > 60) {
+				if (random(1, 100) > 80) {
+					actor.face += 5;
+				}
+			} else if (actor.face <= 60) {
+				if (random(1, 100) > 30) {
+					actor.face += 10;
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (actor.face < 100) {
+				if (random(1, 100) > 50) {
+					actor.face -= 20;
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (actor.face < 100) {
+				if (random(1, 100) > 70) {
+					actor.face -= 20;
+				}
+			}
+		} else {
+			if (actor.face > 60) {
+				if (random(1, 100) > 90) {
+					actor.face += 5;
+				}
+			} else if (actor.face <= 60) {
+				if (random(1, 100) > 40) {
+					actor.face += 10;
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseFaceXY(actor) {
+		if (actor.hormoneBalance >= 200) {
+			if (actor.face > 60) {
+				if (random(1, 100) > 80) {
+					actor.face += 5;
+				}
+			} else if (actor.face <= 60) {
+				if (random(1, 100) > 50) {
+					actor.face += 10;
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (actor.face > 60) {
+				if (random(1, 100) > 80) {
+					actor.face += 10;
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseVoiceXX(actor) {
+		if (actor.hormoneBalance >= 200) {
+			if (actor.voice === 3) {
+				if (random(1, 100) > 90) {
+					actor.voice--;
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (actor.voice === 3) {
+				if (random(1, 100) > 80) {
+					actor.voice--;
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (actor.voice <= 3) {
+				if (random(1, 100) > 30) {
+					actor.voice--;
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (actor.voice <= 3) {
+				if (random(1, 100) > 60) {
+					actor.voice--;
+				}
+			}
+		} else {
+			if (actor.voice === 3) {
+				if (random(1, 100) > 60) {
+					actor.voice--;
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increaseVoiceXY(actor) {
+		if (actor.hormoneBalance >= 200) {
+			if (actor.voice < 2) {
+				if (random(1, 100) > 50) {
+					actor.voice--;
+				}
+			}
+		} else if (actor.hormoneBalance >= 100) {
+			if (actor.voice < 3) {
+				if (random(1, 100) > 50) {
+					actor.voice--;
+				}
+			}
+		} else if (actor.hormoneBalance <= -200) {
+			if (actor.voice > 1) {
+				if (random(1, 100) > 10) {
+					actor.voice--;
+				}
+			}
+		} else if (actor.hormoneBalance <= -100) {
+			if (actor.voice > 1) {
+				if (random(1, 100) > 30) {
+					actor.voice--;
+				}
+			}
+		} else {
+			if (actor.voice > 1) {
+				if (random(1, 100) > 60) {
+					actor.voice--;
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increasePregAdaptationXX(actor) {
+		if (physicalAgeSwap === 3) {
+			if (actor.pregAdaptation < 5) {
+				actor.pregAdaptation = 5;
+			}
+		} else if (physicalAgeSwap === 4) {
+			if (actor.pregAdaptation < 5) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 5) {
+			if (actor.pregAdaptation < 5) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 6) {
+			if (actor.pregAdaptation < 5) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 7) {
+			if (actor.pregAdaptation < 6) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 8) {
+			if (actor.pregAdaptation < 7) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 9) {
+			if (actor.pregAdaptation < 8) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 10) {
+			if (actor.pregAdaptation < 9) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 11) {
+			if (actor.pregAdaptation < 10) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 12) {
+			if (actor.pregAdaptation < 14) {
+				actor.pregAdaptation += 4;
+			}
+		} else if (physicalAgeSwap === 13) {
+			if (actor.pregAdaptation < 18) {
+				actor.pregAdaptation += 4;
+			}
+		} else if (physicalAgeSwap === 14) {
+			if (actor.pregAdaptation < 22) {
+				actor.pregAdaptation += 4;
+			}
+		} else if (physicalAgeSwap === 15) {
+			if (actor.pregAdaptation < 28) {
+				actor.pregAdaptation += 6;
+			}
+		} else if (physicalAgeSwap === 16) {
+			if (actor.pregAdaptation < 34) {
+				actor.pregAdaptation += 6;
+			}
+		} else if (physicalAgeSwap === 17) {
+			if (actor.pregAdaptation < 42) {
+				actor.pregAdaptation += 8;
+			}
+		} else if (physicalAgeSwap === 18) {
+			if (actor.pregAdaptation < 50) {
+				actor.pregAdaptation += 8;
+			}
+		}
+	}
+
+	/**
+	 * @param {FC.HumanState} actor
+	 */
+	function increasePregAdaptationXY(actor) {
+		if (physicalAgeSwap === 3) {
+			if (actor.pregAdaptation < 5) {
+				actor.pregAdaptation = 5;
+			}
+		} else if (physicalAgeSwap === 4) {
+			if (actor.pregAdaptation < 5) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 5) {
+			if (actor.pregAdaptation < 5) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 6) {
+			if (actor.pregAdaptation < 5) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 7) {
+			if (actor.pregAdaptation < 6) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 8) {
+			if (actor.pregAdaptation < 7) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 9) {
+			if (actor.pregAdaptation < 8) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 10) {
+			if (actor.pregAdaptation < 9) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 11) {
+			if (actor.pregAdaptation < 10) {
+				actor.pregAdaptation++;
+			}
+		} else if (physicalAgeSwap === 12) {
+			if (actor.pregAdaptation < 12) {
+				actor.pregAdaptation += 2;
+			}
+		} else if (physicalAgeSwap === 13) {
+			if (actor.pregAdaptation < 14) {
+				actor.pregAdaptation += 2;
+			}
+		} else if (physicalAgeSwap === 14) {
+			if (actor.pregAdaptation < 16) {
+				actor.pregAdaptation += 2;
+			}
+		} else if (physicalAgeSwap === 15) {
+			if (actor.pregAdaptation < 18) {
+				actor.pregAdaptation += 2;
+			}
+		} else if (physicalAgeSwap === 16) {
+			if (actor.pregAdaptation < 20) {
+				actor.pregAdaptation += 2;
+			}
+		} else if (physicalAgeSwap === 17) {
+			if (actor.pregAdaptation < 20) {
+				actor.pregAdaptation += 2;
+			}
+		} else if (physicalAgeSwap === 18) {
+			if (actor.pregAdaptation < 20) {
+				actor.pregAdaptation += 2;
+			}
+		}
+	}
+};
diff --git a/src/endWeek/slaveAssignmentReport.js b/src/endWeek/slaveAssignmentReport.js
index 4f02ad93f8f56c857da3d7afe1e383fe1437aae5..4795a0df978902f2ac8566a77971bb77935ab8b4 100644
--- a/src/endWeek/slaveAssignmentReport.js
+++ b/src/endWeek/slaveAssignmentReport.js
@@ -147,7 +147,7 @@ App.EndWeek.slaveAssignmentReport = function() {
 				}
 				poorHealthNeedReduction(slave);
 				slave.need = Math.round(slave.need);
-				slave.needCap = slave.need;
+				App.EndWeek.saVars.needCapPerSlave[slave.ID] = slave.need;
 			}
 		}
 
@@ -279,7 +279,7 @@ App.EndWeek.slaveAssignmentReport = function() {
 					established: 1,
 					entriesNumberInitial: initialPenthouseTotalEmployeesCount,
 					entriesNumber: _countPenthousePopulation(),
-					manager: null,
+					manager: null, // Recruiter is technically the "manager" according to the facility system, but ALL the penthouse leaders (inc. HG/BG) get counted in general population instead
 					alwaysExists: 0,
 				};
 			} else {
@@ -345,13 +345,12 @@ App.EndWeek.slaveAssignmentReport = function() {
 
 	/* Clean up global SA variables */
 	App.EndWeek.saVars = null;
-	delete V.flSex; // FIXME: remove, once this is passed as a parameter to saRules
 
 	return res;
 
 	function _countPenthousePopulation() {
 		const fs = App.Entity.facilities;
-		return fs.penthouse.employeesIDs().size + fs.headGirlSuite.totalEmployeesCount + fs.armory.totalEmployeesCount;
+		return fs.penthouse.totalEmployeesCount + fs.headGirlSuite.totalEmployeesCount + fs.armory.totalEmployeesCount;
 	}
 
 	function _printSlaveError(warning, slave) {
@@ -488,6 +487,9 @@ App.EndWeek.slaveAssignmentReport = function() {
 				} else if (!canHear(slave)) {
 					_printSlaveUnassignedNote(slave, "can no longer hear");
 					V.MilkmaidID = 0;
+				} else if (V.dairyRestraintsSetting === 2) {
+					_printSlaveUnassignedNote(slave, `has been made redundant by ${V.dairyName}'s industrialization and automation`);
+					V.MilkmaidID = 0;
 				}
 				if (V.MilkmaidID === 0) {
 					removeJob(slave, Job.MILKMAID);
diff --git a/src/events/nonRandom/eliteTakeOver.js b/src/events/Elites/eliteTakeOver.js
similarity index 99%
rename from src/events/nonRandom/eliteTakeOver.js
rename to src/events/Elites/eliteTakeOver.js
index 42de7ed345b8f33b336cd46b204c42fecb30ef94..1de93f3e08bc108f9e2623b0eca5fcb44635b82f 100644
--- a/src/events/nonRandom/eliteTakeOver.js
+++ b/src/events/Elites/eliteTakeOver.js
@@ -96,7 +96,7 @@ App.Events.eliteTakeOver = class eliteTakeOver extends App.Events.BaseEvent {
 				choices.push(new App.Events.Result(`Send a message to the leader of the ${V.mercenariesTitle}`, mercenaries));
 			}
 			if (V.SF.Toggle && V.SF.Active >= 1) {
-				choices.push(new App.Events.Result(`Send a message to ${App.SF.SFC()}`, SF));
+				choices.push(new App.Events.Result(`Send a message to ${App.Mods.SF.SFC()}`, SF));
 			}
 			if (V.PC.pregSource !== -1 && V.PC.pregSource !== -6) {
 				choices.push(new App.Events.Result(`Try and enrage them.`, enrage));
@@ -171,7 +171,7 @@ App.Events.eliteTakeOver = class eliteTakeOver extends App.Events.BaseEvent {
 					break;
 				case "SF":
 					r.push(`You send a quick message to`);
-					App.SF.SFC();
+					App.Mods.SF.SFC();
 					r.push(`about your situation, then you pick up the revolver and quickly take aim.`);
 					specialForcesMessageSent = 1;
 					break;
diff --git a/src/events/nonRandom/pInsemination.js b/src/events/Elites/pInsemination.js
similarity index 99%
rename from src/events/nonRandom/pInsemination.js
rename to src/events/Elites/pInsemination.js
index 47ebe7bf40bb51dd25e3cdde82a8ae9e12b97f5c..115726754551c88cdf474f51e0b52d9bfa904b26 100644
--- a/src/events/nonRandom/pInsemination.js
+++ b/src/events/Elites/pInsemination.js
@@ -1,7 +1,7 @@
 App.Events.PInsemination = class PInsemination extends App.Events.BaseEvent {
 	eventPrerequisites() {
 		return [
-			() => V.playerBred === 1,
+			() => V.playerBred > 0,
 			() => (V.PC.preg === 0 || V.PC.preg === -1),
 			() => V.PC.pregWeek === 0,
 			() => V.PC.vagina >= 1
@@ -13,7 +13,7 @@ App.Events.PInsemination = class PInsemination extends App.Events.BaseEvent {
 
 		V.nextButton = "Continue";
 
-		if (V.playerBredTube !== 1) {
+		if (V.playerBred === 1) {
 			if (V.EliteSires.length === 0) {
 				V.EliteSires = ["crazy", "futa", "moves", "preggo", "quick", "virgin"].shuffle();
 			}
diff --git a/src/events/PE/peCombatTraining.js b/src/events/PE/peCombatTraining.js
index 41aa70af4410b5a06dba36d95c178ed60c002c05..b44bbe3f7c2e8cc3ee51fcfc2a54f0c61010e7c4 100644
--- a/src/events/PE/peCombatTraining.js
+++ b/src/events/PE/peCombatTraining.js
@@ -57,8 +57,7 @@ App.Events.PECombatTraining = class PECombatTraining extends App.Events.BaseEven
 			} else if (canDoAnal(S.Bodyguard)) {
 				r.push(VCheck.Anal(S.Bodyguard, 1));
 			} else {
-				S.Bodyguard.counter.oral += 1;
-				V.oralTotal += 1;
+				seX(S.Bodyguard, "oral", V.PC);
 			}
 			App.Events.addParagraph(frag, r);
 			return frag;
diff --git a/src/events/PE/peHeadgirlConcubine.js b/src/events/PE/peHeadgirlConcubine.js
index 2164298f7dc4f289124f3bc01ddc9d01047c597d..ddc13892f7c6637151d857e8b504b1bf2ca8e878 100644
--- a/src/events/PE/peHeadgirlConcubine.js
+++ b/src/events/PE/peHeadgirlConcubine.js
@@ -479,8 +479,7 @@ App.Events.PEHeadgirlConcubine = class PEHeadgirlConcubine extends App.Events.Ba
 				if (canImpreg(S.Concubine, V.PC)) {
 					knockMeUp(S.Concubine, 10, 0, -1);
 				}
-				S.Concubine.counter.vaginal++;
-				V.vaginalTotal++;
+				seX(S.Concubine, "vaginal", V.PC);
 				r.push(`${He2} moans into you as ${he2} feels you run`);
 				if (V.PC.dick === 0) {
 					r.push(`the cool head of the phallus`);
@@ -507,21 +506,19 @@ App.Events.PEHeadgirlConcubine = class PEHeadgirlConcubine extends App.Events.Ba
 						if (canImpreg(S.Concubine, S.HeadGirl)) {
 							knockMeUp(S.Concubine, 10, 1, S.HeadGirl.ID);
 						}
-						S.Concubine.counter.anal++;
-						V.analTotal++;
+						seX(S.Concubine, "anal", V.PC);
+						seX(S.Concubine, "anal", S.HeadGirl);
 					} else {
 						r.push(`gently eases ${his} cock in beside you.`);
 						if (V.PC.dick !== 0) {
 							r.push(`The added friction against you in ${S.Concubine.slaveName}'s vagina feels incredible.`);
 						}
-						S.Concubine.counter.vaginal++;
-						V.vaginalTotal++;
+						seX(S.Concubine, "vaginal", V.PC);
+						seX(S.Concubine, "vaginal", S.HeadGirl);
 						if (canImpreg(S.Concubine, S.HeadGirl)) {
 							knockMeUp(S.Concubine, 10, 0, S.HeadGirl.ID);
 						}
 					}
-					S.HeadGirl.counter.penetrative++;
-					V.penetrativeTotal++;
 				} else {
 					r.push(`slides a hand down and`);
 					if (canDo.anal.conc) {
@@ -537,15 +534,13 @@ App.Events.PEHeadgirlConcubine = class PEHeadgirlConcubine extends App.Events.Ba
 						if (V.PC.dick !== 0) {
 							r.push(`You feel the penetration through ${S.Concubine.slaveName}'s vaginal walls, an incredible sensation.`);
 						}
-						S.Concubine.counter.anal++;
-						V.analTotal++;
+						seX(S.Concubine, "anal", V.PC);
 					} else {
 						r.push(`gently eases a few fingers in beside you.`);
 						if (V.PC.dick !== 0) {
 							r.push(`The added sensation in ${S.Concubine.slaveName}'s vagina feels incredible.`);
 						}
-						S.Concubine.counter.vaginal++;
-						V.vaginalTotal++;
+						seX(S.Concubine, "vaginal", V.PC);
 					}
 				}
 			} else {
@@ -553,8 +548,8 @@ App.Events.PEHeadgirlConcubine = class PEHeadgirlConcubine extends App.Events.Ba
 				if (canImpreg(S.Concubine, V.PC)) {
 					knockMeUp(S.Concubine, 10, 1, -1);
 				}
-				S.Concubine.counter.anal += 2;
-				V.analTotal += 2;
+				seX(S.Concubine, "anal", V.PC);
+				seX(S.Concubine, "anal", S.HeadGirl);
 				r.push(`Getting the idea, ${S.HeadGirl.slaveName}`);
 				if (canPenetrate(S.HeadGirl)) {
 					if (S.HeadGirl.dick - S.Concubine.anus > 2) {
@@ -577,8 +572,6 @@ App.Events.PEHeadgirlConcubine = class PEHeadgirlConcubine extends App.Events.Ba
 						r.push(`cheeks`);
 					}
 					r.push(`as far as they'll go, rotating ${his2} hips to position ${him2} for another phallus up the butt.`);
-					S.HeadGirl.counter.penetrative++;
-					V.penetrativeTotal++;
 					if (canImpreg(S.Concubine, S.HeadGirl)) {
 						knockMeUp(S.Concubine, 10, 1, S.HeadGirl.ID);
 					}
@@ -691,42 +684,31 @@ App.Events.PEHeadgirlConcubine = class PEHeadgirlConcubine extends App.Events.Ba
 				if (canImpreg(S.HeadGirl, V.PC)) {
 					knockMeUp(S.HeadGirl, 10, 0, -1);
 				}
-				S.HeadGirl.counter.vaginal++;
-				V.vaginalTotal++;
+				seX(S.HeadGirl, "vaginal", V.PC);
 				if (canPenetrate(S.Concubine)) {
 					if (canDo.anal.HG) {
 						if (canImpreg(S.HeadGirl, S.Concubine)) {
 							knockMeUp(S.HeadGirl, 10, 1, V.ConcubineID);
 						}
-						S.HeadGirl.counter.anal++;
-						V.analTotal++;
+						seX(S.HeadGirl, "anal", S.Concubine);
 					} else {
-						S.HeadGirl.counter.vaginal++;
-						V.vaginalTotal++;
 						if (canImpreg(S.HeadGirl, S.Concubine)) {
 							knockMeUp(S.HeadGirl, 10, 0, V.ConcubineID);
 						}
+						seX(S.HeadGirl, "vaginal", S.Concubine);
 					}
-					S.Concubine.counter.penetrative++;
-					V.penetrativeTotal++;
 				} else {
 					if (canDo.anal.HG) {
-						S.HeadGirl.counter.anal++;
-						V.analTotal++;
-					} else {
-						S.HeadGirl.counter.vaginal++;
-						V.vaginalTotal++;
+						seX(S.HeadGirl, "anal", V.PC);
 					}
 				}
 			} else {
 				if (canImpreg(S.HeadGirl, V.PC)) {
 					knockMeUp(S.HeadGirl, 10, 1, -1);
 				}
-				S.HeadGirl.counter.anal += 2;
-				V.analTotal += 2;
+				seX(S.HeadGirl, "anal", V.PC);
 				if (canPenetrate(S.Concubine)) {
-					S.HeadGirl.counter.penetrative++;
-					V.penetrativeTotal++;
+					seX(S.HeadGirl, "anal", S.Concubine);
 					if (canImpreg(S.HeadGirl, S.Concubine)) {
 						knockMeUp(S.HeadGirl, 10, 1, V.ConcubineID);
 					}
diff --git a/src/events/PE/pePitFight.js b/src/events/PE/pePitFight.js
index 5e7968bd2329af46d7fc924a4f0fca643bf9ab4a..456ccc7b30e1e63c448a811d4a06ca702a9334fd 100644
--- a/src/events/PE/pePitFight.js
+++ b/src/events/PE/pePitFight.js
@@ -236,7 +236,7 @@ App.Events.PEPitFight = class PEPitFight extends App.Events.BaseEvent {
 			slave.counter.pitKills += 1;
 			V.pitKillsTotal += 1;
 		} else if (deadlinessValue > (opponent-1)) {
-			r.push(`The combat is long and exhausting. ${slave.slaveName} and ${his} opponent are closely matched in terms of skill, so neither takes foolish risks and a protracted, bloody fight results as both slaves take horrible but non-life-threatening cuts. Finally, ${slave.slaveName}'s inferior physical condition fails ${him} and ${he} falls from exhaustion and blood loss. As ${he} slumps ${he} catches your eye with a look of apology. ${His} opponent stumbles over to open ${his} throat. ${slave.slaveName} <span class="health dec">has been killed.</span>`);
+			r.push(`The combat is long and exhausting. ${slave.slaveName} and ${his} opponent are closely matched in terms of skill, so neither takes foolish risks and a protracted, bloody fight results as both slaves take horrible but non-life-threatening cuts. Finally, ${slave.slaveName}'s inferior physical condition fails ${him} and ${he} falls from exhaustion and blood loss. As ${he} slumps ${he} catches your eye with a look of apology. ${His} opponent stumbles over to open ${his} throat.`);
 			damage = 1000;
 		} else {
 			r.push(`${slave.slaveName} is outmatched from the start. In the first pass, ${his} opponent moves beyond ${him}, opening a long gash in ${his} thigh as ${heU} goes. Thus injured, ${slave.slaveName} fails to block a slash that severs ${his} Achilles tendon on the other side. On ${his} knees, ${he} barely manages to ward off one more blow before the second one opens ${his} belly.`);
diff --git a/src/events/PESS/pessLovingHeadgirl.js b/src/events/PESS/pessLovingHeadgirl.js
index a539fd99929ae6d47f971b8903576738cc3be4b6..5bec0d6339419fff53ebb0ddb64b437d341fb043 100644
--- a/src/events/PESS/pessLovingHeadgirl.js
+++ b/src/events/PESS/pessLovingHeadgirl.js
@@ -120,7 +120,8 @@ App.Events.pessLovingHeadgirl = class pessLovingHeadgirl extends App.Events.Base
 				App.Events.drawEventArt(art, [S.HeadGirl, subSlave], [null, "no clothing"]);
 			}
 
-			r.push(`${He} giggles happily as you seize ${his} ${S.HeadGirl.skin} wrist and pull ${him} towards where your other slaves are mostly already asleep. ${He} jokingly points out ${subSlave.slaveName}, fast asleep. You nod, and ${S.HeadGirl.slaveName} pounces. ${subSlave.slaveName} wakes in terror and confusion to find ${his2} head and neck pinned in a leg-lock that holds ${his2} mouth hard against ${S.HeadGirl.slaveName}'s`);
+			r.push(`${He} giggles happily as you seize ${his} ${S.HeadGirl.skin} wrist and pull ${him} towards where your other slaves are mostly already asleep. ${He} jokingly points out`);
+			r.push(App.UI.DOM.combineNodes(App.UI.DOM.slaveDescriptionDialog(subSlave, subSlave.slaveName), `, fast asleep. You nod, and ${S.HeadGirl.slaveName} pounces. ${subSlave.slaveName} wakes in terror and confusion to find ${his2} head and neck pinned in a leg-lock that holds ${his2} mouth hard against ${S.HeadGirl.slaveName}'s`));
 			if (canDoAnal(S.HeadGirl)) {
 				r.push(`anus.`);
 			} else if (canDoVaginal(S.HeadGirl) && canPenetrate(S.HeadGirl)) {
diff --git a/src/events/PETS/petsAggressiveSchoolteacher.js b/src/events/PETS/petsAggressiveSchoolteacher.js
index 319859a859ef6f6e4b6a4605dae1b5cddd8fb373..e0e45dd8cddebce9b21be3bffc3ba7a6a3ec2cad 100644
--- a/src/events/PETS/petsAggressiveSchoolteacher.js
+++ b/src/events/PETS/petsAggressiveSchoolteacher.js
@@ -40,11 +40,10 @@ App.Events.petsAggressiveSchoolteacher = class petsAggressiveSchoolteacher exten
 			App.Entity.facilities.schoolroom.employees().forEach(function(s) {
 				if (s.intelligenceImplant < 30) {
 					s.intelligenceImplant += 0.1;
-					s.counter.oral += 1;
-					V.oralTotal += 1;
+					seX(s, "oral", S.Schoolteacher, S.Schoolteacher.dick > 0 ? "penetrative" : "vaginal");
 				}
 			});
-			return `You lean against the doorway of the classroom. ${S.Schoolteacher.slaveName} glances at you, but you subtly let ${him} know to continue with ${his} business. When ${he} finishes the lesson and, around the same time, climaxes, you clear your throat. The students all start with surprise and turn to you with trepidation. You observe in a conversational tone of voice that ${S.Schoolteacher.slaveName} is making great sacrifices here, performing an unsexy, boring job, and that any slave that does not work hard to learn will find themselves at the teacher's sexual disposal. Several of the least attentive students <span class="green">try to look studious,</span> though a few of the better ones can't hide a certain anticipation.`;
+			return `You lean against the doorway of the classroom. ${S.Schoolteacher.slaveName} glances at you, but you subtly let ${him} know to continue with ${his} business. When ${he} finishes the lesson and, around the same time, climaxes, you clear your throat. The students all start with surprise and turn to you with trepidation. You observe in a conversational tone of voice that ${S.Schoolteacher.slaveName} is making great sacrifices here, performing a boring, unsexy job, and that any slave that does not work hard to learn will find themselves at the teacher's sexual disposal. Several of the least attentive students <span class="green">try to look studious,</span> though a few of the better ones can't hide a certain anticipation.`;
 		}
 
 		function personal() {
diff --git a/src/events/RE/incest/reDevotedMotherDaughter.js b/src/events/RE/incest/reDevotedMotherDaughter.js
index 1423db3c9758af1b4694aa52f53eeb3a8bad39df..dc2e7c6b71ba96d2442d2ecf04557a6a6bf8144e 100644
--- a/src/events/RE/incest/reDevotedMotherDaughter.js
+++ b/src/events/RE/incest/reDevotedMotherDaughter.js
@@ -31,12 +31,17 @@ App.Events.REDevotedMotherDaughter = class REDevotedMotherDaughter extends App.E
 		} = getPronouns(mommy);
 
 		const {
-			he2, his2, daughter2
-		} = getPronouns(daughter).appendSuffix("2");
+			he: he2, his: his2, daughter: daughter2
+		} = getPronouns(daughter);
 
 		App.Events.drawEventArt(node, [mommy, daughter], "no clothing");
 
-		r.push(`${mommy.slaveName} and ${his} ${daughter2} ${daughter.slaveName} are both good slaves, devoted and obedient. They'd probably do anything you order them to do. By happenstance they come before you for inspection one after the other. They certainly see each other stark naked frequently enough. As you finish ${mommy.slaveName}'s inspection, ${his} ${daughter2} waits patiently for ${his2} turn. It occurs to you that they probably would do <i>anything</i> you order them to do, and that they're so acclimated to sexual slavery that they might well enjoy it.`);
+		r.push(
+			App.UI.DOM.slaveDescriptionDialog(mommy, mommy.slaveName),
+			`and ${his} ${daughter2}`,
+			App.UI.DOM.slaveDescriptionDialog(daughter, daughter.slaveName),
+			`are both good slaves, devoted and obedient. They'd probably do anything you order them to do. By happenstance they come before you for inspection one after the other. They certainly see each other stark naked frequently enough. As you finish ${mommy.slaveName}'s inspection, ${his} ${daughter2} waits patiently for ${his2} turn. It occurs to you that they probably would do <i>anything</i> you order them to do, and that they're so acclimated to sexual slavery that they might well enjoy it.`
+		);
 
 		App.Events.addParagraph(node, r);
 
@@ -48,7 +53,7 @@ App.Events.REDevotedMotherDaughter = class REDevotedMotherDaughter extends App.E
 		function share() {
 			const frag = new DocumentFragment();
 			let r = [];
-			r.push(`Neither of them bat an eye when you announce you're turning in early and that they'll be joining you. Since they're already naked, they get into your big soft bed before you and lie facing each other, with enough room in between them for you to take a central position. They clearly assume you'll start with one of them on each side of you, so they're quite surprised when you slide in behind ${mommy.slaveName} instead. ${daughter.slaveName} snuggles up to ${his2} ${mother} happily enough, however. You extend the foreplay for hours, eventually bringing both of them to such a state of naked arousal that they begin grinding against each other as much as they do you. They get the idea, and things turn into a sort of unspoken mutual one-upmanship between them. What starts with ${daughter.slaveName} clearly feeling very daring as ${he2} sucks ${his2} ${mother}'s nipple ends with ${mommy.slaveName} lying on ${his} back getting fucked by you while ${he} orally pleasures ${daughter.slaveName}. You're face to face with ${daughter.slaveName} and ${he2} groans happily into your mouth as ${mommy.slaveName} moans into ${his2} fuckhole. <span class="trust inc">They have both become more trusting of you.</span>`);
+			r.push(`Neither of them bat an eye when you announce you're turning in early and that they'll be joining you. Since they're already naked, they get into your big soft bed before you and lie facing each other, with enough room in between them for you to take a central position. They clearly assume you'll start with one of them on each side of you, so they're quite surprised when you slide in behind ${mommy.slaveName} instead. ${daughter.slaveName} snuggles up to ${his2} ${mother} happily enough, however. You extend the foreplay for hours, eventually bringing both of them to such a state of naked arousal that they begin grinding against each other as much as they do you. They get the idea, and things turn into a sort of unspoken mutual one-upmanship between them. What starts with ${daughter.slaveName} clearly feeling very daring as ${he2} sucks ${his2} ${mother}'s nipple ends with ${mommy.slaveName} lying on ${his} back getting fucked by you while ${he} orally pleasures ${daughter.slaveName}. You're face to face with ${daughter.slaveName} and ${he2} groans happily into your mouth as ${mommy.slaveName} moans into ${his2} ${daughter.dick > 0 ? `cock` : `fuckhole`}. <span class="trust inc">They have both become more trusting of you.</span>`);
 
 			mommy.trust += 4;
 			daughter.trust += 4;
@@ -72,7 +77,7 @@ App.Events.REDevotedMotherDaughter = class REDevotedMotherDaughter extends App.E
 		function started() {
 			const frag = new DocumentFragment();
 			let r = [];
-			r.push(`You give them orders of devastating simplicity: they are to repair to the couch in your office and are to take turns getting each other off until such time as you tell them otherwise. They're momentarily stunned, but ${mommy.slaveName} takes the lead and draws ${his} ${daughter2} over to the couch${(hasAnyArms(mommy) && hasAnyArms(daughter)) ? "by the hand" : ""}. They're both accomplished sex slaves and obey orders well, so they are quite successful in the little game, if a bit mechanical. For the rest of the day, interviewees come and go and are treated to the sight of the two of them having subdued sex on the couch. Showing off one's slaves for business interlocutors is a common Free Cities practice, but more than one perceptive person figures out what the resemblance between the two slaves and the age gap between them really means. Of course, all those who figure it out are impressed by your sheer decadence.`);
+			r.push(`You give them orders of devastating simplicity: they are to repair to the couch in your office and are to take turns getting each other off until such time as you tell them otherwise. They're momentarily stunned, but ${mommy.slaveName} takes the lead and draws ${his} ${daughter2} over to the couch${(hasAnyArms(mommy) && hasAnyArms(daughter)) ? " by the hand" : ""}. They're both accomplished sex slaves and obey orders well, so they are quite successful in the little game, if a bit mechanical. For the rest of the day, interviewees come and go and are treated to the sight of the two of them having subdued sex on the couch. Showing off one's slaves for business interlocutors is a common Free Cities practice, but more than one perceptive person figures out what the resemblance between the two slaves and the age gap between them really means. Of course, all those who figure it out are impressed by your sheer decadence.`);
 			r.push(`<span class="reputation inc">Your reputation has increased considerably.</span>`);
 			repX(2500, "event", mommy);
 			repX(2500, "event", daughter);
diff --git a/src/events/RE/reAWOL.js b/src/events/RE/reAWOL.js
index bb983757363e28833fb8ea74710243d509fbfe99..a962091df7ba7a34e6eb5db225201f560b66f111 100644
--- a/src/events/RE/reAWOL.js
+++ b/src/events/RE/reAWOL.js
@@ -87,7 +87,7 @@ App.Events.REAWOL = class REAWOL extends App.Events.BaseEvent {
 		function SF() {
 			const frag = new DocumentFragment();
 			let r = [];
-			r.push(`You take a tablet and send ${App.SF.SFC()} a notice about the mutinous mercenary. When you have the majority of the pertinent details committed to text, all that remains is to decide the fate of your quarry.`);
+			r.push(`You take a tablet and send ${App.Mods.SF.SFC()} a notice about the mutinous mercenary. When you have the majority of the pertinent details committed to text, all that remains is to decide the fate of your quarry.`);
 			App.Events.addParagraph(frag, r);
 
 			const choices = [];
diff --git a/src/events/RE/reArcologyInspection.js b/src/events/RE/reArcologyInspection.js
index b288d0f4c5645471a5cf4520e8be4172ab55dce0..672c62c8bccb55bb30c2d03b90b42676d84ef51c 100644
--- a/src/events/RE/reArcologyInspection.js
+++ b/src/events/RE/reArcologyInspection.js
@@ -457,7 +457,7 @@ App.Events.REArcologyInspection = class REArcologyInspection extends App.Events.
 			t.push(`Every arcology has its share of dissidents; it's one of the inevitable results of the semi-anarchic nature of the Free Cities. You have an opportunity to build your own <span class="reputation inc">reputation</span> and also help secure ${agent ? `${agent.slaveName}'s` : `your indirect`} <span class="darkviolet">authority</span> over ${arcology.name}, and it would be a shame to let it pass unheeded. You spend the rest of the day helping pass judgement, and even administer a few whippings and assfuckings yourself, just for good measure.`);
 			repX(100, "event");
 			if (V.secExpEnabled) {
-				App.SecExp.authorityX(250);
+				App.Mods.SecExp.authorityX(250);
 			}
 			return t;
 		}
diff --git a/src/events/RE/reBoomerang.js b/src/events/RE/reBoomerang.js
index 14f2e4784a4603710b6ca7d1de6e263807cac9fd..a51ff4b8611e9cdd87d3643374b2af7733d20de1 100644
--- a/src/events/RE/reBoomerang.js
+++ b/src/events/RE/reBoomerang.js
@@ -44,7 +44,7 @@ App.Events.REBoomerang = class REBoomerang extends App.Events.BaseEvent {
 
 		r.push(`Your work is interrupted by ${V.assistant.name} with an alert from the entrance to the penthouse.`);
 		if (V.assistant) {
-			r.push(Spoken(slave, `"${properTitle()}," ${heA} says, "you're going to want to see this."`));
+			r.push(`"${properTitle()}," ${heA} says, "you're going to want to see this."`);
 		} else {
 			r.push(`${HeA}'s got the incident flagged as not fitting into any of the usual categories of disturbance, and requests your attention.`);
 		}
@@ -127,7 +127,7 @@ App.Events.REBoomerang = class REBoomerang extends App.Events.BaseEvent {
 						r.push(`The`);
 						break;
 					case "D milky herm":
-						r.push(Spoken(slave, `"I got resold me to a dairy. A horrible dairy. They said I'm valuable because I give two kinds of milk."`));
+						r.push(Spoken(slave, `"I got resold to a dairy. A horrible dairy. They said I'm valuable because I give two kinds of milk."`));
 						r.push(`The`);
 						break;
 					default:
@@ -422,6 +422,15 @@ App.Events.REBoomerang = class REBoomerang extends App.Events.BaseEvent {
 				slave.sexualFlaw = "crude";
 				slave.skill.combat = 1;
 				break;
+			case "neoimperialist arcology":
+				r.push(Spoken(slave, `"It was horrible."`));
+				r.push(`You sold ${him} to a Neo-Imperialist arcology; it's nothing short of incredible that ${he} managed to get back here. ${He} must have sold and traded ${himself} without hesitation.`);
+				r.push(Spoken(slave, `"My new owner died, and his wicked son inherited us. He's the cruelest master I've ever seen, and he scourges his harem for fun."`));
+				r.push(`${He} turns around to show you extensive scars and open wounds on ${his} back and buttocks.`);
+				App.Medicine.Modification.addScar(slave, "back", "whip", 2);
+				App.Medicine.Modification.addScar(slave, "butt", "whip", 2);
+				healthDamage(slave, 20);
+				break;
 			case "aztec revivalist arcology":
 				r.push(Spoken(slave, `"It was horrible."`));
 				r.push(`You sold ${him} to an Aztec Revivalist arcology; it's nothing short of incredible that ${he} managed to get back here. ${He} must have sold and traded ${himself} without hesitation.`);
diff --git a/src/events/RE/reCitizenHookup.js b/src/events/RE/reCitizenHookup.js
index 0c4f8af71108e244f1c762970163b3624ecf797c..c4c71ac0758e6a1e85ea856ff1899a828bbb976c 100644
--- a/src/events/RE/reCitizenHookup.js
+++ b/src/events/RE/reCitizenHookup.js
@@ -9,23 +9,12 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 		let r = [];
 		let repopHookupPregnant;
 
-		const fsArray = [];
-		for (const FS of App.Data.FutureSociety.fsNames) {
-			if (V.arcologies[0][FS] !== "unset") {
-				fsArray.push(FS);
-			}
-		}
+		const fsArray = App.Data.FutureSociety.fsNames.filter(f => V.arcologies[0][f] !== "unset");
 		const FS = fsArray.random();
-		console.log(FS);
 		const fsAdj = (fsArray.length > 0) ? App.Data.FutureSociety.records[FS].adj : "none";
 
 		r.push(`At night, the best living areas in the arcology offer a constant mélange of selective entertainments. There's a perpetual social scrum of who is to be invited to what going on, and you occupy a preeminent place atop it, mostly aloof from the struggles of your citizens for recognition and influence. You're invited to almost everything, since everyone who lives here knows the value of being in favor with the owner of the arcology. Invitations to your parties, of course, are some of the most valuable social currency in the arcology and one of ${V.assistant.name}'s most important duties is to help you manage them without wasting your valuable time. It's not actually necessary for you to attend your own parties, since almost everyone will be glad to be seen in the entertainment area of the penthouse whether or not the`);
-		if (V.PC.title === 1) {
-			r.push(`proprietor`);
-		} else {
-			r.push(`proprietress`);
-		}
-		r.push(`is actually present.`);
+		r.push(`${V.PC.title === 1 ? 'proprietor' : 'proprietress'} is actually present.`);
 		App.Events.addParagraph(node, r);
 		r = [];
 		r.push(`But tonight, you've put in an appearance. Your citizens are drinking your`);
@@ -88,7 +77,7 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 				r.push(`a slim young thing`);
 				break;
 			case "Asset Expansionist":
-				r.push(`curvaceous young woman`);
+				r.push(`a curvaceous young woman`);
 				break;
 			case "Pastoralist":
 				r.push(`a hot little lady`);
@@ -433,7 +422,7 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 			const frag = new DocumentFragment();
 			let r = [];
 			r.push(`You turn to face her straight on, and something about the look in your eye fills her with mixed apprehension and anticipation. You agree with her banter and praise her for being so forward-thinking, before transitioning to more direct praise of her style and then her body. You're speaking in a tone that cuts through the room, and by the time you kiss your willing conquest, there's not a person in the room who isn't paying attention. They all understand the message: this gathering is turning into something else, now. Those few who aren't willing to fuck in public withdraw, and everyone who didn't come with a sexual partner sends urgent messages to have appropriate slaves brought from their apartments. You make out with her for a while, letting everyone make arrangements, and then pull her clothes off, making sure her`);
-			if (fsAdj !== "none") {
+			if (!["none", "Multiculturalist"].includes(fsAdj)) {
 				V.arcologies[0][FS] += 5;
 			}
 			switch (fsAdj) {
@@ -482,7 +471,7 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 					r.push(`curvaceous form`);
 					break;
 				case "Pastoralist":
-					r.push(`milk-fed assets`);
+					r.push(`milk-fed plushness`);
 					break;
 				case "Physical Idealist":
 					r.push(`muscular body`);
@@ -525,7 +514,7 @@ App.Events.RECitizenHookup = class RECitizenHookup extends App.Events.BaseEvent
 				default:
 					r.push(`hot young body`);
 			}
-			r.push(`is obvious to everyone. The message is clear, and your guest of honor is the center of attention as you take her there in view of the arcology's leading citizens. Naturally, the story percolates, making it clear that there's nothing you won't do to <span class="green">further acceptance of ${fsAdj} principles.</span>`);
+			r.push(`is obvious to everyone. The message is clear, and your guest of honor is the center of attention as you take her there in view of the arcology's leading citizens. Naturally, the story percolates, making it clear that there's nothing you won't do to <span class="green">further acceptance of ${fsArray.length > 0 ? FutureSocieties.displayAdj(FS) : "societal"}} principles.</span>`);
 
 			App.Events.addParagraph(frag, r);
 			return frag;
diff --git a/src/events/RE/reDevotees.js b/src/events/RE/reDevotees.js
index 7a5dd597a57999f6f7248687c5408dabb1020643..a141523f358ae816e9affcfd7e433d5c32d7a117 100644
--- a/src/events/RE/reDevotees.js
+++ b/src/events/RE/reDevotees.js
@@ -51,7 +51,7 @@ App.Events.REDevotees = class REDevotees extends App.Events.BaseEvent {
 		function casino() {
 			let t = [];
 			t.push(`The croupiers, bouncers and regulars down at the nearest casino hardly know what to think when you appear with a chit full of cash and twice as many partners as you have arms. You live the night big, starting at the poker table with so many tits and asses on display behind you that, <span class="cash inc">baby, you make a killing.</span> ${slaveList} quickly catch the rhythm of the place: slaves can get away with a little more in the smoky, whiskey soaked, money tinted atmosphere, and they <span class="devotion inc">enjoy themselves immensely.</span> They flirt, flash, giggle, kiss each other, and generally destroy the concentration of everyone within twenty ${V.showInches === 2 ? "yards" : "meters"} — except you. Ring-a-ding-ding.`);
-			const inc = random(30, 100)*3;
+			const inc = random(30, 100)*30;
 			for (const s of devotees) {
 				cashX(inc, "event", s);
 				s.devotion += 4;
diff --git a/src/events/RE/reLegendaryCow.js b/src/events/RE/reLegendaryCow.js
index f0d5c8f7aac4f92ed75e437333261c576185c340..63fcd865fbe95594d646e67827d711a925a2c6ac 100644
--- a/src/events/RE/reLegendaryCow.js
+++ b/src/events/RE/reLegendaryCow.js
@@ -28,7 +28,7 @@ App.Events.RELegendaryCow = class RELegendaryCow extends App.Events.BaseEvent {
 
 		r.push(
 			App.UI.DOM.slaveDescriptionDialog(slave),
-			`is an incredible producer of milk. ${He}'s lactating in volumes that would have been unthinkable in the days when drug treatments were limited by consent. A nascent slave dairy trade organization will be holding a public stock show tomorrow, and since they're aware you keep cows, they've sent you an invitation to enter stock to be judged.`
+			`is an incredible producer of ${slave.milkFlavor === "none" ? `` : `${slave.milkFlavor} flavored `}milk. ${He}'s lactating in volumes that would have been unthinkable in the days when drug treatments were limited by consent. A nascent slave dairy trade organization will be holding a public stock show tomorrow, and since they're aware you keep cows, they've sent you an invitation to enter stock to be judged.`
 		);
 
 		App.Events.addParagraph(node, r);
diff --git a/src/events/RE/reMaleArcologyOwner.js b/src/events/RE/reMaleArcologyOwner.js
index 1ba9ddd3241e1b7a9cb803af72a350f91eac1d2d..d30b527a5ac085996a7cb9d5fe631e465ac22f02 100644
--- a/src/events/RE/reMaleArcologyOwner.js
+++ b/src/events/RE/reMaleArcologyOwner.js
@@ -66,7 +66,7 @@ App.Events.REMaleArcologyOwner = class REMaleArcologyOwner extends App.Events.Ba
 			if (V.PC.preg >= 28 && V.PC.pregMood === 2) {
 				r.push(`You move to waddle past him and purposefully stumble, prompting him to catch you. Feigning fatigue, you politely ask if he'd help you out. You aren't exactly subtle as he walks you back to your room, dropping hints at how difficult your pregnancy has been and just how good it feels to be with a man. ${capFirstChar(V.assistant.name)} cleared your suite long ago, so when you enter, disrobe and splay yourself across the bed, it's just you and him.`);
 				if (randomForeignFS > 90) {
-					r.push(`It's immediately clear by the look on his face that you made a mistake. The man clearly comes from a society that dislikes pregnant woman leading and your attempt to manipulate him into being your lover has pushed him past his level of tolerance. He storms out in anger and, upon returning to the party, makes your underhanded efforts known. <span class="reputation dec">Your reputation has taken a major hit.</span>`);
+					r.push(`It's immediately clear by the look on his face that you made a mistake. The man clearly comes from a society that dislikes pregnant women leading, and your attempt to manipulate him into being your lover has pushed him past his level of tolerance. He storms out in anger and, upon returning to the party, makes your underhanded efforts known. <span class="reputation dec">Your reputation has taken a major hit.</span>`);
 					repX(-1000, "event");
 				} else if (randomForeignFS > 70) { // repop
 					r.push(`It's immediately clear by the look on his face that you made a mistake. He wastes no time in leaping onto the bed, and in his haste, barely manages to disrobe. Before you can attempt to take control, he's hilted in your needy vagina and giving you the fucking your body has been craving. He leaves a few hours later with a satisfied expression and returns to the party, where he puts in a good word for just how good you were. <span class="reputation inc">Your reputation has slightly improved,</span> though nowhere near as much as his.`);
diff --git a/src/events/RE/reMaleCitizenHookup.js b/src/events/RE/reMaleCitizenHookup.js
index aa39991768b526334df106cba38a67d3ced76d5d..080a5e7ee85f7a0f9505ac55572119cf1e137dfa 100644
--- a/src/events/RE/reMaleCitizenHookup.js
+++ b/src/events/RE/reMaleCitizenHookup.js
@@ -17,12 +17,7 @@ App.Events.REMaleCitizenHookup = class REMaleCitizenHookup extends App.Events.Ba
 
 		let r = [];
 		r.push(`At night, the best living areas in the arcology offer a constant mélange of selective entertainments. There's a perpetual social scrum of who is to be invited to what going on, and you occupy a preeminent place atop it, mostly aloof from the struggles of your citizens for recognition and influence. You're invited to almost everything, since everyone who lives here knows the value of being in favor with the owner of the arcology. Invitations to your parties, of course, are some of the most valuable social currency in the arcology and one of ${V.assistant.name}'s most important duties is to help you manage them without wasting your valuable time. It's not actually necessary for you to attend your own parties, since almost everyone will be glad to be seen in the entertainment area of the penthouse whether or not the`);
-		if (V.PC.title === 1) {
-			r.push(`proprietor`);
-		} else {
-			r.push(`proprietress`);
-		}
-		r.push(`is actually present.`);
+		r.push(`${V.PC.title === 1 ? 'proprietor' : 'proprietress'} is actually present.`);
 		App.Events.addParagraph(node, r);
 		r = [];
 		r.push(`But tonight, you've put in an appearance. Your citizens are drinking your`);
@@ -646,6 +641,9 @@ App.Events.REMaleCitizenHookup = class REMaleCitizenHookup extends App.Events.Ba
 			const frag = new DocumentFragment();
 			let r = [];
 			r.push(`You turn to face him straight on, and something about the look in your eye fills him with mixed apprehension and anticipation. You agree with his banter and praise him for being so forward-thinking, before transitioning to more direct praise of his style and then his body. You're speaking in a tone that cuts through the room, and by the time you kiss your willing conquest, there's not a person in the room who isn't paying attention. They all understand the message: this gathering is turning into something else, now. Those few who aren't willing to fuck in public withdraw, and everyone who didn't come with a sexual partner sends urgent messages to have appropriate slaves brought from their apartments. You make out with him for a while, letting everyone make arrangements, and then pull his clothes off, making sure his`);
+			if (!["none", "FSNull"].includes(FS)) {
+				V.arcologies[0][FS] += 5;
+			}
 			switch (FS) {
 				case "FSSubjugationist":
 				case "FSSupremacist":
@@ -738,8 +736,7 @@ App.Events.REMaleCitizenHookup = class REMaleCitizenHookup extends App.Events.Ba
 				default:
 					r.push(`hot young body`);
 			}
-			V.arcologies[0][FS] += 5;
-			r.push(`is obvious to everyone. The message is clear, and your guest of honor is the center of attention as you take him there in view of the arcology's leading citizens. Naturally, the story percolates, making it clear that there's nothing you won't do to <span class="green">further acceptance of ${FS} principles.</span>`);
+			r.push(`is obvious to everyone. The message is clear, and your guest of honor is the center of attention as you take him there in view of the arcology's leading citizens. Naturally, the story percolates, making it clear that there's nothing you won't do to <span class="green">further acceptance of ${FS !== "none" ? FutureSocieties.displayAdj(FS) : "societal"} principles.</span>`);
 			if (canGetPregnant(V.PC)) {
 				r.push(knockMeUp(V.PC, 40, 0, -2));
 			}
diff --git a/src/events/RE/reNickname.js b/src/events/RE/reNickname.js
index 23a8e69ea1711a307bb336a3ffbc454503f6ae95..446102ea72a1d16e92e8c790b4f038fa9b385ec8 100644
--- a/src/events/RE/reNickname.js
+++ b/src/events/RE/reNickname.js
@@ -81,48 +81,28 @@ App.Events.RENickname = class RENickname extends App.Events.BaseEvent {
 			function selectCategory(cheat) {
 				const el = new DocumentFragment();
 				if (cheat) {
-					const choice = App.UI.DOM.appendNewElement("span", el, `Select a category of nicknames `);
-					const select = App.UI.DOM.appendNewElement("select", choice);
-					let matchFound = false;
+					App.UI.DOM.appendNewElement("span", el, `Select a category of nicknames `);
+					const options = [];
 					for (const category of qualifiedNicknames.keys()) {
-						const option = App.UI.DOM.appendNewElement("option", select, category);
-						option.value = category;
-						if (option.value === seed) {
-							option.selected = true;
-							matchFound = true;
-						}
-					}
-					if (!matchFound) {
-						select.selectedIndex = -1;
+						options.push({key: category, name: category});
 					}
-					select.onchange = () => {
-						const O = select.options[select.selectedIndex];
-						seed = O.value;
+					el.append(App.UI.DOM.makeSelect(options, seed, value => {
+						seed = value;
 						jQuery(intro).empty().append(introPassage());
-					};
+					}));
 				}
 				return el;
 			}
 			function selectNickname(cheat) {
 				const el = new DocumentFragment();
 				if (cheat) {
-					const select = App.UI.DOM.appendNewElement("select", el);
-					let matchFound = false;
+					const options = [];
 					for (const category of nicknameArray) {
-						const option = App.UI.DOM.appendNewElement("option", select, `'${category}'`);
-						option.value = category;
-						if (option.value === nickname) {
-							option.selected = true;
-							matchFound = true;
-						}
-					}
-					if (!matchFound) {
-						select.selectedIndex = -1;
+						options.push({key: category, name: `'${category}'`});
 					}
-					select.onchange = () => {
-						const O = select.options[select.selectedIndex];
-						nickname = O.value;
-					};
+					el.append(App.UI.DOM.makeSelect(options, nickname, name => {
+						nickname = name;
+					}));
 				} else {
 					App.UI.DOM.appendNewElement("span", el, `${nickname} `, "pink");
 				}
@@ -677,9 +657,9 @@ App.Events.RENickname = class RENickname extends App.Events.BaseEvent {
 				case "catgirl":
 					nickMap.set("catgirl", {
 						nicknameArray: ["Ace", "Bandit", "Bastet", "Bubbles", "Butterscotch", "Cheshire", "Clawdia", "Cupcake", "Cutie", "Dottie", "Dandelion", "Fluffy", "Furball", "Garfield", "Ginger", "Griddlebone", "Grizabella", "Hairball", "Jennyanydots", "Jellicle", "Jemima", "Kitten", "Lynx", "Macavity", "Meow", "Nala", "Neko", "Nyan", "Old Deuteronomy", "Oreo", "Panther", "Puma", "Tabby", "Tiger", "Tigger", "Twitchy", "Simba", "Spots", "Stormy", "Sunshine", "Whiskers", "Ziggy"],
-						situationDesc: `is a catgirl, a highly unusual result of advanced genetic engineering in the postmodern age. Their pronounced cat-like features mark them apart from the rest of your slaves, from the twitching, sensitive ears to the light coating of silky fur across their body, and tend to be the first thing anyone notices when looking at them.`,
+						situationDesc: `is a cat${girl}, a highly unusual result of advanced genetic engineering in the postmodern age. Their pronounced cat-like features mark them apart from the rest of your slaves, from the twitching, sensitive ears to the light coating of silky fur across their body, and tend to be the first thing anyone notices when looking at them.`,
 						applyDesc: `now has a constant and humiliating reminder that their cat-like features define ${him} above all else.`,
-						notApplyDesc: `seems rather ambivalent about your decision to not define ${him} by ${his} catlike nature. ${He} just mrowls at you in a way that could be interpeted as either gratitude or annoyance.`,
+						notApplyDesc: `seems rather ambivalent about your decision to not define ${him} by ${his} catlike nature. ${He} just mrowls at you in a way that could be interpreted as either gratitude or annoyance.`,
 					});
 					break;
 				case "semitic":
@@ -969,9 +949,9 @@ App.Events.RENickname = class RENickname extends App.Events.BaseEvent {
 					if (random(1, 1500) <= 100) {
 						if (slave.physicalAge < 13) {
 							return ["Preteen"];
-						} else if ((slave.physicalAge >= 16) && (slave.physicalAge < 17)) {
+						} else if (slave.physicalAge === 16) { // WHY? (slave.physicalAge >= 16) && (slave.physicalAge < 17)
 							return ["Sweet Sixteen"];
-						} else if ((slave.physicalAge >= 18) && (slave.physicalAge < 19)) {
+						} else if (slave.physicalAge === 18) { // WHY? (slave.physicalAge >= 18) && (slave.physicalAge < 19)
 							/* Not currently possible but we might change later. */
 							return ["Barely Legal"];
 						}
@@ -1096,10 +1076,7 @@ App.Events.RENickname = class RENickname extends App.Events.BaseEvent {
 				notApplyDesc: `realizes that ${he} isn't special just because ${he}'s been fucked so much, and understands that ${he}'ll have to do ${his} best to fuck like a fresh teenager no matter how loose ${he} gets.`,
 			});
 		}
-		if (
-			(slave.boobsImplant / slave.boobs) >= .60 ||
-			(slave.buttImplant / slave.butt) > .60
-		) {
+		if ((slave.boobsImplant / slave.boobs) >= 0.6 || (slave.buttImplant / slave.butt) > 0.6) {
 			nickMap.set("implants", {
 				nicknameArray: ["Balloons", "Blown Up", "Blowup Doll", "Bolted-On", "Enhanced", "Expanded", "Fake", "Implanted", "Implants", "Plastic", "Plastique", "Silicone"],
 				situationDesc: `is full of breast implants. They're so large it's quite obvious they're fake, and the implications are clear: ${He}'s a plastic slut, and the other slaves never tire of letting ${him} know it.`,
@@ -1231,7 +1208,7 @@ App.Events.RENickname = class RENickname extends App.Events.BaseEvent {
 			});
 			if ((slave.ovaries === 1 && slave.vagina === 0) || (slave.mpreg === 1 && slave.anus === 0)) {
 				nickMap.set("virgin preg", {
-					nicknameArray: ["Virgin Mary", "Immaculate", "Miracle"],
+					nicknameArray: ["Aeiparthenos", "Almah", "Annunciated", "Baroness Ampthill", "Chimalman", "Dughdova", "Ever-Virgin", "Immaculate", "Miracle", "Miraculous", "Parthenogenetic", "Rhea Silvia", "Sofonim", "Virgin Mary"],
 					situationDesc: `is pregnant, but that's not what makes ${him} special. ${He} still has an intact hymen, something completely unexpected of a ${girl} in the motherly way. Rumors and superstition surround ${him}.`,
 					applyDesc: `takes a bit of solace from ${his} new hope at ${his} nickname that ${he} will be allowed to complete ${his} unusual pregnancy, and a bit of trepidation of what awaits ${him} when it comes time to give birth.`,
 					notApplyDesc: `dreads and anticipates the day when ${he}'ll lose ${his} virginity, becoming just another pregnant slave.`,
diff --git a/src/events/RE/rePregInventorFCTV.js b/src/events/RE/rePregInventorFCTV.js
index 6f1ecdf1c220f5a7a365b82a8ee8338960c8d46d..57ce2aacfec1e0d6cc8d1062106779ac48d3477e 100644
--- a/src/events/RE/rePregInventorFCTV.js
+++ b/src/events/RE/rePregInventorFCTV.js
@@ -572,7 +572,7 @@ App.Events.rePregInventorFCTV = class rePregInventorFCTV extends App.Events.Base
 				r.push(`centimeters`);
 			}
 			r.push(`above the heads of the studio audience. One particularly adventurous audience member reaches up to place a hand on the slave's stomach to feel it bounce in their hands as ${he} gets fucked, and soon other members of the audience are also reaching up to feel the massive organ. The swing slowly rotates the coupling lovers back and forth over the length of the audience's seats, in a circle, and a wave of eager hands reach up as it does so, caressing your breeder's shaking belly as ${he} gets fucked by the show's moaning host. When Millie and your slave finally convulse in mutual orgasm, the camera zooms in on Millie's face for a close-up. She seems exhausted, but she smiles for it anyway.`);
-			slave.counter.vaginal++;
+			seX(slave, "vaginal", "public");
 			App.Events.addParagraph(el, r);
 			r = [];
 			r.push(
diff --git a/src/events/RE/rePregInventorShowOff.js b/src/events/RE/rePregInventorShowOff.js
index c80f2c699141a696bdfc7378992e6fca9f5f57f6..253d4c39e3455a8687d8e09d01dedb1b085f1152 100644
--- a/src/events/RE/rePregInventorShowOff.js
+++ b/src/events/RE/rePregInventorShowOff.js
@@ -556,7 +556,7 @@ App.Events.rePregInventorShowOff = class rePregInventorShowOff extends App.Event
 			function tv() {
 				const frag = new DocumentFragment();
 				let r = [];
-				r.push(`You are so impressed by ${his} ideas that you arrange to have ${him} demonstrate ${his} discoveries on a prominent FCTV talk show. It will take some time, and you'll have to insure that ${he}'s at least reasonably well known before the show's executives will agree to allow ${him} on-air, but you're certain that ${slave.slaveName}'s name will soon be on the lips of pregnancy-loving slaveowners and Free Cities citizens around the world. In the meantime, you implement ${his} ideas around the arcology. ${He} is <span class="devotion inc">thrilled</span> to have pleased you so much that you would <span class="trust inc">put such faith in ${his} ideas.</span>`);
+				r.push(`You are so impressed by ${his} ideas that you arrange to have ${him} demonstrate ${his} discoveries on a prominent FCTV talk show. It will take some time, and you'll have to ensure that ${he}'s at least reasonably well known before the show's executives will agree to allow ${him} on-air, but you're certain that ${slave.slaveName}'s name will soon be on the lips of pregnancy-loving slaveowners and Free Cities citizens around the world. In the meantime, you implement ${his} ideas around the arcology. ${He} is <span class="devotion inc">thrilled</span> to have pleased you so much that you would <span class="trust inc">put such faith in ${his} ideas.</span>`);
 				cashX(-tvCost, "event", slave);
 				V.pregInventor = 2;
 				V.pregInventions = 1;
diff --git a/src/events/RE/reRelationshipAdvice.js b/src/events/RE/reRelationshipAdvice.js
index 76422d7c1eac7fcbb0ae51ee95139b4b941b1f7a..ae286e23d9baaf42164b273540755412a280891a 100644
--- a/src/events/RE/reRelationshipAdvice.js
+++ b/src/events/RE/reRelationshipAdvice.js
@@ -48,7 +48,7 @@ App.Events.RERelationshipAdvice = class RERelationshipAdvice extends App.Events.
 			`biting ${his} lip.`,
 			Spoken(slave, `"It's`),
 			App.UI.DOM.combineNodes( // TODO: how the heck would we get them to lisp the name
-				App.UI.DOM.slaveDescriptionDialog(relSlave),
+				App.UI.DOM.slaveDescriptionDialog(relSlave, relSlave.slaveName),
 				`."`
 			),
 		);
diff --git a/src/events/RE/reRelativeRecruiter.js b/src/events/RE/reRelativeRecruiter.js
index 089e57ec444c197e7286deabdb7c70a8d3476e3a..7ceacf88562d2e16de5481f847b90d22e4752ffd 100644
--- a/src/events/RE/reRelativeRecruiter.js
+++ b/src/events/RE/reRelativeRecruiter.js
@@ -484,11 +484,11 @@ App.Events.RERelativeRecruiter = class RERelativeRecruiter extends App.Events.Ba
 				function applySexToy() { // either sex
 					slave.piercing.tongue.weight = 1;
 					slave.makeup = 1;
-					if (slave.balls < 4 && slave.balls > 0) {
+					if (slave.balls.isBetween(0, 4)) {
 						slave.balls = 4;
 						slave.scrotum = slave.balls;
 					}
-					if (slave.dick < 5 && slave.dick > 0) {
+					if (slave.dick.isBetween(0, 5)) {
 						slave.dick = 5;
 						slave.foreskin = slave.dick;
 					}
diff --git a/src/events/RE/reRoyalBlood.js b/src/events/RE/reRoyalBlood.js
index d3c4359ab8247aa7c977d7412af73b6643959c4d..8ceca921623800fd1ea4fd83389968a5fe8f92a3 100644
--- a/src/events/RE/reRoyalBlood.js
+++ b/src/events/RE/reRoyalBlood.js
@@ -95,7 +95,7 @@ App.Events.RERoyalBlood = class RERoyalBlood extends App.Events.BaseEvent {
 					`Purchasing the goods and hiring the VTOLs will cost about ${cashFormat(princeCost)}.`
 				));
 			} else {
-				choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave a crown prince.`));
+				choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave the crown prince.`));
 			}
 
 			if (activeSF) {
@@ -106,7 +106,7 @@ App.Events.RERoyalBlood = class RERoyalBlood extends App.Events.BaseEvent {
 						`You will be despised for this action, and trade will be greatly damaged.`
 					));
 				} else {
-					choices.push(new App.Events.Result(null, null, `You lack the necessary reputation to enslave a crown prince.`));
+					choices.push(new App.Events.Result(null, null, `You lack the necessary reputation to enslave the crown prince.`));
 				}
 			}
 
@@ -172,7 +172,7 @@ App.Events.RERoyalBlood = class RERoyalBlood extends App.Events.BaseEvent {
 				`It will cost about ${cashFormat(queenCash)} to enslave ${him3}.`
 			));
 		} else {
-			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave a Queen.`));
+			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave the Queen.`));
 		}
 
 		if (activeSF) {
@@ -183,7 +183,7 @@ App.Events.RERoyalBlood = class RERoyalBlood extends App.Events.BaseEvent {
 					`You will be despised for this action, and trade will be greatly damaged.`
 				));
 			} else {
-				choices.push(new App.Events.Result(null, null, `You lack the necessary reputation to enslave a Queen.`));
+				choices.push(new App.Events.Result(null, null, `You lack the necessary reputation to enslave the Queen.`));
 			}
 		}
 
@@ -273,7 +273,7 @@ App.Events.RERoyalBlood = class RERoyalBlood extends App.Events.BaseEvent {
 				cashX(-princessCashCost, "slaveTransfer", princess);
 				repX(-princessRepCost, "event", princess);
 			} else {
-				App.UI.DOM.appendNewElement("p", text, `Seizing a tablet, you quickly send a message to ${App.SF.SFC()}. After dark, a flight of VTOLs land in the new arcology laden with troops. When they take off again they have the princess aboard clad in chains and make a direct course towards your waiting penthouse.`);
+				App.UI.DOM.appendNewElement("p", text, `Seizing a tablet, you quickly send a message to ${App.Mods.SF.SFC()}. After dark, a flight of VTOLs land in the new arcology laden with troops. When they take off again they have the princess aboard clad in chains and make a direct course towards your waiting penthouse.`);
 				V.arcologies[0].prosperity -= 15;
 
 				// Princess
@@ -281,6 +281,7 @@ App.Events.RERoyalBlood = class RERoyalBlood extends App.Events.BaseEvent {
 			}
 			App.UI.DOM.appendNewElement("p", text, `Eventually ${he} arrives in your penthouse, the perfect image of a demure yet composed princess. ${His} clearly practiced façade of poise and grace fades under scrutiny, however. ${princessArrives()}`);
 
+			orphan(princess);
 			text.append(App.UI.newSlaveIntro(princess));
 
 			return text;
@@ -304,6 +305,7 @@ App.Events.RERoyalBlood = class RERoyalBlood extends App.Events.BaseEvent {
 
 			App.UI.DOM.appendNewElement("p", text, princeArrives());
 
+			orphan(prince);
 			text.append(App.UI.newSlaveIntro(prince));
 
 			return text;
@@ -806,6 +808,13 @@ App.Events.RERoyalBlood = class RERoyalBlood extends App.Events.BaseEvent {
 			return slave;
 		}
 
+		/** @param {App.Entity.SlaveState} slave */
+		function orphan(slave) {
+			// Remove family links from 'child' slaves acquired without their parents
+			slave.mother = 0;
+			slave.father = 0;
+		}
+
 		function queenArrives() {
 			return `Yet, it seems likely that ${his3} relief has more to do with saving ${him3} from a lifetime of gang rape at the mercy of ${his3} former subjects, than it does the familiar luxury. ${He3} submits to biometric scanning obediently and without ${(V.seePreg !== 0) ? `fuss, during which you discover to ${his3} surprise that ${he3} is pregnant. Since ${he3} hasn't begun to show yet, it's unclear whether the child is the former King's or the new arcology owner's. You don't have the means to discern the father of the child, but you notice ${he3} cradles ${his3} ever so slightly rounded stomach protectively nonetheless.` : `fuss.`}`;
 		}
diff --git a/src/events/RE/reShelterInspection.js b/src/events/RE/reShelterInspection.js
index dc6700bce58d38e9a3232a6cd0a9a74e5cc2ffa2..414f45dc6b1acb6d33dc0e2998ce6767f88b21d3 100644
--- a/src/events/RE/reShelterInspection.js
+++ b/src/events/RE/reShelterInspection.js
@@ -695,7 +695,7 @@ App.Events.REShelterInspection = class REShelterInspection extends App.Events.Ba
 							r.push(Spoken(inspectee, `"I'm a milk cow!"`));
 							r.push(`The inspector arches an eyebrow skeptically, and the slave continues,`);
 							r.push(Spoken(inspectee, `"I give milk. See?"`));
-							r.push(`${He} expresses a squirt of milk from one nipple.`);
+							r.push(`${He} expresses a squirt of ${inspectee.milkFlavor === "none" ? `` : `${inspectee.milkFlavor} flavored `}milk from one nipple.`);
 							r.push(Spoken(inspectee, `"It's a nice life. I'm much happier with my current owner, thank you."`));
 							r.push(`The inspector looks pleased, and ${say2}s ${he2}'ll put out a <span class="reputation inc">good word</span> about you.`);
 							repX(500, "event", inspectee);
diff --git a/src/events/RE/reSiblingPlease.js b/src/events/RE/reSiblingPlease.js
index 69250b756f8207303104a1d58c938c95d652b1f6..fa663935d92fcfe30c16ed8f9460299ef162fc0f 100644
--- a/src/events/RE/reSiblingPlease.js
+++ b/src/events/RE/reSiblingPlease.js
@@ -49,7 +49,7 @@ App.Events.RESiblingPlease = class RESiblingPlease extends App.Events.BaseEvent
 		t.push(`You take a moment to look at ${him}, ${canStand(dau) ? "standing" : "sitting"} there in front of your desk. ${He}'s devoted to you, willing to please you for the sake of pleasing you, rather than to avoid punishment or to make ${his} own life easier, and ${he} trusts you implicitly. With that in mind, you ask what's bothering ${him}.`);
 		t.toParagraph();
 
-		t.push(Spoken(dau, `"I...I was thinking about family, and mom. Can...can I have a little sister, ${Master}? We could do all sorts of things together!"`));
+		t.push(Spoken(dau, `"I... I was thinking about family, and mom. Can... can I have a little sister, ${Master}? We could do all sorts of things together!"`));
 		t.push(`${He} winks seductively at you, and suddenly you're thinking about all the fun things you could do with them. And with a bit of patience it's definitely workable;`, contextualIntro(dau, mom, true), `could bear ${mom.counter.births > 0 ? `another` : `a`} child for you, without a doubt.`);
 		t.toParagraph();
 
@@ -134,10 +134,10 @@ App.Events.RESiblingPlease = class RESiblingPlease extends App.Events.BaseEvent
 				t.push(`Even though ${mom.slaveName}'s sopping cunt is already dripping on the couch, you order ${dau.slaveName} to use ${his} mouth to get ${him2} ready for you, and ${he} dives in eagerly.`);
 				seX(dau, "oral", mom, "vaginal", 1);
 			} else if (mom.mpreg) {
-				t.push(`As you briefed ${him}, ${dau.slaveName} uses ${his} mouth and tongue to clean and lubricate the entrance to ${his} mother's anal womb as preparation.`);
+				t.push(`As you had directed, ${dau.slaveName} uses ${his} mouth and tongue to clean and lubricate the entrance to ${his} mother's anal womb as preparation.`);
 				seX(dau, "oral", mom, "anal", 1);
 			} else {
-				t.push(`As you briefed ${him}, ${dau.slaveName} eagerly goes down on ${his} mother's cunt, to get ${him2} good and ready for your cock.`);
+				t.push(`As you had directed, ${dau.slaveName} eagerly goes down on ${his} mother's cunt, to get ${him2} good and ready for your cock.`);
 				seX(dau, "oral", mom, "vaginal", 1);
 			}
 			if (mom.devotion > 50) {
@@ -194,7 +194,7 @@ App.Events.RESiblingPlease = class RESiblingPlease extends App.Events.BaseEvent
 				if (helping.length < 2) {
 					helping.push("so on");
 				}
-				t.push(`Meanwhile, ${dau.slaveName} "helps" any way ${he} can...running ${his} hands over both your bodies, ${toSentence(helping)}.`);
+				t.push(`Meanwhile, ${dau.slaveName} "helps" any way ${he} can... running ${his} hands over both your bodies, ${toSentence(helping)}.`);
 			}
 			t.push(`Eventually, you come deep inside ${him2}, filling ${his2}${mom.mpreg ? ` anal` : ``} womb with your seed.`);
 			t.toParagraph();
diff --git a/src/events/RECI/butthole.js b/src/events/RECI/butthole.js
index 7fffa0fb96ac8fedc8089f40a3dae0d72f4119ac..9e1ae161fe224d9157101df7e88106f63617ff3d 100644
--- a/src/events/RECI/butthole.js
+++ b/src/events/RECI/butthole.js
@@ -663,21 +663,23 @@ App.Events.RECIButthole = class RECIButthole extends App.Events.BaseEvent {
 			t.push(`before continuing.`);
 			t.push(Spoken(eventSlave, `"Well,"`));
 			t.push(`${he} ${say}s, with mock seriousness.`);
-			t.push(Spoken(eventSlave, `"Here in the arcology, we slaves eat a very special liquid diet that keeps us healthy and fit and ready to fuck. And, it's absorbed completely, so our butts are always nice and clean. That way, ${Master} can -"`));
+			t.push(Spoken(eventSlave, `"Here in the arcology, we slaves eat a very special liquid diet that keeps us healthy and fit and ready to fuck. And, it's absorbed completely, so our butts are always nice and clean. That way, ${Master} can –"`));
 			t.push(`${he} clenches ${his} sphincter`);
 			if (V.PC.dick !== 0) {
-				t.push(`around the base of your cock — "fuck`);
-			} else {
-				t.push(`against your invading fingers — "play with`);
-			}
-			t.push(Spoken(eventSlave, `our asses"`));
-			t.push(`— clench —`);
-			t.push(Spoken(eventSlave, `"whenever"`));
-			t.push(`— clench —`);
-			t.push(Spoken(eventSlave, `"${heP}"`));
-			t.push(`— clench —`);
-			t.push(Spoken(eventSlave, `"wants!"`));
-			t.push(`${He} squeals as you use your encircling arm to hoist ${his} torso up a bit higher, and mercilessly`);
+				t.push(`around the base of your cock "– fuck`);
+			} else {
+				t.push(`against your invading fingers "– play with`);
+			}
+			t.push(
+				Spoken(eventSlave, `our asses –"`),
+				`<i>clench</i>`,
+				Spoken(eventSlave, `"– whenever –"`),
+				`<i>clench</i>`,
+				Spoken(eventSlave, `"– ${heP} –"`),
+				`<i>clench</i>`,
+				Spoken(eventSlave, `"– wants!"`),
+				`${He} squeals as you use your encircling arm to hoist ${his} torso up a bit higher, and mercilessly`
+			);
 			if (V.PC.dick !== 0) {
 				t.push(`fuck`);
 			} else {
diff --git a/src/events/REFI/reBoobslut.js b/src/events/REFI/reBoobslut.js
index e579e8905aad27809c3fa521ed829096ad891792..b88b01ba877301d44fd4b097cd3e143b5f7c7495 100644
--- a/src/events/REFI/reBoobslut.js
+++ b/src/events/REFI/reBoobslut.js
@@ -53,7 +53,7 @@ App.Events.REFIBoobslut = class REFIBoobslut extends App.Events.BaseEvent {
 		} else {
 			t.push("over,");
 		}
-		t.push(`take some of ${his2} creamy, slightly vanilla-toned milk straight from the source. Every time you do, ${he2} shudders convulsively,`);
+		t.push(`take some of ${his2} creamy, ${subSlave.milkFlavor === "none" ? `` : `${subSlave.milkFlavor} flavored `}milk straight from the source. Every time you do, ${he2} shudders convulsively,`);
 		if (canTalk(subSlave)) {
 			t.push(`giving little mewling whimpers.`);
 		} else {
diff --git a/src/events/REFS/refsBaronDemand.js b/src/events/REFS/refsBaronDemand.js
index 572313e8be923a27e73ab724bdb1749d3092c575..ae728607266315918e6f9d6a0b8bd1d99c50ef98 100644
--- a/src/events/REFS/refsBaronDemand.js
+++ b/src/events/REFS/refsBaronDemand.js
@@ -16,17 +16,17 @@ App.Events.refsBaronDemand = class refsBaronDemand extends App.Events.BaseEvent
 
 		const choices = [];
 		if (V.cash >= costYes) {
-			choices.push(new App.Events.Result(`Accept their conditions as a show of good faith`, accept, cashFormat(costYes)));
+			choices.push(new App.Events.Result(`Accept their conditions as a show of good faith`, accept, `Will cost ${cashFormat(costYes)}`));
 		}
 		choices.push(new App.Events.Result(`Flat out refuse them`, refuse));
 		if (V.cash >= costGifts) {
-			choices.push(new App.Events.Result(`Refuse their demands, but placate them with gifts and ceremonies`, gifts, cashFormat(costGifts)));
+			choices.push(new App.Events.Result(`Refuse their demands, but placate them with gifts and ceremonies`, gifts, `Will cost ${cashFormat(costGifts)}`));
 		}
 		App.Events.addResponses(node, choices);
 
 		function accept() {
 			repX(2000, "event");
-			cashX(-costYes, "Baron demands");
+			cashX(-costYes, "event");
 			return `You gracefully accept the demands of your Barons, granting them a number of minor new rights and increasing their luxurious Imperial stipends further. Predictably, the Barons are <span class="reputation inc">overjoyed</span> at your flat acceptance, and shower you with praise and compliments for a few days before returning to the management of their now wealthier districts, enriched at the <span class="cash dec">expense of your treasury.</span>`;
 		}
 
@@ -37,7 +37,7 @@ App.Events.refsBaronDemand = class refsBaronDemand extends App.Events.BaseEvent
 		}
 
 		function gifts() {
-			cashX(-costGifts, "Trinkets and entertainment for the Barons");
+			cashX(-costGifts, "event");
 			return `You invite the Barons to a party at your penthouse, informing them of your refusal of the petition over expensive wines and foreign slavegirl entertainment brought in for the evening's amusement. Although the pompous Barons do sulk somewhat at your refusal, the free drink and girls is more than enough to distract even these wealthy intellectuals, and the whole notion of additional Baron privileges is forgotten over the course of one drunken, <span class="cash dec">expensive</span> celebration.`;
 		}
 	}
diff --git a/src/events/REFS/refsDeadBaron.js b/src/events/REFS/refsDeadBaron.js
index 84d4ca0dc77587866a22788d6b8937bcb4e5c1e7..3d444f4f625b24503e83f0d6d3c5c987fe6d0984 100644
--- a/src/events/REFS/refsDeadBaron.js
+++ b/src/events/REFS/refsDeadBaron.js
@@ -29,7 +29,7 @@ App.Events.refsDeadBaron = class refsDeadBaron extends App.Events.BaseEvent {
 			V.arcologies[0].prosperity -= 1;
 			cashX(-2000, "Costs of Administrative Change");
 			repX(-2000, "event");
-			return `You select one of your loyal executives, an ultra-wealthy trader within the arcology who made a fortune in the sale of human bodies, for the new Barony. The man, a portly and unintimidating man that hides a razor-sharp mind behind his fat and an expensive suit, smiles full of teeth as you announce your decision to a waiting crowd of elites. After you go through the formalities and hand him the golden band that'll represent his symbol of office, he shakes your hand vigorously, still smiling devilishly. The furious baronets, robbed of their title, do their best to obstruct the ceremony, and the decision to take the title from their family causes <span class="reputation dec">fear and concern</span> amongst Barons now insecure of their family's future. The next day, the newly-appointed Baron sends you a platter of expensive gifts and foreign candies, complimented with a <span class="cash inc">massive direct deposit to your bank account.</span> You can't help but feel that such a crafty fox might use his new power to <span class="prosperity dec">corner the market</span> in his barony, though.`;
+			return `You select one of your loyal executives, an ultra-wealthy trader within the arcology who made a fortune in the sale of human bodies, for the new Barony. The man, a portly and unintimidating man that hides a razor-sharp mind behind his fat and an expensive suit, smiles full of teeth as you announce your decision to a waiting crowd of elites. After you go through the formalities and hand him the golden band that will represent his symbol of office, he shakes your hand vigorously, still smiling devilishly. The furious baronets, robbed of their title, do their best to obstruct the ceremony, and the decision to take the title from their family causes <span class="reputation dec">fear and concern</span> amongst Barons now insecure of their family's future. The next day, the newly-appointed Baron sends you a platter of expensive gifts and foreign candies, complimented with a <span class="cash inc">massive direct deposit to your bank account.</span> You can't help but feel that such a crafty fox might use his new power to <span class="prosperity dec">corner the market</span> in his barony, though.`;
 		}
 
 		function bureaucrat() {
diff --git a/src/events/REFS/refsFeast.js b/src/events/REFS/refsFeast.js
index 0e91087a5bd04ba4b08c90a8110c9ebbd95f3cb0..483932720a2d78834a54a975a0bab40e6f70cb7d 100644
--- a/src/events/REFS/refsFeast.js
+++ b/src/events/REFS/refsFeast.js
@@ -37,9 +37,9 @@ App.Events.refsFeast = class refsFeast extends App.Events.BaseEvent {
 
 		App.Events.drawEventArt(node, slave);
 
-		App.Events.addParagraph(node, [`Although you regularly host casual parties in ${V.arcologies[0].name}, the demands of the elite nobility, those chosen few who stand above even your millionaires and societal elites, can be truly extravagant. Every once in a while, instead of a simple, classy party, they clamor for something more - a proper feast. As the Emperor of the arcology, it falls to you to organize such an event, and plan it to satisfy even the ravenous appetites of your ever-hungry Barons.`]);
+		App.Events.addParagraph(node, [`Although you regularly host casual parties in ${V.arcologies[0].name}, the demands of the elite nobility, those chosen few who stand above even your millionaires and societal elites, can be truly extravagant. Every once in a while, instead of a simple, classy party, they clamor for something more – a proper feast. As the Emperor of the arcology, it falls to you to organize such an event, and plan it to satisfy even the ravenous appetites of your ever-hungry Barons.`]);
 
-		App.Events.addParagraph(node, [`Planning a genuine feast is no small task. Unlike your typical parties, which can be as simple as preparing food and drinks served by your own slavegirls, this celebration almost by necessity must be an enormous blowout. The Barons will come expecting delicacies from around the world, enough alcohol to get all of them drunk ten times over, foreign slaves and entertainment for the night, and a truly decadent level of indulgence, one befitting of an assembly of rulers. The greatest celebrations can go on for full days at a time, stopped only to sleep before returning to the festivities. Although such lavishness can be crushingly expensive, the best feasts are more than just the best time anyone can have in the Free Cities - they're also calendar events remembered for years to come.`]);
+		App.Events.addParagraph(node, [`Planning a genuine feast is no small task. Unlike your typical parties, which can be as simple as preparing food and drinks served by your own slavegirls, this celebration almost by necessity must be an enormous blowout. The Barons will come expecting delicacies from around the world, enough alcohol to get all of them drunk ten times over, foreign slaves and entertainment for the night, and a truly decadent level of indulgence, one befitting of an assembly of rulers. The greatest celebrations can go on for full days at a time, stopped only to sleep before returning to the festivities. Although such lavishness can be crushingly expensive, the best feasts are more than just the best time anyone can have in the Free Cities – they're also calendar events remembered for years to come.`]);
 
 		const enormousCash = 20000;
 		const moderateCash = 5000;
@@ -58,14 +58,14 @@ App.Events.refsFeast = class refsFeast extends App.Events.BaseEvent {
 		function enormous() {
 			repX(7000, "event");
 			V.arcologies[0].prosperity -= 1;
-			cashX(-enormousCash, "Feasting");
+			cashX(-enormousCash, "event");
 			return `The feast you organize would put Norse raiders and ancient Kings alike to shame; you <span class="cash dec">spend more money</span> in the first few days of planning than most of them would have ever seen in their lives. The Barons arrive at your penthouse on time and are immediately mystified by the overwhelming variety of foods put out on your eloquent tables, served by stunning girls in thin silks that barely conceal their perfect bodies. Entertainers of every stripe lead around flaming swords and well-trained lions, transforming your penthouse into a temporary circus of debauchery and hedonism; there are so many that you can't even remember all those you hired, and every room contains a new wonder or waiting beauty. You deliver a short speech to the Barons, Knights, and other elite you've granted the honor of attending, welcoming the lot to your home; one of your Barons claps loudly the moment you finish and <span class="reputation inc">shouts your name</span> in celebration, which is quickly taken up by the rest of the room. From then on, the next few days are an absolute blur of sex, drink, drugs and food, casting aside all worries and indulging alongside the wealthiest of your arcology in a true display of ultra-hedonism. The hours blend into days of the endless celebration you've organized, until, finally, the Barons and Knights begin to shuffle out in a drunken, exhausted haze, leaving behind a trail of bones and knocked-up slavegirls. No one, yourself included, seems to be able to remember exactly what happened during those days of wild celebration, but everyone agrees that it was <span class="prosperity inc">one of the greatest parties ever held in the Free Cities.</span>`;
 		}
 
 		function moderate() {
-			cashX(-moderateCash, "Feasting");
+			cashX(-moderateCash, "event");
 			repX(2000, "event");
-			return `There's no special cause for celebration this time around, but that doesn't mean you can't have a great time. You lay out platters of expensive food and drink, served by gorgeous maids, for the arriving Barons and Knights, who seem universally pleased to have an opportunity to forget the troubles of rulership and power for a day - not that that's particularly difficult in the Free Cities, anyway. Among the roaring company of ${V.arcologies[0].name}'s wealthiest and most influential citizens, you tear into fresh-cooked meats and the rounded asses of the servants alike, in a glorious celebration where nothing and no one is off-limits. At the end of the evening, when the crowd has finally had their fill and you've fucked and drank enough that you can barely stand to wave them goodbye, nearly each and every Baron leaves the celebration with a <span class="reputation inc">stupid, drunken smile across their face.</span>`;
+			return `There's no special cause for celebration this time around, but that doesn't mean you can't have a great time. You lay out platters of expensive food and drink, served by gorgeous maids, for the arriving Barons and Knights, who seem universally pleased to have an opportunity to forget the troubles of rulership and power for a day – not that that's particularly difficult in the Free Cities, anyway. Among the roaring company of ${V.arcologies[0].name}'s wealthiest and most influential citizens, you tear into fresh-cooked meats and the rounded asses of the servants alike, in a glorious celebration where nothing and no one is off-limits. At the end of the evening, when the crowd has finally had their fill and you've fucked and drank enough that you can barely stand to wave them goodbye, nearly each and every Baron leaves the celebration with a <span class="reputation inc">stupid, drunken smile across their face.</span>`;
 		}
 
 		function refuse() {
diff --git a/src/events/REFS/refsRomanStoicism.js b/src/events/REFS/refsRomanStoicism.js
index a0bcbdc2181d487e1c329ce1ff2ea84c5a627fd4..747c358f58487f37bfa2a27898ddc6c3d6a0652c 100644
--- a/src/events/REFS/refsRomanStoicism.js
+++ b/src/events/REFS/refsRomanStoicism.js
@@ -9,7 +9,7 @@ App.Events.refsRomanStoicism = class refsRomanStoicism extends App.Events.BaseEv
 	execute(node) {
 		const cost = 3000;
 
-		App.Events.addParagraph(node, [`Reviving the ancient Roman civilization in ${V.arcologies[0].name} was a turning point for many of your citizens. At first they only wore togas and stolas to cosplay in their kinky games with their spouse and slaves. But with patience and money, you managed to show them the true meaning of pursuing the vision of a new Rome. You transformed a group of slavers and opportunists into a city of patriotic citizens ready to defend their home and their newfound culture. For your wealthiest peers, choosing the Roman way of life included philosophizing like one. As such they studied stoicism and created a new version fitting of this renewed Roman era. Those dedicated stoics even bought slaves to teach them then philosophize with them.`]);
+		App.Events.addParagraph(node, [`Reviving the ancient Roman civilization in ${V.arcologies[0].name} was a turning point for many of your citizens. At first they only wore togas and stolas to cosplay in their kinky games with their spouse and slaves. But with patience and money, you managed to show them the true meaning of pursuing the vision of a new Rome. You transformed a group of slavers and opportunists into a city of patriotic citizens ready to defend their home and their newfound culture. For your wealthiest peers, choosing the Roman way of life included philosophizing like one. As such they studied stoicism and created a new version fitting of this renewed Roman era. Those dedicated stoics even bought slaves to teach them, then philosophize with them.`]);
 
 		App.Events.addParagraph(node, [`While strolling on a market plaza, you stumble upon a group of citizens listening to one of those stoicism philosophers. But unlike your well-known wealthy thinkers, this stoic and his audience all appear to be poor citizens. Some of his listeners looked even poorer and more desperate. They're terrified of their ineluctable enslavement caused by debts and in need of advice. Or at least in need of hope.`]);
 
diff --git a/src/events/REFS/refsYouthPreferentialistEncounter.js b/src/events/REFS/refsYouthPreferentialistEncounter.js
index 22cb600bd74a09fd08dc407b1733a6bd74221b6e..602ade45ac05463e7c5fcbce119182850de3f80c 100644
--- a/src/events/REFS/refsYouthPreferentialistEncounter.js
+++ b/src/events/REFS/refsYouthPreferentialistEncounter.js
@@ -37,7 +37,7 @@ App.Events.refsYouthPreferentialistEncounter = class refsYouthPreferentialistEnc
 		const choices = [];
 		choices.push(new App.Events.Result(`Let them pass`, ignore));
 		if (V.cash >= cost) {
-			choices.push(new App.Events.Result(`Fuck ${him} over dinner`, pay, `This will cost ${cashFormat(cost)}.`));
+			choices.push(new App.Events.Result(`Fuck ${him} over dinner`, pay, `This will cost ${cashFormat(cost)}`));
 		} else {
 			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to take ${him} on a date.`));
 		}
diff --git a/src/events/RESS/arcadeSadist.js b/src/events/RESS/arcadeSadist.js
index d589c641919aedd4769fff7e7859d5e9fd0b5877..d0fe05d609dfd495846a1aa95e1e12af00e872a7 100644
--- a/src/events/RESS/arcadeSadist.js
+++ b/src/events/RESS/arcadeSadist.js
@@ -29,6 +29,7 @@ App.Events.RESSArcadeSadist = class RESSArcadeSadist extends App.Events.BaseEven
 			He, he, his, him, himself, girl
 		} = getPronouns(eventSlave);
 		const {title: Master, say} = getEnunciation(eventSlave);
+		const hasSight = canSee(eventSlave);
 
 		let artDiv = document.createElement("div"); // named container so we can replace it later
 		App.Events.drawEventArt(artDiv, eventSlave);
@@ -104,12 +105,7 @@ App.Events.RESSArcadeSadist = class RESSArcadeSadist extends App.Events.BaseEven
 			} else {
 				r.push(`Once you've led ${him}`);
 			}
-			r.push(`in there, ${he} stops and`);
-			if (canSee(eventSlave)) {
-				r.push(`watches`);
-			} else {
-				r.push(`listens`);
-			}
+			r.push(`in there, ${he} stops and ${hasSight ? 'watches' : 'listens'}`);
 			if (V.PC.belly >= 100000 || V.PC.weight > 130) {
 				r.push(r.pop() + `as you struggle to join ${him} in the increasingly cramped space.`);
 			} else if (V.PC.belly >= 5000) {
@@ -198,12 +194,7 @@ App.Events.RESSArcadeSadist = class RESSArcadeSadist extends App.Events.BaseEven
 				} else {
 					r.push(`steadily pushing ${himself} along,`);
 				}
-				if (canSee(eventSlave)) {
-					r.push(`staring at`);
-				} else {
-					r.push(`facing`);
-				}
-				r.push(`you with a profound look of mixed <span class="trust inc">trust for your understanding of ${his} horrible sadism,</span> and deep unease that this is what truly gets ${him} off.`);
+				r.push(`${hasSight ? 'staring at' : 'facing'} you with a profound look of mixed <span class="trust inc">trust for your understanding of ${his} horrible sadism,</span> and deep unease that this is what truly gets ${him} off.`);
 				eventSlave.trust += 5;
 				return r;
 			}
@@ -217,19 +208,9 @@ App.Events.RESSArcadeSadist = class RESSArcadeSadist extends App.Events.BaseEven
 				App.Events.drawEventArt(artDiv, [eventSlave, randomArcadeSlave], [eventSlave.clothes, "no clothing"]);
 
 				r.push(`${He} seems to be focusing on the purely physical aspects of the degradation here. The true meaning of this place is so much more, and you decide to share it with ${him}. You call ${his} name, tearing ${his} attention away from the spectacle mere`);
-				if (V.showInches === 2) {
-					r.push(`inches`);
-				} else {
-					r.push(`centimeters`);
-				}
-				r.push(`over your heads, and`);
-				if (canSee(eventSlave)) {
-					r.push(`point`);
-				} else {
-					r.push(`direct ${him}`);
-				}
+				r.push(`${V.showInches === 2 ? 'inches' : 'centimeters'} over your heads, and ${hasSight ? 'point' : `direct ${him}`}`);
 				r.push(`to a particular slave. You tell ${eventSlave.slaveName} that this particular Arcade inmate's name is ${SlaveFullName(randomArcadeSlave)}.`);
-				if (randomArcadeSlave.career !== 0) {
+				if (randomArcadeSlave.career !== "a slave") {
 					r.push(`You tell ${him} that ${he2} is ${randomArcadeSlave.actualAge} years old, that ${he2} is ${randomArcadeSlave.nationality}, and that ${he2} was once ${convertCareer(randomArcadeSlave)}.`);
 				} else {
 					r.push(`You tell ${him} that ${he2} is ${randomArcadeSlave.actualAge} years old and ${randomArcadeSlave.nationality}.`);
@@ -251,12 +232,7 @@ App.Events.RESSArcadeSadist = class RESSArcadeSadist extends App.Events.BaseEven
 				} else {
 					r.push(`orgasming.`);
 				}
-				r.push(`${He} came without being touched. ${He}`);
-				if (canSee(eventSlave)) {
-					r.push(`stares at`);
-				} else {
-					r.push(`faces`);
-				}
+				r.push(`${He} came without being touched. ${He} ${hasSight ? 'stares at' : 'faces'}`);
 				r.push(`the mess ${he} made just by being in the presence of the arcology's <span class="devotion inc">undisputed preeminent sadist;</span> ${he} shudders at the sheer gothic glory of it. ${He} has a new moment to think of when ${he} feels like <span class="fetish inc">indulging ${his} own sadism.</span>`);
 				eventSlave.devotion += 5;
 				eventSlave.fetishStrength = Math.clamp(eventSlave.fetishStrength + 10, 0, 100);
diff --git a/src/events/RESS/devotedNympho.js b/src/events/RESS/devotedNympho.js
index 12f57da096ecafc4d64573e35c668ceb04672339..c44a7b9d37b6ef65b74da5639b88c67a89ebc574 100644
--- a/src/events/RESS/devotedNympho.js
+++ b/src/events/RESS/devotedNympho.js
@@ -152,12 +152,12 @@ App.Events.RESSDevotedNympho = class RESSDevotedNympho extends App.Events.BaseEv
 			} else {
 				r.push(`gush`);
 			}
-			r.push(`of milk issuing from both of ${his} nipples.`);
+			r.push(`of ${milkFlavor(eventSlave)}milk issuing from both of ${his} nipples.`);
 			eventSlave.lactationDuration = 2;
 			eventSlave.boobs -= eventSlave.boobsMilk;
 			eventSlave.boobsMilk = 0;
 		} else if (eventSlave.lactation > 0) {
-			r.push(`drops of milk`);
+			r.push(`drops of ${milkFlavor(eventSlave)}milk`);
 			if (eventSlave.nipples !== "fuckable") {
 				r.push(`appearing at each of ${his} motherly nipples only to be flung onto the floor.`);
 			} else {
diff --git a/src/events/RESS/hotPC.js b/src/events/RESS/hotPC.js
index 6251ca9acb960cc4cdae83b2aa1120ad42f1fe8a..395abc33de7fd1f3d96dd3fe50e61afa2e97d591 100644
--- a/src/events/RESS/hotPC.js
+++ b/src/events/RESS/hotPC.js
@@ -6,6 +6,7 @@ App.Events.RESSHotPC = class RESSHotPC extends App.Events.BaseEvent {
 	actorPrerequisites() {
 		return [
 			[ // single event slave
+				s => s.fetish !== "mindbroken",
 				s => s.energy > 40,
 				s => s.devotion > 0 && s.devotion <= 50,
 				s => s.trust >= -50,
diff --git a/src/events/RESS/injectionsPlease.js b/src/events/RESS/injectionsPlease.js
index 6a51805d262516031b53ead1078ea811b44b5462..3dd77c759fe8e787cded564e976f20ba6a6dbd5d 100644
--- a/src/events/RESS/injectionsPlease.js
+++ b/src/events/RESS/injectionsPlease.js
@@ -174,7 +174,7 @@ App.Events.RESSInjectionsPlease = class RESSInjectionsPlease extends App.Events.
 						possibleDrugs.push({type: "dickMinus", text: `hormones to shrink my dick? I don't need a big dick to get fucked, ${Master}. I don't want to intimidate anyone who might use me.`});
 					}
 					if (eventSlave.balls > 1 && V.arcologies[0].FSSlimnessEnthusiastResearch === 1) {
-						possibleDrugs.push({type: "ballsMinus", text: `hormones to shrink my balls? I don't need to cum buckets while getting fucked, ${Master}. I don't want to out do anyone who might use me.`});
+						possibleDrugs.push({type: "ballsMinus", text: `hormones to shrink my balls? I don't need to cum buckets while getting fucked, ${Master}. I don't want to outdo anyone who might use me.`});
 					}
 					if (eventSlave.butt < 9) {
 						possibleDrugs.push({type: "butt", text: `ass growth drugs? I want whoever's fucking me to have plenty of cushion to push into.`});
diff --git a/src/events/RESS/lazyEvening.js b/src/events/RESS/lazyEvening.js
index 3f1dd22e11506255c3862dadfa998b4d335a866d..64703d90c07ce8fb25c1bd300be3e3199a8e58dc 100644
--- a/src/events/RESS/lazyEvening.js
+++ b/src/events/RESS/lazyEvening.js
@@ -94,7 +94,7 @@ App.Events.RESSLazyEvening = class RESSLazyEvening extends App.Events.BaseEvent
 			} else {
 				t.push(`from ${his} chest`);
 			}
-			t.push(`strains the soft pajama top to it's breaking point.`);
+			t.push(`strains the soft pajama top to its breaking point.`);
 		} else if (eventSlave.intelligence+eventSlave.intelligenceImplant > 50) {
 			t.push(`As a clever ${girl}, ${his} simple${eventSlave.belly >= 5000 ? `, yet tight around the middle,` : ""} summer dress evokes memories of bygone warm weather days at elite old world colleges — and the sexual conquest of their youthful residents.`);
 		} else if (eventSlave.muscles > 30) {
@@ -243,7 +243,7 @@ App.Events.RESSLazyEvening = class RESSLazyEvening extends App.Events.BaseEvent
 			let t = [];
 			t.push(`Though there is no shortage of torments you inflict during the course of your day to day life as an arcology owner, there is something refreshing about torturing a slave out of idle boredom rather than corrective disciple or sexual domination. Your night is filled with ${eventSlave.voice === 0 ? "the horrible rasping that a mute throat substitutes for cries of agony" : "echoing shrieks of anguish"}, though every vocal outburst is idly punished with electro shock or strike of the whip. Come the morning, ${eventSlave.slaveName}`);
 			if (eventSlave.fetish === "masochist") {
-				t.push(`is mortified by the intensity of ${his} orgasms that night,<span class="devotion inc">and more convinced than ever that ${he}'s a pain slut,</span> and yet`);
+				t.push(`is mortified by the intensity of ${his} orgasms that night, <span class="devotion inc">and more convinced than ever that ${he}'s a pain slut,</span> and yet`);
 				eventSlave.devotion += 4;
 			}
 			t.push(`<span class="trust dec">scuttles away to tend to the bruises and marks that litter ${his} battered body.</span>`);
diff --git a/src/events/RESS/milkgasm.js b/src/events/RESS/milkgasm.js
index 88ad47bd72e15355bf64518fc573b6ec42f4162d..f42a81e954552613d4811be0594488d6d28b7598 100644
--- a/src/events/RESS/milkgasm.js
+++ b/src/events/RESS/milkgasm.js
@@ -39,7 +39,7 @@ App.Events.RESSMilkgasm = class RESSMilkgasm extends App.Events.BaseEvent {
 		}
 		r.push(`Any more than that, and ${he} gets painfully sore; any less than that, and`);
 		if (eventSlave.nipples === "inverted" || eventSlave.nipples === "fuckable") {
-			r.push(`${his} milk, backed up behind ${his} ${eventSlave.nipples} nipples, leaves ${him} in agony.`);
+			r.push(`${his} ${milkFlavor(eventSlave)}milk, backed up behind ${his} ${eventSlave.nipples} nipples, leaves ${him} in agony.`);
 		} else {
 			r.push(`${he} begins to spontaneously squirt cream whenever ${his} breasts are subjected to the slightest motion.`);
 		}
@@ -79,7 +79,7 @@ App.Events.RESSMilkgasm = class RESSMilkgasm extends App.Events.BaseEvent {
 		if (eventSlave.nipples === "inverted") {
 			r.push(`wincing`);
 		} else {
-			r.push(`dribbling a little milk`);
+			r.push(`dribbling a little bit of ${milkFlavor(eventSlave)}milk`);
 		}
 		r.push(`as ${he} goes. The other way, ${he} has a distinctly relieved expression and ${his} breasts are much saggier.`);
 
@@ -143,7 +143,7 @@ App.Events.RESSMilkgasm = class RESSMilkgasm extends App.Events.BaseEvent {
 				r.push(`instead as ${he} bucks and grinds against the chair.`);
 				r.push(VCheck.Anal(eventSlave, 1));
 			}
-			r.push(`When ${he} comes, the milkers detect ${his} orgasm to your fucking and shunt the milk into different reservoirs. Though you've never been able to taste much difference, there's a belief out there that 'milk-cum', the squirts of milk a slave milk ${girl} produces when climaxing with ${his} ${getWrittenTitle(eventSlave)}, have special aphrodisiac powers. <span class="cash inc">It can be sold at a special premium.</span> Naturally, <span class="devotion inc">${his} devotion to you has also increased.</span>`);
+			r.push(`When ${he} comes, the milkers detect ${his} orgasm to your fucking and shunt the ${milkFlavor(eventSlave)}milk into different reservoirs. Though you've never been able to taste much difference, there's a belief out there that 'milk-cum', the squirts of milk a slave milk ${girl} produces when climaxing with ${his} ${getWrittenTitle(eventSlave)}, have special aphrodisiac powers. <span class="cash inc">It can be sold at a special premium.</span> Naturally, <span class="devotion inc">${his} devotion to you has also increased.</span>`);
 			cashX(100, "event", eventSlave);
 			eventSlave.devotion += 4;
 			return r;
@@ -170,13 +170,13 @@ App.Events.RESSMilkgasm = class RESSMilkgasm extends App.Events.BaseEvent {
 				} else {
 					r.push(`child's`);
 				}
-				r.push(`kicking is forcing milk out of ${his} swollen breasts.`);
+				r.push(`kicking is forcing ${milkFlavor(eventSlave)}milk out of ${his} swollen breasts.`);
 			}
-			r.push(`Eventually, the slight rising and falling of ${his} ribcage as ${he} inhales and exhales induces enough motion in ${his} overfull breasts that milk spurts out of ${him} with each breath. Satisfied that ${he}'s ready, you`);
+			r.push(`Eventually, the slight rising and falling of ${his} ribcage as ${he} inhales and exhales induces enough motion in ${his} overfull breasts that ${milkFlavor(eventSlave)}milk spurts out of ${him} with each breath. Satisfied that ${he}'s ready, you`);
 			if (V.PC.dick === 0) {
 				r.push(`don a strap-on and`);
 			}
-			r.push(`lead the whimpering, dripping slave out to a public street. Here, you hold ${him} upright so you can fuck ${him} standing. When ${he} finally comes through the pain of ${his} overfull udders, you reach forward and squeeze ${him} so that ${he} ${!canTalk(eventSlave) ? "silently" : ""} screams in pain and relief, spraying jets of milk. ${He} continually aftershock orgasms as you continue pounding. You offer ${his} breasts to the growing crowd, many of whom come forward to taste ${his} cream.`);
+			r.push(`lead the whimpering, dripping slave out to a public street. Here, you hold ${him} upright so you can fuck ${him} standing. When ${he} finally comes through the pain of ${his} overfull udders, you reach forward and squeeze them. Making ${him} ${!canTalk(eventSlave) ? "silently" : ""} scream in pain and relief as ${he} sprays jets of ${milkFlavor(eventSlave)}milk. ${He} continually experiences aftershock orgasms as you continue pounding. You offer ${his} breasts to the growing crowd, many of whom come forward to taste ${his} cream.`);
 			if (!canDoVaginal(eventSlave)) {
 				r.push(`You fuck ${his} butt until they've sucked ${him} empty.`);
 				r.push(VCheck.Anal(eventSlave, 1));
@@ -294,7 +294,7 @@ App.Events.RESSMilkgasm = class RESSMilkgasm extends App.Events.BaseEvent {
 			} else {
 				r.push(`opened,`);
 			}
-			r.push(`the milk begins to jet out of ${him} in a pair of uninterrupted streams. ${He} collapses forward onto ${his} face, crying with relief as the pain in ${his} breasts recedes. As it does, ${he} finally begins to notice`);
+			r.push(`the ${milkFlavor(eventSlave)}milk begins to jet out of ${him} in a pair of uninterrupted streams. ${He} collapses forward onto ${his} face, crying with relief as the pain in ${his} breasts recedes. As it does, ${he} finally begins to notice`);
 			if (canDoAnal(eventSlave)) {
 				r.push(`the pain in ${his} backdoor as you continue to abuse`);
 				if (eventSlave.anus === 0) {
diff --git a/src/events/RESS/nightVisit.js b/src/events/RESS/nightVisit.js
index 08e402ce053ce14759a50dda2b7e82513fb5be9f..832643f8765c2880baeabd7918f33ae5054eae31 100644
--- a/src/events/RESS/nightVisit.js
+++ b/src/events/RESS/nightVisit.js
@@ -137,7 +137,7 @@ App.Events.RESSNightVisit = class RESSNightVisit extends App.Events.BaseEvent {
 				r.push(eventSlave.race);
 			}
 			r.push(`pussy to the limit of what you can get away with without damaging ${him}.`);
-			if (((eventSlave.fetish === "submissive" && eventSlave.fetishStrength > 60) || (eventSlave.energy > 95)) && (eventSlave.fetishKnown === 1)) {
+			if (((eventSlave.fetish === "submissive" && (eventSlave.fetishStrength > 60 || eventSlave.energy > 95))) && (eventSlave.fetishKnown === 1)) {	// TODO: .energy should behave differently
 				r.push(`${He}'s such a submissive that after a while pleasure overwhelms pain to the extent that ${he} manages a <span class="devotion inc">sobbing orgasm.</span>`);
 			} else {
 				r.push(`${He} gets the message: ${he}'s your property and ${his} desires are entirely subject to your will. ${His} <span class="devotion inc">submission</span> to you and <span class="trust inc">fear of you</span> have both increased.`);
diff --git a/src/events/RESS/review/ampDevoted.js b/src/events/RESS/review/ampDevoted.js
index f6c13199541622ec886ae1611e472572942367fa..cf7bfaf93406001ff9ddd25bc4652d225df91798 100644
--- a/src/events/RESS/review/ampDevoted.js
+++ b/src/events/RESS/review/ampDevoted.js
@@ -29,7 +29,7 @@ App.Events.RESSAmpDevoted = class RESSAmpDevoted extends App.Events.BaseEvent {
 		r.push(`looking like the neglected`);
 		if (eventSlave.belly >= 600000) {
 			if (eventSlave.bellyPreg > 0) {
-				r.push(`baby filled womb`);
+				r.push(`baby-filled womb`);
 			} else {
 				r.push(`overinflated sex toy`);
 			}
diff --git a/src/events/RESS/review/backStretch.js b/src/events/RESS/review/backStretch.js
index c9b5c4c243c2160526244fd34bd3e17c3b5bd756..653d133de17d14071dfd2c11aa03fb635de0099a 100644
--- a/src/events/RESS/review/backStretch.js
+++ b/src/events/RESS/review/backStretch.js
@@ -463,7 +463,7 @@ App.Events.RESSBackStretch = class RESSBackStretch extends App.Events.BaseEvent
 				default:
 					r.push(`pulling ${his} soft nipple and some of the areolae around it into your mouth.`);
 			}
-			r.push(`${His} rich milk begins to flow across your tongue, creamy and with a hint of vanilla. ${He} breathes faster and faster as ${he} becomes aroused, but then the stimulation peaks. You keep drinking from ${him}, making no move to stop nursing and start fucking ${him}. ${He} sighs with sudden contentment, realizing that you're going to drink every drop ${he} has, and ${his} sudden relaxation sends a little extra gush of milk into your mouth. ${He} <span class="devotion inc">definitely enjoys the experience,</span> leaning back compliantly as you drain that breast and then ${his} left one, too.`);
+			r.push(`${His} rich ${milkFlavor(eventSlave)}milk begins to flow across your tongue. ${He} breathes faster and faster as ${he} becomes aroused, but then the stimulation peaks. You keep drinking from ${him}, making no move to stop nursing and start fucking ${him}. ${He} sighs with sudden contentment, realizing that you're going to drink every drop ${he} has, and ${his} sudden relaxation sends a little extra gush of ${milkFlavor(eventSlave)}milk into your mouth. ${He} <span class="hotpink">definitely enjoys the experience,</span> leaning back compliantly as you drain that breast and then ${his} left one, too.`);
 			if (eventSlave.boobs > 25000 || (eventSlave.boobs > 10000 && eventSlave.lactation > 1)) {
 				r.push(`Your clothes feel tight around your middle for the rest of the day; you may have indulged a little too much.`);
 			}
diff --git a/src/events/RESS/review/birthdaySex.js b/src/events/RESS/review/birthdaySex.js
new file mode 100644
index 0000000000000000000000000000000000000000..199d4d1db2946e581ecc86a6b7e9a27b2291d166
--- /dev/null
+++ b/src/events/RESS/review/birthdaySex.js
@@ -0,0 +1,119 @@
+App.Events.RESSBirthdaySex = class RESSBirthdaySex extends App.Events.BaseEvent {
+	actorPrerequisites() {
+		return [[
+			s => s.fetish !== "mindbroken",
+			s => s.devotion > 50,
+			s => s.trust > 50,
+			s => s.birthWeek >= 51,
+			s => canWalk(s),
+			s => canTalk(s),
+		]];
+	}
+
+	execute(node) {
+		const [eventSlave] = this.actors.map(a => getSlave(a));
+		const {
+			He,
+			he, his, him, girl,
+		} = getPronouns(eventSlave);
+		const vaginal = canDoVaginal(eventSlave);
+		const isAnalVirgin = (canDoAnal(eventSlave) && eventSlave.anus === 0);
+		const isVirgin = isAnalVirgin || (vaginal && eventSlave.vagina === 0);
+
+		App.Events.drawEventArt(node, eventSlave);
+
+		App.Events.addParagraph(node, [
+			`Your assistant interrupts your work one afternoon to inform you that`,
+			App.UI.DOM.slaveDescriptionDialog(eventSlave),
+			`has arrived to make an unscheduled visit. You can tell ${he}'s nervous, and after a few false starts, ${he} finally musters up the courage to ask what ${he} came to ask.`,
+		]);
+
+		App.Events.addParagraph(node, [
+			Spoken(eventSlave, `"${capFirstChar(getWrittenTitle(eventSlave))},"`),
+			`${he} says.`,
+			Spoken(eventSlave, `"Today is my birthday."`),
+			`A quick glance down at your desk confirms that it is, indeed, ${his} birthday.`,
+			Spoken(eventSlave, `"It's tradition to give gifts to people celebrating their birthdays in the old world,"`),
+			`${he} continues,`,
+			Spoken(eventSlave, `"but gifts and cash are useless to us slaves. Would you please help me celebrate my birthday and ${isVirgin ? `pop my ${!vaginal ? `anal` : ``} cherry` : `fuck me`}?"`),
+		]);
+
+		App.Events.addResponses(node, [
+			new App.Events.Result(`Oblige`, oblige, isAnalVirgin || isVirgin ? `This option will take ${his} ${!vaginal ? `anal` : ``} virginity` : null),
+			new App.Events.Result(`Put ${him} in ${his} place`, rape, isAnalVirgin || isVirgin ? `This option will take ${his} ${!vaginal ? `anal` : ``} virginity` : null),
+			new App.Events.Result(`You have better things to do`, no),
+		]);
+
+		function oblige() {
+			const frag = new DocumentFragment();
+			const r = [];
+			r.push(
+				`The work you were previously doing isn't particularly pressing, and one of your slave${girl}s throwing themselves at you begging for sex is a good distraction as any. You stand up and extend a hand, then lead ${him} to your bedchambers. After a fair bit of foreplay focused primarily on ${him} (this is your gift, after all), you lay ${him} on ${his} back and slowly push your cockhead into ${his} ${vaginal ? `pussy` : `asshole`}. Slowly at first and gradually increasing in speed, you begin to fuck ${him}, managing to bring ${him} to climax with the help of some ${vaginal ? `clitoral` : `manual`} stimulation with one hand. After you blow your own load inside ${him} and pull out, ${he} impulsively throws ${his} arms around your neck and pulls ${him}self in to plant a deep kiss on your lips.`,
+				Spoken(eventSlave, `<span class="devotion inc">"I love you, ${getWrittenTitle(eventSlave)},"</span> ${he} says in a hushed tone.`),
+				vaginal ? VCheck.Vaginal(eventSlave) : VCheck.Anal(eventSlave),
+			);
+
+			seX(eventSlave, vaginal ? "vaginal" : "anal", V.PC);
+			knockMeUp(eventSlave, 1, vaginal ? 0 : 1, -1);
+			eventSlave.devotion += 10;
+
+			App.Events.addParagraph(frag, r);
+			return frag;
+		}
+
+		function rape() {
+			const frag = new DocumentFragment();
+			const r = [];
+			r.push(
+				`You had been working on a particularly stressful assignment when ${he} interrupted you, and you need to blow off some steam. You grab ${him} hand and pull ${him} into your bedchambers before ${he} has time to reconsider, throwing ${him} roughly onto the bed and pulling off your clothes in a matter of seconds. ${He} follows suit, but realizes what you have in mind when you grab ${him} by the waist and thrust the entire length of your cock into ${his} ${vaginal ? `cunt` : `asshole`} in one fluid motion. ${He} begins to beg you to slow down and be gentler, but you only speed up in response. After a few minutes of rough pounding from you and weeping from ${him}, you feel your orgasm approaching and bury yourself as deep inside ${him} as you can as it hits. ${He} doesn't move when you finally pull yourself off of ${him}, opting instead to <span class="trust dec">lie there and cry.</span>`,
+			);
+
+			if (isVirgin) {
+				r.push(`Though your brutal fucking may not have left any permanent physical damage, <span class="lime">breaking in ${his} ${vaginal ? `pussy` : `ass`}</span> in this manner definitely gave ${him} a glimpse of just <span class="devotion dec">what you're capable of.</span>`);
+			}
+
+			if (vaginal) {
+				VCheck.Vaginal(eventSlave);
+			} else {
+				VCheck.Anal(eventSlave);
+			}
+
+			seX(eventSlave, vaginal ? "vaginal" : "anal", V.PC);
+			knockMeUp(eventSlave, 1, vaginal ? 0 : 1, -1);
+			eventSlave.trust -= 10;
+			if (isVirgin) {
+				eventSlave.devotion -= 10;
+			}
+
+			App.Events.addParagraph(frag, r);
+			return frag;
+		}
+
+		function no() {
+			const frag = new DocumentFragment();
+			const r = [];
+			const amount = random(2, 7) * 1000;
+			r.push(`You say nothing, returning instead to your work. After a silent minute of ${him} standing there, looking uncomfortable, ${he} finally takes the hint. ${He} mutters a quick apology and returns to what ${he} doing before ${he} interrupted you. <span class="cash inc">You manage to close the deal that you had been working on,</span> a twinge of satisfaction in your chest as you`);
+			if (V.PC.refreshmentType === 0) {
+				r.push(`take another drag from your ${V.PC.refreshment}.`);
+			} else if (V.PC.refreshmentType === 1) {
+				r.push(`take a swig of ${V.PC.refreshment}.`);
+			} else if (V.PC.refreshmentType === 3) {
+				r.push(`do another line of ${V.PC.refreshment}.`);
+			} else if (V.PC.refreshmentType === 4) {
+				r.push(`inject a little more ${V.PC.refreshment}.`);
+			} else {
+				r.push(`pop another ${V.PC.refreshment} into your mouth.`);
+			}
+
+			cashX(amount, "event");
+
+			App.Events.addParagraph(frag, r);
+			return frag;
+		}
+	}
+
+	get weight() {
+		return 25;
+	}
+};
diff --git a/src/events/RESS/review/bondedLove.js b/src/events/RESS/review/bondedLove.js
index 3f693373a51cbdde9b75d71ccc87022451570ff1..3b1f9553131385d1525a8c94d611cf05f26c097e 100644
--- a/src/events/RESS/review/bondedLove.js
+++ b/src/events/RESS/review/bondedLove.js
@@ -66,7 +66,7 @@ App.Events.RESSBondedLove = class RESSBondedLove extends App.Events.BaseEvent {
 			if (eventSlave.pregSource === -1) {
 				r.push(`completely filled with your ${children},`);
 			}
-			r.push(`and the slight movement within with each struggled step ${he} takes.`);
+			r.push(`and the slight movement within with each struggling step ${he} takes.`);
 		} else if (eventSlave.belly >= 150000) {
 			r.push(`${his} ${belly} belly and the vastly altered gait ${he} steps with to handle it.`);
 		} else if (eventSlave.bellyPreg >= 10000) {
diff --git a/src/events/RESS/review/cowMilking.js b/src/events/RESS/review/cowMilking.js
index 5baa7788c24641eede8f26f86ebe500ed1cb9ed4..eba3f70eaa9cb55d5238852ac50dcc3a83418d56 100644
--- a/src/events/RESS/review/cowMilking.js
+++ b/src/events/RESS/review/cowMilking.js
@@ -66,7 +66,7 @@ App.Events.RESSCowMilking = class RESSCowMilking extends App.Events.BaseEvent {
 			);
 		}
 		if (eventSlave.fetish === "boobs") {
-			r.push(`The shamelessly breast obsessed cow rarely misses an opportunity to ask for mammary intercourse, or anything remotely like it. Something as intimate as having you tug the milk from ${his} nipples would definitely qualify.`);
+			r.push(`The shamelessly breast obsessed cow rarely misses an opportunity to ask for mammary intercourse, or anything remotely like it. Something as intimate as having you tug the ${milkFlavor(eventSlave)}milk from ${his} nipples would definitely qualify.`);
 		} else {
 			r.push(`${He}'s not exactly a breast fetishist, but milking is nonetheless a deeply important activity for ${him}, emotionally; the neurochemical effects of continual lactation are strong. ${He}'s so devoted to you that ${he} probably considers this a reassuringly intimate act.`);
 		}
@@ -108,11 +108,11 @@ App.Events.RESSCowMilking = class RESSCowMilking extends App.Events.BaseEvent {
 			r.push(`udders in your hands. ${He} gasps as ${he} realizes exactly how you plan to do this, and adjusts the bucket so it's below both of ${his} nipples at once.`);
 			r.toParagraph();
 
-			r.push(`${He} instinctually expects the rhythmic tugging that the milkers usually produce, but what ${he} gets is a methodical massage of ${his} breasts, both at once. They're large enough to be more than a single handful, so you go bit by bit, ensuring that no part of ${his} udders goes untouched. ${His} nipples start to gush milk without help after a few moments of this, and ${he} groans with relief and satisfaction as ${he} feels ${his} breasts begin to empty and enjoys the sensation of the massage.`);
+			r.push(`${He} instinctually expects the rhythmic tugging that the milkers usually produce, but what ${he} gets is a methodical massage of ${his} breasts, both at once. They're large enough to be more than a single handful, so you go bit by bit, ensuring that no part of ${his} udders goes untouched. ${His} nipples start to gush ${milkFlavor(eventSlave)}milk without help after a few moments of this, and ${he} groans with relief and satisfaction as ${he} feels ${his} breasts begin to empty and enjoys the sensation of the massage.`);
 			if (eventSlave.fetish === "boobs") {
-				r.push(`${He} orgasms strongly soon after the first jet of milk, producing an especially thick squirt.`);
+				r.push(`${He} orgasms strongly soon after the first jet of ${milkFlavor(eventSlave)}milk, producing an especially thick squirt.`);
 			}
-			r.push(`After you're satisfied, you move your hands to ${his} nipples and milk ${him} like a cow, getting the last drops of milk out of ${him}`);
+			r.push(`After you're satisfied, you move your hands to ${his} nipples and milk ${him} like a cow, getting the last drops of ${milkFlavor(eventSlave)}milk out of ${him}`);
 			if (eventSlave.fetish === "boobs") {
 				r.push(`and producing a shuddering series of aftershocks.`);
 			} else {
@@ -153,7 +153,7 @@ App.Events.RESSCowMilking = class RESSCowMilking extends App.Events.BaseEvent {
 			}
 			r.toParagraph();
 
-			r.push(`You swing a bucket under ${his} nipples and milk ${him} by hand, as though ${he} were a cow. This isn't exactly what ${he} had in mind, but the feeling of your hands on ${his} nipples, tugging the streams of milk out of ${him} and into the bucket beneath`);
+			r.push(`You swing a bucket under ${his} nipples and milk ${him} by hand, as though ${he} were a cow. This isn't exactly what ${he} had in mind, but the feeling of your hands on ${his} nipples, tugging the streams of ${milkFlavor(eventSlave)}milk out of ${him} and into the bucket beneath`);
 			if (eventSlave.fetish === "boobs") {
 				r.push(`brings ${him} very close to orgasm.`);
 			} else {
@@ -161,17 +161,17 @@ App.Events.RESSCowMilking = class RESSCowMilking extends App.Events.BaseEvent {
 			}
 			r.push(`Seeing this, you muse aloud, as though to yourself, that a little farmyard bestiality wouldn't hurt, since there's no one here but you and a dairy cow. Pawing the cow's behind possessively, you finger ${him} aggressively before deciding on`);
 			if (canDoVaginal(eventSlave) && V.PC.dick !== 0) {
-				r.push(`a little cow pussy. You walk around behind ${him} and fuck ${him} hard enough to shake the drops of milk still clinging to ${his} sore nipples down and into the bucket below.`);
+				r.push(`a little cow pussy. You walk around behind ${him} and fuck ${him} hard enough to shake the drops of ${milkFlavor(eventSlave)}milk still clinging to ${his} sore nipples down and into the bucket below.`);
 				r.push(VCheck.Vaginal(eventSlave, 1));
 				r.push(`When you're finished, you step away, leaving your cum to run out of ${his} cunt and down ${his} thighs,`);
 			} else if (canDoAnal(eventSlave) && V.PC.dick !== 0) {
-				r.push(`some cow ass. You walk around behind ${him} and buttfuck ${his} hard enough to shake the drops of milk still clinging to ${his} sore nipples down and into the bucket below.`);
+				r.push(`some cow ass. You walk around behind ${him} and buttfuck ${his} hard enough to shake the drops of ${milkFlavor(eventSlave)}milk still clinging to ${his} sore nipples down and into the bucket below.`);
 				r.push(VCheck.Anal(eventSlave, 1));
 				r.push(`When you're finished, you step away, leaving your cum to drip out of ${his} gaped asshole,`);
 			} else {
 				r.push(`a little cow tongue action.`);
 				if (V.PC.vagina !== -1) {
-					r.push(`You stand up and grind your pussy against the cow's upturned mouth, humping ${his} face hard enough to shake the drops of milk still clinging to ${his} sore nipples down and into the bucket below.`);
+					r.push(`You stand up and grind your pussy against the cow's upturned mouth, humping ${his} face hard enough to shake the drops of ${milkFlavor(eventSlave)}milk still clinging to ${his} sore nipples down and into the bucket below.`);
 					if (V.PC.dick !== 0) {
 						r.push(`You pull away when you're about halfway there, only to shove your cock down ${his} throat instead.`);
 					}
diff --git a/src/events/RESS/review/desperatelyHorny.js b/src/events/RESS/review/desperatelyHorny.js
index ed64b58609ccc9569ef88b4c8ae6a0a50c4a31c0..dc918a7a9620fa22a07d333cc405b08e225d1e06 100644
--- a/src/events/RESS/review/desperatelyHorny.js
+++ b/src/events/RESS/review/desperatelyHorny.js
@@ -480,7 +480,7 @@ App.Events.RESSDesperatelyHorny = class RESSDesperatelyHorny extends App.Events.
 							}
 						} else if (eventSlave.preg > eventSlave.pregData.normalBirth/2) {
 							if (eventSlave.lactation === 1) {
-								r.push(`nipples and describing in whispers how nice and swollen ${he} is with milk.`);
+								r.push(`nipples and describing in whispers how nice and swollen ${he} is with ${milkFlavor(eventSlave)}milk.`);
 							} else {
 								r.push(`breasts and describing in whispers how big ${he}'s gotten since ${he} got pregnant.`);
 							}
@@ -515,7 +515,7 @@ App.Events.RESSDesperatelyHorny = class RESSDesperatelyHorny extends App.Events.
 							}
 						} else if (eventSlave.preg > eventSlave.pregData.normalBirth/2) {
 							if (eventSlave.lactation === 1) {
-								r.push(`nipples and describing in whispers how nice and swollen ${he} is with milk.`);
+								r.push(`nipples and describing in whispers how nice and swollen ${he} is with ${milkFlavor(eventSlave)}milk.`);
 							} else {
 								r.push(`breasts and describing in whispers how big ${he}'s gotten since ${he} got pregnant.`);
 							}
diff --git a/src/events/RESS/review/devotedLotion.js b/src/events/RESS/review/devotedLotion.js
index 68b69b76ece2fb3ab020caa3ec2a1d1689aa34e2..bbb1ade3448bbb6644e93f7d8a146d290fa8ebed 100644
--- a/src/events/RESS/review/devotedLotion.js
+++ b/src/events/RESS/review/devotedLotion.js
@@ -440,8 +440,11 @@ App.Events.RESSDevotedLotion = class RESSDevotedLotion extends App.Events.BaseEv
 				if (V.PC.vagina !== -1) {
 					r.push(`eat you out`);
 				}
-				r.addToLast(`. ${He} complies <span class="devotion inc">submissively,</span> crying quietly in confusion and disarray, all pretense of feminine grace gone. It doesn't take long, since that was quite a lot of fun, and by the time you finish ${he} hasn't yet worked up the courage to touch ${his} <span class="lime">newly widened backdoor.</span>`);
-				eventSlave.anus += 1;
+				r.addToLast(`. ${He} complies <span class="devotion inc">submissively,</span> crying quietly in confusion and disarray, all pretense of feminine grace gone.`);
+				if (V.seeStretching === 1) {
+					r.addToLast(` It doesn't take long, since that was quite a lot of fun, and by the time you finish ${he} hasn't yet worked up the courage to touch ${his} <span class="lime">newly widened backdoor.</span>`);
+					eventSlave.anus += 1;
+				}
 			}
 			eventSlave.devotion += 5;
 			r.toParagraph();
@@ -552,9 +555,12 @@ App.Events.RESSDevotedLotion = class RESSDevotedLotion extends App.Events.BaseEv
 				if (V.PC.vagina !== -1) {
 					r.push(`eat you out`);
 				}
-				r.addToLast(`. ${He} complies <span class="devotion inc">submissively,</span> crying quietly with overstimulation, all pretense of feminine grace gone. It doesn't take long, since that was quite a lot of fun, but by the time you finish ${he}'s gingerly massaging ${his} <span class="lime">newly loosened cunt.</span>`);
+				r.addToLast(`. ${He} complies <span class="devotion inc">submissively,</span> crying quietly with overstimulation, all pretense of feminine grace gone.`);
 				eventSlave.devotion += 5;
-				eventSlave.vagina += 1;
+				if (V.seeStretching === 1 ) {
+					r.addToLast(`It doesn't take long, since that was quite a lot of fun, but by the time you finish ${he}'s gingerly massaging ${his} <span class="lime">newly loosened cunt.</span>`);
+					eventSlave.vagina += 1;
+				}
 			}
 			r.toParagraph();
 			return r.container();
diff --git a/src/events/RESS/review/eliteBreederPlease.js b/src/events/RESS/review/eliteBreederPlease.js
index 1495da65d6ea8cdf2713ccd270d48d635dc60383..7f9a65c73460113e11f0da04796c2ab01b120482 100644
--- a/src/events/RESS/review/eliteBreederPlease.js
+++ b/src/events/RESS/review/eliteBreederPlease.js
@@ -36,7 +36,7 @@ App.Events.RESSEliteBreederPlease = class RESSEliteBreederPlease extends App.Eve
 		r.toParagraph();
 
 		App.Events.addResponses(node, [
-			new App.Events.Result(`Agree`, agree, `This option will sterilize ${him} if ${he} is not deemed worthy of breeding`),
+			new App.Events.Result(`Agree`, agree, `This option costs ${cashFormat(5000)} and will sterilize ${him} if ${he} is not deemed worthy of breeding`),
 			new App.Events.Result(`Refuse`, refuse),
 		]);
 
@@ -46,11 +46,11 @@ App.Events.RESSEliteBreederPlease = class RESSEliteBreederPlease extends App.Eve
 			const div = document.createElement("div");
 			const r = new SpacedTextAccumulator(div);
 
-			r.push(`Having a slave so eager to become a breeder always makes you smile inwardly, but you don't allow your expression to change. Instead, you silently stand up from your chair and make a show of contemplating ${his} request. ${eventSlave.slaveName} waits with bated breath, letting out an audible sigh of relief and gratitude when you accept ${his} offer.`);
+			r.push(`Having a slave so eager to become a breeder always makes you smile inwardly, but you don't allow your expression to change. Instead, you silently stand up from your chair and make a show of contemplating ${his} request. ${eventSlave.slaveName} waits with bated breath, letting out an audible sigh of relief and gratitude when you accept ${his} offer. Without any further ado, you make a quick phone call, and a few short minutes later a small group of Elites enters, ready to grade your slave.`);
 
 			r.toParagraph();
 
-			div.append(eliteBreedingExam(eventSlave));
+			div.append(App.Interact.eliteBreedingExam(eventSlave));
 
 			return r.container();
 		}
diff --git a/src/events/RESS/review/heels_event.js b/src/events/RESS/review/heels_event.js
index 222c7c8a11df89085917fea8d894285356ed233d..f14926455c34f260880e54dfac207add92f91cea 100644
--- a/src/events/RESS/review/heels_event.js
+++ b/src/events/RESS/review/heels_event.js
@@ -73,7 +73,7 @@ App.Events.RESSHeels = class RESSHeels extends App.Events.BaseEvent {
 			new App.Events.Result(`Nothing, ${he}'ll crawl for the rest of the week`, crawl, virginityWarning()),
 			new App.Events.Result(`Pretty heels, we're going out`, out),
 			canDoAnal(eventSlave)
-				? 	new App.Events.Result(`Heels for an anal slut`, slut, virginityWarning(true))
+				? new App.Events.Result(`Heels for an anal slut`, slut, virginityWarning(true))
 				: new App.Events.Result(),
 
 		]);
@@ -140,7 +140,7 @@ App.Events.RESSHeels = class RESSHeels extends App.Events.BaseEvent {
 			$(artDiv).empty();
 			App.Events.drawEventArt(artDiv, eventSlave, "no clothing");
 			r = [];
-			r.push(`You have an appointment, and ${eventSlave.slaveName} gets to be your arm candy. ${He}'s almost beside ${himself} with pride when you leave the penthouse and head out into the warm sun. You have to walk slowly so ${he} can keep ${his} feet and still keep up, since you've taken the unusual step of rewarding ${him} by letting ${him} walk under your arm. To avoid giving the impression that the ${girl} on your arm isn't a slave, ${he}'s naked except for ${his} lovely heels. As ${he} minces along ${his} breasts`);
+			r.push(`You have an appointment, and ${eventSlave.slaveName} gets to be your arm candy. ${He}'s almost beside ${himself} with pride when you leave the penthouse and head out into the warm sun. You have to walk slowly so ${he} can keep ${his} feet steady and still keep up, since you've taken the unusual step of rewarding ${him} by letting ${him} walk under your arm. To avoid giving the impression that the ${girl} on your arm isn't a slave, ${he}'s naked except for ${his} lovely heels. As ${he} minces along ${his} breasts`);
 			if (eventSlave.bellyFluid >= 5000) {
 				r.push(`jiggle delightfully alongside ${his} ${eventSlave.inflationType}-filled belly`);
 			} else if (eventSlave.belly >= 5000) {
diff --git a/src/events/RESS/review/masterfulEntertainer.js b/src/events/RESS/review/masterfulEntertainer.js
index ce6757057eb9f1907a5a0f55da8b79ffbdd4e4cc..9bcbbb48c5f218b4fab5d5cbcb86017f738186eb 100644
--- a/src/events/RESS/review/masterfulEntertainer.js
+++ b/src/events/RESS/review/masterfulEntertainer.js
@@ -29,7 +29,7 @@ App.Events.RESSMasterfulEntertainer = class RESSMasterfulEntertainer extends App
 		let r = [];
 		r.push(
 			`It's Friday evening, the most socially important part of the week in ${V.arcologies[0].name}.`,
-			contextualIntro(PC, eventSlave, true),
+			contextualIntro(PC, eventSlave, true, false, true),
 			`happens to be free this evening, and your schedule is open, too. Lately, ${he}'s been putting on a tour de force of seduction, erotic dance, and lewd entertainment whenever ${he} gets the chance to catch someone's eye`
 		);
 		if (eventSlave.belly >= 5000) {
diff --git a/src/events/RESS/review/notMyName.js b/src/events/RESS/review/notMyName.js
index 52919d4ea3da07dafb681e3f4461f86142a6ed3e..eb48b24b2c29f630f89430346aee3b472ac07da8 100644
--- a/src/events/RESS/review/notMyName.js
+++ b/src/events/RESS/review/notMyName.js
@@ -56,7 +56,7 @@ App.Events.RESSNotMyName = class RESSNotMyName extends App.Events.BaseEvent {
 
 		App.Events.addParagraph(node, r);
 		App.Events.addResponses(node, [
-			new App.Events.Result(`Extirpate this foolishness with pain`, exptirpate),
+			new App.Events.Result(`Extirpate this foolishness with pain`, extirpate),
 			new App.Events.Result(`Allow ${him} to resume ${his} birth name`, allow),
 			new App.Events.Result(`Allow ${him} to resume ${his} birth name, but make it publicly humiliating`, humiliate, `This may impact ${his} sexuality.`),
 			V.arcade > 0
@@ -64,7 +64,7 @@ App.Events.RESSNotMyName = class RESSNotMyName extends App.Events.BaseEvent {
 				: 	new App.Events.Result(),
 		]);
 
-		function exptirpate() {
+		function extirpate() {
 			r = [];
 			r.push(`You seize ${him} and begin to bind ${him} for appropriate punishment. ${eventSlave.slaveName} does not resist you physically at first. ${He} finds ${himself} tied bent over your desk, face-down, with ${his} ${arms} locked behind ${him}`);
 			if (eventSlave.belly >= 1500) {
@@ -115,7 +115,7 @@ App.Events.RESSNotMyName = class RESSNotMyName extends App.Events.BaseEvent {
 			}
 			r.push(
 				`and explain with equanimity that ${he} has two choices: ${he} can either introduce ${himself} to strangers by name and offer them free oral sex, or ${he} can be whipped until ${he} introduces ${himself} to strangers by name and offers them free oral sex. ${His} lip quivers a little, but ${he} stumbles over to a nearby group of local worthies and whimpers hesitantly,`,
-				Spoken(eventSlave, `"H-hi, my name is ${slaveName}, can I suck you off, please?"`),
+				Spoken(eventSlave, `"H-hi, my name is ${slaveName}... can I suck you off, please?"`),
 				`They laugh, and understanding the situation perfectly, give you a <span class="reputation inc">grateful wave</span> even as their leader pushes ${him} to ${his} knees. For the rest of the week, ${he}'s seeing to ${his} duties, sleeping, or blowing strangers after telling them ${his} name. Though ${he} has reassumed ${his} birth name, it is <span class="trust dec">no longer any source of independence to ${him}.</span>`
 			);
 			repX(500, "event", eventSlave);
diff --git a/src/events/RESS/review/nymphoWithAssistant.js b/src/events/RESS/review/nymphoWithAssistant.js
index a2ecc145bc6d4949adb9dd188969818c38450e99..264f876f73612c42e45833640daac0e9e8cae32f 100644
--- a/src/events/RESS/review/nymphoWithAssistant.js
+++ b/src/events/RESS/review/nymphoWithAssistant.js
@@ -165,11 +165,11 @@ App.Events.RESSNymphoWithAssistant = class RESSNymphoWithAssistant extends App.E
 			r.push(`You are not, however, feeling particularly polite. ${eventSlave.slaveName} writhes in anguish when ${he} feels an additional phallus forcing its way past ${his} lips. ${He} tries to relax but loses control and spasms; the throat fucking continues unmercifully and in short order ${he} is gagging desperately. Each of ${his} holes receives the same treatment in turn; all ${he} manages to do in response is writhe here and there, and squeal incoherently whenever ${his} mouth isn't totally full. ${He} has become <span class="devotion inc">more submissive to you.</span>`);
 			r.push(VCheck.Both(eventSlave, 1));
 			eventSlave.devotion += 4;
-			if (eventSlave.vagina === 1 && canDoVaginal(eventSlave)) {
+			if (V.seeStretching === 1 && eventSlave.vagina === 1 && canDoVaginal(eventSlave)) {
 				r.push(`${His} tight pussy <span class="lime">isn't so tight any more.</span>`);
 				eventSlave.vagina += 1;
 			}
-			if (eventSlave.anus === 1 && canDoAnal(eventSlave)) {
+			if (V.seeStretching === 1 && eventSlave.anus === 1 && canDoAnal(eventSlave)) {
 				r.push(`${His} tight butt <span class="lime">has been loosened by the double anal.</span>`);
 				eventSlave.anus += 1;
 			}
diff --git a/src/events/RESS/review/sexySuccubus.js b/src/events/RESS/review/sexySuccubus.js
index 31a073b7cb07b23638335ef75561429e4c984e9c..8301d248f28fb93b625fd907ad24e17c65a765a8 100644
--- a/src/events/RESS/review/sexySuccubus.js
+++ b/src/events/RESS/review/sexySuccubus.js
@@ -51,7 +51,7 @@ App.Events.RESSSexySuccubus = class RESSSexySuccubus extends App.Events.BaseEven
 		if (eventSlave.boobs > 6000) {
 			r.push(`bare, inhumanly large breasts`);
 		} else if (eventSlave.lactation > 0) {
-			r.push(`bare udders, heavy with milk`);
+			r.push(`bare udders, heavy with ${milkFlavor(eventSlave)}milk`);
 		} else if (eventSlave.boobsImplant > 0) {
 			r.push(`naked fake tits`);
 		} else if (eventSlave.boobs > 800) {
diff --git a/src/events/RESS/review/soreAss.js b/src/events/RESS/review/soreAss.js
index 18ccd6d1816c8facf05396b12db55b660df63f7c..0784388fc115e36e50b9ab759c7aeb1f3dc2f658 100644
--- a/src/events/RESS/review/soreAss.js
+++ b/src/events/RESS/review/soreAss.js
@@ -71,7 +71,7 @@ App.Events.RESSSoreAss = class RESSSoreAss extends App.Events.BaseEvent {
 				r.push(`set ${him} on your chest before reaching around to line your cock up with ${his} sore hole. ${He} shudders and writhes when you start pushing yourself inside.`);
 			}
 			r.push(`You use hard pinches to ${his} nipples to punish ${his} whining, forcing ${him} to take a long, painful buttfuck in silence. <span class="gold">${He} has become more afraid of you.</span>`);
-			if (eventSlave.anus < 3) {
+			if (V.seeStretching === 1 && eventSlave.anus < 3) {
 				r.push(`${His} week of tough anal experience has <span class="lime">permanently loosened ${his} anus.</span>`);
 				eventSlave.anus += 1;
 			}
diff --git a/src/events/RESS/review/torpedoSqueeze.js b/src/events/RESS/review/torpedoSqueeze.js
index 239680f6948efc2d3beb252e02aeec7e488df441..49b8cf6723b067f580bbd19cada253444e93833f 100644
--- a/src/events/RESS/review/torpedoSqueeze.js
+++ b/src/events/RESS/review/torpedoSqueeze.js
@@ -261,9 +261,9 @@ App.Events.RESSTorpedoSqueeze = class RESSTorpedoSqueeze extends App.Events.Base
 			if (eventSlave.lactation > 0) {
 				r.addToLast(`, not to mention`);
 				if (eventSlave.lactation === 1) {
-					r.push(`a few drops of milk`);
+					r.push(`a few drops of ${milkFlavor(eventSlave)}milk`);
 				} else {
-					r.push(`an ejaculation-like stream of milk`);
+					r.push(`an ejaculation-like stream of ${milkFlavor(eventSlave)}milk`);
 				}
 				r.push(`from each of ${his} nipples`);
 			}
diff --git a/src/events/RESS/review/usedWhore.js b/src/events/RESS/review/usedWhore.js
index dce4057092626a749df2ffb0ea7be44258a05c6f..90ef6cd54cb865f7b0d70d8a3a55d7edc078085e 100644
--- a/src/events/RESS/review/usedWhore.js
+++ b/src/events/RESS/review/usedWhore.js
@@ -416,7 +416,6 @@ App.Events.RESSUsedWhore = class RESSUsedWhore extends App.Events.BaseEvent {
 				case "a Futanari Sister":
 				case "a slave":
 				case "a slave since birth":
-				case 0:
 					r.push(`once upon a time.`);
 					break;
 				default:
diff --git a/src/events/RESS/scrubbing.js b/src/events/RESS/scrubbing.js
index a32f04af154008e9f8df380cbf710eb26b26e2fc..449ba4d622ddc5c5ec1bbc3afea661f9ba397c93 100644
--- a/src/events/RESS/scrubbing.js
+++ b/src/events/RESS/scrubbing.js
@@ -276,7 +276,13 @@ App.Events.RESSScrubbing = class RESSScrubbing extends App.Events.BaseEvent {
 			}
 			r.push(`and ${his} lubricated thighs before`);
 			if (V.PC.dick === 0) {
-				r.push(`wrestling the slick slave onto ${his} back so you can ride ${his} face while reaching down to spread ${his} legs and molest ${his}`);
+				r.push(`wrestling the slick slave onto ${his} back so you can ride ${his} face while reaching down to spread ${his}`);
+				if (hasBothLegs(eventSlave)) {
+					r.push(`legs`);
+				} else {
+					r.push(`cheeks`);
+				}
+				r.push(`and molest ${his}`);
 				if (canDoVaginal(eventSlave) && canDoAnal(eventSlave)) {
 					r.push(`pussy and ass.`);
 				} else if (canDoVaginal(eventSlave)) {
diff --git a/src/events/RESS/tooThinForCumDiet.js b/src/events/RESS/tooThinForCumDiet.js
index 05edd9457e3e1f7a90c46340193bed34f0454f72..40ca7c432cfef195552178531e02a51ec1bab588 100644
--- a/src/events/RESS/tooThinForCumDiet.js
+++ b/src/events/RESS/tooThinForCumDiet.js
@@ -42,86 +42,47 @@ App.Events.RESSTooThinForCumDiet = class RESSTooThinForCumDiet extends App.Event
 		t.push(`appear outside your door. ${He} hovers outside in the hall, peeking ${his} head around the entry-way, looking very unsure about disturbing you. You stop what you're doing and call ${him} in. ${He}'s reticent at first, but then ${he} obediently steps into your office. ${He} is`);
 		if (App.Data.clothes.get(eventSlave.clothes).exposure >= 4) {
 			t.push(`forced to remain naked at all times, and the most striking thing about ${his} body is how`);
-			if (eventSlave.belly >= 100000) {
-				if (eventSlave.bellyPreg >= 3000) {
-					t.push(`${his} ${belly} pregnancy utterly dwarfs ${his} skinny body.`);
-				} else {
-					t.push(`${his} ${belly} distended belly utterly dwarfs ${his} skinny body.`);
-				}
-			} else if (eventSlave.belly >= 15000) {
-				if (eventSlave.bellyPreg >= 3000) {
-					t.push(`${his} full pregnancy completely dominates ${his} skinny body.`);
-				} else {
-					t.push(`${his} hugely distended belly completely dominates ${his} skinny body.`);
-				}
-			} else if (eventSlave.belly >= 10000) {
-				if (eventSlave.bellyPreg >= 3000) {
-					t.push(`${his} advanced pregnancy dominates ${his} skinny body.`);
-				} else {
-					t.push(`${his} hugely distended belly dominates ${his} skinny body.`);
-				}
-			} else if (eventSlave.belly >= 5000) {
-				if (eventSlave.bellyPreg >= 3000) {
-					t.push(`massive ${his} pregnant belly is compared to ${his} skinny body.`);
-				} else {
-					t.push(`massive ${his} distended belly is compared to ${his} skinny body.`);
-				}
-			} else if (eventSlave.belly >= 1500) {
-				if (eventSlave.bellyPreg > 0) {
-					t.push(`noticeable ${his} growing pregnancy is against ${his} skinny body.`);
-				} else {
-					t.push(`noticeable the curve of ${his} belly is against ${his} skinny body.`);
-				}
-			} else if (eventSlave.belly >= 150) {
-				if (eventSlave.bellyPreg > 0) {
-					t.push(`noticeable ${his} early pregnancy is against ${his} skinny body.`);
-				} else {
-					t.push(`noticeable the curve of ${his} implant is against ${his} skinny body.`);
-				}
-			} else {
-				t.push(`skinny ${he} is.`);
-			}
 		} else {
 			t.push(`forced to wear ${eventSlave.clothes} all day, but even through ${his} outfit, it's easy to see how`);
-			if (eventSlave.belly >= 100000) {
-				if (eventSlave.bellyPreg >= 3000) {
-					t.push(`${his} ${belly} pregnancy utterly dwarfs ${his} skinny body.`);
-				} else {
-					t.push(`${his} ${belly} distended belly utterly dwarfs ${his} skinny body.`);
-				}
-			} else if (eventSlave.belly >= 15000) {
-				if (eventSlave.bellyPreg >= 3000) {
-					t.push(`${his} heavy pregnancy completely dominates ${his} skinny body.`);
-				} else {
-					t.push(`${his} hugely distended belly completely dominates ${his} skinny body.`);
-				}
-			} else if (eventSlave.belly >= 10000) {
-				if (eventSlave.bellyPreg >= 3000) {
-					t.push(`${his} advanced pregnancy dominates ${his} skinny body.`);
-				} else {
-					t.push(`${his} hugely distended belly dominates ${his} skinny body.`);
-				}
-			} else if (eventSlave.belly >= 5000) {
-				if (eventSlave.bellyPreg >= 3000) {
-					t.push(`massive ${his} pregnant belly is compared to ${his} skinny body.`);
-				} else {
-					t.push(`massive ${his} distended belly is compared to ${his} skinny body.`);
-				}
-			} else if (eventSlave.belly >= 1500) {
-				if (eventSlave.bellyPreg > 0) {
-					t.push(`noticeable ${his} growing pregnancy is against ${his} skinny body.`);
-				} else {
-					t.push(`noticeable the curve of ${his} belly is against ${his} skinny body.`);
-				}
-			} else if (eventSlave.belly >= 150) {
-				if (eventSlave.bellyPreg > 0) {
-					t.push(`noticeable ${his} early pregnancy is against ${his} skinny body.`);
-				} else {
-					t.push(`noticeable the curve of ${his} implant is against ${his} skinny body.`);
-				}
+		}
+		if (eventSlave.belly >= 100000) {
+			if (eventSlave.bellyPreg >= 3000) {
+				t.push(`${his} ${belly} pregnancy utterly dwarfs ${his} skinny body.`);
+			} else {
+				t.push(`${his} ${belly} distended belly utterly dwarfs ${his} skinny body.`);
+			}
+		} else if (eventSlave.belly >= 15000) {
+			if (eventSlave.bellyPreg >= 3000) {
+				t.push(`${his} heavy pregnancy completely dominates ${his} skinny body.`);
+			} else {
+				t.push(`${his} hugely distended belly completely dominates ${his} skinny body.`);
+			}
+		} else if (eventSlave.belly >= 10000) {
+			if (eventSlave.bellyPreg >= 3000) {
+				t.push(`${his} advanced pregnancy dominates ${his} skinny body.`);
 			} else {
-				t.push(`impossibly skinny ${he} is.`);
+				t.push(`${his} hugely distended belly dominates ${his} skinny body.`);
 			}
+		} else if (eventSlave.belly >= 5000) {
+			if (eventSlave.bellyPreg >= 3000) {
+				t.push(`massive ${his} pregnant belly is compared to ${his} skinny body.`);
+			} else {
+				t.push(`massive ${his} distended belly is compared to ${his} skinny body.`);
+			}
+		} else if (eventSlave.belly >= 1500) {
+			if (eventSlave.bellyPreg > 0) {
+				t.push(`noticeable ${his} growing pregnancy is against ${his} skinny body.`);
+			} else {
+				t.push(`noticeable the curve of ${his} belly is against ${his} skinny body.`);
+			}
+		} else if (eventSlave.belly >= 150) {
+			if (eventSlave.bellyPreg > 0) {
+				t.push(`noticeable ${his} early pregnancy is against ${his} skinny body.`);
+			} else {
+				t.push(`noticeable the curve of ${his} implant is against ${his} skinny body.`);
+			}
+		} else {
+			t.push(`skinny ${he} is.`);
 		}
 		if (eventSlave.weight > -80) {
 			t.push(`${He}'s not exclusively skin and bones, but ${he}'s close. ${His}`);
@@ -130,11 +91,7 @@ App.Events.RESSTooThinForCumDiet = class RESSTooThinForCumDiet extends App.Event
 		}
 
 		if (eventSlave.boobs < 600) {
-			if (eventSlave.boobs < 300) {
-				t.push(`tiny`);
-			} else if (eventSlave.boobs < 600) {
-				t.push(`small`);
-			}
+			t.push(eventSlave.boobs < 300 ? `tiny` : `small`);
 			t.push("boobs are barely noticeable");
 			t.push(eventSlave.belly >= 5000 ? `above ${his} bloated` : `against ${his} concave`);
 			if (V.arcologies[0].FSSlimnessEnthusiast !== "unset") {
@@ -230,7 +187,7 @@ App.Events.RESSTooThinForCumDiet = class RESSTooThinForCumDiet extends App.Event
 			if (eventSlave.vagina !== 0) {
 				t.push(`even attempting to offer ${his} body for use in gratitude,`);
 			}
-			t.push(`but you simply send ${him} away. You find yourself concerned that you are becoming soft by allowing slaves to dictate what they will and won't eat, but your benevolent decision has already had a <span class="hotpink">positive effect on ${his} attitude.</span> ${He} <span class="mediumaquamarine">trusts you a little more</span> too.`);
+			t.push(`but you simply send ${him} away. You find yourself concerned that you are becoming soft by allowing slaves to dictate what they will and won't eat, but your benevolent decision has already had a <span class="devotion inc">positive effect on ${his} attitude.</span> ${He} <span class="trust inc">trusts you a little more</span> too.`);
 			eventSlave.trust += 2;
 			eventSlave.devotion += 2;
 			eventSlave.dietCum = 0;
@@ -266,15 +223,9 @@ App.Events.RESSTooThinForCumDiet = class RESSTooThinForCumDiet extends App.Event
 			} else {
 				t.push(`self`);
 			}
-			t.push(`inside ${his} butt-hole and subdue ${his} weak, struggling body against your unforgiving desk. <span class="gold">Horrified tears</span> stream down ${his} face with each brutal thrust as you speak into ${his} ear and remind ${him} that slaves are not allowed to dictate their needs to their owners. You know what's best for ${him}, and right now, ${his} proper role is as an eager little depository for the products of the free-cities ejaculate market. It's ${his} job to suck down cum at the whim of ${his} owner, plain and simple, until ${he}'s told otherwise. You butt-fuck the cum-fed slag until ${he} simply lays there and accepts ${his} corrective assrape.`);
+			t.push(`inside ${his} butt-hole and subdue ${his} weak, struggling body against your unforgiving desk. <span class="trust dec">Horrified tears</span> stream down ${his} face with each brutal thrust as you speak into ${his} ear and remind ${him} that slaves are not allowed to dictate their needs to their owners. You know what's best for ${him}, and right now, ${his} proper role is as an eager little depository for the products of the free-cities ejaculate market. It's ${his} job to suck down cum at the whim of ${his} owner, plain and simple, until ${he}'s told otherwise. You butt-fuck the cum-fed slag until ${he} simply lays there and accepts ${his} corrective assrape.`);
 			if (eventSlave.anus === 0) {
-				t.push(`<span class="lime">${His}</span>`);
-				if (eventSlave.butt < 5) {
-					t.push(`<span class="lime">skinny little</span>`);
-				} else {
-					t.push(`<span class="lime">plump little</span>`);
-				}
-				t.push(`<span class="lime">ass is now broken in.</span>`);
+				t.push(`<span class="virginity loss">${His} ${eventSlave.butt < 5 ? 'skinny' : 'plump'} little ass is now broken in.</span>`);
 			}
 			t.push(`${He} sobs quietly with each thrust of your hips, and when you finally`);
 			if (V.PC.dick !== 0) {
@@ -296,7 +247,7 @@ App.Events.RESSTooThinForCumDiet = class RESSTooThinForCumDiet extends App.Event
 			t.push(`to ${his} next assignment.`);
 			App.Events.addParagraph(frag, t);
 			t = [];
-			t.push(`${He}'s learned a valuable lesson about what it truly means to be a slave today, and it's one ${he} <span class="orchid">won't soon forget.</span>`);
+			t.push(`${He}'s learned a valuable lesson about what it truly means to be a slave today, and it's one ${he} <span class="devotion dec">won't soon forget.</span>`);
 			eventSlave.devotion -= 5;
 			eventSlave.trust -= 5;
 			if (eventSlave.anus === 0) {
@@ -341,7 +292,7 @@ App.Events.RESSTooThinForCumDiet = class RESSTooThinForCumDiet extends App.Event
 			t.push(`You then book ${him} to be the main attraction at a corporate office party that afternoon, where ${he} will be the target of a blow-bang and bukkake. You see that ${he}'s dosed heavily with the drugs every day this week, and then book the rest of ${his} afternoons for similar duties, making sure ${he} still tends to ${his} regular assignments as well. In the meantime, you also instruct the kitchen that ${he} is to eat as much cum-based food from the dispensers as ${he} can suck down in order to fuel up for these exhausting escapades.`);
 			App.Events.addParagraph(frag, t);
 			t = [];
-			t.push(`By the end of the week, the aphrodisiacs and ${his} slide into an inescapable routine of cum immersion have done their job, and ${he} has begun to <span class="lightcoral">view cum as an inevitable component of ${his} daily life.</span> ${He} also manages to <span class="green">gain a little weight.</span> Thanks to your manipulation of ${his} Pavlovian responses through extreme drug therapy, ${his} <span class="health dec">health has suffered a bit,</span> but ${he} is also <span class="hotpink">more dependent on you</span> thanks to ${his}`);
+			t.push(`By the end of the week, the aphrodisiacs and ${his} slide into an inescapable routine of cum immersion have done their job, and ${he} has begun to <span class="fetish gain">view cum as an inevitable component of ${his} daily life.</span> ${He} also manages to <span class="improvement">gain a little weight.</span> Thanks to your manipulation of ${his} Pavlovian responses through extreme drug therapy, ${his} <span class="health dec">health has suffered a bit,</span> but ${he} is also <span class="devotion inc">more dependent on you</span> thanks to ${his}`);
 			if (eventSlave.addict === 0) {
 				t.push(`<span class="cyan">new</span>`);
 			} else {
diff --git a/src/events/RETS/reCockmilkInterception.js b/src/events/RETS/reCockmilkInterception.js
index 6c158996f24ae79b1b5f8b00085d45deeaea06f7..e704283d4f8e65a10e9327208b6b537bf84f39f9 100644
--- a/src/events/RETS/reCockmilkInterception.js
+++ b/src/events/RETS/reCockmilkInterception.js
@@ -47,11 +47,11 @@ App.Events.RETSCockmilkInterception = class RETSCockmilkInterception extends App
 			t.push(`${he2}'s not lactating, but ${he2}'s a good semen producer and when ${he2} wakes up, ${he2}'s usually very ready to have one of the machines drain ${his2} balls for ${him2}.`);
 		} else {
 			if (subSlave.preg > subSlave.pregData.normalBirth / 1.33) {
-				t.push(`it's late in ${his2} pregnancy and ${he2} wakes up every day with ${his2} ${subSlave.boobShape} breasts sore, painfully swollen with rich, nutritious milk.`);
+				t.push(`it's late in ${his2} pregnancy and ${he2} wakes up every day with ${his2} ${subSlave.boobShape} breasts sore, painfully swollen with rich, nutritious ${subSlave.milkFlavor === "none" ? `` : `${subSlave.milkFlavor} flavored `}milk.`);
 			} else if (subSlave.preg > subSlave.pregData.normalBirth / 2) {
-				t.push(`${he2}'s pregnant and ${he2} wakes up every day with ${his2} ${subSlave.boobShape} breasts sore and swollen with rich, nutritious milk.`);
+				t.push(`${he2}'s pregnant and ${he2} wakes up every day with ${his2} ${subSlave.boobShape} breasts sore and swollen with rich, nutritious ${subSlave.milkFlavor === "none" ? `` : `${subSlave.milkFlavor} flavored `}milk.`);
 			} else if (subSlave.lactation > 1) {
-				t.push(`the tiny little slow-release implant in each of ${his2} breasts is merciless. It keeps ${his2} mammary glands in a permanent state of barely-safe hyperproduction, and ${he2} wakes up every day with ${his2} terribly sore breasts spontaneously dribbling milk.`);
+				t.push(`the tiny little slow-release implant in each of ${his2} breasts is merciless. It keeps ${his2} mammary glands in a permanent state of barely-safe hyperproduction, and ${he2} wakes up every day with ${his2} terribly sore breasts spontaneously dribbling ${subSlave.milkFlavor === "none" ? `` : `${subSlave.milkFlavor} flavored `}milk.`);
 			} else {
 				t.push(`${his2} lactation is natural, but it's still enough that ${he2} wakes up most days with full, sore breasts.`);
 			}
@@ -134,7 +134,7 @@ App.Events.RETSCockmilkInterception = class RETSCockmilkInterception extends App
 		} else if (subSlave.dick > 8) {
 			t.push(`has an inhumanly monstrous penis that the poor slave's cardiovascular system couldn't possibly bring`);
 			if (slave.drugs === "priapism agents") {
-				t.push(`erect without outside aid; agents like the priapism agents ${he2} is currently on. ${slave.slaveName} has forced as much of its head into ${his} mouth as ${he} can, and is sucking lustily while trying not to choke.`);
+				t.push(`erect without outside aid; aid like the priapism agents ${he2} is currently on. ${slave.slaveName} has forced as much of its head into ${his} mouth as ${he} can, and is sucking lustily while trying not to choke.`);
 			} else {
 				t.push(`erect. ${slave.slaveName} has gotten its huge soft head into ${his} mouth, and is sucking lustily.`);
 			}
@@ -275,7 +275,7 @@ App.Events.RETSCockmilkInterception = class RETSCockmilkInterception extends App
 			t.push(`soft`);
 		}
 		if (subSlave.scrotum && subSlave.balls) {
-			t.push(`dickhead and visibly tickles ${subSlave.slaveName}'s balls with ${his} naughty pink tongue`);
+			t.push(`dickhead and visibly tickles ${subSlave.slaveName}'s balls with ${his} naughty pink tongue.`);
 		} else {
 			t.push(`dickhead.`);
 		}
@@ -478,7 +478,7 @@ App.Events.RETSCockmilkInterception = class RETSCockmilkInterception extends App
 			} else {
 				t.push(`${he}'s no oral master, but ${his} mouth is wet and hot, and ${subSlave.slaveName} clearly likes it more than machine's dick receptacle. ${He2}`);
 			}
-			t.push(`can feel that ${his2} breasts aren't nearly empty of milk yet, and of course the milkers are tugging at ${his2} teats as industriously as ever, so ${he2} relaxes luxuriantly as ${slave.slaveName} starts to climb out from under ${him2}.`);
+			t.push(`can feel that ${his2} breasts aren't nearly empty of ${subSlave.milkFlavor === "none" ? `` : `${subSlave.milkFlavor} flavored `}milk yet, and of course the milkers are tugging at ${his2} teats as industriously as ever, so ${he2} relaxes luxuriantly as ${slave.slaveName} starts to climb out from under ${him2}.`);
 			App.Events.addParagraph(frag, t);
 			t = [];
 
@@ -521,7 +521,7 @@ App.Events.RETSCockmilkInterception = class RETSCockmilkInterception extends App
 			if (subSlave.lactation > 1) {
 				t.push(`lactation is unnaturally copious,`);
 			} else {
-				t.push(`milk is really flowing,`);
+				t.push(`${subSlave.milkFlavor === "none" ? `` : `${subSlave.milkFlavor} flavored `}milk is really flowing now,`);
 			}
 			t.push(`and a thin stream of cream squirts out of ${him2}. It lands on ${slave.slaveName}'s face below, surprising ${him}. ${He} splutters comically, but obeys eagerly when you squeeze ${subSlave.slaveName}'s freed boob and order ${slave.slaveName} to start drinking. After all, you point out, a balanced diet is important. ${slave.slaveName} <span class="trust inc">giggles complaisantly</span> and reaches for the proffered tit. ${subSlave.slaveName} is still basking in the afterglow of ${his2} orgasm and shudders silently with overstimulation as ${he2} feels ${slave.slaveName}'s lips`);
 			if (subSlave.nipples !== "fuckable") {
diff --git a/src/events/RETS/reDatePlease.js b/src/events/RETS/reDatePlease.js
index d00e6c369620fb8ae2a5993639db869171e3c36c..e4da345a5bb73488e783b14adcbbd4d675e89cc0 100644
--- a/src/events/RETS/reDatePlease.js
+++ b/src/events/RETS/reDatePlease.js
@@ -50,7 +50,9 @@ App.Events.RETSDatePlease = class RETSDatePlease extends App.Events.BaseEvent {
 		App.Events.addParagraph(node, t);
 		t = [];
 
-		t.push(`"Thank you, ${master}" ${he} ${say}s. ${Spoken(eventSlave, `"I would like to do something for ${subSlave.slaveName}."`)} You ask if ${he}'s worried about ${his} ${partner} for some reason. "Oh no, ${master}", ${he} answers hurriedly.`);
+		t.push(`"Thank you, ${master}" ${he} ${say}s. ${Spoken(eventSlave, `"I would like to do something for`)}`);
+		t.push(App.UI.DOM.combineNodes(App.UI.DOM.slaveDescriptionDialog(subSlave, Spoken(eventSlave, subSlave.slaveName)), `."`));
+		t.push(`You ask if ${he}'s worried about ${his} ${partner} for some reason. "Oh no, ${master}", ${he} answers hurriedly.`);
 		t.push(Spoken(eventSlave, `"No, no, that came out wrong. It's just that I love ${him2} and I want to, you know, get ${him2} something or do something special for ${him2}. We don't really have stuff of our own, so I can't give ${him2} a present, and we already do everything either one of us wants in bed, so I can't really think of anything."`));
 		t.push(`${He} ${canSee(eventSlave) ? `looks` : `gazes`} at you hopefully.`);
 
@@ -97,7 +99,7 @@ App.Events.RETSDatePlease = class RETSDatePlease extends App.Events.BaseEvent {
 			t = [];
 			t.push(`It costs you a small sum in upkeep and other trifles to cover an unexpected unavailability of both slaves, but they deserve it, and your Attendant does not disappoint. After the slaves have soaked in the main pool for a while, ${he3} gives them a series of mud packs, hot rock massages, and skin treatments, always setting them up right next to each other. They chat a bit at first, but soon relax into companionable silence, ${hasAnyArms(eventSlave) && hasAnyArms(subSlave) ? "holding hands and enjoying" : "side by side to enjoy"} the pampering.`);
 			if (S.Attendant.lactation > 0) {
-				t.push(`${S.Attendant.slaveName} has their evening meal sent down, and supplements it with milk drunk fresh from ${his3} own nipples.`);
+				t.push(`${S.Attendant.slaveName} has their evening meal sent down, and supplements it with ${S.Attendant.milkFlavor === "none" ? `` : `${S.Attendant.milkFlavor} flavored `}milk drunk fresh from ${his3} own nipples.`);
 			}
 			t.push(`This being your penthouse, ${his3} services become quite sexual later in the night, as the Attendant applies all ${his3} talents in choosing positions that emphasize ${eventSlave.slaveName} and ${subSlave.slaveName} being close to each other, a difficult task given`);
 			if (S.Attendant.bellyPreg >= 10000 && eventSlave.bellyPreg >= 10000 && subSlave.bellyPreg >= 10000) {
diff --git a/src/events/RETS/reFucktoyPrefersRelative.js b/src/events/RETS/reFucktoyPrefersRelative.js
index 07d87b12ba3ae291c869c464d9b04be1c8a8c7db..ca2a8b3855b7277e4b861bab61a9a9abfbd0701f 100644
--- a/src/events/RETS/reFucktoyPrefersRelative.js
+++ b/src/events/RETS/reFucktoyPrefersRelative.js
@@ -197,7 +197,7 @@ App.Events.RETSFucktoyPrefersRelative = class RETSFucktoyPrefersRelative extends
 			fucktoy.devotion += 4;
 			fucktoy.trust -= 4;
 			if (fucktoy.fetish === "submissive" && fucktoy.fetishKnown === 1) {
-				t.push(`Still, when you glance down, you catch the faintest hint of a smile; it seems your punishment appealed to him, <span class="fetish inc">reinforcing ${his} submission</span> to your will.`);
+				t.push(`Still, when you glance down, you catch the faintest hint of a smile; it seems your punishment appealed to ${him}, <span class="fetish inc">reinforcing ${his} submission</span> to your will.`);
 				fucktoy.fetishStrength += 10;
 			} else {
 				t.push(`${His} suppression of ${his} attraction naturally leads to a <span class="libido dec">decrease in ${his} libido</span> and <span class="stat drop">attraction to ${women2}.</span>`);
diff --git a/src/events/RETS/reIncestuousNursing.js b/src/events/RETS/reIncestuousNursing.js
index 9ed50150a3424ea8db11fed75020c457986acdde..d61a97e1d863dd5194cbf38e419326d61d41692e 100644
--- a/src/events/RETS/reIncestuousNursing.js
+++ b/src/events/RETS/reIncestuousNursing.js
@@ -73,7 +73,7 @@ App.Events.RETSIncestuousNursing = class RETSIncestuousNursing extends App.Event
 		App.Events.addParagraph(node, t);
 		t = [];
 
-		t.push(`${subSlave.slaveName} is nursing, lustily sucking at one of ${eventSlave.slaveName}'s breasts, ${his2} ${subSlave.skin} throat bobbing as ${he2} swallows gulp after gulp of ${his2} ${mother}'s milk.`);
+		t.push(`${subSlave.slaveName} is nursing, lustily sucking at one of ${eventSlave.slaveName}'s breasts, ${his2} ${subSlave.skin} throat bobbing as ${he2} swallows gulp after gulp of ${his2} ${mother}'s ${milkFlavor(eventSlave)}milk.`);
 		App.Events.addParagraph(node, t);
 		t = [];
 
@@ -419,7 +419,7 @@ App.Events.RETSIncestuousNursing = class RETSIncestuousNursing extends App.Event
 			const frag = document.createDocumentFragment();
 			t = [];
 
-			t.push(`${eventSlave.slaveName} and ${subSlave.slaveName} are properly trained sex slaves, and you wonder whether they still understand exactly how perverted it is to, respectively, nurse one's adult child while getting masturbated by ${him2}, and drink one's ${mother}'s milk while playing with ${his} private parts. So, you decide to explain it to them. You start with ${eventSlave.slaveName}, cuttingly asking whether ${he} understands that ${his} relationship with ${his} ${daughter2} is irrevocably polluted by incest.`);
+			t.push(`${eventSlave.slaveName} and ${subSlave.slaveName} are properly trained sex slaves, and you wonder whether they still understand exactly how perverted it is to, respectively, nurse one's adult child while getting masturbated by ${him2}, and drink one's ${mother}'s ${milkFlavor(eventSlave)}milk while playing with ${his} private parts. So, you decide to explain it to them. You start with ${eventSlave.slaveName}, cuttingly asking whether ${he} understands that ${his} relationship with ${his} ${daughter2} is irrevocably polluted by incest.`);
 			if (eventSlave.fetish === "humiliation") {
 				if (eventSlave.fetishKnown) {
 					t.push(`Getting ${his} nipples sucked on and ${his} ${hands} played with by ${his} own ${daughter2} out in the open already had the humiliation slut's cheeks flaming with shame and arousal, and your words are so deliciously crushing that ${he} gasps once, twice, and then, on ${his} ${daughter2}'s next stroke with ${his2} hand, climaxes, crying with <span class="devotion inc">abject overstimulation.</span>`);
diff --git a/src/events/RETS/reTasteTest.js b/src/events/RETS/reTasteTest.js
index 1e57dcfbdb1928f1fce9b365f33dc30546d9c33f..93e774c2421505406c3cd905f88e7fdc95cfb2bd 100644
--- a/src/events/RETS/reTasteTest.js
+++ b/src/events/RETS/reTasteTest.js
@@ -149,7 +149,7 @@ App.Events.RETSTasteTest = class RETSTasteTest extends App.Events.BaseEvent {
 					t.push(`of ${his2} ${subSlave.inflationType}-filled belly gurgling`);
 				}
 			} else if (subSlave.lactation > 1) {
-				t.push(`of the milk dripping from ${his2} nipples`);
+				t.push(`of the ${subSlave.milkFlavor === "none" ? `` : `${subSlave.milkFlavor} flavored `}milk dripping from ${his2} nipples`);
 			} else {
 				t.push(`of ${his2} bare skin against the cool air`);
 			}
diff --git a/src/events/assistant/assistantFS.js b/src/events/assistant/assistantFS.js
index 76311051b0e72bfd1a88c9c8242aa9e9c5b10e0d..2e5caa9ccaa215605ed274405bac1d4df72831fc 100644
--- a/src/events/assistant/assistantFS.js
+++ b/src/events/assistant/assistantFS.js
@@ -74,7 +74,7 @@ App.Events.assistantFS = class assistantFS extends App.Events.BaseEvent {
 			case "schoolgirl":
 				r.push(`studently appearance`);
 		}
-		r.push(`of your personal assistant pops up on the nearest screen. "${properTitle()}!" ${HeA} says excitedly, "I thought, with how you are shaping society itself, that I should do my part and follow your lead!" You continue to stare sleepily, prompting ${himA} to get to ${hisA} point. "I can adjust my appearance to better fit in with your society, ${properTitle()}; let me demonstrate." ${HeA} focuses intently for a moment and`);
+		r.push(`of your personal assistant pops up on the nearest screen. "${properTitle()}!" ${HeA} says excitedly, "I thought, with how you are shaping society itself, that I should do my part and follow your lead!" You continue to stare sleepily, prompting ${himA} to get to ${hisA} point. "I can adjust my appearance to better fit in with your society, ${properTitle()} – let me demonstrate." ${HeA} focuses intently for a moment and`);
 		switch (V.assistant.appearance) {
 			case "monstergirl":
 				if (V.arcologies[0].FSPaternalist !== "unset") {
diff --git a/src/events/assistant/assistantSP.js b/src/events/assistant/assistantSP.js
index c8a946736294a37d750d49db98ca54d8df2944b0..5c5810746f9bc073220f8ed56727c4757e18f9fa 100644
--- a/src/events/assistant/assistantSP.js
+++ b/src/events/assistant/assistantSP.js
@@ -19,7 +19,7 @@ App.Events.assistantSP = class assistantSP extends App.Events.BaseEvent {
 		let r = [];
 		V.assistant.options = 1;
 
-		const slave = V.slaves.find(s => s.rules.release.masturbation === 1 || s.assignment === Job.CLASSES) || V.slaves.random();
+		const slave = V.slaves.find(s => (s.vagina > 0 || s.anus > 0) && s.rules.release.masturbation === 1) || V.slaves.random();
 		const {him} = getPronouns(slave);
 
 		App.Events.drawEventArt(node, "assistant");
diff --git a/src/events/eventUtils.js b/src/events/eventUtils.js
index 53d3662e6756787e47207efeb51c0ffb6d070149..32f70e094a0391540a8800278193bde4f02fff04 100644
--- a/src/events/eventUtils.js
+++ b/src/events/eventUtils.js
@@ -57,30 +57,35 @@ App.Events.drawEventArt = (function() {
 		let artSpan = document.createElement("span");
 		artSpan.id = "art-frame";
 		if (slaves.length === 1) {
-			let refDiv = document.createElement("div");
-			refDiv.classList.add("imageRef", V.imageChoice === 1 ? "lrgVector" : "lrgRender");
-			let maskDiv = document.createElement("div");
-			maskDiv.classList.add("mask");
-			maskDiv.appendChild(document.createTextNode("\u00a0"));
-			refDiv.appendChild(maskDiv);
-			if (slaves[0] === "assistant") {
-				refDiv.appendChild(App.Art.assistantArt(3));
-			} else {
-				refDiv.appendChild(App.Art.SlaveArtElement(slaves[0], 3, 0));
+			const slave = slaves[0];
+			if (!V.seeCustomImagesOnly ||
+			(slaves[0] === "assistant" && V.assistant.customImage) ||
+			(typeof slave !== "string" && slave.custom.image && slave.custom.image.filename !== "")) {
+				let refDiv = document.createElement("div");
+				refDiv.classList.add("imageRef", V.imageChoice === 1 ? "lrgVector" : "lrgRender");
+				if (slaves[0] === "assistant") {
+					refDiv.appendChild(App.Art.assistantArt(3));
+				} else {
+					refDiv.appendChild(App.Art.SlaveArtElement(slaves[0], 3, 0));
+				}
+				artSpan.appendChild(refDiv);
 			}
-			artSpan.appendChild(refDiv);
 		} else {
 			let colDiv = document.createElement("div");
 			colDiv.classList.add("imageColumn");
 			for (const slave of slaves) {
-				let refDiv = document.createElement("div");
-				refDiv.classList.add("imageRef", "medImg");
-				if (slave === "assistant") {
-					refDiv.appendChild(App.Art.assistantArt(2));
-				} else {
-					refDiv.appendChild(App.Art.SlaveArtElement(slave, 2, 0));
+				if (!V.seeCustomImagesOnly ||
+					(slave === "assistant" && V.assistant.customImage) ||
+					(typeof slave !== "string" && slave.custom.image && slave.custom.image.filename !== "")) {
+					let refDiv = document.createElement("div");
+					refDiv.classList.add("imageRef", "medImg");
+					if (slave === "assistant") {
+						refDiv.appendChild(App.Art.assistantArt(2));
+					} else {
+						refDiv.appendChild(App.Art.SlaveArtElement(slave, 2, 0));
+					}
+					colDiv.appendChild(refDiv);
 				}
-				colDiv.appendChild(refDiv);
 			}
 			artSpan.appendChild(colDiv);
 		}
diff --git a/src/events/gameover.js b/src/events/gameover.js
index d06aa105de5d446c8d12046919dea1c6d55d7228..b0a52f4e6836da9a771fe130de0cc670b7d62bc5 100644
--- a/src/events/gameover.js
+++ b/src/events/gameover.js
@@ -84,6 +84,10 @@ App.Events.Gameover = function() {
 		case "starving citizens":
 			r.push(`You made a promise to your citizens that you would be able to keep them fed, and you had been able to keep that promise – until now, that is. Your food storages have been depleted and you don't have enough money to buy enough to feed the rest of the hungry arcology. Desperate and facing starvation, your once-loyal subjects have taken to the streets, eventually finding their way to your penthouse.${V.arcologyUpgrade.drones ? ` Your drones are only able to keep them at bay for a little while before the sheer number of them overwhelms your defenses.` : ``} Your attempts to calm the crowd fail, and you find yourself wishing you had run when you had the chance as you are grabbed by the crowd and thrown through the nearest window.`);
 			break;
+		case "loanshark":
+			r.push(`You signed a contract with a loanshark, and since you weren't able to pay the debt off, he now technically owns you. – What the man plans to do with a former arcology owner remains to be seen.`);
+			V.slavePC = convertPlayerToSlave(V.PC);
+			break;
 		default:
 			r.push(`Since you are without slaves, Free Cities society no longer considers you a citizen of the first rank. Your personal story may continue, but that part of it worthy of retelling has now ended.`);
 	}
diff --git a/src/events/intro/acquisition.js b/src/events/intro/acquisition.js
index 80c3dfc450b0df8143b82875cc7a2caae2597926..23330f02e9424538ee8825da50c6bb059509715b 100644
--- a/src/events/intro/acquisition.js
+++ b/src/events/intro/acquisition.js
@@ -20,7 +20,7 @@ App.Intro.acquisition = function() {
 	inbreedingCalc();
 	if (V.plot === 1 && V.neighboringArcologies > 0) {
 		V.arcologies.reduce((acc, val) => (val.direction !== 0 && val.prosperity > acc.prosperity) ? val : acc, V.arcologies[1]).rival = 1;
-		V.rivalSet = 1;
+		V.rival.state = 2;
 	}
 	V.targetAge = V.minimumSlaveAge;
 	V.targetAgeNursery = V.minimumSlaveAge;
diff --git a/src/events/intro/customizeSlaveTrade.js b/src/events/intro/customizeSlaveTrade.js
index 162c1cd4ba14080795040adb8efb55b6a44f4fb1..fc381fb63760d45e4447fc3fd8a32e2af8fac9de 100644
--- a/src/events/intro/customizeSlaveTrade.js
+++ b/src/events/intro/customizeSlaveTrade.js
@@ -209,7 +209,7 @@ App.Intro.CustomSlaveTrade = function() {
 			}
 		} else {
 			/* Filtered pop controls */
-			const controlsNationality = App.Data.misc.nationalitiesByRace[baseControlsFilter] || setup[baseControlsFilter + 'Nationalities'];
+			const controlsNationality = App.Data.misc.nationalitiesByRace[baseControlsFilter] || App.Data.misc[baseControlsFilter + 'Nationalities'];
 			const keys = Object.keys(controlsNationality);
 			for (const nation of keys) {
 				const li = document.createElement("LI");
diff --git a/src/events/intro/initNationalities.js b/src/events/intro/initNationalities.js
index ff6d21299563388dc4be7a3249ec9bf2d4bb6a5c..4ddc3e8ef7d462bbc5cb61fffdbda0a69d38f41f 100644
--- a/src/events/intro/initNationalities.js
+++ b/src/events/intro/initNationalities.js
@@ -47,12 +47,12 @@ App.Intro.initNationalities = function() {
 				addTrinket("an artist's impression of an early arcology design");
 				V.arcologyUpgrade.drones = 1;
 				V.arcologyUpgrade.hydro = 1;
-				App.SecExp.unit.gen("bots", true);
+				App.Mods.SecExp.unit.gen("bots", true);
 				break;
 			case "construction":
 				addTrinket("the blueprints of a proto-arcology you helped construct");
 				V.arcologyUpgrade.drones = 1;
-				App.SecExp.unit.gen("bots", true);
+				App.Mods.SecExp.unit.gen("bots", true);
 				break;
 			case "worksite helper":
 				addTrinket("the hardhat you used to wear around worksites");
@@ -422,7 +422,7 @@ App.Intro.initNationalities = function() {
 	const random12 = jsRandomMany(sellable, 12);
 	random12.forEach(cell => { cell.owner = 0; });
 
-	App.SecExp.generalInit();
+	App.Mods.SecExp.generalInit();
 
 	if (V.localEcon > 100) {
 		V.mods.food.cost = Math.max(5 / (1 + (Math.trunc(1000-100000/V.localEcon)/10)/100), 3.125);
@@ -473,7 +473,7 @@ App.Intro.initNationalities = function() {
 		const continentalDefaults = new Map([
 			["North America",	{supr: "white", subj: "black", preset: "Vanilla North America"}],
 			["South America",	{supr: "latina", subj: "black", preset: "Vanilla South America"}],
-			["Brazil",			{supr: "white", subj: "black", preset: "Vanilla Brazil"}],
+			["Brazil",			{supr: "white", subj: "black", preset: "Vanilla South America"}],
 			["the Middle East",	{supr: "middle eastern", subj: "asian", preset: "Vanilla Middle East"}],
 			["Africa",			{supr: "black", subj: "white", preset: "Vanilla Africa"}],
 			["Asia",			{supr: "asian", subj: "indo-aryan", preset: "Vanilla Asia"}],
diff --git a/src/events/intro/introSummary.js b/src/events/intro/introSummary.js
index d41fe93143a09b04072a4c9f46d0d3aa6964f973..ba6b070a335999eaf7401a6d3d2094310b56ce42 100644
--- a/src/events/intro/introSummary.js
+++ b/src/events/intro/introSummary.js
@@ -10,6 +10,19 @@ App.Intro.summary = function() {
 
 	V.minimumSlaveAge = variableAsNumber(V.minimumSlaveAge, 3, 18, 18);
 	V.retirementAge = variableAsNumber(V.retirementAge, 25, 120, 45);
+	let minAge = V.minimumSlaveAge;
+	let maxAge = V.retirementAge - 1 > 60 ? 60 : V.retirementAge - 1;
+	let defaultAge = 18;
+	if(V.targetArcology.fs === "FSMaturityPreferentialist") {
+		minAge = 30;
+		defaultAge = 30;
+	}
+	else if(V.targetArcology.fs === "FSYouthPreferentialist") {
+		maxAge = 29;
+	}
+	V.idealAge = variableAsNumber(V.idealAge, minAge, maxAge, defaultAge);
+	V.targetIdealAge = V.idealAge;
+
 	V.fertilityAge = variableAsNumber(V.fertilityAge, 3, 18, 13);
 	V.potencyAge = variableAsNumber(V.potencyAge, 3, 18, 13);
 	V.PC.mother = Number(V.PC.mother);
@@ -173,8 +186,8 @@ App.Intro.summary = function() {
 								V.PC.skill.trading = -25;
 								V.PC.skill.warfare = -50;
 								V.PC.skill.slaving = -25;
-								V.PC.skill.engineering = 50;
-								V.PC.skill.medicine = -25;
+								V.PC.skill.engineering = -25;
+								V.PC.skill.medicine = 50;
 								V.PC.skill.hacking = -20;
 								V.PC.muscles = 0;
 								break;
@@ -609,6 +622,10 @@ App.Intro.summary = function() {
 		options.addOption("Initial retirement age will be at", "retirementAge")
 			.addComment("May cause issues with New Game and initial slaves if set below 45.").showTextBox();
 
+		V.idealAge = Math.clamp(V.idealAge, minAge, maxAge);
+		options.addOption("Prime age of sexual appeal", "idealAge")
+			.addComment("Perceived beauty will decrease the farther (younger or older) one's appearance is from the ideal.").showTextBox();
+
 		V.fertilityAge = Math.clamp(V.fertilityAge, 3, 18);
 		options.addOption("Girls will not be able to become pregnant if their age is under", "fertilityAge").showTextBox();
 
diff --git a/src/events/intro/newGamePlusPassage.js b/src/events/intro/newGamePlusPassage.js
index 14b371992b12e618075307bebe207cce07388fb8..a7fa901b07841b53d50a7baac81df3290ef671e6 100644
--- a/src/events/intro/newGamePlusPassage.js
+++ b/src/events/intro/newGamePlusPassage.js
@@ -12,7 +12,7 @@ App.Intro.newGamePlus = function() {
 	App.UI.DOM.appendNewElement("p", node, `You have decided to start over and will be able to take a few things with you: a few slaves, a small fraction of your current reserves of money, and possibly even your experience as an arcology owner, which will give you a very powerful career background. Many of your other customizations and settings will be carried over as the defaults for your new game, but can be revised freely.`);
 
 	if (V.cash >= fee) {
-		App.Events.addNode(node, [`You have allocated funds to bring up to ${V.slavesToImportMax} slaves with you (or your equivalent) to a new arcology. It will cost <span class="yellowgreen">${cashFormat(fee)}</span> to insure another slave's safe transfer. You have <span class="yellowgreen">${cashFormat(V.cash)}</span> to spend.`], "div");
+		App.Events.addNode(node, [`You have allocated funds to bring up to ${V.slavesToImportMax} slaves with you (or your equivalent) to a new arcology. It will cost <span class="yellowgreen">${cashFormat(fee)}</span> to ensure another slave's safe transfer. You have <span class="yellowgreen">${cashFormat(V.cash)}</span> to spend.`], "div");
 		App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
 			"Increase slave import capacity by 1.",
 			() => {
diff --git a/src/events/intro/pcAppearance.js b/src/events/intro/pcAppearance.js
index 07206f540ecaa094af3377bc5e6e9acaa6f3e551..85d9523f96babf0c6f83fa72deebcd684ee8afd6 100644
--- a/src/events/intro/pcAppearance.js
+++ b/src/events/intro/pcAppearance.js
@@ -33,11 +33,11 @@ App.UI.Player.appearance = function(options, summary = false) {
 		);
 
 	options.addOption("Your skin tone is", "skin", V.PC).showTextBox()
-		.addValueList(makeAList(App.Medicine.Modification.naturalSkins));
+		.addValueList(makeAList(V.PC.race === "catgirl" ? App.Medicine.Modification.catgirlNaturalSkins : App.Medicine.Modification.naturalSkins));
 
 	if (V.cheatMode) {
 		options.addOption("Your genetic skin tone is", "origSkin", V.PC).showTextBox()
-			.addValueList(makeAList(App.Medicine.Modification.naturalSkins));
+			.addValueList(makeAList(V.PC.race === "catgirl" ? App.Medicine.Modification.catgirlNaturalSkins : App.Medicine.Modification.naturalSkins));
 	}
 
 	if (V.cheatMode) {
diff --git a/src/events/intro/terrainIntro.js b/src/events/intro/terrainIntro.js
index d9aa6ce2347382b8b41731c83d916851890e0da5..bccd6131a31fcc8c73942d6243621861e070c10d 100644
--- a/src/events/intro/terrainIntro.js
+++ b/src/events/intro/terrainIntro.js
@@ -1,3 +1,15 @@
+/**
+ * @typedef FC.ArcologyLocation
+ *
+ * @property {string} name
+ * @property {string} value
+ * @property {string} [market]
+ * @property {string} [commerce]
+ * @property {string} [refugees]
+ * @property {string} [culture]
+ * @property {string[]} [notes]
+ */
+
 App.Intro.terrainIntro = function() {
 	//	:: Terrain Intro [nobr]
 	const node = new DocumentFragment();
@@ -12,67 +24,104 @@ App.Intro.terrainIntro = function() {
 
 	App.UI.DOM.appendNewElement("p", node, `Which kind of Free City hosts your arcology?`, ["intro", "question"]);
 
-	let card = App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink(
-		"Urban",
-		"Location Intro",
-		() => V.terrain = "urban"
-	), "card");
-	cardLine(`<span class="noteworthy">Low</span> minimum slave value and initial <span class="noteworthy">bear market</span> for slaves.`);
-	cardLine(`<span class="positive">High</span> ease of commerce with the old world.`);
-	cardLine(`<span class="positive">High</span> access to refugees and other desperate people.`);
-	cardLine(`<span class="warning">Low</span> cultural independence.`);
-	cardLine(`Unusually compact arcology with few manufacturing sectors.`);
-
-	card = App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink(
-		"Rural",
-		"Location Intro",
-		() => V.terrain = "rural"
-	), "card");
-	cardLine(`High</span> minimum slave value and initial <span class="noteworthy">bull market</span> for slaves.`);
-	cardLine(`Moderate ease of commerce with the old world.`);
-	cardLine(`Moderate access to refugees and other desperate people.`);
-	cardLine(`Moderate cultural independence.`);
-	cardLine(`Widespread arcology with many manufacturing sectors.`);
-
-	card = App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink(
-		"Ravine",
-		"Location Intro",
-		() => V.terrain = "ravine"
-	), "card");
-	cardLine(`<span class="noteworthy">High</span> minimum slave value and initial <span class="noteworthy">bull market</span> for slaves.`);
-	cardLine(`<span class="warning">Low</span> ease of commerce with the old world.`);
-	cardLine(`<span class="warning">Very low</span> access to refugees and other desperate people.`);
-	cardLine(`<span class="positive">High</span> cultural independence.`);
-	cardLine(`The arcology mostly being hidden inside the ravine leads to an unusual layout.`);
-
-	card = App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink(
-		"Marine",
-		"Location Intro",
-		() => V.terrain = "marine"
-	), "card");
-	cardLine(`Moderate minimum slave value and initially balanced market for slaves.`);
-	cardLine(`Moderate ease of commerce with the old world.`);
-	cardLine(`<span class="warning">Low</span> access to refugees and other desperate people.`);
-	cardLine(`<span class="positive">High</span> cultural independence.`);
-	cardLine(`Large amount of markets and an extra shop sector.`);
-
-	card = App.UI.DOM.appendNewElement("div", node, App.UI.DOM.passageLink(
-		"Oceanic",
-		"Location Intro",
-		() => V.terrain = "oceanic"
-	), "card");
-	cardLine(`<span class="noteworthy">High</span> minimum slave value and initial <span class="noteworthy">bull market</span> for slaves.`);
-	cardLine(`Moderate ease of commerce with the old world.`);
-	cardLine(`<span class="warning">Very low</span> access to refugees and other desperate people.`);
-	cardLine(`<span class="positive">Very high</span> cultural independence.`);
-	cardLine(`This unique location attracts the wealthy leading to initial luxury apartments.`);
-	cardLine(`Ensures access to slaves from all over the world and will not associate the arcology with a continent.`);
-	if (V.showSecExp === 1) {
-		cardLine(`Oceanic arcologies will not be subjects of attacks.`);
+	/** @type {FC.ArcologyLocation[]} */
+	const locations = [
+		{
+			name: `Urban`,
+			value: "urban",
+			market: `<span class="noteworthy">Low</span> minimum slave value and initial <span class="noteworthy">bear market</span> for slaves.`,
+			commerce: `<span class="positive">High</span> ease of commerce with the old world.`,
+			refugees: `<span class="positive">High</span> access to refugees and other desperate people.`,
+			culture: `<span class="warning">Low</span> cultural independence.`,
+			notes: [
+				`Unusually compact arcology with few manufacturing sectors.`,
+			],
+		},
+		{
+			name: `Rural`,
+			value: "rural",
+			market: `<span class="noteworthy">High</span> minimum slave value and initial <span class="noteworthy">bull market</span> for slaves.`,
+			commerce: `Moderate ease of commerce with the old world.`,
+			refugees: `Moderate access to refugees and other desperate people.`,
+			culture: `Moderate cultural independence.`,
+			notes: [
+				`Widespread arcology with many manufacturing sectors.`,
+			],
+		},
+		{
+			name: `Ravine`,
+			value: "ravine",
+			market: `<span class="noteworthy">High</span> minimum slave value and initial <span class="noteworthy">bull market</span> for slaves.`,
+			commerce: `<span class="warning">Low</span> ease of commerce with the old world.`,
+			refugees: `<span class="warning">Very low</span> access to refugees and other desperate people.`,
+			culture: `<span class="positive">High</span> cultural independence.`,
+			notes: [
+				`The arcology mostly being hidden inside the ravine leads to an unusual layout.`,
+			],
+		},
+		{
+			name: `Marine`,
+			value: "marine",
+			market: `Moderate minimum slave value and initially balanced market for slaves.`,
+			commerce: `Moderate ease of commerce with the old world.`,
+			refugees: `<span class="warning">Low</span> access to refugees and other desperate people.`,
+			culture: `<span class="positive">High</span> cultural independence.`,
+			notes: [
+				`Large amount of markets and an extra shop sector.`,
+			],
+		},
+		{
+			name: `Oceanic`,
+			value: "oceanic",
+			market: `<span class="noteworthy">High</span> minimum slave value and initial <span class="noteworthy">bull market</span> for slaves.`,
+			commerce: `Moderate ease of commerce with the old world.`,
+			refugees: `<span class="warning">Very low</span> access to refugees and other desperate people.`,
+			culture: `<span class="positive">Very high</span> cultural independence.`,
+			notes: [
+				`This unique location attracts the wealthy leading to initial luxury apartments.`,
+				`Ensures access to slaves from all over the world and will not associate the arcology with a continent.`,
+				V.showSecExp ? `Oceanic arcologies will not be subjects of attacks.` : ``
+			],
+		},
+	];
+
+	const div = document.createElement("div");
+
+	for (const location of locations) {
+		div.append(locationCard(location));
 	}
 
-	function cardLine(string) {
-		App.Events.addNode(card, [string], "div", "indent");
+	node.append(div);
+
+	/** @param {FC.ArcologyLocation} location */
+	function locationCard(location) {
+		const div = App.UI.DOM.makeElement("div", null, ['card']);
+		const keys = ["market", "commerce", "refugees", "culture", "notes"];
+
+		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.passageLink(
+			location.name,
+			"Location Intro",
+			() => V.terrain = location.value,
+		));
+
+		keys
+			.filter(key => location.hasOwnProperty(key))
+			.forEach(key => {
+				const innerDiv = App.UI.DOM.makeElement("div", null, ['indent']);
+				const item = location[key];
+
+				if (Array.isArray(item)) {
+					item.forEach(n => {
+						innerDiv.append(App.UI.DOM.makeElement("div", n, ['note']));
+					});
+				} else {
+					innerDiv.innerHTML = item;
+				}
+
+				div.append(innerDiv);
+			});
+
+		return div;
 	}
 
 	if (V.showSecExp === 1) {
diff --git a/src/events/nonRandom/daughters/pCoupAftermath.js b/src/events/nonRandom/daughters/pCoupAftermath.js
index 0977e320c6994ddd357a3a61ea9c49834e3288b2..4db08a287273c8e57c3dd522c3109478a114dd04 100644
--- a/src/events/nonRandom/daughters/pCoupAftermath.js
+++ b/src/events/nonRandom/daughters/pCoupAftermath.js
@@ -3,20 +3,14 @@ App.Events.PCoupAftermath = class PCoupAftermath extends App.Events.BaseEvent {
 		let r = [];
 
 		V.nextButton = " "; // hide button until user makes a selection
-		V.rivalOwner = 0;
-		V.rivalryPower = 0;
-		if (random(0, 99) <= V.seeDicks) {
-			V.rivalGender = 2;
-		} else {
-			V.rivalGender = 1;
-		}
+		V.rival.gender = random(0, 99) <= V.seeDicks ? 2 : 1;
 		const {
 			HeR,
 			heR, himR,
-		} = getPronouns({pronoun: (V.rivalGender === 2) ? App.Data.Pronouns.Kind.male : App.Data.Pronouns.Kind.female}).appendSuffix("R");
+		} = getPronouns({pronoun: (V.rival.gender === 2) ? App.Data.Pronouns.Kind.male : App.Data.Pronouns.Kind.female}).appendSuffix("R");
 		const {heA} = getPronouns(assistant.pronouns().main).appendSuffix("A");
 
-		const rivalArc = (V.rivalSet !== 0) ? V.arcologies.find(arc => arc.rival === 1) : null;
+		const rivalArc = V.rival.state === 2 ? V.arcologies.find(arc => arc.rival === 1) : null;
 		V.fcnn.push("...evidence also suggests that the Daughters of Liberty had also planned a terrorist attack on...");
 
 		if (V.mercenaries > 3) {
@@ -31,12 +25,12 @@ App.Events.PCoupAftermath = class PCoupAftermath extends App.Events.BaseEvent {
 		r.push(`perform the grisly task of disposing of the bodies of the Daughters killed in the assault. They strip them of anything that might be of use in cleaning up after the attempted coup — communication devices, PDAs, computers, even handwritten notes. The raw intel is scanned and passed to ${V.assistant.name}. Most of it is rubbish.`);
 		App.Events.addParagraph(node, r);
 		r = [];
-		r.push(`Some of it is not. There is evidence of payments from a ${V.rivalSet === 0 ? "nearby Free City" : "neighboring arcology"} to the leadership of the Daughters. ${capFirstChar(V.assistant.name)} is silent for a long time, crosschecking records to assemble a complete picture despite your enemies' attempts to disguise the transactions. Finally, ${V.assistant.name} finishes and displays a picture, using nearly the entire surface of your desk for effect.`);
+		r.push(`Some of it is not. There is evidence of payments from a ${V.rival.state < 2 ? "nearby Free City" : "neighboring arcology"} to the leadership of the Daughters. ${capFirstChar(V.assistant.name)} is silent for a long time, crosschecking records to assemble a complete picture despite your enemies' attempts to disguise the transactions. Finally, ${V.assistant.name} finishes and displays a picture, using nearly the entire surface of your desk for effect.`);
 		if (V.assistant.personality > 0) {
 			r.push(`"This," ${heA} says in a tone of satisfaction, "is the`);
-			if (V.rivalGender === 2) {
+			if (V.rival.gender === 2) {
 				r.push(`bastard`);
-			} else if (V.rivalGender === 1) {
+			} else if (V.rival.gender === 1) {
 				r.push(`bitch`);
 			} else {
 				r.push(`cunt`);
@@ -47,9 +41,9 @@ App.Events.PCoupAftermath = class PCoupAftermath extends App.Events.BaseEvent {
 		}
 
 		r.push(`The face is vigorous, determined, and`);
-		if (V.rivalGender === 2) {
+		if (V.rival.gender === 2) {
 			r.push(`masculine. The very stereotype of the male arcology owner.`);
-		} else if (V.rivalGender === 1) {
+		} else if (V.rival.gender === 1) {
 			r.push(`feminine. The very stereotype of the female arcology owner.`);
 		} else {
 			r.push(`androgynous. The very stereotype of the dissolute arcology owner.`);
@@ -57,7 +51,7 @@ App.Events.PCoupAftermath = class PCoupAftermath extends App.Events.BaseEvent {
 		if (rivalArc) {
 			r.push(
 				`And, as you suspected, it's one of your neighbors. It's the individual who owns`,
-				App.UI.DOM.makeElement("span", `${rivalArc.name}.`, "bold")
+				App.UI.DOM.makeElement("span", `${rivalArc.name}.`, ["bold"])
 			);
 			App.Events.addParagraph(node, r);
 			r = [];
@@ -70,8 +64,8 @@ App.Events.PCoupAftermath = class PCoupAftermath extends App.Events.BaseEvent {
 		App.Events.addParagraph(node, r);
 		r = [];
 		r.push(`You inquire as to whether there's any identifiable cause for the evident dislike.`);
-		if (V.rivalryFS !== 0) {
-			r.push(`"Definitely," says your assistant. "The most cursory review of the recent history of this Free City shows that divergence began with your selection of ${V.rivalryFS} as a society model for the future. They immediately went the opposite direction."`);
+		if (V.rival.FS.name !== "") {
+			r.push(`"Definitely," says your assistant. "The most cursory review of the recent history of this Free City shows that divergence began with your selection of ${V.rival.FS.name} as a society model for the future. They immediately went the opposite direction."`);
 		} else {
 			r.push(`"No," says your assistant. "It may be that giving the Daughters an alternative target was necessary and you were simply unlucky. Alternatively, this may be envy of your success; of rising arcology owners, you have come farthest, fastest."`);
 		}
@@ -102,14 +96,14 @@ App.Events.PCoupAftermath = class PCoupAftermath extends App.Events.BaseEvent {
 			r.push(`Free Cities society is understandably reluctant to condemn, never mind depose, arcology owners. The precedent of removing one would be bad, even if the public brought enough strength together to accomplish it. Your evidence looks quite bad, but isn't so incontrovertible as to cause your fellow aristocrats to take such a drastic measure. Nonetheless, the public is aghast at the spectacle of an arcology owner funding an attack on another. Opinion <span class="rep inc">rallies</span> around you, and you even receive some discreet <span class="cash inc">donations,</span> delivered with the intimation that they are to be used against your enemy. There is stony silence from the Daughters' backer; today, you began a real inter-arcology war.`);
 			repX(1000, "war");
 			cashX(10000, "war");
-			V.rivalryPower = 1;
+			V.rival.power = 1;
 			if (rivalArc) {
 				rivalArc.embargo = 2;
 				rivalArc.embargoTarget = 0;
 				rivalArc.influenceTarget = 0;
-				V.rivalOwner = rivalArc.prosperity;
+				V.rival.prosperity = rivalArc.prosperity;
 			} else {
-				V.rivalOwner = V.arcologies[0].prosperity;
+				V.rival.prosperity = V.arcologies[0].prosperity;
 			}
 			App.Events.addParagraph(frag, r);
 			return frag;
@@ -121,14 +115,14 @@ App.Events.PCoupAftermath = class PCoupAftermath extends App.Events.BaseEvent {
 			unlock();
 			r.push(`The money flows out, and the information flows in. You are rewarded with a reasonably complete picture of your rival's operations. The intelligence will be extremely useful going forward, since by gathering it, you sent an unmistakable signal that you do not consider the matter closed. There is stony silence from the Daughters' backer; today, you began a real inter-arcology war. But, with this information, you can maintain it from a position of advantage.`);
 			cashX(-cashTrace, "war");
-			V.rivalryPower = 5;
+			V.rival.power = 5;
 			if (rivalArc) {
 				rivalArc.embargo = 3;
 				rivalArc.embargoTarget = 0;
 				rivalArc.influenceTarget = 0;
-				V.rivalOwner = rivalArc.prosperity;
+				V.rival.prosperity = rivalArc.prosperity;
 			} else {
-				V.rivalOwner = V.arcologies[0].prosperity;
+				V.rival.prosperity = V.arcologies[0].prosperity;
 			}
 			App.Events.addParagraph(frag, r);
 			return frag;
diff --git a/src/events/nonRandom/daughters/pCoupAttempt.js b/src/events/nonRandom/daughters/pCoupAttempt.js
index dc11d0da501712789824462ce89f745e87ff3063..9afd04086f21a5d62684d709ed9169481a215fe2 100644
--- a/src/events/nonRandom/daughters/pCoupAttempt.js
+++ b/src/events/nonRandom/daughters/pCoupAttempt.js
@@ -10,7 +10,7 @@ App.Events.PCoupAttempt = class PCoupAttempt extends App.Events.BaseEvent {
 
 		V.nextButton = "Continue";
 		V.daughtersVictory = 1;
-		const secExpUnits = App.SecExp.battle.activeUnits();
+		const secExpUnits = App.Mods.SecExp.battle.activeUnits();
 
 		if (V.traitor !== 0) {
 			const weeks = V.traitorWeeks - 1;
diff --git a/src/events/nonRandom/mercs/pMercsHelpCorp.js b/src/events/nonRandom/mercs/pMercsHelpCorp.js
index e49dc499966de0fe9e0267a09532940590625755..f4fe0b6264e5312303f2f7d0f65b1426c09d02b9 100644
--- a/src/events/nonRandom/mercs/pMercsHelpCorp.js
+++ b/src/events/nonRandom/mercs/pMercsHelpCorp.js
@@ -2,7 +2,7 @@ App.Events.PMercsHelpCorp = class PMercsHelpCorp extends App.Events.BaseEvent {
 	eventPrerequisites() {
 		return [
 			() => V.corp.Incorporated > 0,
-			() => V.rivalOwnerEnslaved > 0,
+			() => V.rival.state === 5,
 			() => V.mercenaries >= 3,
 			() => V.mercenariesHelpCorp === 0,
 			() => V.corp.DivExtra > 0,
diff --git a/src/events/nonRandom/pAbducted.js b/src/events/nonRandom/pAbducted.js
index 52e1c77032829a71448991af8ac3c42b9b1f60ba..a5a0d53948b362eb198d170a0ddeab53a93d7185 100644
--- a/src/events/nonRandom/pAbducted.js
+++ b/src/events/nonRandom/pAbducted.js
@@ -238,10 +238,16 @@ App.Events.pAbducted = class pAbducted extends App.Events.BaseEvent {
 				const r = [];
 				assignJob(abductor, "work as a farmhand");
 				cashX(forceNeg(contractCost), "slaveTransfer", abductor);
-				r.push(`You complete the legalities and biometric scanning quickly and cautiously. The idiot will wake up in ${V.farmyardName}, where ${he} will spend the rest of ${his} days working the fields`);
-				if (V.farmyardShows === 1) {
-					r.push(`and`);
-					if (V.seeBestiality === 1) {
+				r.push(`You complete the legalities and biometric scanning quickly and cautiously. The idiot will wake up in ${V.farmyardName}, where ${he} will spend the rest of ${his} days`);
+				if (V.farmyardShows < 2) {
+					r.push(`working the fields`);
+
+					if (V.farmyardShows > 0) {
+						r.push(`and`);
+					}
+				}
+				if (V.farmyardShows > 0) {
+					if (V.seeBestiality) {
 						r.push(`getting fucked by animals.`);
 					} else {
 						r.push(`putting on shows with animals.`);
diff --git a/src/events/nonRandom/pAidInvitation.js b/src/events/nonRandom/pAidInvitation.js
index 362de9d163440d1c0660f3c101f5895dfd401690..2c58bbc85e88c2e2bf88a35b82d9ab89f1250d29 100644
--- a/src/events/nonRandom/pAidInvitation.js
+++ b/src/events/nonRandom/pAidInvitation.js
@@ -11,14 +11,14 @@ App.Events.pAidInvitation = class pAidInvitation extends App.Events.BaseEvent {
 		return [
 			() => V.plot === 1,
 			() => V.week >= 29,
-			() => !V.eventResults.hasOwnProperty("aid")
+			() => !V.eventResults.aid
 		];
 	}
 
 	execute(node) {
 		const trapped = [];
 		let r = [];
-		V.eventResults.aid = 0; // Mark event as seen.
+		V.eventResults.aid = -2; // Mark event as seen.
 		if (V.seeDicks <= 75) {
 			trapped.push("convent");
 			trapped.push("school");
diff --git a/src/events/nonRandom/pInvasion.js b/src/events/nonRandom/pInvasion.js
index 6ca74de452ce7d91950d88b9585da1c59aae6181..0aa592ac02b2043400908087ea378b4e4d7ff7b5 100644
--- a/src/events/nonRandom/pInvasion.js
+++ b/src/events/nonRandom/pInvasion.js
@@ -4,13 +4,12 @@ App.Events.PInvasion = class PInvasion extends App.Events.BaseEvent {
 		V.nextButton = "Continue";
 		const newSlaves = [];
 		V.invasionVictory = 1;
-		V.peacekeepers = 0;
 		const {
 			HeA, HisA,
 			heA, hisA, womanA
 		} = getPronouns(assistant.pronouns().main).appendSuffix("A");
 
-		r.push(`The day that wasn't supposed to come is here. The troubled little country next door is falling apart. Last month, its stock market collapsed. Last week, its government fell. Yesterday, there was open looting in its cities. And today, a faction of disaffected citizens that blames the Free Cities for siphoning off business and causing the collapse seized weapons from unguarded army depots${(V.terrain === "marine" || V.terrain === "oceanic") ? ", armed merchant ships and private vessels, and are approaching the Free City over the water." : "and advanced towards your home."}`);
+		r.push(`The day that wasn't supposed to come is here. The troubled little country next door is falling apart. Last month, its stock market collapsed. Last week, its government fell. Yesterday, there was open looting in its cities. And today, a faction of disaffected citizens that blames the Free Cities for siphoning off business and causing the collapse seized weapons from unguarded army depots${(V.terrain === "marine" || V.terrain === "oceanic") ? ", armed merchant ships and private vessels, and are approaching the Free City over the water." : " and advanced towards your home."}`);
 
 		App.Events.addParagraph(node, r);
 		r = [];
diff --git a/src/events/nonRandom/pLoanshark.js b/src/events/nonRandom/pLoanshark.js
new file mode 100644
index 0000000000000000000000000000000000000000..2c7e064e7b991e726593b6f1b736a3398bdda9aa
--- /dev/null
+++ b/src/events/nonRandom/pLoanshark.js
@@ -0,0 +1,98 @@
+App.Events.pLoanshark = class pLoanshark extends App.Events.BaseEvent {
+	eventPrerequisites() {
+		return [
+			() => V.loans.some(loan => loan.name === 'shark' && loan.deadline === V.week)
+		];
+	}
+
+	execute(node) {
+		V.nextButton = " ";
+
+		const loan = V.loans.find(loan => loan.name === 'shark');
+
+		App.Events.addParagraph(node, [`You took out a loan from one of the local loansharks and the time has come to collect. You receive a notification from ${V.assistant.name} that an envoy and a detachment of mercenaries have arrived to see you, and after the group has been escorted in, the shark's representative clears his throat and begins.`]);
+		App.Events.addParagraph(node, [`"It states here in my records that you recently borrowed ${cashFormat(Math.trunc(loan.principal))} from my boss. It's time to fulfill your end of the deal."`]);
+
+		App.Events.addResponses(node, [
+			V.cash > loan.full
+				? new App.Events.Result(`Pay the man`, pay)
+				: new App.Events.Result(null, null, `You do not have enough cash to pay the loan back`),
+			V.slaves.some(slave => slaveCost(slave) > loan.full)
+				? new App.Events.Result(`Offer one of your slaves instead`, slave)
+				: new App.Events.Result(null, null, `You do not have any slaves valuable enough to cover the loan`),
+			new App.Events.Result(`Refuse`, refuse)
+		]);
+
+		function pay() {
+			cashX(forceNeg(loan.full), "loan");
+			V.loans.delete(V.loans.find(loan => loan.name === 'shark'));
+
+			V.nextButton = "Continue";
+			App.Utils.scheduleSidebarRefresh();
+
+			return `No sense in dragging this out. You roll your eyes and order ${V.assistant.name} to transfer the ¤. The envoy, satisfied that all is as it should be, gives a slight bow and a quick nod to his party. Without another word, the men turn on their heels and leave.`;
+		}
+
+		function slave() {
+			App.Events.addNode(node, [chooseSlave()]);
+			V.loans.delete(V.loans.find(loan => loan.name === 'shark'));
+
+			V.nextButton = "Continue";
+			App.Utils.scheduleSidebarRefresh();
+
+			return `With a slight tilt of your head, you inquire as to whether your lender would be willing to accept a different type of currency instead. The envoy nods and replies, "Yes, that would be acceptable – my patron has authorized me to make trades on his behalf."`;
+
+			function chooseSlave() {
+				const frag = App.UI.DOM.makeElement("div", null, ['margin-top']);
+
+				frag.append(`Choose a slave to send with the group:`);
+
+				V.slaves
+					.filter(slave => slaveCost(slave) > loan.full)
+					.sort((a, b) => slaveCost(a) - slaveCost(b))
+					.forEach(slave => {
+						const div = document.createElement("div");
+						const {him} = getPronouns(slave);
+
+						App.Events.addNode(div, [
+							App.UI.DOM.link(`Send `, () => {
+								App.UI.DOM.replace(frag, `You call ${SlaveFullName(slave)} in. After the representative has taken a moment to inspect ${him}, he nods in satisfaction and taps something on his tablet. A moment later you receive a notification that your debt with the lender has been concluded. The man turns to you once more. "It's been a pleasure," he says dryly. With that, the group departs, ${slave.slaveName} in tow.`);
+
+								removeSlave(slave);
+							}),
+							App.UI.DOM.slaveDescriptionDialog(slave, SlaveFullName(slave)),
+							` (worth ${cashFormat(slaveCost(slave))})`,
+						], "div", ['indent']);
+
+						frag.append(div);
+					});
+
+				return frag;
+			}
+		}
+
+		function refuse() {
+			const text = [];
+
+			if (V.cash > loan.full || V.slaves.some(slave => slaveCost(slave) > loan.full)) {
+				text.push(`You simply give the man a cold smile and cross your arms, a clear signal of defiance and refusal. The envoy gives a subtle signal to one of his compatriots, and the large soldier takes a step forward, restraints in hand. "As you know," the representative begins, "Anyone with significant enough debt is subject to enslavement, and the contract you signed with my employer states that you are now a slave. You're coming with us."`);
+			} else {
+				text.push(`Unfortunately, you're in a little over your head – you have neither the cash needed, nor any slaves valuable enough to cover the cost. Upon hearing this, the envoy nods, his face expressionless. "As you know," he starts, "Anyone with significant enough debt is subject to enslavement, and the contract you signed with my employer states that you are now a slave. You're coming with us."`);
+			}
+
+			if (S.Bodyguard) {
+				const {his, him} = getPronouns(S.Bodyguard);
+
+				text.push(`Your bodyguard, ${S.Bodyguard.slaveName}, draws ${his} pistol faster than you would have thought possible and manages to put a round into the nearest mercenary before the other soldiers gun ${him} down. Unarmed and defenseless, you have no choice but to surrender.`);
+			}
+
+			V.loans.delete(V.loans.find(loan => loan.name === 'shark'));
+			V.gameover = "loanshark";
+			V.nextButton = "Continue";
+			V.nextLink = "Gameover";
+			App.Utils.scheduleSidebarRefresh();
+
+			return text.join(' ');
+		}
+	}
+};
diff --git a/src/events/nonRandom/pRaped.js b/src/events/nonRandom/pRaped.js
index a818f265ec25133ef83c0c7ce8a07684af296f6c..9944294ed0282fe4b8e949b0894efa3e6a079922 100644
--- a/src/events/nonRandom/pRaped.js
+++ b/src/events/nonRandom/pRaped.js
@@ -32,6 +32,7 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 			rapist.waist = 50;
 			rapist.skill.oral = 0;
 			rapist.skill.anal = 0;
+			rapist.pronoun = 1; //janky workaround - reset later by repeating generatePronouns - reexamine in any diversePronouns rework
 		} else {
 			rapist = GenerateNewSlave("XX", genParam);
 			rapist.vagina = 1;
@@ -40,7 +41,7 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 			rapist.waist = -20;
 		}
 		rapist.muscles = Math.max(rapist.muscles, 10);
-		rapist.origin = `You sentenced $him to enslavement for the attempted rape of a free ${womanP}.`;
+		rapist.origin = `You sentenced $him to enslavement for the attempted rape of a free ${womanP} - you, to be exact.`;
 		rapist.devotion = -100;
 		rapist.trust = -100;
 		setHealth(rapist, jsRandom(-40, -20), normalRandInt(15, 3), undefined, 1, jsRandom(30, 80));
@@ -65,7 +66,7 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 				r.push(`over, but your body has grown a bit too unwieldy as of late, so you find yourself quickly outmaneuvered and held with a knife to your throat.`);
 			}
 		} else if (isPCCareerInCategory("slaver") || V.PC.skill.warfare >= 45) {
-			r.push(`The moment you notice an arm coming around from behind you does your training kick in.`);
+			r.push(`The moment you notice an arm coming around from behind you, your training kicks in.`);
 			if (!isHindered(V.PC)) {
 				r.push(`You quickly disarm the assailant and knock them to the floor before placing them in a choke-hold. Once they are subdued, you stand back to decide what to do next.`);
 				V.raped = 0;
@@ -104,184 +105,184 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 			if (V.PC.vagina >= 0) {
 				if (V.PC.butt > 4) {
 					r.push(Spoken(rapist, `"God, the way your fat ass is hugging my dick, you were just made to be bent over, weren't you?"`));
-					r.push(`he states matter of factly as ${he} pulls you closer.`);
+					r.push(`${he} states matter-of-factly as ${he} pulls you closer.`);
 				}
 				r.push(`With ${his} free hand, ${he} begins to explore your vulnerable body.`);
 				if (V.PC.weight > 130) {
 					r.push(Spoken(rapist, `"Normally I don't go for fatties, but for you, I think I can make an exception,"`));
-					r.push(`he chides as grinds against your soft form.`);
+					r.push(`${he} chides as ${he} grinds against your soft form.`);
 				} else if (V.PC.weight > 95) {
 					r.push(Spoken(rapist, `"Bit soon to be letting yourself go, isn't it?"`));
-					r.push(`he chides as grinds against your soft form.`);
+					r.push(`${he} chides as ${he} grinds against your soft form.`);
 				} else if (V.PC.weight > 30) {
 					r.push(Spoken(rapist, `"Nothing wrong with carrying a little extra weight,"`));
-					r.push(`he teases as grinds against your soft form.`);
+					r.push(`${he} teases as ${he} grinds against your soft form.`);
 				}
 				if (isPCCareerInCategory("wealth")) {
 					if (V.PC.boobs >= 300) {
 						r.push(Spoken(rapist, `"Nice and supple. How much did you have to pay for these babies?"`));
-						r.push(`he smirks as he gropes your breasts.`);
+						r.push(`${he} smirks as ${he} gropes your breasts.`);
 					}
 					if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 						r.push(Spoken(rapist, `"Couldn't afford an abortion after you took over? How sad,"`));
-						r.push(`he chuckles as he rubs your pregnant belly.`);
+						r.push(`${he} chuckles as ${he} rubs your pregnant belly.`);
 					}
 					if (V.PC.dick > 0) {
 						r.push(Spoken(rapist, `"Went with the full package didn't you?"`));
-						r.push(`he mocks as he flicks the tip of your stiffening cock.`);
+						r.push(`${he} mocks as ${he} flicks the tip of your stiffening cock.`);
 					}
 				} else if (isPCCareerInCategory("capitalist")) {
 					if (V.PC.boobs >= 300) {
 						r.push(Spoken(rapist, `"Nice and supple. Bet these got you some great deals with guys, didn't they?"`));
-						r.push(`he smirks as he gropes your breasts.`);
+						r.push(`${he} smirks as ${he} gropes your breasts.`);
 					}
 					if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 						r.push(Spoken(rapist, `"Sleeping with guys to close deals? Such a slut,"`));
-						r.push(`he chuckles as he rubs your pregnant belly.`);
+						r.push(`${he} chuckles as ${he} rubs your pregnant belly.`);
 					}
 					if (V.PC.dick > 0) {
 						r.push(Spoken(rapist, `"Guess you fuck people over in more ways than one, don't you?"`));
-						r.push(`he mocks as he flicks the tip of your stiffening cock.`);
+						r.push(`${he} mocks as ${he} flicks the tip of your stiffening cock.`);
 					}
 				} else if (isPCCareerInCategory("mercenary")) {
 					if (V.PC.boobs >= 300) {
 						r.push(Spoken(rapist, `"So did you ever actually see combat, or did you just spend all your days in the barracks servicing the real soldiers?"`));
-						r.push(`he smirks as he gropes your breasts.`);
+						r.push(`${he} smirks as ${he} gropes your breasts.`);
 					}
 					if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 						r.push(Spoken(rapist, `"Well now I know why you aren't serving still,"`));
-						r.push(`he chuckles as he rubs your pregnant belly.`);
+						r.push(`${he} chuckles as ${he} rubs your pregnant belly.`);
 					}
 					if (V.PC.dick > 0) {
 						r.push(Spoken(rapist, `"Got a little surgery between missions, eh?"`));
-						r.push(`he mocks as he flicks the tip of your stiffening cock.`);
+						r.push(`${he} mocks as ${he} flicks the tip of your stiffening cock.`);
 					}
 				} else if (isPCCareerInCategory("engineer")) {
 					if (V.PC.boobs >= 300) {
 						r.push(Spoken(rapist, `"Nice and supple. Did the other engineers care about your designs or just your tits?"`));
-						r.push(`he smirks as he gropes your breasts.`);
+						r.push(`${he} smirks as ${he} gropes your breasts.`);
 					}
 					if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 						r.push(Spoken(rapist, `"I can see why your designs were so popular, you fucked your way into the spotlight!"`));
-						r.push(`he chuckles as he rubs your pregnant belly.`);
+						r.push(`${he} chuckles as ${he} rubs your pregnant belly.`);
 					}
 					if (V.PC.dick > 0) {
 						r.push(Spoken(rapist, `"Well you do know how to erect things, don't you?"`));
-						r.push(`he mocks as he flicks the tip of your stiffening cock.`);
+						r.push(`${he} mocks as ${he} flicks the tip of your stiffening cock.`);
 					}
 				} else if (isPCCareerInCategory("medicine")) {
 					if (V.PC.boobs >= 300) {
 						r.push(Spoken(rapist, `"Nice and supple. Did you implant them yourself?"`));
-						r.push(`he smirks as he gropes your breasts.`);
+						r.push(`${he} smirks as ${he} gropes your breasts.`);
 					}
 					if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 						if (V.PC.dick > 0) {
 							r.push(Spoken(rapist, `"Look at that belly! I bet you inseminated yourself with your own seed,"`));
-							r.push(`he chuckles as he rubs your pregnant belly.`);
+							r.push(`${he} chuckles as ${he} rubs your pregnant belly.`);
 						} else {
 							r.push(Spoken(rapist, `"I see how you work. Mess up a surgery and give the guy a pity fuck. Surprised you couldn't get their spawn out of your belly though. Guess you aren't that good of a surgeon,"`));
-							r.push(`he chuckles as he rubs your pregnant belly.`);
+							r.push(`${he} chuckles as ${he} rubs your pregnant belly.`);
 						}
 					}
 					if (V.PC.dick > 0) {
 						r.push(Spoken(rapist, `"I'm impressed. Your woman impression is quite good. Did you do the surgery yourself?"`));
-						r.push(`he mocks as he flicks the tip of your stiffening cock.`);
+						r.push(`${he} mocks as ${he} flicks the tip of your stiffening cock.`);
 						r.push(Spoken(rapist, `"Still going to fuck you though."`));
 					}
 				} else if (isPCCareerInCategory("slaver")) {
 					if (V.PC.boobs >= 300) {
 						r.push(Spoken(rapist, `"With tits like these, I bet you were the bait used to lure them in,"`));
-						r.push(`he smirks as he gropes your breasts.`);
+						r.push(`${he} smirks as ${he} gropes your breasts.`);
 					}
 					if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 						r.push(Spoken(rapist, `"Did a slave beat me to you?"`));
-						r.push(`he chuckles as he rubs your pregnant belly.`);
+						r.push(`${he} chuckles as ${he} rubs your pregnant belly.`);
 					}
 					if (V.PC.dick > 0) {
 						r.push(Spoken(rapist, `"Bet you raped a bunch of girls with this, didn't you? Consider what's coming karma,"`));
-						r.push(`he mocks as he flicks the tip of your stiffening cock.`);
+						r.push(`${he} mocks as ${he} flicks the tip of your stiffening cock.`);
 					}
 				} else if (isPCCareerInCategory("celebrity")) {
 					if (V.PC.boobs >= 300) {
 						r.push(Spoken(rapist, `"Nice and supple. I wonder how many guys jacked off to your pictures?"`));
-						r.push(`he smirks as he gropes your breasts.`);
+						r.push(`${he} smirks as ${he} gropes your breasts.`);
 					}
 					if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 						r.push(Spoken(rapist, `"I can see how you got so popular!"`));
-						r.push(`he chuckles as he rubs your pregnant belly.`);
+						r.push(`${he} chuckles as ${he} rubs your pregnant belly.`);
 					}
 					if (V.PC.dick > 0) {
 						r.push(Spoken(rapist, `"How much tape did it take to hold this guy down?"`));
-						r.push(`he mocks as he flicks the tip of your stiffening cock.`);
+						r.push(`${he} mocks as ${he} flicks the tip of your stiffening cock.`);
 					}
 				} else if (isPCCareerInCategory("escort")) {
 					if (V.PC.boobs >= 300) {
 						r.push(Spoken(rapist, `"Nice and soft. How many dicks have been between these babies?"`));
-						r.push(`he smirks as he gropes your breasts.`);
+						r.push(`${he} smirks as ${he} gropes your breasts.`);
 					}
 					if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 						r.push(Spoken(rapist, `"What kind of whore doesn't know about protection?"`));
-						r.push(`he chuckles as he rubs your pregnant belly.`);
+						r.push(`${he} chuckles as ${he} rubs your pregnant belly.`);
 					}
 					if (V.PC.dick > 0) {
 						r.push(Spoken(rapist, `"So, did you ever get to use this when you were a prostitute?"`));
-						r.push(`he mocks as he flicks the tip of your stiffening cock.`);
+						r.push(`${he} mocks as ${he} flicks the tip of your stiffening cock.`);
 					}
 				} else if (isPCCareerInCategory("gang")) {
 					if (V.PC.boobs >= 300) {
 						r.push(Spoken(rapist, `"I bet I'm not the first person to do this to you, am I?"`));
-						r.push(`he smirks as he gropes your breasts.`);
+						r.push(`${he} smirks as ${he} gropes your breasts.`);
 					}
 					if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 						r.push(Spoken(rapist, `"Ah, now I get it. Your role in the gang was to lie on your back and take dick all day, wasn't it?"`));
-						r.push(`he chuckles as he rubs your pregnant belly.`);
+						r.push(`${he} chuckles as ${he} rubs your pregnant belly.`);
 					}
 					if (V.PC.dick > 0) {
 						r.push(Spoken(rapist, `"Fuck or be fucked world; today, it's gonna be you,"`));
-						r.push(`he mocks as he flicks the tip of your stiffening cock.`);
+						r.push(`${he} mocks as ${he} flicks the tip of your stiffening cock.`);
 					}
 				} else if (isPCCareerInCategory("servant")) {
 					if (V.PC.boobs >= 300) {
 						r.push(Spoken(rapist, `"Nice and supple. Bet your Master spent a fortune making these so nice,"`));
-						r.push(`he smirks as he gropes your breasts.`);
+						r.push(`${he} smirks as ${he} gropes your breasts.`);
 					}
 					if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 						r.push(Spoken(rapist, `"Holding on to your Master's final gift are you?"`));
-						r.push(`he chuckles as he rubs your pregnant belly.`);
+						r.push(`${he} chuckles as ${he} rubs your pregnant belly.`);
 					}
 					if (V.PC.dick > 0) {
 						r.push(Spoken(rapist, `"When your Master first undressed you, what did he think of his 'girl'?"`));
-						r.push(`he mocks as he flicks the tip of your stiffening cock.`);
+						r.push(`${he} mocks as ${he} flicks the tip of your stiffening cock.`);
 					}
 				} else if (isPCCareerInCategory("BlackHat")) {
 					if (V.PC.boobs >= 300) {
 						r.push(Spoken(rapist, `"Nice and supple. What are the odds that I can find these babies on the internet?"`));
-						r.push(`he smirks as he gropes your breasts.`);
+						r.push(`${he} smirks as ${he} gropes your breasts.`);
 					}
 					if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 						r.push(Spoken(rapist, `"You'd think someone so skilled at breaking security would understand protection themselves. Or did you trade your pussy for information?"`));
-						r.push(`he chuckles as he rubs your pregnant belly.`);
+						r.push(`${he} chuckles as ${he} rubs your pregnant belly.`);
 					}
 					if (V.PC.dick > 0) {
 						r.push(Spoken(rapist, `"Trying to catch a signal with that?"`));
-						r.push(`he mocks as he flicks the tip of your stiffening cock.`);
+						r.push(`${he} mocks as ${he} flicks the tip of your stiffening cock.`);
 					}
 				}
-				r.push(`Finally he reaches your moistening pussy.`);
+				r.push(`Finally ${he} reaches your moistening pussy.`);
 				r.push(Spoken(rapist, `"Already wet are we? Glad you know your place,"`));
-				r.push(`he states as he pulls your clothes off and bends you over.`);
+				r.push(`${he} states as ${he} pulls your clothes off and bends you over.`);
 				if (V.PC.vagina === 0) {
 					r.push(Spoken(rapist, `"And you still have your innocence, how delightful!"`));
 				}
 				App.Events.addParagraph(node, r);
 				r = [];
-				r.push(`You can feel the head of his cock teasing your`);
+				r.push(`You can feel the head of ${his} cock teasing your`);
 				if (V.PC.vagina === 0) {
-					r.push(`virgin pussy; you grit your teeth knowing what will come next. Without mercy, he <span class="red">tears through your hymen</span> and forces himself as deep as your tight pussy lets him. You choke back a sob as he struggles to hilt himself in you. He must have undergone surgery or something because there is no way your body can handle such a monster. You're in agony already - you can't fathom what will happen when he loses his patience.`);
+					r.push(`virgin pussy; you grit your teeth knowing what will come next. Without mercy, ${he} <span class="red">tears through your hymen</span> and forces ${himself} as deep as your tight pussy lets him. You choke back a sob as ${he} struggles to hilt ${himself} in you. ${He} must have undergone surgery or something because there is no way your body can handle such a monster. You're in agony already - you can't fathom what will happen when ${he} loses ${his} patience.`);
 				} else {
-					r.push(`pussy lips; you hope it feels bigger than it really is. As he struggles to force it into you, you regret thinking about it. He must have undergone surgery or something because he fills you completely. You feel weak just from him sticking it in, you can't fathom what will happen once he starts thrusting.`);
+					r.push(`pussy lips; you hope it feels bigger than it really is. As ${he} struggles to force it into you, you regret thinking about it. ${He} must have undergone surgery or something because ${he} fills you completely. You feel weak just from ${him} sticking it in, you can't fathom what will happen once ${he} starts thrusting.`);
 				}
-				r.push(`You soon find out as he wastes no time starting slow. He violently rams his oversized cock deep into you, threatening to penetrate your cervix with each thrust. He quickens his pace, fucking you like a beast.`);
+				r.push(`You soon find out as ${he} wastes no time starting slow. ${He} violently rams ${his} oversized cock deep into you, threatening to penetrate your cervix with each thrust. ${He} quickens ${his} pace, fucking you like a beast.`);
 				if (V.PC.preg < 1) {
 					if (random(1, 100) > 60) {
 						r.push(`His hand rises to your lips and forces something into your mouth.`);
@@ -289,18 +290,18 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 						r.push(`You obey, hoping to just get this over with.`);
 						V.PC.forcedFertDrugs += 3;
 					}
-					r.push(`With one final thrust, he forces through your battered cervix and unloads in the depths of your`);
+					r.push(`With one final thrust, ${he} forces through your battered cervix and unloads in the depths of your`);
 					if (canGetPregnant(V.PC)) {
 						r.push(`fertile`);
 					}
 					r.push(`womb.`);
 				} else {
-					r.push(`With one final thrust, he forces it in as deep as he can into you and blows his seed deep in your aching cunt.`);
+					r.push(`With one final thrust, ${he} forces it in as deep as ${he} can into you and blows ${his} seed deep in your aching cunt.`);
 				}
 				if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 					r.push(Spoken(rapist, `"Now your ${(V.PC.pregType > 1) ? `children` : `child`} will know what a real man's sperm is like!"`));
 				}
-				r.push(`He shoves you to the ground, pussy gaping from the size of his shaft and leaking his huge load all over yourself. By the time you loosen your bindings, he is long gone.`);
+				r.push(`${He} shoves you to the ground, your pussy gaping from the size of ${his} shaft and leaking ${his} huge load all over yourself. By the time you loosen your bindings, ${he} is long gone.`);
 				App.Events.addParagraph(node, r);
 				r = [];
 				r.push(`It would be prudent to up security in your arcology. That or take a guard along when you leave the penthouse. Such a thing, happening to you. You can't allow such an indignity to happen again,`);
@@ -309,7 +310,7 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 				} else {
 					r.push(`you think to yourself,`);
 				}
-				r.push(`as you try to coax his sperm from your abused pussy.`);
+				r.push(`as you try to coax ${his} sperm from your abused pussy.`);
 				if (canGetPregnant(V.PC)) {
 					r.push(`For some reason your body feels really satisfied, despite`);
 					if (V.PC.vagina === 0) {
@@ -317,12 +318,13 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 					} else {
 						r.push(`not climaxing...`);
 					}
-					r.push(`Is this what it feels like to be bred by someone so dominant? You should take a pregnancy test right away and make sure he didn't knock you up.`);
+					r.push(`Is this what it feels like to be bred by someone so dominant? You should take a pregnancy test right away and make sure ${he} didn't knock you up.`);
 					knockMeUp(V.PC, 100, 0, -2);
 				}
 				if (V.PC.vagina === 0) {
 					V.PC.vagina++;
 				}
+				App.Events.addParagraph(node, r);
 			} else {
 				if (V.PC.weight > 95) {
 					r.push(Spoken(rapist, `"I don't mind a little weight, so long as it doesn't get in the way. And even if it did, it won't stop me."`));
@@ -331,7 +333,7 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 				r.push(`With ${his} free hand, ${he} begins to explore your bound body.`);
 				if (V.PC.preg >= 20 || V.PC.belly >= 5000) {
 					r.push(Spoken(rapist, `"Can't say I've ever had sex with a pregnant ${womanP} before... I'll figure it out, don't you worry!"`));
-					r.push(`${he} teases as he rubs your pregnant belly.`);
+					r.push(`${he} teases as ${he} rubs your pregnant belly.`);
 					r.push(Spoken(rapist, `"I won't be far behind you..."`));
 					r.push(`${he} thinks out loud, much to your chagrin.`);
 				}
@@ -571,6 +573,7 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 		function enslave() {
 			const el = new DocumentFragment();
 			cashX(forceNeg(contractCost), "slaveTransfer", rapist);
+			generatePronouns(rapist);
 			el.append(`You complete the legalities and biometric scanning quickly and without fuss. The idiot will regret crossing you when ${he} wakes in the penthouse for basic slave induction.`);
 			el.append(App.UI.newSlaveIntro(rapist));
 			return el;
@@ -579,6 +582,7 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 		function stocks() {
 			const el = new DocumentFragment();
 			const r = [];
+			generatePronouns(rapist);
 			healthDamage(rapist, 10);
 			rapist.behavioralFlaw = "odd";
 			rapist.sexualFlaw = "hates penetration";
@@ -605,6 +609,7 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 		}
 
 		function arcade() {
+			generatePronouns(rapist);
 			assignJob(rapist, "be confined in the arcade");
 			rapist.sentence = 4;
 			cashX(forceNeg(contractCost), "slaveTransfer", rapist);
@@ -615,6 +620,7 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 		function dairy() {
 			const el = new DocumentFragment();
 			const r = [];
+			generatePronouns(rapist);
 			assignJob(rapist, "work in the dairy");
 			cashX(forceNeg(contractCost), "slaveTransfer", rapist);
 			r.push(`You complete the legalities and biometric scanning quickly and cautiously. The idiot will wake up`);
@@ -632,12 +638,19 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 		function farmyard() {
 			const el = new DocumentFragment();
 			const r = [];
+			generatePronouns(rapist);
 			assignJob(rapist, "work as a farmhand");
 			cashX(forceNeg(contractCost), "slaveTransfer", rapist);
-			r.push(`You complete the legalities and biometric scanning quickly and cautiously. The idiot will wake up in ${V.farmyardName}, where ${he} will spend the rest of ${his} days working the fields`);
-			if (V.farmyardShows === 1) {
-				r.push(`and`);
-				if (V.seeBestiality === 1) {
+			r.push(`You complete the legalities and biometric scanning quickly and cautiously. The idiot will wake up in ${V.farmyardName}, where ${he} will spend the rest of ${his} days`);
+			if (V.farmyardShows < 2) {
+				r.push(`working the fields`);
+
+				if (V.farmyardShows > 0) {
+					r.push(`and`);
+				}
+			}
+			if (V.farmyardShows > 0) {
+				if (V.seeBestiality) {
 					r.push(`getting fucked by animals.`);
 				} else {
 					r.push(`putting on shows with animals.`);
@@ -651,6 +664,7 @@ App.Events.pRaped = class pRaped extends App.Events.BaseEvent {
 		function amputate() {
 			const el = new DocumentFragment();
 			const r = [];
+			generatePronouns(rapist);
 			healthDamage(rapist, 20);
 			removeLimbs(rapist, "all");
 			rapist.behavioralFlaw = "odd";
diff --git a/src/events/nonRandom/pSchoolSuggestion.js b/src/events/nonRandom/pSchoolSuggestion.js
index 415ab33edd1dda2bc5d862741d8fb61859d0760c..ead7004b8f2f95c516aa6ddf45e527627fe461d7 100644
--- a/src/events/nonRandom/pSchoolSuggestion.js
+++ b/src/events/nonRandom/pSchoolSuggestion.js
@@ -17,7 +17,7 @@ App.Events.PSchoolSuggestion = class PSchoolSuggestion extends App.Events.BaseEv
 
 		App.Events.addParagraph(node, [`It seems a young, thin woman in a modern business suit was concluding her own argument when you arrived. "In summation, I propose we offer our support for Nueva Universidad de Libertad," says the woman, who you now realize is a very feminine man. "Nullification may seem extreme, but serves to expand the potential market amongst more... traditional slaveowners," says the man, who you <i>now</i> realize is a woman who merely looks like a very feminine man.`]);
 
-		App.Events.addParagraph(node, [`"I believe what you need in a slave is a good base. As such, The Utopian Orphanage is the best. They offer slaves who were raised with careful attention; they're beautiful, smart, well-educated and unspoiled." The young surgeon continues. "No traumas, a happy childhood, obedient and trusting. You can then mold them to your will as you please, I have enough faith in my skills to achieve the results I desire myself."`]);
+		App.Events.addParagraph(node, [`"I believe what you need in a slave is a good base. As such, The Utopian Orphanage is the best. They offer slaves who were raised with careful attention; they're beautiful, smart, well-educated and unspoiled." The young surgeon continues. "No traumas, a happy childhood, obedient and trusting. You can then mold them to your will as you please; I have enough faith in my skills to achieve the results I desire myself."`]);
 
 		if (V.seeDicks !== 100) {
 			App.Events.addParagraph(node, [`"The Slave School for me," says a portly man with a thriving slave breaking business down in the markets. "Their girls are pretty, skilled, and innocent, without any of that weird crap the other schools go in for. Besides, all that special stuff drives up the prices. TSS girls are cheap for what you get. When you're tired of one, just buy another." He turns to his friend and business partner, a much thinner man. "Though I'm sure you disagree with me."`]);
diff --git a/src/events/nonRandom/peacekeepers/pPeacekeepersDeficit.js b/src/events/nonRandom/peacekeepers/pPeacekeepersDeficit.js
index e9977a333b852cf93775232faa53b20d39d1c5da..2cdae4e0db294f994fa20761acf6dc1218df7b65 100644
--- a/src/events/nonRandom/peacekeepers/pPeacekeepersDeficit.js
+++ b/src/events/nonRandom/peacekeepers/pPeacekeepersDeficit.js
@@ -1,16 +1,12 @@
 App.Events.PPeacekeepersDeficit = class PPeacekeepersDeficit extends App.Events.BaseEvent {
 	eventPrerequisites() {
 		return [
-			() => V.peacekeepers !== 0,
+			() => V.peacekeepers.state === 2,
 			() => V.peacekeepers.attitude >= 0
 		];
 	}
 
 	execute(node) {
-		if (V.peacekeepers === 0) { // Do not remove (exists for typing support)
-			return node;
-		}
-
 		V.nextButton = "Continue";
 
 		App.Events.addParagraph(node, [`General ${V.peacekeepers.generalName}'s peacekeeping force has stabilized the neighboring region somewhat. True to his word, the general has indeed concentrated on his peacekeeping mandate, and hasn't done anything that might be construed as a move against the Free City or its interests. There are somewhat fewer refugees available from that area, and it's a less complete refuge for bad actors, but other than that, there hasn't been much reason for you to take notice. Until today, when General ${V.peacekeepers.generalName} gives you a call.`]);
@@ -19,7 +15,7 @@ App.Events.PPeacekeepersDeficit = class PPeacekeepersDeficit extends App.Events.
 		App.Events.addParagraph(node, [`"And second," he continues, "I'm having difficulty housing the prisoners we're taking. We're the only functioning law and order in this area, and in order to keep control I'm having to lock up everyone from armed bandits to petty looters. I don't have the resources to imprison them decently. I'm already getting flak about conditions in our main prison camp here." He arches an eyebrow. "Some people back home seem to care more about keeping prisoners comfortable than they care about getting my wounded men and women the best possible care. And I can't just reduce the prisoner population, either. There are too many of them. Word would get out, and there'd be hell to pay back home."`]);
 		App.Events.addParagraph(node, [`The singular solution to the two problems is obvious. It's equally obvious that General ${V.peacekeepers.generalName} isn't going to be the one to propose it. He's not stupid.`]);
 
-		const assistCash = 100000;
+		const assistCash = 200 * (menialSlaveCost() / 2);
 		const choices = [];
 		if (V.cash >= assistCash) {
 			choices.push(new App.Events.Result(`Offer to assist`, assist, `This will cost ${cashFormat(assistCash)} and provide a number of menial slaves`));
@@ -33,9 +29,6 @@ App.Events.PPeacekeepersDeficit = class PPeacekeepersDeficit extends App.Events.
 
 		function assist() {
 			const frag = new DocumentFragment();
-			if (V.peacekeepers === 0) { // Do not remove (exists for typing support)
-				return;
-			}
 			App.Events.addParagraph(frag, [`Understanding that the general needs to couch the situation in a way he can justify in public, and perhaps in a way he can justify to himself, you offer to house the prisoners on a contract basis, with immediate payment to the general so he can meet his forces' immediate needs. Naturally, the prisoners will be kept busy while you keep them; menial labor seems appropriate. It's unlikely that the situation will ever stabilize to the point where they can be released, so for safety, they should all be detained indefinitely. And of course, each prisoner's individual detention will be available for resale. Just like any other slave's.`]);
 			V.peacekeepers.attitude += 5;
 			V.menials += 200;
@@ -45,9 +38,6 @@ App.Events.PPeacekeepersDeficit = class PPeacekeepersDeficit extends App.Events.
 		}
 
 		function pharmaceutical() {
-			if (V.peacekeepers === 0) { // Do not remove (exists for typing support)
-				return;
-			}
 			let r = [];
 			if (V.cash < 100000) {
 				r.push(`Unfortunately, you lack the funds to buy the prisoners.`);
@@ -57,9 +47,6 @@ App.Events.PPeacekeepersDeficit = class PPeacekeepersDeficit extends App.Events.
 			return r;
 		}
 		function decline() {
-			if (V.peacekeepers === 0) { // Do not remove (exists for typing support)
-				return;
-			}
 			V.peacekeepers.attitude -= 10;
 			repX(5000, "event");
 			return `You decide to use this as an object lesson in the limits of old world power projection, and tell his situation is untenable and that he should withdraw. If he doesn't have the political firepower necessary to get proper support and supply, he's better off cutting his losses. "That's not for you to say," he responds bitterly. "And that's not for me to say, either. I still go where I'm told and do what I'm told. Thank you for your time." He ends the call brusquely. Word of your verbal defense of the Free City's sphere of influence gets around, <span class="reputation inc">greatly improving your reputation.</span>`;
diff --git a/src/events/nonRandom/peacekeepers/pPeacekeepersIndependence.js b/src/events/nonRandom/peacekeepers/pPeacekeepersIndependence.js
index 9a1578adde032b4ebc8deec3171e686b59157e43..7ef26c08b3e738b326137b8239b21bb33fd64365 100644
--- a/src/events/nonRandom/peacekeepers/pPeacekeepersIndependence.js
+++ b/src/events/nonRandom/peacekeepers/pPeacekeepersIndependence.js
@@ -2,21 +2,16 @@ App.Events.PPeacekeepersIndependence = class PPeacekeepersIndependence extends A
 	eventPrerequisites() {
 		return [
 			() => App.Events.effectiveWeek() > 75,
-			() => V.peacekeepers && V.peacekeepers.strength < 50,
-			() => V.rivalOwner === 0,
-			() => V.peacekeepersFate !== 1,
+			() => V.peacekeepers.state === 2 && V.peacekeepers.strength < 50,
+			() => V.rival.state <= 1 || V.rival.state > 2,
 		];
 	}
 
 	execute(node) {
 		let r = [];
-		if (!V.peacekeepers) { // for typing
-			return node;
-		}
 
 		V.nextButton = "Continue";
-		V.peacekeepersFate = 1;
-
+		V.peacekeepers.state = 3;
 		V.peacekeepers.strength = -10;
 
 
@@ -50,9 +45,6 @@ App.Events.PPeacekeepersIndependence = class PPeacekeepersIndependence extends A
 
 		function assistance() {
 			const frag = new DocumentFragment();
-			if (!V.peacekeepers) { // for typing
-				return frag;
-			}
 			cashX(-smallAid, "peacekeepers");
 			V.peacekeepers.strength = 50;
 			V.peacekeepers.attitude += 5;
@@ -65,9 +57,6 @@ App.Events.PPeacekeepersIndependence = class PPeacekeepersIndependence extends A
 
 		function generous() {
 			const frag = new DocumentFragment();
-			if (!V.peacekeepers) { // for typing
-				return frag;
-			}
 			cashX(-generousAid, "peacekeepers");
 			V.peacekeepers.strength = 50;
 			V.peacekeepers.attitude += 25;
@@ -79,9 +68,6 @@ App.Events.PPeacekeepersIndependence = class PPeacekeepersIndependence extends A
 		}
 
 		function decline() {
-			if (!V.peacekeepers) { // for typing
-				return "";
-			}
 			return `You inform General ${V.peacekeepers.generalName} that you will not be providing assistance. He does not falter, but he looks suddenly older, as though the prospect of a decisive strike was giving him the strength to carry on. He expresses his regrets dully, and then ends the call.`;
 		}
 	}
diff --git a/src/events/nonRandom/peacekeepers/pPeacekeepersInfluence.js b/src/events/nonRandom/peacekeepers/pPeacekeepersInfluence.js
index 107b43f2d71228e60469bd4839474df4f7be9296..373b6a331e046ae34ee9734e0217a828b690a46f 100644
--- a/src/events/nonRandom/peacekeepers/pPeacekeepersInfluence.js
+++ b/src/events/nonRandom/peacekeepers/pPeacekeepersInfluence.js
@@ -1,16 +1,12 @@
 App.Events.PPeacekeepersInfluence = class PPeacekeepersInfluence extends App.Events.BaseEvent {
 	eventPrerequisites() {
 		return [
-			() => V.peacekeepers && V.peacekeepers.strength >= 50,
+			() => V.peacekeepers.state === 3 && V.peacekeepers.strength >= 50,
 			() => V.peacekeepers.influenceAnnounced === 0,
 		];
 	}
 
 	execute(node) {
-		if (!V.peacekeepers) { // for typing
-			return node;
-		}
-
 		V.nextButton = "Continue";
 
 		V.peacekeepers.influenceAnnounced = 1;
diff --git a/src/events/nonRandom/peacekeepers/pPeacekeepersIntro.js b/src/events/nonRandom/peacekeepers/pPeacekeepersIntro.js
index 3b2df7799332422eb6f821e288d52d88f33d8703..afff55ab01b19262e7f8ff970eca188cf6a3f303 100644
--- a/src/events/nonRandom/peacekeepers/pPeacekeepersIntro.js
+++ b/src/events/nonRandom/peacekeepers/pPeacekeepersIntro.js
@@ -1,10 +1,8 @@
 App.Events.PPeacekeepersIntro = class PPeacekeepersIntro extends App.Events.BaseEvent {
 	eventPrerequisites() {
 		return [
-			() => V.invasionVictory > 0,
-			() => V.peacekeepers === 0,
-			() => V.peacekeepersGone !== 1,
-			() => App.Events.effectiveWeek() > 48,
+			() => peacekeepersCanBeEstablished(),
+			() => V.peacekeepers.state === 1,
 		];
 	}
 
@@ -13,9 +11,9 @@ App.Events.PPeacekeepersIntro = class PPeacekeepersIntro extends App.Events.Base
 
 		V.nextButton = "Continue";
 
-		V.peacekeepers = {
-			generalName: App.Data.misc.whiteAmericanSlaveSurnames.random(), strength: 20, attitude: 0, independent: 0, undermining: 0, influenceAnnounced: 0, tastes: 0
-		};
+		Object.assign(V.peacekeepers, {
+			generalName: App.Data.misc.whiteAmericanSlaveSurnames.random(), strength: 20, attitude: 0, undermining: 0, influenceAnnounced: 0, tastes: "", state : 2
+		});
 		if (V.continent === "Africa" || V.continent === "Western Europe") {
 			V.peacekeepers.generalName = App.Data.misc.frenchSlaveSurnames.random();
 		} else if (V.continent === "Asia" || V.continent === "Australia") {
@@ -58,7 +56,7 @@ App.Events.PPeacekeepersIntro = class PPeacekeepersIntro extends App.Events.Base
 		App.Events.addParagraph(node, [`As he spoke, you and ${V.assistant.name} surreptitiously checked out what he said. He seems to be telling the truth, and he's correct that your interests won't be immediately affected. Nevertheless, this is a concerning development. General ${V.peacekeepers.generalName} will have thousands of troops and a lot of military hardware under his able command, more or less right next door to the Free City. He might not intend to overstep the bounds of his peacekeeping mandate, but that's no guarantee that his civilian superiors back home won't decide to order him to. Worse, the politics of the Free Cities are almost unanimously hostile to old world power; there will be public resentment about this. On the other hand, General ${V.peacekeepers.generalName} has been successful in these difficult times in no small part due to his willingness to bend the rules. If he sees an opportunity to work with an ambitious arcology owner in furtherance of his goals, he'll probably take it.`]);
 		App.Events.addResponses(node, [
 			new App.Events.Result(`Tell him you disapprove of old world meddling in the Free City's sphere of influence`, disapprove),
-			new App.Events.Result(`Respond politely, but avoid committing yourself`, noncommital),
+			new App.Events.Result(`Respond politely, but avoid committing yourself`, noncommittal),
 			new App.Events.Result(`Share intelligence on that area as a basis for further cooperation`, agree)
 		]);
 
@@ -68,7 +66,7 @@ App.Events.PPeacekeepersIntro = class PPeacekeepersIntro extends App.Events.Base
 			return `You tell him that you consider that area within the Free City's area of influence now, and that you disapprove of old world meddling. "Interesting," he says, noncommittal. "It takes real power projection to maintain a real sphere of influence. It remains to be seen whether your Free City has it. In the meantime, we'll pursue our mission." He inclines his head respectfully, and ends the call. Word of your brusque defense of the Free City's growing influence gets around, <span class="reputation inc">greatly improving your reputation.</span>`;
 		}
 
-		function noncommital() {
+		function noncommittal() {
 			return `You respond politely, stating that you're always willing to listen to business proposals, and that you approach each situation without preconceptions. General ${V.peacekeepers.generalName} understands the unspoken subtext, and that you're not willing to commit yourself to anything definite as yet. He understands, and matches your show of respect before ending the call.`;
 		}
 
diff --git a/src/events/nonRandom/rival/pHostageAcquisition.js b/src/events/nonRandom/rival/pHostageAcquisition.js
index 8d88ff92be7f746d15ab2d78a4002e59b553b70f..884ac491685ee5b5edfd7e69cbdec721b673552e 100644
--- a/src/events/nonRandom/rival/pHostageAcquisition.js
+++ b/src/events/nonRandom/rival/pHostageAcquisition.js
@@ -1,7 +1,7 @@
 App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.BaseEvent {
 	eventPrerequisites() {
 		return [
-			() => V.hostageRescued === 1,
+			() => V.rival.hostageState === 2,
 			() => !!V.hostage
 		];
 	}
@@ -15,7 +15,6 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 			He, His,
 			he, his, him, girl, woman
 		} = getPronouns(V.hostage);
-		V.hostageRescued = 0;
 		V.hostage.weekAcquired = V.week;
 		let closer = 0;
 
@@ -118,13 +117,13 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 		}
 		r.push(`from before you were an arcology owner, and then a pawn in your rival arcology owner's campaign of psychological warfare against you, is now one of your slaves. Your hired mercenaries are en route now with your precious cargo.`);
 
-		switch (V.rivalryFS) {
+		switch (V.rival.FS.name) {
 			case "Racial Subjugationism":
 				if (V.hostage.preg > 0) {
 					WombFatherRace(V.hostage, V.arcologies[0].FSSubjugationistRace);
 				}
 				setHealth(V.hostage, 50, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 10);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -134,7 +133,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"They kept trying to rape me with ${V.arcologies[0].FSSubjugationistRace} slaves!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s nearly the same as you remember ${him}, albeit a bit more hateful towards ${V.arcologies[0].FSSubjugationistRace} people.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -143,11 +142,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					}
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"They raped me with ${V.arcologies[0].FSSubjugationistRace} slaves!" ${He}'s nearly the same as you remember ${him}, albeit with a slight ${V.arcologies[0].FSSubjugationistRace} fetish.`));
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} asks`);
 					r.push(Spoken(V.hostage, `"Can I spend some time with the ${V.arcologies[0].FSSubjugationistRace} slaves?"`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} bluntly asks`);
 					r.push(Spoken(V.hostage, `"Can I get fucked by some ${V.arcologies[0].FSSubjugationistRace} studs?"`));
 					r.push(`While ${he} looks the same as you remember, ${he} definitely doesn't think the same anymore.`);
@@ -168,7 +167,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 						App.Utils.getRaceArrayWithoutParamRace(V.arcologies[0].FSSupremacistRace).random()
 					);
 				}
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -184,7 +183,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 						setHealth(V.hostage, 0, Math.max(V.hostage.health.shortDamage, 10), Math.max(V.hostage.health.longDamage, 10), 0, 100);
 					}
 					V.hostage.custom.tattoo = "$He has slight scarring from being beaten under your rival's rule.";
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} walks into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -200,7 +199,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 						setHealth(V.hostage, 0, Math.max(V.hostage.health.shortDamage, 20), Math.max(V.hostage.health.longDamage, 20), 1, 100);
 					}
 					V.hostage.custom.tattoo = "$He has noticeable scarring from being beaten under your rival's rule.";
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shuffles into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -226,7 +225,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 						setHealth(V.hostage, -10, 25, Math.max(V.hostage.health.longDamage, 25), 2, 100);
 					}
 					V.hostage.custom.tattoo = "$He has heavy scarring from being beaten under your rival's rule.";
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} attempts to stumble into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -273,7 +272,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 			case "Repopulation Focus":
 				setHealth(V.hostage, 50, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 5);
 				WombFlush(V.hostage);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -283,7 +282,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"They took my eggs away!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember, though a medical scan reveals that ${his} ovaries contain absolutely zero egg cells.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -293,11 +292,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"They took my fertility away!"`));
 					r.push(`${He}'s exactly as you remember, though a medical scan reveals that ${his} ovaries contain absolutely zero egg cells.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} says`);
 					r.push(Spoken(V.hostage, `"You don't have to worry about knocking me up, I'm sterile!"`));
 					r.push(`with a wink. While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} bluntly says`);
 					r.push(Spoken(V.hostage, `"I won't let you ruin my body with a child!"`));
 					r.push(`While ${he} looks the same as you remember, ${he} definitely doesn't think the same anymore.`);
@@ -312,7 +311,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 			case "Eugenics":
 				setHealth(V.hostage, 50, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 20);
 				if (V.seeHyperPreg !== 1) {
-					if (V.rivalryDuration <= 5) {
+					if (V.rival.duration <= 5) {
 						r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 						if (V.PC.boobs >= 650) {
 							r.push(`ample bust,`);
@@ -322,7 +321,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 						r.push(`sobbing,`);
 						r.push(Spoken(V.hostage, `"They filled me with cum! I think I'm pregnant!"`));
 						r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember, though a medical scan reveals that ${he} is carrying ${pregNumberName(V.hostage.pregType, 2)}.`);
-					} else if (V.rivalryDuration <= 10) {
+					} else if (V.rival.duration <= 10) {
 						r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 						if (V.PC.boobs >= 650) {
 							r.push(`ample bust`);
@@ -332,11 +331,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 						r.push(`as ${he} breaks down in tears, ${his} rounded middle pressing into your own.`);
 						r.push(Spoken(V.hostage, `"They knocked me up!"`));
 						r.push(`${He}'s exactly as you remember, though a medical scan reveals that ${he} is carrying ${pregNumberName(V.hostage.pregType, 2)}.`);
-					} else if (V.rivalryDuration <= 15) {
+					} else if (V.rival.duration <= 15) {
 						r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} gravid bulk back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} says`);
 						r.push(Spoken(V.hostage, `"Please don't take them from me, I love them..."`));
 						r.push(`While ${he} looks the same as you remember, albeit rather pregnant, ${he} certainly doesn't think the same anymore.`);
-					} else if (V.rivalryDuration <= 20) {
+					} else if (V.rival.duration <= 20) {
 						r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} gravid bulk back and forth, unsure of what to make of you. As you step forward, ${he} carefully steps back. After several steps, ${he} bluntly says`);
 						r.push(Spoken(V.hostage, `"I won't let you hurt them!"`));
 						r.push(`as ${he} covers ${his} pregnant belly. While ${he} looks the same as you remember, albeit very pregnant, ${he} definitely doesn't think the same anymore.`);
@@ -348,7 +347,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 						r.push(`The mercenary captain quickly gags ${him}, "My apologies, I did warn you ${he} was a handful. Please be careful when you unbind ${him}, ${he} may try to do something stupid," he says as he and his group exit your penthouse, leaving you with the enraged ${V.hostage.slaveName}. ${He} looks the same as you remember, but ${he} acts nothing like the ${girl} you used to know. Odds are high that ${he}'ll cause problems for you in the future, especially when ${he} realizes ${his} babies didn't follow ${him} here.`);
 					}
 				} else {
-					if (V.rivalryDuration <= 5) {
+					if (V.rival.duration <= 5) {
 						r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 						if (V.PC.boobs >= 650) {
 							r.push(`ample bust,`);
@@ -358,7 +357,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 						r.push(`sobbing,`);
 						r.push(Spoken(V.hostage, `"They filled me with cum! I think I'm pregnant!"`));
 						r.push(`You gently wrap your arms around ${him} in a comforting embrace, yet you can't help but notice how distended ${his} belly is. ${He}'s exactly as you remember, maybe a little heftier, but a medical scan reveals, horrifyingly, that ${he} is carrying over two dozen babies in ${his} womb.`);
-					} else if (V.rivalryDuration <= 10) {
+					} else if (V.rival.duration <= 10) {
 						r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You try to pull ${him} into your`);
 						if (V.PC.boobs >= 650) {
 							r.push(`ample bust,`);
@@ -368,11 +367,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 						r.push(`but ${his} huge pregnant belly prevents you. As ${he} breaks down in tears, ${he} moans`);
 						r.push(Spoken(V.hostage, `"My womb is soo full..."`));
 						r.push(`${He}'s nearly the same as you remember ${him}, save for ${his} huge pregnant belly, which a medical scan reveals contains over two dozen children.`);
-					} else if (V.rivalryDuration <= 15) {
+					} else if (V.rival.duration <= 15) {
 						r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} super gravid bulk back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough for ${his} monstrous belly to bump into your own, ${he} says`);
 						r.push(Spoken(V.hostage, `"It feels so good to be stuffed completely full of life. You'll let me enjoy this, won't you?"`));
 						r.push(`While ${he} looks the same as you remember, albeit grossly pregnant, ${he} certainly doesn't think the same anymore. A medical exam, much to ${his} enjoyment, reveals ${his} overfilled womb contains nearly two dozen children.`);
-					} else if (V.rivalryDuration <= 20) {
+					} else if (V.rival.duration <= 20) {
 						r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} hyper gravid bulk back and forth, unsure of what to make of you. As you step forward, ${he} carefully steps back. After several steps, ${he} bluntly says`);
 						r.push(Spoken(V.hostage, `"Unless you want to put more babies in me, get back!"`));
 						r.push(`as ${he} attempts to cover ${his} super-sized pregnant belly. While ${he} looks the same as you remember, albeit grotesquely pregnant, ${he} certainly doesn't think the same anymore. A medical exam, much to ${his} delight, reveals ${his} near bursting womb contains nearly two dozen children.`);
@@ -387,7 +386,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Gender Radicalism":
 				setHealth(V.hostage, 60, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 20);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -397,7 +396,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"They acted so weird!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember, if not slightly more attached to you.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -407,11 +406,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"Will you be as kind to me as they were?"`));
 					r.push(`${He}'s exactly as you remember, if not slightly more attached to you.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} asks`);
 					r.push(Spoken(V.hostage, `"Will you love me too?"`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} bluntly shouts`);
 					r.push(Spoken(V.hostage, `"Stay away from me you rapist!"`));
 					r.push(`While ${he} looks the same as you remember, ${he} definitely doesn't think the same anymore.`);
@@ -425,7 +424,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Gender Fundamentalism":
 				setHealth(V.hostage, 20, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 20);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -435,7 +434,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"They did such terrible things to my butt!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember, if not a little curious about anal.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -445,14 +444,14 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"They broke my butthole!"`));
 					r.push(`${He}'s exactly as you remember, minus ${his} loose rear.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} says`);
 					r.push(Spoken(V.hostage, `"Do you want to fuck my butt?`));
 					if (V.seeDicks !== 0) {
 						r.push(`Maybe touch my penis?`);
 					}
 					r.push(Spoken(V.hostage, `" While ${he} looks the same as you remember, minus ${his} very loose butthole${(V.seeDicks !== 0) ? ` and minuscule dick` : ``}, ${he} certainly doesn't think the same anymore.`));
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					V.hostage.trust = 60;
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} bluntly says`);
 					r.push(Spoken(V.hostage, `"Piss off vagina fucker, slaves' asses are for pounding!"`));
@@ -475,7 +474,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				}
 				break;
 			case "Paternalism":
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -489,7 +488,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					if (V.hostage.health.health > -20) {
 						setHealth(V.hostage, 0, Math.max(V.hostage.health.shortDamage, 10), Math.max(V.hostage.health.longDamage, 10), 0, 70);
 					}
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} tries to crawl to you. You help ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -504,7 +503,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					if (V.hostage.health.health > -40) {
 						setHealth(V.hostage, 0, Math.max(V.hostage.health.shortDamage, 20), Math.max(V.hostage.health.longDamage, 20), 0, 80);
 					}
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} tries to crawl to you. You help ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -517,7 +516,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					if (V.hostage.health.health > -60) {
 						setHealth(V.hostage, -10, 25, Math.max(V.hostage.health.longDamage, 25), 1, 90);
 					}
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon being placed in your office, ${V.hostage.slaveName} curls into a fetal position and begins sobbing,. You help ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -543,7 +542,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Degradationism":
 				setHealth(V.hostage, 60, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 0);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -553,7 +552,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"They acted so weird!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember, if not slightly more attached to you.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -563,11 +562,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"Will you be as kind to me as they were?"`));
 					r.push(`${He}'s exactly as you remember, if not slightly more attached to you.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} asks`);
 					r.push(Spoken(V.hostage, `"Will you love me too?"`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} bluntly says`);
 					r.push(Spoken(V.hostage, `"Stay away from me you rapist!"`));
 					r.push(`While ${he} looks the same as you remember, ${he} definitely doesn't think the same anymore.`);
@@ -585,7 +584,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Body Purism":
 				setHealth(V.hostage, 0, Math.max(V.hostage.health.shortDamage, 15), Math.max(V.hostage.health.longDamage, 15), 0, 20);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} attempts to dive into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust.`);
@@ -595,7 +594,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`The weight of ${his} huge ${V.hostage.boobs}cc fake tits knocks the wind out of you. You embrace ${him} as best you can as ${he} sobs`);
 					r.push(Spoken(V.hostage, `"Look what they did to my chest! They ruined it!"`));
 					r.push(`${He} looks similar to how you remember, minus ${his} huge chest of course.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${his} massive ${V.hostage.boobs}cc fake tits into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -605,11 +604,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"Why do these tit balloons feel so good?!"`));
 					r.push(`${He} looks similar to how you remember, minus ${his} massive chest of course.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} massive weight back and forth, unsure of what to make of you. As you step forward, ${he} attempts to move closer, only to fall to the ground under the weight of ${his} obscene ${V.hostage.boobs}cc fake tits. You kneel beside ${him}, a hand on ${his} huge fake ass, as ${he} asks`);
 					r.push(Spoken(V.hostage, `"Do you like them? I think they should be bigger..."`));
 					r.push(`The ${girl} you used to know is barely recognizable under those implants and ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`${V.hostage.slaveName}'s impressive bulk is placed in your office. Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth atop ${his} ${V.hostage.boobs}cc implants, unsure of what to make of you. As you step forward, ${he} screams`);
 					r.push(Spoken(V.hostage, `"Don't pop my implants!"`));
 					r.push(`The ${girl} you used to know is barely recognizable under those implants and ${he} certainly doesn't think the same anymore.`);
@@ -623,7 +622,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Transformation Fetishism":
 				setHealth(V.hostage, 60, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 10);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -633,7 +632,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"They told me such horrible things about you!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -642,11 +641,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					}
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"You aren't going to force implants into me, are you?" While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`));
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} states`);
 					r.push(Spoken(V.hostage, `"Please don't make me into a blow up doll..."`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} screams`);
 					r.push(Spoken(V.hostage, `"Keep away from me! I don't want balloons on my chest!"`));
 					r.push(`While ${he} looks the same as you remember, ${he} definitely doesn't think the same anymore.`);
@@ -660,7 +659,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Youth Preferentialism":
 				setHealth(V.hostage, 60, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 10);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -670,7 +669,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"This old ${woman2} tried to make me ${his2} pet!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -680,7 +679,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"They made me make out with an old lady!"`));
 					r.push(`${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} asks`);
 					if (V.PC.visualAge >= 50) {
 						r.push(Spoken(V.hostage, `"Were you always that attractive?"`));
@@ -688,7 +687,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 						r.push(Spoken(V.hostage, `"Can I hang out with some MILFs?"`));
 					}
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					V.hostage.trust = 40;
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} says`);
 					if (V.PC.visualAge >= 50) {
@@ -709,7 +708,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Maturity Preferentialism":
 				setHealth(V.hostage, 60, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 10);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -719,7 +718,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"This young ${girl2} kept molesting me!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -729,7 +728,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"They made me make out with some young harlot!"`));
 					r.push(`${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} asks`);
 					if (V.PC.visualAge < 35) {
 						r.push(Spoken(V.hostage, `"Were you always that attractive?"`));
@@ -737,7 +736,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 						r.push(Spoken(V.hostage, `"Can I hang out with the rest of the young ladies?"`));
 					}
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					V.hostage.trust = 40;
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} says`);
 					if (V.PC.visualAge < 35) {
@@ -759,7 +758,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 			case "Slimness Enthusiasm":
 				setHealth(V.hostage, -30, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 40);
 				V.hostage.chem = 100;
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} attempts to dive into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust.`);
@@ -769,7 +768,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`The weight of ${his} huge ${V.hostage.boobs}cc tits knocks the wind out of you. You embrace ${him} as best you can, you hands sinking into ${his} soft butt, as ${he} sobs`);
 					r.push(Spoken(V.hostage, `"Look what they did to my chest and ass! They ruined them!"`));
 					r.push(`${He} looks similar to how you remember, minus ${his} huge assets of course.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${his} massive ${V.hostage.boobs}cc breasts into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -779,11 +778,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"Why do these meat balloons feel so good?!"`));
 					r.push(`${He} looks similar to how you remember, minus ${his} massive assets of course.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`${V.hostage.slaveName}'s impressive bulk is placed in your office. Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth atop ${his} ${V.hostage.boobs}cc breasts, causing ${his} chubby body and fat ass to jiggle, unsure of what to make of you. As you step forward, ${he} asks`);
 					r.push(Spoken(V.hostage, `"Can you make my tits bigger?"`));
 					r.push(`The ${girl} you used to know is barely recognizable under those massive tits and ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`${V.hostage.slaveName}'s impressive bulk is placed in your office. Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth atop ${his} ${V.hostage.boobs}cc implants, causing ${his} plump body and huge ass to jiggle, unsure of what to make of you. As you step forward, ${he} screams`);
 					r.push(Spoken(V.hostage, `"Don't take my breasts away!"`));
 					r.push(`The ${girl} you used to know is barely recognizable under those immense tits and ${he} certainly doesn't think the same anymore.`);
@@ -797,7 +796,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Asset Expansionism":
 				setHealth(V.hostage, 60, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 10);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -807,7 +806,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"They told me such horrible things about you!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -817,11 +816,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"You aren't going to make my tits huge, are you?"`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} pleads`);
 					r.push(Spoken(V.hostage, `"Please don't turn me into a big boobed freak..."`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} screams`);
 					r.push(Spoken(V.hostage, `"Keep away from me! I don't want tits bigger than my body!"`));
 					r.push(`While ${he} looks the same as you remember, ${he} definitely doesn't think the same anymore.`);
@@ -835,7 +834,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Pastoralism":
 				setHealth(V.hostage, 60, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 70);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -848,7 +847,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					if (closer && V.hostage.actualAge <= 16 && V.hostage.boobs > 800) {
 						r.push(`Well, except for the sizable busoms pressing against you; puberty was quite generous to ${him}`);
 					}
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -861,11 +860,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					if (closer && V.hostage.actualAge <= 16 && V.hostage.boobs > 800) {
 						r.push(`You can't help but notice the size of ${his} breasts pressing against you; puberty was generous to ${him}`);
 					}
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} says`);
 					r.push(Spoken(V.hostage, `"I don't want to ever be so heavy again..."`));
 					r.push(`${He} is noticeably thinner and much more muscular than you remember; ${he} certainly doesn't think the same anymore, either.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} screams`);
 					r.push(Spoken(V.hostage, `"Keep away from me! I don't want ever want to be a fat cow again!"`));
 					r.push(`${He} is thin and extremely muscular, a stark difference from the soft, chubby ${girl} you used to know; ${he} certainly doesn't think the same anymore, either.`);
@@ -881,7 +880,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Cummunism":
 				setHealth(V.hostage, -30, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 10);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} attempts to dive into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust.`);
@@ -891,7 +890,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`The weight of ${his} huge ${V.hostage.boobs}cc tits knocks the wind out of you. You embrace ${him} as best you can, you hands sinking into ${his} soft butt, as ${he} sobs`);
 					r.push(Spoken(V.hostage, `"They made me fat! My nipples won't stop leaking milk!"`));
 					r.push(`${He} looks similar to how you remember, minus ${his} huge milky assets of course.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${his} massive ${V.hostage.boobs}cc milky breasts into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -901,11 +900,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"Why did they make me into a cow, I don't understand..."`));
 					r.push(`${He} looks similar to how you remember, minus ${his} massive assets of course.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`${V.hostage.slaveName}'s impressive bulk is placed in your office. Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth atop ${his} ${V.hostage.boobs}cc breasts, causing ${his} chubby body and fat ass to jiggle, unsure of what to make of you. As you step forward, ${he} asks`);
 					r.push(Spoken(V.hostage, `"Can you milk me?"`));
 					r.push(`The ${girl} you used to know is barely recognizable under all that fat and ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					V.hostage.trust = 40;
 					r.push(`${V.hostage.slaveName}'s impressive bulk is placed in your office. Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth atop ${his} ${V.hostage.boobs}cc breasts, causing ${his} fat body and huge ass to jiggle, unsure of what to make of you. As you step forward, ${he} asks`);
 					r.push(Spoken(V.hostage, `"I hear a baby will make my milk better, would you like to try?"`));
@@ -919,7 +918,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				}
 				break;
 			case "Physical Idealism":
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -930,7 +929,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(Spoken(V.hostage, `"They made me fat! I'm so glad those guys let me puke up all that food; I don't even want to think how big I'd be otherwise!"`));
 					r.push(`${He} looks similar to how you remember, thanks to the pudge, though that can be easily rectified.`);
 					setHealth(V.hostage, 0, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 0);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${his} meaty body into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -941,12 +940,12 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(Spoken(V.hostage, `"Why did they make me into a sow, I don't understand..."`));
 					r.push(`${He} looks similar to how you remember, minus ${his} added weight of course.`);
 					setHealth(V.hostage, -10, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 0);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth causing ${his} plump body, big breasts and fat ass to jiggle, unsure of what to make of you. As you step forward, ${he} asks`);
 					r.push(Spoken(V.hostage, `"Can I have some food?"`));
 					r.push(`The ${girl} you used to know is barely recognizable under all that fat and ${he} certainly doesn't think the same anymore.`);
 					setHealth(V.hostage, -30, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 0);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth causing ${his} fat body to jiggle, unsure of what to make of you. As you step forward, ${he} stumbles back. After several steps, ${he} screams`);
 					r.push(Spoken(V.hostage, `"Keep away from me! I don't want to work out! Stuffing my face and holes whenever I please is too much fun!"`));
 					r.push(`The ${girl} you used to know is barely recognizable under that obese body; ${he} certainly doesn't think the same anymore, either.`);
@@ -962,7 +961,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Hedonistic Decadence":
 				setHealth(V.hostage, 60, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 70);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -975,7 +974,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					if (closer && V.hostage.actualAge <= 16 && V.hostage.boobs > 800) {
 						r.push(`Well, except for the sizable busoms pressing against you; puberty was quite generous to ${him}`);
 					}
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -988,11 +987,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					if (closer && V.hostage.actualAge <= 16 && V.hostage.boobs > 800) {
 						r.push(`You can't help but notice the size of ${his} breasts pressing against you; puberty was generous to ${him}`);
 					}
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} says`);
 					r.push(Spoken(V.hostage, `"I don't want to ever be so heavy again..."`));
 					r.push(`${He} is noticeably thinner and much more muscular than you remember; ${he} certainly doesn't think the same anymore, either.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} screams`);
 					r.push(Spoken(V.hostage, `"Keep away from me! I don't want ever want to be a fat sow again!"`));
 					r.push(`${He} is thin and extremely muscular, a stark difference from the soft, chubby ${girl} you used to know; ${he} certainly doesn't think the same anymore, either.`);
@@ -1008,7 +1007,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Chattel Religionism":
 				setHealth(V.hostage, 50, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 10);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -1018,7 +1017,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"They told me such horrible things about you!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -1028,11 +1027,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"You aren't trying to make some crazy religion, are you?"`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} pleads`);
 					r.push(Spoken(V.hostage, `"Please don't turn me into a disciple of your religion..."`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} screams`);
 					r.push(Spoken(V.hostage, `"Keep away from me! I don't want to be part of your cult!"`));
 					r.push(`While ${he} looks the same as you remember, ${he} definitely doesn't think the same anymore.`);
@@ -1046,7 +1045,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Multiculturalism":
 				setHealth(V.hostage, 60, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 10);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -1056,7 +1055,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"They said such crazy things!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -1066,11 +1065,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"They made me pray for your arcology; why is that?"`));
 					r.push(`${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} prays`);
 					r.push(Spoken(V.hostage, `"Please pardon this arcology..."`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					V.hostage.trust = 40;
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} drops to ${his}`);
 					if (hasBothLegs(V.hostage)) {
@@ -1091,7 +1090,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Intellectual Dependency":
 				setHealth(V.hostage, 80, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 5);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -1101,7 +1100,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"They tried to teach me the most obscene things!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -1111,13 +1110,13 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"They made me a whore. I feel so disgusting..."`));
 					r.push(`${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					V.hostage.devotion = 40;
 					V.hostage.trust = 40;
 					r.push(`Upon seeing you, ${V.hostage.slaveName} stiffens up and waits for you to make a move. ${He} holds completely still, even as you place a hand on ${his} shoulder. ${He} stutters out a quiet`);
 					r.push(Spoken(V.hostage, `"${Master}? W-what may I do f-for you?"`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					V.hostage.devotion = 65;
 					V.hostage.trust = 65;
 					r.push(`Upon seeing you, ${V.hostage.slaveName} graciously bows, giving you a lovely view down ${his} cleavage. ${He} holds this position, before stating`);
@@ -1133,7 +1132,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Slave Professionalism":
 				setHealth(V.hostage, 60, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 0);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -1143,7 +1142,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"They did things to me! My head hurts so much..."`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -1153,11 +1152,11 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"I can barely remember things anymore; who were you again? I hate to ask, but... I need a good fuck right now..."`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly can't think the same anymore.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} bounces into your arms.`);
 					r.push(Spoken(V.hostage, `"Wanna do it?"`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} wastes no time in`);
 					if (V.PC.dick !== 0) {
 						r.push(`unbuckling your pants`);
@@ -1172,7 +1171,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Petite Admiration":
 				setHealth(V.hostage, 60, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 10);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -1182,7 +1181,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"This giant ${woman2} tried to make me ${his2} pet!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -1192,12 +1191,12 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"They made me make out with a giant!"`));
 					r.push(`${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} asks`);
 					/* player height check here */
 					r.push(Spoken(V.hostage, `"Can I hang out with someone taller than me?"`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					V.hostage.trust = 40;
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} says`);
 					/* player height check here */
@@ -1213,7 +1212,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			case "Statuesque Glorification":
 				setHealth(V.hostage, 60, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 10);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -1223,7 +1222,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"This midget kept molesting me!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -1233,13 +1232,13 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`as ${he} breaks down in tears.`);
 					r.push(Spoken(V.hostage, `"They made me get on ${(hasBothLegs(V.hostage)) ? `my knees` : `the ground`} and make out with some tiny harlot!"`));
 					r.push(`${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} asks`);
 					/* player height check here */
 
 					r.push(Spoken(V.hostage, `"Is there anyone shorter I can hang out with around here?"`));
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					V.hostage.trust = 40;
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} says`);
 					/* player height check here */
@@ -1256,7 +1255,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 				break;
 			default:
 				setHealth(V.hostage, 40, V.hostage.health.shortDamage, V.hostage.health.longDamage, 0, 10);
-				if (V.rivalryDuration <= 5) {
+				if (V.rival.duration <= 5) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} dives into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust,`);
@@ -1266,7 +1265,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					r.push(`sobbing,`);
 					r.push(Spoken(V.hostage, `"They told me such horrible things about you!"`));
 					r.push(`You gently wrap your arms around ${him} in a comforting embrace. ${He}'s exactly as you remember.`);
-				} else if (V.rivalryDuration <= 10) {
+				} else if (V.rival.duration <= 10) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} gingerly approaches, uncertain if ${he} should. You pull ${him} into your`);
 					if (V.PC.boobs >= 650) {
 						r.push(`ample bust`);
@@ -1274,21 +1273,21 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 						r.push(`chest`);
 					}
 					r.push(`as ${he} breaks down in tears.`);
-					if (V.rivalryFS !== 0) {
+					if (V.rival.FS.name !== "") {
 						r.push(Spoken(V.hostage, `"You aren't trying to make some crazy old-timey society, are you?"`));
 					} else {
 						r.push(Spoken(V.hostage, `"You aren't going to try to make me... do things to you, right?"`));
 					}
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 15) {
+				} else if (V.rival.duration <= 15) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} hesitatingly approaches. Once ${he} is close enough ${he} says`);
-					if (V.rivalryFS !== 0) {
+					if (V.rival.FS.name !== "") {
 						r.push(Spoken(V.hostage, `"Please don't make me play along..."`));
 					} else {
 						r.push(Spoken(V.hostage, `"I don't want to be your plaything..."`));
 					}
 					r.push(`While ${he} looks the same as you remember, ${he} certainly doesn't think the same anymore.`);
-				} else if (V.rivalryDuration <= 20) {
+				} else if (V.rival.duration <= 20) {
 					r.push(`Upon seeing you, ${V.hostage.slaveName} shifts ${his} weight back and forth, unsure of what to make of you. As you step forward, ${he} quickly steps back. After several steps, ${he} screams`);
 					r.push(Spoken(V.hostage, `"Keep away from me! I don't want to be part of your crazy society!"`));
 					r.push(`While ${he} looks the same as you remember, ${he} definitely doesn't think the same anymore.`);
@@ -1296,26 +1295,26 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 					V.hostage.trust = 80;
 					r.push(`Your mercenaries radio you upon arrival. "This one's got quite some spunk in ${him}, you better ready yourself. We're coming in now."`);
 					r.push(`Upon seeing you, ${V.hostage.slaveName}'s eyes fill with a distinct hatred. As you step forward, ${he} stands ${his} ground. After several steps, ${he} shouts`);
-					r.push(Spoken(V.hostage, `"Stay away from me, you crazy psycho! ${(V.rivalryFS !== 0) ? `Remaking a fallen empire, madness! You think yourself a king —"` : `You think you can just take whatever you want from people — Fuck, I don't even know if you even THINK of them as people anymore! How dare you even think I —"`}`));
+					r.push(Spoken(V.hostage, `"Stay away from me, you crazy psycho! ${V.rival.FS.name !== "" ? `Remaking a fallen empire, madness! You think yourself a king —"` : `You think you can just take whatever you want from people — Fuck, I don't even know if you even THINK of them as people anymore! How dare you even think I —"`}`));
 					r.push(`The mercenary captain quickly gags ${him}, "My apologies, I did warn you ${he} was a handful. Please be careful when you unbind ${him}, ${he} may try to do something stupid," he says as he and his group exit your penthouse, leaving you with the enraged ${V.hostage.slaveName}. ${He} looks the same as you remember, but ${he} acts nothing like the ${girl} you used to know. Odds are high that ${he}'ll cause problems for you in the future.`);
 				}
 		}
 
-		if (V.rivalryDuration <= 10 || (V.rivalryFS === "Racial Supremacism" && V.rivalryDuration <= 20) || (V.rivalryFS === "Paternalism" && V.rivalryDuration <= 20)) {
+		if (V.rival.duration <= 10 || (V.rival.FS.name === "Racial Supremacism" || V.rival.FS.name === "Paternalism") && V.rival.duration <= 20) {
 			r.push(`${He} considers you ${his} rescuer, since ${his} previous owner subjected ${him} to unremitting horror in an attempt`);
-			if (V.rivalryFS !== 0) {
-				r.push(`to offend your philosophy of ${V.rivalryFS}.`);
+			if (V.rival.FS.name !== "") {
+				r.push(`to offend your philosophy of ${V.rival.FS.name}.`);
 			} else {
 				r.push(`turn ${him} against you.`);
 			}
 			r.push(`${He}'s overjoyed to be your slave.`);
-		} else if ((V.rivalryFS === "Racial Supremacism" && V.rivalryDuration > 20) || (V.rivalryFS === "Paternalism" && V.rivalryDuration > 20)) {
-			r.push(`${His} mind and body were destroyed in an attempt to offend your philosophy of ${V.rivalryFS}. If ${he} ever recovers, ${he}'d consider you ${his} savior and be overjoyed to be your slave.`);
-		} else if (V.rivalryFS === "Slave Professionalism") {
+		} else if ((V.rival.FS.name === "Racial Supremacism" || V.rival.FS.name === "Paternalism") && V.rival.duration > 20) {
+			r.push(`${His} mind and body were destroyed in an attempt to offend your philosophy of ${V.rival.FS.name}. If ${he} ever recovers, ${he}'d consider you ${his} savior and be overjoyed to be your slave.`);
+		} else if (V.rival.FS.name === "Slave Professionalism") {
 			r.push(`${His} mind was ravaged and perverted by rampant use of psychosuppressants and aphrodisiacs. There is no coming back from the damages done.`);
-		} else if (V.rivalryFS === "Intellectual Dependency") {
+		} else if (V.rival.FS.name === "Intellectual Dependency") {
 			r.push(`${He} has undergone so much slave training that ${he} considers this turn of events ultimately meaningless. You are just ${his} new owner and ${he} will serve you to the best of ${his} abilities; as a slave should.`);
-		} else if (V.rivalryDuration > 20) {
+		} else if (V.rival.duration > 20) {
 			r.push(`You took everything from ${him} and ${he} hates you as much as ${he} possibly can for it. You ripped ${him} away from heaven to sentence ${him} to a living hell, and ${he} swears to do everything ${he} can to hurt you.`);
 		} else {
 			r.push(`${He} is horrified by this turn of events. Your rival taught ${him} a great deal about slave life in your arcology and indulged ${his} deepest fantasies. ${V.hostage.slaveName} considers becoming your slave little better than a condemnation to purgatory.`);
@@ -1323,5 +1322,7 @@ App.Events.pHostageAcquisition = class pHostageAcquisition extends App.Events.Ba
 
 		App.Events.addParagraph(node, r);
 		node.append(App.UI.newSlaveIntro(V.hostage));
+		delete V.hostageWife;
+		V.hostage = 0;
 	}
 };
diff --git a/src/events/nonRandom/rival/pRivalInitiation.js b/src/events/nonRandom/rival/pRivalInitiation.js
index 29b37210d002eaf3dd6b073124d81e92fd853ea1..f655fbccb812d85eee3262966b9e5c4bed2c7e18 100644
--- a/src/events/nonRandom/rival/pRivalInitiation.js
+++ b/src/events/nonRandom/rival/pRivalInitiation.js
@@ -1,16 +1,14 @@
 App.Events.PRivalInitiation = class PRivalInitiation extends App.Events.BaseEvent {
 	eventPrerequisites() {
 		return [
-			() => V.rivalOwner === -1,
-			() => !!getSlave(V.rivalID)
+			() => V.rival.state === 3,
+			() => !!getSlave(V.rival.ID)
 		];
 	}
 
 	execute(node) {
-		V.rivalOwner = 0;
-		V.rivalOwnerEnslaved = 1;
-
-		const slave = getSlave(V.rivalID);
+		V.rival.state = 5;
+		const slave = getSlave(V.rival.ID);
 		const {
 			He, His,
 			he, him, his, himself
@@ -34,9 +32,7 @@ App.Events.PRivalInitiation = class PRivalInitiation extends App.Events.BaseEven
 		}
 		App.Events.addResponses(node, choices);
 
-		// reset event trigger
-		V.rivalID = 0;
-
+		delete V.rival.ID;
 		function tour() {
 			const frag = new DocumentFragment();
 			let r = [];
@@ -61,8 +57,7 @@ App.Events.PRivalInitiation = class PRivalInitiation extends App.Events.BaseEven
 				`Such public humiliation starts ${him} down the path of <span class="hotpink">obedience,</span> and is the <span class="green">talk of the Free Cities.</span>`
 			);
 			slave.devotion += 4;
-			slave.counter.oral += 1;
-			V.oralTotal += 1;
+			seX(slave, "oral", V.PC);
 			repX(2500, "event", slave);
 			App.Events.addParagraph(frag, r);
 			return frag;
@@ -81,9 +76,10 @@ App.Events.PRivalInitiation = class PRivalInitiation extends App.Events.BaseEven
 				r.push(`the ground,`);
 			}
 			r.push(`and, in full view of the whole arcology, orally rapes someone who was until this week a slaveowner ${himself}. Behind them, ${V.slaves[1].slaveName} is standing ready for ${his2} turn, and all your other slaves stand behind ${him2}. Public opinion is divided; the precedent is universally agreed to be bad, but the punishment is generally thought to be terrible and deserved. Your slaves, however, are almost insufferably <span class="hotpink">pleased with you</span> for forcing ${slave.slaveName}, whom they still view as a slaveowner, to pleasure them.`);
-			slave.counter.oral += V.slaves.length * 2;
-			V.oralTotal += V.slaves.length * 2;
-			V.slaves.forEach(function(s) { s.devotion += 10; });
+			V.slaves.forEach(s => {
+				seX(slave, "oral", s);
+				s.devotion += 10;
+			});
 			App.Events.addParagraph(frag, r);
 			return frag;
 		}
diff --git a/src/events/nonRandom/rival/pRivalryActions.js b/src/events/nonRandom/rival/pRivalryActions.js
index f9cfe54b370aa2b951dccea328e49f8ff4ecc83f..1b7df31f25e646552c50e116687a73a8da8f085e 100644
--- a/src/events/nonRandom/rival/pRivalryActions.js
+++ b/src/events/nonRandom/rival/pRivalryActions.js
@@ -4,35 +4,33 @@ App.Events.pRivalryActions = function() {
 	function execute() {
 		const node = new DocumentFragment();
 		let r = [];
-		if (V.hostageAnnounced === 1 && V.hostage) {
-			App.Events.drawEventArt(node, V.hostage);
-		}
-		V.rivalryDuration += 1;
+		V.rival.duration++;
 
 		const {
 			HisR, HeR,
 			hisR, himR
-		} = getPronouns({pronoun: (V.rivalGender === 2) ? 1 : 0}).appendSuffix("R");
+		} = getPronouns({pronoun: (V.rival.gender === 2) ? 1 : 0}).appendSuffix("R");
 		const {girlU, hisU, himU, heU} = getNonlocalPronouns(V.seeDicks).appendSuffix("U");
 		const {heA, hisA} = getPronouns(assistant.pronouns().main).appendSuffix("A");
 		const {woman2, he2, his2, him2, mother2, wife2} = getPronouns(V.hostageWife || {pronoun: 0}).appendSuffix("2");
 
-		r.push(`Your inter-arcology war with the arcology owner behind the Daughters of Liberty has dragged on for ${V.rivalryDuration} ${(V.rivalryDuration > 1) ? `weeks` : `week`}. The tone of your arcology is a bit more somber than usual. You have enhanced security in place, and the populace has caught the mood.`);
+		r.push(`Your inter-arcology war with the arcology owner behind the Daughters of Liberty has dragged on for ${num(V.rival.duration)} ${(V.rival.duration > 1) ? `weeks` : `week`}. The tone of your arcology is a bit more somber than usual. You have enhanced security in place, and the populace has caught the mood.`);
 
-		if (V.hostageAnnounced === 1 && V.hostage) {
+		if (V.rival.hostageState === 1 && V.hostage) {
+			App.Events.drawEventArt(node, V.hostage);
 			const {
 				He, His,
 				he, him, himself, his, girl, woman
 			} = getPronouns(V.hostage);
 			const seed = random(1, 100);
 
-			if (V.rivalryDuration >= 30) {
+			if (V.rival.duration >= 30) {
 				r.push(`The latest message from your rival is a live communication.`);
 			} else {
 				r.push(`The latest message from your rival recently arrived, showing ${SlaveFullName(V.hostage)}`);
 			}
-			if (V.rivalryDuration === 1) {
-				switch (V.rivalryFS) {
+			if (V.rival.duration === 1) {
+				switch (V.rival.FS.name) {
 					case "Racial Subjugationism":
 						V.hostage.trust -= 5;
 						V.hostage.devotion -= 5;
@@ -72,7 +70,7 @@ App.Events.pRivalryActions = function() {
 							V.hostage.preg = 4;
 							V.hostage.pregType = 8;
 							V.hostage.pregKnown = 1;
-							V.hostage.pregWeek = V.rivalryDuration;
+							V.hostage.pregWeek = V.rival.duration;
 							WombImpregnate(V.hostage, V.hostage.pregType, 0, V.hostage.preg);
 							SetBellySize(V.hostage);
 							V.hostage.vagina = 2;
@@ -89,7 +87,7 @@ App.Events.pRivalryActions = function() {
 							V.hostage.preg = 4;
 							V.hostage.pregType = 40;
 							V.hostage.pregKnown = 1;
-							V.hostage.pregWeek = V.rivalryDuration;
+							V.hostage.pregWeek = V.rival.duration;
 							WombImpregnate(V.hostage, V.hostage.pregType, 0, V.hostage.preg);
 							SetBellySize(V.hostage);
 							V.hostage.vagina = 2;
@@ -315,8 +313,8 @@ App.Events.pRivalryActions = function() {
 						V.hostage.sexualFlaw = "repressed";
 						r.push(`bound and being introduced to ${his} new lifestyle.`);
 				}
-			} else if (V.rivalryDuration === 6) {
-				switch (V.rivalryFS) {
+			} else if (V.rival.duration === 6) {
+				switch (V.rival.FS.name) {
 					case "Racial Subjugationism":
 						V.hostage.trust -= 5;
 						V.hostage.devotion -= 5;
@@ -361,7 +359,7 @@ App.Events.pRivalryActions = function() {
 							V.hostage.preg = 11;
 							V.hostage.pregType = 8;
 							V.hostage.pregKnown = 1;
-							V.hostage.pregWeek = V.rivalryDuration;
+							V.hostage.pregWeek = V.rival.duration;
 							WombImpregnate(V.hostage, V.hostage.pregType, 0, V.hostage.preg);
 							SetBellySize(V.hostage);
 							V.hostage.counter.oral += 50;
@@ -376,7 +374,7 @@ App.Events.pRivalryActions = function() {
 							V.hostage.preg = 11;
 							V.hostage.pregType = 40;
 							V.hostage.pregKnown = 1;
-							V.hostage.pregWeek = V.rivalryDuration;
+							V.hostage.pregWeek = V.rival.duration;
 							WombImpregnate(V.hostage, V.hostage.pregType, 0, V.hostage.preg);
 							SetBellySize(V.hostage);
 							V.hostage.boobs += 100;
@@ -701,8 +699,8 @@ App.Events.pRivalryActions = function() {
 						V.hostage.fetishStrength = 10;
 						r.push(`questioning why ${he} is yearning to be a part of this society.`);
 				}
-			} else if (V.rivalryDuration === 11) {
-				switch (V.rivalryFS) {
+			} else if (V.rival.duration === 11) {
+				switch (V.rival.FS.name) {
 					case "Racial Subjugationism":
 						V.hostage.trust -= 5;
 						V.hostage.devotion -= 5;
@@ -770,7 +768,7 @@ App.Events.pRivalryActions = function() {
 							V.hostage.preg = 21;
 							V.hostage.pregType = 8;
 							V.hostage.pregKnown = 1;
-							V.hostage.pregWeek = V.rivalryDuration;
+							V.hostage.pregWeek = V.rival.duration;
 							WombImpregnate(V.hostage, V.hostage.pregType, 0, V.hostage.preg);
 							SetBellySize(V.hostage);
 							V.hostage.vagina = 3;
@@ -794,7 +792,7 @@ App.Events.pRivalryActions = function() {
 							V.hostage.preg = 21;
 							V.hostage.pregType = 40;
 							V.hostage.pregKnown = 1;
-							V.hostage.pregWeek = V.rivalryDuration;
+							V.hostage.pregWeek = V.rival.duration;
 							WombImpregnate(V.hostage, V.hostage.pregType, 0, V.hostage.preg);
 							SetBellySize(V.hostage);
 							V.hostage.vagina = 3;
@@ -1146,8 +1144,8 @@ App.Events.pRivalryActions = function() {
 						V.hostage.sexualQuirk = "caring";
 						r.push(`eagerly getting ready to spend some time in the city.`);
 				}
-			} else if (V.rivalryDuration === 16) {
-				switch (V.rivalryFS) {
+			} else if (V.rival.duration === 16) {
+				switch (V.rival.FS.name) {
 					case "Racial Subjugationism":
 						V.hostage.trust -= 5;
 						V.hostage.devotion -= 5;
@@ -1200,7 +1198,7 @@ App.Events.pRivalryActions = function() {
 							V.hostage.preg = 31;
 							V.hostage.pregType = 8;
 							V.hostage.pregKnown = 1;
-							V.hostage.pregWeek = V.rivalryDuration;
+							V.hostage.pregWeek = V.rival.duration;
 							WombImpregnate(V.hostage, V.hostage.pregType, 0, V.hostage.preg);
 							SetBellySize(V.hostage);
 							V.hostage.vagina = 4;
@@ -1220,7 +1218,7 @@ App.Events.pRivalryActions = function() {
 							V.hostage.preg = 31;
 							V.hostage.pregType = 40;
 							V.hostage.pregKnown = 1;
-							V.hostage.pregWeek = V.rivalryDuration;
+							V.hostage.pregWeek = V.rival.duration;
 							WombImpregnate(V.hostage, V.hostage.pregType, 0, V.hostage.preg);
 							SetBellySize(V.hostage);
 							V.hostage.vagina = 4;
@@ -1512,8 +1510,8 @@ App.Events.pRivalryActions = function() {
 						V.hostage.fetishStrength = 100;
 						r.push(`chatting with a group of fresh slaves, explaining how nice it is to live in this arcology.`);
 				}
-			} else if (V.rivalryDuration === 21) {
-				switch (V.rivalryFS) {
+			} else if (V.rival.duration === 21) {
+				switch (V.rival.FS.name) {
 					case "Racial Subjugationism":
 						V.hostage.counter.oral += 50;
 						V.hostage.counter.vaginal += 50;
@@ -1826,9 +1824,9 @@ App.Events.pRivalryActions = function() {
 						V.hostage.counter.vaginal += 1;
 						r.push(`giving an interview. ${He} gushes over how great it is to experience all manners of class and culture, both physically and spiritually.`);
 				}
-			} else if (V.rivalryDuration >= 30) {
-				V.hostageAnnounced = 0;
-				switch (V.rivalryFS) {
+			} else if (V.rival.duration >= 30) {
+				V.rival.hostageState = 0;
+				switch (V.rival.FS.name) {
 					case "Racial Subjugationism":
 						r.push(`"Looking for ${SlaveFullName(V.hostage)}? Too bad, I couldn't bear to think of you ever getting your rotten little hands on ${him}, so I sent ${him} and ${his} lovers someplace far away. Someplace you'll never find them. Bet tha"`);
 						break;
@@ -1910,9 +1908,9 @@ App.Events.pRivalryActions = function() {
 				r.push(`- You end the call.`);
 			} else {
 				const hostageAction = [];
-				switch (V.rivalryFS) {
+				switch (V.rival.FS.name) {
 					case "Racial Subjugationism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 10;
@@ -1921,7 +1919,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`struggling to escape the grasp of a pair of ${V.arcologies[0].FSSubjugationistRace} ${girlU}s.`);
 							hostageAction.push(`struggling to avoid giving ${addA(V.arcologies[0].FSSubjugationistRace)} ${girlU} oral.`);
 							hostageAction.push(`screaming as ${he} gets fucked by ${addA(V.arcologies[0].FSSubjugationistRace)} ${girlU}.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -1931,7 +1929,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`crying gently while a pair of ${V.arcologies[0].FSSubjugationistRace} ${girlU}s fondle ${him}.`);
 							hostageAction.push(`reluctantly giving ${addA(V.arcologies[0].FSSubjugationistRace)} ${girlU} oral.`);
 							hostageAction.push(`crying as ${he} gets fucked by ${addA(V.arcologies[0].FSSubjugationistRace)} ${girlU}.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -1941,7 +1939,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`fooling around with a pair of ${V.arcologies[0].FSSubjugationistRace} ${girlU}s.`);
 							hostageAction.push(`giving ${addA(V.arcologies[0].FSSubjugationistRace)} ${girlU} oral.`);
 							hostageAction.push(`panting as ${he} gets fucked by ${addA(V.arcologies[0].FSSubjugationistRace)} ${girlU}.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 40;
@@ -1960,7 +1958,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Racial Supremacism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust += 5;
 							V.hostage.devotion += 5;
 							V.hostage.weight -= 5;
@@ -1971,7 +1969,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`desperately struggling in a stockade, alongside several other ${V.arcologies[0].FSSupremacistRace} slaves, while a man tries to get it in ${him}.`);
 							hostageAction.push(`struggling against ${his} bindings in a line of ${V.arcologies[0].FSSupremacistRace} slaves, having ${his} bruised holes checked.`);
 							hostageAction.push(`weeping as a dispassionate slave assayer goes down a line of ${V.arcologies[0].FSSupremacistRace} slaves, reciting prices.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust += 5;
 							V.hostage.devotion += 5;
 							V.hostage.weight -= 5;
@@ -1983,7 +1981,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`meekly taking it in the cunt by a man while bound in a stockade alongside several other ${V.arcologies[0].FSSupremacistRace} girls.`);
 							hostageAction.push(`tied up with a defeated look in a line of ${V.arcologies[0].FSSupremacistRace} slaves, having ${his} stretched holes checked.`);
 							hostageAction.push(`crying as a dispassionate slave assayer goes down a line of ${V.arcologies[0].FSSupremacistRace} slaves, reciting prices.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust += 5;
 							V.hostage.devotion += 5;
 							V.hostage.weight -= 5;
@@ -2000,7 +1998,7 @@ App.Events.pRivalryActions = function() {
 								hostageAction.push(`tied up with a downtrodden look in a line of ${V.arcologies[0].FSSupremacistRace} slaves, having ${his} overworked holes examined.`);
 							}
 							hostageAction.push(`silently staring at ${his} feet as a dispassionate slave assayer goes down a line of ${V.arcologies[0].FSSupremacistRace} slaves, reciting prices.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust += 5;
 							V.hostage.devotion += 5;
 							V.hostage.weight -= 5;
@@ -2032,7 +2030,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Repopulation Focus":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 5;
@@ -2042,7 +2040,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`desperately trying to avoid reading the reports on pregnancy in your arcology.`);
 							hostageAction.push(`crying while gently rubbing ${his} infertile stomach.`);
 							hostageAction.push(`sobbing as an autosurgery reads out the details of ${his} infertility.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 5;
@@ -2052,7 +2050,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`carefully reading the reports on pregnancy in your arcology.`);
 							hostageAction.push(`staring at ${his} midriff, contemplating why someone would take ${his} fertility away.`);
 							hostageAction.push(`pondering the health benefits being given to ${him}.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 5;
@@ -2062,7 +2060,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`gently crying while reading the reports on pregnancy in your arcology.`);
 							hostageAction.push(`relaxing, knowing ${he} will never deal with menstruation again.`);
 							hostageAction.push(`accepting that ${his} body will never be ruined by pregnancy.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 5;
@@ -2083,7 +2081,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Eugenics":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 50;
@@ -2099,7 +2097,7 @@ App.Events.pRivalryActions = function() {
 								hostageAction.push(`weeping at the results of a pregnancy test.`);
 								hostageAction.push(`sobbing as ${he} tries to coax the cum out of ${his} womb.`);
 							}
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2116,7 +2114,7 @@ App.Events.pRivalryActions = function() {
 								hostageAction.push(`cringing at a report of the obscene number of babies stretching ${his} womb.`);
 								hostageAction.push(`crying as ${he} cradles ${his} full-sized pregnancy.`);
 							}
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2136,7 +2134,7 @@ App.Events.pRivalryActions = function() {
 								hostageAction.push(`smilingly slightly seeing ${his} many babies via ultrasound.`);
 								hostageAction.push(`doing yoga with helpers to prepare ${his} bloated body for mass childbirth.`);
 							}
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.boobs += 50;
@@ -2175,13 +2173,13 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Gender Radicalism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							hostageAction.push(`being dragged along by ${his} owner on their rounds around their arcology.`);
 							hostageAction.push(`being forced into a pretty dress as to not embarrass ${his} owner, though ${his} tantrum will do just that.`);
 							hostageAction.push(`viciously slapping ${his} owner's hand away.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2189,7 +2187,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`reluctantly following ${his} owner along on their rounds around their arcology.`);
 							hostageAction.push(`reluctantly allowing ${himself} to be dressed to present a good appearance alongside ${his} owner.`);
 							hostageAction.push(`reluctantly holding ${his} owner's hand.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2198,7 +2196,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`politely accompanying ${his} owner on their rounds around their arcology.`);
 							hostageAction.push(`allowing ${himself} to be dressed to present a good appearance alongside ${his} owner.`);
 							hostageAction.push(`holding ${his} owner's hand.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.vaginal += 1;
@@ -2219,14 +2217,14 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Gender Fundamentalism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.anal += 10;
 							hostageAction.push(`struggling not to orgasm to the dick up ${his} ass.`);
 							hostageAction.push(`screaming in terror as a hot shaft slips into ${his} rectum.`);
 							hostageAction.push(`crying in the shower as ${he} attempts to soothe ${his} throbbing rectum.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2234,7 +2232,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`reluctantly pleasuring a man with ${his} ass.`);
 							hostageAction.push(`groaning in discomfort as yet another dick slides into ${his} ass.`);
 							hostageAction.push(`groaning in the shower as ${he} soothes ${his} sore ass.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2248,7 +2246,7 @@ App.Events.pRivalryActions = function() {
 								hostageAction.push(`letting off a moan as a penis slides into ${his} asspussy.`);
 								hostageAction.push(`cleaning ${his} rear while fondling ${his} asspussy.`);
 							}
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.anal += 10;
@@ -2275,7 +2273,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Paternalism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust += 5;
 							V.hostage.devotion += 5;
 							V.hostage.counter.oral += 50;
@@ -2289,7 +2287,7 @@ App.Events.pRivalryActions = function() {
 							}
 							hostageAction.push(`screaming as ${he} has the soles of ${his} feet whipped.`);
 							hostageAction.push(`tearfully begging someone not to cut ${him}.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust += 5;
 							V.hostage.devotion += 5;
 							V.hostage.fetishStrength += 5;
@@ -2304,7 +2302,7 @@ App.Events.pRivalryActions = function() {
 							}
 							hostageAction.push(`crying out as ${his} back is lashed.`);
 							hostageAction.push(`tearfully crying on the ground after someone tripped ${him} and stole ${his} heels for the sole purpose of denying ${him} the ability to walk.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust += 5;
 							V.hostage.devotion += 5;
 							V.hostage.fetishStrength += 5;
@@ -2319,7 +2317,7 @@ App.Events.pRivalryActions = function() {
 							}
 							hostageAction.push(`sobbing as ${he} is mercilessly beaten.`);
 							hostageAction.push(`panicking as ${he} attempts to mime a plea to not get cut by ${his} aggressor.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust += 5;
 							V.hostage.devotion += 5;
 							V.hostage.counter.oral += 50;
@@ -2346,13 +2344,13 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Degradationism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							hostageAction.push(`refusing to be touched by ${his} owner.`);
 							hostageAction.push(`refusing to even look at ${his} owner.`);
 							hostageAction.push(`getting mad when asked about ${his} sexual exploits.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2360,7 +2358,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`reluctantly allowing ${his} owner to play with ${his} body.`);
 							hostageAction.push(`gingerly looking at ${his} owner as they approach.`);
 							hostageAction.push(`blushing and avoiding the question when asked about ${his} sexual exploits.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2368,7 +2366,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`making love with ${his} owner.`);
 							hostageAction.push(`curiously watching ${his} owner as they approach.`);
 							hostageAction.push(`blurting it out and burying ${his} face in ${his} hands when asked about ${his} sexual exploits with ${his} owner.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.vaginal += 1;
@@ -2389,7 +2387,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Body Purism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.boobs += 2000;
@@ -2400,7 +2398,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`trying desperately to stand despite ${his} massive ${V.hostage.boobs}cc fake tits.`);
 							hostageAction.push(`crying while trying to get comfortable with ${his} ${V.hostage.boobs}cc fake tits.`);
 							hostageAction.push(`sobbing as an autosurgery reads out how much ${his} ${V.hostage.boobs}cc implants can be expanded this week.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2412,7 +2410,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`reluctantly exploring ${his} new massive ${V.hostage.boobs}cc implants.`);
 							hostageAction.push(`reluctantly exploring new resting positions due to ${his} ${V.hostage.boobs}cc implants.`);
 							hostageAction.push(`crying as an autosurgery reads out how much ${his} ${V.hostage.boobs}cc implants can be expanded this week.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2424,7 +2422,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`happily playing with ${his} truly immense ${V.hostage.boobs}cc breast implants and huge butt implants.`);
 							hostageAction.push(`happily resting ${his} head on ${his} ${V.hostage.boobs}cc breast implants.`);
 							hostageAction.push(`blushing as an autosurgery reads out how much ${his} ${V.hostage.boobs}cc implants can be expanded this week.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.boobs += 1000;
@@ -2443,13 +2441,13 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Transformation Fetishism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							hostageAction.push(`attempting to refute a report on surgical side effects in your arcology.`);
 							hostageAction.push(`refusing to believe pictures of surgeries performed in your arcology are real.`);
 							hostageAction.push(`wondering why these maniacs care if ${his} body is unaltered or not.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2457,7 +2455,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`refusing to believe a report on surgical side effects in your arcology.`);
 							hostageAction.push(`gaping in surprise at pictures of surgeries performed in your arcology.`);
 							hostageAction.push(`admiring how natural ${his} body truly is.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2465,7 +2463,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`gasping at a report on surgical side effects in your arcology.`);
 							hostageAction.push(`gasping in horror at pictures of surgeries performed in your arcology.`);
 							hostageAction.push(`beginning to understand how beautiful ${his} pure body is.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.vaginal += 1;
@@ -2480,7 +2478,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Youth Preferentialism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 1;
@@ -2489,7 +2487,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`struggling to escape the grasp of a motherly ${woman2}.`);
 							hostageAction.push(`hiding from ${his} MILF partner, sobbing quietly.`);
 							hostageAction.push(`struggling to escape being mothered by ${his} older partner.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2499,7 +2497,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`crying gently while a ${mother2}ly ${woman2} fondles ${him}.`);
 							hostageAction.push(`cringing as ${he} massages ${his} MILF partner's back.`);
 							hostageAction.push(`cautiously tasting ${his} MILF partner's milk.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2509,7 +2507,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`resting in the arms of ${his} MILF friend.`);
 							hostageAction.push(`carefully giving ${his} MILF lover a back massage.`);
 							hostageAction.push(`carefully suckling ${his} MILF friend's nipple.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 10;
@@ -2528,7 +2526,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Maturity Preferentialism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 1;
@@ -2537,7 +2535,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`struggling to escape the grasp of an energetic young $woman2}.`);
 							hostageAction.push(`shouting profanity at ${his} young partner.`);
 							hostageAction.push(`rebuking ${his} young partner's advances.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2547,7 +2545,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`crying gently while a young ${woman2} eagerly fondles ${him}.`);
 							hostageAction.push(`shying away from ${his} young partner.`);
 							hostageAction.push(`curiously fondling ${his} young partner's dick.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2557,7 +2555,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`trying to catch a break as ${his} young friend begs to have some more fun.`);
 							hostageAction.push(`resting alongside ${his} young friend.`);
 							hostageAction.push(`cautiously rubbing ${his} energetic young friend's cock.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 10;
@@ -2576,7 +2574,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Slimness Enthusiasm":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight += 5;
@@ -2584,7 +2582,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`trying desperately to stand despite ${his} massive ${V.hostage.boobs}cc tits.`);
 							hostageAction.push(`crying over ${his} swollen breasts and butt.`);
 							hostageAction.push(`weeping as the breast injections swell ${his} breasts to ${V.hostage.boobs}ccs.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2593,7 +2591,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`reluctantly exploring ${his} new massive ${V.hostage.boobs}cc tits, bigger bottom, and softer body.`);
 							hostageAction.push(`cringing as ${he} feels ${his} huge soft tits and ass.`);
 							hostageAction.push(`cringing as the breast injections swell ${his} breasts to ${V.hostage.boobs}ccs along with ${his} butt.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -2602,7 +2600,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`happily playing with ${his} truly immense ${V.hostage.boobs}cc breasts and huge butt.`);
 							hostageAction.push(`giggling as ${he} gropes ${his} soft body.`);
 							hostageAction.push(`smiling as the breast injections swell ${his} breasts to ${V.hostage.boobs}ccs. ${He} runs ${his} hand across ${his} huge butt and softening body.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight += 5;
@@ -2618,27 +2616,27 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Asset Expansionism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							hostageAction.push(`attempting to refute a report on drug side effects in your arcology.`);
 							hostageAction.push(`refusing to believe pictures of excessively expanded slaves in your arcology are real.`);
 							hostageAction.push(`refusing to show off ${his} natural body.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.vaginal += 1;
 							hostageAction.push(`refusing to believe a report on drug side effects in your arcology.`);
 							hostageAction.push(`gasping in surprise at pictures of excessively expanded slaves in your arcology.`);
 							hostageAction.push(`reluctantly doing a series of stretching exercises to show off ${his} natural body.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.vaginal += 1;
 							hostageAction.push(`gasping at a report on drug side effects in your arcology.`);
 							hostageAction.push(`gasping in horror at pictures of excessively expanded slaves in your arcology.`);
 							hostageAction.push(`doing a series of stretching exercises to show off ${his} natural body.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.vaginal += 1;
@@ -2653,7 +2651,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Pastoralism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight -= 5;
@@ -2661,7 +2659,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`angrily jogging on a treadmill, ${his} fat body and big tits jiggling constantly.`);
 							hostageAction.push(`trying to catch ${his} breath and stop ${his} fat body from sweating.`);
 							hostageAction.push(`struggling to run ${his} overweight body around a track.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight -= 5;
@@ -2671,7 +2669,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`reluctantly doing sit-ups, ${his} plush body struggling to manage.`);
 							hostageAction.push(`checking ${himself} out in the mirror, gawking at how much weight ${he}'s lost.`);
 							hostageAction.push(`attempting to run a lap around the track despite ${his} overweight body.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight -= 5;
@@ -2681,7 +2679,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`lifting weights, ${his} soft body barely hiding ${his} bulging muscles.`);
 							hostageAction.push(`pinching ${his} remaining flab and making a disgusted face.`);
 							hostageAction.push(`running laps around the track to burn off ${his} excess bodyfat.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight -= 5;
@@ -2698,7 +2696,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Cummunism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight += 5;
@@ -2708,7 +2706,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`trying desperately to extract the milk from ${his} massive ${V.hostage.boobs}cc tits. ${He} appears to have gained some weight.`);
 							hostageAction.push(`sobbing as ${he} massages ${his} sore ${V.hostage.boobs}cc udders.`);
 							hostageAction.push(`sobbing as the milkers drain ${his} ${V.hostage.boobs}cc udders.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight += 5;
@@ -2719,7 +2717,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`reluctantly asking for ${his} massive ${V.hostage.boobs}cc tits to be milked. ${He}'s certainly getting soft.`);
 							hostageAction.push(`crying as rubs ${his} uncomfortably massive ${V.hostage.boobs}cc udders and softening belly.`);
 							hostageAction.push(`sighing as the milkers drain ${his} big ${V.hostage.boobs}cc udders while ${he} massages ${his} softening belly.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight += 5;
@@ -2730,7 +2728,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`happily asking for ${his} truly immense ${V.hostage.boobs}cc breasts to be milked. ${His} body has become notably plush.`);
 							hostageAction.push(`humming as ${he} soothes ${his} truly immense sore ${V.hostage.boobs}cc udders. ${He} lets off a content sigh as ${he} jiggles ${his} soft belly.`);
 							hostageAction.push(`sighing with relief as the milkers drain ${his} huge ${V.hostage.boobs}cc udders while ${he} massages ${his} jiggly belly.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight += 5;
@@ -2749,7 +2747,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Physical Idealism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight += 5;
@@ -2758,7 +2756,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`trying desperately to vomit up all the food forced into ${his} bloated stomach while being thwarted by a specialized gag. ${He} appears to have gained some weight.`);
 							hostageAction.push(`sobbing as ${he} is forcibly raped and broken in.`);
 							hostageAction.push(`sobbing as ${he} is forced is experience all manner of perversion in an effort to reveal ${his} fetishes.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight += 5;
@@ -2818,7 +2816,7 @@ App.Events.pRivalryActions = function() {
 									hostageAction.push(`struggling to hold back ${his} joy as another huge load shoots into ${his} fertile womb.`);
 									break;
 							}
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight += 5;
@@ -2878,7 +2876,7 @@ App.Events.pRivalryActions = function() {
 									hostageAction.push(`humming softly as ${he} caresses ${his} early pregnancy.`);
 									break;
 							}
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight += 5;
@@ -3004,7 +3002,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Hedonistic Decadence":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight -= 5;
@@ -3012,7 +3010,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`angrily jogging on a treadmill, ${his} fat body and big tits jiggling constantly.`);
 							hostageAction.push(`trying to catch ${his} breath and stop ${his} fat body from sweating.`);
 							hostageAction.push(`struggling to run ${his} overweight body around a track.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight -= 5;
@@ -3022,7 +3020,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`reluctantly doing sit-ups, ${his} plush body struggling to manage.`);
 							hostageAction.push(`checking ${himself} out in the mirror, gawking at how much weight ${he}'s lost.`);
 							hostageAction.push(`attempting to run a lap around the track despite ${his} overweight body.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight -= 5;
@@ -3032,7 +3030,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`lifting weights, ${his} soft body barely hiding ${his} bulging muscles.`);
 							hostageAction.push(`pinching ${his} remaining flab and making a disgusted face.`);
 							hostageAction.push(`running laps around the track to burn off ${his} excess bodyfat.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.weight -= 5;
@@ -3049,13 +3047,13 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Chattel Religionism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							hostageAction.push(`attempting to refute a report on what's expected of slaves as part of your new religion.`);
 							hostageAction.push(`refusing to believe a video of a religious service in your arcology is real.`);
 							hostageAction.push(`refusing to socialize with other slaves.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -3063,7 +3061,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`refusing to believe a report on what's expected of slaves as part of your new religion.`);
 							hostageAction.push(`questioning the validity of a video of a religious service in your arcology.`);
 							hostageAction.push(`reluctantly spending time in ${his} arcology's cosmopolitan public spaces.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -3071,7 +3069,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`gasping at a report on what's expected of slaves as part of your new religion.`);
 							hostageAction.push(`gasping at the absurdity of a video of a religious service in your arcology.`);
 							hostageAction.push(`cautiously chatting with a group of slaves in ${his} arcology's cosmopolitan public spaces.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.vaginal += 1;
@@ -3086,13 +3084,13 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Multiculturalism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							hostageAction.push(`refusing the tenets of ${his} new religion.`);
 							hostageAction.push(`refusing to pray for your arcology's salvation.`);
 							hostageAction.push(`freaking out as several men approach ${him} for sex.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -3103,7 +3101,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`reluctantly following the tenets of ${his} new religion.`);
 							hostageAction.push(`questioning why ${he} is made to pray for your arcology's salvation.`);
 							hostageAction.push(`crying as ${he} is forced to service three dicks at once.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -3114,7 +3112,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`praying for the souls of the citizens and slaves of your arcology.`);
 							hostageAction.push(`trying to pray for your arcology's salvation.`);
 							hostageAction.push(`attempting to please the three dicks in ${him} as quickly as possible.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 50;
@@ -3135,13 +3133,13 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Intellectual Dependency":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							hostageAction.push(`refusing to pay attention to ${his} lessons.`);
 							hostageAction.push(`refusing to act like a proper ${girl}.`);
 							hostageAction.push(`forced into remedial training after threatening ${his} owner's reputation.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -3157,7 +3155,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`crying silently while being positioned to properly please ${his} partner.`);
 							hostageAction.push(`reluctantly balancing a book on ${his} head to perfect ${his} posture.`);
 							hostageAction.push(`reluctantly practicing enunciation to not risk angering ${his} owner.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -3173,7 +3171,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`attempting to pass an exam on sexual satisfaction.`);
 							hostageAction.push(`trying to show no reaction as ${he} is felt up by ${his} owner's client.`);
 							hostageAction.push(`attempting to please ${his} owner's friends and not be a failure.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 10;
@@ -3198,7 +3196,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Slave Professionalism":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust += 5;
 							V.hostage.devotion += 5;
 							V.hostage.counter.vaginal += 10;
@@ -3210,7 +3208,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`sobbing as ${he} struggles to not masturbate after a large hit of aphrodisiacs.`);
 							hostageAction.push(`holding ${his} head and struggling to recite ${his} favorite poem.`);
 							hostageAction.push(`refusing to put on the makeup presented to ${him}.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust += 5;
 							V.hostage.devotion += 5;
 							V.hostage.fetishStrength += 5;
@@ -3225,7 +3223,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`crying as ${he} rides a dick to orgasm.`);
 							hostageAction.push(`trying not to lose the memories of ${his} life before being captured.`);
 							hostageAction.push(`hesitantly trying on clothes and admiring ${his} figure in the mirror.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust += 5;
 							V.hostage.devotion += 5;
 							V.hostage.fetishStrength += 5;
@@ -3240,7 +3238,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`being presented with a selection of amusements and instead opting for the one between ${hisU} legs.`);
 							hostageAction.push(`walking around with ${his} breasts bouncing out of ${his} top and ${his} short skirt revealing ${his} lack of panties.`);
 							hostageAction.push(`admiring ${himself} in the mirror.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust += 5;
 							V.hostage.devotion += 5;
 							V.hostage.intelligenceImplant = Math.clamp(V.hostage.intelligenceImplant - 5, 0, 30);
@@ -3286,7 +3284,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Petite Admiration":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 1;
@@ -3295,7 +3293,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`struggling in vain as ${he} is carried around by ${his} towering partner.`);
 							hostageAction.push(`crammed under a bed to escape ${his} much larger partner.`);
 							hostageAction.push(`struggling to pull ${his} head away from ${his} much larger partner's crotch.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -3305,7 +3303,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`crying to ${himself} in the arms of ${his} towering partner as ${he} is carried around one of the arcology's public spaces.`);
 							hostageAction.push(`cringing as ${his} much larger partner sits ${him} in ${his2} lap and paws at ${him}.`);
 							hostageAction.push(`crying gently as ${his} much larger partner forces ${his} face to ${his2} crotch.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -3315,7 +3313,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`calmly letting ${his} towering partner carry ${him} around one of the arcology's public spaces.`);
 							hostageAction.push(`carefully sitting in ${his} much larger partner's lap and letting ${him2} fondle ${his} body.`);
 							hostageAction.push(`carefully putting ${his} mouth to use on ${his} much larger partner's crotch.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 15;
@@ -3334,7 +3332,7 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					case "Statuesque Glorification":
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 1;
@@ -3343,7 +3341,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`sitting on a table, out of reach of a shorter ${woman2} and swearing at ${him2}.`);
 							hostageAction.push(`keeping ${his} smaller partner from reaching ${him}.`);
 							hostageAction.push(`rebuking ${his} smaller partner's advances.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -3353,7 +3351,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`crying gently as a shorter ${woman2} eagerly fondles ${him}.`);
 							hostageAction.push(`shying away from ${his} shorter partner.`);
 							hostageAction.push(`curiously exploring ${his} shorter partner's body.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -3363,7 +3361,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`trying to catch a break from ${his} shorter partner's tongue in ${his} pussy.`);
 							hostageAction.push(`spooning ${his} shorter partner.`);
 							hostageAction.push(`cautiously giving ${his} shorter partner a full body massage.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.oral += 7;
@@ -3382,13 +3380,13 @@ App.Events.pRivalryActions = function() {
 						}
 						break;
 					default:
-						if (V.rivalryDuration <= 5) {
+						if (V.rival.duration <= 5) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							hostageAction.push(`refusing to believe what happens to slaves who don't fit into your arcology's revivalist culture.`);
 							hostageAction.push(`refusing to believe a video of your arcology's revivalist public events is real.`);
 							hostageAction.push(`refusing to socialize with other slaves.`);
-						} else if (V.rivalryDuration <= 10) {
+						} else if (V.rival.duration <= 10) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -3396,7 +3394,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`reluctantly reading a report on what happens to slaves who don't fit into your arcology's revivalist culture.`);
 							hostageAction.push(`questioning the validity of a video of your arcology's revivalist public events.`);
 							hostageAction.push(`reluctantly spending time in ${his} arcology's modern public spaces.`);
-						} else if (V.rivalryDuration <= 15) {
+						} else if (V.rival.duration <= 15) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.fetishStrength += 5;
@@ -3404,7 +3402,7 @@ App.Events.pRivalryActions = function() {
 							hostageAction.push(`gasping at a report on what happens to slaves who don't fit into your arcology's revivalist culture.`);
 							hostageAction.push(`gasping at the absurdity of a video of your arcology's revivalist public events.`);
 							hostageAction.push(`cautiously chatting with a group of slaves in ${his} arcology's modern public spaces.`);
-						} else if (V.rivalryDuration <= 20) {
+						} else if (V.rival.duration <= 20) {
 							V.hostage.trust -= 5;
 							V.hostage.devotion -= 5;
 							V.hostage.counter.vaginal += 1;
@@ -3424,18 +3422,18 @@ App.Events.pRivalryActions = function() {
 
 		App.Events.addParagraph(node, r);
 
-		App.UI.DOM.appendNewElement("p", node, `You remind yourself that success in this conflict will not be defined by the traditional measures of impending victory and defeat. The primary concern here is the weight of your holdings against those of your opponent. Improving your arcology's prosperity will move you closer to victory${(V.rivalSet === 1) ? `, and so will attacking the prosperity of your rival's neighboring arcology through economic means` : ``}. Of course, you can also take more direct action.`);
+		App.UI.DOM.appendNewElement("p", node, `You remind yourself that success in this conflict will not be defined by the traditional measures of impending victory and defeat. The primary concern here is the weight of your holdings against those of your opponent. Improving your arcology's prosperity will move you closer to victory${V.rival.state === 2 ? `, and so will attacking the prosperity of your rival's neighboring arcology through economic means` : ``}. Of course, you can also take more direct action.`);
 
 		r = [];
 
 		r.push(`${capFirstChar(V.assistant.name)} collates several options for directly attacking your rival. This is a corporate war, not a military one; your peers would not tolerate a direct attack on ${himR}. You must bankrupt your opponent so they are no longer able to hide within the physical and intangible fortress that is their arcology. Your rival`);
-		if ((V.rivalOwner - V.rivalryPower) / V.arcologies[0].prosperity < 0.6) {
+		if ((V.rival.prosperity - V.rival.power) / V.arcologies[0].prosperity < 0.6) {
 			r.push(`is on their economic knees, putting them on the verge of defeat.`);
-		} else if ((V.rivalOwner - V.rivalryPower) / V.arcologies[0].prosperity < 0.7) {
+		} else if ((V.rival.prosperity - V.rival.power) / V.arcologies[0].prosperity < 0.7) {
 			r.push(`is in a bad financial state, well on the way to final dissolution and defeat.`);
-		} else if ((V.rivalOwner - V.rivalryPower) / V.arcologies[0].prosperity < 0.8) {
+		} else if ((V.rival.prosperity - V.rival.power) / V.arcologies[0].prosperity < 0.8) {
 			r.push(`has taken some hard corporate blows but is still standing.`);
-		} else if ((V.rivalOwner - V.rivalryPower) / V.arcologies[0].prosperity < 0.9) {
+		} else if ((V.rival.prosperity - V.rival.power) / V.arcologies[0].prosperity < 0.9) {
 			r.push(`is starting to feel the pressure.`);
 		} else {
 			r.push(`is essentially undamaged; you have hard work ahead of you.`);
@@ -3449,10 +3447,10 @@ App.Events.pRivalryActions = function() {
 			() => {
 				cashX(-10000, "war");
 				if (random(1, 100) > 50) {
-					V.rivalryPower += 2;
+					V.rival.power += 2;
 					jQuery(result).empty().append(`Money is your infantry, your weapon, your ammunition in one. Last century, your soldiers would have died taking the enemy's positions. Today, your ¤ die <span class="positive">taking</span> ${hisR} holdings. Once more unto the breach.`);
 				} else {
-					V.rivalryPower += 1;
+					V.rival.power++;
 					jQuery(result).empty().append(`Money is your infantry, your weapon, your ammunition in one. Last century, your soldiers would have died before the enemy's machine guns. Today, your ¤ die <span class="red">failing to take</span> ${hisR} holdings. Once more unto the breach.`);
 				}
 			}
@@ -3464,11 +3462,11 @@ App.Events.pRivalryActions = function() {
 				cashX(-10000, "war");
 				if (random(1, 100) > 70) {
 					repX(-100, "war");
-					V.rivalryPower += 5;
+					V.rival.power += 5;
 					jQuery(result).empty().append(`Since you are not so uncouth as to, for example, help fund a coup attempt, you fund traditional acts of corporate sabotage, including hacking, slander, and actual, physical thievery. There are some <span class="reputation dec">minor rumors</span> that you are to blame, but they're outweighed by the <span class="positive">great pressure</span> these incidents put on your enemy.`);
 				} else {
 					repX(-500, "war");
-					V.rivalryPower += 2;
+					V.rival.power += 2;
 					jQuery(result).empty().append(`Since you are not so uncouth as to, for example, help fund a coup attempt, you fund traditional acts of corporate sabotage, including hacking, slander, and actual, physical thievery. Unfortunately, you seem to be a step behind this week. Your enemy <span class="red">prevents</span> many of your attacks, and even manages to turn a few minor players into public confessions that <span class="reputation dec">damage</span> your reputation.`);
 				}
 			}
@@ -3477,7 +3475,7 @@ App.Events.pRivalryActions = function() {
 			`Use ${cashFormat(25000)} creating local shortages`,
 			() => {
 				cashX(-25000, "war");
-				V.rivalryPower += 3;
+				V.rival.power += 3;
 				jQuery(result).empty().append(`With enough money, it's entirely possible to temporarily overwhelm even the advanced free market of the Free Cities. You choose a few critical items — pharmaceutical materials, electronic components, and other physical items — and purchase shipments intended for your rival's arcology. ${HisR} tenants are <span class="positive">seriously inconvenienced</span> and blame their difficulties on their hapless landlord.`);
 			}
 		));
@@ -3486,7 +3484,7 @@ App.Events.pRivalryActions = function() {
 			`Devote ${cashFormat(50000)} to purchasing the support of your peers`,
 			() => {
 				cashX(-50000, "war");
-				V.rivalryPower += 5;
+				V.rival.power += 5;
 				jQuery(result).empty().append(`Your fellow arcology owners have an interest in seeing the funder of the Daughters' attempt on you destroyed, but few of them are willing to spend any money or real effort on the matter. You do a few of them the favor of making the money and effort spent yours. Your rival finds ${hisR} dealings with your mutual peers becoming <span class="positive">strangely difficult.</span> Market opinion is swinging your way.`);
 			}
 		));
@@ -3495,7 +3493,7 @@ App.Events.pRivalryActions = function() {
 				const link = App.UI.DOM.appendNewElement("div", result, App.UI.DOM.link(
 					`Use your connections to throttle your rival's arcology`,
 					() => {
-						V.rivalryPower += 10;
+						V.rival.power += 10;
 						jQuery(result).empty().append(`With every external, and several internal, supply lines severed, ${hisR} tenants are faced with imminent destruction and <span class="positive">rise up</span> against their hapless landlord. ${HeR} will not be able to weather such a siege for long.`);
 					}
 				));
@@ -3510,9 +3508,9 @@ App.Events.pRivalryActions = function() {
 						const el = new DocumentFragment();
 						const r = [];
 						r.push(`One night, you're working late in your office, ${V.assistant.name}'s avatar glowing companionably beside you. Without preamble, ${heA} reports to you in ${hisA} normal tones, "Team One reports ${nickname()} EKIA. Confirm, E. K. I. A. No other casualties, team exfiltrating."`);
-						V.rivalOwner = 0;
-						V.rivalryPower = 0;
-						if (V.rivalSet !== 0) {
+						V.rival.prosperity = 0;
+						V.rival.power = 0;
+						if (V.rival.state === 2) {
 							for (const arc of V.arcologies) {
 								if (arc.rival === 1) {
 									arc.embargo = 0;
@@ -3524,9 +3522,10 @@ App.Events.pRivalryActions = function() {
 								}
 							}
 						}
-						if (V.hostageAnnounced === 1) {
+						V.rival.state = 4;
+						if (V.rival.hostageState === 1) {
 							r.push(`${V.assistant.name} pauses. "Also confirm package is secure."`);
-							V.hostageRescued = 1;
+							V.rival.hostageState = 2;
 						}
 						r.push(`You go back to your work.`);
 						App.Events.addNode(el, r, "div");
@@ -3552,9 +3551,9 @@ App.Events.pRivalryActions = function() {
 							r.push(`EKIA. Confirm, E. K. I. A. No other`);
 						}
 						r.push(`casualties, team exfiltrating."`);
-						V.rivalOwner = 0;
-						V.rivalryPower = 0;
-						if (V.rivalSet !== 0) {
+						V.rival.prosperity = 0;
+						V.rival.power = 0;
+						if (V.rival.state === 2) {
 							for (const arc of V.arcologies) {
 								if (arc.rival === 1) {
 									arc.embargo = 0;
@@ -3562,18 +3561,23 @@ App.Events.pRivalryActions = function() {
 									arc.influenceTarget = -1;
 									arc.rival = 0;
 									arc.government = "direct democracy";
-									if (rivalCaptured && arc.FSSupremacist > 20) {
-										V.rivalRace = arc.FSSupremacistRace;
-									} else if (rivalCaptured && arc.FSSubjugationist > 20) {
-										V.rivalRace = Array.from(setup.filterRaces.keys()).filter(race => race !== arc.FSSubjugationistRace).random();
+									if (rivalCaptured) {
+										V.rival.state = 3;
+										if (arc.FSSupremacist > 20) {
+											V.rival.race = arc.FSSupremacistRace;
+										} else if (arc.FSSubjugationist > 20) {
+											V.rival.race = Array.from(App.Data.misc.filterRacesPublic.keys()).filter(race => race !== arc.FSSubjugationistRace).random();
+										}
+									} else {
+										V.rival.state = 4;
 									}
 									break;
 								}
 							}
 						}
-						if (V.hostageAnnounced === 1) {
+						if (V.rival.hostageState === 1) {
 							r.push(`${V.assistant.name} pauses. "Also confirm package is secure."`);
-							V.hostageRescued = 1;
+							V.rival.hostageState = 2;
 						}
 						r.push(`Smirking to yourself at a job well done, you`);
 						if (rivalCaptured) {
@@ -3593,7 +3597,7 @@ App.Events.pRivalryActions = function() {
 		}
 		return node;
 		function nickname() {
-			switch (V.rivalryFS) {
+			switch (V.rival.FS.name) {
 				case "Racial Subjugationism":
 					return `Racemixer`;
 				case "Racial Supremacism":
diff --git a/src/events/nonRandom/rival/pRivalryCapture.js b/src/events/nonRandom/rival/pRivalryCapture.js
index b3a05152432f81d6565891d271c666911066a0eb..1dff371f2e31c1e56d46dbaea715b89293d96b23 100644
--- a/src/events/nonRandom/rival/pRivalryCapture.js
+++ b/src/events/nonRandom/rival/pRivalryCapture.js
@@ -5,9 +5,10 @@ globalThis.pRivalryCapture = function(condition) {
 	const slave = createRival();
 	const {his, he, him, He} = getPronouns(slave);
 	let r = [];
-	V.rivalOwner = -1;
-	V.rivalRace = 0;
-	V.rivalGender = 0;
+	V.rival.state = 3; // trigger P Rival Initiation
+	V.rival.prosperity = 0;
+	V.rival.power = 0;
+	delete V.rival.gender;
 
 	App.Events.drawEventArt(el, slave);
 
@@ -60,7 +61,7 @@ globalThis.pRivalryCapture = function(condition) {
 	}
 	el.append(r.join(" "));
 
-	V.rivalID = slave.ID; // trigger P Rival Initiation
+	V.rival.ID = slave.ID;
 	el.append(App.UI.newSlaveIntro(slave));
 
 	return el;
@@ -76,7 +77,7 @@ globalThis.pRivalryCapture = function(condition) {
 		let minAge;
 		let maxAge;
 		let pedo;
-		if (V.rivalGender === 2) {
+		if (V.rival.gender === 2) {
 			rivalTypeArray.push("expansionist shemale");
 			rivalTypeArray.push("masculine");
 			rivalTypeArray.push("micropenis");
@@ -98,8 +99,8 @@ globalThis.pRivalryCapture = function(condition) {
 		}
 		rivalType = rivalTypeArray.random();
 
-		if (V.rivalRace && App.Data.misc.filterRaces.has(V.rivalRace)) {
-			race = V.rivalRace;
+		if (V.rival.race && App.Data.misc.filterRacesPublic.has(V.rival.race)) {
+			race = V.rival.race;
 		}
 		switch (rivalType) {
 			case "expansionist shemale":
diff --git a/src/events/nonRandom/rival/pRivalryDispatch.js b/src/events/nonRandom/rival/pRivalryDispatch.js
index 6cc307062f3e13f77731c8f613e31f10a826e18a..0e58325b86a560a2f49ac5f05db751aedde9e77e 100644
--- a/src/events/nonRandom/rival/pRivalryDispatch.js
+++ b/src/events/nonRandom/rival/pRivalryDispatch.js
@@ -2,19 +2,19 @@ App.Events.PRivalryDispatch = class PRivalryDispatch extends App.Events.BaseEven
 	eventPrerequisites() {
 		return [
 			() => V.plot > 0,
-			() => V.rivalOwner > 0,
+			() => V.rival.prosperity > 0,
 			() => (V.eventResults.rivalActionWeek || 0) < V.week
 		];
 	}
 
 	execute(node) {
-		if (V.hostageAnnounced === 0 && V.rivalSet !== 0) {
+		if (V.rival.hostageState === 0 && V.rival.state === 2) {
 			V.eventResults.rivalActionWeek = V.week; // that's all for this week
 			node.append(App.Events.pRivalryHostage());
-		} else if ((V.rivalOwner - V.rivalryPower + 10) / V.arcologies[0].prosperity < 0.5) {
+		} else if ((V.rival.prosperity - V.rival.power + 10) / V.arcologies[0].prosperity < 0.5) {
 			V.eventResults.rivalActionWeek = V.week; // that's all for this week
 			node.append(App.Events.pRivalryVictory());
-		} else if (V.peacekeepers && V.peacekeepers.attitude > 5 && V.rivalryDuration > 1 && !V.eventResults.peacekeeperHelp) {
+		} else if (V.peacekeepers.state === 2 && V.peacekeepers.attitude > 5 && V.rival.duration > 1 && !V.eventResults.peacekeeperHelp) {
 			// can fire this event again to trigger victory or rival actions in the same week
 			node.append(App.Events.PRivalryPeacekeepers());
 		} else {
diff --git a/src/events/nonRandom/rival/pRivalryHostage.js b/src/events/nonRandom/rival/pRivalryHostage.js
index 96768bcce2de284f580a08e0b5a20cf5405440ca..2fcc31b89cb980297d3bf26d8d22eb6d9660dfdc 100644
--- a/src/events/nonRandom/rival/pRivalryHostage.js
+++ b/src/events/nonRandom/rival/pRivalryHostage.js
@@ -3,11 +3,11 @@ App.Events.pRivalryHostage = function() {
 
 	function execute() {
 		const node = new DocumentFragment();
-		V.hostageAnnounced = 1;
+		V.rival.hostageState = 1;
 		V.hostage = createHostage();
 		App.Events.drawEventArt(node, V.hostage);
 
-		switch (V.rivalryFS) {
+		switch (V.rival.FS.name) {
 			case "Maturity Preferentialism":
 			case "Petite Admiration":
 			case "Statuesque Glorification":
@@ -22,7 +22,7 @@ App.Events.pRivalryHostage = function() {
 		const {
 			HeR,
 			heR, hisR
-		} = getPronouns({pronoun: (V.rivalGender === 2) ? 1 : 0}).appendSuffix("R");
+		} = getPronouns({pronoun: (V.rival.gender === 2) ? 1 : 0}).appendSuffix("R");
 		const {girlU} = getNonlocalPronouns(V.seeDicks).appendSuffix("U");
 		const {womanP, girlP} = getPronouns(V.PC).appendSuffix("P");
 		const {woman2, girl2, he2, his2} = getPronouns(V.hostageWife || {pronoun : 0}).appendSuffix("2");
@@ -237,7 +237,7 @@ App.Events.pRivalryHostage = function() {
 		r = [];
 
 		r.push(`"Hello, ${PlayerName()}," your rival sneers. "Sorry to pull you away from`);
-		switch (V.rivalryFS) {
+		switch (V.rival.FS.name) {
 			case "Racial Subjugationism":
 				r.push(`whipping some poor ${V.arcologies[0].FSSubjugationistRace} ${girlU}'s back bloody,`);
 				break;
@@ -329,7 +329,7 @@ App.Events.pRivalryHostage = function() {
 				r.push(`whatever it is you do with your spare time,`);
 		}
 		r.push(`but look what I have here! I just acquired ${him} recently. Lovely, isn't ${he}? I know ${he} wasn't important to you, but ${he} <em>is</em> a reminder of who you were. I think ${he} must have been your type." Your rival turns to the slave and continues. "While we have our little war,`);
-		switch (V.rivalryFS) {
+		switch (V.rival.FS.name) {
 			case "Racial Subjugationism":
 				r.push(`I'm going to treat ${him} well. Train ${him}. ${He}'s a fine Head Girl prospect, don't you think? ${He}'ll have lots of nice ${V.arcologies[0].FSSubjugationistRace} girls to make love to whenever ${he} wants. Isn't that right, ${SlaveFullName(V.hostage)}?" The slave nods uncertainly.`);
 				break;
@@ -412,7 +412,7 @@ App.Events.pRivalryHostage = function() {
 				break;
 			default:
 				r.push(`${he}'s shaping up to be a good slave. I'm keeping ${him} informed of your`);
-				if (V.rivalryFS !== 0) {
+				if (V.rival.FS.name !== "") {
 					r.push(`revisionist`);
 				}
 				r.push(`nonsense, and what your slaves suffer because of it. Isn't that right, ${SlaveFullName(V.hostage)}?" The slave nods uncertainly.`);
@@ -774,7 +774,7 @@ App.Events.pRivalryHostage = function() {
 			slave.pubertyXX = 1;
 			resyncSlaveHight(slave);
 
-			switch (V.rivalryFS) {
+			switch (V.rival.FS.name) {
 				case "Repopulation Focus":
 					slave.preg = -3;
 					break;
diff --git a/src/events/nonRandom/rival/pRivalryPeacekeepers.js b/src/events/nonRandom/rival/pRivalryPeacekeepers.js
index 4be9cf0159f6c630c5ab65ded8607a9bcfb19e84..e05e89754871f110c7d0b1e5a9a0903d46d6a850 100644
--- a/src/events/nonRandom/rival/pRivalryPeacekeepers.js
+++ b/src/events/nonRandom/rival/pRivalryPeacekeepers.js
@@ -20,7 +20,7 @@ App.Events.PRivalryPeacekeepers = (function() {
 		function yes() {
 			V.eventResults.peacekeeperHelp = 1;
 			V.peacekeepers.attitude = 5;
-			V.rivalryPower += 10;
+			V.rival.power += 10;
 			return `You thank him for the offer, and agree. He nods and ends the call, noting that he now has a short-fuse operation to lie on. You didn't pay him or give him anything of value, but it would be childish to assume that the progress that will be made tonight in your ongoing struggle to overthrow your rival was free. The general now considers all or almost all of your accumulated influence with him to be discharged. That said, his reluctance to do business with the Free Cities seems to have diminished markedly.`;
 		}
 
diff --git a/src/events/nonRandom/rival/pRivalryVictory.js b/src/events/nonRandom/rival/pRivalryVictory.js
index f3711ff9a5ade95353abc30c6ad1ae4c94b82121..e61627a5369772d28c0a572045747e0dc19df3fc 100644
--- a/src/events/nonRandom/rival/pRivalryVictory.js
+++ b/src/events/nonRandom/rival/pRivalryVictory.js
@@ -6,16 +6,15 @@ App.Events.pRivalryVictory = function() {
 		const {
 			HisR, HeR,
 			hisR, heR
-		} = getPronouns({pronoun: (V.rivalGender === 2) ? 1 : 0}).appendSuffix("R");
+		} = getPronouns({pronoun: (V.rival.gender === 2) ? 1 : 0}).appendSuffix("R");
 		V.nextButton = " "; // hide button until user makes a selection
-		V.rivalOwner = 0;
-		V.rivalryPower = 0;
-		V.rivalRace = 0;
+		V.rival.prosperity = 0;
+		V.rival.power = 0;
 		const rivalArc = V.arcologies.find(a => a.rival === 1);
 
 		App.Events.addParagraph(node, [`For the first time, you receive a direct call from your rival. You pictured the moment as feeling grander than this, sitting at your desk as usual looking into ${hisR} downcast face. You're the victor in a new form of warfare in which bankruptcy has replaced surrender. If the world survives in its present state, you may one day be remembered as an innovator in the evolution of (nearly) bloodless war. Today, your reputation has <span class="green">greatly improved.</span> But today all you have that's tangible is a view of a still-dignified arcology owner, self-possessed despite the situation.`]);
 
-		App.UI.DOM.appendNewElement("p", node, `"For what it's worth," ${heR} says without preamble, "I had nothing against you. The Daughters wouldn't accept a straight buy-off. Their leadership needed a target to attack, or the rank and file would have killed them themselves and gone ahead attacking me. I had to give them an alternative, or it would have been me." ${HeR} looks nervous for the first time. "So, what do we do now? I've still got enough resources to make the end of this story a messy one for you. Let me go, and I won't. I'll walk away, and I'll sign everything I've got left over to you.${(V.hostageAnnounced === 1 && V.hostage) ? ` Including ${V.hostage.slaveName}, of course.` : ``}`);
+		App.UI.DOM.appendNewElement("p", node, `"For what it's worth," ${heR} says without preamble, "I had nothing against you. The Daughters wouldn't accept a straight buy-off. Their leadership needed a target to attack, or the rank and file would have killed them themselves and gone ahead attacking me. I had to give them an alternative, or it would have been me." ${HeR} looks nervous for the first time. "So, what do we do now? I've still got enough resources to make the end of this story a messy one for you. Let me go, and I won't. I'll walk away, and I'll sign everything I've got left over to you.${(V.rival.hostageState > 0 && V.hostage) ? ` Including ${V.hostage.slaveName}, of course.` : ``}`);
 
 		const result = App.UI.DOM.appendNewElement("div", node);
 
@@ -26,18 +25,18 @@ App.Events.pRivalryVictory = function() {
 				const r = [];
 				unlockContinue();
 				r.push(`You accept, magnanimous in victory. "I don't think I would have done that," your rival replies. "Thank you. When they write the book, I'll make sure you look good."`);
-				if (V.rivalSet !== 0) {
+				if (V.rival.state === 2) {
 					r.push(`${HisR} remaining liquid assets will go to satisfy ${hisR} great debts, but ${hisR} <span class="yellowgreen">arcology holdings are yours.</span>`);
 					if (rivalArc) {
 						updateArc();
 						rivalArc.PCminority += rivalArc.ownership;
 						rivalArc.PCminority = Math.clamp(rivalArc.PCminority, 0, 49);
 					}
-					if (V.hostageAnnounced === 1) {
-						V.hostageRescued = 1;
+					if (V.rival.hostageState === 1) {
+						V.rival.hostageState = 2;
 					}
 				} else {
-					r.push(`${HisR} arcology will go to satisfy ${hisR} great debts, but you will still profit <span class="yellowgreen">immensely</span> from your victory${(V.hostageAnnounced === 1 && V.hostage) ? `, and acquire ${V.hostage.slaveName} as a slave` : ``}.`);
+					r.push(`${HisR} arcology will go to satisfy ${hisR} great debts, but you will still profit <span class="yellowgreen">immensely</span> from your victory${(V.rival.hostageState > 0 && V.hostage) ? `, and acquire ${V.hostage.slaveName} as a slave` : ``}.`);
 					cashX(random(100000, 250000), "war");
 				}
 				App.Events.addNode(el, r, "div");
@@ -52,14 +51,12 @@ App.Events.pRivalryVictory = function() {
 				const r = [];
 				unlockContinue();
 				r.push(`You coldly decline. "That was a mistake," your rival replies, entering a computer command.`);
-				if (V.rivalSet !== 0) {
+				if (V.rival.state === 2) {
 					r.push(`"All my remaining liquid assets have just been <span class="red">carefully dispersed to deny you control of my arcology.</span> You'll get nothing from me." It's true. The financial self-destruction ensures that the fiscal wreckage goes to the arcology's citizens, not you.`);
 					if (rivalArc) {
 						updateArc();
 					}
-					if (V.hostageAnnounced === 1) {
-						r.push(hostageBounty());
-					}
+					r.push(hostageBounty());
 				} else {
 					r.push(`"All my remaining liquid assets have just been <span class="red">expended in an attack on the value of your holdings,</span> and my arcology has been heavily sabotaged. You'll get nothing from me." It's not entirely true, but the damage to your holdings does outweigh your gains by a significant margin. Your rival vanishes back into the old world.`);
 					cashX(random(-10000, -25000), "war");
@@ -68,7 +65,7 @@ App.Events.pRivalryVictory = function() {
 				jQuery(result).empty().append(el);
 			}
 		));
-		if (V.rivalryDuration >= 30 && V.hostageAnnounced === 0 && V.rivalSet !== 0) {
+		if (V.rival.duration >= 30 && V.rival.hostageState === 0 && V.rival.state === 2) {
 			App.UI.DOM.appendNewElement("div", result, App.UI.DOM.link(
 				`Refuse, and place a bounty of ${cashFormat(50000)} on your rival's death`,
 				() => {
@@ -95,19 +92,17 @@ App.Events.pRivalryVictory = function() {
 				const r = [];
 				unlockContinue();
 				r.push(`You coldly decline. "That was a mistake," your rival replies, entering a computer command.`);
-				if (V.rivalSet !== 0) {
+				if (V.rival.state === 2) {
 					r.push(`"All my remaining liquid assets have just been <span class="red">carefully dispersed to deny you control of my arcology.</span> You'll get nothing from me." It's true. The financial self-destruction ensures that the fiscal wreckage goes to the arcology's citizens, not you.`);
 					if (rivalArc) {
 						updateArc();
 						if (rivalArc.FSSupremacist > 20) {
-							V.rivalRace = rivalArc.FSSupremacistRace;
+							V.rival.race = rivalArc.FSSupremacistRace;
 						} else if (rivalArc.FSSubjugationist > 20) {
-							V.rivalRace = Array.from(setup.filterRaces.keys()).filter(race => race !== rivalArc.FSSubjugationistRace).random();
+							V.rival.race = Array.from(App.Data.misc.filterRacesPublic.keys()).filter(race => race !== rivalArc.FSSubjugationistRace).random();
 						}
 					}
-					if (V.hostageAnnounced === 1) {
-						r.push(hostageBounty());
-					}
+					r.push(hostageBounty());
 				} else {
 					r.push(`"All my remaining liquid assets have just been <span class="red">expended in an attack on the value of your holdings,</span> and my arcology has been heavily sabotaged. You'll get nothing from me." It's not entirely true, but the damage to your holdings does outweigh your gains by a significant margin.`);
 					cashX(random(-10000, -25000), "war");
@@ -122,16 +117,17 @@ App.Events.pRivalryVictory = function() {
 		return node;
 
 		function hostageBounty() {
+			if (V.rival.hostageState === 0 || !V.hostage) {
+				return;
+			}
 			const result2 = App.UI.DOM.makeElement("p");
 			App.UI.DOM.appendNewElement("div", result2, App.UI.DOM.link(
 				`Place a bounty of ${cashFormat(10000)} on your rival's psychological warfare tool`,
 				() => {
-					if (V.hostage) {
-						const {He} = getPronouns(V.hostage);
-						jQuery(result2).empty().append(`You make sure to post a bounty sufficient to ensure that ${V.hostage.slaveName}, your rival's psychological warfare tool, does not escape or go unrescued, depending on one's point of view. ${He} is quickly picked out of the chaos of your rival's escape and delivered to you.`);
-						V.hostageRescued = 1;
-						cashX(-10000, "war");
-					}
+					const {He} = getPronouns(V.hostage);
+					jQuery(result2).empty().append(`You make sure to post a bounty sufficient to ensure that ${V.hostage.slaveName}, your rival's psychological warfare tool, does not escape or go unrescued, depending on one's point of view. ${He} is quickly picked out of the chaos of your rival's escape and delivered to you.`);
+					V.rival.hostageState = 2;
+					cashX(-10000, "war");
 				}
 			));
 			return result2;
diff --git a/src/events/nonRandomEvent.js b/src/events/nonRandomEvent.js
index e149948855e8266e4bfcd5ebcf16fb91326b16df..099becebf49a6b1e683879ba2605dca226488b07 100644
--- a/src/events/nonRandomEvent.js
+++ b/src/events/nonRandomEvent.js
@@ -9,6 +9,7 @@ App.Events.getNonrandomEvents = function() {
 		// instantiate all possible scheduled/nonrandom events here
 		// ORDER MATTERS - if multiple events from this list trigger in a single week, they are executed in this order
 
+		new App.Events.pLoanshark(),
 		new App.Events.conflictOptions(),
 		new App.Events.SEPlayerBirth(),
 		new App.Events.SEpcBirthday(),
diff --git a/src/events/randomEvent.js b/src/events/randomEvent.js
index 462608e912ef4139484e39d00436f29a9bfeff11..a89770aa222f6227f0f88487e949e7423f0531de 100644
--- a/src/events/randomEvent.js
+++ b/src/events/randomEvent.js
@@ -23,6 +23,7 @@ App.Events.getIndividualEvents = function() {
 		new App.Events.RESSBadDream(),
 		new App.Events.RESSBedSnuggle(),
 		new App.Events.RESSBirthday(),
+		new App.Events.RESSBirthdaySex(),
 		new App.Events.RESSBondageGear(),
 		new App.Events.RESSBondedLove(),
 		new App.Events.RESSBreastExpansionBlues(),
@@ -456,21 +457,17 @@ App.Events.playRandomIndividualEvent = function() {
 			if (V.RIESkip.length > 0) {
 				countPara.append(` An event has already played for ${toSentence(V.RIESkip.map(s => SlaveFullName(getSlave(s))))}, so they are not eligible to play another.`);
 			}
+
 			const slaveDiv = App.UI.DOM.appendNewElement("div", d, "Show events for this slave: ");
-			const slaveDropdown = App.UI.DOM.appendNewElement("select", slaveDiv);
+			const options = [];
 			const startingSlave = eligibleSlaves.random();
 			for (const s of eligibleSlaves) {
-				const choice = App.UI.DOM.appendNewElement("option", slaveDropdown, SlaveFullName(s));
-				choice.value = s.ID.toString();
-				if (s.ID === startingSlave.ID) {
-					choice.selected = true;
-				}
+				options.push({key: s.ID.toString(), name: SlaveFullName(s)});
 			}
-			slaveDropdown.onchange = () => {
-				const O = slaveDropdown.options[slaveDropdown.selectedIndex];
-				const slaveID = parseInt(O.value);
-				writeEventList(getSlave(slaveID));
-			};
+			slaveDiv.append(App.UI.DOM.makeSelect(options, startingSlave.ID.toString(), slaveID => {
+				writeEventList(getSlave(parseInt(slaveID)));
+			}));
+
 			App.UI.DOM.appendNewElement("p", d, "One of the following individual events would have been chosen for this slave.");
 
 			const linkList = App.UI.DOM.appendNewElement("div", d, '', "event-section");
diff --git a/src/events/reRecruit.js b/src/events/reRecruit.js
index a205f532c2af58e6178ed63e195e9b0cd2aa8ecf..f182c1b76f038dace1f3307d085cd45b975cfbd7 100644
--- a/src/events/reRecruit.js
+++ b/src/events/reRecruit.js
@@ -112,18 +112,13 @@ App.Events.RERecruit = class RERecruit extends App.Events.BaseEvent {
 		if (V.debugMode && V.debugModeEventSelection) {
 			const el = App.UI.DOM.appendNewElement("span", node);
 			App.UI.DOM.appendNewElement("span", el, `One of the following recruitment events would have appeared: `);
-			const select = App.UI.DOM.appendNewElement("select", el);
 			const evList = this.eventList.filter(e => App.Events.canExecute(e));
-			for (const ev of evList) {
-				const choice = App.UI.DOM.appendNewElement("option", select, ev.eventName);
-				choice.value = ev.eventName;
-			}
-			select.selectedIndex = -1;
-			select.onchange = () => {
-				const O = select.options[select.selectedIndex];
+			el.append(App.UI.DOM.makeSelect(evList.map(e => {
+				return {key: e.eventName, name: e.eventName};
+			}), null, e => {
 				el.remove();
-				evList.find(ev => ev.eventName === O.value).execute(node);
-			};
+				evList.find(ev => ev.eventName === e).execute(node);
+			}));
 		} else {
 			// forward execution to the delegate event
 			this.params.event.execute(node);
diff --git a/src/events/reRecruit/schoolSale.js b/src/events/reRecruit/schoolSale.js
index edfab0017c2425b80eb75ee6c23ac6ab9b344130..8f97e9887895158765059ee3d741bc82f01f8168 100644
--- a/src/events/reRecruit/schoolSale.js
+++ b/src/events/reRecruit/schoolSale.js
@@ -26,7 +26,9 @@ App.Events.recSchoolSale = class recSchoolSale extends App.Events.BaseEvent {
 		r.push(Spoken(slave, `"I was raised and trained by a slave orphanage, ${title.toLowerCase()}. It is not legal to own underage ${girl}s, but it is legal to charge an orphan for the costs of raising ${him} when ${he} reaches ${V.minimumSlaveAge}, and those debts are always high enough to enslave ${him}. My ${ordinalSuffix(slave.actualAge)} birthday was yesterday, ${(slave.actualAge === V.minimumSlaveAge) ? `so I am a slave and for sale now` : `so I'm too old to stay at the orphanage any longer`}."`));
 		App.Events.addParagraph(node, r);
 		r = [];
-		r.push(Spoken(slave, `"I have been trained for obedience since I came to the orphanage. At ${Math.min(14, slave.actualAge - 4)} they put me on drugs to make sure I'd grow nice T&A. On my ${ordinalSuffix(Math.min(16, slave.actualAge - 2))} birthday I got my first set of implants. Every time my boobs got used to the implants, I got sent in for a bigger set. I'm on my second set." ${He} unbuttons ${his} blouse and displays a pair of big fake tits. "I've also had my lips done."`));
+		r.push(Spoken(slave, `"I have been trained for obedience since I came to the orphanage. At ${Math.min(14, slave.actualAge - 4)} they put me on drugs to make sure I'd grow nice T&A. On my ${ordinalSuffix(Math.min(16, slave.actualAge - 2))} birthday I got my first set of implants. Every time my boobs got used to the implants, I got sent in for a bigger set. I'm on my second set."`));
+		r.push(`${He} unbuttons ${his} blouse and displays a pair of big fake tits.`);
+		r.push(Spoken(slave, `"I've also had my lips done."`));
 		r.push(`${He} blows you a wet kiss.`);
 		App.Events.addParagraph(node, r);
 		r = [];
diff --git a/src/events/recETS/newSlaveIncestSex.js b/src/events/recETS/newSlaveIncestSex.js
index a50c170aad6957a0d011bc585cf25461e0d1ad5f..963a6e79e2eebf6ee735060c90c6302915f5949b 100644
--- a/src/events/recETS/newSlaveIncestSex.js
+++ b/src/events/recETS/newSlaveIncestSex.js
@@ -137,12 +137,9 @@ globalThis.newSlaveIncestSex = function(relative, relative2) {
 		App.Events.addParagraph(frag, r);
 		relative.devotion -= 4;
 		relative.trust -= 4;
-		relative.counter.oral += 1;
-		V.oralTotal += 1;
 		relative2.devotion -= 4;
 		relative2.trust -= 4;
-		relative2.counter.oral += 1;
-		V.oralTotal += 1;
+		seX(relative, "oral", relative2, "oral");
 		return frag;
 	}
 
diff --git a/src/events/recETS/recetsAddictMotherDaughter.js b/src/events/recETS/recetsAddictMotherDaughter.js
index 340fc0238832c05743eecae91faaa40d5b3655f0..c73e503a99528ea0904b329a2f09d0fc4114e6c4 100644
--- a/src/events/recETS/recetsAddictMotherDaughter.js
+++ b/src/events/recETS/recetsAddictMotherDaughter.js
@@ -61,7 +61,6 @@ App.Events.recetsAddictMotherDaughter = class recetsAddictMotherDaughter extends
 		App.Events.addParagraph(node, [`A matronly woman comes to your penthouse in tears. It seems ${he} is a tenant of yours, and has fallen deeply into debt as a result of aphrodisiac addiction. ${He} offers to sell ${himself} into slavery if you will pay off ${his} debts. ${He} is strangely eager about this, and after some probing it becomes apparent that ${he} is living with ${his} ${daughter2} and wants to avoid having ${his} ${daughter2} involved in this debt.`]);
 
 		App.Events.addParagraph(node, [`Enslaving ${him} will cost ${cashFormat(contractCost)}. Alternatively, you could sell your rights to ${him}. Including costs, this will bring in ${cashFormat(cost - contractCost)}. As a third option, for ${cashFormat(contractCost * 2)} you could manipulate ${him} to bind both mother and ${daughter2}, but you wouldn't be able to examine the ${daughter2} first.`]);
-		r.push();
 
 		const newSlaves = [mother]; /* caller doesn't want relative involved, so you don't get to inspect her even if you can force a sale */
 
@@ -69,7 +68,7 @@ App.Events.recetsAddictMotherDaughter = class recetsAddictMotherDaughter extends
 		const choices = [];
 
 		if (V.cash >= contractCost) {
-			choices.push(new App.Events.Result(`Accept ${his} proposal and enslave ${him}`, enslave, `This will cost ${contractCost}`));
+			choices.push(new App.Events.Result(`Accept ${his} proposal and enslave ${him}`, enslave, `This will cost ${cashFormat(contractCost)}`));
 			choices.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost - contractCost)}`));
 			if (V.cash >= (contractCost * 2)) {
 				choices.push(new App.Events.Result(`Manipulate ${him} to enslave both mother and ${daughter2}`, both, `This will cost ${cashFormat(contractCost * 2)}`));
diff --git a/src/events/recETS/recetsDesperateBroodmother.js b/src/events/recETS/recetsDesperateBroodmother.js
index 42111bdd4d7a2b65ffa3c5e693fe3d5090bffcce..ededc9b8892b1b0b5e05ca1e5eeb162571adeb25 100644
--- a/src/events/recETS/recetsDesperateBroodmother.js
+++ b/src/events/recETS/recetsDesperateBroodmother.js
@@ -186,7 +186,7 @@ App.Events.recetsDesperateBroodmother = class recetsDesperateBroodmother extends
 		r.push(
 			`desperate for work, carrying a young child on ${his} shoulder, quadruplets on ${his} back and a large sack against ${his} middle, while looking absolutely exhausted.`,
 			Spoken(mother, `"Please, would you happen to have any work for a desperate mother? I need to eat, and my babies are starting to go hungry... I tried whoring, but I got pregnant again..."`),
-			`${He} struggles back to allow you to see ${his} full body. The object you thought were ${his} possessions is, in fact, ${his} massively distended stomach.`,
+			`${He} struggles back to allow you to see ${his} full body. The object you thought was ${his} possessions is, in fact, ${his} massively distended stomach.`,
 			Spoken(mother, `"I'm having so many and I don't know what to do anymore... I can't care for this many... Anything you can do for meeEEEEEE!"`),
 			`${He} groans as an intense contraction hits ${him}.`,
 			Spoken(mother, `"Oh god! Not now! Not like this! I'm not ready... Please, I'm giving birth right now... Forget work, I'll be your slave if you can help me..."`),
diff --git a/src/events/recETS/recetsIncestBrotherSister.js b/src/events/recETS/recetsIncestBrotherSister.js
index 501ca1e91e2ea2ce3c452112fbac8bca09f13ace..d715ed783001ef5333bbde93680ea26cac1ba274 100644
--- a/src/events/recETS/recetsIncestBrotherSister.js
+++ b/src/events/recETS/recetsIncestBrotherSister.js
@@ -4,7 +4,6 @@ App.Events.recetsIncestBrotherSister = class recetsIncestBrotherSister extends A
 			() => V.seeDicks !== 100,
 			() => V.seeDicks !== 0,
 			() => V.seeIncest !== 0,
-			() => V.seePreg !== 0,
 			() => V.rep / 400 > random(1, 100) || (V.debugMode > 0 && V.debugModeEventSelection > 0)
 		];
 	}
@@ -17,7 +16,7 @@ App.Events.recetsIncestBrotherSister = class recetsIncestBrotherSister extends A
 		V.encyclopedia = "Enslaving People";
 		const contractCost = 10000;
 		const sis = GenerateNewSlave("XX", {
-			minAge: Math.max(V.fertilityAge + 2, V.minimumSlaveAge + 2), maxAge: 20, ageOverridesPedoMode: 1, disableDisability: 1
+			minAge: Math.max(V.fertilityAge, V.potencyAge + 2, V.minimumSlaveAge + 2), maxAge: 20, ageOverridesPedoMode: 1, disableDisability: 1
 		});
 		sis.origin = "$He offered to become your slave to protect $his incestuous relationship.";
 		sis.career = "a dropout";
@@ -47,8 +46,16 @@ App.Events.recetsIncestBrotherSister = class recetsIncestBrotherSister extends A
 
 		sis.relationshipTarget = bro.ID;
 
-		WombChangeGene(sis, "fatherName", bro.slaveName);
-		WombChangeGene(sis, "motherName", sis.slaveName);
+		if (V.seePreg) {
+			sis.preg = random(20, 30);
+			sis.pregType = either(1, 1, 1, 1, 1, 2, 2, 3);
+			sis.pregKnown = 1;
+			sis.pregWeek = sis.preg;
+			SetBellySize(sis);
+			sis.pregSource = bro.ID;
+			WombChangeGene(sis, "fatherName", bro.slaveName);
+			WombChangeGene(sis, "motherName", sis.slaveName);
+		}
 
 		const {
 			His, sister
@@ -62,7 +69,7 @@ App.Events.recetsIncestBrotherSister = class recetsIncestBrotherSister extends A
 
 		App.Events.addParagraph(node, [`You receive so many messages, as a noted titan of the new Free Cities world, that ${V.assistant.name} has to be quite draconian in culling them. ${HeA} lets only the most important through to you. One category of message that always gets through regardless of content, though, is requests for voluntary enslavement. As the new world takes shape, they've become less rare than they once were.`]);
 
-		App.Events.addParagraph(node, [`This call is coming from a public kiosk, which is usually an indication that the person on the other end is a transient individual who has decided to take slavery over homelessness. In this case, however, the story is more unusual — the callers seem stressed, but otherwise normal. They haltingly and quietly explain that they are a ${sister2} and ${sister} who had to flee their home after their parents found out they were having sex with each other. ${His} gravid middle is testament to that. They feel that life in an arcology together, even as slaves, would be better than their current life on the streets.`]);
+		App.Events.addParagraph(node, [`This call is coming from a public kiosk, which is usually an indication that the person on the other end is a transient individual who has decided to take slavery over homelessness. In this case, however, the story is more unusual — the callers seem stressed, but otherwise normal. They haltingly and quietly explain that they are a ${sister2} and ${sister} who had to flee their home after their parents found out they were having sex with each other. ${V.seePreg ? `${His} gravid middle is testament to that. ` : ``}They feel that life in an arcology together, even as slaves, would be better than their current life on the streets.`]);
 
 		App.Events.addParagraph(node, [`${capFirstChar(V.assistant.name)} assembles a dossier of information and photos from information they've sent describing their bodies and skills, to be used as a substitute for an in-person inspection.`]);
 
diff --git a/src/events/recETS/recetsIncestFatherDaughter.js b/src/events/recETS/recetsIncestFatherDaughter.js
index 051478ec388dc801533eea8bf5f1c899e4acd3f4..c887076a4be0430713450c4d23e2c61b678da058 100644
--- a/src/events/recETS/recetsIncestFatherDaughter.js
+++ b/src/events/recETS/recetsIncestFatherDaughter.js
@@ -4,7 +4,6 @@ App.Events.recetsIncestFatherDaughter = class recetsIncestFatherDaughter extends
 			() => V.seeDicks !== 100,
 			() => V.seeDicks !== 0,
 			() => V.seeIncest !== 0,
-			() => V.seePreg !== 0,
 			() => V.arcologies[0].FSRestart === "unset",
 			() => V.rep / 400 > random(1, 100) || (V.debugMode > 0 && V.debugModeEventSelection > 0)
 		];
@@ -42,16 +41,11 @@ App.Events.recetsIncestFatherDaughter = class recetsIncestFatherDaughter extends
 		const daughter = generateRelatedSlave(father, "daughter");
 		daughter.pubertyXX = 1;
 		daughter.vagina = 3;
-		daughter.preg = 30;
 		daughter.clit = 1;
 		daughter.voice = 2;
 		daughter.skill.vaginal = 50;
 		daughter.boobs = (random(3, 6) * 100);
-		daughter.pregType = 1;
-		daughter.pregKnown = 1;
-		daughter.pregWeek = daughter.preg;
-		daughter.pregSource = father.ID;
-		SetBellySize(daughter);
+		daughter.ovaries = 1;
 		daughter.faceShape = "cute";
 		if (daughter.behavioralFlaw === "hates men") {
 			daughter.behavioralFlaw = "none";
@@ -63,8 +57,16 @@ App.Events.recetsIncestFatherDaughter = class recetsIncestFatherDaughter extends
 
 		father.relationshipTarget = daughter.ID;
 
-		WombChangeGene(daughter, "fatherName", father.slaveName);
-		WombChangeGene(daughter, "motherName", daughter.slaveName);
+		if (V.seePreg) {
+			daughter.preg = random(20, 30);
+			daughter.pregType = either(1, 1, 1, 1, 1, 2, 2, 3);
+			daughter.pregKnown = 1;
+			daughter.pregWeek = daughter.preg;
+			SetBellySize(daughter);
+			daughter.pregSource = father.ID;
+			WombChangeGene(daughter, "fatherName", father.slaveName);
+			WombChangeGene(daughter, "motherName", daughter.slaveName);
+		}
 
 		const {
 			He,
@@ -80,7 +82,7 @@ App.Events.recetsIncestFatherDaughter = class recetsIncestFatherDaughter extends
 
 		App.Events.addParagraph(node, [`You receive so many messages, as a noted titan of the new Free Cities world, that ${V.assistant.name} has to be quite draconian in culling them. ${HeA} lets only the most important through to you. One category of message that always gets through regardless of content, though, is requests for voluntary enslavement. As the new world takes shape, they've become less rare than they once were.`]);
 
-		App.Events.addParagraph(node, [`This call is coming from a public kiosk, which is usually an indication that the person on the other end is a transient individual who has decided to take slavery over homelessness. In this case, however, the story is more unusual — the callers seem stressed, but otherwise normal. They haltingly and quietly explain that they are a father and ${daughter2} who had to flee their home after ${his} wife found out ${he} was having sex with their ${daughter2}. ${His2} gravid middle is testament to that. They feel that life in an arcology together, even as slaves, would be better than their current life on the streets.`]);
+		App.Events.addParagraph(node, [`This call is coming from a public kiosk, which is usually an indication that the person on the other end is a transient individual who has decided to take slavery over homelessness. In this case, however, the story is more unusual — the callers seem stressed, but otherwise normal. They haltingly and quietly explain that they are a father and ${daughter2} who had to flee their home after ${his} wife found out ${he} was having sex with their ${daughter2}. ${V.seePreg ? `${His2} gravid middle is testament to that. ` : ``}They feel that life in an arcology together, even as slaves, would be better than their current life on the streets.`]);
 
 		App.Events.addParagraph(node, [`${capFirstChar(V.assistant.name)} assembles a dossier of information and photos from information they've sent describing their bodies and skills, to be used as a substitute for an in-person inspection.`]);
 
diff --git a/src/events/recETS/recetsIncestMotherSon.js b/src/events/recETS/recetsIncestMotherSon.js
index 51e9b361cd11277d464f01fe07fb09a4cd09e311..3aba98324269d9995670e3537fe171c2f55d8ee5 100644
--- a/src/events/recETS/recetsIncestMotherSon.js
+++ b/src/events/recETS/recetsIncestMotherSon.js
@@ -4,8 +4,6 @@ App.Events.recetsIncestMotherSon = class recetsIncestMotherSon extends App.Event
 			() => V.seeDicks !== 100,
 			() => V.seeDicks !== 0,
 			() => V.seeIncest !== 0,
-			() => V.seePreg !== 0,
-			() => V.arcologies[0].FSRestart === "unset",
 			() => V.rep / 400 > random(1, 100) || (V.debugMode > 0 && V.debugModeEventSelection > 0)
 		];
 	}
@@ -27,20 +25,12 @@ App.Events.recetsIncestMotherSon = class recetsIncestMotherSon extends App.Event
 		mother.oldDevotion = mother.devotion;
 		mother.oldTrust = mother.trust;
 		mother.vagina = 2;
-		mother.preg = 31;
-		mother.pregType = 1;
-		mother.pregKnown = 1;
-		mother.pregWeek = mother.preg;
-		mother.belly = 8000;
-		mother.bellyPreg = 8000;
 		mother.ovaries = 1;
 		mother.counter.birthsTotal++;
 		mother.face = 15;
 		mother.skill.vaginal = 35;
 		mother.anus = 1;
 		mother.boobs += 600;
-		mother.lactation = 1;
-		mother.lactationDuration = 2;
 		mother.boobsImplant = 0;
 		mother.boobsImplantType = "none";
 		mother.butt += 2;
@@ -70,11 +60,20 @@ App.Events.recetsIncestMotherSon = class recetsIncestMotherSon extends App.Event
 		son.relationship = 3;
 		son.relationshipTarget = mother.ID;
 
-		mother.pregSource = son.ID;
 		mother.relationshipTarget = son.ID;
 
-		WombChangeGene(mother, "fatherName", son.slaveName);
-		WombChangeGene(mother, "motherName", mother.slaveName);
+		if (V.seePreg) {
+			mother.lactation = 1;
+			mother.lactationDuration = 2;
+			mother.preg = random(20, 30);
+			mother.pregType = either(1, 1, 1, 1, 1, 2, 2, 3);
+			mother.pregKnown = 1;
+			mother.pregWeek = mother.preg;
+			SetBellySize(mother);
+			mother.pregSource = son.ID;
+			WombChangeGene(mother, "fatherName", son.slaveName);
+			WombChangeGene(mother, "motherName", mother.slaveName);
+		}
 
 		const {
 			He,
@@ -89,7 +88,7 @@ App.Events.recetsIncestMotherSon = class recetsIncestMotherSon extends App.Event
 
 		App.Events.addParagraph(node, [`You receive so many messages, as a noted titan of the new Free Cities world, that ${V.assistant.name} has to be quite draconian in culling them. ${HeA} lets only the most important through to you. One category of message that always gets through regardless of content, though, is requests for voluntary enslavement. As the new world takes shape, they've become less rare than they once were.`]);
 
-		App.Events.addParagraph(node, [`This call is coming from a public kiosk, which is usually an indication that the person on the other end is a transient individual who has decided to take slavery over homelessness. In this case, however, the story is more unusual — the callers seem stressed, but otherwise normal. They haltingly and quietly explain that they are a mother and ${daughter2} who had to flee their home after ${his} husband found out the child in ${his} rounded middle was not his, but his ${daughter2}'s. They feel that life in an arcology together, even as slaves, would be better than their new life on the streets.`]);
+		App.Events.addParagraph(node, [`This call is coming from a public kiosk, which is usually an indication that the person on the other end is a transient individual who has decided to take slavery over homelessness. In this case, however, the story is more unusual — the callers seem stressed, but otherwise normal. They haltingly and quietly explain that they are a mother and ${daughter2} who had to flee their home after ${his} husband ${V.seePreg ? `found out the child in ${his} rounded middle was not his, but his ${daughter2}'s` : `caught them in the act of incest`}. They feel that life in an arcology together, even as slaves, would be better than their new life on the streets.`]);
 
 		App.Events.addParagraph(node, [`${capFirstChar(V.assistant.name)} assembles a dossier of information and photos from information they've sent describing their bodies and skills, to be used as a substitute for an in-person inspection.`]);
 
diff --git a/src/events/recETS/recetsIncestTwinsMixed.js b/src/events/recETS/recetsIncestTwinsMixed.js
index 43df9af85e9bd2600475df2dbe2cc1591baf2e64..668c57d1561aa91180b5a271656a52944ad673fd 100644
--- a/src/events/recETS/recetsIncestTwinsMixed.js
+++ b/src/events/recETS/recetsIncestTwinsMixed.js
@@ -16,10 +16,11 @@ App.Events.recetsIncestTwinsMixed = class recetsIncestTwinsMixed extends App.Eve
 		V.encyclopedia = "Enslaving People";
 		const contractCost = 10000;
 		const sis1 = GenerateNewSlave("XX", {
-			minAge: Math.max(V.fertilityAge, V.minimumSlaveAge), maxAge: 20, ageOverridesPedoMode: 1, disableDisability: 1
+			minAge: Math.max(V.fertilityAge, V.potencyAge, V.minimumSlaveAge), maxAge: 20, ageOverridesPedoMode: 1, disableDisability: 1
 		});
-		sis1.vagina = 1;
 		sis1.origin = "$He offered to become your slave to protect $his incestuous relationship.";
+		sis1.vagina = 1;
+		sis1.ovaries = 1;
 		sis1.devotion = random(-15, 15);
 		sis1.trust = random(-15, 15);
 		sis1.oldDevotion = sis1.devotion;
@@ -60,16 +61,29 @@ App.Events.recetsIncestTwinsMixed = class recetsIncestTwinsMixed extends App.Eve
 		sis2.clothes = "conservative clothing";
 		sis2.relationship = 3;
 		sis2.relationshipTarget = sis1.ID;
+		
 		sis1.relationshipTarget = sis2.ID;
 
-		WombChangeGene(sis1, "fatherName", sis2.slaveName);
-		WombChangeGene(sis1, "motherName", sis1.slaveName);
+		if (V.seePreg) {
+			sis1.preg = random(20, 30);
+			sis1.pregType = either(1, 1, 1, 1, 1, 2, 2, 3);
+			sis1.pregKnown = 1;
+			sis1.pregWeek = sis1.preg;
+			SetBellySize(sis1);
+			sis1.pregSource = sis2.ID;
+			WombChangeGene(sis1, "fatherName", sis2.slaveName);
+			WombChangeGene(sis1, "motherName", sis1.slaveName);
+		}
 
 		const {HeA} = getPronouns(assistant.pronouns().main).appendSuffix("A");
+		const {
+			he, his
+		} = getPronouns(sis1);
+		const children = sis1.pregType > 1 ? "children" : "child";
 
 		App.Events.addParagraph(node, [`You receive so many messages, as a noted titan of the new Free Cities world, that ${V.assistant.name} has to be quite draconian in culling them. ${HeA} lets only the most important through to you. One category of message that always gets through regardless of content, though, is requests for voluntary enslavement. As the new world takes shape, they've become less rare than they once were.`]);
 
-		App.Events.addParagraph(node, [`This call is coming from a public kiosk, which is usually an indication that the person on the other end is a transient individual who has decided to take slavery over homelessness. In this case, however, the story is more unusual — the callers seem stressed, but otherwise normal. They haltingly and quietly explain that they are twins who had to flee their home after their parents found out they were having sex with each other. They feel that life in an arcology together, even as slaves, would be better than their current life on the streets.`]);
+		App.Events.addParagraph(node, [`This call is coming from a public kiosk, which is usually an indication that the person on the other end is a transient individual who has decided to take slavery over homelessness. In this case, however, the story is more unusual — the callers seem stressed, but otherwise normal. They haltingly and quietly explain that they are twins who had to flee their home after their parents found out ${V.seePreg ? `${he} was bearing ${his} twin's ${children}` : `they were having sex with each other`}. They feel that life in an arcology together, even as slaves, would be better than their current life on the streets.`]);
 
 		App.Events.addParagraph(node, [`${capFirstChar(V.assistant.name)} assembles a dossier of information and photos from information they've sent describing their bodies and skills, to be used as a substitute for an in-person inspection.`]);
 
diff --git a/src/events/recETS/recetsMatchedPair.js b/src/events/recETS/recetsMatchedPair.js
index 9ebc19143b965f719dd3ee36c5046782dd1a4a33..5dd86c8f1bcdce5635eba840c84fdeaf6a0fc89c 100644
--- a/src/events/recETS/recetsMatchedPair.js
+++ b/src/events/recETS/recetsMatchedPair.js
@@ -91,7 +91,7 @@ App.Events.recetsMatchedPair = class recetsMatchedPair extends App.Events.BaseEv
 			`One of them speaks up.`,
 			Spoken(sis2, `"We're twins, ${(V.PC.title !== 0) ? "sir" : "ma'am"}. Fraternal twins. We have been given hormone treatments and surgery to match one another more closely, except for one detail."`),
 			`They lift their skirts; the speaker has a hormone-atrophied cock, while ${his} ${sister2} has a pussy, along with a large clit that almost matches ${his} sibling's member in size.`,
-			Spoken(sis2, `"We've also been trained ever since we turned ${V.minimumSlaveAge} to be completely obedient, ${(V.PC.title !== 0) ? "sir" : "ma'am"}, in everything, and sexually proficient."`)
+			Spoken(sis2, `"We've also been trained ever since we turned ${num(V.minimumSlaveAge)} to be completely obedient, ${(V.PC.title !== 0) ? "sir" : "ma'am"}, in everything, and sexually proficient."`)
 		);
 		App.Events.addParagraph(node, r);
 		r = [];
diff --git a/src/events/recETS/recetsMismatchedPair.js b/src/events/recETS/recetsMismatchedPair.js
index 9c0a1d23dfd2afd46d0ce80ef28b86ce6338b405..ede9d5c653a9994c91df5ca99a060e5c59b07e7c 100644
--- a/src/events/recETS/recetsMismatchedPair.js
+++ b/src/events/recETS/recetsMismatchedPair.js
@@ -91,7 +91,6 @@ App.Events.recetsMismatchedPair = class recetsMismatchedPair extends App.Events.
 		} = getPronouns(S.HeadGirl).appendSuffix("3");
 
 		const {title: Master} = getEnunciation(S.HeadGirl);
-		let r = [];
 
 		App.Events.addParagraph(node, [
 			`Your Head Girl comes to see you. ${He3} flags a slave posted for sale on your desk. The posting seems completely unimpressive — just a bitch barely past ${his} ${ordinalSuffix(sis.actualAge)} birthday with basic implants and a pathetic little dick — until ${he3} points out that the person posting ${him} for sale is ${his} ${sister2}. ${His} slightly older, naturally female ${sister2}. Who, to go by the pictures, the younger sibling has desperately been trying to mold ${himself} to look more like.`,
@@ -99,8 +98,7 @@ App.Events.recetsMismatchedPair = class recetsMismatchedPair extends App.Events.
 			`You bring up a video feed of the one-room apartment they share. A man, clearly a client, is sitting on the bed while the sissy rides him. ${He}'s facing away from the john, so ${he} isn't trying to hide the fact that ${he} isn't happy selling ${his} anus for money. The older ${sister2} is naked, but ${he2}'s trying to act as a pimp of sorts rather than helping fuck. ${He2} alternately poses and preens for the john and nonverbally scolds the wincing sissy when he's not paying attention. After the customer finishes, the sissy heads to the toilet to clean ${himself}, and ${his} older ${sister2} whispers to the john that the sissy's for sale. The john laughs at ${him2} and excuses himself.`
 		]);
 
-		App.Events.addParagraph(node, r);
-		r = [];
+		let r = [];
 		r.push(`Enslaving the younger, sissy ${sister} will cost ${cashFormat(contractCost)}. Alternatively, you could sell your rights to ${him}. Including costs, this will bring in ${cashFormat(cost - contractCost)}. As a third option, for ${cashFormat(contractCost * 2)} you could enslave both`);
 		if (sister === sister2) {
 			r.push(`${sister}s,`);
@@ -116,8 +114,8 @@ App.Events.recetsMismatchedPair = class recetsMismatchedPair extends App.Events.
 		const choices = [];
 
 		if (V.cash >= contractCost) {
-			choices.push(new App.Events.Result(`Enslave the sissy slut`, enslave, `This will cost ${contractCost}`));
-			choices.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cost}`));
+			choices.push(new App.Events.Result(`Enslave the sissy slut`, enslave, `This will cost ${cashFormat(contractCost)}`));
+			choices.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));
 			if (V.cash >= (contractCost * 2)) {
 				choices.push(new App.Events.Result(`Enslave both`, both, `This will cost ${cashFormat(contractCost * 2)}`));
 			}
@@ -147,11 +145,8 @@ App.Events.recetsMismatchedPair = class recetsMismatchedPair extends App.Events.
 			newSlave(sis);
 			cashX(forceNeg(contractCost), "slaveTransfer", sis);
 			const frag = new DocumentFragment();
-			r = [];
 			App.Events.addParagraph(frag, [`The poor sissy isn't happy to become a slave, but ${he}'s clearly relieved to be away from ${his} ${sister2}. The bitch isn't likely to have an easy time; the sale didn't clear ${him2} from debt. ${bro.slaveName} describes ${his} basic sexual experience, which includes a lot of sucking and anal whoring. Without further ado ${he} moves from practical sexual slavery at the hands of ${his} ${sister2} to actual sexual slavery.`]);
-			r.push();
 			App.Events.addParagraph(frag, [`${His} ${sister2}-pimp walks in angrily demanding to know why you called ${him2} here. ${He2} sees ${his2} sissy ${sister} kneeling naked next to you, hears the hiss-click of the door closing and locking behind ${him2}, and makes the connection far too late to run. ${He2} begins to scream at both you and ${his2} ${sister} at the top of ${his2} lungs, and manages to keep up an impressive volume until you get ${him2} gagged. ${His2} ${sister} does not move to interfere as you strip and bind ${his2} struggling body. In fact, as you get the gag in place, ${he} begins to laugh an unstable, cracking laugh that degenerates into sobbing.`]);
-			App.Events.addParagraph(frag, r);
 			return frag;
 		}
 	}
diff --git a/src/events/recETS/recetsPoshMotherDaughter.js b/src/events/recETS/recetsPoshMotherDaughter.js
index 3d0339c23386343727aa2e8903db9065d5d2c422..1ed9aff9edb3324ad044f672b8328597b8b3c256 100644
--- a/src/events/recETS/recetsPoshMotherDaughter.js
+++ b/src/events/recETS/recetsPoshMotherDaughter.js
@@ -94,7 +94,7 @@ App.Events.recetsPoshMotherDaughter = class recetsPoshMotherDaughter extends App
 
 		function sell() {
 			cashX((cost - contractCost), "slaveTransfer", mother);
-			return `slave.slaveName accepts being resold without much fuss. ${He}'s merely exchanged one unknown owner for another. For all ${he} knows ${his} new buyer will be less abusive than you would have been. ${He} would be less complacent if ${he} knew who ${his} buyers are; ${he}'ll be immured in an arcade within the hour.`;
+			return `${mother.slaveName} accepts being resold without much fuss. ${He}'s merely exchanged one unknown owner for another. For all ${he} knows ${his} new buyer will be less abusive than you would have been. ${He} would be less complacent if ${he} knew who ${his} buyers are; ${he}'ll be immured in an arcade within the hour.`;
 		}
 
 		function both() {
diff --git a/src/events/scheduled/murderAttempt.js b/src/events/scheduled/murderAttempt.js
index 746b6fb810ff38d7be6e62ead6ce60c9e1124704..b5a2fef5c761d57d0d9b6dc07deb3546eb5b880d 100644
--- a/src/events/scheduled/murderAttempt.js
+++ b/src/events/scheduled/murderAttempt.js
@@ -296,7 +296,7 @@ App.Events.MurderAttempt = class MurderAttempt extends App.Events.BaseEvent {
 					paragraphStart.push(`${companyName} is dealing in a special kind of enslavement. Rather than searching for buyers for the slaves they already have, they instead find potential buyers and acquire those they want to buy. And while there are means to order slaves with certain traits, ${companyName} enslaves the exact individuals you want through fabricated debt, kidnapping or any means necessary.`);
 					if (V.cash >= 50000) {
 						options.push(new App.Events.Result( // age needs to be checked here
-							"Enslaving that annoying girl from high school might be petty, but it will be worth it nonetheless.",
+							"Enslaving that annoying thorn in your side from high school might be petty, but it will be worth it nonetheless.",
 							accept("school"), `Costs ${cashFormat(50000)}`));
 					}
 					if (V.cash >= 250000) {
@@ -481,7 +481,7 @@ App.Events.MurderAttemptFollowup = class MurderAttemptFollowup extends App.Event
 				relation = "your former schoolmate";
 			} else if (type === "star") {
 				slave = GenerateNewSlave('XX');
-				slave.origin = "You bought $her enslavement in an illegal deal.";
+				slave.origin = "You bought $his enslavement in an illegal deal.";
 				slave.voice = 3;
 				slave.skill.entertainment = 60;
 				slave.face = 96 + Math.floor(Math.random() * 5); // Math.random() is always < 1, so range is 0<=x<=4
diff --git a/src/events/scheduled/pitFight.js b/src/events/scheduled/pitFight.js
index 09fc9a8871297efff84a95cab4a61f83c9653347..934149bb4335ba54d84fd4c17fd64510d95b2eaf 100644
--- a/src/events/scheduled/pitFight.js
+++ b/src/events/scheduled/pitFight.js
@@ -1,8 +1,4 @@
 App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent {
-	constructor(actors, params) {
-		super(actors, params);
-	}
-
 	eventPrerequisites() {
 		return [
 			() => !!V.pit,
@@ -13,63 +9,108 @@ App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent {
 	castActors() {
 		const available = [...new Set(V.pit.fighterIDs)];
 
-		if (V.pit.fighters === 4 && V.pit.slavesFighting.length !== 2) {
-			V.pit.fighters = 0;
-			V.pit.slavesFighting = [];
+		if (available.length > 0) {
+			this.actors = getFighters(V.pit.fighters).filter(f => !!f);
+
+			return this.actors.length > 1 || !!V.pit.slaveFightingAnimal;
 		}
 
-		if (V.pit.slaveFightingBodyguard) {	// slave is fighting bodyguard for their life
-			this.actors.push(S.Bodyguard.ID, V.pit.slaveFightingBodyguard);
-		} else if (V.pit.slaveFightingAnimal) { // slave is fighting an animal for their life
-			this.actors.push(V.pit.slaveFightingAnimal);
-		} else {
-			const fighters = V.pit.fighters;
-
-			if (available.length > 0) {
-				if (fighters === 4 &&
-					V.pit.slavesFighting.length === 2 &&
-					V.pit.slavesFighting.every(a => available.includes(a))) {
-					this.actors.push(...V.pit.slavesFighting);
-				} else if (fighters === 3) {
-					V.pit.fighters = random(2);
-
-					if (V.pit.fighters === 2 && (V.active.canine || V.active.hooved || V.active.feline)) {
-						V.pit.slaveFightingAnimal = available.pluck();
-					}
+		return false; // couldn't cast second fighter
+
+		/**
+		 * @param {number} setting
+		 * @returns {Array<number>} slave IDs
+		 */
+		function getFighters(setting) {
+			if (V.pit.slaveFightingAnimal || V.pit.slaveFightingBodyguard) {
+				return getScheduledFight();
+			}
+			if (setting === 4) {
+				return getSpecificFight();
+			}
+			if (setting === 3) {
+				return getRandomFight();
+			}
+			if (setting === 2) {
+				return getAnimalFight();
+			}
+			if (setting === 1) {
+				return getBodyguardFight();
+			}
+			if (setting === 0) {
+				return getSlavesFight();
+			}
+
+			return [];
+
+			function getScheduledFight() {
+				if (V.pit.slaveFightingAnimal) {
+					return [V.pit.slaveFightingAnimal];
+				}
+				if (V.pit.slaveFightingBodyguard) {
+					return [V.pit.slaveFightingBodyguard, S.Bodyguard.ID];
 				}
+			}
 
-				// first fighter
-				if (S.Bodyguard && V.pit.fighters === 1) {
-					available.delete(S.Bodyguard.ID);
-					this.actors.push(S.Bodyguard.ID);
-				} else {
-					this.actors.push(available.pluck());
+			function getSpecificFight() {
+				if (V.pit.slavesFighting.length > 1 &&
+					V.pit.slavesFighting.every(a => available.includes(a) && canFight(getSlave(a)))) {
+					return V.pit.slavesFighting.slice(0, 2);	// cut the array off at 2 items in case it was somehow longer
 				}
+				return [];
+			}
 
-				// second fighter
-				if (V.pit.fighters !== 2 || (!V.active.canine && !V.active.hooved && !V.active.feline)) {
-					if (available.length > 0) {
-						this.actors.push(available.pluck());
-					} else {
-						return false; // couldn't cast second fighter
-					}
+			function getRandomFight() {
+				const fightDelegates = [];
+
+				if (V.active.canine || V.active.hooved || V.active.feline) {
+					fightDelegates.push(getAnimalFight);
+				}
+				if (S.Bodyguard) {						
+					fightDelegates.push(getBodyguardFight);
 				}
+				if (available.length > 1) {
+					fightDelegates.push(getSlavesFight);
+				}
+
+				return fightDelegates.length > 0 ? (fightDelegates.random())() : [];
 			}
 
-			if (fighters === 3) {
-				V.pit.fighters = 3;
+			function getAnimalFight() {
+				const fighter = available.pluck();
+				V.pit.slaveFightingAnimal = fighter;
+
+				return [fighter];
+			}
+
+			function getBodyguardFight() {
+				available.delete(S.Bodyguard.ID);
+				return [available.pluck(), S.Bodyguard.ID];
 			}
-		}
 
-		return this.actors.length > 0;
+			function getSlavesFight() {
+				return [available.pluck(), available.pluck()];
+			}
+
+			/** @param {App.Entity.SlaveState} slave */
+			function canFight(slave) {
+				if (!canWalk(slave)) {
+					return false;
+				}
+
+				return true;
+			}
+		}
 	}
 
+	/** @param {DocumentFragment} node */
 	execute(node) {
 		V.pit.fought = true;
 
-		node.appendChild(V.pit.lethal
-			? App.Facilities.Pit.lethalFight(this.actors)
-			: App.Facilities.Pit.nonlethalFight(this.actors)
-		);
+		if (V.pit.lethal) {
+			node.append(App.Facilities.Pit.lethalFight(this.actors));
+		} else {
+			node.append(App.Facilities.Pit.nonlethalFight(this.actors));
+		}
 	}
 };
diff --git a/src/events/scheduled/pitFightLethal.js b/src/events/scheduled/pitFightLethal.js
index 56d56db7aa01cbd90003b04f0694db512c575ce1..fe732f1cec3174a842786ae8c6abac160a8cd338 100644
--- a/src/events/scheduled/pitFightLethal.js
+++ b/src/events/scheduled/pitFightLethal.js
@@ -16,7 +16,7 @@ App.Facilities.Pit.lethalFight = function(fighters) {
 		animals.push(V.active.feline);
 	}
 
-	if (V.pit.fighters === 2 || V.pit.slaveFightingAnimal) {
+	if (V.pit.fighters === 2  || V.pit.slaveFightingAnimal) {
 		animal = V.pit.animal === 'random'
 			? getAnimal(animals.random())
 			: getAnimal(V.pit.animal);
@@ -34,7 +34,7 @@ App.Facilities.Pit.lethalFight = function(fighters) {
 	}
 
 	if (V.debugMode) {
-		console.log(winner, loser);
+		console.log(winner, loser, animal);
 	}
 
 	intro(frag);
@@ -81,12 +81,12 @@ App.Facilities.Pit.lethalFight = function(fighters) {
 		}
 
 		if (V.arcologies[0].FSRomanRevivalist !== "unset") {
-			r.push(`They `, App.UI.DOM.makeElement("span", 'passionately approve', ['reputation', 'inc']), ` of your hosting lethal combat between slaves; this advances ideas from antiquity about what public events should be.`);
+			r.push(`They `, App.UI.DOM.makeElement("span", `passionately approve`, ['reputation', 'inc']), ` of your hosting lethal combat between slaves; this advances ideas from antiquity about what public events should be.`);
 
 			repX(20 * V.FSSingleSlaveRep * (V.arcologies[0].FSRomanRevivalist / V.FSLockinLevel), "pit");
 			V.arcologies[0].FSRomanRevivalist += (0.4 * V.FSSingleSlaveRep);
 		} else if (V.arcologies[0].FSAztecRevivalist !== "unset") {
-			r.push(`They `, App.UI.DOM.makeElement("span", 'approve', ['reputation', 'inc']), ` of your hosting lethal combat; this advances ideas that blood must flow as it did in ancient times.`);
+			r.push(`They `, App.UI.DOM.makeElement("span", `approve`, ['reputation', 'inc']), ` of your hosting lethal combat; this advances ideas that blood must flow as it did in ancient times.`);
 
 			repX(10 * V.FSSingleSlaveRep * (V.arcologies[0].FSAztecRevivalist / V.FSLockinLevel), "pit");
 			V.arcologies[0].FSAztecRevivalist += (0.2 * V.FSSingleSlaveRep);
@@ -434,9 +434,9 @@ App.Facilities.Pit.lethalFight = function(fighters) {
 						repX(100, "pit", loser);
 					}
 				} else if (loser.boobs > 1200) {
-					r.push(`${loser.slaveName}'s tits are too big to possibly defend, so ${he} can't help but ${canSee(loser) ? `watch` : `cringe`} in horror in horror as the ${animal.species} lunges at ${him}, ${animal.type === "hooved" ? `headfirst` : `fangs and claws outstretched`}. ${loser.slaveName}'s reflexively drops ${his} sword to clasp ${his} ${hasBothArms(loser) ? `hands` : `hand`} over ${his} ruined breasts, gushing blood${loser.boobsImplant > 400 ? ` and implant fluid` : ``}. The ${animal.species} follows up with a ${animal.type === "hooved" ?
-						`fierce bite to ${hasBothLegs(loser) ? `one of ${his} legs` : hasAnyLegs(loser) ? `${his} leg` : `${his} rear`}, causing ${him} to collapse. A second later, than animal's fangs have finished ${him} off.` :
-						`swift kick to the chest, causing ${him} to drop like a rock. Another blow to the head finishes ${him} off.`}`);
+					r.push(`${loser.slaveName}'s tits are too big to possibly defend, so ${he} can't help but ${canSee(loser) ? `watch` : `cringe`} in horror in horror as the ${animal.species} lunges at ${him}, ${animal.type === "hooved" ? `headfirst` : `fangs and claws outstretched`}. ${loser.slaveName}'s reflexively drops ${his} sword to clasp ${his} ${hasBothArms(loser) ? `hands` : `hand`} over ${his} ruined breasts, gushing blood${loser.boobsImplant > 400 ? ` and implant fluid` : ``}. The ${animal.species} follows up with a ${animal.type === "hooved"
+						? `fierce bite to ${hasBothLegs(loser) ? `one of ${his} legs` : hasAnyLegs(loser) ? `${his} leg` : `${his} rear`}, causing ${him} to collapse. A second later, than animal's fangs have finished ${him} off.`
+						: `swift kick to the chest, causing ${him} to drop like a rock. Another blow to the head finishes ${him} off.`}`);
 
 					if (V.pit.audience === "paid") {
 						r.push(`The audience is not very impressed by this easy kill, and your `, App.UI.DOM.makeElement("span", `cut of the betting`, ['cash', 'inc']), ` is also unimpressive.`);
@@ -449,9 +449,9 @@ App.Facilities.Pit.lethalFight = function(fighters) {
 					}
 				} else {
 					if (loser.skill.combat > 0) {
-						r.push(`${loser.slaveName} is reasonably confident in ${his} fighting abilities, but ${he} isn't sure how to go about attacking the ${animal.species}. ${He} decides to open with a series of wide horizontal slashes, but the beast manages to stay out of range of ${his} sword. Realizing this isn't working, ${he} lunges at the animal, leaving ${his} side exposed. The ${animal.species} sees this and ${animal.type === "hooved" ?
-							`headbutts ${him} as hard as it can, sending ${him} flying into the side of ${V.pit.name}. Battered` :
-							`leaves some ${App.UI.DOM.makeElement("span", `deep claw marks in ${his} side.`, ['health', 'dec'])} Bleeding`} and unable to stand, ${loser.slaveName} can do little to stop the ${animal.species} from finishing ${him} off with a ${animal.type === "canine" ? `fierce bite of its fangs to ${his} throat.` : animal.type === "hooved" ? `swift kick to the head.` : `ferocious swipe of its claws to ${his} throat.`}`);
+						r.push(`${loser.slaveName} is reasonably confident in ${his} fighting abilities, but ${he} isn't sure how to go about attacking the ${animal.species}. ${He} decides to open with a series of wide horizontal slashes, but the beast manages to stay out of range of ${his} sword. Realizing this isn't working, ${he} lunges at the animal, leaving ${his} side exposed. The ${animal.species} sees this and ${animal.type === "hooved"
+							? `headbutts ${him} as hard as it can, sending ${him} flying into the side of ${V.pit.name}. Battered`
+							: `leaves some ${App.UI.DOM.makeElement("span", `deep claw marks in ${his} side.`, ['health', 'dec'])} Bleeding`} and unable to stand, ${loser.slaveName} can do little to stop the ${animal.species} from finishing ${him} off with a ${animal.type === "canine" ? `fierce bite of its fangs to ${his} throat.` : animal.type === "hooved" ? `swift kick to the head.` : `ferocious swipe of its claws to ${his} throat.`}`);
 
 						if (V.pit.audience === "paid") {
 							r.push(`The audience is reasonably impressed by the blood, and your `, App.UI.DOM.makeElement("span", `cut of the betting`, ['cash', 'inc']), ` is reasonable.`);
@@ -465,7 +465,7 @@ App.Facilities.Pit.lethalFight = function(fighters) {
 					} else {
 						r.push(animal.type === "hooved"
 							? `The ${animal.species} paws at the ground for a few seconds before launching itself at ${loser.slaveName}. ${He} just barely manages to get out of the way, and the ${animal.species} has to backpedal to avoid smashing into the wall. ${loser.slaveName} isn't out of danger just yet, though — ${he} is still standing directly behind the ${animal.species}. ${He} realizes this too late, as both of the its hooves connect with ${his} jaw. With a sickening ${App.UI.DOM.makeElement("span", `crunch`, ["note"])}, ${he} flies backwards, ${his} body slamming into the other wall of ${V.pit.name} before crumpling in a heap on the ground.`
-							: `${loser.slaveName} doesn't stand a chance, and ${he} knows it. ${He} comes in with a furious overhead slash, which the ${animal.species} dodges with ease. It also dodges the next few slashes before coming to a standstill. With a furious growl, it runs around ${him}, just out of reach of ${his} sword, before jumping at the wall of ${V.pit.name} and launching itself off. Its ${animal.type === "canine" ? `teeth` : `claws`} connect with ${loser.slaveName}'s throat, completely severing ${his} windpipe. ${He} falls to ${his} knees, eyes wide and clutching ${his} throat, before completely collapsing.`
+							: `${loser.slaveName} doesn't stand a chance, and ${he} knows it. ${He} comes in with a furious overhead slash, which the ${animal.species} dodges with ease. It also dodges the next few slashes before coming to a standstill. With a furious growl, it runs around ${him}, just out of reach of ${his} sword, before jumping at the wall of ${V.pit.name} and launching itself off. Its ${animal.type === "canine" ? `teeth` : `claws`} connect with ${loser.slaveName}'s throat, completely severing ${his} windpipe. ${He} falls to ${his} knees, eyes wide and clutching ${his} throat, before completely collapsing.`,
 						);
 
 						if (V.pit.audience === "paid") {
@@ -681,7 +681,7 @@ App.Facilities.Pit.lethalFight = function(fighters) {
 
 	/** @param {DocumentFragment} parent */
 	function postFight(parent) {
-		const mindbrokenSpan = App.UI.DOM.makeElement("span", `no longer capable`, "red");
+		const mindbrokenSpan = App.UI.DOM.makeElement("span", `no longer capable`, ["red"]);
 		const experienceSpan = App.UI.DOM.makeElement("span", `learned basic combat skills.`, ["improvement"]);
 
 		const r = [];
@@ -695,7 +695,7 @@ App.Facilities.Pit.lethalFight = function(fighters) {
 				if (winner.fetish === "mindbroken") {
 					r.push(`${He} was already so broken before today that ${he} will not be seriously affected by having killed another creature with ${his} own ${hasBothArms ? `hands` : `hand`}.`);
 				} else if (winner.devotion > 50) {
-					r.push(`${He} is so devoted that he doesn't see anything wrong with killing another creature.`);
+					r.push(`${He} is so devoted that ${he} doesn't see anything wrong with killing another creature.`);
 				} else {
 					r.push(`${He} isn't happy about having to have taken another creature's life, and tells ${himself} that it was the animal's life or ${hers}.`);
 				}
@@ -834,7 +834,6 @@ App.Facilities.Pit.lethalFight = function(fighters) {
 		App.Events.addParagraph(parent, r);
 	}
 
-
 	// Helper Functions
 
 	/** @returns {boolean} Returns true if fighters[0] won */
@@ -844,21 +843,21 @@ App.Facilities.Pit.lethalFight = function(fighters) {
 				return random(1, 100) > 20;	// 80% chance of winning
 			} else if (deadliness(getSlave(fighters[0])) < animal.deadliness) {
 				return random(1, 100) > 80;	// 20% chance of winning
-			} else if (random(1, 100) > 50) {	// 50/50
+			} else if (random(1, 100) > 50) { // 50/50
 				return true;
-			} else {
-				return false;
 			}
+
+			return false;
 		}
 
 		if (deadliness(getSlave(fighters[0])) > deadliness(getSlave(fighters[1]))) {
 			return random(1, 100) > 20;	// 80% chance of winning
 		} else if (deadliness(getSlave(fighters[0])) < deadliness(getSlave(fighters[1]))) {
 			return random(1, 100) > 80;	// 20% chance of winning
-		} else if (random(1, 100) > 50) {	// 50/50
+		} else if (random(1, 100) > 50) { // 50/50
 			return true;
-		} else {
-			return false;
 		}
+
+		return false;
 	}
 };
diff --git a/src/events/scheduled/pitFightNonlethal.js b/src/events/scheduled/pitFightNonlethal.js
index dc5a0316b5c10f70f9fff513aab28de448f6f366..e2ab147a072a451bb6efe3e385ec802bb4754d22 100644
--- a/src/events/scheduled/pitFightNonlethal.js
+++ b/src/events/scheduled/pitFightNonlethal.js
@@ -433,7 +433,7 @@ App.Facilities.Pit.nonlethalFight = function(fighters) {
 				himself: himself2,
 				girl: girl2,
 				He: He2,
-				His: His2
+				His: His2,
 			} = getPronouns(loser);
 
 			if (!canSee(winner) && !canSee(loser)) {
@@ -577,7 +577,7 @@ App.Facilities.Pit.nonlethalFight = function(fighters) {
 					cashX(1000, "pit", winner);
 				}
 			} else if (loser.piercing.eyebrow.weight > 0) {
-				r.push(`The fight starts slowly, with the two trading jabs. Just as the spectators are getting bored, ${loser.slaveName} takes a glancing blow to the eyebrow. ${His2} piercing catches on ${winner.slaveName}'s glove and tears out. ${loser.slaveName} goes after ${his2} tormentor in fury, streaming blood, the piercing forgotten on the mat. Any tendency ${winner.slaveName} might have had to feel badly about this is extinguished by the assault, and soon ${winner.slaveName} is even willing to follow up on the success by targeting pierced body parts. The fight ends with poor ${loser.slaveName} writhing in pain on the mat, `, App.UI.DOM.makeElement("span", `leaking blood,`, ["health", "dec"]), ` from several terribly shredded areas.`);
+				r.push(`The fight starts slowly, with the two trading jabs. Just as the spectators are getting bored, ${loser.slaveName} takes a glancing blow to the eyebrow. ${His2} piercing catches on ${winner.slaveName}'s glove and tears out. ${loser.slaveName} goes after ${his2} tormentor in fury, streaming blood, the piercing forgotten on the mat. Any tendency ${winner.slaveName} might have had to feel badly about this is extinguished by the assault, and soon ${winner.slaveName} is even willing to follow up on the success by targeting pierced body parts. The fight ends with poor ${loser.slaveName} writhing in pain on the mat, `, App.UI.DOM.makeElement("span", `leaking blood`, ["health", "dec"]), ` from several terribly shredded areas.`);
 
 				if (V.pit.audience === "free") {
 					r.push(`The audience is `, App.UI.DOM.makeElement("span", `reasonably impressed`, ["reputation", "inc"]), ` by the gory spectacle.`);
@@ -706,7 +706,8 @@ App.Facilities.Pit.nonlethalFight = function(fighters) {
 					slave.vagina = slave.vagina < animal.dick.size ? animal.dick.size : slave.vagina;
 				} else if (canDoAnal(slave)) {
 					seX(slave, 'anal', 'animal');
-					slave.anus = slave.anus < animal.dick.size ? animal.dick.size : slave.anus;
+					// @ts-ignore
+					slave.anus = Math.max(slave.anus, stretchedAnusSize(animal.dick.size));
 				} else {
 					seX(slave, 'oral', 'animal');
 				}
@@ -851,7 +852,7 @@ App.Facilities.Pit.nonlethalFight = function(fighters) {
 
 					actX(loser, vaginal);
 				} else if (canDoAnal(loser)) {
-					r.push();
+					r.push(winnerPenetrates(anus));
 
 					if (canPenetrate(winner) && canImpreg(loser, winner) && loser.mpreg) {
 						r.push(loserProtest);
@@ -932,7 +933,7 @@ App.Facilities.Pit.nonlethalFight = function(fighters) {
 
 					actX(loser, vaginal);
 				} else if (canDoAnal(loser)) {
-					r.push();
+					r.push(winnerPenetrates(anus));
 
 					if (canPenetrate(winner) && canImpreg(loser, winner)) {
 						r.push(loserProtest);
@@ -996,7 +997,7 @@ App.Facilities.Pit.nonlethalFight = function(fighters) {
 
 					actX(loser, vaginal);
 				} else if (canDoAnal(loser)) {
-					r.push();
+					r.push(winnerPenetrates(anus));
 
 					if (canPenetrate(winner) && canImpreg(loser, winner)) {
 						r.push(loserProtest);
@@ -1160,15 +1161,15 @@ App.Facilities.Pit.nonlethalFight = function(fighters) {
 				}
 
 				if (winner.fetish === "sadist" && winner.fetishStrength > 90 && winner.sexualFlaw !== "malicious" && winner.devotion > 20) {
-					r.push(`${He} noticed something while ${he} was raping ${loser.slaveName}; watching the way ${he2} writhed in pain was strangely satisfying, as ${he} was making ${him2} suffer. ${winner.slaveName} cums powerfully at the mere thought; ${he} has become `, App.UI.DOM.makeElement("span", `sexually addicted to inflicting pain and anguish.`, "noteworthy"));
+					r.push(`${He} noticed something while ${he} was raping ${loser.slaveName}; watching the way ${he2} writhed in pain was strangely satisfying, as ${he} was making ${him2} suffer. ${winner.slaveName} cums powerfully at the mere thought; ${he} has become `, App.UI.DOM.makeElement("span", `sexually addicted to inflicting pain and anguish.`, ["noteworthy"]));
 
 					winner.sexualFlaw = "malicious";
 				} else if (winner.fetish === "masochist" && winner.fetishStrength > 90 && winner.sexualFlaw !== "self hating" && winner.devotion < 20) {
-					r.push(`${He} feels horrible after forcing ${himself} on ${loser.slaveName}; ${he} is the one that should suffer, not ${him2}. ${winner.slaveName} has `, App.UI.DOM.makeElement("span", `descended into true self hatred.`, "noteworthy"));
+					r.push(`${He} feels horrible after forcing ${himself} on ${loser.slaveName}; ${he} is the one that should suffer, not ${him2}. ${winner.slaveName} has `, App.UI.DOM.makeElement("span", `descended into true self hatred.`, ["noteworthy"]));
 
 					winner.sexualFlaw = "self hating";
 				} else if (winner.fetish === "dom" && winner.fetishStrength > 90 && winner.sexualFlaw !== "abusive" && winner.devotion > 20) {
-					r.push(`${He} noticed something while ${he} was raping ${loser.slaveName}; watching the way ${he2} cowered before ${hasAnyArms(winner) ? `${his} raised palm` : `${him}`} was strangely satisfying, as were the painful moans that accompanied every forceful thrust. ${winner.slaveName} cums powerfully at the mere thought; ${he} has become `, App.UI.DOM.makeElement("span", `sexually abusive, getting off on the thrill of forcing ${himself} on other slaves.`, "noteworthy"));
+					r.push(`${He} noticed something while ${he} was raping ${loser.slaveName}; watching the way ${he2} cowered before ${hasAnyArms(winner) ? `${his} raised palm` : `${him}`} was strangely satisfying, as were the painful moans that accompanied every forceful thrust. ${winner.slaveName} cums powerfully at the mere thought; ${he} has become `, App.UI.DOM.makeElement("span", `sexually abusive, getting off on the thrill of forcing ${himself} on other slaves.`, ["noteworthy"]));
 
 					winner.sexualFlaw = "abusive";
 				} else if (winner.behavioralFlaw === "none" && random(1, 100) < 5 && winner.devotion < 20) {
@@ -1262,7 +1263,7 @@ App.Facilities.Pit.nonlethalFight = function(fighters) {
 			return random(1, 100) > 20;	// 80% chance of winning
 		} else if (deadliness(getSlave(fighters[0])) < deadliness(getSlave(fighters[1]))) {
 			return random(1, 100) > 80;	// 20% chance of winning
-		} else if (random(1, 100) > 50) {	// 50/50
+		} else if (random(1, 100) > 50) { // 50/50
 			return true;
 		}
 
diff --git a/src/events/scheduled/poorKnight.js b/src/events/scheduled/poorKnight.js
index 26f2c5f940fd0e9c4c4608521221be301cf8e33d..2f5bda9bb67d76a85c6b2835157b57f657bf33bf 100644
--- a/src/events/scheduled/poorKnight.js
+++ b/src/events/scheduled/poorKnight.js
@@ -17,7 +17,7 @@ App.Events.SEPoorKnight = class SEPoorKnight extends App.Events.BaseEvent {
 
 		App.Events.addParagraph(node, [`The cruel rambunctiousness of this trader and your own Knights continued for a few hours, with nearby guards both pretending not to notice and not reporting their activities to you, until a factory-working peasant by the name of Valentin approached them in the marketplace and demanded they stop. When the merchant's guards attempted to apprehend him, although you aren't clear on the exact details, it seems he managed to somehow strike down all five, despite being both unarmed and unarmored. The present Knight promptly challenged him to fight, out-of-armor and one-on-one, and was then knocked flat by the peasant in front of the watching marketplace as well.`]);
 
-		App.Events.addParagraph(node, [`This 'Valentin', a quiet man built like a mountain, has very rapidly become a local hero to your peasantry. You have heard petitions calling for him to be Knighted, and the public has nearly immediately come to see him as a courageous fighter against the various injustices of your hierarchical Imperial society. Your Barons, on the other hand, murmur that he is a rabblerouser, a peasant who has clearly forgotten his station at the bottom of the pyramid, and that to do anything but punish him for his insolence will surely lead to riots and unrest. Such a man would surely be a proud and capable Imperial Knight, but to Knight him would undoubtedly be seen as condoning liberal freedoms in your lower classes, and a Knight drawn from the filthy, unwashed peasants is totally unheard of.`]);
+		App.Events.addParagraph(node, [`This "Valentin", a quiet man built like a mountain, has very rapidly become a local hero to your peasantry. You have heard petitions calling for him to be Knighted, and the public has nearly immediately come to see him as a courageous fighter against the various injustices of your hierarchical Imperial society. Your Barons, on the other hand, murmur that he is a rabblerouser, a peasant who has clearly forgotten his station at the bottom of the pyramid, and that to do anything but punish him for his insolence will surely lead to riots and unrest. Such a man would surely be a proud and capable Imperial Knight, but to Knight him would undoubtedly be seen as condoning liberal freedoms in your lower classes, and a Knight drawn from the filthy, unwashed peasants is totally unheard of.`]);
 
 		const festiveCost = 5000;
 		const quietCost = 500;
@@ -36,17 +36,17 @@ App.Events.SEPoorKnight = class SEPoorKnight extends App.Events.BaseEvent {
 		App.Events.addResponses(node, choices);
 
 		function festival() {
-			cashX(-festiveCost, "knighting");
+			cashX(-festiveCost, "event");
 			V.arcologies[0].prosperity -= 2;
 			repX(5000, "event");
-			return `You make your stance on the issue known with a large public ceremony, awarding Valentin with his own private apartment, coat of arms, and a set of Imperial Plate in the very marketplace where he bested a group of brutish foreign thugs and an overly-cocky Knight. A swarm of peasantry surround every inch of the ceremony, <span class="green">cheering your name</span> and 'Sir' Valentin's as you demonstrate that skill and courage is more important than social station. The furious foreign merchant sends you a message a few days later swearing to <span class="red">never return to your arcology,</span> and the Barons grumble about the wildly dancing and celebrating peasants <span class="red">undermining your authority.</span>`;
+			return `You make your stance on the issue known with a large public ceremony, awarding Valentin with his own private apartment, coat of arms, and a set of Imperial Plate in the very marketplace where he bested a group of brutish foreign thugs and an overly-cocky Knight. A swarm of peasantry surround every inch of the ceremony, <span class="green">cheering your name</span> and celebrating Sir Valentin as you demonstrate that skill and courage is more important than social station. The furious foreign merchant sends you a message a few days later swearing to <span class="red">never return to your arcology,</span> and the Barons grumble about the wildly dancing and celebrating peasants <span class="red">undermining your authority.</span>`;
 		}
 
 		function quiet() {
-			cashX(-quietCost, "knighting");
+			cashX(-quietCost, "event");
 			V.arcologies[0].prosperity -= 1;
 			repX(2000, "event");
-			return `You quietly award the brave peasant a set of Imperial Plate and his own apartment in a private ceremony attended only by a handful of your Barons and Knights. Many of the watching oligarchs seem thoroughly unenthusiastic about the enormous, grease-stained man joining their hallowed ranks, but politely clap and congratulate him nevertheless. Even the pompous Knight who he beat a few days ago, still sporting a black eye, claps him on the back after you have him rise as 'Sir' Valentin and congratulates him on a fight "befitting of a real man". Word of your decision soon reaches the peasantry, who <span class="green">celebrate</span> the rewards given for honor, but you later receive a message from the foreign merchant infuriated that you would reward such insolence and claiming that he'll <span class="red">hike his prices for you.</span>`;
+			return `You quietly award the brave peasant a set of Imperial Plate and his own apartment in a private ceremony attended only by a handful of your Barons and Knights. Many of the watching oligarchs seem thoroughly unenthusiastic about the enormous, grease-stained man joining their hallowed ranks, but politely clap and congratulate him nevertheless. Even the pompous Knight who he beat a few days ago, still sporting a black eye, claps him on the back after you have him rise as Sir Valentin and congratulates him on a fight "befitting of a real man". Word of your decision soon reaches the peasantry, who <span class="green">celebrate</span> the rewards given for honor, but you later receive a message from the foreign merchant infuriated that you would reward such insolence and claiming that he'll <span class="red">hike his prices for you.</span>`;
 		}
 
 		function floggingMeat() {
diff --git a/src/events/scheduled/seCoursing.js b/src/events/scheduled/seCoursing.js
index 6d19ae3ea3d55958cd5d18e549d00cc6e2fd3532..4115c6b3f2633755486da121f77f5e435e49dfde 100644
--- a/src/events/scheduled/seCoursing.js
+++ b/src/events/scheduled/seCoursing.js
@@ -899,8 +899,7 @@ App.Events.SECoursing = class SECoursing extends App.Events.BaseEvent {
 						activeLurcher.devotion += 5;
 					}
 				}
-				activeLurcher.counter.penetrative += 1;
-				V.penetrativeTotal += 1;
+				seX(activeLurcher, "penetrative", "slaves", "vaginal");
 				newSlave(hare.slave);/* skip New Slave Intro */
 			} else {
 				if (activeLurcher.devotion > 50) {
diff --git a/src/events/scheduled/seFCNNstation.js b/src/events/scheduled/seFCNNstation.js
index 41c9f4654559ae0de85f237b919e9904d0e3a9e2..8f87cfd72c76afcb23ee9cca054a6cac212e4b34 100644
--- a/src/events/scheduled/seFCNNstation.js
+++ b/src/events/scheduled/seFCNNstation.js
@@ -1,7 +1,7 @@
 App.Events.SEFcnnStation = class SEFcnnStation extends App.Events.BaseEvent {
 	eventPrerequisites() {
 		return [
-			() => V.rivalOwner === 0,
+			() => V.rival.state <= 1 || V.rival.state > 2,
 			() => V.seeFCNN === 1,
 			() => V.FCNNstation === 0,
 			() => V.week > 95,
diff --git a/src/events/scheduled/seFctvRemote.js b/src/events/scheduled/seFctvRemote.js
index 850ad0c0f59b32ea3b55ee617cedb9b421101e19..c70011e8ddd86bca34ff858ed2bb62aeddf93897 100644
--- a/src/events/scheduled/seFctvRemote.js
+++ b/src/events/scheduled/seFctvRemote.js
@@ -142,6 +142,8 @@ App.Events.SEfctvRemote = class SEfctvRemote extends App.Events.BaseEvent {
 			tech.stampTat = "'Shove that upgraded package here' is tattooed above $his rear.";
 			cashX(forceNeg((V.modCost * 2) + V.SPcost), "slaveMod", tech); // two tats and a smart piercing
 
+			App.Events.refreshEventArt([tech, customer]);
+
 			r.push(`With a barely perceptible signal to ${V.assistant.name}, ${his} drone whirs to a stop and begins to fall to the floor. Before it lands, a dart hits ${him} in the neck. ${He} collapses into darkness.`);
 			App.Events.addParagraph(frag, r);
 
@@ -160,9 +162,6 @@ App.Events.SEfctvRemote = class SEfctvRemote extends App.Events.BaseEvent {
 			App.Events.addParagraph(frag, r);
 
 			r = [];
-			if (V.seeImages > 0) {
-				App.Events.drawEventArt(frag, [tech, customer]);
-			}
 			r.push(`The door opens, and one of your citizens appears. ${tech.slaveName} doesn't know it, but you've made a small change to ${his} calendar. ${His} new client has a`);
 			if (customer.dick > 0) {
 				r.push(`legendarily large dick,`);
@@ -313,7 +312,7 @@ App.Events.SEfctvRemote = class SEfctvRemote extends App.Events.BaseEvent {
 				choices.push(new App.Events.Result(`Enslave ${him}`, enslave));
 				choices.push(new App.Events.Result(`Sentence ${him} to a day in a wall with a TV, then enslave ${him}`, stocks));
 			} else {
-				choices.push(new App.Events.Result(null, null, `Cannot afford the ${contractCost} to enslave`));
+				choices.push(new App.Events.Result(null, null, `Cannot afford the ${cashFormat(contractCost)} to enslave`));
 			}
 			choices.push(new App.Events.Result(`Let ${him} go`, release));
 			choices.push(new App.Events.Result(`Let ${him} go but release the footage`, releaseFootage));
diff --git a/src/events/scheduled/seNicaeaCouncil.js b/src/events/scheduled/seNicaeaCouncil.js
index e5117d575df90d34f55a88b87c9ad99c446f9165..58c749deee2c94c7f33287689221f79b357cd3a1 100644
--- a/src/events/scheduled/seNicaeaCouncil.js
+++ b/src/events/scheduled/seNicaeaCouncil.js
@@ -78,12 +78,6 @@ App.Events.SENicaeaCouncil = class SENicaeaCouncil extends App.Events.BaseEvent
 			$(container).empty().append(councilInfluence());
 		}
 
-		function concludeCouncil() {
-			repX(V.nicaea.influence * 10000, "event");
-			V.nicaea.influence = 0;
-			$(container).empty().append(councilInfluence());
-		}
-
 		/**
 		 * @typedef {object} NicaeaChoice
 		 * @property {string} text
@@ -174,7 +168,11 @@ App.Events.SENicaeaCouncil = class SENicaeaCouncil extends App.Events.BaseEvent
 				]));
 
 				App.Events.addParagraph(frag, [
-					App.UI.DOM.link("Conclude the Council",	() => concludeCouncil),
+					App.UI.DOM.link("Conclude the Council",	() => {
+						repX(V.nicaea.influence * 10000, "event");
+						V.nicaea.influence = 0;
+						$(container).empty().append(councilInfluence());
+					}),
 					App.UI.DOM.makeElement("span", "This will let the currently prevailing views stand, and convert your remaining influence with the Council into general reputation", "note")
 				]);
 			} else {
diff --git a/src/events/scheduled/sePCBirthday.desc.js b/src/events/scheduled/sePCBirthday.desc.js
index 18b78dac48c9e19d2e6a64fd84ddf8b59c226432..932f69b801eb631ef1640b3f51e8931b888cd03d 100644
--- a/src/events/scheduled/sePCBirthday.desc.js
+++ b/src/events/scheduled/sePCBirthday.desc.js
@@ -77,9 +77,9 @@ App.Events.pcBirthday.Desc = (function(bday) {
 					This morning, as a `;
 
 				if (V.PC.dick) {
-					html += `mouth around your industrious cock`;
+					html += `mouth around your cock`;
 				} else {
-					html += `tongue inside your industrious cunt`;
+					html += `tongue inside your cunt`;
 				}
 
 				html += ` bids you hello, you find streamers and festive, sparkling decorations emerging from nooks
diff --git a/src/events/scheduled/sePCBirthday.js b/src/events/scheduled/sePCBirthday.js
index b5c8cac6f1551c5227665f56bd497647cfddf15c..98d37d7e3c051ca0caddc11f2ae84d660ca7da61 100644
--- a/src/events/scheduled/sePCBirthday.js
+++ b/src/events/scheduled/sePCBirthday.js
@@ -244,13 +244,13 @@ App.Events.pcBirthday = (function(events) {
 				case "formal":
 					repX(100, "event");
 					if (V.secExpEnabled) {
-						App.SecExp.authorityX(300);
+						App.Mods.SecExp.authorityX(300);
 					}
 					break;
 				case "casual":
 					repX(300, "event");
 					if (V.secExpEnabled) {
-						App.SecExp.authorityX(100);
+						App.Mods.SecExp.authorityX(100);
 					}
 					break;
 			}
diff --git a/src/events/scheduled/sePlayerBirth.js b/src/events/scheduled/sePlayerBirth.js
index 8374d411141feae4f65b0e23902d6c1298bafec9..9d66fcaedb9a8761d2646bc64ec68eefb42d5f47 100644
--- a/src/events/scheduled/sePlayerBirth.js
+++ b/src/events/scheduled/sePlayerBirth.js
@@ -200,11 +200,7 @@ App.Events.SEPlayerBirth = class SEPlayerBirth extends App.Events.BaseEvent {
 					} else {
 						r.push(`two,`);
 					}
-					r.push(`${he} made sure to hone ${his} skills as a midwife to make sure ${he} could protect you and your unborn child`);
-					if (V.PC.pregType > 1) {
-						r.push(`ren`);
-					}
-					r.push(`from any dangers.`);
+					r.push(`${he} made sure to hone ${his} skills as a midwife to make sure ${he} could protect you and your unborn ${onlyPlural(V.PC.pregType, 'child', 'children')} from any dangers.`);
 					if (concubinePresent === 1) {
 						r.push(`<span class="pink">${S.Concubine.slaveName}</span>`);
 						if (hasAnyArms(S.Concubine)) {
@@ -331,10 +327,7 @@ App.Events.SEPlayerBirth = class SEPlayerBirth extends App.Events.BaseEvent {
 					} else {
 						r.push(`bursting`);
 					}
-					r.push(`womb to pop out through the incision. Doing ${his} best, ${he} cuts open your uterus, pulls your child`);
-					if (V.PC.pregType > 1) {
-						r.push(`ren`);
-					}
+					r.push(`womb to pop out through the incision. Doing ${his} best, ${he} cuts open your uterus, pulls your ${onlyPlural(V.PC.pregType, 'child', 'children')}`);
 					r.push(`from you and severs the umbilical cord${(V.PC.pregType > 1) ? "s all at once" : ""}.`);
 					r.toParagraph();
 					r.push(`You awake some time later in the remote surgery, your stomach extremely sore; you quickly realize you're no longer round with child. As you try to rise, ${S.Bodyguard.slaveName} stops you; ${he} hefts you into a bridal carry and takes you to a recovery room, before gently placing you into a warm bed, tucking you in, and hurrying out of the room. Before you can call out, ${he} returns carrying`);
@@ -650,11 +643,7 @@ App.Events.SEPlayerBirth = class SEPlayerBirth extends App.Events.BaseEvent {
 							}
 							r.push(`your spread pussy hungrily as ${his2} erection bobs with anticipation. But you're too tired right now and ${he2} realizes it.`);
 						}
-						r.push(`${He2} helps gather your child`);
-						if (V.PC.pregType > 1) {
-							r.push(`ren`);
-						}
-						r.push(`to`);
+						r.push(`${He2} helps gather your ${onlyPlural(V.PC.pregType, 'child', 'children')} to`);
 						if (S.Concubine.lactation > 0) {
 							r.push(`${his2} and`);
 						}
diff --git a/src/events/scheduled/seRaiding.js b/src/events/scheduled/seRaiding.js
index ed73894ee89bb52e74ced1ed5fb49da6d3095533..4b2165462534046f96ca68a8ec0defd85f8e6212 100644
--- a/src/events/scheduled/seRaiding.js
+++ b/src/events/scheduled/seRaiding.js
@@ -6,7 +6,7 @@ It has been rebalanced to improve capture odds.
 If changing values, check your math and make sure that:
 no target is completely impossible to capture, with or without SF,
 odds of capturing an average target are about 50% WITHOUT the SF,
-and odds of capturing a worst-case target are about 50% WITH the SF.
+and odds of capturing a worst-case target are about 50% WITH fully upgraded SF.
 */
 
 App.Events.SERaiding = class SERaiding extends App.Events.BaseEvent {
@@ -255,7 +255,10 @@ App.Events.SERaiding = class SERaiding extends App.Events.BaseEvent {
 			} else if (slave.muscles > 5) {
 				r.push(`${His} muscles are toned, but still nimble.`);
 				targetEscape += 1;
-			} else if (slave.muscles <= 5) {
+			} else if (slave.muscles < -30) {
+				r.push(`${His} muscles barely have the strength to keep ${him} standing, let alone power a flight.`);
+				targetEscape -= 3;
+			} else if (slave.muscles < -5) {
 				r.push(`${His} body is soft and toneless.`);
 				targetEscape -= 1;
 			} else {
@@ -617,7 +620,7 @@ App.Events.SERaiding = class SERaiding extends App.Events.BaseEvent {
 					slave = GenerateNewSlave("XX", {maxAge: 20, disableDisability: 1});
 					slave.career = "a classical dancer";
 					slave.prestige = 1;
-					slave.prestigeDesc = "$He was the pride of renowned dance troupe.";
+					slave.prestigeDesc = "$He was the pride of a renowned dance troupe.";
 					slave.face = random(-20, 40);
 					slave.anus = 0;
 					slave.vagina = 1;
diff --git a/src/events/scheduled/seWedding.js b/src/events/scheduled/seWedding.js
index 8a54186d19173f7e616941dbf80737536fafe245..2058936bd59c7fe0a48fb08a94916025e43b3a3b 100644
--- a/src/events/scheduled/seWedding.js
+++ b/src/events/scheduled/seWedding.js
@@ -1120,12 +1120,13 @@ App.Events.SEWedding = class SEWedding extends App.Events.BaseEvent {
 			if (V.weddingPlanned === 3 || V.weddingPlanned === 1) {
 				if (brides.some(b => b.relationship !== 0)) {
 					if (slave1.relationshipTarget === V.marrying[1]) {
-						// TODO: not sure about these
 						if (!solo && brides.every((b) => b.fetish === "mindbroken")) {
+							// TODO: write these
 						} else if (!solo && brides.every((b) => b.devotion + b.trust >= 175)) {
 							r.push(`The fact that their relationship together now involves you <span class="hotpink">excites them to no end.</span>`);
 							brides.forEach(slave => slave.devotion += 10);
 						} else if (!solo && brides.every((b) => b.devotion < -20 && b.trust > 20)) {
+							// TODO: write these
 						} else if (!solo && brides.every((b) => b.devotion < -20)) {
 							r.push(`The fact that you would allow them to remain together, albeit as your ${wives}, <span class="hotpink">causes them to begin to see you in a new light.</span>`);
 							brides.forEach(slave => slave.devotion += 15);
@@ -1250,13 +1251,7 @@ App.Events.SEWedding = class SEWedding extends App.Events.BaseEvent {
 			if (V.weddingPlanned === 3) { // Impregnation ceremony
 				for (const slave of brides) {
 					slave.relationship = -3;
-					if (slave.mpreg === 1) {
-						slave.counter.anal += 1;
-						V.analTotal += 1;
-					} else {
-						slave.counter.vaginal += 1;
-						V.vaginalTotal += 1;
-					}
+					seX(slave, slave.mpreg ? "anal" : "vaginal", V.PC);
 					repX(1250, "event", slave);
 					makeTrinkets(slave);
 				}
@@ -1270,8 +1265,7 @@ App.Events.SEWedding = class SEWedding extends App.Events.BaseEvent {
 			} else if (V.weddingPlanned === 1) { // Straightforward ceremony
 				for (const slave of brides) {
 					slave.relationship = -3;
-					slave.counter.oral += 1;
-					V.oralTotal += 1;
+					seX(slave, "oral", V.PC);
 					repX(2000, "event", slave);
 					makeTrinkets(slave);
 				}
@@ -1457,7 +1451,7 @@ App.Events.SEWedding = class SEWedding extends App.Events.BaseEvent {
 				r.push(`You can feel their asses, still somewhat gaped from their ordeals. They've been <span class="lime">loosened</span> by their wedding party.`);
 			} else {
 				for (const slave of brides) {
-					if (slave.anus < 3) {
+					if (V.seeStretching === 1 && slave.anus < 3) {
 						const {his} = getPronouns(slave);
 						slave.anus += 1;
 						r.push(`You can feel ${slave.slaveName}'s ass, still somewhat gaped from its ordeal. It's been <span class="lime">loosened</span> by ${his} wedding party.`);
diff --git a/src/events/schools/resFailure.js b/src/events/schools/resFailure.js
index 159f0fdfa1ddea7276eaac981cc3f7d8901f212a..1692dd4cfbbd4c32e50bdc4535f647ad0d6d01bc 100644
--- a/src/events/schools/resFailure.js
+++ b/src/events/schools/resFailure.js
@@ -25,117 +25,36 @@ App.Events.RESFailure = class RESFailure extends App.Events.BaseEvent {
 		/** @type {App.Entity.SlaveState[]} */
 		const slaveArray = [];
 		if (failedSchool === "TSS") {
-			for (let i = 0; i < slavesToAdd-1; i++) {
-				const slave = GenerateNewSlave("XX", {ageOverridesPedoMode: 1});
-				slave.career = "a slave";
-				slave.butt = either(1, 2, 2, 3);
-				slave.boobs = either(200, 300, 300, 400);
+			for (let i = 0; i < slavesToAdd; i++) {
+				const {slave} = generateMarketSlave("TSS");
 				if (V.TSS.schoolUpgrade === 1) {
 					slave.origin = "$He was given to you by a failed branch campus of the Slavegirl School after $he was retrained as a slave $girl.";
-					slave.butt++;
-					slave.boobs += 200;
 				} else {
 					slave.origin = "$He was given to you by a failed branch campus of the Slavegirl School right after $his majority.";
 				}
-				slave.actualAge = (V.TSS.schoolUpgrade === 1 ? random(36, 42) : 18);
-				slave.anus = (V.TSS.schoolUpgrade === 1 ? 1 : 0);
-				slave.vagina = (V.TSS.schoolUpgrade === 1 ? 1 : 0);
-				slave.visualAge = slave.actualAge;
-				slave.physicalAge = slave.actualAge;
-				slave.ovaryAge = slave.actualAge;
-				slave.intelligenceImplant = 15;
-				slave.teeth = "normal";
-				slave.intelligence = random(-50, 95);
-				slave.devotion = random(25, 45);
-				slave.trust = random(25, 45);
-				setHealth(slave, jsRandom(50, 60), 0, 0, 0);
-				slave.preg = 0;
-				slave.weight = 0;
-				slave.chem = 20;
-				slave.skill.vaginal = (V.TUO.schoolUpgrade !== 0 ? 15 : 0);
-				slave.skill.oral = (V.TUO.schoolUpgrade !== 0 ? 15 : 0);
-				slave.skill.anal = (V.TUO.schoolUpgrade !== 0 ? 15 : 0);
-				slave.skill.whoring = (V.TUO.schoolUpgrade !== 0 ? 15 : 0);
-				slave.skill.entertainment = 15;
-				slave.skill.combat = 0;
-				slave.pubicHStyle = "waxed";
-				slave.underArmHStyle = "waxed";
-				slave.sexualFlaw = either("none");
-				slave.behavioralFlaw = either("none");
-				slave.hStyle = "tails";
-				slave.custom.tattoo = "$He has the simple logo of the corporation that operates the Slavegirl School tattooed on $his left cheek.";
 				slaveArray.push(slave);
 			}
 		} else if (failedSchool === "TUO") {
 			for (let i = 0; i < slavesToAdd; i++) {
-				const slave = GenerateNewSlave(null, {minAge: V.minimumSlaveAge, maxAge: V.fertilityAge, disableDisability: 1});
+				const {slave} = generateMarketSlave("TUO");
 				slave.origin = "$He was given to you by a failed branch of The Utopian Orphanage right after $his graduation.";
-				slave.career = "a slave";
-				setHealth(slave, jsRandom(60, 80), 0, 0, 0);
-				slave.devotion = random(50, 75);
-				slave.trust = random(50, 75);
-				slave.face = (V.TUO.schoolUpgrade === 1 ? random(30, 100) : random(10, 65));
-				slave.intelligence = (V.TUO.schoolUpgrade === 1 ? random(55, 100) : random(35, 75));
-				slave.intelligenceImplant = (V.TUO.schoolUpgrade === 1 ? 30 : 15);
-				slave.accent = (V.TUO.schoolUpgrade === 1 ? 1 : either(0, 1));
-				slave.skill.entertainment = (V.TUO.schoolUpgrade === 1 ? 75 : 45);
-				slave.skill.combat = (V.TUO.schoolUpgrade === 1 ? 1 : 0);
-				slave.skill.vaginal = (V.TUO.schoolUpgrade === 2 ? 15 : 0);
-				slave.skill.oral = (V.TUO.schoolUpgrade === 2 ? 15 : 0);
-				slave.skill.anal = (V.TUO.schoolUpgrade === 2 ? 15 : 0);
-				slave.skill.whoring = (V.TUO.schoolUpgrade === 2 ? 15 : 0);
-				slave.energy = (V.TUO.schoolUpgrade === 2 ? random(40, 95) : random(15, 65));
-				slave.faceImplant = 0;
-				slave.weight = random(-17, 17);
-				slave.muscles = random(0, 20);
-				slave.lips = random(10, 40);
-				slave.lipsImplant = 0;
-				slave.boobs = 50;
-				slave.boobsImplant = 0;
-				slave.butt = random(0, 2);
-				slave.buttImplant = 0;
-				slave.vagina = 0;
-				slave.anus = 0;
 				slaveArray.push(slave);
 			}
 		} else if (failedSchool === "TCR") {
 			for (let i = 0; i < slavesToAdd; i++) {
-				const slave = GenerateNewSlave("XX", {
-					minAge: V.fertilityAge+6, maxAge: 32, disableDisability: 1, ageOverridesPedoMode: 1
-				});
-				slave.slaveName = setup.cowSlaveNames.random();
-				slave.slaveSurname = 0;
-				slave.career = "a dairy cow";
-				slave.butt = either(5, 6, 6, 7, 7, 8, 9);
-				slave.boobs = 30000;
-				slave.lactation = 1;
-				slave.lactationDuration = 2;
-				slave.lactationAdaptation = 100;
-				slave.origin = "$He is a prized dairy cow given to you by a failed local pasture of The Cattle Ranch.";
-				slave.anus = 1;
-				slave.vagina = 5;
-				slave.vaginaLube = 2;
-				setHealth(slave, jsRandom(50, 60), 0, 0, 0);
-				slave.preg = random(30, 39);
-				slave.pregType = random(3, 6);
-				slave.pregKnown = 1;
-				slave.pregWeek = slave.preg;
-				SetBellySize(slave);
-				slave.bellySag = 10;
-				slave.bellySagPreg = 10;
-				slave.hips = either(2, 2, 2, 2, 3);
-				slave.counter.birthsTotal = random(10, 15);
-				slave.geneticQuirks.hyperFertility = 2;
-				slave.weight = random(60, 160);
-				slave.muscles = random(60, 80);
-				slave.chem = 10;
-				slave.pubicHStyle = "waxed";
-				slave.underArmHStyle = "waxed";
-				slave.heels = 1;
-				applyMindbroken(slave, either(-100, -100, -100, -96, -80, -70, -50));
-				slave.hStyle = "neat";
-				slave.collar = "leather with cowbell";
-				slave.brand["right thigh"] = "the logo of the Cattle Ranch";
+				const {slave} = generateMarketSlave("TCR");
+				if (slave.career === "a breeding bull") {
+					slave.geneticQuirks.wellHung = 2;
+					slave.origin = "$He is a prized breeding bull given to you by a failed local pasture of The Cattle Ranch.";
+				} else {
+					slave.geneticQuirks.hyperFertility = 2;
+					slave.counter.birthsTotal *= 2;
+					slave.hips += 1;
+					slave.butt += 1;
+					slave.boobs += 200;
+					slave.vaginaLube = 2;
+					slave.origin = "$He is a prized dairy cow given to you by a failed local pasture of The Cattle Ranch.";
+				}
 				slave.boobsTat = "bovine patterns";
 				slave.buttTat = "bovine patterns";
 				slave.vaginaTat = "bovine patterns";
@@ -150,482 +69,57 @@ App.Events.RESFailure = class RESFailure extends App.Events.BaseEvent {
 			}
 		} else if (failedSchool === "GRI") {
 			for (let i = 0; i < slavesToAdd; i++) {
-				const slave = GenerateNewSlave("XX", {disableDisability: 1});
+				const {slave} = generateMarketSlave("GRI");
 				slave.origin = "$He was given to you by a failed subsidiary lab of the Growth Research Institute right after $his use as a test subject ended.";
-				slave.career = "a slave";
-				slave.intelligenceImplant = 0;
-				slave.devotion = random(-15, -5);
-				slave.trust = random(-25, -45);
-				slave.chem = 100;
-				if (V.GRI.schoolUpgrade === 1) {
-					setHealth(slave, 200, 0, 0, 0);
-				} else {
-					setHealth(slave, jsRandom(-70, 100), 0);
-				}
-				slave.height = random(150, 190);
-				slave.butt = random(4, 10);
-				slave.boobs = 200 * (V.GRI.schoolUpgrade === 2 ? random(15, 30) : random(4, 20));
-				if (V.GRI.schoolUpgrade === 2) {
-					slave.lactation = slave.lactationDuration = 2;
-				}
-				slave.nipples = either("huge", "inverted");
-				slave.areolae = either(0, 1, 2, 3, 4);
-				slave.clit = either(0, 1, 2, 3);
-				slave.lips = random(5, 85);
-				slave.anus = 0;
-				slave.vagina = 0;
-				slave.preg = 0;
-				slave.weight = 0;
-				slave.skill.vaginal = 0;
-				slave.skill.oral = 0;
-				slave.skill.anal = 0;
-				slave.skill.whoring = 0;
-				slave.skill.entertainment = 0;
-				slave.skill.combat = 0;
-				slave.pubicHStyle = "waxed";
-				slave.underArmHStyle = "waxed";
-				slave.actualAge = 19;
-				slave.visualAge = slave.actualAge;
-				slave.physicalAge = slave.actualAge;
-				slave.ovaryAge = slave.actualAge;
-				slave.behavioralFlaw = either("odd");
-				slave.hStyle = "shaved";
-				slave.hLength = 0;
-				slave.custom.tattoo = "$He has a barcode that identified $him when $he was a test subject at the Growth Research Institute tattooed on $his left cheek.";
 				slaveArray.push(slave);
 			}
 		} else if (failedSchool === "SCP") {
 			for (let i = 0; i < slavesToAdd; i++) {
-				const slave = GenerateNewSlave("XX", {disableDisability: 1});
+				const {slave} = generateMarketSlave("SCP");
 				slave.origin = "$He was given to you by a failed branch campus of St. Claver Preparatory after $he served as a plastic surgeon's passing final exam.";
-				slave.chem = 20;
-				slave.career = "a slave";
-				slave.intelligenceImplant = (V.SCP.schoolUpgrade === 1 ? 0 : 15);
-				slave.intelligence = (V.SCP.schoolUpgrade === 1 ? -70 : random(-50, 50));
-				slave.devotion = slave.trust = (V.SCP.schoolUpgrade === 1 ? 20 : random(25, 45));
-				if (V.SCP.schoolUpgrade !== 1) {
-					slave.teeth = "normal";
-				}
-				setHealth(slave, 100, 0, 0, 0);
-				slave.heightImplant = 1;
-				slave.height += 10;
-				slave.buttImplant = (4-slave.butt);
-				slave.butt += slave.buttImplant;
-				slave.boobsImplantType = "normal";
-				slave.boobsImplant = (2000-slave.boobs);
-				slave.boobs += slave.boobsImplant;
-				slave.boobsImplantType = "fillable";
-				slave.nipples = "tiny";
-				slave.areolae = 0;
-				slave.clit = 0;
-				slave.lipsImplant = (75-slave.lips);
-				slave.lips += slave.lipsImplant;
-				slave.faceImplant = 35;
-				slave.face = random(35, 80);
-				slave.anus = 0;
-				slave.vagina = 0;
-				slave.preg = 0;
-				slave.weight = -20;
-				slave.skill.vaginal = (V.SCP.schoolUpgrade === 2 ? 15 : 0);
-				slave.skill.oral = (V.SCP.schoolUpgrade === 2 ? 15 : 0);
-				slave.skill.anal = (V.SCP.schoolUpgrade === 2 ? 15 : 0);
-				slave.skill.whoring = (V.SCP.schoolUpgrade === 2 ? 15 : 0);
-				slave.skill.entertainment = (V.SCP.schoolUpgrade === 2 ? 15 : 0);
-				slave.skill.combat = 0;
-				slave.pubicHStyle = "waxed";
-				slave.underArmHStyle = "waxed";
-				slave.actualAge = 19;
-				slave.visualAge = slave.actualAge;
-				slave.physicalAge = slave.actualAge;
-				slave.ovaryAge = slave.actualAge;
-				slave.sexualFlaw = either("none");
-				slave.behavioralFlaw = either("none");
-				slave.hStyle = "tails";
-				slave.hColor = "blonde";
-				slave.pubicHColor = "blonde";
-				slave.underArmHColor = "blonde";
-				slave.race = "white";
-				slave.skin = "sun tanned";
-				slave.override_H_Color = 1;
-				slave.override_Arm_H_Color = 1;
-				slave.override_Pubic_H_Color = 1;
-				slave.override_Race = 1;
-				slave.override_Skin = 1;
-				slave.custom.tattoo = "$He has the coat of arms of St. Claver Preparatory tattooed on $his left cheek.";
 				slaveArray.push(slave);
 			}
 		} else if (failedSchool === "LDE") {
 			for (let i = 0; i < slavesToAdd; i++) {
-				const slave = GenerateNewSlave("XY", {disableDisability: 1});
+				const {slave} = generateMarketSlave("LDE");
 				slave.origin = "$He was given to you by a failed branch campus of the innovative École des Enculées right after $his graduation.";
-				slave.career = "a slave";
-				slave.intelligenceImplant = 0;
-				slave.chem = 100;
-				slave.devotion = (V.LDE.schoolUpgrade === 1 ? 20 : random(60, 70));
-				slave.trust = (V.LDE.schoolUpgrade === 1 ? 20 : random(55, 60));
-				setHealth(slave, jsRandom(60, 80), 0, 0, 0);
-				slave.muscles = 0;
 				if (random(1, 100) > 75) {
 					slave.geneticQuirks.rearLipedema = 2;
 					slave.butt = random(6, 16);
-				} else {
-					slave.butt = random(4, 5);
-				}
-				slave.face = random(20, 60);
-				slave.boobs = either(500, 650, 800);
-				slave.waist = -15;
-				slave.lips = 35;
-				slave.balls = (V.LDE.schoolUpgrade === 2 ? either(3, 4) : either(1, 1, 1, 2));
-				slave.dick = (V.LDE.schoolUpgrade === 2 ? either(3, 4) : either(1, 1, 1, 2));
-				if (slave.foreskin > 0) {
-					slave.foreskin = slave.dick;
-				}
-				if (slave.balls > 0) {
-					slave.scrotum = slave.balls;
 				}
-				slave.anus = 2;
-				slave.vagina = -1;
-				slave.preg = 0;
-				slave.weight = random(0, 20);
-				slave.skill.vaginal = 0;
-				slave.skill.oral = 15;
-				slave.skill.anal = 100;
-				slave.skill.whoring = 15;
-				slave.skill.entertainment = 15;
-				slave.skill.combat = 0;
-				slave.pubicHStyle = "waxed";
-				slave.underArmHStyle = "waxed";
-				slave.actualAge = 19;
-				slave.visualAge = slave.actualAge;
-				slave.physicalAge = slave.actualAge;
-				slave.ovaryAge = slave.actualAge;
-				slave.sexualFlaw = "none";
-				slave.behavioralFlaw = either("none", "odd");
-				slave.fetishStrength = either(1, 2);
-				slave.fetish = "buttslut";
-				slave.fetishKnown = 1;
-				slave.attrKnown = 1;
-				slave.hStyle = "tails";
-				slave.hLength = 100;
-				slave.custom.tattoo = "$He has the buttock-shaped symbol of the École des Enculées that created $his tattooed on $his left cheek.";
 				slaveArray.push(slave);
 			}
 		} else if (failedSchool === "NUL") {
 			for (let i = 0; i < slavesToAdd; i++) {
-				const slave = GenerateNewSlave(null, {minAge: 16, maxAge: 24, disableDisability: 1});
+				const {slave} = generateMarketSlave("NUL");
 				slave.origin = "$He was given to you by a failed branch campus of Nueva Universidad de Libertad right after $his graduation.";
-				slave.career = "a slave";
-				setHealth(slave, jsRandom(60, 80), 0, 0, 0);
-				slave.devotion = random(60, 75);
-				slave.trust = random(60, 75);
-				slave.intelligenceImplant = 30;
-				slave.intelligence = (V.NUL.schoolUpgrade === 1 ? random(50, 70) : random(20, 50));
-				slave.skill.whoring = (V.NUL.schoolUpgrade === 1 ? random(70, 80) : random(40, 50));
-				slave.skill.entertainment = (V.NUL.schoolUpgrade === 1 ? random(70, 80) : random(40, 50));
-				slave.skill.anal = (V.NUL.schoolUpgrade === 2 ? random(60, 80) : random(10, 30));
-				slave.skill.oral = (V.NUL.schoolUpgrade === 2 ? random(70, 90) : random(20, 40));
-				slave.anus = (V.NUL.schoolUpgrade === 2 ? random(1, 3) : either(0, 0, 0, 0, 1, 1, 1));
-				slave.muscles = 0;
-				slave.face = random(15, 55);
-				slave.faceShape = "androgynous";
-				slave.boobs = 50;
-				slave.butt = 0;
-				slave.vagina = -1;
-				slave.clit = 0;
-				slave.dick = 0;
-				slave.balls = 0;
-				slave.preg = 0;
-				slave.eyebrowHStyle = "bald";
-				slave.underArmHStyle = "bald";
-				slave.pubicHStyle = "bald";
-				slave.hStyle = "bald";
-				slave.custom.tattoo = "$He has the abstract symbol of Nueva Universidad de Libertad tattooed on $his left shoulder.";
 				slaveArray.push(slave);
 			}
 		} else if (failedSchool === "TGA") {
 			for (let i = 0; i < slavesToAdd; i++) {
-				const slave = GenerateNewSlave("XY", {disableDisability: 1});
+				const {slave} = generateMarketSlave("TGA");
 				slave.origin = "$He was given to you by a failed branch campus of the intense Gymnasium-Academy right after $his majority.";
-				slave.career = "a slave";
-				slave.intelligenceImplant = 15;
-				slave.teeth = "normal";
-				slave.intelligence = random(-50, 95);
-				slave.chem = 20;
-				slave.devotion = (V.TGA.schoolUpgrade === 1 ? 20 : random(25, 45));
-				slave.trust = (V.TGA.schoolUpgrade === 1 ? 20 : random(25, 45));
-				setHealth(slave, 100, 0, 0, 0);
-				slave.muscles = either(20, 50, 50);
-				slave.butt = either(2, 2, 3);
-				slave.boobs = either(100, 200);
-				slave.dick = random(3, 5);
-				if (slave.foreskin > 0) {
-					slave.foreskin = slave.dick;
-				}
-				if (slave.balls > 0) {
-					slave.scrotum = slave.balls;
-				}
-				slave.balls = random(3, 5);
-				slave.anus = 0;
-				slave.vagina = -1;
-				slave.preg = 0;
-				slave.weight = 0;
-				slave.skill.vaginal = 0;
-				slave.skill.oral = 0;
-				slave.skill.anal = 0;
-				slave.skill.whoring = 0;
-				slave.skill.entertainment = 0;
-				slave.skill.combat = (V.TGA.schoolUpgrade === 2 ? 1 : 0);
-				slave.pubicHStyle = "waxed";
-				slave.underArmHStyle = "waxed";
-				slave.actualAge = 18;
-				slave.visualAge = slave.actualAge;
-				slave.physicalAge = slave.actualAge;
-				slave.ovaryAge = slave.actualAge;
-				slave.sexualFlaw = either("apathetic", "none");
-				slave.behavioralFlaw = either("arrogant", "none", "odd");
-				slave.hStyle = "neat";
-				slave.hLength = 2;
-				slave.brand["left cheek"] = "the baroque crest of the Gymnasium-Academy that trained $him";
 				slaveArray.push(slave);
 			}
 		} else if (failedSchool === "HA") {
 			for (let i = 0; i < slavesToAdd; i++) {
-				const slave = GenerateNewSlave("XX", {disableDisability: 1});
-				slave.origin = "$He was given to you by a failed branch campus of the Hippolyta Academy right after $his majority.";
-				slave.career = "a slave";
-				slave.intelligenceImplant = 15;
-				slave.teeth = "normal";
-				slave.intelligence = random(0, 95);
-				slave.chem = 20;
-				slave.devotion = (V.HA.schoolUpgrade === 1 ? 20 : random(25, 45));
-				slave.trust = (V.HA.schoolUpgrade === 1 ? 20 : random(25, 45));
-				slave.faceShape = either("cute", "normal");
-				slave.face = either(20, 20, 35, 35, 35, 50, 75, 100);
-				slave.lips = either(0, 10, 25);
-				slave.weight = -10;
-				setHealth(slave, jsRandom(80, 100), 0, 0, 0);
-				slave.actualAge = 18;
-				slave.physicalAge = slave.actualAge;
-				slave.visualAge = slave.actualAge;
-				slave.ovaryAge = slave.actualAge;
-				slave.hips = 0;
-				slave.vagina = random(0, 1);
-				slave.anus = random(0, 1);
-				slave.butt = random(2, 4);
-				slave.boobs = (random(30, 60) * 10);
-				slave.preg = 0;
-				SetBellySize(slave);
-				setHealth(slave, jsRandom(60, 80), 0, 0, 0);
-				slave.muscles = random(40, 60);
-				const minHeight = random(170, 180);
-				slave.height = Math.clamp(Height.random(slave, {limitMult: [2, 15], spread: .1}), minHeight, 274);
-				slave.waist = -15;
-				slave.shoulders = 0;
-				slave.skill.vaginal = 10;
-				slave.skill.oral = 10;
-				slave.skill.anal = 10;
-				slave.skill.whoring = 10;
-				slave.skill.entertainment = either(10, 10, 30);
-				slave.skill.combat = 1;
-				slave.sexualFlaw = either("apathetic", "judgemental", "none", "none");
-				slave.behavioralFlaw = either("arrogant", "none");
-				slave.pubicHStyle = "waxed";
-				slave.underArmHStyle = "waxed";
-				slave.hStyle = either("braided", "bun", "neat", "ponytail", "tails");
-				slave.hLength = random(5, 50);
-				slave.custom.tattoo = "$He has the sword and eagle symbol of the Hippolyta Academy tattooed on $his left shoulder.";
+				const {slave} = generateMarketSlave("HA");
+				slave.origin = "$He was given to you by a failed branch campus of the Hippolyta Academy.";
 				slaveArray.push(slave);
 			}
 		} else if (failedSchool === "TFS") {
+			// normal slaves
 			for (let i = 0; i < slavesToAdd-1; i++) {
-				const slaveGenRange = random(1, 4);
-				let slave;
-				if (V.TFS.schoolUpgrade === 3 && V.TFS.compromiseWeek+15 <= V.week) {
-					slave = GenerateNewSlave(null, {disableDisability: 1});
-				} else {
-					slave = GenerateNewSlave("XY", {disableDisability: 1});
-				}
+				const {slave} = generateMarketSlave("TFS");
 				slave.origin = "$He was a Futanari Sister until you engineered $his early enslavement.";
-				slave.career = "a Futanari Sister";
-				slave.faceShape = either("exotic", "sensual");
-				if (slaveGenRange === 1) {
-					slave.intelligence = random(-50, -20);
-					slave.chem = 150;
-					slave.butt = either(5, 6);
-					slave.hips = 1;
-					slave.face = either(35, 35, 35, 75, 100);
-					slave.boobs = 100*random(12, 20);
-					slave.dick = random(2, 3);
-					if (V.TFS.schoolUpgrade === 3 && V.TFS.compromiseWeek+15 <= V.week) {
-						if (slave.genes === "XY") {
-							slave.balls = slave.scrotum = random(8, 9);
-						} else {
-							slave.balls = 1;
-							slave.scrotum = 0;
-						}
-					} else if (V.TFS.schoolUpgrade === 1) {
-						slave.balls = 1;
-						slave.scrotum = 0;
-					} else if (V.TFS.schoolUpgrade === 2) {
-						slave.balls = slave.scrotum = random(8, 9);
-					} else {
-						slave.balls = slave.scrotum = random(2, 3);
-					}
-					slave.lips = 0;
-					slave.weight = 0;
-					slave.actualAge = random(25, 29);
-					slave.visualAge = slave.actualAge;
-					slave.physicalAge = slave.actualAge;
-					slave.ovaryAge = slave.actualAge;
-					slave.vagina = 2;
-					slave.anus = 2;
-					slave.fetish = "submissive";
-				} else if (slaveGenRange === 2) {
-					slave.intelligence = random(-15, 15);
-					slave.chem = 200;
-					slave.butt = either(6, 7);
-					slave.hips = 2;
-					slave.face = either(35, 35, 75, 75, 100);
-					slave.boobs = 100*random(20, 32);
-					slave.dick = random(3, 4);
-					if (V.TFS.schoolUpgrade === 3 && V.TFS.compromiseWeek+15 <= V.week) {
-						if (slave.genes === "XY") {
-							slave.balls = slave.scrotum = random(9, 10);
-						} else {
-							slave.balls = 1;
-							slave.scrotum = 0;
-						}
-					} else if (V.TFS.schoolUpgrade === 1) {
-						slave.balls = 1;
-						slave.scrotum = 0;
-					} else {
-						slave.balls = slave.scrotum = (V.TFS.schoolUpgrade === 2 ? random(9, 10) : random(3, 4));
-					}
-					slave.lips = random(15, 25);
-					slave.weight = 20;
-					slave.actualAge = random(30, 34);
-					slave.visualAge = slave.actualAge;
-					slave.physicalAge = slave.actualAge;
-					slave.ovaryAge = slave.actualAge;
-					slave.vagina = 2;
-					slave.anus = 2;
-					slave.fetish = either("buttslut", "cumslut");
-				} else if (slaveGenRange === 3) {
-					slave.intelligence = random(16, 50);
-					slave.chem = 250;
-					slave.butt = either(7, 8);
-					slave.hips = 2;
-					slave.face = either(35, 75, 75, 100, 100);
-					slave.boobs = 100*random(32, 42);
-					slave.dick = random(4, 5);
-					if (V.TFS.schoolUpgrade === 3 && V.TFS.compromiseWeek+15 <= V.week) {
-						if (slave.genes === "XY") {
-							slave.balls = slave.scrotum = random(6, 7);
-						} else {
-							slave.balls = 1;
-							slave.scrotum = 0;
-						}
-					} else if (V.TFS.schoolUpgrade === 1) {
-						slave.balls = 1;
-						slave.scrotum = 0;
-					} else {
-						slave.balls = slave.scrotum = (V.TFS.schoolUpgrade === 2 ? random(6, 7) : random(4, 5));
-					}
-					slave.lips = random(25, 55);
-					slave.weight = 20;
-					slave.actualAge = random(35, 39);
-					slave.visualAge = slave.actualAge;
-					slave.physicalAge = slave.actualAge;
-					slave.ovaryAge = slave.actualAge;
-					slave.vagina = 3;
-					slave.anus = 3;
-					slave.fetish = either("buttslut", "cumslut");
-				} else {
-					slave.intelligence = random(51, 95);
-					slave.chem = 300;
-					slave.butt = either(8, 9);
-					slave.hips = 2;
-					slave.face = either(35, 75, 100, 100, 100);
-					slave.boobs = 100*random(44, 60);
-					slave.dick = random(5, 6);
-					slave.geneticQuirks.wellHung = 2;
-					if (V.TFS.schoolUpgrade === 3 && V.TFS.compromiseWeek+15 <= V.week) {
-						if (slave.genes === "XY") {
-							slave.balls = random(7, 8);
-							slave.scrotum = slave.balls;
-						} else {
-							slave.balls = 1;
-							slave.scrotum = 0;
-						}
-					} else if (V.TFS.schoolUpgrade === 1) {
-						slave.balls = 1;
-						slave.scrotum = 0;
-					} else {
-						slave.balls = slave.scrotum = (V.TFS.schoolUpgrade === 2 ? random(7, 8) : random(5, 6));
-					}
-					slave.lips = random(25, 55);
-					slave.weight = 50;
-					slave.actualAge = random(40, 42);
-					slave.visualAge = slave.actualAge;
-					slave.physicalAge = slave.actualAge;
-					slave.ovaryAge = slave.actualAge;
-					slave.vagina = 3;
-					slave.anus = 3;
-					slave.fetish = "dom";
-				}
-				if (slave.foreskin > 0) {
-					slave.foreskin = slave.dick;
-				}
-				slave.preg = -3;
-				if (V.TFS.farmUpgrade > 0) {
-					slave.ovaries = 1;
-					if (V.TFS.farmUpgrade >= 2) {
-						slave.preg = random(1, 41);
-						if (V.TFS.farmUpgrade === 3) {
-							slave.pregType = random(10, 30);
-							slave.pregAdaptation = 300;
-						} else {
-							slave.pregType = 1;
-						}
-						slave.pregSource = -9;
-						slave.pregKnown = 1;
-						slave.pregWeek = slave.preg;
-						SetBellySize(slave);
-					}
-				}
-				slave.intelligenceImplant = 30;
-				slave.teeth = "normal";
-				slave.energy = (V.TFS.schoolUpgrade === 2 ? 100 : slave.physicalAge + random(20, 30));
-				slave.devotion = random(30, 35);
-				slave.trust = random(-15, -5);
-				setHealth(slave, jsRandom(60, 80), 0, 0, 0);
-				slave.muscles = 20;
-				slave.waist = -15;
-				if (slave.genes === "XY") {
-					slave.shoulders = 1;
-				}
-				slave.skill.vaginal = 100;
-				slave.skill.oral = 100;
-				slave.skill.anal = 100;
-				slave.skill.whoring = 15;
-				slave.skill.entertainment = 100;
-				slave.skill.combat = 0;
-				slave.pubicHStyle = "waxed";
-				slave.underArmHStyle = "waxed";
-				if (V.TFS.schoolUpgrade === 1) {
-					slave.sexualQuirk = "caring";
-				}
-				slave.sexualFlaw = either("judgemental", "none");
-				slave.behavioralFlaw = either("arrogant", "none");
-				slave.fetishStrength = 100;
-				slave.fetishKnown = 0;
-				slave.attrKnown = 0;
-				slave.hStyle = "neat";
-				slave.hLength = 150;
-				slave.custom.tattoo = "$He has a simple pink heart tattooed on $his right temple.";
 				slaveArray.push(slave);
 			}
-			const slave = GenerateNewSlave("XY", {disableDisability: 1});
+			// Matron
+			const SGProp = new GenerateNewSlavePram();
+			SGProp.disableDisability = 1;
+			SGProp.minAge = 40;
+			SGProp.maxAge = 42;
+			const slave = GenerateNewSlave("XY", SGProp);
 			slave.origin = "$He was the leader of your arcology's Futanari Sisters until you engineered $his community's failure and enslavement.";
 			slave.career = "a Futanari Sister";
 			slave.intelligence = random(51, 95);
@@ -633,7 +127,7 @@ App.Events.RESFailure = class RESFailure extends App.Events.BaseEvent {
 			slave.butt = either(8, 9);
 			slave.hips = 2;
 			slave.face = 100;
-			slave.boobs = 100*random(44, 60);
+			slave.boobs = 100 * random(44, 60);
 			slave.dick = random(5, 6);
 			if (slave.foreskin > 0) {
 				slave.foreskin = slave.dick;
@@ -641,21 +135,17 @@ App.Events.RESFailure = class RESFailure extends App.Events.BaseEvent {
 			if (V.TFS.schoolUpgrade === 3 && V.TFS.compromiseWeek+15 <= V.week) {
 				slave.balls = slave.scrotum = 10;
 			} else {
-				slave.balls = slave.scrotum = (V.TFS.schoolUpgrade === 1 ? 1 :10);
 				slave.balls = slave.scrotum = (V.TFS.schoolUpgrade === 1 ? 0 : random(5, 6));
 			}
 			slave.lips = random(25, 55);
 			slave.weight = 50;
-			slave.actualAge = random(40, 42);
-			slave.visualAge = slave.actualAge;
-			slave.physicalAge = slave.actualAge;
-			slave.ovaryAge = slave.actualAge;
 			slave.vagina = 3;
 			slave.anus = 3;
 			slave.fetish = "dom";
 			slave.preg = -3;
 			if (V.TFS.farmUpgrade > 0) {
 				slave.ovaries = 1;
+				slave.preg = -1
 				if (V.TFS.farmUpgrade >= 2) {
 					slave.preg = random(1, 41);
 					if (V.TFS.farmUpgrade === 3) {
@@ -729,7 +219,7 @@ App.Events.RESFailure = class RESFailure extends App.Events.BaseEvent {
 			App.Events.addParagraph(node, r);
 			r = [];
 			App.Events.addResponses(node, [
-				new App.Events.Result(`Rape ${him}`, TFSRape, `This will cost ${cashFormat(10000)}`)
+				new App.Events.Result(`Rape ${him}`, TFSRape)
 			]);
 		} else {
 			r.push(`You receive a personal call from a senior representative of ${SCH.title} as you've been expecting since their second missed rent payment. "I apologize," ${he2} says with some embarrassment, "but it seems our expansion into your arcology was a mistake. It's strange — the business climate seemed excellent, and other corporations are doing well."`);
@@ -776,13 +266,12 @@ App.Events.RESFailure = class RESFailure extends App.Events.BaseEvent {
 		function TFSRape() {
 			const frag = new DocumentFragment();
 			let r = [];
-			for (const slave of V.slaves) {
-				if (slave.origin === "$He was the leader of your arcology's Futanari Sisters until you engineered $his community's failure and enslavement.") {
-					slave.devotion += 10;
-					actX(slave, "anal");
-					actX(slave, "vaginal");
-				}
-			}
+			const isMatron = (s) => (s.origin === "$He was the leader of your arcology's Futanari Sisters until you engineered $his community's failure and enslavement.") && (s.newGamePlus !== 1);
+			// player can choose "Rape her" before or after the other choices...if she's not been enslaved yet, alter her template instead
+			const matron = V.slaves.find(isMatron) || slaveArray.find(isMatron);
+			matron.devotion += 10;
+			seX(matron, "anal", V.PC, "penetrative");
+			seX(matron, "vaginal", V.PC, "penetrative");
 			r.push(`You`);
 			if (V.PC.dick !== 0) {
 				r.push(`whip out your dick`);
diff --git a/src/facilities/ads.js b/src/facilities/ads.js
index f120aaabfa0b8f05417be78dda40f506560ac563..9e7134cab6242ccea138884a90d1621d337ee04d 100644
--- a/src/facilities/ads.js
+++ b/src/facilities/ads.js
@@ -791,7 +791,6 @@ App.Ads.report = function(building, preview = false) {
 					App.UI.DOM.makeElement("span", `both`, (building === "brothel") ? "yellowgreen" : "green"),
 					`all-natural girls, and slaves whose beauty has been improved by surgical means.`
 				);
-				t.push();
 			}
 			t.push(`Most customers don't have preferences for either all-natural or surgically enhanced and implanted girls.`);
 		}
diff --git a/src/facilities/arcade/arcade.js b/src/facilities/arcade/arcade.js
index 7d55e6b22f9c58813cbd87948b578bd4ed9445f0..c559c2327e9760c250ce85690525cddd5a31f23f 100644
--- a/src/facilities/arcade/arcade.js
+++ b/src/facilities/arcade/arcade.js
@@ -110,7 +110,10 @@ App.Facilities.Arcade.arcade = class Arcade extends App.Facilities.Facility {
 
 							App.UI.reload();
 						},
-						note: `, increases upkeep costs, and is mutually exclusive with the collectors`,
+						notes: [
+							`increases upkeep costs`,
+							`is mutually exclusive with the collectors`,
+						],
 						prereqs: [
 							() => V.arcadeUpgradeCollectors < 1,
 						],
@@ -145,7 +148,10 @@ App.Facilities.Arcade.arcade = class Arcade extends App.Facilities.Facility {
 
 							App.UI.reload();
 						},
-						note: `, increases upkeep costs, and is mutually exclusive with the injectors`,
+						notes: [
+							`increases upkeep costs`,
+							`is mutually exclusive with the injectors`,
+						],
 						prereqs: [
 							() => V.arcadeUpgradeInjectors < 1,
 						],
@@ -170,7 +176,7 @@ App.Facilities.Arcade.arcade = class Arcade extends App.Facilities.Facility {
 
 							App.UI.reload();
 						},
-						note: ` and will increase upkeep costs`,
+						notes: [`will increase upkeep costs`],
 					},
 				],
 			},
@@ -188,7 +194,7 @@ App.Facilities.Arcade.arcade = class Arcade extends App.Facilities.Facility {
 
 							App.UI.reload();
 						},
-						note: ` and will increase upkeep costs`,
+						notes: [`will increase upkeep costs`],
 					},
 				],
 			},
diff --git a/src/facilities/bodyModification/bodyModification.js b/src/facilities/bodyModification/bodyModification.js
index f8a0da946c7669bedbe1eba272bf68bec40b41c9..fdb834a2affdd991c90046709c695a4b03512cb5 100644
--- a/src/facilities/bodyModification/bodyModification.js
+++ b/src/facilities/bodyModification/bodyModification.js
@@ -96,7 +96,7 @@ App.UI.bodyModification = function(slave, cheat = false) {
 					r.push(`No matter how you chose to apply it, scarring so much of ${his} body has <span class="health dec"> hurt ${his} health.</span>`);
 					healthDamage(slave, 20);
 				} else {
-					if (slave.scar[V.scarTarget.local][V.scarDesign.local] > 0) {
+					if (App.Medicine.Modification.scarRecord(slave)[V.scarTarget.local][V.scarDesign.local] > 0) {
 						r.push(`This is not the first time ${he} was scarred like this.`);
 					}
 					switch (V.scarDesign.local) {
@@ -844,15 +844,15 @@ App.UI.bodyModification = function(slave, cheat = false) {
 		let r = [];
 		const bodyPartData = App.Data.Slave.body.get(V.scarTarget.local);
 
-		for (const scarName in slave.scar) {
+		for (const scarLocation in App.Medicine.Modification.scarRecord(slave)) {
 			const scarDiv = document.createElement("div");
-			scarDiv.append(`${His} ${scarName} is marked with ${App.Desc.expandScarString(slave, scarName)}: `);
+			scarDiv.append(`${His} ${scarLocation} is marked with ${App.Desc.expandScarString(slave, scarLocation)}: `);
 			scarDiv.append(
 				App.UI.DOM.link(
 					"Remove Scar",
 					() => {
 						scarApplied = false;
-						delete slave.scar[scarName];
+						App.Medicine.Modification.removeAllScars(slave, scarLocation);
 						billSurgery();
 						degradation -= 10;
 						refresh();
@@ -874,12 +874,12 @@ App.UI.bodyModification = function(slave, cheat = false) {
 		} else if (bodyPartData && bodyPartData.isPair) {
 			r.push(`Choose a side to scar.`);
 		} else {
-			if (slave.scar.hasOwnProperty(V.scarTarget.local)) {
-				if (slave.scar[V.scarTarget.local][V.scarDesign.local]) {
+			if (App.Medicine.Modification.scarRecord(slave).hasOwnProperty(V.scarTarget.local)) {
+				if (App.Medicine.Modification.scarRecord(slave)[V.scarTarget.local][V.scarDesign.local]) {
 					r.push(`${He} already has ${V.scarDesign.local} scars on ${his} ${V.scarTarget.local}. You can make it worse.`);
 				} else {
 					// check how much scarring is on this part
-					const scarTotalValue = (Object.values(slave.scar[V.scarTarget.local])).reduce((a, b) => a + b, 0);
+					const scarTotalValue = (Object.values(App.Medicine.Modification.scarRecord(slave)[V.scarTarget.local])).reduce((a, b) => a + b, 0);
 					if (scarTotalValue) {
 						r.push(`That would be a new kind of scar to add to the growing collection on ${his} ${V.scarTarget.local}. Life can always be worse for a slave.`);
 					}
@@ -896,19 +896,8 @@ App.UI.bodyModification = function(slave, cheat = false) {
 						} else {
 							// Normal entire body scarring
 							if (V.scarTarget.local === "entire body") {
-								scarArray = ["left breast", "right breast", "back", "lower back", "left buttock", "right buttock"];
-								if (getLeftArmID(slave) === 0) {
-									scarArray.push("left upper arm");
-								}
-								if (getRightArmID(slave) === 0) {
-									scarArray.push("right upper arm");
-								}
-								if (getLeftLegID(slave) === 0) {
-									scarArray.push("left thigh");
-								}
-								if (getRightLegID(slave) === 0) {
-									scarArray.push("right thigh");
-								}
+								scarArray = ["left breast", "right breast", "back", "lower back", "left buttock",
+									"right buttock", "left upper arm", "right upper arm", "left thigh", "right thigh"];
 							} else { // Single scar
 								scarArray = [V.scarTarget.local];
 							}
@@ -924,7 +913,7 @@ App.UI.bodyModification = function(slave, cheat = false) {
 					}
 				)
 			);
-			r.push(`with ${V.scarDesign.local} on the ${V.scarTarget.local}${(slave.scar[V.scarTarget.local]) ? `, adding to the scars that are already there?` : `.`}`);
+			r.push(`with ${V.scarDesign.local} on the ${V.scarTarget.local}${(App.Medicine.Modification.scarRecord(slave)[V.scarTarget.local]) ? `, adding to the scars that are already there?` : `.`}`);
 		}
 		App.Events.addNode(el, r, "div");
 
@@ -939,10 +928,11 @@ App.UI.bodyModification = function(slave, cheat = false) {
 
 		App.UI.DOM.appendNewElement("h2", el, "Branding");
 
-		for (const brandPlace in slave.brand) {
+		const brands = App.Medicine.Modification.brandRecord(slave);
+		for (const brandPlace in brands) {
 			div = document.createElement('div');
-			div.append(`${His} ${brandPlace} is marked with ${slave.brand[brandPlace]}`);
-			if (slave.brand[brandPlace] === V.brandDesign.official) {
+			div.append(`${His} ${brandPlace} is marked with ${brands[brandPlace]}`);
+			if (brands[brandPlace] === V.brandDesign.official) {
 				div.append(`, your `);
 				div.append(App.UI.DOM.passageLink("official brand", "Universal Rules"));
 			}
@@ -956,7 +946,7 @@ App.UI.bodyModification = function(slave, cheat = false) {
 							billSurgery();
 							degradation -= 10;
 						}
-						delete slave.brand[brandPlace];
+						App.Medicine.Modification.removeBrand(slave, brandPlace);
 						refresh();
 					},
 				)
@@ -964,15 +954,15 @@ App.UI.bodyModification = function(slave, cheat = false) {
 			p.append(div);
 		}
 
-		if (jQuery.isEmptyObject(slave.brand)) {
+		if (jQuery.isEmptyObject(brands)) {
 			App.UI.DOM.appendNewElement("div", p, `${His} skin is unmarked.`);
 		}
 
-		if (!(Object.values(slave.brand).includes(V.brandDesign.official)) && !cheat) {
+		if (!(Object.values(brands).includes(V.brandDesign.official)) && !cheat) {
 			div = document.createElement('div');
 			div.append(`${He} lacks your `);
 			div.append(App.UI.DOM.passageLink("official brand", "Universal Rules"));
-			div.append(`, "${V.brandDesign.official}."`);
+			div.append(`, ${V.brandDesign.official}.`);
 			p.append(div);
 		}
 
@@ -982,7 +972,7 @@ App.UI.bodyModification = function(slave, cheat = false) {
 		p = document.createElement('p');
 
 
-		if (slave.brand[V.brandTarget.local] === V.brandDesign.local) {
+		if (brands[V.brandTarget.local] === V.brandDesign.local) {
 			p.append(`${He} already has ${V.brandDesign.local} on ${his} ${V.brandTarget.local}.`);
 		} else if (bodyPartData && bodyPartData.isPair) {
 			p.append(`Choose a side to brand.`);
@@ -996,14 +986,14 @@ App.UI.bodyModification = function(slave, cheat = false) {
 							billMod();
 							degradation += 10;
 						}
-						slave.brand[V.brandTarget.local] = V.brandDesign.local;
+						App.Medicine.Modification.addBrand(slave, V.brandTarget.local, V.brandDesign.local);
 						refresh();
 					},
 				)
 			);
 			p.append(` with ${V.brandDesign.local} on the ${V.brandTarget.local}`);
-			if (slave.brand[V.brandTarget.local]) {
-				p.append(`, covering the "${slave.brand[V.brandTarget.local]}" that is already there? `);
+			if (brands[V.brandTarget.local]) {
+				p.append(`, covering the "${brands[V.brandTarget.local]}" that is already there? `);
 			} else {
 				p.append(`. `);
 			}
@@ -1162,7 +1152,7 @@ App.UI.scarSelect = function(category, slave, cheat = false) {
 		"surgical",
 		"menacing",
 		"exotic"
-	]); // Other common scars might be battle scars or c-Section but it makes little sense to include them here
+	]); // Other common scars might be battle scars or c-Section, but it makes little sense to include them here
 	let linkArray = [];
 	for (const scarType of scarTypes) {
 		linkArray.push(
diff --git a/src/facilities/brothel/brothel.js b/src/facilities/brothel/brothel.js
index edd77423508ef2a2af287bb9d80186e663c5d481..f1807bb98c678ade01573a225701205239d9d6e4 100644
--- a/src/facilities/brothel/brothel.js
+++ b/src/facilities/brothel/brothel.js
@@ -194,7 +194,7 @@ App.Facilities.Brothel.brothel = class Brothel extends App.Facilities.Facility {
 						link: `Upgrade the brothel with aphrodisiac injection systems`,
 						cost: 10000 * V.upgradeMultiplierArcology * V.HackingSkillMultiplier,
 						handler: () => V.PC.skill.engineering += .1,
-						note: ` and will increase upkeep costs`,
+						notes: [`will increase upkeep costs`],
 					},
 					{
 						value: 0.1,
diff --git a/src/facilities/brothel/brothelFramework.js b/src/facilities/brothel/brothelFramework.js
index 394381ad87e8e52292525ef29efdf12c8f9d8d26..b50d706ae25df7d2bd508becc0b027976ab51aee 100644
--- a/src/facilities/brothel/brothelFramework.js
+++ b/src/facilities/brothel/brothelFramework.js
@@ -14,7 +14,7 @@ App.Data.Facilities.brothel = {
 		position: "madam",
 		assignment: Job.MADAM,
 		careers: App.Data.Careers.Leader.madam,
-		skill: null,
+		skill: "madam",
 		publicSexUse: true,
 		fuckdollAccepted: false,
 		broodmotherAccepted: false,
diff --git a/src/facilities/clinic/clinic.js b/src/facilities/clinic/clinic.js
index ce5ca0862d1be5a1dc12653ed5a8f6c2452a7619..ffa099a63148740ca1504f37953e1681fbaf9f5c 100644
--- a/src/facilities/clinic/clinic.js
+++ b/src/facilities/clinic/clinic.js
@@ -106,7 +106,7 @@ App.Facilities.Clinic.clinic = class Clinic extends App.Facilities.Facility {
 						link: `Upgrade the scanners to help detect genomic damage`,
 						cost: 10000 * V.upgradeMultiplierArcology * Math.min(V.upgradeMultiplierMedicine, V.HackingSkillMultiplier),
 						handler: () => V.PC.skill.hacking += 0.1,
-						note: ` and increases the effectiveness of ${V.clinicName}`,
+						notes: [`increases the effectiveness of ${V.clinicName}`],
 					},
 					{
 						value: 1,
@@ -128,7 +128,7 @@ App.Facilities.Clinic.clinic = class Clinic extends App.Facilities.Facility {
 
 							App.UI.reload();
 						},
-						note: ` and increases the effectiveness of ${V.clinicName}`,
+						notes: [`increases the effectiveness of ${V.clinicName}`],
 					},
 					{
 						value: 1,
@@ -145,7 +145,7 @@ App.Facilities.Clinic.clinic = class Clinic extends App.Facilities.Facility {
 						text: `It includes standard diagnostics equipment for common pathogens.`,
 						link: `Install an automated sequencer connected to the Gene Lab to help identify disease-causing pathogens`,
 						cost: 30000 * V.upgradeMultiplierArcology * Math.min(V.upgradeMultiplierMedicine, V.HackingSkillMultiplier),
-						note: ` and helps prevent and fight illness in large slave populations`,
+						notes: [`helps prevent and fight illness in large slave populations`],
 						prereqs: [
 							() => V.geneticMappingUpgrade > 0
 						]
@@ -169,7 +169,7 @@ App.Facilities.Clinic.clinic = class Clinic extends App.Facilities.Facility {
 						link: `Increase the effectiveness of the impurity purging`,
 						cost: 150000 * V.upgradeMultiplierArcology * Math.min(V.upgradeMultiplierMedicine, V.HackingSkillMultiplier),
 						handler: () => V.PC.skill.hacking += 0.1,
-						note: ` and may cause health problems in slaves`,
+						notes: [`may cause health problems in slaves`],
 						prereqs: [
 							() => V.clinicUpgradeFilters > 0,
 						],
@@ -181,7 +181,7 @@ App.Facilities.Clinic.clinic = class Clinic extends App.Facilities.Facility {
 						link: `Further increase the effectiveness of the impurity purging by utilizing nano magnets`,
 						cost: 300000 * V.upgradeMultiplierArcology * Math.min(V.upgradeMultiplierMedicine, V.HackingSkillMultiplier),
 						handler: () => V.PC.skill.hacking += 0.1,
-						note: ` and increases the effectiveness of ${V.clinicName}`,
+						notes: [`increases the effectiveness of ${V.clinicName}`],
 					},
 					{
 						value: 2,
diff --git a/src/facilities/club/DJSelect.js b/src/facilities/club/DJSelect.js
index 0c9709074305f1a13092b2543b5366d85db82500..87218dee727812472b72472d0dcd0539e342a823 100644
--- a/src/facilities/club/DJSelect.js
+++ b/src/facilities/club/DJSelect.js
@@ -7,7 +7,7 @@ App.Facilities.DJSelect = function() {
 	if (S.DJ) {
 		f.append(`${SlaveFullName(S.DJ)} is working as your DJ, managing entertainment in ${V.clubName}. `);
 		f.append(App.UI.DOM.link("Remove DJ", () => {
-			removeJob(S.Concubine, Job.DJ);
+			removeJob(S.DJ, Job.DJ);
 		},
 		[], "Club"
 		));
diff --git a/src/facilities/club/club.js b/src/facilities/club/club.js
index 1687f646ada61e01e965a19bb696ebe480ac361c..bccf3b33b65a38649dfa25da4342803251215ecf 100644
--- a/src/facilities/club/club.js
+++ b/src/facilities/club/club.js
@@ -274,7 +274,7 @@ App.Facilities.Club.club = class Club extends App.Facilities.Facility {
 						link: `Upgrade them with PDAs to help your recruiter`,
 						cost: 10000 * V.upgradeMultiplierArcology * V.HackingSkillMultiplier,
 						handler: () => V.PC.skill.engineering += 0.1,
-						note: ` and will increase upkeep costs`,
+						notes: [`will increase upkeep costs`],
 					},
 					{
 						value: 1,
@@ -354,7 +354,7 @@ App.Facilities.Club.club = class Club extends App.Facilities.Facility {
 		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.passageLink(`Manage club advertisements`, "Club Advertisement", () => {
 			V.nextLink = passage();
 			V.nextButton = "Back";
-		}));
+		}), ["indent"]);
 
 		return div;
 	}
diff --git a/src/facilities/dairy/dairy.js b/src/facilities/dairy/dairy.js
new file mode 100644
index 0000000000000000000000000000000000000000..9e46f7d304fa087663a58c9858cb99f139173025
--- /dev/null
+++ b/src/facilities/dairy/dairy.js
@@ -0,0 +1,805 @@
+App.Facilities.Dairy.dairy = class Dairy extends App.Facilities.Facility {
+	constructor() {
+		const dairy = App.Entity.facilities.dairy;
+		const decommissionHandler = () => {
+			V.dairy = 0;
+			V.dairyDecoration = "standard";
+			V.dairyFeedersUpgrade = 0;
+			V.dairyPregUpgrade = 0;
+			V.dairyStimulatorsUpgrade = 0;
+			V.dairyFeedersSetting = 0;
+			V.dairyPregSetting = 0;
+			V.dairyStimulatorsSetting = 0;
+			V.dairyHyperPregRemodel = 0;
+			V.dairyRestraintsUpgrade = 0;
+			V.dairyUpgradeMenials = 0;
+			V.cumPipeline = 0;
+			V.milkPipeline = 0;
+
+			App.Arcology.cellUpgrade(V.building, App.Arcology.Cell.Manufacturing, "Dairy", "Manufacturing");
+		};
+
+		super(
+			dairy,
+			decommissionHandler,
+		);
+
+		V.nextButton = "Back to Main";
+		V.nextLink = "Main";
+		V.encyclopedia = "Dairy";
+
+		if (V.dairyRestraintsSetting !== 2 || V.dairyRestraintsUpgrade !== 1) {
+			if (V.dairyStimulatorsSetting > 1) {
+				V.dairyStimulatorsSetting = 1;
+			}
+			if (V.dairyPregSetting > 1) {
+				V.dairyPregSetting = 1;
+			}
+			if (V.dairyFeedersSetting > 1) {
+				V.dairyFeedersSetting = 1;
+			}
+		}
+	}
+
+	/** @returns {string} */
+	get intro() {
+		const text = [];
+
+		text.push(`${this.facility.nameCaps} ${V.dairyRestraintsSetting > 1 ? `is an industrial facility, but there's a viewing gallery for visitors.` : ``} ${this.decorations}`);
+		if (this.facility.hostedSlaves > 2) {
+			text.push(`${this.facility.nameCaps} is working steadily.`);
+
+			if (V.dairyRestraintsUpgrade === 1 && V.dairyRestraintsSetting > 1) {
+				text.push(`Each cow is strapped into their own milking machine. The machines are set up in rows, alternating forward and backward so that the cows are interleaved as closely as possible without touching.`);
+
+				if (V.dairyFeedersUpgrade === 1 && V.dairyFeedersSetting > 0) {
+					if (V.dairyFeedersSetting === 2) {
+						text.push(`A phallic feeding tube completely fills each cow's mouth and throat, making it eerily quiet in there. Occasionally one of the cows convulses when a particularly long rush of food and drugs flows down their gullet.`);
+					} else {
+						text.push(`When feeding is required, a phallus extends into cows' mouths.`);
+					}
+				}
+				if (V.dairyStimulatorsUpgrade === 1 && V.dairyStimulatorsSetting > 0) {
+					if (V.dairyStimulatorsSetting === 2) {
+						text.push(`Every cow is being sodomized by a massive phallus. Most are pumping away gently, the strokes taking a long time to push the half-${V.showInches === 2 ? `yard` : `meter`} of shaft into each slave's rectum and pull it out again. When a slave's balls are ready to give cum, however, the pace quickens, and the agonized slave wriggles in involuntary desperation to escape until they finally stiffen, squirt, and slump in exhaustion.`);
+					} else {
+						text.push(`Each cow's anus is periodically fucked by a machine phallus that ejaculates hydration directly up their butt. When a slave's balls are ready to give cum, they are mercilessly sodomized until prostate stimulation forces an orgasm.`);
+					}
+				}
+				if (V.dairyPregUpgrade === 1 && V.dairyPregSetting > 0) {
+					const DrugPlus = V.dairyPregSetting === 3;
+					if (V.dairyPregSetting >= 2) {
+						text.push(`Fertile cows' vaginas are constantly penetrated by huge dildos that ejaculate ${DrugPlus ? 'extra strong' : ''} fertility drugs${DrugPlus ? ' into their progressively distending wombs' : ''}.`);
+						text.push(`The drugs ${DrugPlus ? 'induce intense arousal and' : 'produce'} excessive female lubrication, so the constant dildo rape fills ${this.facility.name} with occasional gushing noises${DrugPlus ? ' and nonstop moaning' : ''}.`);
+					} else {
+						text.push(`The fertile cows are visibly pregnant.`);
+					}
+				}
+			} else {
+				text.push(`The row of milking machines is available for cows to use.`);
+
+				if (V.dairyRestraintsSetting > 0) {
+					text.push(`When they do, the machines gently restrain them until they are completely done.`);
+				}
+				if (V.dairyFeedersUpgrade === 1 && V.dairyFeedersSetting > 0) {
+					text.push(`The machines mount convenient phallic feeders for slaves to suck for tasty food while they're milked.`);
+				}
+				if (V.dairyPregUpgrade === 1 && V.dairyPregSetting > 0) {
+					text.push(`The fertile cows are visibly pregnant.`);
+				}
+				if (V.dairyStimulatorsUpgrade === 1 && V.dairyStimulatorsSetting > 0) {
+					text.push(`The machines gently sodomize cows who need the extra nutrition and treatment the dildos can ejaculate into them${V.seeDicks > 0 ? `, and fuck them more vigorously when they need help ejaculating.` : ``}`);
+				}
+			}
+		} else if (V.bioreactorsXY + V.bioreactorsXX + V.bioreactorsHerm + V.bioreactorsBarren > 0) {
+			text.push(`${this.facility.nameCaps} is quiet and calm. The only sounds are faint sucking and gushing noises.`);
+		} else if (this.facility.hostedSlaves > 0) {
+			text.push(`${this.facility.nameCaps} is sparsely populated.`);
+		} else if (S.Milkmaid) {
+			text.push(`${S.Milkmaid.slaveName} is alone in ${this.facility.name}, and has nothing to do but clean and maintain the equipment.`);
+		} else {
+			text.push(`${this.facility.nameCaps} is empty and quiet.`);
+		}
+
+		return text.join(' ');
+	}
+
+	/** @returns {string} */
+	get decorations() {
+		/** @type {FC.Facilities.Decoration} */
+		let FS = null;
+
+		if (V.dairyRestraintsSetting > 1) {
+			FS = {
+				"Roman Revivalist": `The screens there review each slave's liquid contributions to the state in minute detail.`,
+				"Neo-Imperialist": `The sleek screens display a variety of statistics on each slave's vitals and production.`,
+				"Aztec Revivalist": `The strange sight of the milking machines, designed to look like fertility statues gives the space an imposing feeling.`,
+				"Egyptian Revivalist": `The screens there list a tally of each slave's contributions to the harvest this season. They also identify related slaves who occupy multi-slave milking machines so that they may feed each other directly.`,
+				"Edo Revivalist": `It looks out on a strangely contradictory sight: a beautiful and terrible combination of modern slavery and technology, placed amongst tatami mats and rice paper partitions.`,
+				"Arabian Revivalist": `It looks out on a strangely contradictory sight: a beautiful and terrible combination of modern slavery and technology, placed inside brightly tiled walls.`,
+				"Chinese Revivalist": `The milking machines are fascinating: they're encased in decorative carvings, making it look like the slaves are in the embrace of traditional Chinese depictions of lions, bears, and dragons.`,
+				"Chattel Religionist": `It presents the inmates as lessons, here to expiate their sins in a purgatory created by technology.`,
+				"Degradationist": `The screens there feature, among a sea of facts and figures about each slave, their most recent brain scan.`,
+				"Repopulationist": `The gallery is placed for a good view of each slave's swelling breasts and growing pregnancy. A screen is prominently displayed before each slave, detailing the number of babies she produced and the current number occupying their womb.`,
+				"Eugenics": `The screens there tell very little about the slaves within. That information is privy only to Society's Elite.`,
+				"Asset Expansionist": `It's designed for VIP visits, since this place is arguably the present apogee of expansionism. Nowhere else can breasts become so large. This is a place for pride.`,
+				"Transformation Fetishist": `It's designed for VIP visits, since this place is arguably the present apogee of transformationism. Nowhere else can slaves be so radically changed, from humans into something less — and something more.`,
+				"Gender Radicalist": `The gallery is placed for a good view of each slave's front, from their head to what's between their spread legs.`,
+				"Gender Fundamentalist": `The gallery is placed for a good view of each slave's breasts, belly, and cunt. Visitors can critically compare each feminine advantage.`,
+				"Physical Idealist": `The gallery is placed for a good view of each slave's body. Though muscles are at a lower premium here, there is intense interest in such radical changes to human biology.`,
+				"Supremacist": `The screens there give information about each cow, but the data they present is also predictive. They imply a vision for a world in which more subhumans serve in this way. Many more.`,
+				"Subjugationist": `The screens there give information about each cow, but the data they present is also predictive. They imply a vision for a world in which more milking machines have ${V.arcologies[0].FSSubjugationistRace} components. Many more.`,
+				"Paternalist": `The screens there include feeds that show what media is being pumped into the slaves through their machines. It's designed to provide as much mental stimulation as possible.`,
+				"Pastoralist": `The screens there let the production figures speak for themselves. There may be more personable cows out there, but they don't produce milk like these do.`,
+				"Maturity Preferentialist": `The screens there give each slave's productivity and forecast it into the future. The facility is unmatched at extracting value from mature bodies.`,
+				"Youth Preferentialist": `The screens there give each slave's productivity and forecast it into the future. The best bodies here have many, many years of productivity ahead of them.`,
+				"Body Purist": `The screens there offer reams of data on each slave's product purity. Drugs are necessary here, and each body's balance results in a different grade of product.`,
+				"Slimness Enthusiast": `The screens there alternate live views of the fashionably slim cows in their stalls with brief infomercials on the specialized techniques and equipment ${this.facility.name} uses to extract milk from such modest udders.`,
+				"Hedonistic": `The gallery is placed for a good view of each slave's fattened body and the undulations running through them from the force of the milkers${V.dairyPregSetting || V.dairyFeedersSetting || V.dairyStimulatorsSetting ? ` and other assorted tubes and dildos` : ``}.`,
+				"Intellectual Dependency": `The screens there feature an active scan showcasing each slave's diminishing brain activity.`,
+				"Slave Professionalism": `It serves as a dire warning to what happens to unskilled, moronic slaves.`,
+				"Petite Admiration": `The gallery is placed for a good view of each slave's petite body. Those that don't fit in a standard milking unit are kept well out of sight.`,
+				"Statuesque Glorification": `The gallery is placed for a good view of each slave's body. Fascinated visitors may peruse each slave's productivity statistics contrasted against their height on a corresponding touchscreen.`,
+				"standard": `Fascinated visitors may peruse each slave's productivity statistics on a corresponding touchscreen.`,
+			};
+		} else {
+			FS = {
+				"Roman Revivalist": `is functional and clean, using traditional methods wherever possible. At one end of the long row of stalls there is an alcove with a shrine to the Roman goddess of bountiful harvests.`,
+				"Neo-Imperialist": `is cold and industrial, filled with the latest in industrial harvesting technology. The slaves do their duty underneath the hanging banners of your house, reminding them who owns their very bodies and all they produce.`,
+				"Aztec Revivalist": `is sterile and organized, using traditional methods wherever possible. At one end of the long row of stalls there is an alcove with a shrine to the Aztec god of the Earth.`,
+				"Egyptian Revivalist": `is functional and clean, using traditional methods wherever possible. At one end of the long row of stalls there is an alcove with a shrine to the Egyptian god of bountiful harvests.`,
+				"Edo Revivalist": `is clean and traditional. The stalls are constructed of bamboo and carefully shaped wood, and muscle power is used wherever possible. Cows exercise and help out by walking on a wooden wheel that raises fresh water to ${this.facility.name}.`,
+				"Arabian Revivalist": `is clean and traditional. Its dusky stone walls keep it so warm that the cows go nude, basking in the hot sun between milkings.`,
+				"Chinese Revivalist": `is clean and traditional. The stalls are constructed of bamboo and carefully shaped wood, and muscle power is used wherever possible. Cows exercise and help out by fetching and carrying as best they can.`,
+				"Chattel Religionist": `is functional and clean. There are nice quotations from the holy book on the walls, and there is a little shrine designed to allow a cow who has difficulty standing to make their devotions comfortably.`,
+				"Degradationist": `is harsh and utilitarian. There are stands to restrain cows who aren't being milked for dosing, punishment, or sexual use. There are cattle prods here and there to use on resistant cows, unproductive cows, or cows one wishes to hear scream.`,
+				"Repopulationist": `is comfortable and well-kept. The milking machines are specially designed to maximize a pregnant cow's comfort. After a milking, cows have a wide selection of soft furniture to choose from, so comfortable that most fall fast asleep.`,
+				"Eugenics": `is comfortable, well-kept and well-monitored. Cows are kept track of at all times to make sure no-one tries to increase milk production via pregnancy.`,
+				"Asset Expansionist": `looks misleadingly industrial at first glance. Though the cows here are free-range, the facility mounts a system of slings and cranes to allow slaves with massive udders to walk around with their tits suspended from the ceiling.`,
+				"Transformation Fetishist": `looks like a medical facility at first glance. Transformation is just as much a priority as production: there are surgical and drug injection machines right here.`,
+				"Gender Radicalist": `is comfortable and well-kept. The milking machines include perianal vibrators to massage slaves from butthole to cock while they give cum.`,
+				"Gender Fundamentalist": `is comfortable and well-kept. The milking machines include vibrators so that cows can get off while they're milked.`,
+				"Physical Idealist": `could be mistaken for a gym with milking machines. Cows here are expected to keep fit between milkings, since the best milk comes from cattle who are healthy, muscular, and strong.`,
+				"Supremacist": `is spartan, since that's all subhuman cows need. There are cattle prods here and there to use on resistant cows, unproductive cows, or subhuman cows one wishes to hear scream.`,
+				"Subjugationist": `is spartan, since that's all ${V.arcologies[0].FSSubjugationistRace} cows need. There are cattle prods here and there to use on resistant cows, unproductive cows, or ${V.arcologies[0].FSSubjugationistRace} cows one wishes to hear scream.`,
+				"Paternalist": `is comfortable and well-kept. Rather than stalls, ${this.facility.name} has an open arrangement of machines cows can use freely, and a lovely common area they can relax in afterward.`,
+				"Pastoralist": `is state of the art, but is also brilliantly designed to look like a barn. All the advanced machinery retracts when not in use, leaving the cows in a clean, airy pastoral paradise. It smells of summer.`,
+				"Maturity Preferentialist": `is inviting and homelike. After a milking, cows have a wide selection of soft furniture to choose from, so comfortable that most fall fast asleep.`,
+				"Youth Preferentialist": `is functional, but fun. There are all sorts of fun activities to keep the cows amused between milkings, cleverly adapted for girls with massive mammaries.`,
+				"Body Purist": `is state of the art, and spotlessly clean. All attention here is on the cows, to keep them happy, productive, and pure.`,
+				"Slimness Enthusiast": `is quite unusual. Since the cows it milks may not necessarily have gigantic boobs, the milking machines here can adapt to drain cream from any body.`,
+				"Hedonistic": `is comfortable and fun. The stalls are filled with thick, soft pillows to lounge on while hooked to the milking machines and with plenty of toys to make use of while getting milked. Cows here are expected to binge eat between milkings, since the best milk comes from cattle who are immobile, stuffed with food and hugely fat.`,
+				"Intellectual Dependency": `is simple and fun. Getting situated for milking is easy enough for even the dumbest cow to figure out and there are all sorts of activities to keep the cows amused between milkings.`,
+				"Slave Professionalism": `is functional and clean. A wide selection of informative documentaries and books are available for cows to keep their minds sharp while the milker does its business.`,
+				"Petite Admiration": `is comfortable and well-kept. While designed for miniature cows, accommodations for large udders allow even the lankiest of cattle to make use of the machinery.`,
+				"Statuesque Glorification": `is comfortable and well-kept. While designed for towering cows, accommodations for large udders allow even the shortest of cattle to make use of the machinery; even if they need help to reach it.`,
+				"standard": `is comfortable and well-kept. It features nice rest areas for cows to lounge in after a milking, and exercise equipment to keep them healthy.`,
+			};
+		}
+
+		const res = FS[V.dairyDecoration];
+		if (!res) {
+			throw new Error(`Unknown V.dairyDecoration value of '${V.dairyDecoration}' found in decorations().`);
+		}
+		return res;
+	}
+
+	/** @returns {FC.Facilities.Expand} */
+	get expand() {
+		return {
+			desc: `${this.facility.nameCaps} can support ${V.dairy} milkers. There ${numberWithPluralOne(this.facility.hostedSlaves, 'is', 'are')} currently ${numberWithPluralOne(this.facility.hostedSlaves, 'cow')} being drained in ${V.dairyName}.`,
+			removeSlave: "get milked",
+		};
+	}
+
+	/** @returns {FC.IUpgrade[]}*/
+	get upgrades() {
+		return [
+			{
+				property: "dairyFeedersUpgrade",
+				tiers: [
+					{
+						value: 0,
+						upgraded: 1,
+						text: `${this.facility.nameCaps} is equipped to feed and clean slaves normally.`,
+						link: `Upgrade the milking machines with intubators`,
+						cost: 10000 * V.upgradeMultiplierArcology,
+						handler: () => V.PC.skill.engineering += 0.1,
+						notes: [`will increase upkeep costs`],
+					},
+					{
+						value: 1,
+						text: `The milking machines can hold feeders in slaves' mouths and inject drugs into their bodies, ensuring ideal nutrition and production.`,
+					}
+				],
+			},
+
+			{
+				property: "dairyPregUpgrade",
+				tiers: [
+					{
+						value: 0,
+						upgraded: 1,
+						text: `${this.facility.nameCaps} is not prepared to support cow pregnancies, and therefore cannot be used to contract out fertile slaves' wombs.`,
+						link: `Upgrade the dairy to support pregnancies`,
+						cost: 2500 * V.upgradeMultiplierArcology,
+						handler: () => V.PC.skill.engineering += 0.1,
+						notes: [`will increase upkeep costs`],
+					},
+					{
+						value: 1,
+						text: `${this.facility.nameCaps} can support cow pregnancies.`,
+					}
+				],
+			},
+			{
+				property: "dairyStimulatorsUpgrade",
+				tiers: [
+					{
+						value: 0,
+						upgraded: 1,
+						text: `${this.facility.nameCaps} does not automatically sodomize.`,
+						link: `Upgrade the cockmilking machines with sodomizers`,
+						cost: 10000 * V.upgradeMultiplierArcology,
+						handler: () => V.PC.skill.engineering += 0.1,
+						notes: [`will increase upkeep costs`],
+					},
+					{
+						value: 1,
+						text: `The milking machines mount reciprocating dildos that can sodomize the slaves, delivering extra nutrition and pharmaceuticals. ${V.seeDicks ? `The prostate stimulation also serves to increase semen production, where appropriate.` : ``}`,
+					}
+				],
+			},
+			{
+				property: "dairyPrepUpgrade",
+				tiers: [
+					{
+						value: 0,
+						upgraded: 1,
+						text: `${this.facility.nameCaps}'s industrial machines can only accept slaves with loose holes.`,
+						link: `Install a preparatory raper`,
+						cost: 5000 * V.upgradeMultiplierArcology,
+						handler: () => V.PC.skill.engineering += 0.1,
+						prereqs: [
+							() => (V.dairyPregSetting === 2 || V.dairyStimulatorsSetting === 2)
+						],
+					},
+					{
+						value: 1,
+						text: `${this.facility.nameCaps} features a preparatory raper designed to gape slaves for integration.`,
+					}
+				],
+			},
+			{
+				property: "dairyRestraintsUpgrade",
+				tiers: [
+					{
+						value: 0,
+						upgraded: 1,
+						text: `${this.facility.nameCaps} is not equipped to restrain recalcitrant cows.`,
+						link: `Equip the dairy with milking racks`,
+						cost: 5000 * V.upgradeMultiplierArcology,
+						handler: () => V.PC.skill.engineering += 0.1,
+					},
+					{
+						value: 1,
+						text: `${this.facility.nameCaps} is equipped to restrain cows.`,
+					}
+				],
+			},
+			{
+				property: "dairyHyperPregRemodel",
+				tiers: [
+					{
+						value: 0,
+						upgraded: 1,
+						text: `${this.facility.nameCaps}'s milking racks can be remodeled to hold hyper-pregnant cattle.`,
+						link: `Expand the milking racks`,
+						cost: 10000 * V.upgradeMultiplierArcology,
+						handler: () => V.PC.skill.engineering += 0.1,
+						prereqs: [
+							() => !!V.seeHyperPreg,
+							() => V.dairyRestraintsSetting === 2,
+							() => V.dairyStimulatorsSetting === 2,
+							() => V.dairyFeedersSetting === 2,
+							() => V.dairyPregSetting > 0,
+						],
+					},
+					{
+						value: 1,
+						text: `${this.facility.nameCaps}'s milking racks have been remodeled to allow cows' abnormal pregnancies room to grow.`,
+					}
+				],
+			},
+			{
+				property: "dairySlimMaintainUpgrade",
+				tiers: [
+					{
+						value: 0,
+						upgraded: 1,
+						text: `Dairy cows' breasts will expand normally as a result of the milking process.`,
+						link: `Optimize the milking process to preserve small breast sizes`,
+						cost: 5000 * V.upgradeMultiplierArcology,
+						handler: () => {
+							V.PC.skill.engineering += 0.1;
+							V.dairySlimMaintain = 1;
+						},
+						prereqs: [
+							() => V.arcologies[0].FSSlimnessEnthusiast > 80,
+						],
+					},
+					{
+						value: 0,
+						upgraded: 1,
+						text: `Dairy cows' breasts will expand normally as a result of the milking process.`,
+						link: `Optimize the milking process to preserve small breast sizes`,
+						cost: 5000 * V.upgradeMultiplierArcology,
+						handler: () => {
+							V.PC.skill.engineering += 0.1;
+							V.dairySlimMaintain = 1;
+						},
+						prereqs: [
+							() => V.arcologies[0].FSSlimnessEnthusiast > 20,
+							() => V.arcologies[0].FSSlimnessEnthusiast <= 80,
+						],
+					},
+					{
+						value: 1,
+						text: V.arcologies[0].FSSlimnessEnthusiast > 20
+							? `Thanks to advances precipitated by the arcology's commitment to the fashion of slimmer slaves, ${this.facility.name} has been updated with optimized milkers for small breasts, and a customized drug regimen to extract maximum output while maintaining fashionably small breast sizes.`
+							: `${this.facility.name} has been updated with milkers optimized for small breasts and a customized drug regimen to extract maximum output without causing excessive growth.`,
+					}
+				],
+			},
+			{
+				property: "dairyUpgradeMenials",
+				tiers: [
+					{
+						value: 0,
+						upgraded: 1,
+						text: `There is no provision for milking menial Bioreactors.`,
+						link: `Add hose hookups`,
+						cost: 5000 * V.upgradeMultiplierArcology,
+						handler: () => V.PC.skill.engineering += 0.1,
+						prereqs: [
+							() => V.arcologies[0].FSPaternalist === "unset",
+						],
+					},
+					{
+						value: 1,
+						text: V.menialBioreactors > 0
+							? `Menial Bioreactors are restrained here and there, in every unused space. Hoses run from their nipples${V.seeDicks > 0 ? ` and penises` : ``} into the machinery, and from the machinery into their mouths${V.seeDicks > 0 ? `, anuses, and the pussies beneath their pregnant bellies` : ` and anuses`}.`
+							: `In addition to the standard milking machines, ${this.facility.name} includes numerous hose hookups for menial Bioreactors. When there's space, any menial milkers you own can be placed in any empty space and connected.`,
+					}
+				],
+			},
+		];
+	}
+
+	/** @returns {FC.Facilities.Rule[]} */
+	get rules() {
+		return [
+			{
+				property: "dairyFeedersSetting",
+				prereqs: [
+					() => V.dairyFeedersUpgrade > 0,
+				],
+				options: [
+					{
+						get text() { return `The feeders have been disabled.`; },
+						link: `Deactivate`,
+						value: 0,
+						handler: App.UI.DialogHandler(() => this._getEffect("feeders")),
+					},
+					{
+						get text() { return `The feeders are active.`; },
+						link: `Moderate`,
+						value: 1,
+						handler: App.UI.DialogHandler(() => this._getEffect("feeders")),
+					},
+					{
+						get text() { return `The feeders are industrial.`; },
+						link: `Industrial`,
+						value: 2,
+						handler: App.UI.DialogHandler(() => this._getEffect("feeders")),
+						prereqs: [
+							() => V.dairyRestraintsSetting > 1,
+						],
+					},
+				],
+			},
+			{
+				property: "dairyPregSetting",
+				prereqs: [
+					() => V.dairyPregUpgrade > 0,
+				],
+				options: [
+					{
+						get text() { return `Fertile cows' wombs are not for hire.`; },
+						link: `Not for hire`,
+						value: 0,
+						handler: App.UI.DialogHandler(() => this._getEffect("preg")),
+					},
+					{
+						get text() { return `Fertile cows' wombs are for hire.`; },
+						link: `Moderate`,
+						value: 1,
+						handler: App.UI.DialogHandler(() => this._getEffect("preg")),
+					},
+					{
+						get text() { return `Fertile cows' wombs are industrially employed.`; },
+						link: `Industrial`,
+						value: 2,
+						handler: App.UI.DialogHandler(() => this._getEffect("preg")),
+						prereqs: [
+							() => V.dairyRestraintsSetting > 1,
+						],
+					},
+					{
+						get text() { return `Fertile cows' wombs are worked to capacity.`; },
+						link: `Mass production`,
+						value: 3,
+						handler: App.UI.DialogHandler(() => this._getEffect("preg")),
+						prereqs: [
+							() => V.seeExtreme > 0,
+							() => V.seeHyperPreg > 0,
+							() => V.dairyRestraintsSetting > 1,
+							() => V.dairyHyperPregRemodel === 1,
+						],
+					},
+				],
+			},
+			{
+				property: "dairyStimulatorsSetting",
+				prereqs: [
+					() => V.dairyStimulatorsUpgrade > 0,
+				],
+				options: [
+					{
+						get text() { return `The sodomizers are inactive.`; },
+						link: `Deactivate`,
+						value: 0,
+						handler: App.UI.DialogHandler(() => this._getEffect("stimulators")),
+					},
+					{
+						get text() { return `The sodomizers are active.`; },
+						link: `Moderate`,
+						value: 1,
+						handler: App.UI.DialogHandler(() => this._getEffect("stimulators")),
+					},
+					{
+						get text() { return `The sodomizers are industrial, employing dildos the size of horse phalli.`; },
+						link: `Industrial`,
+						value: 2,
+						handler: App.UI.DialogHandler(() => this._getEffect("stimulators")),
+						prereqs: [
+							() => !!V.seeExtreme,
+							() => V.dairyRestraintsSetting > 1,
+						],
+					},
+				],
+			},
+			{
+				property: "dairyRestraintsSetting",
+				prereqs: [
+					() => V.dairyFeedersUpgrade > 0,
+				],
+				options: [
+					{
+						get text() { return `The cows are restrained only when necessary, allowing obedient cows freedom to range around.`; },
+						link: `Deactivate`,
+						value: 0,
+						handler: App.UI.DialogHandler(() => this._getEffect("restraints")),
+					},
+					{
+						get text() { return `The cows are restrained when being milked, giving the machines full play.`; },
+						link: `Free range`,
+						value: 1,
+						handler: App.UI.DialogHandler(() => this._getEffect("restraints")),
+					},
+					{
+						get text() { return `The cows are restrained permanently, allowing use of industrial techniques even devoted cows would flinch at.`; },
+						link: `Permanent machine milking`,
+						value: 2,
+						handler: App.UI.DialogHandler(() => this._getEffect("restraints")),
+					},
+				],
+			},
+			{
+				property: "createBioreactors",
+				prereqs: [
+					() => V.bioreactorsAnnounced !== 0,
+					() => V.dairyRestraintsSetting === 2,
+					() => V.dairyStimulatorsSetting === 2,
+					() => V.dairyFeedersSetting === 2,
+				],
+				options: [
+					{
+						get text() { return `Perfected cows will be left as slaves.`; },
+						link: `Deactivate`,
+						value: 0,
+					},
+					{
+						get text() { return `Perfected cows will be converted into equipment, permanently removing them from slave status.`; },
+						link: `Convert`,
+						value: 1,
+					},
+
+				],
+			},
+			{
+				property: "dairySlimMaintain",
+				prereqs: [
+					() => !!V.dairySlimMaintainUpgrade,
+				],
+				options: [
+					{
+						get text() { return `Milking will operate as normal and will allow the breasts of slimmer slaves to expand.`; },
+						link: `Normal operation`,
+						value: 0,
+						note: `This will not remove existing lactation implants.`
+					},
+					{
+						get text() { return `Milking will limit the breast growth of slimmer slaves while maximizing their milk output.`; },
+						link: `Preserve breast sizes`,
+						value: 1,
+						note: `This will allow the automatic administration of lactation-inducing drugs.`
+					},
+				],
+			},
+			{
+				property: "dairyImplantsSetting",
+				prereqs: [
+					() => V.dairySlimMaintain === 0,
+				],
+				options: [
+					{
+						get text() { return `Naturally lactating cows, cows with non-lactating breasts, and cows incapable of producing cum will undergo lactation implant surgery to increase their milk output. Cows with working prostates will have them enhanced.`; },
+						link: `Maximize milk production`,
+						value: 0,
+					},
+					{
+						get text() { return `All cows will undergo lactation implant surgery to increase their milk output.`; },
+						link: `Maximize all production`,
+						value: 1,
+					},
+					{
+						get text() { return `Cows will not undergo surgical procedures to maximize production.`; },
+						link: `Restrict maximization surgery`,
+						value: 2,
+					},
+					{
+						get text() { return `Non-lactating cows incapable of producing cum will undergo manual stimulation to promote natural production.`; },
+						link: `Encourage natural lactation`,
+						value: 3,
+					},
+				],
+			},
+			{
+				property: "dairyWeightSetting",
+				prereqs: [],
+				options: [
+					{
+						get text() { return `Cow diets are not being monitored.`; },
+						link: `Deactivate`,
+						value: -1,
+					},
+					{
+						get text() { return `Cows are being kept at least chubby.`; },
+						link: `Chubby`,
+						value: 0,
+						note: V.dairySlimMaintainUpgrade === 1 || V.arcologies[0].FSSlimnessEnthusiast > 20
+							? `Slimness controls will override all weight settings.`
+							: null,
+					},
+					{
+						get text() { return `Cows are being kept overweight.`; },
+						link: `Overweight`,
+						value: 1,
+						note: V.dairySlimMaintainUpgrade === 1 || V.arcologies[0].FSSlimnessEnthusiast > 20
+							? `Slimness controls will override all weight settings.`
+							: null,
+					},
+					{
+						get text() { return `Cows are being kept fat.`; },
+						link: `Fat`,
+						value: 2,
+						note: V.dairySlimMaintainUpgrade === 1 || V.arcologies[0].FSSlimnessEnthusiast > 20
+							? `Slimness controls will override all weight settings.`
+							: null,
+					},
+					{
+						get text() { return `Cows are being kept very fat.`; },
+						link: `Very fat`,
+						value: 3,
+						note: V.dairySlimMaintainUpgrade === 1 || V.arcologies[0].FSSlimnessEnthusiast > 20
+							? `Slimness controls will override all weight settings.`
+							: null,
+					},
+					{
+						get text() { return `Cows are being kept so fat they can barely move.`; },
+						link: `Immobile`,
+						value: 4,
+						note: V.dairySlimMaintainUpgrade === 1 || V.arcologies[0].FSSlimnessEnthusiast > 20
+							? `Slimness controls will override all weight settings.`
+							: null,
+					},
+				],
+			},
+			{
+				property: "milkmaidImpregnates",
+				prereqs: [
+					() => !!S.Milkmaid,
+				],
+				options: [
+					{
+						get text() { return `${S.Milkmaid.slaveName} will not keep the cows pregnant ${getPronouns(S.Milkmaid).himself}.`; },
+						link: `Forbid`,
+						value: 0,
+					},
+					{
+						get text() { return `Keeping the cows pregnant is part of ${S.Milkmaid.slaveName}'s job.`; },
+						link: `Allow`,
+						value: 1,
+					},
+				],
+			},
+			{
+				property: "dairyHormonesSetting",
+				prereqs: [],
+				options: [
+					{
+						get text() { return `Hormone application is left to your discretion.`; },
+						link: `Deactivate`,
+						value: -1,
+					},
+					{
+						get text() { return `Cows will not be given hormones.`; },
+						link: `No hormones`,
+						value: 0,
+						note: `Favors milk production when possible.`,
+					},
+					{
+						get text() { return `Cows will be given hormones.`; },
+						link: `Normal dosage`,
+						value: 1,
+						note: `Favors milk production when possible.`,
+					},
+					{
+						get text() { return `Cows will undergo intense hormone treatment.`; },
+						link: `Maximum dosage`,
+						value: 2,
+						note: `Favors milk production when possible.`,
+					},
+				],
+			},
+		];
+	}
+
+	/** @returns {HTMLDivElement} */
+	get stats() {
+		return App.UI.DOM.makeElement("div", App.Facilities.Dairy.Stats(true));
+	}
+
+	/** @returns {HTMLDivElement} */
+	get warning() {
+		const div = document.createElement("div");
+		if (V.dairyPregSetting > 1 || V.dairyFeedersSetting > 1 || V.dairyStimulatorsSetting > 1) {
+			App.Events.addNode(div, [
+				`<span class="warning">Current milking machine settings will have dramatic and possibly irreversible effects on cow bodies and minds.</span>`
+			]);
+		}
+		return div;
+	}
+
+	/**
+	 * Returns the dialog text to display when setting a rule.
+	 * @param {'feeders'|'stimulators'|'preg'|'restraints'} setting
+	 */
+	_getEffect(setting) {
+		const text = [];
+		const {He: HeU, he: heU, him: himU, his: hisU, himself: himselfU} = getNonlocalPronouns(V.seeDicks);
+
+		if (this.facility.hostedSlaves > 1) {
+			if (setting === "feeders") {
+				if (V.dairyFeedersSetting < 2) {
+					text.push(`In unison, the milking machines withdraw their feeders from the slaves' throats. The slaves gag and cough, strings of feeding fluid and saliva running between their lips and the heads of the feeding phalli. These remain close to their faces so that the slaves can suck them off once they get hungry, which they will, soon. The slaves' mouths and tongues are very tired, and most of them rest with their mouths open and their tongues hanging out.`);
+				} else {
+					text.push(`In unison, the milking machines press their feeding phalli into the slaves' mouths and down their throats. Once situated, they begin to facefuck the slaves, who gag and struggle as they figure out how to breathe while this is going on. Once each slave is no longer panicking and is inhaling and exhaling regularly, there is a hydraulic sound and the transparent reservoir of feeding fluid near their head begins to drain. The slaves swallow desperately, their bellies beginning to swell with nutrition and drugs.`);
+				}
+			} else if (setting === "preg") {
+				if (V.dairyPregSetting < 2) {
+					for (const slave of this.facility.employees()) {
+						const {He, him, his} = getPronouns(slave);
+						if (slave.vagina.isBetween(-1, 3)) {
+							text.push(`${slave.slaveName}'s milking machine ejects ${him}, since it cannot fit the mandated dildo into ${his} tight cunt. <span class="yellow">${He} has been kicked out of ${this.facility.name}.</span>`);
+							removeJob(slave, Job.DAIRY);
+						}
+						if (V.dairyPregSetting > 0) {
+							WombCleanGenericReserve(slave, "incubator", 9999);
+							WombCleanGenericReserve(slave, "nursery", 9999);
+							if (slave.broodmother > 0 || slave.bellyImplant !== -1) {
+								text.push(`${slave.slaveName}'s milking machine ejects ${him}, since it detected a foreign body in ${his} womb blocking its required functions. <span class="yellow">${He} has been kicked out of ${this.facility.name}.</span>`);
+								removeJob(slave, Job.DAIRY);
+							}
+						}
+					}
+
+					text.push(`In unison, the milking machines withdraw their dildos from the pregnant slaves' vaginas. The auxiliary drug injectors hiss as the slaves are filled with drugs that promote natural lubrication. The slaves begin to shift awkwardly as they feel their pussies begin to drool slick female fluids. Once a machine judges that its slave's cunt is sufficiently wet, it readies a gigantic dildo. The slaves cannot see their own groins, but as soon as the heads of the dildos touch their pussylips, they begin to`);
+					text.push(`struggle instinctively against their restraints${V.dairyFeedersSetting < 2 ? ', and the more energetic ones begin to weep': ''}.`);
+					text.push(`As the massive phalli begin to ejaculate fertility drugs and semen, they drive all resistance out of the poor girls.`);
+				} else {
+					text.push(`In unison, the milking machines withdraw their monstrous dildos from the pregnant slaves' stretched cunts. Their pussies' overcharged production of natural lubricant produces a gush of pent-up female fluids from each loose vagina as the phalli slide clear.`);
+
+					if (V.dairyFeedersSetting < 2) {
+						text.push(`The slaves moan with relief at the sudden reduction in fullness. Being penetrated like that while pregnant must be quite uncomfortable.`);
+					} else {
+						text.push(`The slaves are silent, since their mouths and throats are being fucked by the feeders, but most of them relax a little in their restraints.`);
+					}
+					text.push(`The machines do replace the withdrawn dildos with more reasonably sized phalli and resume thrusting, but the slaves are relieved anyway.`);
+				}
+			} else if (setting === "stimulators") {
+				if (V.dairyStimulatorsSetting < 2) {
+					for (const slave of this.facility.employees().filter(s => s.vagina.isBetween(-1, 3))) {
+						const {He, him, his} = getPronouns(slave);
+						text.push(`${slave.slaveName}'s milking machine ejects ${him}, since it cannot fit its massive anal dildo up ${his} tight asshole. <span class="yellow">${He} has been kicked out of ${this.facility.name}.</span>`);
+						removeJob(slave, Job.DAIRY);
+					}
+
+					text.push(`In unison, the milking machines shove their dildos deep into slaves' anuses, ejaculating large quantities of lubricant deep inside their rectums. The slaves start in surprise at the sudden rush of warm slick fluid, and then relax as the phalli withdraw themselves from their butts. Their relief is short-lived, however, as their assholes are only empty for a moment. The reasonably sized dildos are replaced with dildos the size of horse cocks. As soon as the slaves feel the heads of these monstrous phalli press inexorably against their sphincters,`);
+					text.push(`they begin to ${V.dairyStimulatorsSetting < 2 ? 'scream and struggle instinctively' : 'struggle wildly'}. As the constant assrape that will define their existences for the foreseeable future begins in earnest, their ${V.dairyStimulatorsSetting < 2 ? 'whining' : 'wriggling'}`);
+					text.push(`gradually diminishes as each slave is exhausted and slumps within their restraints. The machines take no notice, and continue the relentless sodomy.`);
+				} else {
+					text.push(`In unison, the milking machines withdraw their gargantuan dildos from the slaves' loosened anuses.`);
+
+					if (V.dairyStimulatorsSetting < 2) {
+						text.push(`Several of the more energetic slaves begin to cry quietly with relief`);
+					} else {
+						text.push(`The slaves are silent, since their mouths and throats are being fucked by the feeders, but most of them slump against their machines with relief`);
+					}
+					text.push(`as their sphincters gradually recover from wide open to merely gaping. The machines switch out the withdrawn dildos for phalli that are just large, but the slaves barely react at all as they are penetrated. After what their sphincters have been through, a merely big dick is nothing to them.`);
+				}
+			} else if (setting === "restraints") {
+				if (V.dairyRestraintsSetting < 2) {
+					if (V.dairyRestraintsSetting === 1) {
+						for (const slave of this.facility.employees().filter(s => s.indentureRestrictions > 1)) {
+							const {He, he, him} = getPronouns(slave);
+							text.push(`${slave.slaveName}'s milking machine declines to restrain ${him}, since ${he} is encoded as an indentured servant protected from restraint for milking. <span class="yellow">${He} has been kicked out of ${this.facility.name}.</span>`);
+							removeJob(slave, Job.DAIRY);
+						}
+
+						text.push(`The next cow to stumble over to a milking machine to be drained is gently but firmly embraced by its restraints, allowing it to suck ${himU} dry and violate ${himU} without any regard for ${hisU} feelings. Most of the cows accept this new wrinkle in their lives, since the restraints let them go afterward, and the milking machines bring temporary relief. Some, however, begin to regard the machines with concern.`);
+					} else {
+						text.push(`The next cow to stumble over to a milking machine to be drained finds to ${hisU} surprise that ${heU} is not restrained while it sucks ${himU} dry. ${HeU} wiggles around experimentally, verifying that ${heU} is indeed free to pull ${himselfU} away from its ministrations if ${heU} wishes. There's little actual impact on the cows' behavior, since they still need the relief the machines offer.`);
+					}
+				} else {
+					if (V.dairyRestraintsSetting === 2) {
+						for (const slave of this.facility.employees().filter(s => s.indentureRestrictions > 1)) {
+							const {He, he, him} = getPronouns(slave);
+							text.push(`${slave.slaveName}'s milking machine declines to restrain ${him}, since ${he} is encoded as an indentured servant protected from restraint for milking. <span class="yellow">${He} has been kicked out of ${this.facility.name}.</span>`);
+							removeJob(slave, Job.DAIRY);
+						}
+						if (S.Milkmaid) {
+							const {his} = getPronouns(S.Milkmaid);
+							text.push(`${S.Milkmaid.slaveName} has been removed from ${his} position as Milkmaid, since an industrialized dairy automates ${his} duties.`);
+							removeJob(S.Milkmaid, Job.MILKMAID);
+						}
+
+						text.push(`The next time a cow tries to get up after being milked, ${heU} finds to ${hisU} sudden terror that the machine will not let ${himU} go. It continues to add fluids to ${hisU} body, and remove them from ${hisU} nipples, ignoring ${hisU} mounting panic as ${heU} realizes that it's to be ${hisU} new partner and lover, on a level far more intimate than any possible human relationship. The other cows approach their machines with trepidation, but the mounting pressure in their udders forces them to embrace their immurement despite their terror.`);
+					} else {
+						text.push(`The next time a cow finishes an intensive milking period, ${hisU} restraints loosen. ${HeU} does not move for a long time, as though ${heU} is unable to believe that ${heU} is, at least in an immediate and local sense, free. Finally, ${heU} prises ${himselfU} out of ${hisU} milking machine's embrace, thick strings of fluid leading from it to ${hisU} orifices as ${heU} pulls each one off of its corresponding port.`);
+					}
+				}
+			}
+		}
+
+		return text.join(' ');
+	}
+
+	/** @returns {HTMLDivElement[]} */
+	get customNodes() {
+		return [
+			this.warning,
+		];
+	}
+};
diff --git a/src/facilities/dairy/industrialDairyAssignmentScene.js b/src/facilities/dairy/industrialDairyAssignmentScene.js
index a1944d60f1c2ebdf04f9f0b734bf9c644138c27b..c82dbdd9e0226d41cf84f2982fd4f4f613f1f207 100644
--- a/src/facilities/dairy/industrialDairyAssignmentScene.js
+++ b/src/facilities/dairy/industrialDairyAssignmentScene.js
@@ -493,7 +493,7 @@ App.Facilities.Dairy.industrialAssignmentScene = function(slave) {
 			slave.vagina = 3;
 		}
 		r.push(`The machine detects that ${he} requires the attention of the preparatory raper before it can penetrate ${him} successfully, and holds ${him} in place while the raper slides along its track in the ceiling. It comes to rest above the slave's defenseless body and extends its implements towards ${him}. ${He} can't see or hear it, but ${he} senses that something's happening and shivers.`);
-		if (V.dairyPregSetting > 1 && V.dairyPregSetting > 1 && isFertile(slave) && slave.vagina < 3 && slave.mpreg !== 1) { // TODO: Correct one of the identical sub-expressions on both sides of operator "&&"
+		if (V.dairyPregSetting > 1 && isFertile(slave) && slave.vagina < 3 && slave.mpreg !== 1) {
 			r.push(`${His} pussy is nowhere near ready to accept the passage of drugs and cum in and new slaves out. The new machine lubes ${him} thoroughly and then`);
 			if (slave.vagina === 0) {
 				r.push(`takes ${his} virginity`);
@@ -504,7 +504,7 @@ App.Facilities.Dairy.industrialAssignmentScene = function(slave) {
 		}
 		if (V.dairyStimulatorsSetting > 1 && slave.anus < 3) {
 			r.push(`${He}'ll be drinking through ${his} mouth almost constantly, but that won't be enough. ${He}'ll have to absorb hydration and nutrition from both ends to keep up with the outflow ${he}'ll produce.`);
-			if (V.dairyPregSetting > 1 && V.dairyPregSetting > 1 && isFertile(slave) && slave.vagina < 3 && slave.mpreg !== 1) { // TODO: Correct one of the identical sub-expressions on both sides of operator "&&"
+			if (V.dairyPregSetting > 1 && isFertile(slave) && slave.vagina < 3 && slave.mpreg !== 1) {
 				r.push(`It`);
 			} else {
 				r.push(`The new machine`);
diff --git a/src/facilities/farmyard/animals/Animal.js b/src/facilities/farmyard/animals/Animal.js
index 9aa3708022ac61f847113edd16910b2ea9d4ce60..dde095cc057da57576306689fbf220a389973a07 100644
--- a/src/facilities/farmyard/animals/Animal.js
+++ b/src/facilities/farmyard/animals/Animal.js
@@ -37,7 +37,7 @@ App.Entity.Animal = class Animal {
 
 	/** @returns {this} */
 	purchase() {
-		V.animals[this.type].push(this);
+		V.animals[this.type].push(this.name);
 
 		if (V.pit && !V.pit.animal) {
 			V.pit.animal = this.name;
@@ -46,6 +46,21 @@ App.Entity.Animal = class Animal {
 		return this;
 	}
 
+	/** @returns {this} */
+	sell() {
+		if (this.isActive) {
+			V.active[this.type] = V.animals[this.type].random() || null;
+		}
+
+		if (V.pit && V.pit.animal === this.name) {
+			V.pit.animal = null;
+		}
+
+		V.animals[this.type] = V.animals[this.type].filter(animal => animal !== this.name);
+
+		return this;
+	}
+
 	/** @param {string} name */
 	setName(name) {
 		this.name = name;
diff --git a/src/facilities/farmyard/animals/animals.js b/src/facilities/farmyard/animals/animals.js
index 2c94185aed50444ac0acad0574b71d24bc770edc..09ee4edd805744e34c32d3d9fb7523a24b9117a7 100644
--- a/src/facilities/farmyard/animals/animals.js
+++ b/src/facilities/farmyard/animals/animals.js
@@ -1,54 +1,24 @@
 App.Facilities.Farmyard.animals = function() {
-	App.Facilities.Farmyard.animals.init();
+	if (!App.Data.animals || App.Data.animals.size === 0) {
+		App.Facilities.Farmyard.animals.init();
+	}
 
 	const frag = new DocumentFragment();
+	const hrMargin = '0';
 
 	App.UI.DOM.appendNewElement("h1", frag, 'Animals');
-	const activeDiv = App.UI.DOM.appendNewElement("div", frag, null, ['margin-bottom']);
-	const domesticDiv = App.UI.DOM.appendNewElement("div", frag, null, ['margin-bottom']);
-	const exoticDiv = App.UI.DOM.appendNewElement("div", frag, null, ['margin-bottom']);
 
-	const hrMargin = '0';
+	const activeDiv = App.UI.DOM.appendNewElement("div", frag, activeAnimals(), ['margin-bottom']);
 
-	const canine = 'canine';
-	const hooved = 'hooved';
-	const feline = 'feline';
-	const exotic = 'exotic';
-	const domestic = 'domestic';
+	App.UI.DOM.appendNewElement("div", frag, domestic(), ['margin-bottom']);
+	App.UI.DOM.appendNewElement("div", frag, exotic(), ['margin-bottom']);
+	frag.append(addAnimal());
 
 	V.nextButton = "Back";
 	V.nextLink = "Farmyard";
 	V.returnTo = "Farmyard Animals";
 	V.encyclopedia = "Farmyard";
 
-	if (V.active.canine || V.active.hooved || V.active.feline) {
-		App.UI.DOM.appendNewElement("h2", activeDiv, 'Active Animals');
-	}
-
-	App.UI.DOM.appendNewElement("h2", domesticDiv, 'Domestic Animals');
-
-	if (V.farmyardKennels > 1 || V.farmyardStables > 1 || V.farmyardCages > 1) {
-		App.UI.DOM.appendNewElement("h2", exoticDiv, 'Exotic Animals');
-	}
-
-	activeDiv.append(activeAnimals());
-
-	domesticDiv.append(
-		domesticCanines(),
-		domesticHooved(),
-		domesticFelines(),
-	);
-
-	exoticDiv.append(
-		exoticCanines(),
-		exoticHooved(),
-		exoticFelines(),
-	);
-
-	if (V.debugMode || V.cheatMode) {
-		frag.append(addAnimal());
-	}
-
 	return frag;
 
 	// Active Animals
@@ -60,7 +30,7 @@ App.Facilities.Farmyard.animals = function() {
 
 			hr.style.margin = hrMargin;
 
-			App.UI.DOM.appendNewElement("span", div, 'Canine', ['bold']);
+			App.UI.DOM.appendNewElement("h2", div, 'Active Animals');
 
 			div.append(hr);
 
@@ -77,15 +47,18 @@ App.Facilities.Farmyard.animals = function() {
 			return div;
 		}
 
-		return document.createElement("div");
+		return new DocumentFragment();
 
 		function canine() {
 			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
 			const options = new App.UI.OptionsGroup();
 
+			App.UI.DOM.appendNewElement("h3", div, 'Canine');
+
 			const option = options.addOption(null, "canine", V.active);
 			V.animals.canine.forEach(canine => {
-				option.addValue(capFirstChar(canine.name), canine.name).pulldown();
+				const _canine = getAnimal(canine);
+				option.addValue(capFirstChar(_canine.name), _canine.name).pulldown();
 			});
 
 			div.append(`Your ${V.active.canine} is currently set as your active canine.`, options.render());
@@ -97,9 +70,12 @@ App.Facilities.Farmyard.animals = function() {
 			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
 			const options = new App.UI.OptionsGroup();
 
+			App.UI.DOM.appendNewElement("h3", div, 'Hooved');
+
 			const option = options.addOption(null, "hooved", V.active);
 			V.animals.hooved.forEach(hooved => {
-				option.addValue(capFirstChar(hooved.name), hooved.name).pulldown();
+				const _hooved = getAnimal(hooved);
+				option.addValue(capFirstChar(_hooved.name), _hooved.name).pulldown();
 			});
 
 			div.append(`Your ${V.active.hooved} is currently set as your active hooved animal.`, options.render());
@@ -111,9 +87,12 @@ App.Facilities.Farmyard.animals = function() {
 			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
 			const options = new App.UI.OptionsGroup();
 
+			App.UI.DOM.appendNewElement("h3", div, 'Feline');
+
 			const option = options.addOption(null, "feline", V.active);
 			V.animals.feline.forEach(feline => {
-				option.addValue(capFirstChar(feline.name), feline.name).pulldown();
+				const _felines = getAnimal(feline);
+				option.addValue(capFirstChar(_felines.name), _felines.name).pulldown();
 			});
 
 			div.append(`Your ${V.active.feline} is currently set as your active feline.`, options.render());
@@ -124,108 +103,159 @@ App.Facilities.Farmyard.animals = function() {
 
 	// Domestic Animals
 
-	function domesticCanines() {
-		if (V.farmyardKennels) {
-			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
-			const hr = document.createElement("hr");
+	function domestic() {
+		const frag = new DocumentFragment();
 
-			hr.style.margin = hrMargin;
+		App.UI.DOM.appendNewElement("h2", frag, 'Domestic Animals');
 
-			App.UI.DOM.appendNewElement("span", div, 'Dogs', ['bold']);
+		frag.append(
+			canine(),
+			hooved(),
+			feline(),
+		);
 
-			div.append(hr, animalList(canine, domestic, 5000, canine));
+		return frag;
 
-			return div;
-		}
+		function canine() {
+			if (V.farmyardKennels) {
+				const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+				const hr = document.createElement("hr");
 
-		return document.createElement("div");
-	}
+				hr.style.margin = hrMargin;
 
-	function domesticHooved() {
-		if (V.farmyardStables) {
-			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
-			const hr = document.createElement("hr");
+				App.UI.DOM.appendNewElement("span", div, 'Dogs', ['bold']);
+				div.append(hr, animalList('canine', 'domestic', 5000, 'canine', 'dog'));
 
-			hr.style.margin = hrMargin;
+				if ([...App.Data.animals].some(animal =>
+					animal.type === 'canine' &&
+					animal.rarity === 'domestic' &&
+					animal.species !== 'dog')) {
+					const hr = document.createElement("hr");
 
-			App.UI.DOM.appendNewElement("span", div, 'Hooved Animals', ['bold']);
+					hr.style.margin = hrMargin;
 
-			div.append(hr, animalList(hooved, domestic, 20000, hooved));
+					App.UI.DOM.appendNewElement("span", div, 'Other Canines', ['bold']);
+					div.append(hr, animalList('canine', 'domestic', 5000, 'canine', null, 'dog'));
+				}
 
-			return div;
-		}
+				return div;
+			}
 
-		return document.createElement("div");
-	}
+			return new DocumentFragment();
+		}
 
-	function domesticFelines() {
-		if (V.farmyardCages) {
-			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
-			const hr = document.createElement("hr");
+		function hooved() {
+			if (V.farmyardStables) {
+				const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+				const hr = document.createElement("hr");
 
-			hr.style.margin = hrMargin;
+				hr.style.margin = hrMargin;
 
-			App.UI.DOM.appendNewElement("span", div, 'Cats', ['bold']);
+				App.UI.DOM.appendNewElement("span", div, 'Hooved Animals', ['bold']);
+				div.append(hr, animalList('hooved', 'domestic', 20000, 'hooved'));
 
-			div.append(hr, animalList(feline, domestic, 1000, feline));
+				return div;
+			}
 
-			return div;
+			return new DocumentFragment();
 		}
 
-		return document.createElement("div");
+		function feline() {
+			if (V.farmyardCages) {
+				const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+				const hr = document.createElement("hr");
+
+				hr.style.margin = hrMargin;
+
+				App.UI.DOM.appendNewElement("span", div, 'Cats', ['bold']);
+				div.append(hr, animalList('feline', 'domestic', 1000, 'feline', 'cat'));
+
+				if ([...App.Data.animals].some(animal =>
+					animal.type === 'feline' &&
+					animal.rarity === 'domestic' &&
+					animal.species !== 'cat')) {
+					const hr = document.createElement("hr");
+
+					hr.style.margin = hrMargin;
+
+					App.UI.DOM.appendNewElement("span", div, 'Other Felines', ['bold']);
+					div.append(hr, animalList('feline', 'domestic', 5000, 'feline', null, 'cat'));
+				}
+
+				return div;
+			}
+
+			return new DocumentFragment();
+		}
 	}
 
 	// Exotic Animals
 
-	function exoticCanines() {
-		if (V.farmyardKennels > 1) {
-			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
-			const hr = document.createElement("hr");
+	function exotic() {
+		const frag = new DocumentFragment();
 
-			hr.style.margin = hrMargin;
+		if (V.farmyardKennels > 1 || V.farmyardStables > 1 || V.farmyardCages > 1) {
+			App.UI.DOM.appendNewElement("h2", frag, 'Exotic Animals');
+		}
+
+		frag.append(
+			canine(),
+			hooved(),
+			feline(),
+		);
+
+		return frag;
 
-			App.UI.DOM.appendNewElement("span", div, 'Canines', ['bold']);
+		function canine() {
+			if (V.farmyardKennels > 1) {
+				const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+				const hr = document.createElement("hr");
 
-			div.append(hr, animalList(canine, exotic, 50000, canine));
+				hr.style.margin = hrMargin;
 
-			return div;
+				App.UI.DOM.appendNewElement("span", div, 'Canines', ['bold']);
+
+				div.append(hr, animalList('canine', 'exotic', 50000, 'canine'));
+
+				return div;
+			}
+
+			return new DocumentFragment();
 		}
 
-		return document.createElement("div");
-	}
+		function hooved() {
+			if (V.farmyardStables > 1) {
+				const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+				const hr = document.createElement("hr");
 
-	function exoticHooved() {
-		if (V.farmyardStables > 1) {
-			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
-			const hr = document.createElement("hr");
+				hr.style.margin = hrMargin;
 
-			hr.style.margin = hrMargin;
+				App.UI.DOM.appendNewElement("span", div, 'Hooved Animals', ['bold']);
 
-			App.UI.DOM.appendNewElement("span", div, 'Hooved Animals', ['bold']);
+				div.append(hr, animalList('hooved', 'exotic', 75000, 'hooved'));
 
-			div.append(hr, animalList(hooved, exotic, 75000, hooved));
+				return div;
+			}
 
-			return div;
+			return new DocumentFragment();
 		}
 
-		return document.createElement("div");
-	}
+		function feline() {
+			if (V.farmyardCages > 1) {
+				const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
+				const hr = document.createElement("hr");
 
-	function exoticFelines() {
-		if (V.farmyardCages > 1) {
-			const div = App.UI.DOM.makeElement("div", null, ['margin-bottom']);
-			const hr = document.createElement("hr");
+				hr.style.margin = hrMargin;
 
-			hr.style.margin = hrMargin;
+				App.UI.DOM.appendNewElement("span", div, 'Felines', ['bold']);
 
-			App.UI.DOM.appendNewElement("span", div, 'Felines', ['bold']);
+				div.append(hr, animalList('feline', 'exotic', 100000, 'feline'));
 
-			div.append(hr, animalList(feline, exotic, 100000, feline));
+				return div;
+			}
 
-			return div;
+			return new DocumentFragment();
 		}
-
-		return document.createElement("div");
 	}
 
 	// Helper Functions
@@ -239,21 +269,32 @@ App.Facilities.Farmyard.animals = function() {
 	 * @param {number} param.price
 	 * @param {function():void} param.setActiveHandler
 	 * @param {function():void} param.purchaseHandler
+	 * @param {function():void} param.sellHandler
 	 * @returns {string|HTMLElement}
 	 */
-	function animalLink({animal, active, type, price, setActiveHandler, purchaseHandler}) {
-		if (animal.purchased || V.animals[animal.type].some(a => a.name === animal.name)) {
+	function animalLink({animal, active, type, price, setActiveHandler, purchaseHandler, sellHandler}) {
+		if (animal.purchased || V.animals[animal.type].some(a => a === animal.name)) {
+			const div = document.createElement("div");
+
+			const options = [];
+
 			if (V.active[active] && V.active[active] === animal.name) {
-				return App.UI.DOM.makeElement("span", `Set as active ${type}`, ["note"]);
+				options.push(
+					App.UI.DOM.disabledLink(`Set as active ${type}`, ['Already set as active']),
+					App.UI.DOM.link(`Sell`, sellHandler)
+				);
 			} else {
-				return App.UI.DOM.link(`Set as active ${type}`, setActiveHandler);
+				options.push(
+					App.UI.DOM.link(`Set as active ${type}`, setActiveHandler),
+					App.UI.DOM.link(`Sell`, sellHandler)
+				);
 			}
+
+			div.append(App.UI.DOM.generateLinksStrip(options));
+
+			return div;
 		} else {
-			return App.UI.DOM.link(
-				`Purchase`,
-				purchaseHandler,
-				[], '', `Costs ${cashFormat(price)} and will incur upkeep costs.`
-			);
+			return makePurchase(`Purchase ${animal.articleAn} ${animal.name}`, price, "farmyard", {notes: [`will incur upkeep costs`], handler: purchaseHandler});
 		}
 	}
 
@@ -263,58 +304,76 @@ App.Facilities.Farmyard.animals = function() {
 	 * @param {'domestic'|'exotic'} rarity One of 'domestic' or 'exotic'.
 	 * @param {number} price
 	 * @param {string} active The name of the current active animal of the given type.
+	 * @param {string} [species] Any specific species to filter by,
+	 * @param {string} [exclude] Any species to exclude.
 	 * @returns {HTMLDivElement}
 	 */
-	function animalList(type, rarity, price, active) {
-		const mainDiv = document.createElement("div");
-		const filteredArray = App.Data.animals.filter(animal => animal.rarity === rarity && animal.type === type);
-
-		filteredArray.forEach(animal => {
-			const animalDiv = document.createElement("div");
-			const optionSpan = document.createElement("span");
-
-			const args = {
-				animal: animal,
-				active: active,
-				type: type,
-				price: price,
-				setActiveHandler() {
-					animal.setActive();
-					App.UI.DOM.replace(mainDiv, animalList(type, rarity, price, active));
-					App.UI.DOM.replace(activeDiv, activeAnimals());
-				},
-				purchaseHandler() {
-					cashX(forceNeg(price), "farmyard");
-					animal.purchase();
-					if (!V.active[animal.type]) {
-						animal.setActive();
-					}
-					App.UI.DOM.replace(activeDiv, activeAnimals());
-					App.UI.DOM.replace(mainDiv, animalList(type, rarity, price, active));
+	function animalList(type, rarity, price, active, species, exclude) {
+		const div = document.createElement("div");
+		[...App.Data.animals]
+			.filter(animal => animal.rarity === rarity && animal.type === type && animal.species !== exclude)
+			.forEach(animal => {
+				if (species && animal.species !== species) {
+					return div;
 				}
-			};
 
-			optionSpan.append(animalLink(args));
+				const animalDiv = document.createElement("div");
+				const optionDiv = App.UI.DOM.makeElement("div", null, ['indent']);
 
-			animalDiv.append(capFirstChar(animal.name), ' ', optionSpan);
-
-			mainDiv.appendChild(animalDiv);
-		});
+				const args = {
+					animal: animal,
+					active: active,
+					type: type,
+					price: price,
+					setActiveHandler() {
+						animal.setActive();
+						App.UI.DOM.replace(div, animalList(type, rarity, price, active));
+						App.UI.DOM.replace(activeDiv, activeAnimals());
+					},
+					purchaseHandler() {
+						cashX(forceNeg(price), "farmyard");
+						animal.purchase();
+						if (!V.active[animal.type]) {
+							animal.setActive();
+						}
+						App.UI.DOM.replace(activeDiv, activeAnimals());
+						App.UI.DOM.replace(div, animalList(type, rarity, price, active, species, exclude));
+					},
+					sellHandler() {
+						cashX(price * 0.75, "farmyard");
+						animal.sell();
+						App.UI.DOM.replace(activeDiv, activeAnimals());
+						App.UI.DOM.replace(div, animalList(type, rarity, price, active, species, exclude));
+					},
+				};
+
+				optionDiv.append(animalLink(args));
+				animalDiv.append(capFirstChar(animal.name), optionDiv);
+
+				div.append(animalDiv);
+			});
 
-		return mainDiv;
+		return div;
 	}
 
 	function addAnimal() {
-		const addAnimalDiv = document.createElement("div");
+		const frag = new DocumentFragment();
+
+		const nameDiv = document.createElement("div");
+		const speciesDiv = document.createElement("div");
+		const typeDiv = document.createElement("div");
+		const rarityDiv = document.createElement("div");
+		const articleDiv = document.createElement("div");
 		const dickDiv = document.createElement("div");
 		const deadlinessDiv = document.createElement("div");
-		const addDiv = App.UI.DOM.makeElement("div", null, ['animal-add']);
+		const addDiv = App.UI.DOM.makeElement("div", null, ['margin-top']);
 
 		const animal = new App.Entity.Animal(null, null, "canine", "domestic");
+		let animalName = animal.name || 'animal';
 
-		App.UI.DOM.appendNewElement("div", addAnimalDiv, `Add a New Animal`, ['uppercase', 'bold']);
+		App.UI.DOM.appendNewElement("h2", frag, `Custom Animals`);
 
-		addAnimalDiv.append(
+		frag.append(
 			name(),
 			species(),
 			type(),
@@ -325,156 +384,78 @@ App.Facilities.Farmyard.animals = function() {
 			add(),
 		);
 
-		return addAnimalDiv;
+		return frag;
 
 		function name() {
-			const nameDiv = document.createElement("div");
-
 			nameDiv.append(
 				`Name: `,
 				App.UI.DOM.makeTextBox(animal.name || '', value => {
 					animal.setName(value);
+					animal.setSpecies(value);
+					animalName = animal.name;
 
-					App.UI.DOM.replace(nameDiv, name);
-					App.UI.DOM.replace(dickDiv, dick);
-					App.UI.DOM.replace(deadlinessDiv, deadliness);
-					App.UI.DOM.replace(addDiv, add);
+					refresh();
 				}),
+				App.UI.DOM.makeElement("span", ` Can be lowercase.`, ['note']),
 			);
 
 			return nameDiv;
 		}
 
 		function species() {
-			const speciesDiv = document.createElement("div");
-
 			speciesDiv.append(
 				`Species: `,
-				App.UI.DOM.makeTextBox(animal.species || '', value => {
+				App.UI.DOM.makeTextBox(animal.species || animal.name || '', value => {
 					animal.setSpecies(value);
 
-					App.UI.DOM.replace(speciesDiv, species);
-					App.UI.DOM.replace(addDiv, add);
+					refresh();
 				}),
+				App.UI.DOM.makeElement("span", ` Can be different than the animal's name.`, ['note']),
 			);
 
 			return speciesDiv;
 		}
 
 		function type() {
-			const typeDiv = document.createElement("div");
-
-			const typeLinks = [];
+			const options = new App.UI.OptionsGroup().customRefresh(refresh);
+			options.addOption(null, "type", animal)
+				.addValue('Canine', 'canine')
+				.addValue('Hooved', 'hooved')
+				.addValue('Feline', 'feline');
 
 			if (animal.type === "canine") {
-				typeLinks.push(
-					App.UI.DOM.disabledLink(`Canine`, [`Already selected.`]),
-					App.UI.DOM.link(`Hooved`, () => {
-						animal.setType('hooved');
-
-						App.UI.DOM.replace(typeDiv, type);
-					}),
-					App.UI.DOM.link(`Feline`, () => {
-						animal.setType("feline");
-
-						App.UI.DOM.replace(typeDiv, type);
-					}),
-				);
+				typeDiv.append(`The ${animalName} is a canine.`, options.render());
 			} else if (animal.type === "hooved") {
-				typeLinks.push(
-					App.UI.DOM.link(`Canine`, () => {
-						animal.setType("canine");
-
-						App.UI.DOM.replace(typeDiv, type);
-					}),
-					App.UI.DOM.disabledLink(`Hooved`, [`Already selected.`]),
-					App.UI.DOM.link(`Feline`, () => {
-						animal.setType("feline");
-
-						App.UI.DOM.replace(typeDiv, type);
-					}),
-				);
+				typeDiv.append(`The ${animalName} is a hooved animal.`, options.render());
 			} else {
-				typeLinks.push(
-					App.UI.DOM.link(`Canine`, () => {
-						animal.setType("canine");
-
-						App.UI.DOM.replace(typeDiv, type);
-					}),
-					App.UI.DOM.link(`Hooved`, () => {
-						animal.setType("hooved");
-
-						App.UI.DOM.replace(typeDiv, type);
-					}),
-					App.UI.DOM.disabledLink(`Feline`, [`Already selected.`]),
-				);
+				typeDiv.append(`The ${animalName} is a feline.`, options.render());
 			}
 
-			typeDiv.append(`Type: `, App.UI.DOM.generateLinksStrip(typeLinks));
-
 			return typeDiv;
 		}
 
 		function rarity() {
-			const rarityDiv = document.createElement("div");
-
-			const rarityLinks = [];
+			const options = new App.UI.OptionsGroup().customRefresh(refresh);
+			options.addOption(null, "rarity", animal)
+				.addValue('Domestic', 'domestic')
+				.addValue('Exotic', 'exotic');
 
 			if (animal.rarity === "domestic") {
-				rarityLinks.push(
-					App.UI.DOM.disabledLink(`Domestic`, [`Already selected.`]),
-					App.UI.DOM.link(`Exotic`, () => {
-						animal.setRarity('exotic');
-
-						App.UI.DOM.replace(rarityDiv, rarity);
-					}),
-				);
+				rarityDiv.append(`The ${animalName} is domesticated.`, options.render());
 			} else {
-				rarityLinks.push(
-					App.UI.DOM.link(`Domestic`, () => {
-						animal.setRarity('domestic');
-
-						App.UI.DOM.replace(rarityDiv, rarity);
-					}),
-					App.UI.DOM.disabledLink(`Exotic`, [`Already selected.`]),
-				);
+				rarityDiv.append(`The ${animalName} is exotic and tamed.`, options.render());
 			}
 
-			rarityDiv.append(`Rarity: `, App.UI.DOM.generateLinksStrip(rarityLinks));
-
 			return rarityDiv;
 		}
 
 		function article() {
-			const articleDiv = document.createElement("div");
-
-			const articleLinks = [];
-
-			if (animal.articleAn === 'a') {
-				articleLinks.push(
-					App.UI.DOM.link("Yes", () => {
-						animal.articleAn = 'an';
-
-						App.UI.DOM.replace(articleDiv, article);
-						App.UI.DOM.replace(dickDiv, dick);
-						App.UI.DOM.replace(deadlinessDiv, deadliness);
-					}),
-					App.UI.DOM.disabledLink("No", [`Already selected.`]),
-				);
-			} else {
-				articleLinks.push(
-					App.UI.DOM.disabledLink("Yes", [`Already selected.`]),
-					App.UI.DOM.link("No", () => {
-						animal.articleAn = 'a';
-
-						App.UI.DOM.replace(articleDiv, article);
-						App.UI.DOM.replace(dickDiv, dick);
-						App.UI.DOM.replace(deadlinessDiv, deadliness);
-					}),
-				);
-			}
+			const options = new App.UI.OptionsGroup().customRefresh(refresh);
+			options.addOption(null, "articleAn", animal)
+				.addValue('Yes', 'an')
+				.addValue('No', 'a');
 
-			articleDiv.append(`Is this animal's name preceded by an 'an'? `, App.UI.DOM.generateLinksStrip(articleLinks));
+			articleDiv.append(`Is the ${animalName}'s name preceded by an 'an'?`, options.render());
 
 			return articleDiv;
 		}
@@ -488,13 +469,13 @@ App.Facilities.Farmyard.animals = function() {
 				const dickSizeDiv = document.createElement("div");
 
 				dickSizeDiv.append(
-					`How large is ${animal.name ? `${animal.articleAn} male ${animal.name}` : `a male`}'s penis? `,
+					`How large is a male${animal.name ? ` ${animalName}` : ``}'s penis? `,
 					App.UI.DOM.makeTextBox(animal.dick.size || 2, value => {
 						animal.setDick(value, animal.dick.desc || null);
 
-						App.UI.DOM.replace(dickSizeDiv, dickSize);
+						refresh();
 					}, true),
-					App.UI.DOM.makeElement("span", `1 is smallest, and default is 2. `, ['note']),
+					App.UI.DOM.makeElement("span", ` 1 is smallest and default is 2.`, ['note']),
 				);
 
 				return dickSizeDiv;
@@ -504,13 +485,13 @@ App.Facilities.Farmyard.animals = function() {
 				const dickDescDiv = document.createElement("div");
 
 				dickDescDiv.append(
-					`What does it look like? `,
+					`What does the penis look like? `,
 					App.UI.DOM.makeTextBox(animal.dick.desc || '', value => {
 						animal.setDick(animal.dick.size || 2, value);
 
-						App.UI.DOM.replace(dickDescDiv, dickDesc);
+						refresh();
 					}),
-					App.UI.DOM.makeElement("span", `Default is 'large'. `, ['note']),
+					App.UI.DOM.makeElement("span", ` Default is 'large', but you can use any descriptor.`, ['note']),
 				);
 
 				return dickDescDiv;
@@ -523,7 +504,7 @@ App.Facilities.Farmyard.animals = function() {
 				App.UI.DOM.makeTextBox(5, value => {
 					animal.setDick(value);
 				}, true),
-				App.UI.DOM.makeElement("span", `Default is 5. `, ['note']),
+				App.UI.DOM.makeElement("span", ` Default is 5.`, ['note']),
 			);
 
 			return deadlinessDiv;
@@ -532,8 +513,6 @@ App.Facilities.Farmyard.animals = function() {
 		function add() {
 			const disabledReasons = [];
 
-			let link;
-
 			if (!animal.name) {
 				disabledReasons.push(`Animal must have a name.`);
 			}
@@ -543,19 +522,28 @@ App.Facilities.Farmyard.animals = function() {
 			}
 
 			if (disabledReasons.length > 0) {
-				link = App.UI.DOM.disabledLink(`Add`, disabledReasons);
+				App.UI.DOM.appendNewElement("div", addDiv, App.UI.DOM.disabledLink(`Add`, disabledReasons), ['margin-top']);
 			} else {
-				link = App.UI.DOM.link(`Add`, () => {
-					App.Data.animals.push(animal);
+				App.UI.DOM.appendNewElement("div", addDiv, App.UI.DOM.link(`Add`, () => {
+					App.Data.animals.add(animal);
 
-					App.UI.DOM.replace(addAnimalDiv, addAnimal);
-				});
+					App.UI.reload();
+				}), ['margin-top']);
 			}
 
-			addDiv.appendChild(link);
-
 			return addDiv;
 		}
+
+		function refresh() {
+			App.UI.DOM.replace(nameDiv, name);
+			App.UI.DOM.replace(speciesDiv, species);
+			App.UI.DOM.replace(typeDiv, type);
+			App.UI.DOM.replace(rarityDiv, rarity);
+			App.UI.DOM.replace(articleDiv, article);
+			App.UI.DOM.replace(dickDiv, dick);
+			App.UI.DOM.replace(deadlinessDiv, deadliness);
+			App.UI.DOM.replace(addDiv, add);
+		}
 	}
 };
 
@@ -565,13 +553,15 @@ App.Facilities.Farmyard.animals = function() {
  * @returns {App.Entity.Animal}
  */
 globalThis.getAnimal = function(name) {
-	return V.animals.canine.find(animal => animal.name === name) ||
-		V.animals.hooved.find(animal => animal.name === name) ||
-		V.animals.feline.find(animal => animal.name === name);
+	if (!App.Data.animals || App.Data.animals.size === 0) {
+		App.Facilities.Farmyard.animals.init();
+	}
+
+	return [...App.Data.animals].find(animal => animal.name === name);
 };
 
 App.Facilities.Farmyard.animals.init = function() {
-	if (!App.Data.animals || App.Data.animals.length === 0) {
+	if (!App.Data.animals || App.Data.animals.size === 0) {
 		class Animal extends App.Entity.Animal {}
 
 		const dog = 'dog';
@@ -584,7 +574,7 @@ App.Facilities.Farmyard.animals.init = function() {
 		const an = 'an';
 
 		/** @type {Animal[]} */
-		App.Data.animals = [
+		[
 			new Animal("beagle", dog, canine, domestic)
 				.setDeadliness(2),
 			new Animal("bulldog", dog, canine, domestic),
@@ -638,9 +628,9 @@ App.Facilities.Farmyard.animals.init = function() {
 			new Animal("lynx", "lynx", feline, exotic),
 			new Animal("puma", "puma", feline, exotic),
 			new Animal("tiger", "tiger", feline, exotic),
-		];
+		].forEach(animal => App.Data.animals.add(animal));
 	}
 };
 
-/** @type {App.Entity.Animal[]} */
-App.Data.animals = App.Data.animals || [];
+/** @type {Set<App.Entity.Animal>} */
+App.Data.animals = App.Data.animals || new Set;
diff --git a/src/facilities/farmyard/farmyard.js b/src/facilities/farmyard/farmyard.js
index 82d3ea2965ced685a6e1413582563ec45bb57888..9260ae223aa05d7d326dcfcf58344d1660abe3df 100644
--- a/src/facilities/farmyard/farmyard.js
+++ b/src/facilities/farmyard/farmyard.js
@@ -116,7 +116,7 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 			"Slave Professionalism": `Despite the surroundings, those of your slaves that are allowed to wear clothes are dressed in clean outfits.${V.seeBestiality ? ` Those bearing litters walk with practiced care, protecting their young.` : ``} They go about their tasks methodically and with care, with ${S.Farmer ? S.Farmer.slaveName : `senior farmhands`} watching carefully to correct any lax behavior.`,
 			"Petite Admiration": `The buildings are squat, one story affairs that allow those of smaller stature easier access. ${V.seeBestiality ? ` Those closer to physical perfection bear the cum stains of their recent breedings.` : ``}`,
 			"Statuesque Glorification": `Those workers who are smaller and less fit have been given the worst jobs, mucking out the pens and stables. ${V.seeBestiality ? ` Those closer to physical perfection bear the cum stains of their recent breedings.` : ``}`,
-			"standard": `It is very much a converted warehouse still, sectioned off in various 'departments'${V.farmyardUpgrades.machinery ? ` with machinery placed where it can be` : V.farmyardUpgrades.hydroponics ? ` and plumbing for the hydroponics system running every which way` : ``}.`,
+			"standard": `It is very much a converted warehouse still, sectioned off into various "departments"${V.farmyardUpgrades.machinery ? ` with machinery placed where it can be` : V.farmyardUpgrades.hydroponics ? ` and plumbing for the hydroponics system running every which way` : ``}.`,
 		};
 
 		const res = FS[V.farmyardDecoration];
@@ -155,7 +155,9 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 
 							App.UI.reload();
 						},
-						note: ` and slightly decreases upkeep costs`,
+						notes: [
+							`slightly decreases upkeep cost.`
+						],
 					},
 					{
 						value: 1,
@@ -178,7 +180,10 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 
 							App.UI.reload();
 						},
-						note: `, moderately increases crop yield, and slightly increases upkeep costs`,
+						notes: [
+							`moderately increases crop yield`,
+							`slightly increases upkeep costs`,
+						],
 						prereqs: [
 							() => V.farmyardUpgrades.pump > 0,
 						],
@@ -204,7 +209,9 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 
 							App.UI.reload();
 						},
-						note: ` and moderately decreases upkeep costs`,
+						notes: [
+							`moderately decreases upkeep costs`,
+						],
 						prereqs: [
 							() => V.farmyardUpgrades.fertilizer > 0,
 						],
@@ -230,7 +237,10 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 
 							App.UI.reload();
 						},
-						note: `, moderately increases crop yield, and slightly increases upkeep costs`,
+						notes: [
+							`moderately increases crop yield`,
+							`slightly increases upkeep costs`,
+						],
 						prereqs: [
 							() => V.farmyardUpgrades.hydroponics > 0,
 						],
@@ -256,7 +266,10 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 
 							App.UI.reload();
 						},
-						note: `, moderately increases crop yield, and slightly increases upkeep costs`,
+						notes: [
+							`moderately increases crop yield`,
+							`slightly increases upkeep costs`,
+						],
 						prereqs: [
 							() => V.farmyardUpgrades.seeds > 0
 						],
@@ -282,15 +295,20 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 				],
 				options: [
 					{
-						get text() { return `Slaves in ${V.farmyardName} are not putting on shows with animals.`; },
-						link: `End shows`,
+						get text() { return `Slaves in ${V.farmyardName} are focusing their efforts on producing as much food as possible.`; },
+						link: `Food only`,
 						value: 0,
 					},
 					{
-						get text() { return `Slaves in ${V.farmyardName} are putting on shows with animals.`; },
-						link: `Begin shows`,
+						get text() { return `Slaves in ${V.farmyardName} are both producing food and putting on shows with animals.`; },
+						link: `Both food and shows`,
 						value: 1,
 					},
+					{
+						get text() { return `Slaves in ${V.farmyardName} are only putting on shows with animals.`; },
+						link: `Shows only`,
+						value: 2,
+					},
 				],
 			},
 			{
@@ -317,6 +335,7 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 				property: "farmyardRestraints",
 				prereqs: [
 					() => !!V.farmyardBreeding,
+					() => V.farmyardShows !== 0,
 				],
 				options: [
 					{
@@ -334,6 +353,11 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 		];
 	}
 
+	/** @returns {HTMLDivElement} */
+	get stats() {
+		return App.UI.DOM.makeElement("div", App.Facilities.Farmyard.Stats(true));
+	}
+
 	/** @returns {HTMLDivElement} */
 	get menials() {
 		const div = document.createElement("div");
@@ -350,7 +374,7 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 		// Transferring
 
 		if (V.farmMenials) {
-			div.append(`Assigned to ${V.farmyardName} ${V.farmMenials === 1 ? `is` : `are`} ${V.farmMenials} menial ${V.farmMenials === 1 ? `slave` : `slaves`}, working to produce as much food for your arcology as they can. `);
+			div.append(`Assigned to ${V.farmyardName} ${V.farmMenials === 1 ? `is` : `are`} ${num(V.farmMenials)} menial ${V.farmMenials === 1 ? `slave` : `slaves`}, working to produce as much food for your arcology as they can. `);
 		}
 
 		if (V.farmMenialsSpace) {
@@ -466,13 +490,12 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 		if (V.farmMenialsSpace < 2000) {
 			App.UI.DOM.appendNewElement("div", div, `There is enough room in ${V.farmyardName} to build housing, enough to give ${V.farmMenialsSpace + 100} menial slaves a place to sleep and relax.`);
 
-			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link(`Build a new housing unit`, () => {
-				cashX(forceNeg(unitCost), "farmyard");
-				V.farmMenialsSpace += 100;
-
-				this.refresh();
-			},
-			[], '', `Costs ${cashFormat(unitCost)} and increases housing by ${num(100)}.`), ['indent']);
+			App.UI.DOM.appendNewElement("div", div, makePurchase(`Build a new housing unit`, unitCost, "capEx", {
+				handler: () => {
+					V.farmMenialsSpace += 100;
+				},
+				notes: [`increases housing by ${num(100)}`],
+			}));
 		}
 
 		return div;
@@ -489,17 +512,18 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 		let canines = '';
 
 		if (CL === 1) {
-			dogs = `${V.animals.canine[0].name}s`;
+			const first = getAnimal(V.animals.canine[0]);
+			dogs = `${first.name}s`;
 
-			if (V.animals.canine[0].species === "dog") {
-				canines = V.animals.canine[0].name;
+			if (first.species === "dog") {
+				canines = first.name;
 			} else {
-				canines = asPlural(V.animals.canine[0].species);
+				canines = asPlural(first.species);
 			}
 		} else if (CL < 3) {
 			dogs = `a couple different breeds of dogs`;
 
-			if (V.animals.canine.every(c => c.species === "dog")) {
+			if (V.animals.canine.every(c => getAnimal(c).species === "dog")) {
 				canines = `a couple different breeds of dog`;
 			} else {
 				canines = `a couple different species of canine`;
@@ -510,32 +534,38 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 		}
 
 		if (V.farmyardKennels === 0) {
-			div.append(`There is enough room in ${V.farmyardName} to build kennels to house canines.`);
-			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link(`Add kennels`, () => {
-				cashX(forceNeg(cost), "farmyard");
-				V.farmyardKennels = 1;
-				V.PC.skill.engineering += .1;
-
-				this.refresh();
-			}, [], '', `Costs ${cashFormat(cost)}, will incur upkeep costs, and unlocks domestic canines.`), ['indent']);
+			div.append(
+				`There is enough room in ${V.farmyardName} to build kennels to house canines.`,
+				makePurchase(`Add kennels`, cost, "capEx", {
+					notes: [
+						`will incur upkeep costs`,
+						`unlocks domestic canines`,
+					],
+					handler: () => {
+						V.farmyardKennels = 1;
+						V.PC.skill.engineering += .1;
+					},
+				}),
+			);
 		} else if (V.farmyardKennels === 1) {
-			div.append(App.UI.DOM.passageLink("Kennels", "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${CL < 1 ? `empty` : `occupied by ${dogs}`}.`);
-
-			if (V.rep > 10000) {
-				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link("Upgrade kennels", () => {
-					cashX(forceNeg(cost * 2), "farmyard");
-					V.farmyardKennels = 2;
-					V.PC.skill.engineering += .1;
-
-					this.refresh();
-				}, [], '', `Costs ${cashFormat(cost * 2)} will incur additional upkeep costs, and unlocks exotic canines.`), ['indent']);
-			} else {
-				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.disabledLink("Upgrade kennels",
-					[`You must be more reputable to be able to house exotic canines.`]),
-				['indent']);
-			}
+			div.append(
+				App.UI.DOM.passageLink(`Kennels`, "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${CL < 1 ? `empty` : `occupied by ${dogs}`}.`,
+				makePurchase(`Upgrade kennels`, cost * 2, "capEx", {
+					notes: [
+						`will incur additional upkeep costs`,
+						`unlocks exotic canines`,
+					],
+					handler: () => {
+						V.farmyardKennels = 2;
+						V.PC.skill.engineering += .1;
+					},
+					prereqs: [
+						[V.rep > 10000, `You must be more reputable to be able to house exotic canines.`],
+					],
+				})
+			);
 		} else if (V.farmyardKennels === 2) {
-			div.append(App.UI.DOM.passageLink("Large kennels", "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${CL < 1 ? `empty` : `occupied by ${canines}`}.`);
+			div.append(App.UI.DOM.passageLink(`Large kennels`, "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${CL < 1 ? `empty` : `occupied by ${canines}`}. `);
 		}
 
 		return div;
@@ -549,38 +579,46 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 
 		const HL = V.animals.hooved.length;
 
+		const first = getAnimal(V.animals.hooved[0]);
 		const hooved = HL === 1
-			? `${V.animals.hooved[0].name}s` : HL < 3
+			? `${first.name}s` : HL < 3
 				? `several different types of hooved animals`
 				: `all kinds of hooved animals`;
 
 		if (V.farmyardStables === 0) {
-			div.append(`There is enough room in ${V.farmyardName} to build a stables to house hooved animals.`);
-			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link("Add stables", () => {
-				cashX(forceNeg(cost), "farmyard");
-				V.farmyardStables = 1;
-				V.PC.skill.engineering += .1;
-
-				this.refresh();
-			}, [], '', `Costs ${cashFormat(cost)}, will incur upkeep costs, and unlocks domestic hooved animals.`), ['indent']);
+			div.append(
+				`There is enough room in ${V.farmyardName} to build a stables to house hooved animals.`,
+				makePurchase(`Add stables`, cost, "capEx", {
+					notes: [
+						`will incur upkeep costs`,
+						`unlocks domestic hooved animals`,
+					],
+					handler: () => {
+						V.farmyardStables = 1;
+						V.PC.skill.engineering += .1;
+					},
+				}),
+			);
 		} else if (V.farmyardStables === 1) {
-			div.append(App.UI.DOM.passageLink("Stables", "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${HL < 1 ? `empty` : `occupied by ${hooved}`}.`);
-
-			if (V.rep > 10000) {
-				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link("Upgrade stables", () => {
-					cashX(forceNeg(cost * 2), "farmyard");
-					V.farmyardStables = 2;
-					V.PC.skill.engineering += .1;
-
-					this.refresh();
-				}, [], '', `Costs ${cashFormat(cost * 2)}, will incur additional upkeep costs, and unlocks exotic hooved animals.`), ['indent']);
-			} else {
-				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.disabledLink("Upgrade stables",
-					[`You must be more reputable to be able to house exotic hooved animals.`]),
-				['indent']);
-			}
+			div.append(
+				App.UI.DOM.passageLink(`Stables`, "Farmyard Animals"),
+				` have been built in one corner of ${V.farmyardName}, and are currently ${HL < 1 ? `empty` : `occupied by ${hooved}`}.`,
+				makePurchase(`Upgrade stables`, cost * 2, "capEx", {
+					notes: [
+						`will incur additional upkeep cost`,
+						`unlocks exotic hooved animal`,
+					],
+					handler: () => {
+						V.farmyardStables = 2;
+						V.PC.skill.engineering += .1;
+					},
+					prereqs: [
+						[V.rep > 10000, `You must be more reputable to be able to house exotic hooved animals.`],
+					],
+				})
+			);
 		} else if (V.farmyardStables === 2) {
-			div.append(App.UI.DOM.passageLink("Large stables", "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${HL < 1 ? `empty` : `occupied by ${hooved}`}.`);
+			div.append(App.UI.DOM.passageLink(`Large stables`, "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${HL < 1 ? `empty` : `occupied by ${hooved}`}. `);
 		}
 
 		return div;
@@ -597,17 +635,18 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 		let felines = '';
 
 		if (FL === 1) {
-			cats = `${V.animals.feline[0].name}s`;
+			const first = getAnimal(V.animals.feline[0]);
+			cats = `${first.name}s`;
 
-			if (V.animals.feline[0].species === "cat") {
-				felines = V.animals.feline[0].name;
+			if (first.species === "cat") {
+				felines = first.name;
 			} else {
-				felines = asPlural(V.animals.feline[0].species);
+				felines = asPlural(first.species);
 			}
 		} else if (FL < 3) {
 			cats = `a couple different breeds of cats`;
 
-			if (V.animals.feline.every(c => c.species === "cat")) {
+			if (V.animals.feline.every(c => getAnimal(c).species === "cat")) {
 				felines = `a couple different breeds of cat`;
 			} else {
 				felines = `a couple different species of feline`;
@@ -618,99 +657,102 @@ App.Facilities.Farmyard.farmyard = class Farmyard extends App.Facilities.Facilit
 		}
 
 		if (V.farmyardCages === 0) {
-			div.append(`There is enough room in ${V.farmyardName} to build cages to house felines.`);
-			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link("Add cages", () => {
-				cashX(forceNeg(cost), "farmyard");
-				V.farmyardCages = 1;
-				V.PC.skill.engineering += .1;
-
-				this.refresh();
-			}, [], '', `Costs ${cashFormat(cost)}, will incur upkeep costs, and unlocks domestic felines.`), ['indent']);
+			div.append(
+				`There is enough room in ${V.farmyardName} to build cages to house felines.`,
+				makePurchase(`Add cages`, cost, "capEx", {
+					notes: [
+						`will incur upkeep costs`,
+						`unlocks domestic felines`,
+					],
+					handler: () => {
+						V.farmyardCages = 1;
+						V.PC.skill.engineering += .1;
+					},
+				})
+			);
 		} else if (V.farmyardCages === 1) {
-			div.append(App.UI.DOM.passageLink("Cages", "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${FL < 1 ? `empty` : `occupied by ${cats}`}.`);
-
-			if (V.rep > 10000) {
-				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link("Upgrade cages", () => {
-					cashX(forceNeg(cost * 2), "farmyard");
-					V.farmyardCages = 2;
-					V.PC.skill.engineering += .1;
-
-					this.refresh();
-				}, [], '', `Costs ${cashFormat(cost * 2)}, will increase upkeep costs, and unlocks exotic felines.`), ['indent']);
-			} else {
-				App.UI.DOM.appendNewElement("div", div, App.UI.DOM.disabledLink("Upgrade cages",
-					[`You must be more reputable to be able to house exotic felines.`]),
-				['indent']);
-			}
+			div.append(
+				App.UI.DOM.passageLink(`Cages`, "Farmyard Animals"),
+				` have been built in one corner of ${V.farmyardName}, and are currently ${FL < 1 ? `empty` : `occupied by ${cats}`}. `,
+				makePurchase(`Upgrade cages`, cost * 2, "capEx", {
+					notes: [
+						`will increase upkeep cost`,
+						`unlocks exotic feline`,
+					],
+					handler: () => {
+						V.farmyardCages = 2;
+						V.PC.skill.engineering += .1;
+					},
+					prereqs: [
+						[V.rep > 10000, `You must be more reputable to be able to house exotic felines.`],
+					],
+				})
+			);
 		} else if (V.farmyardCages === 2) {
-			div.append(App.UI.DOM.passageLink("Large cages", "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${FL < 1 ? `empty` : `occupied by ${felines}`}.`);
+			div.append(App.UI.DOM.passageLink(`Large cages`, "Farmyard Animals"), ` have been built in one corner of ${V.farmyardName}, and are currently ${FL < 1 ? `empty` : `occupied by ${felines}`}.`);
 		}
 
 		return div;
 	}
 
-	/** @returns {HTMLDivElement} */
-	get removeAnimalHousing() {
-		const div = App.UI.DOM.makeElement("div", null, ['margin-top']);
-
-		const cost = ((V.farmyardKennels + V.farmyardStables + V.farmyardCages) * 5000) * V.upgradeMultiplierArcology;
-
-		if (V.farmyardKennels || V.farmyardStables || V.farmyardCages) {
-			App.UI.DOM.appendNewElement("div", div, App.UI.DOM.link("Remove the animal housing", () => {
-				V.farmyardKennels = 0;
-				V.farmyardStables = 0;
-				V.farmyardCages = 0;
+	/** @returns {DocumentFragment} */
+	get animals() {
+		const frag = new DocumentFragment();
 
-				V.animals = {
-					canine: [],
-					hooved: [],
-					feline: [],
-				};
+		App.UI.DOM.appendNewElement("h2", frag, `Animals`);
 
-				V.active = {
-					canine: null,
-					hooved: null,
-					feline: null,
-				};
+		frag.append(
+			this.kennels,
+			this.stables,
+			this.cages,
+			removeAnimalHousing(),
+		);
 
-				if (V.pit) {
-					V.pit.animal = null;
-				}
+		return frag;
 
-				V.farmyardShows = 0;
-				V.farmyardBreeding = 0;
-				V.farmyardRestraints = 0;
+		function removeAnimalHousing() {
+			const frag = new DocumentFragment();
 
-				cashX(forceNeg(cost), "farmyard");
+			const cost = ((V.farmyardKennels + V.farmyardStables + V.farmyardCages) * 5000) * V.upgradeMultiplierArcology;
 
-				this.refresh();
-			},
-			[], '', `Will cost ${cashFormat(cost)}.`), ['indent']);
-		}
+			if (V.farmyardKennels || V.farmyardStables || V.farmyardCages) {
+				App.UI.DOM.appendNewElement("div", frag, makePurchase(`Remove the animal housing`, cost, "capEx", {
+					handler: () => {
+						V.farmyardKennels = 0;
+						V.farmyardStables = 0;
+						V.farmyardCages = 0;
 
-		return div;
-	}
+						V.animals = {
+							canine: [],
+							hooved: [],
+							feline: [],
+						};
 
-	/** @returns {HTMLDivElement} */
-	get animals() {
-		const div = document.createElement("div");
+						V.active = {
+							canine: null,
+							hooved: null,
+							feline: null,
+						};
 
-		App.UI.DOM.appendNewElement("h2", div, `Animals`);
+						if (V.pit) {
+							V.pit.animal = null;
+						}
 
-		div.append(
-			this.kennels,
-			this.stables,
-			this.cages,
-		);
+						V.farmyardShows = 0;
+						V.farmyardBreeding = 0;
+						V.farmyardRestraints = 0;
+					},
+				}), ['margin-top']);
+			}
 
-		return div;
+			return frag;
+		}
 	}
 
-	/** @returns {HTMLDivElement[]} */
+	/** @returns {DocumentFragment[]} */
 	get customNodes() {
 		return [
 			this.animals,
-			this.removeAnimalHousing,
 		];
 	}
 };
diff --git a/src/facilities/farmyard/food/food.js b/src/facilities/farmyard/food/food.js
index b265d2ffc3cc0744b330c35e1b65d461b23bac8e..50d0c3b770b882e764671af8c398f79bd7f1eb35 100644
--- a/src/facilities/farmyard/food/food.js
+++ b/src/facilities/farmyard/food/food.js
@@ -36,6 +36,22 @@ App.Facilities.Farmyard.foodAmount = function(slave) {
 		}
 	}
 
+	if (slave) {
+		food += slaveProduction(slave);
+
+		if (V.farmyardShows === 1) {
+			food *= 0.5;
+		} else if (V.farmyardShows === 2) {
+			return 0;
+		}
+	} else {
+		food += menialProduction();
+	}
+
+	food = Math.trunc(Math.max(food, 0));
+
+	return food;
+
 	function slaveProduction(slave) {
 		let food = 100;
 
@@ -50,7 +66,7 @@ App.Facilities.Farmyard.foodAmount = function(slave) {
 		} else if (slave.health.tired + 20 >= 90 && !willWorkToDeath(slave)) {
 			slave.devotion -= 10;
 			slave.trust -= 5;
-			food *= 0.9;
+			food *= 0.5;
 		}
 
 		if (slave.muscles > 30) {
@@ -87,22 +103,8 @@ App.Facilities.Farmyard.foodAmount = function(slave) {
 	}
 
 	function menialProduction() {
-		return food * 1.25;
-	}
-
-	if (slave) {
-		food += slaveProduction(slave);
-
-		if (V.farmyardShows) {
-			food *= 0.5;
-		}
-	} else {
-		food += menialProduction();
+		return food * 0.85;
 	}
-
-	food = Math.trunc(Math.max(food, 0));
-
-	return food;
 };
 
 /** The total amount of food produced in a given week. */
diff --git a/src/facilities/farmyard/food/foodMarket.js b/src/facilities/farmyard/food/foodMarket.js
index d1e92b0ff9e202bab9eb344128264a82d0148417..6fcbd010a7d7a2c4a0a5f7dce57c07e889502fb1 100644
--- a/src/facilities/farmyard/food/foodMarket.js
+++ b/src/facilities/farmyard/food/foodMarket.js
@@ -7,7 +7,7 @@ App.UI.foodMarket = function() {
 	frag.append(
 		overview(),
 		buy(),
-		sell(),
+		// sell(),	// TODO: temporarily disabled for balancing
 		remove(),
 	);
 
@@ -28,7 +28,7 @@ App.UI.foodMarket = function() {
 		text.push(`The food market has <span class="food">${massFormat(V.mods.food.amount)}</span> in storage, valued at a total of ${cashFormat(foodValue)}.`);
 
 		if (V.mods.food.amount > consumption) {
-			text.push(`This is enough to provide for ${numberWithPluralOne(V.slaves.length, `slave`)} and ${numberWithPluralOne(citizens, `citizen`)} for about ${numberWithPluralOne(Math.trunc(V.mods.food.amount / consumption), `week`)}.`);
+			text.push(`This is enough to provide for ${numberWithPluralOne(V.slaves.length, `slave`)} and ${numberWithPluralOne(citizens, `citizen`)} for about ${years(Math.trunc(V.mods.food.amount / consumption))}.`);
 		} else if (V.mods.food.amount < consumption) {
 			text.push(`You will need an additional ${massFormat(consumption - V.mods.food.amount)} to provide for ${numberWithPluralOne(V.slaves.length, `slave`)} and ${numberWithPluralOne(citizens, `citizen`)} during the upcoming week.`);
 		}
@@ -39,7 +39,7 @@ App.UI.foodMarket = function() {
 	}
 
 	function buy() {
-		const div = document.createElement("div");
+		const div = App.UI.DOM.makeElement("div", null, ['indent']);
 		const links = [];
 
 		div.append(`Buy `);
@@ -69,7 +69,7 @@ App.UI.foodMarket = function() {
 	}
 
 	function sell() {
-		const div = document.createElement("div");
+		const div = App.UI.DOM.makeElement("div", null, ['indent']);
 		const links = [];
 
 		div.append(`Sell `);
diff --git a/src/facilities/farmyard/food/saProduceFood.js b/src/facilities/farmyard/food/saProduceFood.js
new file mode 100644
index 0000000000000000000000000000000000000000..d5e89f19b891d8ab4d4a6289e0ec380fb9fbef8e
--- /dev/null
+++ b/src/facilities/farmyard/food/saProduceFood.js
@@ -0,0 +1,130 @@
+/**
+ * Returns a string describing the effects of the slave working to produce food.
+ * To see full effects, see farmyardShows.js
+ * @param {App.Entity.SlaveState} slave
+ * @returns {string}
+ */
+App.Facilities.Farmyard.produceFood = function(slave) {
+	const {he, him, his, He, His} = getPronouns(slave);
+
+	const text = [];
+
+	text.push(
+		devotion(),
+		muscles(),
+		weight(),
+		health(),
+		sight(),
+		hearing(),
+		shows(),
+	);
+
+	return text.join(' ');
+
+	function devotion() {
+		if (slave.devotion > 50) {
+			return `${He}'s so devoted to you that ${he} works harder and produces more food.`;
+		} else if (slave.devotion < -50) {
+			return `${He}'s so resistant that ${he} doesn't work as hard, and thus produces less food.`;
+		} else {
+			return `${He} doesn't feel particularly compelled to work hard or slack off and produces an average amount of food.`;
+		}
+	}
+
+	function health() {
+		const text = [];
+
+		text.push(
+			healthCondition(),
+			healthIllness(),
+		);
+
+		return text.join(' ');
+	}
+
+	function healthCondition() {
+		if (slave.health.condition > 50) {
+			return `${His} shining health helps ${him} work harder and longer.`;
+		} else if (slave.health.condition < -50) {
+			return `${His} poor health impedes ${his} ability to work efficiently.`;
+		}
+	}
+
+	function healthIllness() {
+		const text = [];
+		let health = ``;
+		let exhaustion = ``;
+
+		if (slave.health.illness > 0 || slave.health.tired > 60) {
+			if (slave.health.illness === 1) {
+				health = `feeling under the weather`;
+			} else if (slave.health.illness === 2) {
+				health = `a minor illness`;
+			} else if (slave.health.illness === 3) {
+				health = `being sick`;
+			} else if (slave.health.illness === 4) {
+				health = `being very sick`;
+			} else if (slave.health.illness === 5) {
+				health = `a terrible illness`;
+			}
+
+			if (slave.health.tired > 90) {
+				exhaustion = `exhaustion`;
+			} else if (slave.health.tired > 60) {
+				exhaustion = `being tired`;
+			}
+
+			text.push(`${He} performed worse this week due to <span class="health dec">${health}${slave.health.illness > 0 && slave.health.tired > 60 ? ` and ` : ``}${exhaustion}.</span>`);
+
+			text.push(tired());
+		}
+
+		return text;
+	}
+
+	function tired() {
+		if (slaveResting(slave)) {
+			return `${He} spends reduced hours working the soil in order to <span class="health dec">offset ${his} lack of rest.</span>`;
+		} else if (slave.health.tired + 20 >= 90 && !willWorkToDeath(slave)) {
+			return `${He} attempts to refuse work due to ${his} exhaustion, but can do little to stop it or the resulting <span class="trust dec">severe punishment.</span> ${He} <span class="devotion dec">purposefully underperforms,</span> choosing ${his} overall well-being over the consequences, <span class="health dec">greatly reducing yields.</span>`;
+		} else {
+			return `Hours of manual labor quickly add up, leaving ${him} <span class="health dec">physically drained</span> by the end of the day.`;
+		}
+	}
+
+	function muscles() {
+		if (slave.muscles > 50) {
+			return `${His} muscular form helps ${him} work better, increasing ${his} productivity.`;
+		} else if (slave.muscles < -50) {
+			return `${He} is so weak that ${he} is not able to work effectively.`;
+		}
+	}
+
+	function weight() {
+		if (slave.weight > 95) {
+			return `${He} is so overweight that ${he} has to stop every few minutes to catch ${his} breath, and so ${his} productivity suffers. `;
+		}
+	}
+
+	function sight() {
+		if (!canSee(slave)) {
+			return `${His} blindness makes it extremely difficult for ${him} to work, severely limiting ${his} production.`;
+		} else if (!canSeePerfectly(slave)) {
+			return `${His} nearsightedness makes it harder for ${him} to work as hard as ${he} otherwise would.`;
+		}
+	}
+
+	function hearing() {
+		if (slave.hears === -1) {
+			return `${He} is hard-of-hearing, which gets in the way of ${his} work whenever ${he} misses directions${S.Farmer ? ` from ${S.Farmer.slaveName}` : ``}.`;
+		} else if (slave.hears < -1) {
+			return `${He} is deaf, which gets in the way of ${his} work whenever ${he} misses directions${S.Farmer ? ` from ${S.Farmer.slaveName}` : ``}.`;
+		}
+	}
+
+	function shows() {
+		if (V.farmyardShows > 0) {
+			return `Since ${he} also has to put on shows for your citizens, ${he} can only work on food production for half of ${his} shift, cutting down on the amount of food ${he} would have otherwise produced.`;
+		}
+	}
+};
diff --git a/src/facilities/farmyard/shows/farmShowsIncome.js b/src/facilities/farmyard/shows/farmShowsIncome.js
index 693f3eca2a9e6d22f3b783c89263f09afb3600e0..ee6d2b6b21027f2531e7e918f20a101f9c48613b 100644
--- a/src/facilities/farmyard/shows/farmShowsIncome.js
+++ b/src/facilities/farmyard/shows/farmShowsIncome.js
@@ -122,17 +122,19 @@ App.Facilities.Farmyard.farmShowsIncome = function(slave) {
 
 		if (arcology.FSPaternalist !== "unset") {
 			if (V.seeBestiality) {
-				if (V.farmyardBreeding) {
-					if (V.farmyardRestraints) {
-						cash *= 0.5;
+				if (!V.policies.bestialityOpenness) {
+					if (V.farmyardBreeding) {
+						if (V.farmyardRestraints) {
+							cash *= 0.5;
+						} else {
+							cash *= 0.7;
+						}
 					} else {
-						cash *= 0.7;
-					}
-				} else {
-					if (V.farmyardRestraints) {
-						cash *= 0.8;
-					} else {
-						cash *= 0.9;
+						if (V.farmyardRestraints) {
+							cash *= 0.8;
+						} else {
+							cash *= 0.9;
+						}
 					}
 				}
 			}
@@ -455,6 +457,10 @@ App.Facilities.Farmyard.farmShowsIncome = function(slave) {
 			cash *= 1.75;
 		}
 
+		if (V.farmyardShows < 2) {
+			cash *= 0.5;
+		}
+
 		setSlaveDevotion();
 		setSlaveTrust();
 
diff --git a/src/facilities/farmyard/shows/saFarmyardShows.js b/src/facilities/farmyard/shows/saFarmyardShows.js
index c0551e09d405870a698f6a1c4125c8b6453f7950..556140b72adee13453f069874f439507667757da 100644
--- a/src/facilities/farmyard/shows/saFarmyardShows.js
+++ b/src/facilities/farmyard/shows/saFarmyardShows.js
@@ -1,5 +1,5 @@
 /**
- * Returns a string describing the effects of the slave putting on shows only
+ * Returns a string describing the effects of the slave putting on shows.
  * To see full effects, see farmyardShows.js
  * @param {App.Entity.SlaveState} slave
  * @returns {string}
@@ -13,406 +13,458 @@ App.Facilities.Farmyard.putOnShows = function(slave) {
 
 	const heavyMods = SlaveStatsChecker.modScore(slave).total > 20;
 
-	const r = [];
+	const text = [];
 
 	if (V.seeBestiality) {
 		seX(slave, "bestiality", "animal", "bestiality", random(35, 65));
 	}
 
-	r.push(`${He} also puts on shows with animals this week.`);
+	text.push(
+		`${He} ${V.farmyardShows < 2 ? `also ` : ``}puts on shows with animals this week.`,
+		FSEffects(),
+		virginity(),
+		careers(),
+		prestige(),
+		health(),
+		face(),
+		devotion(),
+		weight(),
+		muscles(),
+		eyesight(),
+		hearing(),
+		pregnancy(),
+		tiredness(),
+		intelligence(),
+		energy(),
+		fetish(),
+		behavioralFlaw(),
+		behavioralQuirk(),
+		sexualFlaw(),
+		sexualQuirk(),
+		openness(),
+		rival(),
+	);
 
-	// FS
+	incomeStats.income += Math.trunc(App.Facilities.Farmyard.farmShowsIncome(slave));
 
-	if (arcology.FSSupremacist !== "unset") {
-		if (isSuperiorRace(slave)) {
-			if (V.seeBestiality) {
-				r.push(`Society <span class="reputation dec">disapproves</span> of your allowing a member of the elite race to be degraded in such a fashion, and thus ${he} didn't earn as much.`);
+	return text.join(' ');
+
+	function FSEffects() {
+		const text = [];
+
+		if (arcology.FSSupremacist !== "unset") {
+			if (isSuperiorRace(slave)) {
+				if (V.seeBestiality) {
+					text.push(`Society <span class="reputation dec">disapproves</span> of your allowing a member of the elite race to be degraded in such a fashion, and thus ${he} didn't earn as much.`);
+				} else {
+					text.push(`Since ${arcology.FSSupremacistRace} slaves are in fashion, ${he} attracts a little more attention than if ${he} wasn't ${arcology.FSSupremacistRace}.`);
+				}
 			} else {
-				r.push(`Since ${arcology.FSSupremacistRace} slaves are in fashion, ${he} attracts a little more attention than if ${he} wasn't ${arcology.FSSupremacistRace}.`);
+				text.push(`Society doesn't disapprove of ${him} not being ${arcology.FSSupremacistRace}, but ${he} doesn't earn as much as ${he} would if ${he} was.`);
 			}
-		} else {
-			r.push(`Society doesn't disapprove of ${him} not being ${arcology.FSSupremacistRace}, but ${he} doesn't earn as much as ${he} would if ${he} was.`);
 		}
-	}
 
-	if (arcology.FSSubjugationist !== "unset") {
-		if (isInferiorRace(slave)) {
-			if (V.seeBestiality) {
-				r.push(`Society <span class="reputation inc">approves</span> of the degradation you submit your ${arcology.FSSubjugationistRace} slaves to, and so ${he} earns you a bit more.`);
+		if (arcology.FSSubjugationist !== "unset") {
+			if (isInferiorRace(slave)) {
+				if (V.seeBestiality) {
+					text.push(`Society <span class="reputation inc">approves</span> of the degradation you submit your ${arcology.FSSubjugationistRace} slaves to, and so ${he} earns you a bit more.`);
+				} else {
+					// FIXME: Type 'FC.NoObject' is not assignable to type 'string'.
+					text.push(`Fewer people want to go see ${addA(arcology.FSSubjugationistRace)} slave put on a show, and so ${he} doesn't earn as much as ${he} otherwise could.`);
+				}
 			} else {
-				// FIXME: Type 'FC.NoObject' is not assignable to type 'string'.
-				r.push(`Fewer people want to go see ${addA(arcology.FSSubjugationistRace)} slave put on a show, and so ${he} doesn't earn as much as ${he} otherwise could.`);
-			}
-		} else {
-			if (V.seeBestiality) {
-				r.push(`Society doesn't disapprove of ${him} not being ${arcology.FSSubjugationistRace}, but ${he} doesn't earn as much as ${he} would if ${he} was.`);
+				if (V.seeBestiality) {
+					text.push(`Society doesn't disapprove of ${him} not being ${arcology.FSSubjugationistRace}, but ${he} doesn't earn as much as ${he} would if ${he} was.`);
+				}
 			}
 		}
-	}
 
-	if (arcology.FSRepopulationFocus !== "unset") {
-		if (isPreg(slave)) {
-			if (slave.eggType === "human") {
-				r.push(`Society <span class="reputation inc">greatly approves</span> of your having pregnant slaves ${V.seeBestiality ? `have sex` : `put on shows`} with animals.`);
-			} else {
-				r.push(`Society is <span class="reputation dec">disgusted</span> by ${his} pregnancy when they realize that what it is in ${his} womb is not human.`);
+		if (arcology.FSRepopulationFocus !== "unset") {
+			if (isPreg(slave)) {
+				if (slave.eggType === "human") {
+					text.push(`Society <span class="reputation inc">greatly approves</span> of your having pregnant slaves ${V.seeBestiality ? `have sex` : `put on shows`} with animals.`);
+				} else {
+					text.push(`Society is <span class="reputation dec">disgusted</span> by ${his} pregnancy when they realize that what it is in ${his} womb is not human.`);
+				}
 			}
 		}
-	}
 
-	if (arcology.FSRestart !== "unset") {
-		if (isPreg(slave)) {
-			if (isEliteBreeder(slave)) {
-				if (slave.eggType === "human") {
-					r.push(`Society is <span class="reputation dec">horrified</span> by the fact that you would dare defile a slave deemed fit for humanity's revival in such a manner, especially one that is carrying the future of the planet.`);
+		if (arcology.FSRestart !== "unset") {
+			if (isPreg(slave)) {
+				if (isEliteBreeder(slave)) {
+					if (slave.eggType === "human") {
+						text.push(`Society is <span class="reputation dec">horrified</span> by the fact that you would dare defile a slave deemed fit for humanity's revival in such a manner, especially one that is carrying the future of the planet.`);
+					} else {
+						text.push(`Society is <span class="reputation dec">absolutely repulsed</span> by the fact that you would dare defile a slave deemed fit for humanity's revival in such a manner, especially when they learn that what is in ${his} womb is not even human.`);
+					}
 				} else {
-					r.push(`Society is <span class="reputation dec">absolutely repulsed</span> by the fact that you would dare defile a slave deemed fit for humanity's revival in such a manner, especially when they learn that what is in ${his} womb is not even human.`);
+					if (slave.eggType === "human") {
+						text.push(`Society is <span class="reputation dec">extremely disgusted</span> by ${his} pregnancy and the fact that you would have ${him} ${V.seeBestiality ? `have sex` : `put on shows`} with animals while sporting a baby bump.`);
+					} else {
+						text.push(`Society is disgusted by ${his} pregnancy until they learn that what is in ${his} womb is not human.`);
+					}
 				}
 			} else {
-				if (slave.eggType === "human") {
-					r.push(`Society is <span class="reputation dec">extremely disgusted</span> by ${his} pregnancy and the fact that you would have ${him} ${V.seeBestiality ? `have sex` : `put on shows`} with animals while sporting a baby bump.`);
-				} else {
-					r.push(`Society is disgusted by ${his} pregnancy until they learn that what is in ${his} womb is not human.`);
+				if (V.seeBestiality && isEliteBreeder(slave)) {
+					text.push(`Society is <span class="reputation dec">heavily disapproving</span> of the fact that you would dare defile a slave deemed fit for humanity's revival in such a manner.`);
 				}
 			}
-		} else {
-			if (V.seeBestiality && isEliteBreeder(slave)) {
-				r.push(`Society is <span class="reputation dec">heavily disapproving</span> of the fact that you would dare defile a slave deemed fit for humanity's revival in such a manner.`);
-			}
 		}
-	}
 
-	if (arcology.FSGenderRadicalist !== "unset") {
-		if (slave.dick > 0) {
-			r.push(`${His} patrons <span class="reputation inc">approve</span> of the fact that ${he} has a dick.`);
-		} else {
-			r.push(`${His} patrons <span class="reputation dec">are disappointed</span> that ${he} doesn't have a dick.`);
+		if (arcology.FSGenderRadicalist !== "unset") {
+			if (slave.dick > 0) {
+				text.push(`${His} patrons <span class="reputation inc">approve</span> of the fact that ${he} has a dick.`);
+			} else {
+				text.push(`${His} patrons <span class="reputation dec">are disappointed</span> that ${he} doesn't have a dick.`);
+			}
 		}
-	}
 
-	if (arcology.FSGenderFundamentalist !== "unset") {
-		if (isPreg(slave) || App.Data.misc.fakeBellies.includes(slave.bellyAccessory)) {
-			r.push(`${His} viewers <span class="reputation inc">approve</span> of the fact that ${he} is sporting a baby bump${App.Data.misc.fakeBellies.includes(slave.bellyAccessory) ? `, even though ${hers} isn't real` : ``}.`);
-		} else {
-			r.push(`${His} viewers <span class="reputation dec">are disappointed</span> that ${he} isn't pregnant.`);
+		if (arcology.FSGenderFundamentalist !== "unset") {
+			if (isPreg(slave) || App.Data.misc.fakeBellies.includes(slave.bellyAccessory)) {
+				text.push(`${His} viewers <span class="reputation inc">approve</span> of the fact that ${he} is sporting a baby bump${App.Data.misc.fakeBellies.includes(slave.bellyAccessory) ? `, even though ${hers} isn't real` : ``}.`);
+			} else {
+				text.push(`${His} viewers <span class="reputation dec">are disappointed</span> that ${he} isn't pregnant.`);
+			}
 		}
-	}
 
-	if (arcology.FSPaternalist !== "unset") {
-		if (V.seeBestiality) {
-			if (V.farmyardBreeding) {
-				if (V.farmyardRestraints) {
-					r.push(`Your citizens are <span class="reputation dec">extremely disapproving</span> of the fact that you would allow your slaves to be treated as nothing more than a bound breeding toy for your animals.`);
-				} else {
-					r.push(`Your citizens are <span class="reputation dec">highly disapproving</span> of the fact that you would allow your slaves to be treated as nothing more than a breeding toy for your animals.`);
-				}
-			} else {
-				if (V.farmyardRestraints) {
-					r.push(`Your citizens are <span class="reputation dec">very disapproving</span> of the fact that you would allow your slaves to be treated as nothing more than a bound toy for your animals.`);
+		if (arcology.FSPaternalist !== "unset") {
+			if (V.seeBestiality) {
+				if (V.policies.bestialityOpenness) {
+					text.push(`Your citizens would normally disapprove of your using slaves as toys for your animals, but the policy you enacted encouraging bestiality, combined with some clever, subtle advertising, leads them to see nothing wrong with it.`);
 				} else {
-					r.push(`Your citizens are <span class="reputation dec">disapproving</span> of the fact that you would allow your slaves to be treated as nothing more than a toy for your animals.`);
+					if (V.farmyardBreeding) {
+						if (V.farmyardRestraints) {
+							text.push(`Your citizens are <span class="reputation dec">extremely disapproving</span> of the fact that you would allow your slaves to be treated as nothing more than a bound breeding toy for your animals.`);
+						} else {
+							text.push(`Your citizens are <span class="reputation dec">highly disapproving</span> of the fact that you would allow your slaves to be treated as nothing more than a breeding toy for your animals.`);
+						}
+					} else {
+						if (V.farmyardRestraints) {
+							text.push(`Your citizens are <span class="reputation dec">very disapproving</span> of the fact that you would allow your slaves to be treated as nothing more than a bound toy for your animals.`);
+						} else {
+							text.push(`Your citizens are <span class="reputation dec">disapproving</span> of the fact that you would allow your slaves to be treated as nothing more than a toy for your animals.`);
+						}
+					}
 				}
 			}
 		}
-	}
 
-	if (arcology.FSDegradationist !== "unset") {
-		if (V.seeBestiality) {
-			if (V.farmyardBreeding) {
-				if (V.farmyardRestraints) {
-					r.push(`Your citizens are <span class="reputation dec">extremely approving</span> of the fact that you would allow your slaves to be treated as nothing more than a bound breeding toy for your animals.`);
-				} else {
-					r.push(`Your citizens are <span class="reputation dec">highly approving</span> of the fact that you would allow your slaves to be treated as nothing more than a breeding toy for your animals.`);
-				}
-			} else {
-				if (V.farmyardRestraints) {
-					r.push(`Your citizens are <span class="reputation dec">very approving</span> of the fact that you would allow your slaves to be treated as nothing more than a bound toy for your animals.`);
+		if (arcology.FSDegradationist !== "unset") {
+			if (V.seeBestiality) {
+				if (V.farmyardBreeding) {
+					if (V.farmyardRestraints) {
+						text.push(`Your citizens are <span class="reputation dec">extremely approving</span> of the fact that you would allow your slaves to be treated as nothing more than a bound breeding toy for your animals.`);
+					} else {
+						text.push(`Your citizens are <span class="reputation dec">highly approving</span> of the fact that you would allow your slaves to be treated as nothing more than a breeding toy for your animals.`);
+					}
 				} else {
-					r.push(`Your citizens are <span class="reputation dec">approving</span> of the fact that you would allow your slaves to be treated as nothing more than a toy for your animals.`);
+					if (V.farmyardRestraints) {
+						text.push(`Your citizens are <span class="reputation dec">very approving</span> of the fact that you would allow your slaves to be treated as nothing more than a bound toy for your animals.`);
+					} else {
+						text.push(`Your citizens are <span class="reputation dec">approving</span> of the fact that you would allow your slaves to be treated as nothing more than a toy for your animals.`);
+					}
 				}
 			}
 		}
-	}
 
-	if (arcology.FSBodyPurist !== "unset") {
-		if (SlaveStatsChecker.isModded(slave)) {
-			r.push(`The members of the audience <span class="reputation dec">disapprove</span> that you would use a slave with ${heavyMods ? `such heavy` : ``} modifications to put on shows.`);
+		if (arcology.FSBodyPurist !== "unset") {
+			if (SlaveStatsChecker.isModded(slave)) {
+				text.push(`The members of the audience <span class="reputation dec">disapprove</span> that you would use a slave with ${heavyMods ? `such heavy` : ``} modifications to put on shows.`);
+			}
 		}
-	}
 
-	if (arcology.FSTransformationFetishist !== "unset") {
-		if (SlaveStatsChecker.isModded(slave)) {
-			r.push(`The members of the audience <span class="reputation inc">approve</span> that you would use a slave with ${heavyMods ? `such heavy` : ``} modifications to put on shows.`);
+		if (arcology.FSTransformationFetishist !== "unset") {
+			if (SlaveStatsChecker.isModded(slave)) {
+				text.push(`The members of the audience <span class="reputation inc">approve</span> that you would use a slave with ${heavyMods ? `such heavy` : ``} modifications to put on shows.`);
+			}
 		}
-	}
 
-	if (arcology.FSYouthPreferentialist !== "unset") {
-		if (isYoung(slave)) {
-			r.push(`${arcology.name}'s citizens <span class="reputation inc">approve</span> of your using young slaves to put on shows.`);
-		} else {
-			r.push(`${arcology.name}'s citizens <span class="reputation dec">disapprove</span> of your using such old slaves to put on shows.`);
+		if (arcology.FSYouthPreferentialist !== "unset") {
+			if (isYoung(slave)) {
+				text.push(`${arcology.name}'s citizens <span class="reputation inc">approve</span> of your using young slaves to put on shows.`);
+			} else {
+				text.push(`${arcology.name}'s citizens <span class="reputation dec">disapprove</span> of your using such old slaves to put on shows.`);
+			}
 		}
-	}
 
-	if (arcology.FSMaturityPreferentialist !== "unset") {
-		if (isYoung(slave)) {
-			r.push(`${arcology.name}'s citizens <span class="reputation inc">approve</span> of your using mature slaves to put on shows.`);
-		} else {
-			r.push(`${arcology.name}'s citizens <span class="reputation dec">disapprove</span> of your using such young slaves to put on shows.`);
+		if (arcology.FSMaturityPreferentialist !== "unset") {
+			if (isYoung(slave)) {
+				text.push(`${arcology.name}'s citizens <span class="reputation inc">approve</span> of your using mature slaves to put on shows.`);
+			} else {
+				text.push(`${arcology.name}'s citizens <span class="reputation dec">disapprove</span> of your using such young slaves to put on shows.`);
+			}
 		}
-	}
 
-	if (arcology.FSSlimnessEnthusiast !== "unset") {
-		if (isSlim(slave)) {
-			r.push(`${His} slim body <span class="reputation inc">attracts a wider audience.</span>`);
-		} else {
-			r.push(`Society finds your using a slave with such a flabby body <span class="reputation dec">disgusting.</span>`);
+		if (arcology.FSSlimnessEnthusiast !== "unset") {
+			if (isSlim(slave)) {
+				text.push(`${His} slim body <span class="reputation inc">attracts a wider audience.</span>`);
+			} else {
+				text.push(`Society finds your using a slave with such a flabby body <span class="reputation dec">disgusting.</span>`);
+			}
 		}
-	}
 
-	if (arcology.FSAssetExpansionist !== "unset") {
-		if (isStacked(slave)) {
-			r.push(`Society <span class="reputation inc">approves</span> of the fact that you respect their ideals in using a slave with larger assets.`);
+		if (arcology.FSAssetExpansionist !== "unset") {
+			if (isStacked(slave)) {
+				text.push(`Society <span class="reputation inc">approves</span> of the fact that you respect their ideals in using a slave with larger assets.`);
+			}
 		}
-	}
 
-	if (arcology.FSPastoralist !== "unset") {
-		if (slave.boobs >= 1000) {
-			r.push(`The fact that ${slave.slaveName} has such large udders <span class="reputation inc">pleases your citizens.</span>`);
+		if (arcology.FSPastoralist !== "unset") {
+			if (slave.boobs >= 1000) {
+				text.push(`The fact that ${slave.slaveName} has such large udders <span class="reputation inc">pleases your citizens.</span>`);
+			}
+
+			if (slave.lactation > 0) {
+				text.push(`Your citizens ${slave.boobs >= 1000 ? `also ` : ``}<span class="reputation inc">approve</span> of the fact that ${he} is visibly lactating.`);
+			}
 		}
 
-		if (slave.lactation > 0) {
-			r.push(`Your citizens ${slave.boobs >= 1000 ? `also ` : ``}<span class="reputation inc">approve</span> of the fact that ${he} is visibly lactating.`);
+		if (arcology.FSPhysicalIdealist !== "unset") {
+			if (genderLawPass(slave)) {
+				text.push(`The fact that ${slave.slaveName} has what is considered the ideal form also <span class="reputation inc">helps ${him} attract attention,</span> and so ${he} earns a bit more.`);
+			} else {
+				text.push(`${His} form isn't exactly what ${arcology.name}'s citizens consider ideal, and so ${he} doesn't <span class="reputation dec">earn as much</span> as ${he} could have otherwise.`);
+			}
 		}
-	}
 
-	if (arcology.FSPhysicalIdealist !== "unset") {
-		if (genderLawPass(slave)) {
-			r.push(`The fact that ${slave.slaveName} has what is considered the ideal form also <span class="reputation inc">helps ${him} attract attention,</span> and so ${he} earns a bit more.`);
-		} else {
-			r.push(`${His} form isn't exactly what ${arcology.name}'s citizens consider ideal, and so ${he} doesn't <span class="reputation dec">earn as much</span> as ${he} could have otherwise.`);
+		if (arcology.FSHedonisticDecadence !== "unset") {
+			if (slave.weight > 10) {
+				text.push(`Since ${slave.slaveName} is large enough to please ${arcology.name}'s citizens, ${he} earns slightly more.`);
+			} else {
+				text.push(`${He} doesn't earn quite as much ${he} would have if ${he} was a bit larger in size.`);
+			}
 		}
-	}
 
-	if (arcology.FSHedonisticDecadence !== "unset") {
-		if (slave.weight > 10) {
-			r.push(`Since ${slave.slaveName} is large enough to please ${arcology.name}'s citizens, ${he} earns slightly more.`);
-		} else {
-			r.push(`${He} doesn't earn quite as much ${he} would have if ${he} was a bit larger in size.`);
+		if (arcology.FSPetiteAdmiration !== "unset") {
+			if (heightPass(slave)) {
+				text.push(`The fact that you are using such small slaves <span class="reputation inc">pleases your citizens.</span>`);
+			} else {
+				text.push(`The fact that you are using such small slaves <span class="reputation dec">displeases your citizens.</span>`);
+			}
 		}
-	}
 
-	if (arcology.FSPetiteAdmiration !== "unset") {
-		if (heightPass(slave)) {
-			r.push(`The fact that you are using such small slaves <span class="reputation inc">pleases your citizens.</span>`);
-		} else {
-			r.push(`The fact that you are using such small slaves <span class="reputation dec">displeases your citizens.</span>`);
+		if (arcology.FSStatuesqueGlorification !== "unset") {
+			if (heightPass(slave)) {
+				text.push(`Your citizens <span class="reputation inc">approve</span> of your using such statuesque slaves for putting on shows.`);
+			} else {
+				text.push(`Your citizens <span class="reputation dec">disapprove</span> of your not using taller slaves for putting on shows.`);
+			}
 		}
+
+		return text.join(' ');
 	}
 
-	if (arcology.FSStatuesqueGlorification !== "unset") {
-		if (heightPass(slave)) {
-			r.push(`Your citizens <span class="reputation inc">approve</span> of your using such statuesque slaves for putting on shows.`);
-		} else {
-			r.push(`Your citizens <span class="reputation dec">disapprove</span> of your not using taller slaves for putting on shows.`);
+	function virginity() {
+		if (V.seeBestiality) {
+			if (slave.devotion > 50 && canBeDeflowered(slave)) {
+				return `${slave.slaveName} promised the crowd ${he} would allow one of your animals to deflower ${him} onstage <span class="cash inc">if they all donated enough ¤,</span> and ${he} stayed true to ${his} word – <span class="virginity loss">${his} tight little ${slave.vagina === 0 ? `pussy` : `ass`} has been broken in.</span>`;
+			}
 		}
 	}
 
-	// Virginity
+	function careers() {
+		const text = [];
 
-	if (V.seeBestiality) {
-		if (slave.devotion > 50 &&
-			(slave.vagina === 0 && canDoVaginal(slave)) ||
-			(slave.anus === 0 && canDoAnal(slave))) {
-			r.push(`${slave.slaveName} promised the crowd ${he} would allow one of your animals to deflower ${him} onstage <span class="cash inc">if they all donated enough ¤,</span> and ${he} stayed true to ${his} word – <span class="virginity loss">${his} tight little ${slave.vagina === 0 ? `pussy` : `ass`} has been broken in.</span>`);
+		if (App.Data.Careers.General.entertainment.includes(slave.career)) {
+			text.push(`${He} has experience with putting on shows from ${his} life before ${he} was a slave, making ${him} more effective at putting on shows.`);
 		}
-	}
 
-	// Careers
+		if (App.Data.Careers.Leader.farmer.includes(slave.career)) {
+			text.push(`${He} ${App.Data.Careers.General.entertainment.includes(slave.career) ? `also` : ``} has experience in working with animals from ${his} life before ${he} was a slave, making ${him} more effective at putting on shows.`);
+		}
 
-	if (App.Data.Careers.General.entertainment.includes(slave.career)) {
-		r.push(`${He} has experience with putting on shows from ${his} life before ${he} was a slave, making ${him} more effective at putting on shows.`);
+		return text.join(' ');
 	}
 
-	if (App.Data.Careers.Leader.farmer.includes(slave.career)) {
-		r.push(`${He} ${App.Data.Careers.General.entertainment.includes(slave.career) ? `also` : ``} has experience in working with animals from ${his} life before ${he} was a slave, making ${him} more effective at putting on shows.`);
-	}
+	function prestige() {
+		const text = [];
 
-	// Prestige
+		if (slave.prestige === 1) {
+			text.push(`Your citizens are so eager to see someone they recognize ${V.seeBestiality ? `be ${V.farmyardBreeding ? `bred` : `rutted`} by an animal` : `put on shows with an animal`} that they are willing to pay a bit more.`);
+		} else if (slave.prestige === 2) {
+			text.push(`Your citizens are so eager to see someone well-known ${V.seeBestiality ? `be ${V.farmyardBreeding ? `bred` : `rutted`} by an animal` : `put on shows with an animal`} that they are willing to pay a fair bit more.`);
+		} else if (slave.prestige === 3) {
+			text.push(`Your citizens are so eager to see someone so famous ${V.seeBestiality ? `be ${V.farmyardBreeding ? `bred` : `rutted`} by an animal` : `put on shows with an animal`} that they are willing to pay much more.`);
+		}
 
-	if (slave.prestige === 1) {
-		r.push(`Your citizens are so eager to see someone they recognize ${V.seeBestiality ? `be ${V.farmyardBreeding ? `bred` : `rutted`} by an animal` : `put on shows with an animal`} that they are willing to pay a bit more.`);
-	} else if (slave.prestige === 2) {
-		r.push(`Your citizens are so eager to see someone well-known ${V.seeBestiality ? `be ${V.farmyardBreeding ? `bred` : `rutted`} by an animal` : `put on shows with an animal`} that they are willing to pay a fair bit more.`);
-	} else if (slave.prestige === 3) {
-		r.push(`Your citizens are so eager to see someone so famous ${V.seeBestiality ? `be ${V.farmyardBreeding ? `bred` : `rutted`} by an animal` : `put on shows with an animal`} that they are willing to pay much more.`);
-	}
+		if (slave.porn.prestige === 1) {
+			text.push(`${He} earns a bit more because some of your citizens already know ${him} from porn.`);
+		} else if (slave.porn.prestige === 2) {
+			text.push(`${He} earns quite a bit more because a lot of your citizens already know ${him} from porn.`);
+		} else if (slave.porn.prestige === 3) {
+			text.push(`${He} earns a lot more because ${he} is so famous from porn.`);
+		}
 
-	if (slave.porn.prestige === 1) {
-		r.push(`${He} earns a bit more because some of your citizens already know ${him} from porn.`);
-	} else if (slave.porn.prestige === 2) {
-		r.push(`${He} earns quite a bit more because a lot of your citizens already know ${him} from porn.`);
-	} else if (slave.porn.prestige === 3) {
-		r.push(`${He} earns a lot more because ${he} is so famous from porn.`);
+		return text.join(' ');
 	}
 
-	// Health
-
-	if (slave.health.condition > 50) {
-		r.push(`${He} is in such excellent health that ${he} is able to put on longer and more energetic shows, earning you more.`);
-	} else if (slave.health.condition < -20) {
-		r.push(`${His} poor health negatively affects ${his} ability to put on good shows, cutting into your profits.`);
+	function health() {
+		if (slave.health.condition > 50) {
+			return `${He} is in such excellent health that ${he} is able to put on longer and more energetic shows, earning you more.`;
+		} else if (slave.health.condition < -20) {
+			return `${His} poor health negatively affects ${his} ability to put on good shows, cutting into your profits.`;
+		}
 	}
 
 	// TODO: add checks for family and relationships
-
-	if (slave.face > 40) {
-		r.push(`${He} is so ${beautyString} that ${his} audience is willing to pay more to watch ${him} put on shows.`);
-	} else if (slave.face > 10) {
-		r.push(`${He} is so ${prettyString} that ${his} audience is willing to pay more to watch ${him} put on shows.`);
-	} else if (slave.face < -10) {
-		r.push(`${His} audience isn't willing to pay as much because of how unattractive ${his} face is.`);
-	} else if (slave.face < -40) {
-		r.push(`${His} audience isn't willing to pay as much because of how hard ${his} face is to look at.`);
+	function face() {
+		if (slave.face > 40) {
+			return `${He} is so ${beautyString} that ${his} audience is willing to pay more to watch ${him} put on shows.`;
+		} else if (slave.face > 10) {
+			return `${He} is so ${prettyString} that ${his} audience is willing to pay more to watch ${him} put on shows.`;
+		} else if (slave.face < -10) {
+			return `${His} audience isn't willing to pay as much because of how unattractive ${his} face is.`;
+		} else if (slave.face < -40) {
+			return `${His} audience isn't willing to pay as much because of how hard ${his} face is to look at.`;
+		}
 	}
 
 	// TODO: incorporate seeBestiality, breeding, and restraints
-	if (slave.devotion > 50) {
-		if (slave.trust > 50) {
-			r.push(`${He} is so devoted that ${he} works ${his} hardest to make ${his} show a good one.`);
-		} else if (slave.trust < -50) {
-			r.push(`${He} is both devoted to you and terrified of you, so ${he} tries ${his} best to make ${his} show a good one.`);
-		}
-	} else if (slave.devotion < -50) {
-		if (slave.trust > 50) {
-			r.push(`${slave.slaveName} purposefully does the bare minimum ${he} can get away with to spite you.`);
-		} else if (slave.trust < -50) {
-			r.push(`${slave.slaveName} refuses to do anything without punishment, which is evident from ${his} meager earnings.`);
+	function devotion() {
+		if (slave.devotion > 50) {
+			if (slave.trust > 50) {
+				return `${He} is so devoted that ${he} works ${his} hardest to make ${his} show a good one.`;
+			} else if (slave.trust < -50) {
+				return `${He} is both devoted to you and terrified of you, so ${he} tries ${his} best to make ${his} show a good one.`;
+			}
+		} else if (slave.devotion < -50) {
+			if (slave.trust > 50) {
+				return `${slave.slaveName} purposefully does the bare minimum ${he} can get away with to spite you.`;
+			} else if (slave.trust < -50) {
+				return `${slave.slaveName} refuses to do anything without punishment, which is evident from ${his} meager earnings.`;
+			}
 		}
 	}
 
-	if (slave.weight > 30) {
-		if (arcology.FSHedonisticDecadence === "unset") {
-			r.push(`Your citizens are not willing to pay as much to see such a fat slave put on shows, so ${he} loses some income.`);
+	function weight() {
+		if (slave.weight > 30) {
+			if (arcology.FSHedonisticDecadence === "unset") {
+				return `Your citizens are not willing to pay as much to see such a fat slave put on shows, so ${he} loses some income.`;
+			}
+		} else if (slave.weight < -30) {
+			return `Your citizens don't like watching such a sickly-looking slaves put on shows, so ${he} loses some income.`;
 		}
-	} else if (slave.weight < -30) {
-		r.push(`Your citizens don't like watching such a sickly-looking slaves put on shows, so ${he} loses some income.`);
 	}
 
-	if (slave.muscles < -30) {
-		r.push(`${slave.slaveName} is so weak that ${he} cannot even properly handle the animals ${he}'s assigned to ${V.seeBestiality ? `fuck` : `work with`}, and isn't able to put on any sort of meaningful show.`);
+	function muscles() {
+		if (slave.muscles < -30) {
+			return `${slave.slaveName} is so weak that ${he} cannot even properly handle the animals ${he}'s assigned to ${V.seeBestiality ? `fuck` : `work with`}, and isn't able to put on any sort of meaningful show.`;
+		}
 	}
 
-	if (!canSeePerfectly(slave)) {
-		r.push(`${His} ${!canSee(slave) ? `blindness makes it impossible` : `nearsightedness makes it harder`} for ${him} to see what ${he}'s doing, affecting ${his} ability to put on a good show.`);
+	function eyesight() {
+		if (!canSeePerfectly(slave)) {
+			return `${His} ${!canSee(slave) ? `blindness makes it impossible` : `nearsightedness makes it harder`} for ${him} to see what ${he}'s doing, affecting ${his} ability to put on a good show.`;
+		}
 	}
 
-	if (slave.hears < 0) {
-		r.push(`${His} ${slave.hears < -1 ? `lack of` : `poor`} hearing makes it difficult for ${him} to hear what ${his} audience wants from ${him}, which really affects ${his} earnings.`);
+	function hearing() {
+		if (slave.hears < 0) {
+			return `${His} ${slave.hears < -1 ? `lack of` : `poor`} hearing makes it difficult for ${him} to hear what ${his} audience wants from ${him}, which really affects ${his} earnings.`;
+		}
 	}
 
-	if (isPreg(slave)) {
-		r.push(`${His}${slave.bellyPreg > 100000 ? ` advanced` : ``} pregnancy makes it more difficult for him to effectively put on a good show.`);
+	function pregnancy() {
+		if (isPreg(slave)) {
+			return `${His}${slave.bellyPreg > 100000 ? ` advanced` : ``} pregnancy makes it more difficult for him to effectively put on a good show.`;
+		}
 	}
 
-	if (slave.health.tired > 60) {
-		r.push(`${He} is so tired that the energy in ${his} shows is basically nonexistent, affecting ${his} profits.`);
+	function tiredness() {
+		if (slave.health.tired > 60) {
+			return `${He} is so tired that the energy in ${his} shows is basically nonexistent, affecting ${his} profits.`;
+		}
 	}
 
-	if (slave.intelligence > 50) {
-		r.push(`Because ${he} is so intelligent, ${he} is able to tailor ${his} shows to ${his} audience, helping ${him} bring in more in profits.`);
-	} else if (slave.intelligence < -50) {
-		r.push(`${He} is so slow that all ${he} can really do is just ${V.seeBestiality ? `lie there and take it` : `put on the most basic of moves`}, which your audience finds dull and uninteresting.`);
+	function intelligence() {
+		if (slave.intelligence > 50) {
+			return `Because ${he} is so intelligent, ${he} is able to tailor ${his} shows to ${his} audience, helping ${him} bring in more in profits.`;
+		} else if (slave.intelligence < -50) {
+			return `${He} is so slow that all ${he} can really do is just ${V.seeBestiality ? `lie there and take it` : `put on the most basic of moves`}, which your audience finds dull and uninteresting.`;
+		}
 	}
 
-	if (slave.energy > 95) {
-		r.push(`The fact that ${he} is a nymphomaniac helps ${him} to go for longer, allowing ${him} to really put on an amazing show.`);
-	} else if (slave.energy > 80) {
-		r.push(`The fact that ${his} sex drive is so powerful helps ${him} to really put on good shows.`);
-	} else if (slave.energy > 60) {
-		r.push(`The fact that ${his} sex drive is so good helps ${him} to put on good shows.`);
-	} else if (slave.energy > 40) {
-		r.push(`${His} average sex drive allows ${him} to put on a decent show.`);
-	} else if (slave.energy > 20) {
-		r.push(`The fact that ${his} sex drive is so poor affects ${his} performance.`);
-	} else {
-		r.push(`The fact that ${his} sex drive is nonexistent really hinders ${his} ability to put on a decent show.`);
+	function energy() {
+		if (slave.energy > 95) {
+			return `The fact that ${he} is a nymphomaniac helps ${him} to go for longer, allowing ${him} to really put on an amazing show.`;
+		} else if (slave.energy > 80) {
+			return `The fact that ${his} sex drive is so powerful helps ${him} to really put on good shows.`;
+		} else if (slave.energy > 60) {
+			return `The fact that ${his} sex drive is so good helps ${him} to put on good shows.`;
+		} else if (slave.energy > 40) {
+			return `${His} average sex drive allows ${him} to put on a decent show.`;
+		} else if (slave.energy > 20) {
+			return `The fact that ${his} sex drive is so poor affects ${his} performance.`;
+		} else {
+			return `The fact that ${his} sex drive is nonexistent really hinders ${his} ability to put on a decent show.`;
+		}
 	}
 
-	switch (slave.fetish) {
-		case "submissive":
-			if (V.seeBestiality) {
-				if (slave.fetishKnown) {
-					r.push(`${He} is so submissive that ${he} willingly accepts ${his} position as an animal's fucktoy and <span class="reputation inc">is able to put on a decent show.</span>`);
-				} else {
-					r.push(`${S.HeadGirl ? `${S.HeadGirl.slaveName} notices` : `You notice`} that ${slave.slaveName} seems to have really taken to ${his} position as a fucktoy for animals. <span class="lightcoral">${He}'s a submissive!</span>`);
-				}
-			} else {
-				if (slave.fetishKnown) {
-					r.push(`Being a submissive, ${he} <span class="reputation dec">doesn't have the confidence required</span> to really put on a good show.`);
+	function fetish() {
+		switch (slave.fetish) {
+			case "submissive":
+				if (V.seeBestiality) {
+					if (slave.fetishKnown) {
+						return `${He} is so submissive that ${he} willingly accepts ${his} position as an animal's fucktoy and <span class="reputation inc">is able to put on a decent show.</span>`;
+					} else {
+						return `${S.HeadGirl ? `${S.HeadGirl.slaveName} notices` : `You notice`} that ${slave.slaveName} seems to have really taken to ${his} position as a fucktoy for animals. <span class="lightcoral">${He}'s a submissive!</span>`;
+					}
 				} else {
-					r.push(`${slave.slaveName} doesn't seem to have the type of fortitude needed to put on a show, and after some probing, you discover why - it turns out <span class="lightcoral">${he}'s a submissive!</span>`);
+					if (slave.fetishKnown) {
+						return `Being a submissive, ${he} <span class="reputation dec">doesn't have the confidence required</span> to really put on a good show.`;
+					} else {
+						return `${slave.slaveName} doesn't seem to have the type of fortitude needed to put on a show, and after some probing, you discover why - it turns out <span class="lightcoral">${he}'s a submissive!</span>`;
+					}
 				}
-			}
-			break;
-
-		case "humiliation":
-			if (V.seeBestiality) {
-				if (slave.fetishKnown) {
-					r.push(`${slave.slaveName} uses the most of this humiliating experience to really put on a show, to <span class="reputation inc">the approval of ${his} audience</span>.`);
+			case "humiliation":
+				if (V.seeBestiality) {
+					if (slave.fetishKnown) {
+						return `${slave.slaveName} uses the most of this humiliating experience to really put on a show, to <span class="reputation inc">the approval of ${his} audience</span>.`;
+					}
 				}
-			}
-			break;
-
-		default:
-			break;
+		}
 	}
 
-	switch (slave.behavioralFlaw) {
-		case "arrogant":
-			r.push(`${He} tries ${his} hardest to avoid ${V.seeBestiality ? `fucking animals` : `putting on shows`} because of ${his} arrogance, <span class="cash dec">which affects ${his} profits</span> and <span class="reputation dec">your reputation.</span>`);
-			break;
-
-		case "devout":
-			r.push(`${He} often prays ${V.seeBestiality ? ` while getting fucked by animals` : ` during ${his} shows`}, which your citizens <span class="reputation dec">find off-putting.</span>`);
-			break;
+	function behavioralFlaw() {
+		switch (slave.behavioralFlaw) {
+			case "arrogant":
+				return `${He} tries ${his} hardest to avoid ${V.seeBestiality ? `fucking animals` : `putting on shows`} because of ${his} arrogance, <span class="cash dec">which affects ${his} profits</span> and <span class="reputation dec">your reputation.</span>`;
 
-		default:
-			break;
+			case "devout":
+				return `${He} often prays ${V.seeBestiality ? ` while getting fucked by animals` : ` during ${his} shows`}, which your citizens <span class="reputation dec">find off-putting.</span>`;
+		}
 	}
 
-	switch (slave.behavioralQuirk) {
-		case "sinful":
-			r.push(`${He} relishes in ${his} ability to do something so sinful and depraved, and <span class="reputation inc">really puts on a show.</span>`);
-			break;
-
-		default:
-			break;
+	function behavioralQuirk() {
+		switch (slave.behavioralQuirk) {
+			case "sinful":
+				return `${He} relishes in ${his} ability to do something so sinful and depraved, and <span class="reputation inc">really puts on a show.</span>`;
+		}
 	}
 
-	switch (slave.sexualFlaw) {
-		case "shamefast":
-			r.push(`${His} crippling shamefastness <span class="reputation dec">limits ${his} ability</span> to put on a decent show.`);
-			break;
-
-		default:
-			break;
+	function sexualFlaw() {
+		switch (slave.sexualFlaw) {
+			case "shamefast":
+				return `${His} crippling shamefastness <span class="reputation dec">limits ${his} ability</span> to put on a decent show.`;
+		}
 	}
 
-	switch (slave.sexualQuirk) {
-		case "perverted":
-			r.push(`${His} shows are a <span class="reputation inc">real spectacle,</span> since ${he} is so perverted that ${he} is willing to go far beyond the bare minimum.`);
-			break;
-
-		default:
-			break;
+	function sexualQuirk() {
+		switch (slave.sexualQuirk) {
+			case "perverted":
+				return `${His} shows are a <span class="reputation inc">real spectacle,</span> since ${he} is so perverted that ${he} is willing to go far beyond the bare minimum.`;
+		}
 	}
 
-	if (V.policies.bestialityOpenness > 0) {
-		r.push(`Society's acceptance of and enthusiasm towards bestiality earns ${him} quite a bit more than ${he} would have made otherwise.`);
+	function openness() {
+		if (V.policies.bestialityOpenness > 0) {
+			return `Society's acceptance of and enthusiasm towards bestiality earns ${him} quite a bit more than ${he} would have made otherwise.`;
+		}
 	}
 
-	incomeStats.income += Math.trunc(App.Facilities.Farmyard.farmShowsIncome(slave));
-
-	return r.join(' ');
+	function rival() {
+		if (slave.rivalry > 0 && V.seeBestiality) {
+			return `${getSlave(slave.rivalryTarget).slaveName} hates ${him} and is glad to see that ${he}'s been assigned to fuck animals all day.`;
+		}
+	}
 };
diff --git a/src/facilities/geneLab.js b/src/facilities/geneLab.js
index faf224eb027ef3d937e4024b4e8302251051f724..bd24b876d80eb2a7aeffde9ca10974a105df7d27 100644
--- a/src/facilities/geneLab.js
+++ b/src/facilities/geneLab.js
@@ -22,6 +22,7 @@ App.UI.geneLab = function() {
 
 	App.UI.DOM.appendNewElement("h2", node, `Genetic Modification`);
 	const immortalityCost = 50000000;
+	const flavoringCost = 150000;
 	if (V.dispensaryUpgrade === 0) {
 		App.UI.DOM.appendNewElement("div", node, `The fabricator must be upgraded before it can produce treatments to alter genes`, "note");
 	} else {
@@ -60,6 +61,20 @@ App.UI.geneLab = function() {
 			} else {
 				App.UI.DOM.appendNewElement("div", node, `The fabricator is capable of producing treatments to induce various genetic anomalies.`);
 			}
+
+			if (V.bioEngineeredFlavoringResearch === 1) {
+				App.UI.DOM.appendNewElement("div", node, `The fabricator is capable of producing treatments to change the flavor of a slave's milk.`);
+			} else if (V.cash >= flavoringCost) {
+				App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
+					"Fund research into bio-engineered human milk flavoring",
+					() => {
+						cashX(forceNeg(flavoringCost), "capEx");
+						V.bioEngineeredFlavoringResearch = 1;
+						App.UI.reload();
+					}, [], "",
+					`Costs ${cashFormat(flavoringCost)}. This will allow changing the flavor of a slave's milk`
+				));
+			}
 		}
 		if (V.seeCats === 1) {
 			let r = [];
diff --git a/src/facilities/incubator/incubatorInteract.js b/src/facilities/incubator/incubatorInteract.js
index 967c764ed41d8fa267e1c3f37768477b66baea47..ea6ce2fc56137af7fa9102925cf27b7ce39b4a0d 100644
--- a/src/facilities/incubator/incubatorInteract.js
+++ b/src/facilities/incubator/incubatorInteract.js
@@ -966,10 +966,10 @@ App.UI.incubator = function() {
 						if (vision.right === 0 && tankOrgans.rightEye !== 1) {
 							linkArray.push(makeLink("Prepare right eye", () => { App.Medicine.OrganFarm.growIncubatorOrgan(V.incubator.tanks[i], "rightEye"); }, refresh));
 						}
-						if (vision.left === 0 && vision.right === 0 && linkArray.length === 2) {
+						if (vision.left === 0 && vision.right === 0 && tankOrgans.leftEye !== 1 && tankOrgans.rightEye !== 1) {
 							linkArray.push(
 								makeLink(
-									"Prepare right eye",
+									"Prepare both eyes",
 									() => {
 										App.Medicine.OrganFarm.growIncubatorOrgan(V.incubator.tanks[i], "rightEye");
 										App.Medicine.OrganFarm.growIncubatorOrgan(V.incubator.tanks[i], "leftEye");
@@ -978,7 +978,7 @@ App.UI.incubator = function() {
 								)
 							);
 						}
-						if (vision.left === 0 && vision.right === 0 && linkArray.length === 0) {
+						if (vision.left === 0 && vision.right === 0 && tankOrgans.leftEye === 1 && tankOrgans.rightEye === 1) {
 							linkArray.push(App.UI.DOM.makeElement("span", `Both eyes are already prepared.`, `detail`));
 						} else if (tankOrgans.leftEye === 1) {
 							linkArray.push(App.UI.DOM.makeElement("span", `A left eye is already prepared.`, `detail`));
diff --git a/src/facilities/manage/dispensary.js b/src/facilities/manage/dispensary.js
index f8b08cb88fb114cd6dd77dbc604fecad0b0fd574..bd3aceaefe70adc4f3e53403cf84a2c5b1c5d48c 100644
--- a/src/facilities/manage/dispensary.js
+++ b/src/facilities/manage/dispensary.js
@@ -34,27 +34,25 @@ App.UI.dispensary = function() {
 
 	/**
 	 * @param {string} name
-	 * @param {string|Node} note
+	 * @param {string[]} notes
 	 * @param {function(): void} callback
 	 * @param {number} cost
 	 * @param {string} [existingDesc=""]
 	 * @returns {DocumentFragment}
 	 */
-	function upgrade(name, note, callback, cost, existingDesc = "") {
+	function upgrade(name, notes, callback, cost, existingDesc = "") {
 		const f = new DocumentFragment();
 		r = [];
 		if (existingDesc !== "") {
 			r.push(existingDesc);
 		}
-		r.push(App.UI.DOM.link(name, () => {
-			cashX(-cost, "capEx");
-			callback();
-			refresh();
+		r.push(makePurchase(name, cost, "capEx", {
+			handler: callback,
+			notes,
+			refresh,
 		}));
-		r.push(`<span class="detail">Costs ${cashFormat(cost)}</span>`);
-		App.Events.addNode(f, r, "div");
 
-		App.UI.DOM.appendNewElement("div", f, note, ["indent", "note"]);
+		App.Events.addNode(f, r, "div");
 
 		return f;
 	}
@@ -79,12 +77,12 @@ App.UI.dispensary = function() {
 
 		if (V.dispensaryUpgrade === 0) {
 			if (V.rep > 5000) {
-				p.append(upgrade("Upgrade the pharmaceutical fabricator", "Will improve production efficiency further decreasing costs.", () => {
+				p.append(upgrade("Upgrade the pharmaceutical fabricator", ["Will improve production efficiency, further decreasing costs."], () => {
 					V.dispensaryUpgrade = 1;
 					V.drugsCost = (V.drugsCost * 2) / 3;
 				}, 30000 * V.upgradeMultiplierArcology));
 			} else {
-				App.UI.DOM.appendNewElement("div", p, "You lack the reputation to obtain cutting-edge pharmaceutical fabricator upgrades.", "note");
+				App.UI.DOM.appendNewElement("div", p, "You lack the reputation to obtain cutting-edge pharmaceutical fabricator upgrades.", ["note"]);
 			}
 		}
 		f.append(p);
@@ -105,34 +103,34 @@ App.UI.dispensary = function() {
 			text += " standard growth hormones.";
 			if (V.rep > 6000) {
 				p.append(upgrade("Purchase data on prototype growth hormone tests",
-					"Should improve the reliability of growth injections of all kinds.",
+					["Should improve the reliability of growth injections of all kinds."],
 					() => { V.injectionUpgrade = 1; }, 25000 * pcSkillCheck, text));
 			} else {
 				r = [text];
 				r.push(`<span class="note">You lack the reputation to obtain prototype medicines.</span>`);
-				App.Events.addNode(p, r, "div", "note");
+				App.Events.addNode(p, r, "div", ["note"]);
 			}
 		} else if (V.injectionUpgrade === 1) {
 			text += " prototype growth hormones.";
 			if (V.rep > 10000) {
 				p.append(upgrade("Upgrade the fabricator to customize each slave's growth hormones",
-					"Should improve the reliability of growth injections of all kinds.",
+					["Should improve the reliability of growth injections of all kinds."],
 					() => { V.injectionUpgrade = 2; }, 50000 * pcSkillCheck, text));
 			} else {
 				r = [text];
 				r.push(`<span class="note">You lack the reputation to obtain prototype fabricator upgrades.</span>`);
-				App.Events.addNode(p, r, "div", "note");
+				App.Events.addNode(p, r, "div", ["note"]);
 			}
 		} else if (V.injectionUpgrade === 2) {
 			text += " customized growth hormones.";
 			if (V.rep > 14000) {
 				p.append(upgrade("Upgrade the fabricator with prototype biomechanical microfactories",
-					"Should improve the reliability of growth injections of all kinds.",
+					["Should improve the reliability of growth injections of all kinds."],
 					() => { V.injectionUpgrade = 3; }, 100000 * pcSkillCheck, text));
 			} else {
 				r = [text];
 				r.push(`<span class="note">You lack the reputation to obtain prototype biomechanical microfactories.</span>`);
-				App.Events.addNode(p, r, "div", "note");
+				App.Events.addNode(p, r, "div", ["note"]);
 			}
 		} else {
 			App.Events.addNode(p, [text, "the world's most effective growth hormones."], "div");
@@ -143,11 +141,11 @@ App.UI.dispensary = function() {
 		if (V.hormoneUpgradeMood === 0) {
 			text += " standardized hormone replacement therapies.";
 			if (V.rep > 2000) {
-				p.append(upgrade("Upgrade for individualized therapy", "Should eliminate the occasional moodiness and sexual disinterest caused by generalized therapy.", () => { V.hormoneUpgradeMood = 1; }, 10000 * pcSkillCheck, text));
+				p.append(upgrade("Upgrade for individualized therapy", ["Should eliminate the occasional moodiness and sexual disinterest caused by generalized therapy."], () => { V.hormoneUpgradeMood = 1; }, 10000 * pcSkillCheck, text));
 			} else {
 				r = [text];
 				r.push(`<span class="note">You lack the reputation to obtain advanced drug manufacturing components.</span>`);
-				App.Events.addNode(p, r, "div", "note");
+				App.Events.addNode(p, r, "div", ["note"]);
 			}
 		} else {
 			App.Events.addNode(p, [text, "individualized hormone replacement therapies."], "div");
@@ -157,11 +155,11 @@ App.UI.dispensary = function() {
 		if (V.hormoneUpgradePower === 0) {
 			text += " are traditional: they're formulated to mimic natural hormones.";
 			if (V.rep > 4000) {
-				p.append(upgrade("Purchase data on advanced HRT", "Should increase the power of hormone therapies.", () => { V.hormoneUpgradePower = 1; }, 25000 * pcSkillCheck, text));
+				p.append(upgrade("Purchase data on advanced HRT", ["Should increase the power of hormone therapies."], () => { V.hormoneUpgradePower = 1; }, 25000 * pcSkillCheck, text));
 			} else {
 				r = [text];
 				r.push(`<span class="note">You lack the reputation to obtain prototype medicines.</span>`);
-				App.Events.addNode(p, r, "div", "note");
+				App.Events.addNode(p, r, "div", ["note"]);
 			}
 		} else {
 			App.Events.addNode(p, [text, "are advanced: they're formulated to improve on natural hormones."], "div");
@@ -171,11 +169,11 @@ App.UI.dispensary = function() {
 		if (V.hormoneUpgradeShrinkage === 0) {
 			text += " are broad-spectrum.";
 			if (V.rep > 4000) {
-				p.append(upgrade("Purchase data on targeted HRT", "Should reduce atrophy of organs corresponding to original sex.", () => { V.hormoneUpgradeShrinkage = 1; }, 25000 * pcSkillCheck, text));
+				p.append(upgrade("Purchase data on targeted HRT", ["Should reduce atrophy of organs corresponding to original sex."], () => { V.hormoneUpgradeShrinkage = 1; }, 25000 * pcSkillCheck, text));
 			} else {
 				r = [text];
 				r.push(`<span class="note">You lack the reputation to obtain prototype medicines.</span>`);
-				App.Events.addNode(p, r, "div", "note");
+				App.Events.addNode(p, r, "div", ["note"]);
 			}
 		} else {
 			App.Events.addNode(p, [text, "are targeted, reducing atrophy of organs corresponding to original sex."], "div");
@@ -184,9 +182,9 @@ App.UI.dispensary = function() {
 		if (V.precociousPuberty === 1) {
 			if (V.pubertyHormones === 0) {
 				if (V.rep > 4500 * pcSkillCheck) {
-					p.append(upgrade("Fund research into powerful hormonal injections to jumpstart puberty", "Will allow the production of powerful hormonal drugs designed to force a slave through puberty without regard for side effects.", () => { V.pubertyHormones = 1; }, 30000 * pcSkillCheck));
+					p.append(upgrade("Fund research into powerful hormonal injections to jumpstart puberty", ["Will allow the production of powerful hormonal drugs designed to force a slave through puberty without regard for side effects."], () => { V.pubertyHormones = 1; }, 30000 * pcSkillCheck));
 				} else {
-					App.Events.addNode(p, ["You lack the reputation to fund forced puberty drugs"], "div", "note");
+					App.Events.addNode(p, ["You lack the reputation to fund forced puberty drugs"], "div", ["note"]);
 				}
 			} else {
 				App.Events.addNode(p, ["The fabricator is producing extra strong hormonal drugs designed to force a slave through puberty."], "div");
@@ -209,9 +207,9 @@ App.UI.dispensary = function() {
 		if (V.feeder === 1) {
 			if (V.dietXXY === 0) {
 				if (V.rep > 3500 * pcSkillCheck) {
-					p.append(upgrade("Fund research into developing hermaphrodite hormone therapies", "Will allow for specially balanced meals to be served in the cafeteria designed to promote both halves of a herm's sexuality.", () => { V.dietXXY = 1; }, 10000 * pcSkillCheck));
+					p.append(upgrade("Fund research into developing hermaphrodite hormone therapies", ["Will allow for specially balanced meals to be served in the cafeteria designed to promote both halves of a herm's sexuality."], () => { V.dietXXY = 1; }, 10000 * pcSkillCheck));
 				} else {
-					App.Events.addNode(p, ["You lack the reputation to fund research into hermaphrodite hormones."], "div", "note");
+					App.Events.addNode(p, ["You lack the reputation to fund research into hermaphrodite hormones."], "div", ["note"]);
 				}
 			} else {
 				App.Events.addNode(p, ["The fabricator is producing meals to be served in the cafeteria designed to promote both halves of a herm's sexuality."], "div");
@@ -224,9 +222,9 @@ App.UI.dispensary = function() {
 			if (V.feeder === 1) {
 				if (V.reproductionFormula === 0) {
 					if (V.rep > 10000 * pcSkillCheck) {
-						p.append(upgrade("Purchase reputable breeders' dietary blends", "Will allow for specially refined meals to be served in the cafeteria designed to promote energetic sperm and robust pregnancies. Side effects may include an increased number of twins being conceived.", () => { V.reproductionFormula = 1; }, 25000 * pcSkillCheck));
+						p.append(upgrade("Purchase reputable breeders' dietary blends", ["Will allow for specially refined meals to be served in the cafeteria designed to promote energetic sperm and robust pregnancies. Side effects may include an increased number of twins being conceived."], () => { V.reproductionFormula = 1; }, 25000 * pcSkillCheck));
 					} else {
-						App.Events.addNode(p, ["You lack the reputation to access breeders' dietary blends."], "div", "note");
+						App.Events.addNode(p, ["You lack the reputation to access breeders' dietary blends."], "div", ["note"]);
 					}
 				} else {
 					App.Events.addNode(p, ["The fabricator is producing meals to be served in the cafeteria that promote energetic sperm and robust pregnancies."], "div");
@@ -237,21 +235,21 @@ App.UI.dispensary = function() {
 		}
 
 		if (V.cumProDiet === 0) {
-			p.append(upgrade("Purchase recipes to encourage cum production", "Will allow for specially designed meals to be served in the cafeteria to promote cum production.", () => { V.cumProDiet = 1; }, 5000 * pcSkillCheck));
+			p.append(upgrade("Purchase recipes to encourage cum production", ["Will allow for specially designed meals to be served in the cafeteria to promote cum production."], () => { V.cumProDiet = 1; }, 5000 * pcSkillCheck));
 		} else {
 			App.Events.addNode(p, ["The fabricator is producing meals to be served in the cafeteria designed to promote cum production."], "div");
 		}
 
 		if (V.seePreg === 1) {
 			if (V.dietFertility === 0) {
-				p.append(upgrade("Purchase recipes to encourage ovulation", "Will allow for specially designed meals to be served in the cafeteria to promote slave fertility.", () => { V.dietFertility = 1; }, 5000 * pcSkillCheck));
+				p.append(upgrade("Purchase recipes to encourage ovulation", ["Will allow for specially designed meals to be served in the cafeteria to promote slave fertility."], () => { V.dietFertility = 1; }, 5000 * pcSkillCheck));
 			} else if (V.dietFertility === 1) {
 				App.Events.addNode(p, ["The fabricator is producing meals to be served in the cafeteria designed to promote slave fertility."], "div");
 			}
 		}
 
 		if (V.dietCleanse === 0) {
-			p.append(upgrade("Purchase cleansing recipes to lessen carcinogen buildup", "Will allow for specially designed meals to be served in the cafeteria to counteract excessive drug use.", () => { V.dietCleanse = 1; }, 10000 * pcSkillCheck));
+			p.append(upgrade("Purchase cleansing recipes to lessen carcinogen buildup", ["Will allow for specially designed meals to be served in the cafeteria to counteract excessive drug use."], () => { V.dietCleanse = 1; }, 10000 * pcSkillCheck));
 		} else if (V.dietCleanse === 1) {
 			App.Events.addNode(p, ["The fabricator is producing meals to be served in the cafeteria designed to counteract excessive drug use and good health. They smell awful and taste worse than they look, but they're healthy."], "div");
 		}
@@ -269,26 +267,26 @@ App.UI.dispensary = function() {
 		let p = document.createElement("p");
 
 		if (V.curativeUpgrade === 0 && V.rep > 6000 * pcSkillCheck) {
-			p.append(upgrade("Purchase data on advanced curatives", "Should improve the effectiveness of curative treatment.", () => { V.curativeUpgrade = 1; }, 25000 * pcSkillCheck));
+			p.append(upgrade("Purchase data on advanced curatives", ["Should improve the effectiveness of curative treatment."], () => { V.curativeUpgrade = 1; }, 25000 * pcSkillCheck));
 		} else if (V.curativeUpgrade === 1) {
 			App.Events.addNode(p, ["The fabricator is producing highly effective curative cocktails."], "div");
 		}
 
 
 		if (V.growthStim === 0 && V.rep > 6000 * pcSkillCheck) {
-			p.append(upgrade("Purchase data on growth stimulants", "Will allow the manufacturing of drugs to encourage growth in slave height.", () => { V.growthStim = 1; }, 20000 * pcSkillCheck));
+			p.append(upgrade("Purchase data on growth stimulants", ["Will allow the manufacturing of drugs to encourage growth in slave height."], () => { V.growthStim = 1; }, 20000 * pcSkillCheck));
 		} else if (V.growthStim === 1) {
 			App.Events.addNode(p, ["The fabricator is able to produce growth stimulants."], "div");
 		}
 
 		if (V.aphrodisiacUpgradeRefine === 0 && V.rep > 6000 * pcSkillCheck) {
-			p.append(upgrade("Purchase data on refined aphrodisiacs", "Will prevent most physical side effects of aphrodisiacs. Once the formulas are changed they cannot be changed back.", () => { V.aphrodisiacUpgradeRefine = 1; }, 20000 * pcSkillCheck));
+			p.append(upgrade("Purchase data on refined aphrodisiacs", ["Will prevent most physical side effects of aphrodisiacs. Once the formulas are changed they cannot be changed back."], () => { V.aphrodisiacUpgradeRefine = 1; }, 20000 * pcSkillCheck));
 		} else if (V.aphrodisiacUpgradeRefine === 1) {
 			App.Events.addNode(p, ["The fabricator is producing refined aphrodisiacs with limited hormonal effects."], "div");
 		}
 
 		if (V.aphrodisiacUpgrade === 0 && V.rep > 6000 * pcSkillCheck) {
-			p.append(upgrade("Purchase data on aphrodisiac withdrawal treatment", "Should prevent most negative effects of withdrawal.", () => { V.aphrodisiacUpgrade = 1; }, 10000 * pcSkillCheck));
+			p.append(upgrade("Purchase data on aphrodisiac withdrawal treatment", ["Should prevent most negative effects of withdrawal."], () => { V.aphrodisiacUpgrade = 1; }, 10000 * pcSkillCheck));
 		} else if (V.aphrodisiacUpgrade === 1) {
 			App.Events.addNode(p, ["The fabricator is producing a substitute that will protect slaves from aphrodisiac withdrawal."], "div");
 		}
@@ -296,19 +294,19 @@ App.UI.dispensary = function() {
 		if (V.healthyDrugsUpgrade === 0) {
 			if (V.injectionUpgrade !== 0 && V.curativeUpgrade === 1 && V.aphrodisiacUpgrade === 1) {
 				if (V.rep >= 15000 * pcSkillCheck) {
-					p.append(upgrade("Fund research into drug formulations without negative physical side effects", "Will prevent the negative side effects of excessive drug usage on your slaves.", () => { V.healthyDrugsUpgrade = 1; }, 500000 * pcSkillCheck));
+					p.append(upgrade("Fund research into drug formulations without negative physical side effects", ["Will prevent the negative side effects of excessive drug usage on your slaves."], () => { V.healthyDrugsUpgrade = 1; }, 500000 * pcSkillCheck));
 				} else {
-					App.Events.addNode(p, ["You lack the reputation to access the technology necessary to develop advanced drug formulations."], "div", "note");
+					App.Events.addNode(p, ["You lack the reputation to access the technology necessary to develop advanced drug formulations."], "div", ["note"]);
 				}
 			} else {
-				App.Events.addNode(p, ["You must purchase all other major upgrades before developing advanced drug formulations."], "div", "note");
+				App.Events.addNode(p, ["You must purchase all other major upgrades before developing advanced drug formulations."], "div", ["note"]);
 			}
 		} else {
 			App.Events.addNode(p, ["The fabricator has been upgraded to optimize the structures of your other drugs, eliminating their negative side effects."], "div");
 		}
 
 		if (V.arcologies[0].FSBodyPuristLaw === 1) {
-			App.Events.addNode(p, ["The pharmaceutical fabricator is working with your body purist arcology to reduce long term drug side effects."], "div", "note");
+			App.Events.addNode(p, ["The pharmaceutical fabricator is working with your body purist arcology to reduce long term drug side effects."], "div", ["note"]);
 		}
 
 		f.append(p);
@@ -329,30 +327,30 @@ App.UI.dispensary = function() {
 			if (V.pregSpeedControl === 1) {
 				App.Events.addNode(p, ["The fabricator is producing extremely complex gestation control agents. They can be used to control gestation speed, and even suppress labor for some time."], "div");
 			} else if (V.superFertilityDrugs === 1 && V.rep > 10000 * pcSkillCheck) {
-				p.append(upgrade("Fund research pregnancy speed control methods", "Fund underground research labs to develop methods for controlling pregnancy progress.", () => {
+				p.append(upgrade("Fund research pregnancy speed control methods", ["Fund underground research labs to develop methods for controlling pregnancy progress."], () => {
 					V.pregSpeedControl = 1;
 					V.clinicSpeedGestation = 0;
 				}, 200000 * pcSkillCheck));
 			} else if (V.rep <= 10000 * pcSkillCheck) {
-				App.Events.addNode(p, ["You lack the reputation required to contact underground research labs to develop methods for controlling pregnancy progress."], "div", "note");
+				App.Events.addNode(p, ["You lack the reputation required to contact underground research labs to develop methods for controlling pregnancy progress."], "div", ["note"]);
 			}
 		} else if (V.birthsTotal > 10) {
 			if (V.pregSpeedControl === 1) {
 				App.Events.addNode(p, ["The fabricator is producing extremely complex gestation control agents. They can be used to control gestation speed, and even suppress labor for some time."], "div");
 			} else if (V.rep > 10000 * pcSkillCheck) {
-				p.append(upgrade("Fund research pregnancy speed control methods", "Fund underground research labs to develop methods for controlling pregnancy progress.", () => {
+				p.append(upgrade("Fund research pregnancy speed control methods", ["Fund underground research labs to develop methods for controlling pregnancy progress."], () => {
 					V.pregSpeedControl = 1;
 					V.clinicSpeedGestation = 0;
 				}, 200000 * pcSkillCheck));
 			} else if (V.rep <= 10000 * pcSkillCheck) {
-				App.Events.addNode(p, ["You lack the reputation required to contact underground research labs to develop methods for controlling pregnancy progress."], "div", "note");
+				App.Events.addNode(p, ["You lack the reputation required to contact underground research labs to develop methods for controlling pregnancy progress."], "div", ["note"]);
 			}
 		} else {
-			App.Events.addNode(p, ["You lack the experience handling pregnant slaves required to convince underground research labs to do business with you in the development of controlled fetal development."], "div", "note");
+			App.Events.addNode(p, ["You lack the experience handling pregnant slaves required to convince underground research labs to do business with you in the development of controlled fetal development."], "div", ["note"]);
 		}
 
 		if (V.superFertilityDrugs === 0 && V.rep > 2500 * pcSkillCheck && V.seeHyperPreg === 1) {
-			p.append(upgrade("Purchase data on powerful fertility drugs", "Should improve the likelihood of conception and multiples.", () => { V.superFertilityDrugs = 1; }, 20000 * pcSkillCheck));
+			p.append(upgrade("Purchase data on powerful fertility drugs", ["Should improve the likelihood of conception and multiples."], () => { V.superFertilityDrugs = 1; }, 20000 * pcSkillCheck));
 		} else if (V.superFertilityDrugs === 1) {
 			App.Events.addNode(p, ["The fabricator is producing highly effective fertility agents. There is a warning present involving overdosing and instances of ten or more children."], "div");
 		}
@@ -369,77 +367,77 @@ App.UI.dispensary = function() {
 
 		if (V.ImplantProductionUpgrade === 1 && V.arcologies[0].FSTransformationFetishistDecoration >= 100) {
 			if (V.arcologies[0].FSTransformationFetishistResearch === 0 && V.rep <= 5000 * pcSkillCheck) {
-				App.Events.addNode(p, ["You lack the reputation to access experimental gigantic implants and elasticizing filler."], "div", "note");
+				App.Events.addNode(p, ["You lack the reputation to access experimental gigantic implants and elasticizing filler."], "div", ["note"]);
 			} else if (V.arcologies[0].FSTransformationFetishistResearch === 0) {
-				p.append(upgrade("Purchase data on gigantic implants and elasticizing filler", "Will allow the fabrication of gigantic implants using the autosurgery and filler capable of overfilling existing fillable implants.", () => { V.arcologies[0].FSTransformationFetishistResearch = 1; }, 20000 * pcSkillCheck));
+				p.append(upgrade("Purchase data on gigantic implants and elasticizing filler", ["Will allow the fabrication of gigantic implants using the autosurgery and filler capable of overfilling existing fillable implants."], () => { V.arcologies[0].FSTransformationFetishistResearch = 1; }, 20000 * pcSkillCheck));
 			} else if (V.arcologies[0].FSTransformationFetishistResearch > 0) {
 				App.Events.addNode(p, ["The fabricator is capable of crafting gigantic implants and elasticizing filler designed to overfill existing implants."], "div");
 			}
 		} else if (V.arcologies[0].FSTransformationFetishistResearch === 1) {
 			App.Events.addNode(p, ["The fabricator is capable of crafting gigantic implants and elasticizing filler designed to overfill existing implants."], "div");
 		} else {
-			App.Events.addNode(p, ["Transformation Fetishist focused research unavailable."], "div", "note");
+			App.Events.addNode(p, ["Transformation Fetishist focused research unavailable."], "div", ["note"]);
 		}
 
 		if (V.arcologies[0].FSAssetExpansionistResearch === 1) {
 			App.Events.addNode(p, ["The fabricator has been upgraded to manufacture extremely powerful growth drugs."], "div");
 		} else if (V.arcologies[0].FSAssetExpansionistDecoration === 100) {
 			if (V.rep >= 5000 * pcSkillCheck) {
-				p.append(upgrade("Fund research into drug formulations for growth without limit", "Will allow creation of drugs to push assets to unthinkable sizes.", () => { V.arcologies[0].FSAssetExpansionistResearch = 1; }, 30000 * pcSkillCheck));
+				p.append(upgrade("Fund research into drug formulations for growth without limit", ["Will allow creation of drugs to push assets to unthinkable sizes."], () => { V.arcologies[0].FSAssetExpansionistResearch = 1; }, 30000 * pcSkillCheck));
 			} else {
-				App.Events.addNode(p, ["You lack the reputation to access the research necessary to develop advanced growth drug formulations."], "div", "note");
+				App.Events.addNode(p, ["You lack the reputation to access the research necessary to develop advanced growth drug formulations."], "div", ["note"]);
 			}
 		} else {
-			App.Events.addNode(p, ["Asset Expansionist focused research unavailable."], "div", "note");
+			App.Events.addNode(p, ["Asset Expansionist focused research unavailable."], "div", ["note"]);
 		}
 
 		if (V.arcologies[0].FSSlaveProfessionalismResearch === 1) {
 			App.Events.addNode(p, ["The fabricator has been upgraded to manufacture a compound that steadily improves intelligence."], "div");
 		} else if (V.arcologies[0].FSSlaveProfessionalismDecoration === 100) {
 			if (V.rep >= 5000 * pcSkillCheck) {
-				p.append(upgrade("Fund research into producing an intelligence boosting compound", "Will allow the creation of a drug that improves mental faculties.", () => { V.arcologies[0].FSSlaveProfessionalismResearch = 1; }, 60000 * pcSkillCheck));
+				p.append(upgrade("Fund research into producing an intelligence boosting compound", ["Will allow the creation of a drug that improves mental faculties."], () => { V.arcologies[0].FSSlaveProfessionalismResearch = 1; }, 60000 * pcSkillCheck));
 			} else {
-				App.Events.addNode(p, ["You lack the reputation to access the research necessary to produce an intelligence boosting compound."], "div", "note");
+				App.Events.addNode(p, ["You lack the reputation to access the research necessary to produce an intelligence boosting compound."], "div", ["note"]);
 			}
 		} else {
-			App.Events.addNode(p, ["Slave Professionalism focused research unavailable."], "div", "note");
+			App.Events.addNode(p, ["Slave Professionalism focused research unavailable."], "div", ["note"]);
 		}
 
 		if (V.arcologies[0].FSSlimnessEnthusiastResearch === 1) {
 			App.Events.addNode(p, ["The fabricator has been upgraded to manufacture growth reversing drugs."], "div");
 		} else if (V.arcologies[0].FSSlimnessEnthusiastDecoration === 100) {
 			if (V.rep >= 5000 * pcSkillCheck) {
-				p.append(upgrade("Fund research into drug formulations for slimming slaves", "Will allow creation of drugs to shrink assets.", () => { V.arcologies[0].FSSlimnessEnthusiastResearch = 1; }, 30000 * pcSkillCheck));
+				p.append(upgrade("Fund research into drug formulations for slimming slaves", ["Will allow creation of drugs to shrink assets."], () => { V.arcologies[0].FSSlimnessEnthusiastResearch = 1; }, 30000 * pcSkillCheck));
 			} else {
-				App.Events.addNode(p, ["You lack the reputation to access the research necessary to develop asset reducing drug formulations."], "div", "note");
+				App.Events.addNode(p, ["You lack the reputation to access the research necessary to develop asset reducing drug formulations."], "div", ["note"]);
 			}
 		} else {
-			App.Events.addNode(p, ["Slimness Enthusiast focused research unavailable."], "div", "note");
+			App.Events.addNode(p, ["Slimness Enthusiast focused research unavailable."], "div", ["note"]);
 		}
 
 		if (V.arcologies[0].FSYouthPreferentialistResearch === 1) {
 			App.Events.addNode(p, ["The fabricator has been upgraded to manufacture extremely effective beauty creams designed to combat aging."], "div");
 		} else if (V.arcologies[0].FSYouthPreferentialistDecoration === 100) {
 			if (V.rep >= 5000 * pcSkillCheck) {
-				p.append(upgrade("Fund research into skin care designed to reverse the effects of aging", "Will allow creation of beauty creams designed to make slaves look young again.", () => { V.arcologies[0].FSYouthPreferentialistResearch = 1; }, 30000 * pcSkillCheck));
+				p.append(upgrade("Fund research into skin care designed to reverse the effects of aging", ["Will allow creation of beauty creams designed to make slaves look young again."], () => { V.arcologies[0].FSYouthPreferentialistResearch = 1; }, 30000 * pcSkillCheck));
 			} else {
-				App.Events.addNode(p, ["You lack the reputation to access the research necessary to develop beauty creams designed to make slaves look young again."], "div", "note");
+				App.Events.addNode(p, ["You lack the reputation to access the research necessary to develop beauty creams designed to make slaves look young again."], "div", ["note"]);
 			}
 		} else {
-			App.Events.addNode(p, ["Youth Preferentialist focused research unavailable."], "div", "note");
+			App.Events.addNode(p, ["Youth Preferentialist focused research unavailable."], "div", ["note"]);
 		}
 
 		if (V.arcologies[0].FSHedonisticDecadenceDecoration === 100) {
 			if (V.arcologies[0].FSHedonisticDecadenceResearch === 0) {
 				if (V.rep >= 5000 * pcSkillCheck) {
-					p.append(upgrade("Purchase recipes for concentrated, shaped slave food", `Will allow production of solid slave food in various familiar shapes and flavors. Addictive and a little fatty.${(V.arcologies[0].FSDegradationist === "unset" ? "" : " Since your slaves don't deserve luxuries, a modified recipe formulated to cause severe stomach cramps minutes after ingestion will be developed.")}`, () => { V.arcologies[0].FSHedonisticDecadenceResearch = 1; }, 50000 * pcSkillCheck));
+					p.append(upgrade("Purchase recipes for concentrated, shaped slave food", [`Will allow production of solid slave food in various familiar shapes and flavors. Addictive and a little fatty.${(V.arcologies[0].FSDegradationist === "unset" ? "" : " Since your slaves don't deserve luxuries, a modified recipe formulated to cause severe stomach cramps minutes after ingestion will be developed.")}`], () => { V.arcologies[0].FSHedonisticDecadenceResearch = 1; }, 50000 * pcSkillCheck));
 				} else {
-					App.Events.addNode(p, ["You lack the reputation to access the research necessary to purchase concentrated, shaped slave food recipes."], "div", "note");
+					App.Events.addNode(p, ["You lack the reputation to access the research necessary to purchase concentrated, shaped slave food recipes."], "div", ["note"]);
 				}
 			} else {
 				let text = `The fabricator has been upgraded to manufacture tasty, extremely addictive, solid slave food in various familiar shapes and flavors. While they look and taste like real food, their consistency is all wrong. Slaves gorging on them are likely to experience steady weight gain.${(V.arcologies[0].FSDegradationist === "unset" ? "" : " Since your slaves don't deserve luxuries, all food crafted will cause severe stomach cramps minutes after ingestion. Coupled with their addictive nature, it ought to be quite torturous.")}`;
 				if (V.arcologies[0].FSSlimnessEnthusiast > 50 && V.arcologies[0].FSHedonisticDecadenceDietResearch === 0) {
-					p.append(upgrade("Purchase diet recipes", "Will prevent rampant weight gain from ruining your slim slaves.", () => { V.arcologies[0].FSHedonisticDecadenceDietResearch = 1; }, 10000 * pcSkillCheck, text));
+					p.append(upgrade("Purchase diet recipes", ["Will prevent rampant weight gain from ruining your slim slaves."], () => { V.arcologies[0].FSHedonisticDecadenceDietResearch = 1; }, 10000 * pcSkillCheck, text));
 				} else if (V.arcologies[0].FSHedonisticDecadenceDietResearch === 1) {
 					App.Events.addNode(p, [text, "A diet recipe is being utilized to prevent unwanted weight gain."], "div");
 				}
@@ -447,7 +445,7 @@ App.UI.dispensary = function() {
 		} else if (V.arcologies[0].FSHedonisticDecadenceResearch === 1) {
 			let text = `The fabricator has been upgraded to manufacture tasty, extremely addictive, solid slave food in various familiar shapes and flavors. While they look and taste like real food, their consistency is all wrong. Slaves gorging on them are likely to experience steady weight gain.${V.arcologies[0].FSDegradationist === "unset" ? "" : "Since your slaves don't deserve luxuries, all food crafted will cause severe stomach cramps minutes after ingestion. Coupled with their addictive nature, it ought to be quite torturous."}`;
 			if (V.arcologies[0].FSHedonisticDecadenceDietResearch === 0) {
-				p.append(upgrade("Purchase diet recipes", `Will prevent rampant unwanted weight gain from ruining your ${V.arcologies[0].FSSlimnessEnthusiast > 20 ? "slim " : ""}slaves.`, () => { V.arcologies[0].FSHedonisticDecadenceDietResearch = 1; }, 10000 * pcSkillCheck));
+				p.append(upgrade("Purchase diet recipes", [`Will prevent rampant unwanted weight gain from ruining your ${V.arcologies[0].FSSlimnessEnthusiast > 20 ? "slim " : ""}slaves.`], () => { V.arcologies[0].FSHedonisticDecadenceDietResearch = 1; }, 10000 * pcSkillCheck));
 			} else if (V.arcologies[0].FSHedonisticDecadenceDietResearch === 1) {
 				App.Events.addNode(p, [text, "A diet recipe is being utilized to prevent unwanted weight gain."], "div");
 			}
@@ -459,7 +457,7 @@ App.UI.dispensary = function() {
 			}), "indent");
 			App.Events.addNode(p, ["Will <span class=\"noteworthy\">completely</span> remove this research."]);
 		} else {
-			App.Events.addNode(p, ["Hedonistic Decadence focused research unavailable."], "div", "note");
+			App.Events.addNode(p, ["Hedonistic Decadence focused research unavailable."], "div", ["note"]);
 		}
 		f.append(p);
 		return f;
diff --git a/src/facilities/masterSuite/masterSuite.js b/src/facilities/masterSuite/masterSuite.js
index f184bc0e32568f8b9af181325cc0003d9a163aac..d9b7c76cb11c4ece1d2812bc5c67c4bb3421c95b 100644
--- a/src/facilities/masterSuite/masterSuite.js
+++ b/src/facilities/masterSuite/masterSuite.js
@@ -44,6 +44,16 @@ App.Facilities.MasterSuite.masterSuite = class MasterSuite extends App.Facilitie
 		}
 	}
 
+	/** @returns {HTMLDivElement} */
+	get slaves() {
+		const div = document.createElement("div");
+		if (this.facility.manager) {
+			div.append(App.UI.SlaveList.displayManager(this.facility));
+		}
+		div.append(App.UI.SlaveList.listSJFacilitySlaves(this.facility, passage(), true, undefined, App.UI.SlaveList.Decoration.personalAttention));
+		return div;
+	}
+
 	/** @returns {string} */
 	get intro() {
 		const text = [];
@@ -271,7 +281,7 @@ App.Facilities.MasterSuite.masterSuite = class MasterSuite extends App.Facilitie
 						link: `Refit the suite to the height of traditional opulence`,
 						cost: 25000 * V.upgradeMultiplierArcology,
 						handler: () => V.PC.skill.engineering += .1,
-						note: ` and will focus the suite on you`,
+						notes: [`will focus the suite on you`],
 					},
 					{
 						value: 0,
@@ -280,7 +290,7 @@ App.Facilities.MasterSuite.masterSuite = class MasterSuite extends App.Facilitie
 						link: `Remodel the suite around a luxurious pit for group sex`,
 						cost: 25000 * V.upgradeMultiplierArcology,
 						handler: () => V.PC.skill.engineering += .1,
-						note: ` and will encourage fucktoys to fuck each other`,
+						notes: [`will encourage fucktoys to fuck each other`],
 					},
 					{
 						value: 1,
@@ -288,7 +298,7 @@ App.Facilities.MasterSuite.masterSuite = class MasterSuite extends App.Facilitie
 						upgraded: 2,
 						link: `Remodel the suite around a luxurious pit for group sex`,
 						cost: 10000 * V.upgradeMultiplierArcology,
-						note: ` and will encourage fucktoys to fuck each other`,
+						notes: [`will encourage fucktoys to fuck each other`],
 					},
 					{
 						value: 2,
@@ -296,7 +306,7 @@ App.Facilities.MasterSuite.masterSuite = class MasterSuite extends App.Facilitie
 						upgraded: 1,
 						link: `Refit the suite to the height of traditional opulence`,
 						cost: 10000 * V.upgradeMultiplierArcology,
-						note: ` and will focus the suite on you`,
+						notes: [`will focus the suite on you`],
 					},
 				],
 			},
diff --git a/src/facilities/nursery/nursery.js b/src/facilities/nursery/nursery.js
index 598c33f5457b662d5f92178a0aae2ceb08dec3c6..81eebf3378eb7dac4af4ec2b3663f3bae0449817 100644
--- a/src/facilities/nursery/nursery.js
+++ b/src/facilities/nursery/nursery.js
@@ -68,8 +68,8 @@ App.Facilities.Nursery.nursery = class Nursery extends App.Facilities.Facility {
 			"Body Purist": `is decorated to be very clean cut and sterilized with perfect corners and curves; symbolic of the human figure. Nursery maids are encouraged to show off their natural assets to show the children what the appropriate body should be.`,
 			"Slimness Enthusiast": `constantly encourages the kids to try and keep their slim and cute physiques. They are given perfectly metered meals to make this possible.`,	// TODO: tie this in to food system
 			"Hedonistic": `would make any toddler drool in amazement. Meals and naps every other hour, cribs stalked with toys and blankets, and plush slaves carry them to and fro without preamble. A delicious layer of baby fat is the ideal figure of a baby, and they couldn't be happier.`,
-			"Intellectual Dependency": ``,	// TODO:
-			"Slave Professionalism": ``,	// TODO:
+			"Intellectual Dependency": `is decorated in some way relating to Intellectual Dependency.`,	// TODO:
+			"Slave Professionalism": `is decorated in some way relating to Slave Professionalism.`,	// TODO:
 			"Petite Admiration": `has large photos and paintings on the walls depicting small, petite children enjoying ${this.facility.name}'s amenities and having fun together.`,
 			"Statuesque Glorification": `has large photos and paintings on the walls depicting tall children enjoying ${this.facility.name}'s amenities and having fun together.`,
 			"standard": `is as comfortable and child-friendly as it needs to be. They have everything they need to grow into a proper slave.`,
@@ -109,7 +109,7 @@ App.Facilities.Nursery.nursery = class Nursery extends App.Facilities.Facility {
 						link: `Upgrade the monitoring system`,
 						cost: 1000 * V.upgradeMultiplierArcology,
 						handler: () => V.PC.skill.engineering += 0.1,
-						note: ` and will increase upkeep costs`,
+						notes: [`will increase upkeep costs`],
 					},
 					{
 						value: 1,
@@ -127,7 +127,7 @@ App.Facilities.Nursery.nursery = class Nursery extends App.Facilities.Facility {
 						link: `Install a playground`,
 						cost: 1000 * V.upgradeMultiplierArcology,
 						handler: () => V.PC.skill.engineering += 0.1,
-						note: ` and will increase upkeep costs`,
+						notes: [`will increase upkeep costs`],
 					},
 					{
 						value: 1,
@@ -145,7 +145,7 @@ App.Facilities.Nursery.nursery = class Nursery extends App.Facilities.Facility {
 						link: `Invest in purpose-built hormones`,
 						cost: 1000 * V.upgradeMultiplierArcology,
 						handler: () => V.PC.skill.engineering += 0.1,
-						note: ` and will increase upkeep costs`,
+						notes: [`will increase upkeep costs`],
 					},
 					{
 						value: 1,
diff --git a/src/facilities/nursery/utils/nurseryUtils.js b/src/facilities/nursery/utils/nurseryUtils.js
index 7a53c03f07c66d9c6306181a466eeb12bbe18f4a..dad2b09614e2568e4f43c62d3b4ff6bbef1f2eaf 100644
--- a/src/facilities/nursery/utils/nurseryUtils.js
+++ b/src/facilities/nursery/utils/nurseryUtils.js
@@ -72,12 +72,12 @@ App.Facilities.Nursery.infantToChild = function infantToChild(child) {
 	child.accent = 0;
 	child.ageImplant = 0;
 	child.arm = {
-		left: new App.Entity.LimbState(),
-		right: new App.Entity.LimbState()
+		left: new App.Entity.ArmState(),
+		right: new App.Entity.LegState()
 	};
 	child.leg = {
-		left: new App.Entity.LimbState(),
-		right: new App.Entity.LimbState()
+		left: new App.Entity.LegState(),
+		right: new App.Entity.LegState()
 	};
 	child.analArea = 0;
 	child.anus = 0;
@@ -156,7 +156,7 @@ App.Facilities.Nursery.infantToChild = function infantToChild(child) {
 		titleLisp: ""
 	};
 	child.daughters = 0;
-	child.devotion = 40;	// TODO:
+	child.devotion = 40;
 	child.dick = 0;
 	child.dickAccessory = "none";
 	child.dickTat = 0;
@@ -426,7 +426,7 @@ App.Facilities.Nursery.nameChild = function nameChild(child) {
 		r += `<br>
 		<<link "Have your PA assign ${him} a random cat name">>
 		<<replace "#naming">>`;
-		child.slaveName = setup.catSlaveNames.random();
+		child.slaveName = App.Data.misc.catSlaveNames.random();
 		child.birthName = child.slaveName;
 		r += `${V.assistant.name} registers the new ${girl} as "${child.slaveName}" in your registry.
 		<</replace>>
@@ -631,12 +631,12 @@ App.Facilities.Nursery.newChild = function newChild(child) {
 	/* eslint-enable */
 
 	child.arm = {
-		left: new App.Entity.LimbState(),
-		right: new App.Entity.LimbState()
+		left: new App.Entity.ArmState(),
+		right: new App.Entity.ArmState()
 	};
 	child.leg = {
-		left: new App.Entity.LimbState(),
-		right: new App.Entity.LimbState()
+		left: new App.Entity.LegState(),
+		right: new App.Entity.LegState()
 	};
 
 	if (V.surnamesForbidden === 1) {
diff --git a/src/facilities/penthouse/penthousePassage.js b/src/facilities/penthouse/managePenthouse.js
similarity index 94%
rename from src/facilities/penthouse/penthousePassage.js
rename to src/facilities/penthouse/managePenthouse.js
index 7e9092e1e075e5cabcfecb7aa3359a952ea0e3b3..6af54c4b0885ac634bb94035a0acf467180de4fe 100644
--- a/src/facilities/penthouse/penthousePassage.js
+++ b/src/facilities/penthouse/managePenthouse.js
@@ -34,7 +34,7 @@ App.UI.managePenthouse = function() {
 				)
 			);
 		} else if (V.SF.FS.Tension > 100) {
-			App.UI.DOM.appendNewElement("div", el, App.SF.fsIntegration.badOutcomeFirebase());
+			App.UI.DOM.appendNewElement("div", el, App.Mods.SF.fsIntegration.badOutcomeFirebase());
 		}
 		return el;
 	}
@@ -47,46 +47,34 @@ App.UI.managePenthouse = function() {
 		// Dorms
 		const dormCost = Math.trunc(V.dormitory * 1000 * V.upgradeMultiplierArcology);
 		r.push(`The main penthouse dormitory, which houses slaves who aren't living in a facility and aren't granted a luxurious standard of living, has a capacity of`);
-		r.push(App.UI.DOM.makeElement("span", JSON.stringify(V.dormitory), "bold"));
+		r.push(App.UI.DOM.makeElement("span", JSON.stringify(V.dormitory), ["bold"]));
 		r.push(`slaves.`);
 		r.push(
-			App.UI.DOM.makeElement("div", App.UI.DOM.link(
-				"Expand the dormitory",
-				() => {
-					cashX(forceNeg(dormCost), "capEx");
+			makePurchase(`Expand the dormitory`, dormCost, "capEx", {
+				handler: () => {
 					V.dormitory += 10;
 					V.PC.skill.engineering += .1;
-					App.UI.reload();
-				},
-				[],
-				"",
-				`Costs ${cashFormat(dormCost)}`
-			), ['indent'])
+				}
+			})
 		);
-		r.push(App.UI.DOM.makeElement("span", `Exceeding this limit is bad for slaves' health, devotion and trust.`, "detail"));
+		r.push(App.UI.DOM.makeElement("div", `Exceeding this limit is bad for slaves' health, devotion and trust.`, ["detail", "indent"]));
 		App.Events.addNode(el, r, "div");
 
 		// Luxury rooms
 		r = [];
 		const luxuryCost = Math.trunc(V.rooms * 1000 * V.upgradeMultiplierArcology);
 		r.push(`The penthouse also features little individual rooms, which house slaves who do enjoy a luxurious standard of living. They have a capacity of`);
-		r.push(App.UI.DOM.makeElement("span", JSON.stringify(V.rooms), "bold"));
+		r.push(App.UI.DOM.makeElement("span", JSON.stringify(V.rooms), ["bold"]));
 		r.push(`slaves.`);
 		r.push(
-			App.UI.DOM.makeElement("div", App.UI.DOM.link(
-				"Expand the rooms",
-				() => {
-					cashX(forceNeg(luxuryCost), "capEx");
+			makePurchase(`Expand the rooms`, luxuryCost, "capEx", {
+				handler: () => {
 					V.rooms += 5;
 					V.PC.skill.engineering += .1;
-					App.UI.reload();
-				},
-				[],
-				"",
-				`Costs ${cashFormat(luxuryCost)}`
-			), ['indent'])
+				}
+			})
 		);
-		r.push(App.UI.DOM.makeElement("span", `The number of rooms determines the number of slaves that can be granted luxury.`, "detail"));
+		r.push(App.UI.DOM.makeElement("div", `The number of rooms determines the number of slaves that can be granted luxury.`, ["detail", "indent"]));
 		App.Events.addNode(el, r, "div");
 		return el;
 	}
@@ -419,25 +407,15 @@ App.UI.managePenthouse = function() {
 		r = [];
 		if (V.boobAccessibility > 0 || V.pregAccessibility > 0 || V.dickAccessibility > 0 || V.ballsAccessibility > 0 || V.buttAccessibility > 0) {
 			const removeCost = Math.trunc((5000 * (V.boobAccessibility + V.pregAccessibility + V.dickAccessibility + V.ballsAccessibility + V.buttAccessibility)) * V.upgradeMultiplierArcology);
-			App.UI.DOM.appendNewElement(
-				"div",
-				el,
-				App.UI.DOM.link(
-					"Remove the accessibility renovations",
-					() => {
-						cashX(forceNeg(removeCost), "capEx");
-						V.boobAccessibility = 0;
-						V.pregAccessibility = 0;
-						V.dickAccessibility = 0;
-						V.ballsAccessibility = 0;
-						V.buttAccessibility = 0;
-					},
-					[],
-					"Manage Penthouse",
-					`Will cost ${cashFormat(removeCost)}`
-				),
-				"detail"
-			);
+			el.append(makePurchase(`Remove the accessibility renovations`, removeCost, "capEx", {
+				handler: () => {
+					V.boobAccessibility = 0;
+					V.pregAccessibility = 0;
+					V.dickAccessibility = 0;
+					V.ballsAccessibility = 0;
+					V.buttAccessibility = 0;
+				}
+			}));
 		}
 		App.Events.addNode(el, r, "div");
 
@@ -531,14 +509,14 @@ App.UI.managePenthouse = function() {
 	function makeLink(title, handler, cost = 5000) {
 		const el = new DocumentFragment();
 		cost = Math.trunc(cost * V.upgradeMultiplierArcology);
-		el.append(new Purchase(title, cost, "capEx", {
+		el.append(makePurchase(title, cost, "capEx", {
 			handler: () => {
 				handler();
 
 				V.PC.skill.engineering += .1;
 				jQuery(container).empty().append(createPage());
 			}
-		}).render());
+		}));
 
 		return el;
 	}
diff --git a/src/facilities/penthouse/penthouseFramework.js b/src/facilities/penthouse/penthouseFramework.js
index f1865abfed8afbfc9bec59222e21e3fc3ee53059..ee9be3de8a40e2c19d9e6dbcf2bc800c4f822241 100644
--- a/src/facilities/penthouse/penthouseFramework.js
+++ b/src/facilities/penthouse/penthouseFramework.js
@@ -170,23 +170,24 @@ App.Entity.Facilities.Penthouse = class extends App.Entity.Facilities.Facility {
 	}
 
 	/** Facility slave capacity
+	 * Note that slaves in a relationship may share luxury rooms, so actual capacity is slightly larger (@see penthouseCensus)
 	 * @override
 	 * @returns {number} */
 	get capacity() {
-		return V.dormitory;
-	}
-
-	/** Number of already hosted slaves
-	 * @returns {number} */
-	get hostedSlaves() {
-		return V.dormitoryPopulation;
+		return V.dormitory + V.rooms;
 	}
 
 	/** Penthouse can be overcrowded, so it always has free space
+	 * @override
 	 * @returns {boolean} */
 	get hasFreeSpace() {
 		return true;
 	}
+
+	/** Not meaningful */
+	occupancyReport() {
+		return "";
+	}
 };
 
 App.Entity.facilities.penthouse = new App.Entity.Facilities.Penthouse();
diff --git a/src/facilities/pit/pit.js b/src/facilities/pit/pit.js
index 0276a96a07ce0662a258212d6c12babfa02c3d88..a4efa0f2f0e0814a6ee1a6b540fd303facbfc9e3 100644
--- a/src/facilities/pit/pit.js
+++ b/src/facilities/pit/pit.js
@@ -26,21 +26,89 @@ App.Facilities.Pit.pit = class Pit extends App.Facilities.Facility {
 	get intro() {
 		const text = [];
 
-		text.push(`${this.facility.nameCaps} is clean and ready,`);
+		text.push(`${this.facility.nameCaps} ${this.decorations}`);
 
 		if (this.facility.hostedSlaves > 2) {
-			text.push(`with a pool of slaves assigned to fight in the next week's bout.`);
-		} else if (this.facility.hostedSlaves === 1) {
-			text.push(`but only one slave is assigned to the week's bout.`);
+			text.push(`It has a pool of slaves assigned to fight in the next week's bout.`);
+		} else if (this.facility.hostedSlaves > 1) {
+			text.push(`It has two slaves assigned to the week's bout.`);
 		} else if (this.facility.hostedSlaves > 0) {
-			text.push(`with slaves assigned to the week's bout.`);
+			text.push(`It only has one slave assigned to the week's bout.`);
 		} else {
-			text.push(`but no slaves are assigned to fight.`);
+			text.push(`It doesn't have any slaves assigned to fight.`);
 		}
 
 		return text.join(' ');
 	}
 
+	/** @returns {string} */
+	get decorations() {
+		const chattelReligionist = () => {
+			const text = [`is a large, modern arena decorated with frescoes of two fictional slaves reaching the afterlife. On the upper walls near the seatings, the obedient slave blissfully follow ${V.seeDicks < 100 ? `her` : `his`} master through`];
+			if (V.arcologies[0].FSRomanRevivalist !== "unset") {
+				text.push(`Elysian Fields' gates, Pluto's chthonic arcology, while on the walls of the fighting area, the disobedient one is sentenced to suffer in a hellish-looking old world city named Tartarus.`);
+			} else if (V.arcologies[0].FSNeoImperialist !== "unset") {
+				text.push(`Heaven's gates, God's celestial arcology, while on the wall of the fighting area, the disobedient one is dragged by demonlike raiders down to Hell.`);
+			} else if (V.arcologies[0].FSEgyptianRevivalist !== "unset") {
+				text.push(`Aaru's gates, Osiris' celestial arcology, while on the wall of the fighting area, the disobedient one, whose heart is heavier than the feather of Maat, is eaten by Ammit, the devourer of souls.`);
+			} else if (V.arcologies[0].FSEdoRevivalist !== "unset") {
+				text.push(`Takamagahara's gates, Amaterasu's celestial arcology, while on the wall of the fighting area, the disobedient one is tortured in Jigoku by oni-like raiders.`);
+			} else if (V.arcologies[0].FSArabianRevivalist !== "unset") {
+				text.push(`Jannah's gates, Allah's celestial arcology, while on the wall of the fighting area, the disobedient one is thrown by two angels into Jahannam for the awaiting ifrit-like raiders.`);
+			} else if (V.arcologies[0].FSChineseRevivalist !== "unset") {
+				text.push(`Tian's gates, Jade Emperor's arcology, while on the wall of the fighting area, the disobedient one is tortured in Diyu by yaoguai-like raiders.`);
+			} else if (V.arcologies[0].FSAztecRevivalist !== "unset") {
+				text.push(`Tonatiuhtlán's gates, Tōnatiuh's celestial arcology, to accompany the sun during the morning, while on the wall of the fighting area, the disobedient one is sent to Mictlān to suffer through many challenges.`);
+			} else {
+				text.push(`Paradise's gates, Allslaver's celestial arcology, while on the wall of the fighting area, the disobedient one is sentenced to survive in the Wasteland of the Freedom Trickster.`);
+			}
+			return text.join(" ");
+		};
+
+
+		/** @type {FC.Facilities.Decoration} */
+		const FS = {
+			"Roman Revivalist": `is a circular Roman amphitheater-like structure with a coffered dome built of limestone. Walls are covered with mosaics depicting various idealized gladiatorial fights. At the bottom, the pit is covered with a fine layered of sand.`,
+			"Neo-Imperialist": `is a futurist, gothic-styled indoor list field with a retractable ceiling and a modular arena where tournaments are held. While most of them are used for slaves fighting, ${V.arcologies[0].name}'s citizens may enjoy and participate in neo-jousting with highly-powered motorcycles and modern mock battles with heavily-armored knights.`,
+			"Aztec Revivalist": `is a large rectangular masonry structure used for both Mesoamerican ballgames and slave fights decorated in the traditional Aztec way, with stacked stone walls painted with bright murals.`,
+			"Egyptian Revivalist": `is a a simple sunken pit with a sand floor and sandstone walls. In the seating area, there are papyriform columns supporting the ceiling while the walls are decorated with hieroglyphic and pictorial frescoes.`,
+			"Edo Revivalist": `is a lush Japanese garden surrounding a pond filled with large, colorful koi. A red wooden footbridge links the garden with the small island that lies in the middle of the pond, which is where the slaves fight.`,
+			"Arabian Revivalist": `is a riad, a symmetrical indoor garden centered around the fighting area. Seating for guests are available under the shade of the flora and the surrounding balconies decorated with complex arabesque.`,
+			"Chinese Revivalist": `is decorated like a traditional Chinese courtyard, with a large open area in the center surrounded by low buildings with brick walls and clay tile roofs. A couple of bronze-cast Chinese guardian lions protect the entrance of the structure.`,
+			"Chattel Religionist": chattelReligionist(),
+			"Degradationist": `is a large, modern arena with huge screens mounted strategically to allow its guests the best possible view of the combatants' rape or dismemberment.`,
+			"Repopulationist": `is a large, modern stadium with a large open area in the center for the fighters. The bleachers are connected with adjacent birthing areas furnished with wall screens allowing the mothers to enjoy the fight while increasing ${V.arcologies[0].name}'s population.`,
+			"Eugenics": `is a large, modern arena with a large open area in the center for the fighters. The seating area is divided in two to separate the Elite, who own the most comfortable seats with the best views, from the unwashed masses.`,
+			"Asset Expansionist": `is a large, modern arena that has been designed to welcome all of your well-stacked citizens and slaves. The front row is designed to accommodate and reward the most hypertrophied ones.`,
+			"Transformation Fetishist": `is both a architectural and engineering marvel made with some of the most recently crafted composite materials and filled with cutting-edge technologies designed to record the fighters from every angle.`,
+			"Gender Radicalist": `is a large, modern arena that offers the best seats to slave owners, with a designated spot at their feet for their slaves with dicks.`,
+			"Gender Fundamentalist": `is a large, modern arena with a clear separation between gender. Front seats are reserved for male citizens while the back seats are left for women and slaves.`,
+			"Physical Idealist": `is a large, modern arena  made nearly entirely of marble decorated with imposing statues of muscular athletes that seem to support the structure with ease.`,
+			"Supremacist": `is a massive arena decorated to glorified ${V.arcologies[0].FSSupremacistRace} architecture, martial arts and military superiority throughout history.`,
+			"Subjugationist": `is a large, modern arena that looks like a zoo enclosure, where ${V.arcologies[0].name}'s citizens can comfortably watch ${V.arcologies[0].FSSubjugationistRace} subhuman rape${V.seeBestiality ? ` and bestiality` : ``}.`,
+			"Paternalist": `is a large, modern arena with seating that allows not only your citizens, but also menial and sexual slaves to come and watch the combatants fighting.`,
+			"Pastoralist": `is a large, modern arena${V.dairy > 0 ? ` connected with ${V.dairyName} pipelines` : ``}. The fighting area can receive low quality body fluids of various quantities that makes each fight more unique.`,
+			"Maturity Preferentialist": `is a large arena with the same architectural style as the arenas built in the first arcologies ever made.`,
+			"Youth Preferentialist": `is a large, modern arena that is regularly decorated by the most trending arcologies' fashion designers.`,
+			"Body Purist": `is a large arena made entirely out of local wood and stone and constructed with little to no fasteners, bindings or adhesives.`,
+			"Slimness Enthusiast": `is a large, modern  arena made of graphene and other lightweight materials, allowing natural light to illuminate every corner of the structure.`,
+			"Hedonistic": `is both a large, modern arena and a congregation of restaurants. Its many chefs compete as fiercely as the fighters to offer vast quantities of caloric nourishment for the audience.`,
+			"Intellectual Dependency": `is a large, modern arena decorated with simple and cartoonish representation of gladiatorial fights. Phallus-shaped foam bats are given to the easily-bored bimbo slaves while their masters watch the fights in peace.`,
+			"Slave Professionalism": `is a large, modern arena decorated with displays of armed and unarmed fighting stances to incite slave owners to train their favorite slaves with combat skills.`,
+			"Petite Admiration": `is a small, modern arena that is surprisingly roomy on the inside and decorated with artwork of small, cunning heroes defeating dumb giants.`,
+			"Statuesque Glorification": `is a colossal arena that can be seen from any sector of the arcology and looks like a shepherd casting its protective shadow on the herd of smaller buildings.`,
+			"standard": `is fairly unremarkable – little more than a fairly large, circular amphitheater set into one corner of ${V.arcologies[0].name}.`,
+		};
+
+		const res = FS[V.pit.decoration];
+
+		if (!res) {
+			throw new Error(`Unknown V.pit.decoration value of '${V.pit.decoration}' found in decorations().`);
+		}
+
+		return res;
+	}
+
 	/** @returns {FC.Facilities.Expand} */
 	get expand() {
 		return {
@@ -143,7 +211,7 @@ App.Facilities.Pit.pit = class Pit extends App.Facilities.Facility {
 
 								V.pit.slavesFighting = [];
 							},
-						}
+						},
 					],
 					object: V.pit,
 				},
@@ -187,7 +255,7 @@ App.Facilities.Pit.pit = class Pit extends App.Facilities.Facility {
 							prereqs: [
 								() => (!!V.active.canine && !!V.active.hooved) ||
 									(!!V.active.canine && !!V.active.feline) ||
-									(!!V.active.hooved && !!V.active.feline)
+									(!!V.active.hooved && !!V.active.feline),
 							],
 						},
 					],
diff --git a/src/facilities/pit/pitFramework.js b/src/facilities/pit/pitFramework.js
index 9401caf98b6190bcd06014cbbe54350956456467..ffb7a1954f45fc8c5a9222b5b663b002b2b4d967 100644
--- a/src/facilities/pit/pitFramework.js
+++ b/src/facilities/pit/pitFramework.js
@@ -12,7 +12,7 @@ App.Data.Facilities.pit = {
 	},
 	defaultJob: "fighter",
 	manager: null,
-	decorated: false
+	decorated: true,
 };
 
 App.Entity.Facilities.PitFighterJob = class extends App.Entity.Facilities.FacilitySingleJob {
diff --git a/src/facilities/pit/pitUtils.js b/src/facilities/pit/pitUtils.js
index ade3beb5d66f8895e4279878304897f80a002619..987315f9d05a6106e1a89a83e76e790d114618b2 100644
--- a/src/facilities/pit/pitUtils.js
+++ b/src/facilities/pit/pitUtils.js
@@ -6,6 +6,7 @@ App.Facilities.Pit.init = function() {
 		animal: null,
 		audience: "free",
 		bodyguardFights: false,
+		decoration: "standard",
 		fighters: 0,
 		fighterIDs: [],
 		fought: false,
diff --git a/src/facilities/salon/salonPassage.js b/src/facilities/salon/salonPassage.js
index f1de54201cc772d32e0a553ae56df51442003d83..70974df9f6d32f10cbec07ec904bb287f42381ac 100644
--- a/src/facilities/salon/salonPassage.js
+++ b/src/facilities/salon/salonPassage.js
@@ -1,9 +1,10 @@
 /**
  * UI for the Salon. Refreshes without refreshing the passage.
  * @param {App.Entity.SlaveState} slave
- * @param {boolean} cheat if true, will hide scenes and keep the player from being billed for changes.
+ * @param {boolean} [cheat=false] if true, will hide scenes and keep the player from being billed for changes.
+ * @param {boolean} [startingGirls=false] change systems for starting girls
  */
-App.UI.salon = function(slave, cheat = false) {
+App.UI.salon = function(slave, cheat = false, startingGirls = false) {
 	const container = document.createElement("span");
 	container.id = "salon";
 	const {
@@ -20,7 +21,11 @@ App.UI.salon = function(slave, cheat = false) {
 			App.Events.drawEventArt(el, slave);
 			el.append(intro());
 		}
-		el.append(eyewear());
+		if (!startingGirls) {
+			// Starting girls has its own, more powerful, eye modifier which interferes with this one.
+			// TODO: unify them
+			el.append(eyewear());
+		}
 		if (
 			(["leopard", "tiger", "jaguar"].includes(slave.earT) && slave.earTColor !== "hairless")
 			|| ["leopard", "tiger", "jaguar", "gazelle", "tanuki", "raccoon"].includes(slave.tailShape)
@@ -402,7 +407,8 @@ App.UI.salon = function(slave, cheat = false) {
 
 		if (cheat) {
 			option = options.addOption(`${His} natural skin color is`, "origSkin", slave).showTextBox().pulldown();
-			for (const skin of App.Medicine.Modification.naturalSkins) {
+			const naturalSkins = slave.race === "catgirl" ? App.Medicine.Modification.catgirlNaturalSkins : App.Medicine.Modification.naturalSkins;
+			for (const skin of naturalSkins) {
 				option.addValue(capFirstChar(skin), skin, () => slave.skin = slave.origSkin);
 			}
 		}
@@ -555,7 +561,7 @@ App.UI.salon = function(slave, cheat = false) {
 		} else {
 			r.push(`${His} groin is completely hairless.`);
 		}
-		option = options.addOption(r.join(" "), "pubicHColor", slave).showTextBox();
+		option = options.addOption(r.join(" "), "pubicHColor", slave);
 		if (hasPubes) {
 			if (slave.pubicHColor !== slave.hColor) {
 				option.addValue("Match the curtains", slave.hColor);
diff --git a/src/facilities/schoolroom/schoolroom.js b/src/facilities/schoolroom/schoolroom.js
index c45e8183787eee36a68f60bd79d69ed80c37d2e5..02f9d3117cb705fc0cfba60e21c9c7f9aef82293 100644
--- a/src/facilities/schoolroom/schoolroom.js
+++ b/src/facilities/schoolroom/schoolroom.js
@@ -104,7 +104,7 @@ App.Facilities.Schoolroom.schoolroom = class Schoolroom extends App.Facilities.F
 						text: `${this.facility.nameCaps} inculcates the basic skills necessary to a sex slave.`,
 						link: `Upgrade the curriculum to cover some intermediate skills`,
 						cost: 10000 * V.upgradeMultiplierArcology,
-						note: ` and increases the effectiveness of ${V.schoolroomName}`,
+						notes: [`increases the effectiveness of ${V.schoolroomName}`],
 					},
 					{
 						value: 1,
@@ -121,7 +121,7 @@ App.Facilities.Schoolroom.schoolroom = class Schoolroom extends App.Facilities.F
 						text: `${this.facility.nameCaps} includes only basic language classes in its curriculum.`,
 						link: `Install advanced linguistic interfaces to efficiently teach the arcology's lingua franca`,
 						cost: 5000 * V.upgradeMultiplierArcology * V.HackingSkillMultiplier,
-						note: ` and increases the effectiveness of ${V.schoolroomName}`,
+						notes: [`increases the effectiveness of ${V.schoolroomName}`],
 					},
 					{
 						value: 1,
@@ -170,7 +170,7 @@ App.Facilities.Schoolroom.schoolroom = class Schoolroom extends App.Facilities.F
 						text: `${this.facility.nameCaps} teaches woefully smart slaves using its modified methods.`,
 						link: `Purchase specialized materials to help smart slaves get on the right track`,
 						cost: 5000 * V.upgradeMultiplierArcology * V.HackingSkillMultiplier,
-						note: ` and increases the effectiveness of ${V.schoolroomName}`,
+						notes: [`increases the effectiveness of ${V.schoolroomName}`],
 						prereqs: [
 							() => V.schoolroomRemodelBimbo > 0,
 						],
@@ -189,7 +189,7 @@ App.Facilities.Schoolroom.schoolroom = class Schoolroom extends App.Facilities.F
 						link: `Purchase specialized materials to help stupid slaves learn good`,
 						cost: 5000 * V.upgradeMultiplierArcology * V.HackingSkillMultiplier,
 						handler: () => V.schoolroomRemodelBimbo = 0,
-						note: ` and increases the effectiveness of ${V.schoolroomName}`,
+						notes: [`increases the effectiveness of ${V.schoolroomName}`],
 						prereqs: [
 							() => V.schoolroomRemodelBimbo === 0,
 						],
diff --git a/src/facilities/servantsQuarters/servantsQuarters.js b/src/facilities/servantsQuarters/servantsQuarters.js
index 406ab74403f4967046fab24eeee8b23758520418..2179d22eb5075ccc85de405d26df16291a12a08b 100644
--- a/src/facilities/servantsQuarters/servantsQuarters.js
+++ b/src/facilities/servantsQuarters/servantsQuarters.js
@@ -102,7 +102,7 @@ App.Facilities.ServantsQuarters.servantsQuarters = class ServantsQuarters extend
 						link: `Upgrade the monitoring systems to force harder work`,
 						cost: 10000 * V.upgradeMultiplierArcology * V.HackingSkillMultiplier,
 						handler: () => V.PC.skill.hacking += 0.1,
-						note: ` and will increase upkeep costs`,
+						notes: [`will increase upkeep costs`],
 					},
 					{
 						value: 1,
diff --git a/src/facilities/spa/spa.js b/src/facilities/spa/spa.js
index 26e483764fb209950c2ef02be2799e221a76f031..e44076a07eec71cb1edab06d85b18d05edbe5fa8 100644
--- a/src/facilities/spa/spa.js
+++ b/src/facilities/spa/spa.js
@@ -106,7 +106,7 @@ App.Facilities.Spa.spa = class Spa extends App.Facilities.Facility {
 						text: `${this.facility.nameCaps} is a standard spa.`,
 						link: `Upgrade ${V.spaName} with saunas, steam rooms, and mineral water baths`,
 						cost: 1000 * V.upgradeMultiplierArcology,
-						note: ` and increases the effectiveness of ${V.spaName}`,
+						notes: [`increases the effectiveness of ${V.spaName}`],
 					},
 					{
 						value: 1,
diff --git a/src/facilities/statistics.js b/src/facilities/statistics.js
index 4d0af165db08327df3725360cc19bccfede5d8cd..68bb2ea1b83dbb8c9313a1d2347928d5b6508ca3 100644
--- a/src/facilities/statistics.js
+++ b/src/facilities/statistics.js
@@ -537,11 +537,10 @@ App.Facilities.Farmyard.Stats = (function() {
 			H.makeEmptyCell()
 		]);
 		if (showDetails) {
-			const slaveStats = H.makeSlaveStatsTable(stats, "Farmhand details", ["Farmhand", "Milk/Cum/Fluids", "Revenue", "Expenses", "Net Income", "Rep. Change"]);
+			const slaveStats = H.makeSlaveStatsTable(stats, "Farmhand details", ["Farmhand", "Revenue", "Expenses", "Net Income", "Rep. Change"]);
 			for (const record of b.income.values()) {
 				const netIncome = record.income - record.cost;
 				H.addValueRow(slaveStats, H.makeSlaveLabel(record.slaveName, record.customLabel), [
-					H.makeProductionCell(record.milk, record.cum, record.fluid),
 					H.makeValueCell("cash", record.income),
 					H.makeValueCell("cash", record.cost, {forceNeg: true}),
 					H.makeValueCell("cash", netIncome),
diff --git a/src/facilities/surgery/analyzePregnancy.js b/src/facilities/surgery/analyzePregnancy.js
index 0279720d92cfb4b99ca91043552ede6cc0322a25..26d217cb4ece8dc01152b916166802db56c90713 100644
--- a/src/facilities/surgery/analyzePregnancy.js
+++ b/src/facilities/surgery/analyzePregnancy.js
@@ -52,7 +52,7 @@ globalThis.analyzePregnancies = function(mother, cheat) {
 				}
 				option = options.addOption(`Skin tone: ${capFirstChar(genes.skin)}`, "skin", genes);
 				if (cheat) {
-					option.showTextBox().pulldown().addValueList(App.Medicine.Modification.naturalSkins);
+					option.showTextBox().pulldown().addValueList(genes.race === "catgirl" ? App.Medicine.Modification.catgirlNaturalSkins : App.Medicine.Modification.naturalSkins);
 				}
 				option = options.addOption(`Intelligence index: ${genes.intelligence} out of 100`, "intelligence", genes);
 				if (cheat) {
diff --git a/src/facilities/surgery/multiImplant.js b/src/facilities/surgery/multiImplant.js
index 2996e64cd54d461b11b1221ea8263a40a24b9a20..a1d983184265b9b62eb0ab97c901c458833c44d3 100644
--- a/src/facilities/surgery/multiImplant.js
+++ b/src/facilities/surgery/multiImplant.js
@@ -1,7 +1,7 @@
 App.UI.multipleOrganImplant = function() {
 	const node = new DocumentFragment();
 
-	node.append(intro());
+	node.append(intro(), organs());
 
 	App.UI.DOM.appendNewElement("h1", node, "Implant Prosthetics");
 
@@ -39,34 +39,21 @@ App.UI.multipleOrganImplant = function() {
 				switch (p.id) {
 					case "ocular":
 						if (getBestVision(slave) === 0) {
-							eyeSurgery(slave, "both", "cybernetic");
-							cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
-							surgeryDamage(slave, 20);
-							V.surgeryType = "ocular implant";
-							node.append(App.UI.SlaveInteract.surgeryDegradation(slave));
+							applyProcedure(new App.Medicine.Surgery.Procedures.OcularImplant(slave, "both"));
 						} else {
 							App.UI.DOM.appendNewElement("span", div, `Since ${he} has working eyes the ${App.Data.prosthetics.ocular.name} will be put into storage.`, "note");
 						}
 						break;
 					case "cochlear":
 						if (slave.hears !== 0) {
-							slave.earImplant = 1;
-							cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
-							surgeryDamage(slave, 20);
-							V.surgeryType = "cochlear implant";
-							node.append(App.UI.SlaveInteract.surgeryDegradation(slave));
+							applyProcedure(new App.Medicine.Surgery.Procedures.CochlearImplant(slave));
 						} else {
 							App.UI.DOM.appendNewElement("span", div, `Since ${he} has working ears the ${App.Data.prosthetics.cochlear.name} will be put into storage.`, "note");
 						}
 						break;
 					case "electrolarynx":
 						if (slave.voice <= 0) {
-							slave.electrolarynx = 1;
-							slave.voice = 2;
-							cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
-							surgeryDamage(slave, 20);
-							V.surgeryType = "electrolarynx";
-							node.append(App.UI.SlaveInteract.surgeryDegradation(slave));
+							applyProcedure(new App.Medicine.Surgery.Procedures.Electrolarynx(slave));
 						} else {
 							App.UI.DOM.appendNewElement("span", div, `Since ${he} has a voice the ${App.Data.prosthetics.electrolarynx.name} will be put into storage.`, "note");
 						}
@@ -332,7 +319,11 @@ App.UI.multipleOrganImplant = function() {
 
 		App.UI.DOM.appendNewElement("p", frag, r.join(" "));
 
-		const applyFrag = new DocumentFragment();
+		return frag;
+	}
+
+	function organs() {
+		const f = new DocumentFragment();
 
 		let F = App.Medicine.OrganFarm;
 		for (const slave of V.slaves) {
@@ -341,10 +332,10 @@ App.UI.multipleOrganImplant = function() {
 				continue;
 			}
 
-			App.UI.DOM.appendNewElement("h2", applyFrag, slave.slaveName);
+			App.UI.DOM.appendNewElement("h2", f, slave.slaveName);
 
 			for (let j = 0; j < sortedOrgans.length; j++) {
-				App.UI.DOM.appendNewElement("h3", applyFrag, F.Organs.get(sortedOrgans[j]).name);
+				App.UI.DOM.appendNewElement("h3", f, F.Organs.get(sortedOrgans[j]).name);
 
 				let actions = F.Organs.get(sortedOrgans[j]).implantActions;
 				let manual = false;
@@ -360,16 +351,16 @@ App.UI.multipleOrganImplant = function() {
 					if (!actions[k].canImplant(slave)) {
 						let error = actions[k].implantError(slave);
 						if (error !== "") {
-							App.UI.DOM.appendNewElement("div", applyFrag, error, "warning");
+							App.UI.DOM.appendNewElement("div", f, error, "warning");
 						}
 					} else {
 						const procedure = App.Medicine.OrganFarm.instantiateProcedure(slave, actions[k]);
 						if (slave.health.health - procedure.healthCost < -75) {
-							App.UI.DOM.appendNewElement("div", applyFrag, "Estimated health impact too great, skipping further surgeries.", "warning");
+							App.UI.DOM.appendNewElement("div", f, "Estimated health impact too great, skipping further surgeries.", "warning");
 							cancel = true;
 							break;
 						} else {
-							applyFrag.append(App.Medicine.OrganFarm.implant(sortedOrgans[j], procedure));
+							f.append(App.Medicine.OrganFarm.implant(sortedOrgans[j], procedure));
 							success = true;
 						}
 					}
@@ -378,16 +369,10 @@ App.UI.multipleOrganImplant = function() {
 					break;
 				}
 				if (!success && manual) {
-					App.UI.DOM.appendNewElement("div", applyFrag, `Cannot implant ${F.Organs.get(sortedOrgans[j]).name.toLowerCase()} automatically, try implanting manually in the remote surgery.`, "note");
+					App.UI.DOM.appendNewElement("div", f, `Cannot implant ${F.Organs.get(sortedOrgans[j]).name.toLowerCase()} automatically, try implanting manually in the remote surgery.`, "note");
 				}
 			}
 		}
-		frag.append(applyFrag);
-
-		// TODO: what is this for?
-		// if (any) {
-		// 	App.UI.DOM.appendNewElement("h1", frag, "Implant Organs");
-		// }
-		return frag;
+		return f;
 	}
 };
diff --git a/src/facilities/surgery/surgeryPassageExotic.js b/src/facilities/surgery/surgeryPassageExotic.js
index 354390ea5d6d0c1b61dd7c7d60a9943b9e899745..2d4f38eb683fbbbf7f46992cf66d3884366401f5 100644
--- a/src/facilities/surgery/surgeryPassageExotic.js
+++ b/src/facilities/surgery/surgeryPassageExotic.js
@@ -22,6 +22,9 @@ App.UI.surgeryPassageExotic = function(slave, refreshParent, cheat = false) {
 		if (V.geneticMappingUpgrade >= 1) {
 			App.UI.DOM.appendNewElement("h3", frag, `Retro-virus treatments:`);
 			frag.append(geneTherapy());
+			if (slave.milkFlavor !== "none") {
+				frag.append(milkFlavoring());
+			}
 		}
 		frag.append(bodySwap());
 
@@ -34,7 +37,7 @@ App.UI.surgeryPassageExotic = function(slave, refreshParent, cheat = false) {
 			if (slave.indentureRestrictions > 1) {
 				App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
 			} else {
-				for (const race of App.Data.misc.filterRaces.keys()) {
+				for (const race of App.Data.misc.filterRacesBase.keys()) {
 					if (slave.race === race) {
 						continue;
 					}
@@ -82,7 +85,16 @@ App.UI.surgeryPassageExotic = function(slave, refreshParent, cheat = false) {
 							new App.Medicine.Surgery.Procedures.ImmortalityTreatment(slave),
 							refresh, cheat));
 					} else {
-						App.UI.DOM.appendNewElement("div", el, `${He} already is already immortal`, ["choices", "note"]);
+						App.UI.DOM.appendNewElement("div", el, `${He} is already immortal`, ["choices", "note"]);
+					}
+				}
+				if (V.bioEngineeredFlavoringResearch === 1){
+					if (slave.milkFlavor === "none") {
+						linkArray.push(App.Medicine.Surgery.makeLink(
+							new App.Medicine.Surgery.Procedures.milkFlavoring(slave),
+							refresh, cheat));
+					} else {
+						App.UI.DOM.appendNewElement("div", el, `${His} milk can already be flavored`, ["choices", "note"]);
 					}
 				}
 				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
@@ -93,10 +105,10 @@ App.UI.surgeryPassageExotic = function(slave, refreshParent, cheat = false) {
 			function retroVirus() {
 				const el = new DocumentFragment();
 				const slaveGeneList = App.UI.DOM.appendNewElement("ul", el);
-				const select = App.UI.DOM.makeElement("select", null, "choices");
 				const canEditGenes = slave.indentureRestrictions === 0 && slave.health.health >= 0;
-				select.classList.add("rajs-list");
 				const description = App.UI.DOM.appendNewElement("div", el, null);
+
+				const options = /** @type {selectOption[]} */ [];
 				for (const gene in slave.geneticQuirks) {
 					const geneData = App.Data.geneticQuirks.get(gene);
 
@@ -120,18 +132,13 @@ App.UI.surgeryPassageExotic = function(slave, refreshParent, cheat = false) {
 						continue;
 					}
 					if (canEditGenes) {
-						const choice = App.UI.DOM.appendNewElement("option", select, capFirstChar(geneData.title));
-						choice.value = gene;
-						select.append(choice);
+						options.push({key: gene, name: capFirstChar(geneData.title)});
 					}
 				}
 				if (canEditGenes) {
-					select.selectedIndex = -1;
-					select.onchange = () => {
-						// selectedGene = select.options[select.selectedIndex];
-						jQuery(description).empty().append(describeGene(select.value));
-					};
-					el.append(select);
+					el.append(App.UI.DOM.makeSelect(options, null, gene => {
+						jQuery(description).empty().append(describeGene(gene));
+					}));
 				}
 
 				return el;
@@ -171,6 +178,47 @@ App.UI.surgeryPassageExotic = function(slave, refreshParent, cheat = false) {
 			}
 		}
 
+		function milkFlavoring() {
+			const el = new DocumentFragment();
+			App.UI.DOM.appendNewElement("h2", el, "Milk Flavor");
+			const options = new App.UI.OptionsGroup();
+			let option;
+			let title;
+			let showChoices = true;
+
+			if (slave.milkFlavor === "natural") {
+				title = `${His} milk is natural.`;
+			} else {
+				title = `${His} milk is ${slave.milkFlavor} flavored.`;
+			}
+			App.UI.DOM.appendNewElement("div", el, title);
+
+			if (showChoices) {
+				if (slave.milkFlavor !== "natural") {
+					options.addCustomOption("")
+						.addButton("Remove flavoring", () => {
+							slave.milkFlavor = "natural";
+							App.UI.reload();
+						});
+				}
+
+				option = options.addOption("Flavors", "milkFlavor", slave);
+				for (const flavor of App.Data.milk.Flavors) {
+					option.addValue(capFirstChar(flavor.value), flavor.value, billMod);
+				}
+				option.pulldown();
+			}
+			el.append(options.render());
+
+			return el;
+
+			function billMod() {
+				if (!cheat) {
+					cashX(forceNeg(V.modCost), "slaveMod", slave);
+				}
+			}
+		}
+
 		function bodySwap() {
 			const el = new DocumentFragment();
 			const r = [];
diff --git a/src/facilities/surgery/surgeryPassageFaceAndHair.js b/src/facilities/surgery/surgeryPassageFaceAndHair.js
index e5b15ef77d03f44172d3795fff1fad4505838b25..ffe425dfae92be8ac31495c5557e25616daad15c 100644
--- a/src/facilities/surgery/surgeryPassageFaceAndHair.js
+++ b/src/facilities/surgery/surgeryPassageFaceAndHair.js
@@ -536,13 +536,13 @@ App.UI.surgeryPassageHairAndFace = function(slave, refreshParent, cheat = false)
 
 			if (slave.earImplant !== 1) {
 				if (slave.hears === -1) {
-					if (slave.earImplant !== 1 && slave.earShape !== "none") {
+					if (slave.earShape !== "none") {
 						linkArray.push(App.Medicine.Surgery.makeLink(
 							new App.Medicine.Surgery.Procedures.EarFix(slave),
 							refresh, cheat));
 					}
 				} else if (slave.hears === 0) {
-					if (V.seeExtreme === 1 && slave.earImplant !== 1 && slave.indentureRestrictions < 1) {
+					if (V.seeExtreme === 1 && slave.indentureRestrictions < 1) {
 						linkArray.push(App.Medicine.Surgery.makeLink(
 							new App.Medicine.Surgery.Procedures.EarMuffle(slave),
 							refresh, cheat));
@@ -634,36 +634,13 @@ App.UI.surgeryPassageHairAndFace = function(slave, refreshParent, cheat = false)
 				r.push(`${He} has moderate lip implants.`);
 			}
 			r.push(App.UI.DOM.makeElement("span", `New implants will reduce ${his} oral skills`, "note"));
+
 			App.Events.addNode(el, r, "div");
 
-			if (slave.indentureRestrictions >= 2) {
-				App.UI.DOM.appendNewElement("div", el, `${His} indenture forbids elective surgery`, ["choices", "note"]);
-			} else if ((slave.lips <= 75) || ((slave.lips <= 95) && (V.seeExtreme === 1))) {
-				if (slave.lipsImplant > 0) {
-					linkArray.push(App.Medicine.Surgery.makeLink(
-						new App.Medicine.Surgery.Procedures.IncreaseLipImplant(slave),
-						refresh, cheat));
-				} else {
-					linkArray.push(App.Medicine.Surgery.makeLink(
-						new App.Medicine.Surgery.Procedures.AddLipImplant(slave),
-						refresh, cheat));
-				}
-			}
-			if (slave.lipsImplant !== 0) {
-				if (slave.indentureRestrictions < 2) {
-					linkArray.push(App.Medicine.Surgery.makeLink(
-						new App.Medicine.Surgery.Procedures.RemoveLipImplant(slave),
-						refresh, cheat));
-				}
-			}
-			if (slave.lips >= 10 && slave.lipsImplant === 0) {
-				if (slave.indentureRestrictions < 2) {
-					linkArray.push(App.Medicine.Surgery.makeLink(
-						new App.Medicine.Surgery.Procedures.ReduceLips(slave),
-						refresh, cheat));
-				}
-			}
-			App.UI.DOM.appendNewElement("div", el, App.UI.DOM.generateLinksStrip(linkArray), "choices");
+			const surgeries = App.Medicine.Surgery.sizingProcedures.lips(slave, App.Medicine.Surgery.allSizingOptions());
+			const surgeryLinks = surgeries.map(s => App.Medicine.Surgery.makeLink(s, refresh, cheat));
+			App.UI.DOM.appendNewElement("div", el, (App.UI.DOM.generateLinksStrip(surgeryLinks)), ["choices"]);
+
 			return el;
 		}
 
diff --git a/src/facilities/surgery/surgeryPassageStructural.js b/src/facilities/surgery/surgeryPassageStructural.js
index 72ab09b9f1bc3f59654939b0143df09e26021b4d..9abd966edd24f1441a85d66d0b0f660077a5f52b 100644
--- a/src/facilities/surgery/surgeryPassageStructural.js
+++ b/src/facilities/surgery/surgeryPassageStructural.js
@@ -19,12 +19,16 @@ App.UI.surgeryPassageStructural = function(slave, refreshParent, cheat = false)
 		} = getPronouns(slave);
 
 		frag.append(shoulders(), hips());
-		if (hasBothNaturalLegs(slave)) {
+		if (hasAnyNaturalLegs(slave)) {
 			frag.append(limbLength(), tendons());
+		} else if (hasAnyNaturalArms(slave)) {
+			frag.append(limbLength());
 		}
+		App.UI.DOM.appendNewElement("h3", frag, `Amputation`);
 		if (slave.indenture < 0) {
-			App.UI.DOM.appendNewElement("h3", frag, `Amputation`);
 			frag.append(amputate());
+		} else {
+			App.UI.DOM.appendNewElement("div", frag, `${His} indenture forbids disfiguring surgery.`);
 		}
 		App.UI.DOM.appendNewElement("h3", frag, `Prosthetics`);
 		frag.append(prostheticInterface(), tail(), back(), App.Medicine.OrganFarm.fullMenu(slave, refresh, cheat));
diff --git a/src/facilities/surgery/surgeryPassageUpper.js b/src/facilities/surgery/surgeryPassageUpper.js
index c3412a38df1ed4c4e50f90223aef64791314fb9a..6f8bbec972dc53a5e821306d247661d8c6177033 100644
--- a/src/facilities/surgery/surgeryPassageUpper.js
+++ b/src/facilities/surgery/surgeryPassageUpper.js
@@ -409,30 +409,29 @@ App.UI.surgeryPassageUpper = function(slave, refreshParent, cheat = false) {
 			} else if (slave.bellyImplant > 0) {
 				r.push(`got a ${slave.bellyImplant}cc implant filled implant located in ${his} abdomen.`);
 				if (slave.cervixImplant === 1) {
-					r.push(`${He} also has micropump filter installed in ${his} cervix feeding into the implant.`);
+					r.push(`${He} also has a micropump filter installed in ${his} cervix feeding into the implant.`);
 				} else if (slave.cervixImplant === 2) {
-					r.push(`${He} also has micropump filter installed in ${his} rectum feeding into the implant.`);
+					r.push(`${He} also has a micropump filter installed in ${his} rectum feeding into the implant.`);
 				} else if (slave.cervixImplant === 3) {
-					r.push(`${He} also has micropump filter installed in both ${his} holes feeding into the implant.`);
+					r.push(`${He} also has a micropump filter installed in both ${his} holes feeding into the implant.`);
 				}
-			} else if (slave.bellyFluid >= 1500) {
-				r.push(`got a ${slave.inflationType}-filled implant located in ${his} abdomen.`);
-				if (slave.cervixImplant === 1) {
-					r.push(`${He} also has micropump filter installed in ${his} cervix feeding into the implant.`);
-				} else if (slave.cervixImplant === 2) {
-					r.push(`${He} also has micropump filter installed in ${his} rectum feeding into the implant.`);
-				} else if (slave.cervixImplant === 3) {
-					r.push(`${He} also has micropump filter installed in both ${his} holes feeding into the implant.`);
+				if (slave.bellyFluid >= 1500) {
+					r.push(`${He} also has a bellyful of ${slave.inflationType}.`);
 				}
 			} else if (slave.bellyImplant === 0) {
 				r.push(`got an empty fillable implant located in ${his} abdomen.`);
 				if (slave.cervixImplant === 1) {
-					r.push(`${He} also has micropump filter installed in ${his} cervix feeding into the implant.`);
+					r.push(`${He} also has a micropump filter installed in ${his} cervix feeding into the implant.`);
 				} else if (slave.cervixImplant === 2) {
-					r.push(`${He} also has micropump filter installed in ${his} rectum feeding into the implant.`);
+					r.push(`${He} also has a micropump filter installed in ${his} rectum feeding into the implant.`);
 				} else if (slave.cervixImplant === 3) {
-					r.push(`${He} also has micropump filter installed in both ${his} holes feeding into the implant.`);
+					r.push(`${He} also has a micropump filter installed in both ${his} holes feeding into the implant.`);
+				}
+				if (slave.bellyFluid >= 1500) {
+					r.push(`${He} also has a bellyful of ${slave.inflationType}.`);
 				}
+			} else if (slave.bellyFluid >= 1500) {
+				r.push(`got a bellyful of ${slave.inflationType}.`);
 			} else {
 				r.push(`got a normal stomach.`);
 			}
diff --git a/src/facilities/toyShop/toyShop.js b/src/facilities/toyShop/toyShop.js
index 4e910d977a1da986d7ac2637f112a4c07f12b59d..300d5b90b6cf74ef7047326a836ffa9ff0b19b36 100644
--- a/src/facilities/toyShop/toyShop.js
+++ b/src/facilities/toyShop/toyShop.js
@@ -326,32 +326,21 @@ App.UI.toyShop = function() {
 	/**
 	 * @param {toy} toy
 	 * @param {string} itemKey
-	 * @returns {DocumentFragment}
+	 * @returns {HTMLElement}
 	 */
 	function selectDesign(toy, itemKey) {
-		const el = new DocumentFragment();
-		const choice = App.UI.DOM.appendNewElement("span", el, ` or choose an existing design to edit `);
-		const select = App.UI.DOM.appendNewElement("select", choice);
-		let matchFound = false;
+		const choice = App.UI.DOM.makeElement("span", ` or choose an existing design to edit `);
+		const options = [];
 		for (const [key, values] of V.customItem[itemKey]) {
-			const option = App.UI.DOM.appendNewElement("option", select, values.name);
-			option.value = key;
-			if (option.value === toy.name) {
-				option.selected = true;
-				matchFound = true;
-			}
-		}
-		if (!matchFound) {
-			select.selectedIndex = -1;
+			options.push({key: key, name: values.name});
 		}
-		select.onchange = () => {
-			const O = select.options[select.selectedIndex];
-			toy.selected = O.value;
+		choice.append(App.UI.DOM.makeSelect(options, toy.name, key => {
+			toy.selected = key;
 			toy.name = toy.selected;
 			toy.data = V.customItem[itemKey].get(toy.selected);
 			refresh();
-		};
-		return el;
+		}));
+		return choice;
 	}
 
 	function refresh() {
diff --git a/src/futureSocieties/fsDecoration.js b/src/futureSocieties/fsDecoration.js
index f923166cb32ad50d148abe06d12c4a7c47ed348c..88681cef66b82e451ad85acf79c59b1ab410c810 100644
--- a/src/futureSocieties/fsDecoration.js
+++ b/src/futureSocieties/fsDecoration.js
@@ -85,16 +85,11 @@ App.UI.FSChangeDecoration = function(FS, items = []) {
 			el.append(`${V.arcologies[0].name} is not customized to support this goal. `);
 			if (V.arcologies[0][FS] >= 10) {
 				el.append(
-					App.UI.DOM.link(
-						`Modify your arcology's internal media to support this goal`,
-						() => {
+					makePurchase(`Modify your arcology's internal media to support this goal`, costs, "capEx", {
+						handler: () => {
 							V.arcologies[0][FSDecoration] = 40;
-							cashX(forceNeg(costs), "capEx");
 						},
-						[],
-						"Future Society",
-						`Costs ${cashFormat(costs)}`
-					),
+					}),
 				);
 			} else {
 				el.append(`You must advance this goal before customization to support it becomes available. `);
@@ -105,16 +100,11 @@ App.UI.FSChangeDecoration = function(FS, items = []) {
 			if (V.arcologies[0][FS] >= 30) {
 				costs = 10000;
 				el.append(
-					App.UI.DOM.link(
-						`Redecorate your arcology's public spaces to support this goal`,
-						() => {
+					makePurchase(`Redecorate your arcology's public spaces to support this goal`, costs, "capEx", {
+						handler: () => {
 							V.arcologies[0][FSDecoration] = 60;
-							cashX(forceNeg(costs), "capEx");
-						},
-						[],
-						"Future Society",
-						`Costs ${cashFormat(costs)}`
-					),
+						}
+					}),
 				);
 			} else {
 				el.append(`You must advance this goal before further customization to support it becomes available. `);
@@ -125,16 +115,11 @@ App.UI.FSChangeDecoration = function(FS, items = []) {
 			if (V.arcologies[0][FS] >= 50) {
 				costs = 10000;
 				el.append(
-					App.UI.DOM.link(
-						`Station slaves in your arcology's public spaces to promote this goal`,
-						() => {
+					makePurchase(`Station slaves in your arcology's public spaces to promote this goal`, costs, "capEx", {
+						handler: () => {
 							V.arcologies[0][FSDecoration] = 80;
-							cashX(forceNeg(costs), "capEx");
-						},
-						[],
-						"Future Society",
-						`Costs ${cashFormat(costs)}`
-					),
+						}
+					}),
 				);
 			} else {
 				el.append(`You must advance this goal before further customization to support it becomes available. `);
@@ -146,37 +131,29 @@ App.UI.FSChangeDecoration = function(FS, items = []) {
 				if (FS === "FSRestart") {
 					costs = 75000;
 					el.append(
-						App.UI.DOM.link(
-							`Customize the exterior of the arcology to support this goal and fully establish the Societal Elite`,
-							() => {
+						makePurchase(`Customize the exterior of the arcology to support this goal and fully establish the Societal Elite`, costs, "capEx", {
+							handler: () => {
 								V.arcologies[0][FSDecoration] = 100;
 								V.upgradeMultiplierArcology = upgradeMultiplier('engineering');
 								V.upgradeMultiplierMedicine = upgradeMultiplier('medicine');
 								for (const item of items) {
 									_.set(V, item, 1);
 								}
-							},
-							[],
-							"Future Society",
-							`Costs ${cashFormat(costs)}`
-						),
+							}
+						}),
 					);
 				} else {
 					costs = 10000;
 					el.append(
-						App.UI.DOM.link(
-							`Customize the exterior of the arcology to support this goal`,
-							() => {
+						makePurchase(`Customize the exterior of the arcology to support this goal`, costs, "capEx", {
+							handler: () => {
 								V.arcologies[0][FSDecoration] = 100;
 								cashX(forceNeg(costs), "capEx");
 								for (const item of items) {
 									_.set(V, item, 1);
 								}
-							},
-							[],
-							"Future Society",
-							`Costs ${cashFormat(costs)}`
-						),
+							}
+						}),
 					);
 				}
 			} else {
diff --git a/src/futureSocieties/fsPassage.js b/src/futureSocieties/fsPassage.js
index dbf0835259b3b482b5b6f69ac1bbf8c17bcb8855..a43f65ae91fd8ee418be2c6f31ec1f1ffdc69a21 100644
--- a/src/futureSocieties/fsPassage.js
+++ b/src/futureSocieties/fsPassage.js
@@ -38,84 +38,84 @@ App.UI.fsPassage = function() {
 	 * FIRST FS STORING FOR RIVALRY
 	 */
 	function setup() {
-		if (V.rivalryFS === 0) {
+		if (V.rival.FS.name === "") {
 			if (arc.FSSubjugationist !== "unset") {
-				V.rivalryFS = "Racial Subjugationism";
-				V.rivalryFSRace = arc.FSSubjugationistRace;
+				V.rival.FS.name = "Racial Subjugationism";
+				V.rival.FS.race = arc.FSSubjugationistRace;
 			}
 			if (arc.FSSupremacist !== "unset") {
-				V.rivalryFS = "Racial Supremacism";
-				V.rivalryFSRace = arc.FSSupremacistRace;
+				V.rival.FS.name = "Racial Supremacism";
+				V.rival.FS.race = arc.FSSupremacistRace;
 			}
 			if (arc.FSGenderRadicalist !== "unset") {
-				V.rivalryFS = "Gender Radicalism";
+				V.rival.FS.name = "Gender Radicalism";
 			} else if (arc.FSGenderFundamentalist !== "unset") {
-				V.rivalryFS = "Gender Fundamentalism";
+				V.rival.FS.name = "Gender Fundamentalism";
 			}
 			if (arc.FSRepopulationFocus !== "unset") {
-				V.rivalryFS = "Repopulation Focus";
+				V.rival.FS.name = "Repopulation Focus";
 			} else if (arc.FSRestart !== "unset") {
-				V.rivalryFS = "Eugenics";
+				V.rival.FS.name = "Eugenics";
 			}
 			if (arc.FSPaternalist !== "unset") {
-				V.rivalryFS = "Paternalism";
+				V.rival.FS.name = "Paternalism";
 			} else if (arc.FSDegradationist !== "unset") {
-				V.rivalryFS = "Degradationism";
+				V.rival.FS.name = "Degradationism";
 			}
 			if (arc.FSBodyPurist !== "unset") {
-				V.rivalryFS = "Body Purism";
+				V.rival.FS.name = "Body Purism";
 			} else if (arc.FSTransformationFetishist !== "unset") {
-				V.rivalryFS = "Transformation Fetishism";
+				V.rival.FS.name = "Transformation Fetishism";
 			}
 			if (arc.FSYouthPreferentialist !== "unset") {
-				V.rivalryFS = "Youth Preferentialism";
+				V.rival.FS.name = "Youth Preferentialism";
 			} else if (arc.FSMaturityPreferentialist !== "unset") {
-				V.rivalryFS = "Maturity Preferentialism";
+				V.rival.FS.name = "Maturity Preferentialism";
 			}
 			if (arc.FSSlimnessEnthusiast !== "unset") {
-				V.rivalryFS = "Slimness Enthusiasm";
+				V.rival.FS.name = "Slimness Enthusiasm";
 			} else if (arc.FSAssetExpansionist !== "unset") {
-				V.rivalryFS = "Asset Expansionism";
+				V.rival.FS.name = "Asset Expansionism";
 			}
 			if (arc.FSPastoralist !== "unset") {
-				V.rivalryFS = "Pastoralism";
+				V.rival.FS.name = "Pastoralism";
 			} else if (arc.FSCummunism !== "unset") {
-				V.rivalryFS = "Cummunism";
+				V.rival.FS.name = "Cummunism";
 			}
 			if (arc.FSHedonisticDecadence !== "unset") {
-				V.rivalryFS = "Hedonistic Decadence";
+				V.rival.FS.name = "Hedonistic Decadence";
 			} else if (arc.FSPhysicalIdealist !== "unset") {
-				V.rivalryFS = "Physical Idealism";
+				V.rival.FS.name = "Physical Idealism";
 			}
 			if (arc.FSIntellectualDependency !== "unset") {
-				V.rivalryFS = "Intellectual Dependency";
+				V.rival.FS.name = "Intellectual Dependency";
 			} else if (arc.FSSlaveProfessionalism !== "unset") {
-				V.rivalryFS = "Slave Professionalism";
+				V.rival.FS.name = "Slave Professionalism";
 			}
 			if (arc.FSPetiteAdmiration !== "unset") {
-				V.rivalryFS = "Petite Admiration";
+				V.rival.FS.name = "Petite Admiration";
 			} else if (arc.FSStatuesqueGlorification !== "unset") {
-				V.rivalryFS = "Statuesque Glorification";
+				V.rival.FS.name = "Statuesque Glorification";
 			}
 			if (arc.FSChattelReligionist !== "unset") {
-				V.rivalryFS = "Chattel Religionism";
+				V.rival.FS.name = "Chattel Religionism";
 			} else if (arc.FSNull !== "unset") {
-				V.rivalryFS = "Multiculturalism";
+				V.rival.FS.name = "Multiculturalism";
 			}
 			if (arc.FSRomanRevivalist !== "unset") {
-				V.rivalryFS = "Roman Revivalism";
+				V.rival.FS.name = "Roman Revivalism";
 			} else if (arc.FSNeoImperialist !== "unset") {
-				V.rivalryFS = "Neo-Imperialism";
+				V.rival.FS.name = "Neo-Imperialism";
 			} else if (arc.FSAztecRevivalist !== "unset") {
-				V.rivalryFS = "Aztec Revivalism";
+				V.rival.FS.name = "Aztec Revivalism";
 			} else if (arc.FSEgyptianRevivalist !== "unset") {
-				V.rivalryFS = "Egyptian Revivalism";
+				V.rival.FS.name = "Egyptian Revivalism";
 			} else if (arc.FSEdoRevivalist !== "unset") {
-				V.rivalryFS = "Edo Revivalism";
+				V.rival.FS.name = "Edo Revivalism";
 			} else if (arc.FSArabianRevivalist !== "unset") {
-				V.rivalryFS = "Arabian Revivalism";
+				V.rival.FS.name = "Arabian Revivalism";
 			} else if (arc.FSChineseRevivalist !== "unset") {
-				V.rivalryFS = "Chinese Revivalism";
+				V.rival.FS.name = "Chinese Revivalism";
 			}
 		}
 	}
@@ -372,21 +372,14 @@ App.UI.fsPassage = function() {
 					r.push(`${arc.FSSupremacistRace} superiority.`);
 				}
 				r.push(`Select race:`);
-				const select = document.createElement("select");
-				r.push(select);
+				const options = [];
 				for (const race of App.Utils.getRaceArrayWithoutParamRace(arc.FSSubjugationistRace)) { // Subjugation race cannot be superior, so remove
-					const choice = App.UI.DOM.appendNewElement("option", select, capFirstChar(race));
-					choice.value = race;
-					if (race === arc.FSSupremacistRace) {
-						choice.selected = true;
-					}
+					options.push({key: race, name: capFirstChar(race)});
 				}
-
-				select.onchange = () => {
-					const O = select.options[select.selectedIndex];
-					arc.FSSupremacistRace = O.value;
+				r.push(App.UI.DOM.makeSelect(options, arc.FSSupremacistRace, race => {
+					arc.FSSupremacistRace = /** @type {FC.Race} */ (race);
 					App.UI.reload();
-				};
+				}));
 			} else {
 				/* <span class="note"><span style="font-weight:Bold">Racial Supremacism:</span> a belief in the superiority of a chosen race.</span>*/
 			}
@@ -415,22 +408,15 @@ App.UI.fsPassage = function() {
 					r.push(`${arc.FSSubjugationistRace} inferiority.`);
 				}
 				r.push(`Select race:`);
-				const select = document.createElement("select");
-				r.push(select);
 
+				const options = [];
 				for (const race of App.Utils.getRaceArrayWithoutParamRace(arc.FSSupremacistRace)) { // Superior race cannot be subj, so remove
-					const choice = App.UI.DOM.appendNewElement("option", select, capFirstChar(race));
-					choice.value = race;
-					if (race === arc.FSSubjugationistRace) {
-						choice.selected = true;
-					}
+					options.push({key: race, name: capFirstChar(race)});
 				}
-
-				select.onchange = () => {
-					const O = select.options[select.selectedIndex];
-					arc.FSSubjugationistRace = O.value;
+				r.push(App.UI.DOM.makeSelect(options, arc.FSSubjugationistRace, race => {
+					arc.FSSubjugationistRace = race;
 					App.UI.reload();
-				};
+				}));
 			} else {
 				/* <span class="note"><span style="font-weight:Bold">Racial Subjugationism:</span> a belief in the inferiority of a subject race.</span>*/
 			}
@@ -732,6 +718,15 @@ App.UI.fsPassage = function() {
 							"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();
 							}
 						)
@@ -756,6 +751,13 @@ App.UI.fsPassage = function() {
 							"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();
 							}
 						)
diff --git a/src/futureSocieties/futureSociety.js b/src/futureSocieties/futureSociety.js
index 20967c98c1ce532b7dcb103bfbcb3594c6b0df39..ef28cb60a6c758131e22069205cd3437a83f2d57 100644
--- a/src/futureSocieties/futureSociety.js
+++ b/src/futureSocieties/futureSociety.js
@@ -26,7 +26,8 @@ globalThis.FutureSocieties = (function() {
 		DecorationBonus: FSDecorationBonus,
 		Change: FSChange,
 		HighestDecoration: FSHighestDecoration,
-		arcSupport: arcSupport
+		arcSupport: arcSupport,
+		researchAvailable,
 	};
 
 	/** get the list of FSes active for a particular arcology
@@ -334,6 +335,7 @@ globalThis.FutureSocieties = (function() {
 				}
 				V.propOutcome = 0;
 				V.failedElite = 0;
+				V.playerBred = 0;
 				break;
 			case "FSIntellectualDependency":
 				arcology.FSIntellectualDependencyLaw = 0;
@@ -405,7 +407,7 @@ globalThis.FutureSocieties = (function() {
 
 	/* call as FutureSocieties.DecorationCleanup() */
 	function DecorationCleanup() {
-		for (const facility of Object.values(App.Entity.facilities).filter(f => f.isDecorated)) {
+		for (const facility of Object.values(App.Entity.facilities).filter(f => f.established && f.isDecorated)) {
 			ValidateFacilityDecoration(facility);
 		}
 	}
@@ -798,4 +800,14 @@ globalThis.FutureSocieties = (function() {
 			}
 		}
 	}
+
+	/**
+	 *
+	 * @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;
+	}
 })();
diff --git a/src/gui/Encyclopedia/encyclopedia.tw b/src/gui/Encyclopedia/encyclopedia.tw
index fc06e17d0f8387d5cffbadf0f7ee6953ffeb6133..c13e2573c188e5f27cbb7370ffb59104a78c169f 100644
--- a/src/gui/Encyclopedia/encyclopedia.tw
+++ b/src/gui/Encyclopedia/encyclopedia.tw
@@ -851,8 +851,6 @@ ARCOLOGY FACILITIES
 <<case "Nursery">>
 	The ''Nursery'' is used to raise children from birth naturally. Once a spot is reserved for the child, they will be placed in the Nursery upon birth and ejected once they are old enough. The Nursery can be furnished according to <<= App.Encyclopedia.Dialog.linkSC("future society", "Future Societies")>> styles, and doing so can add a slight @@.hotpink;<<= App.Encyclopedia.Dialog.linkSC("devotion", "From Rebellious to Devoted")>>@@ boost to slaves working there.
 
-	<br><br>''Extended family mode must be enabled.'' //This entry still needs work and will be updated with more information as it matures. If this message is still here, remind one of the devs to remove it.//
-
 
 <<case "Farmyard">>		/* TODO: this will need more information */
 	The ''Farmyard'' is where the majority of the <<= App.Encyclopedia.Dialog.linkSC("food", "Food")>> in your arcology is grown, once it is built. It also allows you to house animals<<if $seeBestiality == 1>>, which you can have interact with your slaves<</if>>. The Farmyard can be furnished according to <<= App.Encyclopedia.Dialog.linkSC("future society", "Future Societies")>> styles, and doing so can add a slight @@.hotpink;<<= App.Encyclopedia.Dialog.linkSC("devotion", "From Rebellious to Devoted")>>@@ boost to slaves working there. /* TODO: this may need to be changed */
@@ -1936,7 +1934,7 @@ LORE: INTERVIEWS
 	<br>''Autistic Boi'' for Mediterranean market preset.
 	<br>''anon'' for the PA subjugationist and supremacist FS appearances.
 	<br>''Editoranon and Milkanon?'' for prison markets and the nursing handjob scene.
-	<br>''DCoded'' for creating the favicon and adding animals to the Pit, as well as nursery and animal-related content, scenes, facilities and fixes. Also added an oral scene, the reminder system, and created and fixed a number of bugs.
+	<br>''DCoded'' for creating the favicon, nursery, and farmyard, as well as animal-related content. Created a food system as well as a loan system. Refactored tons of code and standardized the facility passages. Also added several new scenes and interactions, the reminder system, and created and fixed a number of bugs.
 	<br>''HiveBro'' for giving hyperpregnant slaves some serious loving.
 	<br>''Quin2k'' for overwriting save function and expired tweak via Vrelnir & co.
 	<br>''ezsh'' for bugfixing and creating a tool to build twineJS and twineCSS for me. Set up a revised SC update process as well. Has contributed massive revisions to the game's structure. Keeps the RA in line.
@@ -2139,8 +2137,6 @@ MODS
 <<case "The Incubation Facility">>
 	A facility used to rapidly age children kept within its aging tanks using a combination of growth hormones, accelerants, stem cells and other chemicals; slaves that come out of it are rarely healthy. The Incubator requires a massive amount of electricity to run, though once powered contains a battery backup that can last at least a day. It can be upgraded to combat malnutrition and thinness caused by a body growing far beyond any natural rate. Hormones can also be added to encourage puberty and even sex organ development. Growth control systems include cost saving overrides, though enabling them may result in bloated, sex crazed slaves barely capable of moving.
 
-	<br><br>''Extended family mode must be enabled.'' /*Removed for brevity, replace if necessary*/
-
 <<case "Organic Mesh Breast Implant">>
 	A specialized organic implant produced from the dispensary designed to be implanted into to a slave's natural breast tissue to maintain a slave's breast shape no matter how big her breasts may grow. An expensive and risky procedure proportional to the size of the breasts the mesh will be implanted into. Should health become an issue, the slave in surgery may undergo an emergency mastectomy. Furthermore, once implanted, the mesh cannot be safely removed from the breast. However, total breast removal will rid the slave of the implant; consider strongly when and if you want to implant the mesh before doing so. They are exceedingly difficult to identify once bound to the breast tissue, and combined with their natural shape, are often overlooked.
 
diff --git a/src/gui/Encyclopedia/encyclopediaBeingInCharge.js b/src/gui/Encyclopedia/encyclopediaBeingInCharge.js
index a22593a9a1b6e145928a91cdcc08cf455727bfee..091847ce13606e00fc198badf89776dcebff09d1 100644
--- a/src/gui/Encyclopedia/encyclopediaBeingInCharge.js
+++ b/src/gui/Encyclopedia/encyclopediaBeingInCharge.js
@@ -121,19 +121,10 @@ App.Encyclopedia.addArticle("Rules Assistant", function() {
 	App.Events.addParagraph(f, r);
 
 	r = [];
-	r.push(App.Encyclopedia.topic("Rule activation"));
-	r.push("In order to apply a rule to slaves, the activation will need to be set. Choose an activation type");
-	r.push(App.UI.DOM.combineNodes("(",
-		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,");
-	r.push(App.UI.DOM.combineNodes(App.Encyclopedia.Dialog.linkDOM("health", "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, fetuses, implant size, or age) and then choose the level at which to apply. For example to apply a rule to obedient slaves, choose");
-	r.push(App.Encyclopedia.Dialog.linkDOM("devotion", "From Rebellious to Devoted", "devotion accept"));
-	r.push("for the activation and 4 or more for the lower limit by selecting <span class='encyclopedia interaction'>>=.</span>");
-	r.push(`You can also create custom conditions using any property of a slave, which you can find documented <a target='_blank' class='link-external' href='https://gitgud.io/pregmodfan/fc-pregmod/-/raw/pregmod-master/devNotes/legacy files/slave%20variables%20documentation.md'>here.</a>`);
+	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 = [];
@@ -141,11 +132,6 @@ App.Encyclopedia.addArticle("Rules Assistant", function() {
 	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("Applying a rule to specific assignments"));
-	r.push("You can apply a rule only to slaves on individual assignments by selecting them under <span class='encyclopedia interaction'>Apply to assignments.</span> For example a rule can give aphrodisiacs to slaves on whoring assignments. <span class='note'>This is mutually exclusive to automatically giving an assignment to slaves.</span>");
-	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");
@@ -153,11 +139,6 @@ App.Encyclopedia.addArticle("Rules Assistant", function() {
 	r.push("slave can be set to automatically be put on the whoring assignment. <span class='note'>This is mutually exclusive to applying a rule to assignments.</span>");
 	App.Events.addParagraph(f, r);
 
-	r = [];
-	r.push(App.Encyclopedia.topic("Applying a rule to facilities"));
-	r.push("You can apply a rule to slaves in any or all facilities as long as that facility has been constructed. The rule will only apply to slaves within the selected facilities. <span class='note'>This is mutually exclusive to automatically putting slaves into a facility.</span>");
-	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. <span class='note'>This is mutually exclusive to applying a rule to facilities.</span>");
@@ -294,6 +275,7 @@ App.Encyclopedia.addCategory("beingInCharge", function() {
 	links.push(App.Encyclopedia.Dialog.linkDOM("Random Events", "Random Events"));
 	links.push(App.Encyclopedia.Dialog.linkDOM("Costs Summary", "Costs Summary"));
 	links.push(App.Encyclopedia.Dialog.linkDOM("Rules Assistant", "Rules Assistant"));
+	links.push(App.Encyclopedia.Dialog.linkDOM("RA Condition Editor", "RA Condition Editor"));
 	links.push(App.Encyclopedia.Dialog.linkDOM("The Corporation", "The Corporation"));
 	links.push(App.Encyclopedia.Dialog.linkDOM("Sexual Energy", "Sexual Energy"));
 	links.push(App.Encyclopedia.Dialog.linkDOM("PC Skills", "PC Skills"));
diff --git a/src/gui/Encyclopedia/encyclopediaRAActivationEditor.js b/src/gui/Encyclopedia/encyclopediaRAActivationEditor.js
new file mode 100644
index 0000000000000000000000000000000000000000..78e8cad4665e1c0bef587fb92d2cd60f2d9d01b3
--- /dev/null
+++ b/src/gui/Encyclopedia/encyclopediaRAActivationEditor.js
@@ -0,0 +1,142 @@
+App.Encyclopedia.addArticle("RA Condition Editor", function() {
+	/**
+	 * @param {HTMLElement} container
+	 * @param {string} col1
+	 * @param {string} col2
+	 * @param {string} col3
+	 */
+	function tableHead(container, col1, col2, col3) {
+		App.UI.DOM.appendNewElement("div", container, col1, "head");
+		App.UI.DOM.appendNewElement("div", container, col2, "head");
+		App.UI.DOM.appendNewElement("div", container, col3, "head");
+	}
+
+	/**
+	 * @param {ReadonlyMap<string, Getter<*>>} getters
+	 */
+	function getterTable(getters) {
+		const container = document.createElement("p");
+		container.classList.add("rule-help-table");
+
+		tableHead(container, "Name", "Description", "Requirements");
+
+		for (const getter of getters.values()) {
+			if (getter.visible && !getter.visible()) {
+				continue;
+			}
+			App.UI.DOM.appendNewElement("div", container, getter.name);
+			App.UI.DOM.appendNewElement("div", container, getter.description);
+			const div = document.createElement("div");
+			if (getter.requirements) {
+				div.append(getter.requirements);
+			}
+			container.append(div);
+		}
+
+		return container;
+	}
+
+	/**
+	 * @param {HTMLElement} container
+	 * @param {string} name
+	 * @param {string} description
+	 * @param {string} dataTypes
+	 */
+	function transformerRow(container, name, description, dataTypes) {
+		App.UI.DOM.appendNewElement("div", container, name);
+		App.UI.DOM.appendNewElement("div", container, description);
+		App.UI.DOM.appendNewElement("div", container, dataTypes);
+	}
+
+	function transformerTable() {
+		const el = document.createElement("p");
+		el.classList.add("rule-help-table");
+
+		tableHead(el, "Name", "Description", "Data types");
+
+		transformerRow(el, "And", "True, if all input values are true.", "Boolean");
+		transformerRow(el, "Or", "True, if at least one input value is true.", "Boolean");
+		transformerRow(el, "Sum all", "Sums up all input values", "Number");
+		transformerRow(el, "Multiply all", "Multiplies all input values", "Number");
+		transformerRow(el, "Maximum", "Gives the largest input value", "Number");
+		transformerRow(el, "Minimum", "Gives the smallest input value", "Number");
+		transformerRow(el, "=, ≠", "Compares the input values based on the comparator in " +
+			"the middle. Both sides need to have the same data type.", "Boolean, Number, String");
+		transformerRow(el, "<, ⩽, >, ⩾", "Compares the input values based on the comparator in " +
+			"the middle. Both sides need to have the same data type.", "Boolean, Number");
+		transformerRow(el, "-", "Subtracts the second value from the first value", "Number");
+		transformerRow(el, "/", "Divides the second value by the first value", "Number");
+		transformerRow(el, "Contains", "True, if the second value is somewhere in the first value",
+			"String");
+		transformerRow(el, "Not …", "Negates the input value.", "Boolean");
+		transformerRow(el, "If … Then … Else …",
+			"If the first value is true, returns the second value, otherwise the third value. The second " +
+			"and third input value have to be the same data type.", "Boolean / Any");
+
+		return el;
+	}
+
+	const acc = new SpacedTextAccumulator();
+
+	acc.push("Rule conditions consist of two types of elements, data getters and data transformers. Data getters can " +
+		"read out values from various places, which can then be used to base conditions on. Data transformers " +
+		"take one or more elements as input and transform the input values into a single new value. Together they " +
+		"can create complex conditions for activating rules.");
+	acc.toParagraph();
+
+	acc.push("To build a new condition drag the elements you need from the part browser into the main condition " +
+		"field next to it.");
+	acc.toParagraph();
+
+	App.UI.DOM.appendNewElement("h2", acc.container(), "Finding errors");
+	acc.push("It is possible to create element trees which are invalid, for example because the input value of an " +
+		"element has the wrong data type. When this is the case there will be an error message above the rule " +
+		"editor and the broken elements are marked. As long as there are errors the rule cannot be saved and will " +
+		"revert to it's previous state when leaving the RA or editing another rule. In the error message the first " +
+		"error corresponds to the innermost broken element. When solving errors it is advised to work from inside to " +
+		"outside, as outer errors are often caused by errors further inside.");
+	acc.toParagraph();
+
+	App.UI.DOM.appendNewElement("h2", acc.container(), "Data transformers");
+	acc.push("Data transformers can handle 3 different data types: Boolean, Number and String. Not all transformers " +
+		"accept all data types. Number and Boolean can be used interchangeably, the conversion is as follows: " +
+		"Putting a Number into a boolean transformer will interpret 0 as false and all other values as true. " +
+		"Putting a Boolean into a number transformer will interpret false as 0 and true as 1.");
+	acc.toParagraph();
+	acc.container().append(transformerTable());
+
+	App.UI.DOM.appendNewElement("h2", acc.container(), "Data getters");
+
+	acc.push("There are a number of predefined getters which read values either from a slave or from the global " +
+		"state. They always have a predefined data type.");
+	acc.toParagraph();
+
+	let c = acc.container();
+	App.UI.DOM.appendNewElement("h3", c, "Boolean getters");
+	c.append(getterTable(App.RA.Activation.getterManager.booleanGetters));
+	App.UI.DOM.appendNewElement("h3", c, "Assignment getters");
+	acc.push("A special type of boolean getters checking if the slave has the given assignment");
+	acc.toParagraph();
+	c = acc.container();
+	c.append(getterTable(App.RA.Activation.getterManager.assignmentGetters));
+	App.UI.DOM.appendNewElement("h3", c, "Number getters");
+	c.append(getterTable(App.RA.Activation.getterManager.numberGetters));
+	App.UI.DOM.appendNewElement("h3", c, "String getters");
+	c.append(getterTable(App.RA.Activation.getterManager.stringGetters));
+
+	App.UI.DOM.appendNewElement("h3", c, "Custom getters");
+	acc.push("If greater freedom is required for the conditions needed, a custom data getter can be used.",
+		"It operates on a context object with the following properties: slave: The slave currently tested against.",
+		"It is required to explicitly set the return type. If the set type does not match the actual return type, " +
+		"the condition evaluation will fail!");
+	acc.toParagraph();
+	acc.push("For example to get the slave name you can use");
+	acc.push(App.UI.DOM.makeElement("span", "context => slave.slaveName", ["monospace"]));
+	acc.push("and set the getter type to string.");
+	acc.toParagraph();
+	acc.push("Documentation for slave attributes can be found " +
+		"<a target='_blank' class='link-external' href='https://gitgud.io/pregmodfan/fc-pregmod/-/raw/pregmod-master/devNotes/legacy files/slave%20variables%20documentation.md'>here.</a>");
+	acc.toParagraph();
+
+	return acc.container();
+}, "beingInCharge");
diff --git a/src/gui/options/options.js b/src/gui/options/options.js
index a63c6e53abbfc6e398261e7ff3c6c49fbdb429a9..6fabc95ef506d7a657c783fe905c43fe24f364af 100644
--- a/src/gui/options/options.js
+++ b/src/gui/options/options.js
@@ -5,9 +5,7 @@ App.UI.optionsPassage = function() {
 	el.append(intro());
 
 	// Results
-	const results = document.createElement("div");
-	results.id = "results";
-	el.append(results);
+	const results = App.UI.DOM.appendNewElement("div", el);
 
 	try {
 		const tabBar = new App.UI.Tabs.TabBar("Options");
@@ -73,7 +71,7 @@ App.UI.optionsPassage = function() {
 					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);
+					jQuery(results).empty().append(span);
 				},
 				[],
 				"",
@@ -87,7 +85,7 @@ App.UI.optionsPassage = function() {
 					`Reset Reputation (${V.rep})`,
 					() => {
 						V.rep = 0;
-						jQuery("#results").empty().append(`Reputation reset to ${V.rep}`);
+						jQuery(results).empty().append(`Reputation reset to ${V.rep}`);
 					},
 					[],
 					"Options"
@@ -101,7 +99,7 @@ App.UI.optionsPassage = function() {
 					`Reset Money (${V.cash})`,
 					() => {
 						V.cash = 500;
-						jQuery("#results").empty().append(`Cash reset to ${V.cash}`);
+						jQuery(results).empty().append(`Cash reset to ${V.cash}`);
 					},
 					[],
 					"Options"
@@ -119,7 +117,7 @@ App.UI.optionsPassage = function() {
 						V.PC.prostate = 0;
 						V.PC.scrotum = 0;
 						V.PC.ballsImplant = 0;
-						jQuery("#results").empty().append(`Cash reset to ${V.cash}`);
+						jQuery(results).empty().append(`Cash reset to ${V.cash}`);
 					},
 					[],
 					"Options",
@@ -159,7 +157,7 @@ App.UI.optionsPassage = function() {
 			.addComment("<div>This mod is triggered after week 72. It is non-canon where it conflicts with canonical updates to the base game.</div>");
 
 		options.addOption("The Security Expansion mod is", "secExpEnabled")
-			.addValue("Enabled", 1).on().addCallback(() => App.SecExp.generalInit())
+			.addValue("Enabled", 1).on().addCallback(() => App.Mods.SecExp.generalInit())
 			.addValue("Disabled", 0).off()
 			.addComment("<div>The mod can be activated in any moment, but it may result in unbalanced gameplay if activated very late in the game.</div>");
 
@@ -316,7 +314,7 @@ App.UI.optionsPassage = function() {
 				links.push(App.UI.DOM.link(
 					"Give Authority",
 					() => {
-						App.SecExp.authorityX(1000);
+						App.Mods.SecExp.authorityX(1000);
 					},
 					[],
 					"Options"
@@ -324,7 +322,7 @@ App.UI.optionsPassage = function() {
 				links.push(App.UI.DOM.link(
 					"Remove Authority",
 					() => {
-						App.SecExp.authorityX(-1000);
+						App.Mods.SecExp.authorityX(-1000);
 					},
 					[],
 					"Options"
@@ -448,7 +446,7 @@ App.UI.optionsPassage = function() {
 				["random", [100]],
 			]);
 
-			App.SecExp.unit.squads("human").forEach(u => u.loyalty = numberGenerator());
+			App.Mods.SecExp.unit.squads("human").forEach(u => u.loyalty = numberGenerator());
 			function numberGenerator() {
 				const range = numberMap.get(level);
 				if (range[1]) {
@@ -780,6 +778,8 @@ App.UI.optionsPassage = function() {
 			.addComment("This will enable a new way to interact with slaves. Currently working but missing flavor text.");
 
 		el.append(options.render());
+
+		el.append(App.UI.playerMods());
 		return el;
 	}
 };
@@ -978,6 +978,10 @@ App.Intro.contentAndFlavor = function(isIntro) {
 		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
 		.addComment("Will not affect extreme surgeries already applied in-game.");
 
+	options.addOption("Permanent stretching of holes is currently", "seeStretching")
+		.addValue("Enabled", 1).on().addValue("Disabled", 0).off()
+		.addComment("Will not affect holes already stretched.");
+
 	options.addOption("Bestiality related content is currently", "seeBestiality")
 		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
 
@@ -1112,7 +1116,7 @@ App.UI.artOptions = function() {
 	const el = new DocumentFragment();
 	let options = new App.UI.OptionsGroup();
 
-	if (V.seeImages) {
+	if (V.seeImages && !V.seeCustomImagesOnly) {
 		const art = App.UI.DOM.appendNewElement("div", el, App.Art.SlaveArtElement(BaseSlave(), 2, 0), ["imageRef", "medImg"]);
 		art.style.float = "none";
 		art.style.display = "block";
@@ -1123,98 +1127,104 @@ App.UI.artOptions = function() {
 	options.addOption("Images are", "seeImages")
 		.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
 
-	/* REMOVE THIS WARNING ONCE ART DEVELOPMENT RESUMES */
-	options.addComment('<span class="warning">All image packs are currently incomplete; some outfits will not be displayed.</span>');
-
 	if (V.seeImages > 0) {
-		const option = options.addOption("Image style is", "imageChoice")
-			.addValueList([ // Keeping the most up to date options as the first in line
-				["Elohiem's interactive WebGL", 4],
-				["NoX/Deepmurk's vector art", 1],
-				["Revamped embedded vector art", 3],
-				["Non-embedded vector art", 2],
-				["Shokushu's rendered image pack", 0],
-			]);
-		if (V.imageChoice === 1) {
-			options.addComment("The only 2D art in somewhat recent development. Contains many outfits.");
-			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("Show custom images only", "seeCustomImagesOnly")
+			.addValue("Enabled", 1).addValue("Disabled", 0);
+
+		if (!V.seeCustomImagesOnly) {
+			/* REMOVE THIS WARNING ONCE ART DEVELOPMENT RESUMES */
+			options.addComment('<span class="warning">All image packs are currently incomplete; some outfits will not be displayed.</span>');
+			const option = options.addOption("Image style is", "imageChoice")
+				.addValueList([ // Keeping the most up to date options as the first in line
+					["Elohiem's interactive WebGL", 4],
+					["NoX/Deepmurk's vector art", 1],
+					["Revamped embedded vector art", 3],
+					["Non-embedded vector art", 2],
+					["Shokushu's rendered image pack", 5],
+				]);
+			if (V.imageChoice === 1) {
+				options.addComment("The only 2D art in somewhat recent development. Contains many outfits.");
+				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 === 5) {
+				options.addComment("Dead since long before the end of vanilla. You need to" +
+					" <a href='https://mega.nz/#!upoAlBaZ!EbZ5wCixxZxBhMN_ireJTXt0SIPOywO2JW9XzTIPhe0' target='_blank'>download the image" +
+					" pack</a> 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.addComment("This art development is dead.");
+				options.addOption("Clothing erection bulges are", "showClothingErection")
+					.addValue("Enabled", true).on().addValue("Disabled", false).off();
+			} else if (V.imageChoice === 4) {
+				options.addComment(`This art is currently (12/12/21) the most actively developed. Real time 3D models. <a href='https://mega.nz/folder/m1JQ3JAQ#2GJsM7csBBvBu0DX8SB2kA' target='_blank'> Download the WebGL art assets</a> and place the 'webgl' folder into the resources/ folder where this HTML file is.
+				Then <b>refresh</b> the page.
+				Create the resources folder if it does not exist. <span class="warning">(Android/MacOS not supported)</span>`);
+
+				let option = options.addOption("Supersampling (SSAA)", "setSuperSampling");
+				for (const value of [0.25, 0.5, 1, 2, 4]) {
+					option.addValue(`${value}`, value);
+				}
+				option.addComment("Multiplies the resolution of the render. Use a smaller factor for low-end GPU's.");
 
-			options.addOption("Height scaling", "seeHeight")
-				.addValue("All images", 2).on().addValue("Small images", 1).addValue("Disabled", 0).off();
+				option = options.addOption("Texture resolution", "setTextureResolution");
+				for (const value of [512, 1024, 2048, 4096]) {
+					option.addValue(`${value}`, value);
+				}
+				option.addComment("Refresh the page to take affect.");
+
+				options.addOption("Face culling", "setFaceCulling")
+					.addValue("Enabled", true).off().addValue("Disabled", false).on()
+					.addComment("Whether to draw the backside of the model, affects transparent surfaces such as hair. Enabling is recommended for low-end GPU's.");
+				options.addOption("Pan speed", "setPanSpeed")
+					.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("Rotation speed", "setRotationSpeed")
+					.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("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("Auto-frame", "setAutoFrame")
+					.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
+				if (V.setAutoFrame === 1) {
+					options.addOption("Default view", "setDefaultView").showTextBox()
+						.addComment("Choose a value between 0 and 1.");
+				}
+				options.addOption("Large Image size", "setImageSize").showTextBox()
+					.addComment("Recommended to be between 0.5 and 1.5.");
+				options.addOption("Ambient Occlusion", "setSSAO")
+					.addValue("Enabled", true).on().addValue("Disabled", false).off();
+				options.addOption("SubSurface Scattering", "setSSS")
+					.addValue("Enabled", true).on().addValue("Disabled", false).off();
+				options.addOption("Shadowmapping", "setShadowMapping")
+					.addValue("Enabled", true).on().addValue("Disabled", false).off();
+				options.addOption("Tonemapping", "setTonemapping")
+					.addValue("Enabled", true).on().addValue("Disabled", false).off();
+			} else if (V.imageChoice === 2) {
+				option.addComment("This art development is dead since vanilla. Since it is not embedded, requires a separate art pack to be downloaded.");
+			}
 
-			options.addOption("Clothing erection bulges are", "showClothingErection")
-				.addValue("Enabled", true).on().addValue("Disabled", false).off();
-		} else if (V.imageChoice === 0) {
-			options.addComment("Dead since long before the end of vanilla. You need to" +
-				" <a href='https://mega.nz/#!upoAlBaZ!EbZ5wCixxZxBhMN_ireJTXt0SIPOywO2JW9XzTIPhe0' target='_blank'>download the image" +
-				" pack</a> and put the 'renders' folder into the resources/ folder where this html file is.");
+			options.addOption("PA avatar art is", "seeAvatar")
+				.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
 
-			options.addOption("Slave summary fetish images are", "seeMainFetishes")
+			options.addOption("Slave images in lists are", "seeSummaryImages")
 				.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
-		} else if (V.imageChoice === 3) {
-			options.addComment("This art development is dead.");
-			options.addOption("Clothing erection bulges are", "showClothingErection")
-				.addValue("Enabled", true).on().addValue("Disabled", false).off();
-		} else if (V.imageChoice === 4) {
-			options.addComment(`This art is currently (12/12/21) the most actively developed. Real time 3D models. <a href='https://mega.nz/folder/m1JQ3JAQ#2GJsM7csBBvBu0DX8SB2kA' target='_blank'> Download the WebGL art assets</a> and place the 'webgl' folder into the resources/ folder where this HTML file is.
-			Then <b>refresh</b> the page.
-			Create the resources folder if it does not exist. <span class="warning">(Android/MacOS not supported)</span>`);
-
-			let option = options.addOption("Supersampling (SSAA)", "setSuperSampling");
-			for (const value of [0.25, 0.5, 1, 2, 4]) {
-				option.addValue(`${value}`, value);
-			}
-			option.addComment("Multiplies the resolution of the render. Use a smaller factor for low-end GPU's.");
 
-			option = options.addOption("Texture resolution", "setTextureResolution");
-			for (const value of [512, 1024, 2048, 4096]) {
-				option.addValue(`${value}`, value);
-			}
-			option.addComment("Refresh the page to take affect.");
-
-			options.addOption("Face culling", "setFaceCulling")
-				.addValue("Enabled", true).off().addValue("Disabled", false).on()
-				.addComment("Whether to draw the backside of the model, affects transparent surfaces such as hair. Enabling is recommended for low-end GPU's.");
-			options.addOption("Pan speed", "setPanSpeed")
-				.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("Rotation speed", "setRotationSpeed")
-				.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("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("Auto-frame", "setAutoFrame")
+			options.addOption("Slave images in the weekly report are", "seeReportImages")
 				.addValue("Enabled", 1).on().addValue("Disabled", 0).off();
-			if (V.setAutoFrame === 1) {
-				options.addOption("Default view", "setDefaultView").showTextBox()
-					.addComment("Choose a value between 0 and 1.");
-			}
-			options.addOption("Large Image size", "setImageSize").showTextBox()
-				.addComment("Recommended to be between 0.5 and 1.5.");
-			options.addOption("Ambient Occlusion", "setSSAO")
-				.addValue("Enabled", true).on().addValue("Disabled", false).off();
-			options.addOption("SubSurface Scattering", "setSSS")
-				.addValue("Enabled", true).on().addValue("Disabled", false).off();
-			options.addOption("Shadowmapping", "setShadowMapping")
-				.addValue("Enabled", true).on().addValue("Disabled", false).off();
-			options.addOption("Tonemapping", "setTonemapping")
-				.addValue("Enabled", true).on().addValue("Disabled", false).off();
-		} else if (V.imageChoice === 2) {
-			option.addComment("This art development is dead since vanilla. Since it is not embedded, requires a separate art pack to be downloaded.");
 		}
+	}
 
-		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;
 };
diff --git a/src/gui/options/optionsGroup.js b/src/gui/options/optionsGroup.js
index c49892ec2149452801e93eb75c9acdc3e5275a03..d51a9902e19397a6605f46e1d3a14c040bc32ce9 100644
--- a/src/gui/options/optionsGroup.js
+++ b/src/gui/options/optionsGroup.js
@@ -268,36 +268,21 @@ App.UI.OptionsGroup = (function() {
 					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 options = this.valuePairs.map(value => {
+					return {key: value.value, name: value.name};
+				});
+				buttonGroup.append(App.UI.DOM.makeSelect(options, this.object[this.property], value => {
+					if (!isNaN(Number(value))) {
+						// @ts-ignore
+						value = Number(value);
 					}
-					const originalObj = this.valuePairs.find(obj => obj.name === O.textContent);
+					this.object[this.property] = value;
+					const originalObj = this.valuePairs.find(obj => obj.value === value);
 					if (originalObj && typeof originalObj.callback === "function") {
 						originalObj.callback(originalObj.value);
 					}
 					refresh();
-				};
-				buttonGroup.append(select);
+				}));
 			}
 
 			if (this.textbox) {
@@ -576,3 +561,25 @@ App.UI.OptionsGroup = (function() {
 		}
 	};
 })();
+
+/** A wrapper for option handlers that shows a dialog with the results of setting the option.
+ * @template T
+ * @param {function(T): string|HTMLElement|DocumentFragment} contentGenerator
+ * @param {string} [caption]
+ * @returns {function(T): void}
+ */
+App.UI.DialogHandler = function(contentGenerator, caption) {
+	return (arg) => {
+		const dialogContent = contentGenerator(arg);
+		if (dialogContent) {
+			if (Dialog.isOpen()) {
+				Dialog.close();
+			}
+			if (caption) {
+				Dialog.setup(caption);
+			}
+			$(Dialog.body()).empty().append(dialogContent);
+			Dialog.open();
+		}
+	};
+};
diff --git a/src/gui/sideBar.js b/src/gui/sideBar.js
index d9c086210a02d3fccc704407847fd3446fab3ab9..41914c8fb846785776dd6b67e9d2bb52d758eb3a 100644
--- a/src/gui/sideBar.js
+++ b/src/gui/sideBar.js
@@ -38,9 +38,6 @@ App.Utils.userButton = function(nextButton = V.nextButton, nextLink = V.nextLink
 			el.append(link);
 			el.append(" ");
 			App.UI.DOM.appendNewElement("span", el, App.UI.Hotkeys.hotkeys("endWeek"), "hotkey");
-			if (V.rulesAssistantAuto === 1 && DefaultRulesError()) {
-				App.UI.DOM.appendNewElement("div", el, `WARNING: Rules Assistant has rules with errors!`, "yellow");
-			}
 		} else {
 			if (nextButton !== " ") {
 				link = App.UI.DOM.passageLink(
diff --git a/src/gui/storyCaption.js b/src/gui/storyCaption.js
index b15f42506ba6d6b20edb3313c60483ef42da0b3f..2a71195f1cdea4453ad9fd47642c623f0e20643e 100644
--- a/src/gui/storyCaption.js
+++ b/src/gui/storyCaption.js
@@ -19,7 +19,7 @@ App.UI.storyCaption = function() {
 			fragment.append(cash());
 		}
 
-		if (V.mods.food.enabled) {
+		if (V.mods.food.enabled && V.mods.food.market) {
 			fragment.append(food());
 		}
 
@@ -76,7 +76,7 @@ App.UI.storyCaption = function() {
 	}
 
 	const p = document.createElement("p");
-	p.append(App.UI.DOM.makeElement("span", "FCE", "bold"), ": ",
+	p.append(App.UI.DOM.makeElement("span", "FCE", ["bold"]), ": ",
 		App.Encyclopedia.Dialog.linkDOM(V.encyclopedia, V.encyclopedia));
 	fragment.append(p);
 
@@ -100,7 +100,7 @@ App.UI.storyCaption = function() {
 	}
 
 	function weather() {
-		const div = App.UI.DOM.appendNewElement("div", fragment, V.weatherToday.name, "note");
+		const div = App.UI.DOM.appendNewElement("div", fragment, V.weatherToday.name, ["note"]);
 		if (V.weatherToday.severity === 1) {
 			div.classList.add("cyan");
 		} else if (V.weatherToday.severity === 2) {
@@ -140,7 +140,7 @@ App.UI.storyCaption = function() {
 				div.append("(");
 				let cashDiff = V.cash - V.cashLastWeek;
 				if (cashDiff > 0) {
-					App.UI.DOM.appendNewElement("span", div, cashFormat(cashDiff), "green");
+					App.UI.DOM.appendNewElement("span", div, cashFormat(cashDiff), ["green"]);
 				} else {
 					App.UI.DOM.appendNewElement("span", div, cashFormat(cashDiff), ["cash", "dec"]);
 				}
@@ -199,12 +199,12 @@ App.UI.storyCaption = function() {
 			});
 		} else {
 			if (pass === "Main") {
-				const foodDiv2 = document.createElement("div");
-				foodDiv2.append("(");
+				const innerDiv = document.createElement("div");
+				innerDiv.append("(");
 				const foodDiff = (V.mods.food.amount - V.mods.food.lastWeek);
-				App.UI.DOM.appendNewElement("span", foodDiv2, massFormat(foodDiff), foodDiff < 0 ? "red" : "chocolate");
-				foodDiv2.append(" since last week)");
-				fragment.append(foodDiv2);
+				App.UI.DOM.appendNewElement("span", innerDiv, massFormat(foodDiff), foodDiff < 0 ? ["red"] : ["chocolate"]);
+				innerDiv.append(" since last week)");
+				fragment.append(innerDiv);
 			}
 		}
 
@@ -231,7 +231,19 @@ App.UI.storyCaption = function() {
 
 	function slaves() {
 		const div = document.createElement("div");
-		App.UI.DOM.appendNewElement("span", div, "Total Sex Slaves", "pink");
+		const dormsPop = V.dormitoryPopulation;
+		const roomsPop = V.roomsPopulation;
+		const dormsCap = V.dormitory;
+		const roomsCap = V.rooms;
+		const css = [];
+
+		if ((dormsPop > dormsCap || roomsPop > roomsCap) && V.sideBarOptions.Style === 'compact') {
+			css.push("warning");
+		} else {
+			css.push("pink");
+		}
+
+		App.UI.DOM.appendNewElement("span", div, "Total Sex Slaves", css);
 		div.append(` | ${V.slaves.length}`);
 		if (V.sideBarOptions.roomPop > 0 && V.sideBarOptions.Style === 'compact') {
 			tippy(div, {
@@ -260,10 +272,10 @@ App.UI.storyCaption = function() {
 	 */
 	function roomRow(name, pops, cap) {
 		const div = document.createElement("div");
-		App.UI.DOM.appendNewElement("span", div, name, "pink");
+		App.UI.DOM.appendNewElement("span", div, name, ["pink"]);
 		div.append(" | ");
 		if (pops > cap) {
-			App.UI.DOM.appendNewElement("span", div, String(pops), "warning");
+			App.UI.DOM.appendNewElement("span", div, String(pops), ["warning"]);
 		} else {
 			div.append(String(pops));
 		}
@@ -273,7 +285,7 @@ App.UI.storyCaption = function() {
 
 	function economy() {
 		const div = document.createElement("div");
-		App.UI.DOM.appendNewElement("span", div, "GSP", "yellowgreen");
+		App.UI.DOM.appendNewElement("span", div, "GSP", ["yellowgreen"]);
 		div.append(` | ${num(Math.trunc(0.1 * V.arcologies[0].prosperity))}`);
 		if (V.showNumbers === 2 || (V.showNumbers === 1 && Math.trunc(0.1 * V.arcologies[0].prosperity) > V.showNumbersMax)) {
 			div.append("m");
@@ -354,12 +366,12 @@ App.UI.storyCaption = function() {
 
 	function authority() {
 		const div = document.createElement("div");
-		App.UI.DOM.appendNewElement("span", div, "Auth", "darkviolet");
+		App.UI.DOM.appendNewElement("span", div, "Auth", ["darkviolet"]);
 
 		div.append(" | ");
 		const span = document.createElement("span");
 		span.className = "darkviolet";
-		App.SecExp.authorityX();
+		App.Mods.SecExp.authorityX();
 		if (V.SecExp.core.authority > 19500) {
 			span.append("divine will");
 		} else if (V.SecExp.core.authority > 19000) {
@@ -415,10 +427,10 @@ App.UI.storyCaption = function() {
 
 	function security() {
 		const div = document.createElement("div");
-		App.UI.DOM.appendNewElement("span", div, "Security", "deepskyblue");
+		App.UI.DOM.appendNewElement("span", div, "Security", ["deepskyblue"]);
 		div.append(" | ");
 
-		App.UI.DOM.appendNewElement("span", div, `${Math.trunc(V.SecExp.core.security)}%`, "deepskyblue");
+		App.UI.DOM.appendNewElement("span", div, `${Math.trunc(V.SecExp.core.security)}%`, ["deepskyblue"]);
 		if (showCheats()) {
 			div.append(App.UI.DOM.makeTextBox(V.SecExp.core.security, sec => {
 				V.SecExp.core.security = Math.clamp(Math.trunc(sec), 0, 100);
@@ -432,9 +444,9 @@ App.UI.storyCaption = function() {
 	function crime() {
 		V.SecExp.core.crimeLow = Math.clamp(V.SecExp.core.crimeLow, 0, 100);
 		const div = document.createElement("div");
-		App.UI.DOM.appendNewElement("span", div, "Crime", "orangered");
+		App.UI.DOM.appendNewElement("span", div, "Crime", ["orangered"]);
 		div.append(" | ");
-		App.UI.DOM.appendNewElement("span", div, `${Math.trunc(V.SecExp.core.crimeLow)}%`, "orangered");
+		App.UI.DOM.appendNewElement("span", div, `${Math.trunc(V.SecExp.core.crimeLow)}%`, ["orangered"]);
 
 		if (showCheats()) {
 			div.append(App.UI.DOM.makeTextBox(V.SecExp.core.crimeLow, crime => {
@@ -495,13 +507,13 @@ App.UI.storyCaption = function() {
 			const div = document.createElement("div");
 			div.classList.add("cash", "dec");
 			div.append("This slave will cost ",
-				App.UI.DOM.makeElement("span", cashFormat(cost), "bold"), ".",
+				App.UI.DOM.makeElement("span", cashFormat(cost), ["bold"]), ".",
 				App.UI.DOM.makeElement("div", `You only have: ${cashFormat(V.cash)}.`));
 			p.append(div);
 		} else {
 			const div = document.createElement("div");
 			div.append("This slave will cost ",
-				App.UI.DOM.makeElement("span", cashFormat(cost), "cash"), ".",
+				App.UI.DOM.makeElement("span", cashFormat(cost), ["cash"]), ".",
 				App.UI.DOM.makeElement("div", `You have ${cashFormat(V.cash)}.`));
 			p.append(div);
 		}
diff --git a/src/init/storyInit.js b/src/init/storyInit.js
index 1245717fa59b9eac9cdcf9acb2abee89bef88bd3..16281efd191cd2d5cda128e9cdbb39997fb49eab 100644
--- a/src/init/storyInit.js
+++ b/src/init/storyInit.js
@@ -47,7 +47,7 @@ App.Intro.init = function() {
 	});
 	V.JobIDMap = makeJobIdMap();
 
-	App.SF.Init();
+	App.Mods.SF.Init();
 
 	V.weatherToday = App.Data.Weather.hotNice.random();
 	V.weatherLastWeek = 1;
diff --git a/src/interaction/budgets/recordTemplates.js b/src/interaction/budgets/recordTemplates.js
index dfc9618022c4b6454e3f48c98d6c692a3497332e..d9f7f2d6dfdc4d31f6340a225ab78533c94db88c 100644
--- a/src/interaction/budgets/recordTemplates.js
+++ b/src/interaction/budgets/recordTemplates.js
@@ -133,6 +133,7 @@ App.Data.Records.LastWeeksCash = function() {
 	this.fines = 0;
 	this.event = 0; // poker night etc. Try to file things elsewhere if you can.
 	this.war = 0;
+	this.loan = 0;
 
 	// Policies
 	this.food = 0;
diff --git a/src/interaction/main/mainLinks.js b/src/interaction/main/mainLinks.js
index 9e7eead9df65d275079c8dc17f52700eb58d7a7a..ad83a80b88504afa64c0908e160fabfc3ffbbe7d 100644
--- a/src/interaction/main/mainLinks.js
+++ b/src/interaction/main/mainLinks.js
@@ -71,7 +71,7 @@ App.UI.View.mainLinks = function() {
 					const trainees = [];
 					PA.forEach((trainee, i) => {
 						trainees.push(App.UI.DOM.combineNodes(App.UI.DOM.makeElement("span", SlaveFullName(trainee), "slave-name"),
-							` to ${App.personalAttention.getText(V.personalAttention.slaves[i].objective, trainee)}`));
+							` to ${App.PersonalAttention.getText(V.personalAttention.slaves[i].objective, trainee)}`));
 					});
 					fragment.append(App.UI.DOM.toSentence(trainees));
 
diff --git a/src/interaction/main/walkPast.js b/src/interaction/main/walkPast.js
index c2bf35d788b83da96d47718f13bb6d87e81c8a9f..46a7791342afb99da1ff1768328c5a63d7350693 100644
--- a/src/interaction/main/walkPast.js
+++ b/src/interaction/main/walkPast.js
@@ -103,7 +103,7 @@ globalThis.walkPast = (function() {
 		}
 
 		const {
-			him, his, He
+			him, his, He,
 		} = getPronouns(activeSlave);
 
 		let links = [];
@@ -176,7 +176,7 @@ globalThis.walkPast = (function() {
 		let r = "";
 
 		const {
-			he, his
+			he, his,
 		} = getPronouns(activeSlave);
 
 		if (partnerSlave !== undefined) { /* potential problem point */
@@ -210,12 +210,12 @@ globalThis.walkPast = (function() {
 
 		const {
 			he, him, his, himself, boy,
-			He, His
+			He, His,
 		} = getPronouns(activeSlave);
 
 		if (partnerSlave !== undefined) {
 			const {
-				he2, him2, his2, himself2
+				he2, him2, his2, himself2,
 			} = getPronouns(partnerSlave).appendSuffix("2");
 			const partnerName = partnerSlave.slaveName;
 			const race2 = (V.seeRace ? partnerSlave.race : "");
@@ -2048,7 +2048,7 @@ globalThis.walkPast = (function() {
 		const pronouns = getPronouns(slave);
 		const {
 			he, him, his,
-			His
+			His,
 		} = pronouns;
 
 		target = "fBoobs";
@@ -2494,7 +2494,7 @@ globalThis.walkPast = (function() {
 	function buttWatch(slave) {
 		const {
 			he, him, his, boy,
-			He, His
+			He, His,
 		} = getPronouns(slave);
 
 		target = "fButt";
@@ -2604,7 +2604,7 @@ globalThis.walkPast = (function() {
 			case "an oversized t-shirt and boyshorts":
 				t += `${His} boyshorts tightly cling to ${his} rear as ${he} `;
 				if (slave.butt > 5) {
-					t += `moves. It's filled out by so much ass you can't help but oggle.`;
+					t += `moves. It's filled out by so much ass you can't help but ogle.`;
 				} else {
 					t += `moves.`;
 				}
@@ -2847,7 +2847,7 @@ globalThis.walkPast = (function() {
 	function bellyWatch(slave) {
 		const {
 			he, him, his,
-			He, His
+			He, His,
 		} = getPronouns(slave);
 
 		target = "fVagina";
@@ -3022,7 +3022,7 @@ globalThis.walkPast = (function() {
 							t += `${His} giant belly fills ${his} habit; it looks absolutely sinful.`;
 							break;
 						case "a halter top dress":
-							t += `${His} giant belly fills ${his} halter top dress, it struggles to contain ${his} belly.`;
+							t += `${His} giant belly fills ${his} halter top dress, which struggles to contain it.`;
 							break;
 						case "a ball gown":
 							t += `Your gaze is drawn to ${his} giant pregnant belly by ${his} struggling fabulous silken ball gown.`;
@@ -4684,7 +4684,7 @@ globalThis.walkPast = (function() {
 							t += `${His} giant belly fills ${his} habit; it looks absolutely sinful.`;
 							break;
 						case "a halter top dress":
-							t += `${His} giant belly fills ${his} halter top dress, it struggles to contain ${his} belly.`;
+							t += `${His} giant belly fills ${his} halter top dress, which struggles to contain it.`;
 							break;
 						case "a ball gown":
 							t += `Your gaze is drawn to ${his} giant belly by ${his} struggling fabulous silken ball gown.`;
@@ -7738,7 +7738,7 @@ globalThis.walkPast = (function() {
 	function vaginaWatch(slave) {
 		const {
 			he, him, his,
-			He, His
+			He, His,
 		} = getPronouns(slave);
 
 		target = "fVagina";
@@ -8328,7 +8328,7 @@ globalThis.walkPast = (function() {
 	function dickWatch(slave) {
 		const {
 			he, him, his,
-			He, His
+			He, His,
 		} = getPronouns(slave);
 
 		target = "fDick";
@@ -8918,7 +8918,7 @@ globalThis.walkPast = (function() {
 	function anusWatch(slave) {
 		const {
 			he, him, his, boy,
-			He, His
+			He, His,
 		} = getPronouns(slave);
 
 		target = "fAnus";
@@ -9247,7 +9247,7 @@ globalThis.walkPast = (function() {
 	function lipWatch(slave) {
 		const {
 			he, him, his,
-			His
+			His,
 		} = getPronouns(slave);
 
 		t += App.Desc.face(slave);
diff --git a/src/interaction/prostheticConfig.js b/src/interaction/prostheticConfig.js
index 44147410af15659fb89f0fca0c1fedfcbf71e45b..9a64ec644b246b8b9dc56fb3a13121a187343c6b 100644
--- a/src/interaction/prostheticConfig.js
+++ b/src/interaction/prostheticConfig.js
@@ -324,30 +324,19 @@ App.UI.prostheticsConfig = function(slave) {
 		return f;
 
 		function tailSelect() {
-			const frag = new DocumentFragment();
-			const sortedTails = Array.from(App.Data.modTails.keys()).sort((a, b) => a > b ? 1 : -1);
-			const select = App.UI.DOM.appendNewElement("select", frag);
-			let matchFound = false;
-			for (const shape of sortedTails) {
-				const option = App.UI.DOM.appendNewElement("option", select, App.Data.modTails.get(shape).animal);
-				option.value = shape;
-				if (option.value === slave.tailShape) {
-					option.selected = true;
-					matchFound = true;
-				}
-			}
-			if (!matchFound) {
-				select.selectedIndex = -1;
-			}
-			select.onchange = () => {
+			const sortedTails = Array.from(App.Data.modTails.keys())
+				.sort((a, b) => a > b ? 1 : -1)
+				.map(tail => {
+					return {key: tail, name: App.Data.modTails.get(tail).animal};
+				});
+			return App.UI.DOM.makeSelect(sortedTails, slave.tailShape, tail => {
 				V.prostheticsConfig = "attachTail";
 				slave.tail = "mod";
-				slave.tailShape = select.options[select.selectedIndex].value;
+				slave.tailShape = /** @type {FC.TailShape} */ (tail);
 				slave.tailColor = (slave.tailColor === "none") ? slave.hColor : slave.tailColor; // if color not set yet, match hair.
 				cashX(forceNeg(V.modCost), "slaveMod", slave);
 				App.UI.reload();
-			};
-			return frag;
+			});
 		}
 	}
 
diff --git a/src/interaction/prostheticLabPassage.js b/src/interaction/prostheticLabPassage.js
index 6c2858a02d3d5b3d855c0cdfaaaab41be53cbe80..9f2faebb0d366b297f4e6dde8c40e91f5f0fc873 100644
--- a/src/interaction/prostheticLabPassage.js
+++ b/src/interaction/prostheticLabPassage.js
@@ -154,7 +154,7 @@ App.UI.prostheticLab = function() {
 		if (V.researchLab.menials > 0) {
 			linkArray = [];
 			for (const num of [1, 5, 10]) {
-				if (V.researchLab.hired >= num) {
+				if (V.researchLab.menials >= num) {
 					linkArray.push(App.UI.DOM.link(
 						`${num}x`,
 						() => {
diff --git a/src/interaction/selectPartner.js b/src/interaction/selectPartner.js
new file mode 100644
index 0000000000000000000000000000000000000000..5f6f640e3671d79c0e9efd671ccaa86196314d23
--- /dev/null
+++ b/src/interaction/selectPartner.js
@@ -0,0 +1,75 @@
+App.Interact.BaseChoosePartnerRenderer = class {
+	/** Set up selection of a second slave for an interaction (i.e. Slave/Slave or threesome with PC)
+	 * @param {App.Entity.SlaveState} slave
+	 */
+	constructor(slave) {
+		this.slave = slave;
+		this.intro = "";
+		this.instructions = "Select an eligible slave";
+		this.noneEligible = "You have no slaves capable of this act.";
+		this.execute = (/** @type {App.Entity.SlaveState} */ slave, /** @type {App.Entity.SlaveState} */ partner) => new DocumentFragment();
+	}
+
+	/** Determines whether a particular candidate is eligible to join slave for this interaction
+	 * @param {App.Entity.SlaveState} candidate
+	 * @returns {boolean}
+	 */
+	eligible(candidate) {
+		return true;
+	}
+
+	/** Details to render for a particular candidate entry, which will be relevant for the player's decision
+	 * @param {App.Entity.SlaveState} candidate
+	 * @param {ParentNode} container
+	 */
+	renderDetail(candidate, container) {
+	}
+};
+
+/** Allows the player to choose a second slave to participate in a slave interaction.
+ * @param {App.Interact.BaseChoosePartnerRenderer} renderer
+ * @returns {HTMLDivElement}
+ */
+App.Interact.choosePartner = function(renderer) {
+	const target = document.createElement("div");
+
+	Dialog.setup(renderer.instructions);
+	Dialog.open();
+	Dialog.append(renderChoices());
+
+	function renderChoices() {
+		const node = new DocumentFragment();
+		App.UI.DOM.appendNewElement("div", node, renderer.intro);
+		const slave = renderer.slave;
+
+		const eligibles = V.slaves.filter((s) => (s.ID !== slave.ID) && renderer.eligible(s));
+		for (const eligible of eligibles) {
+			const div = App.UI.DOM.appendNewElement("div", node);
+			div.append(App.UI.DOM.link(
+				SlaveFullName(eligible),
+				() => {
+					Dialog.close();
+					App.UI.DOM.replace(target, renderer.execute(slave, eligible));
+				}
+			));
+			if (eligible.custom.label) {
+				App.UI.DOM.appendNewElement("span", div, ` ${eligible.custom.label}`, ["custom-label"]);
+			}
+			if (totalRelatives(slave) > 0) {
+				const relTerm = relativeTerm(slave, eligible);
+				if (relTerm !== null) {
+					App.UI.DOM.appendNewElement("span", div, ` ${capFirstChar(relTerm)}`, ["relationship"]);
+				}
+			}
+			renderer.renderDetail(eligible, div);
+		}
+
+		if (eligibles.length === 0) {
+			App.UI.DOM.appendNewElement("div", node, renderer.noneEligible, ["note"]);
+		}
+
+		return node;
+	}
+
+	return target;
+};
diff --git a/src/interaction/sellSlave.js b/src/interaction/sellSlave.js
index 71c95d2433bc397f2cd329d00e19e1982827d2e3..06ed5b232bfc3793e8e9b665ff20b9d3bb9f027a 100644
--- a/src/interaction/sellSlave.js
+++ b/src/interaction/sellSlave.js
@@ -307,51 +307,52 @@ App.Interact.sellSlave = function(slave) {
 				t.push(`${His} albinism makes ${him} rather desirable.`);
 			}
 
+			if (slave.milkFlavor !== "none") {
+				t.push(`${His} flavored milk makes ${him} rather desired by Pastoralist and other milk lovers`);
+			}
+
 			if (slave.geneticQuirks.progeria !== 2 && slave.geneticQuirks.neoteny === 2 && slave.actualAge > slave.visualAge + 5) {
 				t.push(`${He} appears to be neotonic, which will turn off some but attract others. Overall should prove positive though.`);
 			}
 
-			if (slave.career !== 0) {
-				if (App.Data.Careers.Leader.bodyguard.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good Bodyguard; that's valuable.`);
-				} else if (App.Data.Careers.Leader.wardeness.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good Wardeness; that's valuable.`);
-				} else if (App.Data.Careers.Leader.attendant.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good Attendant; that's valuable.`);
-				} else if (App.Data.Careers.Leader.nurse.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good Nurse; that's valuable.`);
-				} else if (App.Data.Careers.Leader.matron.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good Matron; that's valuable.`);
-				} else if (App.Data.Careers.Leader.schoolteacher.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good Schoolteacher; that's valuable.`);
-				} else if (App.Data.Careers.Leader.stewardess.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good Stewardess; that's valuable.`);
-				} else if (App.Data.Careers.Leader.milkmaid.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good Milkmaid; that's valuable.`);
-				} else if (App.Data.Careers.Leader.farmer.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good Farmer; that's valuable.`);
-				} else if (App.Data.Careers.Leader.madam.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good Madam; that's valuable.`);
-				} else if (App.Data.Careers.Leader.DJ.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good DJ; that's valuable.`);
-				} else if (App.Data.Careers.Leader.HG.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good Head Girl; that's valuable.`);
-				} else if (App.Data.Careers.Leader.recruiter.includes(slave.career)) {
-					t.push(`${His} background would help make ${him} a good Recruiter; that's valuable.`);
-				} else if (App.Data.Careers.General.entertainment.includes(slave.career)) {
-					t.push(`${His} background should help ${his} flirting a little.`);
-				} else if (App.Data.Careers.General.whore.includes(slave.career)) {
-					t.push(`${His} background should help ${his} fucking a little.`);
-				} else if (App.Data.Careers.General.grateful.includes(slave.career)) {
-					t.push(`${His} background should make ${him} a bit more trusting.`);
-				} else if (App.Data.Careers.General.menial.includes(slave.career)) {
-					t.push(`${His} background should make ${him} a bit more tractable.`);
-				} else if (App.Data.Careers.General.servant.includes(slave.career)) {
-					t.push(`${His} background should make ${him} a good servant.`);
-				}
+			if (App.Data.Careers.Leader.bodyguard.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good Bodyguard; that's valuable.`);
+			} else if (App.Data.Careers.Leader.wardeness.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good Wardeness; that's valuable.`);
+			} else if (App.Data.Careers.Leader.attendant.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good Attendant; that's valuable.`);
+			} else if (App.Data.Careers.Leader.nurse.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good Nurse; that's valuable.`);
+			} else if (App.Data.Careers.Leader.matron.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good Matron; that's valuable.`);
+			} else if (App.Data.Careers.Leader.schoolteacher.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good Schoolteacher; that's valuable.`);
+			} else if (App.Data.Careers.Leader.stewardess.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good Stewardess; that's valuable.`);
+			} else if (App.Data.Careers.Leader.milkmaid.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good Milkmaid; that's valuable.`);
+			} else if (App.Data.Careers.Leader.farmer.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good Farmer; that's valuable.`);
+			} else if (App.Data.Careers.Leader.madam.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good Madam; that's valuable.`);
+			} else if (App.Data.Careers.Leader.DJ.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good DJ; that's valuable.`);
+			} else if (App.Data.Careers.Leader.HG.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good Head Girl; that's valuable.`);
+			} else if (App.Data.Careers.Leader.recruiter.includes(slave.career)) {
+				t.push(`${His} background would help make ${him} a good Recruiter; that's valuable.`);
+			} else if (App.Data.Careers.General.entertainment.includes(slave.career)) {
+				t.push(`${His} background should help ${his} flirting a little.`);
+			} else if (App.Data.Careers.General.whore.includes(slave.career)) {
+				t.push(`${His} background should help ${his} fucking a little.`);
+			} else if (App.Data.Careers.General.grateful.includes(slave.career)) {
+				t.push(`${His} background should make ${him} a bit more trusting.`);
+			} else if (App.Data.Careers.General.menial.includes(slave.career)) {
+				t.push(`${His} background should make ${him} a bit more tractable.`);
+			} else if (App.Data.Careers.General.servant.includes(slave.career)) {
+				t.push(`${His} background should make ${him} a good servant.`);
 			}
 			if ((V.week - slave.weekAcquired >= 20) && (slave.skill.entertainment >= 100)) {
-				// FIXME: review this
 				if (!App.Data.Careers.General.entertainment.includes(slave.career)) {
 					t.push(`${He}'s gotten enough experience as a slave entertainer that ${he} has the added value of a ${girl} with a history in entertainment from before ${he} was a slave.`);
 				}
@@ -674,7 +675,8 @@ App.Interact.sellSlave = function(slave) {
 				}
 			}
 
-			if (!jQuery.isEmptyObject(slave.brand)) {
+			const brands = App.Medicine.Modification.brandRecord(slave);
+			if (!jQuery.isEmptyObject(brands)) {
 				if (V.rep > 10000) {
 					t.push(`I see ${he}'s branded with your mark; with your stellar reputation, that will make ${him} appraise better.`);
 				} else if (V.rep < 5000) {
@@ -2137,7 +2139,7 @@ App.Interact.sellSlave = function(slave) {
 					let slaveImpact;
 					r.push(`${slave.slaveName} is taken away by an expensive, flashy shuttle shortly after you finalize the trade. ${He} is swept into a life of luxury; the next time you see ${him}, ${he}'s dressed in a manner more befitting of a consort than a simple slave.`);
 					for (const s of V.slaves) {
-						if (s.intelligence + s.intelligenceImplant < 50) {
+						if (s.intelligence + s.intelligenceImplant > 50) {
 							s.devotion -= 2;
 							slaveImpact = 1;
 						}
@@ -2584,6 +2586,27 @@ App.Interact.sellSlave = function(slave) {
 					return r;
 				}
 			}],
+			["Milk aficionado", {
+				cost: 500 * Math.trunc((cost * 1.4) / 500),
+				offerDesc: `from a wealthy milk aficionado that would like to add ${him} to ${his} dairy.`,
+				get requirements() { return (slave.milkFlavor !== "none" && slave.boobsImplant === 0 && slave.health.condition > 40); },
+				percentOdds: 50,
+				get completeSale() {
+					const r = [];
+					let slaveImpact;
+					r.push(`${slave.slaveName} is a common sight around the arcology, since free range cows are allowed to range between milkings. ${He} seems reasonably content.`);
+					for (const s of V.slaves) {
+						if (s.milkFlavor !== "none") {
+							s.trust += 1;
+							slaveImpact = 1;
+						}
+					}
+					if (slaveImpact === 1) {
+						r.push(`Your other flavored milk producing slaves hope that they'll also be <span class="trust inc">lucky enough</span> to find themselves being taken care of in a wealthy mans dairy too, should you decide to sell them.`);
+					}
+					return r;
+				}
+			}],
 			["harvester", {
 				cost: 500 * Math.trunc((cost * 1.2) / 500),
 				offerDesc: `from an organ harvesting firm that acquires healthy raw materials cheaply.`,
@@ -2712,7 +2735,7 @@ App.Interact.sellSlave = function(slave) {
 				}
 			}],
 		]);
-		if (V.peacekeepers !== 0) {
+		if (V.peacekeepers.state === 3) {
 			buyers.set("peacekeepers", {
 				cost: V.peacekeepers.attitude < 100
 					? 500 * Math.trunc((cost * 0.5) / 500)
@@ -2724,17 +2747,14 @@ App.Interact.sellSlave = function(slave) {
 						return `from the sex slave buyer for General ${V.peacekeepers.generalName}'s client state${V.peacekeepers.tastes ? `, which prefers ${V.peacekeepers.tastes}` : ``}.`;
 					}
 				},
-				get requirements() { return (V.plot && V.peacekeepers && V.peacekeepers.strength >= 50); },
+				get requirements() { return (V.plot && V.peacekeepers.strength >= 50); },
 				percentOdds: 100,
 				get completeSale() {
 					const r = [];
-					if (V.peacekeepers === 0) {
-						return r;
-					}
 					r.push(`${slave.slaveName} is delivered to General ${V.peacekeepers.generalName}'s forces, to serve as a barracks whore. Several days later, the purchasing officer forwards a short shot of ${slave.slaveName}`);
 
 					cost = slaveCost(slave);
-					if (V.peacekeepers.tastes === 0) {
+					if (V.peacekeepers.tastes === "") {
 						const influential = (cost > random(10000, 50000) || V.peacekeepers.attitude > 90);
 						if (influential && slave.belly >= 300000) {
 							r.push(`smiling as ${his} ${bellyAdjective(slave)} belly is used as the center of a large bukkake party. You can just barely make out the figure of someone taking ${him} from behind beyond ${his} immensity. There's a note attached, stating superfluously that ${his} exotic feature makes ${him} very popular. General ${V.peacekeepers.generalName}'s buyer is going to be looking for more massive bellied ${girl}s in the future.`);
diff --git a/src/interaction/siPhysicalRegimen.js b/src/interaction/siPhysicalRegimen.js
index 2982bfabd179dcf2b4a0285cfb9c1106dc0f4d1b..456c1a7a313bf5db6831f0e96684493e09ee1a38 100644
--- a/src/interaction/siPhysicalRegimen.js
+++ b/src/interaction/siPhysicalRegimen.js
@@ -670,7 +670,7 @@ App.UI.SlaveInteract.physicalRegimen = function(slave, refresh) {
 							if (WL === 1) {
 								title.textContent = `${His} child will be placed in ${V.nurseryName}. `;
 							} else if (reservedNursery < WL) {
-								title.textContent = `_reservedNursery of ${his} children will be placed in ${V.nurseryName}.`;
+								title.textContent = `${reservedNursery} of ${his} children will be placed in ${V.nurseryName}.`;
 							} else if (WL === 2) {
 								title.textContent = `Both of ${his} children will be placed in ${V.nurseryName}. `;
 							} else {
diff --git a/src/interaction/siRecords.js b/src/interaction/siRecords.js
index bcc3a112ecc39068f1143019514acdd36dfa6e53..0d6f302ebd6aff881c21d18470d4ce15cd2ecd25 100644
--- a/src/interaction/siRecords.js
+++ b/src/interaction/siRecords.js
@@ -17,7 +17,7 @@ App.UI.SlaveInteract.records = function(slave, refresh) {
 		slave.porn.spending = Math.clamp(Math.ceil(slave.porn.spending / 1000) * 1000, 0, 5000);
 
 		if (slave.porn.prestige === 3) {
-			App.UI.DOM.appendNewElement("div", el, `${He} is so prestigious in the realm of ${slave.porn.fameType} porn that ${his} fame is self-sustaining.`, "note");
+			App.UI.DOM.appendNewElement("div", el, `${He} is so prestigious in the realm of ${slave.porn.fameType} porn that ${his} fame is self-sustaining.`, ["note"]);
 		} else if (slave.porn.feed === 0) {
 			r = [];
 			r.push(`The media hub is not releasing highlights of ${his} sex life.`);
@@ -234,33 +234,27 @@ App.UI.SlaveInteract.records = function(slave, refresh) {
 			ownedSlavesSpan.append(innerSpan);
 		}
 
-		if (slave.partners.has(-1)) {
-			other.push(`you`);
-		}
-		if (slave.partners.has(-2)) {
-			other.push(`citizens of ${V.arcologies[0].name}`);
-		}
-		if (slave.partners.has(-3)) {
-			other.push(`your former master`);
-		}
-		if (slave.partners.has(-4)) {
-			other.push(`another arcology owner`);
-		}
-		if (slave.partners.has(-6)) {
-			other.push(`members of the Societal Elite`);
-		}
-		if (slave.partners.has(-8)) {
-			other.push(`some of your animals`);
-		}
-		if (slave.partners.has(-9)) {
-			other.push(`members of the Futanari Sisters`);
+		const partners = new Map([
+			[-1, "you"],
+			[-2, `citizens of ${V.arcologies[0].name}`],
+			[-3, `your former master`],
+			[-4, `another arcology owner`],
+			[-6, `members of the Societal Elite`],
+			[-8, `your animals`],
+			[-9, `members of the Futanari Sisters`],
+		]);
+
+		for (const [ID, name] of partners) {
+			if (slave.partners.has(ID)) {
+				other.push(name);
+			}
 		}
 
 		const link = App.UI.DOM.link(`${numberWithPluralOne(slaves.length, 'other slave')}`, () => {
 			const innerDiv = document.createElement("div");
 
 			innerDiv.append(
-				`${slave.slaveName} has slept with ${other.length > 0 ? `${toSentence(other)}, as well as `: ``}`,
+				`${slave.slaveName} has ${other.length > 0 ? `been fucked by ${toSentence(other)}, as well as `: `slept with`}`,
 				ownedSlavesSpan
 			);
 
@@ -273,14 +267,12 @@ App.UI.SlaveInteract.records = function(slave, refresh) {
 				link,
 				`so far.`,
 			);
-		} else if (other.length > 0) {
-			text.push(`${He} hasn't had sex with any of your slaves yet.`);
-		} else {
+		} else if (other.length === 0) {
 			text.push(`${He} hasn't had sex with anyone yet.`);
 		}
 
 		if (other.length > 0) {
-			text.push(`${He} has ${slaves.length > 0 ? `also` : ``} had sex with ${toSentence(other)}${slaves.length > 0 ? `` : `, though`}.`);
+			text.push(`${He} has ${slaves.length > 0 ? `also` : `only`} had sex with ${toSentence(other)}.`);
 		}
 
 		App.Events.addNode(div, text);
@@ -291,9 +283,9 @@ App.UI.SlaveInteract.records = function(slave, refresh) {
 	r = [];
 	linkArray = [];
 	if (V.slaveCostFactor > 1) {
-		r.push(App.UI.DOM.makeElement("span", `The slave market is bullish; the price of slaves is high.`, "yellow"));
+		r.push(App.UI.DOM.makeElement("span", `The slave market is bullish; the price of slaves is high.`, ["yellow"]));
 	} else if (V.slaveCostFactor < 1) {
-		r.push(App.UI.DOM.makeElement("span", `The slave market is bearish; the price of slaves is low.`, "yellow"));
+		r.push(App.UI.DOM.makeElement("span", `The slave market is bearish; the price of slaves is low.`, ["yellow"]));
 	}
 
 	if (V.slaves.length < 2) {
diff --git a/src/interaction/siRules.js b/src/interaction/siRules.js
index 6034405bf2dcc7d0a8609d2ff2cf7f15de64c494..2b05a1c0f80b98d186b21c889b4c2db1f065c9dd 100644
--- a/src/interaction/siRules.js
+++ b/src/interaction/siRules.js
@@ -413,6 +413,7 @@ App.UI.SlaveInteract.rules = function(slave, refresh) {
 			// Level
 			level.set(`No sex`, `none`);
 			level.set(`All sex`, `all`);
+			level.set(`Disabled`, `off`);
 
 			// Body part
 			bodyPart.set(`Vanilla`, `vanilla`);
diff --git a/src/interaction/siWardrobe.js b/src/interaction/siWardrobe.js
index 3636d4feee5f356f87cb66071a083edcb1a90451..49c5533360ee4824d881d2a95a77fab856204beb 100644
--- a/src/interaction/siWardrobe.js
+++ b/src/interaction/siWardrobe.js
@@ -138,7 +138,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		const label = document.createElement('div');
 		label.append(`Slave selects ${his} own outfits: `);
 
-		App.UI.DOM.appendNewElement("span", label, slave.choosesOwnClothes ? "Allowed" : "Forbidden", "bold");
+		App.UI.DOM.appendNewElement("span", label, slave.choosesOwnClothes ? "Allowed" : "Forbidden", ["bold"]);
 
 		el.appendChild(label);
 
@@ -175,7 +175,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		if (slave.fuckdoll === 0) {
 			// First Row
 			label = document.createElement('div');
-			label.append(`Clothes: `, App.UI.DOM.spanWithTooltip(slave.clothes, itemTooltip(slave.clothes, "clothes"), "bold"));
+			label.append(`Clothes: `, App.UI.DOM.spanWithTooltip(slave.clothes, itemTooltip(slave.clothes, "clothes"), ["bold"]));
 
 			if (slave.fuckdoll !== 0 || slave.clothes === "restrictive latex" || slave.clothes === "a latex catsuit" || slave.clothes === "a cybersuit" || slave.clothes === "a comfortable bodysuit") {
 				if (V.seeImages === 1 && V.imageChoice === 1) {
@@ -190,7 +190,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		}
 
 		label = document.createElement('div');
-		label.append(`Collar: `, App.UI.DOM.spanWithTooltip(slave.collar, itemTooltip(slave.collar, "collar"), "bold"));
+		label.append(`Collar: `, App.UI.DOM.spanWithTooltip(slave.collar, itemTooltip(slave.collar, "collar"), ["bold"]));
 		// Choose her own
 		if (slave.collar !== `none`) {
 			label.append(noneLink("collar"));
@@ -243,7 +243,6 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 			let array = [];
 
 			for (const [key, object] of App.Data.slaveWear.collar) {
-				// FIXME: Property 'harsh' does not exist on type 'slaveWear | slaveWearChastity'.
 				if (T.filters.hasOwnProperty("harsh") && ((T.filters.harsh === false && object.harsh) || (T.filters.harsh === true && !object.harsh))) {
 					continue;
 				}
@@ -270,7 +269,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		const el = document.createElement('div');
 
 		const label = document.createElement('div');
-		label.append(`Mask: `, App.UI.DOM.spanWithTooltip(slave.faceAccessory, itemTooltip(slave.faceAccessory, "faceAccessory"), "bold"));
+		label.append(`Mask: `, App.UI.DOM.spanWithTooltip(slave.faceAccessory, itemTooltip(slave.faceAccessory, "faceAccessory"), ["bold"]));
 
 		// Choose her own
 		if (slave.faceAccessory !== `none`) {
@@ -313,7 +312,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		const el = document.createElement('div');
 
 		const label = document.createElement('div');
-		label.append(`Gag: `, App.UI.DOM.spanWithTooltip(slave.mouthAccessory, itemTooltip(slave.mouthAccessory, "mouthAccessory"), "bold"));
+		label.append(`Gag: `, App.UI.DOM.spanWithTooltip(slave.mouthAccessory, itemTooltip(slave.mouthAccessory, "mouthAccessory"), ["bold"]));
 
 		// Choose her own
 		if (slave.mouthAccessory !== `none`) {
@@ -344,7 +343,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		// App.Desc.armwear(slave)
 
 		const label = document.createElement('div');
-		label.append(`Arm accessory: `, App.UI.DOM.spanWithTooltip(slave.armAccessory, itemTooltip(slave.armAccessory, "armAccessory"), "bold"));
+		label.append(`Arm accessory: `, App.UI.DOM.spanWithTooltip(slave.armAccessory, itemTooltip(slave.armAccessory, "armAccessory"), ["bold"]));
 
 		// Choose her own
 		if (slave.armAccessory !== "none") {
@@ -365,7 +364,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		const el = document.createElement('div');
 		const label = App.UI.DOM.appendNewElement("div", el, `Shoes: `);
 
-		label.append(App.UI.DOM.spanWithTooltip(slave.shoes, itemTooltip(slave.shoes, "shoes"), "bold"));
+		label.append(App.UI.DOM.spanWithTooltip(slave.shoes, itemTooltip(slave.shoes, "shoes"), ["bold"]));
 
 		/* We have "barefoot" in App.Data.slaveWear.slaveWear to cover for this
 			// Choose her own
@@ -404,7 +403,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		const el = document.createElement('div');
 		const label = App.UI.DOM.appendNewElement("div", el, `Leg accessory: `);
 
-		label.append(App.UI.DOM.spanWithTooltip(slave.legAccessory, itemTooltip(slave.legAccessory, "legAccessory")));
+		label.append(App.UI.DOM.spanWithTooltip(slave.legAccessory, itemTooltip(slave.legAccessory, "legAccessory"), ["bold"]));
 
 		// Choose her own
 		if (slave.legAccessory !== "none") {
@@ -417,7 +416,9 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 	}
 
 	function bellyAccessory() {
+		/** @type {Array<FC.BellyAccessory>} */
 		let array = [];
+		/** @type {Array<FC.BellyAccessory>} */
 		let empathyArray = [];
 
 		for (const [key, object] of App.Data.bellyAccessory) {
@@ -439,7 +440,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 
 		let label = App.UI.DOM.appendNewElement("div", el, `Belly accessory: `);
 
-		label.append(App.UI.DOM.spanWithTooltip(slave.bellyAccessory, itemTooltip(slave.bellyAccessory, "bellyAccessory"), "bold"));
+		label.append(App.UI.DOM.spanWithTooltip(slave.bellyAccessory, itemTooltip(slave.bellyAccessory, "bellyAccessory"), ["bold"]));
 
 		// Choose her own
 		if (slave.bellyAccessory !== `none`) {
@@ -471,7 +472,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		const el = document.createElement('div');
 
 		const label = document.createElement('div');
-		label.append(`Anal accessory: `, App.UI.DOM.spanWithTooltip(slave.buttplug, itemTooltip(slave.buttplug, "buttplug"), "bold"));
+		label.append(`Anal accessory: `, App.UI.DOM.spanWithTooltip(slave.buttplug, itemTooltip(slave.buttplug, "buttplug"), ["bold"]));
 
 		if (slave.buttplug !== `none`) {
 			label.append(noneLink("buttplug"));
@@ -523,7 +524,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		}
 
 		const label = document.createElement('div');
-		label.append(`Anal accessory attachment: `, App.UI.DOM.spanWithTooltip(slave.buttplugAttachment, itemTooltip(slave.buttplugAttachment, "buttplugAttachment"), "bold"));
+		label.append(`Anal accessory attachment: `, App.UI.DOM.spanWithTooltip(slave.buttplugAttachment, itemTooltip(slave.buttplugAttachment, "buttplugAttachment"), ["bold"]));
 
 		if (slave.buttplugAttachment !== `none`) {
 			label.append(noneLink("buttplugAttachment"));
@@ -560,7 +561,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		const el = document.createElement('div');
 
 		const label = document.createElement('div');
-		label.append(`Vaginal accessory: `, App.UI.DOM.spanWithTooltip(slave.vaginalAccessory, itemTooltip(slave.vaginalAccessory, "vaginalAccessory"), "bold"));
+		label.append(`Vaginal accessory: `, App.UI.DOM.spanWithTooltip(slave.vaginalAccessory, itemTooltip(slave.vaginalAccessory, "vaginalAccessory"), ["bold"]));
 
 		if (slave.vaginalAccessory !== `none`) {
 			label.append(noneLink("vaginalAccessory"));
@@ -621,7 +622,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 
 		let label = App.UI.DOM.appendNewElement("div", el, `Vaginal accessory attachment: `);
 
-		label.append(App.UI.DOM.spanWithTooltip(slave.vaginalAttachment, itemTooltip(slave.vaginalAttachment, "vaginalAttachment"), "bold"));
+		label.append(App.UI.DOM.spanWithTooltip(slave.vaginalAttachment, itemTooltip(slave.vaginalAttachment, "vaginalAttachment"), ["bold"]));
 
 		if (slave.vaginalAttachment !== `none`) {
 			label.append(noneLink("vaginalAttachment"));
@@ -657,7 +658,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 		const el = document.createElement('div');
 
 		const label = document.createElement('div');
-		label.append(`Dick accessory: `, App.UI.DOM.spanWithTooltip(slave.dickAccessory, itemTooltip(slave.dickAccessory, "dickAccessory")));
+		label.append(`Dick accessory: `, App.UI.DOM.spanWithTooltip(slave.dickAccessory, itemTooltip(slave.dickAccessory, "dickAccessory"), ["bold"]));
 
 		if (slave.dickAccessory !== `none`) {
 			label.append(noneLink("dickAccessory"));
@@ -720,7 +721,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 			chasCho = `THERE HAS BEEN AN ERROR `;
 		}
 
-		label.append(App.UI.DOM.spanWithTooltip(chasCho, itemTooltip(chasCho, "chastity"), "bold"));
+		label.append(App.UI.DOM.spanWithTooltip(chasCho, itemTooltip(chasCho, "chastity"), ["bold"]));
 
 		if (slave.chastityAnus !== 0 || slave.chastityPenis !== 0 || slave.chastityVagina !== 0) {
 			label.append(
@@ -1003,7 +1004,7 @@ App.UI.SlaveInteract.wardrobe = function(slave, contentRefresh) {
 					);
 
 					if (item.fs && item.fs.unlocks) {
-						link.append(App.UI.DOM.spanWithTooltip(`FS`, FutureSocieties.displayAdj(item.fs.unlocks), "note"));
+						link.append(App.UI.DOM.spanWithTooltip(`FS`, FutureSocieties.displayAdj(item.fs.unlocks), ["note"]));
 					}
 				}
 				linkArray.push(link);
diff --git a/src/interaction/siWork.js b/src/interaction/siWork.js
index 2ef248c80fcadc15a334218cbd1ec7c0e9f71645..dbed779881d07d1a14510dec0deb5841e00c85c5 100644
--- a/src/interaction/siWork.js
+++ b/src/interaction/siWork.js
@@ -10,7 +10,7 @@ App.UI.SlaveInteract.work = function(slave, refresh) {
 	let span;
 	const links = [];
 	const {
-		His, He,
+		He,
 		his, him
 	} = getPronouns(slave);
 
@@ -46,10 +46,6 @@ App.UI.SlaveInteract.work = function(slave, refresh) {
 		div = document.createElement('div');
 		div.id = "mini-scene";
 		p.appendChild(div);
-
-		span = document.createElement('span');
-		span.id = "useSlave";
-		p.appendChild(span);
 		p.appendChild(useSlaveDisplay());
 	}
 	el.append(p);
@@ -173,7 +169,7 @@ App.UI.SlaveInteract.work = function(slave, refresh) {
 		// add a note node if required
 		if (linkDesc.note) {
 			span.append(" ");
-			App.UI.DOM.appendNewElement("span", span, linkDesc.note, "note");
+			App.UI.DOM.appendNewElement("span", span, linkDesc.note, ["note"]);
 		}
 		return span;
 	}
@@ -248,13 +244,13 @@ App.UI.SlaveInteract.work = function(slave, refresh) {
 		let tutor = tutorForSlave(slave);
 
 		if (tutor === null) {
-			App.UI.DOM.appendNewElement("span", title, `none.`, "bold");
+			App.UI.DOM.appendNewElement("span", title, `none.`, ["bold"]);
 		} else {
-			App.UI.DOM.appendNewElement("span", title, tutor + `.`, "bold");
+			App.UI.DOM.appendNewElement("span", title, tutor + `.`, ["bold"]);
 		}
 
 		if (tutor != null) {
-			App.UI.DOM.appendNewElement("span", title, ` To progress slave needs to be assigned to: "` + Job.CLASSES + `" or "` + Job.SCHOOL + `".`, "note");
+			App.UI.DOM.appendNewElement("span", title, ` To progress slave needs to be assigned to: "` + Job.CLASSES + `" or "` + Job.SCHOOL + `".`, ["note"]);
 		}
 
 		let list = ["None"];
@@ -419,7 +415,7 @@ App.UI.SlaveInteract.work = function(slave, refresh) {
 				if (canImpreg(slave, slave)) {
 					sexOptions.push({text: `Use ${his} own seed to impregnate ${him}`, scene: () => App.Interact.fSlaveSelfImpreg(slave)});
 				}
-				sexOptions.push({text: `Use another slave to impregnate ${him}`, scene: () => App.Interact.fSlaveImpreg(slave)});
+				sexOptions.push({text: `Use another slave to impregnate ${him}`, scene: () => App.Interact.choosePartner(new App.Interact.fSlaveImpregChoosePartner(slave))});
 			}
 			if (slave.assignment !== Job.DAIRY && slave.assignment !== Job.ARCADE && slave.assignment !== Job.CELLBLOCK) {
 				if (V.dairyPiping === 1) {
@@ -545,117 +541,78 @@ App.UI.SlaveInteract.work = function(slave, refresh) {
 				}
 			}
 			if (canDoVaginal(slave)) {
-				sexOptions.push({text: `Have another slave fuck ${his} pussy`, goto: `FSlaveSlaveVag`});
+				sexOptions.push({text: `Have another slave fuck ${his} pussy`, scene: () => App.Interact.choosePartner(new App.Interact.fSlaveSlaveVagChoosePartner(slave))});
 			}
 			if (canDoAnal(slave)) {
-				sexOptions.push({text: `Have another slave fuck ${his} ass`, goto: `FSlaveSlaveAss`});
+				sexOptions.push({text: `Have another slave fuck ${his} ass`, scene: () => App.Interact.choosePartner(new App.Interact.fSlaveSlaveAssChoosePartner(slave))});
 			}
 			if (canPenetrate(slave)) {
-				sexOptions.push({text: `Have another slave ride ${his} cock`, goto: `FSlaveSlaveDick`});
+				sexOptions.push({text: `Have another slave ride ${his} cock`, scene: () => App.Interact.choosePartner(new App.Interact.fSlaveSlaveDickChoosePartner(slave))});
 			} else if (slave.clit >= 4) {
-				sexOptions.push({text: `Have another slave ride ${his} clit-dick`, goto: `FSlaveSlaveDick`});
+				sexOptions.push({text: `Have another slave ride ${his} clit-dick`, scene: () => App.Interact.choosePartner(new App.Interact.fSlaveSlaveDickChoosePartner(slave))});
 			}
 			if (V.seeBestiality) {
+				/** @type {FC.SlaveActs} */
+				let act;
+
+				if ([Job.FUCKTOY, Job.MASTERSUITE].includes(slave.assignment)) {
+					if (slave.toyHole === "pussy") {
+						act = "vaginal";
+					} else if (slave.toyHole === "ass") {
+						act = "anal";
+					} else if (slave.toyHole === "mouth") {
+						act = "oral";
+					} else {
+						if (canDoVaginal(slave)) {
+							act = "vaginal";
+						} else if (canDoAnal(slave)) {
+							act = "anal";
+						} else {
+							act = "oral";
+						}
+					}
+				} else if (canDoVaginal(slave)) {
+					act = "vaginal";
+				} else if (canDoAnal(slave)) {
+					act = "anal";
+				} else {
+					act = "oral";
+				}
+
 				if (V.farmyardKennels > 0 && V.active.canine) {
 					sexOptions.push({
 						text: `Have ${getAnimal(V.active.canine).articleAn} ${V.active.canine} mount ${him}`,
-						scene: () => App.Interact.fAnimal(slave, "canine"),
+						scene: () => App.Interact.fAnimal(slave, "canine", act),
 					});
 				}
 				if (V.farmyardStables > 0 && V.active.hooved) {
 					sexOptions.push({
 						text: `Let ${getAnimal(V.active.hooved).articleAn} ${V.active.hooved} mount ${him}`,
-						scene: () => App.Interact.fAnimal(slave, "hooved"),
+						scene: () => App.Interact.fAnimal(slave, "hooved", act),
 					});
 				}
 				if (V.farmyardCages > 0 && V.active.feline) {
 					sexOptions.push({
 						text: `Have ${getAnimal(V.active.feline).articleAn} ${V.active.feline} mount ${him}`,
-						scene: () => App.Interact.fAnimal(slave, "feline"),
+						scene: () => App.Interact.fAnimal(slave, "feline", act),
 					});
 				}
 			}
 			sexOptions.push({text: `Abuse ${him}`, scene: () => App.Interact.fAbuse(slave)});
-			if (V.seeIncest === 1) {
-				const availRelatives = availableRelatives(slave);
-				if (availRelatives.mother) {
+			if (V.seeIncest === 1 && totalRelatives(slave) > 0) {
+				const availableRelatives = V.slaves.filter(s => areRelated(s, slave) && isSlaveAvailable(s));
+				if (availableRelatives.length > 1) {
 					sexOptions.push({
-						text: `Fuck ${him} with ${his} mother`,
-						scene: () => App.Interact.fRelation(slave, getSlave(slave.mother))
+						text: `Fuck ${him} with one of ${his} close relatives`,
+						scene: () => App.Interact.choosePartner(new App.Interact.fRelationChoosePartner(slave)),
 					});
-				} else if (availRelatives.motherName !== null) {
-					sexOptions.push({text: `${His} mother, ${availRelatives.motherName}, is unavailable`});
-				}
-				/*
-				if (availRelatives.father) {
-					sexOptions.push({text: `Fuck ${him} with ${his} father`, scene: () => App.Interact.fRelation(slave, getSlave(slave.father))});
-				} else if (availRelatives.fatherName !== null) {
-					sexOptions.push({text: `${His} father, ${availRelatives.fatherName}, is unavailable`});
-				}
-				*/
-				if (slave.daughters > 0) {
-					if (availRelatives.daughters === 0) {
-						if (slave.daughters === 1) {
-							sexOptions.push({
-								text: `Fuck ${him} with ${his} daughter`,
-								disabled: `${His} ${availRelatives.oneDaughterRel} is unavailable`
-							});
-						} else {
-							sexOptions.push({
-								text: `Fuck ${him} with one of ${his} daughters`,
-								disabled: `${His} daughters are unavailable`
-							});
-						}
-					} else {
-						if (slave.daughters === 1) {
-							sexOptions.push({
-								text: `Fuck ${him} with ${his} ${availRelatives.oneDaughterRel}`,
-								scene: () => App.Interact.fRelation(slave, randomAvailableDaughter(slave))
-							});
-						} else {
-							sexOptions.push({
-								text: `Fuck ${him} with one of ${his} daughters`,
-								scene: () => App.Interact.fRelation(slave, randomAvailableDaughter(slave))
-							});
-						}
-						/*
-						if (availRelatives.daughters > 1) {
-							sexOptions.push({text: `Fuck ${him} with ${his} daughters`, scene: () => App.Interact.fRelation(slave, daughters?)});
-						}
-						*/
-					}
-				}
-				if (slave.sisters > 0) {
-					if (availRelatives.sisters === 0) {
-						if (slave.sisters === 1) {
-							sexOptions.push({
-								text: `Fuck ${him} with ${his} sister`,
-								disabled: `${His} ${availRelatives.oneSisterRel} is unavailable`
-							});
-						} else {
-							sexOptions.push({
-								text: `Fuck ${him} with one of ${his} sisters`,
-								disabled: `${His} sisters are unavailable`
-							});
-						}
-					} else {
-						if (slave.sisters === 1) {
-							sexOptions.push({
-								text: `Fuck ${him} with ${his} ${availRelatives.oneSisterRel}`,
-								scene: () => App.Interact.fRelation(slave, randomAvailableSister(slave))
-							});
-						} else {
-							sexOptions.push({
-								text: `Fuck ${him} with one of ${his} sisters`,
-								scene: () => App.Interact.fRelation(slave, randomAvailableSister(slave))
-							});
-						}
-						/*
-						if (availRelatives.sisters > 1) {
-							sexOptions.push({text: `Fuck ${him} with ${his} sisters`, scene: () => App.Interact.fRelation(slave, sisters?)});
-						}
-						*/
-					}
+				} else if (availableRelatives.length === 1) {
+					sexOptions.push({
+						text: `Fuck ${him} with ${his} ${relativeTerm(slave, availableRelatives[0])} ${SlaveFullName(availableRelatives[0])}`,
+						scene: () => App.Interact.fRelation(slave, availableRelatives[0]),
+					});
+				} else {
+					sexOptions.push({text: `None of ${his} close relatives are available`});
 				}
 			}
 			if (slave.relationship > 0) {
@@ -685,7 +642,7 @@ App.UI.SlaveInteract.work = function(slave, refresh) {
 				}
 			}
 			if (slave.fetish !== "mindbroken" && slave.accent < 4 && ((canTalk(slave)) || hasAnyArms(slave))) {
-				sexOptions.push({text: `Ask ${him} about ${his} feelings`, scene: () => App.Interact.feelings(slave)});
+				sexOptions.push({text: `Ask ${him} about ${his} feelings`, scene: () => App.Interact.fFeelings(slave)});
 				if (V.PC.dick > 0) {
 					sexOptions.push({text: `Make ${him} beg`, scene: () => App.Interact.fBeg(slave)});
 				}
@@ -876,7 +833,7 @@ App.UI.SlaveInteract.work = function(slave, refresh) {
 			// add a note node if required
 			if (linkDesc.note) {
 				span.append(" ");
-				App.UI.DOM.appendNewElement("span", span, linkDesc.note, "note");
+				App.UI.DOM.appendNewElement("span", span, linkDesc.note, ["note"]);
 			}
 			return span;
 		}
diff --git a/src/interaction/universalRules.js b/src/interaction/universalRules.js
index 718b8a99954caf280dc9f98ca8bbbc32125ead2e..f77c28bfe85606a78c964edb57cecedd7dd75297 100644
--- a/src/interaction/universalRules.js
+++ b/src/interaction/universalRules.js
@@ -221,7 +221,6 @@ App.UI.universalRules = function() {
 			.addValue("No", 0).off();
 		if (V.universalRulesBirthing === 1) {
 			option.addComment(`Heavily pregnant slaves will be scanned daily for signs of labor and moved to a birthing area immediately if any are detected.`);
-			r.push();
 		} else {
 			option.addComment(`Heavily pregnant slaves will be required to work right up until they feel contractions. This will increase upkeep costs for these slaves`);
 		}
diff --git a/src/interaction/useSlave/useSlave.js b/src/interaction/useSlave/useSlave.js
index e9ab9ef2b5f548563bae9e8a02a0216ad642fdd0..6fa129796950035ac388ad090a9e64ffcedf2774 100644
--- a/src/interaction/useSlave/useSlave.js
+++ b/src/interaction/useSlave/useSlave.js
@@ -44,7 +44,7 @@ App.UI.SlaveInteract.useSlave = function(slave) {
 			if (introShown) {
 				div.append(`You are out of stamina.`);
 			} else {
-				App.UI.DOM.appendNewElement("span", div, `You have recently had sex with ${him}`, "note");
+				App.UI.DOM.appendNewElement("span", div, `You have recently had sex with ${him}`, ["note"]);
 			}
 		}
 
@@ -157,7 +157,7 @@ App.UI.SlaveInteract.useSlave = function(slave) {
 	}
 
 	// Helper functions
-	
+
 	// Adjust characters' clothing state before scene is shown
 	function setUpClothing(playerState, slaveState) {
 		// Assume the PC is fully clothed. Remove the bra if boobs are small/nonexistent.
@@ -176,6 +176,7 @@ App.UI.SlaveInteract.useSlave = function(slave) {
 		const noUnderwearOutfits = ["a burkini", "a comfortable bodysuit", "a tight Imperial bodysuit", "a cybersuit", "a fallen nuns habit", "a leotard", "a latex catsuit", "a monokini", "a one-piece swimsuit", "a scalemail bikini", "a slutty klan robe", "a slutty maid outfit", "a slutty nurse outfit", "a slutty pony outfit", "a slutty qipao", "a slutty schutzstaffel uniform", "a string bikini", "a succubus outfit", "a toga", "an apron", "chains", "clubslut netting", "harem gauze", "overalls", "restrictive latex", "shibari ropes", "slutty business attire", "slutty jewelry", "uncomfortable straps"]; // ex. swimsuits, slutty jewelry, bodysuits
 		const noBottomOutfits = ["a button-up shirt", "a sweater", "a t-shirt", "a tank-top", "a tube top", "an oversized t-shirt"];
 		const noTopOutfits = ["boyshorts", "cutoffs", "jeans", "leather pants", "sport shorts"];
+
 		if (nakedOutfits.includes(slave.clothes)) {
 			slaveState.clothing.top.isOff = true;
 			slaveState.clothing.bottom.isOff = true;
diff --git a/src/interaction/useSlave/useSlaveHelpers.js b/src/interaction/useSlave/useSlaveHelpers.js
index f267aeaeff4b2906d4980ffd410a5860d98b244a..6025197be61c4ce929e7fc1588c48dce98411f9f 100644
--- a/src/interaction/useSlave/useSlaveHelpers.js
+++ b/src/interaction/useSlave/useSlaveHelpers.js
@@ -6,17 +6,22 @@ App.UI.SlaveInteract.Position = {
 };
 
 /** @enum {string} */
-App.UI.SlaveInteract.Action = {
+App.UI.SlaveInteract.SexAct = {
 	ANAL: 'anal',
-	FINGERING: 'fingering',
-	KISSING: 'kissing',
 	ORAL: 'oral',
 	PENETRATING: 'penetrating',
 	RECEIVING: 'receiving',
-	TOUCHING: 'touching',
 	VAGINAL: 'vaginal',
 };
 
+/** @enum {string} */
+App.UI.SlaveInteract.Action = {
+	FINGERING: 'fingering',
+	KISSING: 'kissing',
+	RECEIVING: 'receiving',
+	TOUCHING: 'touching',
+};
+
 App.UI.SlaveInteract.Option = class Option {
 	/**
 	 * @param {string} link
@@ -43,7 +48,9 @@ App.UI.SlaveInteract.CharacterState = class CharacterState {
 		this.lust = 0;
 		/** @type {number} The lust level when the character's last orgasm occurred */
 		this.previousOrgasm = 0;
-		/** @type {App.UI.SlaveInteract.Action} What action the character is currently doing. */
+		/** @type {App.UI.SlaveInteract.Action} Which primary sex act the character is currently doing. */
+		this.sexAct = null;
+		/** @type {App.UI.SlaveInteract.Action} What other actions the character is currently doing. */
 		this.action = null;
 		/** @type {App.UI.SlaveInteract.Position} Whether the character is standing, kneeling, or laying down. */
 		this.position = null;
diff --git a/src/interaction/useSlave/useSlaveOptions.js b/src/interaction/useSlave/useSlaveOptions.js
index d97d2cb2683e49373bf2518a8729e7a375e6edc2..0e9d214924636fafc05bae750b2339798db254ae 100644
--- a/src/interaction/useSlave/useSlaveOptions.js
+++ b/src/interaction/useSlave/useSlaveOptions.js
@@ -8,7 +8,7 @@
 App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerState, slaveState) {
 	const refreshArt = () => App.Events.refreshEventArt(clone);
 
-	const {He, he, him, his, hers} = getPronouns(clone);
+	const {He, His, he, him, his, hers} = getPronouns(clone);
 
 	/** @enum {string} */
 	const Fetish = {
@@ -30,24 +30,26 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 	const Position = App.UI.SlaveInteract.Position;
 	/** @enum {string} */
 	const Action = App.UI.SlaveInteract.Action;
+	/** @enum {string} */
+	const SexAct = App.UI.SlaveInteract.SexAct;
 
-	function recordSex(action) {
-		switch (action) {
-			case Action.ORAL:
+	function recordSex(sexAct) {
+		switch (sexAct) {
+			case SexAct.ORAL:
 				if (!slaveState.hasDoneOral) {
 					seX(slave, "oral", player);
 					slaveState.hasDoneOral = true;
 					playerState.hasDoneOral = true;
 				}
 				break;
-			case Action.VAGINAL:
+			case SexAct.VAGINAL:
 				if (!slaveState.hasDoneVaginal) {
 					seX(slave, "vaginal", player);
 					slaveState.hasDoneVaginal = true;
 					playerState.hasDoneVaginal = true;
 				}
 				break;
-			case Action.ANAL:
+			case SexAct.ANAL:
 				if (!slaveState.hasDoneAnal) {
 					seX(slave, "anal", player);
 					slaveState.hasDoneAnal = true;
@@ -74,14 +76,28 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			},
 			reaction: this.reactionText.keepKissing(clone),
 		},
+		{
+			link: `Stop kissing ${him}`,
+			desc: contextualText.stopKissing(clone),
+			tooltip: `${His} lips can please you in other ways, too.`,
+			prereq: () =>
+				clone.mouthAccessory === none &&
+				playerState.action === Action.KISSING &&
+				slaveState.action === Action.KISSING,
+			effect: () => {
+				playerState.action = null;
+				slaveState.action = null;
+			},
+			reaction: this.reactionText.stopKissing(clone),
+		},
 		{
 			link: `Keep fucking ${him}`,
 			desc: contextualText.keepFucking(clone),
 			tooltip: `It feels too good to stop now.`,
 			prereq: () =>
-				playerState.action === Action.PENETRATING &&
-				(slaveState.action === Action.VAGINAL ||
-				slaveState.action === Action.ANAL),
+				playerState.sexAct === SexAct.PENETRATING &&
+				(slaveState.sexAct === SexAct.VAGINAL ||
+				slaveState.sexAct === SexAct.ANAL),
 			effect: () => {
 				playerState.lust += 2;
 				slaveState.lust++;
@@ -93,9 +109,9 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			desc: contextualText.holdDown(clone),
 			tooltip: `${He}'s not going anywhere if you can help it.`,
 			prereq: () =>
-				playerState.action === Action.PENETRATING &&
-				(slaveState.action === Action.VAGINAL ||
-				slaveState.action === Action.ANAL),
+				playerState.sexAct === SexAct.PENETRATING &&
+				(slaveState.sexAct === SexAct.VAGINAL ||
+				slaveState.sexAct === SexAct.ANAL),
 			effect: () => {
 				playerState.lust += 2;
 				slaveState.lust++;
@@ -107,12 +123,12 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			desc: contextualText.stopFucking(clone),
 			tooltip: `You can always put it back in. ${He} can't stop you.`,
 			prereq: () =>
-				playerState.action === Action.PENETRATING &&
-				(slaveState.action === Action.VAGINAL ||
-				slaveState.action === Action.ANAL),
+				playerState.sexAct === SexAct.PENETRATING &&
+				(slaveState.sexAct === SexAct.VAGINAL ||
+				slaveState.sexAct === SexAct.ANAL),
 			effect: () => {
-				playerState.action = null;
-				slaveState.action = null;
+				playerState.sexAct = null;
+				slaveState.sexAct = null;
 			},
 			reaction: this.reactionText.stopFucking(clone),
 		},
@@ -120,9 +136,7 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Let ${him} keep pleasuring you`,
 			desc: contextualText.continueOral(clone),
 			tooltip: `Lay back and enjoy ${his} service.`,
-			prereq: () =>
-				playerState.action === Action.RECEIVING &&
-				slaveState.action === Action.ORAL,
+			prereq: () => slaveState.sexAct === SexAct.ORAL,
 			effect: () => {
 				playerState.lust += 2;
 				slaveState.lust++;
@@ -133,9 +147,7 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Hold ${his} head down`,
 			desc: contextualText.holdHeadDown(clone),
 			tooltip: `${He} can breathe when you've cum.`,
-			prereq: () =>
-				playerState.action === Action.RECEIVING &&
-				slaveState.action === Action.ORAL,
+			prereq: () => slaveState.sexAct === SexAct.ORAL,
 			effect: () => {
 				playerState.lust += 2;
 				slaveState.lust++;
@@ -146,10 +158,10 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Order ${him} to stop pleasuring you`,
 			desc: contextualText.stopOral(clone),
 			tooltip: `Time for ${him} to please you another way.`,
-			prereq: () => slaveState.action === Action.ORAL,
+			prereq: () => slaveState.sexAct === SexAct.ORAL,
 			effect: () => {
-				playerState.action = null;
-				slaveState.action = null;
+				playerState.sexAct = null;
+				slaveState.sexAct = null;
 			},
 			reaction: this.reactionText.stopOral(clone),
 		},
@@ -158,13 +170,13 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			desc: contextualText.cumOnFace(clone),
 			tooltip: `Let it all out on ${his} face.`,
 			prereq: () => playerState.lust - playerState.previousOrgasm >= 25 &&
-				slaveState.action === Action.ORAL,
+				slaveState.sexAct === SexAct.ORAL,
 			effect: () => {
 				playerState.previousOrgasm = playerState.lust;
 				slaveState.lust += 2;
 
-				playerState.action = null;
-				slaveState.action = null;
+				playerState.sexAct = null;
+				slaveState.sexAct = null;
 			},
 			reaction: this.reactionText.cumOnFace(clone),
 		},
@@ -173,13 +185,13 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			desc: contextualText.cumInMouth(clone),
 			tooltip: `${V.PC.dick !== 0 ? `Shoot your cum down ${his} throat.` : `${He} won't dare stop until you're satisfied.`}`,
 			prereq: () => playerState.lust - playerState.previousOrgasm >= 25 &&
-				slaveState.action === Action.ORAL,
+				slaveState.sexAct === SexAct.ORAL,
 			effect: () => {
 				playerState.previousOrgasm = playerState.lust;
 				slaveState.lust += 3;
 
-				playerState.action = null;
-				slaveState.action = null;
+				playerState.sexAct = null;
+				slaveState.sexAct = null;
 			},
 			reaction: this.reactionText.cumInMouth(clone),
 		},
@@ -187,11 +199,11 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Cum in ${his} pussy`,
 			desc: contextualText.cumInPussy(clone),
 			tooltip: `Cum deep inside ${him}. Fill ${him} up. You know it'll feel amazing.`,
-			prereq: () => 
+			prereq: () =>
 				playerState.lust - playerState.previousOrgasm >= 25 &&
 				V.PC.dick !== 0 &&
-				playerState.action === Action.PENETRATING &&
-				slaveState.action === Action.VAGINAL,
+				playerState.sexAct === SexAct.PENETRATING &&
+				slaveState.sexAct === SexAct.VAGINAL,
 			effect: () => {
 				playerState.previousOrgasm = playerState.lust;
 				slaveState.lust += 4;
@@ -200,8 +212,8 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 					knockMeUp(slave, 25, 0, -1);
 				}
 
-				playerState.action = null;
-				slaveState.action = null;
+				playerState.sexAct = null;
+				slaveState.sexAct = null;
 			},
 			reaction: this.reactionText.cumInPussy(clone),
 		},
@@ -209,11 +221,11 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Cum in ${his} ass`,
 			desc: contextualText.cumInAnus(clone),
 			tooltip: `Make a mess of ${his} ass. Show ${him} ${his} place.`,
-			prereq: () => 
+			prereq: () =>
 				playerState.lust - playerState.previousOrgasm >= 25 &&
 				V.PC.dick !== 0 &&
-				playerState.action === Action.PENETRATING &&
-				slaveState.action === Action.ANAL,
+				playerState.sexAct === SexAct.PENETRATING &&
+				slaveState.sexAct === SexAct.ANAL,
 			effect: () => {
 				playerState.previousOrgasm = playerState.lust;
 				slaveState.lust += 3;
@@ -222,8 +234,8 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 					knockMeUp(slave, 25, 1, -1);
 				}
 
-				playerState.action = null;
-				slaveState.action = null;
+				playerState.sexAct = null;
+				slaveState.sexAct = null;
 			},
 			reaction: this.reactionText.cumInAnus(clone),
 		},
@@ -231,18 +243,21 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Make ${him} cum`,
 			desc: contextualText.makeSlaveCum(clone),
 			tooltip: `${He}'s been a good slave, and deserves a reward.`,
-			prereq: () => 
+			prereq: () =>
 				slaveState.lust - slaveState.previousOrgasm >= 25 &&
-				(playerState.action === Action.ORAL &&
-				slaveState.action === Action.RECEIVING) ||
+				((playerState.sexAct === SexAct.ORAL &&
+				slaveState.sexAct === SexAct.RECEIVING) ||
 				(playerState.action === Action.FINGERING &&
-				slaveState.action === Action.VAGINAL),
+				slaveState.action === Action.RECEIVING)),
 			effect: () => {
 				playerState.lust++;
 				slaveState.previousOrgasm = slaveState.lust;
 
-				playerState.action = null;
-				slaveState.action = null;
+				if (playerState.sexAct === SexAct.ORAL) {
+					playerState.sexAct = null;
+					slaveState.sexAct = null;
+					playerState.position = Position.STANDING;
+				}				
 			},
 			reaction: this.reactionText.makeSlaveCum(clone),
 		},
@@ -256,7 +271,9 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Kiss ${him}`,
 			desc: faceText.regularKiss(clone),
 			tooltip: `Press your lips to ${hers} and kiss ${him}.`,
-			prereq: () => clone.mouthAccessory === none,
+			prereq: () => clone.mouthAccessory === none &&
+				playerState.sexAct !== SexAct.ORAL &&
+				slaveState.sexAct !== SexAct.ORAL,
 			effect: () => {
 				playerState.lust++;
 				slaveState.lust++;
@@ -270,7 +287,9 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Kiss ${him} passionately`,
 			desc: faceText.passionateKiss(clone),
 			tooltip: `Press ${his} body to yours and kiss ${him}.`,
-			prereq: () => clone.mouthAccessory === none,
+			prereq: () => clone.mouthAccessory === none &&
+				playerState.sexAct !== SexAct.ORAL &&
+				slaveState.sexAct !== SexAct.ORAL,
 			effect: () => {
 				playerState.lust++;
 				slaveState.lust++;
@@ -284,7 +303,9 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Kiss ${him} intimately`,
 			desc: faceText.intimateKiss(clone),
 			tooltip: `Share a romantic kiss.`,
-			prereq: () => clone.mouthAccessory === none,
+			prereq: () => clone.mouthAccessory === none &&
+				playerState.sexAct !== SexAct.ORAL &&
+				slaveState.sexAct !== SexAct.ORAL,
 			effect: () => {
 				playerState.lust++;
 				slaveState.lust++;
@@ -298,22 +319,23 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Have ${him} go down on you`,
 			desc: faceText.slaveGivesOral(clone),
 			tooltip: `Have ${him} give you oral.`,
-			prereq: () => 
+			prereq: () =>
 				(clone.mouthAccessory === none || clone.mouthAccessory === "ring gag") &&
 				playerState.bottomFree &&
 				!playerState.clothing.underwear &&
 				!playerState.isKneeling &&
-				slaveState.action !== Action.ORAL,
+				slaveState.sexAct === null &&
+				slaveState.action !== Action.KISSING,
 			effect: () => {
 				slaveState.position = Position.KNEELING;
 
 				playerState.lust += 3;
 				slaveState.lust++;
 
-				playerState.action = Action.RECEIVING;
-				slaveState.action = Action.ORAL;
+				playerState.sexAct = SexAct.RECEIVING;
+				slaveState.sexAct = SexAct.ORAL;
 
-				recordSex(slaveState.action);
+				recordSex(slaveState.sexAct);
 			},
 			reaction: this.reactionText.slaveGivesOral(clone),
 		},
@@ -321,11 +343,13 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Go down on ${him}`,
 			desc: faceText.playerGivesOral(clone),
 			tooltip: `Give ${him} oral.`,
-			prereq: () => 
+			prereq: () =>
 				slaveState.clothing.bottom.isOff &&
 				!slave.chastityVagina &&
 				!slave.chastityPenis &&
 				!slaveState.clothing.underwear &&
+				playerState.sexAct === null &&
+				playerState.action !== Action.KISSING &&
 				!playerState.isKneeling &&
 				!slaveState.isKneeling,
 			effect: () => {
@@ -334,10 +358,10 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 				playerState.lust++;
 				slaveState.lust++;
 
-				playerState.action = Action.ORAL;
-				slaveState.action = Action.RECEIVING;
+				playerState.sexAct = SexAct.ORAL;
+				slaveState.sexAct = SexAct.RECEIVING;
 
-				recordSex(playerState.action);
+				recordSex(playerState.sexAct);
 			},
 			reaction: this.reactionText.playerGivesOral(clone),
 		},
@@ -365,7 +389,9 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			desc: chestText.lick(clone),
 			tooltip: clone.boobs >= 300 ? `Give ${his} boobs a taste.` : `Run your tongue along ${his} chest.`,
 			prereq: () => slaveState.topFree &&
-				!slaveState.clothing.bra,
+				!slaveState.clothing.bra &&
+				playerState.sexAct !== SexAct.ORAL &&
+				slaveState.sexAct !== SexAct.ORAL,
 			effect: () => {
 				playerState.lust += 2;
 				slaveState.lust += clone.fetish === Fetish.BOOBS ? 8 : 5;
@@ -380,7 +406,9 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			desc: chestText.suck(clone),
 			tooltip: `See if you can't get any milk.`,
 			prereq: () => slaveState.topFree &&
-				!slaveState.clothing.bra,
+				!slaveState.clothing.bra &&
+				playerState.sexAct !== SexAct.ORAL &&
+				slaveState.sexAct !== SexAct.ORAL,
 			effect: () => {
 				playerState.lust += 2;
 				slaveState.lust += clone.fetish === Fetish.BOOBS ? 9 : 5;
@@ -395,7 +423,9 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			desc: chestText.bite(clone),
 			tooltip: `Give them a little nibble.`,
 			prereq: () => slaveState.topFree &&
-				!slaveState.clothing.bra,
+				!slaveState.clothing.bra &&
+				playerState.sexAct !== SexAct.ORAL &&
+				slaveState.sexAct !== SexAct.ORAL,
 			effect: () => {
 				playerState.lust += 2;
 				slaveState.lust += clone.fetish === Fetish.BOOBS ? 8 : 5;
@@ -414,10 +444,11 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Grope ${his} pussy`,
 			desc: crotchText.gropePussy(clone),
 			tooltip: `Fondle and play with ${his} crotch a bit.`,
-			prereq: () => 
+			prereq: () =>
 				clone.vagina > -1 &&
 				!clone.chastityVagina &&
-				slaveState.bottomFree,
+				slaveState.bottomFree &&
+				slaveState.sexAct !== SexAct.VAGINAL,
 			effect: () => {
 				playerState.lust++;
 				slaveState.lust++;
@@ -431,10 +462,11 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Grope ${his} dick`,
 			desc: crotchText.gropeDick(clone),
 			tooltip: `Rub ${his} cock a little.`,
-			prereq: () => 
+			prereq: () =>
 				clone.dick > 0 &&
 				!clone.chastityPenis &&
-				slaveState.bottomFree,
+				slaveState.bottomFree &&
+				slaveState.sexAct !== SexAct.PENETRATING,
 			effect: () => {
 				playerState.lust++;
 				slaveState.lust += 2;
@@ -462,17 +494,18 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Finger ${his} pussy`,
 			desc: crotchText.fingerPussy(clone),
 			tooltip: `Play with ${his} clit a little, maybe slide a finger in there. Go on, you know you want to.`,
-			prereq: () => 
+			prereq: () =>
 				clone.vagina > -1 &&
 				(slaveState.bottomFree || clothes.includes("dress")) &&
 				!slaveState.clothing.underwear &&
-				!clone.chastityVagina,
+				!clone.chastityVagina &&
+				slaveState.sexAct !== SexAct.VAGINAL,
 			effect: () => {
 				playerState.lust += 2;
 				slaveState.lust += 5;
 
 				playerState.action = Action.FINGERING;
-				slaveState.action = Action.VAGINAL;
+				slaveState.action = Action.RECEIVING;
 			},
 			reaction: this.reactionText.fingerPussy(clone),
 		},
@@ -480,16 +513,17 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Finger ${his} asshole`,
 			desc: crotchText.fingerAnus(clone),
 			tooltip: `Play with ${his} backdoor a little. Go on, you know you want to.`,
-			prereq: () => 
-				(slaveState.bottomFree || clothes.includes("dress")) && 
+			prereq: () =>
+				(slaveState.bottomFree || clothes.includes("dress")) &&
 				!slaveState.clothing.underwear &&
-				!clone.chastityAnus,
+				!clone.chastityAnus &&
+				slaveState.sexAct !== SexAct.ANAL,
 			effect: () => {
 				playerState.lust += 2;
 				slaveState.lust += clone.fetish === Fetish.BUTTSLUT ? 7 : 4;
 
 				playerState.action = Action.FINGERING;
-				slaveState.action = Action.ANAL;
+				slaveState.action = Action.RECEIVING;
 			},
 			reaction: this.reactionText.fingerAnus(clone),
 		},
@@ -497,14 +531,15 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Take ${his} virginity`,
 			desc: crotchText.takeVirginity(clone),
 			tooltip: `Make ${him} remember ${his} first time being used as a proper sex slave.`,
-			prereq: () => 
+			prereq: () =>
 				slave.vagina === 0 &&
 				slaveState.bottomFree &&
 				!slaveState.clothing.underwear &&
 				!clone.chastityVagina &&
 				playerState.bottomFree &&
 				!playerState.clothing.underwear &&
-				slaveState.action !== Action.VAGINAL &&
+				playerState.sexAct === null &&
+				slaveState.sexAct === null &&
 				playerState.lust - playerState.previousOrgasm > 5,
 			effect: () => {
 				playerState.lust += 10;
@@ -521,10 +556,10 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 					slave.trust -= 4;
 				}
 
-				playerState.action = Action.PENETRATING;
-				slaveState.action = Action.VAGINAL;
+				playerState.sexAct = SexAct.PENETRATING;
+				slaveState.sexAct = SexAct.VAGINAL;
 
-				recordSex(slaveState.action);
+				recordSex(slaveState.sexAct);
 			},
 			reaction: this.reactionText.takeVirginity(clone),
 		},
@@ -532,23 +567,24 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Fuck ${his} pussy`,
 			desc: crotchText.fuckPussy(clone),
 			tooltip: `Push your ${player.dick ? `dick` : `strapon`} into ${his} pussy.`,
-			prereq: () => 
+			prereq: () =>
 				slave.vagina > 0 &&
 				slaveState.bottomFree &&
 				!slaveState.clothing.underwear &&
 				!clone.chastityVagina &&
 				playerState.bottomFree &&
 				!playerState.clothing.underwear &&
-				slaveState.action !== Action.VAGINAL &&
+				playerState.sexAct === null &&
+				slaveState.sexAct === null &&
 				playerState.lust - playerState.previousOrgasm > 5,
 			effect: () => {
 				playerState.lust += 8;
 				slaveState.lust += 8;
 
-				playerState.action = Action.PENETRATING;
-				slaveState.action = Action.VAGINAL;
+				playerState.sexAct = SexAct.PENETRATING;
+				slaveState.sexAct = SexAct.VAGINAL;
 
-				recordSex(slaveState.action);
+				recordSex(slaveState.sexAct);
 			},
 			reaction: this.reactionText.fuckPussy(clone),
 		},
@@ -556,14 +592,15 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Take ${his} anal virginity`,
 			desc: crotchText.takeAnalVirginity(clone),
 			tooltip: `Use ${his} butt for the first of surely many times.`,
-			prereq: () => 
+			prereq: () =>
 				slave.anus === 0 &&
 				slaveState.bottomFree &&
 				!slaveState.clothing.underwear &&
 				!clone.chastityAnus &&
 				playerState.bottomFree &&
 				!playerState.clothing.underwear &&
-				slaveState.action !== Action.ANAL &&
+				playerState.sexAct === null &&
+				slaveState.sexAct === null &&
 				playerState.lust - playerState.previousOrgasm > 5,
 			effect: () => {
 				playerState.lust += 10;
@@ -579,10 +616,10 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 					slave.trust -= 5;
 				}
 
-				playerState.action = Action.PENETRATING;
-				slaveState.action = Action.ANAL;
+				playerState.sexAct = SexAct.PENETRATING;
+				slaveState.sexAct = SexAct.ANAL;
 
-				recordSex(slaveState.action);
+				recordSex(slaveState.sexAct);
 			},
 			reaction: this.reactionText.takeAnalVirginity(clone),
 		},
@@ -590,23 +627,24 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Fuck ${his} asshole`,
 			desc: crotchText.fuckAnus(clone),
 			tooltip: `Push your ${player.dick ? `dick` : `strapon`} into ${his} asshole.`,
-			prereq: () => 
+			prereq: () =>
 				slave.anus > 0 &&
 				slaveState.bottomFree &&
 				!slaveState.clothing.underwear &&
 				!clone.chastityAnus &&
 				playerState.bottomFree &&
 				!playerState.clothing.underwear &&
-				slaveState.action !== Action.ANAL &&
+				playerState.sexAct === null &&
+				slaveState.sexAct === null &&
 				playerState.lust - playerState.previousOrgasm > 5,
 			effect: () => {
 				playerState.lust += 8;
 				slaveState.lust += clone.fetish === Fetish.BUTTSLUT ? 8 : 5;
 
-				playerState.action = Action.PENETRATING;
-				slaveState.action = Action.ANAL;
+				playerState.sexAct = SexAct.PENETRATING;
+				slaveState.sexAct = SexAct.ANAL;
 
-				recordSex(slaveState.action);
+				recordSex(slaveState.sexAct);
 			},
 			reaction: this.reactionText.fuckAnus(clone),
 		},
@@ -614,23 +652,31 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Start a sixty-nine`,
 			desc: crotchText.sixtyNine(clone),
 			tooltip: `Show each other some mutual affection.`,
-			prereq: () => 
+			prereq: () =>
 				slaveState.bottomFree &&
 				playerState.bottomFree &&
 				!slaveState.clothing.underwear &&
 				!playerState.clothing.underwear &&
 				!slave.chastityVagina &&
 				!slave.chastityPenis &&
-				(slaveState.action !== Action.ORAL ||
-				playerState.action !== Action.ORAL),
+				playerState.action !== Action.KISSING &&
+				slaveState.action !== Action.KISSING &&
+				/**
+				 * Allow the act to happen if either:
+				 * - Neither character is performing a sex act
+				 * - Exactly one character is performing oral sex on the other
+				**/ 
+				((playerState.sexAct === null && slaveState.sexAct === null) || 
+				((slaveState.sexAct === SexAct.ORAL || playerState.sexAct === SexAct.ORAL) &&
+				(slaveState.sexAct !== SexAct.ORAL || playerState.sexAct !== SexAct.ORAL))),
 			effect: () => {
 				playerState.lust += 10;
 				slaveState.lust += 10;
 
-				playerState.action = Action.ORAL;
-				slaveState.action = Action.ORAL;
+				playerState.sexAct = SexAct.ORAL;
+				slaveState.sexAct = SexAct.ORAL;
 
-				recordSex(slaveState.action);
+				recordSex(slaveState.sexAct);
 			},
 			reaction: this.reactionText.sixtyNine(clone),
 		},
@@ -643,7 +689,10 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Have ${him} dance for you`,
 			desc: generalText.dance(clone),
 			tooltip: `Make ${him} give you a sensual dance.`,
-			prereq: () => !slaveState.isKneeling && !slaveState.isLaying,
+			prereq: () => !slaveState.isKneeling &&
+				!slaveState.isLaying &&
+				slaveState.sexAct === null &&
+				slaveState.action !== Action.KISSING,
 			effect: () => {
 				playerState.lust += 4;
 				slaveState.lust += 3;
@@ -657,7 +706,9 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			prereq: () =>
 				!slaveState.isKneeling &&
 				!slaveState.isLaying &&
-				clothes !== "no clothing",
+				clothes !== "no clothing" &&
+				slaveState.sexAct === null &&
+				slaveState.action !== Action.KISSING,
 			effect: () => {
 				clone.clothes = "no clothing";
 				slaveState.clothing.top.isOff = true;
@@ -675,7 +726,8 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Push ${him} down`,
 			desc: generalText.pushDown(clone),
 			tooltip: `Put ${him} on ${his} knees.`,
-			prereq: () => !slaveState.isKneeling,
+			prereq: () => !slaveState.isKneeling &&
+				slaveState.sexAct === null,
 			effect: () => {
 				slaveState.position = Position.KNEELING;
 			},
@@ -685,17 +737,30 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Pull ${him} up`,
 			desc: generalText.pullUp(clone),
 			tooltip: `Have ${him} stand up.`,
-			prereq: () => slaveState.isKneeling,
+			prereq: () => slaveState.isKneeling &&
+				slaveState.sexAct === null,
 			effect: () => {
 				slaveState.position = Position.STANDING;
 			},
 			reaction: this.reactionText.pullUp(clone),
 		},
+		{
+			link: `Stand up`,
+			desc: generalText.standUp(clone),
+			tooltip: `Get back on your feet.`,
+			prereq: () => playerState.isKneeling &&
+				playerState.sexAct === null,
+			effect: () => {
+				playerState.position = Position.STANDING;
+			},
+			reaction: this.reactionText.standUp(clone),
+		},
 		{
 			link: `Pull ${him} in close`,
 			desc: generalText.pullClose(clone),
 			tooltip: `Pull ${his} body in close to yours.`,
-			prereq: () => !slaveState.close,
+			prereq: () => !slaveState.close &&
+				slaveState.sexAct === null,
 			effect: () => {
 				slaveState.close = true;
 			},
@@ -705,7 +770,8 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Push ${him} away`,
 			desc: generalText.pushAway(clone),
 			tooltip: `Put some distance between you two.`,
-			prereq: () => slaveState.close,
+			prereq: () => slaveState.close &&
+				slaveState.sexAct === null,
 			effect: () => {
 				slaveState.close = false;
 			},
@@ -715,7 +781,9 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Put ${him} on your lap`,
 			desc: generalText.putOnLap(clone),
 			tooltip: `Ask ${him} if ${he}'s been naughty or nice.`,
-			prereq: () => !slaveState.onLap && !playerState.onLap,
+			prereq: () => !slaveState.onLap &&
+				!playerState.onLap &&
+				slaveState.sexAct === null,
 			effect: () => {
 				slaveState.onLap = true;
 			},
@@ -725,7 +793,8 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Get ${him} off your lap`,
 			desc: generalText.getOffLap(clone),
 			tooltip: `That's enough of that.`,
-			prereq: () => slaveState.onLap,
+			prereq: () => slaveState.onLap &&
+				slaveState.sexAct === null,
 			effect: () => {
 				slaveState.onLap = false;
 			},
@@ -735,7 +804,9 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Take ${him} to bed`,
 			desc: generalText.goToBed(clone),
 			tooltip: `Take ${him} somewhere a bit more comfortable.`,
-			prereq: () => !playerState.isLaying && !slaveState.isLaying,
+			prereq: () => !playerState.isLaying &&
+				!slaveState.isLaying &&
+				slaveState.sexAct === null,
 			effect: () => {
 				playerState.position = Position.LAYING;
 				slaveState.position = Position.LAYING;
@@ -746,7 +817,9 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Get out of bed`,
 			desc: generalText.getOutOfBed(clone),
 			tooltip: `In case you need a little more maneuverability.`,
-			prereq: () => playerState.isLaying && slaveState.isLaying,
+			prereq: () => playerState.isLaying &&
+				slaveState.isLaying &&
+				slaveState.sexAct === null,
 			effect: () => {
 				playerState.position = Position.STANDING;
 				slaveState.position = Position.STANDING;
@@ -757,7 +830,8 @@ App.UI.SlaveInteract.useSlave.options = function(player, clone, slave, playerSta
 			link: `Bring in another slave`,
 			desc: generalText.bringInSlave(clone),
 			tooltip: `Have another slave join the two of you.`,
-			prereq: () => V.slaves.length > 1,
+			prereq: () => V.slaves.length > 1 &&
+				slaveState.sexAct === null,
 			effect: () => {
 				return;	// temporarily disabled
 			},
diff --git a/src/interaction/useSlave/useSlaveText.js b/src/interaction/useSlave/useSlaveText.js
index 40354b9fab98fee38ddb955f651fa51dbcf81065..2de5c25d2009bd0f66f3edfb4c78d872a7f07632 100644
--- a/src/interaction/useSlave/useSlaveText.js
+++ b/src/interaction/useSlave/useSlaveText.js
@@ -14,6 +14,20 @@ App.UI.SlaveInteract.useSlave.contextualText = {
 		}
 	},
 	/** @param {FC.SlaveState} slave */
+	stopKissing(slave) {
+		const {his} = getPronouns(slave);
+
+		if (slave.devotion > 50) {
+			return `You pull your lips away. A quiet moan of longing escapes ${his} slightly agape mouth.`;
+		} else if (slave.devotion > 20) {
+			return `Stop kissing test 2`;
+		} else if (slave.devotion > -20) {
+			return `Stop kissing test 3`;
+		} else {
+			return `Stop kissing test 4`;
+		}
+	},
+	/** @param {FC.SlaveState} slave */
 	keepFucking(slave) {
 		const {him, his} = getPronouns(slave);
 
@@ -158,7 +172,7 @@ App.UI.SlaveInteract.useSlave.contextualText = {
 		const {He, he, him, his} = getPronouns(slave);
 
 		if (slave.devotion > 50) {
-			return `You decide to reward ${slave.slaveName} with an orgasm. ${slave.dick > 0 ? `You stroke ${his} cock with your hand, feeling ${him} get ever harder. ${He} is very aroused, so it doesn't take long before ${he} goes over the edge, shooting cum all over the floor and getting a bit on your hand. Satisfied, ${he}'s ready and eager to please you.` : `You rub ${his} pussy with your fingers for a bit before moving your mouth down to lick ${him}. You flick your mouth over ${his} soft petals${slave.clit >= 0 ? ` and ${his} clit,` : `,`} rapidly bringing ${him} to orgasm. ${He} gasps as ${his} body convulses with pleasure and ${his} pussy lets out a small bit of ejaculate. ${He}'s satisfied and eager to please you.`}`;
+			return `You decide to reward ${slave.slaveName} with an orgasm. ${slave.dick > 0 ? `You stroke ${his} cock with your hand, feeling ${him} get ever harder. ${He} is very aroused, so it doesn't take long before ${he} goes over the edge, shooting cum all over the floor and getting a bit on your hand. Satisfied, ${he}'s ready and eager to please you.` : `You rub ${his} pussy, flicking your fingers over ${his} soft petals${slave.clit >= 0 ? ` and ${his} clit,` : `,`} rapidly bringing ${him} to orgasm. ${He} gasps as ${his} body convulses with pleasure and ${his} pussy lets out a small bit of ejaculate. ${He}'s satisfied and eager to please you.`}`;
 		} else if (slave.devotion > 20) {
 			return `Make slave cum 2`;
 		} else if (slave.devotion > -20) {
@@ -521,6 +535,19 @@ App.UI.SlaveInteract.useSlave.generalText = {
 		}
 	},
 
+	/** @param {FC.SlaveState} slave */
+	standUp(slave) {
+		if (slave.devotion > 50) {
+			return `You stand back up.`;
+		} else if (slave.devotion > 20) {
+			return `You stand back up.`;
+		} else if (slave.devotion > -20) {
+			return `You stand back up.`;
+		} else {
+			return `You stand back up.`;
+		}
+	},
+
 	/** @param {FC.SlaveState} slave */
 	pushAway(slave) {
 		const {He, him} = getPronouns(slave);
@@ -930,6 +957,20 @@ App.UI.SlaveInteract.useSlave.reactionText = {
 		}
 	},
 	/** @param {FC.SlaveState} slave */
+	stopKissing(slave) {
+		// const {him, his} = getPronouns(slave);
+
+		if (slave.devotion > 50) {
+			return Spoken(slave, `"I love your lips, ${getEnunciation(slave).title}..."`);
+		} else if (slave.devotion > 20) {
+			return `stopKissing reaction test 2`;
+		} else if (slave.devotion > -20) {
+			return `stopKissing reaction test 3`;
+		} else {
+			return `stopKissing reaction test 4`;
+		}
+	},
+	/** @param {FC.SlaveState} slave */
 	keepFucking(slave) {
 		// const {him, his} = getPronouns(slave);
 
@@ -1406,6 +1447,20 @@ App.UI.SlaveInteract.useSlave.reactionText = {
 		}
 	},
 	/** @param {FC.SlaveState} slave */
+	standUp(slave) {
+		// const {him, his} = getPronouns(slave);
+
+		if (slave.devotion > 50) {
+			return Spoken(slave, `"Oh, what would you like to do now, ${getEnunciation(slave).title}?"`);
+		} else if (slave.devotion > 20) {
+			return `standUp reaction test 2`;
+		} else if (slave.devotion > -20) {
+			return `standUp reaction test 3`;
+		} else {
+			return `standUp reaction test 4`;
+		}
+	},
+	/** @param {FC.SlaveState} slave */
 	pullClose(slave) {
 		// const {him, his} = getPronouns(slave);
 
diff --git a/src/js/CustomSlave.js b/src/js/CustomSlave.js
index 8c88013928a04f9d111f491c437531a2b8ddba67..b519a0589ef15aa964731fa0b8ca245c9a83d490 100644
--- a/src/js/CustomSlave.js
+++ b/src/js/CustomSlave.js
@@ -156,14 +156,14 @@ App.Entity.CustomSlaveOrder = class CustomSlaveOrder {
 		this.nationality = "Stateless";
 
 		/** desired left and right leg state
-		 * @type {{left: App.Entity.LimbState, right: App.Entity.LimbState}}
+		 * @type {{left: App.Entity.LegState, right: App.Entity.LegState}}
 		 */
-		this.leg = {left: new App.Entity.LimbState(), right: new App.Entity.LimbState()};
+		this.leg = {left: new App.Entity.LegState(), right: new App.Entity.LegState()};
 
 		/** desired left and right arm state
-		 * @type {{left: App.Entity.LimbState, right: App.Entity.LimbState}}
+		 * @type {{left: App.Entity.ArmState, right: App.Entity.ArmState}}
 		 */
-		this.arm = {left: new App.Entity.LimbState(), right: new App.Entity.LimbState()};
+		this.arm = {left: new App.Entity.ArmState(), right: new App.Entity.ArmState()};
 
 		/** desired eye state
 		 * Only the "vision" property is used, all others are ignored
diff --git a/src/js/DefaultRules.js b/src/js/DefaultRules.js
index bcf2e42558140a61ad5a88373fbf2231497c29fa..92f422a9a0f3d135a5e5ba67d946e034d70d5f80 100644
--- a/src/js/DefaultRules.js
+++ b/src/js/DefaultRules.js
@@ -1193,30 +1193,11 @@ globalThis.DefaultRules = (function() {
 			return;
 		}
 
-		/** @typedef {"lips" | "boobs" | "butt" | "dick" | "balls"} DrugTarget */
 		// Asset Growth
 		const growthDrugs = new Set(["breast injections", "breast redistributors", "butt injections", "butt redistributors", "hyper breast injections", "hyper butt injections", "hyper penis enhancement", "hyper testicle enhancement", "intensive breast injections", "intensive butt injections", "intensive penis enhancement", "intensive testicle enhancement", "lip atrophiers", "lip injections", "penis atrophiers", "penis enhancement", "testicle atrophiers", "testicle enhancement"]);
 
-		// WARNING: property names in fleshFunc, growDrugs, and shrinkDrugs must be identical and this fact is used by the drugs() below
-		/** @type {Record<DrugTarget, (s: App.Entity.SlaveState) => number>} */
-		const fleshFunc = {
-			lips: s => s.lips - s.lipsImplant,
-			boobs: s => s.boobs - s.boobsImplant - s.boobsMilk,
-			butt: s => s.butt - s.buttImplant,
-			dick: s => s.dick,
-			balls: s => s.balls,
-		};
-
-		/** @type {Record<DrugTarget, number>} */
-		const maxAssetSize = {
-			lips: V.seeExtreme ? 95 : 85,
-			boobs: 48000,
-			butt: 20,
-			dick: 31,
-			balls: 125
-		};
-
-		/** @type {Record<DrugTarget, FC.Drug>} */
+		// WARNING: property names in growDrugs, and shrinkDrugs must be identical and this fact is used by the drugs() below
+		/** @type {Record<FC.SizableBodyPart, FC.Drug>} */
 		const growDrugs = {
 			lips: "lip injections",
 			boobs: "breast injections",
@@ -1252,7 +1233,7 @@ globalThis.DefaultRules = (function() {
 			}
 		}
 
-		/** @type {Record<DrugTarget, FC.Drug>} */
+		/** @type {Record<FC.SizableBodyPart, FC.Drug>} */
 		const shrinkDrugs = {
 			lips: null,
 			boobs: null,
@@ -1277,8 +1258,8 @@ globalThis.DefaultRules = (function() {
 
 		/**
 		 * @param {App.Entity.SlaveState} slave
-		 * @param {DrugTarget} asset
-		 * @param {FC.RA.NumericTarget | FC.RA.ExpressiveNumericTarget} target
+		 * @param {FC.SizableBodyPart} asset
+		 * @param {FC.RA.ExpressiveNumericTarget} target
 		 * @param {{drug: FC.Drug, weight: number}[]} priorities
 		 * @param {number} step
 		 */
@@ -1287,16 +1268,28 @@ globalThis.DefaultRules = (function() {
 				return;
 			}
 
-			if (V.experimental.raGrowthExpr === 1 && typeof target.val === 'string') {
+			if (typeof target.val === 'string') {
 				const interpreter = new Function("slave", "return (" + target.val + ");");
-				target.val = runWithReadonlyProxy(() => interpreter(createReadonlyProxy(slave)));
+				const newVal = runWithReadonlyProxy(() => interpreter(createReadonlyProxy(slave)));
 				if (V.debugMode) {
-					console.log(asset + " expression for '" + slave.slaveName + "' resolves to " + target.val.toString());
+					console.log(asset + " expression for '" + slave.slaveName + "' resolves to " + newVal.toString());
 				}
+				return drugsImpl(slave, asset, {cond: target.cond, val: newVal}, priorities, step);
 			}
 
-			const flesh = fleshFunc[asset](slave);
-			if (growDrugs[asset] !== null && App.RA.shallGrow(flesh, target, step) && maxAssetSize[asset] > slave[asset]) {
+			return drugsImpl(slave, asset, {cond: target.cond, val: target.val}, priorities, step);
+		}
+
+		/**
+		 * @param {App.Entity.SlaveState} slave
+		 * @param {FC.SizableBodyPart} asset
+		 * @param {FC.RA.NumericTarget} target
+		 * @param {{drug: FC.Drug, weight: number}[]} priorities
+		 * @param {number} step
+		 */
+		 function drugsImpl(slave, asset, target, priorities, step) {
+			const flesh = App.Medicine.fleshSize(slave, asset);
+			if (growDrugs[asset] !== null && App.RA.shallGrow(flesh, target, step) && App.Medicine.maxAssetSize(asset) > slave[asset]) {
 				priorities.push({
 					drug: growDrugs[asset],
 					weight: 1.0 - (flesh / target.val)
@@ -1810,6 +1803,21 @@ globalThis.DefaultRules = (function() {
 		}
 	}
 
+	/**
+	 * @param {FC.SlaveState} slave
+	 * @param {number} hormones
+	 * @param {string} slaveClass
+	 */
+	const applyHormones = (slave, hormones, slaveClass) => {
+		if (!_.isNil(hormones)) {
+			const newHormones = slave.indentureRestrictions >= 2 ? Math.clamp(hormones, -1, 1) : hormones;
+			if (slave.hormones !== newHormones) {
+				slave.hormones = newHormones;
+				r += `<br>${slave.slaveName} is ${slaveClass}, so ${he} has been put on the appropriate hormonal regime.`;
+			}
+		}
+	};
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 * @param {FC.RA.RuleSetters} rule
@@ -1817,31 +1825,9 @@ globalThis.DefaultRules = (function() {
 	function ProcessPenisHormones(slave, rule) {
 		if (slave.dick > 0) {
 			if (slave.balls === 0) {
-				if ((rule.gelding !== undefined) && (rule.gelding !== null)) {
-					if (slave.hormones !== rule.gelding) {
-						const oldHormones = slave.hormones;
-						slave.hormones = rule.gelding;
-						if (slave.indentureRestrictions >= 2) {
-							slave.hormones = Math.clamp(slave.hormones, -1, 1);
-						}
-						if (slave.hormones !== oldHormones) {
-							r += `<br>${slave.slaveName} is a gelding, so ${he} has been put on the appropriate hormonal regime.`;
-						}
-					}
-				}
+				applyHormones(slave, rule.gelding, "a gelding");
 			} else if (slave.balls > 0) {
-				if ((rule.XY !== undefined) && (rule.XY !== null)) {
-					if (slave.hormones !== rule.XY) {
-						const oldHormones = slave.hormones;
-						slave.hormones = rule.XY;
-						if (slave.indentureRestrictions >= 2) {
-							slave.hormones = Math.clamp(slave.hormones, -1, 1);
-						}
-						if (slave.hormones !== oldHormones) {
-							r += `<br>${slave.slaveName} is a shemale, so ${he} has been put on the appropriate hormonal regime.`;
-						}
-					}
-				}
+				applyHormones(slave, rule.XY, "a shemale");
 			}
 		}
 	}
@@ -1851,17 +1837,8 @@ globalThis.DefaultRules = (function() {
 	 * @param {FC.RA.RuleSetters} rule
 	 */
 	function ProcessFemaleHormones(slave, rule) {
-		if ((slave.vagina > -1) && (slave.dick === 0) && (rule.XX !== undefined) && (rule.XX !== null)) {
-			if (slave.hormones !== rule.XX) {
-				const oldHormones = slave.hormones;
-				slave.hormones = rule.XX;
-				if (slave.indentureRestrictions >= 2) {
-					slave.hormones = Math.clamp(slave.hormones, -1, 1);
-				}
-				if (slave.hormones !== oldHormones) {
-					r += `<br>${slave.slaveName} is a female, so ${he} has been put on the appropriate hormonal regime.`;
-				}
-			}
+		if ((slave.vagina > -1) && (slave.dick === 0)) {
+			applyHormones(slave, rule.XX, "a female");
 		}
 	}
 
@@ -2224,50 +2201,84 @@ globalThis.DefaultRules = (function() {
 	 * @param {App.Entity.SlaveState} slave
 	 * @param {FC.RA.RuleSetters} rule
 	 */
-	function ProcessStyle(slave, rule) {
+	function processEyeColor(slave, rule) {
+		// calculate our goals
+		// iris
+		let leftIris = getLeftEyeColor(slave);
+		let rightIris = getRightEyeColor(slave);
+		if (rule.iris === "natural") {
+			leftIris = getGeneticEyeColor(slave, "left", "iris");
+			rightIris = getGeneticEyeColor(slave, "right", "iris");
+		} else if (rule.iris) {
+			leftIris = rule.iris;
+			rightIris = rule.iris;
+		}
+
+		// pupil
+		let leftPupil = getLeftEyePupil(slave);
+		let rightPupil = getRightEyePupil(slave);
+		if (rule.pupil === "natural") {
+			leftPupil = getGeneticEyeColor(slave, "left", "pupil");
+			rightPupil = getGeneticEyeColor(slave, "right", "pupil");
+		} else if (rule.pupil) {
+			leftPupil = rule.pupil;
+			rightPupil = rule.pupil;
+		}
+
+		// sclera
+		let leftSclera = getLeftEyeSclera(slave);
+		let rightSclera = getRightEyeSclera(slave);
+		if (rule.sclera === "natural") {
+			leftSclera = getGeneticEyeColor(slave, "left", "sclera");
+			rightSclera = getGeneticEyeColor(slave, "right", "sclera");
+		} else if (rule.sclera) {
+			leftSclera = rule.sclera;
+			rightSclera = rule.sclera;
+		}
+
 		if (
-			(rule.iris !== undefined && rule.iris !== null) ||
-			(rule.pupil !== undefined && rule.pupil !== null) ||
-			(rule.sclera !== undefined && rule.sclera !== null)
-		) {
-			if (
-				getLeftEyeColor(slave) !== rule.iris || getRightEyeColor(slave) !== rule.iris ||
-				getLeftEyePupil(slave) !== rule.pupil || getRightEyePupil(slave) !== rule.pupil ||
-				getLeftEyeSclera(slave) !== rule.sclera || getRightEyeSclera(slave) !== rule.sclera
-			) {
-				let iris = rule.iris || getLeftEyeColor(slave);
-				let pupil = rule.pupil || getLeftEyePupil(slave);
-				let sclera = rule.sclera || getLeftEyeSclera(slave);
-				setEyeColorFull(slave, iris, pupil, sclera, "left");
-
-				iris = rule.iris || getRightEyeColor(slave);
-				pupil = rule.pupil || getRightEyePupil(slave);
-				sclera = rule.sclera || getRightEyeSclera(slave);
-				setEyeColorFull(slave, iris, pupil, sclera, "right");
+			getLeftEyeColor(slave) !== leftIris || getRightEyeColor(slave) !== rightIris ||
+			getLeftEyePupil(slave) !== leftPupil || getRightEyePupil(slave) !== rightPupil ||
+			getLeftEyeSclera(slave) !== leftSclera || getRightEyeSclera(slave) !== rightSclera
 
-				cashX(forceNeg(V.modCost), "slaveMod", slave);
-				const lensDesc = [];
-				if (rule.iris) {
-					if (hasBothEyes(slave)) {
-						lensDesc.push(`${rule.iris} irises`);
-					} else {
-						lensDesc.push(`a ${rule.iris} iris`);
-					}
+		) {
+			setEyeColorFull(slave, leftIris, leftPupil, leftSclera, "left");
+			setEyeColorFull(slave, rightIris, rightPupil, rightSclera, "right");
+
+			cashX(forceNeg(V.modCost), "slaveMod", slave);
+			const lensDesc = [];
+			if (rule.iris) {
+				if (hasBothEyes(slave)) {
+					lensDesc.push(`${leftIris === rightIris ? leftIris : (rightIris + " " + leftIris)} irises`);
+				} else {
+					lensDesc.push(`a ${hasLeftEye(slave) ? leftIris : rightIris} iris`);
 				}
-				if (rule.pupil) {
-					if (hasBothEyes(slave)) {
-						lensDesc.push(`${rule.pupil} pupils`);
-					} else {
-						lensDesc.push(`a ${rule.pupil} pupil`);
-					}
+			}
+			if (rule.pupil) {
+				if (hasBothEyes(slave)) {
+					lensDesc.push(`${leftPupil === rightPupil ? leftPupil : (rightPupil + " " + leftPupil)} pupils`);
+				} else {
+					lensDesc.push(`a ${hasLeftEye(slave) ? leftPupil : rightPupil} pupil`);
 				}
-				if (rule.sclera) {
-					lensDesc.push(`${rule.sclera} sclera`);
+			}
+			if (rule.sclera) {
+				if (hasBothEyes(slave)) {
+					lensDesc.push(`${leftSclera === rightSclera ? leftSclera : (rightSclera + " " + leftSclera)} sclera`);
+				} else {
+					lensDesc.push(`a ${hasLeftEye(slave) ? leftSclera : rightSclera} sclera`);
 				}
-				const lens = lensDesc.slice(0, lensDesc.length - 1).join(', ') + ", and " + lensDesc.slice(-1);
-				r += `<br>${slave.slaveName} has been given ${hasBothEyes(slave) ? `contact lenses` : `a contact lens`} with ${lens}.`;
 			}
+			const lens = toSentence(lensDesc);
+			r += `<br>${slave.slaveName} has been given ${hasBothEyes(slave) ? `contact lenses` : `a contact lens`} with ${lens}.`;
 		}
+	}
+
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {FC.RA.RuleSetters} rule
+	 */
+	function ProcessStyle(slave, rule) {
+		processEyeColor(slave, rule);
 
 		if (rule.makeup !== undefined && (rule.makeup !== null)) {
 			if (slave.makeup !== rule.makeup) {
@@ -2913,6 +2924,7 @@ globalThis.DefaultRules = (function() {
 		}
 		if (rule.autoBrand === 1 && rule.brandDesign !== null) {
 			if (slave.health.condition > -20) {
+				const brands = App.Medicine.Modification.brandRecord(slave);
 				let brandPlace = "";
 				let left;
 				let right;
@@ -2956,11 +2968,11 @@ globalThis.DefaultRules = (function() {
 						left = "left breast";
 						right = "right breast";
 					}
-					if (rule.brandDesign !== slave.brand[left] && rule.brandDesign !== slave.brand[right]) {
+					if (rule.brandDesign !== brands[left] && rule.brandDesign !== brands[right]) {
 						brandPlace = "both";
-					} else if (rule.brandDesign !== slave.brand[left]) {
+					} else if (rule.brandDesign !== brands[left]) {
 						brandPlace = "left";
-					} else if (rule.brandDesign !== slave.brand[right]) {
+					} else if (rule.brandDesign !== brands[right]) {
 						brandPlace = "right";
 					}
 
@@ -3011,7 +3023,7 @@ globalThis.DefaultRules = (function() {
 					}
 
 					// Brand location does NOT need to be split into a left and right, (and may or may not contain left OR right already.)
-				} else if (slave.brand[rule.brandTarget] !== rule.brandDesign) {
+				} else if (brands[rule.brandTarget] !== rule.brandDesign) {
 					if (
 						(!hasLeftArm(slave) && ["left upper arm", "left lower arm", "left wrist", "left hand"].includes(rule.brandTarget)) ||
 						(!hasRightArm(slave) && ["right upper arm", "right lower arm", "right wrist", "right hand"].includes(rule.brandTarget)) ||
@@ -3031,13 +3043,13 @@ globalThis.DefaultRules = (function() {
 					healthDamage(slave, 10);
 					r += `<br>${slave.slaveName} has been branded on the `;
 					if (brandPlace === "left") {
-						slave.brand[left] = rule.brandDesign;
+						App.Medicine.Modification.addBrand(slave, left, rule.brandDesign);
 						r += `${left}`;
 					} else if (brandPlace === "right") {
-						slave.brand[right] = rule.brandDesign;
+						App.Medicine.Modification.addBrand(slave, right, rule.brandDesign);
 						r += `${right}`;
 					} else if (brandPlace === "anywhere") {
-						slave.brand[rule.brandTarget] = rule.brandDesign;
+						App.Medicine.Modification.addBrand(slave, rule.brandTarget, rule.brandDesign);
 						r += `${rule.brandTarget}`;
 					}
 					r += `, with <span class="trust dec">fear</span>${slave.devotion < 18 ? `, <span class="devotion dec">regard,</span>` : ``} and <span class="health dec">health</span> consequences.`;
@@ -3046,8 +3058,8 @@ globalThis.DefaultRules = (function() {
 					}
 					slave.trust -= 5;
 				} else if (brandPlace === "both") {
-					slave.brand[left] = rule.brandDesign;
-					slave.brand[right] = rule.brandDesign;
+					App.Medicine.Modification.addBrand(slave, left, rule.brandDesign);
+					App.Medicine.Modification.addBrand(slave, right, rule.brandDesign);
 					healthDamage(slave, 20);
 					r += `<br>${slave.slaveName} has been branded on both ${rule.brandTarget}, with <span class="trust dec">fear</span>${slave.devotion < 18 ? `, <span class="devotion dec">regard,</span>` : ``} and <span class="health dec">health</span> consequences.`;
 					if (slave.devotion < 18) {
@@ -3146,33 +3158,6 @@ globalThis.DefaultRules = (function() {
 	return DefaultRules;
 })();
 
-globalThis.RuleHasError = function() {
-	const rxCheckEqual = /[^!=<>]=[^=<>]/gi;
-	const compileCheck = function(code) {
-		try {
-			// TODO: This should use a cached Function, which should be the same as below.
-			new Function(`return ${code}`);
-		} catch (e) {
-			return false;
-		}
-		return true;
-	};
-
-	/**
-	 * @param {FC.RA.Rule} rule
-	 * @returns {boolean}
-	 */
-	function check(rule) {
-		return rule.condition.function === "custom" &&
-			(rule.condition.data.match(rxCheckEqual) ||
-				!compileCheck(rule.condition.data));
-	}
-
-	return check;
-}();
-
-globalThis.DefaultRulesError = () => V.defaultRules.some(r => RuleHasError(r));
-
 /**
  * @param {App.Entity.SlaveState} slave
  */
diff --git a/src/js/Purchase.js b/src/js/Purchase.js
deleted file mode 100644
index a13f10cff8dc26180ba32b0e07d90aa24640e9b2..0000000000000000000000000000000000000000
--- a/src/js/Purchase.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/** Creates a user-facing "purchase" button. */
-globalThis.Purchase = class Purchase {
-	/**
-	 * Creates a new button allowing the user to purchase something.
-	 * @param {string} text The text to display.
-	 * @param {number} cost The amount of ¤ the purchase costs.
-	 * @param {keyof App.Data.Records.LastWeeksCash} what What the purchase is for.
-	 * @param {Object} [args] Any additional arguments to pass.
-	 * @param {string} [args.note] Any additional information to display.
-	 * @param {function():void} [args.handler] Any custom handler to run upon purchase.
-	 */
-	constructor(text, cost, what, {note, handler} = {}) {
-		/** @type {string} */
-		this.link = text;
-		/** @type {number} */
-		this.cost = cost;
-		/** @type {keyof App.Data.Records.LastWeeksCash} */
-		this.what = what;
-		/** @type {string} */
-		this.note = note;
-		/** @type {function():void} */
-		this.handler = handler;
-	}
-
-	render() {
-		const div = App.UI.DOM.makeElement("div", null, ['indent']);
-
-		if (V.purchaseStyle === 'button') {
-			div.append(this.renderButton());
-		} else {
-			div.append(this.renderLink());
-		}
-
-		return div;
-	}
-
-	executeHandler() {
-		cashX(forceNeg(this.cost), this.what);
-
-		if (this.handler) {
-			this.handler();
-		}
-	}
-
-	/**
-	 * Renders a button.
-	 *
-	 * @private
-	 */
-	renderButton() {
-		const text = App.UI.DOM.makeElement("span", this.link, ['note']);
-		const price = this.cost !== 0 ? `${cashFormat(Math.trunc(this.cost))}` : `free`;
-		const button = App.UI.DOM.makeElement("button", capFirstChar(price), ['purchase-button']);
-
-		if (V.cash > this.cost) {
-			button.onclick = () => this.executeHandler();
-
-			if (this.note) {
-				const note = this.note.substring(0, 5) === ' and ' ? this.note.replace(' and ', '') : this.note;
-				tippy(button, {
-					content: capFirstChar(note),
-				});
-			}
-		} else {
-			button.classList.add("disabled");
-
-			tippy(button, {
-				content: `You cannot afford this purchase`,
-			});
-		}
-
-		text.append(button);
-
-		return text;
-	}
-
-	/**
-	 * Renders a link.
-	 *
-	 * @private
-	 */
-	renderLink() {
-		const span = document.createElement("span");
-		const price = this.cost !== 0 ? `${cashFormat(Math.trunc(this.cost))}` : `free`;
-		const cost = `${this.cost !== 0 ? `Costs ${price}` : capFirstChar(price)}${this.note || ''}`;
-		const link = App.UI.DOM.link(`${this.link} `, () => this.executeHandler(), [], '');
-		const disabledLink = App.UI.DOM.disabledLink(`${this.link} `, ['You cannot afford this purchase']);
-
-		if (V.cash > this.cost) {
-			span.append(link);
-		} else {
-			span.append(disabledLink);
-		}
-
-		App.UI.DOM.appendNewElement("span", span, cost, ['note']);
-
-		return span;
-	}
-};
diff --git a/src/js/SlaveState.js b/src/js/SlaveState.js
index 13da8b7c798eac59bc7fd106d1c0962cc2098661..4e4ffec6e55ee507181b21a2e4ece06464513ef2 100644
--- a/src/js/SlaveState.js
+++ b/src/js/SlaveState.js
@@ -289,15 +289,30 @@ App.Entity.SlaveActionsCountersState = class {
 		this.miscarriages = 0;
 		/** number of labors slave has undergone */
 		this.laborCount = 0;
-		/** oral sex count */
+		/** The number of times the actor has had oral sex.
+		 *
+		 * Use only for logic checks. To increment, use `seX()`.
+		 */
 		this.oral = 0;
-		/** vaginal sex count */
+		/** The number of times the actor has had vaginal sex.
+		 *
+		 * Use only for logic checks. To increment, use `seX()`.
+		 */
 		this.vaginal = 0;
-		/** anal sex count */
+		/** The number of times the actor has had anal sex.
+		 *
+		 * Use only for logic checks. To increment, use `seX()`.
+		 */
 		this.anal = 0;
-		/** breast sex count */
+		/** The number of times the actor has given a titjob.
+		 *
+		 * Use only for logic checks. To increment, use `seX()`.
+		 */
 		this.mammary = 0;
-		/** penetrative sex count */
+		/** The number of times the actor has penetrated an orifice.
+		 *
+		 * Use only for logic checks. To increment, use `seX()`.
+		 */
 		this.penetrative = 0;
 		/** number of times used by the general public */
 		this.publicUse = 0;
@@ -352,7 +367,7 @@ App.Entity.SlaveCustomAddonsState = class SlaveCustomAddonsState {
 	}
 };
 
-App.Entity.scarState = class {
+App.Entity.ScarState = class {
 	constructor() {
 		/**
 		 * generic scar
@@ -388,7 +403,6 @@ App.Entity.scarState = class {
 		 * chain/manacles scar, focused on wrists ankles or neck
 		 * * 0: no scar
 		 * * 1+: increasing intensity of scar
-		 * 1+: increasing intensity of scar
 		 */
 		this.chain = 0;
 		/**
@@ -429,7 +443,6 @@ App.Entity.genitalPiercingState = class extends App.Entity.piercingState {
 	}
 };
 
-
 App.Entity.piercingStateRA = class {
 	constructor() {
 		/** @type {FC.PiercingType} */
@@ -450,7 +463,6 @@ App.Entity.genitalPiercingStateRA = class extends App.Entity.piercingStateRA {
 	}
 };
 
-
 App.Entity.completePiercingState = class {
 	constructor() {
 		this.ear = new App.Entity.piercingState();
@@ -502,6 +514,35 @@ App.Entity.LimbState = class LimbState {
 		 * * 6: cybernetic
 		 */
 		this.type = 1;
+		/**
+		 * Partial ScarState:
+		 * The body part in question, such as back or left hand.
+		 * The key of that part is the type of scar they can have and the value is how serious it is, from 0 up.
+		 * @type {Object.<string, Partial<App.Entity.ScarState>>} */
+		this.scar = {};
+		/**
+		 * Key: body part
+		 * Value: Brand description
+		 * @type {Object.<string, string>} */
+		this.brand = {};
+	}
+};
+
+/**
+ * To ensure that all new arms contain expected attributes
+ */
+App.Entity.ArmState = class extends App.Entity.LimbState {
+	constructor() {
+		super();
+	}
+};
+
+/**
+ * To ensure that all new legs contain expected attributes
+ */
+App.Entity.LegState = class extends App.Entity.LimbState {
+	constructor() {
+		super();
 	}
 };
 
@@ -569,11 +610,11 @@ App.Entity.SlaveState = class SlaveState {
 		 * _0: Obtained prior to game start / at game start_ */
 		this.weekAcquired = 0;
 		/** slave's origin
-		 * @type {FC.Zeroable<string>} */
-		this.origin = 0;
+		 * @type {string} */
+		this.origin = "";
 		/** career prior to enslavement
-		 * @type {FC.Zeroable<string>} */
-		this.career = 0;
+		 * @type {string} */
+		this.career = "a slave";
 		/** slave's ID */
 		this.ID = 0;
 		/** slave's prestige */
@@ -941,19 +982,19 @@ App.Entity.SlaveState = class SlaveState {
 		 * * 3: quadruped interface
 		 */
 		this.PLimb = 0;
-		/*
+		/**
 		 * legs of the slave
 		 */
 		this.leg = {
-			left: new App.Entity.LimbState(),
-			right: new App.Entity.LimbState()
+			left: new App.Entity.LegState(),
+			right: new App.Entity.LegState()
 		};
 		/**
 		 * arms of the slave
 		 */
 		this.arm = {
-			left: new App.Entity.LimbState(),
-			right: new App.Entity.LimbState()
+			left: new App.Entity.ArmState(),
+			right: new App.Entity.ArmState()
 		};
 		/** are heels clipped
 		 * @type {FC.Bool}
@@ -1052,7 +1093,7 @@ App.Entity.SlaveState = class SlaveState {
 		 * * "fillable"
 		 * * "advanced fillable"
 		 * * "hyper fillable"
-		 * @type {FC.SizingImplantType}
+		 * @type {FC.InstalledSizingImplantType}
 		 */
 		this.boobsImplantType = "none";
 		/**
@@ -1173,7 +1214,7 @@ App.Entity.SlaveState = class SlaveState {
 		 * * "fillable"
 		 * * "advanced fillable"
 		 * * "hyper fillable"
-		 * @type {FC.SizingImplantType}
+		 * @type {FC.InstalledSizingImplantType}
 		 */
 		this.buttImplantType = "none";
 		/**
@@ -1607,9 +1648,7 @@ App.Entity.SlaveState = class SlaveState {
 		 * * 9: color-coordinated metallic
 		 */
 		this.nails = 0;
-		/**
-		 * brand
-		 * @type {Object.<string, string>} */
+		/** @type {Object.<string, string>} */
 		this.brand = {};
 		this.piercing = new App.Entity.completePiercingState();
 		/**
@@ -2476,7 +2515,7 @@ App.Entity.SlaveState = class SlaveState {
 		 * Sub-object:
 		 * the body part in question, such as back or left hand
 		 * the key of that part is the type of scar they can have and the value is how serious it is, from 0 up
-		 * @type {Object.<string, Partial<App.Entity.scarState>>} */
+		 * @type {Object.<string, Partial<App.Entity.ScarState>>} */
 		this.scar = {};
 		/**
 		 * In a eugenics society, this slave is a designated breeder.
@@ -2629,6 +2668,8 @@ App.Entity.SlaveState = class SlaveState {
 			 * 0: no; 1: yes */
 			immortality: 0
 		};
+		/** flavor of their milk*/
+		this.milkFlavor = "none";
 		/* eslint-disable camelcase*/
 		this.NCSyouthening = 0;
 		this.override_Race = 0;
diff --git a/src/js/SpacedTextAccumulator.js b/src/js/SpacedTextAccumulator.js
index 98dc3fdbef1630eebb4b2c028219034c55052d4a..c86bd406dea1d3fd3f4f8684722ad18d7a58bb37 100644
--- a/src/js/SpacedTextAccumulator.js
+++ b/src/js/SpacedTextAccumulator.js
@@ -1,8 +1,8 @@
+/** @template {HTMLElement|DocumentFragment} [ContainerT=DocumentFragment] */
 globalThis.SpacedTextAccumulator = class SpacedTextAccumulator {
-	/** @param {HTMLElement|DocumentFragment} [container] */
+	/** @param {ContainerT} [container] */
 	constructor(container) {
-		/** @type {HTMLElement|DocumentFragment} */
-		this._container = container || new DocumentFragment();
+		this._container = container || /** @type {ContainerT} */(new DocumentFragment());
 		/** @type {(string|HTMLElement|DocumentFragment)[]} */
 		this._accumulator = [];
 		this._checked = false;
diff --git a/src/js/assignJS.js b/src/js/assignJS.js
index ce31bda622f49f78872b99d9bcec9da72690296a..3404969012d42e6edea6ecf84af5b0566c2a6ec0 100644
--- a/src/js/assignJS.js
+++ b/src/js/assignJS.js
@@ -417,10 +417,10 @@ globalThis.assignJob = function(slave, job) {
 	V.JobIDMap[restingAssignment].delete(slave.ID);
 	V.JobIDMap[slave.assignment].add(slave.ID);
 
-	if (!assignmentVisible(slave) && V.personalAttention.task === PersonalAttention.TRAINING) {
+	if (!assignmentVisible(slave) && !App.Entity.facilities.masterSuite.isHosted(slave) && V.personalAttention.task === PersonalAttention.TRAINING) {
 		if (V.personalAttention.slaves.deleteWith(s => s.ID === slave.ID).length > 0) {
 			if (V.personalAttention.slaves.length === 0) {
-				App.personalAttention.reset();
+				App.PersonalAttention.reset();
 				r += `${slave.slaveName} no longer has your personal attention; you plan to focus on ${V.personalAttention.task}.`;
 			} else {
 				r += `${slave.slaveName} no longer has your personal attention.`;
@@ -622,7 +622,7 @@ globalThis.removeJob = function(slave, assignment, saveRecord = false) {
 					}
 				}
 				if (V.personalAttention.task === PersonalAttention.SUPPORTHG && V.HeadGirlID === 0) {
-					App.personalAttention.reset();
+					App.PersonalAttention.reset();
 					r += `You no longer have a slave assigned to be your Head Girl, so you turn your personal attention to focus on ${V.personalAttention.task}.`;
 				}
 				V.HGTimeInGrade = 0;
diff --git a/src/js/birth/birth.js b/src/js/birth/birth.js
index 755ab30a6e23240b5a214148489be606c5a7606c..2843267c2dd1ebbe454c10ba895d2ee5ae2c8178 100644
--- a/src/js/birth/birth.js
+++ b/src/js/birth/birth.js
@@ -106,6 +106,11 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 		if (cSection) {
 			App.Medicine.Modification.addScar(slave, "belly", "c-section");
 		}
+		if (cSection || slave.scar.hasOwnProperty("belly") && slave.scar.belly["c-section"] > 0) {
+			App.Events.addResponses(el, [
+				new App.Events.Result("Remove c-section scar(s).", scarring)
+			]);
+		}
 		slave.labor = 0;
 	}
 
@@ -232,8 +237,8 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 							}
 						} else { // made it to birthing area
 							r.push(`With childbirth approaching, ${slave.slaveName} is carried to ${his} prepared birthing area.`);
-						} // close amp birth
-					} // close always c-sec
+						}
+					}
 				} else {
 					if (V.dairyRestraintsSetting > 1 && slave.career === "a bioreactor") {
 						r.push(`As ${slave.slaveName}'s water breaks, a mechanical basket is extended under ${his} laboring`);
@@ -279,12 +284,12 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 							r.push(`${he} continues enjoying ${his} milking.`);
 						}
 					}
-				} // close cow birth
+				}
 			} else {
 				if (!hasAnyLegs(slave)) {
 					r.push(`With childbirth approaching, ${slave.slaveName} is carried to ${his} prepared birthing area.`);
 				}
-			} // close broodmother birth
+			}
 		} else if (slave.fuckdoll !== 0) {
 			if (V.universalRulesCSec === 1 || (slave.mpreg === 0 && slave.vagina < 0)) {
 				cSection = true;
@@ -302,7 +307,7 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 				r.push(`baby starts to crown. Once both it and yourself are finished, you send its offspring off and it to the autosurgery for cleaning.`);
 			}
 			r.push(`It barely comprehends what has happened, nor will it realize when another child is conceived in it.`);
-		} // close Fuckdoll birth
+		}
 
 		App.Events.addNode(el, r);
 		return el;
@@ -942,7 +947,7 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 					slave.preg = 0;
 				}
 				// I think, it's not logical to break her reproductive system out of repair, if she is only type 1 broodmother. In this case she have to birth only like 5-10 fully grown babies, others get progressively smaller. It's should be even smaller stress to body then for "normal" hyperpregnant with 15-20+ children - they have to birth them all at full size.
-				if (slave.vagina < 6) {
+				if (V.seeStretching === 1 && slave.vagina < 6) {
 					slave.vagina = 6;
 				}
 				healthDamage(slave, 30);
@@ -999,12 +1004,12 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 									r.push(deadlyBirthScene());
 								} else {
 									r.push(suddenBirthScene());
-								} // closes deadly birth
-							} // closes reg birth
+								}
+							}
 						} else { // made it to birthing area
 							r.push(ampBirth());
-						} // close amp birth
-					} // close always c-sec
+						}
+					}
 				} else {
 					if (V.dairyRestraintsSetting > 1 && slave.career === "a bioreactor") {
 						r.push(`Once the ${childrenAre} secure, the basket retracts allowing access to ${his}`);
@@ -1060,7 +1065,7 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 							r.push(`of ${his} ${children} being removed from the milking stall before returning ${his} focus to draining ${his} breasts.`);
 						}
 					}
-				} // close cow birth
+				}
 			} else {
 				if (!hasAnyLegs(slave)) {
 					r.push(ampBirth());
@@ -1069,7 +1074,7 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 				} else {
 					r.push(hyperBroodmotherBirth());
 				}
-			} // close broodmother birth
+			}
 		}
 		App.Events.addNode(el, r);
 		return el;
@@ -1242,7 +1247,7 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 				r.push(App.UI.DOM.makeElement("span", `stretched out ${his} anus.`, "lime"));
 				//no need for description now
 				*/
-				if (slave.anus < 3 || (V.dairyPregSetting > 1 && slave.anus < 4)) {
+				if (V.seeStretching === 1 && (slave.anus < 3 || (V.dairyPregSetting > 1 && slave.anus < 4))) {
 					slave.anus += 1;
 				}
 			} else {
@@ -1251,7 +1256,7 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 				r.push(App.UI.DOM.makeElement("span", `stretched out ${his} vagina.`, "lime"));
 				//no need for description now
 				*/
-				if (slave.vagina < 3 || (V.dairyPregSetting > 1 && slave.vagina < 4)) {
+				if (V.seeStretching === 1 && (slave.vagina < 3 || (V.dairyPregSetting > 1 && slave.vagina < 4))) {
 					slave.vagina += 1;
 				}
 			}
@@ -1791,6 +1796,9 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 			} else if (slave.sexualFlaw === "breeder") {
 				r.push(slave.slaveName);
 				r.push(App.UI.DOM.makeElement("span", ` almost orgasms`, "hotpink"));
+				if (slave.geneticQuirks.uterineHypersensitivity === 2) {
+					r.push(`again`);
+				}
 				r.push(`when ${he} imagines ${his} ${children} being raised into`);
 				if (numBeingBorn === 1) {
 					r.push(`a breeding-obsessed baby-factory,`);
@@ -1810,7 +1818,7 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 				r.push(`${He} will miss ${his} ${children}, but ${he} expected that.`);
 				slave.devotion += 4;
 			} else if (slave.devotion > 20) {
-				r.push(`${slave.slaveName} will naturally miss ${his} ${children}, but will is broken enough to hope that ${his} offspring will have a better life, or at least an enjoyable one.`);
+				r.push(`${slave.slaveName} will naturally miss ${his} ${children}, but ${his} will is broken enough to hope that ${his} offspring will have a better life, or at least an enjoyable one.`);
 			} else {
 				r.push(`${slave.slaveName} will of course`);
 				r.push(App.UI.DOM.makeElement("span", `hate you for this.`, "mediumorchid"));
@@ -2175,7 +2183,7 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 					const result = document.createElement("div");
 					const r = [];
 					surgeryDamage(slave, 10);
-					result.append(`Installation of belly implant is relatively simple procedure. Using the fact that ${his} body and internal organs have already adapted to pregnancy, it's possible to greatly expand the initial size of implant. ${He} will still look pregnant post surgery and recovery.`);
+					result.append(`Installation of a belly implant is relatively simple. Using the fact that ${his} body and internal organs have already adapted to pregnancy, it's possible to greatly expand the initial size of the implant. ${He} will still look pregnant post surgery and recovery.`);
 					if (slave.devotion > 50) {
 						r.push(`${He} leaves the surgery with ${his} belly still very gravid, and as such, knows you put something into ${his} womb replacing ${his} prior natural pregnancy. ${He} is`);
 						r.push(App.UI.DOM.makeElement("span", `curious`, "hotpink"));
@@ -2212,6 +2220,12 @@ globalThis.birth = function(slave, {birthStorm = false, cSection = false, artRen
 		return el;
 	}
 
+	function scarring() {
+		cashX(forceNeg(V.surgeryCost), "slaveSurgery", slave);
+		surgeryDamage(slave, 10);
+		delete slave.scar.belly["c-section"];
+	}
+
 	function broodmotherBirth() {
 		const el = document.createElement("p");
 		const birthScene = random(1, 100);
diff --git a/src/js/economyJS.js b/src/js/economyJS.js
index 55817a4ce164530f275506d6ac8481d475829227..5cbe49ea29c91399fb6bb976f50faebab65d12b5 100644
--- a/src/js/economyJS.js
+++ b/src/js/economyJS.js
@@ -341,7 +341,7 @@ globalThis.calculateCosts = (function() {
 			predictTotalSlaveCosts()
 		);
 
-		totalCosts += App.SecExp.upkeep.cost();
+		totalCosts += App.Mods.SecExp.upkeep.cost();
 
 		if (V.incubator.capacity > 0) {
 			totalCosts += getIncubatorCosts();
@@ -393,7 +393,7 @@ globalThis.calculateCosts = (function() {
 		cashX(forceNeg(getPCCosts()), "PCmedical");
 		getTotalSlaveCosts();
 
-		cashX(forceNeg(App.SecExp.upkeep.cost()), "securityExpansion");
+		cashX(forceNeg(App.Mods.SecExp.upkeep.cost()), "securityExpansion");
 
 		if (V.incubator.capacity > 0) {
 			cashX(forceNeg(getIncubatorCosts()), "incubator");
@@ -660,12 +660,12 @@ globalThis.calculateCosts = (function() {
 
 	function getFarmyardCosts() {
 		const facility = V.farmyard * V.facilityCost;
-		const exotic = V.animals.canine.filter(c => c.rarity === "exotic").length +
-			V.animals.hooved.filter(h => h.rarity === "exotic").length +
-			V.animals.feline.filter(f => f.rarity === "exotic").length;
-		const domestic = V.animals.canine.filter(c => c.rarity === "domestic").length +
-			V.animals.hooved.filter(h => h.rarity === "domestic").length +
-			V.animals.feline.filter(f => f.rarity === "domestic").length;
+		const exotic = V.animals.canine.map(c => getAnimal(c)).filter(c => c.rarity === "exotic").length +
+			V.animals.hooved.map(h => getAnimal(h)).filter(h => h.rarity === "exotic").length +
+			V.animals.feline.map(f => getAnimal(f)).filter(f => f.rarity === "exotic").length;
+		const domestic = V.animals.canine.map(c => getAnimal(c)).filter(c => c.rarity === "domestic").length +
+			V.animals.hooved.map(h => getAnimal(h)).filter(h => h.rarity === "domestic").length +
+			V.animals.feline.map(f => getAnimal(f)).filter(f => f.rarity === "domestic").length;
 		return (
 			(
 				(facility) +
@@ -706,7 +706,7 @@ globalThis.calculateCosts = (function() {
 	}
 
 	function getPeacekeeperCosts() {
-		return (V.peacekeepers !== 0 && V.peacekeepers.undermining !== 0) ? V.peacekeepers.undermining : 0;
+		return (V.peacekeepers.state === 2 && V.peacekeepers.undermining !== 0) ? V.peacekeepers.undermining : 0;
 	}
 
 	function getMercenariesCosts() {
@@ -751,6 +751,9 @@ globalThis.calculateCosts = (function() {
 
 	function getPolicyCosts() {
 		let costs = 0;
+		if (V.policies.idealAge && (V.targetIdealAge !== V.idealAge)) {
+			costs += 1500;
+		}
 		if (V.policies.alwaysSubsidizeGrowth === 1) {
 			costs += policies.cost();
 		}
@@ -836,7 +839,7 @@ globalThis.calculateCosts = (function() {
 	 */
 	function getSFCosts() {
 		if (V.SF.Toggle && V.SF.Active >= 1) {
-			return App.SF.AAR()[1];
+			return App.Mods.SF.AAR()[1];
 		}
 		return 0;
 	}
@@ -1355,7 +1358,7 @@ globalThis.getSlaveCostArray = function(s) {
 	}
 
 	// Tutoring
-	if (tutorForSlave(s)) {
+	if (tutorForSlave(s) && (Job.CLASSES === s.assignment || Job.SCHOOL === s.assignment)) {
 		retval.push({text: "Tutoring expenses", value: 7500});
 	}
 
@@ -2168,7 +2171,7 @@ globalThis.endWeekSlaveMarket = function() {
 /**
  * @param {App.Entity.SlaveState} s
  * @param {object|undefined} facility
- * @returns {Object}
+ * @returns {FC.SlaveStatisticData}
  */
 globalThis.getSlaveStatisticData = function(s, facility) {
 	if (!facility) { // Base data, even without facility
@@ -2383,10 +2386,6 @@ globalThis.forceNeg = function(x) {
 	return -Math.abs(x);
 };
 
-Number.prototype.toFixedHTML = function() {
-	return num(Number.prototype.toFixed.apply(this, arguments)).replace(/\.0+$/, '<span style="opacity: 0.3">$&</span>');
-};
-
 globalThis.SectorCounts = function() {
 	// Ternaries: - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
 	V.AProsperityCapModified = V.AProsperityCapModified > 0 ? V.AProsperityCapModified : 0;
diff --git a/src/js/eventHandlers.js b/src/js/eventHandlers.js
index c72f2e3efddaaa583adc4962106404e95bf8b628..521bb80790a99932e8c9cc5a1df85733d39dc7fd 100644
--- a/src/js/eventHandlers.js
+++ b/src/js/eventHandlers.js
@@ -33,9 +33,12 @@ App.EventHandlers = function() {
 	}
 
 	function storyReady() {
+		App.Status.storyReady = true;
 		App.UI.Theme.init();
 		App.UI.Hotkeys.init();
 		App.UI.GlobalTooltips.update();
+		// Load player mods. Do this last
+		App.Modding.internal.load();
 	}
 
 	function optionsChanged() {
diff --git a/src/js/extendedFamilyModeJS.js b/src/js/extendedFamilyModeJS.js
index a1dfc48376ce25d0992d11f7eb2387eeffc22253..f4a851b37513bddf73a80c6c489225a4a7b5eac4 100644
--- a/src/js/extendedFamilyModeJS.js
+++ b/src/js/extendedFamilyModeJS.js
@@ -206,18 +206,18 @@ globalThis.areCousins = function(slave1, slave2) {
 		return false;
 	}
 
-	let slave1Mom;
-	let slave1Dad;
-	let slave2Mom;
-	let slave2Dad;
+	const slave1Mom = getSlave(slave1.mother);
+	const slave1Dad = getSlave(slave1.father);
+	const slave2Mom = getSlave(slave2.mother);
+	const slave2Dad = getSlave(slave2.father);
 
-	if ((slave1Mom = getSlave(slave1.mother)) && (slave2Mom = getSlave(slave2.mother)) && !sameTParent(slave1Mom, slave2Mom) && sameMom(slave1Mom, slave2Mom) && sameDad(slave1Mom, slave2Mom)) {
+	if (slave1Mom && slave2Mom && !sameTParent(slave1Mom, slave2Mom) && sameMom(slave1Mom, slave2Mom) && sameDad(slave1Mom, slave2Mom)) {
 		return true;
-	} else if ((slave1Mom = getSlave(slave1.mother)) && (slave2Dad = getSlave(slave2.father)) && !sameTParent(slave1Mom, slave2Dad) && sameMom(slave1Mom, slave2Dad) && sameDad(slave1Mom, slave2Dad)) {
+	} else if (slave1Mom && slave2Dad && !sameTParent(slave1Mom, slave2Dad) && sameMom(slave1Mom, slave2Dad) && sameDad(slave1Mom, slave2Dad)) {
 		return true;
-	} else if ((slave1Dad = getSlave(slave1.father)) && (slave2Mom = getSlave(slave2.mother)) && !sameTParent(slave1Dad, slave2Mom) && sameMom(slave1Dad, slave2Mom) && sameDad(slave1Dad, slave2Mom)) {
+	} else if (slave1Dad && slave2Mom && !sameTParent(slave1Dad, slave2Mom) && sameMom(slave1Dad, slave2Mom) && sameDad(slave1Dad, slave2Mom)) {
 		return true;
-	} else if ((slave1Dad = getSlave(slave1.father)) && (slave2Dad = getSlave(slave2.father)) && !sameTParent(slave1Dad, slave2Dad) && sameMom(slave1Dad, slave2Dad) && sameDad(slave1Dad, slave2Dad)) {
+	} else if (slave1Dad && slave2Dad && !sameTParent(slave1Dad, slave2Dad) && sameMom(slave1Dad, slave2Dad) && sameDad(slave1Dad, slave2Dad)) {
 		return true;
 	}
 
@@ -291,110 +291,6 @@ globalThis.randomRelatedAvailableSlave = function(slave) {
 	return randomRelatedSlave(slave, (s) => isSlaveAvailable(s));
 };
 
-/**
- * @param {Relative} slave
- * @returns {App.Entity.SlaveState}
- */
-globalThis.randomSister = function(slave) {
-	return randomRelatedSlave(slave, (s) => areSisters(slave, s) > 0);
-};
-
-/**
- * @param {Relative} slave
- * @returns {App.Entity.SlaveState}
- */
-globalThis.randomTwinSister = function(slave) {
-	return randomRelatedSlave(slave, (s) => areSisters(slave, s) === 1);
-};
-
-/**
- * @param {Relative} slave
- * @returns {App.Entity.SlaveState}
- */
-globalThis.randomAvailableSister = function(slave) {
-	return randomRelatedSlave(slave, (s) => isSlaveAvailable(s) && areSisters(slave, s) > 0);
-};
-
-/**
- * @param {Relative} slave
- * @returns {App.Entity.SlaveState}
- */
-globalThis.randomDaughter = function(slave) {
-	return randomRelatedSlave(slave, (s) => isParentP(s, slave));
-};
-
-/**
- * @param {Relative} slave
- * @returns {App.Entity.SlaveState}
- */
-globalThis.randomAvailableDaughter = function(slave) {
-	return randomRelatedSlave(slave, (s) => isSlaveAvailable(s) && isParentP(s, slave));
-};
-
-/**
- * @param {Relative} slave
- * @returns {App.Entity.SlaveState}
- */
-globalThis.randomParent = function(slave) {
-	return randomRelatedSlave(slave, (s) => isParentP(slave, s));
-};
-
-/**
- * @param {Relative} slave
- * @returns {App.Entity.SlaveState}
- */
-globalThis.randomAvailableParent = function(slave) {
-	return randomRelatedSlave(slave, (s) => isSlaveAvailable(s) && isParentP(slave, s));
-};
-
-/**
- * @param {Relative} slave
- * @returns {object}
- */
-globalThis.availableRelatives = function(slave) {
-	let avail = {
-		mother: false,
-		motherName: null,
-		father: false,
-		fatherName: null,
-		sisters: 0,
-		daughters: 0,
-		oneSisterRel: null,
-		oneDaughterRel: null
-	};
-
-	V.slaves.forEach((other) => {
-		if (slave.mother === other.ID) {
-			avail.motherName = other.slaveName;
-		}
-		if (slave.father === other.ID) {
-			avail.fatherName = other.slaveName;
-		}
-		if (isSlaveAvailable(other)) {
-			if (slave.mother === other.ID) {
-				avail.mother = true;
-			}
-			if (slave.father === other.ID) {
-				avail.father = true;
-			}
-			if (slave.ID === other.mother || slave.ID === other.father) {
-				avail.daughters++;
-				if (avail.daughters === 1) {
-					avail.oneDaughterRel = relativeTerm(slave, other);
-				}
-			}
-			if (areSisters(slave, other) > 0) {
-				avail.sisters++;
-				if (avail.sisters === 1) {
-					avail.oneSisterRel = relativeTerm(slave, other);
-				}
-			}
-		}
-	});
-
-	return avail;
-};
-
 globalThis.totalPlayerRelatives = function(pc) {
 	let relatives = 0;
 	if (pc.mother > 0) {
diff --git a/src/js/ibcJS.js b/src/js/ibcJS.js
index 41ffff33f8a284a32c85ade6b73339c110dfb090..7ac1750f6a171a038573048d41b27ae5ff98f75a 100644
--- a/src/js/ibcJS.js
+++ b/src/js/ibcJS.js
@@ -14,13 +14,35 @@
 /* eslint-disable camelcase */
 /* eslint-disable eqeqeq */
 globalThis.ibc = (() => {
+	let realWorld =
+	{
+		getPlayerCharacter() { return V.PC; },
+
+		findSlaveState(id) {
+			return (slaveStateById(id) || V.genePool.find((s) => s.ID === id) || ((id in V.missingTable) ? V.missingTable[id] : null) || null);
+		},
+
+		getSlavesAndSuch() {
+			let all_slave_like = V.slaves.concat(V.genePool).concat(V.cribs).concat(V.incubator.tanks).concat(Object.values(V.missingTable));
+
+			if (V.boomerangSlave !== 0) all_slave_like.push(V.boomerangSlave);
+			if (V.traitor !== 0) all_slave_like.push(V.traitor);
+			if (V.activeSlave !== 0) all_slave_like.push(V.activeSlave);
+
+			return all_slave_like;
+		},
+
+		getFetuses() {
+			/** @type {FC.FetusGenetics[]} */
+			return V.slaves.filter(s => s.preg > 0).map(s => s.womb.map(i => i.genetics)).reduce((res, cur) => res.concat(cur), []);
+		}
+	};
+
+	let hasInbreedingCoefficient = (s) => "inbreedingCoeff" in s && s["inbreedingCoeff"] !== -1;
+
 	// These IDs are considered to be unknown parents
 	let or_null = (s) => specificCharacterID(s) ? s : null;
 
-	// Find some sort of state for a slave. Checks first the gene pool, then V.slaves, then the
-	// missing table
-	let find_gp = (id) => (slaveStateById(id) || V.genePool.find((s) => s.ID === id) || ((id in V.missingTable) ? V.missingTable[id] : null) || null);
-
 	/** The player's old master is a known parent, but we don't normally have a slavelike object
 	 * for him. We use this one instead, wherever necessary.
 	 * @type {IBCRelative} */
@@ -38,276 +60,95 @@ globalThis.ibc = (() => {
 		this.id = id; // Node ID
 		this.mother = null;
 		this.father = null;
-		this.nodecodes = []; // NodeCodes
-		this.nodecodes_str = []; // String version of the NodeCodes, for comparison
 		this._coeff = null; // Cached CoI
-		this.child_count = 0; // Number of children of the node, for computing NodeCodes
+		this._ancestorNodeCount = null;
 	}
 
-	// Determine the length of the shared prefix between the two NodeCode parameters
-	let prefix_len = (nca, ncb) => {
-		let i = 0;
-		for (i = 0; i < Math.min(nca.length, ncb.length); i++) {
-			if (nca[i] !== ncb[i]) {
-				break;
-			}
-		}
-		return i;
-	};
-
-	// Determine the set of longest common prefixes for a node pair
-	let prefixes = (a, b) => {
-		let found = [];
-		let found_s = [];
-		a.nodecodes.forEach(nca => {
-			let match = false;
-			b.nodecodes.forEach(ncb => {
-				let l = prefix_len(nca, ncb);
-				if (l === 0 && match) {
-					return;
-				}
+	class CoancestryCache
+	{
+		valuesByLeastParentId = {};
 
-				if (l > 0) {
-					match = true;
-					let pfx = nca.slice(0, l);
-					let pfx_s = pfx.join(';');
-
-					if (!found_s.includes(pfx_s)) {
-						found_s.push(pfx_s);
-						found.push(pfx);
-					}
-				}
-			});
-		});
+		coefficientOfInbreeding(node) {
+			if (node._coeff === null)
+				node._coeff = this.kinship(node.mother, node.father);
 
-		return found;
-	};
-
-	// Search up the tree to find a given NodeCode, starting at `n`
-	let find_nc = (nc, n) => {
-		if (n.nodecodes_str.includes(nc.join(';'))) {
-			return n;
-		}
-
-		let ret = null;
-		if (n.mother !== null) {
-			ret = find_nc(nc, n.mother);
-		}
-		if (n.father !== null && ret === null) {
-			ret = find_nc(nc, n.father);
+			return node._coeff;
 		}
 
-		return ret;
-	};
-
-	// Determine the set of common ancestors between a node pair
-	let common = (a, b) => {
-		let pfx = prefixes(a, b);
-		let pfx_s = pfx.map(s => s.join(';'));
-		let anc = [];
-
-		while (pfx.length > 0) {
-			let p = pfx.shift();
-			pfx_s.shift();
-			let ret = find_nc(p, a);
-
-			ret.nodecodes.forEach(nc => {
-				let i = pfx_s.indexOf(nc.join(';'));
-				if (i === -1) {
-					return;
-				}
-
-				pfx.splice(i, 1);
-				pfx_s.splice(i, 1);
-			});
-
-			if (anc.findIndex(s => (s[0] == ret)) === -1) {
-				anc.push([ret, p]);
-			}
-		}
-
-		return anc;
-	};
-
-	// Determine the set of NodeCodes on `n` with prefix `x`
-	let mps = (n, x) => {
-		let x_s = x.join(';');
-		return n.nodecodes.filter(nc => (nc.slice(0, x.length).join(';') === x_s));
-	};
-
-	// Compute the set of all paths to the parents of `n` with prefix `x`
-	let pp = (mother, father, x) => {
-		let m = mps(mother, x);
-		let f = mps(father, x);
-
-		let prod = [];
-		m.forEach(i => {
-			f.forEach(j => {
-				prod.push([i, j]);
-			});
-		});
-
-		return prod;
-	};
-
-	let kinship = (mother, father) => {
-		let coeffNum = 0;
-		if (!mother || !father) {
-			coeffNum = 0;
-		} else if (mother === father) {
-			coeffNum = 0.5 * (1 + coeff(mother));
-		} else {
-			let cf = 0;
-			let cmn = common(mother, father);
-
-			cmn.forEach(el => {
-				let c = el[0];
-				let p = el[1];
-				let p_s = p.join(';');
-
-				let paths = pp(mother, father, p);
-				let paths_s = paths.map(p => [p[0].join(';'), p[1].join(';')].join(','));
-
-				cmn.forEach(el2 => {
-					let co = el2[0];
-					if (co == c) {
-						return;
+		kinship(motherNode, fatherNode) {  // also known as "coancestry"; this is equal to the coefficient of inbreeding for any children the two given parents may have
+			if (!motherNode || !fatherNode)
+				return 0;
+			else if (motherNode === fatherNode)
+				// just two simple rules are needed to express it: self-with-self coancestry is (1 + coefficient of inbreeding of self) / 2, and...
+				return (1 + this.coefficientOfInbreeding(motherNode)) / 2;
+
+			return this.kinshipCache(motherNode.id, fatherNode.id,
+				() => {
+					let p1 = motherNode;
+					let p2 = fatherNode;
+					if (p1._ancestorNodeCount > p2._ancestorNodeCount)
+					{
+						// (to exercise the second rule mentioned in the comment below, it's fine to step up to either person's parents; but here the stepping up is aimed into
+						// the larger of the two ancestry trees, in a crude effort to keep the kinship() arguments at about the same generational level when possible, thereby
+						// maybe maximizing the chance that the same few pairs of arguments will keep coming into the function - which may possibly make caching extra effective.
+						// as the wording here indicates, the benefit of this has not actually been verified, but what the heck it's simple)
+						let p_ = p1;
+						p1 = p2;
+						p2 = p_;
 					}
-					let m_pp = [];
-					let f_pp = [];
-
-					co.nodecodes.forEach(nc => {
-						if (nc.slice(0, p.length).join(';') != p_s) {
-							return;
-						}
 
-						m_pp = m_pp.concat(mps(mother, nc));
-						f_pp = f_pp.concat(mps(father, nc));
-					});
-
-					m_pp.forEach(mp => {
-						f_pp.forEach(fp => {
-							let mf_s = [mp.join(';'), fp.join(';')].join(',');
-							let i = paths_s.indexOf(mf_s);
-							if (i === -1) {
-								return;
-							}
-							paths_s.splice(i, 1);
-							paths.splice(i, 1);
-						});
-					});
+					// ...one-with-another coancestry is (one-with-other's-father coancestry + one-with-other's-mother coancestry) / 2
+					return (this.kinship(p1, p2.mother) + this.kinship(p1, p2.father)) / 2;
 				});
-				paths.forEach(p => {
-					let pfx = prefix_len(p[0], p[1]);
+		}
 
-					cf += 0.5 ** (p[0].length + p[1].length + 1 - 2 * pfx) * (1 + coeff(c));
-				});
-			});
+		kinshipCache(motherId, fatherId, calculateValue) {  // this method exists solely for caching purposes
+			let id1 = motherId;
+			let id2 = fatherId;
+			if (id1 > id2) { let id_ = id1; id1 = id2; id2 = id_; }
 
-			coeffNum = cf;
-		}
+			let vs = this.valuesByLeastParentId;
 
-		return coeffNum;
-	};
+			let vs1 = vs[id1];
+			if (vs1 === undefined)
+				vs1 = vs[id1] = [];
 
-	// Determine the coefficient of inbreeding of a node `n`
-	let coeff = n => {
-		if (n._coeff === null) {
-			n._coeff = kinship(n.mother, n.father);
+			// cache format, conceptually: a set of arrays of numbers.  the top-level set is indexed by id1.  a lower-level array has the format
+			// [id, kinship value, id, kinship value, ...] with the id in an entry corresponding to id2 here and with the pairs in the array being kept invariably sorted by id.
+			return this.kinship_cache(vs1, id2, calculateValue);
 		}
-		return n._coeff;
-	};
 
-	// Populate the NodeCodes.
-	//
-	// Each node has a set of NodeCodes, which represent the set of paths from it to its ancestors.
-	// NodeCodes here are represented by arrays of integers.
-	//
-	// NodeCodes are constructed recursively in this fashion:
-	//
-	// - Assign each of the founders (nodes with both parents === null) an unique ID, starting from
-	//	0 and incrementing each time (the order doesn't matter); a founder's set of NodeCodes has
-	//	exactly one NodeCode, which is [ID] (an array containing only their ID)
-	//
-	// - For each other node, let M be its child number w.r.t. its mother and N its child number
-	//	w.r.t. its father, i.e. the number of children that the respective parent has had before
-	//	this one (the order is not important to the algorithm, it's arbitrary here for
-	//	convenience). Its set of NodeCodes is the set of all its mother's NodeCodes with M appended
-	//	and all of its father's NodeCodes with N appended. For example, if its mother has the
-	//	NodeCodes [[2]] and M = 3 and its father has the NodeCodes [[0,1], [3,1]] and N = 1 then
-	//	the set of NodeCodes for this node would be
-	//
-	//		[[2, 3], [0, 1, 1], [3, 1, 1]]
-	//
-	// We do this iteratively here, looping over the set of all nodes until each has been assigned
-	// a NodeCode. This requires looping through a number of times equal to the number of
-	// generations, since as soon as both parents have NodeCodes their children's NodeCodes may be
-	// computed.
-	let make_nc = nodes => {
-		// Generate founder NodeCodes
-		let total = Object.keys(nodes).length;
-		let seen = [];
-		let curid = 0;
-		Object.values(nodes).forEach(n => {
-			if (n.mother !== null || n.father !== null) {
-				return;
+		kinship_cache(vs, id, calculateValue) {  // this method exists solely for caching purposes
+			let entryCount = vs.length / 2;
+
+			// do a simple binary search
+			let searchRangeStart = 0;
+			let searchRangeEnd = entryCount;
+			while (searchRangeEnd > searchRangeStart)
+			{
+				let middleIndex = searchRangeStart + Math.floor((searchRangeEnd - searchRangeStart) / 2);
+				let idThere = vs[middleIndex * 2];
+				if (idThere === id)
+					return vs[middleIndex * 2 + 1];  // cached value found
+				else if (id < idThere)
+					searchRangeEnd = middleIndex;
+				else
+					searchRangeStart = middleIndex + 1;
 			}
-			n.nodecodes.push([curid]);
-			curid += 1;
-			seen.push(n.id);
-		});
-
-		// Generate the rest of the NodeCodes
-		let oldSeenLength = -1;
-		while (seen.length !== total) {
-			oldSeenLength = seen.length;
-			Object.keys(nodes).forEach(s => {
-				let n = nodes[s];
-				if (seen.includes(+s)) { // We've already done this
-					return;
-				} else if ((n.mother !== null && n.mother.nodecodes.length === 0) || (n.father !== null && n.father.nodecodes.length === 0)) { // Too soon, we haven't done its parents
-					return;
-				}
-
-				seen.push(n.id);
-				// Compute the NodeCodes from its parents
-				[n.mother, n.father].forEach((a, i) => {
-					if (a === null || (n.mother === n.father && i === 1)) { // Ignore missing parents/repeated
-						return;
-					}
-
-					a.nodecodes.forEach(nc => {
-						// Copy the NodeCode, push the child number, then add it
-						let nnc = nc.slice();
-						nnc.push(a.child_count);
-						n.nodecodes.push(nnc);
-					});
-					a.child_count += 1;
-				});
 
-				// NodeCodes must be sorted; this suffices
-				n.nodecodes.sort();
-			});
-			// check to make sure we're progressing...if not, there's a cycle in the graph
-			// dump all the nodes participating in or descended from the cycle and let the player figure it out
-			if (oldSeenLength === seen.length) {
-				const badSlaveIDs = Object.keys(nodes).filter(s => !seen.includes(+s)).map(k => nodes[k].id);
-				throw (`Inbreeding calculation: heritance cycle detected. Check slave IDs: ${badSlaveIDs}`);
-			}
+			// the appropriate location for the cached value was found, but the value isn't there yet, so add it
+			let v = calculateValue();
+			vs.splice(searchRangeStart * 2, 0, id, v);
+			return v;
 		}
-
-		// Cache the string NodeCodes
-		Object.values(nodes).forEach(n => {
-			n.nodecodes_str = n.nodecodes.map(nc => nc.join(';'));
-		});
-	};
+	}
 
 	/** Make nodes for an array of slaves
 	 * @param {IBCRelative[]} slaves
 	 * @param {boolean} [ignore_coeffs=false]
 	 * @returns {Object.<number, IBCNode>|{}}
 	 */
-	let nodes_slaves = (slaves, ignore_coeffs = false) => {
+	let nodes_slaves = (world, slaves, ignore_coeffs = false) => {
 		let nodes = {};
 
 		/** Recursively create the nodes we need, moving upwards from the given slave
@@ -326,10 +167,10 @@ globalThis.ibc = (() => {
 				[m, f].forEach(p => {
 					if (p !== null && !(p in nodes)) { // Not created, we have to do something
 						if (p === -1) {
-							create_node_rec(V.PC);
+							create_node_rec(world.getPlayerCharacter());
 						} else {
 							// Search for a slave state, genePool entry, or missingTable entry
-							let gp = find_gp(p);
+							let gp = world.findSlaveState(p);
 							if (gp !== null) {
 								// If we find one, we might have ancestry information: recurse
 								create_node_rec(gp);
@@ -346,18 +187,26 @@ globalThis.ibc = (() => {
 				nodes[s.ID].father = (f === null) ? f : nodes[f];
 
 				// Try to use a cached CoI for performance
-				let sg = find_gp(s.ID);
-				if (!ignore_coeffs && sg !== null && "inbreedingCoeff" in sg && sg.inbreedingCoeff !== -1) {
+				let sg = world.findSlaveState(s.ID);
+				if (!ignore_coeffs && sg !== null && hasInbreedingCoefficient(sg)) {
 					nodes[s.ID]._coeff = sg.inbreedingCoeff;
 				}
 			}
 		};
 
-		// Populate the nodes
 		slaves.forEach(s => create_node_rec(s));
 
-		// Populate NodeCodes
-		make_nc(nodes);
+		let countSelfAndAncestors = function(node) {
+			if (node === null)
+				return 0 + 0;  // no self, no ancestors
+
+			if (node._ancestorNodeCount === null)
+				node._ancestorNodeCount = countSelfAndAncestors(node.mother) + countSelfAndAncestors(node.father);
+
+			return 1 + node._ancestorNodeCount;  // 1 self, maybe some ancestors
+		};
+		for (let slave of slaves)
+			countSelfAndAncestors(nodes[slave.ID]);
 
 		return nodes;
 	};
@@ -368,14 +217,14 @@ globalThis.ibc = (() => {
 	 * @param {boolean} [ignore_coeffs=false]
 	 * @returns {Object.<number, number>}
 	 */
-	let coeff_slaves = (slaves, ignore_coeffs = false) => {
+	let coeff_slaves = (world, slaves, ignore_coeffs = false) => {
 		/** @type {Object.<number, number>} */
 		let ret = {};
 		if (!ignore_coeffs) {
 			// First, pull as many existing CoI off the slaves
 			slaves.forEach(s => {
-				let sg = find_gp(s.ID);
-				if (sg !== null && "inbreedingCoeff" in sg && sg.inbreedingCoeff !== -1) {
+				let sg = world.findSlaveState(s.ID);
+				if (sg !== null && hasInbreedingCoefficient(sg)) {
 					ret[s.ID] = sg.inbreedingCoeff;
 				}
 			});
@@ -384,11 +233,12 @@ globalThis.ibc = (() => {
 		// Now do any we haven't done already
 		slaves = slaves.filter(s => (!(s.ID in ret)));
 		if (slaves.length > 0) {
-			let nodes = nodes_slaves(slaves, ignore_coeffs);
+			let nodes = nodes_slaves(world, slaves, ignore_coeffs);
+			let coancestryCache = new CoancestryCache();
 
 			// Compute coefficients
 			slaves.forEach(s => {
-				ret[s.ID] = coeff(nodes[s.ID]);
+				ret[s.ID] = coancestryCache.coefficientOfInbreeding(nodes[s.ID]);
 			});
 		}
 
@@ -401,12 +251,12 @@ globalThis.ibc = (() => {
 	 * @param {boolean} [ignore_coeffs=false]
 	 * @returns {number}
 	 */
-	let kinship_slaves = (a, b, ignore_coeffs = false) => {
+	let kinship_slaves = (world, a, b, ignore_coeffs = false) => {
 		if (!a || !b) {
 			return 0;
 		}
 
-		return kinship_one_many(a, [b], ignore_coeffs)[b.ID];
+		return kinship_one_many(world, a, [b], ignore_coeffs)[b.ID];
 	};
 
 	/** Determine the coefficient of inbreeding of a single slave
@@ -414,17 +264,17 @@ globalThis.ibc = (() => {
 	 * @param {boolean} [ignore_coeffs=false]
 	 * @returns {number}
 	 */
-	let coeff_slave = (slave, ignore_coeffs = false) => {
-		if (!ignore_coeffs && "inbreedingCoeff" in slave && slave.inbreedingCoeff !== -1) {
+	let coeff_slave = (world, slave, ignore_coeffs = false) => {
+		if (!ignore_coeffs && hasInbreedingCoefficient(slave)) {
 			return slave.inbreedingCoeff;
 		}
 
-		let gp = find_gp(slave.ID);
-		if (!ignore_coeffs && gp !== null && "inbreedingCoeff" in gp && gp.inbreedingCoeff !== -1) {
+		let gp = world.findSlaveState(slave.ID);
+		if (!ignore_coeffs && gp !== null && hasInbreedingCoefficient(gp)) {
 			return gp.inbreedingCoeff;
 		}
 
-		return coeff_slaves([slave], ignore_coeffs)[slave.ID];
+		return coeff_slaves(world, [slave], ignore_coeffs)[slave.ID];
 	};
 
 	/** Determine the kinship between one and many slaves. Returns an mapping from the ID of each of
@@ -434,12 +284,13 @@ globalThis.ibc = (() => {
 	 * @param {boolean} [ignore_coeffs=false]
 	 * @returns {Object.<number, number>}
 	 */
-	let kinship_one_many = (a, others, ignore_coeffs = false) => {
-		let nodes = nodes_slaves(others.concat([a]), ignore_coeffs);
+	let kinship_one_many = (world, a, others, ignore_coeffs = false) => {
+		let nodes = nodes_slaves(world, others.concat([a]), ignore_coeffs);
 
 		let ks = {0: 0};
+		let coancestryCache = new CoancestryCache();
 		others.forEach(s => {
-			ks[s.ID] = kinship(nodes[a.ID], nodes[s.ID]);
+			ks[s.ID] = coancestryCache.kinship(nodes[a.ID], nodes[s.ID]);
 		});
 
 		return ks;
@@ -451,28 +302,18 @@ globalThis.ibc = (() => {
 	 * This should be called if parents are changed.
 	 * @param {number[]} ids
 	 */
-	let recalculate_coeff_ids = (ids) => {
+	let recalculate_coeff_ids = (world, ids) => {
 		// These are all the slave-like objects, i.e. they have ID, mother, and father. There will
 		// be multiple elements with the same ID: we want this, since we have to replace all
 		// occurrences of the COI for the affected slaves
 		/** @type {IBCRelative[]} */
-		let all_slave_like = V.slaves.concat(V.genePool).concat(V.cribs).concat(V.incubator.tanks).concat(Object.values(V.missingTable));
-		if (V.boomerangSlave !== 0) {
-			all_slave_like.push(V.boomerangSlave);
-		}
-		if (V.traitor !== 0) {
-			all_slave_like.push(V.traitor);
-		}
-		if (V.activeSlave !== 0) {
-			all_slave_like.push(V.activeSlave);
-		}
-		all_slave_like.push(V.PC);
+		let all_slave_like = world.getSlavesAndSuch();
+		all_slave_like.push(world.getPlayerCharacter());
 		// Add a fake entry for the PC's old master
 		all_slave_like.push(oldMaster);
 
 		// Gather the genetics of all current fetuses
-		/** @type {FC.FetusGenetics[]} */
-		let all_fetuses = V.slaves.filter(s => s.preg > 0).map(s => s.womb.map(i => i.genetics)).reduce((res, cur) => res.concat(cur), []);
+		let all_fetuses = world.getFetuses();
 
 		/** Recursively find all of the given ID's children, born and unborn
 		 * @param {number} id
@@ -520,29 +361,22 @@ globalThis.ibc = (() => {
 
 		// Now we assemble the tree from the slaves
 		let needed_slaves = all_slave_like.filter(s => (needed_slave_ids.has(s.ID) || needed_parent_ids.has(s.ID)));
-		let nodes = nodes_slaves(needed_slaves, true);
+		let nodes = nodes_slaves(world, needed_slaves, true);
 
 		// Now calculate the inbreeding coefficients (they're cached in the tree once calculated)
+		let coancestryCache = new CoancestryCache();
 		needed_slaves.filter(s => needed_slave_ids.has(s.ID)).forEach(s => {
-			s.inbreedingCoeff = coeff(nodes[s.ID]);
+			s.inbreedingCoeff = coancestryCache.coefficientOfInbreeding(nodes[s.ID]);
 		});
 
 		// Finally, handle all of the kinship for the fetuses
-		let kinship_cache = new Map(); // Manually cache it
 		needed_fetuses.forEach(f => {
 			if (or_null(f.mother) === null || or_null(f.father) === null) {
 				f.inbreedingCoeff = 0;
 				return;
 			}
 
-			// Use a string of the form "parent;parent" to store the cache value; since kinship is
-			// commutative, the minimum parent ID will be first
-			let kinship_str = Math.min(f.mother, f.father) + ';' + Math.max(f.mother, f.father);
-			if (!kinship_cache.has(kinship_str)) {
-				kinship_cache.set(kinship_str, kinship(nodes[f.mother], nodes[f.father]));
-			}
-
-			f.inbreedingCoeff = kinship_cache.get(kinship_str);
+			f.inbreedingCoeff = coancestryCache.kinship(nodes[f.mother], nodes[f.father]);
 		});
 	};
 
@@ -550,16 +384,19 @@ globalThis.ibc = (() => {
 	 * @see recalculate_coeff_ids
 	 * @param {number} id
 	 */
-	let recalculate_coeff_id = (id) => {
-		return recalculate_coeff_ids([id]);
+	let recalculate_coeff_id = (world, id) => {
+		return recalculate_coeff_ids(world, [id]);
 	};
 
 	return {
-		coeff: coeff_slave,
-		coeff_slaves,
-		kinship: kinship_slaves,
-		kinship_one_many,
-		recalculate_coeff_ids,
-		recalculate_coeff_id
+		_test: {
+			coeff_slave,
+		},
+		coeff: coeff_slave.bind(null, realWorld),
+		coeff_slaves: coeff_slaves.bind(null, realWorld),
+		kinship: kinship_slaves.bind(null, realWorld),
+		kinship_one_many: kinship_one_many.bind(null, realWorld),
+		recalculate_coeff_ids: recalculate_coeff_ids.bind(null, realWorld),
+		recalculate_coeff_id: recalculate_coeff_id.bind(null, realWorld)
 	};
 })();
diff --git a/src/js/itemAvailability.js b/src/js/itemAvailability.js
index 8b7efc871ff61cda73b387cbff9101162ac8460a..26b33ee29848229f1b0a375cdff77cacf15e2a33 100644
--- a/src/js/itemAvailability.js
+++ b/src/js/itemAvailability.js
@@ -245,8 +245,8 @@ globalThis.addProsthetic = function(slave, prosthetic) {
 		if (limb > 0) {
 			let p = {
 				id: prosthetic,
-				arm: {left: new App.Entity.LimbState(), right: new App.Entity.LimbState()},
-				leg: {left: new App.Entity.LimbState(), right: new App.Entity.LimbState()}
+				arm: {left: new App.Entity.ArmState(), right: new App.Entity.ArmState()},
+				leg: {left: new App.Entity.LegState(), right: new App.Entity.LegState()}
 			};
 			p.arm.left.type = limb;
 			p.arm.right.type = limb;
diff --git a/src/js/main.js b/src/js/main.js
index becda31cd2681bc718b1011526fed6693ea7b4b8..e577fee479c272087ca1c528ccdbd84845c50a40 100644
--- a/src/js/main.js
+++ b/src/js/main.js
@@ -184,7 +184,11 @@ App.MainView.full = function() {
 
 		penthouseCensus();
 		V.costs = Math.trunc(calculateCosts.predict());
-		V.currentRule = V.defaultRules[0];
+		if (V.defaultRules.length > 0) {
+			V.currentRule = V.defaultRules[0].ID;
+		} else {
+			V.currentRule = null;
+		}
 		SlaveSort.slaves(V.slaves);
 
 		App.UI.SlaveList.ScrollPosition.restore();
@@ -229,11 +233,6 @@ App.MainView.full = function() {
 
 				App.UI.reload();
 			}, null, '', `This will only check slaves in the Penthouse.`));
-
-			if (DefaultRulesError()) {
-				App.UI.DOM.appendNewElement("div", div, `One or more rules' custom conditions has errors!`,
-					['center', 'warning', 'notification']);
-			}
 		}
 
 		App.UI.DOM.appendNewElement("div", div, App.UI.DOM.generateLinksStrip(links), ['center', 'margin-bottom']);
diff --git a/src/js/makePurchase.js b/src/js/makePurchase.js
new file mode 100644
index 0000000000000000000000000000000000000000..02ddc73010c63752bee7aec07c74b193193780ac
--- /dev/null
+++ b/src/js/makePurchase.js
@@ -0,0 +1,138 @@
+/**
+ * Creates a user-facing link or button allowing the user to purchase something.
+ * @param {string} text The text to display.
+ * @param {number} cost The amount of ¤ the purchase costs.
+ * @param {keyof App.Data.Records.LastWeeksCash} what What the purchase is for.
+ * @param {Object} [args] Any additional arguments to pass.
+ * @param {string[]} [args.notes] Any additional information to display. Must be lowercase and end in no punctuation.
+ * @param {function():void} args.handler Any custom handler to run upon purchase.
+ * @param {[boolean, string][]} [args.prereqs] Any prerequisites that must be met for the purchase to be available, with a note for when the prerequisites are not met.
+ * @param {function():void} [args.refresh] Any function to run that updates the screen, if not the default `App.UI.reload()`.
+ */
+globalThis.makePurchase = function(text, cost, what, {notes, handler, prereqs, refresh}) {
+	return App.UI.DOM.makeElement("div", V.purchaseStyle === 'button' ? renderButton() : renderLink());
+
+	function execute() {
+		cashX(forceNeg(cost), what);
+
+		if (handler) {
+			handler();
+		}
+
+		if (!refresh) {
+			App.UI.reload();
+		} else {
+			refresh();
+		}
+	}
+
+	function renderButton() {
+		const span = App.UI.DOM.makeElement("span", null, ['note']);
+		const price = cost !== 0 ? `${cashFormat(Math.trunc(cost))}` : `free`;
+		const button = App.UI.DOM.makeElement("button", capFirstChar(price), ['purchase-button']);
+
+		if (V.cash >= cost &&
+			(!prereqs || prereqs.every(prereq => prereq[0] === true))) {
+			button.onclick = execute;
+
+			if (notes) {
+				const span = document.createElement("span");
+				const ul = document.createElement("ul");
+
+				if (notes.length > 1) {
+					ul.append(...notes.map(note => {
+						const li = document.createElement("li");
+						li.append(capFirstChar(note));
+
+						return li;
+					}));
+
+					span.append(ul);
+				} else {
+					span.append(capFirstChar(notes[0]));
+				}
+
+				tippy(button, {
+					content: span,
+				});
+			}
+		} else {
+			const span = document.createElement("span");
+			const ul = document.createElement("ul");
+			const reasons = [];
+
+			if (V.cash < cost) {
+				reasons.push(`You lack the necessary funds to make this purchase`);
+			}
+
+			if (prereqs) {
+				prereqs.forEach(prereq => {
+					if (prereq[0] !== true) {
+						reasons.push(prereq[1]);
+					}
+				});
+			}
+
+			if (reasons.length > 1) {
+				for (const li of reasons.map(reason => {
+					const li = document.createElement("li");
+					li.append(reason);
+					return li;
+				})) {
+					ul.append(li);
+				}
+
+				span.append(ul);
+			} else {
+				span.append(reasons[0]);
+			}
+
+			button.classList.add("disabled");
+
+			tippy(button, {
+				content: span,
+			});
+		}
+
+		span.append(
+			button,
+			text,
+		);
+
+		return span;
+	}
+
+	function renderLink() {
+		const span = App.UI.DOM.makeElement("span", null, ['indent']);
+		const price = [`${cost !== 0 ? `Costs ${cashFormat(Math.trunc(cost))}` : `Free`}`];
+
+		if (notes) {
+			price.push(...notes);
+		}
+
+		if (V.cash >= cost &&
+			(!prereqs || prereqs.every(prereq => prereq[0] === true))) {
+			span.append(App.UI.DOM.link(`${text} `, execute, [], ''));
+		} else {
+			const reasons = [];
+
+			if (V.cash < cost) {
+				reasons.push(`You cannot afford this purchase`);
+			}
+
+			if (prereqs) {
+				prereqs.forEach(prereq => {
+					if (prereq[0] !== true) {
+						reasons.push(prereq[1]);
+					}
+				});
+			}
+
+			span.append(App.UI.DOM.disabledLink(`${text} `, reasons));
+		}
+
+		App.UI.DOM.appendNewElement("span", span, toSentence(price), ['note']);
+
+		return span;
+	}
+};
diff --git a/src/js/modification.js b/src/js/modification.js
index 5dff40616f2fe8e4a5884bbf54c70463c8e51d0e..3dd770dce5f67dc0b4af150fed5e4a575853985b 100644
--- a/src/js/modification.js
+++ b/src/js/modification.js
@@ -1,57 +1,203 @@
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {Record<string, string>}
+ */
+App.Medicine.Modification.brandRecord = function(slave) {
+	const scars = Object.assign({}, slave.brand);
+	Object.assign(scars, slave.leg.left?.brand);
+	Object.assign(scars, slave.leg.right?.brand);
+	Object.assign(scars, slave.arm.left?.brand);
+	Object.assign(scars, slave.arm.right?.brand);
+	return scars;
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @param {string} location
+ * @returns {{brand:Record<string, string>, scar: Record<string, Partial<App.Entity.ScarState>>}}
+ */
+App.Medicine.Modification.modifiableBodyPart = function(slave, location) {
+	const bodyPartRoot = App.UI.bodyPartRoot(location);
+	const bodyPartData = App.Data.Slave.body.get(bodyPartRoot);
+
+	/** @type {{brand:Record<string, string>, scar: Record<string, Partial<App.Entity.ScarState>>}} */
+	let object = slave;
+
+	// if undefined: custom location
+	if (bodyPartData !== undefined) {
+		// select the correct scar object based on location
+		if (bodyPartData.category === "legs") {
+			if (location.startsWith("left")) {
+				if (getLeftLegID(slave) === 1) {
+					object = slave.leg.left;
+				} else {
+					return undefined;
+				}
+			} else {
+				if (getRightLegID(slave) === 1) {
+					object = slave.leg.right;
+				} else {
+					return undefined;
+				}
+			}
+		} else if (bodyPartData.category === "arms") {
+			if (location.startsWith("left")) {
+				if (getLeftArmID(slave) === 1) {
+					object = slave.arm.left;
+				} else {
+					return undefined;
+				}
+			} else {
+				if (getRightArmID(slave) === 1) {
+					object = slave.arm.right;
+				} else {
+					return undefined;
+				}
+			}
+		}
+	}
+
+	return object;
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @param {string} location
+ * @returns {Record<string, string>} If undefined, the location does not exist or can't be branded.
+ */
+App.Medicine.Modification.brandObject = function(slave, location) {
+	return App.Medicine.Modification.modifiableBodyPart(slave, location)?.brand;
+};
+
+/**
+ * Creates a new brand on a slaves body at a given location. Does nothing, if the location (for example an arm) does not
+ * exist or can't be branded.
+ * @param {App.Entity.SlaveState} slave
+ * @param {string} location
+ * @param {string} design
+ */
+App.Medicine.Modification.addBrand = function(slave, location, design) {
+	const scarObject = App.Medicine.Modification.brandObject(slave, location);
+	if (scarObject === undefined) {
+		// body part does not exist
+		return;
+	}
+	scarObject[location] = design;
+};
+
 /**
  * Basic application of scar
  * @param {App.Entity.SlaveState} slave
- * @param {string} scar
- * @param {keyof App.Entity.scarState} design
- * @param {number} [weight]
+ * @param {string} location
+ */
+App.Medicine.Modification.removeBrand = function(slave, location) {
+	const brandObject = App.Medicine.Modification.brandObject(slave, location);
+	if (brandObject === undefined) {
+		// body part does not exist
+		return;
+	}
+
+	delete brandObject[location];
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {Record<string, Partial<App.Entity.ScarState>>}
+ */
+App.Medicine.Modification.scarRecord = function(slave) {
+	const scars = Object.assign({}, slave.scar);
+	Object.assign(scars, slave.leg.left?.scar);
+	Object.assign(scars, slave.leg.right?.scar);
+	Object.assign(scars, slave.arm.left?.scar);
+	Object.assign(scars, slave.arm.right?.scar);
+	return scars;
+};
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @param {string} location
+ * @returns {Record<string, Partial<App.Entity.ScarState>>} If undefined, the location does not exist or can't be scarred.
+ */
+App.Medicine.Modification.scarObject = function(slave, location) {
+	return App.Medicine.Modification.modifiableBodyPart(slave, location)?.scar;
+};
+
+/**
+ * Creates a new scar on a slaves body at a given location. Does nothing, if the location (for example an arm) does not
+ * exist or can't be scarred.
+ * @param {App.Entity.SlaveState} slave
+ * @param {string} location
+ * @param {keyof App.Entity.ScarState|string} design
+ * @param {number} [weight=1]
  */
-App.Medicine.Modification.addScar = function(slave, scar, design, weight) {
+App.Medicine.Modification.addScar = function(slave, location, design, weight = 1) {
 	/*
 	V.scarApplied = 1;
 	surgeryDamage(slave, 10); // dangerous to uncomment this as sometimes many scars are applied at once.
 	cashX(forceNeg(surgery.costs), "slaveSurgery", slave);
 	surgeryDamage(slave, (V.PC.skill.medicine >= 100) ? Math.round(surgery.healthCosts / 2) : surgery.healthCosts);*/
-	if (!weight) {
-		weight = 1;
+
+	const scarObject = App.Medicine.Modification.scarObject(slave, location);
+	if (scarObject === undefined) {
+		// body part does not exist
+		return;
 	}
-	if (!slave.scar.hasOwnProperty(scar)) {
-		slave.scar[scar] = new App.Entity.scarState();
+
+	if (!scarObject.hasOwnProperty(location)) {
+		scarObject[location] = new App.Entity.ScarState();
 	}
-	if (!slave.scar[scar].hasOwnProperty(design)) {
-		slave.scar[scar][design] = weight;
+	if (scarObject[location].hasOwnProperty(design)) {
+		scarObject[location][design] += weight;
 	} else {
-		slave.scar[scar][design] += weight;
+		scarObject[location][design] = weight;
+	}
+};
+
+/**
+ * Remove all scars from a given location
+ * @param {App.Entity.SlaveState} slave
+ * @param {string} location
+ */
+App.Medicine.Modification.removeAllScars = function(slave, location) {
+	const scarObject = App.Medicine.Modification.scarObject(slave, location);
+	if (scarObject === undefined) {
+		// body part does not exist
+		return;
 	}
+
+	delete scarObject[location];
 };
+
 /**
  * Basic application of scar
  * @param {App.Entity.SlaveState} slave
- * @param {string} scar
- * @param {keyof App.Entity.scarState} design
+ * @param {string} location
+ * @param {keyof App.Entity.ScarState|string} design
  */
-App.Medicine.Modification.removeScar = function(slave, scar, design) {
-	/*
-	V.scarApplied = 1;
-	surgeryDamage(slave, 10); //dangerous to uncomment this as sometimes many scars are applied at once.
-	cashX(forceNeg(surgery.costs), "slaveSurgery", slave);
-	surgeryDamage(slave, (V.PC.skill.medicine >= 100) ? Math.round(surgery.healthCosts / 2) : surgery.healthCosts);*/
-	if (slave.scar.hasOwnProperty(scar)) { // if scar object exists for this body part
-		if (slave.scar[scar].hasOwnProperty(design)) { // if object has this kind of scar (might be custom)
+App.Medicine.Modification.removeScar = function(slave, location, design) {
+	const scarObject = App.Medicine.Modification.scarObject(slave, location);
+	if (scarObject === undefined) {
+		// body part does not exist
+		return;
+	}
+
+	if (scarObject.hasOwnProperty(location)) { // if scar object exists for this body part
+		if (scarObject[location].hasOwnProperty(design)) { // if object has this kind of scar (might be custom)
 			if (["burn", "c-section", "chain", "cutting", "exotic", "generic", "menacing", "surgical", "whip"].includes(design)) {
-				slave.scar[scar][design] = 0;
+				scarObject[location][design] = 0;
 			} else {
-				delete slave.scar[scar][design]; // scar was custom
+				delete scarObject[location][design]; // scar was custom
 			}
 		}
 		// remove the scar object entirely if no entry is scarred:
-		let weights = Object.values(slave.scar[scar]);
+		let weights = Object.values(scarObject[location]);
 		let total = 0;
 		let i;
 		for (i = 0; i < weights.length; i++) {
 			total += weights[i];
 		}
 		if (total === 0) {
-			delete slave.scar[scar];
+			delete scarObject[location];
 		}
 	}
 };
@@ -103,7 +249,7 @@ App.Medicine.Modification.addScourged = function(slave, weight) {
  * Scars a slave over a large section of their body.
  * @param {App.Entity.SlaveState} slave
  * @param {string} location full, upper, lower, left or right
- * @param {keyof App.Entity.scarState} type whip, burn, surgical, generic
+ * @param {keyof App.Entity.ScarState} type whip, burn, surgical, generic
  * @param {number} weight
  */
 App.Medicine.Modification.addBulkScars = function(slave, location, type, weight) {
@@ -166,7 +312,7 @@ App.Medicine.Modification.setPiercing = function(slave, location, weight) {
 		He, His,
 		he, his, him
 	} = getPronouns(slave);
-	const delta = weight - slave[`${location}Piercing`];
+	const delta = weight - slave.piercing[location].weight;
 	let r = [];
 	if (location === "tongue") {
 		if (slave.fetishKnown && slave.fetish === "cumslut" && slave.fetishStrength > 10) {
diff --git a/src/js/personalAttentionFunctions.js b/src/js/personalAttentionFunctions.js
index a580106dde3eb7d6fabfa8d8002cb992597e9e93..f796cf76ae3dda091a494713464706b59c31fc18 100644
--- a/src/js/personalAttentionFunctions.js
+++ b/src/js/personalAttentionFunctions.js
@@ -1,4 +1,4 @@
-App.personalAttention.reset = function() {
+App.PersonalAttention.reset = function() {
 	if (isPCCareerInCategory("escort")) {
 		V.personalAttention = {task: PersonalAttention.WHORING};
 	} else if (isPCCareerInCategory("servant")) {
@@ -12,7 +12,7 @@ App.personalAttention.reset = function() {
 	* @param {string} input
 	* @returns {string}
 	*/
-App.personalAttention.update = function(input) {
+App.PersonalAttention.update = function(input) {
 	switch (input) {
 		case "soften her behavioral flaw":
 			return "soften behavioral flaw";
@@ -44,7 +44,7 @@ App.personalAttention.update = function(input) {
 	* @param {App.Entity.SlaveState} slave
 	* @returns {string}
 	*/
-App.personalAttention.getText = function(objective, slave) {
+App.PersonalAttention.getText = function(objective, slave) {
 	const {his, him} = getPronouns(slave);
 	switch (objective) {
 		case "soften behavioral flaw":
diff --git a/src/js/physicalDevelopment.js b/src/js/physicalDevelopment.js
deleted file mode 100644
index 96fa22e73aefdb98a755e36161b8888c7f4a40c3..0000000000000000000000000000000000000000
--- a/src/js/physicalDevelopment.js
+++ /dev/null
@@ -1,3752 +0,0 @@
-globalThis.physicalDevelopment = (function physicalDevelopment() {
-	"use strict";
-
-	let gigantomastiaMod;
-	let uterineHypersensitivityMod;
-	let rearQuirk;
-	let rearQuirkDivider;
-	let dickMod;
-	let physicalAgeSwap;
-
-	return physicalDevelopment;
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function physicalDevelopment(slave) {
-		if (slave.geneticQuirks.progeria === 2) {
-			// since progeria increases .physicalAge, we need to work around it.
-			// nothing other than the incubator drastically desyncs it, and progeria slaves do not live through incubation, so this should be fine.
-			physicalAgeSwap = slave.actualAge;
-		} else {
-			physicalAgeSwap = slave.physicalAge;
-		}
-		if (slave.geneMods.NCS !== 1) {
-			/* NCS completely blocks all natural physical growth: no height increases. It also blocks all hormonal secondary sexual * characteristics. So, on the female side: no boobs, no butt, no hips, and no labia. And on the male side: no dick, no clit, no balls, no scrotum, no shoulders. */
-			/* so this is a big old NO-OP to skip the physical development. */
-			if (slave.geneticQuirks.androgyny === 2) { /* takes a mix of both to create a very androgynous slave */
-				if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2) {
-					increaseHeightDwarf(slave);
-				} else if (slave.geneticQuirks.gigantism === 2) {
-					increaseHeightGiant(slave);
-				} else if (slave.geneticQuirks.neoteny === 2) {
-					increaseHeightNeoteny(slave);
-				} else {
-					increaseHeightXX(slave);
-				}
-				if (slave.geneticQuirks.neoteny !== 2) {
-					if (slave.boobs - slave.boobsImplant <= 300) {
-						increaseBoobsXX(slave);
-					}
-					if (slave.dick.isBetween(0, 3) || slave.geneticQuirks.wellHung === 2) {
-						increaseDick(slave);
-					}
-					if (slave.balls.isBetween(0, 3)) {
-						increaseBalls(slave);
-					}
-					if (slave.vagina > 0 && slave.ovaries > 0 && physicalAgeSwap > slave.pubertyAgeXX) {
-						increaseWetness(slave);
-					}
-					if (slave.waist < 10) {
-						increaseWaistXY(slave);
-					}
-					if (slave.hips - slave.hipsImplant < 0) {
-						increaseHipsXX(slave);
-					}
-					if (slave.butt - slave.buttImplant < 3) {
-						increaseButtXX(slave);
-					}
-				}
-				increasePregAdaptationXX(slave);
-			} else if (slave.genes === "XX") { /* loli becoming a woman */
-				if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2) {
-					increaseHeightDwarf(slave);
-				} else if (slave.geneticQuirks.gigantism === 2) {
-					increaseHeightGiant(slave);
-				} else if (slave.geneticQuirks.neoteny === 2) {
-					increaseHeightNeoteny(slave);
-				} else {
-					increaseHeightXX(slave);
-				}
-				if (physicalAgeSwap === 13 || (physicalAgeSwap > 13 && (slave.hormoneBalance >= 100 || slave.hormoneBalance <= -100))) {
-					increaseFaceXX(slave);
-					if (slave.voice > 0) {
-						increaseVoiceXX(slave);
-					}
-				}
-				if (slave.geneticQuirks.neoteny !== 2) {
-					increaseBoobsXX(slave);
-					if (slave.clit > 0) {
-						increaseClit(slave);
-					}
-					if (slave.vagina > 0 && slave.ovaries > 0 && physicalAgeSwap > slave.pubertyAgeXX) {
-						increaseWetness(slave);
-					}
-					increaseWaistXX(slave);
-					increaseHipsXX(slave);
-					increaseButtXX(slave);
-				}
-				increasePregAdaptationXX(slave);
-			} else {
-				/* shota becoming a man */
-				if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2) {
-					increaseHeightDwarf(slave);
-				} else if (slave.geneticQuirks.gigantism === 2) {
-					increaseHeightGiant(slave);
-				} else if (slave.geneticQuirks.neoteny === 2) {
-					increaseHeightNeoteny(slave);
-				} else {
-					increaseHeightXY(slave);
-				}
-				if (physicalAgeSwap === 13 || (physicalAgeSwap > 13 && (slave.hormoneBalance >= 100 || slave.hormoneBalance <= -100))) {
-					increaseFaceXY(slave);
-					if (slave.voice > 1) {
-						increaseVoiceXY(slave);
-					}
-				}
-				if (slave.geneticQuirks.neoteny !== 2) {
-					increaseBoobsXY(slave);
-					if (slave.dick > 0) {
-						increaseDick(slave);
-					}
-					if (slave.balls > 0) {
-						increaseBalls(slave);
-					}
-					increaseWaistXY(slave);
-					increaseHipsXY(slave);
-					increaseButtXY(slave);
-				}
-				increasePregAdaptationXY(slave);
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseHeightXX(slave) {
-		if (slave.hormoneBalance >= 200) {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 91) {
-					slave.height += jsEither([8, 8, 9, 9]);
-				} else if (slave.height <= 101) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 101) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 109) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 109) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 116) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 116) {
-					slave.height += jsEither([5, 5, 6, 6]);
-				} else if (slave.height <= 124) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 124) {
-					slave.height += jsEither([7, 7, 8, 8]);
-				} else if (slave.height <= 131) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 131) {
-					slave.height += jsEither([5, 5, 6, 6]);
-				} else if (slave.height <= 137) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 137) {
-					slave.height += jsEither([4, 4, 5, 5]);
-				} else if (slave.height <= 144) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 144) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 156) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 156) {
-					slave.height += jsEither([5, 5, 6, 6]);
-				} else if (slave.height <= 163) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 163) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 168) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 168) {
-					slave.height += jsEither([5, 5, 6, 6]);
-				} else if (slave.height <= 171) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 171) {
-					slave.height += jsEither([4, 4, 5, 5]);
-				} else if (slave.height <= 173) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 0, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 0, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 0, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 0, 1, 1]);
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 91) {
-					slave.height += jsEither([8, 8, 9, 9, 9]);
-				} else if (slave.height <= 101) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 101) {
-					slave.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (slave.height <= 109) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 109) {
-					slave.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (slave.height <= 116) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 116) {
-					slave.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (slave.height <= 124) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 124) {
-					slave.height += jsEither([7, 7, 8, 8, 8]);
-				} else if (slave.height <= 131) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 131) {
-					slave.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (slave.height <= 137) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 137) {
-					slave.height += jsEither([4, 4, 5, 5, 5]);
-				} else if (slave.height <= 144) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 144) {
-					slave.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (slave.height <= 156) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 156) {
-					slave.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (slave.height <= 163) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 163) {
-					slave.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (slave.height <= 168) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 168) {
-					slave.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (slave.height <= 171) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 171) {
-					slave.height += jsEither([4, 4, 5, 5, 5]);
-				} else if (slave.height <= 173) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 91) {
-					slave.height += jsEither([9, 9, 9, 10, 10]);
-				} else if (slave.height <= 101) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 101) {
-					slave.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (slave.height <= 109) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 109) {
-					slave.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (slave.height <= 116) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 116) {
-					slave.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (slave.height <= 124) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 124) {
-					slave.height += jsEither([8, 8, 8, 9, 9]);
-				} else if (slave.height <= 131) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 131) {
-					slave.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (slave.height <= 137) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 137) {
-					slave.height += jsEither([5, 5, 5, 6, 6]);
-				} else if (slave.height <= 144) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 144) {
-					slave.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (slave.height <= 156) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 156) {
-					slave.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (slave.height <= 163) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 163) {
-					slave.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (slave.height <= 168) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 168) {
-					slave.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (slave.height <= 171) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 171) {
-					slave.height += jsEither([5, 5, 5, 6, 6]);
-				} else if (slave.height <= 173) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 91) {
-					slave.height += jsEither([8, 9, 9, 10, 10]);
-				} else if (slave.height <= 101) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 101) {
-					slave.height += jsEither([6, 7, 7, 8, 8]);
-				} else if (slave.height <= 109) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 109) {
-					slave.height += jsEither([6, 7, 7, 8, 8]);
-				} else if (slave.height <= 116) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 116) {
-					slave.height += jsEither([5, 6, 6, 7, 7]);
-				} else if (slave.height <= 124) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 124) {
-					slave.height += jsEither([7, 8, 8, 9, 9]);
-				} else if (slave.height <= 131) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 131) {
-					slave.height += jsEither([5, 6, 6, 7, 7]);
-				} else if (slave.height <= 137) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 137) {
-					slave.height += jsEither([4, 5, 5, 6, 6]);
-				} else if (slave.height <= 144) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 144) {
-					slave.height += jsEither([6, 7, 7, 8, 8]);
-				} else if (slave.height <= 156) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 156) {
-					slave.height += jsEither([5, 6, 6, 7, 7]);
-				} else if (slave.height <= 163) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 163) {
-					slave.height += jsEither([6, 7, 7, 8, 8]);
-				} else if (slave.height <= 168) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 168) {
-					slave.height += jsEither([5, 6, 6, 7, 7]);
-				} else if (slave.height <= 171) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 171) {
-					slave.height += jsEither([4, 5, 5, 6, 6]);
-				} else if (slave.height <= 173) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 1, 1, 2, 2]);
-				}
-			}
-		} else {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 91) {
-					slave.height += jsEither([8, 8, 9, 9, 9, 10]);
-				} else if (slave.height <= 101) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 101) {
-					slave.height += jsEither([6, 6, 7, 7, 8, 8]);
-				} else if (slave.height <= 109) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 109) {
-					slave.height += jsEither([6, 6, 7, 7, 7, 8]);
-				} else if (slave.height <= 116) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 116) {
-					slave.height += jsEither([5, 5, 6, 6, 6, 7]);
-				} else if (slave.height <= 124) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 124) {
-					slave.height += jsEither([7, 7, 8, 8, 8, 9]);
-				} else if (slave.height <= 131) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 131) {
-					slave.height += jsEither([5, 5, 6, 6, 6, 7]);
-				} else if (slave.height <= 137) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 137) {
-					slave.height += jsEither([4, 4, 5, 5, 5, 6]);
-				} else if (slave.height <= 144) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 144) {
-					slave.height += jsEither([6, 6, 7, 7, 7, 8]);
-				} else if (slave.height <= 156) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 156) {
-					slave.height += jsEither([5, 5, 6, 6, 6, 7]);
-				} else if (slave.height <= 163) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 163) {
-					slave.height += jsEither([6, 6, 7, 7, 7, 8]);
-				} else if (slave.height <= 168) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 168) {
-					slave.height += jsEither([5, 5, 6, 6, 6, 7]);
-				} else if (slave.height <= 171) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 171) {
-					slave.height += jsEither([4, 4, 5, 5, 5, 6]);
-				} else if (slave.height <= 173) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 0, 1, 1, 1, 2]);
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 0, 1, 1, 1, 2]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 0, 1, 1, 1, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 174) {
-					slave.height += jsEither([0, 0, 1, 1, 1, 2]);
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseHeightXY(slave) {
-		if (slave.hormoneBalance >= 200) {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 93) {
-					slave.height += jsEither([9, 9, 10, 10]);
-				} else if (slave.height <= 103) {
-					slave.height += 6;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 103) {
-					slave.height += jsEither([7, 7, 8, 8]);
-				} else if (slave.height <= 110) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 110) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 117) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 117) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 124) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 124) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 131) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 131) {
-					slave.height += jsEither([5, 5, 6, 6]);
-				} else if (slave.height <= 137) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 137) {
-					slave.height += jsEither([4, 4, 5, 5]);
-				} else if (slave.height <= 144) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 144) {
-					slave.height += jsEither([5, 5, 6, 6]);
-				} else if (slave.height <= 150) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 150) {
-					slave.height += jsEither([5, 5, 6, 6]);
-				} else if (slave.height <= 156) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 156) {
-					slave.height += jsEither([5, 5, 6, 6]);
-				} else if (slave.height <= 162) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 162) {
-					slave.height += jsEither([7, 7, 8, 8]);
-				} else if (slave.height <= 170) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 170) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 177) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 177) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 184) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 184) {
-					slave.height += jsEither([2, 2, 3, 3]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 185) {
-					slave.height += jsEither([1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 186) {
-					slave.height += jsEither([0, 0, 1, 1]);
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 93) {
-					slave.height += jsEither([9, 9, 9, 10, 10]);
-				} else if (slave.height <= 103) {
-					slave.height += 6;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 103) {
-					slave.height += jsEither([7, 7, 8, 8, 8]);
-				} else if (slave.height <= 110) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 110) {
-					slave.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (slave.height <= 117) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 117) {
-					slave.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (slave.height <= 124) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 124) {
-					slave.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (slave.height <= 131) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 131) {
-					slave.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (slave.height <= 137) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 137) {
-					slave.height += jsEither([4, 4, 5, 5, 5]);
-				} else if (slave.height <= 144) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 144) {
-					slave.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (slave.height <= 150) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 150) {
-					slave.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (slave.height <= 156) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 156) {
-					slave.height += jsEither([5, 5, 6, 6, 6]);
-				} else if (slave.height <= 162) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 162) {
-					slave.height += jsEither([7, 7, 8, 8, 8]);
-				} else if (slave.height <= 170) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 170) {
-					slave.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (slave.height <= 177) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 177) {
-					slave.height += jsEither([6, 6, 7, 7, 7]);
-				} else if (slave.height <= 184) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 184) {
-					slave.height += jsEither([2, 2, 3, 3, 3]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 185) {
-					slave.height += jsEither([1, 1, 2, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 186) {
-					slave.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 93) {
-					slave.height += jsEither([10, 10, 11, 11]);
-				} else if (slave.height <= 103) {
-					slave.height += 6;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 103) {
-					slave.height += jsEither([8, 8, 9, 9]);
-				} else if (slave.height <= 110) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 110) {
-					slave.height += jsEither([7, 7, 8, 8]);
-				} else if (slave.height <= 117) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 117) {
-					slave.height += jsEither([7, 7, 8, 8]);
-				} else if (slave.height <= 124) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 124) {
-					slave.height += jsEither([7, 7, 8, 8]);
-				} else if (slave.height <= 131) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 131) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 137) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 137) {
-					slave.height += jsEither([5, 5, 6, 6]);
-				} else if (slave.height <= 144) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 144) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 150) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 150) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 156) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 156) {
-					slave.height += jsEither([6, 6, 7, 7]);
-				} else if (slave.height <= 162) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 162) {
-					slave.height += jsEither([8, 8, 9, 9]);
-				} else if (slave.height <= 170) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 170) {
-					slave.height += jsEither([7, 7, 8, 8]);
-				} else if (slave.height <= 177) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 177) {
-					slave.height += jsEither([7, 7, 8, 8]);
-				} else if (slave.height <= 184) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 184) {
-					slave.height += jsEither([3, 3, 4, 4]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 185) {
-					slave.height += jsEither([2, 2, 3, 3]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 186) {
-					slave.height += jsEither([1, 1, 2, 2]);
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 93) {
-					slave.height += jsEither([10, 10, 10, 11, 11]);
-				} else if (slave.height <= 103) {
-					slave.height += 6;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 103) {
-					slave.height += jsEither([8, 8, 8, 9, 9]);
-				} else if (slave.height <= 110) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 110) {
-					slave.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (slave.height <= 117) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 117) {
-					slave.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (slave.height <= 124) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 124) {
-					slave.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (slave.height <= 131) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 131) {
-					slave.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (slave.height <= 137) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 137) {
-					slave.height += jsEither([5, 5, 5, 6, 6]);
-				} else if (slave.height <= 144) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 144) {
-					slave.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (slave.height <= 150) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 150) {
-					slave.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (slave.height <= 156) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 156) {
-					slave.height += jsEither([6, 6, 6, 7, 7]);
-				} else if (slave.height <= 162) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 162) {
-					slave.height += jsEither([8, 8, 8, 9, 9]);
-				} else if (slave.height <= 170) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 170) {
-					slave.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (slave.height <= 177) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 177) {
-					slave.height += jsEither([7, 7, 7, 8, 8]);
-				} else if (slave.height <= 184) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 184) {
-					slave.height += jsEither([3, 3, 3, 4, 4]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 185) {
-					slave.height += jsEither([2, 2, 2, 3, 3]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 186) {
-					slave.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			}
-		} else {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 93) {
-					slave.height += jsEither([9, 9, 10, 10, 10, 11]);
-				} else if (slave.height <= 103) {
-					slave.height += 6;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 103) {
-					slave.height += jsEither([7, 7, 8, 8, 9, 9]);
-				} else if (slave.height <= 110) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 110) {
-					slave.height += jsEither([6, 6, 7, 7, 8, 8]);
-				} else if (slave.height <= 117) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 117) {
-					slave.height += jsEither([6, 6, 7, 7, 8, 8]);
-				} else if (slave.height <= 124) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 124) {
-					slave.height += jsEither([6, 6, 7, 7, 8, 8]);
-				} else if (slave.height <= 131) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 131) {
-					slave.height += jsEither([5, 5, 6, 6, 7, 7]);
-				} else if (slave.height <= 137) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 137) {
-					slave.height += jsEither([4, 4, 5, 5, 5, 6]);
-				} else if (slave.height <= 144) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 144) {
-					slave.height += jsEither([5, 5, 6, 6, 7, 7]);
-				} else if (slave.height <= 150) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 150) {
-					slave.height += jsEither([5, 5, 6, 6, 6, 7]);
-				} else if (slave.height <= 156) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 156) {
-					slave.height += jsEither([5, 5, 6, 6, 7, 7]);
-				} else if (slave.height <= 162) {
-					slave.height += 3;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 162) {
-					slave.height += jsEither([7, 7, 8, 8, 9, 9]);
-				} else if (slave.height <= 170) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 170) {
-					slave.height += jsEither([6, 6, 7, 7, 8, 8]);
-				} else if (slave.height <= 177) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 177) {
-					slave.height += jsEither([6, 6, 7, 7, 8, 8]);
-				} else if (slave.height <= 184) {
-					slave.height += 4;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 184) {
-					slave.height += jsEither([2, 2, 3, 3, 4, 4]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 185) {
-					slave.height += jsEither([1, 1, 2, 2, 3, 3]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 186) {
-					slave.height += jsEither([0, 0, 1, 1, 2, 2]);
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseHeightDwarf(slave) {
-		if (slave.hormoneBalance >= 200) {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 80) {
-					slave.height += jsEither([1, 1, 2, 2]);
-				} else if (slave.height <= 84) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 84) {
-					slave.height += jsEither([4, 4, 5, 5]);
-				} else if (slave.height <= 90) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 90) {
-					slave.height += jsEither([8, 8, 9, 9]);
-				} else if (slave.height <= 100) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 100) {
-					slave.height += jsEither([3, 3, 4, 4]);
-				} else if (slave.height <= 105) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 105) {
-					slave.height += jsEither([2, 2, 3, 3]);
-				} else if (slave.height <= 109) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 109) {
-					slave.height += jsEither([3, 3, 4, 4]);
-				} else if (slave.height <= 114) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 114) {
-					slave.height += jsEither([2, 2, 3, 3]);
-				} else if (slave.height <= 118) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 118) {
-					slave.height += jsEither([2, 2, 3, 3]);
-				} else if (slave.height <= 122) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 122) {
-					slave.height += jsEither([3, 3, 4, 4]);
-				} else if (slave.height <= 127) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 127) {
-					slave.height += jsEither([3, 3, 4, 4]);
-				} else if (slave.height <= 132) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 132) {
-					slave.height += jsEither([1, 1, 2, 2]);
-				} else if (slave.height <= 135) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 135) {
-					slave.height += jsEither([1, 1, 2, 2]);
-				} else if (slave.height <= 138) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 138) {
-					slave.height += jsEither([1, 1, 2, 2]);
-				} else if (slave.height <= 141) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([0, 0, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([0, 0, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([0, 0, 1, 1]);
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 80) {
-					slave.height += jsEither([1, 1, 2, 2, 2]);
-				} else if (slave.height <= 84) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 84) {
-					slave.height += jsEither([4, 4, 5, 5, 5]);
-				} else if (slave.height <= 90) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 90) {
-					slave.height += jsEither([8, 8, 9, 9, 9]);
-				} else if (slave.height <= 100) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 100) {
-					slave.height += jsEither([3, 3, 4, 4, 4]);
-				} else if (slave.height <= 105) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 105) {
-					slave.height += jsEither([2, 2, 3, 3, 3]);
-				} else if (slave.height <= 109) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 109) {
-					slave.height += jsEither([3, 3, 4, 4, 4]);
-				} else if (slave.height <= 114) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 114) {
-					slave.height += jsEither([2, 2, 3, 3, 3]);
-				} else if (slave.height <= 118) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 118) {
-					slave.height += jsEither([2, 2, 3, 3, 3]);
-				} else if (slave.height <= 122) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 122) {
-					slave.height += jsEither([3, 3, 4, 4, 4]);
-				} else if (slave.height <= 127) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 127) {
-					slave.height += jsEither([3, 3, 4, 4, 4]);
-				} else if (slave.height <= 132) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 132) {
-					slave.height += jsEither([1, 1, 2, 2, 2]);
-				} else if (slave.height <= 135) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 135) {
-					slave.height += jsEither([1, 1, 2, 2, 2]);
-				} else if (slave.height <= 138) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 138) {
-					slave.height += jsEither([1, 1, 2, 2, 2]);
-				} else if (slave.height <= 141) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([0, 0, 1, 1, 1]);
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 80) {
-					slave.height += jsEither([2, 2, 3, 3]);
-				} else if (slave.height <= 84) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 84) {
-					slave.height += jsEither([5, 5, 6, 6]);
-				} else if (slave.height <= 90) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 90) {
-					slave.height += jsEither([9, 9, 10, 10]);
-				} else if (slave.height <= 100) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 100) {
-					slave.height += jsEither([4, 4, 5, 5]);
-				} else if (slave.height <= 105) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 105) {
-					slave.height += jsEither([3, 3, 4, 4]);
-				} else if (slave.height <= 109) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 109) {
-					slave.height += jsEither([4, 4, 5, 5]);
-				} else if (slave.height <= 114) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 114) {
-					slave.height += jsEither([3, 3, 4, 4]);
-				} else if (slave.height <= 118) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 118) {
-					slave.height += jsEither([3, 3, 4, 4]);
-				} else if (slave.height <= 122) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 122) {
-					slave.height += jsEither([4, 4, 5, 5]);
-				} else if (slave.height <= 127) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 127) {
-					slave.height += jsEither([4, 4, 5, 5]);
-				} else if (slave.height <= 132) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 132) {
-					slave.height += jsEither([2, 2, 3, 3]);
-				} else if (slave.height <= 135) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 135) {
-					slave.height += jsEither([2, 2, 3, 3]);
-				} else if (slave.height <= 138) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 138) {
-					slave.height += jsEither([2, 2, 3, 3]);
-				} else if (slave.height <= 141) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([1, 1, 2, 2]);
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 80) {
-					slave.height += jsEither([2, 2, 2, 3, 3]);
-				} else if (slave.height <= 84) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 84) {
-					slave.height += jsEither([5, 5, 5, 6, 6]);
-				} else if (slave.height <= 90) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 90) {
-					slave.height += jsEither([9, 9, 9, 10, 10]);
-				} else if (slave.height <= 100) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 100) {
-					slave.height += jsEither([4, 4, 4, 5, 5]);
-				} else if (slave.height <= 105) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 105) {
-					slave.height += jsEither([3, 3, 3, 4, 4]);
-				} else if (slave.height <= 109) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 109) {
-					slave.height += jsEither([4, 4, 4, 5, 5]);
-				} else if (slave.height <= 114) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 114) {
-					slave.height += jsEither([3, 3, 3, 4, 4]);
-				} else if (slave.height <= 118) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 118) {
-					slave.height += jsEither([3, 3, 3, 4, 4]);
-				} else if (slave.height <= 122) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 122) {
-					slave.height += jsEither([4, 4, 4, 5, 5]);
-				} else if (slave.height <= 127) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 127) {
-					slave.height += jsEither([4, 4, 4, 5, 5]);
-				} else if (slave.height <= 132) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 132) {
-					slave.height += jsEither([2, 2, 2, 3, 3]);
-				} else if (slave.height <= 135) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 135) {
-					slave.height += jsEither([2, 2, 2, 3, 3]);
-				} else if (slave.height <= 138) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 138) {
-					slave.height += jsEither([2, 2, 2, 3, 3]);
-				} else if (slave.height <= 141) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([1, 1, 1, 2, 2]);
-				}
-			}
-		} else {
-			if (physicalAgeSwap === 3) {
-				if (slave.height <= 80) {
-					slave.height += jsEither([1, 1, 2, 2, 3, 3]);
-				} else if (slave.height <= 84) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 4) {
-				if (slave.height <= 84) {
-					slave.height += jsEither([4, 4, 5, 5, 6, 6]);
-				} else if (slave.height <= 90) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 5) {
-				if (slave.height <= 90) {
-					slave.height += jsEither([8, 8, 9, 9, 10, 10]);
-				} else if (slave.height <= 100) {
-					slave.height += 5;
-				}
-			} else if (physicalAgeSwap === 6) {
-				if (slave.height <= 100) {
-					slave.height += jsEither([3, 3, 4, 4, 5, 5]);
-				} else if (slave.height <= 105) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 7) {
-				if (slave.height <= 105) {
-					slave.height += jsEither([2, 2, 3, 3, 4, 4]);
-				} else if (slave.height <= 109) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 8) {
-				if (slave.height <= 109) {
-					slave.height += jsEither([3, 3, 4, 4, 5, 5]);
-				} else if (slave.height <= 114) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.height <= 114) {
-					slave.height += jsEither([2, 2, 3, 3, 4, 4]);
-				} else if (slave.height <= 118) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.height <= 118) {
-					slave.height += jsEither([2, 2, 3, 3, 4, 4]);
-				} else if (slave.height <= 122) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.height <= 122) {
-					slave.height += jsEither([3, 3, 4, 4, 5, 5]);
-				} else if (slave.height <= 127) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.height <= 127) {
-					slave.height += jsEither([3, 3, 4, 4, 5, 5]);
-				} else if (slave.height <= 132) {
-					slave.height += 2;
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.height <= 132) {
-					slave.height += jsEither([1, 1, 2, 2, 3, 3]);
-				} else if (slave.height <= 135) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.height <= 135) {
-					slave.height += jsEither([1, 1, 2, 2, 3, 3]);
-				} else if (slave.height <= 138) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.height <= 138) {
-					slave.height += jsEither([1, 1, 2, 2, 3, 3]);
-				} else if (slave.height <= 141) {
-					slave.height += 1;
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([0, 0, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([0, 0, 1, 1, 2, 2]);
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.height <= 143) {
-					slave.height += jsEither([0, 0, 1, 1, 2, 2]);
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseHeightGiant(slave) {
-		if (slave.hormoneBalance >= 200) {
-			if (physicalAgeSwap < 16) {
-				if (slave.height <= 270) {
-					slave.height += jsRandom(5, 12);
-				}
-			} else {
-				if (slave.height <= 270) {
-					slave.height += jsRandom(3, 7);
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (physicalAgeSwap < 16) {
-				if (slave.height <= 270) {
-					slave.height += jsRandom(7, 15);
-				}
-			} else {
-				if (slave.height <= 270) {
-					slave.height += jsRandom(5, 7);
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap < 16) {
-				if (slave.height <= 270) {
-					slave.height += jsRandom(10, 25);
-				}
-			} else {
-				if (slave.height <= 270) {
-					slave.height += jsRandom(7, 13);
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap < 16) {
-				if (slave.height <= 270) {
-					slave.height += jsRandom(7, 22);
-				}
-			} else {
-				if (slave.height <= 270) {
-					slave.height += jsRandom(7, 12);
-				}
-			}
-		} else {
-			if (physicalAgeSwap < 16) {
-				if (slave.height <= 270) {
-					slave.height += jsRandom(7, 20);
-				}
-			} else {
-				if (slave.height <= 270) {
-					slave.height += jsRandom(5, 10);
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseHeightNeoteny(slave) {
-		if (physicalAgeSwap <= 12) {
-			if (slave.height <= 120) {
-				slave.height += jsEither([0, 0, 1, 1, 2, 2]);
-			}
-		} else if (physicalAgeSwap === 13) {
-			if (slave.height <= 120) {
-				slave.height += jsEither([0, 0, 1, 1, 2, 2]);
-			}
-		} else if (physicalAgeSwap === 14) {
-			if (slave.height <= 120) {
-				slave.height += jsEither([0, 0, 1, 1, 2, 2]);
-			}
-		} else if (physicalAgeSwap === 15) {
-			if (slave.height <= 120) {
-				slave.height += jsEither([0, 0, 1, 1, 2, 2]);
-			}
-		} else if (physicalAgeSwap === 16) {
-			if (slave.height <= 130) {
-				slave.height += jsEither([0, 0, 1, 1, 2, 2]);
-			}
-		} else if (physicalAgeSwap === 17) {
-			if (slave.height <= 130) {
-				slave.height += jsEither([0, 0, 1, 1, 2, 2]);
-			}
-		} else if (physicalAgeSwap === 18) {
-			if (slave.height <= 130) {
-				slave.height += jsEither([0, 0, 1, 1, 2, 2]);
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseBoobsXX(slave) {
-		if (slave.geneticQuirks.gigantomastia === 2 && slave.geneticQuirks.macromastia === 2) {
-			gigantomastiaMod = 3;
-		} else if (slave.geneticQuirks.gigantomastia === 2) {
-			gigantomastiaMod = 2;
-		} else if (slave.geneticQuirks.macromastia === 2) {
-			gigantomastiaMod = 1.5;
-		} else if (slave.geneticQuirks.gigantomastia === 3) {
-			gigantomastiaMod = 1.2;
-		} else if (slave.geneticQuirks.macromastia === 3) {
-			gigantomastiaMod = 1.1;
-		} else {
-			gigantomastiaMod = 1;
-		}
-		if (slave.hormoneBalance >= 200) {
-			if (physicalAgeSwap === 8) {
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 9) {
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 10) {
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 11) {
-				if (slave.boobs < (600 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			} else if (physicalAgeSwap === 12) {
-				if (slave.boobs < (700 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			} else if (physicalAgeSwap === 13) {
-				if (slave.boobs < (1000 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			} else if (physicalAgeSwap === 14) {
-				if (slave.boobs < (800 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			} else if (physicalAgeSwap === 15) {
-				if (slave.boobs < (900 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			} else if (physicalAgeSwap === 16) {
-				if (slave.boobs < (1200 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			} else if (physicalAgeSwap === 17) {
-				if (slave.boobs < (1600 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			} else if (physicalAgeSwap === 18) {
-				if (slave.boobs < (2000 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (physicalAgeSwap === 8) {
-				slave.boobs += 25;
-			} else if (physicalAgeSwap === 9) {
-				slave.boobs += 25;
-			} else if (physicalAgeSwap === 10) {
-				slave.boobs += 25;
-			} else if (physicalAgeSwap === 11) {
-				if (slave.boobs < (500 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 12) {
-				if (slave.boobs < (600 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 13) {
-				if (slave.boobs < (900 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 14) {
-				if (slave.boobs < (700 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 15) {
-				if (slave.boobs < (800 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 16) {
-				if (slave.boobs < (1000 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 17) {
-				if (slave.boobs < (1200 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 18) {
-				if (slave.boobs < (1600 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap >= 11) {
-				if (slave.boobs > 200 && gigantomastiaMod !== 3) {
-					slave.boobs -= 100;
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap >= 11) {
-				if (slave.boobs > 200 && gigantomastiaMod !== 3) {
-					slave.boobs -= 50;
-				}
-			}
-		} else {
-			if (physicalAgeSwap === 11) {
-				if (slave.boobs < (300 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.boobs < (300 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.boobs < (400 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.boobs < (500 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.boobs < (500 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.boobs < (800 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (50 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.boobs < (800 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (60 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.boobs < (800 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (70 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseBoobsXY(slave) {
-		if (slave.geneticQuirks.gigantomastia === 2 && slave.geneticQuirks.macromastia === 2) {
-			gigantomastiaMod = 3;
-		} else if (slave.geneticQuirks.gigantomastia === 2) {
-			gigantomastiaMod = 2;
-		} else if (slave.geneticQuirks.macromastia === 2) {
-			gigantomastiaMod = 1.5;
-		} else if (slave.geneticQuirks.gigantomastia === 3) {
-			gigantomastiaMod = 1.2;
-		} else if (slave.geneticQuirks.macromastia === 3) {
-			gigantomastiaMod = 1.1;
-		} else {
-			gigantomastiaMod = 1;
-		}
-		if (slave.hormoneBalance >= 200) {
-			if (physicalAgeSwap === 8) {
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 9) {
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 10) {
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 11) {
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 12) {
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 13) {
-				if (slave.boobs < (1000 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 14) {
-				if (slave.boobs < (800 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			} else if (physicalAgeSwap === 15) {
-				if (slave.boobs < (900 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			} else if (physicalAgeSwap === 16) {
-				if (slave.boobs < (1200 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			} else if (physicalAgeSwap === 17) {
-				if (slave.boobs < (1600 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			} else if (physicalAgeSwap === 18) {
-				if (slave.boobs < (2000 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 100;
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (physicalAgeSwap === 8) {
-				slave.boobs += 25;
-			} else if (physicalAgeSwap === 9) {
-				slave.boobs += 25;
-			} else if (physicalAgeSwap === 10) {
-				slave.boobs += 25;
-			} else if (physicalAgeSwap === 11) {
-				slave.boobs += 25;
-			} else if (physicalAgeSwap === 12) {
-				slave.boobs += 25;
-			} else if (physicalAgeSwap === 13) {
-				if (slave.boobs < (900 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 25;
-			} else if (physicalAgeSwap === 14) {
-				if (slave.boobs < (700 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 15) {
-				if (slave.boobs < (800 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 16) {
-				if (slave.boobs < (1000 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 17) {
-				if (slave.boobs < (1200 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			} else if (physicalAgeSwap === 18) {
-				if (slave.boobs < (1600 * gigantomastiaMod)) {
-					if (jsRandom(1, 100) > (40 / gigantomastiaMod)) {
-						slave.boobs += 100;
-					}
-				}
-				slave.boobs += 50;
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap >= 11) {
-				if (slave.boobs > 200 && gigantomastiaMod !== 3) {
-					slave.boobs -= 100;
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap >= 11) {
-				if (slave.boobs > 200 && gigantomastiaMod !== 3) {
-					slave.boobs -= 50;
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseHipsXX(slave) {
-		if (slave.geneticQuirks.uterineHypersensitivity === 2) {
-			uterineHypersensitivityMod = 1.5;
-		} else if (slave.geneticQuirks.uterineHypersensitivity === 1) {
-			uterineHypersensitivityMod = 1.2;
-		} else {
-			uterineHypersensitivityMod = 1;
-		}
-		if (slave.hormoneBalance >= 200) {
-			if (physicalAgeSwap === 8) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 90 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 90 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 90 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (physicalAgeSwap === 8) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 95 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 95 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 95 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 8) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 99 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 95 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 95 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 95 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 8) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 95 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 90 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 90 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 90 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			}
-		} else {
-			if (physicalAgeSwap === 8) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 90 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 60 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 60 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 60 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 60 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseHipsXY(slave) {
-		if (slave.geneticQuirks.uterineHypersensitivity === 2) {
-			uterineHypersensitivityMod = 1.3;
-		} else if (slave.geneticQuirks.uterineHypersensitivity === 1) {
-			uterineHypersensitivityMod = 1.15;
-		} else {
-			uterineHypersensitivityMod = 1;
-		}
-		if (slave.hormoneBalance >= 200) {
-			if (physicalAgeSwap === 8) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 90 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 90 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 90 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (physicalAgeSwap === 8) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 95 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 95 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 95 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 14) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 99 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 14) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 95 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			}
-		} else {
-			if (physicalAgeSwap === 14) {
-				if (slave.hips < 2) {
-					if (jsRandom(1, 100) > 60 / uterineHypersensitivityMod) {
-						slave.hips++;
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseButtXX(slave) {
-		rearQuirk = slave.geneticQuirks.rearLipedema === 2 ? 2 : 0;
-		rearQuirkDivider = rearQuirk === 0 ? 1 : rearQuirk;
-
-		if (slave.hormoneBalance >= 200) {
-			if (physicalAgeSwap === 8) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (80 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (80 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (80 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (20 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.butt < (4 + rearQuirk)) {
-					if (jsRandom(1, 100) > (20 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.butt < (4 + rearQuirk)) {
-					if (jsRandom(1, 100) > (20 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (physicalAgeSwap === 8) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (90 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (90 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (90 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (40 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.butt < (4 + rearQuirk)) {
-					if (jsRandom(1, 100) > (40 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.butt < (4 + rearQuirk)) {
-					if (jsRandom(1, 100) > (40 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 8) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (90 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (95 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (95 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (95 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 8) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (80 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (90 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (90 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (90 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			}
-		} else {
-			if (physicalAgeSwap === 8) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (60 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (60 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (60 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (60 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseButtXY(slave) {
-		rearQuirk = slave.geneticQuirks.rearLipedema === 2 ? 2 : 0;
-		rearQuirkDivider = rearQuirk === 0 ? 1 : rearQuirk;
-		if (slave.hormoneBalance >= 200) {
-			if (physicalAgeSwap === 8) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (80 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (80 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (80 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (20 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.butt < (4 + rearQuirk)) {
-					if (jsRandom(1, 100) > (20 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.butt < (4 + rearQuirk)) {
-					if (jsRandom(1, 100) > (20 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (physicalAgeSwap === 8) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (90 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (90 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (90 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (40 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.butt < (4 + rearQuirk)) {
-					if (jsRandom(1, 100) > (40 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 8) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (90 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 8) {
-				if (slave.butt < (3 + rearQuirk)) {
-					if (jsRandom(1, 100) > (80 / rearQuirkDivider)) {
-						slave.butt++;
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseDick(slave) {
-		dickMod = (slave.geneticQuirks.wellHung === 2 ? 2 : 1);
-
-		if (slave.hormoneBalance >= 200) {
-			//
-		} else if (slave.hormoneBalance >= 100) {
-			//
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 8) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (70 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.dick < 6 && dickMod === 2) {
-					if (jsRandom(1, 100) > 70) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (70 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (70 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (70 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (50 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (20 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (20 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (70 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (70 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (70 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 8) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (90 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.dick < 6 && dickMod === 2) {
-					if (jsRandom(1, 100) > 70) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (90 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (90 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (90 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (70 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (40 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (40 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (90 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (90 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (90 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			}
-		} else {
-			if (physicalAgeSwap === 9) {
-				if (slave.dick < 6 && dickMod === 2) {
-					if (jsRandom(1, 100) > 70) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.dick < 6 && dickMod === 2) {
-					if (jsRandom(1, 100) > 70) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.dick < 6 && dickMod === 2) {
-					if (jsRandom(1, 100) > 70) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.dick < 6 && dickMod === 2) {
-					if (jsRandom(1, 100) > 70) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (50 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (50 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.dick < 6) {
-					if (jsRandom(1, 100) > (50 / dickMod)) {
-						slave.dick++;
-						if (slave.foreskin > 0) {
-							slave.foreskin++;
-						}
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseBalls(slave) {
-		if (slave.hormoneBalance >= 200) {
-			//
-		} else if (slave.hormoneBalance >= 100) {
-			//
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 8) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 10) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 70) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 70) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 70) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 50) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 20) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 20) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 70) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 70) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 70) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 8) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 30) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 90) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 90) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 90) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 70) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 40) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 40) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 90) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 90) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 90) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			}
-		} else {
-			if (physicalAgeSwap === 8) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 50) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 50) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 50) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.balls < 6) {
-					if (jsRandom(1, 100) > 50) {
-						slave.balls++;
-						if (slave.scrotum > 0) {
-							slave.scrotum++;
-						}
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseClit(slave) {
-		if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 8) {
-				if (slave.clit < 4) {
-					if (jsRandom(1, 100) > 70) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.clit < 4) {
-					if (jsRandom(1, 100) > 70) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.clit < 4) {
-					if (jsRandom(1, 100) > 70) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.clit < 4) {
-					if (jsRandom(1, 100) > 50) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.clit < 4) {
-					if (jsRandom(1, 100) > 50) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.clit < 4) {
-					if (jsRandom(1, 100) > 50) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.clit < 4) {
-					if (jsRandom(1, 100) > 50) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.clit < 4) {
-					if (jsRandom(1, 100) > 50) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.clit < 4) {
-					if (jsRandom(1, 100) > 50) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.clit < 4) {
-					if (jsRandom(1, 100) > 50) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.clit < 4) {
-					if (jsRandom(1, 100) > 50) {
-						slave.clit++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap === 8) {
-				if (slave.clit.isBetween(0, 4)) {
-					if (jsRandom(1, 100) > 90) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 9) {
-				if (slave.clit.isBetween(0, 4)) {
-					if (jsRandom(1, 100) > 90) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 10) {
-				if (slave.clit.isBetween(0, 4)) {
-					if (jsRandom(1, 100) > 90) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 11) {
-				if (slave.clit.isBetween(0, 4)) {
-					if (jsRandom(1, 100) > 70) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 12) {
-				if (slave.clit.isBetween(0, 4)) {
-					if (jsRandom(1, 100) > 70) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 13) {
-				if (slave.clit.isBetween(0, 4)) {
-					if (jsRandom(1, 100) > 70) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 14) {
-				if (slave.clit.isBetween(0, 4)) {
-					if (jsRandom(1, 100) > 70) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 15) {
-				if (slave.clit.isBetween(0, 4)) {
-					if (jsRandom(1, 100) > 70) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 16) {
-				if (slave.clit.isBetween(0, 4)) {
-					if (jsRandom(1, 100) > 70) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 17) {
-				if (slave.clit.isBetween(0, 4)) {
-					if (jsRandom(1, 100) > 70) {
-						slave.clit++;
-					}
-				}
-			} else if (physicalAgeSwap === 18) {
-				if (slave.clit.isBetween(0, 4)) {
-					if (jsRandom(1, 100) > 70) {
-						slave.clit++;
-					}
-				}
-			}
-		}
-		if (physicalAgeSwap >= 11 && slave.geneticQuirks.wellHung === 2 && slave.clit < 5 && jsRandom(1, 100) > 60) {
-			slave.clit++;
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseWetness(slave) {
-		if (slave.geneticQuirks.uterineHypersensitivity === 2) {
-			uterineHypersensitivityMod = 1.5;
-		} else if (slave.geneticQuirks.uterineHypersensitivity === 1) {
-			uterineHypersensitivityMod = 1.2;
-		} else {
-			uterineHypersensitivityMod = 1;
-		}
-		if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap === 8 || physicalAgeSwap === 9) {
-				if (slave.vaginaLube < 1) {
-					if (jsRandom(1, 100) > 90 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				}
-			} else if (physicalAgeSwap <= 12) {
-				if (slave.vaginaLube < 1) {
-					if (jsRandom(1, 100) > 60 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				} else if (slave.vaginaLube < 2) {
-					if (jsRandom(1, 100) > 80 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				}
-			} else if (physicalAgeSwap <= 15) {
-				if (slave.vaginaLube < 1) {
-					if (jsRandom(1, 100) > 30 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				} else if (slave.vaginaLube < 2) {
-					if (jsRandom(1, 100) > 50 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				}
-			} else if (physicalAgeSwap <= 18) {
-				if (slave.vaginaLube < 1) {
-					if (jsRandom(1, 100) > 10 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				} else if (slave.vaginaLube < 2) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap > 9 && physicalAgeSwap <= 12) {
-				if (slave.vaginaLube < 1) {
-					if (jsRandom(1, 100) > 70 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				}
-			} else if (physicalAgeSwap <= 15) {
-				if (slave.vaginaLube < 1) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				} else if (slave.vaginaLube < 2) {
-					if (jsRandom(1, 100) > 70 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				}
-			} else if (physicalAgeSwap <= 18) {
-				if (slave.vaginaLube < 1) {
-					if (jsRandom(1, 100) > 20 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				} else if (slave.vaginaLube < 2) {
-					if (jsRandom(1, 100) > 40 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= 20) {
-			if (physicalAgeSwap > 15 && physicalAgeSwap <= 18) {
-				if (slave.vaginaLube < 1) {
-					if (jsRandom(1, 100) > 50 / uterineHypersensitivityMod) {
-						slave.vaginaLube++;
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseWaistXX(slave) {
-		if (slave.hormoneBalance >= 200) {
-			if (physicalAgeSwap >= 12) {
-				if (slave.waist > -60) {
-					if (jsRandom(1, 100) > 20) {
-						slave.waist -= 5;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (physicalAgeSwap >= 12) {
-				if (slave.waist > -30) {
-					if (jsRandom(1, 100) > 20) {
-						slave.waist -= 5;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap >= 12) {
-				if (slave.waist < 60) {
-					if (jsRandom(1, 100) > 20) {
-						slave.waist += 5;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap >= 12) {
-				if (slave.waist < 30) {
-					if (jsRandom(1, 100) > 20) {
-						slave.waist += 5;
-					}
-				}
-			}
-		} else {
-			if (physicalAgeSwap >= 12) {
-				if (slave.waist > -20) {
-					if (jsRandom(1, 100) > 60) {
-						slave.waist -= 5;
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseWaistXY(slave) {
-		if (slave.hormoneBalance >= 200) {
-			if (physicalAgeSwap >= 12) {
-				if (slave.waist > -30) {
-					if (jsRandom(1, 100) > 20) {
-						slave.waist -= 5;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (physicalAgeSwap >= 12) {
-				if (slave.waist > -15) {
-					if (jsRandom(1, 100) > 20) {
-						slave.waist -= 5;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (physicalAgeSwap >= 12) {
-				if (slave.waist < 90) {
-					if (jsRandom(1, 100) > 20) {
-						slave.waist += 5;
-					}
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (physicalAgeSwap >= 12) {
-				if (slave.waist < 60) {
-					if (jsRandom(1, 100) > 20) {
-						slave.waist += 5;
-					}
-				}
-			}
-		} else {
-			if (physicalAgeSwap >= 12) {
-				if (slave.waist < 20) {
-					if (jsRandom(1, 100) > 60) {
-						slave.waist += 5;
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseFaceXX(slave) {
-		if (slave.hormoneBalance >= 200) {
-			if (slave.face > 60) {
-				if (jsRandom(1, 100) > 80) {
-					slave.face += 5;
-				}
-			} else if (slave.face <= 60) {
-				if (jsRandom(1, 100) > 30) {
-					slave.face += 10;
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (slave.face > 60) {
-				if (jsRandom(1, 100) > 80) {
-					slave.face += 5;
-				}
-			} else if (slave.face <= 60) {
-				if (jsRandom(1, 100) > 30) {
-					slave.face += 10;
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (slave.face < 100) {
-				if (jsRandom(1, 100) > 50) {
-					slave.face -= 20;
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (slave.face < 100) {
-				if (jsRandom(1, 100) > 70) {
-					slave.face -= 20;
-				}
-			}
-		} else {
-			if (slave.face > 60) {
-				if (jsRandom(1, 100) > 90) {
-					slave.face += 5;
-				}
-			} else if (slave.face <= 60) {
-				if (jsRandom(1, 100) > 40) {
-					slave.face += 10;
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseFaceXY(slave) {
-		if (slave.hormoneBalance >= 200) {
-			if (slave.face > 60) {
-				if (jsRandom(1, 100) > 80) {
-					slave.face += 5;
-				}
-			} else if (slave.face <= 60) {
-				if (jsRandom(1, 100) > 50) {
-					slave.face += 10;
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (slave.face > 60) {
-				if (jsRandom(1, 100) > 80) {
-					slave.face += 10;
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseVoiceXX(slave) {
-		if (slave.hormoneBalance >= 200) {
-			if (slave.voice === 3) {
-				if (jsRandom(1, 100) > 90) {
-					slave.voice--;
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (slave.voice === 3) {
-				if (jsRandom(1, 100) > 80) {
-					slave.voice--;
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (slave.voice <= 3) {
-				if (jsRandom(1, 100) > 30) {
-					slave.voice--;
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (slave.voice <= 3) {
-				if (jsRandom(1, 100) > 60) {
-					slave.voice--;
-				}
-			}
-		} else {
-			if (slave.voice === 3) {
-				if (jsRandom(1, 100) > 60) {
-					slave.voice--;
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increaseVoiceXY(slave) {
-		if (slave.hormoneBalance >= 200) {
-			if (slave.voice < 2) {
-				if (jsRandom(1, 100) > 50) {
-					slave.voice--;
-				}
-			}
-		} else if (slave.hormoneBalance >= 100) {
-			if (slave.voice < 3) {
-				if (jsRandom(1, 100) > 50) {
-					slave.voice--;
-				}
-			}
-		} else if (slave.hormoneBalance <= -200) {
-			if (slave.voice > 1) {
-				if (jsRandom(1, 100) > 10) {
-					slave.voice--;
-				}
-			}
-		} else if (slave.hormoneBalance <= -100) {
-			if (slave.voice > 1) {
-				if (jsRandom(1, 100) > 30) {
-					slave.voice--;
-				}
-			}
-		} else {
-			if (slave.voice > 1) {
-				if (jsRandom(1, 100) > 60) {
-					slave.voice--;
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increasePregAdaptationXX(slave) {
-		if (physicalAgeSwap === 3) {
-			if (slave.pregAdaptation < 5) {
-				slave.pregAdaptation = 5;
-			}
-		} else if (physicalAgeSwap === 4) {
-			if (slave.pregAdaptation < 5) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 5) {
-			if (slave.pregAdaptation < 5) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 6) {
-			if (slave.pregAdaptation < 5) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 7) {
-			if (slave.pregAdaptation < 6) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 8) {
-			if (slave.pregAdaptation < 7) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 9) {
-			if (slave.pregAdaptation < 8) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 10) {
-			if (slave.pregAdaptation < 9) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 11) {
-			if (slave.pregAdaptation < 10) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 12) {
-			if (slave.pregAdaptation < 14) {
-				slave.pregAdaptation += 4;
-			}
-		} else if (physicalAgeSwap === 13) {
-			if (slave.pregAdaptation < 18) {
-				slave.pregAdaptation += 4;
-			}
-		} else if (physicalAgeSwap === 14) {
-			if (slave.pregAdaptation < 22) {
-				slave.pregAdaptation += 4;
-			}
-		} else if (physicalAgeSwap === 15) {
-			if (slave.pregAdaptation < 28) {
-				slave.pregAdaptation += 6;
-			}
-		} else if (physicalAgeSwap === 16) {
-			if (slave.pregAdaptation < 34) {
-				slave.pregAdaptation += 6;
-			}
-		} else if (physicalAgeSwap === 17) {
-			if (slave.pregAdaptation < 42) {
-				slave.pregAdaptation += 8;
-			}
-		} else if (physicalAgeSwap === 18) {
-			if (slave.pregAdaptation < 50) {
-				slave.pregAdaptation += 8;
-			}
-		}
-	}
-
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 */
-	function increasePregAdaptationXY(slave) {
-		if (physicalAgeSwap === 3) {
-			if (slave.pregAdaptation < 5) {
-				slave.pregAdaptation = 5;
-			}
-		} else if (physicalAgeSwap === 4) {
-			if (slave.pregAdaptation < 5) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 5) {
-			if (slave.pregAdaptation < 5) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 6) {
-			if (slave.pregAdaptation < 5) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 7) {
-			if (slave.pregAdaptation < 6) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 8) {
-			if (slave.pregAdaptation < 7) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 9) {
-			if (slave.pregAdaptation < 8) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 10) {
-			if (slave.pregAdaptation < 9) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 11) {
-			if (slave.pregAdaptation < 10) {
-				slave.pregAdaptation++;
-			}
-		} else if (physicalAgeSwap === 12) {
-			if (slave.pregAdaptation < 12) {
-				slave.pregAdaptation += 2;
-			}
-		} else if (physicalAgeSwap === 13) {
-			if (slave.pregAdaptation < 14) {
-				slave.pregAdaptation += 2;
-			}
-		} else if (physicalAgeSwap === 14) {
-			if (slave.pregAdaptation < 16) {
-				slave.pregAdaptation += 2;
-			}
-		} else if (physicalAgeSwap === 15) {
-			if (slave.pregAdaptation < 18) {
-				slave.pregAdaptation += 2;
-			}
-		} else if (physicalAgeSwap === 16) {
-			if (slave.pregAdaptation < 20) {
-				slave.pregAdaptation += 2;
-			}
-		} else if (physicalAgeSwap === 17) {
-			if (slave.pregAdaptation < 20) {
-				slave.pregAdaptation += 2;
-			}
-		} else if (physicalAgeSwap === 18) {
-			if (slave.pregAdaptation < 20) {
-				slave.pregAdaptation += 2;
-			}
-		}
-	}
-})();
diff --git a/src/js/pregJS.js b/src/js/pregJS.js
index e0facf9fe6d6f3ca93ade68995391bf32a3d6b0b..44529f375689fbb08e58a532020a120335122e7f 100644
--- a/src/js/pregJS.js
+++ b/src/js/pregJS.js
@@ -474,10 +474,12 @@ globalThis.getNurseryReserved = function( /* slaves */ ) {
 	return FetusGlobalReserveCount("nursery");
 };
 
+/** Find a slave's father, if they are also one of your slaves, wherever they may be
+ * @param {number} fatherID
+ * @returns {FC.HumanState}
+ */
 globalThis.findFather = function(fatherID) {
-	let father;
-
-	father = getSlave(fatherID);
+	let father = getSlave(fatherID);
 	if (father === undefined) {
 		if (V.incubator.capacity > 0) {
 			father = V.incubator.tanks.find(s => s.ID === fatherID);
@@ -492,13 +494,6 @@ globalThis.findFather = function(fatherID) {
 	return father;
 };
 
-globalThis.adjustFatherProperty = function(actor, property, newValue) {
-	let father = findFather(actor.ID);
-	if (father) {
-		father[property] = newValue;
-	}
-};
-
 /* not to be used until that last part is defined. It may become slave.boobWomb.volume or some shit */
 /**
  * @param {App.Entity.SlaveState} slave
diff --git a/src/Mods/Reminder/reminder.js b/src/js/reminder.js
similarity index 100%
rename from src/Mods/Reminder/reminder.js
rename to src/js/reminder.js
diff --git a/src/js/removeSlave.js b/src/js/removeSlave.js
index c651c4a507e2354022ea9a2bb95e90c829a92523..7afb953dd2961739af064e8765815b2607079d72 100644
--- a/src/js/removeSlave.js
+++ b/src/js/removeSlave.js
@@ -130,7 +130,7 @@ globalThis.removeSlave = function(slave) {
 		if (V.personalAttention.task === PersonalAttention.TRAINING) {
 			V.personalAttention.slaves.deleteWith(s => s.ID === AS_ID);
 			if (V.personalAttention.slaves.length === 0) {
-				App.personalAttention.reset();
+				App.PersonalAttention.reset();
 			}
 		}
 
diff --git a/src/js/rulesAssistant.js b/src/js/rulesAssistant.js
index ea79fadd5afb1cb743dd2494d96746da89000b68..8c41de45b58d4b562c664f84536b179cd08893d6 100644
--- a/src/js/rulesAssistant.js
+++ b/src/js/rulesAssistant.js
@@ -108,7 +108,6 @@ globalThis.RAFacilityRemove = function(slave, rule) {
 globalThis.ruleAppliesP = function(rule, slave) {
 	let V = State.variables;
 	let cond = rule.condition;
-	let slaveAttribute = slave[cond.data.attribute];
 
 	// Check if slave should be excluded from having rule applied to again
 	if (cond.applyRuleOnce) {
@@ -124,51 +123,15 @@ globalThis.ruleAppliesP = function(rule, slave) {
 		}
 	}
 
-	// assignment / facility / special slaves / specific slaves check
-	if (cond.assignment.length > 0 && !cond.assignment.includes(slave.assignment)) {
-		return false;
-	} else if (cond.selectedSlaves.length > 0 && !cond.selectedSlaves.includes(slave.ID)) {
+	//  special slaves / specific slaves check
+	if (cond.selectedSlaves.length > 0 && !cond.selectedSlaves.includes(slave.ID)) {
 		return false;
 	} else if (cond.excludedSlaves.includes(slave.ID)) {
 		return false;
 	}
 
 	// attribute / function check
-	let flag = true;
-	switch (cond.function) {
-		case false: // never applies
-			flag = false;
-			break;
-		case "between": // between two values of a slave's attribute
-			if (slaveAttribute === undefined && cond.data.attribute.includes(".")) {
-				slaveAttribute = cond.data.attribute
-					.split(".")
-					.reduce(
-						(reduceSlave, attribute) =>
-							(reduceSlave && reduceSlave[attribute] !== undefined)
-								? reduceSlave[attribute]
-								: undefined,
-						slave
-					);
-			}
-			// check if slave value is between rule values, if bounds exist
-			flag = (cond.data.value[0] === null || slaveAttribute > cond.data.value[0]) &&
-				(cond.data.value[1] === null || slaveAttribute < cond.data.value[1]);
-			break;
-		case "belongs": // the attribute belongs in the list of values
-			flag = cond.data.value.includes(slave[cond.data.attribute]);
-			break;
-		case "custom": // user provided JS function
-			// TODO: This should use a cached Function instead of 'eval'ing
-			try {
-				flag = eval(cond.data)(slave);
-			} catch (e) {
-				// Put together a more useful message for the player. Does mean we are losing the stacktrace.
-				throw new Error(`Rule '${rule.name}' custom condition failed: '${e.message}'`);
-			}
-			break;
-	}
-	if (!flag) {
+	if (!App.RA.Activation.evaluate(slave, cond.activation)) {
 		return false;
 	}
 
@@ -176,7 +139,7 @@ globalThis.ruleAppliesP = function(rule, slave) {
 		V.rulesToApplyOnce[rule.ID].push(slave.ID);
 	}
 	// If rule always applies.
-	if (cond.applyRuleOnce && !V.rulesToApplyOnce[rule.ID].includes(slave.ID) && flag) {
+	if (cond.applyRuleOnce && !V.rulesToApplyOnce[rule.ID].includes(slave.ID)) {
 		V.rulesToApplyOnce[rule.ID].push(slave.ID);
 	}
 
@@ -207,9 +170,7 @@ App.RA.newRule = function() {
 	/** @returns {FC.RA.RuleConditions} */
 	function emptyConditions() {
 		return {
-			function: false,
-			data: {},
-			assignment: [],
+			activation: ["devotion", 20, "gt", 1, "and"],
 			selectedSlaves: [],
 			excludedSlaves: [],
 			applyRuleOnce: false,
@@ -370,9 +331,13 @@ App.RA.newRule = function() {
 			shoulders: null,
 			shouldersImplant: null,
 			boobs: null,
+			boobsImplantTypes: null,
+			boobsImplantAllowReplacing: true,
 			hips: null,
 			hipsImplant: null,
 			butt: null,
+			buttImplantTypes: null,
+			buttImplantAllowReplacing: true,
 			faceShape: null,
 			lips: null,
 			holes: null,
@@ -417,18 +382,6 @@ App.RA.makeTarget = function(condition, val) {
 	};
 };
 
-/**
- * Creates RA range object used in rules
- * @param {number} minValue
- * @param {number} maxValue
- * @returns {FC.RA.NumericRange}
- */
-App.RA.makeRange = function(minValue, maxValue) {
-	return {
-		min: minValue, max: maxValue
-	};
-};
-
 /**
  * Shall the current value be increased according to the target and condition
  * @param {number} current
@@ -497,9 +450,7 @@ App.RA.ruleDeepAssign = function deepAssign(target, source) {
 globalThis.initRules = function() {
 	const rule = emptyDefaultRule();
 	rule.name = "Obedient Slaves";
-	rule.condition.function = "between";
-	rule.condition.data.attribute = "devotion";
-	rule.condition.data.value = [20, null];
+	rule.condition.activation = ["devotion", 20, "gte", 1, "and"];
 
 	V.defaultRules = [rule];
 	V.rulesToApplyOnce = {};
diff --git a/src/js/rulesAssistantOptions.js b/src/js/rulesAssistantOptions.js
index 70ba73f21535303c9fae4ac50794b30c47c87d4c..d47e17530bd85da037165d1c16ba5bef4abd7997 100644
--- a/src/js/rulesAssistantOptions.js
+++ b/src/js/rulesAssistantOptions.js
@@ -30,6 +30,10 @@ App.RA.options = (function() {
 			}
 		}
 		root = new Root(div);
+		V.passageSwitchHandler = () => {
+			saveSettings();
+			App.RA.Activation.Editor.reset();
+		};
 	}
 
 	function returnP(e) { return e.keyCode === 13; }
@@ -90,11 +94,20 @@ App.RA.options = (function() {
 
 	// reload the passage
 	function reload() {
+		saveSettings();
+		App.RA.Activation.Editor.reset();
 		const elem = root.element;
 		elem.innerHTML = "";
 		rulesAssistantOptions(elem);
 	}
 
+	/**
+	 * Save the settings for this rule.
+	 */
+	function saveSettings() {
+		App.RA.Activation.Editor.save(cond => current_rule.condition.activation = cond);
+	}
+
 	const parse = {
 		integer(string) {
 			let n = parseInt(string, 10);
@@ -824,7 +837,7 @@ App.RA.options = (function() {
 	class NumericRangeEditor extends EditorWithShortcuts {
 		/**
 		 * @param {string} prefix
-		 * @param {Array} [data=[]]
+		 * @param {Array<[string, FC.NumericRange]>} [data=[]]
 		 * @param {boolean} [allowNullValue=true]
 		 * @param {number} [min=0]
 		 * @param {number} [max=100]
@@ -891,7 +904,7 @@ App.RA.options = (function() {
 			const vMin = parse(this._minEditor.value);
 			const vMax = parse(this._maxEditor.value);
 			return (vMin === null && vMax === null) ? null
-				: App.RA.makeRange(vMin !== null ? vMin : this._min, vMax !== null ? vMax : this._max);
+				: App.Utils.makeRange(vMin !== null ? vMin : this._min, vMax !== null ? vMax : this._max);
 		}
 
 		setTextValue(what) {
@@ -1164,13 +1177,13 @@ App.RA.options = (function() {
 				const paragraph = document.createElement("p");
 				paragraph.innerHTML = "<strong>No rules</strong>";
 				this.appendChild(new Element(paragraph));
-				this.appendChild(new NoRules(this));
+				this.appendChild(new NoRules());
 				return;
 			}
-			this.appendChild(new RuleSelector(this));
-			this.appendChild(new RuleOptions(this));
-			this.appendChild(new ConditionEditor(this));
-			this.appendChild(new EffectEditor(this));
+			this.appendChild(new RuleSelector());
+			this.appendChild(new RuleOptions());
+			this.appendChild(new ConditionEditor());
+			this.appendChild(new EffectEditor());
 			App.UI.tabBar.handlePreSelectedTab("appearance", true);
 		}
 
@@ -1205,7 +1218,7 @@ App.RA.options = (function() {
 	// buttons for selecting the current rule
 	class RuleSelector extends List {
 		constructor() {
-			super("Current rule", V.defaultRules.map(i => [(i.name + (RuleHasError(i) ? " <span class='yellow'>[!]</span>" : "")), i]), false);
+			super("Current rule", V.defaultRules.map(i => [i.name, i]), false);
 			this.setValue(current_rule.name);
 			this.onchange = function(rule) {
 				V.currentRule = rule.ID;
@@ -1220,7 +1233,10 @@ App.RA.options = (function() {
 			super();
 			this.appendChild(new OptionsItem("New Rule", newRule));
 			this.appendChild(new OptionsItem("Remove Rule", removeRule));
-			this.appendChild(new OptionsItem("Apply rules", () => this.appendChild(new ApplicationLog())));
+			this.appendChild(new OptionsItem("Apply rules", () => {
+				saveSettings();
+				this.appendChild(new ApplicationLog());
+			}));
 			this.appendChild(new OptionsItem("Lower Priority", lowerPriority));
 			this.appendChild(new OptionsItem("Higher Priority", higherPriority));
 			this.appendChild(new OptionsItem("Rename", rename(this)));
@@ -1270,355 +1286,15 @@ App.RA.options = (function() {
 	class ConditionEditor extends Section {
 		constructor() {
 			super("Activation Condition");
-			this.appendChild(new ConditionFunction());
-			this.appendChild(new AssignmentInclusion());
-			this.appendChild(new FacilityHeadAssignmentInclusion());
+			this.appendChild(new ConditionBuilder());
 			this.appendChild(new SpecificInclusionExclusion());
 			this.appendChild(new ApplyRuleOnce());
 		}
 	}
 
-	class ConditionFunction extends Element {
-		constructor() {
-			super();
-			const items = [
-				["Never", false],
-				["Always", true],
-				["Custom", "custom"],
-				["Devotion", "devotion"],
-				["Trust", "trust"],
-				["Health", "health.condition"],
-				["Fatigue", "health.tired"],
-				["Sex", "genes"],
-				["Sex drive", "energy"],
-				["Height", "height"],
-				["Weight", "weight"],
-				["Age", "actualAge"],
-				["Body Age", "physicalAge"],
-				["Visible Age", "visualAge"],
-				["Muscles", "muscles"],
-				["Lactation", "lactation"],
-				["Pregnancy", "preg"],
-				["Pregnancy Multiples", "pregType"],
-				["Belly Implant", "bellyImplant"],
-				["Belly Size", "belly"],
-				["Education", "intelligenceImplant"],
-				["Intelligence", "intelligence"],
-				["Fetish", "fetish"],
-				["Accent", "accent"],
-				["Waist", "waist"],
-				["Amputation", "amp"],
-				["Carcinogen Buildup", "chem"],
-			];
-			this.fnlist = new List("Activation function", items, false);
-			this.fnlist.setValue(["between", "belongs"].includes(current_rule.condition.function) ? current_rule.condition.data.attribute : current_rule.condition.function);
-			this.fnlist.onchange = (value) => this.fnchanged(value);
-			this.appendChild(this.fnlist);
-			this.fneditor = null;
-
-			switch (current_rule.condition.function) {
-				case false:
-				case true:
-					break;
-				case "custom":
-					this.show_custom_editor(CustomEditor, current_rule.condition.data);
-					break;
-				case "between":
-					this.show_custom_editor(RangeEditor, current_rule.condition.function, current_rule.condition.data);
-					break;
-				case "belongs":
-					this.show_custom_editor(ItemEditor, current_rule.condition.function, current_rule.condition.data);
-					break;
-			}
-		}
-
-		betweenP(attribute) {
-			return [
-				"devotion",
-				"trust",
-				"health.condition",
-				"health.tired",
-				"energy",
-				"height",
-				"weight",
-				"actualAge",
-				"physicalAge",
-				"visualAge",
-				"muscles",
-				"lactation",
-				"preg",
-				"pregType",
-				"bellyImplant",
-				"belly",
-				"intelligenceImplant",
-				"intelligence",
-				"accent",
-				"waist",
-				"chem",
-			].includes(attribute);
-		}
-
-		belongsP(attribute) {
-			return [
-				"fetish",
-				"amp",
-				"genes",
-			].includes(attribute);
-		}
-
-		show_custom_editor(what, ...args) {
-			if (this.custom_editor !== null) { this.hide_custom_editor(); }
-			this.custom_editor = new what(...args);
-			this.appendChild(this.custom_editor);
-		}
-
-		hide_custom_editor() {
-			if (this.custom_editor) {
-				this.custom_editor.remove();
-				this.custom_editor = null;
-			}
-		}
-
+	class ConditionBuilder extends Element {
 		render() {
-			return document.createElement("div");
-		}
-
-		fnchanged(value) {
-			if (this.fneditor !== null) {
-				this.fneditor.element.remove();
-				this.fneditor = null;
-			}
-			if (value === true || value === false) {
-				current_rule.condition.function = value;
-				current_rule.condition.data = {};
-				this.hide_custom_editor();
-			} else if (value === "custom") {
-				current_rule.condition.function = "custom";
-				current_rule.condition.data = "";
-				this.show_custom_editor(CustomEditor, current_rule.condition.data);
-			} else if (this.betweenP(value)) {
-				current_rule.condition.function = "between";
-				current_rule.condition.data = {attribute: value, value: [null, null]};
-				this.show_custom_editor(RangeEditor, current_rule.condition.function, current_rule.condition.data);
-			} else if (this.belongsP(value)) {
-				current_rule.condition.function = "belongs";
-				current_rule.condition.data = {attribute: value, value: []};
-				this.show_custom_editor(ItemEditor, current_rule.condition.function, current_rule.condition.data);
-			}
-		}
-	}
-
-	class CustomEditor extends Element {
-		constructor(data) {
-			if (data.length === 0) { data = "(slave) => slave.slaveName === 'Fancy Name'"; }
-			super(data);
-		}
-
-		render(data) {
-			const elem = document.createElement("div");
-			const textarea = document.createElement("textarea");
-			textarea.innerHTML = data;
-			$(textarea).blur(() => {
-				current_rule.condition.data = textarea.value;
-				// TODO: this would be a good place to cache the Function object that will be used by RuleHasError and ruleAppliesP
-				reload();
-			});
-			elem.appendChild(textarea);
-
-			if (RuleHasError(current_rule)) {
-				const errorMessage = document.createElement("div");
-				$(errorMessage).addClass("yellow");
-				errorMessage.innerText = "WARNING: There are errors in this condition. Please ensure the syntax is correct and equality is either '==' or '===', not '='";
-				elem.appendChild(errorMessage);
-			}
-
-			const explanation = document.createElement("div");
-			explanation.innerHTML = `Insert <kbd>(slave) =></kbd> followed by a valid <a target='_blank' class='link-external' href='https://www.w3schools.com/js/js_comparisons.asp'>JavaScript comparison and/or logical operation</a>. For variable names to use see <a target='_blank' class='link-external' href='https://gitgud.io/pregmodfan/fc-pregmod/-/raw/pregmod-master/devNotes/legacy%20files/slave%20variables%20documentation.md'>this list</a>.`;
-			elem.appendChild(explanation);
-			return elem;
-		}
-	}
-
-
-	class RangeEditor extends Element {
-		render(fn, data) {
-			const elem = document.createElement("div");
-
-			const minlabel = document.createElement("label");
-			minlabel.innerHTML = "Lower bound: ";
-			elem.appendChild(minlabel);
-
-			const min = document.createElement("input");
-			min.setAttribute("type", "text");
-			min.value = `${data.value[0]}`;
-			min.onkeypress = e => { if (returnP(e)) { this.setmin(min.value); } };
-			min.onblur = e => this.setmin(min.value);
-			this.min = min;
-			elem.appendChild(min);
-
-			elem.appendChild(document.createElement("br"));
-
-			const maxLabel = document.createElement("label");
-			maxLabel.innerHTML = "Upper bound: ";
-			elem.appendChild(maxLabel);
-
-			const max = document.createElement("input");
-			max.setAttribute("type", "text");
-			max.value = `${data.value[1]}`;
-			max.onkeypress = e => { if (returnP(e)) { this.setmax(max.value); } };
-			max.onblur = e => this.setmax(max.value);
-			this.max = max;
-			elem.appendChild(max);
-
-			const infoBar = document.createElement("div");
-			infoBar.innerHTML = this.info(data.attribute);
-			elem.appendChild(infoBar);
-
-			return elem;
-		}
-
-		parse(value) {
-			value = value.trim();
-			if (value === "null") {
-				value = null;
-			} else {
-				value = parseInt(value);
-				if (isNaN(value)) { value = null; }
-			}
-			return value;
-		}
-
-		setmin(value) {
-			current_rule.condition.data.value[0] = this.parse(value);
-			this.min.value = `${current_rule.condition.data.value[0]}`;
-		}
-
-		setmax(value) {
-			current_rule.condition.data.value[1] = this.parse(value);
-			this.max.value = `${current_rule.condition.data.value[1]}`;
-		}
-
-		info(attribute) {
-			return ({
-				"devotion": "Very Hateful: (-∞, -95), Hateful: [-95, -50), Resistant: [-50, -20), Ambivalent: [-20, 20], Accepting: (20, 50], Devoted: (50, 95], Worshipful: (95, ∞)",
-				"trust": "Extremely terrified: (-∞, -95), Terrified: [-95, -50), Frightened: [-50, -20), Fearful: [-20, 20], Careful: (20, 50], Trusting: (50, 95], Total trust: (95, ∞)",
-				"health.condition": "Death: (-∞, -100), Near Death: [-100, -90), Extremely Unhealthy: [-90, -50), Unhealthy: [-50, -20), Healthy: [-20, 20], Very Healthy: (20, 50], Extremely Healthy: (50, 90], Unnaturally Healthy: (90, ∞)",
-				"health.tired": "Energetic: (-∞, 0], Rested: (0, 30], Tired: (30, 60], Fatigued: (60, 90], Exhausted: (90, ∞)",
-				"energy": "Frigid: (-∞, 20], Poor: (20, 40], Average: (40, 60], Powerful: (60, 80], Sex Addict: (80, 100), Nympho: 100",
-				"weight": "Emaciated: (-∞, -95), Skinny: [-95, -30), Thin: [-30, -10), Average: [-10, 10], Plush: (10, 30], Overweight: (30, 95], Fat: (95, 130], Obese: (130, 160], Super Obese: (160, 190], Dangerously Obese: (190, ∞)",
-				"lactation": "None: 0, 1: Natural, 2: Lactation implant",
-				"preg": "Barren: -2, On contraceptives: -1, Not pregnant: 0, Pregnancy weeks: [1, ∞)",
-				"pregType": "Fetus count, known only after the 10th week of pregnancy",
-				"bellyImplant": "Volume in CCs. None: -1",
-				"belly": "Volume in CCs, any source",
-				"intelligenceImplant": "Education level. 0: uneducated, 15: educated, 30: advanced education, (0, 15): incomplete education.",
-				"intelligence": "From moronic to brilliant: [-100, 100]",
-				"accent": "No accent: 0, Nice accent: 1, Bad accent: 2, Can't speak language: 3 and above",
-				"waist": "Masculine waist: (95, ∞), Ugly waist: (40, 95], Unattractive waist: (10, 40], Average waist: [-10, 10], Feminine waist: [-40, -10), Wasp waist: [-95, -40), Absurdly narrow: (-∞, -95)",
-			}[attribute] || " ");
-		}
-	}
-
-	class ItemEditor extends Element {
-		render(fn, data) {
-			const elem = document.createElement("div");
-
-			const input = document.createElement("input");
-			input.setAttribute("type", "text");
-			input.value = JSON.stringify(data.value);
-			input.onkeypress = e => { if (returnP(e)) { this.setValue(input); } };
-			input.onblur = e => this.setValue(input);
-			this.input = input;
-			elem.appendChild(input);
-
-			const infoBar = document.createElement("div");
-			infoBar.innerHTML = this.info(data.attribute);
-			elem.appendChild(infoBar);
-
-			return elem;
-		}
-
-		info(attribute) {
-			return `Insert a valid JSON array. Known values: ${{
-				"fetish": "buttslut, cumslut, masochist, sadist, dom, submissive, boobs, pregnancy, none (AKA vanilla)",
-				"amp": "Amputated: 1, Not amputated: 0",
-				"genes": "XX, XY",
-			}[attribute]}`;
-		}
-
-		setValue(input) {
-			try {
-				const arr = JSON.parse(input.value);
-				current_rule.condition.data.value = arr;
-				input.value = JSON.stringify(arr);
-			} catch (e) {
-				alert(e);
-			}
-		}
-	}
-
-	class AssignmentInclusionBase extends ButtonList {
-		/**
-		 * @param {string} label
-		 * @param {FC.Data.JobDesc[]} [jobs]
-		 * @param {App.Entity.Facilities.SingleJobFacility[]} [facilities]
-		 */
-		constructor(label, jobs, facilities) {
-			super(label);
-			this._attributes = {};
-			if (jobs !== undefined) {
-				jobs.forEach(job => {
-					this._attributes[capFirstChar(job.position)] = job.assignment;
-				});
-			}
-			if (facilities !== undefined) {
-				facilities.forEach(f => {
-					if (f.established && f.desc.defaultJob != null) { /* eslint-disable-line eqeqeq */
-						const displayName = f.name === "the " + f.genericName ? f.genericName : f.name;
-						this._attributes[displayName] = f.desc.jobs[f.desc.defaultJob].assignment;
-					}
-				});
-			}
-			for (const i in this._attributes) {
-				this.appendChild(new ButtonItem(i, this.getAttribute(i), current_rule.condition.assignment.includes(this.getAttribute(i))));
-			}
-		}
-
-		onchange() {
-			const allValues = this.getAllValues();
-			current_rule.condition.assignment = this.getSelection().concat(current_rule.condition.assignment.filter(a => !allValues.includes(a)));
-		}
-
-		getAttribute(what) {
-			return this._attributes[what];
-		}
-	}
-
-
-	class AssignmentInclusion extends AssignmentInclusionBase {
-		constructor() {
-			let facilities = [];
-			for (const f of Object.values(App.Entity.facilities)) {
-				if (f === App.Entity.facilities.penthouse) {
-					continue;
-				}
-				if (f.established) {
-					facilities.push(f);
-				}
-			}
-			super("Apply to assignments and facilities", Object.values(App.Data.Facilities.penthouse.jobs), facilities);
-		}
-	}
-
-	class FacilityHeadAssignmentInclusion extends AssignmentInclusionBase {
-		constructor() {
-			const jobs = [];
-			for (const f of Object.values(App.Entity.facilities)) {
-				if (f.established && f.desc.manager !== null) {
-					jobs.push(f.desc.manager);
-				}
-			}
-			super("Apply to facility heads", jobs);
+			return App.RA.Activation.Editor.build(current_rule.condition.activation);
 		}
 	}
 
@@ -1936,7 +1612,13 @@ App.RA.options = (function() {
 			this.appendChild(new CosmeticSurgeryList());
 			this.appendChild(new LipSurgeryList());
 			this.appendChild(new ButtSurgeryList());
+			this.appendChild(new SizingImplantType("butt", "butt"));
+			this.appendChild(new SizingImplantAllowReplacing("butt", "butt"));
 			this.appendChild(new BreastSurgeryList());
+			this.appendChild(new SizingImplantType("breast", "boobs"));
+			this.appendChild(new SizingImplantAllowReplacing("breast", "boobs"));
+			this.appendChild(new HipsAndShoulderSurgeryList("shoulders", "shoulders"));
+			this.appendChild(new HipsAndShoulderSurgeryList("pelvis", "hips"));
 			this.appendChild(new TighteningSurgeryList());
 			this.appendChild(new TummyTuckSurgeryList());
 			this.appendChild(new BodyHairSurgeryList());
@@ -2694,16 +2376,16 @@ App.RA.options = (function() {
 		constructor() {
 			const hdp = V.arcologies[0].FSHedonisticDecadence !== "unset";
 			const pairs = [
-				["emaciated", App.RA.makeRange(-100, -96)],
-				["very thin", App.RA.makeRange(-95, -31)],
-				["pleasingly thin", App.RA.makeRange(-30, -11)],
-				["healthy", App.RA.makeRange(-10, 10)],
-				["nicely plush", App.RA.makeRange(11, 30)],
-				[hdp ? "quite curvy" : "chubby", App.RA.makeRange(31, 95)],
-				[hdp ? "extremely curvy" : "overweight", App.RA.makeRange(96, 130)],
-				[hdp ? "amazingly curvy" : "very overweight", App.RA.makeRange(131, 160)],
-				[hdp ? "spectacularly curvy" : "extremely overweight", App.RA.makeRange(161, 190)],
-				[hdp ? "perfectly curvy" : "dangerously overweight", App.RA.makeRange(191, 200)]
+				["emaciated", App.Utils.makeRange(-100, -96)],
+				["very thin", App.Utils.makeRange(-95, -31)],
+				["pleasingly thin", App.Utils.makeRange(-30, -11)],
+				["healthy", App.Utils.makeRange(-10, 10)],
+				["nicely plush", App.Utils.makeRange(11, 30)],
+				[hdp ? "quite curvy" : "chubby", App.Utils.makeRange(31, 95)],
+				[hdp ? "extremely curvy" : "overweight", App.Utils.makeRange(96, 130)],
+				[hdp ? "amazingly curvy" : "very overweight", App.Utils.makeRange(131, 160)],
+				[hdp ? "spectacularly curvy" : "extremely overweight", App.Utils.makeRange(161, 190)],
+				[hdp ? "perfectly curvy" : "dangerously overweight", App.Utils.makeRange(191, 200)]
 			];
 			super("Weight", pairs, true, -100, 200);
 			this.setValue(current_rule.set.weight);
@@ -3137,7 +2819,7 @@ App.RA.options = (function() {
 	}
 	class IrisColorList extends List {
 		constructor() {
-			const items = App.Medicine.Modification.eyeColor.map(color => color.value);
+			const items = ["natural"].concat(App.Medicine.Modification.eyeColor.map(color => color.value));
 			super("Iris", items);
 			this.setValue(current_rule.set.iris);
 			this.onchange = (value) => current_rule.set.iris = value;
@@ -3145,7 +2827,7 @@ App.RA.options = (function() {
 	}
 	class PupilShapeList extends List {
 		constructor() {
-			const items = ["none"].concat(App.Medicine.Modification.eyeShape.map(shape => shape.value));
+			const items = ["natural"].concat(App.Medicine.Modification.eyeShape.map(shape => shape.value));
 			super("Pupil", items);
 			this.setValue(current_rule.set.pupil);
 			this.onchange = (value) => current_rule.set.pupil = value;
@@ -3153,7 +2835,7 @@ App.RA.options = (function() {
 	}
 	class ScleraColorList extends List {
 		constructor() {
-			const items = ["none"].concat(App.Medicine.Modification.eyeColor.map(color => color.value));
+			const items = ["natural"].concat(App.Medicine.Modification.eyeColor.map(color => color.value));
 			super("Sclera", items);
 			this.setValue(current_rule.set.sclera);
 			this.onchange = (value) => current_rule.set.sclera = value;
@@ -4085,45 +3767,45 @@ App.RA.options = (function() {
 		}
 	}
 
-	class LipSurgeryList extends NumericTargetEditor {
+	class LipSurgeryList extends NumericRangeEditor {
 		constructor() {
 			const items = [
-				["removed", 0],
-				["plush", 20],
-				["big", 40],
-				["huge", 70],
-				["facepussy", 95],
+				["removed", App.Utils.makeRange(0, 0)],
+				["plush", App.Utils.makeRange(20, 20)],
+				["big", App.Utils.makeRange(40, 40)],
+				["huge", App.Utils.makeRange(70, 70)],
+				["facepussy", App.Utils.makeRange(95, 95)],
 			];
-			super("Lip implants", items, true, 0, 95, true);
+			super("Lip implants", items, true, 0, 95);
 			this.setValue(current_rule.set.surgery.lips);
 			this.onchange = (value) => current_rule.set.surgery.lips = value;
 		}
 	}
 
-	class ButtSurgeryList extends NumericTargetEditor {
+	class ButtSurgeryList extends NumericRangeEditor {
 		constructor() {
 			const items = [
-				["removed", 0],
-				["slim", 2],
-				["stacked", 4],
-				["huge", 6],
-				["maximized", 9],
+				["removed", App.Utils.makeRange(0, 0)],
+				["slim", App.Utils.makeRange(2, 2)],
+				["stacked", App.Utils.makeRange(4, 4)],
+				["huge", App.Utils.makeRange(6, 6)],
+				["maximized", App.Utils.makeRange(9, 9)],
 			];
-			super("Buttock implants", items, true, 0, 9, true);
+			super("Buttock implants", items, true, 0, 9);
 			this.setValue(current_rule.set.surgery.butt);
 			this.onchange = (value) => current_rule.set.surgery.butt = value;
 		}
 	}
 
-	class BreastSurgeryList extends NumericTargetEditor {
+	class BreastSurgeryList extends NumericRangeEditor {
 		constructor() {
 			const items = [
-				["removed", 0],
-				["slim", 400],
-				["stacked", 1000],
-				["huge", 2000],
-				["barely functional", 9000],
-				["maximized", 48000]
+				["removed", App.Utils.makeRange(0, 0)],
+				["slim", App.Utils.makeRange(400, 400)],
+				["stacked", App.Utils.makeRange(1000, 1000)],
+				["huge", App.Utils.makeRange(2000, 2000)],
+				["barely functional", App.Utils.makeRange(9000, 9000)],
+				["maximized", App.Utils.makeRange(48000, 48000)]
 			];
 			super("Breast implants", items, true, 0, 48000, true);
 			this.setValue(current_rule.set.surgery.boobs);
@@ -4131,6 +3813,57 @@ App.RA.options = (function() {
 		}
 	}
 
+	class HipsAndShoulderSurgeryList extends ListSelector {
+		/**
+		 * @param {string} label
+		 * @param {string} target rule.set.surgery member name
+		 */
+		constructor(label, target ) {
+			const items = [
+				["Narrowing", -1],
+				["Broadening", 1]
+			];
+			if (V.surgeryUpgrade) {
+				items.unshift(["Advanced narrowing", -2]);
+				items.push(["Advanced broadening", 2]);
+			}
+			super(`${label.toUpperFirst()} change`, items, true);
+			this.setValue(current_rule.set.surgery[`${target}Implant`]);
+			this.onchange = (value) => current_rule.set.surgery[`${target}Implant`] = value;
+		}
+	}
+
+	class SizingImplantType extends MultiListSelector {
+		constructor(label, target) {
+			/** @type {Array<[string, FC.SizingImplantType]>} */
+			const items = [
+				["Normal", "normal"],
+				["Fillable", "fillable"],
+				["Advanced fillable", "advanced fillable"]
+			];
+			if (V.arcologies[0].FSTransformationFetishistResearch === 1) {
+				items.push(["Hyper fillable", "hyper fillable"]);
+			}
+			items.push(["String", "string"]);
+			super(`${label.toUpperFirst()} implant type`, items);
+			this.setValue(current_rule.set.surgery[`${target}ImplantTypes`]);
+			this.onchange = (value) => current_rule.set.surgery[`${target}ImplantTypes`] = value;
+		}
+	}
+
+	class SizingImplantAllowReplacing extends BooleanSwitch {
+		/**
+		 * @param {string} label
+		 * @param {FC.SizingImplantTarget} target
+		 */
+		constructor(label, target) {
+			super(`Replace other types of ${label} implants`);
+
+			this.setValue(current_rule.set.surgery[`${target}ImplantAllowReplacing`]);
+			this.onchange = (value) => current_rule.set.surgery[`${target}ImplantAllowReplacing`] = value;
+		}
+	}
+
 	class TighteningSurgeryList extends RadioSelector {
 		constructor() {
 			const items = [
diff --git a/src/js/rulesAutosurgery.js b/src/js/rulesAutosurgery.js
index 7771473e94b1813bd9dd4b159f6481c6591675fd..a471808277e3bc4db0453bd739e2a41cdedd135b 100644
--- a/src/js/rulesAutosurgery.js
+++ b/src/js/rulesAutosurgery.js
@@ -48,22 +48,22 @@ globalThis.rulesAutosurgery = (function() {
 				.map(x => x.set));
 		if ((thisSurgery.hips !== null) && (thisSurgery.butt !== null)) {
 			if (slave.hips < -1) {
-				if (App.RA.shallGrow(2, thisSurgery.butt)) {
-					thisSurgery.butt = App.RA.makeTarget('==', 2);
+				if (App.Utils.distanceToRange(2, thisSurgery.butt) > 0) {
+					thisSurgery.butt = App.Utils.makeRange(2, 2);
 				}
 			} else if (slave.hips < 0) {
-				if (App.RA.shallGrow(4, thisSurgery.butt)) {
-					thisSurgery.butt = App.RA.makeTarget('==', 4);
+				if (App.Utils.distanceToRange(4, thisSurgery.butt) > 0) {
+					thisSurgery.butt = App.Utils.makeRange(4, 4);
 				}
 			} else if (slave.hips > 0) {
-				if (App.RA.shallGrow(8, thisSurgery.butt)) {
-					thisSurgery.butt = App.RA.makeTarget('==', 8);
+				if (App.Utils.distanceToRange(8, thisSurgery.butt) > 0) {
+					thisSurgery.butt = App.Utils.makeRange(8, 8);
 				}
 			} else if (slave.hips > 1) {
 				// true
 			} else {
-				if (App.RA.shallGrow(6, thisSurgery.butt)) {
-					thisSurgery.butt = App.RA.makeTarget('==', 6);
+				if (App.Utils.distanceToRange(6, thisSurgery.butt) > 0) {
+					thisSurgery.butt = App.Utils.makeRange(8, 6);
 				}
 			}
 		}
@@ -92,56 +92,78 @@ globalThis.rulesAutosurgery = (function() {
 		}
 
 		/**
-		 *
-		 * @param {string} bodyPart
-		 * @param {!FC.RA.NumericTarget} target
+		 * Computes procedure efficiency for selecting the best one
+		 * @param {App.Medicine.Surgery.Procedure} proc
 		 */
-		function bodyPartSizing(bodyPart, target) {
-			const shallShrink = App.RA.shallShrink(slave[`${bodyPart}Implant`], target);
-			let shallGrow = false;
-			let options;
-			let sorter;
-			if (shallShrink) {
-				if (target.val === 0) {
-					commitProcedure(`surgery to remove ${his} ${bodyPart} implants`, () => {
-						slave[bodyPart] -= slave[`${bodyPart}Implant`];
-						slave[`${bodyPart}Implant`] = 0;
-						slave[`${bodyPart}ImplantType`] = "none";
-					});
-					return;
-				}
-				options = {reduction: true, replace: true};
-				sorter = (left, right) => -right.targetEffect / right.costs + left.targetEffect / left.costs;
-			} else if (App.RA.shallGrow(slave[`${bodyPart}Implant`], target)) {
-				shallGrow = true;
-				options = {augmentation: true, replace: true};
-				sorter = (left, right) => right.targetEffect / right.costs - left.targetEffect / left.costs;
+		function procedureEfficiency(proc) {
+			const value = typeof proc.changeValue === "number" ? Math.abs(proc.changeValue) : 1.;
+			return (value / proc.cost + value / proc.healthCost);
+		}
+
+		/**
+		 * @param {FC.SizingImplantTarget} bodyPart
+		 * @param {!FC.NumericRange} range
+		 * @param {FC.SizingImplantType[]} implantTypes
+		 * @param {boolean} replaceImplants
+		 */
+		function bodyPartSizing(bodyPart, range, implantTypes, replaceImplants) {
+			const current = App.Medicine.implantInfo(slave, bodyPart);
+			const distance = App.Utils.distanceToRange(current.volume, range);
+			const shallShrink = distance < 0;
+			const shallGrow = distance > 0;
+			const shallReplaceImplantType = replaceImplants && (current.volume > 0) &&
+				(implantTypes !== null && !implantTypes.some(v => v === current.type));
+
+			if (!shallShrink && !shallGrow && !shallReplaceImplantType) {
+				return;
 			}
-			if (!shallShrink && !shallGrow) { return; }
 
-			let surgeryOptions = App.Medicine.Surgery.sizingProcedures.bodyPart(bodyPart, slave, options);
+			let surgeryOptions = App.Medicine.Surgery.sizingProcedures.bodyPart(bodyPart, slave, {
+				allowedTypes: implantTypes ? new Set(implantTypes) : null,
+				replace: shallReplaceImplantType,
+				targetSize: range
+			});
 			surgeryOptions = surgeryOptions
 				.filter(surgery => surgery.disabledReasons.length === 0);
-			surgeryOptions = surgeryOptions.sort(sorter);
+			if (!surgeryOptions.length) {
+				return;
+			}
 
-			for (const so of surgeryOptions) {
-				if (shallShrink && App.RA.shallShrink(slave[`${bodyPart}Implant`], target, so.changeValue) ||
-					shallGrow && App.RA.shallGrow(slave[`${bodyPart}Implant`], target, so.changeValue)
-				) {
-					const [diff, reaction] = App.Medicine.Surgery.apply(so, false);
+			surgeryOptions.sort((a, b) => procedureEfficiency(b) - procedureEfficiency(a));
 
-					const result1 = reaction.reaction(slave, diff);
-					const result2 = reaction.outro(slave, diff, result1);
+			const so = surgeryOptions[0];
+			const surgeryResult = App.Medicine.Surgery.apply(so, false);
+			if (!surgeryResult) {
+				return;
+			}
+
+			const [diff, reaction] = surgeryResult;
+			const result1 =  reaction.reaction(slave, diff);
+			const result2 = reaction.outro(slave, diff, result1);
 
-					App.Utils.Diff.applyDiff(slave, diff);
+			App.Utils.Diff.applyDiff(slave, diff);
 
-					slave.devotion += result1.devotion + result2.devotion;
-					slave.trust += result1.trust + result2.trust;
+			slave.devotion += result1.devotion + result2.devotion;
+			slave.trust += result1.trust + result2.trust;
 
-					// TODO: shortReaction and devotion/trust changes
+			// TODO: shortReaction and devotion/trust changes
 
-					surgeries.push(`${so.description}`);
-					break;
+			surgeries.push(`${so.description}`);
+		}
+
+		/**
+		 *
+		 * @param {string} label
+		 * @param {"hips"|"shoulders"} target
+		 */
+		function pelvisShouldersImplants(label, target){
+			const request = thisSurgery[`${target}Implant}`];
+			if (Math.abs(request) > 0) {
+				if (Math.abs(request) < 2 || V.surgeryUpgrade) {
+					const change = request > 0 ? 1 : -1;
+					commitProcedure(`surgery to ${request > 0 ? "broaden" : "narrow"} ${his} ${label}`,
+						s => { s[target] += change; s[`${target}Implant}`] += change; },
+						40);
 				}
 			}
 		}
@@ -150,6 +172,10 @@ globalThis.rulesAutosurgery = (function() {
 			return `<span class='red'>Either this slave is extremely unwell or they are assigned to have more than two surgeries.</span>`;
 		}
 
+		// start with most damaging procedures
+		pelvisShouldersImplants("pelvis", "hips");
+		pelvisShouldersImplants("shoulders", "shoulders");
+
 		if (thisSurgery.eyes === 1 && anyVisionEquals(slave, 1)) {
 			// possibly two surgeries at once, in turn health cost is halved
 			if (getLeftEyeVision(slave) === 1) {
@@ -204,11 +230,15 @@ globalThis.rulesAutosurgery = (function() {
 				}
 			});
 		} else if (thisSurgery.boobs) {
-			bodyPartSizing("boobs", thisSurgery.boobs);
+			bodyPartSizing("boobs", thisSurgery.boobs, thisSurgery.boobsImplantTypes, thisSurgery.boobsImplantAllowReplacing);
 		}
 
 		if (thisSurgery.butt !== null) {
-			bodyPartSizing("butt", thisSurgery.butt);
+			bodyPartSizing("butt", thisSurgery.butt, thisSurgery.buttImplantTypes, thisSurgery.buttImplantAllowReplacing);
+		}
+
+		if (thisSurgery.lips != null) {
+			bodyPartSizing("lips", thisSurgery.lips, null, true);
 		}
 
 		if (slave.anus > 3 && thisSurgery.cosmetic > 0) {
@@ -290,8 +320,8 @@ globalThis.rulesAutosurgery = (function() {
 				slave.hStyle = "bald";
 				slave.bald = 1;
 			}, 0);
-		} else if (slave.weight >= 10 && thisSurgery.cosmetic > 0) {
-			commitProcedure("liposuction", s => { s.weight -= 50; });
+		} else if (slave.weight >= 60 && thisSurgery.cosmetic > 0) {
+			commitProcedure("liposuction", s => { s.weight = 10; });
 		} else if ((slave.bellySagPreg > 0 || slave.bellySag > 0) && (thisSurgery.cosmetic > 0 || thisSurgery.tummy > 0 )) {
 			commitProcedure("a tummy tuck", () => {
 				slave.bellySag = 0;
@@ -302,22 +332,6 @@ globalThis.rulesAutosurgery = (function() {
 				slave.voice += 1;
 				slave.voiceImplant += 1;
 			});
-		} else if (App.RA.shallShrink(slave.lipsImplant, thisSurgery.lips) && thisSurgery.lips.val === 0) {
-			commitProcedure(`surgery to remove ${his} lip implants`, () => {
-				slave.lips -= slave.lipsImplant;
-				slave.lipsImplant = 0;
-				if (slave.skill.oral > 10) {
-					slave.skill.oral -= 10;
-				}
-			});
-		} else if (App.RA.shallGrow(slave.lipsImplant, thisSurgery.lips, 10) && slave.lips <= 95) {
-			commitProcedure("bigger lips", () => {
-				slave.lipsImplant += 10;
-				slave.lips += 10;
-				if (slave.skill.oral > 10) {
-					slave.skill.oral -= 10;
-				}
-			});
 		} else if (slave.scar.hasOwnProperty("belly") && slave.scar.belly["c-section"] > 0 && thisSurgery.cosmetic > 0) {
 			commitProcedure("surgery to remove a c-section scar", s => { App.Medicine.Modification.removeScar(s, "belly", "c-section"); });
 		} else if (slave.faceImplant <= 45 && slave.face <= 95 && thisSurgery.cosmetic === 2) {
diff --git a/src/js/salon.js b/src/js/salon.js
index 127a647bc8a4ec9c53f620c8f96a8b12698754ea..356efbee4e24f1709ff41da44edf0f10e46712c1 100644
--- a/src/js/salon.js
+++ b/src/js/salon.js
@@ -1,6 +1,6 @@
 /**
  * @param {FC.HumanState} entity
- * @param {boolean} cheat
+ * @param {boolean} [cheat=false]
  * @returns {HTMLDivElement}
  */
 App.Medicine.Modification.eyeSelector = function(entity, cheat = false) {
diff --git a/src/js/sexActsJS.js b/src/js/sexActsJS.js
index 0c171a411bc7acbdcf5e124260bab10f563f2185..c77029ae723e49b6b32878ea9711eb14f27cc77f 100644
--- a/src/js/sexActsJS.js
+++ b/src/js/sexActsJS.js
@@ -506,4 +506,47 @@ globalThis.seX = function(slave1, act1, slave2, act2 = "penetrative", count = 1)
 		actX(slave2, act2, count);
 		addPartner(slave1, slave2);
 	}
+
+	/**
+	 * @param {FC.HumanState} slave
+	 * @param {FC.HumanState|FC.AnimalState|number} partner The slave's partner, or the ID of the slave's partner.
+	 *
+	 * | ***ID*** | **Type**              |
+	 * |---------:|:----------------------|
+	 * | *-1*     | PC                    |
+	 * | *-2*     | Citizen               |
+	 * | *-3*     | PC's former master    |
+	 * | *-4*     | Fellow arcology owner |
+	 * | *-6*     | Societal Elite        |
+	 * | *-8*     | Animal                |
+	 * | *-9*     | Futanari Sister       |
+	 */
+	function addPartner(slave, partner) {
+	/** @returns {FC.HumanState} */
+		function getPartnerState() {
+			if (typeof partner === "number") {
+				if (partner === -1) {
+					return V.PC;
+				} else if (partner > 0) {
+					return getSlave(partner);
+				}
+			} else if ("partners" in partner) {
+				return partner;
+			}
+			return null;
+		}
+
+		if (typeof partner === "number") {
+			slave.partners.add(partner);
+		} else if ("ID" in partner) {
+			slave.partners.add(partner.ID);
+		} else {
+			throw new TypeError(`Partner must be an object or ID, not "${partner}"`);
+		}
+
+		const partnerState = getPartnerState();
+		if (partnerState) {
+			partnerState.partners.add(slave.ID);
+		}
+	}
 };
diff --git a/src/js/slaveCostJS.js b/src/js/slaveCostJS.js
index 0bb4e8a41d4b0e56c92d32bc87cee2f4aec73edf..fbf8596cb9b2e8801f3681d730ce2f1b8ade8f2f 100644
--- a/src/js/slaveCostJS.js
+++ b/src/js/slaveCostJS.js
@@ -200,7 +200,7 @@ globalThis.BeautyArray = (function() {
 				}
 			} else {
 				if (heightPass(slave)) {
-					let ageDiv = (slave.physicalAge >= 16) ? 1 : (16 - slave.physicalAge); // this could probably be better, but bad at math. Intent is for younger, and thus naturally shorter than the threshold, slaves receive a weaker bonus.
+					const ageDiv = (slave.physicalAge >= 16) ? 1 : (16 - slave.physicalAge); // this could probably be better, but bad at math. Intent is for younger, and thus naturally shorter than the threshold, slaves receive a weaker bonus.
 					adjustBeauty("Height: Petite Admiration", ((161 - slave.height) * ((arcology.FSPetiteAdmiration / 50) + 0.5) / ageDiv));
 				} else if (slave.height >= 170) {
 					adjustBeauty("Height: Petite Admiration", -((slave.height - 169) * (arcology.FSPetiteAdmiration / 50)));
@@ -214,10 +214,11 @@ globalThis.BeautyArray = (function() {
 					adjustBeauty("Height: Statuesque Glorification, law", -((Height.mean(slave) - slave.height) * (arcology.FSStatuesqueGlorification / 50)));
 				}
 			} else {
+				const effectiveHeight = slave.height + shoeHeight(slave);
 				if (heightPass(slave)) {
-					adjustBeauty("Height: Statuesque Glorification", ((slave.height + shoeHeight(slave) - 169) * ((arcology.FSStatuesqueGlorification / 50) + 0.5)));
+					adjustBeauty("Height: Statuesque Glorification", ((effectiveHeight - 169) * ((arcology.FSStatuesqueGlorification / 50) + 0.5)));
 				} else {
-					adjustBeauty("Height: Statuesque Glorification", -(((arcology.FSStatuesqueGlorification / 10) + (170 - slave.height + shoeHeight(slave))) * 2));
+					adjustBeauty("Height: Statuesque Glorification", -(((arcology.FSStatuesqueGlorification / 10) + (170 - effectiveHeight)) * 2));
 				}
 			}
 		} else {
@@ -233,33 +234,33 @@ globalThis.BeautyArray = (function() {
 		switch (slave.faceShape) {
 			case "masculine":
 				if (arcology.FSGenderRadicalist !== "unset") {
-					adjustBeauty("Face: Gender Radicalist", -((2 - (arcology.FSGenderRadicalist / 25)) * (slave.face / 30)));
+					adjustBeauty("Masculine face: Gender Radicalist", -((2 - (arcology.FSGenderRadicalist / 25)) * (slave.face / 30)));
 				} else if (arcology.FSGenderFundamentalist !== "unset") {
-					adjustBeauty("Face: Gender Fundamentalist", -((2 + (arcology.FSGenderFundamentalist / 25)) * (slave.face / 30)));
+					adjustBeauty("Masculine face: Gender Fundamentalist", -((2 + (arcology.FSGenderFundamentalist / 25)) * (slave.face / 30)));
 				} else {
-					adjustBeauty("Face: General", -(2 * (slave.face / 30)));
+					adjustBeauty("Masculine face: General", -(2 * (slave.face / 30)));
 				}
 				break;
 			case "androgynous":
 				if (arcology.FSGenderRadicalist !== "unset") {
-					adjustBeauty("Face: Gender Radicalist", (2 - ((1 - (arcology.FSGenderRadicalist / 25)) * (slave.face / 30))));
+					adjustBeauty("Androgynous face: Gender Radicalist", (2 - ((1 - (arcology.FSGenderRadicalist / 25)) * (slave.face / 30))));
 				} else if (arcology.FSGenderFundamentalist !== "unset") {
-					adjustBeauty("Face: Gender Fundamentalist", (2 - ((1 + (arcology.FSGenderFundamentalist / 25)) * (slave.face / 30))));
+					adjustBeauty("Androgynous face: Gender Fundamentalist", (2 - ((1 + (arcology.FSGenderFundamentalist / 25)) * (slave.face / 30))));
 				} else {
-					adjustBeauty("Face: General", (2 - (slave.face / 30)));
+					adjustBeauty("Androgynous face: General", (2 - (slave.face / 30)));
 				}
 				break;
 			case "exotic":
-				adjustBeauty("Face: General", (2 * (slave.face / 30)));
+				adjustBeauty("Exotic face: General", (2 * (slave.face / 30)));
 				break;
 			case "feline":
-				adjustBeauty("Face: General", (2 * (slave.face / 30)));
+				adjustBeauty("Feline face: General", (2 * (slave.face / 30)));
 				break;
 			case "sensual":
-				adjustBeauty("Face: General", (2 + (slave.face / 30)));
+				adjustBeauty("Sensual face: General", (2 + (slave.face / 30)));
 				break;
 			case "cute":
-				adjustBeauty("Face: General", (8 / 3));
+				adjustBeauty("Cute face: General", (8 / 3));
 				break;
 		}
 	}
@@ -340,7 +341,8 @@ globalThis.BeautyArray = (function() {
 	 */
 	function calcCosmeticsBeauty(slave) {
 		if (V.rep > 10000 || V.rep < 5000) {
-			if (Object.values(slave.brand).includes(V.brandDesign.official)) {
+			const brands = App.Medicine.Modification.brandRecord(slave);
+			if (Object.values(brands).includes(V.brandDesign.official)) {
 				if (V.rep > 10000) {
 					adjustBeauty("Brand: Famous", (1));
 				} else if (V.rep < 5000) {
@@ -351,12 +353,10 @@ globalThis.BeautyArray = (function() {
 		if (slave.minorInjury !== 0) {
 			adjustBeauty("Minor Injury", -(2));
 		}
-		if (slave.scar !== {}) {
-			const scars = Object.keys(slave.scar);
-			for (const bodypart of scars) {
-				if (slave.scar[bodypart].surgical > 0) {
-					adjustBeauty("Scar", -(slave.scar[bodypart].surgical));
-				}
+		const scars = App.Medicine.Modification.scarRecord(slave);
+		for (const bodypart of Object.keys(scars)) {
+			if (scars[bodypart].surgical > 0) {
+				adjustBeauty("Scar", -(scars[bodypart].surgical));
 			}
 		}
 		if (slave.nails > 0) {
@@ -382,9 +382,9 @@ globalThis.BeautyArray = (function() {
 				break;
 			case "freckles":
 			case "heavily freckled":
-				if ((skinToneLevel(slave.skin) > 5) && (skinToneLevel(slave.skin) < 10)) {
+				if (App.Medicine.Modification.naturalSkins.includes(slave.skin) && skinToneLevel(slave.skin).isBetween(5, 10)) {
 					adjustBeauty("Freckles", 2);
-					if (slave.hColor === "red") {
+					if (App.Data.misc.redheadColors.includes(slave.hColor)) {
 						adjustBeauty("Freckles: Redhead", 2);
 					}
 				}
@@ -431,12 +431,12 @@ globalThis.BeautyArray = (function() {
 			adjustBeauty("Skilled: Slave Professionalism", ((arcology.FSSlaveProfessionalism / 50) * ((slave.skill.entertainment + slave.skill.whoring + slave.skill.oral + slave.skill.anal + slave.skill.vaginal) / 100))); /* 10 */
 		}
 		if (arcology.FSYouthPreferentialist !== "unset") {
-			if (V.retirementAge <= 60) {
-				adjustBeauty("Age: Youth Preferentialist", ((30 - slave.visualAge) / (30 - V.minimumSlaveAge) * ((arcology.FSYouthPreferentialist / 2) + (arcology.FSYouthPreferentialistLaw * 10)))); /* max 60 */
+			if(slave.visualAge < 30) {
+				adjustBeauty("Age: Youth Preferentialist", Math.clamp(((arcology.FSYouthPreferentialist / 2) + (arcology.FSYouthPreferentialistLaw * 10)) - Math.round(Math.abs(slave.visualAge - V.idealAge) * 2.222),0,60)); /* max 60 */
 			}
 		} else if (arcology.FSMaturityPreferentialist !== "unset") {
-			if (V.retirementAge.isBetween(30, 60, true)) {
-				adjustBeauty("Age: Maturity Preferentialist", ((30 - slave.visualAge) / (30 - V.retirementAge) * ((arcology.FSMaturityPreferentialist / 2) + (arcology.FSMaturityPreferentialistLaw * 10)))); /* max 60, problems if retirementAge is 30 or under */
+			if(slave.visualAge >= 30 && slave.visualAge < 60) {
+				adjustBeauty("Age: Maturity Preferentialist", Math.clamp(((arcology.FSMaturityPreferentialist / 2) + (arcology.FSMaturityPreferentialistLaw * 10)) - Math.round(Math.abs(slave.visualAge - V.idealAge) * 2.222),0,60)); /* max 60 */
 			}
 		}
 		if (arcology.FSBodyPurist > 20) {
@@ -500,7 +500,8 @@ globalThis.BeautyArray = (function() {
 		adjustBeauty(`Voice Pitch`, (slave.voice));
 		adjustBeauty(`Skill: Entertainment (${slave.skill.entertainment})`, (slave.skill.entertainment / 10));
 		adjustBeauty(`Skill: Whoring (${slave.skill.whoring})`, (slave.skill.whoring / 10));
-		adjustBeauty(`Age: Visual Age (${slave.visualAge})`, -(3 * slave.visualAge));
+		const ageBeautyPenaltyOffset = slave.visualAge - V.idealAge === 0 ? 0 : 9;
+		adjustBeauty(`Age: Visual Age (${slave.visualAge})`, -((3 * Math.abs(slave.visualAge - V.idealAge)) + ageBeautyPenaltyOffset));
 		if (App.Data.Careers.General.entertainment.includes(slave.career)) {
 			adjustBeauty("Career: Entertainment", (20));
 		} else if (V.week - slave.weekAcquired >= 20 && slave.skill.entertainment >= 100) {
@@ -561,7 +562,7 @@ globalThis.BeautyArray = (function() {
 			} else if (slave.balls > 60) {
 				adjustBeauty("Huge Balls: Asset Expansionist", (6 + (slave.balls * (arcology.FSAssetExpansionist / 800)))); /* 16 */
 			} else if (slave.balls > 10) {
-				adjustBeauty("Vestigial Balls: Asset Expansionist", (slave.balls * (arcology.FSAssetExpansionist / 1000))); /* 6 */
+				adjustBeauty("Big Balls: Asset Expansionist", (slave.balls * (arcology.FSAssetExpansionist / 1000))); /* 6 */
 			}
 		} else if (arcology.FSGenderFundamentalist !== "unset") {
 			if (slave.scrotum > 0) {
@@ -576,7 +577,7 @@ globalThis.BeautyArray = (function() {
 				} else if (slave.balls > 10) {
 					adjustBeauty("Huge Scrotum: Gender Radicalist", (15 + (slave.balls * (arcology.FSGenderRadicalist / 400)))); /* 30 */
 				} else {
-					adjustBeauty("Vestigial Scrotum: Gender Radicalist", (slave.balls * (1 + (arcology.FSGenderRadicalist / 200)))); /* 15 */
+					adjustBeauty("Scrotum: Gender Radicalist", (slave.balls * (1 + (arcology.FSGenderRadicalist / 200)))); /* 15 */
 				}
 			}
 		} else {
@@ -640,7 +641,7 @@ globalThis.BeautyArray = (function() {
 				}
 			} else {
 				if (slave.butt >= 6) {
-					if (slave.buttImplant / slave.butt < 0.50) {
+					if (slave.buttImplant / slave.butt < 0.5) {
 						adjustBeauty("Butt Implant: General", -((1.5 * slave.butt) + 6)); /* will get nasty at huge sizes */
 					}
 				}
@@ -770,7 +771,7 @@ globalThis.BeautyArray = (function() {
 							adjustBeauty("Boob Implant: Slimness Enthusiast", -((0.05 * slave.boobs) + 10));
 						}
 					} else if (slave.boobs >= 2000) {
-						if (slave.boobsImplant / slave.boobs < 0.50) {
+						if (slave.boobsImplant / slave.boobs < 0.5) {
 							adjustBeauty("Boob Implant: Slimness Enthusiast", -((0.05 * slave.boobs) + 10));
 						}
 					} else if (slave.boobs >= 1000) {
@@ -778,7 +779,7 @@ globalThis.BeautyArray = (function() {
 							adjustBeauty("Boob Implant: Slimness Enthusiast", -((0.05 * slave.boobs) + 10));
 						}
 					} else {
-						if (slave.boobsImplant / slave.boobs < 0.10) {
+						if (slave.boobsImplant / slave.boobs < 0.1) {
 							adjustBeauty("Boob Implant: Slimness Enthusiast", -((0.05 * slave.boobs) + 10));
 						}
 					}
@@ -790,7 +791,7 @@ globalThis.BeautyArray = (function() {
 							adjustBeauty("Boob Implant: General", -(30 + (0.005 * slave.boobs))); /* will get nasty at huge sizes */
 						}
 					} else if (slave.boobs >= 2000) {
-						if (slave.boobsImplant / slave.boobs < 0.50) {
+						if (slave.boobsImplant / slave.boobs < 0.5) {
 							adjustBeauty("Boob Implant: General", -(30 + (0.005 * slave.boobs))); /* will get nasty at huge sizes */
 						}
 					} else if (slave.boobs >= 1000) {
@@ -798,7 +799,7 @@ globalThis.BeautyArray = (function() {
 							adjustBeauty("Boob Implant: General", -(30 + (0.005 * slave.boobs))); /* will get nasty at huge sizes */
 						}
 					} else {
-						if (slave.boobsImplant / slave.boobs < 0.10) {
+						if (slave.boobsImplant / slave.boobs < 0.1) {
 							adjustBeauty("Boob Implant: General", -(30 + (0.005 * slave.boobs))); /* will get nasty at huge sizes */
 						}
 					}
@@ -2320,12 +2321,13 @@ globalThis.FResultTooltip = function(slave, forSale = 0) {
  * @param {boolean} [isStartingSlave=false] is the slave a "starting slave"
  * @param {boolean} [followLaws=false] Apply cost variations from enacted Slave Market Regulations
  * @param {boolean} [isSpecial=false] is this slave a special/hero slave
+	* @param {object} [fromMarket=null] is this slave from the market
  * @param {boolean} [returnDOM]
  * @returns {number|Object}
  */
-globalThis.slaveCost = function(slave, isStartingSlave = false, followLaws = false, isSpecial = false, returnDOM = false) {
+globalThis.slaveCost = function(slave, isStartingSlave = false, followLaws = false, isSpecial = false, returnDOM = false, fromMarket = null) {
 	const milked = App.SlaveAssignment.getMilked(slave, 1.0, true);
-	const beautyObj = slaveCostBeauty(slave, isStartingSlave, followLaws, isSpecial);
+	const beautyObj = slaveCostBeauty(slave, isStartingSlave, followLaws, isSpecial, fromMarket);
 	const cost = beautyObj.cost;
 	/** Arbitrarily, let's say their milk worth is what they would make in a year. Blocking starting slave for now because milk makes so much money, the estimation makes game start impossible. */
 	const milkYear = milked.cash * 52;
@@ -2437,49 +2439,54 @@ globalThis.slaveCost = function(slave, isStartingSlave = false, followLaws = fal
 	}
 };
 
-globalThis.slaveCostBeauty = (function() {
-	"use strict";
-
-	/** @type {FC.ArcologyState} */
-	let arcology;
-	let multiplier;
-	let cost;
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @param {boolean} isStartingSlave is the slave a "starting slave"
+ * @param {boolean} followLaws Apply cost variations from enacted Slave Market Regulations
+ * @param {boolean} isSpecial is this slave a special/hero slave
+	* @param {object} [fromMarket=null] is this slave from the market
+ * @returns {Object}
+ */
+globalThis.slaveCostBeauty = function(slave, isStartingSlave, followLaws, isSpecial, fromMarket) {
+	const arcology = V.arcologies[0];
+	let multiplier = V.slaveCostFactor;
+	let cost = Beauty(slave) * FResult(slave, 1);
 	const map = new Map([]);
 
-	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {boolean} isStartingSlave is the slave a "starting slave"
-	 * @param {boolean} followLaws Apply cost variations from enacted Slave Market Regulations
-	 * @param {boolean} isSpecial is this slave a special/hero slave
-	 * @returns {Object}
-	 */
-	function slaveCost(slave, isStartingSlave, followLaws, isSpecial) {
-		arcology = V.arcologies[0];
-		multiplier = V.slaveCostFactor;
-		cost = Beauty(slave) * FResult(slave, 1);
+	calcGenitalsCost(slave);
+	calcDevotionTrustCost(slave, isSpecial);
+	calcPreferencesCost(slave);
+	calcPregCost(slave);
+	if (slave.prestige + slave.porn.prestige > 0) {
+		calcPrestigeCost(slave);
+	}
+	calcFSCost(slave);
+	if (V.seeAge === 1) {
+		calcAgeCost(slave);
+	}
+	calcCareersCost(slave);
+	calcMiscCost(slave);
+	calcIndentureCost(slave); /* multipliers */
 
-		calcGenitalsCost(slave);
-		calcDevotionTrustCost(slave, isSpecial);
-		calcPreferencesCost(slave);
-		calcPregCost(slave);
-		if (slave.prestige + slave.porn.prestige > 0) {
-			calcPrestigeCost(slave);
-		}
-		calcFSCost(slave);
-		if (V.seeAge === 1) {
-			calcAgeCost(slave);
-		}
-		calcCareersCost(slave);
-		calcMiscCost(slave);
-		calcIndentureCost(slave); /* multipliers */
+	calcCost(followLaws);
+	if (isStartingSlave) {
+		calcStartingSlaveCost(slave);
+	}
 
-		calcCost(followLaws);
-		if (isStartingSlave) {
-			calcStartingSlaveCost(slave);
+	if (fromMarket) {
+		if (fromMarket.limitReached) {
+			cost += cost * ((V.slavesSeen - V.slaveMarketLimit) * 0.1); // updateMultiplier(`Market reach exceeded`, (cost * (V.slavesSeen - V.slaveMarketLimit)));
+		}		
+		if (fromMarket.costMod > 0 && fromMarket.costMod <= 1) {
+			cost *= fromMarket.costMod;
+		} else {
+			cost += fromMarket.costMod;
 		}
-		return {cost: cost, map: map};
+		cost = 500 * Math.trunc(cost / 500);
 	}
 
+	return {cost: cost, map: map};
+
 	/**
 	 * @param {App.Entity.SlaveState} slave
 	 */
@@ -2749,46 +2756,44 @@ globalThis.slaveCostBeauty = (function() {
 	 * @param {App.Entity.SlaveState} slave
 	 */
 	function calcCareersCost(slave) {
-		if (slave.career !== 0) {
-			if (slave.career === "a slave") {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.bodyguard.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.wardeness.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.attendant.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.nurse.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.matron.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.schoolteacher.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.stewardess.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.milkmaid.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.farmer.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.madam.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.DJ.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.HG.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.Leader.recruiter.includes(slave.career)) {
-				updateMultiplier(`career`, 0.1);
-			} else if (App.Data.Careers.General.entertainment.includes(slave.career)) {
-				updateMultiplier(`career`, 0.05);
-			} else if (App.Data.Careers.General.whore.includes(slave.career)) {
-				updateMultiplier(`career`, 0.05);
-			} else if (App.Data.Careers.General.grateful.includes(slave.career)) {
-				updateMultiplier(`career`, 0.05);
-			} else if (App.Data.Careers.General.menial.includes(slave.career)) {
-				updateMultiplier(`career`, 0.05);
-			} else if (App.Data.Careers.General.servant.includes(slave.career)) {
-				updateMultiplier(`career`, 0.05);
-			}
+		if (slave.career === "a slave") {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.bodyguard.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.wardeness.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.attendant.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.nurse.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.matron.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.schoolteacher.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.stewardess.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.milkmaid.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.farmer.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.madam.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.DJ.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.HG.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.Leader.recruiter.includes(slave.career)) {
+			updateMultiplier(`career`, 0.1);
+		} else if (App.Data.Careers.General.entertainment.includes(slave.career)) {
+			updateMultiplier(`career`, 0.05);
+		} else if (App.Data.Careers.General.whore.includes(slave.career)) {
+			updateMultiplier(`career`, 0.05);
+		} else if (App.Data.Careers.General.grateful.includes(slave.career)) {
+			updateMultiplier(`career`, 0.05);
+		} else if (App.Data.Careers.General.menial.includes(slave.career)) {
+			updateMultiplier(`career`, 0.05);
+		} else if (App.Data.Careers.General.servant.includes(slave.career)) {
+			updateMultiplier(`career`, 0.05);
 		}
 		if (V.week - slave.weekAcquired >= 20 && slave.skill.entertainment >= 100) {
 			if (!App.Data.Careers.General.entertainment.includes(slave.career)) {
@@ -2864,10 +2869,11 @@ globalThis.slaveCostBeauty = (function() {
 		if (slave.geneticQuirks.albinism === 2) {
 			updateMultiplier(`albinism`, 0.2);
 		}
+		const brands = App.Medicine.Modification.brandRecord(slave);
 		if (V.rep > 10000) {
-			updateMultiplier(`high rep brand`, 0.1 * (Object.getOwnPropertyNames(slave.brand).length));
+			updateMultiplier(`high rep brand`, 0.1 * (Object.getOwnPropertyNames(brands).length));
 		} else if (V.rep < 5000) {
-			updateMultiplier(`low rep brand`, -0.1 * (Object.getOwnPropertyNames(slave.brand).length));
+			updateMultiplier(`low rep brand`, -0.1 * (Object.getOwnPropertyNames(brands).length));
 		}
 		updateMultiplier(`limbs`, -getLimbCount(slave, 0) * 0.05);
 		if (!canSee(slave)) {
@@ -2977,9 +2983,7 @@ globalThis.slaveCostBeauty = (function() {
 			multiplier += value;
 		}
 	}
-
-	return slaveCost;
-})();
+};
 
 /**
  * @param {App.Entity.SlaveState} slave
diff --git a/src/js/slaveExpenses.js b/src/js/slaveExpenses.js
index 7aa54a24094c1b50929a2992b07b230df8911736..7b19a7891534005c9a8d3ff8211270e72933a7f7 100644
--- a/src/js/slaveExpenses.js
+++ b/src/js/slaveExpenses.js
@@ -65,7 +65,7 @@ globalThis.slaveImpactLongTerm = function(slave) {
 	let text;
 
 	// Background and original cost
-	if (slave.origin !== 0) {
+	if (slave.origin !== "") {
 		App.UI.DOM.appendNewElement("div", frag, pronounsForSlaveProp(slave, slave.origin), "indent");
 	}
 	div = document.createElement("div");
@@ -80,7 +80,7 @@ globalThis.slaveImpactLongTerm = function(slave) {
 		cost = slave.slaveCost;
 	} else {
 		text = `You have no record of how much `;
-		if (slave.origin !== 0) {
+		if (slave.origin !== "") {
 			text += `this`;
 		} else {
 			text += `${he} originally`;
diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js
index e0a2470ee3aae76bae5259da169e09eb5a65cf9b..935ad0682be9fbd760154bf8867eb6ab1c82d285 100644
--- a/src/js/slaveListing.js
+++ b/src/js/slaveListing.js
@@ -132,10 +132,9 @@ App.UI.SlaveList.render = function() {
 		}
 		const slave = slaveStateById(id);
 
-		if (batchRenderer) {
+		if (batchRenderer && (!V.seeCustomImagesOnly || (V.seeCustomImagesOnly && slave.custom.image))) {
 			let imgDiv = document.createElement("div");
-			imgDiv.classList.add("imageRef");
-			imgDiv.classList.add("smlImg");
+			imgDiv.classList.add("imageRef", "smlImg", "margin-right");
 			imgDiv.appendChild(batchRenderer.render(slave));
 			res.appendChild(imgDiv);
 		}
@@ -156,11 +155,6 @@ App.UI.SlaveList.render = function() {
 		if ((slave.assignment === Job.REST) && (slave.health.condition >= -20)) {
 			assignment.className = "freeAssignment";
 			assignment.innerText = slave.assignment;
-		} else if ((slave.assignment === Job.CONFINEMENT) && ((slave.devotion > 20) || ((slave.trust < -20) && (slave.devotion >= -20)) || ((slave.trust < -50) && (slave.devotion >= -50)))) {
-			assignment.innerText = slave.assignment;
-			if (slave.sentence > 0) {
-				assignment.innerText += ` (${slave.sentence} weeks)`;
-			}
 		} else if (slave.choosesOwnAssignment === 1) {
 			assignment.innerText = `choose ${getPronouns(slave).possessive} own job`;
 		} else {
@@ -459,6 +453,15 @@ App.UI.SlaveList.Decoration.penthousePositions = function(slave) {
 	if (fcs.armory.manager.isEmployed(slave)) {
 		return App.UI.DOM.makeElement("span", 'BG', ['lightcoral', 'strong']);
 	}
+	return App.UI.SlaveList.Decoration.personalAttention(slave);
+};
+
+/**
+ * returns just the "PA" prefix
+ * @param {App.Entity.SlaveState} slave
+ * @returns {HTMLElement}
+ */
+App.UI.SlaveList.Decoration.personalAttention = function(slave) {
 	if (V.personalAttention.task === PersonalAttention.TRAINING && V.personalAttention.slaves.some(s => s.ID === slave.ID)) {
 		return App.UI.DOM.makeElement("span", 'PA', ['lightcoral', 'strong']);
 	}
@@ -503,23 +506,26 @@ App.UI.SlaveList.SlaveInteract.stdInteract = function(slave, text) {
 		App.UI.SlaveList.ScrollPosition.record();
 		V.AS = slave.ID;
 	});
+
 	if (V.favorites.includes(slave.ID)) {
 		return App.UI.DOM.combineNodes(
 			App.UI.DOM.makeElement("span", String.fromCharCode(0xe800), ["icons", "favorite"]),
 			" ", link);
 	}
+
 	return link;
 };
 
 /**
  * @param {App.Entity.SlaveState} slave
+ * @param {slaveToElement} decoratorFunction
  * @returns {DocumentFragment|HTMLElement}
  */
-App.UI.SlaveList.SlaveInteract.penthouseInteract = function(slave) {
-	let decoration = App.UI.SlaveList.Decoration.penthousePositions(slave);
-	let stdLink = App.UI.SlaveList.SlaveInteract.stdInteract(slave);
+App.UI.SlaveList.SlaveInteract.decoratedInteract = function(slave, decoratorFunction) {
+	const decoration = decoratorFunction ? decoratorFunction(slave) : null;
+	const stdLink = App.UI.SlaveList.SlaveInteract.stdInteract(slave);
 	if (decoration) {
-		let fr = document.createDocumentFragment();
+		const fr = document.createDocumentFragment();
 		fr.appendChild(decoration);
 		fr.appendChild(document.createTextNode(' '));
 		fr.appendChild(stdLink);
@@ -537,22 +543,18 @@ App.UI.SlaveList.sortingLinks = function(passage) {
 	const textify = string => capFirstChar(string.replace(/([A-Z])/g, " $1"));
 
 	let span = App.UI.DOM.makeElement("span", "Sort by: ");
-	let order = ["devotion", "trust", "name", "assignment", "seniority", "actualAge", "visualAge", "physicalAge", "weeklyIncome", "health", "weight", "muscles", "intelligence", "sexDrive", "pregnancy"];
-	const select = App.UI.DOM.appendNewElement("select", span);
-
-	for (const so of order) {
-		const choice = App.UI.DOM.appendNewElement("option", select, textify(so));
-		choice.value = so;
-		if (V.sortSlavesBy === so) {
-			choice.selected = true;
-		}
-	}
+	let order = ["devotion", "trust", "name", "assignment", "seniority", "actualAge", "visualAge", "physicalAge", "weeklyIncome", "health", "weight", "muscles", "intelligence", "sexDrive", "pregnancy", "prestige"];
+	const orderMap = order.map(so => {
+		return {key: so, name: capFirstChar(so)};
+	});
 
-	select.onchange = () => {
-		V.sortSlavesBy = select.options[select.selectedIndex].value;
-		App.UI.reload();
-	};
-	div.append(span);
+	div.append(
+		span,
+		App.UI.DOM.makeSelect(orderMap, V.sortSlavesBy, val => {
+			V.sortSlavesBy = val;
+			App.UI.reload();
+		}),
+	);
 
 	span = App.UI.DOM.makeElement("span", " Sort direction: ");
 	order = ["descending", "ascending"];
@@ -569,16 +571,17 @@ App.UI.SlaveList.sortingLinks = function(passage) {
  * @param {string} [facilityPassage]
  * @param {boolean} [showTransfersTab=false]
  * @param {{assign: string, remove: string, transfer: (string| undefined)}} [tabCaptions]
+ * @param {slaveToElement} [decoratorFunction]
  * @returns {DocumentFragment}
  */
-App.UI.SlaveList.listSJFacilitySlaves = function(facility, facilityPassage, showTransfersTab = false, tabCaptions = undefined) {
+App.UI.SlaveList.listSJFacilitySlaves = function(facility, facilityPassage, showTransfersTab = false, tabCaptions = undefined, decoratorFunction = undefined) {
 	const job = facility.job();
 
 	facilityPassage = facilityPassage || passage();
 	tabCaptions = tabCaptions || {
 		assign: 'Assign a slave',
 		remove: 'Remove a slave',
-		transfer: 'Transfer from Facility'
+		transfer: 'Transfer from Facility',
 	};
 	const frag = document.createDocumentFragment();
 	if (V.sortSlavesMain) {
@@ -600,7 +603,7 @@ App.UI.SlaveList.listSJFacilitySlaves = function(facility, facilityPassage, show
 	if (facilitySlaves.length > 0) {
 		SlaveSort.IDs(facilitySlaves);
 		tabBar.addTab(tabCaptions.remove, "remove", App.UI.SlaveList.render(facilitySlaves, [],
-			App.UI.SlaveList.SlaveInteract.stdInteract,
+			(slave) => App.UI.SlaveList.SlaveInteract.decoratedInteract(slave, decoratorFunction),
 			(slave) => App.UI.DOM.link(`Retrieve ${getPronouns(slave).object} from ${facility.name}`, () => removeJob(slave, job.desc.assignment), [], facilityPassage)
 		));
 	} else {
@@ -643,7 +646,7 @@ App.UI.SlaveList.listSJFacilitySlaves = function(facility, facilityPassage, show
 			}
 		}, []);
 		return App.UI.SlaveList.render(passedSlaves, rejectedSlaves,
-			App.UI.SlaveList.SlaveInteract.stdInteract,
+			(slave) => App.UI.SlaveList.SlaveInteract.decoratedInteract(slave, decoratorFunction),
 			(slave) => App.UI.DOM.link(`Send ${getPronouns(slave).object} to ${facility.name}`, () => { assignmentTransition(slave, job.desc.assignment, facilityPassage); }));
 	}
 };
@@ -749,6 +752,9 @@ App.UI.SlaveList.stdFacilityPage = function(facility, showTransfersPage) {
 
 App.UI.SlaveList.penthousePage = function() {
 	const ph = App.Entity.facilities.penthouse;
+	/** @type {slaveToElement} */
+	const interactRenderer = (slave) =>
+		App.UI.SlaveList.SlaveInteract.decoratedInteract(slave, App.UI.SlaveList.Decoration.penthousePositions);
 
 	function overviewTabContent() {
 		const fragment = document.createDocumentFragment();
@@ -766,8 +772,7 @@ App.UI.SlaveList.penthousePage = function() {
 			const link = App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Manage Head Girl", "Head Girl Select"), "major-link");
 			link.id = "manageHG";
 			slaveWrapper.append(link, " ", App.UI.DOM.makeElement("span", App.UI.Hotkeys.hotkeys("Head Girl Select"), "hotkey"));
-			slaveWrapper.append(App.UI.SlaveList.render([HG.ID], [],
-				App.UI.SlaveList.SlaveInteract.penthouseInteract));
+			slaveWrapper.append(App.UI.SlaveList.render([HG.ID], [], interactRenderer));
 		} else {
 			if (V.slaves.length > 1) {
 				slaveWrapper.append("You have ", App.UI.DOM.makeElement("span", "not", "warning"), " selected a Head Girl");
@@ -807,8 +812,7 @@ App.UI.SlaveList.penthousePage = function() {
 			const link = App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Manage Recruiter", "Recruiter Select"), "major-link");
 			link.id = "manageRecruiter";
 			slaveWrapper.append(link, " ", App.UI.DOM.makeElement("span", App.UI.Hotkeys.hotkeys("Recruiter Select"), "hotkey"));
-			slaveWrapper.append(App.UI.SlaveList.render([RC.ID], [],
-				App.UI.SlaveList.SlaveInteract.penthouseInteract));
+			slaveWrapper.append(App.UI.SlaveList.render([RC.ID], [], interactRenderer));
 		} else {
 			slaveWrapper.append("You have ", App.UI.DOM.makeElement("span", "not", "warning"), " selected a Recruiter. ",
 				App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Select one", "Recruiter Select"), "major-link"),
@@ -829,8 +833,7 @@ App.UI.SlaveList.penthousePage = function() {
 				const link = App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Manage Bodyguard", "BG Select"), "major-link");
 				link.id = "manageBG";
 				slaveWrapper.append(link, " ", App.UI.DOM.makeElement("span", App.UI.Hotkeys.hotkeys("BG Select"), "hotkey"));
-				slaveWrapper.append(App.UI.SlaveList.render([BG.ID], [],
-					App.UI.SlaveList.SlaveInteract.penthouseInteract));
+				slaveWrapper.append(App.UI.SlaveList.render([BG.ID], [], interactRenderer));
 				slaveWrapper.append(App.MainView.useGuard());
 			} else {
 				slaveWrapper.append("You have ", App.UI.DOM.makeElement("span", "not", "warning"), " selected a Bodyguard. ",
@@ -860,8 +863,8 @@ App.UI.SlaveList.penthousePage = function() {
 		SlaveSort.IDs(employeesIDs);
 		return {
 			n: employeesIDs.length,
-			dom: App.UI.SlaveList.render(employeesIDs, [], App.UI.SlaveList.SlaveInteract.penthouseInteract,
-				V.fucktoyInteractionsPosition === 1 && job === "fucktoy" ? App.MainView.useFucktoy : null)
+			dom: App.UI.SlaveList.render(employeesIDs, [], interactRenderer,
+				V.fucktoyInteractionsPosition === 1 && job === "fucktoy" ? App.MainView.useFucktoy : null),
 		};
 	}
 
@@ -882,7 +885,7 @@ App.UI.SlaveList.penthousePage = function() {
 		return {
 			tabName: tabName,
 			caption: caption,
-			content: content
+			content: content,
 		};
 	}
 
@@ -948,13 +951,13 @@ App.UI.SlaveList.penthousePage = function() {
 		}
 		SlaveSort.IDs(penthouseSlavesIDs);
 		return makeTabDesc("all", `All${V.useSlaveSummaryTabs > 0 ? ` (${penthouseSlavesIDs.length})` : ""}`,
-			App.UI.SlaveList.render(penthouseSlavesIDs, [], App.UI.SlaveList.SlaveInteract.penthouseInteract));
+			App.UI.SlaveList.render(penthouseSlavesIDs, [], interactRenderer));
 	}
 
 	function favorites() {
 		SlaveSort.IDs(V.favorites);
 		return makeTabDesc("favorites", `Favorites${V.useSlaveSummaryTabs > 0 ? ` (${V.favorites.length})` : ""}`,
-			App.UI.SlaveList.render(V.favorites, [], App.UI.SlaveList.SlaveInteract.penthouseInteract));
+			App.UI.SlaveList.render(V.favorites, [], interactRenderer));
 	}
 
 	const fragment = new DocumentFragment();
diff --git a/src/js/slaveSummaryHelpers.js b/src/js/slaveSummaryHelpers.js
index d0da895b53852567d7d84a8057e5ac4fe7092878..8d60472158758f2114e1d7545bafa6a26665bb11 100644
--- a/src/js/slaveSummaryHelpers.js
+++ b/src/js/slaveSummaryHelpers.js
@@ -84,51 +84,13 @@ App.UI.SlaveSummaryImpl = function() {
 			return r;
 		}
 
-		/**
-		 * @param {object} dict
-		 * @param {*} value
-		 * @param {*} [defaultValue]
-		 * @returns {*|null}
-		 */
-		function getExactRating(dict, value, defaultValue = null) {
-			const res = dict[value];
-			return res ? res : defaultValue;
-		}
-
-		/**
-		 * @param {object} ratings
-		 * @param {number} value
-		 * @returns {*|null}
-		 */
-		function getNumericRating(ratings, value) {
-			for (const key in ratings) {
-				if (parseInt(key) >= value) {
-					return ratings[key];
-				}
-			}
-			return null;
-		}
-
-		/**
-		 * @param {object} ratings
-		 * @param {number[]} values
-		 * @returns {*|null}
-		 */
-		function getMultiNumericRating(ratings, values) {
-			const firstRating = getNumericRating(ratings, values[0]);
-			if (firstRating === null || typeof firstRating === "string" || firstRating.hasOwnProperty("desc")) {
-				return firstRating;
-			}
-			return getMultiNumericRating(firstRating, values.slice(1));
-		}
-
 		/**
 		 * @typedef {object} StyledDesc
 		 * @property {string} desc
 		 * @property {string|string[]} [style]
 		 */
 
-		/** @typedef {Object.<string, StyledDesc>} StyledRatings */
+		/** @typedef {Object.<number, StyledDesc>} StyledRatings */
 		/**
 		 * @param {Node} container
 		 * @param {StyledRatings} ratings
@@ -137,8 +99,7 @@ App.UI.SlaveSummaryImpl = function() {
 		 * @param {boolean} [stdDecor=false]
 		 */
 		function makeRatedStyledSpan(container, ratings, value, offset = 0, stdDecor = false) {
-			/** @type {StyledDesc} */
-			const d = getNumericRating(ratings, value + offset);
+			const d = App.Ratings.numeric(ratings, value + offset);
 			if (d) {
 				makeSpan(container, d.desc, d.style, stdDecor, value);
 			}
@@ -393,9 +354,6 @@ App.UI.SlaveSummaryImpl = function() {
 			makeSpan,
 			makeBlock,
 			makeParagraph,
-			getExactRating,
-			getNumericRating,
-			getMultiNumericRating,
 			makeStyledSpan,
 			makeRatedStyledSpan,
 			makeMappedStyledSpan,
@@ -630,7 +588,7 @@ App.UI.SlaveSummaryImpl = function() {
 		 */
 		function long_age(slave, c) {
 			const style = "pink";
-			makeSpan(c, V.showAgeDetail ? `Age ${slave.actualAge}` : helpers.getNumericRating(data.long.body.age, slave.actualAge), style, true);
+			makeSpan(c, V.showAgeDetail ? `Age ${slave.actualAge}` : App.Ratings.numeric(data.long.body.age, slave.actualAge), style, true);
 			/*
 			 ** No NCS, then do the standard, However because of the wrinkles of Incubators, as long as visual age is greater
 			 ** than or equal to physical age, we do the old physical body/Looks for fresh out of the can NCS slaves.
@@ -668,7 +626,7 @@ App.UI.SlaveSummaryImpl = function() {
 		 * @returns {void}
 		 */
 		function long_face(slave, c) {
-			const r = helpers.getNumericRating(data.long.body.face, slave.face + 100);
+			const r = App.Ratings.numeric(data.long.body.face, slave.face + 100);
 			makeSpan(c, `${r.desc} ${slave.faceShape} face`, r.style, true, slave.face);
 		}
 
@@ -723,7 +681,7 @@ App.UI.SlaveSummaryImpl = function() {
 		 */
 		function long_muscles(slave, c) {
 			const h = helpers;
-			h.makeStyledSpan(c, h.getMultiNumericRating(data.long.body.muscles, [slave.muscles + 100, h.FSData.policy.PhysicalIdealist.active]), slave.muscles, true);
+			h.makeStyledSpan(c, App.Ratings.multiNumeric(data.long.body.muscles, [slave.muscles + 100, h.FSData.policy.PhysicalIdealist.active]), slave.muscles, true);
 		}
 
 		/**
@@ -747,7 +705,7 @@ App.UI.SlaveSummaryImpl = function() {
 		function long_tits_ass(slave, c) {
 			const h = helpers;
 			h.makeStyledSpan(c,
-				h.getMultiNumericRating(data.long.body.titsAss,
+				App.Ratings.multiNumeric(data.long.body.titsAss,
 					[slave.boobs, slave.butt, h.FSData.policy.AssetExpansionist.active, slave.weight + 100, slave.muscles + 100]));
 		}
 
@@ -801,6 +759,17 @@ App.UI.SlaveSummaryImpl = function() {
 			}
 		}
 
+		/**
+		 * @param {App.Entity.SlaveState} slave
+		 * @param {Node} c
+		 * @returns {void}
+		 */
+		function milk_flavor(slave, c) {
+			if (slave.milkFlavor !== "none" && slave.lactation >= 1) {
+				makeSpan(c, `${capFirstChar(slave.milkFlavor)} flavored milk.`, "pink");
+			}
+		}
+
 		/**
 		 * @param {App.Entity.SlaveState} slave
 		 * @param {Node} c
@@ -830,7 +799,7 @@ App.UI.SlaveSummaryImpl = function() {
 			if (V.showAgeDetail === 1) {
 				r.textContent += slave.actualAge.toString();
 			} else if (slave.actualAge >= 18) {
-				r.textContent += helpers.getNumericRating(data.short.body.age, slave.actualAge);
+				r.textContent += App.Ratings.numeric(data.short.body.age, slave.actualAge);
 			}
 
 			if (slave.actualAge !== slave.physicalAge) {
@@ -902,7 +871,7 @@ App.UI.SlaveSummaryImpl = function() {
 		 */
 		function short_muscles(slave, c) {
 			const h = helpers;
-			h.makeStyledSpan(c, h.getMultiNumericRating(data.short.body.muscles, [slave.muscles + 100, h.FSData.policy.PhysicalIdealist.active]), slave.muscles, true);
+			h.makeStyledSpan(c, App.Ratings.multiNumeric(data.short.body.muscles, [slave.muscles + 100, h.FSData.policy.PhysicalIdealist.active]), slave.muscles, true);
 		}
 
 		/**
@@ -926,7 +895,7 @@ App.UI.SlaveSummaryImpl = function() {
 		function short_tits_ass(slave, c) {
 			const h = helpers;
 			h.makeStyledSpan(c,
-				h.getMultiNumericRating(data.short.body.titsAss,
+				App.Ratings.multiNumeric(data.short.body.titsAss,
 					[slave.boobs, slave.butt, h.FSData.policy.AssetExpansionist.active, slave.weight + 100, slave.muscles + 100]));
 		}
 
@@ -993,7 +962,8 @@ App.UI.SlaveSummaryImpl = function() {
 			} else {
 				makeSpan(c, "Mods");
 			}
-			if (!jQuery.isEmptyObject(slave.brand)) {
+			const brands = App.Medicine.Modification.brandRecord(slave);
+			if (!jQuery.isEmptyObject(brands)) {
 				makeSpan(c, "Br");
 			}
 		}
@@ -1008,8 +978,8 @@ App.UI.SlaveSummaryImpl = function() {
 				return;
 			}
 			const intelligence = slave.intelligence + slave.intelligenceImplant;
-			const educationStr = helpers.getNumericRating(data.short.mental.education, slave.intelligenceImplant + 15);
-			const intelligenceRating = helpers.getNumericRating(data.short.mental.intelligence, intelligence + 100);
+			const educationStr = App.Ratings.numeric(data.short.mental.education, slave.intelligenceImplant + 15);
+			const intelligenceRating = App.Ratings.numeric(data.short.mental.intelligence, intelligence + 100);
 			makeSpan(c, `${intelligenceRating.desc}${educationStr}`, intelligenceRating.style, true, intelligence);
 		}
 
@@ -1025,7 +995,7 @@ App.UI.SlaveSummaryImpl = function() {
 				helpers.makeStyledSpan(c, sd.mss);
 			} else {
 				SSkills += slave.skill.vaginal;
-				helpers.makeStyledSpan(c, helpers.getMultiNumericRating(sd.sex, [SSkills, slave.vagina >= 0 ? 1 : 0]), Math.trunc(SSkills), true);
+				helpers.makeStyledSpan(c, App.Ratings.multiNumeric(sd.sex, [SSkills, slave.vagina >= 0 ? 1 : 0]), Math.trunc(SSkills), true);
 				helpers.makeRatedStyledSpan(c, sd.whoring, slave.skill.whoring, 0, true);
 				helpers.makeRatedStyledSpan(c, sd.entertainment, slave.skill.entertainment, 0, true);
 			}
@@ -1062,8 +1032,8 @@ App.UI.SlaveSummaryImpl = function() {
 				return;
 			}
 			const intelligence = slave.intelligence + slave.intelligenceImplant;
-			const educationStr = helpers.getNumericRating(data.long.mental.education, slave.intelligenceImplant + 15);
-			const intelligenceRating = helpers.getNumericRating(data.long.mental.intelligence, intelligence + 100);
+			const educationStr = App.Ratings.numeric(data.long.mental.education, slave.intelligenceImplant + 15);
+			const intelligenceRating = App.Ratings.numeric(data.long.mental.intelligence, intelligence + 100);
 			makeSpan(c, `${intelligenceRating.desc}${educationStr}`, intelligenceRating.style, true, intelligence);
 		}
 
@@ -1079,7 +1049,7 @@ App.UI.SlaveSummaryImpl = function() {
 				helpers.makeStyledSpan(c, sd.mss);
 			} else {
 				SSkills += slave.skill.vaginal;
-				helpers.makeStyledSpan(c, helpers.getMultiNumericRating(sd.sex, [SSkills, slave.vagina >= 0 ? 1 : 0]), Math.trunc(SSkills), true);
+				helpers.makeStyledSpan(c, App.Ratings.multiNumeric(sd.sex, [SSkills, slave.vagina >= 0 ? 1 : 0]), Math.trunc(SSkills), true);
 				helpers.makeRatedStyledSpan(c, sd.whoring, slave.skill.whoring, 0, true);
 				helpers.makeRatedStyledSpan(c, sd.entertainment, slave.skill.entertainment, 0, true);
 			}
@@ -1112,7 +1082,7 @@ App.UI.SlaveSummaryImpl = function() {
 		 * @returns {void}
 		 */
 		function long_clothes(slave, c) {
-			makeSpan(c, helpers.getExactRating(data.long.clothes, slave.clothes, 'Naked.'));
+			makeSpan(c, App.Ratings.exact(data.long.clothes, slave.clothes, 'Naked.'));
 		}
 
 		/**
@@ -1269,7 +1239,7 @@ App.UI.SlaveSummaryImpl = function() {
 				if (!tbl || typeof tbl === 'string') {
 					return tbl;
 				}
-				return helpers.getNumericRating(tbl, slave.fetishStrength);
+				return App.Ratings.numeric(tbl, slave.fetishStrength);
 			}
 
 			const fStr = fetishStr(slave);
@@ -1347,20 +1317,20 @@ App.UI.SlaveSummaryImpl = function() {
 		}
 
 		/**
-		 * @param {App.Entity.SlaveState} slave
+		 * @param {FC.SlaveState} slave
 		 * @param {Node} c
 		 * @returns {void}
 		 */
 		function long_fetish(slave, c) {
-			function fetishStr(slave) {
+			function fetishStr() {
 				const tbl = data.long.fetish[slave.fetish];
 				if (!tbl || typeof tbl === 'string') {
 					return tbl;
 				}
-				return helpers.getNumericRating(tbl, slave.fetishStrength);
+				return App.Ratings.numeric(tbl, slave.fetishStrength);
 			}
 
-			const fStr = fetishStr(slave);
+			const fStr = fetishStr();
 			if (fStr) {
 				makeSpan(c, fStr, "lightcoral", true, slave.fetishStrength);
 			}
@@ -1614,6 +1584,7 @@ App.UI.SlaveSummaryImpl = function() {
 				waist: long_waist,
 				implants: long_implants,
 				lactation: long_lactation,
+				milkflavor: milk_flavor,
 				mods: long_mods,
 				intelligence: long_intelligence,
 				skills: long_skills,
diff --git a/src/js/slaveSummaryWidgets.js b/src/js/slaveSummaryWidgets.js
index 436db4661e79a749062a40525ee892ca7498155b..8d1fd7184d7ce6f089baf01ae02b4fa656d04c91 100644
--- a/src/js/slaveSummaryWidgets.js
+++ b/src/js/slaveSummaryWidgets.js
@@ -14,7 +14,7 @@ App.UI.SlaveSummaryRenderers = function() {
 				makeSpan(c, "MB", "mindbroken");
 			} else {
 				helpers.makeRatedStyledSpan(c, data.short.mental.devotion, slave.devotion, 100, true);
-				helpers.makeStyledSpan(c, helpers.getMultiNumericRating(data.short.mental.trust, [slave.trust + 100, slave.devotion + 100]),
+				helpers.makeStyledSpan(c, App.Ratings.multiNumeric(data.short.mental.trust, [slave.trust + 100, slave.devotion + 100]),
 					slave.trust, true);
 			}
 		},
@@ -114,7 +114,7 @@ App.UI.SlaveSummaryRenderers = function() {
 		 * @returns {void}
 		 */
 		weight: function(slave, c) {
-			helpers.makeStyledSpan(c, helpers.getMultiNumericRating(data.short.body.weight,
+			helpers.makeStyledSpan(c, App.Ratings.multiNumeric(data.short.body.weight,
 				[slave.weight + 100, helpers.FSData.policy.HedonisticDecadence.active, slave.hips + 2]), slave.weight, true);
 		},
 
@@ -127,7 +127,7 @@ App.UI.SlaveSummaryRenderers = function() {
 			const makeSpan = helpers.makeSpan;
 			if (slave.dick > 0) {
 				let dickDesc = slave.balls === 0 ? "Geld" : "";
-				const dickBallsDesc = helpers.getMultiNumericRating(data.short.body.genitalia.dickBalls, [slave.dick, slave.balls]);
+				const dickBallsDesc = App.Ratings.multiNumeric(data.short.body.genitalia.dickBalls, [slave.dick, slave.balls]);
 				if (dickBallsDesc) {
 					dickDesc += ` ${dickBallsDesc}`;
 				}
@@ -143,7 +143,7 @@ App.UI.SlaveSummaryRenderers = function() {
 			if (slave.anus === 0) {
 				makeSpan(c, "AV", "lime");
 			}
-			const holesDesc = helpers.getMultiNumericRating(data.long.body.genitalia.holes, [slave.vagina, slave.anus]);
+			const holesDesc = App.Ratings.multiNumeric(data.long.body.genitalia.holes, [slave.vagina, slave.anus]);
 			if (holesDesc) {
 				makeSpan(c, holesDesc, "pink");
 			}
@@ -398,7 +398,7 @@ App.UI.SlaveSummaryRenderers = function() {
 				makeSpan(c, "Mindbroken.", "mindbroken");
 			} else {
 				helpers.makeRatedStyledSpan(c, data.long.mental.devotion, slave.devotion, 100, true);
-				helpers.makeStyledSpan(c, helpers.getMultiNumericRating(data.long.mental.trust, [slave.trust + 100, slave.devotion + 100]),
+				helpers.makeStyledSpan(c, App.Ratings.multiNumeric(data.long.mental.trust, [slave.trust + 100, slave.devotion + 100]),
 					slave.trust, true);
 			}
 		},
@@ -420,7 +420,7 @@ App.UI.SlaveSummaryRenderers = function() {
 		 * @returns {void}
 		 */
 		weight: function(slave, c) {
-			helpers.makeStyledSpan(c, helpers.getMultiNumericRating(data.long.body.weight,
+			helpers.makeStyledSpan(c, App.Ratings.multiNumeric(data.long.body.weight,
 				[slave.weight + 100, helpers.FSData.policy.HedonisticDecadence.active, slave.hips + 2]), slave.weight, true);
 		},
 
@@ -449,7 +449,7 @@ App.UI.SlaveSummaryRenderers = function() {
 		genitalia: function(slave, c) {
 			if (slave.dick > 0) {
 				let dickDesc = slave.balls === 0 ? "Gelded." : "";
-				const dickBallsDesc = helpers.getMultiNumericRating(data.long.body.genitalia.dickBalls, [slave.dick, slave.balls]);
+				const dickBallsDesc = App.Ratings.multiNumeric(data.long.body.genitalia.dickBalls, [slave.dick, slave.balls]);
 				if (dickBallsDesc) {
 					dickDesc += ` ${dickBallsDesc}`;
 				}
@@ -465,7 +465,7 @@ App.UI.SlaveSummaryRenderers = function() {
 			if (slave.anus === 0) {
 				helpers.makeSpan(c, "Anal virgin.", "lime");
 			}
-			const holesDesc = helpers.getMultiNumericRating(data.long.body.genitalia.holes, [slave.vagina, slave.anus]);
+			const holesDesc = App.Ratings.multiNumeric(data.long.body.genitalia.holes, [slave.vagina, slave.anus]);
 			if (holesDesc) {
 				helpers.makeSpan(c, holesDesc, "pink");
 			}
@@ -523,7 +523,7 @@ App.UI.SlaveSummaryRenderers = function() {
 				makeSpan(c, "Belly Implant.", styles);
 			} else if ((slave.preg <= -2) && (slave.ovaries === 1 || slave.mpreg === 1)) {
 				makeSpan(c, "Barren.", styles);
-			} else if ((slave.ovaries === 0) && (slave.vagina !== -1) && (slave.genes === "XX")) {
+			} else if ((slave.ovaries === 0 && slave.mpreg === 0) && (slave.vagina !== -1) && (slave.genes === "XX")) {
 				makeSpan(c, "Barren.", styles);
 			} else if (slave.pubertyXX === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) {
 				makeSpan(c, "Not ovulating yet.", styles);
@@ -618,8 +618,10 @@ App.UI.SlaveSummaryRenderers = function() {
 			b.waist(slave, c);
 			b.implants(slave, c);
 			b.lactation(slave, c);
+			b.milkflavor(slave, c);
 			b.mods(slave, c);
-			if (!jQuery.isEmptyObject(slave.brand)) {
+			const brands = App.Medicine.Modification.brandRecord(slave);
+			if (!jQuery.isEmptyObject(brands)) {
 				helpers.makeSpan(c, 'Branded.');
 			}
 		},
@@ -631,7 +633,7 @@ App.UI.SlaveSummaryRenderers = function() {
 		 */
 		hormoneBalance: function(slave, c) {
 			const colorClass = slave.hormoneBalance <= -21 ? "deepskyblue" : "pink";
-			const desc = helpers.getNumericRating(data.long.hormoneBalance, slave.hormoneBalance + 500);
+			const desc = App.Ratings.numeric(data.long.hormoneBalance, slave.hormoneBalance + 500);
 			helpers.makeSpan(c, desc + " hormone balance.", colorClass);
 		},
 
@@ -774,7 +776,7 @@ App.UI.SlaveSummaryRenderers = function() {
 		 * @returns {void}
 		 */
 		origins: function(slave, c) {
-			if (typeof slave.origin === "string") {
+			if (slave.origin !== "") {
 				const para = helpers.makeParagraph(c);
 				para.classList.add("gray");
 				para.textContent = pronounsForSlaveProp(slave, slave.origin);
@@ -881,14 +883,14 @@ App.UI.SlaveSummary = function() {
 		}
 	}
 
-	function settingsChanged(newState) {
+	function settingsChanged(newState = V) {
 		try {
 			const newStateIsOK = newState && newState.hasOwnProperty("UI") && newState.UI.hasOwnProperty("slaveSummary");
 			const settingsObj = newStateIsOK ? newState.UI.slaveSummary : V.UI.slaveSummary;
 
 			initDelegates(settingsObj);
-			App.UI.SlaveSummaryImpl.helpers.syncFSData(newState ? newState.arcologies[0] : V.arcologies[0]);
-			App.Art.setDynamicCSS(newState ? newState : V);
+			App.UI.SlaveSummaryImpl.helpers.syncFSData(newState.arcologies[0]);
+			App.Art.setDynamicCSS(newState);
 		} catch (ex) {
 			console.log(`Slave summary settings change handler encountered an error: ${ex}`);
 		}
diff --git a/src/js/statsChecker/eyeChecker.js b/src/js/statsChecker/eyeChecker.js
index 82f03cca7cb0b54b80734216e84b21ced11b7ef9..ab817eb9bb113204d41a836260f9b9f805e43196 100644
--- a/src/js/statsChecker/eyeChecker.js
+++ b/src/js/statsChecker/eyeChecker.js
@@ -256,23 +256,28 @@ globalThis.hasVisibleHeterochromia = function(slave) {
 };
 
 /**
- * Gives the genetic color of the specified eye.
+ * Gives the genetic color of the specified eye part.
  *
  * @param {FC.HumanState} playerOrSlave
- * @param {string} side
+ * @param {FC.BodySide} side
+ * @param {"iris"|"pupil"|"sclera"} [eyePart="iris"]
  * @returns {string}
  */
-globalThis.getGeneticEyeColor = function(playerOrSlave, side) {
-	if (side !== "left" && side !== "right") { return "ERROR:" + side; }
-
-	if (playerOrSlave.geneticQuirks.albinism === 2 && "albinismOverride" in playerOrSlave) {
-		return playerOrSlave.albinismOverride.eyeColor;
-	} else {
-		if (side === "left" && typeof playerOrSlave.geneticQuirks.heterochromia === "string") {
-			return playerOrSlave.geneticQuirks.heterochromia;
+globalThis.getGeneticEyeColor = function(playerOrSlave, side, eyePart = "iris") {
+	if (eyePart === "iris") {
+		if (playerOrSlave.geneticQuirks.albinism === 2 && "albinismOverride" in playerOrSlave) {
+			return playerOrSlave.albinismOverride.eyeColor;
 		} else {
-			return playerOrSlave.eye.origColor;
+			if (side === "left" && typeof playerOrSlave.geneticQuirks.heterochromia === "string") {
+				return playerOrSlave.geneticQuirks.heterochromia;
+			} else {
+				return playerOrSlave.eye.origColor;
+			}
 		}
+	} else if (eyePart === "pupil") {
+		return playerOrSlave.race === "catgirl" ? "catlike" : "circular";
+	} else {
+		return "white";
 	}
 };
 
@@ -285,11 +290,17 @@ globalThis.getGeneticEyeColor = function(playerOrSlave, side) {
 globalThis.getLenseCount = function(slave) {
 	let count = 0;
 
-	if (hasRightEye(slave) && getRightEyeColor(slave) !== getGeneticEyeColor(slave, "right")) {
+	if (hasRightEye(slave) &&
+		(getRightEyeColor(slave) !== getGeneticEyeColor(slave, "right", "iris")) ||
+		(getRightEyePupil(slave) !== getGeneticEyeColor(slave, "right", "pupil")) ||
+		(getRightEyeSclera(slave) !== getGeneticEyeColor(slave, "right", "sclera"))) {
 		count++;
 	}
 
-	if (hasLeftEye(slave) && getLeftEyeColor(slave) !== getGeneticEyeColor(slave, "left")) {
+	if (hasLeftEye(slave) &&
+		getLeftEyeColor(slave) !== getGeneticEyeColor(slave, "left", "iris") ||
+		(getLeftEyePupil(slave) !== getGeneticEyeColor(slave, "left", "pupil")) ||
+		(getLeftEyeSclera(slave) !== getGeneticEyeColor(slave, "left", "sclera"))) {
 		count++;
 	}
 
diff --git a/src/js/statsChecker/statsChecker.js b/src/js/statsChecker/statsChecker.js
index d58e340e1e13f6745f6e05241aeb9e032897beb1..781a6287e8d5ec70199e231f7d5e571115768236 100644
--- a/src/js/statsChecker/statsChecker.js
+++ b/src/js/statsChecker/statsChecker.js
@@ -169,7 +169,8 @@ globalThis.SlaveStatsChecker = (function() {
 	 */
 	function brandScore(slave) {
 		let score = 0;
-		score += Object.getOwnPropertyNames(slave.brand).length;
+		const brands = App.Medicine.Modification.brandRecord(slave);
+		score += Object.getOwnPropertyNames(brands).length;
 		return score;
 	}
 
@@ -182,11 +183,10 @@ globalThis.SlaveStatsChecker = (function() {
 		let score = 0;
 		let scars;
 		if (slave.hasOwnProperty("scar")) { /* For very old saves this may not be defined yet and blocks the save from loading. */
-			scars = Object.keys(slave.scar);
-			for (const bodypart of scars) {
-				const bodyparts = Object.keys(slave.scar[bodypart]);
-				for (const kind of bodyparts) {
-					score += slave.scar[bodypart][kind];
+			scars = App.Medicine.Modification.scarRecord(slave);
+			for (const bodypart of Object.keys(scars)) {
+				for (const kind of Object.keys(scars[bodypart])) {
+					score += scars[bodypart][kind];
 				}
 			}
 		}
@@ -1130,3 +1130,14 @@ globalThis.canBeReceptrix = function(slave) {
 		slave.physicalAge < 70
 	);
 };
+
+globalThis.milkFlavor = function(slave) {
+	if (slave.milkFlavor === "none") {
+		return ``;
+	}
+	return `${slave.milkFlavor} flavored `;
+};
+
+globalThis.canBeDeflowered = function(slave) {
+	return (slave.vagina === 0 && canDoVaginal(slave)) || (slave.anus === 0 && canDoAnal(slave));
+};
diff --git a/src/js/storyJS.js b/src/js/storyJS.js
index d1215b564cc2896792c93b8ef528193776c4903d..d086bd7528ae0e40ce840c343627a6b83936d005 100644
--- a/src/js/storyJS.js
+++ b/src/js/storyJS.js
@@ -1,6 +1,10 @@
 /* config.history.tracking = false;*/
 // State.expired.disable;
 
+globalThis.peacekeepersCanBeEstablished = function() {
+	return V.invasionVictory > 0 && App.Events.effectiveWeek() > 48;
+}
+
 /**
  * @param {number} x
  * @param {number} minValue
@@ -230,7 +234,7 @@ globalThis.cumAmount = function(slave) {
 	}
 	cum *= healthPenalty(slave);
 	cum = Math.trunc(cum);
-	cum = Math.clamp(cum, 1, 1000000000000000000);
+	cum = Math.clamp(cum, 1, 1_000_000_000_000_000);
 	return cum;
 };
 
diff --git a/src/js/upgrade.js b/src/js/upgrade.js
index 17375c27520a53d5bd59b8fb05e9c8e1019ded15..6c7300124909cc8fe83672bb5be740f09550d4e5 100644
--- a/src/js/upgrade.js
+++ b/src/js/upgrade.js
@@ -28,7 +28,7 @@ App.Upgrade = class Upgrade {
 
 		this.tiers.forEach(tier => {
 			const {
-				value, link, text, upgraded, handler, note, prereqs, nodes,
+				value, link, text, upgraded, handler, notes, prereqs, nodes,
 			} = tier;
 
 			const cost = Math.trunc(tier.cost) || 0;
@@ -38,18 +38,16 @@ App.Upgrade = class Upgrade {
 				App.UI.DOM.appendNewElement("div", frag, text);
 
 				if (link) {
-					App.UI.DOM.appendNewElement("div", frag, new Purchase(link, cost, "capEx", {
-						note,
+					App.UI.DOM.appendNewElement("div", frag, makePurchase(link, cost, "capEx", {
+						notes,
 						handler: () => {
 							this._object[this._property] = upgraded;
 
 							if (handler) {
 								handler();
 							}
-
-							this.refresh();
 						},
-					}).render());
+					}));
 				}
 
 				if (nodes) {
diff --git a/src/js/utilsAssessSlave.js b/src/js/utilsAssessSlave.js
index 908a147fa1604c5950bd7bb3ea9f079de2cb3c4c..39bf59bcf3e96d9e135c1cacd80d7d6ca0f88c9f 100644
--- a/src/js/utilsAssessSlave.js
+++ b/src/js/utilsAssessSlave.js
@@ -115,8 +115,12 @@ globalThis.canImproveIntelligence = function(slave) {
  * @returns {number}
  */
 globalThis.maxHeight = function(slave) {
-	let max = Math.clamp((Height.mean(slave) * 1.25), 0, 274); /* max achievable height is expected height plus 25% */
+	let max = Math.clamp(((Height.mean(slave) * 1.25) + slave.heightImplant * 10), 0, 274); /* max achievable height is expected height plus 25% */
 
+	if (slave.geneticQuirks.neoteny === 2 && slave.physicalAge > 12) { /* Limit neoteny slaves to 12 year old max height */
+		max = Math.clamp(((Height.mean(slave.nationality, slave.race, slave.genes, 12) * 1.25) + slave.heightImplant * 10), 0, 274);
+	}
+	
 	if (slave.geneticQuirks.dwarfism === 2 && slave.geneticQuirks.gigantism !== 2) {
 		max = Math.min(max, 160);
 	}
@@ -194,12 +198,12 @@ globalThis.getWrittenTitle = function(slave) {
 };
 
 /**
- * @param {App.Entity.SlaveState} slave
+ * @param {FC.HumanState} slave
  * @returns {string}
  */
 globalThis.SlaveFullName = function(slave) {
 	const pair = slave.slaveSurname ? [slave.slaveName, slave.slaveSurname] : [slave.slaveName];
-	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(slave.nationality)) || (V.surnameOrder === 2)) {
+	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Ancient Chinese Revivalist", "Hungarian", "Japanese", "Edo Revivalist", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(slave.nationality)) || (V.surnameOrder === 2)) {
 		pair.reverse();
 	}
 	return pair.join(" ");
@@ -210,7 +214,7 @@ globalThis.SlaveFullName = function(slave) {
  * @returns {boolean}
  */
 globalThis.isShelterSlave = function(slave) {
-	return (typeof slave.origin === "string" && slave.origin.includes("Slave Shelter"));
+	return slave.origin.includes("Slave Shelter");
 };
 
 // TODO: Expand or remove the following unused function.
diff --git a/src/js/utilsDOM.js b/src/js/utilsDOM.js
index 62ee6645ceefe4d17a92651963fc164221a8317d..9c8b0a10ab35aac4bfe32206f0f371f151a3ab2f 100644
--- a/src/js/utilsDOM.js
+++ b/src/js/utilsDOM.js
@@ -276,6 +276,7 @@ App.UI.DOM.makeTextBox = function(defaultValue, onEnter, numberOnly = false) {
 		to 0 and trigger a change event we can't distinguish from setting the value to 0 explicitly.
 		The workaround is resetting the value to the last known valid value and not triggering onEnter.
 		*/
+		input.classList.add("number");
 		let oldValue = defaultValue;
 		updateValue = event => {
 			const newValue = Number(event.target.value);
@@ -583,7 +584,7 @@ App.UI.DOM.makeCheckbox = function(arg) {
  * @returns {HTMLDivElement|DocumentFragment}
  */
 App.UI.DOM.drawOneSlaveRight = function(node, slave, batchRenderer) {
-	if (!V.seeImages || !slave) {
+	if (!V.seeImages || (V.seeCustomImagesOnly && !slave.custom.image) || !slave) {
 		return new DocumentFragment();
 	}
 	const artElement = batchRenderer ? batchRenderer.render(slave) : App.Art.SlaveArtElement(slave, 2, 0);
diff --git a/src/js/utilsMisc.js b/src/js/utilsMisc.js
index 1a1ad6cbb1d1723c782ad7cb8c327f6bc57218dc..82b8a3075f1e44519cb67512ce957e48157e3306 100644
--- a/src/js/utilsMisc.js
+++ b/src/js/utilsMisc.js
@@ -248,8 +248,8 @@ App.Utils.totalNetWorth = function() {
 
 	total += Math.trunc(V.mods.food.amount * V.mods.food.cost);
 
-	total += App.SF.totalNetWorth();
-	total -= App.SecExp.upkeep.cost();
+	total += App.Mods.SF.totalNetWorth();
+	total -= App.Mods.SecExp.upkeep.cost();
 
 	return total;
 };
@@ -318,17 +318,9 @@ globalThis.generalRefreshment = function name() {
 	}
 };
 
-/**
- * @typedef {Object} trinketData
- * @property {string} [name]
- * @property {number|null} [id]
- * @property {string} [extra]
- * @property {string} [napkinShape]
- */
-
 /**
  * @param {string} name
- * @param {trinketData} [object]
+ * @param {FC.TrinketData} [object]
  */
 globalThis.addTrinket = function(name, object) {
 	if (object) {
@@ -340,6 +332,33 @@ globalThis.addTrinket = function(name, object) {
 		if (!V.trinkets.get(name)) {
 			V.trinkets.set(name, 0);
 		}
-		V.trinkets.set(name, V.trinkets.get(name) +1);
+		V.trinkets.set(name, V.trinkets.get(name) + 1);
+	}
+};
+
+/**
+ * Creates range object
+ * @param {number} minValue
+ * @param {number} maxValue
+ * @returns {FC.NumericRange}
+ */
+App.Utils.makeRange = function(minValue, maxValue) {
+	return {
+		min: minValue, max: maxValue
+	};
+};
+
+/**
+ * Compares value to a range
+ * @param {number} value
+ * @param {FC.NumericRange} [range]
+ * @returns {number} The value which when added to `value` brings it within the range [min:max]
+ * `positive` when value is less than range min, `0` when the value is whithin the range or
+ * the range is `null`, and `negative` when value is greater than range max
+ */
+App.Utils.distanceToRange = function(value, range) {
+	if (!range) {
+		return 0;
 	}
+	return value < range.min ? range.min - value : (value > range.max ? range.max - value : 0);
 };
diff --git a/src/js/utilsPC.js b/src/js/utilsPC.js
index 260cad200864018e3ad88dd3bad27447efdcaa7b..9f734cb276e081f6e0555584a85e054349cc2360 100644
--- a/src/js/utilsPC.js
+++ b/src/js/utilsPC.js
@@ -40,7 +40,7 @@ globalThis.properMaster = function() {
  */
 globalThis.PlayerName = function() {
 	const names = V.PC.slaveSurname ? [V.PC.slaveName, V.PC.slaveSurname] : [V.PC.slaveName];
-	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(V.PC.nationality)) || (V.surnameOrder === 2)) {
+	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Ancient Chinese Revivalist", "Hungarian", "Japanese", "Edo Revivalist", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(V.PC.nationality)) || (V.surnameOrder === 2)) {
 		names.reverse();
 	}
 	return names.join(" ");
@@ -637,12 +637,14 @@ globalThis.onBedRest = function(actor) {
 		return true;
 	} else if (actor.bellyPreg >= actor.pregAdaptation * 2200) {
 		return true;
+	} else if (isInduced(actor)) {
+		return true;
 	}
 	return false;
 };
 
 /** Returns if the player can eat solid food.
- * Consdier moving this to encompass slaves in the future.
+ * Consider moving this to encompass slaves in the future.
  * @param {App.Entity.PlayerState} actor
  * @returns {boolean}
  */
diff --git a/src/js/utilsSlave.js b/src/js/utilsSlave.js
index 8ae29c3b277f3d7dcf707a9c8be016afbf976812..1b13711a4f918af6d3f017b5fee947edacc6b559 100644
--- a/src/js/utilsSlave.js
+++ b/src/js/utilsSlave.js
@@ -1348,7 +1348,7 @@ globalThis.pronounReplacer = function(slavetext) {
 /**
  * Describes a slaves pre-slavery career in a gender sensitive way. If career is "a dominatrix" but the slave is male and the pronoun system is on, returns "a dominator"
  * @param {App.Entity.SlaveState} slave
- * @returns {FC.Zeroable<string>}
+ * @returns {string}
  */
 globalThis.convertCareer = function(slave) {
 	let job = slave.career;
@@ -1619,7 +1619,7 @@ globalThis.randomRaceSkin = function(raceName) {
 			skin = jsEither(["fair", "light", "pale"]);
 			break;
 		case "catgirl":
-			skin = jsEither(["black", "white", "brown", "red", "black and white striped", "yellow"]);
+			skin = jsEither(App.Medicine.Modification.catgirlNaturalSkins);
 			break;
 		default:
 			skin = jsEither(["dark", "light", "pale"]);
@@ -2132,7 +2132,7 @@ globalThis.fetishChangeChance = function(slave) {
  */
 globalThis.SlaveFullBirthName = function(slave) {
 	const pair = slave.birthSurname ? [slave.birthName, slave.birthSurname] : [slave.birthName];
-	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(slave.nationality)) || (V.surnameOrder === 2)) {
+	if ((V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Ancient Chinese Revivalist", "Hungarian", "Japanese", "Edo Revivalist", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(slave.nationality)) || (V.surnameOrder === 2)) {
 		pair.reverse();
 	}
 	return pair.join(" ");
@@ -3299,7 +3299,7 @@ globalThis.ageSlave = function(slave, forceDevelopment = false) {
 		slave.ovaryAge += 0.2;
 	}
 	if (slave.physicalAge <= 18 && (forceDevelopment || V.loliGrow > 0)) {
-		physicalDevelopment(slave);
+		App.EndWeek.Shared.physicalDevelopment(slave);
 	}
 };
 
@@ -3359,26 +3359,45 @@ globalThis.slaveSkillIncrease = function(targetSkill, slave, skillIncrease = 1)
 	let r = "";
 	let skillDec;
 	const {He, he, his, him} = getPronouns(slave);
-	const isLeadershipRole = ['headGirl', 'recruiter', 'bodyguard', 'madam', 'DJ', 'nurse', 'teacher', 'attendant', 'matron', 'stewardess', 'milkmaid', 'farmer', 'wardeness'].includes(targetSkill);
+	const isLeadership = [
+		['headGirl', 'HG'],
+		['recruiter', 'recruiter'],
+		['bodyguard', 'bodyguard'],
+		['madam', 'madam'],
+		['DJ', 'DJ'],
+		['nurse', 'nurse'],
+		['teacher', 'schoolteacher'],
+		['attendant', 'attendant'],
+		['matron', 'matron'],
+		['stewardess', 'stewardess'],
+		['milkmaid', 'milkmaid'],
+		['farmer', 'farmer'],
+		['wardeness', 'wardeness']
+	];
+	const isLeadershipRole = isLeadership.find(s => s[0].includes(targetSkill))
 	if (isLeadershipRole) {
-		if (slave.skill[targetSkill] <= 20) {
-			if (slave.skill[targetSkill] + skillIncrease > 20) {
-				r = `<span class="green">${He} now has basic skills as a ${capFirstChar(targetSkill)}</span>`;
-			}
-		} else if (slave.skill[targetSkill] <= 60) {
-			if (slave.skill[targetSkill] + skillIncrease > 60) {
-				r = `<span class="green">${He} now has some skill as a ${capFirstChar(targetSkill)} under ${his} belt.</span>`;
-			}
-		} else if (slave.skill[targetSkill] <= 120) {
-			if (slave.skill[targetSkill] + skillIncrease > 120) {
-				r = `<span class="green">${He} is becoming well-versed as a ${capFirstChar(targetSkill)} candidate.</span>`;
-			}
-		} else if (slave.skill[targetSkill] < 200) {
-			if (slave.skill[targetSkill] + skillIncrease >= 200) {
-				r = `<span class="green">${He} now has knowledge on par with those with applicable career experience for a ${capFirstChar(targetSkill)}.</span>`;
+		if (!App.Data.Careers.Leader[isLeadershipRole[1]].includes(slave.career)) {
+			if (slave.skill[targetSkill] <= 20) {
+				if (slave.skill[targetSkill] + skillIncrease > 20) {
+					r = `<span class="green">${He} now has basic skills as a ${capFirstChar(targetSkill)}</span>`;
+				}
+			} else if (slave.skill[targetSkill] <= 60) {
+				if (slave.skill[targetSkill] + skillIncrease > 60) {
+					r = `<span class="green">${He} now has some skill as a ${capFirstChar(targetSkill)} under ${his} belt.</span>`;
+				}
+			} else if (slave.skill[targetSkill] <= 120) {
+				if (slave.skill[targetSkill] + skillIncrease > 120) {
+					r = `<span class="green">${He} is becoming well-versed as a ${capFirstChar(targetSkill)} candidate.</span>`;
+				}
+			} else if (slave.skill[targetSkill] < 200) {
+				if (slave.skill[targetSkill] + skillIncrease >= 200) {
+					r = `<span class="green">${He} now has knowledge on par with those with applicable career experience for a ${capFirstChar(targetSkill)}.</span>`;
+					V.slaveTutor[capFirstChar(targetSkill)].delete(slave.ID);
+				}
+			} else { // failsafe
 				V.slaveTutor[capFirstChar(targetSkill)].delete(slave.ID);
 			}
-		} else { // failsafe
+		} else {
 			V.slaveTutor[capFirstChar(targetSkill)].delete(slave.ID);
 		}
 	} else {
@@ -3593,50 +3612,6 @@ globalThis.randomRapeRivalryTarget = function(slave, predicate) {
 	return arr.find(predicate);
 };
 
-/**
- * TODO: move this into seX() once interact scenes are converted
- * @param {FC.HumanState} slave
- * @param {FC.HumanState|FC.AnimalState|number} partner The slave's partner, or the ID of the slave's partner.
- *
- * | ***ID*** | **Type**              |
- * |---------:|:----------------------|
- * | *-1*     | PC                    |
- * | *-2*     | Citizen               |
- * | *-3*     | PC's former master    |
- * | *-4*     | Fellow arcology owner |
- * | *-6*     | Societal Elite        |
- * | *-8*     | Animal                |
- * | *-9*     | Futanari Sister       |
- */
-globalThis.addPartner = function(slave, partner) {
-	/** @returns {FC.HumanState} */
-	function getPartnerState() {
-		if (typeof partner === "number") {
-			if (partner === -1) {
-				return V.PC;
-			} else if (partner > 0) {
-				return getSlave(partner);
-			}
-		} else if ("partners" in partner) {
-			return partner;
-		}
-		return null;
-	}
-
-	if (typeof partner === "number") {
-		slave.partners.add(partner);
-	} else if ("ID" in partner) {
-		slave.partners.add(partner.ID);
-	} else {
-		throw new TypeError(`Partner must be an object or ID, not "${partner}"`);
-	}
-
-	const partnerState = getPartnerState();
-	if (partnerState) {
-		partnerState.partners.add(slave.ID);
-	}
-};
-
 globalThis.resetHGCum = function(s) {
 	return 2 + Math.trunc((s.balls / 5) + (s.energy / 95) + (s.health.condition / 95) + (s.devotion / 95) + (V.reproductionFormula * 5));
 };
@@ -3758,3 +3733,11 @@ App.Utils.showSlaveChanges = function(edited, original, dispatch, crumb = "") {
 		}
 	}
 };
+
+/** Calculates the minimum anus size to accommodate a particular dick size
+ * @param {number} dickSize
+ * @returns {FC.AnusType}
+ */
+globalThis.stretchedAnusSize = function(dickSize) {
+	return /** @type {FC.AnusType} */ (Math.clamp(dickSize, 0, 4));
+};
diff --git a/src/js/utilsSlaves.js b/src/js/utilsSlaves.js
index fde2f0631c2f5d6d259c09ba780ae78fe6e80ea1..74d517ee0c0392df0de49a450bc2ac1a6c99331f 100644
--- a/src/js/utilsSlaves.js
+++ b/src/js/utilsSlaves.js
@@ -69,6 +69,8 @@ globalThis.SlaveSort = function() {
 		DsexDrive: (a, b) => effectiveEnergy(b) - effectiveEnergy(a),
 		Apregnancy: (a, b) => effectivePreg(a) - effectivePreg(b),
 		Dpregnancy: (a, b) => effectivePreg(b) - effectivePreg(a),
+		Aprestige: (a, b) => a.prestige - b.prestige,
+		Dprestige: (a, b) => b.prestige - a.prestige,
 	};
 
 	return {
diff --git a/src/js/vignettes.js b/src/js/vignettes.js
index 6e61b8f7dcf487a5ad196f9eeb28c6cbab73b46d..cd617d62bba1ff2fc0a3431c51c3a4c427fd161e 100644
--- a/src/js/vignettes.js
+++ b/src/js/vignettes.js
@@ -1690,7 +1690,7 @@ globalThis.GetVignette = function(slave) {
 			}
 			if (slave.nipples === "fuckable" || slave.nipples === "flat") {
 				vignettes.push({
-					text: `${he} lost a customer who refused ${he} could possibly be a proper cow with nipples like ${hers},`,
+					text: `${he} lost a customer who refused to believe ${he} could possibly be a proper cow with nipples like ${hers},`,
 					type: "cash",
 					effect: -1,
 				});
diff --git a/src/js/wombJS.js b/src/js/wombJS.js
index c2a86bec54093f7ecf80e882e4528f5815861999..ea100841dd207f7410043e6e26dfc4e33df304a6 100644
--- a/src/js/wombJS.js
+++ b/src/js/wombJS.js
@@ -47,7 +47,7 @@ globalThis.WombInit = function(actor) {
 	if (actor.pregData === undefined) {
 		actor.pregData = clone(App.Data.misc.pregData.human);
 		// Setup should be through deep copy, so in future, if we like, these values can be changed individually. Gameplay expansion possibilities. But for dev time to simplify debugging:
-		// actor.pregData = setup.pregData.human; // any changes in setup pregData template will be applied immediately to all. But can't be made separate changes.
+		// actor.pregData = App.Data.misc.pregData.human; // any changes in App.Data.misc pregData template will be applied immediately to all. But can't be made separate changes.
 	}
 
 	if (typeof actor.eggType !== 'string') {
diff --git a/src/markets/marketUI.js b/src/markets/marketUI.js
index 0b823840f1aa93e8a716d55c2591404ffc31a03e..be8770010fe5471e0dc092770768419d64500b18 100644
--- a/src/markets/marketUI.js
+++ b/src/markets/marketUI.js
@@ -9,8 +9,8 @@
 App.Markets.purchaseFramework = function(slaveMarket, {sTitleSingular = "slave", sTitlePlural = "slaves", costMod = 1} = {}) {
 	const el = new DocumentFragment();
 	const {slave, text} = generateMarketSlave(slaveMarket, (V.market.numArcology || 1));
-	const costObj = getCost();
-	const cost = costObj.cost;
+	const limitReached = V.slavesSeen > V.slaveMarketLimit;
+	const cost = getCost().cost;
 	let prisonCrime = "";
 	if (slaveMarket === V.prisonCircuit[V.prisonCircuitIndex]) {
 		prisonCrime = pronounsForSlaveProp(slave, text);
@@ -19,35 +19,23 @@ App.Markets.purchaseFramework = function(slaveMarket, {sTitleSingular = "slave",
 	}
 
 	App.Events.addParagraph(el, [
-		`The offered price is`,
-		App.UI.DOM.combineNodes(costObj.report, "."),
-		V.slavesSeen > V.slaveMarketLimit ? `You have cast such a wide net for slaves this week that it is becoming more expensive to find more for sale. Your reputation helps determine your reach within the slave market.` : ``
+		`The offered price is`, App.UI.DOM.combineNodes(getCost().report, "."),
+		limitReached ? `You have cast such a wide net for slaves this week that it is becoming more expensive to find more for sale. Your reputation helps determine your reach within the slave market.` : ``
 	]);
 
 	el.append(choices());
 	return el;
 
 	function getCost() {
-		const costObj = slaveCost(slave, false, !App.Data.misc.lawlessMarkets.includes(slaveMarket), false, true);
-		let cost = costObj.cost;
-		if (V.slavesSeen > V.slaveMarketLimit) {
-			cost += cost * ((V.slavesSeen - V.slaveMarketLimit) * 0.1);
-		}
-		if (costMod > 0 && costMod <= 1) {
-			cost = cost * costMod;
-		} else {
-			cost = cost + costMod;
-		}
-		console.log("CostMod: ", costMod);
-		cost = 500 * Math.trunc(cost / 500);
-		return {cost, report: costObj.report};
+		const {cost, report} = slaveCost(slave, false, !App.Data.misc.lawlessMarkets.includes(slaveMarket), false, true, {limitReached, costMod});
+		return {cost, report};
 	}
 
 	function choices() {
 		const {him, his} = getPronouns(slave);
 		const el = document.createElement("p");
 		let title = {};
-		V.slavesSeen += 1;
+		V.slavesSeen++;
 		if (sTitleSingular === "prisoner") {
 			title = {
 				decline: `Inspect a different prisoner`,
@@ -145,13 +133,13 @@ App.Markets.purchaseFramework = function(slaveMarket, {sTitleSingular = "slave",
 			);
 		}
 
-		el.append(App.Desc.longSlave(slave, {market: slaveMarket, prisonCrime: prisonCrime}));
+		el.append(App.Desc.longSlave(slave, {market: slaveMarket, prisonCrime}));
 		return el;
 
 		function student() {
 			if (App.Data.misc.schools.has(slaveMarket)) {
 				V[slaveMarket].schoolSale = 0;
-				V[slaveMarket].studentsBought += 1;
+				V[slaveMarket].studentsBought++;
 			}
 		}
 	}
diff --git a/src/markets/specificMarkets/corporateMarket.js b/src/markets/specificMarkets/corporateMarket.js
index 74fd3135ecb57dc00df62d87713f1c6afa86b6bc..3b990318bd66e917934a195cd915c559940cc115 100644
--- a/src/markets/specificMarkets/corporateMarket.js
+++ b/src/markets/specificMarkets/corporateMarket.js
@@ -1,6 +1,6 @@
 App.Markets.corporate = function() {
 	const el = new DocumentFragment();
-	let r = [];
+	const r = new SpacedTextAccumulator(el);
 	let dickVision;
 	if (V.corp.SpecGender === 2) {
 		dickVision = 100;
@@ -76,21 +76,26 @@ App.Markets.corporate = function() {
 		r.push(`a rack of`);
 	}
 	r.push(`your corporation's slaves.`);
-	App.UI.DOM.appendNewElement("p", el, r.join(" "));
-	r = [];
-
+	r.toParagraph();
 
 	r.push(`${HeU} explains that the corporation captures many people, so it only retains and trains those that fit its product lines.`);
-
 	let costMod = 1;
 	if (V.corp.Market === 1) {
 		r.push(`Your own local franchise of your corporation allows you to enjoy a discount.`);
 		costMod = 0.9;
+		r.push(App.UI.DOM.link(
+			"End corporate slave sales here and return this sector to standard markets.",
+			() => {
+				V.corp.Market = 0;
+				App.Arcology.cellUpgrade(V.building, App.Arcology.Cell.Market, "Corporate Market", "Markets");
+			},
+			[],
+			"Main"
+		));
 	}
+	r.toParagraph();
 
-	App.UI.DOM.appendNewElement("p", el, App.Markets.purchaseFramework("corporate", {costMod: costMod}));
-
-	r = [];
+	el.append(App.Markets.purchaseFramework("corporate", {costMod: costMod}));
 
 	r.push(`${HisU} presentation done, the`);
 	if (V.corp.SpecDick === 1 && V.corp.SpecPussy === 1) {
@@ -127,10 +132,9 @@ App.Markets.corporate = function() {
 		r.push(`${HeU} gets down on ${hisU} knees right there, making ${hisU} mouth available if you feel like riding ${hisU} face`);
 	}
 	r.push(`while you browse.`);
-	App.UI.DOM.appendNewElement("p", el, r.join(" "));
+	r.toParagraph();
 
-	let result = document.createElement("span");
-	result.id = "result";
+	const result = App.UI.DOM.appendNewElement("span", el);
 	result.append(
 		App.UI.DOM.link(
 			`Use ${himU}`,
@@ -153,22 +157,10 @@ App.Markets.corporate = function() {
 				} else {
 					r.push(`${HeU}'s very well trained, and does all the work. Once you move in and straddle ${himU}, ${heU} gets right down to it, or in this case, up to it. ${HisU} clever tongue runs gently along your labia to build anticipation before starting a delightful dance around and then atop your clitoris. You orgasm in no time at all, a climax which ${heU} carefully prolongs by kissing you full on the pussy in just the right way, only breaking the oral embrace when you've ridden it as far as you'll go.`);
 				}
-				jQuery("#result").empty().append(r.join(" "));
+				jQuery(result).empty().append(r.join(" "));
 			}
 		)
 	);
-	el.append(result);
-	App.UI.DOM.appendNewElement("p", el,
-		App.UI.DOM.link(
-			"End corporate slave sales here and return this sector to standard markets",
-			() => {
-				V.corp.Market = 0;
-				App.Arcology.cellUpgrade(V.building, App.Arcology.Cell.Market, "Corporate Market", "Markets");
-			},
-			[],
-			"Main"
-		)
-	);
 
 	return el;
 };
diff --git a/src/markets/specificMarkets/criminalMarkets.js b/src/markets/specificMarkets/criminalMarkets.js
index 3dd8e65a24ead1c6e4b9751651915f92909ac147..b870c44761fb717589a351935ee2edddc470c6a8 100644
--- a/src/markets/specificMarkets/criminalMarkets.js
+++ b/src/markets/specificMarkets/criminalMarkets.js
@@ -3,12 +3,8 @@ App.Markets["low tier criminals"] = function() {
 	let r = [];
 	// mixed prisoners
 	r.push(`You board the transport to a small prison on the edge of the city spanning from the foot of your arcology with the appearance of an old world police station. You arrive inside and are met by a cute receptionist, asking why one such as yourself would visit such a place. With formalities out of the way, the head of the station is called and arrives shortly. "Well now, didn't expect to see you here. Came to pick up a criminal and give them a chance at not being a menial?" You are then led further into the station and into the prisoners' quarters; most of them appear downcast and dismal, but some look up to see what the commotion is about. "You! Come here! This fine`);
-	if (V.PC.title === 1) {
-		r.push(`gentleman`);
-	} else {
-		r.push(`lady`);
-	}
-	r.push(`wants to take a look, so be on your best behavior!" the head calls out, bringing one of the criminals close enough to be inspected.`);
+	r.push(`${V.PC.title === 1 ? 'gentleman' : 'lady'}`);
+	r.push(`wants to take a look, so be on your best behavior!" the station's head calls out, bringing one of the criminals close enough to be inspected.`);
 	el.append(r.join(" "));
 	el.append(App.Markets.purchaseFramework("low tier criminals", {sTitleSingular: "prisoner", sTitlePlural: "prisoners"}));
 	return el;
@@ -31,11 +27,7 @@ App.Markets["gangs and smugglers"] = function() {
 	App.UI.DOM.appendNewElement("p", el, r.join(" "));
 	r = [];
 	r.push(`You finally reach the warden's office. "Welcome,`);
-	if (V.PC.title === 1) {
-		r.push(`Mister`);
-	} else {
-		r.push(`Miss`);
-	}
+	r.push(`${V.PC.title === 1 ? 'Mister' : 'Miss'}`);
 	r.push(`${V.PC.slaveSurname}. I never thought my prison could have turned to a trade such as this, but times are hard." He beckons you to the seat opposite him. "But I'm not one to complain when opportunities come my way." He motions to his guards to bring in a select stock for your perusal. "We house some tough nuts in this establishment, but if you believe you can capitalize on these criminals, we'll be happy to have you take them off our hands." The guard returns with a convict ready to be sold.`);
 
 	el.append(r.join(" "));
@@ -81,11 +73,7 @@ App.Markets["juvenile detention"] = function() {
 	}
 	r.toParagraph();
 	r.push(`You walk into the lobby of the facility and are greeted by a stern-looking heavyset woman in a warden's uniform. "Always happy to have you visit, `);
-	if (V.PC.title === 1) {
-		r.push(`Mister`);
-	} else {
-		r.push(`Miss`);
-	}
+	r.push(`${V.PC.title === 1 ? 'Mister' : 'Miss'}`);
 	r.push(`${V.PC.slaveSurname}. Your patronage is appreciated. I've arranged for a few of our detainees that need some extra discipline to be present in the courtyard, right this way."`);
 	r.toParagraph();
 	r.push(`Entering the courtyard, you see lines painted on the asphalt for athletic activity, faded through time and wear. A pair of tired basketball hoops and patched soccer goals frame the scene, while a cluster of teens${V.minimumSlaveAge < 13 ? " and preteens" : ""} mills around in one corner. A short blast from a guard's whistle brings them to attention and the warden begins calling them forward, one at a time, and ordering them to strip for inspection.`);
diff --git a/src/markets/specificMarkets/customSlaveMarket.js b/src/markets/specificMarkets/customSlaveMarket.js
index 3ac9f8f5a466f3e6f86fa685d77b1102c3a68e8e..8eb1481e7084a78377d1926b4543573cdf3accf4 100644
--- a/src/markets/specificMarkets/customSlaveMarket.js
+++ b/src/markets/specificMarkets/customSlaveMarket.js
@@ -62,33 +62,23 @@ App.Markets["Custom Slave"] = function() {
 		createDescription(el, description, "age");
 
 		// Choices
-		const select = document.createElement("select");
+		const options = [];
 		for (let i = 0; i < ages.length; i++) {
 			const high = ages[i];
-			const low = (ages[i - 1] + 1 ) || (ages[i] - 1); // First element of array has nothing before it, obviously, so display low as one less than high.
+			const low = (ages[i - 1] + 1) || (ages[i] - 1); // First element of array has nothing before it, obviously, so display low as one less than high.
 			if (low < V.minimumSlaveAge) {
 				continue;
 			} else if (high > V.retirementAge) {
-				const option = document.createElement("option");
-				option.text = `${low}+`;
-				option.value = low.toString();
-				select.append(option);
+				options.push({key: low.toString(), name: `${low}+`});
 				break;
 			}
 
-			const option = document.createElement("option");
-			option.text = `${low}-${high}`;
-			option.value = high.toString();
-			if (slave.age === high) {
-				option.selected = true;
-			}
-			select.append(option);
+			options.push({key: high.toString(), name: `${low}-${high}`});
 		}
-		select.onchange = () => {
-			slave.age = Number(select.options[select.selectedIndex].value);
+		el.append(App.UI.DOM.makeSelect(options, slave.age.toString(), a => {
+			slave.age = Number(a);
 			jQuery("#age-text").empty().append(description());
-		};
-		el.append(select);
+		}));
 		return el;
 
 		function description() {
@@ -297,32 +287,18 @@ App.Markets["Custom Slave"] = function() {
 	function race() {
 		const el = document.createElement("div");
 		const slaveProperty = "race";
-		const choices = new Map([
-			["ethnicity is unimportant", "Ethnicity is unimportant"],
-		]);
-		for (const [race, capRace] of App.Data.misc.filterRaces) {
-			choices.set(race, capRace);
+		const choices = [{key: "ethnicity is unimportant", name: "Ethnicity is unimportant"}];
+		for (const [race, capRace] of App.Data.misc.filterRacesPublic) {
+			choices.push({key: race, name: capRace});
 		}
 
 		createDescription(el, description, slaveProperty);
 
 		// Choices
-
-		const select = document.createElement("select");
-		for (const [value, text] of choices) {
-			const option = document.createElement("option");
-			option.text = text;
-			option.value = value;
-			if (slave.race === option.value) {
-				option.selected = true;
-			}
-			select.append(option);
-		}
-		select.onchange = () => {
-			slave.race = select.options[select.selectedIndex].value;
+		el.append(App.UI.DOM.makeSelect(choices, slave.race, r => {
+			slave.race = r;
 			jQuery("#race-text").empty().append(description());
-		};
-		el.append(select);
+		}));
 
 		function description() {
 			const el = new DocumentFragment();
@@ -345,31 +321,18 @@ App.Markets["Custom Slave"] = function() {
 	function skin() {
 		const el = document.createElement("div");
 		const slaveProperty = "skin";
-		const choices = new Map([
-			["left natural", "Left natural"]
-		]);
+		const choices = [{key: "left natural", name: "Left natural"}];
 		for (const skin of App.Medicine.Modification.naturalSkins) {
-			choices.set(skin, capFirstChar(skin));
+			choices.push({key: skin, name: capFirstChar(skin)});
 		}
 
 		createDescription(el, description, slaveProperty);
 
 		// Choices
-		const select = document.createElement("select");
-		for (const [value, text] of choices) {
-			const option = document.createElement("option");
-			option.text = text;
-			option.value = value;
-			if (slave.skin === option.value) {
-				option.selected = true;
-			}
-			select.append(option);
-		}
-		select.onchange = () => {
-			slave.skin = select.options[select.selectedIndex].value;
+		el.append(App.UI.DOM.makeSelect(choices, slave.skin, s => {
+			slave.skin = s;
 			jQuery("#skin-text").empty().append(description());
-		};
-		el.append(select);
+		}));
 
 		function description() {
 			const el = new DocumentFragment();
@@ -913,7 +876,8 @@ App.Markets["Custom Slave"] = function() {
 				App.UI.DOM.link(
 					"Add",
 					() => {
-						_.set(slave, value, new App.Entity.LimbState());
+						const limb = value.startsWith("leg.") ? new App.Entity.LegState() : new App.Entity.ArmState();
+						_.set(slave, value, limb);
 						jQuery(`#${descText.id}`).empty().append(description(true, text));
 					}
 				)
@@ -942,38 +906,26 @@ App.Markets["Custom Slave"] = function() {
 	function nationality() {
 		const el = document.createElement("div");
 		const slaveProperty = "nationality";
-		const choices = new Map([
-			["slave", "Slave"],
-			["Stateless", "Stateless"],
-			["Nationality is unimportant", "Nationality is unimportant"],
-		]);
+		const choices = [{key: "slave", name: "Slave"},
+			{key: "Stateless", name: "Stateless"},
+			{key: "Nationality is unimportant", name: "Nationality is unimportant"},
+		];
 		for (const nationality of App.Data.misc.baseNationalities) {
-			choices.set(nationality, nationality);
+			choices.push({key: nationality, name: nationality});
 		}
 
 		createDescription(el, description, slaveProperty);
 
 		// Choices
-		const select = document.createElement("select");
-		for (const [value, text] of choices) {
-			const option = document.createElement("option");
-			option.text = text;
-			option.value = value;
-			if (slave.nationality === option.value) {
-				option.selected = true;
-			}
-			select.append(option);
-		}
-		select.onchange = () => {
-			slave.nationality = select.options[select.selectedIndex].value;
+		el.append(App.UI.DOM.makeSelect(choices, slave.nationality, nat => {
+			slave.nationality = nat;
 			jQuery("#nationality-text").empty().append(description());
-		};
-		el.append(select);
+		}));
 
 		function description() {
-			for (const [value, text] of choices) {
-				if (slave.nationality === value) {
-					return `${text}. `;
+			for (const choice of choices) {
+				if (slave.nationality === choice.key) {
+					return `${choice.name}. `;
 				}
 			}
 		}
diff --git a/src/markets/specificMarkets/huskSlave.js b/src/markets/specificMarkets/huskSlave.js
index 940188ef402c869db6b65e4dd47eb4706540b537..656fba5aa571e1ff28a05de72d7fcdd316423796 100644
--- a/src/markets/specificMarkets/huskSlave.js
+++ b/src/markets/specificMarkets/huskSlave.js
@@ -97,7 +97,7 @@ App.Markets["Husk Slave"] = function() {
 		);
 
 		const linkArray = [];
-		const races = new Map(App.Data.misc.filterRaces);
+		const races = new Map(App.Data.misc.filterRacesPublic);
 		races.set("not important", "Not Important");
 		for (const [race, capRace] of races) {
 			if (V.huskSlave.race === race) {
diff --git a/src/markets/specificMarkets/prestigiousSlave.js b/src/markets/specificMarkets/prestigiousSlave.js
index f8e3e6bf4052a2aeec6bc92255159745dd42db2e..20e721233a79f1111bbd254f8d6908fe5d76cf97 100644
--- a/src/markets/specificMarkets/prestigiousSlave.js
+++ b/src/markets/specificMarkets/prestigiousSlave.js
@@ -49,19 +49,12 @@ App.Markets["Prestigious Slave"] = function() {
 				content.append(passage());
 			};
 			const cheatOptions = (V.seeDicks > 0) ? options.concat(...dickOptions) : Array.from(options);
-			const slaveDropdown = App.UI.DOM.appendNewElement("select", frag);
-			for (const o of cheatOptions) {
-				const choice = App.UI.DOM.appendNewElement("option", slaveDropdown, capFirstChar(o));
-				choice.value = o;
-				if (seed === o) {
-					choice.selected = true;
-				}
-			}
-			slaveDropdown.onchange = () => {
-				const O = slaveDropdown.options[slaveDropdown.selectedIndex];
-				seed = O.value;
+			frag.append(App.UI.DOM.makeSelect(cheatOptions.map(v => {
+				return {key: v, name: capFirstChar(v)};
+			}), seed, v => {
+				seed = v;
 				reload();
-			};
+			}));
 			App.UI.DOM.appendNewElement("span", frag, App.UI.DOM.link(" Refresh slave", reload));
 		}
 		slave = makeSlave(seed);
diff --git a/src/markets/specificMarkets/schoolFutanari.js b/src/markets/specificMarkets/schoolFutanari.js
index d43461afdeaaac6daec2290eb44d9313d161cc49..f8e8ba9b80d4ce2cd23de548d8e655379c82449b 100644
--- a/src/markets/specificMarkets/schoolFutanari.js
+++ b/src/markets/specificMarkets/schoolFutanari.js
@@ -32,7 +32,7 @@ App.Markets.TFS = function() {
 				App.UI.DOM.appendNewElement("p", el, `It hasn't been long enough since you allowed them to use your organ farm to add ovaries to themselves for the effects to be obvious yet. Most of them are doubtless pregnant, however. There's been a subtle shift in their sexual behavior, too: they're much more likely to focus on vaginal sex than they were before, so much so that they often double penetrate each others' pussies. When there aren't any cunts available, they do their best to hold their orgasms until one opens up, so to speak.`);
 			}
 		}
-		App.UI.DOM.appendNewElement("p", el, `Visitors are not common: in fact, visitors are only as frequent as you feel like visiting. It takes a while before they notice you. When a dreamy-eyed young futa finally does, she reaches a lazy hand over to alert the eldest one present by tugging on one of her nipples and pointing in your direction. The elder looks over at you and gives you a friendly wave followed by a wait-one-moment gesture. She's curled up on her back with her cockhead in her own mouth, using both hands to give her own shaft a boob job while a younger futa is eats her ass and fingers her pussy. The futa matron orgasms promptly, sucking down her own cum. She gets up languidly, her plush body, softening forearm-sized dick, and enormous natural boobs making it a wonderful sight.`);
+		App.UI.DOM.appendNewElement("p", el, `Visitors are not common: in fact, visitors are only as frequent as you feel like visiting. It takes a while before they notice you. When a dreamy-eyed young futa finally does, she reaches a lazy hand over to alert the eldest one present by tugging on one of her nipples and pointing in your direction. The elder looks over at you and gives you a friendly wave followed by a wait-one-moment gesture. She's curled up on her back with her cockhead in her own mouth, using both hands to give her own shaft a boob job while a younger futa eats her ass and fingers her pussy. The futa matron orgasms promptly, sucking down her own cum. She gets up languidly, her plush body, softening forearm-sized dick, and enormous natural boobs making it a wonderful sight.`);
 
 		r = [];
 		if (V.PC.title === 1) {
@@ -57,7 +57,6 @@ App.Markets.TFS = function() {
 		App.UI.DOM.appendNewElement("p", el, r.join(" "));
 
 		const result = App.UI.DOM.appendNewElement("p", el);
-		result.id = "result";
 		App.UI.DOM.appendNewElement(
 			"div",
 			result,
@@ -76,7 +75,7 @@ App.Markets.TFS = function() {
 						r.push(`and trails nibbles and kisses along your inner thighs before nuzzling her plush lips and hot tongue against your womanhood. Perusing the very thorough pictures and videos of the pretty futanari for sale here is arousing enough without a truly masterful cunt pleaser working her magic between your legs, and you've orgasmed before you finish one listing. She prolongs the climax cleverly and then starts to build you towards another.`);
 					}
 
-					jQuery("#result").empty().append(r.join(" "));
+					jQuery(result).empty().append(r.join(" "));
 				}
 			)
 		);
@@ -144,7 +143,7 @@ App.Markets.TFS = function() {
 							default:
 								V.futaAddiction = 0;
 						}
-						jQuery("#result").empty().append(r.join(" "));
+						jQuery(result).empty().append(r.join(" "));
 					}
 				)
 			);
diff --git a/src/markets/specificMarkets/slaveShelter.js b/src/markets/specificMarkets/slaveShelter.js
index 792da858761877d8a1c1abcc5119399b3cbba3c9..3aaee6e3bcd3f83db72c29c9561f6f09d99145a9 100644
--- a/src/markets/specificMarkets/slaveShelter.js
+++ b/src/markets/specificMarkets/slaveShelter.js
@@ -69,7 +69,7 @@ App.Markets["Slave Shelter"] = function() {
 					V.shelterSlave.career = "a slave";
 					eyeSurgery(V.shelterSlave, "both", "blind");
 					setEyeColor(V.shelterSlave, "milky white");
-					V.shelterSlave.custom.desc = "$He has an obvious burn across $his eyes.";
+					App.Medicine.Modification.addScar(V.shelterSlave, "face", "burn", 2);
 					V.shelterSlave.devotion = jsRandom(-100, -90);
 					V.shelterSlave.trust = jsRandom(-100, -90);
 					setHealth(V.shelterSlave, jsRandom(-60, -40), normalRandInt(10, 3), normalRandInt(20, 3));
@@ -121,7 +121,7 @@ App.Markets["Slave Shelter"] = function() {
 					V.shelterSlave.behavioralFlaw = either("anorexic", "anorexic", "anorexic", "odd");
 					V.shelterSlave.sexualFlaw = either("apathetic", "neglectful", "self hating");
 					V.shelterSlave.fetish = either("masochist", "none", "none");
-					V.shelterSlave.custom.desc = "The scars from $his crudely performed self-castration are still visible on $his lower groin.";
+					App.Medicine.Modification.addScar(V.shelterSlave, "pubic mound", "scars from $his crudely performed self-castration");
 					break;
 				case "cannibal victim female":
 					if (V.pedo_mode === 1) {
@@ -144,7 +144,8 @@ App.Markets["Slave Shelter"] = function() {
 					V.shelterSlave.behavioralFlaw = either("anorexic", "anorexic", "anorexic", "odd");
 					V.shelterSlave.sexualFlaw = either("apathetic", "neglectful", "self hating");
 					V.shelterSlave.fetish = either("masochist", "none", "none");
-					V.shelterSlave.custom.desc = "$His chest is covered by an ugly mess of scar tissue.";
+					App.Medicine.Modification.addScar(V.shelterSlave, "left breast", "an ugly mess of scar tissue");
+					App.Medicine.Modification.addScar(V.shelterSlave, "right breast", "an ugly mess of scar tissue");
 					break;
 				case "degraded DoL":
 					V.shelterSlave = GenerateNewSlave(null, {minAge: 14, disableDisability: 1, ageOverridesPedoMode: 1});
diff --git a/src/neighbor/arcologyDiplomacy.js b/src/neighbor/arcologyDiplomacy.js
index a49fec0339156804894ed5a956b6c04af7129feb..2bce76fea10aeba8f349280f7d3660a41ea002a9 100644
--- a/src/neighbor/arcologyDiplomacy.js
+++ b/src/neighbor/arcologyDiplomacy.js
@@ -100,6 +100,10 @@ App.Neighbor.PassiveFSInfluence = class {
 		let conflicting = new Map();
 		const arcology = V.arcologies[this._arcID];
 
+		if (arcology.direction === 0 && fs === "FSNull") {
+			return ``; // Multiculturalism in the player's arcology is not affected by passive influence
+		}
+
 		for (const [i, rel] of this._relationships) {
 			if (rel.shared.some((s) => s === fs)) {
 				if (V.arcologies[i][fs] > arcology[fs] + this._thresh) {
@@ -136,8 +140,7 @@ App.Neighbor.PassiveFSInfluence = class {
 			}
 			t.push(`in ${arcology.name} is influenced by`);
 			const sharedNames = shared.map((i) => V.arcologies[i].name + "'s");
-			t.push(sharedNames.reduce((res, ch, i, arr) => res + (i === arr.length - 1 ? ' and ' : ', ') + ch) +
-				` more advanced ${shared.length === 1 ? "society" : "societies"}.`);
+			t.push(`${toSentence(sharedNames)} more advanced ${shared.length === 1 ? "society" : "societies"}.`);
 		}
 
 		// passive slowing influence
@@ -154,10 +157,9 @@ App.Neighbor.PassiveFSInfluence = class {
 			let conflictOutput = [];
 			for (const [conflictFS, arcs] of conflicting) {
 				const conflictNames = arcs.map((i) => V.arcologies[i].name + "'s");
-				conflictOutput.push(conflictNames.reduce((res, ch, i, arr) => res + (i === arr.length - 1 ? ' and ' : ', ') + ch) +
-					` more advanced ${FutureSocieties.displayAdj(conflictFS)} ${arcs.length === 1 ? "society" : "societies"}`);
+				conflictOutput.push(`${toSentence(conflictNames)} more advanced ${FutureSocieties.displayAdj(conflictFS)} ${arcs.length === 1 ? "society" : "societies"}`);
 			}
-			t.push(conflictOutput.reduce((res, ch, i, arr) => res + (i === arr.length - 1 ? ' and ' : ', ') + ch) + '.');
+			t.push(toSentence(conflictOutput) + '.');
 		}
 
 		return t.join(" ");
diff --git a/src/neighbor/neighborDescription.js b/src/neighbor/neighborDescription.js
index be0408f197757524e9be12a778520fc07010c412..72d1f0f3c4f7a9619b6b8300666b5f5ec18466b9 100644
--- a/src/neighbor/neighborDescription.js
+++ b/src/neighbor/neighborDescription.js
@@ -35,7 +35,7 @@ App.UI.neighborDescription = function(i) {
 	}
 	let economicUncertainty = App.Utils.economicUncertainty(i);
 	if (V.arcologies[i].direction === 0) {
-		r.push(`You control <span class="lime">${V.arcologies[i].ownership}%</span> of the arcology, and the largest minority holder controls <span class="orange">${V.arcologies[i].minority}%.</span>`);
+		r.push(`You control <span class="lime">${V.arcologies[i].ownership}%</span> of the arcology${V.arcologies[0].ownership !== 100 ? `, and the largest minority holder controls <span class="orange">${V.arcologies[i].minority}%.</span>` : `.`}`);
 	} else if ((V.arcologies[i].government !== "your trustees") && (V.arcologies[i].government !== "your agent")) {
 		r.push(`Its leadership has control of approximately <span class="orange">${Math.trunc(V.arcologies[i].ownership*economicUncertainty)}%</span> of the arcology${(V.arcologies[i].minority > V.arcologies[i].ownership-10) ? `, a dangerously narrow margin over competition with a <span class="tan">${Math.trunc(V.arcologies[i].minority*economicUncertainty)}%</span> share` : ``}.`);
 	}
diff --git a/src/neighbor/neighborInteract.js b/src/neighbor/neighborInteract.js
index 8f2b6ae0b64b5628076c162f0a78296466096bc0..b6d6bfd4b94403d4941f9bd663883df1ddd849f0 100644
--- a/src/neighbor/neighborInteract.js
+++ b/src/neighbor/neighborInteract.js
@@ -119,6 +119,7 @@ App.Neighbor.Interact = function() {
 
 	const interact = (function() {
 		let nd = new App.Neighbor.Display((id) => replaceDetails(id));
+		const DEMAND_PER_PERCENT = 2;
 
 		return list;
 
@@ -183,8 +184,7 @@ App.Neighbor.Interact = function() {
 					App.UI.DOM.appendNewElement("p", frag, `Your arcology's culture is capable of starting to exert cultural sway over other arcologies. It can project ${desc[0]}.`);
 				}
 			} else {
-				const ownershipCost = 500 * Math.trunc(V.arcologies[arcID].prosperity * (1 + (V.arcologies[arcID].demandFactor / 100)));
-				frag.append(`A 1% interest in this arcology is worth ${cashFormat(ownershipCost)}. `);
+				frag.append(`A 1% interest in this arcology is worth ${cashFormat(buyValue(V.arcologies[arcID], 1))}. `);
 				if (V.arcologies[arcID].ownership + V.arcologies[arcID].PCminority + V.arcologies[arcID].minority < 100) {
 					frag.append(`The transaction fee is ${cashFormat(10000)}.`);
 				}
@@ -192,18 +192,16 @@ App.Neighbor.Interact = function() {
 				if (V.arcologies[arcID].ownership + V.arcologies[arcID].PCminority + V.arcologies[arcID].minority < 100) {
 					let links = [];
 					links.push(App.UI.DOM.link("Buy", () => {
-						cashX(forceNeg(ownershipCost), "war");
-						cashX(-10000, "war");
+						cashX(-(buyValue(V.arcologies[arcID], 1) + 10000), "war");
 						V.arcologies[arcID].PCminority += 1;
-						V.arcologies[arcID].demandFactor += 2;
+						V.arcologies[arcID].demandFactor += DEMAND_PER_PERCENT;
 					}, [], "Neighbor Interact"));
 					if (V.arcologies[arcID].ownership + V.arcologies[arcID].PCminority + V.arcologies[arcID].minority <= 90) {
-						if (V.cash > ownershipCost * 10) {
+						if (V.cash > buyValue(V.arcologies[arcID], 10) + 10000) {
 							const link = App.UI.DOM.link("10%", () => {
-								cashX(forceNeg(ownershipCost * 10), "war");
-								cashX(-10000, "war");
+								cashX(-(buyValue(V.arcologies[arcID], 10) + 10000), "war");
 								V.arcologies[arcID].PCminority += 10;
-								V.arcologies[arcID].demandFactor += 20;
+								V.arcologies[arcID].demandFactor += DEMAND_PER_PERCENT * 10;
 							}, [], "Neighbor Interact");
 							links.push(link);
 						}
@@ -217,9 +215,9 @@ App.Neighbor.Interact = function() {
 				if (V.arcologies[arcID].PCminority > 0) {
 					let links = [];
 					links.push(App.UI.DOM.link("Sell", () => {
-						cashX(ownershipCost, "war");
+						cashX(sellValue(V.arcologies[arcID], 1), "war");
 						V.arcologies[arcID].PCminority -= 1;
-						V.arcologies[arcID].demandFactor -= 2;
+						V.arcologies[arcID].demandFactor -= DEMAND_PER_PERCENT;
 						if (V.arcologies[arcID].government !== "your agent" && V.arcologies[arcID].government !== "your trustees" && V.arcologies[arcID].rival !== 1) {
 							if (V.arcologies[arcID].ownership + V.arcologies[arcID].PCminority + V.arcologies[arcID].minority < 10) {
 								V.arcologies[arcID].ownership += 10;
@@ -229,9 +227,9 @@ App.Neighbor.Interact = function() {
 					}, [], "Neighbor Interact"));
 					if (V.arcologies[arcID].PCminority >= 10) {
 						links.push(App.UI.DOM.link("10%", () => {
-							cashX((ownershipCost * 10), "war");
+							cashX(sellValue(V.arcologies[arcID], 10), "war");
 							V.arcologies[arcID].PCminority -= 10;
-							V.arcologies[arcID].demandFactor -= 20;
+							V.arcologies[arcID].demandFactor -= DEMAND_PER_PERCENT * 10;
 							if (V.arcologies[arcID].government !== "your agent" && V.arcologies[arcID].government !== "your trustees" && V.arcologies[arcID].rival !== 1) {
 								if (V.arcologies[arcID].ownership + V.arcologies[arcID].PCminority + V.arcologies[arcID].minority < 10) {
 									V.arcologies[arcID].ownership += 10;
@@ -273,6 +271,34 @@ App.Neighbor.Interact = function() {
 			return frag;
 		}
 
+		/**
+		 * How much does it cost to buy x percent of a given arcology
+		 * @param {FC.ArcologyState} arc
+		 * @param {number} percent
+		 * @returns {number}
+		 */
+		function buyValue(arc, percent) {
+			const baseValue = 500 * arc.prosperity;
+			// scale the demand in such a way that buying twice in a row costs the same as buying double once.
+			const scaledDemand = arc.demandFactor + (DEMAND_PER_PERCENT * (percent / 2));
+			const scalingFactor = 1 + (scaledDemand / 100);
+			return Math.round(baseValue * scalingFactor * percent);
+		}
+
+		/**
+		 * How much does the player get when selling x percent of a given arcology
+		 * @param {FC.ArcologyState} arc
+		 * @param {number} percent
+		 * @returns {number}
+		 */
+		function sellValue(arc, percent) {
+			const baseValue = 500 * arc.prosperity;
+			// scale the demand in such a way that selling twice in a row gives the same as selling double once.
+			const scaledDemand = arc.demandFactor - (DEMAND_PER_PERCENT * (percent / 2));
+			const scalingFactor = 1 + (scaledDemand / 100);
+			return Math.round(baseValue * scalingFactor * percent);
+		}
+
 		/** Create a div containing actions specific to arcologies that are under the player's control
 		 * @param {number} arcID
 		 * @returns {Element}
diff --git a/src/npc/agent/agentCompany.js b/src/npc/agent/agentCompany.js
index 5d4d65093c590c53cd745ed16a6a21ca6856255c..6da9ad67c910620402efce06952f023a89f4cc6d 100644
--- a/src/npc/agent/agentCompany.js
+++ b/src/npc/agent/agentCompany.js
@@ -45,7 +45,7 @@ App.UI.SlaveInteract.agentCompany = function(lover) {
 	r.push(`${agent.slaveName} smiles back at ${him}, glowing with pleasure, and responds with exaggerated arousal.`);
 	switch (agent.fetish) {
 		case "submissive":
-			r.push(Spoken(agent, `"Looking forward to sleeping in your arms, babe,"`), `the submissive`);
+			r.push(Spoken(agent, `"Looking forward to sleeping ${hasBothArms(agent) ? "in your arms" : "with you"}, babe,"`), `the submissive`);
 			break;
 		case "cumslut":
 			r.push(Spoken(agent, `"Can't wait to kiss you, babe,"`), `the orally fixated`);
diff --git a/src/npc/bodyguard/bgDescription.js b/src/npc/bodyguard/bgDescription.js
index 5bd634470ccd346eb9f92bb07585ae05e45bb098..1d2257ac1443a73939de6e63d0221022b50273b3 100644
--- a/src/npc/bodyguard/bgDescription.js
+++ b/src/npc/bodyguard/bgDescription.js
@@ -36,7 +36,25 @@ App.Desc.bodyguard = function(slave) {
 	function bgWeapon() {
 		const w = [];
 		if ((slave.muscles + slave.height - 100) / 25 > 5) {
-			w.push(`${He} has a long ceramic sword strapped to ${his} back,`);
+			w.push(`${He} has a long ceramic`);
+				if (V.arcologies[0].FSRomanRevivalist !== "unset") {
+					w.push('spatha');
+				} else if (V.arcologies[0].FSNeoImperialist !== "unset") {
+					w.push(`claymore`);
+				} else if (V.arcologies[0].FSEgyptianRevivalist !== "unset") {
+					w.push(`shotel`);
+				} else if (V.arcologies[0].FSEdoRevivalist !== "unset") {
+					w.push(`odachi`);
+				} else if (V.arcologies[0].FSArabianRevivalist !== "unset") {
+					w.push(`kilij`);
+				} else if (V.arcologies[0].FSChineseRevivalist !== "unset") {
+					w.push(`changdao`);
+				} else if (V.arcologies[0].FSAztecRevivalist !== "unset") {
+					w.push(`macuahuitl`);
+				} else {
+					w.push(``);
+				}
+			w.push(`sword strapped to ${his} back,`);
 			switch (slave.nationality) {
 				case "American":
 					w.push(`and, in keeping with ${his} heritage, a US Ordnance Mk43 Mod.1 GPMG`);
@@ -148,7 +166,25 @@ App.Desc.bodyguard = function(slave) {
 			}
 			w.push(`slung crosswise on ${his} chest.`);
 		} else if ((slave.muscles + slave.height - 100) / 25 > 4) {
-			w.push(`${He} has a ceramic sword strapped to ${his} back`);
+			w.push(`${He} has a ceramic`);
+				if (V.arcologies[0].FSRomanRevivalist !== "unset") {
+					w.push('gladius');
+				} else if (V.arcologies[0].FSNeoImperialist !== "unset") {
+					w.push(`kightly`);
+				} else if (V.arcologies[0].FSEgyptianRevivalist !== "unset") {
+					w.push(`khopesh`);
+				} else if (V.arcologies[0].FSEdoRevivalist !== "unset") {
+					w.push(`katana`);
+				} else if (V.arcologies[0].FSArabianRevivalist !== "unset") {
+					w.push(`shamshir`);
+				} else if (V.arcologies[0].FSChineseRevivalist !== "unset") {
+					w.push(`jian`);
+				} else if (V.arcologies[0].FSAztecRevivalist !== "unset") {
+					w.push(`macuahuitl`);
+				} else {
+					w.push(``);
+				}
+			w.push(`sword strapped to ${his} back`);
 			switch (slave.nationality) {
 				case "American":
 					w.push(`and, in keeping with ${his} heritage, a Colt M16A4 assault rifle`);
@@ -290,7 +326,25 @@ App.Desc.bodyguard = function(slave) {
 			}
 			w.push(`slung across ${his} chest.`);
 		} else if ((slave.muscles + slave.height - 100) / 25 > 3) {
-			w.push(`${He} has a straight ceramic sword strapped to ${his} back`);
+			w.push(`${He} has a`);
+				if (V.arcologies[0].FSRomanRevivalist !== "unset") {
+					w.push('curved ceramic falcata');
+				} else if (V.arcologies[0].FSNeoImperialist !== "unset") {
+					w.push(`straight ceramic estoc`);
+				} else if (V.arcologies[0].FSEgyptianRevivalist !== "unset") {
+					w.push(`sickle-shaped`);
+				} else if (V.arcologies[0].FSEdoRevivalist !== "unset") {
+					w.push(`curved ceramic wakizashi`);
+				} else if (V.arcologies[0].FSArabianRevivalist !== "unset") {
+					w.push(`curved ceramic yatagan`);
+				} else if (V.arcologies[0].FSChineseRevivalist !== "unset") {
+					w.push(`curved ceramic dao`);
+				} else if (V.arcologies[0].FSAztecRevivalist !== "unset") {
+					w.push(`straight ceramic macuahuitl`);
+				} else {
+					w.push(`straight ceramic`);
+				}
+			w.push(`sword strapped to ${his} back`);
 			switch (slave.nationality) {
 				case "American":
 					w.push(`and, in keeping with ${his} heritage, a KRISS Vector SMG`);
@@ -398,7 +452,25 @@ App.Desc.bodyguard = function(slave) {
 			}
 			w.push(`slung across ${his} chest.`);
 		} else {
-			w.push(`${He} has a short ceramic sword strapped to ${his} back`);
+			w.push(`${He} has a short ceramic`);
+				if (V.arcologies[0].FSRomanRevivalist !== "unset") {
+					w.push('pugio');
+				} else if (V.arcologies[0].FSNeoImperialist !== "unset") {
+					w.push(`baselard`);
+				} else if (V.arcologies[0].FSEgyptianRevivalist !== "unset") {
+					w.push(`acinaces`);
+				} else if (V.arcologies[0].FSEdoRevivalist !== "unset") {
+					w.push(`tanto`);
+				} else if (V.arcologies[0].FSArabianRevivalist !== "unset") {
+					w.push(`jambiya`);
+				} else if (V.arcologies[0].FSChineseRevivalist !== "unset") {
+					w.push(`nandao`);
+				} else if (V.arcologies[0].FSAztecRevivalist !== "unset") {
+					w.push(`macuahuitl`);
+				} else {
+					w.push(``);
+				}
+			w.push(`sword strapped to ${his} back`);
 			switch (slave.nationality) {
 				case "American":
 					w.push(`and, in keeping with ${his} heritage, a MAC-10 machine pistol`);
diff --git a/src/npc/children/ChildState.js b/src/npc/children/ChildState.js
index 0c74279d58d4ea6fd11250f4005589b5c3f0100b..febdfae4c1a7f098ef43be27749bb4a5198dc553 100644
--- a/src/npc/children/ChildState.js
+++ b/src/npc/children/ChildState.js
@@ -24,11 +24,11 @@ App.Facilities.Nursery.ChildState = class ChildState {
 		 * _0: Obtained prior to game start / at game start_ */
 		this.weekAcquired = 0;
 		/** Child's origin
-		 * @type {FC.Zeroable<string>} */
+		 * @type {string} */
 		this.origin = "$He was born and raised in your arcology.";
 		/** Career prior to enslavement
-		 * @type {FC.Zeroable<string>} */
-		this.career = 0;
+		 * @type {string} */
+		this.career = "a slave";
 		/** Child's ID */
 		this.ID = 0;
 		/**
@@ -352,8 +352,8 @@ App.Facilities.Nursery.ChildState = class ChildState {
 		 * * 6: swiss army leg
 		 */
 		this.leg = {
-			left: new App.Entity.LimbState(),
-			right: new App.Entity.LimbState()
+			left: new App.Entity.LegState(),
+			right: new App.Entity.LegState()
 		};
 		/**
 		 * arms of the slave
@@ -366,8 +366,8 @@ App.Facilities.Nursery.ChildState = class ChildState {
 		 * * 6: swiss army arm
 		 */
 		this.arm = {
-			left: new App.Entity.LimbState(),
-			right: new App.Entity.LimbState()
+			left: new App.Entity.ArmState(),
+			right: new App.Entity.ArmState()
 		};
 		/** Are heels clipped
 		 *
@@ -466,7 +466,7 @@ App.Facilities.Nursery.ChildState = class ChildState {
 		 * * "fillable"
 		 * * "advanced fillable"
 		 * * "hyper fillable"
-		 * @type {FC.SizingImplantType}
+		 * @type {FC.InstalledSizingImplantType}
 		 */
 		this.boobsImplantType = "none";
 		/**
@@ -584,7 +584,7 @@ App.Facilities.Nursery.ChildState = class ChildState {
 		 * * "fillable"
 		 * * "advanced fillable"
 		 * * "hyper fillable"
-		 * @type {FC.SizingImplantType}
+		 * @type {FC.InstalledSizingImplantType}
 		 */
 		this.buttImplantType = "none";
 		/**
@@ -1900,8 +1900,14 @@ App.Facilities.Nursery.ChildState = class ChildState {
 			/** Is the slave immortal?
 			 * @type {FC.Bool}
 			 * 0: no; 1: yes */
-			immortality: 0
-		};
+			 immortality: 0,
+			 /** Is the slave's milk flavored?
+			  * @type {FC.Bool}
+			  * 0: no; 1: yes */
+			 flavoring: 0
+		 };
+		 /** flavor of their milk*/
+		 this.milkFlavor = "none";
 		/* eslint-disable camelcase*/
 		this.NCSyouthening = 0;
 		this.override_Race = 0;
diff --git a/src/npc/children/childSummary.js b/src/npc/children/childSummary.js
index 39e1ccd891f8d0d157c71a4e400a0b5cf4edad04..0b6499fee5fceea96df8ac4f3b216a6fc6285489 100644
--- a/src/npc/children/childSummary.js
+++ b/src/npc/children/childSummary.js
@@ -259,7 +259,7 @@ App.Facilities.Nursery.ChildSummary = function(child) {
 		}
 		r += `&nbsp;&nbsp;&nbsp;&nbsp;`;
 		rulesAssistant(child);
-		if (abbreviate.origins === 2 && child.origin !== 0) {
+		if (abbreviate.origins === 2 && child.origin !== "") {
 			origins(child);
 		}
 		return r;
diff --git a/src/npc/databases/cheatmodeDatabase.js b/src/npc/databases/cheatmodeDatabase.js
index 21c46257673df7d2c9cb5e205cfe197c5123da11..93236105eaed23226f9ef389c7ba5811bedd9ced 100644
--- a/src/npc/databases/cheatmodeDatabase.js
+++ b/src/npc/databases/cheatmodeDatabase.js
@@ -126,7 +126,7 @@ App.Intro.cheatModeSlaves = function() {
 	cheatSlave.attrXX = 80;
 	cheatSlave.attrXY = 40;
 	cheatSlave.fetishKnown = 1;
-	cheatSlave.brand["left hand"] = "a large letter 'S'";
+	App.Medicine.Modification.addBrand(cheatSlave, "left hand", "a large letter 'S'");
 	cheatSlave.custom.desc = "$He speaks with the demeaning accent of slaves from the Old South.";
 	if (V.seeDicks !== 0) {
 		cheatSlave.genes = "XY";
@@ -193,7 +193,7 @@ App.Intro.cheatModeSlaves = function() {
 	cheatSlave.energy = 100;
 	cheatSlave.attrXY = 40;
 	cheatSlave.fetishKnown = 1;
-	cheatSlave.brand["left hand"] = "a large letter 'S'";
+	App.Medicine.Modification.addBrand(cheatSlave, "left hand", "a large letter 'S'");
 	cheatSlave.custom.desc = "$He speaks with the demeaning accent of slaves from the Old South.";
 	cheatSlave.mother = 990001;
 	if (V.seeDicks !== 100) {
diff --git a/src/npc/databases/dSlavesDatabase.js b/src/npc/databases/dSlavesDatabase.js
index 57d725ec95ecd7107f43991c0d8cf137896490b1..f10b60df74d8f12b674e02fc877b9949502503cc 100644
--- a/src/npc/databases/dSlavesDatabase.js
+++ b/src/npc/databases/dSlavesDatabase.js
@@ -900,8 +900,8 @@ App.Data.HeroSlaves.D = [
 		height: 155,
 		race: "white",
 		eye: {origColor: "blue"},
-		origHColor: "strawberry blonde",
-		pubicHColor: "strawberry blonde",
+		origHColor: "strawberry-blonde",
+		pubicHColor: "strawberry-blonde",
 		origSkin: "white",
 		hLength: 60,
 		hStyle: "luxurious",
@@ -1813,8 +1813,8 @@ App.Data.HeroSlaves.D = [
 		weight: 20,
 		race: "white",
 		eye: {origColor: "green"},
-		origHColor: "strawberry blonde",
-		pubicHColor: "strawberry blonde",
+		origHColor: "strawberry-blonde",
+		pubicHColor: "strawberry-blonde",
 		origSkin: "white",
 		hLength: 60,
 		hStyle: "neat",
diff --git a/src/npc/descriptions/boobs/boobs.js b/src/npc/descriptions/boobs/boobs.js
index b1edaaf2396621e8330052131fd0f336e32328d5..edaa2296cd827cc7fa45ca53bbba8c7d7235bfb0 100644
--- a/src/npc/descriptions/boobs/boobs.js
+++ b/src/npc/descriptions/boobs/boobs.js
@@ -601,7 +601,7 @@ App.Desc.boobs = function() {
 					} else if (slave.boobs > 2000) {
 						r += `${slave.slaveName}'s ${adjNoun} are bulging inside a beautiful halter top dress.`;
 					} else if (slave.boobs > 800) {
-						r += `${slave.slaveName}'s is draped inside a beautiful halter top dress, making ${his} ${adjNoun} the center of attention.`;
+						r += `${slave.slaveName}'s ${adjNoun} are draped inside a beautiful halter top dress, making them the center of attention.`;
 					} else if (slave.boobs < 300) {
 						r += `${slave.slaveName} is wearing a beautiful silky halter top dress, almost as if it was sculpted to hug ${his} flat chest.`;
 					} else {
@@ -920,13 +920,13 @@ App.Desc.boobs = function() {
 					if (slave.boobs > 20000) {
 						r += `${slave.slaveName} is wearing a massively oversized custom crop-top designed to handle ${his} monumental tits. Even so, it's stretched taut just struggling to cover ${his} nipples, causing acres of breast flesh to spill out from under and above it.`;
 					} else if (slave.boobs > 10000) {
-						r += `${slave.slaveName}'s oversized crop-top struggles to contain even half of ${his} ${adjNoun} leaving plenty of underboob visible alongside with ${his} cleavage. Every motion risks a nipple popping free.`;
+						r += `${slave.slaveName}'s oversized crop-top struggles to contain even half of ${his} ${adjNoun}, leaving plenty of underboob visible alongside with ${his} cleavage. Every motion risks a nipple popping free.`;
 					} else if (slave.boobs > 8000) {
-						r += `${slave.slaveName}'s oversized crop-top struggles to contain ${his} ${adjNoun} leaving plenty of underboob visible alongside with ${his} cleavage.`;
+						r += `${slave.slaveName}'s oversized crop-top struggles to contain ${his} ${adjNoun}, leaving plenty of underboob visible alongside with ${his} cleavage.`;
 					} else if (slave.boobs > 4000) {
 						r += `${slave.slaveName} has swapped up to the largest crop-top available. Even so, it barely covers them and creates plenty of cleavage.`;
 					} else if (slave.boobs > 2000) {
-						r += `${slave.slaveName}'s crop-top struggles to contain ${his} ${adjNoun} leaving plenty of underboob visible alongside with ${his} cleavage.`;
+						r += `${slave.slaveName}'s crop-top struggles to contain ${his} ${adjNoun}, leaving plenty of underboob visible alongside with ${his} cleavage.`;
 					} else if (slave.boobs > 800) {
 						r += `${slave.slaveName}'s crop-top tightly hugs ${his} ${adjNoun} creating plenty of cleavage.`;
 					} else if (slave.boobs < 300) {
@@ -1688,7 +1688,7 @@ App.Desc.nipples = function(slave, descType) {
 					}
 					break;
 				case "fuckable":
-					r += `swollen shut ${slave.lactation > 0 ? 'and leaking milk' : ''}.`;
+					r += `swollen shut and leaking ${slave.milkFlavor === "none" ? `` : `${slave.milkFlavor} flavored `}milk.`;
 					break;
 				default:
 					r += 'stiffly erect.';
@@ -1784,19 +1784,19 @@ App.Desc.nipples = function(slave, descType) {
 
 	if (slave.lactation > 0) {
 		if ((slave.assignment === App.Data.Facilities.dairy.jobs.cow.assignment) && (V.dairyRestraintsSetting > 1)) {
-			r += ` The transparent lines coming off the cups attached to each of ${his} nipples are white with a constant stream of milk.`;
+			r += ` The transparent lines coming off the cups attached to each of ${his} nipples are white with a constant stream of ${slave.milkFlavor === "none" ? `` : `${slave.milkFlavor} flavored `}milk.`;
 		} else if (slave.lactation === 1) {
 			if (slave.boobs > 300) {
 				if (slave.boobsMilk > 0) {
-					r += ` ${His} breasts are painfully engorged with milk.`;
+					r += ` ${His} breasts are painfully engorged with ${slave.milkFlavor === "none" ? `` : `${slave.milkFlavor} flavored `}milk.`;
 				} else {
-					r += ` ${His} motherly breasts are full of milk.`;
+					r += ` ${His} motherly breasts are full of ${slave.milkFlavor === "none" ? `` : `${slave.milkFlavor} flavored `}milk.`;
 				}
 			} else {
 				if (slave.boobsMilk > 0) {
-					r += ` ${His} chest is painfully engorged with milk and leaks with the slightest provocation.`;
+					r += ` ${His} chest is painfully engorged with ${slave.milkFlavor === "none" ? `` : `${slave.milkFlavor} `}milk and leaks with the slightest provocation.`;
 				} else {
-					r += ` ${His} sensitive chest is swollen with milk.`;
+					r += ` ${His} sensitive chest is swollen with ${slave.milkFlavor === "none" ? `` : `${slave.milkFlavor} flavored `}milk.`;
 				}
 			}
 		} else if (slave.fuckdoll > 0) {
@@ -1807,9 +1807,9 @@ App.Desc.nipples = function(slave, descType) {
 			} else if (slave.nipples === "inverted") {
 				r += ` ${His} inverted nipples prevent ${him} from releasing milk spontaneously. The lactation drugs are so powerful that if ${he} hasn't been milked in the past hour or so, the built-up pressure leaves ${him} ${!canTalk(slave) ? 'weeping' : 'whining'} piteously.`;
 			} else if (slave.energy > 95) {
-				r += ` The powerful lactation drugs keep ${his} breasts so full of milk that when ${he} orgasms ${slave.balls > 0 ? `${he} releases three jets of white fluid: a stream of milk from each nipple and a squirt of cum from ${his} dickhead` : `${he} cums milk out of ${his} nipples`}.`;
+				r += ` The powerful lactation drugs keep ${his} breasts so full of ${slave.milkFlavor === "none" ? `` : `${slave.milkFlavor} flavored `}milk that when ${he} orgasms ${slave.balls > 0 ? `${he} releases three jets of white fluid: a stream of milk from each nipple and a squirt of cum from ${his} dickhead` : `${he} cums milk out of ${his} nipples`}.`;
 			} else {
-				r += ` The lactation drugs are so powerful that if ${he} hasn't been milked in the past hour or so, ${he} leaves a mess wherever ${he} goes.`;
+				r += ` The lactation drugs are so powerful that if ${he} hasn't been milked in the past hour or so, ${he} leaves ${slave.milkFlavor === "none" ? `a milky mess` : `a mess of ${slave.milkFlavor} flavored milk`} wherever ${he} goes.`;
 			}
 		}
 		if (slave.lactationAdaptation > 10) {
diff --git a/src/npc/descriptions/boobs/boobsShape.js b/src/npc/descriptions/boobs/boobsShape.js
index 23ad59580196402b38f27d4985fe758d6043cc0e..a041233b19940e7db53cbdc422aa90f669e0351b 100644
--- a/src/npc/descriptions/boobs/boobsShape.js
+++ b/src/npc/descriptions/boobs/boobsShape.js
@@ -150,7 +150,18 @@ App.Desc.boobsShape = function(slave) {
 						} else if (slave.boobs > 5000) {
 							r.push(`They're huge pillows of soft flesh whose natural wide-set shape somehow keeps them from touching despite their mass.`);
 						} else if (slave.boobs > 2500) {
-							r.push(`They're orbs of soft flesh whose natural wide-set shape obscures ${his} upper arms. They rest without natural cleavage despite their size.`);
+							r.push(`They're orbs of soft flesh whose natural wide-set shape obscures ${his}`);
+							if (hasAnyArms(slave)) {
+								r.push(`upper`);
+								if (hasBothArms(slave)) {
+									r.push(`arms.`);
+								} else {
+									r.push(`arm.`);
+								}
+							} else {
+								r.push(`arm stumps.`);
+							}
+							r.push(`They rest without natural cleavage despite their size.`);
 						} else if (slave.boobs > 1000) {
 							r.push(`They're wide-set, with their weight pointing each nipple away from ${his} sternum.`);
 						} else if (slave.boobs > 500) {
diff --git a/src/npc/descriptions/butt/butt.js b/src/npc/descriptions/butt/butt.js
index b29684f16c379e49db0e9606bcd818214310fec3..3b2d0b828b8422a494fc0f1e2cb323954b5e495c 100644
--- a/src/npc/descriptions/butt/butt.js
+++ b/src/npc/descriptions/butt/butt.js
@@ -1091,7 +1091,7 @@ App.Desc.butt = function(slave, descType = DescType.NORMAL) {
 		if (V.arcologies[0].FSSlimnessEnthusiast > 20 && V.arcologies[0].FSHedonisticDecadence === "unset") {
 			r.push(either("fashionable", "sleek and attractive", "small and enticing"));
 		} else {
-			r.push(either("rounded, small", "small but rounded", "small, sleek"));
+			r.push(either("small, rounded", "small but rounded", "small, sleek"));
 		}
 		r.push(`rear end,`);
 	} else if (slave.butt <= 3) {
diff --git a/src/npc/descriptions/butt/buttplug.js b/src/npc/descriptions/butt/buttplug.js
index aeda22857187a3e07c3f32239609d6d3c8e1c28b..bf6b9f715d142bcad15fc9521dc25fef16b5df15 100644
--- a/src/npc/descriptions/butt/buttplug.js
+++ b/src/npc/descriptions/butt/buttplug.js
@@ -618,11 +618,12 @@ App.Desc.buttplug = function(slave, descType = DescType.NORMAL) {
 				r.push(`${slave.buttplug}.`);
 			}
 		} else {
+			const plug = slave.buttplug.startsWith("long ") ? slave.buttplug.slice(5) : slave.buttplug;
 			r.push(`It's filled by a standard sized, overly long`);
 			if (slave.anus > 2) {
-				r.push(`${slave.buttplug}, which is on the verge of sliding out ${his} rear.`);
+				r.push(`${plug}, which is on the verge of sliding out ${his} rear.`);
 			} else {
-				r.push(`${slave.buttplug}.`);
+				r.push(`${plug}.`);
 			}
 			r.push(`It causes a noticeable bulge in ${his} belly.`);
 		}
diff --git a/src/npc/descriptions/career.js b/src/npc/descriptions/career.js
index 692cda989f1a91b994a58f2c85a0ca8c35bef8aa..10bad3191c3110ff96f8f46fd2de91b5c5409db4 100644
--- a/src/npc/descriptions/career.js
+++ b/src/npc/descriptions/career.js
@@ -10,117 +10,115 @@ App.Desc.career = function(slave) {
 	const career = convertCareer(slave);
 
 	if (slave.fuckdoll === 0) {
-		if (slave.career !== 0) {
-			if (slave.career === "a slave") {
-				r.push(`${He} was a slave long before you obtained ${him}.`);
-			} else if (slave.career === "a slave since birth") {
-				r.push(`${He}'s been your slave ${his} entire life.`);
-			} else if (slave.career === "a meat toilet" || slave.career === "a cum dump") {
-				r.push(`${He} sees ${himself} as a cum receptacle.`);
-			} else if (slave.career === "a dairy cow") {
-				r.push(`${He}'s been broken into the belief that ${he} is nothing more than a cow to be milked and bred.`);
-			} else if (slave.career === "a breeding bull") {
-				r.push(`${He}'s been broken into the belief that ${he} is nothing more than a bull destined to fill fertile wombs with calves.`);
-			} else if (slave.career === "a breeder") {
-				r.push(`Before you obtained ${him}, ${he} was a breeding slave.`);
-			} else if (slave.career === "a bioreactor") {
-				r.push(`${He} has spent time as a cow in an industrial dairy, an experience that marked ${him} deeply.`);
-			} else {
-				r.push(`Before ${he} was a slave, ${he} was`);
-				if (App.Data.Careers.Leader.bodyguard.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as a Bodyguard.`);
-				} else if (App.Data.Careers.Leader.wardeness.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as a Wardeness for`);
-					if (V.cellblock === 0) {
-						r.push(`a Cellblock.`);
-					} else {
-						r.push(`${V.cellblockName}.`);
-					}
-				} else if (App.Data.Careers.Leader.attendant.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as an Attendant for`);
-					if (V.spa === 0) {
-						r.push(`a Spa.`);
-					} else {
-						r.push(`${V.spaName}.`);
-					}
-				} else if (App.Data.Careers.Leader.matron.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as a Matron for`);
-					if (V.nursery === 0 && V.nurseryNannies === 0) {
-						r.push(`a Nursery.`);
-					} else {
-						r.push(`${V.nurseryName}.`);
-					}
-				} else if (App.Data.Careers.Leader.nurse.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as a Nurse for`);
-					if (V.clinic === 0) {
-						r.push(`a Clinic.`);
-					} else {
-						r.push(`${V.clinicName}.`);
-					}
-				} else if (App.Data.Careers.Leader.schoolteacher.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as a Schoolteacher for`);
-					if (V.schoolroom === 0) {
-						r.push(`a Schoolroom.`);
-					} else {
-						r.push(`${V.schoolroomName}.`);
-					}
-				} else if (App.Data.Careers.Leader.stewardess.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as a Stewardess for`);
-					if (V.servantsQuarters === 0) {
-						r.push(`a Servant's Quarters.`);
-					} else {
-						r.push(`${V.servantsQuartersName}.`);
-					}
-				} else if (App.Data.Careers.Leader.milkmaid.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as a Milkmaid for`);
-					if (V.dairy === 0) {
-						r.push(`a Dairy.`);
-					} else {
-						r.push(`${V.dairyName}.`);
-					}
-				} else if (App.Data.Careers.Leader.farmer.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as a Farmer for`);
-					if (V.farmyard === 0) {
-						r.push(`a Farmyard.`);
-					} else {
-						r.push(`${V.farmyardName}.`);
-					}
-				} else if (App.Data.Careers.Leader.madam.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as a Madam for`);
-					if (V.brothel === 0) {
-						r.push(`a Brothel.`);
-					} else {
-						r.push(`${V.brothelName}.`);
-					}
-				} else if (App.Data.Careers.Leader.DJ.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as a DJ for`);
-					if (V.club === 0) {
-						r.push(`a Club.`);
-					} else {
-						r.push(`${V.clubName}.`);
-					}
-				} else if (App.Data.Careers.Leader.HG.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as a Head Girl.`);
-				} else if (App.Data.Careers.Leader.recruiter.includes(slave.career)) {
-					r.push(`${career}, giving ${him} potential as a recruiter.`);
-				} else if (App.Data.Careers.General.entertainment.includes(slave.career)) {
-					r.push(`${career}, giving ${him} a slight edge at entertainment.`);
-				} else if (App.Data.Careers.General.whore.includes(slave.career)) {
-					r.push(`${career}, giving ${him} a slight edge at sexual commerce.`);
-				} else if (App.Data.Careers.General.grateful.includes(slave.career)) {
-					r.push(`${career}, so ${he} can remember what it's like`);
-					if (slave.career === "prisoner") {
-						r.push(`no one looking out for you.`);
-					} else {
-						r.push(`to have the freedom to starve.`);
-					}
-				} else if (App.Data.Careers.General.menial.includes(slave.career)) {
-					r.push(`${career}, giving ${him} experience following orders.`);
-				} else if (App.Data.Careers.General.servant.includes(slave.career)) {
-					r.push(`${career}, giving ${him} a slight edge in housekeeping.`);
+		if (slave.career === "a slave") {
+			r.push(`${He} was a slave long before you obtained ${him}.`);
+		} else if (slave.career === "a slave since birth") {
+			r.push(`${He}'s been your slave ${his} entire life.`);
+		} else if (slave.career === "a meat toilet" || slave.career === "a cum dump") {
+			r.push(`${He} sees ${himself} as a cum receptacle.`);
+		} else if (slave.career === "a dairy cow") {
+			r.push(`${He}'s been broken into the belief that ${he} is nothing more than a cow to be milked and bred.`);
+		} else if (slave.career === "a breeding bull") {
+			r.push(`${He}'s been broken into the belief that ${he} is nothing more than a bull destined to fill fertile wombs with calves.`);
+		} else if (slave.career === "a breeder") {
+			r.push(`Before you obtained ${him}, ${he} was a breeding slave.`);
+		} else if (slave.career === "a bioreactor") {
+			r.push(`${He} has spent time as a cow in an industrial dairy, an experience that marked ${him} deeply.`);
+		} else {
+			r.push(`Before ${he} was a slave, ${he} was`);
+			if (App.Data.Careers.Leader.bodyguard.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as a Bodyguard.`);
+			} else if (App.Data.Careers.Leader.wardeness.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as a Wardeness for`);
+				if (V.cellblock === 0) {
+					r.push(`a Cellblock.`);
+				} else {
+					r.push(`${V.cellblockName}.`);
+				}
+			} else if (App.Data.Careers.Leader.attendant.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as an Attendant for`);
+				if (V.spa === 0) {
+					r.push(`a Spa.`);
+				} else {
+					r.push(`${V.spaName}.`);
+				}
+			} else if (App.Data.Careers.Leader.matron.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as a Matron for`);
+				if (V.nursery === 0 && V.nurseryNannies === 0) {
+					r.push(`a Nursery.`);
+				} else {
+					r.push(`${V.nurseryName}.`);
+				}
+			} else if (App.Data.Careers.Leader.nurse.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as a Nurse for`);
+				if (V.clinic === 0) {
+					r.push(`a Clinic.`);
+				} else {
+					r.push(`${V.clinicName}.`);
+				}
+			} else if (App.Data.Careers.Leader.schoolteacher.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as a Schoolteacher for`);
+				if (V.schoolroom === 0) {
+					r.push(`a Schoolroom.`);
+				} else {
+					r.push(`${V.schoolroomName}.`);
+				}
+			} else if (App.Data.Careers.Leader.stewardess.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as a Stewardess for`);
+				if (V.servantsQuarters === 0) {
+					r.push(`a Servant's Quarters.`);
 				} else {
-					r.push(`${career}.`);
+					r.push(`${V.servantsQuartersName}.`);
 				}
+			} else if (App.Data.Careers.Leader.milkmaid.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as a Milkmaid for`);
+				if (V.dairy === 0) {
+					r.push(`a Dairy.`);
+				} else {
+					r.push(`${V.dairyName}.`);
+				}
+			} else if (App.Data.Careers.Leader.farmer.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as a Farmer for`);
+				if (V.farmyard === 0) {
+					r.push(`a Farmyard.`);
+				} else {
+					r.push(`${V.farmyardName}.`);
+				}
+			} else if (App.Data.Careers.Leader.madam.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as a Madam for`);
+				if (V.brothel === 0) {
+					r.push(`a Brothel.`);
+				} else {
+					r.push(`${V.brothelName}.`);
+				}
+			} else if (App.Data.Careers.Leader.DJ.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as a DJ for`);
+				if (V.club === 0) {
+					r.push(`a Club.`);
+				} else {
+					r.push(`${V.clubName}.`);
+				}
+			} else if (App.Data.Careers.Leader.HG.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as a Head Girl.`);
+			} else if (App.Data.Careers.Leader.recruiter.includes(slave.career)) {
+				r.push(`${career}, giving ${him} potential as a recruiter.`);
+			} else if (App.Data.Careers.General.entertainment.includes(slave.career)) {
+				r.push(`${career}, giving ${him} a slight edge at entertainment.`);
+			} else if (App.Data.Careers.General.whore.includes(slave.career)) {
+				r.push(`${career}, giving ${him} a slight edge at sexual commerce.`);
+			} else if (App.Data.Careers.General.grateful.includes(slave.career)) {
+				r.push(`${career}, so ${he} can remember what it's like`);
+				if (slave.career === "prisoner") {
+					r.push(`no one looking out for you.`);
+				} else {
+					r.push(`to have the freedom to starve.`);
+				}
+			} else if (App.Data.Careers.General.menial.includes(slave.career)) {
+				r.push(`${career}, giving ${him} experience following orders.`);
+			} else if (App.Data.Careers.General.servant.includes(slave.career)) {
+				r.push(`${career}, giving ${him} a slight edge in housekeeping.`);
+			} else {
+				r.push(`${career}.`);
 			}
 		}
 		if (V.week - slave.weekAcquired >= 20 && slave.skill.entertainment >= 100) {
diff --git a/src/npc/descriptions/crotch/crotch.js b/src/npc/descriptions/crotch/crotch.js
index 54db5164c5222f35cf3297f232b7bbce4989d462..f18d10114d71e95071d12113a34243f29f4cf186 100644
--- a/src/npc/descriptions/crotch/crotch.js
+++ b/src/npc/descriptions/crotch/crotch.js
@@ -1437,13 +1437,19 @@ App.Desc.crotch = function(slave, descType = DescType.NORMAL) {
 					default:
 						if (slave.vagina > -1) {
 							r.push(`${slave.slaveName}'s`);
-							if (slave.dick > 0) {
-								r.push(`hermaphroditic genitalia are`);
+							if (slave.dick > 0 && slave.chastityPenis === 1 && slave.chastityVagina === 1) {
+								r.push(`hermaphroditic genitalia are concealed only by the chastity devices imprisoning them.`);
+							} else if (slave.dick > 0 && slave.chastityPenis === 1) {
+								r.push(`pussy is bare and available beneath ${his} caged, hermaphroditic cock.`);
+							} else if (slave.dick > 0 && slave.chastityVagina === 1) {
+								r.push(`pussy is concealed only by the chastity belt imprisoning it, ${his} hermaphroditic cock resting atop.`);
+							} else if (slave.chastityVagina === 1) {
+								r.push(`pussy is concealed only by the chastity belt imprisoning it.`);
 							} else {
-								r.push(`pussy is`);
+								r.push(`pussy is bare and available.`);
 							}
-							r.push(`bare and available.`);
 						} else if (slave.chastityPenis === 1) {
+							r.push(`${slave.slaveName}'s cock is concealed only by the chastity cage imprisoning it.`);
 						} else if (slave.dick > 0) {
 							r.push(`${slave.slaveName}'s`);
 							switch (slave.dick) {
diff --git a/src/npc/descriptions/crotch/dick.js b/src/npc/descriptions/crotch/dick.js
index 81156e5d035a1728fefcad08f05fd2ba613ce068..1a98ebe438d7aa8d2b668b25ba9d65bae4585244 100644
--- a/src/npc/descriptions/crotch/dick.js
+++ b/src/npc/descriptions/crotch/dick.js
@@ -1490,7 +1490,6 @@ App.Desc.dick = function(slave, descType = DescType.NORMAL) {
 			}
 		}
 	}
-	// CLOSES DETAILED DICK DESCRIPTION
 
 	if (slave.prostate === 0) {
 		if (slave.dick > 0 || slave.balls > 0) {
diff --git a/src/npc/descriptions/crotch/vagina.js b/src/npc/descriptions/crotch/vagina.js
index 6683772a8c8ab5ba1a11f09d6b8936ffd0139414..81b0d83a9a166054cfd7b10924f2edd8f8d588a4 100644
--- a/src/npc/descriptions/crotch/vagina.js
+++ b/src/npc/descriptions/crotch/vagina.js
@@ -11,7 +11,7 @@ App.Desc.vagina = function(slave) {
 	if (slave.dick > 0) {
 		if (slave.vagina > -1) {
 			r.push(`${His}`);
-			if (slave.genes === "XX") {
+			if (slave.genes === "XX" || slave.prestigeDesc && slave.prestigeDesc.includes("natural-born hermaphrodite")) {
 				r.push(`beautifully natural`);
 			} else if (slave.ovaries === 1) {
 				r.push(`finely crafted`);
@@ -510,7 +510,7 @@ App.Desc.vagina = function(slave) {
 							r.push(`${His} efforts force ${his} distended middle to jiggle around, stirring up the aphrodisiacs contained in ${his} gut and strengthening their effects even more.`);
 						}
 					} else if ((slave.dick !== 0) && (slave.balls === 0)) {
-						r.push(`The extreme dose of aphrodisiacs combined with the lack of balls that keeps ${him} flaccid have ${him} in a state of extreme sexual frustration; ${he}'s rubbing ${his} limp dick distractedly`);
+						r.push(`The extreme dose of aphrodisiacs combined with the lack of balls that keeps ${him} flaccid have ${him} in a state of extreme sexual frustration; ${he}'s rubbing ${his} limp dick`);
 						if ((slave.fetish === "buttslut") || ((slave.sexualFlaw !== "hates anal") && (slave.counter.anal > 9))) {
 							r.push(`distractedly and unconsciously humping ${his} ass against whatever's next to ${him} for anal stimulation.`);
 						} else {
@@ -520,7 +520,7 @@ App.Desc.vagina = function(slave) {
 							r.push(`${His} efforts force ${his} distended middle to jiggle around, stirring up the aphrodisiacs contained in ${his} gut and strengthening their effects even more.`);
 						}
 					} else if ((slave.dick !== 0) && !canAchieveErection(slave)) {
-						r.push(`The extreme dose of aphrodisiacs combined with ${his} inability to become erect have ${him} in a state of extreme sexual frustration; ${he}'s rubbing ${his} limp dick distractedly`);
+						r.push(`The extreme dose of aphrodisiacs combined with ${his} inability to become erect have ${him} in a state of extreme sexual frustration; ${he}'s rubbing ${his} limp dick`);
 						if ((slave.fetish === "buttslut") || ((slave.sexualFlaw !== "hates anal") && (slave.counter.anal > 9))) {
 							r.push(`distractedly and unconsciously humping ${his} ass against whatever's next to ${him} for anal stimulation.`);
 						} else {
@@ -561,7 +561,7 @@ App.Desc.vagina = function(slave) {
 							r.push(`${His} efforts force ${his} distended middle to jiggle around, stirring up the aphrodisiacs contained in ${his} gut and strengthening their effects even more.`);
 						}
 					} else if ((slave.dick !== 0) && (slave.hormoneBalance >= 100)) {
-						r.push(`The aphrodisiacs combined with the hormones that keep ${him} flaccid have ${him} sexually frustrated; ${he}'s touching ${his} limp dick distractedly`);
+						r.push(`The aphrodisiacs combined with the hormones that keep ${him} flaccid have ${him} sexually frustrated; ${he}'s touching ${his} limp dick`);
 						if ((slave.fetish === "buttslut") || ((slave.sexualFlaw !== "hates anal") && (slave.counter.anal > 9))) {
 							r.push(`distractedly and unconsciously rubbing ${his} ass against whatever's next to ${him}.`);
 						} else {
@@ -571,7 +571,7 @@ App.Desc.vagina = function(slave) {
 							r.push(`${His} efforts force ${his} distended middle to jiggle around, stirring up the aphrodisiacs contained in ${his} gut and strengthening their effects even more.`);
 						}
 					} else if ((slave.dick !== 0) && (slave.balls === 0)) {
-						r.push(`The aphrodisiacs combined with the lack of balls that keeps ${him} flaccid have ${him} sexually frustrated; ${he}'s touching ${his} limp dick distractedly`);
+						r.push(`The aphrodisiacs combined with the lack of balls that keeps ${him} flaccid have ${him} sexually frustrated; ${he}'s touching ${his} limp dick`);
 						if ((slave.fetish === "buttslut") || ((slave.sexualFlaw !== "hates anal") && (slave.counter.anal > 9))) {
 							r.push(`distractedly and unconsciously rubbing ${his} ass against whatever's next to ${him}.`);
 						} else {
diff --git a/src/npc/descriptions/describeBrands.js b/src/npc/descriptions/describeBrands.js
index b88b3a3fa5cccfc67d9c0d46618db88dc899b73d..d81c3c66a12a050d32132c81e9e0c6d0f673e92a 100644
--- a/src/npc/descriptions/describeBrands.js
+++ b/src/npc/descriptions/describeBrands.js
@@ -27,8 +27,9 @@ App.Desc.brand = function(slave, surface) {
 			}
 			r += `${toSentence(array)}. `;
 		} else if (surface) { /* describes a single branded body part */
-			if (surface === "belly" && App.Data.misc.fakeBellies.includes(slave.bellyAccessory) && slave.brand.belly) {
-				r += `${His} fake belly has the same brand, ${slave.brand.belly}, as ${his} real one. `;
+			const brands = App.Medicine.Modification.brandRecord(slave);
+			if (surface === "belly" && App.Data.misc.fakeBellies.includes(slave.bellyAccessory) && brands.belly) {
+				r += `${His} fake belly has the same brand, ${brands.belly}, as ${his} real one. `;
 			} else {
 				const description = desc(surface);
 				if (description !== "") {
@@ -45,9 +46,10 @@ App.Desc.brand = function(slave, surface) {
 	 */
 	function desc(part) {
 		const surface = App.Desc.oppositeSides(part);
-		const centerBrand = slave.brand[surface.center] ? pronounsForSlaveProp(slave, slave.brand[surface.center]) : undefined;
-		const leftBrand = slave.brand[surface.left] ? pronounsForSlaveProp(slave, slave.brand[surface.left]) : undefined;
-		const rightBrand = slave.brand[surface.right] ? pronounsForSlaveProp(slave, slave.brand[surface.right]) : undefined;
+		const brands = App.Medicine.Modification.brandRecord(slave);
+		const centerBrand = brands[surface.center] ? pronounsForSlaveProp(slave, brands[surface.center]) : undefined;
+		const leftBrand = brands[surface.left] ? pronounsForSlaveProp(slave, brands[surface.left]) : undefined;
+		const rightBrand = brands[surface.right] ? pronounsForSlaveProp(slave, brands[surface.right]) : undefined;
 		if (centerBrand) { // center defined, body part has no mirror.
 			return `${centerBrand} branded into the flesh of ${his} ${surface.center}`;
 		} else { // Center not defined, body part has a mirror.
diff --git a/src/npc/descriptions/describeScars.js b/src/npc/descriptions/describeScars.js
index ef75910d776895db2a2a989ca270af7ddd7b585d..a7d326d6a26002ac9cd6fbc09df224e38ed2ff86 100644
--- a/src/npc/descriptions/describeScars.js
+++ b/src/npc/descriptions/describeScars.js
@@ -1,124 +1,139 @@
 /**
+ * Slave is the slave in question, but call the body part without modifiers. Rather than using "left breast" and
+ * "right breast" just use "breast". The function will then describe any scars on the breasts, if present, in natural
+ * language.
  * @param {App.Entity.SlaveState} slave
  * @param {string|object} surface
- * @returns {string} Slave's scar. Slave is the slave in question, but call the body part without modifiers. Rather than using "left breast" and "right breast" just use "breast". The function will then describe any scars on the breasts, if present, in natural language.
+ * @returns {string} Slave's scar.
  */
 App.Desc.scar = function(slave, surface) {
-	"use strict";
-	let r = [];
+	if (V.showBodyMods !== 1) {
+		return "";
+	}
+
+	const r = [];
 	const bellyAccessory = slave.bellyAccessory;
 	const {
 		him, his, He, His
 	} = getPronouns(slave);
-	if (V.showBodyMods === 1) {
-		if (surface === "extra") { // Make a sentence that describes all body parts that aren't explicitly described elsewhere in longSlave. If you scar a slave on her thumb, for instance. But why.
-			let extraMarks = App.Desc.extraMarks(slave, "scar");
-			extraMarks = Object.keys(extraMarks);
-			let length = extraMarks.length;
-			if (length === 0) {
-				return "";
-			} else if (length === 1) {
-				r.push(`${He} also has a single unusual scar:`);
-			} else {
-				r.push(`${He} also has several unusual scars:`);
-			}
-			const scarPhrases = [];
-			for (const bodyPart of extraMarks) {
-				const t = [];
-				surface = App.Desc.oppositeSides(bodyPart);
-				if (slave.scar[surface.center]) { // center defined, body part has no mirror.
-					t.push(`${App.Desc.expandScarString(slave, surface.center)} on ${his} ${surface.center}`);
-				} else { // Center not defined, body part has a mirror.
-					let left = App.Desc.expandScarString(slave, surface.left);
-					let right = App.Desc.expandScarString(slave, surface.right);
-					if (!slave.scar[surface.left] && !slave.scar[surface.right]) {
-						// no marks
-					} else if (bodyPart.startsWith("right ") && slave.scar[surface.left]) {
-						// we already described it on the left
-					} else if (left === right) {
-						// matching places and marks
-						// note that the slave.scar object won't have slave.scar["upper armS"] with an S defined, just the left and right, so we just use the left since we know they match.
-						t.push(`${left} on both ${his} ${surface.both}`);
-					} else if (slave.scar[surface.left] && slave.scar[surface.right]) {
-						// matching places but different marks
-						t.push(`both ${left} on ${his} ${surface.left}, and ${right} scared into ${his} ${surface.right}`);
-					} else if (slave.scar[surface.left]) {
-						// left
-						t.push(`${left} on ${his} ${surface.left}`);
-					} else if (slave.scar[surface.right]) {
-						// right
-						t.push(`${right} on ${his} ${surface.right}`);
-					}
+	const scars = App.Medicine.Modification.scarRecord(slave);
+
+	if (surface === "extra") { // Make a sentence that describes all body parts that aren't explicitly described elsewhere in longSlave. If you scar a slave on her thumb, for instance. But why.
+		let extraMarks = App.Desc.extraMarks(slave, "scar");
+		extraMarks = Object.keys(extraMarks);
+		let length = extraMarks.length;
+		if (length === 0) {
+			return "";
+		} else if (length === 1) {
+			r.push(`${He} also has a single unusual scar:`);
+		} else {
+			r.push(`${He} also has several unusual scars:`);
+		}
+		const scarPhrases = [];
+		for (const bodyPart of extraMarks) {
+			const t = [];
+			surface = App.Desc.oppositeSides(bodyPart);
+			if (scars[surface.center]) { // center defined, body part has no mirror.
+				t.push(`${App.Desc.expandScarString(slave, surface.center)} on ${his} ${surface.center}`);
+			} else { // Center not defined, body part has a mirror.
+				let left = App.Desc.expandScarString(slave, surface.left);
+				let right = App.Desc.expandScarString(slave, surface.right);
+				if (!scars[surface.left] && !scars[surface.right]) {
+					// no marks
+				} else if (bodyPart.startsWith("right ") && scars[surface.left]) {
+					// we already described it on the left
+				} else if (left === right) {
+					// matching places and marks
+					// note that the 'scars' object won't have scars["upper armS"] with an S defined, just the left and right, so we just use the left since we know they match.
+					t.push(`${left} on both ${his} ${surface.both}`);
+				} else if (scars[surface.left] && scars[surface.right]) {
+					// matching places but different marks
+					t.push(`both ${left} on ${his} ${surface.left}, and ${right} scared into ${his} ${surface.right}`);
+				} else if (scars[surface.left]) {
+					// left
+					t.push(`${left} on ${his} ${surface.left}`);
+				} else if (scars[surface.right]) {
+					// right
+					t.push(`${right} on ${his} ${surface.right}`);
 				}
-				scarPhrases.push(t.join(" "));
 			}
-			if (scarPhrases.length > 0) {
-				r.push(`${toSentence(scarPhrases)}.`);
-			}
-		} else if (surface) { /* describes a single scarred body part */
-			surface = App.Desc.oppositeSides(surface);
-			if (surface.center === "belly" && App.Data.misc.fakeBellies.includes(bellyAccessory) && slave.scar.hasOwnProperty("belly")) {
-				r.push(`${His} fake belly has the same scar, ${App.Desc.expandScarString(slave, surface.center)}, as ${his} real one.`);
-			} else {
-				if (slave.scar[surface.center]) { // center defined, body part has no mirror.
-					r.push(`${He} has ${App.Desc.expandScarString(slave, surface.center)} on ${his} ${surface.center}.`);
-				} else { // Center not defined, body part has a mirror.
-					let left = App.Desc.expandScarString(slave, surface.left);
-					let right = App.Desc.expandScarString(slave, surface.right);
-					if (!slave.scar[surface.left] && !slave.scar[surface.right]) {
-						// no marks
-					} else if (left === right) {
-						// matching places and marks
-						// note that the slave.scar object won't have slave.scar["upper armS"] with an S defined, just the left and right, so we just use the left since we know they match.
-						r.push(`${He} has ${left} on both ${his} ${surface.both}.`);
-					} else if (slave.scar[surface.left] && slave.scar[surface.right]) {
-						// matching places but different marks
-						r.push(`${He} has both ${left} on ${his} ${surface.left}, and ${right} scared into ${his} ${surface.right}.`);
-					} else if (slave.scar[surface.left]) {
-						// left
-						r.push(`${He} has ${left} on ${his} ${surface.left}.`);
-					} else if (right) {
-						// right
-						r.push(`${He} has ${right} on ${his} ${surface.right}.`);
-					}
+			scarPhrases.push(t.join(" "));
+		}
+		if (scarPhrases.length > 0) {
+			r.push(`${toSentence(scarPhrases)}.`);
+		}
+	} else if (surface) { /* describes a single scarred body part */
+		surface = App.Desc.oppositeSides(surface);
+		if (surface.center === "belly" && App.Data.misc.fakeBellies.includes(bellyAccessory) && scars.hasOwnProperty("belly")) {
+			r.push(`${His} fake belly has the same scar, ${App.Desc.expandScarString(slave, surface.center)}, as ${his} real one.`);
+		} else {
+			if (scars[surface.center]) { // center defined, body part has no mirror.
+				r.push(`${He} has ${App.Desc.expandScarString(slave, surface.center)} on ${his} ${surface.center}.`);
+			} else { // Center not defined, body part has a mirror.
+				let left = App.Desc.expandScarString(slave, surface.left);
+				let right = App.Desc.expandScarString(slave, surface.right);
+				if (!scars[surface.left] && !scars[surface.right]) {
+					// no marks
+				} else if (left === right) {
+					// matching places and marks
+					// note that the 'scars' object won't have scars["upper armS"] with an S defined, just the left and right, so we just use the left since we know they match.
+					r.push(`${He} has ${left} on both ${his} ${surface.both}.`);
+				} else if (scars[surface.left] && scars[surface.right]) {
+					// matching places but different marks
+					r.push(`${He} has both ${left} on ${his} ${surface.left}, and ${right} scared into ${his} ${surface.right}.`);
+				} else if (scars[surface.left]) {
+					// left
+					r.push(`${He} has ${left} on ${his} ${surface.left}.`);
+				} else if (right) {
+					// right
+					r.push(`${He} has ${right} on ${his} ${surface.right}.`);
 				}
 			}
-		} else { /* describes all scarred body parts */
-			for (let [key, value] of Object.entries(slave.scar)) {
-				if (r.length === 0) {
-					r.push(`${He} has`);
-				}
-				if (key === "belly" && App.Data.misc.fakeBellies.includes(bellyAccessory) && slave.scar.hasOwnProperty("belly")) {
-					r.push(`${value} scared on both ${his} real belly and ${his} fake one,`);
-				} else {
-					r.push(`${value} on ${his} ${key},`);
-				}
+		}
+	} else { /* describes all scarred body parts */
+		for (let [key, value] of Object.entries(scars)) {
+			if (r.length === 0) {
+				r.push(`${He} has`);
 			}
-			if (r.length !== 0) {
-				r.push(`marking ${him} as yours.`);
+			if (key === "belly" && App.Data.misc.fakeBellies.includes(bellyAccessory) && scars.hasOwnProperty("belly")) {
+				r.push(`${value} scared on both ${his} real belly and ${his} fake one,`);
 			} else {
-				r.push(`${His} body is unmarked by scars.`);
+				r.push(`${value} on ${his} ${key},`);
 			}
 		}
+		if (r.length !== 0) {
+			r.push(`marking ${him} as yours.`);
+		} else {
+			r.push(`${His} body is unmarked by scars.`);
+		}
 	}
 	return r.join(" ");
 };
 
 /**
+ *  Slave's scar. Slave is the slave in question, but call the body part without modifiers. Rather than using
+ *  "left breast" and "right breast" just use "breast". The function will then describe any scars on the breasts, if
+ *  present, in natural language.
  * @param {App.Entity.SlaveState} slave
  * @param {string} surface
- * @returns {string} Slave's scar. Slave is the slave in question, but call the body part without modifiers. Rather than using "left breast" and "right breast" just use "breast". The function will then describe any scars on the breasts, if present, in natural language.
+ * @returns {string}
  */
-App.Desc.expandScarString = function(slave, surface) { // scars can sometimes be an int. This function generates a reasonable description. It can later be expanded to apply to different body parts, or include features of the slave such as skin tone or weight
-	if (!slave.scar[surface]) {
+App.Desc.expandScarString = function(slave, surface) {
+	// scars can sometimes be an int. This function generates a reasonable description. It can later be expanded to
+	// apply to different body parts, or include features of the slave such as skin tone or weight
+
+	const scars = App.Medicine.Modification.scarRecord(slave);
+	if (!scars[surface]) {
 		return "";
 	}
+
 	let r;
 	const {he, his} = getPronouns(slave);
-	const bodypart = Object.keys(slave.scar[surface]);
+
+	const bodypart = Object.keys(scars[surface]);
 	const scarPhrases = [];
 	for (const kind of bodypart) {
-		let scar = slave.scar[surface][kind];
+		let scar = scars[surface][kind];
 		r = [];
 		if (scar === 0) {
 			continue;
diff --git a/src/npc/descriptions/descriptionWidgets.js b/src/npc/descriptions/descriptionWidgets.js
index 204026eb02b73a506cd57a7632f4e2df6df28700..d2948e0bb7395ea70b8ebcef092ebc8f368d8652 100644
--- a/src/npc/descriptions/descriptionWidgets.js
+++ b/src/npc/descriptions/descriptionWidgets.js
@@ -96,7 +96,7 @@ App.Desc.eyes = function(slave, descType = DescType.NORMAL) {
 		}
 		r += `, `;
 		if (slave.fetish === "mindbroken") {
-			r += `fitting for vacant expression constantly adorning ${his} face; ${his} broken mind lacks the ability to form higher thought and is completely reliant on others to think for ${him}.`;
+			r += `fitting for vacant expression constantly adorning ${his} face; ${he} lacks the ability to form higher thought and is completely reliant on others to think for ${him}.`;
 		} else if (slave.intelligence > 95) {
 			r += `but ${his} facial expressions reveal ${he} is incisive, quick, cunning; `;
 			if (slave.intelligence + slave.intelligenceImplant >= 130) {
@@ -224,7 +224,7 @@ App.Desc.eyes = function(slave, descType = DescType.NORMAL) {
 		}
 	} else {
 		if (slave.fetish === "mindbroken") {
-			r += `${His} ${App.Desc.eyesColor(slave, "", "eye", "eyes", false)} ${hasBothEyes(slave) ? "are" : "is"} dull and vacant; ${his} broken mind lacks the capacity for higher thought.`;
+			r += `${His} ${App.Desc.eyesColor(slave, "", "eye", "eyes", false)} ${hasBothEyes(slave) ? "are" : "is"} dull and vacant; ${he} lacks the capacity for higher thought.`;
 		} else if (slave.intelligence > 95) {
 			r += `${His} ${App.Desc.eyeColor(slave)}-eyed gaze is incisive, quick, cunning; `;
 			if (slave.intelligence + slave.intelligenceImplant >= 130) {
@@ -468,7 +468,25 @@ App.Desc.ageAndHealth = function(slave) {
 		}
 		age = slave.actualAge + 1;
 		r += ` ${He} `;
-		if (slave.birthWeek >= 52 && V.seeAge) {
+		if(slave.actualAge === V.idealAge || (slave.actualAge === V.idealAge - 1 && slave.birthWeek >= 52 && V.seeAge)) {
+			if(slave.birthWeek >= 52 && V.seeAge) {
+				r += `is going to turn ${age} this week`;
+				if (V.showAgeDetail && V.seeAge !== 0 && slave.actualAge !== V.idealAge) {
+					r += `, and people are already beginning to eye ${him}.`;
+				} else {
+					r += `.`;
+				}
+			}
+			else if(!slave.birthWeek && V.seeAge) {
+				r += `just turned ${num(slave.actualAge)} this week, which many citizens find especially appealing.`;
+			}
+			else if (slave.birthWeek < 4 && V.seeAge) {
+				r += `only turned ${num(slave.actualAge)} this month. `;
+			} else {
+				r += `is ${num(slave.actualAge)} years old${birthday}. `;
+			}
+		}
+		else if (slave.birthWeek >= 52 && V.seeAge) {
 			r += `is going to turn ${age} this week,`;
 		} else if (slave.actualAge < 3) {
 			r += `is an infant, only `;
@@ -513,21 +531,9 @@ App.Desc.ageAndHealth = function(slave) {
 		} else if (slave.actualAge < 17) {
 			r += `is young and fresh at ${num(slave.actualAge)}${birthday}. `;
 		} else if (slave.actualAge < 18) {
-			r += `is young, fresh, and nearly 18${birthday}`;
-			if (V.showAgeDetail && V.seeAge !== 0) {
-				if (V.seeAge) {
-					r += ` and people are already beginning to eye ${him}`;
-				}
-			}
-			r += `. `;
+			r += `is young, fresh, and nearly 18${birthday}.`;
 		} else if (slave.actualAge < 19) {
-			if (!slave.birthWeek && V.seeAge) {
-				r += `just turned ${num(slave.actualAge)} this week, which many citizens find especially appealing. `;
-			} else if (slave.birthWeek < 4 && V.seeAge) {
-				r += `only turned ${num(slave.actualAge)} this month. `;
-			} else {
-				r += `is ${num(slave.actualAge)} years old${birthday}. `;
-			}
+			r += `is ${num(slave.actualAge)} years old${birthday}. `;
 		} else if (slave.actualAge < 20) {
 			r += `is in ${his} final year as a teenager at age 19${birthday}. `;
 		} else if (slave.actualAge < 26) {
@@ -738,6 +744,9 @@ App.Desc.ageAndHealth = function(slave) {
 			if (slave.geneMods.immortality === 1) {
 				r += `Due to extensive genetic modification, ${he} is essentially immortal and will not die of old age. `;
 			}
+			if (slave.geneMods.flavoring === 1) {
+				r += `Due to genetic modification ${his} milk tastes like ${slave.milkFlavor}. `;
+			}
 		}
 	} else {
 		r += ` The Fuckdoll gives no external indication of ${his} health or age, but upon query ${his} systems reports that ${he} is `;
@@ -1359,23 +1368,27 @@ App.Desc.sexualHistory = function(slave) {
 		r += `${He} has had a total of ${numberWithPluralOne(slave.counter.miscarriages, "miscarriage")}. `;
 	}
 
-	if (slave.counter.slavesKnockedUp > 0) {
-		r += `${He}'s knocked up ${numberWithPluralOne(slave.counter.slavesKnockedUp, "other slave girl")} `;
-		if (slave.counter.slavesFathered > 0) {
-			r += `and fathered ${numberWithPluralOne(slave.counter.slavesKnockedUp, "new slave")} `;
-		}
-		r += `for you. `;
-	} else if (slave.counter.slavesFathered > 0) {
-		r += `${He}'s fathered ${numberWithPluralOne(slave.counter.slavesKnockedUp, "new slave")} for you. `;
-	}
-	if (slave.counter.PCKnockedUp > 0) {
-		r += `${He}'s managed to knock you up ${numberWithPluralOne(slave.counter.PCKnockedUp, "time")}`;
-		if (slave.counter.PCChildrenFathered > 0) {
-			r += ` and is the father of ${slave.counter.PCChildrenFathered} of your children`;
+	if (slave.counter.slavesKnockedUp > 0 || slave.counter.slavesFathered > 0 || slave.counter.PCKnockedUp > 0 || slave.counter.PCChildrenFathered > 0) {
+		r += `<span class="relationship">`;
+		if (slave.counter.slavesKnockedUp > 0) {
+			r += `${He}'s knocked up ${numberWithPluralOne(slave.counter.slavesKnockedUp, "other slave girl")} `;
+			if (slave.counter.slavesFathered > 0) {
+				r += `and fathered ${numberWithPluralOne(slave.counter.slavesKnockedUp, "new slave")} `;
+			}
+			r += `for you. `;
+		} else if (slave.counter.slavesFathered > 0) {
+			r += `${He}'s fathered ${numberWithPluralOne(slave.counter.slavesFathered, "new slave")} for you. `;
+		}
+		if (slave.counter.PCKnockedUp > 0) {
+			r += `${He}'s managed to knock you up ${numberWithPluralOne(slave.counter.PCKnockedUp, "time")}`;
+			if (slave.counter.PCChildrenFathered > 0) {
+				r += ` and is the father of ${slave.counter.PCChildrenFathered} of your children`;
+			}
+			r += `. `;
+		} else if (slave.counter.PCChildrenFathered > 0) {
+			r += `${He}'s the father of ${slave.counter.PCChildrenFathered} of your children.`;
 		}
-		r += `. `;
-	} else if (slave.counter.PCChildrenFathered > 0) {
-		r += `${He}'s the father of ${slave.counter.PCChildrenFathered} of your children.`;
+		r += `</span>`;
 	}
 
 	return r;
diff --git a/src/npc/descriptions/dimensions.js b/src/npc/descriptions/dimensions.js
index eadeb7c0e883186e780ad65000b6e78a462e5432..8f59c77a4122d67b3ab9d5268ffe95d03b33b392 100644
--- a/src/npc/descriptions/dimensions.js
+++ b/src/npc/descriptions/dimensions.js
@@ -34,7 +34,7 @@ App.Desc.dimensions = function(slave) {
 		const r = [];
 		const averageHeight = Height.mean(slave);
 		const age = slave.physicalAge < 16 ? ` for ${his} age` : ``;
-		const amp = !hasBothLegs(slave) ? `, or would be if ${he} had legs` : ``;
+		const amp = !hasAnyLegs(slave) ? `, or would be if ${he} had legs` : ``;
 
 		r.push(`is`);
 		if (slave.height <= (averageHeight + 5) && slave.height >= (averageHeight - 5)) {
diff --git a/src/npc/descriptions/heightImplant.js b/src/npc/descriptions/heightImplant.js
index 5ab221f576d274f7c641f3464e778743197bef2e..dc3923afb8e1c0573114c1cec9c37623178e52bd 100644
--- a/src/npc/descriptions/heightImplant.js
+++ b/src/npc/descriptions/heightImplant.js
@@ -7,16 +7,28 @@ App.Desc.heightImplant = function(slave) {
 	const {his} = getPronouns(slave);
 	if (slave.heightImplant > 1) {
 		r = limbs();
-		r.push(`are wrong; it's obvious that they have been artificially lengthened.`);
+		r.push(isare());
+		r.push(`wrong; it's obvious that`);
+		r.push(ithastheyhave());
+		r.push(`been artificially lengthened.`);
 	} else if (slave.heightImplant > 0) {
 		r = limbs();
-		r.push(`are odd, as though they have been artificially lengthened.`);
+		r.push(isare());
+		r.push(`odd, as though`);
+		r.push(ithastheyhave());
+		r.push(`been artificially lengthened.`);
 	} else if (slave.heightImplant < -1) {
 		r = limbs();
-		r.push(`are wrong; it's obvious that they have been artificially shortened.`);
+		r.push(isare());
+		r.push(`wrong; it's obvious that`);
+		r.push(ithastheyhave());
+		r.push(`been artificially shortened.`);
 	} else if (slave.heightImplant < 0) {
 		r = limbs();
-		r.push(`are odd, as though they have been artificially shortened.`);
+		r.push(isare());
+		r.push(`odd, as though`);
+		r.push(ithastheyhave());
+		r.push(`been artificially shortened.`);
 	}
 
 	return r.join(" ");
@@ -43,4 +55,24 @@ App.Desc.heightImplant = function(slave) {
 		}
 		return r;
 	}
+
+	function isare() {
+		const d = [];
+		if (getLimbCount(slave) === 1) {
+			d.push(`is`);
+		} else {
+			d.push(`are`);
+		}
+		return d;
+	}
+
+	function ithastheyhave() {
+		const d = [];
+		if (getLimbCount(slave) === 1) {
+			d.push(`it has`);
+		} else {
+			d.push(`they have`);
+		}
+		return d;
+	}
 };
diff --git a/src/npc/descriptions/longSlave.js b/src/npc/descriptions/longSlave.js
index bbcfac572338aeb2ad3ab961fba61422c00ef2bd..5d55dfc4c661ad6edd17fec48e1c84099a99ea8d 100644
--- a/src/npc/descriptions/longSlave.js
+++ b/src/npc/descriptions/longSlave.js
@@ -18,7 +18,9 @@ App.Desc.longSlave = function(slave, {descType, market = 0, prisonCrime, noArt}
 	descType = descType || (market ? DescType.MARKET : DescType.NORMAL);
 
 	if (!noArt) {
-		App.Events.drawEventArt(el, slave);
+		if (!V.seeCustomImagesOnly || V.seeCustomImagesOnly && slave.custom.image && slave.custom.image.filename !== "") {
+			App.Events.drawEventArt(el, slave);
+		}
 	}
 
 	p = document.createElement("p");
@@ -233,7 +235,7 @@ App.Desc.longSlave = function(slave, {descType, market = 0, prisonCrime, noArt}
 		if (origin === "$auto") {
 			origin = App.StartingGirls.playerOrigin(slave).preview;
 		}
-		if (origin !== 0) {
+		if (origin !== "") {
 			r.push(pronounsForSlaveProp(slave, origin));
 		}
 	}
@@ -293,6 +295,40 @@ App.Desc.longSlave = function(slave, {descType, market = 0, prisonCrime, noArt}
 		r.push(`bimbo by societal trends.`);
 	}
 
+	/* Needs contemplation. Slightly redundant with descriptionsWidgets.
+	if(slave.visualAge === V.idealAge) {
+		if(slave.actualAge === V.idealAge) {
+			r.push(`${He} is ${slave.actualAge}, `);
+		} else {
+			r.push(`${He} appears to be ${slave.visualAge}, `);
+		}
+		if(V.idealAge === 18) {
+			r.push(`and many still find this age especially attractive due to old world tradition.`);
+		} else {
+			r.push(`and many in the arcology find this age especially attractive.`);
+		}
+	} else if (slave.visualAge !== slave.actualAge && slave.visualAge === V.idealAge - 1) {
+		r.push(`${He} appears to be ${slave.visualAge}, which is nearly the ideal, but as ${he} is actually ${slave.actualAge}, this can sometimes be cause for confusion regarding the appropriate level of enthusiasm society should have for ${him}.`);
+	} else if(slave.visualAge === V.idealAge - 1) {
+		if(slave.actualAge === V.idealAge - 1) {
+			r.push(`${He} is ${slave.actualAge}, `);
+		} else {
+			r.push(`${He} appears to be ${slave.visualAge}, `);
+		}
+		if(V.idealAge === 18) {
+			r.push(`and many are already looking forward to ${his} birthday with great anticipation due to old world tradition.`);
+		} else {
+			r.push(`and many in the arcology are already looking forward to ${his} birthday with great anticipation.`);
+		}
+	} else if(slave.actualAge === V.idealAge && slave.visualAge !== V.idealAge) {
+		r.push(`${He} is ${slave.actualAge}, a fact that many in the arcology find appealing `);
+		if(V.idealAge === 18) {
+			r.push(`because of old world tradition, `);
+		}
+		r.push(`but due to ${his} appearing to be ${slave.visualAge}, there is less enthusiasm for ${him} than there might otherwise be.`);
+	}
+	*/
+
 	$(p).append(r.join(" "));
 
 	if (V.showScores !== 0) {
@@ -336,7 +372,16 @@ App.Desc.longSlave = function(slave, {descType, market = 0, prisonCrime, noArt}
 		const wins = slave.counter.pitWins;
 		const losses = slave.counter.pitLosses;
 
-		r.push(`${He} has participated in ${num(wins + losses)} pit fights, with ${numberWithPluralOne(wins, "win")} and ${numberWithPluralOne(losses, "loss", "losses")}.`);
+		r.push(`${He} has participated in ${num(wins + losses)} pit fights,`);
+		if (wins > 0) {
+			if (losses > 0) {
+				r.push(`with ${numberWithPluralOne(wins, "win")} and ${numberWithPluralOne(losses, "loss", "losses")}.`);
+			} else {
+				r.push(`${wins > 2 ? `all of ` : `both of `}which ${he} won.`);
+			}
+		} else {
+			r.push(`${losses > 2 ? `all of ` : `both of `}which ${he} lost.`);
+		}
 	}
 
 	if (slave.counter.pitKills > 0) {
@@ -358,11 +403,12 @@ App.Desc.longSlave = function(slave, {descType, market = 0, prisonCrime, noArt}
 	}
 
 	let scarCounter = 0;
-	for (let scarName in slave.scar) {
+	const scars = App.Medicine.Modification.scarRecord(slave)
+	for (let scarName in scars) {
 		if (slave.ID === V.BodyguardID && scarCounter > 1) {
 			r.push(`${His} scars make ${him} look even more menacing than ${he} actually is.`);
 			break;
-		} else if ((slave.ID === V.BodyguardID) && slave.scar[scarName].menacing > 0) {
+		} else if ((slave.ID === V.BodyguardID) && scars[scarName].menacing > 0) {
 			r.push(`${His} menacing scar makes ${him} look terrifying.`);
 			break;
 		} else if ((slave.ID === V.WardenessID) && scarCounter > 1) {
@@ -419,10 +465,10 @@ App.Desc.longSlave = function(slave, {descType, market = 0, prisonCrime, noArt}
 	}
 
 	if (slave.fuckdoll === 0) {
-		if (slave.hColor === "red") {
+		if (App.Data.misc.redheadColors.includes(slave.hColor)) {
 			if (slave.hLength >= 10) {
 				if (slave.markings === "freckles" || slave.markings === "heavily freckled") {
-					if (skinToneLevel(slave.skin).isBetween(5, 10)) {
+					if (App.Medicine.Modification.naturalSkins.includes(slave.skin) && skinToneLevel(slave.skin).isBetween(5, 10)) {
 						r.push(`It goes perfectly with ${his} ${slave.skin} skin and freckles.`);
 					}
 				}
diff --git a/src/npc/descriptions/mind.js b/src/npc/descriptions/mind.js
index 0fc895f059ed2c1c7229e322ac1be4f6d761d6e8..76512280e1fc90ef58b528fff325e1a1c875656c 100644
--- a/src/npc/descriptions/mind.js
+++ b/src/npc/descriptions/mind.js
@@ -12,7 +12,7 @@ App.Desc.mind = function(slave, descType) {
 		r.push(App.Desc.eyes(slave, descType));
 
 		if (slave.fetish === "mindbroken") {
-			r.push(`However, <span class="coral">${his} mind is fundamentally broken;</span> everything ${he} experiences will quickly be forgotten.`);
+			r.push(`<span class="coral">${His} mind is fundamentally broken;</span> everything ${he} experiences will quickly be forgotten.`);
 		} else {
 			r.push(behavioralFlaws());
 			r.push(behavioralQuirks());
@@ -514,7 +514,11 @@ App.Desc.mind = function(slave, descType) {
 					if (slave.fetishStrength > 95) {
 						r.push(`${He} has a <span class="lightcoral">pregnancy fetish,</span> and finds anything related to reproduction sexy.`);
 					} else if (slave.fetishStrength > 60) {
-						r.push(`${He} has an <span class="lightcoral">impregnation fantasy,</span> and enjoys bareback sex.`);
+						if ((canDoVaginal(slave) && slave.vagina > 0) || (slave.mpreg && canGetPregnant(slave))) {
+							r.push(`${He} has an <span class="lightcoral">impregnation fantasy,</span> and enjoys bareback sex.`);
+						} else {
+							r.push(`${He} has an <span class="lightcoral">impregnation fantasy,</span> and is titillated by the idea of growing heavy with child.`);
+						}
 					} else {
 						r.push(`${He} has a recurring <span class="lightcoral">impregnation fantasy.</span>`);
 					}
diff --git a/src/npc/descriptions/sceneIntro.js b/src/npc/descriptions/sceneIntro.js
index 95bf532cfa018df24f935827cc73021cb20db099..b9132008ecbdf0a3602975f07958e18a3e25ab01 100644
--- a/src/npc/descriptions/sceneIntro.js
+++ b/src/npc/descriptions/sceneIntro.js
@@ -11,7 +11,7 @@ App.Desc.sceneIntro = function(slave, descType) {
 
 	if (descType === DescType.EVENT) {
 		r.push(`${He} is currently involved in an event, but is assigned to ${slave.assignment}.`);
-		if (slave.assignment === "be a subordinate slave") {
+		if (slave.assignment === Job.SUBORDINATE) {
 			let lsd = getSlave(slave.subTarget);
 			if (lsd) {
 				r.push(`${He} has been ordered to serve <span class="slave name simple">${SlaveFullName(lsd)}</span> specifically.`);
@@ -38,33 +38,41 @@ App.Desc.sceneIntro = function(slave, descType) {
 		const r = [];
 		if (slave.fuckdoll > 0) {
 			r.push(`You order another slave to bring ${him} before your desk so you can inspect ${him}.`);
-		} else if ((slave.assignment === "work in the dairy") && (V.dairyRestraintsSetting > 1)) {
+		} else if ((slave.assignment === Job.DAIRY) && (V.dairyRestraintsSetting > 1)) {
 			r.push(`You go down to ${V.dairyName} to inspect ${his} heaving body.`);
-		} else if (slave.assignment === "be your agent") {
+		} else if (slave.assignment === Job.AGENT) {
 			const arc = V.arcologies.find(a => a.leaderID === slave.ID);
 			r.push(`You place a call to ${arc ? arc.name : `${his} current location`}, and ${he} instantly appears on camera.`);
 		} else {
 			r.push(`${He} comes to you for an inspection`);
 			switch (slave.assignment) {
-				case "whore":
+				case Job.WHORE:
+				case Job.BROTHEL:
 					r.push(`between customers.`);
 					break;
-				case "serve the public":
+				case Job.PUBLIC:
 					r.push(`from where ${he} was offering ${himself} publicly.`);
 					break;
-				case "work a glory hole":
+				case Job.CLUB:
+					r.push(`from where ${he} was dancing in ${V.clubName}.`);
+					break;
+				case Job.GLORYHOLE:
 					r.push(`straight from confinement in a glory hole.`);
 					break;
-				case "get milked":
+				case Job.ARCADE:
+					r.push(`straight from confinement in ${V.arcadeName}.`);
+					break;
+				case Job.MILKED:
+				case Job.DAIRY:
 					r.push(`between milkings.`);
 					break;
-				case "work as a farmhand":
+				case Job.FARMYARD:
 					r.push(`from where ${he} was taking care of crops and animals.`);
 					break;
-				case "rest":
+				case Job.REST:
 					r.push(`from where ${he} was resting.`);
 					break;
-				case "work as a nanny":
+				case Job.NURSERY:
 					r.push(`from where ${he} was`);
 					if (V.nurseryChildren === 1) {
 						r.push(`taking care of a child.`);
@@ -74,45 +82,54 @@ App.Desc.sceneIntro = function(slave, descType) {
 						r.push(`keeping ${V.nurseryName} clean.`);
 					}
 					break;
-				case "please you":
+				case Job.FUCKTOY:
 					r.push(`from where ${he} was offering ${himself} to you.`);
 					break;
-				case "be a subordinate slave":
+				case Job.MASTERSUITE:
+					r.push(`from ${V.masterSuiteName}.`);
+					break;
+				case Job.SUBORDINATE:
 					if (slave.subTarget === -1) {
 						r.push(`from where ${he} was resting after ${his} latest baby-making session.`);
 					} else {
 						r.push(`straight from orally servicing another slave.`);
 					}
 					break;
-				case "be a servant":
+				case Job.HOUSE:
+				case Job.QUARTER:
 					r.push(`straight from bathing another slave.`);
 					break;
-				case "be the Schoolteacher":
+				case Job.TEACHER:
 					r.push(`between slave training contracts.`);
 					break;
-				case "stay confined":
+				case Job.SCHOOL:
+				case Job.CLASSES:
+					r.push(`between classes.`);
+					break;
+				case Job.CONFINEMENT:
 					r.push(`straight from ${his} confinement.`);
 					break;
-				case "guard you":
+				case Job.CELLBLOCK:
+					r.push(`straight from ${his} cell in ${V.cellblockName}.`);
+					break;
+				case Job.BODYGUARD:
 					r.push(`armed and alert.`);
 					break;
-				case "recruit girls":
+				case Job.RECRUITER:
 					if (V.recruiterTarget !== "other arcologies") {
 						r.push(`after ${he} finishes cybering with a prospective recruit.`);
+					} else if (V.arcologies[0].influenceTarget === -1) {
+						r.push(`right away, since you haven't decided on an arcology to target for cultural influence, leaving ${him} with nothing to do.`);
 					} else {
-						if (V.arcologies[0].influenceTarget === -1) {
-							r.push(`right away, since you haven't decided on an arcology to target for cultural influence, leaving ${him} with nothing to do.`);
-						} else {
-							const arc = V.arcologies.find(a => a.direction === V.arcologies[0].influenceTarget);
-							r.push(`from where ${he} was resting after ${his} latest sexually exhausting visit to ${arc ? arc.name : "a nearby arcology"}.`);
-						}
+						const arc = V.arcologies.find(a => a.direction === V.arcologies[0].influenceTarget);
+						r.push(`from where ${he} was resting after ${his} latest sexually exhausting visit to ${arc ? arc.name : "a nearby arcology"}.`);
 					}
 					break;
-				case "be your Head Girl":
+				case Job.HEADGIRL:
 					r.push(`with updates on your other slaves ready for your review.`);
 					break;
 				default:
-					r.push(`as quickly as ${he} can.`);
+					r.push(`as quickly as ${he} can. ${He} is assigned to ${slave.assignment}.`);
 			}
 		}
 		return r.join(" ");
@@ -262,6 +279,8 @@ App.Desc.sceneIntro = function(slave, descType) {
 			r.push(`${He} lives in ${his} own suite within your penthouse,`);
 		} else if ((slave.ID === V.BodyguardID) && (V.dojo > 1)) {
 			r.push(`${He} lives in ${his} own room within the armory,`);
+		} else if ([Job.MASTERSUITE, Job.CONCUBINE].includes(slave.assignment) && V.masterSuiteUpgradeLuxury === 1) {
+			r.push(`${He} sleeps with you in your bed,`);
 		} else if ((slave.assignment === "work in the dairy") && (V.dairyRestraintsSetting > 1)) {
 			r.push(`${He} sleeps attached to a milking machine,`);
 		} else if (slave.rules.living === "spare") {
diff --git a/src/npc/descriptions/skin.js b/src/npc/descriptions/skin.js
index 0d77ff53d2da7b6dc66f65512b809f612a36cf5e..2b18f0c34152a9a671a13489d36251ecfeda8413 100644
--- a/src/npc/descriptions/skin.js
+++ b/src/npc/descriptions/skin.js
@@ -77,7 +77,7 @@ App.Desc.skin = function(slave, descType) {
 			r.push(`${slave.skin} and lightly spotted.`);
 		} else if (slave.markings === "freckles") {
 			r.push(`${slave.skin} and lightly`);
-			if ((skinToneLevel(slave.skin) > 5) && (skinToneLevel(slave.skin) < 10) && (slave.hColor === "red")) {
+			if (App.Medicine.Modification.naturalSkins.includes(slave.skin) && skinToneLevel(slave.skin).isBetween(5, 10) && (App.Data.misc.redheadColors.includes(slave.hColor))) {
 				r.push(`freckled, an attractive combination.`);
 			} else {
 				r.push(`freckled.`);
@@ -86,7 +86,7 @@ App.Desc.skin = function(slave, descType) {
 			r.push(`${slave.skin} and heavily spotted.`);
 		} else if (slave.markings === "heavily freckled") {
 			r.push(`${slave.skin} and heavily`);
-			if ((skinToneLevel(slave.skin) > 5) && (skinToneLevel(slave.skin) < 10) && (slave.hColor === "red")) {
+			if (App.Medicine.Modification.naturalSkins.includes(slave.skin) && skinToneLevel(slave.skin).isBetween(5, 10) && (App.Data.misc.redheadColors.includes(slave.hColor))) {
 				r.push(`freckled, an attractive combination.`);
 			} else {
 				r.push(`freckled.`);
diff --git a/src/npc/descriptions/style/footwear.js b/src/npc/descriptions/style/footwear.js
index 11a82a2e19243e4bbaf63182a651d2d2125518ce..fb0a856acbe727d350db3c5703df1e59bed4bfa5 100644
--- a/src/npc/descriptions/style/footwear.js
+++ b/src/npc/descriptions/style/footwear.js
@@ -1987,7 +1987,7 @@ App.Desc.footwear = function(slave) {
 						}
 						break;
 					default:
-						if (bothFeet) {
+						if (!bothFeet) {
 							r.push("a");
 						}
 						r.push(`comically bare ${feet}.`);
@@ -2053,7 +2053,7 @@ App.Desc.footwear = function(slave) {
 						}
 						break;
 					default:
-						if (bothFeet) {
+						if (!bothFeet) {
 							r.push("a");
 						}
 						r.push(`ridiculously bare stockinged ${feet}.`);
@@ -2118,7 +2118,7 @@ App.Desc.footwear = function(slave) {
 						}
 						break;
 					default:
-						if (bothFeet) {
+						if (!bothFeet) {
 							r.push("a");
 						}
 						r.push(`ridiculously bare stockinged ${feet}.`);
@@ -2568,7 +2568,7 @@ App.Desc.footwear = function(slave) {
 						if (bothFeet) {
 							r.push(`ballet shoes made to force ${him} to walk en pointe.`);
 						} else {
-							r.push(`a ballet shoe made so tall ${he} he has to crawl wherever ${he} goes.`);
+							r.push(`a ballet shoe made so tall ${he} has to crawl wherever ${he} goes.`);
 						}
 						break;
 					case "platform shoes":
diff --git a/src/npc/descriptions/style/hairClothing.js b/src/npc/descriptions/style/hairClothing.js
index f5a8711acf2ed99b9ae3f8e7bd3de8c6acf35d3c..b99b8a5b518f9c583e6138b88b65871fa2e90aca 100644
--- a/src/npc/descriptions/style/hairClothing.js
+++ b/src/npc/descriptions/style/hairClothing.js
@@ -1273,7 +1273,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is gathered into floor-length tails by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is gathered into secure tails and doubled up so ${he} can do business without them getting in the way.`);
+								r.push(`is gathered into secure tails and doubled up so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -1434,7 +1434,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is gathered into long tails by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is gathered into secure tails so ${he} can do business without them getting in the way.`);
+								r.push(`is gathered into secure tails so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -1595,7 +1595,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is gathered into short tails by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is gathered into short tails so ${he} can do business without them getting in the way.`);
+								r.push(`is gathered into short tails so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -3775,7 +3775,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is gathered into a long ponytail by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is gathered into a secure ponytail so ${he} can do business without them getting in the way.`);
+								r.push(`is gathered into a secure ponytail so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -4117,7 +4117,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is gathered into floor-length braids by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is gathered into secure braids and doubled up so ${he} can do business without them getting in the way.`);
+								r.push(`is gathered into secure braids and doubled up so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -4272,7 +4272,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is tied into long braids and secured by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is tied into long braids and secured so ${he} can do business without them getting in the way.`);
+								r.push(`is tied into long braids and secured so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 								r.push(`is tied into long braids and secured by white cloth ties emblazoned with little red crosses.`);
@@ -4426,7 +4426,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is gathered into short braids by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is gathered into short braids so ${he} can do business without them getting in the way.`);
+								r.push(`is gathered into short braids so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -4607,7 +4607,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is in floor-length dreadlocks, some in gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is in dreadlocks and tied up so ${he} can do business without them getting in the way.`);
+								r.push(`is in dreadlocks and tied up so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -4764,7 +4764,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is in dreadlocks, some in gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is in dreadlocks and tied so ${he} can do business without them getting in the way.`);
+								r.push(`is in dreadlocks and tied so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -4919,7 +4919,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is in short dreadlocks, some with gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is in short dreadlocks and tied so ${he} can do business without them getting in the way.`);
+								r.push(`is in short dreadlocks and tied so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -5100,7 +5100,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is curled into long flowing locks, secured by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is curled into long flowing locks and tied up so ${he} can do business without them getting in the way.`);
+								r.push(`is curled into long flowing locks and tied up so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -5255,7 +5255,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is curled into long locks secured by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is curled into long locks and tied so ${he} can do business without them getting in the way.`);
+								r.push(`is curled into long locks and tied so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -5410,7 +5410,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is curled into short locks secured by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is curled into short locks and tied so ${he} can do business without them getting in the way.`);
+								r.push(`is curled into short locks and tied so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -5591,7 +5591,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is permed into long flowing curls, secured by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is permed into long flowing curls and tied up so ${he} can do business without them getting in the way.`);
+								r.push(`is permed into long flowing curls and tied up so ${he} can do business without it getting in the way.`);
 								break;
 							case "a nice nurse outfit":
 							case "a slutty nurse outfit":
@@ -5746,7 +5746,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is permed and secured by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is permed and tied so ${he} can do business without them getting in the way.`);
+								r.push(`is permed and tied so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -5901,7 +5901,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is permed into short waves secured by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is permed into short waves and tied so ${he} can do business without them getting in the way.`);
+								r.push(`is permed into short waves and tied so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
@@ -8448,7 +8448,7 @@ App.Desc.hairClothing = function(slave) {
 								r.push(`is gathered into short coils by gaudy gold clasps.`);
 								break;
 							case "nice business attire":
-								r.push(`is gathered into short coils so ${he} can do business without them getting in the way.`);
+								r.push(`is gathered into short coils so ${he} can do business without it getting in the way.`);
 								break;
 							case "a slutty nurse outfit":
 							case "a nice nurse outfit":
diff --git a/src/npc/descriptions/style/upperFace.js b/src/npc/descriptions/style/upperFace.js
index 3265bef00878304553f8e4029df69999b31f2000..e58346043369ab18350e8e418ba4f4218ad6faa8 100644
--- a/src/npc/descriptions/style/upperFace.js
+++ b/src/npc/descriptions/style/upperFace.js
@@ -191,7 +191,7 @@ App.Desc.upperFace = function(slave) {
 				}
 			}
 		}
-		// CLOSES EYEWEAR
+
 		if (slave.earwear === "hearing aids" || slave.earwear === "muffling ear plugs" || slave.earwear === "deafening ear plugs") {
 			r.push(`In ${his} ears, ${he} wears`);
 			if (slave.earwear === "hearing aids") {
diff --git a/src/npc/descriptions/womb/superfetation.js b/src/npc/descriptions/womb/superfetation.js
index 4be3a3870a587e7ae274c492c1b90e5b9a621ca5..f1841349f2e6cc05bd2836a0374bf4d2dd6a4cea 100644
--- a/src/npc/descriptions/womb/superfetation.js
+++ b/src/npc/descriptions/womb/superfetation.js
@@ -4,12 +4,22 @@
  * @returns {string}
  */
 App.Desc.superfetation = function(slave, descType) {
+	function daddyName(daddyID) {
+		if (daddyID > 0) {
+			const lsd = findFather(daddyID);
+			if (lsd) {
+				return SlaveFullName(lsd);
+			}
+		} else if (daddyID in V.missingTable && V.showMissingSlaves) {
+			return V.missingTable[daddyID].fullName;
+		}
+		return "another slave";
+	}
+
 	const r = [];
 	const {
 		his, His
 	} = getPronouns(slave);
-	let lsd;
-	let daddy;
 	const slaveWD = WombGetLittersData(slave);
 	if (slave.geneticQuirks.superfetation === 2 && slaveWD.litters.length > 1 && V.pregnancyMonitoringUpgrade === 1 && descType !== DescType.MARKET) {
 		r.push(`${His} womb contains ${num(slaveWD.litters.length)} separate pregnancies:`);
@@ -19,151 +29,43 @@ App.Desc.superfetation = function(slave, descType) {
 			const was = countLitter > 1 ? "were" : "was";
 			if (litCount === 0) {
 				r.push(`the eldest`);
-				if (countLitter > 1) {
-					r.push(`set of ${num(countLitter)},`);
-				} else {
-					r.push(`one,`);
-				}
-				r.push(`at ${slaveWD.litters[litCount]}`);
-				if (slaveWD.litters[litCount] > 1) {
-					r.push(`weeks`);
-				} else {
-					r.push(`week`);
-				}
-				r.push(`of development,`);
-				if (slaveWD.litterData[litCount][0].fatherID === -7) {
-					r.push(`${is} from the gene lab,`);
-				} else if (slaveWD.litterData[litCount][0].age > slave.pregData.normalBirth / 8) {
-					if (slaveWD.litterData[litCount][0].fatherID === -1) {
-						r.push(`${was} fathered by your seed,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -2) {
-						r.push(`${was} fathered by one of your citizens,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -3) {
-						r.push(`${was} fathered by your former Master,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -4) {
-						r.push(`${was} fathered by another arcology owner,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -5) {
-						r.push(`${was} fathered by one of your clients,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -6) {
-						r.push(`${was} fathered by a member of the Societal Elite,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -9) {
-						r.push(`${was} fathered by the Futanari Sisters,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === 0) {
-						r.push(`${is} from an unidentifiable source,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === slave.ID) {
-						r.push(`${is} from ${his} own handiwork,`);
-					} else {
-						if (slaveWD.litterData[litCount][0].fatherID > 0) {
-							lsd = findFather(slaveWD.litterData[litCount][0].fatherID);
-							if (lsd) {
-								daddy = SlaveFullName(lsd);
-							} else {
-								daddy = "another slave";
-							}
-						} else if (slaveWD.litterData[litCount][0].fatherID in V.missingTable && V.showMissingSlaves) {
-							daddy = V.missingTable[slave.pregSource].fullName;
-						}
-						r.push(`${was} fathered by ${daddy}'s seed,`);
-					}
-				} else {
-					r.push(`${is} too young to tell the father of,`);
-				}
 			} else if (litCount === slaveWD.litters.length - 1) {
 				r.push(`and the youngest`);
-				if (countLitter > 1) {
-					r.push(`set of ${num(countLitter)},`);
-				} else {
-					r.push(`one,`);
-				}
-				r.push(`at ${slaveWD.litters[litCount]}`);
-				if (slaveWD.litters[litCount] > 1) {
-					r.push(`weeks`);
-				} else {
-					r.push(`week`);
-				}
-				r.push(`of development,`);
-				if (slaveWD.litterData[litCount][0].fatherID === -7) {
-					r.push(`${is} from the gene lab.`);
-				} else if (slaveWD.litterData[litCount][0].age > slave.pregData.normalBirth / 8) {
-					if (slaveWD.litterData[litCount][0].fatherID === -1) {
-						r.push(`${was} fathered by your seed.`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -2) {
-						r.push(`${was} fathered by one of your citizens.`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -3) {
-						r.push(`${was} fathered by your former Master. He was quite the busy man.`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -4) {
-						r.push(`${was} fathered by another arcology owner.`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -5) {
-						r.push(`${was} fathered by one of your clients.`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -6) {
-						r.push(`${was} fathered by a member of the Societal Elite.`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -9) {
-						r.push(`${was} fathered by the Futanari Sisters.`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === 0) {
-						r.push(`${is} from an unidentifiable source.`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === slave.ID) {
-						r.push(`${is} from ${his} own seed.`);
-					} else {
-						if (slaveWD.litterData[litCount][0].fatherID > 0) {
-							lsd = findFather(slaveWD.litterData[litCount][0].fatherID);
-							if (lsd) {
-								daddy = SlaveFullName(lsd);
-							} else {
-								daddy = "another slave";
-							}
-						} else if (slaveWD.litterData[litCount][0].fatherID in V.missingTable && V.showMissingSlaves) {
-							daddy = V.missingTable[slave.pregSource].fullName;
-						}
-						r.push(`${was} fathered by ${daddy}'s seed.`);
-					}
-				} else {
-					r.push(`${is} too young to tell the father of.`);
-				}
 			} else {
-				r.push(`the next set of ${num(countLitter)} at ${slaveWD.litters[litCount]}`);
-				if (slaveWD.litters[litCount] > 1) {
-					r.push(`weeks`);
-				} else {
-					r.push(`week`);
-				}
-				r.push(`of development`);
-				if (slaveWD.litterData[litCount][0].fatherID === -7) {
-					r.push(`${is} from the gene lab,`);
-				} else if (slaveWD.litterData[litCount][0].age > slave.pregData.normalBirth / 8) {
-					if (slaveWD.litterData[litCount][0].fatherID === -1) {
-						r.push(`${was} fathered by your seed,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -2) {
-						r.push(`${was} fathered by one of your citizens,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -3) {
-						r.push(`${was} fathered by your former Master,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -4) {
-						r.push(`${was} fathered by another arcology owner,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -5) {
-						r.push(`${was} fathered by one of your clients,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -6) {
-						r.push(`${was} fathered by a member of the Societal Elite,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === -9) {
-						r.push(`${was} fathered by the Futanari Sisters,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === 0) {
-						r.push(`${is} from an unidentifiable source,`);
-					} else if (slaveWD.litterData[litCount][0].fatherID === slave.ID) {
-						r.push(`${is} from ${his} own handiwork,`);
-					} else {
-						if (slaveWD.litterData[litCount][0].fatherID > 0) {
-							lsd = findFather(slaveWD.litterData[litCount][0].fatherID);
-							if (lsd) {
-								daddy = SlaveFullName(lsd);
-							} else {
-								daddy = "another slave";
-							}
-						} else if (slaveWD.litterData[litCount][0].fatherID in V.missingTable && V.showMissingSlaves) {
-							daddy = V.missingTable[slave.pregSource].fullName;
-						}
-						r.push(`${was} fathered by ${daddy}'s seed,`);
-					}
+				r.push(`the next`);
+			}
+			if (countLitter > 1) {
+				r.push(`set of ${num(countLitter)},`);
+			} else {
+				r.push(`one,`);
+			}
+			r.push(`at ${numberWithPluralOne(slaveWD.litters[litCount], "week")} of development,`);
+			if (slaveWD.litterData[litCount][0].fatherID === -7) {
+				r.push(`${is} from the gene lab,`);
+			} else if (slaveWD.litterData[litCount][0].age > slave.pregData.normalBirth / 8) {
+				if (slaveWD.litterData[litCount][0].fatherID === -1) {
+					r.push(`${was} fathered by your seed,`);
+				} else if (slaveWD.litterData[litCount][0].fatherID === -2) {
+					r.push(`${was} fathered by one of your citizens,`);
+				} else if (slaveWD.litterData[litCount][0].fatherID === -3) {
+					r.push(`${was} fathered by your former Master,`);
+				} else if (slaveWD.litterData[litCount][0].fatherID === -4) {
+					r.push(`${was} fathered by another arcology owner,`);
+				} else if (slaveWD.litterData[litCount][0].fatherID === -5) {
+					r.push(`${was} fathered by one of your clients,`);
+				} else if (slaveWD.litterData[litCount][0].fatherID === -6) {
+					r.push(`${was} fathered by a member of the Societal Elite,`);
+				} else if (slaveWD.litterData[litCount][0].fatherID === -9) {
+					r.push(`${was} fathered by the Futanari Sisters,`);
+				} else if (slaveWD.litterData[litCount][0].fatherID === 0) {
+					r.push(`${is} from an unidentifiable source,`);
+				} else if (slaveWD.litterData[litCount][0].fatherID === slave.ID) {
+					r.push(`${is} from ${his} own handiwork,`);
 				} else {
-					r.push(`${is} too young to tell the father of,`);
+					r.push(`${was} fathered by ${daddyName(slaveWD.litterData[litCount][0].fatherID)}'s seed,`);
 				}
+			} else {
+				r.push(`${is} too young to tell the father of,`);
 			}
 		}
 	}
diff --git a/src/npc/generate/generateGenetics.js b/src/npc/generate/generateGenetics.js
index 3d0ec6b553f8c56f85c2702e77a48c4f95882a80..1b5ffaeeaff97f3673e1baac4b46fb2268a2867f 100644
--- a/src/npc/generate/generateGenetics.js
+++ b/src/npc/generate/generateGenetics.js
@@ -104,8 +104,8 @@ globalThis.generateGenetics = (function() {
 		genes.inbreedingCoeff = ibc.kinship(mother, father);
 		genes.nationality = setNationality(father, mother);
 		genes.geneticQuirks = setGeneticQuirks(activeFather, activeMother, genes.gender);
-		genes.skin = setSkin(father, mother);
 		genes.race = setRace(father, mother);
+		genes.skin = setSkin(father, mother, genes.race);
 		genes.intelligence = setIntelligence(father, mother, activeMother, actor2, genes.inbreedingCoeff);
 		genes.face = setFace(father, mother, activeMother, actor2, genes.geneticQuirks, genes.inbreedingCoeff);
 		genes.faceShape = setFaceShape(father, mother, genes.geneticQuirks);
@@ -284,8 +284,12 @@ globalThis.generateGenetics = (function() {
 		return race;
 	}
 
-	// skin
-	function setSkin(father, mother) {
+	/**
+	 * @param {FC.Zeroable<FC.HumanState>} father
+	 * @param {FC.HumanState} mother
+	 * @param {FC.Race} race
+	 */
+	function setSkin(father, mother, race) {
 		/** @type {FC.Zeroable<string>} */
 		let fatherSkin = 0;
 		let dadSkinIndex;
@@ -316,21 +320,54 @@ globalThis.generateGenetics = (function() {
 			"ivory": 2,
 			"pure white": 1
 		};
-		const momSkinIndex = mother ? (skinToMelanin[mother.origSkin] || 13) : 8;
-		if (father !== 0) {
-			fatherSkin = father.origSkin;
-		} else if (fatherRace !== 0) {
-			fatherSkin = randomRaceSkin(fatherRace);
-		}
-		dadSkinIndex = fatherSkin !== 0 ? (skinToMelanin[fatherSkin] || 13) : 8;
-		const skinIndex = Math.round(Math.random() * (dadSkinIndex - momSkinIndex) + momSkinIndex);
+		const racialSkinToneBounds = {
+			"black": [21, 25],
+			"white": [4, 12],
+			"latina": [10, 22],
+			"indo-aryan": [9, 24],
+			"malay": [9, 24],
+			"pacific islander": [11, 24],
+			"amerindian": [11, 22],
+			"asian": [4, 15],
+			"middle eastern": [10, 21],
+			"semitic": [10, 21],
+			"southern european": [9, 15]
+		};
 
 		let prop = "";
-		for (prop in skinToMelanin) {
-			if (!skinToMelanin.hasOwnProperty(prop)) { continue; }
-			if (skinIndex >= skinToMelanin[prop]) { return prop; }
+		if (race === "catgirl") {
+			// pick a random catgirl color, slightly preferring the parents' coloration if applicable
+			const catgirlColors = [...App.Medicine.Modification.catgirlNaturalSkins];
+			if (mother.origSkin in catgirlColors) {
+				catgirlColors.push(mother.origSkin, mother.origSkin);
+			}
+			if (father && father.origSkin in catgirlColors) {
+				catgirlColors.push(father.origSkin, father.origSkin);
+			}
+			return catgirlColors.random();
+		} else {
+			// blend the father's and mother's skintones
+			const momSkinIndex = mother ? (skinToMelanin[mother.origSkin] || 13) : 8;
+			if (father !== 0) {
+				fatherSkin = father.origSkin;
+			} else if (fatherRace !== 0) {
+				fatherSkin = randomRaceSkin(fatherRace);
+			}
+			dadSkinIndex = fatherSkin !== 0 ? (skinToMelanin[fatherSkin] || 13) : 8;
+
+			let skinIndex = Math.round(Math.random() * (dadSkinIndex - momSkinIndex) + momSkinIndex);
+			if (race in racialSkinToneBounds) {
+				// don't exceed the skintone bounds of the already-selected race (note that "mixed race" does not have bounds)
+				skinIndex = Math.clamp(skinIndex, racialSkinToneBounds[race][0], racialSkinToneBounds[race][1]);
+			}
+
+			// find the skin name associated with the blended skintone
+			for (prop in skinToMelanin) {
+				if (!skinToMelanin.hasOwnProperty(prop)) { continue; }
+				if (skinIndex >= skinToMelanin[prop]) { return prop; }
+			}
+			return prop;
 		}
-		return prop; // skinIndex can be zero - now false?
 	}
 
 	/** Make sure a given eye color is a valid genetic eye color and not the result of some modification.
diff --git a/src/npc/generate/generateMarketSlave.js b/src/npc/generate/generateMarketSlave.js
index 2146b4897c02b8680dacc1d86031d244cf8bef3a..4e298cb935d5d07ff5e1fa403f59d65a6e6b0271 100644
--- a/src/npc/generate/generateMarketSlave.js
+++ b/src/npc/generate/generateMarketSlave.js
@@ -738,9 +738,9 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 				if (jsRandom(1, 100) > 80) {
 					// brand em up
 					if (jsRandom(1, 100) > 50) {
-						slave.brand["left buttock"] = "SLUT";
+						App.Medicine.Modification.addBrand(slave, "left buttock", "SLUT");
 					} else {
-						slave.brand["left buttock"] = "Slave";
+						App.Medicine.Modification.addBrand(slave, "left buttock", "Slave");
 					}
 				}
 			}
@@ -1807,11 +1807,12 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 			slave.butt = jsEither([2, 2, 3]);
 			slave.boobs = jsEither([100, 200]);
 			slave.dick = jsRandom(3, 5);
+			if (slave.foreskin > 0) {
+				slave.foreskin = slave.dick;
+			}
 			slave.balls = jsRandom(3, 5);
+			slave.scrotum = slave.balls;
 			slave.anus = 0;
-			slave.vagina = -1;
-			slave.preg = 0;
-			SetBellySize(slave);
 			slave.weight = 0;
 			slave.waist = jsRandom(-10, 30);
 			slave.skill.vaginal = 0;
@@ -1831,7 +1832,7 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 			slave.behavioralFlaw = jsEither(["arrogant", "none", "odd"]);
 			slave.hStyle = "neat";
 			slave.hLength = 2;
-			slave.brand["left cheek"] = "the baroque crest of the Gymnasium-Academy that trained $him";
+			App.Medicine.Modification.addBrand(slave, "left cheek", "the baroque crest of the Gymnasium-Academy that trained $him");
 			break;
 		}
 		case "TCR": {
@@ -1905,7 +1906,7 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 				slave.energy = 100;
 				applyMindbroken(slave, -100);
 				slave.hStyle = "neat";
-				slave.brand["right thigh"] = "the logo of the Cattle Ranch";
+				App.Medicine.Modification.addBrand(slave, "right thigh", "the logo of the Cattle Ranch");
 			} else {
 				SGProp.minAge = 19;
 				SGProp.maxAge = 24;
@@ -1949,8 +1950,43 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 			break;
 		}
 		case "TFS": {
-			SGProp.minAge = 25;
-			SGProp.maxAge = 29;
+			let sisterAge = jsRandom(1, 5);
+			if (sisterAge === 5) {
+				if (V.retirementAge <= 40) {
+					sisterAge = jsRandom(1, 4);
+				} else {
+					SGProp.minAge = 40;
+					SGProp.maxAge = 42;
+				}
+			}
+			if (sisterAge === 4) {
+				if (V.retirementAge <= 35) {
+					sisterAge = jsRandom(1, 3);
+				} else {
+					SGProp.minAge = 35;
+					SGProp.maxAge = 39;
+				}
+			}
+			if (sisterAge === 3) {
+				if (V.retirementAge <= 30) {
+					sisterAge = jsRandom(1, 2);
+				} else {
+					SGProp.minAge = 30;
+					SGProp.maxAge = 34;
+				}
+			}
+			if (sisterAge === 2) {
+				if (V.retirementAge <= 25) {
+					sisterAge = 1;
+				} else {
+					SGProp.minAge = 25;
+					SGProp.maxAge = 29;
+				}
+			}
+			if (sisterAge === 1) {
+				SGProp.minAge = 19;
+				SGProp.maxAge = 24;
+			}
 			SGProp.ageOverridesPedoMode = 1;
 			SGProp.disableDisability = 1;
 			if (V.TFS.schoolUpgrade === 3 && V.TFS.compromiseWeek + 15 <= V.week) {
@@ -1962,9 +1998,8 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 			slave.career = "a Futanari Sister";
 			slave.faceShape = jsEither(["exotic", "sensual"]);
 			slave.pubertyXY = 1;
-			const sisterAge = jsRandom(1, 5);
 			if (sisterAge === 1) {
-				slave.intelligence = -60;
+				slave.intelligence = random(-60, -30);
 				slave.hips = 0;
 				slave.face = jsEither([35, 35, 35, 75, 100]);
 				if (V.TFS.schoolUpgrade === 3 && V.TFS.compromiseWeek + 15 <= V.week) {
@@ -1988,15 +2023,11 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 				slave.lips = 10;
 				slave.weight = 0;
 				slave.waist = jsRandom(-30, 10);
-				slave.actualAge = jsRandom(19, 24);
-				slave.physicalAge = slave.actualAge;
-				slave.visualAge = slave.actualAge;
-				slave.ovaryAge = slave.actualAge;
 				slave.vagina = 2;
 				slave.anus = 2;
 				slave.fetish = "submissive";
 			} else if (sisterAge === 2) {
-				slave.intelligence = -30;
+				slave.intelligence = random(-50, -20);
 				slave.hips = 1;
 				slave.face = jsEither([35, 35, 35, 75, 100]);
 				if (V.TFS.schoolUpgrade === 3 && V.TFS.compromiseWeek + 15 <= V.week) {
@@ -2024,7 +2055,7 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 				slave.anus = 2;
 				slave.fetish = jsEither(["buttslut", "cumslut", "submissive"]);
 			} else if (sisterAge === 3) {
-				slave.intelligence = 0;
+				slave.intelligence = random(-15, 15);
 				slave.hips = 2;
 				slave.face = jsEither([35, 35, 75, 75, 100]);
 				if (V.TFS.schoolUpgrade === 3 && V.TFS.compromiseWeek + 15 <= V.week) {
@@ -2048,15 +2079,11 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 				slave.lips = jsRandom(15, 25);
 				slave.weight = 20;
 				slave.waist = jsRandom(-30, 20);
-				slave.actualAge = jsRandom(30, 34);
-				slave.physicalAge = slave.actualAge;
-				slave.visualAge = slave.actualAge;
-				slave.ovaryAge = slave.actualAge;
 				slave.vagina = 2;
 				slave.anus = 2;
 				slave.fetish = jsEither(["buttslut", "cumslut"]);
 			} else if (sisterAge === 4) {
-				slave.intelligence = 30;
+				slave.intelligence = random(16, 50);
 				slave.hips = 2;
 				slave.face = jsEither([35, 75, 75, 100, 100]);
 				if (V.TFS.schoolUpgrade === 3 && V.TFS.compromiseWeek + 15 <= V.week) {
@@ -2080,15 +2107,11 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 				slave.lips = jsRandom(25, 55);
 				slave.weight = 20;
 				slave.waist = jsRandom(-30, 20);
-				slave.actualAge = jsRandom(35, 39);
-				slave.physicalAge = slave.actualAge;
-				slave.visualAge = slave.actualAge;
-				slave.ovaryAge = slave.actualAge;
 				slave.vagina = 3;
 				slave.anus = 3;
 				slave.fetish = jsEither(["buttslut", "cumslut", "dom"]);
 			} else {
-				slave.intelligence = 60;
+				slave.intelligence = random(51, 95);
 				slave.hips = 2;
 				slave.face = jsEither([35, 75, 100, 100, 100]);
 				if (V.TFS.schoolUpgrade === 3 && V.TFS.compromiseWeek + 15 <= V.week) {
@@ -2112,10 +2135,6 @@ globalThis.generateMarketSlave = function(market = "kidnappers", numArcology = 1
 				slave.lips = jsRandom(25, 55);
 				slave.weight = 50;
 				slave.waist = jsRandom(-50, 20);
-				slave.actualAge = jsRandom(40, 42);
-				slave.physicalAge = slave.actualAge;
-				slave.visualAge = slave.actualAge;
-				slave.ovaryAge = slave.actualAge;
 				slave.vagina = 3;
 				slave.anus = 3;
 				slave.fetish = "dom";
diff --git a/src/npc/generate/generateNewSlaveJS.js b/src/npc/generate/generateNewSlaveJS.js
index 7ce7bc3833a6df2ffacaceabba832784122418bc..691e0b754e72ccbf4a0d7039f7288f0488129ec1 100644
--- a/src/npc/generate/generateNewSlaveJS.js
+++ b/src/npc/generate/generateNewSlaveJS.js
@@ -1484,7 +1484,7 @@ globalThis.GenerateNewSlave = (function() {
 				slave.lips = jsRandom(5, 30);
 				slave.origSkin = jsEither(["pure black", "ebony", "black", "dark brown", "brown"]);
 				slave.origHColor = jsEither(["jet black", "black", "black", "black", "dark brown"]);
-				slave.hStyle = jsEither(["crinkled", "neat"]);
+				slave.hStyle = jsEither(["afro", "neat"]);
 				eyeColor(["brown"], true);
 				break;
 			case "white":
@@ -1553,7 +1553,7 @@ globalThis.GenerateNewSlave = (function() {
 				break;
 			case "catgirl":
 				slave.lips = jsRandom(5, 25);
-				slave.origSkin = jsEither(["white", "brown", "black", "red", "yellow", "black and white striped"]);
+				slave.origSkin = jsEither(App.Medicine.Modification.catgirlNaturalSkins);
 				slave.origHColor = jsEither(["black", "white", "golden", "red", "brown"]);
 				slave.hStyle = jsEither(["undercut", "neat"]);
 				slave.faceShape = "feline";
diff --git a/src/npc/generate/heroCreator.js b/src/npc/generate/heroCreator.js
index d7bbbce417ea74cc81f9db34e17f4852f665a07e..8c0c6cb7adeeed2dded23e8e9f866fc090ebbeda 100644
--- a/src/npc/generate/heroCreator.js
+++ b/src/npc/generate/heroCreator.js
@@ -88,7 +88,7 @@ App.Utils.getHeroSlave = function(heroSlave) {
 	}
 	generatePronouns(heroSlave);
 	if (heroSlave.geneMods === undefined) {
-		heroSlave.geneMods = {NCS: 0, rapidCellGrowth: 0, immortality: 0};
+		heroSlave.geneMods = {NCS: 0, rapidCellGrowth: 0, immortality: 0, bioEngineeredMilkFlavoring: 0};
 	}
 	if (heroSlave.geneMods.NCS === undefined) {
 		heroSlave.geneMods.NCS = 0;
@@ -99,6 +99,9 @@ App.Utils.getHeroSlave = function(heroSlave) {
 	if (heroSlave.geneMods.immortality === undefined) {
 		heroSlave.geneMods.immortality = 0;
 	}
+	if (heroSlave.geneMods.flavoring === undefined) {
+		heroSlave.geneMods.flavoring = 0;
+	}
 
 	// WombInit(heroSlave);
 	const newSlave = BaseSlave();
diff --git a/src/npc/generate/lawCompliance.js b/src/npc/generate/lawCompliance.js
index 1177cec825cc83fc49934fb50c6fe478936a34e8..c4018d3685061a6a854f125a0c8a67649e4a5e17 100644
--- a/src/npc/generate/lawCompliance.js
+++ b/src/npc/generate/lawCompliance.js
@@ -179,7 +179,7 @@ App.Desc.lawCompliance = function(slave, market = 0) {
 			slave.pregKnown = 1;
 			SetBellySize(slave);
 		}
-		return `If ${he} was unable to become pregnant before, ${he} has been made to now. ${He} is fertilized surgically to insure a healthy pregnancy.`;
+		return `If ${he} was unable to become pregnant before, ${he} has been made to now. ${He} is fertilized surgically to ensure a healthy pregnancy.`;
 	}
 
 	function FSAssetExpansionistSMR() {
@@ -190,9 +190,15 @@ App.Desc.lawCompliance = function(slave, market = 0) {
 		slave.lips = jsRandom(15, 55);
 		if (slave.dick > 0) {
 			slave.dick = jsRandom(4, 7);
+			if (slave.foreskin > 0) {
+				slave.foreskin = (slave.dick + either(-1, 0, 0));
+			}
 		}
 		if (slave.balls > 0) {
 			slave.balls = jsRandom(4, 7);
+			if (slave.scrotum > 0) {
+				slave.scrotum = (slave.balls + either(-1, 0, 0));
+			}
 		}
 		return `${He} has been on powerful growth hormones for a long time, and has experienced growth in several areas as a result.`;
 	}
diff --git a/src/npc/generate/newChildIntro.js b/src/npc/generate/newChildIntro.js
index b537b8e214fcd29fa4aa8920c97378ba0a94f58d..04f0ce1d96d0fa413c65c41a029d92b67b8891e9 100644
--- a/src/npc/generate/newChildIntro.js
+++ b/src/npc/generate/newChildIntro.js
@@ -104,7 +104,7 @@ App.UI.newChildIntro = function(slave) {
 			App.UI.DOM.link(
 				`Have your PA assign ${him} a random cat name`,
 				() => {
-					slave.slaveName = setup.catSlaveNames.random();
+					slave.slaveName = App.Data.misc.catSlaveNames.random();
 					slave.birthName = slave.slaveName;
 					jQuery(naming).empty().append(`${V.assistant.name} registers the new ${girl} as "${slave.slaveName}" in your registry.`);
 					jQuery(newName).empty().append(SlaveFullName(slave));
diff --git a/src/npc/generate/newSlaveIntro.js b/src/npc/generate/newSlaveIntro.js
index f1fce83dff362c39d0c9ae8b5b3c0c49672274de..8513da0032af949507d877e4a022a395d0f60d9c 100644
--- a/src/npc/generate/newSlaveIntro.js
+++ b/src/npc/generate/newSlaveIntro.js
@@ -877,8 +877,9 @@ App.UI.newSlaveIntro = function(slave, slave2, {tankBorn = false, momInterest =
 		}
 
 		if (slave.breedingMark === 1) {
-			el.append(`${He} knows ${his} duty in life and playfully splays ${himself} across your desk with ${his} legs spread wide. Unfortunately, ${he} must first be unwrapped before any breeding can begin, so for the time being, ${he} rights ${himself} and makes ${his} way to your crotch to show you just how much ${he} was worth the ¤.`);
-			actX(slave, "oral");
+			// TODO: this entire section is super weird and should be rewritten
+			// el.append(`${He} knows ${his} duty in life and playfully splays ${himself} across your desk with ${his} legs spread wide. Unfortunately, ${he} must first be unwrapped before any breeding can begin, so for the time being, ${he} rights ${himself} and makes ${his} way to your crotch to show you just how much ${he} was worth the ¤.`);
+			// actX(slave, "oral");
 		} else {
 			if (V.rulesAssistantAuto === 0) {
 				div = document.createElement("div");
@@ -1760,86 +1761,84 @@ App.UI.newSlaveIntro = function(slave, slave2, {tankBorn = false, momInterest =
 					});
 					break;
 				default:
-					if (typeof slave.origin === "string") {
-						if (slave.origin.includes("enslavement for the attempted rape of a free")) {
-							introText(`and since ${he} tried to rape you...`);
-							choice({
-								linkName: `Show ${him} how a professional does it`,
-								result: function(slave) {
-									const r = [];
-									r.push(`Judging from ${his} earlier, amateur attempt, it's clear ${slave.slaveName} is unfamiliar with the subtle nuances of a high-quality rape. You decide to clear your schedule for the rest of the day and teach ${him} yourself${PC.dick === 0 ? `, with the help of your trusty strap-on, of course` : ``}. Once ${he}'s bent over across your desk and properly restrained, ${his} lesson begins with you thrusting your`);
-									if (PC.dick === 0) {
-										r.push(`fake`);
+					if (slave.origin.includes("enslavement for the attempted rape of a free")) {
+						introText(`and since ${he} tried to rape you...`);
+						choice({
+							linkName: `Show ${him} how a professional does it`,
+							result: function(slave) {
+								const r = [];
+								r.push(`Judging from ${his} earlier, amateur attempt, it's clear ${slave.slaveName} is unfamiliar with the subtle nuances of a high-quality rape. You decide to clear your schedule for the rest of the day and teach ${him} yourself${PC.dick === 0 ? `, with the help of your trusty strap-on, of course` : ``}. Once ${he}'s bent over across your desk and properly restrained, ${his} lesson begins with you thrusting your`);
+								if (PC.dick === 0) {
+									r.push(`fake`);
+								}
+								r.push(`cock down ${his} throat as far as it will go. Over the course of the next several hours, you ensure that ${he} understands the fine points of nonconsensual oral${slave.vagina > -1 ? `, vaginal,` : ``} and anal intercourse as intimately as possible. When you're finally too tired to continue,you unshackle ${his} <span class="health dec">bruised and bloody body</span> and ask ${him} what ${he} learned. ${His} voice hoarse from the same brutal fucking that has gaped ${his} <span class="lime">asshole</span> ${(slave.vagina > -1) ? `and <span class="lime">pussy</span>` : ``}, ${he} hesitantly replies that ${he} has <span class="hotpink">learned a great deal about true dominance,</span> before fainting on the spot from a mixture of total exhaustion and pure terror. You've taught your student well.`);
+								actX(slave, "oral", 15);
+								slave.anus = 2;
+								actX(slave, "anal", 15);
+								if (slave.vagina > -1) {
+									slave.vagina = 2;
+									actX(slave, "vaginal", 15);
+								}
+								if (isFertile(slave) && PC.dick > 0) {
+									knockMeUp(slave, 100, 0, -1);
+								}
+								slave.devotion += 100;
+								return r.join(" ");
+							},
+
+						});
+						choice({
+							linkName: `Show ${him} that ${he} could have just asked`,
+							result: function(slave) {
+								const r = [];
+								r.push(`You tell ${slave.slaveName} that while ${his} previous attempt to fuck you was very flattering, ${he} should know that one can catch more flies with honey. Ordering the confused slave to lean back over and onto your desk, you proceed to gently`);
+								if (slave.dick > 0) {
+									r.push(`stroke`);
+								} else {
+									r.push(`finger`);
+								}
+								r.push(`${him} until ${his} arousal overwhelms ${his} wariness of you. Once ${he}'s finally relaxed, you climb on top of ${him}, and gently ease`);
+								if (PC.vagina > 0 && canPenetrate(slave)) {
+									r.push(`your pussy onto ${his} cock. ${He} shudders and moan softly as you slide yourself up and down ${his} shaft with steadily increasing speed. You keep your eyes locked on ${hers} all the while, as ${his} expression shifts from bewilderment to acceptance to ecstasy, as ${he} soon shoots ${his} seed up into you. Afterwards, you slip ${his} softening cock out of you, climb off of ${him}, and leave the exhausted and overwhelmed slave${girl} on your desk as you attend to business elsewhere. You think ${he}'s <span class="orangered">going to like it here.</span>`);
+									actX(slave, "penetrative");
+									if (canImpreg(V.PC, slave)) {
+										knockMeUp(V.PC, 100, 0, slave.ID);
 									}
-									r.push(`cock down ${his} throat as far as it will go. Over the course of the next several hours, you ensure that ${he} understands the fine points of nonconsensual oral${slave.vagina > -1 ? `, vaginal,` : ``} and anal intercourse as intimately as possible. When you're finally too tired to continue,you unshackle ${his} <span class="health dec">bruised and bloody body</span> and ask ${him} what ${he} learned. ${His} voice hoarse from the same brutal fucking that has gaped ${his} <span class="lime">asshole</span> ${(slave.vagina > -1) ? `and <span class="lime">pussy</span>` : ``}, ${he} hesitantly replies that ${he} has <span class="hotpink">learned a great deal about true dominance,</span> before fainting on the spot from a mixture of total exhaustion and pure terror. You've taught your student well.`);
-									actX(slave, "oral", 15);
-									slave.anus = 2;
-									actX(slave, "anal", 15);
+								} else {
+									r.push(`yourself into ${his}`);
 									if (slave.vagina > -1) {
-										slave.vagina = 2;
-										actX(slave, "vaginal", 15);
+										r.push(`pussy.`);
+									} else {
+										r.push(`asshole.`);
 									}
-									if (isFertile(slave) && PC.dick > 0) {
-										knockMeUp(slave, 100, 0, -1);
+									r.push(`${He} shudders and moans softly as you piston your`);
+									if (PC.dick > 0) {
+										r.push(`dick`);
+									} else {
+										r.push(`strap-on`);
 									}
-									slave.devotion += 100;
-									return r.join(" ");
-								},
-
-							});
-							choice({
-								linkName: `Show ${him} that ${he} could have just asked`,
-								result: function(slave) {
-									const r = [];
-									r.push(`You tell ${slave.slaveName} that while ${his} previous attempt to fuck you was very flattering, ${he} should know that one can catch more flies with honey. Ordering the confused slave to lean back over and onto your desk, you proceed to gently`);
-									if (slave.dick > 0) {
-										r.push(`stroke`);
+									r.push(`in and out of ${his} hole with steadily increasing intensity. You keep your eyes locked on ${hers} all the while, as ${his} expression shifts from bewilderment to acceptance to ecstasy, as you soon shoot your seed down into ${him}. Afterwards, you slip your`);
+									if (PC.dick > 0) {
+										r.push(`softening`);
 									} else {
-										r.push(`finger`);
+										r.push(`plastic`);
 									}
-									r.push(`${him} until ${his} arousal overwhelms ${his} wariness of you. Once ${he}'s finally relaxed, you climb on top of ${him}, and gently ease`);
-									if (PC.vagina > 0 && canPenetrate(slave)) {
-										r.push(`your pussy onto ${his} cock. ${He} shudders and moan softly as you slide yourself up and down ${his} shaft with steadily increasing speed. You keep your eyes locked on ${hers} all the while, as ${his} expression shifts from bewilderment to acceptance to ecstasy, as ${he} soon shoots ${his} seed up into you. Afterwards, you slip ${his} softening cock out of you, climb off of ${him}, and leave the exhausted and overwhelmed slave${girl} on your desk as you attend to business elsewhere. You think ${he}'s <span class="orangered">going to like it here.</span>`);
-										actX(slave, "penetrative");
-										if (canImpreg(V.PC, slave)) {
-											knockMeUp(V.PC, 100, 0, slave.ID);
+									r.push(`cock out of ${him}, climb off of ${him}, and leave the exhausted and overwhelmed slave${girl} on your desk as you attend to business elsewhere. You think ${he}'s <span class="orangered">going to like it here.</span>`);
+									if (slave.vagina > -1) {
+										r.push(VCheck.Vaginal(slave, 1));
+										actX(slave, "vaginal");
+										if (isFertile(slave) && PC.dick > 0) {
+											knockMeUp(slave, 100, 0, -1);
 										}
 									} else {
-										r.push(`yourself into ${his}`);
-										if (slave.vagina > -1) {
-											r.push(`pussy.`);
-										} else {
-											r.push(`asshole.`);
-										}
-										r.push(`${He} shudders and moans softly as you piston your`);
-										if (PC.dick > 0) {
-											r.push(`dick`);
-										} else {
-											r.push(`strap-on`);
-										}
-										r.push(`in and out of ${his} hole with steadily increasing intensity. You keep your eyes locked on ${hers} all the while, as ${his} expression shifts from bewilderment to acceptance to ecstasy, as you soon shoot your seed down into ${him}. Afterwards, you slip your`);
-										if (PC.dick > 0) {
-											r.push(`softening`);
-										} else {
-											r.push(`plastic`);
-										}
-										r.push(`cock out of ${him}, climb off of ${him}, and leave the exhausted and overwhelmed slave${girl} on your desk as you attend to business elsewhere. You think ${he}'s <span class="orangered">going to like it here.</span>`);
-										if (slave.vagina > -1) {
-											r.push(VCheck.Vaginal(slave, 1));
-											actX(slave, "vaginal");
-											if (isFertile(slave) && PC.dick > 0) {
-												knockMeUp(slave, 100, 0, -1);
-											}
-										} else {
-											r.push(VCheck.Anal(slave, 1));
-											actX(slave, "anal");
-										}
+										r.push(VCheck.Anal(slave, 1));
+										actX(slave, "anal");
 									}
-									slave.trust += 100;
-									return r.join(" ");
-								},
-							});
-						}
+								}
+								slave.trust += 100;
+								return r.join(" ");
+							},
+						});
 					}
 			}
 
@@ -2486,7 +2485,13 @@ App.UI.newSlaveIntro = function(slave, slave2, {tankBorn = false, momInterest =
 										r.push(`<span class="green">${He}'s a breast fetishist!</span>`);
 										slave.fetishKnown = 1;
 									} else {
-										r.push(`You kneel behind ${him} and begin to gently massage ${his} swollen breasts. A steady stream of milk begins to erupt from each nipple. The sensation overwhelms ${him} almost immediately, and ${his} arms struggle against ${his} restraints as ${he} fights an impending orgasm. It's an amusing sight that goes on until ${he} is fully drained.`);
+										r.push(`You kneel behind ${him} and begin to gently massage ${his} swollen breasts. A steady stream of milk begins to erupt from each nipple. The sensation overwhelms ${him} almost immediately, and ${his}`);
+										if (hasBothArms(slave)) {
+											r.push(`arms struggle`);
+										} else {
+											r.push(`body struggles`);
+										}
+										r.push(`against ${his} restraints as ${he} fights an impending orgasm. It's an amusing sight that goes on until ${he} is fully drained.`);
 										r.push(`<span class="green">${He}'s a breast fetishist!</span>`);
 										slave.fetishKnown = 1;
 									}
@@ -3306,13 +3311,7 @@ App.UI.newSlaveIntro = function(slave, slave2, {tankBorn = false, momInterest =
 									slave.fetish = "dom";
 									slave.fetishStrength = 20;
 								}
-								if (canPenetrate(slave)) {
-									slave.counter.penetrative++;
-									V.penetrativeTotal++;
-								} else {
-									slave.counter.oral++;
-									V.oralTotal++;
-								}
+								seX(slave, canPenetrate(slave) ? "penetrative" : "oral", "slaves");
 							} else {
 								r.push(`scream of pain from the bound ${girlU}. Looking up, you see ${slave.slaveName}`);
 								if (canPenetrate(slave)) {
@@ -3326,8 +3325,7 @@ App.UI.newSlaveIntro = function(slave, slave2, {tankBorn = false, momInterest =
 									slave.fetishStrength = 20;
 								}
 								if (canPenetrate(slave)) {
-									slave.counter.penetrative++;
-									V.penetrativeTotal++;
+									seX(slave, "penetrative", "slaves");
 								}
 							}
 							slave.devotion += 4;
@@ -4039,7 +4037,7 @@ App.UI.newSlaveIntro = function(slave, slave2, {tankBorn = false, momInterest =
 					});
 				}
 			}
-			// CLOSES MINDBROKEN CHECK
+
 			lineBreak();
 			choice({
 				linkName: `Spank ${him}`,
@@ -4799,9 +4797,10 @@ App.UI.newSlaveIntro = function(slave, slave2, {tankBorn = false, momInterest =
 					(V.arcologies[0].FSSubjugationist !== "unset" && slave.race === V.arcologies[0].FSSubjugationistRace)
 				)
 			) {
-				slave.brand[brandTarget] = V.brandDesign.secondary; // Slur made no sense, use the backup
+				// Slur made no sense, use the backup
+				App.Medicine.Modification.addBrand(slave, brandTarget, V.brandDesign.secondary);
 			} else {
-				slave.brand[brandTarget] = V.brandDesign.primary;
+				App.Medicine.Modification.addBrand(slave, brandTarget, V.brandDesign.primary);
 			}
 			slave.devotion -= 5;
 			slave.trust -= 10;
diff --git a/src/npc/infants/infantSummary.js b/src/npc/infants/infantSummary.js
index e17f68532a9df9f92742633ea7a2d1f7b02e1122..2171b9167e231e9a4f031cd728972f7b5775eee6 100644
--- a/src/npc/infants/infantSummary.js
+++ b/src/npc/infants/infantSummary.js
@@ -46,7 +46,7 @@ App.Facilities.Nursery.InfantSummary = function(child) {
 
 		r += `&nbsp;&nbsp;&nbsp;&nbsp;`;
 
-		if (abbreviate.origins === 2 && child.origin !== 0) {
+		if (abbreviate.origins === 2 && child.origin !== "") {
 			r += origins();
 		}
 
diff --git a/src/npc/interaction/FFuckdollAnal.js b/src/npc/interaction/FFuckdollAnal.js
index ee8968d3ee4b2204ac2a24c1019883b598b42fa3..550fc70058c1096da62273c8d01b4816e4f7ef10 100644
--- a/src/npc/interaction/FFuckdollAnal.js
+++ b/src/npc/interaction/FFuckdollAnal.js
@@ -12,8 +12,6 @@ App.Interact.fFuckdollAnal = function(slave) {
 		he, his, him
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
-
 	seX(slave, "anal", V.PC, "penetrative");
 	r.push(`You decide to use the Fuckdoll's`);
 	if (slave.anus > 3) {
diff --git a/src/npc/interaction/FFuckdollImpreg.js b/src/npc/interaction/FFuckdollImpreg.js
index 7ae1839ac119d210da994225ab9de9466a305637..e1a288bd003058658c1bdac2847d6d0d39888eb2 100644
--- a/src/npc/interaction/FFuckdollImpreg.js
+++ b/src/npc/interaction/FFuckdollImpreg.js
@@ -12,14 +12,12 @@ App.Interact.fFuckdollImpreg = function(slave) {
 		he, his, him
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
 	const bonus = random(6, 20);
+	seX(slave, slave.mpreg ? "anal" : 'vaginal', V.PC, "penetrative", bonus + 1);
 
 	if (slave.mpreg === 1) {
-		slave.counter.anal += bonus + 1;
 		V.analTotal += bonus + 1;
 	} else {
-		slave.counter.vaginal += bonus + 1;
 		V.vaginalTotal += bonus + 1;
 	}
 
diff --git a/src/npc/interaction/FFuckdollOral.js b/src/npc/interaction/FFuckdollOral.js
index 6ea7b81106c0a8a205cb154e75ab682d4d3c80d1..b1a207dbea44589c6a866ec01c9a59b544e543af 100644
--- a/src/npc/interaction/FFuckdollOral.js
+++ b/src/npc/interaction/FFuckdollOral.js
@@ -12,8 +12,6 @@ App.Interact.fFuckdollOral = function(slave) {
 		he, his, him
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
-
 	seX(slave, "oral", V.PC, "penetrative");
 	r.push(`You decide to use the Fuckdoll's`);
 	if (slave.lips > 95) {
diff --git a/src/npc/interaction/FFuckdollVaginal.js b/src/npc/interaction/FFuckdollVaginal.js
index a4ad469a6d21bb78d11fd56989d9dc91f0b00413..57202af5626dfabdfa14ea29c1193c245512201e 100644
--- a/src/npc/interaction/FFuckdollVaginal.js
+++ b/src/npc/interaction/FFuckdollVaginal.js
@@ -12,8 +12,6 @@ App.Interact.fFuckdollVaginal = function(slave) {
 		he, his, him
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
-
 	seX(slave, "vaginal", V.PC, "penetrative");
 	r.push(`You decide to use the Fuckdoll's`);
 	if (slave.vagina > 3) {
diff --git a/src/npc/interaction/FSuckle.js b/src/npc/interaction/FSuckle.js
index a59ba0ff2e02ef3b8caf1a620d0468142c9d76ea..7ea15f6099556f1145b2af2808851bec87cad7b1 100644
--- a/src/npc/interaction/FSuckle.js
+++ b/src/npc/interaction/FSuckle.js
@@ -12,8 +12,6 @@ App.Interact.fSuckle = function(slave) {
 		he, his, him, himself
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
-
 	seX(slave, "mammary", V.PC, "oral");
 	let mood;
 	if (V.PC.pregMood === 0 || V.PC.preg < 28) {
@@ -606,11 +604,7 @@ App.Interact.fSuckle = function(slave) {
 	} else if (mood === 1) {
 		r.push(`You can only hope ${he}'ll return the favor when you yourself become too heavy with milk.`);
 	} else if (V.PC.preg > 30) {
-		r.push(`You know that you'll soon have your own child`);
-		if (V.PC.pregType > 1) {
-			r.push(`ren`);
-		}
-		r.push(`to share this feeling with and deep down, you hope to enjoy it just as much as ${he} does.`);
+		r.push(`You know that you'll soon have your own ${onlyPlural(V.PC.pregType, 'child', 'children')} to share this feeling with and deep down, you hope to enjoy it just as much as ${he} does.`);
 	}
 
 	if (slave.boobs >= 20000) {
@@ -694,11 +688,7 @@ App.Interact.fSuckle = function(slave) {
 	} else if (mood === 1) {
 		r.push(`You cuddle up against ${him}, holding close to ${him} as you snooze off your milky meal.`);
 		if (slave.fetish === "mindbroken") {
-			r.push(`${He} struggles in discomfort at your pregnant weight pinning ${him} down until ${he} manages to rouse your child`);
-			if (V.PC.pregType > 1) {
-				r.push(`ren`);
-			}
-			r.push(`and get you to move.`);
+			r.push(`${He} struggles in discomfort at your pregnant weight pinning ${him} down until ${he} manages to rouse your ${onlyPlural(V.PC.pregType, 'child', 'children')} and get you to move.`);
 		} else if (slave.devotion > 20 && slave.trust > 20) {
 			r.push(`${He} holds you close, gently caressing your head and pregnancy as you rest it off.`);
 		} else if (slave.trust < -20) {
diff --git a/src/npc/interaction/fAnimal.js b/src/npc/interaction/fAnimal.js
index 496b3f5269af3b32331d17af272fad2f209d2b4a..f209b35b617ed988af706f4c714c0bfcbc2bdfba 100644
--- a/src/npc/interaction/fAnimal.js
+++ b/src/npc/interaction/fAnimal.js
@@ -1,9 +1,10 @@
 /**
  * @param {App.Entity.SlaveState} slave
  * @param {"canine"|"hooved"|"feline"} type
+ * @param {FC.SlaveActs} act
  * @returns {DocumentFragment}
  */
-App.Interact.fAnimal = function(slave, type) {
+App.Interact.fAnimal = function(slave, type, act) {
 	const frag = new DocumentFragment();
 
 	const {
@@ -18,9 +19,6 @@ App.Interact.fAnimal = function(slave, type) {
 		ORAL: "oral",
 	};
 
-	/** @type {FC.SlaveActs} */
-	let act;
-
 	const approvingFetishes = ["masochist", "humiliation", "perverted", "sinful"];	// not strictly fetishes, but approvingFetishesAndBehavioralQuirksAndSexualQuirks doesn't have the same ring to it
 
 	/** @type {App.Entity.Animal} */
@@ -28,12 +26,14 @@ App.Interact.fAnimal = function(slave, type) {
 
 	/** @type {0|1|2} */
 	let hole;
+	/** @type {string} */
 	let fetishDesc;
+	/** @type {() => string} */
 	let orifice;
 
 	const anAnimal = `${animal.articleAn} ${animal.name}`;
 
-	if (slave.assignment === Job.FUCKTOY || slave.assignment === Job.MASTERSUITE) {
+	if ([Job.FUCKTOY, Job.MASTERSUITE].includes(slave.assignment)) {
 		if (slave.toyHole === "pussy") {
 			act = "vaginal";
 		} else if (slave.toyHole === "ass") {
@@ -101,387 +101,422 @@ App.Interact.fAnimal = function(slave, type) {
 
 	const text = new SpacedTextAccumulator(frag);
 
-	if (canWalk(slave)) {
-		text.push(`You call ${him} over and`);
-	} else {
-		text.push(`You order another slave to bring ${slave.slaveName} over. Once ${he} is situated, you`);
+	text.push(
+		intro(),
+		setup(),
+		consummation(),
+	);
+
+	if (act === Acts.VAGINAL) {
+		slave.vagina = Math.max(slave.vagina, animal.dick.size);
+	} else if (act === Acts.ANAL) {
+		// @ts-ignore
+		slave.anus = Math.max(slave.anus, stretchedAnusSize(animal.dick.size));
 	}
 
-	text.push(`tell ${him} you want to watch ${him} ${act === Acts.ORAL
-		? `suck off`
-		: act === Acts.VAGINAL
-			? `get fucked by`
-			: `get fucked in the ass by`} ${anAnimal}.`);
+	if (act !== Acts.ORAL && canGetPregnant(slave) && canBreed(slave, animal)) {
+		knockMeUp(slave, 5, hole, -8);
+	}
 
-	if (slave.fetish === "mindbroken") {
-		text.push(`${slave.slaveName} nods ${his} head dumbly, ${his} eyes vacant${!canSee(slave) ? ` as always` : ``}.`);
+	if (random(1, 100) > 100 + slave.devotion && slave.energy < 95) {
+		text.push(slaveGainsFlaw());
+	} else if (slave.devotion > 20) {
+		text.push(slaveGainsQuirk());
 	}
 
-	if (slave.fetish !== "mindbroken") {
-		if (slave.devotion > 50) {
-			if (act === Acts.ORAL) {
-				if (slaveApproves) {
-					text.push(`${slave.slaveName}'s face visibly brightens at the prospect of ${fetishDesc}, even if it's an animal${slave.fetish === "cumslut" ? `'s cum` : ` that ${he} has to suck off`}.`);
-				} else {
-					text.push(`${slave.slaveName} visibly blanches at the thought of having to suck down an animal's cum, but ${he} is so devoted to you that ${he} reluctantly agrees.`);
-				}
-			} else {
-				if ((act === Acts.VAGINAL && slave.vagina > 0) ||
-					(act === Acts.ANAL && slave.anus > 0)) {
+	if (V.postSexCleanUp) {
+		text.push(cleanup());
+	}
+
+	text.toParagraph();
+
+	return frag;
+
+	// Text Functions
+
+	function intro() {
+		const text = [];
+
+		if (canWalk(slave)) {
+			text.push(`You call ${him} over and`);
+		} else {
+			text.push(`You order another slave to bring ${slave.slaveName} over. Once ${he} is situated, you`);
+		}
+
+		text.push(`tell ${him} you want to watch ${him} ${act === Acts.ORAL
+			? `suck off`
+			: act === Acts.VAGINAL
+				? `get fucked by`
+				: `get fucked in the ass by`} ${anAnimal}.`);
+
+		if (slave.fetish === "mindbroken") {
+			text.push(`${slave.slaveName} nods ${his} head dumbly, ${his} eyes vacant${!canSee(slave) ? ` as always` : ``}.`);
+		} else {
+			if (slave.devotion > 50) {
+				if (act === Acts.ORAL) {
 					if (slaveApproves) {
-						text.push(`${slave.slaveName}'s face visibly brightens at the thought of ${fetishDesc}, even if the dick is an animal's.`);
+						text.push(`${slave.slaveName}'s face visibly brightens at the prospect of ${fetishDesc}, even if it's an animal${slave.fetish === "cumslut" ? `'s cum` : ` that ${he} has to suck off`}.`);
 					} else {
-						text.push(`${slave.slaveName} looks visibly disturbed, but is so attentive to your will that ${he} agrees.`);
+						text.push(`${slave.slaveName} visibly blanches at the thought of having to suck down an animal's cum, but ${he} is so devoted to you that ${he} reluctantly agrees.`);
 					}
 				} else {
-					if (slaveApproves) {
-						text.push(`${slave.slaveName}'s face visibly brightens at the thought of ${fetishDesc}, although ${he} seems a bit hesitant at the thought of giving ${his} virginity to an animal.`);
+					if ((act === Acts.VAGINAL && slave.vagina > 0) ||
+						(act === Acts.ANAL && slave.anus > 0)) {
+						if (slaveApproves) {
+							text.push(`${slave.slaveName}'s face visibly brightens at the thought of ${fetishDesc}, even if the dick is an animal's.`);
+						} else {
+							text.push(`${slave.slaveName} looks visibly disturbed, but is so attentive to your will that ${he} agrees.`);
+						}
 					} else {
-						text.push(`${slave.slaveName} looks visibly shaken at the thought of having ${his} precious ${!canDoVaginal(slave) ? `anal ` : ``}virginity taken by an animal, but is so attentive to your will that ${he} ultimately agrees.`);
+						if (slaveApproves) {
+							text.push(`${slave.slaveName}'s face visibly brightens at the thought of ${fetishDesc}, although ${he} seems a bit hesitant at the thought of giving ${his} virginity to an animal.`);
+						} else {
+							text.push(`${slave.slaveName} looks visibly shaken at the thought of having ${his} precious ${!canDoVaginal(slave) ? `anal ` : ``}virginity taken by an animal, but is so attentive to your will that ${he} ultimately agrees.`);
+						}
 					}
 				}
-			}
-		} else if (slave.devotion > 20) {
-			if (act === Acts.ORAL) {
-				if (slaveApproves) {
-					text.push(`${slave.slaveName} isn't too keen on the idea of sucking off an animal, but the idea of ${fetishDesc} is enough to get ${him} to comply.`);
-				} else {
-					text.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of blowing an animal, but quickly regains ${his} composure.`);
-				}
-			} else {
-				if (
-					(act === Acts.VAGINAL && slave.vagina > 0) ||
-						(act === Acts.ANAL && slave.anus > 0)
-				) {
+			} else if (slave.devotion > 20) {
+				if (act === Acts.ORAL) {
 					if (slaveApproves) {
-						text.push(`${slave.slaveName} doesn't seem terribly keen on the idea of fucking an animal, but the thought of ${fetishDesc} seems to be enough to win ${him} over.`);
+						text.push(`${slave.slaveName} isn't too keen on the idea of sucking off an animal, but the idea of ${fetishDesc} is enough to get ${him} to comply.`);
 					} else {
-						text.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of fucking an animal, but quickly regains ${his} composure.`);
+						text.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of blowing an animal, but quickly regains ${his} composure.`);
 					}
 				} else {
-					if (slaveApproves) {
-						text.push(`${slave.slaveName} clearly has some reservations about having ${his} ${act === Acts.ANAL ? `anal ` : ``}virginity taken by ${anAnimal}, but the thought of ${fetishDesc} is enough to make agree to comply.`);
+					if (
+						(act === Acts.VAGINAL && slave.vagina > 0) ||
+							(act === Acts.ANAL && slave.anus > 0)
+					) {
+						if (slaveApproves) {
+							text.push(`${slave.slaveName} doesn't seem terribly keen on the idea of fucking an animal, but the thought of ${fetishDesc} seems to be enough to win ${him} over.`);
+						} else {
+							text.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of fucking an animal, but quickly regains ${his} composure.`);
+						}
 					} else {
-						text.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of having ${his} precious ${act === Acts.ANAL ? `rosebud` : `pearl`} taken by a beast, but quickly regains ${his} composure.`);
+						if (slaveApproves) {
+							text.push(`${slave.slaveName} clearly has some reservations about having ${his} ${act === Acts.ANAL ? `anal ` : ``}virginity taken by ${anAnimal}, but the thought of ${fetishDesc} is enough to make agree to comply.`);
+						} else {
+							text.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of having ${his} precious ${act === Acts.ANAL ? `rosebud` : `pearl`} taken by a beast, but quickly regains ${his} composure.`);
+						}
 					}
 				}
-			}
-		} else if (slave.devotion >= -20) {
-			if (act === Acts.ORAL) {
-				if (slaveApproves) {
-					text.push(`${slave.slaveName} looks disgusted at the thought of sucking off an animal at first, but the thought of the ${fetishDesc} that comes with it seems to spark a small flame of lust in ${him}.`);
-				} else {
-					text.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of blowing an animal${canWalk(slave) ? `, and only the threat of worse punishment keeps ${him} from running away as fast as ${he} can` : ``}.`);
-				}
-			} else {
-				if ((act === Acts.VAGINAL && slave.vagina > 0) || (act === Acts.ANAL && slave.anus > 0)) {
+			} else if (slave.devotion >= -20) {
+				if (act === Acts.ORAL) {
 					if (slaveApproves) {
-						text.push(`${slave.slaveName} looks disgusted at the thought of fucking an animal at first, but the thought of the ${fetishDesc} that comes with it seems to spark a small flame of lust in ${him}.`);
+						text.push(`${slave.slaveName} looks disgusted at the thought of sucking off an animal at first, but the thought of the ${fetishDesc} that comes with it seems to spark a small flame of lust in ${him}.`);
 					} else {
-						text.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of fucking an animal${canWalk(slave) ? `, and only the threat of worse punishment keeps ${him} from running away as fast as ${he} can` : ``}.`);
+						text.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of blowing an animal${canWalk(slave) ? `, and only the threat of worse punishment keeps ${him} from running away as fast as ${he} can` : ``}.`);
 					}
 				} else {
-					if (slaveApproves) {
-						text.push(`${slave.slaveName} clearly has some reservations about having ${his} ${act === Acts.ANAL ? `anal ` : ``}virginity taken by ${anAnimal}, but the thought of ${fetishDesc} is enough to make agree to comply.`);
+					if ((act === Acts.VAGINAL && slave.vagina > 0) || (act === Acts.ANAL && slave.anus > 0)) {
+						if (slaveApproves) {
+							text.push(`${slave.slaveName} looks disgusted at the thought of fucking an animal at first, but the thought of the ${fetishDesc} that comes with it seems to spark a small flame of lust in ${him}.`);
+						} else {
+							text.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of fucking an animal${canWalk(slave) ? `, and only the threat of worse punishment keeps ${him} from running away as fast as ${he} can` : ``}.`);
+						}
 					} else {
-						text.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of having ${his} precious ${act === Acts.ANAL ? `rosebud` : `pearl`} taken by a beast${canWalk(slave) ? `, and only the threat of worse punishment keeps ${him} from running away as fast as ${he} can` : ``}.`);
+						if (slaveApproves) {
+							text.push(`${slave.slaveName} clearly has some reservations about having ${his} ${act === Acts.ANAL ? `anal ` : ``}virginity taken by ${anAnimal}, but the thought of ${fetishDesc} is enough to make agree to comply.`);
+						} else {
+							text.push(`${slave.slaveName} tries in vain to conceal ${his} horror at the thought of having ${his} precious ${act === Acts.ANAL ? `rosebud` : `pearl`} taken by a beast${canWalk(slave) ? `, and only the threat of worse punishment keeps ${him} from running away as fast as ${he} can` : ``}.`);
+						}
 					}
 				}
+			} else {
+				text.push(`${slave.slaveName}'s face contorts into a mixture of ${slave.devotion < -50 ? `hatred, anger, and disgust` : `anger and disgust`}, ${canWalk(slave)
+					? `and only the threat of far worse punishment is enough to prevent ${him} from running out of the room`
+					: `but ${he} knows ${he} is powerless to stop you`}.`);
 			}
-		} else {
-			text.push(`${slave.slaveName}'s face contorts into a mixture of ${slave.devotion < -50 ? `hatred, anger, and disgust` : `anger and disgust`}, ${canWalk(slave)
-				? `and only the threat of far worse punishment is enough to prevent ${him} from running out of the room`
-				: `but ${he} knows ${he} is powerless to stop you`}.`);
 		}
+
+		return text.join(' ');
 	}
 
-	if (slave.devotion > 50) {
-		if (act === Acts.ORAL) {
-			text.push(`You have ${him} kneel on the floor before calling in the ${animal.name}. The beast slowly saunters up to the slave where ${he} waits, showing little concern when the slave reaches out and begins masturbating it to begin the process of getting the animal hard. Once the ${animal.name} is hard enough, ${slave.slaveName} takes its cock and begins to give it a few tentative licks before finally putting it in ${his} mouth.`);
-		} else {
-			text.push(`You have ${him} ${App.Data.clothes.get(slave.clothes).exposure <= 3 ? `take off ${his} clothes and ` : ``}get on the floor, ass in the air, before calling in the ${animal.name}. The beast slowly saunters up to the slave, where it takes only a few short moments for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
-		}
+	function setup() {
+		const text = [];
 
-		switch (animal.name) {
-			case V.active.canine:
-				if (type === Acts.ORAL) {
-					if (slaveApproves) {
-						text.push(`The slave seems to quickly get over the fact that the dick currently in ${his} mouth belongs to a canine as ${his} more carnal desires kick in.`);
-					} else {
-						text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, then gives a groan as the beast thrusts, filling ${his} throat.`);
-					}
-				} else {
-					if (canWalk(slave)) {
-						text.push(`The canine clambers up to mount ${slave.slaveName}, eliciting a squeal from the ${girl} as its claws dig into ${his} flesh.`);
+		if (slave.devotion > 50) {
+			if (act === Acts.ORAL) {
+				text.push(`You have ${him} kneel on the floor before calling in the ${animal.name}. The beast slowly saunters up to the slave where ${he} waits, showing little concern when the slave reaches out and begins masturbating it to begin the process of getting the animal hard. Once the ${animal.name} is hard enough, ${slave.slaveName} takes its cock and begins to give it a few tentative licks before finally putting it in ${his} mouth.`);
+			} else {
+				text.push(`You have ${him} ${App.Data.clothes.get(slave.clothes).exposure <= 3 ? `take off ${his} clothes and ` : ``}get on the floor, ass in the air, before calling in the ${animal.name}. The beast slowly saunters up to the slave, where it takes only a few short moments for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
+			}
+
+			switch (animal.name) {
+				case V.active.canine:
+					if (type === Acts.ORAL) {
+						if (slaveApproves) {
+							text.push(`The slave seems to quickly get over the fact that the dick currently in ${his} mouth belongs to a canine as ${his} more carnal desires kick in.`);
+						} else {
+							text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, then gives a groan as the beast thrusts, filling ${his} throat.`);
+						}
 					} else {
-						text.push(`The canine takes a few curious sniffs, then lines up its large cock with ${slave.slaveName}'s ${orifice()}.`);
-					}
+						if (canWalk(slave)) {
+							text.push(`The canine clambers up to mount ${slave.slaveName}, eliciting a squeal from the ${girl} as its claws dig into ${his} flesh.`);
+						} else {
+							text.push(`The canine takes a few curious sniffs, then lines up its large cock with ${slave.slaveName}'s ${orifice()}.`);
+						}
 
-					text.push(`It takes a few tries, but the ${animal.name} finally manages to sink its cock into ${his} ${slaveApproves && act === Acts.VAGINAL ? `wet ` : ``}${orifice()}.`);
-				}
-				break;
-			case V.active.hooved:
-				if (type === Acts.ORAL) {
-					if (slaveApproves) {
-						text.push(`The slave seems to quickly get over the fact that dick currently in ${his} mouth is not a human one as ${his} more carnal desires kick in.`);
+						text.push(`It takes a few tries, but the ${animal.name} finally manages to sink its cock into ${his} ${slaveApproves && act === Acts.VAGINAL ? `wet ` : ``}${orifice()}.`);
+					}
+					break;
+				case V.active.hooved:
+					if (type === Acts.ORAL) {
+						if (slaveApproves) {
+							text.push(`The slave seems to quickly get over the fact that dick currently in ${his} mouth is not a human one as ${his} more carnal desires kick in.`);
+						} else {
+							text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, then gives a groan as the beast thrusts, stretching ${his} poor throat to the limit.`);
+						}
 					} else {
-						text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, then gives a groan as the beast thrusts, stretching ${his} poor throat to the limit.`);
+						text.push(`${slave.slaveName} gives a long, drawn-out moan as the huge phallus `, slave.vagina < 4 ? `<span class="change positive">stretches</span>` : `fills`, ` ${his} ${orifice()} nearly to its breaking point.`);
 					}
-				} else {
-					text.push(`${slave.slaveName} gives a long, drawn-out moan as the huge phallus `, slave.vagina < 4 ? `<span class="change positive">stretches</span>` : `fills`, ` ${his} ${orifice()} nearly to its breaking point.`);
-				}
-				break;
-			case V.active.feline:
-				if (type === Acts.ORAL) {
-					if (slaveApproves) {
-						text.push(`The slave seems to quickly get over the fact that dick currently in ${his} mouth belongs to ${anAnimal} as ${his} more carnal desires kick in.`);
+					break;
+				case V.active.feline:
+					if (type === Acts.ORAL) {
+						if (slaveApproves) {
+							text.push(`The slave seems to quickly get over the fact that dick currently in ${his} mouth belongs to ${anAnimal} as ${his} more carnal desires kick in.`);
+						} else {
+							text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, then gives a groan as the beast thrusts, the barbs on its cock rubbing the inside of ${his} mouth raw.`);
+						}
 					} else {
-						text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, then gives a groan as the beast thrusts, the barbs on its cock rubbing the inside of ${his} mouth raw.`);
+						text.push(`${slave.slaveName} gives a squeal of pain as the barbed cock makes its way into ${his} ${orifice()}.`);
 					}
-				} else {
-					text.push(`${slave.slaveName} gives a squeal of pain as the barbed cock makes its way into ${his} ${orifice()}.`);
-				}
-				break;
-			default:
-				throw new Error(`Unexpected animal type '${animal}' in fAnimal()`);
-		}
+					break;
+				default:
+					throw new Error(`Unexpected animal type '${animal}' in fAnimal()`);
+			}
 
-		if (act !== Acts.ORAL) {
-			text.push(virginityCheck(act));
-		}
-	} else if (slave.devotion > 20) {
-		if (act === Acts.ORAL) {
-			text.push(`You tell ${him} to kneel on the floor before calling in the ${animal.name}. The beast slowly saunters up to the slave where ${he} waits, showing little concern when the slave hesitantly reaches out and begins masturbating it to begin the process of getting the animal hard. Once the ${animal.name} is hard enough, ${slave.slaveName} takes its cock, and, after taking a moment to steel ${his} resolve, begins to give it a few reluctant licks before putting it in ${his} mouth.`);
-		} else {
-			text.push(`You tell ${him} to ${App.Data.clothes.get(slave.clothes).exposure <= 3 ? `take off ${his} clothes and ` : ``}get on the floor, ass in the air, before calling in the ${animal.name}. The beast slowly saunters up to the slave, where it takes only a few seconds for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
-		}
+			if (act !== Acts.ORAL) {
+				text.push(virginityCheck(act));
+			}
+		} else if (slave.devotion > 20) {
+			if (act === Acts.ORAL) {
+				text.push(`You tell ${him} to kneel on the floor before calling in the ${animal.name}. The beast slowly saunters up to the slave where ${he} waits, showing little concern when the slave hesitantly reaches out and begins masturbating it to begin the process of getting the animal hard. Once the ${animal.name} is hard enough, ${slave.slaveName} takes its cock, and, after taking a moment to steel ${his} resolve, begins to give it a few reluctant licks before putting it in ${his} mouth.`);
+			} else {
+				text.push(`You tell ${him} to ${App.Data.clothes.get(slave.clothes).exposure <= 3 ? `take off ${his} clothes and ` : ``}get on the floor, ass in the air, before calling in the ${animal.name}. The beast slowly saunters up to the slave, where it takes only a few seconds for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
+			}
 
-		switch (animal.name) {
-			case V.active.canine:
-				if (type === Acts.ORAL) {
-					if (slaveApproves) {
-						text.push(`Though the slave still seems to have some reservations about sucking off an animal, ${he} seems to forget that the cock in ${his} mouth belongs to ${anAnimal} soon enough, once ${his} carnal desires kick in.`);
+			switch (animal.name) {
+				case V.active.canine:
+					if (type === Acts.ORAL) {
+						if (slaveApproves) {
+							text.push(`Though the slave still seems to have some reservations about sucking off an animal, ${he} seems to forget that the cock in ${his} mouth belongs to ${anAnimal} soon enough, once ${his} carnal desires kick in.`);
+						} else {
+							text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+						}
 					} else {
-						text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+						if (canWalk(slave)) {
+							text.push(`The canine clambers up to mount ${slave.slaveName}, eliciting a squeal from the ${girl} as its claws dig into ${his} flesh.`);
+						} else {
+							text.push(`The canine takes a few curious sniffs, then lines up its large cock with ${slave.slaveName}'s ${orifice()}.`);
+						}
+
+						text.push(`It takes a few tries, but the ${animal.name} finally manages to sink its cock into ${his} ${slaveApproves && act === Acts.VAGINAL ? `wet ` : ``}${orifice()}.`);
 					}
-				} else {
-					if (canWalk(slave)) {
-						text.push(`The canine clambers up to mount ${slave.slaveName}, eliciting a squeal from the ${girl} as its claws dig into ${his} flesh.`);
+					break;
+				case V.active.hooved:
+					if (type === Acts.ORAL) {
+						if (slaveApproves) {
+							text.push(`Though the slave still seems to have some reservations about sucking off ${anAnimal}, ${he} seems to forget that the cock in ${his} mouth isn't human soon enough, once ${his} carnal desires kick in.`);
+						} else {
+							text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+						}
+					} else {
+						text.push(`${slave.slaveName} gives a long, drawn-out groan as the huge phallus `, slave.vagina < 4 ? `<span class="change positive">stretches</span>` : `fills`, ` ${his} ${orifice()} nearly to its breaking point.`);
+					}
+					break;
+				case V.active.feline:
+					if (type === Acts.ORAL) {
+						if (slaveApproves) {
+							text.push(`Though the slave still seems to have some reservations about sucking off an animal, ${he} seems to forget that the cock in ${his} mouth belongs to a feline soon enough, once ${his} carnal desires kick in.`);
+						} else {
+							text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s barbed dick fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+						}
 					} else {
-						text.push(`The canine takes a few curious sniffs, then lines up its large cock with ${slave.slaveName}'s ${orifice()}.`);
+						text.push(`${slave.slaveName} gives a squeal of pain as the barbed cock makes its way into ${his} ${orifice()}.`);
 					}
+					break;
+				default:
+					throw new Error(`Unexpected animal type '${animal}' in fAnimal()`);
+			}
 
-					text.push(`It takes a few tries, but the ${animal.name} finally manages to sink its cock into ${his} ${slaveApproves && act === Acts.VAGINAL ? `wet ` : ``}${orifice()}.`);
-				}
-				break;
-			case V.active.hooved:
-				if (type === Acts.ORAL) {
-					if (slaveApproves) {
-						text.push(`Though the slave still seems to have some reservations about sucking off ${anAnimal}, ${he} seems to forget that the cock in ${his} mouth isn't human soon enough, once ${his} carnal desires kick in.`);
+			if (act !== Acts.ORAL) {
+				text.push(virginityCheck(act));
+			}
+		} else if (slave.devotion > -20) {
+			if (act === Acts.ORAL) {
+				text.push(`You force ${him} to kneel on the floor before calling in the ${animal.name}. The beast slowly saunters up to the slave where ${he} waits, showing little concern when the slave reluctantly reaches out and begins masturbating it to begin the process of getting the animal hard. Once the ${animal.name} is hard enough, ${slave.slaveName} takes its cock and begins to give it a few tentative licks before finally putting it in ${his} mouth.`);
+			} else {
+				text.push(`You force ${him} to ${App.Data.clothes.get(slave.clothes).exposure <= 3 ? `take off ${his} clothes and ` : ``}get on the floor, ass in the air, before calling in the ${animal.name}. The beast slowly saunters up to the slave, where it takes only a few short moments for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
+			}
+
+			switch (animal.name) {
+				case V.active.canine:
+					if (type === Acts.ORAL) {
+						if (slaveApproves) {
+							text.push(`Though the slave still seems to have some reservations about sucking off an animal, ${he} seems to forget that the cock in ${his} mouth belongs to ${anAnimal} soon enough, once ${his} carnal desires kick in.`);
+						} else {
+							text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+						}
 					} else {
-						text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+						if (canWalk(slave)) {
+							text.push(`The canine clambers up to mount ${slave.slaveName}, eliciting a squeal from the ${girl} as its claws dig into ${his} flesh.`);
+						} else {
+							text.push(`The canine takes a few curious sniffs, then lines up its large cock with ${slave.slaveName}'s ${orifice()}.`);
+						}
+
+						text.push(`It takes a few tries, but the ${animal.name} finally manages to sink its cock into ${his} ${slaveApproves && act === Acts.VAGINAL ? `wet ` : ``}${orifice()}.`);
 					}
-				} else {
-					text.push(`${slave.slaveName} gives a long, drawn-out groan as the huge phallus `, slave.vagina < 4 ? `<span class="change positive">stretches</span>` : `fills`, ` ${his} ${orifice()} nearly to its breaking point.`);
-				}
-				break;
-			case V.active.feline:
-				if (type === Acts.ORAL) {
-					if (slaveApproves) {
-						text.push(`Though the slave still seems to have some reservations about sucking off an animal, ${he} seems to forget that the cock in ${his} mouth belongs to a feline soon enough, once ${his} carnal desires kick in.`);
+					break;
+				case V.active.hooved:
+					if (type === Acts.ORAL) {
+						if (slaveApproves) {
+							text.push(`Though the slave still seems to have some reservations about sucking off ${anAnimal}, ${he} seems to forget that the cock in ${his} mouth isn't human soon enough, once ${his} carnal desires kick in.`);
+						} else {
+							text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+						}
 					} else {
-						text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s barbed dick fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+						text.push(`${slave.slaveName} gives a long, drawn-out groan as the huge phallus `, slave.vagina < 4 ? `<span class="change positive">stretches</span>` : `fills`, ` ${his} ${orifice()} nearly to its breaking point.`);
 					}
-				} else {
-					text.push(`${slave.slaveName} gives a squeal of pain as the barbed cock makes its way into ${his} ${orifice()}.`);
-				}
-				break;
-			default:
-				throw new Error(`Unexpected animal type '${animal}' in fAnimal()`);
-		}
+					break;
+				case V.active.feline:
+					if (type === Acts.ORAL) {
+						if (slaveApproves) {
+							text.push(`Though the slave still seems to have some reservations about sucking off an animal, ${he} seems to forget that the cock in ${his} mouth belongs to a feline soon enough, once ${his} carnal desires kick in.`);
+						} else {
+							text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s barbed dick fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+						}
+					} else {
+						text.push(`${slave.slaveName} gives a squeal of pain as the barbed cock makes its way into ${his} ${orifice()}.`);
+					}
+					break;
+				default:
+					throw new Error(`Unexpected animal type '${animal}' in fAnimal()`);
+			}
 
-		if (act !== Acts.ORAL) {
-			text.push(virginityCheck(act));
-		}
-	} else if (slave.devotion > -20) {
-		if (act === Acts.ORAL) {
-			text.push(`You force ${him} to kneel on the floor before calling in the ${animal.name}. The beast slowly saunters up to the slave where ${he} waits, showing little concern when the slave reluctantly reaches out and begins masturbating it to begin the process of getting the animal hard. Once the ${animal.name} is hard enough, ${slave.slaveName} takes its cock and begins to give it a few tentative licks before finally putting it in ${his} mouth.`);
+			if (act !== Acts.ORAL) {
+				text.push(virginityCheck(act));
+			}
 		} else {
-			text.push(`You force ${him} to ${App.Data.clothes.get(slave.clothes).exposure <= 3 ? `take off ${his} clothes and ` : ``}get on the floor, ass in the air, before calling in the ${animal.name}. The beast slowly saunters up to the slave, where it takes only a few short moments for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
-		}
+			if (act === Acts.ORAL) {
+				text.push(`You have to physically force ${him} to kneel on the floor before calling in the ${animal.name}. The beast slowly saunters up to the slave where ${he} is restrained, showing little concern when another slave reaches out and begins masturbating it to begin the process of getting the animal hard. Once the ${animal.name} is hard enough, the slave takes its cock and lines it up with ${slave.slaveName}'s mouth. The animal needs no prompting, and thrusts itself into ${his} ring-gagged mouth.`);
+			} else {
+				text.push(`You have to physically force ${him} to ${App.Data.clothes.get(slave.clothes).exposure <= 3 ? `take off ${his} clothes and ` : ``} get on the floor, ass in the air and restraints around ${his} wrists and ankles, before calling in the ${animal.name}. The beast slowly saunters up to the slave, where it takes only a few short moments for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
+			}
 
-		switch (animal.name) {
-			case V.active.canine:
-				if (type === Acts.ORAL) {
-					if (slaveApproves) {
-						text.push(`Though the slave still seems to have some reservations about sucking off an animal, ${he} seems to forget that the cock in ${his} mouth belongs to ${anAnimal} soon enough, once ${his} carnal desires kick in.`);
-					} else {
-						text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
-					}
-				} else {
-					if (canWalk(slave)) {
-						text.push(`The canine clambers up to mount ${slave.slaveName}, eliciting a squeal from the ${girl} as its claws dig into ${his} flesh.`);
+			switch (animal.name) {
+				case V.active.canine:
+					if (type === Acts.ORAL) {
+						if (slaveApproves) {
+							text.push(`The slave glares daggers at you as ${he} takes the full length of the canine's cock in ${his} mouth, but ${slave.dick
+								? canAchieveErection(slave)
+									? `${his} fully-erect dick`
+									: `the precum leaking from ${his} dick`
+								: slave.vagina > -1
+									? `a slight sheen on ${his} pussylips`
+									: `a slight blush to ${his} cheeks`}
+									tells you that ${he}'s enjoying this, at least a little.`);
+						} else {
+							text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, and you get the feeling ${he} would have run away a long time ago if ${he} wasn't a little tied up at the moment.`);
+						}
 					} else {
-						text.push(`The canine takes a few curious sniffs, then lines up its large cock with ${slave.slaveName}'s ${orifice()}.`);
-					}
+						if (canWalk(slave)) {
+							text.push(`The canine clambers up to mount ${slave.slaveName}, eliciting a squeal from the ${girl} as its claws dig into ${his} flesh.`);
+						} else {
+							text.push(`The canine takes a few curious sniffs, then lines up its large cock with ${slave.slaveName}'s ${orifice()}.`);
+						}
 
-					text.push(`It takes a few tries, but the ${animal.name} finally manages to sink its cock into ${his} ${slaveApproves && act === Acts.VAGINAL ? `wet ` : ``}${orifice()}.`);
-				}
-				break;
-			case V.active.hooved:
-				if (type === Acts.ORAL) {
-					if (slaveApproves) {
-						text.push(`Though the slave still seems to have some reservations about sucking off ${anAnimal}, ${he} seems to forget that the cock in ${his} mouth isn't human soon enough, once ${his} carnal desires kick in.`);
+						text.push(`It takes a few tries, but the ${animal.name} finally manages to sink its cock into ${his} ${slaveApproves && act === Acts.VAGINAL ? `wet ` : ``}${orifice()}.`);
+					}
+					break;
+				case V.active.hooved:
+					if (type === Acts.ORAL) {
+						if (slaveApproves) {
+							text.push(`The slave glares daggers at you as ${he} takes the full length of the ${animal.name}'s cock in ${his} mouth, but ${slave.dick
+								? canAchieveErection(slave)
+									? `${his} fully-erect dick`
+									: `the precum leaking from ${his} dick`
+								: slave.vagina > -1
+									? `a slight sheen on ${his} pussylips`
+									: `a slight blush to ${his} cheeks`}
+									tells you that ${he}'s enjoying this, at least a little.`);
+						} else {
+							text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, and you get the feeling ${he} would have run away a long time ago if ${he} wasn't a little tied up at the moment.`);
+						}
 					} else {
-						text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+						text.push(`${slave.slaveName} lets out a blood-curdling scream as the huge phallus `, slave.vagina < 4 ? `<span class="change positive">stretches</span>` : `fills`, ` ${his} ${orifice()} nearly to its breaking point.`);
 					}
-				} else {
-					text.push(`${slave.slaveName} gives a long, drawn-out groan as the huge phallus `, slave.vagina < 4 ? `<span class="change positive">stretches</span>` : `fills`, ` ${his} ${orifice()} nearly to its breaking point.`);
-				}
-				break;
-			case V.active.feline:
-				if (type === Acts.ORAL) {
-					if (slaveApproves) {
-						text.push(`Though the slave still seems to have some reservations about sucking off an animal, ${he} seems to forget that the cock in ${his} mouth belongs to a feline soon enough, once ${his} carnal desires kick in.`);
+					break;
+				case V.active.feline:
+					if (type === Acts.ORAL) {
+						if (slaveApproves) {
+							text.push(`The slave glares daggers at you as ${he} takes the full length of the feline's cock in ${his} mouth, but ${slave.dick
+								? canAchieveErection(slave)
+									? `${his} fully-erect dick`
+									: `the precum leaking from ${his} dick`
+								: slave.vagina > -1
+									? `a slight sheen on ${his} pussylips`
+									: `a slight blush to ${his} cheeks`}
+									tells you that ${he}'s enjoying this, at least a little.`);
+						} else {
+							text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s barbed dick fills it, and you get the feeling ${he} would have run away a long time ago if ${he} wasn't a little tied up at the moment .`);
+						}
 					} else {
-						text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s barbed dick fills it, and you get the feeling ${he} is beginning to reevaluate just how much ${he} wants to avoid punishment.`);
+						text.push(`${slave.slaveName} lets out a blood-curdling scream as the barbed cock makes its way into ${his} ${orifice()}.`);
 					}
-				} else {
-					text.push(`${slave.slaveName} gives a squeal of pain as the barbed cock makes its way into ${his} ${orifice()}.`);
-				}
-				break;
-			default:
-				throw new Error(`Unexpected animal type '${animal}' in fAnimal()`);
-		}
+					break;
+				default:
+					throw new Error(`Unexpected animal type '${animal}' in fAnimal()`);
+			}
 
-		if (act !== Acts.ORAL) {
-			text.push(virginityCheck(act));
-		}
-	} else {
-		if (act === Acts.ORAL) {
-			text.push(`You have to physically force ${him} to kneel on the floor before calling in the ${animal.name}. The beast slowly saunters up to the slave where ${he} is restrained, showing little concern when another slave reaches out and begins masturbating it to begin the process of getting the animal hard. Once the ${animal.name} is hard enough, the slave takes its cock and lines it up with ${slave.slaveName}'s mouth. The animal needs no prompting, and thrusts itself into ${his} ring-gagged mouth.`);
-		} else {
-			text.push(`You have to physically force ${him} to ${App.Data.clothes.get(slave.clothes).exposure <= 3 ? `take off ${his} clothes and ` : ``} get on the floor, ass in the air and restraints around ${his} wrists and ankles, before calling in the ${animal.name}. The beast slowly saunters up to the slave, where it takes only a few short moments for its animal brain to realize that what it is standing behind is a warm hole that needs to be filled with seed.`);
+			if (act !== Acts.ORAL) {
+				text.push(virginityCheck(act));
+			}
 		}
 
+		return text.join(' ');
+	}
+
+	function consummation() {
+		const text = [];
+
 		switch (animal.name) {
 			case V.active.canine:
-				if (type === Acts.ORAL) {
-					if (slaveApproves) {
-						text.push(`The slave glares daggers at you as ${he} takes the full length of the canine's cock in ${his} mouth, but ${slave.dick
-							? canAchieveErection(slave)
-								? `${his} fully-erect dick`
-								: `the precum leaking from ${his} dick`
-							: slave.vagina > -1
-								? `a slight sheen on ${his} pussylips`
-								: `a slight blush to ${his} cheeks`}
-								tells you that ${he}'s enjoying this, at least a little.`);
-					} else {
-						text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, and you get the feeling ${he} would have run away a long time ago if ${he} wasn't a little tied up at the moment.`);
-					}
+				if (act === Acts.ORAL) {
+					// TODO: rewrite this so its not so similar
+					text.push(`The ${animal.species === "dog" ? `hound` : animal.name} wastes no time in beginning to hammer away at ${his} ${orifice()} in the way only canines can, causing ${slave.slaveName} to moan uncontrollably as its thick, veiny member probes the depths of ${his} ${orifice()}. A few short minutes later, ${he} gives a loud groan ${slaveApproves ? `and shakes in orgasm ` : ``}as the ${animal.name}'s knot begins to swell and its dick begins to erupt a thick stream of jizz down ${his} abused throat. Soon enough, the ${animal.name} finally finishes cumming and its knot is sufficiently small enough to slip out of ${slave.slaveName}'s mouth, causing ${him} to immediately begin coughing and retching uncontrollably. Having finished its business, the ${animal.name} runs off, presumably in search of food.`);
 				} else {
-					if (canWalk(slave)) {
-						text.push(`The canine clambers up to mount ${slave.slaveName}, eliciting a squeal from the ${girl} as its claws dig into ${his} flesh.`);
-					} else {
-						text.push(`The canine takes a few curious sniffs, then lines up its large cock with ${slave.slaveName}'s ${orifice()}.`);
-					}
-
-					text.push(`It takes a few tries, but the ${animal.name} finally manages to sink its cock into ${his} ${slaveApproves && act === Acts.VAGINAL ? `wet ` : ``}${orifice()}.`);
+					text.push(`The ${animal.species === "dog" ? `hound` : animal.name} wastes no time in beginning to hammer away at ${his} ${orifice()} in the way only canines can, causing ${slave.slaveName} to moan uncontrollably as its thick, veiny member probes the depths of ${his} ${orifice()}. A few short minutes later, ${he} gives a loud groan ${slaveApproves ? `and shakes in orgasm ` : ``}as the ${animal.name}'s knot begins to swell and its dick begins to erupt a thick stream of jizz into ${his} ${orifice()}. Soon enough, the ${animal.name} finally finishes cumming and its knot is sufficiently small enough to slip out of ${slave.slaveName}'s ${act === Acts.VAGINAL && slave.vagina < 3 || act === Acts.ANAL && slave.anus < 2
+						? `now-gaping ${orifice()}`
+						: orifice()}, causing a thick stream of cum to slide out of it. Having finished its business, the ${animal.name} runs off, presumably in search of food.`);
 				}
 				break;
 			case V.active.hooved:
-				if (type === Acts.ORAL) {
-					if (slaveApproves) {
-						text.push(`The slave glares daggers at you as ${he} takes the full length of the ${animal.name}'s cock in ${his} mouth, but ${slave.dick
-							? canAchieveErection(slave)
-								? `${his} fully-erect dick`
-								: `the precum leaking from ${his} dick`
-							: slave.vagina > -1
-								? `a slight sheen on ${his} pussylips`
-								: `a slight blush to ${his} cheeks`}
-								tells you that ${he}'s enjoying this, at least a little.`);
-					} else {
-						text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s cock fills it, and you get the feeling ${he} would have run away a long time ago if ${he} wasn't a little tied up at the moment.`);
-					}
+				if (act === Acts.ORAL) {
+					text.push(`The ${animal.species === "horse" ? `stallion` : animal.name} begins to thrust faster and faster, causing ${him} to moan and groan past the huge ${animal.species} cock stretching ${his} poor throat to its limits. Before too long, the ${animal.name}'s movements begin to slow, and you can see its large testicles contract as its begins to erupt and pour its thick semen down ${his} throat and into ${his} stomach, filling it to the brim. After what seems like an impossibly long time, the ${animal.name}'s dick finally begins to soften and pull out, causing ${slave.slaveName} to begin coughing and retching uncontrollably. You have another slave lead the ${animal.name} away, with a fresh apple as a treat for its good performance.`);
 				} else {
-					text.push(`${slave.slaveName} lets out a blood-curdling scream as the huge phallus `, slave.vagina < 4 ? `<span class="change positive">stretches</span>` : `fills`, ` ${his} ${orifice()} nearly to its breaking point.`);
+					text.push(`The ${animal.species === "horse" ? `stallion` : animal.name} begins to thrust faster and faster, causing ${him} to moan and groan as the huge ${animal.species} cock ${act === Acts.VAGINAL ? `batters ${his} cervix` : `fills ${him} completely`}. Before too long, the ${animal.name}'s movements begin to slow, and you can see its large testicles contract as its begins to erupt and fill ${his} ${orifice()} with its thick baby batter. After what seems like an impossibly long time, the ${animal.name}'s dick finally begins to soften and pull out, leaving ${slave.slaveName} panting and covered in sweat. You have another slave lead the ${animal.name} away, with a fresh apple as a treat for its good performance.`);
 				}
 				break;
 			case V.active.feline:
-				if (type === Acts.ORAL) {
-					if (slaveApproves) {
-						text.push(`The slave glares daggers at you as ${he} takes the full length of the feline's cock in ${his} mouth, but ${slave.dick
-							? canAchieveErection(slave)
-								? `${his} fully-erect dick`
-								: `the precum leaking from ${his} dick`
-							: slave.vagina > -1
-								? `a slight sheen on ${his} pussylips`
-								: `a slight blush to ${his} cheeks`}
-								tells you that ${he}'s enjoying this, at least a little.`);
-					} else {
-						text.push(`The slave visibly gags as the unfamiliar texture of ${anAnimal}'s barbed dick fills it, and you get the feeling ${he} would have run away a long time ago if ${he} wasn't a little tied up at the moment .`);
-					}
+				if (act === Acts.ORAL) {
+					text.push(`The ${animal.name} begins to move, thrusting faster and faster. The ${girl} underneath it can't stop a groan of pain from escaping ${his} lips as the ${animal.species}'s barbed dick rubs the inside of ${his} mouth and throat raw. After a few minutes of painful coupling, the ${animal.species}'s thrusts finally slow, then stop completely as its ${animal.species !== "cat" ? `large` : ``} cock erupts down ${slave.slaveName}'s throat. With a ${animal.species !== "cat" ? `deep bellow` : `loud meow`}, he finally dismounts, gives you a long look, then stalks off.`);
 				} else {
-					text.push(`${slave.slaveName} lets out a blood-curdling scream as the barbed cock makes its way into ${his} ${orifice()}.`);
+					text.push(`The ${animal.name} begins to move, thrusting faster and faster. The ${girl} underneath it can't stop a groan of pain from escaping ${his} lips as the ${animal.species}'s barbed dick rubs the inside of ${his} ${orifice()} raw. After a few minutes of painful coupling, the ${animal.species}'s thrusts finally slow, then stop completely as its ${animal.species !== "cat" ? `large` : ``} cock erupts, filling ${slave.slaveName} with its sperm. With a ${animal.species !== "cat" ? `deep bellow` : `loud meow`}, he finally dismounts, gives you a long look, then stalks off.`);
 				}
+
+				healthDamage(slave, 1);
 				break;
 			default:
 				throw new Error(`Unexpected animal type '${animal}' in fAnimal()`);
 		}
 
-		if (act !== Acts.ORAL) {
-			text.push(virginityCheck(act));
-		}
-	}
-
-	switch (animal.name) {
-		case V.active.canine:
-			if (act === Acts.ORAL) {
-				// TODO: rewrite this so its not so similar
-				text.push(`The ${animal.species === "dog" ? `hound` : animal.name} wastes no time in beginning to hammer away at ${his} ${orifice()} in the way only canines can, causing ${slave.slaveName} to moan uncontrollably as its thick, veiny member probes the depths of ${his} ${orifice()}. A few short minutes later, ${he} gives a loud groan ${slaveApproves ? `and shakes in orgasm ` : ``}as the ${animal.name}'s knot begins to swell and its dick begins to erupt a thick stream of jizz down ${his} abused throat. Soon enough, the ${animal.name} finally finishes cumming and its knot is sufficiently small enough to slip out of ${slave.slaveName}'s mouth, causing ${him} to immediately begin coughing and retching uncontrollably. Having finished its business, the ${animal.name} runs off, presumably in search of food.`);
-			} else {
-				text.push(`The ${animal.species === "dog" ? `hound` : animal.name} wastes no time in beginning to hammer away at ${his} ${orifice()} in the way only canines can, causing ${slave.slaveName} to moan uncontrollably as its thick, veiny member probes the depths of ${his} ${orifice()}. A few short minutes later, ${he} gives a loud groan ${slaveApproves ? `and shakes in orgasm ` : ``}as the ${animal.name}'s knot begins to swell and its dick begins to erupt a thick stream of jizz into ${his} ${orifice()}. Soon enough, the ${animal.name} finally finishes cumming and its knot is sufficiently small enough to slip out of ${slave.slaveName}'s ${act === Acts.VAGINAL && slave.vagina < 3 || act === Acts.ANAL && slave.anus < 2
-					? `now-gaping ${orifice()}`
-					: orifice()}, causing a thick stream of cum to slide out of it. Having finished its business, the ${animal.name} runs off, presumably in search of food.`);
-			}
-			break;
-		case V.active.hooved:
-			if (act === Acts.ORAL) {
-				text.push(`The ${animal.species === "horse" ? `stallion` : animal.name} begins to thrust faster and faster, causing ${him} to moan and groan past the huge ${animal.species} cock stretching ${his} poor throat to its limits. Before too long, the ${animal.name}'s movements begin to slow, and you can see its large testicles contract as its begins to erupt and pour its thick semen down ${his} throat and into ${his} stomach, filling it to the brim. After what seems like an impossibly long time, the ${animal.name}'s dick finally begins to soften and pull out, causing ${slave.slaveName} to begin coughing and retching uncontrollably. You have another slave lead the ${animal.name} away, with a fresh apple as a treat for its good performance.`);
-			} else {
-				text.push(`The ${animal.species === "horse" ? `stallion` : animal.name} begins to thrust faster and faster, causing ${him} to moan and groan as the huge ${animal.species} cock ${act === Acts.VAGINAL ? `batters ${his} cervix` : `fills ${him} completely`}. Before too long, the ${animal.name}'s movements begin to slow, and you can see its large testicles contract as its begins to erupt and fill ${his} ${orifice()} with its thick baby batter. After what seems like an impossibly long time, the ${animal.name}'s dick finally begins to soften and pull out, leaving ${slave.slaveName} panting and covered in sweat. You have another slave lead the ${animal.name} away, with a fresh apple as a treat for its good performance.`);
-			}
-			break;
-		case V.active.feline:
-			if (act === Acts.ORAL) {
-				text.push(`The ${animal.name} begins to move, thrusting faster and faster. The ${girl} underneath it can't stop a groan of pain from escaping ${his} lips as the ${animal.species}'s barbed dick rubs the inside of ${his} mouth and throat raw. After a few minutes of painful coupling, the ${animal.species}'s thrusts finally slow, then stop completely as its ${animal.species !== "cat" ? `large` : ``} cock erupts down ${slave.slaveName}'s throat. With a ${animal.species !== "cat" ? `deep bellow` : `loud meow`}, he finally dismounts, gives you a long look, then stalks off.`);
-			} else {
-				text.push(`The ${animal.name} begins to move, thrusting faster and faster. The ${girl} underneath it can't stop a groan of pain from escaping ${his} lips as the ${animal.species}'s barbed dick rubs the inside of ${his} ${orifice()} raw. After a few minutes of painful coupling, the ${animal.species}'s thrusts finally slow, then stop completely as its ${animal.species !== "cat" ? `large` : ``} cock erupts, filling ${slave.slaveName} with its sperm. With a ${animal.species !== "cat" ? `deep bellow` : `loud meow`}, he finally dismounts, gives you a long look, then stalks off.`);
-			}
-
-			healthDamage(slave, 1);
-			break;
-		default:
-			throw new Error(`Unexpected animal type '${animal}' in fAnimal()`);
-	}
-
-	if (act === Acts.VAGINAL) {
-		slave.vagina = slave.vagina < animal.dick.size ? animal.dick.size : slave.vagina;
-	} else if (act === Acts.ANAL) {
-		slave.anus = slave.anus < animal.dick.size ? animal.dick.size : slave.anus;
-	}
-
-	if (act !== Acts.ORAL && canGetPregnant(slave) && canBreed(slave, animal)) {
-		knockMeUp(slave, 5, hole, -8);
+		return text.join(' ');
 	}
 
-	if (random(1, 100) > 100 + slave.devotion && slave.energy < 95) {
-		text.push(slaveGainsFlaw());
-	} else if (slave.devotion > 20) {
-		text.push(slaveGainsQuirk());
-	}
+	function cleanup() {
+		const text = [];
 
-	if (V.postSexCleanUp) {
 		if (act !== Acts.ORAL) {
 			if (act === Acts.VAGINAL) {
 				if (slave.vagina === 3) {
@@ -563,13 +598,9 @@ App.Interact.fAnimal = function(slave, type) {
 			}
 		}
 
-		text.toParagraph();
+		return text.join(' ');
 	}
 
-	return frag;
-
-	// Text Functions
-
 	function slaveGainsFlaw() {
 		switch (act) {
 			case Acts.ORAL:
@@ -584,7 +615,7 @@ App.Interact.fAnimal = function(slave, type) {
 				if (slave.sexualFlaw !== "hates penetration") {
 					slave.sexualFlaw = "hates penetration";
 
-					return `<span class="flaw gain">Having ${anAnimal} fuck ${his} by force has given ${him} a hatred of penetration.</span>`;
+					return `<span class="flaw gain">Having ${anAnimal} fuck ${him} by force has given ${him} a hatred of penetration.</span>`;
 				}
 
 				break;
diff --git a/src/npc/interaction/fAnus.js b/src/npc/interaction/fAnus.js
index 67e1ab3415883495e2736a94a3d43a24af2e9ad4..7dde70b5bdf860438d6bbb2d9b324ac3bc7c10c0 100644
--- a/src/npc/interaction/fAnus.js
+++ b/src/npc/interaction/fAnus.js
@@ -4,8 +4,7 @@
  * @returns {DocumentFragment}
  */
 App.Interact.fAnus = function(slave) {
-	const node = new DocumentFragment();
-	let r = [];
+	const frag = new DocumentFragment();
 
 	const {
 		He, His,
@@ -14,433 +13,491 @@ App.Interact.fAnus = function(slave) {
 
 	seX(slave, "anal", V.PC, "penetrative");
 
-	r.push(`You call ${him} over so you can`);
-	if (slave.anus > 3) {
-		r.push(`fuck ${his} gaping anus.`);
-	} else if (slave.anus === 3) {
-		r.push(`fuck ${his} loose butthole.`);
-	} else if (slave.anus === 2) {
-		r.push(`use ${his} whorish asshole.`);
-	} else if (slave.anus === 1) {
-		r.push(`use ${his} tight butt.`);
-	} else {
-		r.push(`take ${his} anal virginity.`);
-	}
+	const text = new SpacedTextAccumulator(frag);
 
-	if (slave.fetish === "buttslut" && slave.devotion >= -20) {
-		r.push(`${He}'s delighted at the prospect of ${his} favorite activity.`);
-	} else if (slave.fetish === "buttslut") {
-		r.push(`${He} perks up at the prospect of ${his} favorite activity, but the idea of spending it with you instantly sours ${his} mood.`);
-	}
+	text.push(
+		setup(),
+		consummation(),
+		belly(),
+		anusTat(),
+	);
 
-	if (slave.anusTat === "tribal patterns") {
-		r.push(`${His} bleached asshole is an inviting sight, after all.`);
-	} else if (slave.anusTat === "scenes") {
-		r.push(`${His} tattooed asshole invites sodomy, after all.`);
-	} else if (slave.anusTat === "degradation") {
-		r.push(`The tattoos on ${his} asshole make it clear ${he}'s an anal slut, after all.`);
+	if (random(1, 100) > (100 + slave.devotion)) {
+		slaveGainsFlaw();
+	} else if (random(1, 100) > (110 - slave.devotion)) {
+		slaveGainsQuirk();
 	}
 
-	if (slave.heels === 1) {
-		if (shoeHeelCategory(slave) > 0) {
-			r.push(`As ${he} went past your desk, ${his} high heels and surgically altered legs enforced a gait that presented ${his} butt enticingly.`);
-		} else {
-			r.push(`As ${he} crawls along on`);
-			if (hasAllLimbs(slave)) {
-				r.push(`all fours,`);
-			} else {
-				r.push(`the ground,`);
-			}
-			r.push(`${his} anus is readily available.`);
-		}
+	if (V.postSexCleanUp) {
+		text.push(cleanup());
 	}
 
-	if (slave.piercing.anus.weight > 1) {
-		r.push(`The ring of stud piercings around ${his} anus should massage you delightfully as you sodomize ${him}.`);
-	} else if (slave.piercing.anus.weight === 1) {
-		r.push(`${His} perineum piercing has a big ring in it, which you should be able to feel when you hilt yourself in ${his} ass.`);
-	}
+	text.toParagraph();
+
+	return frag;
+
+	function setup() {
+		const text = [];
 
-	if (slave.anusTat !== 0 && slave.anusTat !== 4) {
-		r.push(`${His} anus is invitingly bleached,`);
-		if (slave.vagina > -1) {
-			r.push(`which is appropriate: rather than looking like ${he} has a hole for fucking and an ass, it looks like ${he} has two fuckholes.`);
+		text.push(`You call ${him} over so you can`);
+
+		if (slave.anus > 3) {
+			text.push(`fuck ${his} gaping anus.`);
+		} else if (slave.anus === 3) {
+			text.push(`fuck ${his} loose butthole.`);
+		} else if (slave.anus === 2) {
+			text.push(`use ${his} whorish asshole.`);
+		} else if (slave.anus === 1) {
+			text.push(`use ${his} tight butt.`);
 		} else {
-			r.push(`making ${his} sole fuckable hole look nice and natural.`);
+			text.push(`take ${his} anal virginity.`);
 		}
-	}
 
-	if (slave.anus === 0) {
-		if (slave.devotion > 20) {
-			r.push(`${He} accepts your orders without comment and presents ${his} virgin anus for defloration. You`);
-			if (V.PC.dick === 0) {
-				r.push(`don a strap-on and`);
-			}
-			r.push(`gently sodomize ${him}. You gently ease into ${his} butthole and slowly accelerate your thrusting into ${his} ass. Since ${he} is already well broken, this new connection with ${his} ${getWrittenTitle(slave)} <span class="devotion inc">increases ${his} devotion to you.</span> <span class="virginity loss">${His} tight little ass has been broken in.</span> ${He} looks forward to having ${his} asshole fucked by you again.`);
-			slave.devotion += 4;
-		} else if (slave.devotion >= -20) {
-			r.push(`${He} is clearly unhappy at the idea of taking a dick up ${his} butt. ${He} obeys orders anyway, and lies there wincing and moaning as you`);
-			if (V.PC.dick === 0) {
-				r.push(`don a strap-on and`);
-			}
-			r.push(`fuck ${his} ass. You gently ease into ${his} butthole and slowly accelerate your thrusting into ${his} ass. However ${he} still squeals in pain as you continue pounding. <span class="virginity loss">${His} tight little ass has been broken in,</span> and ${he} <span class="trust dec">fears further anal pain.</span>`);
-			slave.trust -= 5;
-		} else {
-			r.push(`${He} is appalled at the idea of taking it up the ass${(V.PC.dick === 0) ? ` and cries with fear as you don a strap-on` : ``}. ${He} does anyway though, sobbing into the cushions`);
-			if (hasAnyArms(slave)) {
-				r.push(`while you hold ${his} ${hasBothArms(slave) ? `arms` : `arm`} behind ${him}`);
-			}
-			r.push(r.pop() + `.`);
-			r.push(`You force yourself into ${his} butthole and continue thrusting your member into ${his} ass. ${He} sobs and cries with disgust while you pump into ${his} rear. The painful anal rape <span class="devotion dec">decreases ${his} devotion to you.</span> <span class="virginity loss">${His} tight little ass has been broken in,</span> and ${he} is <span class="trust dec">terrified of further anal pain.</span>`);
-			slave.devotion -= 10;
-			slave.trust -= 10;
+		if (slave.fetish === "buttslut" && slave.devotion >= -20) {
+			text.push(`${He}'s delighted at the prospect of ${his} favorite activity.`);
+		} else if (slave.fetish === "buttslut") {
+			text.push(`${He} perks up at the prospect of ${his} favorite activity, but the idea of spending it with you instantly sours ${his} mood.`);
+		}
+
+		if (slave.anusTat === "tribal patterns") {
+			text.push(`${His} bleached asshole is an inviting sight, after all.`);
+		} else if (slave.anusTat === "scenes") {
+			text.push(`${His} tattooed asshole invites sodomy, after all.`);
+		} else if (slave.anusTat === "degradation") {
+			text.push(`The tattoos on ${his} asshole make it clear ${he}'s an anal slut, after all.`);
 		}
-		slave.anus++;
-	} else if (slave.fetish === "mindbroken") {
-		if (hasAnyArms(slave)) {
-			r.push(`You instruct ${him} to present ${his} anus. ${He} dully`);
-			if (hasBothLegs(slave)) {
-				r.push(`kneels`);
+
+		if (slave.heels === 1) {
+			if (shoeHeelCategory(slave) > 0) {
+				text.push(`As ${he} went past your desk, ${his} high heels and surgically altered legs enforced a gait that presented ${his} butt enticingly.`);
 			} else {
-				r.push(`bends over`);
+				text.push(`As ${he} crawls along on`);
+				if (hasAllLimbs(slave)) {
+					text.push(`all fours,`);
+				} else {
+					text.push(`the ground,`);
+				}
+				text.push(`${his} anus is readily available.`);
 			}
-			r.push(`and spreads ${his} buttocks${V.PC.dick === 0 ? ` as you don a strap-on` : ``}. You spit on ${his} hole and ram`);
-		} else {
-			r.push(`Talking to a broken mind is pointless, so you simply set ${him} on the couch, spread ${his} buttocks with one hand, spit on ${his} hole, and ram`);
 		}
-		if (V.PC.dick === 0) {
-			r.push(`it`);
-		} else {
-			r.push(`your cock`);
-		}
-		r.push(`up ${his}`);
-		if (V.seeRace === 1) {
-			r.push(slave.race);
-		}
-		r.push(`butt. ${His} butthole spasms as you assrape ${him},`);
-		if (V.PC.dick === 0) {
-			r.push(`an amusing sight.`);
-		} else {
-			r.push(`squeezing your dick nicely.`);
+
+		if (slave.piercing.anus.weight > 1) {
+			text.push(`The ring of stud piercings around ${his} anus should massage you delightfully as you sodomize ${him}.`);
+		} else if (slave.piercing.anus.weight === 1) {
+			text.push(`${His} perineum piercing has a big ring in it, which you should be able to feel when you hilt yourself in ${his} ass.`);
 		}
-		if (slave.dick !== 0 && canAchieveErection(slave)) {
-			if (slave.chastityPenis === 1) {
-				r.push(`Automatic responses give ${him} an erection, which ${his} chastity makes so uncomfortable that ${he} spasms. This cycle continues repeatedly, ${his} rectum squeezing unconsciously each time.`);
-			} else if (slave.prostate !== 0) {
-				r.push(`Despite ${his} mental deficiency, the prostate stimulation gives ${him} an erection anyway.`);
+
+		if (slave.anusTat !== 0 && slave.anusTat === "bleached") {
+			text.push(`${His} anus is invitingly bleached,`);
+			if (slave.vagina > -1) {
+				text.push(`which is appropriate: rather than looking like ${he} has a hole for fucking and an ass, it looks like ${he} has two fuckholes.`);
 			} else {
-				r.push(`Without a prostate, there's little stimulation to provoke an involuntary response, and ${his} cock stays limp.`);
+				text.push(`making ${his} sole fuckable hole look nice and natural.`);
 			}
-		} else if (slave.chastityPenis === 1) {
-			r.push(`${His} dick chastity keeps ${his} pointless cock hidden away while you use ${his} anus like a pussy.`);
-		} else if (slave.dick !== 0) {
-			r.push(`${His} cock is totally flaccid throughout.`);
 		}
-	} else if (slave.devotion < -20) {
-		if (!isAmputee(slave)) {
-			r.push(`You instruct ${him} to present ${his} anus${V.PC.dick === 0 ? ` as you don a strap-on` : ``}. Horrified, ${he} tries to back away, but you catch ${him} and throw ${him} on the couch next to your desk. ${He} tries to`);
-			if (hasAnyArms(slave)) {
-				r.push(`shield ${his} asshole,`);
+
+		return text.join(' ');
+	}
+
+	function consummation() {
+		const text = [];
+
+
+		if (slave.anus === 0) {
+			if (slave.devotion > 20) {
+				text.push(`${He} accepts your orders without comment and presents ${his} virgin anus for defloration. You`);
+				if (V.PC.dick === 0) {
+					text.push(`don a strap-on and`);
+				}
+				text.push(`gently sodomize ${him}. You gently ease into ${his} butthole and slowly accelerate your thrusting into ${his} ass. Since ${he} is already well broken, this new connection with ${his} ${getWrittenTitle(slave)} <span class="devotion inc">increases ${his} devotion to you.</span> <span class="virginity loss">${His} tight little ass has been broken in.</span> ${He} looks forward to having ${his} asshole fucked by you again.`);
+				slave.devotion += 4;
+			} else if (slave.devotion >= -20) {
+				text.push(`${He} is clearly unhappy at the idea of taking a dick up ${his} butt. ${He} obeys orders anyway, and lies there wincing and moaning as you`);
+				if (V.PC.dick === 0) {
+					text.push(`don a strap-on and`);
+				}
+				text.push(`fuck ${his} ass. You gently ease into ${his} butthole and slowly accelerate your thrusting into ${his} ass. However ${he} still squeals in pain as you continue pounding. <span class="virginity loss">${His} tight little ass has been broken in,</span> and ${he} <span class="trust dec">fears further anal pain.</span>`);
+				slave.trust -= 5;
 			} else {
-				r.push(`back away,`);
+				text.push(`${He} is appalled at the idea of taking it up the ass${(V.PC.dick === 0) ? ` and cries with fear as you don a strap-on` : ``}. ${He} does anyway though, sobbing into the cushions`);
+				if (hasAnyArms(slave)) {
+					text.push(`while you hold ${his} ${hasBothArms(slave) ? `arms` : `arm`} behind ${him}`);
+				}
+				text.push(text.pop() + `.`);
+				text.push(`You force yourself into ${his} butthole and continue thrusting your member into ${his} ass. ${He} sobs and cries with disgust while you pump into ${his} rear. The painful anal rape <span class="devotion dec">decreases ${his} devotion to you.</span> <span class="virginity loss">${His} tight little ass has been broken in,</span> and ${he} is <span class="trust dec">terrified of further anal pain.</span>`);
+				slave.devotion -= 10;
+				slave.trust -= 10;
 			}
-			r.push(`but you pin`);
+			slave.anus++;
+		} else if (slave.fetish === "mindbroken") {
 			if (hasAnyArms(slave)) {
-				r.push(`${his} ${hasBothArms(slave) ? "hands" : "hand"} behind ${him} with one hand,`);
+				text.push(`You instruct ${him} to present ${his} anus. ${He} dully`);
+				if (hasBothLegs(slave)) {
+					text.push(`kneels`);
+				} else {
+					text.push(`bends over`);
+				}
+				text.push(`and spreads ${his} buttocks${V.PC.dick === 0 ? ` as you don a strap-on` : ``}. You spit on ${his} hole and ram`);
 			} else {
-				r.push(`${him} down,`);
+				text.push(`Talking to a broken mind is pointless, so you simply set ${him} on the couch, spread ${his} buttocks with one hand, spit on ${his} hole, and ram`);
 			}
-			r.push(`spit on ${his} hole, and ram your`);
 			if (V.PC.dick === 0) {
-				r.push(`fake dick`);
+				text.push(`it`);
 			} else {
-				r.push(`cock`);
+				text.push(`your cock`);
 			}
-			r.push(`up ${his} butt with the other hand.`);
-		} else {
-			r.push(`You tell ${him} it's time for an assfuck. ${He}'s horrified, but as an amputee can do nothing about it. You spit on ${his} hole and ram your`);
+			text.push(`up ${his}`);
+			if (V.seeRace === 1) {
+				text.push(slave.race);
+			}
+			text.push(`butt. ${His} butthole spasms as you assrape ${him},`);
 			if (V.PC.dick === 0) {
-				r.push(`fake dick`);
+				text.push(`an amusing sight.`);
 			} else {
-				r.push(`cock`);
+				text.push(`squeezing your dick nicely.`);
 			}
-			r.push(`up ${his}`);
-			if (V.seeRace === 1) {
-				r.push(slave.race);
-			}
-			r.push(`butt.`);
-		}
-		r.push(`${His} butthole spasms as you assrape ${him},`);
-		if (V.PC.dick === 0) {
-			r.push(`an amusing sight.`);
-		} else {
-			r.push(`squeezing your dick nicely.`);
-		}
-		if (slave.dick !== 0 && canAchieveErection(slave)) {
-			if (slave.prostate === 0) {
-				r.push(`${He} lacks a prostate, denying ${him} any real pleasure from this. ${His} dick stays flaccid as you rape ${him}.`);
+			if (slave.dick !== 0 && canAchieveErection(slave)) {
+				if (slave.chastityPenis === 1) {
+					text.push(`Automatic responses give ${him} an erection, which ${his} chastity makes so uncomfortable that ${he} spasms. This cycle continues repeatedly, ${his} rectum squeezing unconsciously each time.`);
+				} else if (slave.prostate !== 0) {
+					text.push(`Despite ${his} mental deficiency, the prostate stimulation gives ${him} an erection anyway.`);
+				} else {
+					text.push(`Without a prostate, there's little stimulation to provoke an involuntary response, and ${his} cock stays limp.`);
+				}
 			} else if (slave.chastityPenis === 1) {
-				r.push(`Despite ${his} unwillingness to be sodomized, the prostate stimulation starts to give ${him} an erection, which ${his} dick chastity makes horribly uncomfortable. ${He} bucks with the pain, ${his} asshole spasming delightfully.`);
-			} else {
-				r.push(`Despite ${his} unwillingness to be sodomized, the prostate stimulation gives ${him} an erection. ${He}'s mortified that ${he} would get hard while being anally raped.`);
+				text.push(`${His} dick chastity keeps ${his} pointless cock hidden away while you use ${his} anus like a pussy.`);
+			} else if (slave.dick !== 0) {
+				text.push(`${His} cock is totally flaccid throughout.`);
 			}
-		} else if (slave.chastityPenis === 1) {
-			r.push(`${His} dick chastity keeps ${his} bitch cock hidden away while you use ${his} anus like a pussy.`);
-		} else if (slave.dick !== 0) {
-			r.push(`${His} flaccid dick is ground into the back of the couch as you rape ${him}.`);
-		}
-	} else if (slave.devotion <= 20 && slave.vagina < 0) {
-		if (!isAmputee(slave)) {
-			r.push(`You instruct ${him} to present ${his} anus${V.PC.dick === 0 ? ` as you don a strap-on` : ``}. ${He} knows a sissy slave takes it up the butt, and lies on the couch next to your desk with ${his}`);
-			if (!hasAnyLegs(slave)) {
-				r.push(`hips`);
+		} else if (slave.devotion < -20) {
+			if (!isAmputee(slave)) {
+				text.push(`You instruct ${him} to present ${his} anus${V.PC.dick === 0 ? ` as you don a strap-on` : ``}. Horrified, ${he} tries to back away, but you catch ${him} and throw ${him} on the couch next to your desk. ${He} tries to`);
+				if (hasAnyArms(slave)) {
+					text.push(`shield ${his} asshole,`);
+				} else {
+					text.push(`back away,`);
+				}
+				text.push(`but you pin`);
+				if (hasAnyArms(slave)) {
+					text.push(`${his} ${hasBothArms(slave) ? "hands" : "hand"} behind ${him} with one hand,`);
+				} else {
+					text.push(`${him} down,`);
+				}
+				text.push(`spit on ${his} hole, and ram your`);
+				if (V.PC.dick === 0) {
+					text.push(`fake dick`);
+				} else {
+					text.push(`cock`);
+				}
+				text.push(`up ${his} butt with the other hand.`);
 			} else {
-				r.push(hasBothLegs(slave) ? `legs` : `leg`);
+				text.push(`You tell ${him} it's time for an assfuck. ${He}'s horrified, but as an amputee can do nothing about it. You spit on ${his} hole and ram your`);
+				if (V.PC.dick === 0) {
+					text.push(`fake dick`);
+				} else {
+					text.push(`cock`);
+				}
+				text.push(`up ${his}`);
+				if (V.seeRace === 1) {
+					text.push(slave.race);
+				}
+				text.push(`butt.`);
 			}
-			r.push(`in the air, spreading ${his} buttocks`);
-			if (!hasAnyArms(slave)) {
-				r.push(`as best ${he} can.`);
+			text.push(`${His} butthole spasms as you assrape ${him},`);
+			if (V.PC.dick === 0) {
+				text.push(`an amusing sight.`);
 			} else {
-				r.push(`with ${his} ${hasBothArms(slave) ? `hands` : `hand`}.`);
+				text.push(`squeezing your dick nicely.`);
 			}
-		} else {
-			r.push(`You tell ${him} it's time for an assfuck. ${He}'s hesitant, but as an amputee can do nothing about it.`);
-		}
-		r.push(`You take your time and fuck ${his}`);
-		if (V.seeRace === 1) {
-			r.push(slave.race);
-		}
-		r.push(`butthole for a good long while`);
-		if (slave.chastityPenis !== 1) {
-			if (slave.dick !== 0) {
-				r.push(`so ${his} limp dick flops around`);
-			} else if (slave.balls !== 0) {
-				r.push(`as ${his} erect dick waves in the air`);
+			if (slave.dick !== 0 && canAchieveErection(slave)) {
+				if (slave.prostate === 0) {
+					text.push(`${He} lacks a prostate, denying ${him} any real pleasure from this. ${His} dick stays flaccid as you rape ${him}.`);
+				} else if (slave.chastityPenis === 1) {
+					text.push(`Despite ${his} unwillingness to be sodomized, the prostate stimulation starts to give ${him} an erection, which ${his} dick chastity makes horribly uncomfortable. ${He} bucks with the pain, ${his} asshole spasming delightfully.`);
+				} else {
+					text.push(`Despite ${his} unwillingness to be sodomized, the prostate stimulation gives ${him} an erection. ${He}'s mortified that ${he} would get hard while being anally raped.`);
+				}
+			} else if (slave.chastityPenis === 1) {
+				text.push(`${His} dick chastity keeps ${his} bitch cock hidden away while you use ${his} anus like a pussy.`);
+			} else if (slave.dick !== 0) {
+				text.push(`${His} flaccid dick is ground into the back of the couch as you rape ${him}.`);
 			}
-		}
-		r.push(r.pop() + `.`);
-		r.push(`This gives you enough time to stroke ${him} until ${he} gets aroused despite ${his} discomfort with anal. ${He} doesn't orgasm, but ${he}'s getting accustomed to ${his} asshole as a sexual organ.`);
-	} else if (slave.devotion < 10) {
-		if (!isAmputee(slave)) {
-			r.push(`You instruct ${him} to present ${his}`);
+		} else if (slave.devotion <= 20 && slave.vagina < 0) {
+			if (!isAmputee(slave)) {
+				text.push(`You instruct ${him} to present ${his} anus${V.PC.dick === 0 ? ` as you don a strap-on` : ``}. ${He} knows a sissy slave takes it up the butt, and lies on the couch next to your desk with ${his}`);
+				if (!hasAnyLegs(slave)) {
+					text.push(`hips`);
+				} else {
+					text.push(hasBothLegs(slave) ? `legs` : `leg`);
+				}
+				text.push(`in the air, spreading ${his} buttocks`);
+				if (!hasAnyArms(slave)) {
+					text.push(`as best ${he} can.`);
+				} else {
+					text.push(`with ${his} ${hasBothArms(slave) ? `hands` : `hand`}.`);
+				}
+			} else {
+				text.push(`You tell ${him} it's time for an assfuck. ${He}'s hesitant, but as an amputee can do nothing about it.`);
+			}
+			text.push(`You take your time and fuck ${his}`);
 			if (V.seeRace === 1) {
-				r.push(slave.race);
+				text.push(slave.race);
+			}
+			text.push(`butthole for a good long while`);
+			if (slave.chastityPenis !== 1) {
+				if (slave.dick !== 0) {
+					text.push(`so ${his} limp dick flops around`);
+				} else if (slave.balls !== 0) {
+					text.push(`as ${his} erect dick waves in the air`);
+				}
 			}
-			r.push(`anus${V.PC.dick === 0 ? ` as you don a strap-on` : ``}. ${He} hesitates but eventually lies on the couch next to your desk with ${his}`);
-			if (!hasAnyLegs(slave)) {
-				r.push(`hips`);
+			text.push(text.pop() + `.`);
+			text.push(`This gives you enough time to stroke ${him} until ${he} gets aroused despite ${his} discomfort with anal. ${He} doesn't orgasm, but ${he}'s getting accustomed to ${his} asshole as a sexual organ.`);
+		} else if (slave.devotion < 10) {
+			if (!isAmputee(slave)) {
+				text.push(`You instruct ${him} to present ${his}`);
+				if (V.seeRace === 1) {
+					text.push(slave.race);
+				}
+				text.push(`anus${V.PC.dick === 0 ? ` as you don a strap-on` : ``}. ${He} hesitates but eventually lies on the couch next to your desk with ${his}`);
+				if (!hasAnyLegs(slave)) {
+					text.push(`hips`);
+				} else {
+					text.push(hasBothLegs(slave) ? `legs` : `leg`);
+				}
+				text.push(`in the air, spreading ${his} buttocks`);
+				if (!hasAnyArms(slave)) {
+					text.push(`as best ${he} can.`);
+				} else {
+					text.push(`with ${his} ${hasBothArms(slave) ? `hands` : `hand`}.`);
+				}
 			} else {
-				r.push(hasBothLegs(slave) ? `legs` : `leg`);
+				text.push(`You tell ${him} it's time for an assfuck. ${He}'s hesitant, but as an amputee can do nothing about it.`);
 			}
-			r.push(`in the air, spreading ${his} buttocks`);
-			if (!hasAnyArms(slave)) {
-				r.push(`as best ${he} can.`);
+			text.push(`You take your time and fuck ${his} butthole for a good long while.`);
+			if (slave.anus === 1) {
+				text.push(`${His} ass is so tight that ${he} winces with anal pain`);
+			} else if (slave.anus === 2) {
+				text.push(`${His} experienced ass takes your`);
+				if (V.PC.dick === 0) {
+					text.push(`fake dick`);
+				} else {
+					text.push(`cock`);
+				}
+				text.push(`without trouble`);
 			} else {
-				r.push(`with ${his} ${hasBothArms(slave) ? `hands` : `hand`}.`);
+				text.push(`${His} asspussy is so loose you can pound it as hard as you like`);
 			}
-		} else {
-			r.push(`You tell ${him} it's time for an assfuck. ${He}'s hesitant, but as an amputee can do nothing about it.`);
-		}
-		r.push(`You take your time and fuck ${his} butthole for a good long while.`);
-		if (slave.anus === 1) {
-			r.push(`${His} ass is so tight that ${he} winces with anal pain`);
-		} else if (slave.anus === 2) {
-			r.push(`${His} experienced ass takes your`);
-			if (V.PC.dick === 0) {
-				r.push(`fake dick`);
+			if (slave.dick !== 0 && !canAchieveErection(slave)) {
+				text.push(`as ${his} limp dick flops around.`);
+			} else if (slave.dick !== 0 && canAchieveErection(slave)) {
+				text.push(`as ${his} erect dick waves in the air.`);
+			} else if (slave.vagina === -1) {
+				text.push(`as it does its duty as ${his} sole fuckhole.`);
 			} else {
-				r.push(`cock`);
+				text.push(`as it substitutes for ${his} pussy.`);
 			}
-			r.push(`without trouble`);
-		} else {
-			r.push(`${His} asspussy is so loose you can pound it as hard as you like`);
-		}
-		if (slave.dick !== 0 && !canAchieveErection(slave)) {
-			r.push(`as ${his} limp dick flops around.`);
-		} else if (slave.dick !== 0 && canAchieveErection(slave)) {
-			r.push(`as ${his} erect dick waves in the air.`);
-		} else if (slave.vagina === -1) {
-			r.push(`as it does its duty as ${his} sole fuckhole.`);
-		} else {
-			r.push(`as it substitutes for ${his} pussy.`);
-		}
-		r.push(`${He} gets aroused despite ${his} discomfort with anal, though ${he} doesn't orgasm.`);
-	} else {
-		if (hasAnyLegs(slave)) {
-			r.push(`${He} kneels on the couch`);
+			text.push(`${He} gets aroused despite ${his} discomfort with anal, though ${he} doesn't orgasm.`);
 		} else {
-			r.push(`You lay ${him} on the couch`);
-		}
-		r.push(`with ${his}`);
-		if (V.seeRace === 1) {
-			r.push(slave.race);
-		}
-		r.push(`butt facing you, back strongly arched to angle ${his} rectum for more comfortable anal coupling.`);
-		if (hasAnyArms(slave) && slave.prostate > 1 && slave.dick > 3) {
-			if (V.PC.dick === 0) {
-				r.push(`While you don a strap-on, ${he}`);
+			if (hasAnyLegs(slave)) {
+				text.push(`${He} kneels on the couch`);
 			} else {
-				r.push(`${He}`);
+				text.push(`You lay ${him} on the couch`);
 			}
-			r.push(`shoves ${his} slavering dick down and around towards ${his} ass and squeezes it, pushing a lot of ${his} precum out to lube ${his} own asshole.`);
-		} else {
+			text.push(`with ${his}`);
+			if (V.seeRace === 1) {
+				text.push(slave.race);
+			}
+			text.push(`butt facing you, back strongly arched to angle ${his} rectum for more comfortable anal coupling.`);
+			if (hasAnyArms(slave) && slave.prostate > 1 && slave.dick > 3) {
+				if (V.PC.dick === 0) {
+					text.push(`While you don a strap-on, ${he}`);
+				} else {
+					text.push(`${He}`);
+				}
+				text.push(`shoves ${his} slavering dick down and around towards ${his} ass and squeezes it, pushing a lot of ${his} precum out to lube ${his} own asshole.`);
+			} else {
+				if (V.PC.dick === 0) {
+					text.push(`You don a strap-on and let some saliva fall onto its head`);
+				} else {
+					text.push(`You let some saliva fall onto your dickhead`);
+				}
+				text.push(`before penetrating ${him}.`);
+			}
+			text.push(`You take your time and fuck ${his} butthole for a good long while.`);
+			if (slave.anus === 1) {
+				text.push(`${His} ass is so tight that ${he} has to concentrate on relaxing for you.`);
+			} else if (slave.anus === 2) {
+				text.push(`${His} experienced ass feels great.`);
+			} else {
+				text.push(`${His} asspussy is so loose you can pound it as hard as you like.`);
+			}
+			text.push(`${He} rubs ${his}`);
+			if (!hasAnyArms(slave)) {
+				text.push(`body against you as much as ${he} can manage,`);
+			} else if (canAchieveErection(slave)) {
+				text.push(`hard-on,`);
+			} else if (slave.dick !== 0) {
+				text.push(`soft dick,`);
+			} else if (slave.chastityVagina || slave.clit === 0) {
+				text.push(`nipples,`);
+			} else if (slave.clit > 2) {
+				text.push(`huge, stiff clit,`);
+			} else {
+				text.push(`clit,`);
+			}
+			text.push(`and brings ${himself} to orgasm before you.`);
 			if (V.PC.dick === 0) {
-				r.push(`You don a strap-on and let some saliva fall onto its head`);
+				text.push(`The sight of ${him} gasping and shaking ${his} way through an anal orgasm brings you to climax yourself, and you shove yourself against the strap-on harness with enough force to give the slave's sensitized hole a final brutal stretching.`);
 			} else {
-				r.push(`You let some saliva fall onto your dickhead`);
+				text.push(`${His} orgasmic rectal spasms squeeze your cock and you blow your load inside ${his} ass.`);
 			}
-			r.push(`before penetrating ${him}.`);
-		}
-		r.push(`You take your time and fuck ${his} butthole for a good long while.`);
-		if (slave.anus === 1) {
-			r.push(`${His} ass is so tight that ${he} has to concentrate on relaxing for you.`);
-		} else if (slave.anus === 2) {
-			r.push(`${His} experienced ass feels great.`);
-		} else {
-			r.push(`${His} asspussy is so loose you can pound it as hard as you like.`);
-		}
-		r.push(`${He} rubs ${his}`);
-		if (!hasAnyArms(slave)) {
-			r.push(`body against you as much as ${he} can manage,`);
-		} else if (canAchieveErection(slave)) {
-			r.push(`hard-on,`);
-		} else if (slave.dick !== 0) {
-			r.push(`soft dick,`);
-		} else if (slave.chastityVagina || slave.clit === 0) {
-			r.push(`nipples,`);
-		} else if (slave.clit > 2) {
-			r.push(`huge, stiff clit,`);
-		} else {
-			r.push(`clit,`);
-		}
-		r.push(`and brings ${himself} to orgasm before you.`);
-		if (V.PC.dick === 0) {
-			r.push(`The sight of ${him} gasping and shaking ${his} way through an anal orgasm brings you to climax yourself, and you shove yourself against the strap-on harness with enough force to give the slave's sensitized hole a final brutal stretching.`);
-		} else {
-			r.push(`${His} orgasmic rectal spasms squeeze your cock and you blow your load inside ${his} ass.`);
 		}
+
+
+		return text.join(' ');
 	}
 
-	if (slave.bellyPreg >= 1500) {
-		r.push(`The poor slave's pregnant belly causes ${him} some discomfort as you sodomize ${him}.`);
-	} else if (slave.bellyImplant >= 1500) {
-		r.push(`The poor ${girl}'s implant filled belly causes ${him} some discomfort as you sodomize ${him}.`);
-	} else if (slave.bellyFluid >= 1500) {
-		r.push(`The poor ${girl}'s sloshing belly causes ${him} some discomfort as you sodomize ${him}, though the lewd jiggling the pounding sends through it is quite a sight.`);
+	function belly() {
+		if (slave.bellyPreg >= 1500) {
+			return `The poor slave's pregnant belly causes ${him} some discomfort as you sodomize ${him}.`;
+		} else if (slave.bellyImplant >= 1500) {
+			return `The poor ${girl}'s implant filled belly causes ${him} some discomfort as you sodomize ${him}.`;
+		} else if (slave.bellyFluid >= 1500) {
+			return `The poor ${girl}'s sloshing belly causes ${him} some discomfort as you sodomize ${him}, though the lewd jiggling the pounding sends through it is quite a sight.`;
+		}
+
+		return ``;
 	}
 
-	if (slave.anusTat === "scenes" && slave.anus === 1) {
-		r.push(`As you fucked ${his} butt, the decorative pattern around ${his} ass stretched open. When you pull out, ${his} momentary gape closes the pattern up quickly.`);
-	} else if (slave.anusTat === "scenes") {
-		r.push(`As you fucked ${his} butt, the decorative pattern around ${his} ass stretched open. When you pull out, ${his} gape leaves the pattern distorted.`);
-	} else if (slave.anusTat === "degradation") {
-		r.push(`As you fucked ${his} butt, the offensive language around ${his} ass stretched and distorted.`);
+	function anusTat() {
+		if (slave.anusTat === "scenes" && slave.anus === 1) {
+			return `As you fucked ${his} butt, the decorative pattern around ${his} ass stretched open. When you pull out, ${his} momentary gape closes the pattern up quickly.`;
+		} else if (slave.anusTat === "scenes") {
+			return `As you fucked ${his} butt, the decorative pattern around ${his} ass stretched open. When you pull out, ${his} gape leaves the pattern distorted.`;
+		} else if (slave.anusTat === "degradation") {
+			return `As you fucked ${his} butt, the offensive language around ${his} ass stretched and distorted.`;
+		}
+
+		return ``;
 	}
 
-	if (random(1, 100) > (100 + slave.devotion)) {
+	function slaveGainsFlaw() {
 		if (slave.fetish !== "buttslut" && slave.energy <= 95 && slave.sexualFlaw !== "hates anal") {
-			r.push(`Being assraped has given ${him} a <span class="flaw gain">hatred of anal sex.</span>`);
 			slave.sexualFlaw = "hates anal";
+
+			return `Being assraped has given ${him} a <span class="flaw gain">hatred of anal sex.</span>`;
 		}
-	} else if (random(1, 100) > (110-slave.devotion)) {
+
+		return ``;
+	}
+
+	function slaveGainsQuirk() {
 		if (slave.fetish === "none" && slave.sexualFlaw !== "hates anal") {
-			r.push(`Orgasming to the sensation of your member in ${his} bottom <span class="fetish gain">has ${him} eager for anal.</span>`);
 			slave.fetish = "buttslut";
 			slave.fetishKnown = 1;
+
+			return `Orgasming to the sensation of your member in ${his} bottom <span class="fetish gain">has ${him} eager for anal.</span>`;
 		}
+
+		return ``;
 	}
 
-	if (V.PC.dick !== 0) {
-		if (slave.cervixImplant === 2 || slave.cervixImplant === 3) {
-			slave.bellyImplant += random(10, 20);
-		}
+	function cleanup() {
+		const text = [];
 
-		if (slave.anus > 3) {
-			r.push(`Your cum falls out of ${his} gaping hole.`);
-		} else if (slave.anus > 2) {
-			r.push(`Cum flows out of ${his} gaped butthole.`);
-		} else if (slave.anus === 2) {
-			r.push(`Cum drips out of ${his} newly gaped anus.`);
-		} else if (slave.anus === 1) {
-			r.push(`${His} still-tight ass keeps your load inside ${him}.`);
-		}
+		if (V.PC.dick !== 0) {
+			if (slave.cervixImplant === 2 || slave.cervixImplant === 3) {
+				slave.bellyImplant += random(10, 20);
+			}
 
-		if (canImpreg(slave, V.PC)) {
-			r.push(knockMeUp(slave, 5, 1, -1));
-		}
+			if (slave.anus > 3) {
+				text.push(`Your cum falls out of ${his} gaping hole.`);
+			} else if (slave.anus > 2) {
+				text.push(`Cum flows out of ${his} gaped butthole.`);
+			} else if (slave.anus === 2) {
+				text.push(`Cum drips out of ${his} newly gaped anus.`);
+			} else if (slave.anus === 1) {
+				text.push(`${His} still-tight ass keeps your load inside ${him}.`);
+			}
 
-		if (V.postSexCleanUp > 0) {
-			if (canMove(slave)) {
-				let anus;
-				if (slave.anus < 2) {
-					anus = "tight butt";
-				} else if (slave.anus < 3) {
-					anus = "used butthole";
-				} else if (slave.anus < 4) {
-					anus = "gaping butthole";
-				} else {
-					anus = "anal gape";
-				}
-				switch (slave.assignment) {
-					case "work in the brothel":
-						r.push(`${He} goes to wash ${his} ${anus} so ${his} next customer can have the illusion that he's the first to use it today.`);
-						break;
-					case "serve in the club":
-						r.push(`${He} goes to wash and delicately perfume ${his} ${anus} so it can gratify the finest citizen.`);
-						break;
-					case "work in the dairy":
-						r.push(`${He} goes off to carefully wash ${his} ${anus} to avoid besmirching the nice clean dairy.`);
-						break;
-					case "work as a farmhand":
-						r.push(`${He} goes off to wash ${his} ${anus} to avoid tainting the food in ${V.farmyardName}.`);
-						break;
-					case "work as a servant":
-						r.push(`${He} rushes to wash ${his} ${anus}, impatient to get back to ${his} many chores.`);
-						break;
-					case "work as a nanny":
-						r.push(`${He} goes off to wash ${his} ${anus}, before hurrying to continue taking care of the children in ${V.nurseryName}.`);
-						break;
-					case "whore":
-						r.push(`${He} uses an enema to clean ${his} ${anus} before returning to offering it for sale.`);
-						break;
-					case "serve the public":
-						r.push(`${He} uses an enema to clean ${his} ${anus} before returning to offering it for free.`);
-						break;
-					case "be a servant":
-						r.push(`${He} uses an enema to clean ${his} ${anus}, since ${his} chores didn't perform themselves while you used ${his} backdoor.`);
-						break;
-					case "rest":
-						r.push(`${He} uses an enema to clean ${his} ${anus} before crawling back into bed, face-down.`);
-						break;
-					case "get milked":
-						r.push(`${He} uses an enema to clean ${his} ${anus}`);
-						if (slave.lactation > 0) {
-							r.push(`before going to get ${his} uncomfortably milk-filled tits drained.`);
-						} else {
-							r.push(`and then rests until ${his} balls are ready to be drained again.`);
-						}
-						break;
-					case "please you":
-						r.push(`${He} uses an enema to clean ${his} ${anus} before returning to await your next use of ${his} backdoor, as though nothing had happened.`);
-						break;
-					case "be a subordinate slave":
-						r.push(`${He} uses an enema to clean ${his} ${anus}, though it's only a matter of time before another slave decides to play with ${his} backdoor.`);
-						break;
-					case "be your Head Girl":
-						r.push(`${He} uses an enema to clean ${his} ${anus}, worried that ${his} charges got up to trouble while ${he} enjoyed the buttsex.`);
-						break;
-					case "guard you":
-						r.push(`${He} hurries off to wash ${his} ${anus} so you'll be unguarded for as little time as possible.`);
-						break;
-					case "be the Schoolteacher":
-						r.push(`${He} uses an enema to clean ${his} ${anus} before ${he} returns to teaching ${his} classes, a little bow-legged.`);
-						break;
-					default:
-						r.push(`${He} hurries off to wash ${his} ${anus} before going back to ${slave.assignment}.`);
+			if (canImpreg(slave, V.PC)) {
+				text.push(knockMeUp(slave, 5, 1, -1));
+			}
+
+			if (V.postSexCleanUp > 0) {
+				if (canMove(slave)) {
+					let anus;
+					if (slave.anus < 2) {
+						anus = "tight butt";
+					} else if (slave.anus < 3) {
+						anus = "used butthole";
+					} else if (slave.anus < 4) {
+						anus = "gaping butthole";
+					} else {
+						anus = "anal gape";
+					}
+					switch (slave.assignment) {
+						case "work in the brothel":
+							text.push(`${He} goes to wash ${his} ${anus} so ${his} next customer can have the illusion that he's the first to use it today.`);
+							break;
+						case "serve in the club":
+							text.push(`${He} goes to wash and delicately perfume ${his} ${anus} so it can gratify the finest citizen.`);
+							break;
+						case "work in the dairy":
+							text.push(`${He} goes off to carefully wash ${his} ${anus} to avoid besmirching the nice clean dairy.`);
+							break;
+						case "work as a farmhand":
+							text.push(`${He} goes off to wash ${his} ${anus} to avoid tainting the food in ${V.farmyardName}.`);
+							break;
+						case "work as a servant":
+							text.push(`${He} rushes to wash ${his} ${anus}, impatient to get back to ${his} many chores.`);
+							break;
+						case "work as a nanny":
+							text.push(`${He} goes off to wash ${his} ${anus}, before hurrying to continue taking care of the children in ${V.nurseryName}.`);
+							break;
+						case "whore":
+							text.push(`${He} uses an enema to clean ${his} ${anus} before returning to offering it for sale.`);
+							break;
+						case "serve the public":
+							text.push(`${He} uses an enema to clean ${his} ${anus} before returning to offering it for free.`);
+							break;
+						case "be a servant":
+							text.push(`${He} uses an enema to clean ${his} ${anus}, since ${his} chores didn't perform themselves while you used ${his} backdoor.`);
+							break;
+						case "rest":
+							text.push(`${He} uses an enema to clean ${his} ${anus} before crawling back into bed, face-down.`);
+							break;
+						case "get milked":
+							text.push(`${He} uses an enema to clean ${his} ${anus}`);
+							if (slave.lactation > 0) {
+								text.push(`before going to get ${his} uncomfortably milk-filled tits drained.`);
+							} else {
+								text.push(`and then rests until ${his} balls are ready to be drained again.`);
+							}
+							break;
+						case "please you":
+							text.push(`${He} uses an enema to clean ${his} ${anus} before returning to await your next use of ${his} backdoor, as though nothing had happened.`);
+							break;
+						case "be a subordinate slave":
+							text.push(`${He} uses an enema to clean ${his} ${anus}, though it's only a matter of time before another slave decides to play with ${his} backdoor.`);
+							break;
+						case "be your Head Girl":
+							text.push(`${He} uses an enema to clean ${his} ${anus}, worried that ${his} charges got up to trouble while ${he} enjoyed the buttsex.`);
+							break;
+						case "guard you":
+							text.push(`${He} hurries off to wash ${his} ${anus} so you'll be unguarded for as little time as possible.`);
+							break;
+						case "be the Schoolteacher":
+							text.push(`${He} uses an enema to clean ${his} ${anus} before ${he} returns to teaching ${his} classes, a little bow-legged.`);
+							break;
+						default:
+							text.push(`${He} hurries off to wash ${his} ${anus} before going back to ${slave.assignment}.`);
+					}
 				}
 			}
 		}
+
+		return text.join(' ');
 	}
-	App.Events.addParagraph(node, r);
-	return node;
 };
diff --git a/src/npc/interaction/fAssistedSex.js b/src/npc/interaction/fAssistedSex.js
index f80db4b197d7a0c080aad3eaaa52c8e26e25d9cc..63f4e5b3e8037883477dd3696efb27cc78a644b5 100644
--- a/src/npc/interaction/fAssistedSex.js
+++ b/src/npc/interaction/fAssistedSex.js
@@ -4,140 +4,184 @@
  * @returns {DocumentFragment}
  */
 App.Interact.fAssistedSex = function(slave) {
-	const node = new DocumentFragment();
-	let r = [];
+	const frag = new DocumentFragment();
 
 	const {
 		He,
 		he, his, him, himself
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
+	seX(slave, "oral", V.PC);
 
-	r.push(`You order ${his} servants forward so that ${he} can tease you with ${his} enormously swollen body.`);
-	if (slave.devotion > 95) {
-		r.push(`Smirking, ${he} leans backwards,`);
-		if (hasBothArms(slave)) {
-			r.push(`raising ${his} hands above ${his} head`);
-		} else if (hasAnyArms(slave)) {
-			r.push(`raising ${his} hand above ${his} head`);
-		} else {
-			r.push(`with two slender arms rising upward behind ${him}, making it look like ${he} has limbs once more`);
-		}
-		r.push(`as a gaggle of ${his} trained menials slide underneath ${his} belly, lifting the monolithic organ off the ground and setting the tightly packed orb to wobbling.`);
-	} else if (slave.trust < -20 && slave.devotion > -10) {
-		r.push(`Smiling nervously, ${he} leans backwards,`);
-		if (hasBothArms(slave)) {
-			r.push(`raising ${his} hands above ${his} head`);
-		} else if (hasAnyArms(slave)) {
-			r.push(`raising ${his} hand above ${his} head`);
-		} else {
-			r.push(`with two slender arms rising upward behind ${him}, making it look like ${he} has limbs once more`);
-		}
-		r.push(`as a gaggle of ${his} trained menials slide underneath ${his} belly, lifting the monolithic organ off the ground and setting the tightly packed orb to wobbling.`);
-	} else {
-		if (hasBothArms(slave)) {
-			r.push(`${He} covers ${his}`);
-			if (canSee(slave)) {
-				r.push(`eyes`);
+	const text = new SpacedTextAccumulator(frag);
+
+	text.push(
+		intro(),
+		setup(),
+		consummation(),
+		cleanup(),
+	);
+
+	text.toParagraph();
+
+	return frag;
+
+	function intro() {
+		const text = [];
+
+		text.push(`You order ${his} servants forward so that ${he} can tease you with ${his} enormously swollen body.`);
+
+		if (slave.devotion > 95) {
+			text.push(`Smirking, ${he} leans backwards,`);
+			if (hasBothArms(slave)) {
+				text.push(`raising ${his} hands above ${his} head`);
+			} else if (hasAnyArms(slave)) {
+				text.push(`raising ${his} hand above ${his} head`);
 			} else {
-				r.push(`face`);
+				text.push(`with two slender arms rising upward behind ${him}, making it look like ${he} has limbs once more`);
 			}
-			r.push(`with ${his} hands,`);
-		} else if (hasAnyArms(slave)) {
-			r.push(`${He} tries to cover ${his}`);
-			if (canSee(slave)) {
-				r.push(`eyes`);
+			text.push(`as a gaggle of ${his} trained menials slide underneath ${his} belly, lifting the monolithic organ off the ground and setting the tightly packed orb to wobbling.`);
+		} else if (slave.trust < -20 && slave.devotion > -10) {
+			text.push(`Smiling nervously, ${he} leans backwards,`);
+			if (hasBothArms(slave)) {
+				text.push(`raising ${his} hands above ${his} head`);
+			} else if (hasAnyArms(slave)) {
+				text.push(`raising ${his} hand above ${his} head`);
 			} else {
-				r.push(`face`);
+				text.push(`with two slender arms rising upward behind ${him}, making it look like ${he} has limbs once more`);
 			}
-			r.push(`with ${his} hand,`);
+			text.push(`as a gaggle of ${his} trained menials slide underneath ${his} belly, lifting the monolithic organ off the ground and setting the tightly packed orb to wobbling.`);
 		} else {
-			r.push(`Two slender arms snake around from behind ${him}, almost making it look like ${he} has limbs once more. They cover ${his} quivering`);
-			if (canSee(slave)) {
-				r.push(`eyes`);
+			if (hasBothArms(slave)) {
+				text.push(`${He} covers ${his}`);
+				if (canSee(slave)) {
+					text.push(`eyes`);
+				} else {
+					text.push(`face`);
+				}
+				text.push(`with ${his} hands,`);
+			} else if (hasAnyArms(slave)) {
+				text.push(`${He} tries to cover ${his}`);
+				if (canSee(slave)) {
+					text.push(`eyes`);
+				} else {
+					text.push(`face`);
+				}
+				text.push(`with ${his} hand,`);
 			} else {
-				r.push(`expression`);
+				text.push(`Two slender arms snake around from behind ${him}, almost making it look like ${he} has limbs once more. They cover ${his} quivering`);
+				if (canSee(slave)) {
+					text.push(`eyes`);
+				} else {
+					text.push(`expression`);
+				}
 			}
-		}
-		r.push(`as a gaggle of ${his} trained menials slide underneath ${his} belly, lifting the monolithic organ off the ground and setting the tightly packed orb to wobbling.`);
-		if (hasBothArms(slave)) {
-			r.push(`Two more servants take hold of ${his} arms, forcing ${him} to lift them above ${his} head.`);
-		} else if (hasAnyArms(slave)) {
-			r.push(`Another servant takes hold of ${his} arm, forcing ${him} to lift it above ${his} head.`);
-		} else {
-			r.push(`The hands covering ${his}`);
-			if (canSee(slave)) {
-				r.push(`eyes`);
+
+			text.push(`as a gaggle of ${his} trained menials slide underneath ${his} belly, lifting the monolithic organ off the ground and setting the tightly packed orb to wobbling.`);
+
+			if (hasBothArms(slave)) {
+				text.push(`Two more servants take hold of ${his} arms, forcing ${him} to lift them above ${his} head.`);
+			} else if (hasAnyArms(slave)) {
+				text.push(`Another servant takes hold of ${his} arm, forcing ${him} to lift it above ${his} head.`);
 			} else {
-				r.push(`head`);
+				text.push(`The hands covering ${his}`);
+				if (canSee(slave)) {
+					text.push(`eyes`);
+				} else {
+					text.push(`head`);
+				}
+				text.push(`draw away, revealing ${his} crying face, then lift above ${his} head in a deliberately provocative pose.`);
 			}
-			r.push(`draw away, revealing ${his} crying face, then lift above ${his} head in a deliberately provocative pose.`);
+
+			text.push(`${He} tenses in a moment of instinctive resistance, then surrenders ${his} body to ${his} aids' total control, clearly afraid of punishment.`);
 		}
-		r.push(`${He} tenses in a moment of instinctive resistance, then surrenders ${his} body to ${his} aids' total control, clearly afraid of punishment.`);
-	}
-	r.push(`You remove your clothes and lie back on the office couch,`);
-	if (V.PC.dick !== 0) {
-		r.push(`allowing your exposed, full-mast dick to loll in front of you.`);
-	} else {
-		r.push(`spreading your exposed, oozing twat.`);
-	}
-	if (slave.devotion > 95) {
-		r.push(`Licking ${his} lips,`);
-	} else if (slave.trust < -20 && slave.devotion > -10) {
-		r.push(`Breathing heavily,`);
-	} else {
-		r.push(`Smiling fakely,`);
+
+		return text.join(' ');
 	}
-	r.push(`${he} draws toward you, half-floating on a river of silent, groping hands. When ${he} is mere`);
-	if (V.showInches === 2) {
-		r.push(`inches`);
-	} else {
-		r.push(`centimeters`);
+
+	function setup() {
+		const text = [];
+
+		text.push(`You remove your clothes and lie back on the office couch,`);
+
+		if (V.PC.dick !== 0) {
+			text.push(`allowing your exposed, full-mast dick to loll in front of you.`);
+		} else {
+			text.push(`spreading your exposed, oozing twat.`);
+		}
+
+		return text.join(' ');
 	}
-	r.push(`away from you, ${his} servants lift ${him} higher, and ${he}`);
-	if (V.PC.dick !== 0) {
-		r.push(`teases your dick with a series of masterful — and carefully balanced — belly isolations, rubbing the thick nub of ${his} belly button in small semicircles around your oozing cockhead as ${he} does so. Right when you feel ready to explode, ${he} rotates around, bringing`);
-		if (slave.butt > 11) {
-			r.push(`${his} overgrown, wobbling ass cheeks`);
-		} else if (slave.butt > 5) {
-			r.push(`${his} huge, wobbling ass cheeks`);
-		} else if (Math.floor(slave.buttImplant/slave.butt) > .60) {
-			r.push(`${his} saline inflated ass cheeks`);
-		} else if (slave.butt > 2) {
-			r.push(`${his} wobbling ass cheeks`);
+
+	function consummation() {
+		const text = [];
+
+		if (slave.devotion > 95) {
+			text.push(`Licking ${his} lips,`);
+		} else if (slave.trust < -20 && slave.devotion > -10) {
+			text.push(`Breathing heavily,`);
 		} else {
-			r.push(`the shallow inverted bowls of ${his} petite ass cheeks`);
+			text.push(`With a fake smile,`);
 		}
-		r.push(`level with your erection. Two of ${his} servants reach around ${his} inflated profile and push ${his} cheeks together, wrapping your dick in a firm layer of butt cleavage. ${He} lifts ${his} ass, then drops it, again and again, smacking your chest on the downswing as ${his} servants manipulate ${his} hotdogging to maximize your pleasure.`);
-		if (canDoVaginal(slave)) {
-			r.push(`When you feel the tension within you reaching its apex, you signal to ${his} servants to hold ${him} in place. With ${his} silent menials, still as statues, anchoring ${his} bloated body at the perfect angle for fucking while contorting their anonymous bodies to frame ${him} in a manner that maximizes ${his} visual attractiveness, you grab hold of ${his} flanks and ram into ${his} pregnant pussy, driving ${him} to the first of many orgasms in just a few casual thrusts.`);
-			r.push(VCheck.Vaginal(slave, 1));
-			r.push(`When you feel your own orgasm approaching, you pull out, ejaculating`);
-		} else if (canDoAnal(slave)) {
-			r.push(`When you feel the tension within you reaching its apex, you signal to ${his} servants to hold ${him} in place. With ${his} silent menials, still as statues, anchoring ${his} bloated body at the perfect angle for fucking while contorting their anonymous bodies to frame ${him} in a manner that maximizes ${his} visual attractiveness, you grab hold of ${his} flanks and ram into ${his} asshole, driving ${him} to the first of many orgasms with just a few casual thrusts.`);
-			r.push(VCheck.Anal(slave, 1));
-			r.push(`When you feel your own orgasm approaching, you pull out, ejaculating`);
+
+		text.push(`${he} draws toward you, half-floating on a river of silent, groping hands. When ${he} is mere`);
+
+		if (V.showInches === 2) {
+			text.push(`inches`);
 		} else {
-			r.push(`When you feel the tension with your reaching its apex, you signal to ${his} servants and they pull ${him} forward. You ejaculate`);
+			text.push(`centimeters`);
 		}
-		r.push(`a thick stream of semen all over ${his} ass and back, ${he} shifts into a kneeling position on the ground in front of you, tilted sideways so that ${his} massive fecundity can pool on the ground beside ${him}, and gently sucks you off, cleaning your dick with ${his} mouth.`);
-		slave.counter.oral++;
-		V.oralTotal++;
-	} else {
-		r.push(`Presses the thick nub of ${his} belly button into your pussy, rubbing it back and forth against your engorged clit as ${he} performs a series of masterful — and carefully balanced — belly isolations. After ${he} has you quaking at the edge of release, ${he} rolls forward and buries ${his} head in your lap, plying you with ${his}`);
-		if (slave.devotion > 95) {
-			r.push(`devoted tongue`);
-		} else if (slave.trust < -20 && slave.devotion > -10) {
-			r.push(`dedicated tongue`);
+
+		text.push(`away from you, ${his} servants lift ${him} higher, and ${he}`);
+
+		if (V.PC.dick !== 0) {
+			text.push(`teases your dick with a series of masterful — and carefully balanced — belly isolations, rubbing the thick nub of ${his} belly button in small semicircles around your oozing cockhead as ${he} does so. Right when you feel ready to explode, ${he} rotates around, bringing`);
+
+			if (slave.butt > 11) {
+				text.push(`${his} overgrown, wobbling ass cheeks`);
+			} else if (slave.butt > 5) {
+				text.push(`${his} huge, wobbling ass cheeks`);
+			} else if (Math.floor(slave.buttImplant/slave.butt) > .60) {
+				text.push(`${his} saline inflated ass cheeks`);
+			} else if (slave.butt > 2) {
+				text.push(`${his} wobbling ass cheeks`);
+			} else {
+				text.push(`the shallow inverted bowls of ${his} petite ass cheeks`);
+			}
+
+			text.push(`level with your erection. Two of ${his} servants reach around ${his} inflated profile and push ${his} cheeks together, wrapping your dick in a firm layer of butt cleavage. ${He} lifts ${his} ass, then drops it, again and again, smacking your chest on the downswing as ${his} servants manipulate ${his} hotdogging to maximize your pleasure.`);
+
+			if (canDoVaginal(slave)) {
+				text.push(`When you feel the tension within you reaching its apex, you signal to ${his} servants to hold ${him} in place. With ${his} silent menials, still as statues, anchoring ${his} bloated body at the perfect angle for fucking while contorting their anonymous bodies to frame ${him} in a manner that maximizes ${his} visual attractiveness, you grab hold of ${his} flanks and ram into ${his} pregnant pussy, driving ${him} to the first of many orgasms in just a few casual thrusts.`);
+				text.push(VCheck.Vaginal(slave, 1));
+				text.push(`When you feel your own orgasm approaching, you pull out, ejaculating`);
+			} else if (canDoAnal(slave)) {
+				text.push(`When you feel the tension within you reaching its apex, you signal to ${his} servants to hold ${him} in place. With ${his} silent menials, still as statues, anchoring ${his} bloated body at the perfect angle for fucking while contorting their anonymous bodies to frame ${him} in a manner that maximizes ${his} visual attractiveness, you grab hold of ${his} flanks and ram into ${his} asshole, driving ${him} to the first of many orgasms with just a few casual thrusts.`);
+				text.push(VCheck.Anal(slave, 1));
+				text.push(`When you feel your own orgasm approaching, you pull out, ejaculating`);
+			} else {
+				text.push(`When you feel the tension with your reaching its apex, you signal to ${his} servants and they pull ${him} forward. You ejaculate`);
+			}
+
+			text.push(`a thick stream of semen all over ${his} ass and back, ${he} shifts into a kneeling position on the ground in front of you, tilted sideways so that ${his} massive fecundity can pool on the ground beside ${him}, and gently sucks you off, cleaning your dick with ${his} mouth.`);
 		} else {
-			r.push(`tongue`);
+			text.push(`Presses the thick nub of ${his} belly button into your pussy, rubbing it back and forth against your engorged clit as ${he} performs a series of masterful — and carefully balanced — belly isolations. After ${he} has you quaking at the edge of release, ${he} rolls forward and buries ${his} head in your lap, plying you with ${his}`);
+
+			if (slave.devotion > 95) {
+				text.push(`devoted tongue`);
+			} else if (slave.trust < -20 && slave.devotion > -10) {
+				text.push(`dedicated tongue`);
+			} else {
+				text.push(`tongue`);
+			}
+
+			text.push(`and driving you into a series of crashing orgasms. When ${his} tongue tires, ${he} tries to draw away, but you grab hold of ${his} head and hold ${him} in place until you are finished.`);
 		}
-		r.push(`and driving you into a series of crashing orgasms. When ${his} tongue tires, ${he} tries to draw away, but you grab hold of ${his} head and hold ${him} in place until you are finished.`);
-		slave.counter.oral++;
-		V.oralTotal++;
+
+		return text.join(' ');
+	}
+
+	function cleanup() {
+		return `Once you are satisfied, you send ${him} away to clean ${himself} up before returning to ${his} duties.`;
 	}
-	r.push(`Once you are satisfied, you send ${him} away to clean ${himself} up before returning to ${his} duties.`);
-	App.Events.addParagraph(node, r);
-	return node;
 };
diff --git a/src/npc/interaction/fBeg.js b/src/npc/interaction/fBeg.js
index aca72060a4f6cf30471f5e3bc563909cd3568557..673d56ad331ba8e14940245411aadfa1b410b5dc 100644
--- a/src/npc/interaction/fBeg.js
+++ b/src/npc/interaction/fBeg.js
@@ -4,16 +4,13 @@
  * @returns {DocumentFragment}
  */
 App.Interact.fBeg = function(slave) {
-	const node = new DocumentFragment();
-	let r = [];
+	const frag = new DocumentFragment();
 
 	const {
 		He, His,
 		he, his, him, himself, woman, girl
 	} = getPronouns(slave);
 
-	const {title: Master, say: say} = getEnunciation(slave);
-
 	const {
 		hisP,
 	} = getPronouns(V.PC).appendSuffix("P");
@@ -22,692 +19,682 @@ App.Interact.fBeg = function(slave) {
 	const hands = hasBothArms(slave) ? "hands" : "hand";
 	const knees = hasBothLegs(slave) ? "knees" : "knee";
 
-	/* things I need: checks for canWalk() to see how easily she can move, blindness checks, replacement for BoobsDesc, maybe devotion catches for certain flaws */
-	/* priority! femPC support! */
-
-	r.push(`You call ${him} over to you for inspection. ${App.Desc.boobs(slave)}`);	/* this part needs expansion */
-	r.push(`You look at ${him} lustfully and instruct ${him} to strip.`);
-	if (slave.sexualFlaw === "shamefast") {
-		r.push(`Tears well up in ${his} eyes at the idea of showing ${his} naked body.`);
-	} else if (slave.sexualQuirk === "tease") {
-		r.push(`${He} blushes with arousal. ${He} has kept ${his} innate embarrassment at the thought of being naked, but you have infused this with overwhelming arousal. ${His} cheeks are red as ${he} removes ${his} clothes, giving quite a strip tease as ${he} does.`);
-	} else if (slave.sexualFlaw === "repressed") {
-		r.push(`${He} subconsciously uses ${his} ${hands} to try to cover ${his} body. ${He} is still repressing ${his} own sexuality. That type of behavior may have been allowed in the old world, but it has no place in a Free City.`);
-	} else if (slave.sexualFlaw === "idealistic") {
-		r.push(
-			`${He} shakes ${his} head pleadingly.`,
-			Spoken(slave, `"But I don't consent,"`),
-			`${he} responds. You laugh in such a way that tells ${him} that ${his} consent is irrelevant. ${He} is still idealistic, believing that sex should be a consensual expression of love and intimacy. Such ideas were common in the Old World, but they have no place in a Free City. You decide to grab ${him} and forcefully rip ${his} clothes from ${his} body, since obedience could simply be seen as consent. ${He} screams and plead as you pin ${his} arms, ripping and tearing at the cloth that keeps ${his} beauty from sight.`
-		);
-	} else if (slave.sexualFlaw === "neglectful") {
-		r.push(
-			`${He} replies`,
-			Spoken(slave, `"Yes, ${slave.rudeTitle === 1 ? PoliteRudeTitle(slave) : Master},""`),
-			`${he} replies contritely. ${He} has no sense of self beyond your usefulness of ${him}, and selflessly sacrifices ${his} own comfort for your pleasure.`
-		);
-	} else if (slave.sexualFlaw === "attention whore") {
-		r.push(`${He} eagerly begins to shirk ${his} wear, drawing as much attention to the process as possible.`);
-	} else {
-		if (slave.devotion < -20) {
-			r.push(`${He} resists, forcing you to undress ${him} yourself.`);
-		} else if (slave.devotion >= -20) {
-			r.push(`${He} obeys, and moves to the center of your office to disrobe for you.`);
-		}
-	}
-	if (slave.devotion >= -20) {
-		r.push(`${He} begins to undress with`);
-		if (slave.skill.entertainment >= 100) {
-			r.push(`masterful skill, teasing and taunting all the way down. ${He} rolls ${his} hips and most sexual parts as ${he} removes ${his} clothing.`);
-		} else if (slave.skill.entertainment >= 80) {
-			r.push(`arousing skill. Even though the goal is just to get ${him} naked, your slave knows that ${his} job is to entertain you with ${his} every move.`);
-		} else if (slave.skill.entertainment >= 50) {
-			r.push(`notable skill. ${He} takes the opportunity to give you a light strip tease as ${he} undresses.`);
-		} else if (slave.skill.entertainment >= 20) {
-			r.push(`a decent effort. ${He} isn't your most entertaining slave, but ${he} still makes an effort to arouse you with ${his} undressing.`);
-		} else if (slave.skill.entertainment >= 9) {
-			r.push(`some effort to be sexy. ${His} moves are less than skillful and the undressing is more pragmatic than arousing.`);
-		} else {
-			r.push(`no effort to be sexy. ${He} has no entertainment skill, and the only goal of ${his} actions is to go from clothed to naked.`);
-		}
+	const {title: Master, say: say} = getEnunciation(slave);
+
+	const text = new SpacedTextAccumulator(frag);
+
+	// TODO: priority! femPC support!
+	// TODO: checks for canWalk() to see how easily she can move, blindness checks, replacement for BoobsDesc, maybe devotion
+	// TODO: catches for certain flaws
+
+	text.push(
+		intro(),
+		setup(),
+		consummation(),
+	);
+
+	if (random(1, 100) > (100 + slave.devotion)) {
+		slaveGainsFlaw();
+	} else if (random(1, 100) > (110 - slave.devotion)) {
+		slaveGainsQuirk();
 	}
 
-	if (slave.fetishStrength > 60) {
-		switch (slave.fetish) {
-			case "submissive":
-				r.push(`As ${he} begins to strip you grab ${him} without warning and begin to tear off ${his} clothes. Your slave expected you to allow ${him} to obey your command, and so ${he} is initially taken aback by the sudden force but ${his} submissive nature keeps ${him} from resisting. ${He} is such a submissive slut that you feel obligation to push ${his} status even further. You bind ${his} arms tightly behind ${his} back in a leather monoglove, lacing it tighter until ${his} elbows are touching. ${He} gives a soft whimper, but you both know that this is for your benefit and not a protest.`);
-				if (slave.piercing.nipple.weight >= 1) {
-					r.push(`You then retrieve heavy bells and attach them to ${his} nipple rings.`);
-				} else {
-					r.push(`You reach into your pocket and retrieve two weighted and belled nipple clamps, attaching them tightly to your slave's delicate nipples.`);
-				}
-				r.push(`You tell ${him} to bounce so that they jingle, reminding ${him} of ${his} status.`);
-				break;
-			case "masochist":
-				r.push(
-					`Once ${he} is fully exposed you give ${him} a firm slap across the tits. ${He}'s a masochist and relishes the pain with sexual arousal. You ask your painslut if ${he} deserves to be punished.`,
-					Spoken(slave, `"Oh yes, ${slave.rudeTitle === 1 ? PoliteRudeTitle(slave) : Master}. Please punish your little slut."`),
-					`Sensing that your slave is getting too much enjoyment from ${his} beating, you cease.`
-				);
-				break;
-		}
+	text.toParagraph();
+
+	return frag;
+
+	function intro() {
+		const text = [];
+		// TODO: this part needs expansion
+		text.push(`You call ${him} over to you for inspection. ${App.Desc.boobs(slave)}`);
+
+		return text.join(' ');
 	}
 
-	r.push(`You stare at the naked figure standing before you.`);
-
-	if (canSee(slave)) {
-		if (slave.boobsTat === "rude words") {
-			r.push(
-				`The words on ${his} chest stand out at you. You ask ${him} what ${his} tits say.`,
-				Spoken(slave, `"Fuckslave,"`),
-				`${he} replies. You ask if that's what ${he} is.`
-			);
-			if (slave.behavioralFlaw === "liberated") {
-				r.push(
-					Spoken(slave, `"I'm nobody's property. I'm a free ${woman}!"`),
-					`${he} shoots back.`,
-					Spoken(slave, `"We shall see," you reply.`)
-				);
-			} else if (slave.devotion < -20) {
-				r.push(`${He} does ${his} best to shake ${his} head.`);
-			} else {
-				r.push(Spoken(slave, `"Yes ${Master}, that's what I am."`));
-			}
-		} else if (slave.boobsTat === "possessive") {
-			r.push(
-				`The words on ${his} chest stand out at you. You ask ${him} what ${his} tits say.`,
-				Spoken(slave, `"It's your personal symbol,"`),
-				`${he} replies. You ask if that's what ${he} is.`
-			);
-			if (slave.behavioralFlaw === "liberated") {
-				r.push(
-					Spoken(slave, `"I'm nobody's property. I'm a free ${woman}!"`),
-					`${he} shoots back.`,
-					Spoken(slave, `"We shall see," you reply.`)
-				);
-			} else if (slave.devotion < -20) {
-				r.push(`${He} does ${his} best to shake ${his} head.`);
-			} else {
-				r.push(Spoken(slave, `"Yes, ${Master} that's what I am."`));
-			}
-		} else if (slave.boobsTat === "degradation") {
-			r.push(
-				`The words on ${his} chest stand out at you. You ask ${him} what ${his} tits say. "`,
-				Spoken(slave, `${Master}'s Bitch,"`),
-				`${he} replies. You ask if that's what ${he} is.`);
-			if (slave.behavioralFlaw === "liberated") {
-				r.push(
-					Spoken(slave, `"I'm nobody's property. I'm a free ${woman}!"`),
-					`${he} shoots back.`,
-					Spoken(slave, `"We shall see," you reply.`)
-				);
-			} else if (slave.devotion < -20) {
-				r.push(`${He} does ${his} best to shake ${his} head.`);
+	function setup() {
+		const text = [];
+
+		text.push(`You look at ${him} lustfully and instruct ${him} to strip.`);
+
+		if (slave.sexualFlaw === "shamefast") {
+			text.push(`Tears well up in ${his} eyes at the idea of showing ${his} naked body.`);
+		} else if (slave.sexualQuirk === "tease") {
+			text.push(`${He} blushes with arousal. ${He} has kept ${his} innate embarrassment at the thought of being naked, but you have infused this with overwhelming arousal. ${His} cheeks are red as ${he} removes ${his} clothes, giving quite a strip tease as ${he} does.`);
+		} else if (slave.sexualFlaw === "repressed") {
+			text.push(`${He} subconsciously uses ${his} ${hands} to try to cover ${his} body. ${He} is still repressing ${his} own sexuality. That type of behavior may have been allowed in the old world, but it has no place in a Free City.`);
+		} else if (slave.sexualFlaw === "idealistic") {
+			text.push(`${He} shakes ${his} head pleadingly. ${Spoken(slave, `"But I don't consent,"`)} ${he} responds. You laugh in such a way that tells ${him} that ${his} consent is irrelevant. ${He} is still idealistic, believing that sex should be a consensual expression of love and intimacy. Such ideas were common in the Old World, but they have no place in a Free City. You decide to grab ${him} and forcefully rip ${his} clothes from ${his} body, since obedience could simply be seen as consent. ${He} screams and plead as you`);
+
+			if (hasBothArms(slave)) {
+				text.push(`pin ${his} arms,`);
 			} else {
-				r.push(Spoken(slave, `"Yes ${Master}, that's what I am."`));
+				text.push(`hold ${him} in place,`);
 			}
+
+			text.push(`ripping and tearing at the cloth that keeps ${his} beauty from sight.`);
+		} else if (slave.sexualFlaw === "neglectful") {
+			text.push(`${He} replies ${Spoken(slave, `"Yes, ${slave.rudeTitle ? PoliteRudeTitle(slave) : Master},""`)} ${he} replies contritely. ${He} has no sense of self beyond your usefulness of ${him}, and selflessly sacrifices ${his} own comfort for your pleasure.`);
+		} else if (slave.sexualFlaw === "attention whore") {
+			text.push(`${He} eagerly begins to shirk ${his} wear, drawing as much attention to the process as possible.`);
 		} else {
-			r.push(`${His} body belongs to you, and your slave needs to remember that.`);
+			if (slave.devotion < -20) {
+				text.push(`${He} resists, forcing you to undress ${him} yourself.`);
+			} else if (slave.devotion >= -20) {
+				text.push(`${He} obeys, and moves to the center of your office to disrobe for you.`);
+			}
 		}
-	} else {
-		r.push(`${His} body belongs to you, and your slave needs to remember that.`);
-	}
 
-	r.push(`You then tell your slave to kneel at your feet.`);
-	if (slave.behavioralFlaw === "bitchy") {
-		r.push(
-			`${He} rolls ${his} eyes sasses you a bit,`,
-			Spoken(slave, `"Whatever,"`),
-			`${he} scoffs and`
-		);
-	} else if (slave.behavioralFlaw === "arrogant") {
-		r.push(`${He} stands up even straighter than before,`);
-		if (hasBothArms(slave)) {
-			r.push(`crossing ${his} arms and`);
-		}
-		r.push(`widening ${his} stance. ${His} arrogance makes obeying commands like this difficult, but that is not your concern. You give ${him} a look that tells ${him} that pain will await if ${he} does not obey. ${He}`);
-	} else if (slave.behavioralQuirk === "confident") {
-		r.push(`${He} confidently moves to obey. ${He}`);
-	} else if (slave.behavioralFlaw === "liberated") {
-		r.push(`${He} stands up even straighter than before,`);
-		if (hasBothArms(slave)) {
-			r.push(`crossing ${his} arms and`);
-		}
-		r.push(
-			`widening ${his} stance.`,
-			Spoken(slave, `"I am not some animal,"`),
-			`${he} protests,`,
-			Spoken(slave, `"I am a free ${woman}."`),
-			`You laugh at ${his} continued delusions. Liberated ${womenU} have no place in a Free City. You remind ${him} that pain awaits ${him} should ${he} defy you further and ${he}`
-		);
-	} else if (slave.behavioralQuirk === "advocate") {
-		r.push(`${He} smiles at the demonstration of ${his} rightful place as a lowly slave. ${He}`);
-	} else if (slave.behavioralFlaw === "odd") {
-		r.push(`${He} sticks ${his} tongue out at you, blowing raspberries in an act of futile defiance. ${He} really is an odd one. ${He}`);
-	} else if (slave.behavioralQuirk === "funny") {
-		r.push(`${He} smiles and turns ${his} butt to you, swaying it cutely as ${his} silly way of acknowledging your command. ${He}`);
-	} else {
-		r.push(`${He}`);
+		return text.join(' ');
 	}
 
-	if (slave.devotion < -20) {
-		if (slave.trust < -50) {
-			r.push(`drops terrified to the ground.`);
-		} else {
-			if (!canTalk(slave)) {
-				r.push(`gestures`);
-			} else if (SlaveStatsChecker.checkForLisp(slave)) {
-				r.push(`lisps`);
-			} else {
-				r.push(`declares`);
-			}
-			r.push(`angrily that slavery is wrong and ${he} will not bow. You look at your assistant who silently summons two other, more obedient slaves from their duties.`);
-			if (slave.piercing.nipple.weight > 1) {
-				r.push(`You reach out and grab ${him} by ${his} nipple chain, pulling ${him} in harshly. ${He} yelps in pain, but knows better than to pull away.`);
-			} else if (slave.piercing.nose.weight > 1) {
-				r.push(`You reach out and grab ${him} by ${his} nose ring, pulling ${him} in harshly. ${He} yelps in pain, but knows better than to pull away.`);
-			} else {
-				r.push(`You reach out and grab ${him} firmly by the collar.`);
-			}
-			r.push(`"One more chance, slut." By now, the other slaves have arrived and are standing loyally by your side. Your loyal slaves force ${him} to`);
-			if (hasAnyLegs(slave)) {
-				r.push(`${his} ${knees}.`);
+	function consummation() {
+		const text = [];
+
+		if (slave.devotion >= -20) {
+			text.push(`${He} begins to undress with`);
+
+			if (slave.skill.entertainment >= 100) {
+				text.push(`masterful skill, teasing and taunting all the way down. ${He} rolls ${his} hips and most sexual parts as ${he} removes ${his} clothing.`);
+			} else if (slave.skill.entertainment >= 80) {
+				text.push(`arousing skill. Even though the goal is just to get ${him} naked, your slave knows that ${his} job is to entertain you with ${his} every move.`);
+			} else if (slave.skill.entertainment >= 50) {
+				text.push(`notable skill. ${He} takes the opportunity to give you a light strip tease as ${he} undresses.`);
+			} else if (slave.skill.entertainment >= 20) {
+				text.push(`a decent effort. ${He} isn't your most entertaining slave, but ${he} still makes an effort to arouse you with ${his} undressing.`);
+			} else if (slave.skill.entertainment >= 9) {
+				text.push(`some effort to be sexy. ${His} moves are less than skillful and the undressing is more pragmatic than arousing.`);
 			} else {
-				r.push(`the ground.`);
+				text.push(`no effort to be sexy. ${He} has no entertainment skill, and the only goal of ${his} actions is to go from clothed to naked.`);
 			}
 		}
-		r.push(`"Head at crotch level," you clarify. "Remember your purpose."`); // Rewrite to remove player voice?
-	} else if (slave.devotion < 20) {
-		r.push(`is not enthusiastic, but is obedient enough to go down without much threat of discipline.`);
-	} else if (slave.devotion > 20) {
-		if (slave.fetishKnown === 1) {
+
+		if (slave.fetishStrength > 60) {
 			switch (slave.fetish) {
 				case "submissive":
-					r.push(`bows ${his} head and humbly assumes ${his} rightful position at ${his} ${getWrittenTitle(slave)}'s feet.`);
-					break;
-				case "dom":
-					r.push(`would rather be standing by your side making your other sluts bow, but ${he} still knows that you are ${his} ${getWrittenTitle(slave)}.`);
-					break;
-				case "sadist":
-					r.push(`would rather be pushing one of your other whores painfully to their knees, but ${he} still obeys.`);
-					break;
-				case "masochist":
-					r.push(`waits just long enough to receive a disciplinary slap, making ${him} blush with arousal as ${he} kneels before you.`);
-					break;
-				case "cumslut":
-					r.push(`is excited to be closer to your`);
-					if (canTaste(slave)) {
-						r.push(`delicious`);
-					} else {
-						r.push(`heavenly`);
-					}
-					r.push(`crotch, and hurries to match ${his} eyes to your`);
-					if (V.PC.dick > 0) {
-						r.push(`package.`);
-					} else {
-						r.push(`crotch.`);
-					}
-					break;
-				case "humiliation":
-					r.push(`makes a big show of it as ${he} lowers ${himself} dramatically before you.`);
-					break;
-				case "buttslut":
-					r.push(`leans heavily forward so that ${his} ass sticks out ridiculously far as ${he}`);
-					if (hasAnyLegs(slave)) {
-						r.push(`bends ${his} ${knees} and`);
-					}
-					r.push(`goes to the floor.`);
-					break;
-				case "pregnancy":
-					r.push(`obeys your command and goes to`);
-					if (hasBothLegs(slave)) {
-						r.push(`${his} knees.`);
+					text.push(`As ${he} begins to strip you grab ${him} without warning and begin to tear off ${his} clothes. Your slave expected you to allow ${him} to obey your command, and so ${he} is initially taken aback by the sudden force but ${his} submissive nature keeps ${him} from resisting. ${He} is such a submissive slut that you feel obligation to push ${his} status even further. You bind ${his} arms tightly behind ${his} back in a leather monoglove, lacing it tighter until ${his} elbows are touching. ${He} gives a soft whimper, but you both know that this is for your benefit and not a protest.`);
+
+					if (slave.piercing.nipple.weight >= 1) {
+						text.push(`You then retrieve heavy bells and attach them to ${his} nipple rings.`);
 					} else {
-						r.push(`the floor.`);
+						text.push(`You reach into your pocket and retrieve two weighted and belled nipple clamps, attaching them tightly to your slave's delicate nipples.`);
 					}
+
+					text.push(`You tell ${him} to bounce so that they jingle, reminding ${him} of ${his} status.`);
+
 					break;
-				case "boobs":
-					r.push(`pulls ${his} shoulders back strongly while leaning far enough forward to drag ${his}`);
-					if (slave.boobs >= 10000) {
-						r.push(`weighty mammaries`);
-					} else if (slave.boobs >= 2000) {
-						r.push(`cumbersome udders`);
-					} else if (slave.boobs >= 1000) {
-						r.push(`massive slave tits`);
-					} else if (slave.boobs >= 800) {
-						r.push(`forward-thrust breasts`);
-					} else if (slave.boobs >= 500) {
-						r.push(`meager chest`);
-					} else if (slave.boobs <= 400) {
-						r.push(`pathetic slave boobs`);
-					} else {
-						r.push(`tits`);
-					}
-					r.push(`across your body as ${he} goes down.`);
+				case "masochist":
+					text.push(`Once ${he} is fully exposed you give ${him} a firm slap across the tits. ${He}'s a masochist and relishes the pain with sexual arousal. You ask your painslut if ${he} deserves to be punished. ${Spoken(slave, `"Oh yes, ${slave.rudeTitle === 1 ? PoliteRudeTitle(slave) : Master}. Please punish your little slut."`)} Sensing that your slave is getting too much enjoyment from ${his} beating, you cease.`);
+
 					break;
-				default:
-					r.push(`obeys your command and goes to`);
-					if (hasBothLegs(slave)) {
-						r.push(`${his} knees.`);
-					} else {
-						r.push(`the floor.`);
-					}
 			}
-		} else {
-			r.push(`obeys your command and goes to`);
-			if (hasBothLegs(slave)) {
-				r.push(`${his} knees.`);
+		}
+
+		text.push(`You stare at the naked figure standing before you.`);
+
+		if (canSee(slave)) {
+			if (slave.boobsTat === "rude words") {
+				text.push(`The words on ${his} chest stand out at you. You ask ${him} what ${his} tits say. ${Spoken(slave, `"Fuckslave,"`)} ${he} replies. You ask if that's what ${he} is.`);
+
+				if (slave.behavioralFlaw === "liberated") {
+					text.push(`${Spoken(slave, `"I'm nobody's property. I'm a free ${woman}!"`)} ${he} shoots back. ${Spoken(slave, `"We shall see," you reply.`)}`);
+				} else if (slave.devotion < -20) {
+					text.push(`${He} does ${his} best to shake ${his} head.`);
+				} else {
+					text.push(Spoken(slave, `"Yes ${Master}, that's what I am."`));
+				}
+			} else if (slave.boobsTat === "possessive") {
+				text.push(`The words on ${his} chest stand out at you. You ask ${him} what ${his} tits say. ${Spoken(slave, `"It's your personal symbol,"`)} ${he} replies. You ask if that's what ${he} is.`);
+				if (slave.behavioralFlaw === "liberated") {
+					text.push(Spoken(slave, `"I'm nobody's property. I'm a free ${woman}!" ${he} shoots back. ${Spoken(slave, `"We shall see," you reply.`)}`));
+				} else if (slave.devotion < -20) {
+					text.push(`${He} does ${his} best to shake ${his} head.`);
+				} else {
+					text.push(Spoken(slave, `"Yes, ${Master} that's what I am."`));
+				}
+			} else if (slave.boobsTat === "degradation") {
+				text.push(`The words on ${his} chest stand out at you. You ask ${him} what ${his} tits say. " ${Spoken(slave, `${Master}'s Bitch,"`)} ${he} replies. You ask if that's what ${he} is.`);
+
+				if (slave.behavioralFlaw === "liberated") {
+					text.push(Spoken(slave, `"I'm nobody's property. I'm a free ${woman}!" ${he} shoots back. ${Spoken(slave, `"We shall see," you reply.`)}`));
+				} else if (slave.devotion < -20) {
+					text.push(`${He} does ${his} best to shake ${his} head.`);
+				} else {
+					text.push(Spoken(slave, `"Yes ${Master}, that's what I am."`));
+				}
 			} else {
-				r.push(`the floor.`);
+				text.push(`${His} body belongs to you, and your slave needs to remember that.`);
 			}
-		}
-	}
-	if (slave.devotion < -20) {
-		r.push(`The other slaves guide ${him} to adjust ${his} posture so ${his} eyes are directly in line with your`);
-		if (V.PC.dick > 0) {
-			r.push(`package.`);
 		} else {
-			r.push(`crotch.`);
+			text.push(`${His} body belongs to you, and your slave needs to remember that.`);
 		}
-	} else {
-		r.push(`${He} kneels so that ${his} eyes are directly level with your`);
-		if (V.PC.dick > 0) {
-			r.push(`package.`);
+
+		text.push(`You then tell your slave to kneel at your feet.`);
+
+		if (slave.behavioralFlaw === "bitchy") {
+			text.push(`${He} rolls ${his} eyes at you. ${Spoken(slave, `"Whatever,"`)} ${he} scoffs and`);
+		} else if (slave.behavioralFlaw === "arrogant") {
+			text.push(`${He} stands up even straighter than before,`);
+
+			if (hasBothArms(slave)) {
+				text.push(`crossing ${his} arms and`);
+			}
+
+			text.push(`widening ${his} stance. ${His} arrogance makes obeying commands like this difficult, but that is not your concern. You give ${him} a look that tells ${him} that pain will await if ${he} does not obey. ${He}`);
+		} else if (slave.behavioralQuirk === "confident") {
+			text.push(`${He} confidently moves to obey. ${He}`);
+		} else if (slave.behavioralFlaw === "liberated") {
+			text.push(`${He} stands up even straighter than before,`);
+
+			if (hasBothArms(slave)) {
+				text.push(`crossing ${his} arms and`);
+			}
+
+			text.push(`widening ${his} stance. ${Spoken(slave, `"I am not some animal,"`)} ${he} protests, ${Spoken(slave, `"I am a free ${woman}."`)} You laugh at ${his} continued delusions. Liberated ${womenU} have no place in a Free City. You remind ${him} that pain awaits ${him} should ${he} defy you further and ${he}`);
+		} else if (slave.behavioralQuirk === "advocate") {
+			text.push(`${He} smiles at the demonstration of ${his} rightful place as a lowly slave. ${He}`);
+		} else if (slave.behavioralFlaw === "odd") {
+			text.push(`${He} sticks ${his} tongue out at you, blowing raspberries in an act of futile defiance. ${He} really is an odd one. ${He}`);
+		} else if (slave.behavioralQuirk === "funny") {
+			text.push(`${He} smiles and turns ${his} butt to you, swaying it cutely as ${his} silly way of acknowledging your command. ${He}`);
 		} else {
-			r.push(`crotch.`);
+			text.push(`${He}`);
 		}
-	}
 
-	if (V.PC.dick > 0) {
-		if (slave.energy > 50) {
-			r.push(`${He} cant help but stare in lust at your`);
-			if (V.PC.balls >= 30) {
-				r.push(`monstrous, massive pair of watermelon sized balls.`);
-			} else if (V.PC.balls >= 14) {
-				r.push(`enormous, heavy pair of balls.`);
-			} else if (V.PC.balls >= 9) {
-				r.push(`huge pair of balls, bulging like softballs from behind your suit.`);
-			} else if (V.PC.balls >= 5) {
-				r.push(`large pair of balls, swinging heavily as you move.`);
+		if (slave.devotion < -20) {
+			if (slave.trust < -50) {
+				text.push(`drops terrified to the ground.`);
 			} else {
-				r.push(`manly package.`);
+				if (!canTalk(slave)) {
+					text.push(`gestures`);
+				} else if (SlaveStatsChecker.checkForLisp(slave)) {
+					text.push(`lisps`);
+				} else {
+					text.push(`declares`);
+				}
+
+				text.push(`angrily that slavery is wrong and ${he} will not bow. You look at your assistant who silently summons two other, more obedient slaves from their duties.`);
+
+				if (slave.piercing.nipple.weight > 1) {
+					text.push(`You reach out and grab ${him} by ${his} nipple chain, pulling ${him} in harshly. ${He} yelps in pain, but knows better than to pull away.`);
+				} else if (slave.piercing.nose.weight > 1) {
+					text.push(`You reach out and grab ${him} by ${his} nose ring, pulling ${him} in harshly. ${He} yelps in pain, but knows better than to pull away.`);
+				} else {
+					text.push(`You reach out and grab ${him} firmly by the collar.`);
+				}
+
+				text.push(`"One more chance, slut." By now, the other slaves have arrived and are standing loyally by your side. Your loyal slaves force ${him} to`);
+
+				if (hasAnyLegs(slave)) {
+					text.push(`${his} ${knees}.`);
+				} else {
+					text.push(`the ground.`);
+				}
 			}
-		} else if (V.PC.scrotum > 0) {
-			r.push(`Your balls loom directly in front of ${his} face.`);
-		}
-	}
 
-	r.push(`Now kneeling at your feet naked before you, your slave waits for ${his} ${getWrittenTitle(slave)}'s command. You take some time to survey the slut's properly displayed body.`);
+			text.push(`"Head at crotch level," you clarify. "Remember your purpose."`); // TODO: remove player voice
+		} else if (slave.devotion < 20) {
+			text.push(`is not enthusiastic, but is obedient enough to go down without much threat of discipline.`);
+		} else if (slave.devotion > 20) {
+			if (slave.fetishKnown === 1) {
+				switch (slave.fetish) {
+					case "submissive":
+						text.push(`bows ${his} head and humbly assumes ${his} rightful position at ${his} ${getWrittenTitle(slave)}'s feet.`);
+						break;
+					case "dom":
+						text.push(`would rather be standing by your side making your other sluts bow, but ${he} still knows that you are ${his} ${getWrittenTitle(slave)}.`);
+						break;
+					case "sadist":
+						text.push(`would rather be pushing one of your other whores painfully to their knees, but ${he} still obeys.`);
+						break;
+					case "masochist":
+						text.push(`waits just long enough to receive a disciplinary slap, making ${him} blush with arousal as ${he} kneels before you.`);
+						break;
+					case "cumslut":
+						text.push(`is excited to be closer to your`);
 
-	if (slave.butt > 6) {
-		r.push(`${His} massive ass is so huge that ${he} it squishes around ${his} ${hasBothLegs(slave) ? `heels` : `heel`}, almost reaching the floor.`);
-	} else if (slave.butt > 4) {
-		r.push(`${His} ${either("ass", "rear end")} is so round and large it rolls out from ${his} back in two perfect mounds. The cheeks are so thick it forms a perfect crevice between them, more than a couple`);
-		if (V.showInches === 2) {
-			r.push(`inches`);
-		} else {
-			r.push(`centimeters`);
-		}
-		r.push(`deep.`);
-	} else if (slave.butt > 2) {
-		r.push(`${His} nice ${either("plump", "thick")} ${either("ass", "butt")} curves out noticeably, even while ${he} sits on ${his} ${knees}.`);
-	} else {
-		r.push(`${His} cute and tight ass rests gently on ${his} ${hasBothLegs(slave) ? `ankles` : `ankle`}.`);
-	}
+						if (canTaste(slave)) {
+							text.push(`delicious`);
+						} else {
+							text.push(`heavenly`);
+						}
 
+						text.push(`crotch, and hurries to match ${his} eyes to your`);
 
-	if (slave.energy > 95) {
-		r.push(`${His} eyes fill with lust at the helplessness of kneeling at your crotch.`);
-	}
-	if (slave.fetishKnown === 1) {
-		if (slave.fetishStrength > 60) {
-			switch (slave.fetish) {
-				case "submissive":
-					r.push(`${He} keeps ${his} eyes down and poises ${his} body to be fully available to ${his} ${getWrittenTitle(slave)}, trying to model for you the image of the perfect submissive.`);
-					break;
-				case "dom":
-					r.push(`Despite ${his} kneeling stature, ${his} back is straight and shoulders back.`);
-					break;
-				case "masochist":
-					r.push(`${He} positions ${himself} uncomfortably, bringing visual pleasure to you and pain to ${himself}. ${He} accentuates ${his} most sensitive parts, inviting you to slap or spank them.`);
-					break;
-				case "cumslut": {
-					r.push(`${he} goes to ${his} ${knees}, all the while staring at your`);
-					const pcCrotch = [];
-					if (V.PC.dick !== 0) {
-						pcCrotch.push(`manly bulge`);
-					}
-					if (V.PC.vagina !== -1) {
-						pcCrotch.push(`feminine mound`);
-					}
-					r.push(`${toSentence(pcCrotch)}.`);
-					break;
+						if (V.PC.dick > 0) {
+							text.push(`package.`);
+						} else {
+							text.push(`crotch.`);
+						}
+						break;
+					case "humiliation":
+						text.push(`makes a big show of it as ${he} lowers ${himself} dramatically before you.`);
+						break;
+					case "buttslut":
+						text.push(`leans heavily forward so that ${his} ass sticks out ridiculously far as ${he}`);
+
+						if (hasAnyLegs(slave)) {
+							text.push(`bends ${his} ${knees} and`);
+						}
+
+						text.push(`goes to the floor.`);
+						break;
+					case "pregnancy":
+						text.push(`obeys your command and goes to`);
+
+						if (hasBothLegs(slave)) {
+							text.push(`${his} knees.`);
+						} else {
+							text.push(`the floor.`);
+						}
+
+						break;
+					case "boobs":
+						text.push(`pulls ${his} shoulders back strongly while leaning far enough forward to drag ${his}`);
+
+						if (slave.boobs >= 10000) {
+							text.push(`weighty mammaries`);
+						} else if (slave.boobs >= 2000) {
+							text.push(`cumbersome udders`);
+						} else if (slave.boobs >= 1000) {
+							text.push(`massive slave tits`);
+						} else if (slave.boobs >= 800) {
+							text.push(`forward-thrust breasts`);
+						} else if (slave.boobs >= 500) {
+							text.push(`meager chest`);
+						} else if (slave.boobs <= 400) {
+							text.push(`pathetic slave boobs`);
+						} else {
+							text.push(`tits`);
+						}
+
+						text.push(`across your body as ${he} goes down.`);
+						break;
+					default:
+						text.push(`obeys your command and goes to`);
+
+						if (hasBothLegs(slave)) {
+							text.push(`${his} knees.`);
+						} else {
+							text.push(`the floor.`);
+						}
+				}
+			} else {
+				text.push(`obeys your command and goes to`);
+
+				if (hasBothLegs(slave)) {
+					text.push(`${his} knees.`);
+				} else {
+					text.push(`the floor.`);
 				}
-				case "humiliation":
-					r.push(`${He} eagerly takes to this humiliating position, hoping to demonstrate ${his} willingness to be degraded by ${his} ${getWrittenTitle(slave)}.`);
-					break;
-				case "buttslut":
-					r.push(`${He} positions ${himself}, sticking ${his} butt out as far as ${he} can manage, hoping to draw your attention to ${his} favorite area.`);
-					break;
-				case "boobs":
-					r.push(`${he} kneels with ${his} back strongly arching far back and diligently works to touch ${his} elbows behind ${his} back to best display ${his}`);
-					if (slave.boobs >= 10000) {
-						r.push(`colossal mammaries`);
-					} else if (slave.boobs >= 2000) {
-						r.push(`gigantic udders`);
-					} else if (slave.boobs >= 1000) {
-						r.push(`massive slave tits`);
-					} else if (slave.boobs >= 800) {
-						r.push(`prominent breasts`);
-					} else if (slave.boobs >= 400) {
-						r.push(`modest chest`);
-					} else if (slave.boobs <= 400) {
-						r.push(`pathetic slave boobs`);
-					}
-					r.push(`for ${his} ${getWrittenTitle(slave)}.`);
-					if (slave.lactation > 0) {
-						r.push(`Milk dribbles down the soft curves of ${his} chest as a further sign of ${his} arousal.`);
-					}
-					r.push(`This is, of course, how all slaves are supposed to kneel, but ${he} takes the pose with added dedication.`);
-					break;
-				default:
-					r.push(`${He} positions ${himself} with ${his} ${knees} spread wide, hoping that you will turn your attention to`);
-					if (canDoVaginal(slave)) {
-						r.push(`${his} wet pussy.`);
-					} else if (canAchieveErection(slave)) {
-						r.push(`${his} hard cock.`);
-					} else {
-						r.push(`${him}.`);
-					}
 			}
 		}
-	}
-	r.push(`You give ${him} permission to speak, and tell ${him} that ${he} may beg ${his} ${getWrittenTitle(slave)}.`);
-
-	if (slave.devotion < -20) {
-		if (slave.trust < -50) {
-			switch (slave.rules.punishment) {
-				case "confinement":
-					r.push(`Your slave simply`);
-					if (hasAnyArms(slave)) {
-						r.push(`presses ${his} ${hands} together and`);
-					}
-					r.push(`begs you not to lock ${him} up in the bad-${girl} box.`);
-					break;
-				case "whipping":
-					r.push(`Your slave simply`);
-					if (hasAnyArms(slave)) {
-						r.push(`presses ${his} ${hands} together and`);
-					}
-					r.push(`begs you not to whip ${him}.`);
-					break;
-				case "chastity":
-					if (slave.energy > 60) {
-						r.push(`Your slave simply presses ${his} ${hands} together and begs you not to take away ${his} next orgasm`);
-					} else {
-						r.push(`Your slave simply asks that you not change ${his} punishment. ${He} fears you, but using chastity as a punishment is not an efficient way to command ${his} obedience, since ${he} has no sexual energy.`);
-					}
-			}
-		} else {
-			if (slave.behavioralFlaw === "bitchy") {
-				r.push(
-					`${He} turns ${his} nose up in utter disgust.`,
-					Spoken(slave, `"Why, to feed your ${girl === "boy" ? `misandristic` : `misogynistic`} ego? Thanks, but no."`),
-					`${He} looks at your other slaves holding ${him} down,`,
-					Spoken(slave, `"Why don't you get one of these mindless cunts to do it? Or are they not hot enough?"`),
-					`${He} is disobedient and bitchy, a bad combo.`);
-			} else if (slave.behavioralFlaw === "arrogant") {
-				r.push(
-					`${He} tries to cock ${his} shoulders back, giving a death glare to the slaves holding ${him} in place,`,
-					Spoken(slave, `"I don't need anything from you,"`),
-					`${he} hisses. ${He} is disobedient and arrogant, a bad combo.`
-				);
-			} else if (slave.behavioralFlaw === "liberated") {
-				r.push(
-					`${He} does ${his} best to spit in your face, but the height difference means ${he} only stains your shirt.`,
-					Spoken(slave, `"I demand you release me!"`),
-					`${he} scowls,`,
-					Spoken(slave, `"Or I'm going to call the police!"`),
-					`You smile at ${his} pathetically outdated worldview. You tell ${him} that's a good idea, since you know how rebellious slaves fare in jail.`
-				);
-			} else if (slave.behavioralFlaw === "odd") {
-				r.push(
-					`${He} purses ${his} lips and bounces on ${his} heels in futile rebellion.`,
-					Spoken(slave, `"Nuh-uh."`),
-					`${he} puffs, shaking ${his} head wildly.`
-				);
+
+		if (slave.devotion < -20) {
+			text.push(`The other slaves guide ${him} to adjust ${his} posture so ${his} eyes are directly in line with your`);
+
+			if (V.PC.dick > 0) {
+				text.push(`package.`);
 			} else {
-				r.push(`${He} simply sits there, struggling against the hands holding ${him} down.`);
+				text.push(`crotch.`);
 			}
-		}
-		r.push(`This is clearly the best you are going to get out of ${him} until ${he} is better trained. You`);
-		if (slave.trust >= -50) {
-			r.push(`signal your loyal slaves to lift ${him} to ${his} feet, and`);
-		}
-		r.push(`send ${him} away for now.`);
-	} else if (slave.devotion < 20) {
-		if (slave.behavioralFlaw === "bitchy") {
-			r.push(
-				`${He} turns ${his} nose up in utter disgust.`,
-				Spoken(slave, `"Why, to feed your ${girl === "boy" ? `misandristic` : `misogynistic`} ego? Thanks, but no."`),
-				`${He} looks at your other slaves holding ${him} down,`,
-				Spoken(slave, `"Why don't you get one of these mindless cunts to do it? Or are they not hot enough?"`),
-				`${He} is disobedient and bitchy, a bad combo.`);
-		} else if (slave.behavioralFlaw === "arrogant") {
-			r.push(
-				`${He} tries to cock ${his} shoulders back, giving a death glare to the slaves holding ${him} in place,`,
-				Spoken(slave, `"I don't need anything from you,"`),
-				`${he} hisses. ${He} is disobedient and arrogant, a bad combo.`
-			);
-		} else if (slave.behavioralFlaw === "liberated") {
-			r.push(`${He} does ${his} best to spit in your face, but the height difference means ${he} only stains your shirt.`,
-				Spoken(slave, `"I demand you release me!"`),
-				`${he} scowls,`,
-				Spoken(slave, `"Or I'm going to call the police!"`),
-				`You smile at ${his} pathetically outdated worldview. You tell ${him} that's a good idea, since you know how rebellious slaves fair in jail.`
-			);
-		} else if (slave.behavioralFlaw === "odd") {
-			r.push(
-				`${He} purses ${his} lips and bounces on ${his} heels in futile rebellion.`,
-				Spoken(slave, `"Nuh-uh."`),
-				`${he} puffs, shaking ${his} head wildly.`
-			);
-		} else if (slave.sexualFlaw === "shamefast") {
-			r.push(
-				`${He} tries to cover ${his} naked body from your gaze`,
-				Spoken(slave, `"Please, can I just put some clothes on?"`)
-			);
 		} else {
-			r.push(
-				`${He} looks up at you with a sudden glimpse of hope, and begins to plead,`,
-				Spoken(slave, `"Please, sir, please set me free. I don't want to be here.`)
-			);
-			if (slave.energy < 50) {
-				r.push(Spoken(slave, `I have no desire for sex. I don't want to be your toy! Please let me go."`));
+			text.push(`${He} kneels so that ${his} eyes are directly level with your`);
+
+			if (V.PC.dick > 0) {
+				text.push(`package.`);
 			} else {
-				r.push(Spoken(slave, `I might even come back to share consensual love with you. I just don't want to be property. Please, let me go."`));
+				text.push(`crotch.`);
 			}
 		}
-		r.push(`You tell your slave to rise to ${his} feet. Even though ${he} desired the impossible, it wasn't a total waste. You feel as though you have a pretty good understanding of where your slave stands. You send ${him} away with ${his} request denied, and you resolve to break ${him} more in the coming weeks.`);
-	} else if (slave.devotion <= 60) {
-		r.push(`Your slave looks at ${his} ${getWrittenTitle(slave)} with obedient eyes.`);
-	} else if (slave.devotion <= 100) {
-		r.push(`Your devoted slave takes the begging position,`);
-		if (slave.fetish !== "submissive") {
-			r.push(`${he} even brings ${his} ${hands} up like a dog's paws.`);
-		} else {
-			if (slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-				r.push(`and ${he} bows ${his} head in total submission.`);
-				if (slave.piercing.nipple.weight > 0) {
-					r.push(`The armbinder thrusts ${his} tits out nicely, and ${his} nipple rings are pulled tight by the weighted bells weighing them down.`);
-				} else if (slave.piercing.nipple.weight > 1) {
-					r.push(`The armbinder thrusts ${his} tits out nicely, and ensures that ${his} nipple chains are pulled tight by the angle of ${his} shoulders. The bells on ${his} nipple piercings jungle sweetly as ${he} breathes.`);
+
+		if (V.PC.dick > 0) {
+			if (slave.energy > 50) {
+				text.push(`${He} cant help but stare in lust at your`);
+				if (V.PC.balls >= 30) {
+					text.push(`monstrous, massive pair of watermelon sized balls.`);
+				} else if (V.PC.balls >= 14) {
+					text.push(`enormous, heavy pair of balls.`);
+				} else if (V.PC.balls >= 9) {
+					text.push(`huge pair of balls, bulging like softballs from behind your suit.`);
+				} else if (V.PC.balls >= 5) {
+					text.push(`large pair of balls, swinging heavily as you move.`);
 				} else {
-					r.push(`The armbinder thrusts ${his} tits out nicely and ${his} nipples are now red from the clamps pressing down hard on ${his} sensitive flesh. Every painful shudder makes the bells jungle ever so sweetly.`);
+					text.push(`manly package.`);
 				}
-			} else {
-				r.push(`${he} even brings ${his} ${hands} up like a dog's paws.`);
+			} else if (V.PC.scrotum > 0) {
+				text.push(`Your balls loom directly in front of ${his} face.`);
 			}
 		}
 
-		r.push(Spoken(slave, `"Yes Master. Thank you, ${Master}."`));
-		r.push(`${He} is fully subservient to you, and would do anything to please you.`);
-	}
+		text.push(`Now kneeling at your feet naked before you, your slave waits for ${his} ${getWrittenTitle(slave)}'s command. You take some time to survey the slut's properly displayed body.`);
+
+		if (slave.butt > 6) {
+			text.push(`${His} massive ass is so huge that ${he} it squishes around ${his} ${hasBothLegs(slave) ? `heels` : `heel`}, almost reaching the floor.`);
+		} else if (slave.butt > 4) {
+			text.push(`${His} ${either("ass", "rear end")} is so round and large it rolls out from ${his} back in two perfect mounds. The cheeks are so thick it forms a perfect crevice between them, more than a couple`);
+
+			if (V.showInches === 2) {
+				text.push(`inches`);
+			} else {
+				text.push(`centimeters`);
+			}
+
+			text.push(`deep.`);
+		} else if (slave.butt > 2) {
+			text.push(`${His} nice ${either("plump", "thick")} ${either("ass", "butt")} curves out noticeably, even while ${he} sits on ${his} ${knees}.`);
+		} else {
+			text.push(`${His} cute and tight ass rests gently on ${his} ${hasBothLegs(slave) ? `ankles` : `ankle`}.`);
+		}
 
-	if (slave.devotion > 20) {
-	/* eventually plan to make a string of Paraphilia text, which will be stronger versions of their fetish counterparts. */
+		if (slave.energy > 95) {
+			text.push(`${His} eyes fill with lust at the helplessness of kneeling at your crotch.`);
+		}
 		if (slave.fetishKnown === 1) {
 			if (slave.fetishStrength > 60) {
 				switch (slave.fetish) {
 					case "submissive":
-						r.push(
-							`${He} adjusts ${his} monoglove behind ${his} back, jingling ${his} nipple bells as ${he} does.`,
-							Spoken(slave, `"Please ${Master},"`),
-							`${he} begs with genuine humility,`,
-							Spoken(slave, `"please use your slave in whatever way you see fit. This slave has no purpose but to please ${his} ${Master}."`)
-						);
+						text.push(`${He} keeps ${his} eyes down and poises ${his} body to be fully available to ${his} ${getWrittenTitle(slave)}, trying to model for you the image of the perfect submissive.`);
 						break;
 					case "dom":
-						r.push(
-							`${He} looks up at you. Even from ${his} kneeling position ${his} eyes carry confident domination.`,
-							Spoken(slave, `"${Master}, I know my place is beneath you. Give me the authority to lord over your other slaves and I will force them to serve you as I do."`)
-						);
+						text.push(`Despite ${his} kneeling stature, ${his} back is straight and shoulders back.`);
 						break;
 					case "masochist":
-						r.push(
-							Spoken(slave, `"I know I haven't disobeyed,"`),
-							`${he} begins,`,
-							Spoken(slave, `"but I just need to be punished."`),
-							`You smile down at your little painslut, running your finger along ${his} chin.`,
-							Spoken(slave, `"Please ${Master}, beat me. Beat my ass until it's red and clamp my nipples until they bleed. Please! I need to feel your strength!"`)
-						);
+						text.push(`${He} positions ${himself} uncomfortably, bringing visual pleasure to you and pain to ${himself}. ${He} accentuates ${his} most sensitive parts, inviting you to slap or spank them.`);
 						break;
-					case "cumslut":
-						r.push(`Your little cumslut can't stop staring at your`);
-						if (V.PC.balls >= 30) {
-							r.push(`monstrous, massive pair of watermelon sized balls.`);
-						} else if (V.PC.balls >= 14) {
-							r.push(`enormous, heavy pair of balls.`);
-						} else if (V.PC.balls >= 9) {
-							r.push(`huge pair of balls, bulging like softballs from behind your suit.`);
-						} else if (V.PC.balls >= 5) {
-							r.push(`large pair of balls, swinging heavily as you move.`);
-						} else {
-							r.push(`crotch.`);
-						}
-						r.push(
-							`Drool begins to drip from ${his} lips, and you have to remind your slave that ${he} is here to beg.`,
-							Spoken(slave, `"${Master},"`),
-							`${he} breathes heavily,`,
-							Spoken(slave, `"Please let me`)
-						);
+					case "cumslut": {
+						text.push(`${he} goes to ${his} ${knees}, all the while staring at your`);
+
+						const pcCrotch = [];
+
 						if (V.PC.dick !== 0) {
-							r.push(Spoken(slave, `suck your magnificent`));
-							if (V.PC.vagina !== -1) {
-								r.push(Spoken(slave, `cock and eat you out,`));
-							} else {
-								r.push(Spoken(slave, `cock,`));
-							}
-						} else {
-							r.push(Spoken(slave, `eat your delicious pussy,`));
+							pcCrotch.push(`manly bulge`);
+						}
+						if (V.PC.vagina !== -1) {
+							pcCrotch.push(`feminine mound`);
 						}
-						r.push(Spoken(slave, `please."`));
-						r.push(`You smile at the little cocksucker, so eager to please.`);
+
+						text.push(`${toSentence(pcCrotch)}.`);
 						break;
+					}
 					case "humiliation":
-						r.push(`${He} sits so that ${his} body is on full display,`);
-						r.push(Spoken(slave, `"Please ${Master}, use me and humiliate me. Take me out to the public square so that everyone can see you overpower me."`));
+						text.push(`${He} eagerly takes to this humiliating position, hoping to demonstrate ${his} willingness to be degraded by ${his} ${getWrittenTitle(slave)}.`);
 						break;
 					case "buttslut":
-						r.push(
-							`${He} positions ${his} back so ${his} ass sticks out even further`,
-							Spoken(slave, `"${Master},"`),
-							`${he} begs,`,
-							Spoken(slave, `"use my ass! ${(slave.sexualQuirk === "painal queen") ? `Make me squeal! ` : ``}I just need your cock in my most useful fuckhole, please!"`)
-						);
+						text.push(`${He} positions ${himself}, sticking ${his} butt out as far as ${he} can manage, hoping to draw your attention to ${his} favorite area.`);
 						break;
 					case "boobs":
-						r.push(`${He}`);
-						if (!hasAnyArms(slave)) {
-							r.push(`leans ${his} head back and juts out ${his} tits, raising`);
-						} else {
-							r.push(`takes ${his} ${hands} and presses ${his} tits together, lifting`);
+						text.push(`${he} kneels with ${his} back strongly arching far back and diligently works to touch ${his} elbows behind ${his} back to best display ${his}`);
+
+						if (slave.boobs >= 10000) {
+							text.push(`colossal mammaries`);
+						} else if (slave.boobs >= 2000) {
+							text.push(`gigantic udders`);
+						} else if (slave.boobs >= 1000) {
+							text.push(`massive slave tits`);
+						} else if (slave.boobs >= 800) {
+							text.push(`prominent breasts`);
+						} else if (slave.boobs >= 400) {
+							text.push(`modest chest`);
+						} else if (slave.boobs <= 400) {
+							text.push(`pathetic slave boobs`);
 						}
-						r.push(`them to display for you ${his} primary purpose in life.`);
+
+						text.push(`for ${his} ${getWrittenTitle(slave)}.`);
+
 						if (slave.lactation > 0) {
-							r.push(`More milk`);
-							if (!hasAnyArms(slave)) {
-								r.push(`dribbles`);
-							} else {
-								r.push(`squirts`);
-							}
-							r.push(`from each teat as ${he} bears them.`);
+							text.push(`Milk dribbles down the soft curves of ${his} chest as a further sign of ${his} arousal.`);
 						}
-						r.push(Spoken(slave, `"I beg of you, ${Master}, I need you to use my tits. Suck them, squeeze them, fuck them, I cannot cum without you using my slave tits! I am nothing more than a ${canWalk(slave) ? `walking ` : ``}tit-carrier, and my only purpose is to offer these breasts to you."`));
+
+						text.push(`This is, of course, how all slaves are supposed to kneel, but ${he} takes the pose with added dedication.`);
 						break;
-					case "pregnancy":
-						r.push(`${He} begins to`);
-						if (hasAnyArms(slave)) {
-							r.push(`caress`);
+					default:
+						text.push(`${He} positions ${himself} with ${his} ${knees} spread wide, hoping that you will turn your attention to`);
+
+						if (canDoVaginal(slave)) {
+							text.push(`${his} wet pussy.`);
+						} else if (canAchieveErection(slave)) {
+							text.push(`${his} hard cock.`);
 						} else {
-							r.push(`stick out`);
+							text.push(`${him}.`);
+						}
+				}
+			}
+		}
+
+		text.push(`You give ${him} permission to speak, and tell ${him} that ${he} may beg ${his} ${getWrittenTitle(slave)}.`);
+
+		if (slave.devotion < -20) {
+			if (slave.trust < -50) {
+				switch (slave.rules.punishment) {
+					case "confinement":
+						text.push(`Your slave simply`);
+
+						if (hasAnyArms(slave)) {
+							text.push(`presses ${his} ${hands} together and`);
 						}
-						r.push(
-							`${his} stomach.`,
-							Spoken(slave, `"Use me as your breeder, ${Master}, please! I just want to be filled with your seed forever!"`)
-						);
+
+						text.push(`begs you not to lock ${him} up in the bad-${girl} box.`);
 						break;
-					default:
-						r.push(`${He} kneels`);
-						if (hasBothLegs(slave)) {
-							r.push(`with ${his} legs far spread.`);
+					case "whipping":
+						text.push(`Your slave simply`);
+
+						if (hasAnyArms(slave)) {
+							text.push(`presses ${his} ${hands} together and`);
+						}
+
+						text.push(`begs you not to whip ${him}.`);
+						break;
+					case "chastity":
+						if (slave.energy > 60) {
+							text.push(`Your slave simply presses ${his} ${hands} together and begs you not to take away ${his} next orgasm`);
 						} else {
-							r.push(`on the floor.`);
+							text.push(`Your slave simply asks that you not change ${his} punishment. ${He} fears you, but using chastity as a punishment is not an efficient way to command ${his} obedience, since ${he} has no sexual energy.`);
 						}
-						r.push(Spoken(slave, `"Use my fuckhole ${Master}, I beg you. Please, I need you to fuck me!"`));
 				}
 			} else {
-				r.push(
-					Spoken(slave, `"${Master}, I exist to serve you."`),
-					`${He} ${say}s,`,
-					Spoken(slave, `"I have no other purpose in life. I beg of you, please never let me leave your service. Let me wait on you forever. I swear I will always be obedient. Let me cook your meals, clean your penthouse, care for your other slaves, even make me a cow. I don't care, as long as I'm here serving you."`),
-					`${He} knows that ${his} rightful place is a slave, and ${he} is dedicated to living out that role to the fullest.`
-				);
-				if (slave.behavioralQuirk === "advocate") {
-					r.push(Spoken(slave, `"I see now," ${he} continues, "that slavery really is a ${woman}'s rightful place. ${He} has no purpose except to serve ${his} ${Master}."`));
+				if (slave.behavioralFlaw === "bitchy") {
+					text.push(`${He} turns ${his} nose up in utter disgust. ${Spoken(slave, `"Why, to feed your ${girl === "boy" ? `misandristic` : `misogynistic`} ego? Thanks, but no."`)} ${He} looks at your other slaves holding ${him} down, ${Spoken(slave, `"Why don't you get one of these mindless cunts to do it? Or are they not hot enough?"`)} ${He} is disobedient and bitchy, a bad combo.`);
+				} else if (slave.behavioralFlaw === "arrogant") {
+					text.push(`${He} tries to cock ${his} shoulders back, giving a death glare to the slaves holding ${him} in place, ${Spoken(slave, `"I don't need anything from you,"`)} ${he} hisses. ${He} is disobedient and arrogant, a bad combo.`);
+				} else if (slave.behavioralFlaw === "liberated") {
+					text.push(`${He} does ${his} best to spit in your face, but the height difference means ${he} only stains your shirt. ${Spoken(slave, `"I demand you release me!"`)} ${he} scowls, ${Spoken(slave, `"Or I'm going to call the police!"`)} You smile at ${his} pathetically outdated worldview. You tell ${him} that's a good idea, since you know how rebellious slaves fare in jail.`);
+				} else if (slave.behavioralFlaw === "odd") {
+					text.push(`${He} purses ${his} lips and bounces on ${his} heels in futile rebellion. ${Spoken(slave, `"Nuh-uh."`)} ${he} puffs, shaking ${his} head wildly.`);
+				} else {
+					text.push(`${He} simply sits there, struggling against the hands holding ${him} down.`);
 				}
 			}
-		} else {
-			r.push(
-				Spoken(slave, `"${Master}, I exist to serve you."`),
-				`${He} says,`,
-				Spoken(slave, `"I have no other purpose in life. I beg of you, please never let me leave your service. Let me wait on you forever. I swear I will always be obedient. Let me cook your meals, clean your penthouse, care for your other slaves, even make me a cow. I don't care, as long as I'm here serving you."`),
-				`${He} knows that ${his} rightful place is a slave, and ${he} is dedicated to living out that role to the fullest.`
-			);
-			if (slave.behavioralQuirk === "advocate") {
-				r.push(
-					Spoken(slave, `"I see now,"`),
-					`${he} continues,`,
-					Spoken(slave, `"that slavery really is a ${woman}'s rightful place. ${He} has no purpose except to serve ${his} ${Master}."`)
-				);
+
+			text.push(`This is clearly the best you are going to get out of ${him} until ${he} is better trained. You`);
+
+			if (slave.trust >= -50) {
+				text.push(`signal your loyal slaves to lift ${him} to ${his} feet, and`);
+			}
+
+			text.push(`send ${him} away for now.`);
+		} else if (slave.devotion < 20) {
+			if (slave.behavioralFlaw === "bitchy") {
+				text.push(`${He} turns ${his} nose up in utter disgust. ${Spoken(slave, `"Why, to feed your ${girl === "boy" ? `misandristic` : `misogynistic`} ego? Thanks, but no."`)} ${He} looks at your other slaves holding ${him} down, ${Spoken(slave, `"Why don't you get one of these mindless cunts to do it? Or are they not hot enough?"`)} ${He} is disobedient and bitchy, a bad combo.`);
+			} else if (slave.behavioralFlaw === "arrogant") {
+				text.push(`${He} tries to cock ${his} shoulders back, giving a death glare to the slaves holding ${him} in place, ${Spoken(slave, `"I don't need anything from you,"`)} ${he} hisses. ${He} is disobedient and arrogant, a bad combo.`);
+			} else if (slave.behavioralFlaw === "liberated") {
+				text.push(`${He} does ${his} best to spit in your face, but the height difference means ${he} only stains your shirt. ${Spoken(slave, `"I demand you release me!"`)} ${he} scowls, ${Spoken(slave, `"Or I'm going to call the police!"`)} You smile at ${his} pathetically outdated worldview. You tell ${him} that's a good idea, since you know how rebellious slaves fare in jail.`);
+			} else if (slave.behavioralFlaw === "odd") {
+				text.push(`${He} purses ${his} lips and bounces on ${his} heels in futile rebellion. ${Spoken(slave, `"Nuh-uh."`)} ${he} puffs, shaking ${his} head wildly.`);
+			} else if (slave.sexualFlaw === "shamefast") {
+				text.push(`${He} tries to cover ${his} naked body from your gaze ${Spoken(slave, `"Please, can I just put some clothes on?"`)}`);
+			} else {
+				text.push(`${He} looks up at you with a sudden glimpse of hope, and begins to plead, ${Spoken(slave, `"Please, sir, please set me free. I don't want to be here.`)}`);
+
+				if (slave.energy < 50) {
+					text.push(Spoken(slave, `I have no desire for sex. I don't want to be your toy! Please let me go."`));
+				} else {
+					text.push(Spoken(slave, `I might even come back to share consensual love with you. I just don't want to be property. Please, let me go."`));
+				}
+			}
+
+			text.push(`You tell your slave to rise to ${his} feet. Even though ${he} desired the impossible, it wasn't a total waste. You feel as though you have a pretty good understanding of where your slave stands. You send ${him} away with ${his} request denied, and you resolve to break ${him} more in the coming weeks.`);
+		} else if (slave.devotion <= 60) {
+			text.push(`Your slave looks at ${his} ${getWrittenTitle(slave)} with obedient eyes.`);
+		} else if (slave.devotion <= 100) {
+			text.push(`Your devoted slave takes the begging position,`);
+			if (slave.fetish !== "submissive") {
+				text.push(`${he} even brings ${his} ${hands} up like a dog's paws.`);
+			} else {
+				if (slave.fetishKnown === 1 && slave.fetishStrength > 60) {
+					text.push(`and ${he} bows ${his} head in total submission.`);
+
+					if (slave.piercing.nipple.weight > 0) {
+						text.push(`The armbinder thrusts ${his} tits out nicely, and ${his} nipple rings are pulled tight by the weighted bells weighing them down.`);
+					} else if (slave.piercing.nipple.weight > 1) {
+						text.push(`The armbinder thrusts ${his} tits out nicely, and ensures that ${his} nipple chains are pulled tight by the angle of ${his} shoulders. The bells on ${his} nipple piercings jungle sweetly as ${he} breathes.`);
+					} else {
+						text.push(`The armbinder thrusts ${his} tits out nicely and ${his} nipples are now red from the clamps pressing down hard on ${his} sensitive flesh. Every painful shudder makes the bells jungle ever so sweetly.`);
+					}
+				} else {
+					text.push(`${he} even brings ${his} ${hands} up like a dog's paws.`);
+				}
 			}
+
+			text.push(Spoken(slave, `"Yes Master. Thank you, ${Master}." ${He} is fully subservient to you, and would do anything to please you.`));
 		}
-		r.push(`You smile at your obedient little slave, and agree to grant ${his} request.`);
+
+		if (slave.devotion > 20) {
+			// TODO: eventually plan to make a string of Paraphilia text, which will be stronger versions of their fetish counterparts.
+			if (slave.fetishKnown === 1) {
+				if (slave.fetishStrength > 60) {
+					switch (slave.fetish) {
+						case "submissive":
+							text.push( `${He} adjusts ${his} monoglove behind ${his} back, jingling ${his} nipple bells as ${he} does. ${Spoken(slave, `"Please ${Master},"`)} ${he} begs with genuine humility, ${Spoken(slave, `"please use your slave in whatever way you see fit. This slave has no purpose but to please ${his} ${Master}."`)}`);
+							break;
+						case "dom":
+							text.push( `${He} looks up at you. Even from ${his} kneeling position ${his} eyes carry confident domination. ${Spoken(slave, `"${Master}, I know my place is beneath you. Give me the authority to lord over your other slaves and I will force them to serve you as I do."`)}`);
+							break;
+						case "masochist":
+							text.push (`${Spoken(slave, `"I know I haven't disobeyed,"`)} ${he} begins, ${Spoken(slave, `"but I just need to be punished."`)} You smile down at your little painslut, running your finger along ${his} chin. ${Spoken(slave, `"Please ${Master}, beat me. Beat my ass until it's red and clamp my nipples until they bleed. Please! I need to feel your strength!"`)}`);
+							break;
+						case "cumslut":
+							text.push(`Your little cumslut can't stop staring at your`);
+
+							if (V.PC.balls >= 30) {
+								text.push(`monstrous, massive pair of watermelon sized balls.`);
+							} else if (V.PC.balls >= 14) {
+								text.push(`enormous, heavy pair of balls.`);
+							} else if (V.PC.balls >= 9) {
+								text.push(`huge pair of balls, bulging like softballs from behind your suit.`);
+							} else if (V.PC.balls >= 5) {
+								text.push(`large pair of balls, swinging heavily as you move.`);
+							} else {
+								text.push(`crotch.`);
+							}
+
+							text.push( `Drool begins to drip from ${his} lips, and you have to remind your slave that ${he} is here to beg. ${Spoken(slave, `"${Master},"`)} ${he} breathes heavily, ${Spoken(slave, `"Please let me`)}`);
+
+							if (V.PC.dick !== 0) {
+								text.push(Spoken(slave, `suck your magnificent`));
+								if (V.PC.vagina !== -1) {
+									text.push(Spoken(slave, `cock and eat you out,`));
+								} else {
+									text.push(Spoken(slave, `cock,`));
+								}
+							} else {
+								text.push(Spoken(slave, `eat your delicious pussy,`));
+							}
+
+							text.push(Spoken(slave, `please." You smile at the little cocksucker, so eager to please.`));
+							break;
+						case "humiliation":
+							text.push(`${He} sits so that ${his} body is on full display, ${Spoken(slave, `"Please ${Master}, use me and humiliate me. Take me out to the public square so that everyone can see you overpower me."`)}`);
+							break;
+						case "buttslut":
+							text.push( `${He} positions ${his} back so ${his} ass sticks out even further ${Spoken(slave, `"${Master},"`)} ${he} begs, ${Spoken(slave, `"use my ass! ${(slave.sexualQuirk === "painal queen") ? `Make me squeal! ` : ``}I just need your cock in my most useful fuckhole, please!"`)}`);
+							break;
+						case "boobs":
+							text.push(`${He}`);
+
+							if (!hasAnyArms(slave)) {
+								text.push(`leans ${his} head back and juts out ${his} tits, raising`);
+							} else {
+								text.push(`takes ${his} ${hands} and presses ${his} tits together, lifting`);
+							}
+
+							text.push(`them to display for you ${his} primary purpose in life.`);
+
+							if (slave.lactation > 0) {
+								text.push(`More milk`);
+
+								if (!hasAnyArms(slave)) {
+									text.push(`dribbles`);
+								} else {
+									text.push(`squirts`);
+								}
+
+								text.push(`from each teat as ${he} bears them.`);
+							}
+
+							text.push(Spoken(slave, `"I beg of you, ${Master}, I need you to use my tits. Suck them, squeeze them, fuck them, I cannot cum without you using my slave tits! I am nothing more than a ${canWalk(slave) ? `walking ` : ``}tit-carrier, and my only purpose is to offer these breasts to you."`));
+							break;
+						case "pregnancy":
+							text.push(`${He} begins to`);
+
+							if (hasAnyArms(slave)) {
+								text.push(`caress`);
+							} else {
+								text.push(`stick out`);
+							}
+
+							text.push( `${his} stomach. ${Spoken(slave, `"Use me as your breeder, ${Master}, please! I just want to be filled with your seed forever!"`)}`);
+							break;
+						default:
+							text.push(`${He} kneels`);
+
+							if (hasBothLegs(slave)) {
+								text.push(`with ${his} legs far spread.`);
+							} else {
+								text.push(`on the floor.`);
+							}
+
+							text.push(Spoken(slave, `"Use my fuckhole ${Master}, I beg you. Please, I need you to fuck me!"`));
+					}
+				} else {
+					text.push(Spoken(slave, `"${Master}, I exist to serve you." ${He} ${say}s, ${Spoken(slave, `"I have no other purpose in life. I beg of you, please never let me leave your service. Let me wait on you forever. I swear I will always be obedient. Let me cook your meals, clean your penthouse, care for your other slaves, even make me a cow. I don't care, as long as I'm here serving you." ${He} knows that ${his} rightful place is a slave, and ${he} is dedicated to living out that role to the fullest.`)}`));
+
+					if (slave.behavioralQuirk === "advocate") {
+						text.push(Spoken(slave, `"I see now," ${he} continues, "that slavery really is a ${woman}'s rightful place. ${He} has no purpose except to serve ${his} ${Master}."`));
+					}
+				}
+			} else {
+				text.push(Spoken(slave, `"${Master}, I exist to serve you." ${He} says, ${Spoken(slave, `"I have no other purpose in life. I beg of you, please never let me leave your service. Let me wait on you forever. I swear I will always be obedient. Let me cook your meals, clean your penthouse, care for your other slaves, even make me a cow. I don't care, as long as I'm here serving you."`)} ${He} knows that ${his} rightful place is a slave, and ${he} is dedicated to living out that role to the fullest.`));
+
+				if (slave.behavioralQuirk === "advocate") {
+					text.push(Spoken(slave, `"I see now," ${he} continues, ${Spoken(slave, `"that slavery really is a ${woman}'s rightful place. ${He} has no purpose except to serve ${his} ${Master}."`)}`));
+				}
+			}
+
+			text.push(`You smile at your obedient little slave, and agree to grant ${his} request.`);
+		}
+
+		return text.join(' ');
 	}
 
-	if (random(1, 100) > (100 + slave.devotion)) {
+	function slaveGainsFlaw() {
 		if (slave.fetish !== "submissive" && slave.energy <= 95 && slave.behavioralFlaw !== "liberated") {
-			r.push(`Seeing the humiliating acts your slaves are expected to perform has made ${him} <span class="flaw gain">determined to be free.</span>`);
 			slave.behavioralFlaw = "liberated";
+
+			return `Seeing the humiliating acts your slaves are expected to perform has made ${him} <span class="flaw gain">determined to be free.</span>`;
 		}
-	} else if (random(1, 100) > (110 - slave.devotion)) {
-		if (slave.fetish === "none" && slave.behavioralFlaw !== "liberated") {
-			r.push(`Feeling the joy of kneeling before such a powerful ${getWrittenTitle(slave)}`);
 
-			r.push(`and begging at ${hisP} feet has <span class="fetish gain">encouraged ${him} to be more submissive.</span>`);
+		return ``;
+	}
+
+	function slaveGainsQuirk() {
+		if (slave.fetish === "none" && slave.behavioralFlaw !== "liberated") {
 			slave.fetish = "submissive";
 			slave.fetishKnown = 1;
+
+			return `Feeling the joy of kneeling before such a powerful ${getWrittenTitle(slave)} and begging at ${hisP} feet has <span class="fetish gain">encouraged ${him} to be more submissive.</span>`;
 		}
+
+		return ``;
 	}
-	App.Events.addParagraph(node, r);
-	return node;
 };
diff --git a/src/npc/interaction/fBellyFuck.js b/src/npc/interaction/fBellyFuck.js
index 9456db3fa582b319c5f17227620a98510e586625..5f999e3d31a7f2b6fc8595b34b48eb6cdfd3a767 100644
--- a/src/npc/interaction/fBellyFuck.js
+++ b/src/npc/interaction/fBellyFuck.js
@@ -4,125 +4,177 @@
  * @returns {DocumentFragment}
  */
 App.Interact.fBellyFuck = function(slave) {
-	const node = new DocumentFragment();
-	let r = [];
+	const frag = new DocumentFragment();
 
 	const {
 		He,
 		he, his, him, himself
 	} = getPronouns(slave);
 
-	slave.partners.add(-1);
-
-	r.push(`You have ${him} brought to you so that you can fuck ${his} hyperpregnant body.`);
-	if (tooBigBelly(slave)) {
-		r.push(`${He} is pinned to the ground by ${his}`);
-		if (slave.bellyPreg >= 1000000) {
-			r.push(`impossibly exploded baby bump,`);
-		} else if (slave.bellyPreg >= 750000) {
-			r.push(`massively swollen baby bump,`);
-		} else if (slave.bellyPreg >= 600000) {
-			r.push(`titanic baby belly,`);
+	seX(slave, canDoVaginal(slave) ? "vaginal" : "anal", V.PC);
+
+	const text = new SpacedTextAccumulator(frag);
+
+	text.push(
+		intro(),
+		setup(),
+		consummation(),
+	);
+
+	text.toParagraph();
+
+	return frag;
+
+	function intro() {
+		const text = [];
+
+		text.push(`You have ${him} brought to you so that you can fuck ${his} hyperpregnant body.`);
+
+		if (tooBigBelly(slave)) {
+			text.push(`${He} is pinned to the ground by ${his}`);
+
+			if (slave.bellyPreg >= 1000000) {
+				text.push(`impossibly exploded baby bump,`);
+			} else if (slave.bellyPreg >= 750000) {
+				text.push(`massively swollen baby bump,`);
+			} else if (slave.bellyPreg >= 600000) {
+				text.push(`titanic baby belly,`);
+			} else {
+				text.push(`massive belly,`);
+			}
+
+			text.push(`and won't be a particularly able lover because of this, but enjoying ${his} immobility is half the point.`);
+		} else if (!hasAnyLegs(slave)) {
+			text.push(`${He} has no limbs to stand on, so ${he} is left resting atop ${his}`);
+
+			if (slave.bellyPreg >= 1000000) {
+				text.push(`impossibly exploded baby bump.`);
+			} else if (slave.bellyPreg >= 750000) {
+				text.push(`massively swollen baby bump.`);
+			} else if (slave.bellyPreg >= 600000) {
+				text.push(`titanic baby belly.`);
+			} else {
+				text.push(`massive belly.`);
+			}
+
+			text.push(`${He} won't be a particularly able lover, but enjoying ${his} immobility is half the point.`);
+		} else if (!canStand(slave)) {
+			text.push(`${He} can't support ${himself}, so ${he} is left leaning against ${his}`);
+
+			if (slave.bellyPreg >= 1000000) {
+				text.push(`impossibly exploded baby bump.`);
+			} else if (slave.bellyPreg >= 750000) {
+				text.push(`massively swollen baby bump.`);
+			} else if (slave.bellyPreg >= 600000) {
+				text.push(`titanic baby belly.`);
+			} else {
+				text.push(`massive belly.`);
+			}
+
+			text.push(`${He} won't be a particularly able lover, but enjoying ${his} immobility is half the point.`);
 		} else {
-			r.push(`massive belly,`);
+			text.push(`${He} can still stand despite ${his}`);
+			if (slave.bellyPreg >= 1000000) {
+				text.push(`impossibly exploded baby bump,`);
+			} else if (slave.bellyPreg >= 750000) {
+				text.push(`massively swollen baby bump,`);
+			} else if (slave.bellyPreg >= 600000) {
+				text.push(`titanic baby belly,`);
+			} else {
+				text.push(`massive belly,`);
+			}
+
+			text.push(`and won't be a particularly able lover because of this, but enjoying this obstacle is half the point.`);
 		}
-		r.push(`and won't be a particularly able lover because of this, but enjoying ${his} immobility is half the point.`);
-	} else if (!hasAnyLegs(slave)) {
-		r.push(`${He} has no limbs to stand on, so ${he} is left resting atop ${his}`);
-		if (slave.bellyPreg >= 1000000) {
-			r.push(`impossibly exploded baby bump.`);
-		} else if (slave.bellyPreg >= 750000) {
-			r.push(`massively swollen baby bump.`);
-		} else if (slave.bellyPreg >= 600000) {
-			r.push(`titanic baby belly.`);
+
+		text.push(`Once ${he} is situated in the center of your office, you walk a circle around ${him}, taking special care to`);
+
+		if (slave.bellyTat === "a heart") {
+			text.push(`trace a hand over the obliterated heart shaped tattoo on the front of ${his} immensely stretched belly.`);
+		} else if (slave.bellyTat === "a star") {
+			text.push(`trace a hand over the obliterated star shaped tattoo on the front of ${his} immensely stretched belly.`);
+		} else if (slave.bellyTat === "a butterfly") {
+			text.push(`trace a hand over the obliterated butterfly tattoo on the front of ${his} immensely stretched belly.`);
 		} else {
-			r.push(`massive belly.`);
+			text.push(`trace a hand over the obliterated, stretched out expanse of slightly darker flesh where ${his} belly button used to be.`);
 		}
-		r.push(`${He} won't be a particularly able lover, but enjoying ${his} immobility is half the point.`);
-	} else if (!canStand(slave)) {
-		r.push(`${He} can't support ${himself}, so ${he} is left leaning against ${his}`);
-		if (slave.bellyPreg >= 1000000) {
-			r.push(`impossibly exploded baby bump.`);
-		} else if (slave.bellyPreg >= 750000) {
-			r.push(`massively swollen baby bump.`);
-		} else if (slave.bellyPreg >= 600000) {
-			r.push(`titanic baby belly.`);
+
+		return text.join(' ');
+	}
+
+	function setup() {
+		const text = [];
+
+		if (slave.devotion > 95) {
+			text.push(`${He} purrs in response to your touch, leaning forward against ${his} belly and`);
+
+			if (!hasAnyLegs(slave)) {
+				text.push(`wiggles`);
+			} else {
+				text.push(`lifts ${his} toes off the ground as ${he}`);
+				if (hasBothLegs(slave)) {
+					text.push(`spreads ${his} legs`);
+				} else {
+					text.push(`moves ${his} leg`);
+				}
+			}
+
+			text.push(`in preparation for you.`);
+		} else if (slave.trust < -20 && slave.devotion > -10) {
+			text.push(`${He} groans at your touch.`);
 		} else {
-			r.push(`massive belly.`);
+			text.push(`${He} winces at your touch.`);
 		}
-		r.push(`${He} won't be a particularly able lover, but enjoying ${his} immobility is half the point.`);
-	} else {
-		r.push(`${He} can still stand despite ${his}`);
-		if (slave.bellyPreg >= 1000000) {
-			r.push(`impossibly exploded baby bump,`);
-		} else if (slave.bellyPreg >= 750000) {
-			r.push(`massively swollen baby bump,`);
-		} else if (slave.bellyPreg >= 600000) {
-			r.push(`titanic baby belly,`);
+
+		text.push(`When you get to ${his} rear, you slap ${his}`);
+
+		if (slave.butt > 11) {
+			text.push(`insanely enormous ass,`);
+		} else if (slave.butt > 5) {
+			text.push(`huge ass,`);
+		} else if (Math.floor(slave.buttImplant/slave.butt) > .60) {
+			text.push(`jiggly, saline filled ass,`);
+		} else if (slave.butt > 2) {
+			text.push(`thick ass,`);
 		} else {
-			r.push(`massive belly,`);
+			text.push(`pert ass,`);
 		}
-		r.push(`and won't be a particularly able lover because of this, but enjoying this obstacle is half the point.`);
-	}
-	r.push(`Once ${he} is situated in the center of your office, you walk a circle around ${him}, taking special care to`);
-	if (slave.bellyTat === "a heart") {
-		r.push(`trace a hand over the obliterated heart shaped tattoo on the front of ${his} immensely stretched belly.`);
-	} else if (slave.bellyTat === "a star") {
-		r.push(`trace a hand over the obliterated star shaped tattoo on the front of ${his} immensely stretched belly.`);
-	} else if (slave.bellyTat === "a butterfly") {
-		r.push(`trace a hand over the obliterated butterfly tattoo on the front of ${his} immensely stretched belly.`);
-	} else {
-		r.push(`trace a hand over the obliterated, stretched out expanse of slightly darker flesh where ${his} belly button used to be.`);
-	}
-	if (slave.devotion > 95) {
-		r.push(`${He} purrs in response to your touch, leaning forward against ${his} belly and`);
-		if (!hasAnyLegs(slave)) {
-			r.push(`wiggles`);
+
+		text.push(`and then spread ${his} cheeks for easier access to ${his}`);
+
+		if (canDoVaginal(slave)) {
+			text.push(
+				`cunt.`,
+				VCheck.Vaginal(slave, 1),
+			);
 		} else {
-			r.push(`lifts ${his} toes off the ground as ${he}`);
-			if (hasBothLegs(slave)) {
-				r.push(`spreads ${his} legs`);
-			} else {
-				r.push(`moves ${his} leg`);
-			}
+			text.push(
+				`asshole.`,
+				VCheck.Anal(slave, 1),
+			);
 		}
-		r.push(`in preparation for you.`);
-	} else if (slave.trust < -20 && slave.devotion > -10) {
-		r.push(`${He} groans at your touch.`);
-	} else {
-		r.push(`${He} winces at your touch.`);
-	}
-	r.push(`When you get to ${his} rear, you slap ${his}`);
-	if (slave.butt > 11) {
-		r.push(`insanely enormous ass,`);
-	} else if (slave.butt > 5) {
-		r.push(`huge ass,`);
-	} else if (Math.floor(slave.buttImplant/slave.butt) > .60) {
-		r.push(`jiggly, saline filled ass,`);
-	} else if (slave.butt > 2) {
-		r.push(`thick ass,`);
-	} else {
-		r.push(`pert ass,`);
-	}
-	r.push(`and then spread ${his} cheeks for easier access to ${his}`);
-	if (canDoVaginal(slave)) {
-		r.push(`cunt.`);
-		r.push(VCheck.Vaginal(slave, 1));
-	} else {
-		r.push(`asshole.`);
-		r.push(VCheck.Anal(slave, 1));
-	}
-	r.push(`Heaving upward, you push ${him} fully onto ${his} belly, then lean into ${him}, fucking ${him} in a unique spin on the wheelbarrow position`);
-	if (V.PC.dick === 0) {
-		r.push(`with your strap-on`);
+
+		return text.join(' ');
 	}
-	r.push(`and setting ${his} tightly packed gut to jiggling. ${He} moans in mixed pain and pleasure as you bring ${him} over the edge and, by the time you finish with ${him} and allow ${him} to return to ${his} duties, it's clear`);
-	if (slave.belly > slave.pregAdaptation*2000) {
-		r.push(`that your recent escapades <span class="health dec">have done lasting damage to ${his} body.</span>`);
-		healthDamage(slave, 10);
-	} else {
-		r.push(`that you've left ${him} thoroughly exhausted.`);
+
+	function consummation() {
+		const text = [];
+
+		text.push(`Heaving upward, you push ${him} fully onto ${his} belly, then lean into ${him}, fucking ${him} in a unique spin on the wheelbarrow position`);
+
+		if (V.PC.dick === 0) {
+			text.push(`with your strap-on`);
+		}
+
+		text.push(`and setting ${his} tightly packed gut to jiggling. ${He} moans in mixed pain and pleasure as you bring ${him} over the edge and, by the time you finish with ${him} and allow ${him} to return to ${his} duties, it's clear`);
+
+		if (slave.belly > slave.pregAdaptation * 2000) {
+			text.push(`that your recent escapades <span class="health dec">have done lasting damage to ${his} body.</span>`);
+			healthDamage(slave, 10);
+		} else {
+			text.push(`that you've left ${him} thoroughly exhausted.`);
+		}
+
+		return text.join(' ');
 	}
-	App.Events.addParagraph(node, r);
-	return node;
 };
diff --git a/src/npc/interaction/fBoobs.js b/src/npc/interaction/fBoobs.js
index 2bd57c1e6436b6184f9a898666d5a765e3df5f7b..0fd3c45186b204e45ea11b3e2157d3df6033721e 100644
--- a/src/npc/interaction/fBoobs.js
+++ b/src/npc/interaction/fBoobs.js
@@ -12,7 +12,6 @@ App.Interact.fBoobs = function(slave) {
 		he, his, him, himself, hers
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
 	seX(slave, "mammary", V.PC, "penetrative");
 
 	r.push(`You call ${him} over so you can play with ${his}`);
@@ -196,13 +195,13 @@ App.Interact.fBoobs = function(slave) {
 		}
 		r.push(`sending ${him} gasping over the edge as well.`);
 	} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60 && slave.fetishKnown === 1 && slave.chastityPenis === 1) {
-		r.push(`${He} comes over eagerly, with hunger in ${his} eyes. ${He} gives you a titjob with ${his} lubricated cleavage while you sit at your desk. As a cumslut ${he}'s almost desperate to get your cum into ${him}`);
+		r.push(`${He} comes over eagerly, with hunger in ${his} eyes. ${He} gives you a titjob with ${his} lubricated cleavage while you sit at your desk. As a cumslut ${he}'s almost desperate to get your cum into ${his}`);
 		if (V.seeRace === 1) {
 			r.push(slave.race);
 		}
 		r.push(`mouth and rubs a nipple with one hand and ${his} anal opening with the other, since ${he} can't touch ${his} cock. The situation brings ${him} some pleasure, but the first twitches of ${his} cock against ${his} chastity cage are so uncomfortable that ${he} subsides into busy mechanical dick sucking. ${He} writhes uncomfortably, frustrated beyond belief.`);
 	} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60 && slave.fetishKnown === 1 && slave.dick !== 0 && V.PC.dick !== 0) {
-		r.push(`${He} comes over eagerly, with hunger in ${his} eyes. ${He} gives you a titjob with ${his} lubricated cleavage while you sit at your desk. As a cumslut ${he}'s almost desperate to get your cum into ${him}`);
+		r.push(`${He} comes over eagerly, with hunger in ${his} eyes. ${He} gives you a titjob with ${his} lubricated cleavage while you sit at your desk. As a cumslut ${he}'s almost desperate to get your cum into ${his}`);
 		if (V.seeRace === 1) {
 			r.push(slave.race);
 		}
@@ -214,7 +213,7 @@ App.Interact.fBoobs = function(slave) {
 		}
 		r.push(`in anticipation. When you finish, ${he} sits back with an ecstatic look on ${his} face and lets your cum rest in ${his} mouth as ${he} climaxes into ${his} hand. ${He} pours ${his} own cum from ${his} hand into ${his} mouth so it can mingle with yours.`);
 	} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60 && slave.fetishKnown === 1 && V.PC.dick !== 0) {
-		r.push(`${He} comes over eagerly, with hunger in ${his} eyes. ${He} gives you a titjob with ${his} lubricated cleavage while you sit at your desk. As a cumslut ${he}'s almost desperate to get your cum into ${him}`);
+		r.push(`${He} comes over eagerly, with hunger in ${his} eyes. ${He} gives you a titjob with ${his} lubricated cleavage while you sit at your desk. As a cumslut ${he}'s almost desperate to get your cum into ${his}`);
 		if (V.seeRace === 1) {
 			r.push(slave.race);
 		}
diff --git a/src/npc/interaction/fButt.js b/src/npc/interaction/fButt.js
index 61ab016c5c632ef1a21509be831085b452f21e3f..002e71087893db40252c575a46967d26c549e6e3 100644
--- a/src/npc/interaction/fButt.js
+++ b/src/npc/interaction/fButt.js
@@ -4,495 +4,627 @@
  * @returns {DocumentFragment}
  */
 App.Interact.fButt = function(slave) {
-	const node = new DocumentFragment();
-	let r = [];
+	const frag = new DocumentFragment();
 
 	const {
 		He, His,
 		he, his, him, girl
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
-
-	r.push(`You call ${him} over so you can`);
-	if (!canDoVaginal(slave)) {
-		r.push(`use ${his} sole fuckhole.`);
-	} else if (slave.vagina > 3) {
-		r.push(`fuck ${his} gaping holes.`);
-	} else if (slave.vagina > 2) {
-		r.push(`fuck ${his} loose holes.`);
-	} else if (slave.vagina === 2) {
-		r.push(`use ${his} whorish holes.`);
-	} else if (slave.vagina === 1) {
-		r.push(`use ${his} tight holes.`);
-	} else if (slave.vagina === 0 || slave.anus === 0) {
-		r.push(`take ${his} virginity.`);
+	const text = new SpacedTextAccumulator(frag);
+
+	text.push(
+		intro(),
+		setup(),
+		consummation(),
+	);
+
+	if (random(1, 100) > (100 + slave.devotion)) {
+		text.push(slaveGainsFlaw());
+	} else if (random(1, 100) > (110 - slave.devotion)) {
+		text.push(slaveGainsQuirk());
 	}
 
-	if (slave.vagina !== -1) {
-		if (slave.vaginaTat === "tribal patterns") {
-			r.push(`The tattoos on ${his} abdomen certainly draw attention there.`);
-		} else if (slave.vaginaTat === "scenes") {
-			r.push(`The tattoos on ${his} abdomen nicely illustrate what you mean to do to ${him}.`);
-		} else if (slave.vaginaTat === "degradation") {
-			r.push(`The tattoos on ${his} abdomen are asking you to, after all.`);
-		} else if (slave.vaginaTat === "lewd crest") {
-			r.push(`The crest on ${his} abdomen screams debauchery and implores you to use ${him}.`);
+	text.push(cleanup());
+
+	text.toParagraph();
+
+	return frag;
+
+	function intro() {
+		const text = [];
+
+		text.push(`You call ${him} over so you can`);
+		if (!canDoVaginal(slave)) {
+			text.push(`use ${his} sole fuckhole.`);
+		} else if (slave.vagina > 3) {
+			text.push(`fuck ${his} gaping holes.`);
+		} else if (slave.vagina > 2) {
+			text.push(`fuck ${his} loose holes.`);
+		} else if (slave.vagina === 2) {
+			text.push(`use ${his} whorish holes.`);
+		} else if (slave.vagina === 1) {
+			text.push(`use ${his} tight holes.`);
+		} else if (slave.vagina === 0 || slave.anus === 0) {
+			text.push(`take ${his} virginity.`);
 		}
+
+		return text.join(' ');
 	}
 
-	if (slave.piercing.vagina.weight > 1) {
-		r.push(`${His} pierced lips and clit have ${him} nice and wet.`);
-		if (slave.dick !== 0) {
-			r.push(`Metal glints all up and down ${his} cock.`);
-		}
-	} else if (slave.piercing.vagina.weight === 1) {
-		r.push(`${His} pierced clit has ${his} nice and moist.`);
-		if (slave.dick !== 0) {
-			r.push(`Metal glints at the head of ${his} cock.`);
+	function setup() {
+		const text = [];
+
+		if (slave.vagina !== -1) {
+			if (slave.vaginaTat === "tribal patterns") {
+				text.push(`The tattoos on ${his} abdomen certainly draw attention there.`);
+			} else if (slave.vaginaTat === "scenes") {
+				text.push(`The tattoos on ${his} abdomen nicely illustrate what you mean to do to ${him}.`);
+			} else if (slave.vaginaTat === "degradation") {
+				text.push(`The tattoos on ${his} abdomen are asking you to, after all.`);
+			} else if (slave.vaginaTat === "lewd crest") {
+				text.push(`The crest on ${his} abdomen screams debauchery and implores you to use ${him}.`);
+			}
 		}
-	}
 
-	if (slave.piercing.anus.weight > 1) {
-		r.push(`The ring of stud piercings around ${his} anus should massage you delightfully as you sodomize ${him}.`);
-	} else if (slave.piercing.anus.weight === 1) {
-		r.push(`${His} perineum piercing has a big ring in it, which you should be able to feel when you hilt yourself in ${his} ass.`);
-	}
+		if (slave.piercing.vagina.weight > 1) {
+			text.push(`${His} pierced lips and clit have ${him} nice and wet.`);
 
-	if (slave.anusTat !== 0 && slave.anusTat !== 4) {
-		r.push(`${His} anus is invitingly bleached,`);
-		if (slave.vagina > -1) {
-			r.push(`which is appropriate: rather than looking like ${he} has a hole for fucking and an ass, it looks like ${he} has two fuckholes.`);
-		} else {
-			r.push(`making ${his} sole fuckable hole look nice and natural.`);
+			if (slave.dick !== 0) {
+				text.push(`Metal glints all up and down ${his} cock.`);
+			}
+		} else if (slave.piercing.vagina.weight === 1) {
+			text.push(`${His} pierced clit has ${his} nice and moist.`);
+
+			if (slave.dick !== 0) {
+				text.push(`Metal glints at the head of ${his} cock.`);
+			}
 		}
-	}
 
-	if (slave.vagina === 0 && slave.anus === 0 && canDoVaginal(slave)) {
-		if (V.PC.dick === 0) {
-			r.push(`You step into a strap-on, lubricate it, and break in ${his} holes in quick succession.`);
-		} else {
-			r.push(`Brooking no resistance, you take ${his} virginity and then break in ${his} virgin butt.`);
+		if (slave.piercing.anus.weight > 1) {
+			text.push(`The ring of stud piercings around ${his} anus should massage you delightfully as you sodomize ${him}.`);
+		} else if (slave.piercing.anus.weight === 1) {
+			text.push(`${His} perineum piercing has a big ring in it, which you should be able to feel when you hilt yourself in ${his} ass.`);
 		}
-		if (slave.devotion > 50) {
-			r.push(`You ease yourself into ${his} pussy before gradually working your way into ${his} ass and alternate between the two holes while ${he} begins to moan. In just a few minutes, ${he} has lost ${his} virginity and been assfucked for the first time. ${He} <span class="devotion inc">submits utterly</span> to your spoilage of ${his} innocence and thanks you meekly for introducing ${him} to proper sexual slavery. <span class="virginity loss">${His} holes have been broken in.</span>`);
-			slave.devotion += 10;
-		} else if (slave.devotion > 20) {
-			r.push(`You ease yourself into ${his} pussy before gradually working your way into ${his} ass and alternate between the two holes while ${he} begins to moan. In just a few minutes, ${he} has lost ${his} virginity and been assfucked for the first time. ${He}'s so bewildered by the pain and novelty that all ${he} feels is <span class="trust dec">a little fear</span> of further use. <span class="virginity loss">${His} holes have been broken in.</span>`);
-			slave.trust -= 5;
-		} else {
-			r.push(`You force yourself into ${his} pussy before gradually working your way into ${his} ass. ${He} sobs and cries with disgust while you alternate between the two holes. In just a few minutes, ${he} has lost ${his} virginity to rape and ${his} anal virginity to a rough buttfuck. To say ${he} <span class="devotion dec">resents you</span> and <span class="trust dec">fears further abuse</span> would be an understatement. <span class="virginity loss">${His} holes have been broken in.</span>`);
-			slave.devotion -= 10;
-			slave.trust -= 10;
+
+		if (slave.anusTat === "bleached") {
+			text.push(`${His} anus is invitingly bleached,`);
+
+			if (slave.vagina > -1) {
+				text.push(`which is appropriate: rather than looking like ${he} has a hole for fucking and an ass, it looks like ${he} has two fuckholes.`);
+			} else {
+				text.push(`making ${his} sole fuckable hole look nice and natural.`);
+			}
 		}
-		r.push(VCheck.Both(slave, 1));
-	} else if (slave.vagina === 0 && canDoVaginal(slave)) {
-		if (slave.devotion > 20) {
-			r.push(`${He} accepts your orders without comment and presents ${his} virgin pussy for defloration${(V.PC.dick === 0) ? `, watching with some small trepidation as you don a strap-on` : ``}. You gently ease into ${his} pussy before gradually increasing the intensity of your thrusts into ${him}. Before long, ${he}'s moaning loudly as you pound away. Since ${he} is already well broken, this new connection with ${his} ${getWrittenTitle(slave)} <span class="devotion inc">increases ${his} devotion to you.</span> <span class="virginity loss">${His} pussy has been broken in.</span>`);
-			slave.devotion += 10;
-		} else if (slave.devotion >= -20) {
-			r.push(`${He} is clearly unhappy at losing ${his} pearl of great price to you; this probably isn't what ${he} imagined ${his} first real sex would be like.`);
+
+		return text.join(' ');
+	}
+
+	function consummation() {
+		const text = [];
+
+		if (slave.vagina === 0 && slave.anus === 0 && canDoVaginal(slave)) {
 			if (V.PC.dick === 0) {
-				r.push(`${His} lower lip quivers with trepidation as ${he} watches you don a strap-on and maneuver to fuck ${his} virgin hole.`);
+				text.push(`You step into a strap-on, lubricate it, and break in ${his} holes in quick succession.`);
+			} else {
+				text.push(`Brooking no resistance, you take ${his} virginity and then break in ${his} virgin butt.`);
 			}
-			r.push(`You gently ease into ${his} pussy before gradually increasing the intensity of your thrusts into ${him}. Before long, ${he}'s moaning as you pound away. Nevertheless, this new connection with ${his} ${getWrittenTitle(slave)} <span class="devotion inc">increases ${his} devotion to you.</span> <span class="virginity loss">${His} pussy has been broken in,</span> and ${he} is <span class="trust dec">fearful</span> that sex will continue to be painful.`);
-			slave.devotion += 5;
-			slave.trust -= 5;
-		} else {
-			r.push(`As you anticipated, ${he} refuses to give you ${his} virginity. And as you expected, ${he} is unable to resist you. ${He} cries as`);
-			if (V.PC.dick === 0) {
-				r.push(`your strap-on`);
+
+			if (slave.devotion > 50) {
+				text.push(`You ease yourself into ${his} pussy before gradually working your way into ${his} ass and alternate between the two holes while ${he} begins to moan. In just a few minutes, ${he} has lost ${his} virginity and been assfucked for the first time. ${He} <span class="devotion inc">submits utterly</span> to your spoilage of ${his} innocence and thanks you meekly for introducing ${him} to proper sexual slavery. <span class="virginity loss">${His} holes have been broken in.</span>`);
+
+				slave.devotion += 10;
+			} else if (slave.devotion > 20) {
+				text.push(`You ease yourself into ${his} pussy before gradually working your way into ${his} ass and alternate between the two holes while ${he} begins to moan. In just a few minutes, ${he} has lost ${his} virginity and been assfucked for the first time. ${He}'s so bewildered by the pain and novelty that all ${he} feels is <span class="trust dec">a little fear</span> of further use. <span class="virginity loss">${His} holes have been broken in.</span>`);
+
+				slave.trust -= 5;
 			} else {
-				r.push(`your cock`);
+				text.push(`You force yourself into ${his} pussy before gradually working your way into ${his} ass. ${He} sobs and cries with disgust while you alternate between the two holes. In just a few minutes, ${he} has lost ${his} virginity to rape and ${his} anal virginity to a rough buttfuck. To say ${he} <span class="devotion dec">resents you</span> and <span class="trust dec">fears further abuse</span> would be an understatement. <span class="virginity loss">${His} holes have been broken in.</span>`);
+
+				slave.devotion -= 10;
+				slave.trust -= 10;
 			}
-			r.push(`opens ${his} fresh, tight hole. You force your way into ${his} pussy and continue thrusting into ${him}. ${He} sobs and cries with horror as you pound away. The rape <span class="devotion dec">decreases ${his} devotion to you.</span> <span class="virginity loss">${His} pussy has been broken in,</span> and ${he} <span class="trust dec">fears further abuse.</span>`);
-			slave.devotion -= 10;
-			slave.trust -= 15;
-		}
-		r.push(VCheck.Vaginal(slave, 1));
-	} else if (slave.anus === 0) {
-		if (slave.devotion > 20) {
-			r.push(`${He} accepts your orders without comment and presents ${his} virgin anus for defloration. You`);
-			if (V.PC.dick === 0) {
-				r.push(`don a strap-on and`);
+
+			text.push(VCheck.Both(slave, 1));
+		} else if (slave.vagina === 0 && canDoVaginal(slave)) {
+			if (slave.devotion > 20) {
+				text.push(`${He} accepts your orders without comment and presents ${his} virgin pussy for defloration${(V.PC.dick === 0) ? `, watching with some small trepidation as you don a strap-on` : ``}. You gently ease into ${his} pussy before gradually increasing the intensity of your thrusts into ${him}. Before long, ${he}'s moaning loudly as you pound away. Since ${he} is already well broken, this new connection with ${his} ${getWrittenTitle(slave)} <span class="devotion inc">increases ${his} devotion to you.</span> <span class="virginity loss">${His} pussy has been broken in.</span>`);
+
+				slave.devotion += 10;
+			} else if (slave.devotion >= -20) {
+				text.push(`${He} is clearly unhappy at losing ${his} pearl of great price to you; this probably isn't what ${he} imagined ${his} first real sex would be like.`);
+
+				if (V.PC.dick === 0) {
+					text.push(`${His} lower lip quivers with trepidation as ${he} watches you don a strap-on and maneuver to fuck ${his} virgin hole.`);
+				}
+
+				text.push(`You gently ease into ${his} pussy before gradually increasing the intensity of your thrusts into ${him}. Before long, ${he}'s moaning as you pound away. Nevertheless, this new connection with ${his} ${getWrittenTitle(slave)} <span class="devotion inc">increases ${his} devotion to you.</span> <span class="virginity loss">${His} pussy has been broken in,</span> and ${he} is <span class="trust dec">fearful</span> that sex will continue to be painful.`);
+
+				slave.devotion += 5;
+				slave.trust -= 5;
+			} else {
+				text.push(`As you anticipated, ${he} refuses to give you ${his} virginity. And as you expected, ${he} is unable to resist you. ${He} cries as`);
+				if (V.PC.dick === 0) {
+					text.push(`your strap-on`);
+				} else {
+					text.push(`your cock`);
+				}
+
+				text.push(`opens ${his} fresh, tight hole. You force your way into ${his} pussy and continue thrusting into ${him}. ${He} sobs and cries with horror as you pound away. The rape <span class="devotion dec">decreases ${his} devotion to you.</span> <span class="virginity loss">${His} pussy has been broken in,</span> and ${he} <span class="trust dec">fears further abuse.</span>`);
+
+				slave.devotion -= 10;
+				slave.trust -= 15;
 			}
-			r.push(`gently sodomize ${him}. You gently ease yourself into ${his} butthole and gradually speed up your thrusts while ${he} slowly learns to move ${his} hips along with you. Since ${he} is already well broken, this new connection with ${his} ${getWrittenTitle(slave)} <span class="devotion inc">increases ${his} devotion to you.</span> <span class="virginity loss">${His} tight little ass has been broken in.</span>`);
-			slave.devotion += 4;
-		} else if (slave.devotion >= -20) {
-			r.push(`${He} is clearly unhappy at the idea of taking a dick up ${his} butt. ${He} obeys orders anyway, and lies there wincing and moaning as you`);
+			text.push(VCheck.Vaginal(slave, 1));
+		} else if (slave.anus === 0) {
+			if (slave.devotion > 20) {
+				text.push(`${He} accepts your orders without comment and presents ${his} virgin anus for defloration. You`);
+
+				if (V.PC.dick === 0) {
+					text.push(`don a strap-on and`);
+				}
+
+				text.push(`gently sodomize ${him}. You gently ease yourself into ${his} butthole and gradually speed up your thrusts while ${he} slowly learns to move ${his} hips along with you. Since ${he} is already well broken, this new connection with ${his} ${getWrittenTitle(slave)} <span class="devotion inc">increases ${his} devotion to you.</span> <span class="virginity loss">${His} tight little ass has been broken in.</span>`);
+
+				slave.devotion += 4;
+			} else if (slave.devotion >= -20) {
+				text.push(`${He} is clearly unhappy at the idea of taking a dick up ${his} butt. ${He} obeys orders anyway, and lies there wincing and moaning as you`);
+
+				if (V.PC.dick === 0) {
+					text.push(`don a strap-on and`);
+				}
+
+				text.push(`fuck ${his} ass. <span class="virginity loss">${His} tight little ass has been broken in,</span> and ${he} <span class="trust dec">fears further anal pain.</span>`);
+
+				slave.trust -= 5;
+			} else {
+				text.push(`${He} is appalled at the idea of taking it up the ass${(V.PC.dick === 0) ? ` and cries with fear as you don a strap-on` : ``}. ${He} does anyway though, sobbing into the cushions`);
+
+				if (hasAnyArms(slave)) {
+					text.push(`while you hold ${his} ${hasBothArms(slave) ? `arms` : `arm`} behind ${him}`);
+				}
+
+				text.push(text.pop() + `.`);
+				text.push(`You force yourself into ${his} butthole. ${He} sobs and cries with disgust while you continue thrusting into ${his} ass. The painful anal rape <span class="devotion dec">decreases ${his} devotion to you.</span> <span class="virginity loss">${His} tight little ass has been broken in,</span> and ${he} is <span class="trust dec">terrified of further anal pain.</span>`);
+
+				slave.devotion -= 5;
+				slave.trust -= 5;
+			}
+
+			text.push(VCheck.Anal(slave, 1));
+		} else if (slave.devotion < -20) {
 			if (V.PC.dick === 0) {
-				r.push(`don a strap-on and`);
+				text.push(`You don a cruelly large strap-on, and you do it so ${he} can`);
+
+				if (canSee(slave)) {
+					text.push(`see`);
+				} else if (canHear(slave)) {
+					text.push(`hear`);
+				} else {
+					text.push(`notice`);
+				}
+
+				text.push(`it.`);
 			}
-			r.push(`fuck ${his} ass. <span class="virginity loss">${His} tight little ass has been broken in,</span> and ${he} <span class="trust dec">fears further anal pain.</span>`);
-			slave.trust -= 5;
-		} else {
-			r.push(`${He} is appalled at the idea of taking it up the ass${(V.PC.dick === 0) ? ` and cries with fear as you don a strap-on` : ``}. ${He} does anyway though, sobbing into the cushions`);
-			if (hasAnyArms(slave)) {
-				r.push(`while you hold ${his} ${hasBothArms(slave) ? `arms` : `arm`} behind ${him}`);
+
+			text.push(`${He} tries to refuse you, so you throw ${him} across the back of the couch next to your desk with ${his}`);
+
+			if (V.seeRace === 1) {
+				text.push(slave.race);
 			}
-			r.push(r.pop() + `.`);
-			r.push(`You force yourself into ${his} butthole. ${He} sobs and cries with disgust while you continue thrusting into ${his} ass. The painful anal rape <span class="devotion dec">decreases ${his} devotion to you.</span> <span class="virginity loss">${His} tight little ass has been broken in,</span> and ${he} is <span class="trust dec">terrified of further anal pain.</span>`);
-			slave.devotion -= 5;
-			slave.trust -= 5;
-		}
-		r.push(VCheck.Anal(slave, 1));
-	} else if (slave.devotion < -20) {
-		if (V.PC.dick === 0) {
-			r.push(`You don a cruelly large strap-on, and you do it so ${he} can`);
-			if (canSee(slave)) {
-				r.push(`see`);
-			} else if (canHear(slave)) {
-				r.push(`hear`);
-			} else {
-				r.push(`notice`);
+
+			text.push(`ass in the air. You finger ${his} anus`);
+
+			if (slave.vagina !== -1) {
+				text.push(`while fucking ${his} pussy`);
+			} else if (hasBothLegs(slave)) {
+				text.push(`while frotting ${his} thighs`);
 			}
-			r.push(`it.`);
-		}
-		r.push(`${He} tries to refuse you, so you throw ${him} across the back of the couch next to your desk with ${his}`);
-		if (V.seeRace === 1) {
-			r.push(slave.race);
-		}
-		r.push(`ass in the air. You finger ${his} anus`);
-		if (slave.vagina !== -1) {
-			r.push(`while fucking ${his} pussy`);
-		} else if (hasBothLegs(slave)) {
-			r.push(`while frotting ${his} thighs`);
-		}
-		r.push(`for a bit and then switch to ${his} now-ready anus. ${He} sobs as you penetrate ${his} rectum.`);
-		if (slave.dick !== 0 && canAchieveErection(slave)) {
-			if (slave.prostate === 0) {
-				r.push(`${He} lacks a prostate, denying ${him} any real pleasure. ${His} dick stays flaccid as you rape ${him}.`);
+
+			text.push(`for a bit and then switch to ${his} now-ready anus. ${He} sobs as you penetrate ${his} rectum.`);
+
+			if (slave.dick !== 0 && canAchieveErection(slave)) {
+				if (slave.prostate === 0) {
+					text.push(`${He} lacks a prostate, denying ${him} any real pleasure. ${His} dick stays flaccid as you rape ${him}.`);
+				} else if (slave.chastityPenis === 1) {
+					text.push(`Despite ${his} unwillingness to be sodomized, the prostate stimulation starts to give ${him} an erection, which ${his} dick chastity makes horribly uncomfortable. ${He} bucks with the pain, ${his} asshole spasming delightfully.`);
+				} else {
+					text.push(`Despite ${his} unwillingness to be sodomized, the prostate stimulation gives ${him} an erection. ${He}'s mortified that ${he} would get hard while being anally raped.`);
+				}
 			} else if (slave.chastityPenis === 1) {
-				r.push(`Despite ${his} unwillingness to be sodomized, the prostate stimulation starts to give ${him} an erection, which ${his} dick chastity makes horribly uncomfortable. ${He} bucks with the pain, ${his} asshole spasming delightfully.`);
+				text.push(`${His} dick chastity keeps ${his} bitch cock hidden away while you use ${his} anus like a pussy.`);
+			} else if (slave.dick !== 0) {
+				text.push(`${His} flaccid dick is ground into the back of the couch as you rape ${him}.`);
+			}
+
+			text.push(VCheck.Both(slave, 1));
+		} else if (slave.devotion <= 50) {
+			text.push(`You throw ${him} across the back of the couch next to your desk with ${his} ass in the air${(V.PC.dick === 0) ? `, and don a strap-on` : ``}. You finger ${his}`);
+
+			if (V.seeRace === 1) {
+				text.push(slave.race);
+			}
+
+			text.push(`ass while`);
+
+			if (slave.vagina !== -1) {
+				text.push(`fucking ${his} pussy`);
 			} else {
-				r.push(`Despite ${his} unwillingness to be sodomized, the prostate stimulation gives ${him} an erection. ${He}'s mortified that ${he} would get hard while being anally raped.`);
+				text.push(`frotting ${his} thighs`);
 			}
-		} else if (slave.chastityPenis === 1) {
-			r.push(`${His} dick chastity keeps ${his} bitch cock hidden away while you use ${his} anus like a pussy.`);
-		} else if (slave.dick !== 0) {
-			r.push(`${His} flaccid dick is ground into the back of the couch as you rape ${him}.`);
-		}
-		r.push(VCheck.Both(slave, 1));
-	} else if (slave.devotion <= 50) {
-		r.push(`You throw ${him} across the back of the couch next to your desk with ${his} ass in the air${(V.PC.dick === 0) ? `, and don a strap-on` : ``}. You finger ${his}`);
-		if (V.seeRace === 1) {
-			r.push(slave.race);
-		}
-		r.push(`ass while`);
-		if (slave.vagina !== -1) {
-			r.push(`fucking ${his} pussy`);
-		} else {
-			r.push(`frotting ${his} thighs`);
-		}
-		r.push(`for a bit and then switch to ${his} now-ready anus.`);
-		if (slave.anus === 1) {
-			r.push(`${His} ass is so tight that you have to work yourself in.`);
-		} else if (slave.anus === 2) {
-			r.push(`Your`);
-			if (V.PC.dick === 0) {
-				r.push(`fake dick`);
+
+			text.push(`for a bit and then switch to ${his} now-ready anus.`);
+
+			if (slave.anus === 1) {
+				text.push(`${His} ass is so tight that you have to work yourself in.`);
+			} else if (slave.anus === 2) {
+				text.push(`Your`);
+				if (V.PC.dick === 0) {
+					text.push(`fake dick`);
+				} else {
+					text.push(`cock`);
+				}
+				text.push(`slides easily up ${his} ass.`);
 			} else {
-				r.push(`cock`);
+				text.push(`You slide into ${his} already-gaping asspussy with ease.`);
+			}
+
+			text.push(`${He} gasps as you penetrate ${his} rectum, but you timed the switch so that ${he} was on the verge of orgasm, and ${he} comes immediately.`);
+
+			if (slave.dick !== 0 && canAchieveErection(slave)) {
+				if (slave.chastityPenis) {
+					text.push(`${He} managed to stay soft within ${his} dick chastity, but ${he} dribbled a lot of precum onto the couch. You make ${his} lick it up, and ${he} obeys, shuddering with unsatisfied arousal.`);
+				} else {
+					text.push(`${His} cock spatters the couch with cum, and you make ${his} lick it up.`);
+				}
+			} else if (slave.clit > 2) {
+				text.push(`${His} clit is so large that it bobs slightly with each thrust.`);
 			}
-			r.push(`slides easily up ${his} ass.`);
+
+			text.push(VCheck.Both(slave, 1));
 		} else {
-			r.push(`You slide into ${his} already-gaping asspussy with ease.`);
-		}
-		r.push(`${He} gasps as you penetrate ${his} rectum, but you timed the switch so that ${he} was on the verge of orgasm, and ${he} comes immediately.`);
-		if (slave.dick !== 0 && canAchieveErection(slave)) {
-			if (slave.chastityPenis) {
-				r.push(`${He} managed to stay soft within ${his} dick chastity, but ${he} dribbled a lot of precum onto the couch. You make ${his} lick it up, and ${he} obeys, shuddering with unsatisfied arousal.`);
+			if (hasAnyLegs(slave)) {
+				text.push(`${He} kneels on the floor`);
 			} else {
-				r.push(`${His} cock spatters the couch with cum, and you make ${his} lick it up.`);
+				text.push(`You lay ${him} on the floor`);
 			}
-		} else if (slave.clit > 2) {
-			r.push(`${His} clit is so large that it bobs slightly with each thrust.`);
-		}
-		r.push(VCheck.Both(slave, 1));
-	} else {
-		if (hasAnyLegs(slave)) {
-			r.push(`${He} kneels on the floor`);
-		} else {
-			r.push(`You lay ${him} on the floor`);
-		}
-		r.push(`so you can take ${him} at will${(V.PC.dick === 0) ? `, and don a strap-on` : ``}. You finger ${his}`);
-		if (V.seeRace === 1) {
-			r.push(slave.race);
-		}
-		r.push(`ass while`);
-		if (canDoVaginal(slave)) {
-			r.push(`fucking ${his} pussy`);
-		} else {
-			r.push(`frotting ${his}`);
-		}
-		r.push(`for a bit and then switch to ${his} now-ready anus.`);
-		if (slave.anus === 1) {
-			r.push(`${His} ass is so tight that you have to work yourself in.`);
-		} else if (slave.anus === 2) {
-			r.push(`Your cock slides easily up ${his} ass.`);
-		} else {
-			r.push(`You slide into ${his} already-gaping asspussy with ease.`);
-		}
-		r.push(`You fuck ${him} there for a while before repeatedly pulling out and stuffing yourself back in. ${He} moans each time you fill`);
-		if (canDoVaginal(slave)) {
-			r.push(`a`);
-		} else {
-			r.push(his);
-		}
-		r.push(`waiting hole.`);
-		if (slave.dick !== 0 && canAchieveErection(slave)) {
-			if (slave.chastityPenis === 1) {
-				r.push(`Whenever ${he} starts to get hard, ${his} dick chastity gives ${him} an awful twinge of pain. You do your best to be up ${his} butt when this happens so you can experience the resulting spasm.`);
+
+			text.push(`so you can take ${him} at will${(V.PC.dick === 0) ? `, and don a strap-on` : ``}. You finger ${his}`);
+
+			if (V.seeRace === 1) {
+				text.push(slave.race);
+			}
+
+			text.push(`ass while`);
+
+			if (canDoVaginal(slave)) {
+				text.push(`fucking ${his} pussy`);
+			} else {
+				text.push(`frotting ${his}`);
+			}
+
+			text.push(`for a bit and then switch to ${his} now-ready anus.`);
+
+			if (slave.anus === 1) {
+				text.push(`${His} ass is so tight that you have to work yourself in.`);
+			} else if (slave.anus === 2) {
+				text.push(`Your cock slides easily up ${his} ass.`);
 			} else {
-				r.push(`Every time you penetrate, ${his} erect dick jerks up and slaps ${his} stomach.`);
+				text.push(`You slide into ${his} already-gaping asspussy with ease.`);
 			}
-		} else if (slave.dick !== 0) {
-			if (slave.chastityPenis === 1) {
-				r.push(`${His} dick chastity keeps ${his} girly bitchclit hidden, just like it belongs.`);
+
+			text.push(`You fuck ${him} there for a while before repeatedly pulling out and stuffing yourself back in. ${He} moans each time you fill`);
+
+			if (canDoVaginal(slave)) {
+				text.push(`a`);
 			} else {
-				r.push(`Every time you penetrate, ${his} limp dick flops around lamely.`);
+				text.push(his);
+			}
+
+			text.push(`waiting hole.`);
+
+			if (slave.dick !== 0 && canAchieveErection(slave)) {
+				if (slave.chastityPenis === 1) {
+					text.push(`Whenever ${he} starts to get hard, ${his} dick chastity gives ${him} an awful twinge of pain. You do your best to be up ${his} butt when this happens so you can experience the resulting spasm.`);
+				} else {
+					text.push(`Every time you penetrate, ${his} erect dick jerks up and slaps ${his} stomach.`);
+				}
+			} else if (slave.dick !== 0) {
+				if (slave.chastityPenis === 1) {
+					text.push(`${His} dick chastity keeps ${his} girly bitchclit hidden, just like it belongs.`);
+				} else {
+					text.push(`Every time you penetrate, ${his} limp dick flops around lamely.`);
+				}
+			} else if (slave.clit > 2) {
+				text.push(`${His} clit is so large that it bobs slightly with each thrust.`);
 			}
-		} else if (slave.clit > 2) {
-			r.push(`${His} clit is so large that it bobs slightly with each thrust.`);
+
+			text.push(VCheck.Both(slave, 1));
 		}
-		r.push(VCheck.Both(slave, 1));
-	}
 
-	if (slave.bellyPreg >= 1500) {
-		r.push(`The poor ${girl}'s pregnant belly makes taking a rough fuck in both ${his} holes uncomfortable for ${him}.`);
-	} else if (slave.bellyImplant >= 1500) {
-		r.push(`The poor ${girl}'s implant filled belly makes taking a rough fuck in both ${his} holes uncomfortable for ${him}.`);
-	} else if (slave.bellyFluid >= 1500) {
-		r.push(`The poor ${girl}'s sloshing belly makes taking a rough fuck in both ${his} holes uncomfortable for ${him}, though the lewd jiggling the pounding sends through it is quite a sight.`);
-	}
+		if (slave.bellyPreg >= 1500) {
+			text.push(`The poor ${girl}'s pregnant belly makes taking a rough fuck in both ${his} holes uncomfortable for ${him}.`);
+		} else if (slave.bellyImplant >= 1500) {
+			text.push(`The poor ${girl}'s implant filled belly makes taking a rough fuck in both ${his} holes uncomfortable for ${him}.`);
+		} else if (slave.bellyFluid >= 1500) {
+			text.push(`The poor ${girl}'s sloshing belly makes taking a rough fuck in both ${his} holes uncomfortable for ${him}, though the lewd jiggling the pounding sends through it is quite a sight.`);
+		}
 
-	if (slave.anusTat === "scenes" && slave.anus === 1) {
-		r.push(`As you fucked ${his} butt, the decorative pattern around ${his} ass stretched open. When you pull out, ${his} momentary gape closes the pattern up quickly.`);
-	} else if (slave.anusTat === "scenes") {
-		r.push(`As you fucked ${his} butt, the decorative pattern around ${his} ass stretched open. When you pull out, ${his} gape leaves the pattern distorted.`);
-	} else if (slave.anusTat === "degradation") {
-		r.push(`As you fucked ${his} butt, the offensive language around ${his} ass stretched and distorted.`);
+		if (slave.anusTat === "scenes" && slave.anus === 1) {
+			text.push(`As you fucked ${his} butt, the decorative pattern around ${his} ass stretched open. When you pull out, ${his} momentary gape closes the pattern up quickly.`);
+		} else if (slave.anusTat === "scenes") {
+			text.push(`As you fucked ${his} butt, the decorative pattern around ${his} ass stretched open. When you pull out, ${his} gape leaves the pattern distorted.`);
+		} else if (slave.anusTat === "degradation") {
+			text.push(`As you fucked ${his} butt, the offensive language around ${his} ass stretched and distorted.`);
+		}
+
+		return text.join(' ');
 	}
 
-	if (random(1, 100) > (100+slave.devotion)) {
+	function slaveGainsFlaw() {
 		if (slave.fetish !== "buttslut" && slave.energy <= 95 && slave.sexualFlaw !== "hates penetration") {
-			r.push(`Being brutally used has given ${him} a <span class="flaw gain">hatred of penetration.</span>`);
 			slave.sexualFlaw = "hates penetration";
+
+			return `Being brutally used has given ${him} a <span class="flaw gain">hatred of penetration.</span>`;
 		}
-	} else if (random(1, 100) > (110-slave.devotion)) {
+
+		return ``;
+	}
+
+	function slaveGainsQuirk() {
 		if (slave.fetish === "none" && slave.sexualFlaw !== "hates penetration") {
-			r.push(`Orgasming to your use of ${his} fuckhole <span class="fetish gain">has ${him} eager for more buttsex.</span>`);
 			slave.fetish = "buttslut";
 			slave.fetishKnown = 1;
+
+			return `Orgasming to your use of ${his} fuckhole <span class="fetish gain">has ${him} eager for more buttsex.</span>`;
 		}
+
+		return ``;
 	}
 
-	if (V.PC.dick !== 0) {
-		if (slave.cervixImplant === 2 || slave.cervixImplant === 3) {
-			slave.bellyImplant += random(10, 20);
-		}
+	function cleanup() {
+		const text = [];
 
-		if (slave.anus > 3) {
-			r.push(`${His} gaping hole drips your cum right out again.`);
-		} else if (slave.anus > 2) {
-			r.push(`Cum drips out of ${his} loose hole.`);
-		} else if (slave.anus === 2) {
-			r.push(`Cum drips out of ${his} loosened anus.`);
-		} else if (slave.anus === 1) {
-			r.push(`${His} still-tight ass keeps your load inside ${him}.`);
-		}
+		if (V.PC.dick !== 0) {
+			if (slave.cervixImplant === 2 || slave.cervixImplant === 3) {
+				slave.bellyImplant += random(10, 20);
+			}
 
-		if (canMove(slave) && V.postSexCleanUp > 0) {
-			switch (slave.assignment) {
-				case "whore":
-					r.push(`${He} heads to the bathroom to clean ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes before returning to selling them publicly.`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole before returning to selling it publicly.`);
-					} else {
-						r.push(`face before returning to selling ${his} mouth publicly.`);
-					}
-					break;
-				case "serve the public":
-					r.push(`${He} heads to the bathroom to clean ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes before returning to offering it for free.`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole before returning to offering it for free.`);
-					} else {
-						r.push(`face before returning to offering ${his} mouth for free.`);
-					}
-					break;
-				case "rest":
-					r.push(`${He} stumbles to the bathroom to clean ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole`);
-					} else {
-						r.push(`face`);
-					}
-					r.push(`before crawling back into bed.`);
-					break;
-				case "be the Schoolteacher":
-					r.push(`${He} heads to the bathroom to clean ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole`);
-					} else {
-						r.push(`face`);
-					}
-					r.push(`before ${he} returns to teaching ${his} classes.`);
-					break;
-				case "get milked":
-					r.push(`${He} hurries to the bathroom to clean ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole`);
-					} else {
-						r.push(`face`);
-					}
-					if (slave.lactation > 0) {
-						r.push(`before going to get ${his} uncomfortably milk-filled tits drained.`);
-					} else {
-						r.push(`and then rests until ${his} balls are ready to be drained again.`);
-					}
-					break;
-				case "please you":
-					r.push(`${He} hurries to the bathroom to clean ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole`);
-					} else {
-						r.push(`face`);
-					}
-					r.push(`before returning to await your next use of ${his} body, as though nothing had happened.`);
-					break;
-				case "be a subordinate slave":
-					r.push(`${He} moves to the bathroom to clean ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes,`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole,`);
-					} else {
-						r.push(`face,`);
-					}
-					r.push(`though it's only a matter of time before another slave decides to play with ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`pussy or asshole.`);
-					} else if (canDoVaginal(slave)) {
-						r.push(`pussy.`);
-					} else if (canDoAnal(slave)) {
-						r.push(`asshole.`);
-					} else {
-						r.push(`face.`);
-					}
-					break;
-				case "be a servant":
-					r.push(`${He} hurries to the bathroom to clean ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes,`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole,`);
-					} else {
-						r.push(`face,`);
-					}
-					r.push(`since ${his} chores didn't perform themselves while you used ${him}.`);
-					break;
-				case "be your Head Girl":
-					r.push(`${He} hurries to the bathroom to clean ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes,`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole,`);
-					} else {
-						r.push(`face,`);
-					}
-					r.push(`worried that ${his} charges got up to trouble while you had your cock in ${him}.`);
-					break;
-				case "guard you":
-					r.push(`${He} hurries off to wash ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole`);
-					} else {
-						r.push(`face`);
-					}
-					r.push(`so you'll be unguarded for as little time as possible.`);
-					break;
-				case "work in the brothel":
-					r.push(`${He} goes to wash ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole`);
-					} else {
-						r.push(`face`);
-					}
-					r.push(`so ${his} next customer can have the illusion that he's the first to use it today.`);
-					break;
-				case "serve in the club":
-					r.push(`${He} goes to wash and delicately perfume ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes so they`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole so it`);
-					} else {
-						r.push(`face so it`);
-					}
-					r.push(`can gratify the finest citizen.`);
-					break;
-				case "work in the dairy":
-					r.push(`${He} goes off to carefully wash ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole`);
-					} else {
-						r.push(`face`);
-					}
-					r.push(`to avoid besmirching the nice clean dairy.`);
-					break;
-				case "work as a farmhand":
-					r.push(`${He} goes off to wash ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole`);
-					} else {
-						r.push(`face`);
-					}
-					r.push(`to avoid tainting the food in ${V.farmyardName}.`);
-					break;
-				case "work as a servant":
-					r.push(`${He} rushes to wash ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes,`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole,`);
-					} else {
-						r.push(`face,`);
-					}
-					r.push(`impatient to get back to ${his} undiminished chores.`);
-					break;
-				case "work as a nanny":
-					r.push(`${He} rushes to wash ${his}`);
-					if (canDoVaginal(slave) && canDoAnal(slave)) {
-						r.push(`holes,`);
-					} else if (canDoVaginal(slave) || canDoAnal(slave)) {
-						r.push(`fuckhole,`);
-					} else {
-						r.push(`face,`);
-					}
-					r.push(`before hurrying to continue taking care of the children in ${V.nurseryName}.`);
+			if (slave.anus > 3) {
+				text.push(`${His} gaping hole drips your cum right out again.`);
+			} else if (slave.anus > 2) {
+				text.push(`Cum drips out of ${his} loose hole.`);
+			} else if (slave.anus === 2) {
+				text.push(`Cum drips out of ${his} loosened anus.`);
+			} else if (slave.anus === 1) {
+				text.push(`${His} still-tight ass keeps your load inside ${him}.`);
+			}
+
+			if (canMove(slave) && V.postSexCleanUp > 0) {
+				switch (slave.assignment) {
+					case "whore":
+						text.push(`${He} heads to the bathroom to clean ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes before returning to selling them publicly.`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole before returning to selling it publicly.`);
+						} else {
+							text.push(`face before returning to selling ${his} mouth publicly.`);
+						}
+						break;
+					case "serve the public":
+						text.push(`${He} heads to the bathroom to clean ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes before returning to offering it for free.`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole before returning to offering it for free.`);
+						} else {
+							text.push(`face before returning to offering ${his} mouth for free.`);
+						}
+						break;
+					case "rest":
+						text.push(`${He} stumbles to the bathroom to clean ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole`);
+						} else {
+							text.push(`face`);
+						}
+
+						text.push(`before crawling back into bed.`);
+						break;
+					case "be the Schoolteacher":
+						text.push(`${He} heads to the bathroom to clean ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole`);
+						} else {
+							text.push(`face`);
+						}
+
+						text.push(`before ${he} returns to teaching ${his} classes.`);
+						break;
+					case "get milked":
+						text.push(`${He} hurries to the bathroom to clean ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole`);
+						} else {
+							text.push(`face`);
+						}
+
+						if (slave.lactation > 0) {
+							text.push(`before going to get ${his} uncomfortably milk-filled tits drained.`);
+						} else {
+							text.push(`and then rests until ${his} balls are ready to be drained again.`);
+						}
+						break;
+					case "please you":
+						text.push(`${He} hurries to the bathroom to clean ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole`);
+						} else {
+							text.push(`face`);
+						}
+
+						text.push(`before returning to await your next use of ${his} body, as though nothing had happened.`);
+						break;
+					case "be a subordinate slave":
+						text.push(`${He} moves to the bathroom to clean ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes,`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole,`);
+						} else {
+							text.push(`face,`);
+						}
+
+						text.push(`though it's only a matter of time before another slave decides to play with ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`pussy or asshole.`);
+						} else if (canDoVaginal(slave)) {
+							text.push(`pussy.`);
+						} else if (canDoAnal(slave)) {
+							text.push(`asshole.`);
+						} else {
+							text.push(`face.`);
+						}
+
+						break;
+					case "be a servant":
+						text.push(`${He} hurries to the bathroom to clean ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes,`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole,`);
+						} else {
+							text.push(`face,`);
+						}
+
+						text.push(`since ${his} chores didn't perform themselves while you used ${him}.`);
+						break;
+					case "be your Head Girl":
+						text.push(`${He} hurries to the bathroom to clean ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes,`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole,`);
+						} else {
+							text.push(`face,`);
+						}
+
+						text.push(`worried that ${his} charges got up to trouble while you had your cock in ${him}.`);
+						break;
+					case "guard you":
+						text.push(`${He} hurries off to wash ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole`);
+						} else {
+							text.push(`face`);
+						}
+
+						text.push(`so you'll be unguarded for as little time as possible.`);
+						break;
+					case "work in the brothel":
+						text.push(`${He} goes to wash ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole`);
+						} else {
+							text.push(`face`);
+						}
+
+						text.push(`so ${his} next customer can have the illusion that he's the first to use it today.`);
+						break;
+					case "serve in the club":
+						text.push(`${He} goes to wash and delicately perfume ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes so they`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole so it`);
+						} else {
+							text.push(`face so it`);
+						}
+
+						text.push(`can gratify the finest citizen.`);
+						break;
+					case "work in the dairy":
+						text.push(`${He} goes off to carefully wash ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole`);
+						} else {
+							text.push(`face`);
+						}
+
+						text.push(`to avoid besmirching the nice clean dairy.`);
+						break;
+					case "work as a farmhand":
+						text.push(`${He} goes off to wash ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole`);
+						} else {
+							text.push(`face`);
+						}
+
+						text.push(`to avoid tainting the food in ${V.farmyardName}.`);
+						break;
+					case "work as a servant":
+						text.push(`${He} rushes to wash ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes,`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole,`);
+						} else {
+							text.push(`face,`);
+						}
+
+						text.push(`impatient to get back to ${his} undiminished chores.`);
+						break;
+					case "work as a nanny":
+						text.push(`${He} rushes to wash ${his}`);
+
+						if (canDoVaginal(slave) && canDoAnal(slave)) {
+							text.push(`holes,`);
+						} else if (canDoVaginal(slave) || canDoAnal(slave)) {
+							text.push(`fuckhole,`);
+						} else {
+							text.push(`face,`);
+						}
+
+						text.push(`before hurrying to continue taking care of the children in ${V.nurseryName}.`);
+						break;
+				}
 			}
 		}
+
+		return text.join(' ');
 	}
-	App.Events.addParagraph(node, r);
-	return node;
 };
diff --git a/src/npc/interaction/fCaress.js b/src/npc/interaction/fCaress.js
index 94346cfae826b42e1f4133359992fb9656ccdcbd..446c1230b28c3db57592759fa1fb003c433179b1 100644
--- a/src/npc/interaction/fCaress.js
+++ b/src/npc/interaction/fCaress.js
@@ -4,359 +4,411 @@
  * @returns {DocumentFragment}
  */
 App.Interact.fCaress = function(slave) {
-	const node = new DocumentFragment();
-	let r = [];
+	const frag = new DocumentFragment();
 
 	const {
 		He, His,
 		he, his, him, himself, hers, woman, girl
 	} = getPronouns(slave);
 
-	const {title: Master, say: say} = getEnunciation(slave);
-
-	const {womanP} = getPronouns(V.PC).appendSuffix("P");
-
-	r.push(`You tell ${slave.slaveName} to`);
-	if (!hasAnyLegs(slave)) {
-		r.push(`have another slave set ${him} down on your desk.`);
-	} else if (tooBigBreasts(slave)) {
-		r.push(`have another slave help ${him} heft ${his} tits so ${he} can be near you.`);
-	} else if (tooBigBelly(slave)) {
-		r.push(`have another slave help ${him} heft ${his} belly so ${he} can be near you.`);
-	} else if (tooBigButt(slave)) {
-		r.push(`have another slave help ${him} heft ${his} ass cheeks so ${he} can be near you.`);
-	} else if (tooBigDick(slave)) {
-		r.push(`have another slave help ${him} heft ${his} cock so ${he} can be near you.`);
-	} else if (tooBigBalls(slave)) {
-		r.push(`have another slave help ${him} heft ${his} balls so ${he} can be near you.`);
-	} else if (tooFatSlave(slave)) {
-		r.push(`have another slave help ${him} up so ${he} can be near you.`);
-	} else {
-		r.push(`move closer towards you.`);
-	}
+	const {title: Master, say} = getEnunciation(slave);
+
+	const {woman: womanP} = getPronouns(V.PC);
+
+	const text = new SpacedTextAccumulator(frag);
+
+	text.push(
+		intro(),
+		setup(),
+		consummation(),
+	);
+
+	text.toParagraph();
 
-	if (slave.fetish === "mindbroken" && slave.relationship !== -3) {
-		r.push(`${He} complies mechanically. ${He} remembers that when getWrittenTitle(slave)'s commands are not obeyed, there is punishment.`);
-	} else if (slave.relationship === -2) {
-		r.push(`${He} eagerly complies, happy to be near the object of ${his} longing. Once ${he}'s close, you hold ${his} face in your palms and gaze deeply`);
-		if (canSee(slave)) {
-			r.push(`into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he} loves overwhelming, and ${his} eyes flick downward after a moment.`);
+	return frag;
+
+	function intro() {
+		const text = [];
+
+		text.push(`You tell ${slave.slaveName} to`);
+
+		if (!hasAnyLegs(slave)) {
+			text.push(`have another slave set ${him} down on your desk.`);
+		} else if (tooBigBreasts(slave)) {
+			text.push(`have another slave help ${him} heft ${his} tits so ${he} can be near you.`);
+		} else if (tooBigBelly(slave)) {
+			text.push(`have another slave help ${him} heft ${his} belly so ${he} can be near you.`);
+		} else if (tooBigButt(slave)) {
+			text.push(`have another slave help ${him} heft ${his} ass cheeks so ${he} can be near you.`);
+		} else if (tooBigDick(slave)) {
+			text.push(`have another slave help ${him} heft ${his} cock so ${he} can be near you.`);
+		} else if (tooBigBalls(slave)) {
+			text.push(`have another slave help ${him} heft ${his} balls so ${he} can be near you.`);
+		} else if (tooFatSlave(slave)) {
+			text.push(`have another slave help ${him} up so ${he} can be near you.`);
 		} else {
-			r.push(`upon ${his} face. ${He} senses the intense look from the ${womanP} ${he} loves and finds it overwhelming, and after a moment glances away.`);
+			text.push(`move closer towards you.`);
 		}
-		r.push(`${He} blushes furiously.`);
-	} else if (slave.relationship === -3) {
-		if (slave.fetish === "mindbroken") {
-			r.push(`${He} complies mechanically. ${He} remembers that when ${getWrittenTitle(slave)}'s commands are not obeyed, there is punishment. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} blank ${App.Desc.eyesColor(slave)}. ${He} doesn't react.`);
-		} else if (slave.devotion+slave.trust >= 175) {
-			r.push(`${He} happily complies, eager to be close to the ${womanP} who married ${him}. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s married to affirming, and looks down with a`);
-			if (canSee(slave)) {
-				r.push(`smile, running ${his} eyes over your`);
-				if (V.PC.boobs >= 300) {
-					r.push(`bosom.`);
-				} else {
-					r.push(`chest.`);
-				}
-			} else {
-				r.push(`smile.`);
-			}
-		} else if (slave.devotion < -20 && slave.trust > 20) {
-			r.push(`${He} complies. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s forcibly married to disturbing, and`);
-			if (canSee(slave)) {
-				r.push(`breaks eye contact.`);
-			} else {
-				r.push(`turns ${his} face away.`);
-			}
-		} else if (slave.devotion < -20) {
-			r.push(`${He} complies out of fear. Once ${he}'s close, you hold ${his} shaking face in your palms and look into ${his} teary ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s forcibly married to terrifying, and`);
+
+		return text.join(' ');
+	}
+
+	function setup() {
+		const text = [];
+
+		if (slave.fetish === "mindbroken" && slave.relationship !== -3) {
+			text.push(`${He} complies mechanically. ${He} remembers that when getWrittenTitle(slave)'s commands are not obeyed, there is punishment.`);
+		} else if (slave.relationship === -2) {
+			text.push(`${He} eagerly complies, happy to be near the object of ${his} longing. Once ${he}'s close, you hold ${his} face in your palms and gaze deeply`);
+
 			if (canSee(slave)) {
-				r.push(`breaks eye contact.`);
+				text.push(`into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he} loves overwhelming, and ${his} eyes flick downward after a moment.`);
 			} else {
-				r.push(`turns ${his} face away.`);
+				text.push(`upon ${his} face. ${He} senses the intense look from the ${womanP} ${he} loves and finds it overwhelming, and after a moment glances away.`);
 			}
-		} else {
-			r.push(`${He} complies obediently. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s married to reassuring, and looks down with a slight`);
-			if (canSee(slave)) {
-				r.push(`smile, running ${his} eyes over your`);
-				if (V.PC.boobs >= 300) {
-					r.push(`bosom.`);
+
+			text.push(`${He} blushes furiously.`);
+		} else if (slave.relationship === -3) {
+			if (slave.fetish === "mindbroken") {
+				text.push(`${He} complies mechanically. ${He} remembers that when ${getWrittenTitle(slave)}'s commands are not obeyed, there is punishment. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} blank ${App.Desc.eyesColor(slave)}. ${He} doesn't react.`);
+			} else if (slave.devotion+slave.trust >= 175) {
+				text.push(`${He} happily complies, eager to be close to the ${womanP} who married ${him}. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s married to affirming, and looks down with a`);
+
+				if (canSee(slave)) {
+					text.push(`smile, running ${his} eyes over your`);
+					if (V.PC.boobs >= 300) {
+						text.push(`bosom.`);
+					} else {
+						text.push(`chest.`);
+					}
+				} else {
+					text.push(`smile.`);
+				}
+			} else if (slave.devotion < -20 && slave.trust > 20) {
+				text.push(`${He} complies. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s forcibly married to disturbing, and`);
+
+				if (canSee(slave)) {
+					text.push(`breaks eye contact.`);
 				} else {
-					r.push(`chest.`);
+					text.push(`turns ${his} face away.`);
+				}
+			} else if (slave.devotion < -20) {
+				text.push(`${He} complies out of fear. Once ${he}'s close, you hold ${his} shaking face in your palms and look into ${his} teary ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s forcibly married to terrifying, and`);
+
+				if (canSee(slave)) {
+					text.push(`breaks eye contact.`);
+				} else {
+					text.push(`turns ${his} face away.`);
 				}
 			} else {
-				r.push(`smile.`);
+				text.push(`${He} complies obediently. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s married to reassuring, and looks down with a slight`);
+
+				if (canSee(slave)) {
+					text.push(`smile, running ${his} eyes over your`);
+					if (V.PC.boobs >= 300) {
+						text.push(`bosom.`);
+					} else {
+						text.push(`chest.`);
+					}
+				} else {
+					text.push(`smile.`);
+				}
 			}
+		} else if (slave.devotion > 75) {
+			text.push(`${He} hurriedly complies, happy to be near you. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from ${his} beloved ${getWrittenTitle(slave)} disconcerting, and ${his} eyes flick downward after a moment. ${He} blushes furiously.`);
+		} else if (slave.devotion > 50) {
+			text.push(`${He} hurriedly complies, happy to be near you. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense attention from ${his} ${getWrittenTitle(slave)} disconcerting, and ${he} looks down after a moment, blushing.`);
+		} else if (slave.devotion > 20) {
+			text.push(`${He} hurriedly complies, happy to be near you. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense attention from ${his} ${getWrittenTitle(slave)} worrying, and ${he} looks down after a moment, blushing nervously.`);
+		} else if (slave.devotion >= -20 && slave.trust >= -20) {
+			text.push(`${He} visibly considers disobedience, but decides that complying with such an apparently harmless order is safe, for now. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense attention from ${his} ${getWrittenTitle(slave)} worrying, and ${he} looks down after a moment, ${his} lower lip trembling with nervousness.`);
+		} else if (slave.trust < -20) {
+			text.push(`The command terrifies ${him}, but ${he}'s more frightened still of the consequences of disobedience, and ${he} complies. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} looks down fearfully, and begins to shake with terror, tears leaking silently down ${his} cheeks.`);
+		} else {
+			text.push(`${He} pauses, obviously considering whether to resist, but eventually decides to save ${his} strength to fight more onerous orders, and gives in. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} stares back, but after a few moments ${he} loses the contest of wills and looks down.`);
 		}
-	} else if (slave.devotion > 75) {
-		r.push(`${He} hurriedly complies, happy to be near you. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from ${his} beloved ${getWrittenTitle(slave)} disconcerting, and ${his} eyes flick downward after a moment. ${He} blushes furiously.`);
-	} else if (slave.devotion > 50) {
-		r.push(`${He} hurriedly complies, happy to be near you. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense attention from ${his} ${getWrittenTitle(slave)} disconcerting, and ${he} looks down after a moment, blushing.`);
-	} else if (slave.devotion > 20) {
-		r.push(`${He} hurriedly complies, happy to be near you. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense attention from ${his} ${getWrittenTitle(slave)} worrying, and ${he} looks down after a moment, blushing nervously.`);
-	} else if (slave.devotion >= -20 && slave.trust >= -20) {
-		r.push(`${He} visibly considers disobedience, but decides that complying with such an apparently harmless order is safe, for now. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense attention from ${his} ${getWrittenTitle(slave)} worrying, and ${he} looks down after a moment, ${his} lower lip trembling with nervousness.`);
-	} else if (slave.trust < -20) {
-		r.push(`The command terrifies ${him}, but ${he}'s more frightened still of the consequences of disobedience, and ${he} complies. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} looks down fearfully, and begins to shake with terror, tears leaking silently down ${his} cheeks.`);
-	} else {
-		r.push(`${He} pauses, obviously considering whether to resist, but eventually decides to save ${his} strength to fight more onerous orders, and gives in. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} ${App.Desc.eyesColor(slave)}. ${He} stares back, but after a few moments ${he} loses the contest of wills and looks down.`);
-	}
 
-	r.push(`You delicately lift ${his} head and touch your fingertips to ${his} chin, tenderly brushing along the line of ${his} mouth with your`);
-	if (V.PC.title === 1) {
-		r.push(`manly`);
-	} else {
-		r.push(`feminine`);
+		return text.join(' ');
 	}
-	r.push(`thumb.`);
-	if (slave.lipsTat !== 0) {
-		r.push(`Your fingers trace ${his} facial tattoos, slowly picking out the patterns against ${his} ${slave.skin} skin.`);
-	}
-	if (slave.piercing.lips.weight+slave.piercing.tongue.weight > 2) {
-		r.push(`You touch each of ${his} facial piercings, one by one, feeling the hard metal contrast with ${his} pliant flesh.`);
-	}
-	r.push(`Then, you gently tilt ${his}`);
-	if (slave.face > 95) {
-		r.push(`overwhelmingly stunning`);
-	} else if (slave.face > 10) {
-		r.push(`alluring`);
-	} else if (slave.face >= -10) {
-		r.push(`appealing`);
-	} else if (slave.face >= -40) {
-		r.push(`plain`);
-	} else {
-		r.push(`rough`);
-	}
-	r.push(`head back and lightly touch ${his}`);
-	if (slave.lips > 95) {
-		r.push(`facepussy`);
-	} else {
-		if (slave.lips > 70) {
-			r.push(`pillowlike`);
-		} else if (slave.lips > 40) {
-			r.push(`generous`);
-		} else if (slave.lips > 20) {
-			r.push(`plush`);
-		}
-		r.push(`lips`);
-	}
-	r.push(`with your fingertips. You use your fingers and thumbs to slowly slide along ${his} mouth, ${his} chin, ${his} cheeks then around ${his} face. You use a deft touch to thoroughly explore the shape of ${his}`);
-	if (slave.face > 95) {
-		r.push(`gorgeous`);
-	} else if (slave.face > 10) {
-		r.push(`nice`);
-	} else if (slave.face >= -10) {
-		r.push(`cute`);
-	} else if (slave.face >= -40) {
-		r.push(`fair`);
-	} else {
-		r.push(`prominent`);
-	}
-	r.push(`cheekbones. Grazing ${his} temple and brushing ${his} forehead simultaneously, you smoothly motion along ${his} eyelids and nose, and tenderly stroke ${his} face with both hands as you take ${his} head lightly and trace around it, gently massaging as you go. You work your way down, slowly and gradually, along ${his} neck with one hand, then the other, briefly pausing before continuing your path down to ${his} shoulders and`);
-	if (slave.fetish !== "mindbroken") {
-		r.push(`${he} starts to gasp as`);
-	} else {
-		r.push(`starts to shudder as`);
-	}
-	r.push(`you slide your hands down ${his} side, across ${his} back and along ${his} belly taking every moment to savor the contours of ${his} body before going back up again to ${his} face.`);
 
-	if (slave.fetish === "mindbroken") {
-		r.push(`${His} posture doesn't change. ${He} initially only reacts slightly to your physical touch but then stops reacting completely. When you stop, ${his} ${App.Desc.eyesColor(slave)} track the movements of your hands briefly but then stare blankly ahead of ${him}, awaiting further use of ${his} body.`);
-	} else if (slave.relationship === -2) {
-		r.push(`${His} eyes gradually close and ${he} slowly leans ${his} head back, relaxing as ${he} feels your caress. ${He} gently gasps as ${he} feels your warm`);
+	function consummation() {
+		const text = [];
+
+
+		text.push(`You delicately lift ${his} head and touch your fingertips to ${his} chin, tenderly brushing along the line of ${his} mouth with your`);
+
 		if (V.PC.title === 1) {
-			r.push(`manly`);
+			text.push(`manly`);
 		} else {
-			r.push(`feminine`);
+			text.push(`feminine`);
 		}
-		r.push(`hand. When you finally stop gently caressing ${him}, ${his} eyes remain closed and ${his} mouth still in a rapturous shape for a moment before ${he} slowly opens ${his} eyes and smiles at you, ${he} has an eager look on ${his} face.`);
-		if (hasAnyArms(slave)) {
-			r.push(`A hand reaches dumbly up to ${his} face mimicking your last movements.`);
+
+		text.push(`thumb.`);
+
+		if (slave.lipsTat !== 0) {
+			text.push(`Your fingers trace ${his} facial tattoos, slowly picking out the patterns against ${his} ${slave.skin} skin.`);
 		}
-		r.push(``);
-		if (slave.accent >= 3) {
-			r.push(`${He} does ${his} best to communicate love with ${his} ${App.Desc.eyesColor(slave)}, since ${he} does not speak ${V.language} well enough to express ${himself}.`);
-		} else if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${He} does ${his} best to communicate love with ${his} ${App.Desc.eyesColor(slave)}.`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs that ${he} loves you.`);
-		} else {
-			r.push(
-				Spoken(slave, `"I love you, ${Master},"`),
-				`${he} ${say}s dreamily.`
-			);
+
+		if (slave.piercing.lips.weight + slave.piercing.tongue.weight > 2) {
+			text.push(`You touch each of ${his} facial piercings, one by one, feeling the hard metal contrast with ${his} pliant flesh.`);
 		}
-		r.push(`${He} looks as though ${he} wants much more than your mere caress.`);
-	} else if (slave.devotion > 50 && slave.fetish === "dom" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-		r.push(`As you start to touch ${his}`);
+
+		text.push(`Then, you gently tilt ${his}`);
+
 		if (slave.face > 95) {
-			r.push(`gorgeous`);
+			text.push(`overwhelmingly stunning`);
 		} else if (slave.face > 10) {
-			r.push(`lovely`);
+			text.push(`alluring`);
 		} else if (slave.face >= -10) {
-			r.push(`pretty`);
+			text.push(`appealing`);
 		} else if (slave.face >= -40) {
-			r.push(`homely`);
-		} else {
-			r.push(`ugly`);
-		}
-		r.push(`face, ${he} smiles at you and takes your hand in ${hers}, following its movements. ${He} tries hard to stop ${himself} from losing ${himself} in your masterful hands. ${He} takes ${his} tendency towards sexual dominance right up to the edge of insubordination, when ${he} starts to caress your face in turn. When you finally stop, ${his} eyes are closed and ${he}'s smiling.`);
-		if (slave.accent >= 3) {
-			r.push(`${He} does ${his} best to communicate excitement with ${his} ${App.Desc.eyesColor(slave)}, since ${he} does not speak ${V.language} well enough to express ${himself}.`);
-		} else if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${He} does ${his} best to communicate excitement with ${his} ${App.Desc.eyesColor(slave)}.`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs that ${he} liked that.`);
+			text.push(`plain`);
 		} else {
-			r.push(
-				Spoken(slave, `"That was fun, ${Master},"`),
-				`${he} ${say}s cheerfully.`
-			);
+			text.push(`rough`);
 		}
-		r.push(`${He} looks at you, ${his} eyes almost begging you to give ${him} more than your mere caress.`);
-	} else if (slave.devotion > 50 && slave.fetish === "cumslut" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-		r.push(`${He} stiffens at your touch but slowly relaxes to your fingers on ${his} face. As you move your fingers along ${his} lips, ${he} reacts almost as though ${he}'s receiving oral. ${He} starts to gently suck your fingers, moaning into your hand and pressing ${himself} lewdly against your`);
-		if (V.PC.boobs >= 1400) {
-			r.push(`giant tits.`);
-		} else if (V.PC.boobs >= 1200) {
-			r.push(`huge breasts.`);
-		} else if (V.PC.boobs >= 1000) {
-			r.push(`big breasts.`);
-		} else if (V.PC.boobs >= 800) {
-			r.push(`prominent breasts.`);
-		} else if (V.PC.boobs >= 650) {
-			r.push(`unremarkable breasts.`);
-		} else if (V.PC.boobs >= 500) {
-			r.push(`breasts.`);
-		} else if (V.PC.boobs >= 300) {
-			r.push(`tiny breasts.`);
-		} else if (V.PC.title > 0) {
-			r.push(`manly chest.`);
-		} else {
-			r.push(`non-existent breasts.`);
-		}
-		if (slave.teeth === "pointy") {
-			r.push(`${He}'s very careful to avoid spearing your finger with ${his} sharp teeth.`);
-		} else if (slave.teeth === "fangs") {
-			r.push(`${He} holds perfectly still so you may trace ${his} fangs without getting poked.`);
-		} else if (slave.teeth === "fang") {
-			r.push(`You give ${his} lone fang a little extra attention as you work.`);
-		}
-		r.push(`${He} achieves a weak orgasm before you stop caressing ${him}.`);
-		if (slave.accent >= 3) {
-			r.push(`${He} does ${his} best to communicate undiminished lust with ${his} ${App.Desc.eyesColor(slave)}, since ${he} does not speak ${V.language} well enough to express ${himself}.`);
-		} else if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${He} does ${his} best to communicate undiminished lust with ${his} ${App.Desc.eyesColor(slave)}.`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs that ${he} liked that.`);
-		} else {
-			r.push(
-				Spoken(slave, `"That was fun, ${Master},"`),
-				`${he} ${say}s lustfully.`
-			);
-		}
-		r.push(`${He} looks at you as if ${he} wants more than your hands touching ${him}.`);
-	} else if (slave.devotion > 50) {
-		r.push(`${He} accepts your touch with devotion, leaning ${his} head back at your gentle caress along ${his} face. ${He} leans ${his} body forward, pressing ${himself} against you, and you feel the intense heat from ${his} body against your`);
-		const firm = V.PC.boobsImplant/V.PC.boobs >= .60 ? "firm" : "soft";
-		if (V.PC.boobs >= 1400) {
-			r.push(`expansive ${firm} chest.`);
-		} else if (V.PC.boobs >= 1200) {
-			r.push(`huge ${firm} breasts.`);
-		} else if (V.PC.boobs >= 1000) {
-			r.push(`big ${firm} breasts.`);
-		} else if (V.PC.boobs >= 800) {
-			r.push(`soft breasts.`);
-		} else if (V.PC.boobs >= 500) {
-			r.push(`breasts.`);
-		} else if (V.PC.boobs >= 300) {
-			r.push(`small chest.`);
-		} else if (V.PC.title > 0) {
-			r.push(`manly chest.`);
-		} else {
-			r.push(`flat chest.`);
-		}
-		r.push(`${He} gradually closes ${his} eyes and when you finally stop,`);
-		if (hasAnyArms(slave)) {
-			r.push(`${he} runs ${his} hand delightfully across ${his} face where you last touched ${him},`);
-		} else {
-			r.push(`there is`);
-		}
-		r.push(`a euphoric look on ${his} ${slave.skin} face.`);
-		if (slave.accent >= 3) {
-			r.push(`${He} does ${his} best to communicate devotion with ${his} ${App.Desc.eyesColor(slave)}, since ${he}'s not confident in ${his} ability to express it in ${V.language}.`);
-		} else if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${He} does ${his} best to communicate devotion with ${his} ${App.Desc.eyesColor(slave)}.`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs that ${he} loves you.`);
-		} else {
-			r.push(
-				Spoken(slave, `"I love you, ${Master},"`),
-				`${he} ${say}s jubilantly.`
-			);
-		}
-		r.push(`${He} looks at you longingly, almost as if ${he}'s bursting to say that ${he} wants more than your mere caress.`);
-	} else if (slave.devotion > 20) {
-		r.push(`${He} accepts your touch willingly. As you are so close to ${him}, you sense considerable turmoil in the`);
-		if (slave.physicalAge > 30) {
-			r.push(`${woman};`);
-		} else {
-			r.push(`${girl};`);
-		}
-		r.push(`${he}'s doing ${his} duty as a slave by complying with your wishes, and is probably struggling with the mixture of resistance, obedience and perhaps even devotion forced to the forefront of ${his} mind by your touch across ${his} face. When you finally move your hand away, ${his} ${App.Desc.eyesColor(slave)} gaze into yours searchingly, looking for answers that are not there.`);
-		if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${His} eyes beg for an answer: is that it?`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs hesitantly, asking if that's it.`);
-		} else {
-			r.push(
-				`${He} asks hesitantly,`,
-				Spoken(slave, `"I-is that it, ${Master}?"`)
-			);
-		}
-	} else if (slave.devotion >= -20 && slave.trust < -20) {
-		r.push(`${He} shakes at your touch fearfully. As you move your hand along ${his} unresisting face, ${his} eagerness to avoid punishment leads ${him} to stiffen, ${his} nervousness is made apparent. You continue stroking ${his} cheek, enjoying ${his} fear, and the physical intimacy slowly does its work. ${He} starts to relax, ${his} resistance easing and ${his} eyes start to close. When finally move your hand away, ${he} looks at you for a long moment, ${his} eyes darting up at you, before visibly catching ${himself} with a reminder that ${he}'s a slave and you're ${his} owner.`);
-		if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${His} eyes beg for an answer: is that it?`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs hesitantly, asking if that's it.`);
+
+		text.push(`head back and lightly touch ${his}`);
+
+		if (slave.lips > 95) {
+			text.push(`facepussy`);
 		} else {
-			r.push(
-				`${He} asks hesitantly,`,
-				Spoken(slave, `"I-is that it, ${Master}?"`)
-			);
+			if (slave.lips > 70) {
+				text.push(`pillowlike`);
+			} else if (slave.lips > 40) {
+				text.push(`generous`);
+			} else if (slave.lips > 20) {
+				text.push(`plush`);
+			}
+			text.push(`lips`);
 		}
-	} else if (slave.trust < -50) {
-		r.push(`${He} is nearly frozen with fear, and does not resist as you start to caress ${his} face. In fact, ${he} barely reacts at all. ${He} stares at you as you move your fingers across ${his} stiff face, but it's like touching a statue. ${He} is so filled with terror that ${he} remains stiff even as it becomes clear to ${him} you're not going to hurt ${him}. When you bore of touching the`);
-		if (slave.physicalAge > 30) {
-			r.push(`${woman}`);
+
+		text.push(`with your fingertips. You use your fingers and thumbs to slowly slide along ${his} mouth, ${his} chin, ${his} cheeks then around ${his} face. You use a deft touch to thoroughly explore the shape of ${his}`);
+
+		if (slave.face > 95) {
+			text.push(`gorgeous`);
+		} else if (slave.face > 10) {
+			text.push(`nice`);
+		} else if (slave.face >= -10) {
+			text.push(`cute`);
+		} else if (slave.face >= -40) {
+			text.push(`fair`);
 		} else {
-			r.push(`${girl}`);
+			text.push(`prominent`);
 		}
-		r.push(`and move your hand away, ${he} stares at you in utter incomprehension.`);
-		if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${His} eyes beg for an answer: is that it?`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs spastically, begging fearfully to know if that's it.`);
+
+		text.push(`cheekbones. Grazing ${his} temple and brushing ${his} forehead simultaneously, you smoothly motion along ${his} eyelids and nose, and tenderly stroke ${his} face with both hands as you take ${his} head lightly and trace around it, gently massaging as you go. You work your way down, slowly and gradually, along ${his} neck with one hand, then the other, briefly pausing before continuing your path down to ${his} shoulders and`);
+
+		if (slave.fetish !== "mindbroken") {
+			text.push(`${he} starts to gasp as`);
 		} else {
-			r.push(
-				`${He} asks nervously,`,
-				Spoken(slave, `"I-is that it, ${Master}?"`)
-			);
+			text.push(`starts to shudder as`);
 		}
-		r.push(`Then ${he} cringes.`);
-	} else {
-		r.push(`${He} reflexively turns away from you, but you catch ${his} head with one hand and slowly but gently move your other hand along ${his} face. Spluttering, ${he} leans backwards, but you tip forward with ${him} and pin ${him} against your desk, not stopping your gentle touch on ${his} head. ${He} tries to wriggle out of your grasp desperately, but ${his} struggles slowly subside as ${he} realizes that you're not taking this any farther. When you bore of it and move your hand away, ${he} stares at you in utter incomprehension.`);
-		if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${His} eyes demand an answer: is that it?`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs irritably, asking whether that's it.`);
+
+		text.push(`you slide your hands down ${his} side, across ${his} back and along ${his} belly taking every moment to savor the contours of ${his} body before going back up again to ${his} face.`);
+
+		if (slave.fetish === "mindbroken") {
+			text.push(`${His} posture doesn't change. ${He} initially only reacts slightly to your physical touch but then stops reacting completely. When you stop, ${his} ${App.Desc.eyesColor(slave)} track the movements of your hands briefly but then stare blankly ahead of ${him}, awaiting further use of ${his} body.`);
+		} else if (slave.relationship === -2) {
+			text.push(`${His} eyes gradually close and ${he} slowly leans ${his} head back, relaxing as ${he} feels your caress. ${He} gently gasps as ${he} feels your warm`);
+
+			if (V.PC.title === 1) {
+				text.push(`manly`);
+			} else {
+				text.push(`feminine`);
+			}
+
+			text.push(`hand. When you finally stop gently caressing ${him}, ${his} eyes remain closed and ${his} mouth still in a rapturous shape for a moment before ${he} slowly opens ${his} eyes and smiles at you, ${he} has an eager look on ${his} face.`);
+
+			if (hasAnyArms(slave)) {
+				text.push(`A hand reaches dumbly up to ${his} face mimicking your last movements.`);
+			}
+
+			if (slave.accent >= 3) {
+				text.push(`${He} does ${his} best to communicate love with ${his} ${App.Desc.eyesColor(slave)}, since ${he} does not speak ${V.language} well enough to express ${himself}.`);
+			} else if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${He} does ${his} best to communicate love with ${his} ${App.Desc.eyesColor(slave)}.`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs that ${he} loves you.`);
+			} else {
+				text.push(`${Spoken(slave, `"I love you, ${Master},"`)} ${he} ${say}s dreamily.`);
+			}
+
+			text.push(`${He} looks as though ${he} wants much more than your mere caress.`);
+		} else if (slave.devotion > 50 && slave.fetish === "dom" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
+			text.push(`As you start to touch ${his}`);
+
+			if (slave.face > 95) {
+				text.push(`gorgeous`);
+			} else if (slave.face > 10) {
+				text.push(`lovely`);
+			} else if (slave.face >= -10) {
+				text.push(`pretty`);
+			} else if (slave.face >= -40) {
+				text.push(`homely`);
+			} else {
+				text.push(`ugly`);
+			}
+
+			text.push(`face, ${he} smiles at you and takes your hand in ${hers}, following its movements. ${He} tries hard to stop ${himself} from losing ${himself} in your masterful hands. ${He} takes ${his} tendency towards sexual dominance right up to the edge of insubordination, when ${he} starts to caress your face in turn. When you finally stop, ${his} eyes are closed and ${he}'s smiling.`);
+
+			if (slave.accent >= 3) {
+				text.push(`${He} does ${his} best to communicate excitement with ${his} ${App.Desc.eyesColor(slave)}, since ${he} does not speak ${V.language} well enough to express ${himself}.`);
+			} else if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${He} does ${his} best to communicate excitement with ${his} ${App.Desc.eyesColor(slave)}.`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs that ${he} liked that.`);
+			} else {
+				text.push(`${Spoken(slave, `"That was fun, ${Master},"`)} ${he} ${say}s cheerfully.`);
+			}
+
+			text.push(`${He} looks at you, ${his} eyes almost begging you to give ${him} more than your mere caress.`);
+		} else if (slave.devotion > 50 && slave.fetish === "cumslut" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
+			text.push(`${He} stiffens at your touch but slowly relaxes to your fingers on ${his} face. As you move your fingers along ${his} lips, ${he} reacts almost as though ${he}'s receiving oral. ${He} starts to gently suck your fingers, moaning into your hand and pressing ${himself} lewdly against your`);
+
+			if (V.PC.boobs >= 1400) {
+				text.push(`giant tits.`);
+			} else if (V.PC.boobs >= 1200) {
+				text.push(`huge breasts.`);
+			} else if (V.PC.boobs >= 1000) {
+				text.push(`big breasts.`);
+			} else if (V.PC.boobs >= 800) {
+				text.push(`prominent breasts.`);
+			} else if (V.PC.boobs >= 650) {
+				text.push(`unremarkable breasts.`);
+			} else if (V.PC.boobs >= 500) {
+				text.push(`breasts.`);
+			} else if (V.PC.boobs >= 300) {
+				text.push(`tiny breasts.`);
+			} else if (V.PC.title > 0) {
+				text.push(`manly chest.`);
+			} else {
+				text.push(`non-existent breasts.`);
+			}
+
+			if (slave.teeth === "pointy") {
+				text.push(`${He}'s very careful to avoid spearing your finger with ${his} sharp teeth.`);
+			} else if (slave.teeth === "fangs") {
+				text.push(`${He} holds perfectly still so you may trace ${his} fangs without getting poked.`);
+			} else if (slave.teeth === "fang") {
+				text.push(`You give ${his} lone fang a little extra attention as you work.`);
+			}
+
+			text.push(`${He} achieves a weak orgasm before you stop caressing ${him}.`);
+
+			if (slave.accent >= 3) {
+				text.push(`${He} does ${his} best to communicate undiminished lust with ${his} ${App.Desc.eyesColor(slave)}, since ${he} does not speak ${V.language} well enough to express ${himself}.`);
+			} else if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${He} does ${his} best to communicate undiminished lust with ${his} ${App.Desc.eyesColor(slave)}.`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs that ${he} liked that.`);
+			} else {
+				text.push(`${Spoken(slave, `"That was fun, ${Master},"`)} ${he} ${say}s lustfully.`);
+			}
+
+			text.push(`${He} looks at you as if ${he} wants more than your hands touching ${him}.`);
+		} else if (slave.devotion > 50) {
+			text.push(`${He} accepts your touch with devotion, leaning ${his} head back at your gentle caress along ${his} face. ${He} leans ${his} body forward, pressing ${himself} against you, and you feel the intense heat from ${his} body against your`);
+
+			const firm = V.PC.boobsImplant / V.PC.boobs >= .60 ? "firm" : "soft";
+			if (V.PC.boobs >= 1400) {
+				text.push(`expansive ${firm} chest.`);
+			} else if (V.PC.boobs >= 1200) {
+				text.push(`huge ${firm} breasts.`);
+			} else if (V.PC.boobs >= 1000) {
+				text.push(`big ${firm} breasts.`);
+			} else if (V.PC.boobs >= 800) {
+				text.push(`soft breasts.`);
+			} else if (V.PC.boobs >= 500) {
+				text.push(`breasts.`);
+			} else if (V.PC.boobs >= 300) {
+				text.push(`small chest.`);
+			} else if (V.PC.title > 0) {
+				text.push(`manly chest.`);
+			} else {
+				text.push(`flat chest.`);
+			}
+
+			text.push(`${He} gradually closes ${his} eyes and when you finally stop,`);
+
+			if (hasAnyArms(slave)) {
+				text.push(`${he} runs ${his} hand delightfully across ${his} face where you last touched ${him},`);
+			} else {
+				text.push(`there is`);
+			}
+
+			text.push(`a euphoric look on ${his} ${slave.skin} face.`);
+
+			if (slave.accent >= 3) {
+				text.push(`${He} does ${his} best to communicate devotion with ${his} ${App.Desc.eyesColor(slave)}, since ${he}'s not confident in ${his} ability to express it in ${V.language}.`);
+			} else if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${He} does ${his} best to communicate devotion with ${his} ${App.Desc.eyesColor(slave)}.`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs that ${he} loves you.`);
+			} else {
+				text.push(`${Spoken(slave, `"I love you, ${Master},"`)} ${he} ${say}s jubilantly.`);
+			}
+
+			text.push(`${He} looks at you longingly, almost as if ${he}'s bursting to say that ${he} wants more than your mere caress.`);
+		} else if (slave.devotion > 20) {
+			text.push(`${He} accepts your touch willingly. As you are so close to ${him}, you sense considerable turmoil in the`);
+
+			if (slave.physicalAge > 30) {
+				text.push(`${woman};`);
+			} else {
+				text.push(`${girl};`);
+			}
+
+			text.push(`${he}'s doing ${his} duty as a slave by complying with your wishes, and is probably struggling with the mixture of resistance, obedience and perhaps even devotion forced to the forefront of ${his} mind by your touch across ${his} face. When you finally move your hand away, ${his} ${App.Desc.eyesColor(slave)} gaze into yours searchingly, looking for answers that are not there.`);
+
+			if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${His} eyes beg for an answer: is that it?`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs hesitantly, asking if that's it.`);
+			} else {
+				text.push(`${He} asks hesitantly, ${Spoken(slave, `"I-is that it, ${Master}?"`)}`);
+			}
+		} else if (slave.devotion >= -20 && slave.trust < -20) {
+			text.push(`${He} shakes at your touch fearfully. As you move your hand along ${his} unresisting face, ${his} eagerness to avoid punishment leads ${him} to stiffen, ${his} nervousness is made apparent. You continue stroking ${his} cheek, enjoying ${his} fear, and the physical intimacy slowly does its work. ${He} starts to relax, ${his} resistance easing and ${his} eyes start to close. When finally move your hand away, ${he} looks at you for a long moment, ${his} eyes darting up at you, before visibly catching ${himself} with a reminder that ${he}'s a slave and you're ${his} owner.`);
+
+			if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${His} eyes beg for an answer: is that it?`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs hesitantly, asking if that's it.`);
+			} else {
+				text.push(`${He} asks hesitantly, ${Spoken(slave, `"I-is that it, ${Master}?"`)}`);
+			}
+		} else if (slave.trust < -50) {
+			text.push(`${He} is nearly frozen with fear, and does not resist as you start to caress ${his} face. In fact, ${he} barely reacts at all. ${He} stares at you as you move your fingers across ${his} stiff face, but it's like touching a statue. ${He} is so filled with terror that ${he} remains stiff even as it becomes clear to ${him} you're not going to hurt ${him}. When you bore of touching the`);
+
+			if (slave.physicalAge > 30) {
+				text.push(`${woman}`);
+			} else {
+				text.push(`${girl}`);
+			}
+
+			text.push(`and move your hand away, ${he} stares at you in utter incomprehension.`);
+
+			if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${His} eyes beg for an answer: is that it?`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs spastically, begging fearfully to know if that's it.`);
+			} else {
+				text.push(`${He} asks nervously, ${Spoken(slave, `"I-is that it, ${Master}?"`)}`);
+			}
+
+			text.push(`Then ${he} cringes.`);
 		} else {
-			r.push(
-				`${He} splutters,`,
-				Spoken(slave, `"Is that it, ${Master}!?"`)
-			);
+			text.push(`${He} reflexively turns away from you, but you catch ${his} head with one hand and slowly but gently move your other hand along ${his} face. Spluttering, ${he} leans backwards, but you tip forward with ${him} and pin ${him} against your desk, not stopping your gentle touch on ${his} head. ${He} tries to wriggle out of your grasp desperately, but ${his} struggles slowly subside as ${he} realizes that you're not taking this any farther. When you bore of it and move your hand away, ${he} stares at you in utter incomprehension.`);
+
+			if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${His} eyes demand an answer: is that it?`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs irritably, asking whether that's it.`);
+			} else {
+				text.push(`${He} splutters, ${Spoken(slave, `"Is that it, ${Master}!?"`)}`);
+			}
 		}
+
+		return text.join(' ');
 	}
-	App.Events.addParagraph(node, r);
-	return node;
 };
diff --git a/src/npc/interaction/fDance.js b/src/npc/interaction/fDance.js
index 466ffa260eb2836a00585cb8188055c61b5c4673..7557c9e1ff7dece1df7953e11fbc2e119dd7f2e4 100644
--- a/src/npc/interaction/fDance.js
+++ b/src/npc/interaction/fDance.js
@@ -4,1656 +4,1735 @@
  * @returns {DocumentFragment}
  */
 App.Interact.fDance = function(slave) {
-	const node = new DocumentFragment();
-	let r = [];
+	const frag = new DocumentFragment();
 
 	// TODO: expand fetish blocks
-
 	const {
 		He, His,
 		he, his, him, hers, himself, woman, girl
 	} = getPronouns(slave);
-	const {hisP, womenP, womanP} = getPronouns(V.PC).appendSuffix("P");
-	r.push(`You tell ${V.assistant.name} to summon ${slave.slaveName} and set some erotic music. When your slave arrives, ${he} finds the lights in your office flashing club colors. You gesture towards the platform in the center of your office and tell ${him} to dance for you.`);
+	const {his: hisP, women: womenP, woman: womanP} = getPronouns(V.PC);
 
-	if (slave.skill.entertainment > 99) {
-		r.push(`${He} slides ${his} ass gracefully unto the stage, then dramatically raises ${his} elongated ${(hasBothLegs(slave)) ? `legs one at a time` : `leg`} onto the platform. Circling to ${his} ${(hasBothLegs(slave)) ? `knees` : `knee`}, ${he} raises ${his} ass in the air`);
-		if (hasAnyArms(slave)) {
-			r.push(`and glides ${his} ${(hasBothArms(slave)) ? `hands` : `hand`} up ${his} ${(hasBothLegs(slave)) ? `legs` : `leg`}`);
-		}
-		r.push(`as ${he} stands upright.`);
-	} else if (slave.skill.entertainment > 60) {
-		r.push(`${He} takes ${his} rightful place on your stage.`);
-	} else if (slave.skill.entertainment > 40) {
-		r.push(`${He} goes to take ${his} place on your stage and dance for ${his} ${getWrittenTitle(slave)}.`);
-	} else if (slave.skill.entertainment > 20) {
-		r.push(`${He} ascends to the platform and begins to grind at the pole.`);
-	} else if (slave.skill.entertainment > 9) {
-		r.push(`${He} climbs up onto the platform and grabs onto the pole.`);
-	} else if (slave.skill.entertainment > -10) {
-		r.push(`${He} climbs up onto the platform and grabs onto the pole.`);
+	const text = new SpacedTextAccumulator(frag);
+
+	text.push(
+		intro(),
+		consummation(),
+	);
+
+	// TODO: more varied reactions planned
+	if (random(1, 100) > (100 + slave.devotion)) {
+		text.push(slaveGainsFlaw());
+	} else if (random(1, 100) > (110 - slave.devotion)) {
+		text.push(slaveGainsQuirk());
+	}
+
+	text.toParagraph();
+
+	return frag;
+
+	function intro() {
+		return `You tell ${V.assistant.name} to summon ${slave.slaveName} and turn on some erotic music. When your slave arrives, ${he} finds the lights in your office flashing club colors. You gesture towards the platform in the center of your office and tell ${him} to dance for you.`;
 	}
 
-	if (slave.weight > 190) {
-		r.push(`${He} is so ${either("enormous", "massive")} that ${he} can barely move ${his} weight around. ${His} rolls sway and jiggle with every move, creating a ripple canvas of swirling fat.`);
-	} else if (slave.weight > 160) {
-		r.push(`${He} is quite large, and ${his} weight threatens to pull ${him} down every time ${he} sways. ${His} rolls sway and jiggle with every move, creating a ripple canvas of swirling fat.`);
-	} else if (slave.weight > 130) {
-		r.push(`${His} chubby rolls dance to a beat of their own as your slave sways and moves to the music.`);
-	} else if (slave.weight > 50) {
-		r.push(`${His} chubby body jiggles nicely as ${he} moves.`);
-	} else if (slave.weight > 20) {
-		r.push(`${His} form sways and moves with the music in a most alluring way.`);
-	} else if (slave.weight > 0) {
-		r.push(`${His} trim body is highlighted by ${his} dance. Whenever ${he} rolls ${his} ass or sways ${his} hips it highlights the contours of ${his} waist.`);
-	} else if (slave.weight < 0) {
-		r.push(`Your slave's trim body glides to the music like a ${either("belly dancer", "stripper")}. ${He} is thin and tight, with no body fat to speak of,`);
-		if (slave.boobs > 400) {
-			r.push(`making ${his} tits`);
-			if (slave.butt > 1) {
-				r.push(`and ass`);
-			}
-			r.push(`the main focus of ${his} dance.`);
-		} else {
-			if (slave.butt > 1) {
-				r.push(`making ${his} ass the main focus of ${his} dance.`);
-			} else {
-				r.push(`totally flat. ${His} body is flat and girlish, providing a tastefully alluring display.`);
+	function consummation() {
+		const text = [];
+
+		text.push(
+			skill(),
+			weight(),
+			devotion(),
+			face(),
+			strip(),
+			conclusion(),
+		);
+
+		return text.join(' ');
+
+		function skill() {
+			const text = [];
+
+
+			if (slave.skill.entertainment > 99) {
+				text.push(`${He} slides ${his} ass gracefully unto the stage, then dramatically raises ${his} elongated ${(hasBothLegs(slave)) ? `legs one at a time` : `leg`} onto the platform. Circling to ${his} ${(hasBothLegs(slave)) ? `knees` : `knee`}, ${he} raises ${his} ass in the air`);
+
+				if (hasAnyArms(slave)) {
+					text.push(`and glides ${his} ${(hasBothArms(slave)) ? `hands` : `hand`} up ${his} ${(hasBothLegs(slave)) ? `legs` : `leg`}`);
+				}
+
+				text.push(`as ${he} stands upright.`);
+			} else if (slave.skill.entertainment > 60) {
+				text.push(`${He} takes ${his} rightful place on your stage.`);
+			} else if (slave.skill.entertainment > 40) {
+				text.push(`${He} goes to take ${his} place on your stage and dance for ${his} ${getWrittenTitle(slave)}.`);
+			} else if (slave.skill.entertainment > 20) {
+				text.push(`${He} ascends to the platform and begins to grind at the pole.`);
+			} else if (slave.skill.entertainment > 9) {
+				text.push(`${He} climbs up onto the platform and grabs onto the pole.`);
+			} else if (slave.skill.entertainment > -10) {
+				text.push(`${He} climbs up onto the platform and grabs onto the pole.`);
 			}
+
+
+			return text.join(' ');
 		}
-	}
-	r.push(`${His} face is`);
-	switch (slave.faceShape) {
-		case "masculine":
-			if (slave.face < -95) {
-				r.push(`hideously manly, distracting you from anything positive that may be going on.`);
-			} else if (slave.face < -40) {
-				r.push(`ugly and masculine, and you find it difficult to enjoy looking at ${him}.`);
-			} else if (slave.face < -10) {
-				r.push(`unattractively masculine, distracting you from time to time.`);
-			} else if (slave.face <= 10) {
-				r.push(`masculine, but not distracting.`);
-			} else if (slave.face <= 40) {
-				r.push(`attractive masculine, adding an interesting contrast to the feminine dance.`);
-			} else if (slave.face <= 95) {
-				r.push(`manly and handsome, which adds a flair of intrigue to the dance.`);
-			} else {
-				r.push(`the height of masculine handsomeness, adding a value to the dance only present in the Free Cities.`);
-			}
-			break;
-		case "androgynous":
-			if (slave.face < -95) {
-				r.push(`disturbingly androgynous and terribly ugly, distracting you from anything positive that may be going on.`);
-			} else if (slave.face < -40) {
-				r.push(`neither masculine nor feminine and quite ugly, and you find it difficult to enjoy looking at ${him}.`);
-			} else if (slave.face < -10) {
-				r.push(`strangely androgynous, distracting you from time to time.`);
-			} else if (slave.face <= 10) {
-				r.push(`strangely androgynous, but not distracting.`);
-			} else if (slave.face <= 40) {
-				r.push(`androgynous, and attractive enough that it adds an interesting flair to the dance.`);
-			} else if (slave.face <= 95) {
-				r.push(`gorgeously androgynous which is distracting and perplexing all at once.`);
-			} else {
-				r.push(`so gorgeously androgynous that you can't be brought to look away.`);
-			}
-			break;
-		case "cute":
-			if (slave.face < -95) {
-				r.push(`pitifully cute. ${He}'s so ugly and cute you can't help but be turned off and drawn in simultaneously.`);
-			} else if (slave.face < -40) {
-				r.push(`not attractive, but ${his} cuteness makes ${him} pitifully appealing.`);
-			} else if (slave.face < -10) {
-				r.push(`not attractive, but is still cute enough to keep you entertained.`);
-			} else if (slave.face <= 10) {
-				r.push(`appealingly cute.`);
-			} else if (slave.face <= 40) {
-				r.push(`cute and attractive, adding genuine appeal to ${his} performance.`);
-			} else if (slave.face <= 95) {
-				r.push(`so cute as ${he} dances for you. You appreciate the fullness of ${his} beauty.`);
-			} else {
-				r.push(`so perfectly cute, you can't help but smile every time ${he} looks your way.`);
-			}
-			break;
-		case "sensual":
-			if (slave.face < -95) {
-				r.push(`not attractive; not even a little. But the natural "fuck me" look of ${his} face helps give you something to look forward to once ${he}'s naked.`);
-			} else if (slave.face < -40) {
-				r.push(`not attractive, but the natural "fuck me" look of ${his} face helps give you something to look forward to once ${he}'s naked.`);
-			} else if (slave.face < -10) {
-				r.push(`not great looking, but the natural sexiness make's it easier to enjoy.`);
-			} else if (slave.face <= 10) {
-				r.push(`sensuality alone. Neither attractive, nor unattractive. Just sex.`);
-			} else if (slave.face <= 40) {
-				r.push(`begging for sex, being so enticing and sultry.`);
-			} else if (slave.face <= 95) {
-				r.push(`constantly turning you on, with the sensual structure of ${his} beautiful face never letting sex leave your mind.`);
-			} else {
-				r.push(`making you`);
-				if (V.PC.dick !== 0) {
-					r.push(`rock hard`);
-					if (V.PC.vagina !== -1) {
-						r.push(`and dripping wet`);
+
+		function weight() {
+			const text = [];
+
+			if (slave.weight > 190) {
+				text.push(`${He} is so ${either("enormous", "massive")} that ${he} can barely move ${his} weight around. ${His} rolls sway and jiggle with every move, creating a ripple canvas of swirling fat.`);
+			} else if (slave.weight > 160) {
+				text.push(`${He} is quite large, and ${his} weight threatens to pull ${him} down every time ${he} sways. ${His} rolls sway and jiggle with every move, creating a ripple canvas of swirling fat.`);
+			} else if (slave.weight > 130) {
+				text.push(`${His} chubby rolls dance to a beat of their own as your slave sways and moves to the music.`);
+			} else if (slave.weight > 50) {
+				text.push(`${His} chubby body jiggles nicely as ${he} moves.`);
+			} else if (slave.weight > 20) {
+				text.push(`${His} form sways and moves with the music in a most alluring way.`);
+			} else if (slave.weight > 0) {
+				text.push(`${His} trim body is highlighted by ${his} dance. Whenever ${he} rolls ${his} ass or sways ${his} hips it highlights the contours of ${his} waist.`);
+			} else if (slave.weight < 0) {
+				text.push(`Your slave's trim body glides to the music like a ${either("belly dancer", "stripper")}. ${He} is thin and tight, with no body fat to speak of,`);
+
+				if (slave.boobs > 400) {
+					text.push(`making ${his} tits`);
+					if (slave.butt > 1) {
+						text.push(`and ass`);
 					}
+					text.push(`the main focus of ${his} dance.`);
 				} else {
-					r.push(`dripping wet`);
+					if (slave.butt > 1) {
+						text.push(`making ${his} ass the main focus of ${his} dance.`);
+					} else {
+						text.push(`totally flat. ${His} body is flat and girlish, providing a tastefully alluring display.`);
+					}
 				}
-				r.push(`as you lust after ${his} sexual beauty.`);
-			}
-			break;
-		case "exotic":
-			if (slave.face < -95) {
-				r.push(`hideously unusual, distracting you from anything positive that may be going on.`);
-			} else if (slave.face < -40) {
-				r.push(`ugly and unusual, and you find it difficult to enjoy looking at ${him}.`);
-			} else if (slave.face < -10) {
-				r.push(`not great to look at, but perplexing and abnormal. You try to focus on ${his} body instead.`);
-			} else if (slave.face <= 10) {
-				r.push(`interesting and unusual. It isn't particularly attractive, but none of your slaves have a face quite like ${hers}.`);
-			} else if (slave.face <= 40) {
-				r.push(`exotic and alluring, just attractive enough to make ${him} good office décor, but not so much that it's distracting.`);
-			} else if (slave.face <= 95) {
-				r.push(`a testament to the benefits of a global slave market. It makes ${him} a perfect office trophy.`);
-			} else {
-				r.push(`an exotic masterpiece. Having ${him} dance in your office is like hanging foreign art on the walls, a perfect trophy of your slaving reach.`);
-			}
-			break;
-		case "feline":
-			if (slave.face < -95) {
-				r.push(`revolting in its alien cat-like appearance, the mangy fur distracting you tremendously.`);
-			} else if (slave.face < -40) {
-				r.push(`ugly and feline, making it hard to do anything but stare at ${his} bizarre cat features.`);
-			} else if (slave.face < -10) {
-				r.push(`relatively unattractive in its strange feline appearance, though you try to look more at ${his} furred body.`);
-			} else if (slave.face <= 10) {
-				r.push(`fascinating in its strange cat-like looks. ${His} whiskers twitch about as ${he} moves.`);
-			} else if (slave.face <= 40) {
-				r.push(`attractive and feline, catching your eye and drawing your attention to ${his} soft fur and twitching button nose.`);
-			} else if (slave.face <= 95) {
-				r.push(`gorgeous in its feline construction, a beautiful melody of fur and whiskers that's hard to even look away from.`);
-			} else {
-				r.push(`a breathtakingly beautiful catgirl, a true monument to the wonders of genetic engineering with ${his} perfectly-constructed fur and luxurious feline curves. Just looking at ${him} draws you in intimately, whiskers twitching.`);
 			}
-			break;
-		default:
-			if (slave.face < -95) {
-				r.push(`not great to look at. Not even a little. You try to focus on ${his} body instead, finding yourself immediately turned off when ${he} catches your gaze.`);
-			} else if (slave.face < -40) {
-				r.push(`a bit of a turn off. You try to watch ${his} body instead.`);
-			} else if (slave.face < -10) {
-				r.push(`not a highlight. ${He} isn't beautiful, and you would rather watch ${his} body.`);
-			} else if (slave.face <= 10) {
-				r.push(`quite feminine and pleasing. You aren't captivated by ${his} face, but you don't avoid it either.`);
-			} else if (slave.face <= 40) {
-				r.push(`feminine and attractive. You find yourself looking at it from time to time.`);
-			} else if (slave.face <= 95) {
-				r.push(`beautiful and feminine. You often find your eyes locked on ${his} face for long periods of time.`);
-			} else {
-				r.push(`absolutely stunning. Watching ${his} face is often more pleasing than watching ${him} dance.`);
+
+			return text.join(' ');
+		}
+
+		function devotion() {
+			const text = [];
+
+			if (slave.devotion < -20) {
+				text.push(`It's clear that ${he} hates being on display for you. ${He} resents you for making ${him} dance for you,`);
+
+				if (slave.trust < -50) {
+					text.push(`but ${he} is to terrified of you to see what happens if ${he} resists`);
+				} else {
+					text.push(`and refuses to comply. In order to make ${him} obey, a leash is attached from`);
+
+					if (slave.collar !== "none") {
+						switch (slave.collar) {
+							case "uncomfortable leather":
+								text.push(`the steel ring on ${his} leather collar`);
+								break;
+							case "preg biometrics":
+								text.push(`${his} collar`);
+								break;
+							case "silk ribbon":
+								text.push(`${his} silk ribbon`);
+								break;
+							case "tight steel":
+								text.push(`${his} steel collar`);
+								break;
+							case "shock punishment":
+								text.push(`${his} shock collar`);
+								break;
+							case "neck corset":
+								text.push(`an O-ring at the from of ${his} neck corset`);
+								break;
+							case "stylish leather":
+								text.push(`${his} collar`);
+								break;
+							case "satin choker":
+								text.push(`${his} choker collar`);
+								break;
+							case "heavy gold":
+								text.push(`${He} is wearing a heavy gold collar, an outstanding bit of ostentation.`);
+								break;
+							case "pretty jewelry":
+								text.push(`${his} ornate collar`);
+								break;
+							case "bell collar":
+								text.push(`the ring attaching ${his} bell to ${his} collar, and`);
+								break;
+							case "leather with cowbell":
+								text.push(`the ring attaching ${his} bell to ${his} collar, and`);
+								break;
+							case "bowtie":
+								text.push(`${his} bowtie collar`);
+								break;
+							case "neck tie":
+								text.push(`${his} neck tie`);
+								break;
+							case "ancient Egyptian":
+								if (slave.piercing.nose.weight === 2) {
+									text.push(`${his} nose ring.`);
+								} else if (slave.piercing.nipple.weight === 2) {
+									text.push(`${his} nipple chain.`);
+								} else {
+									text.push(`${his} wesekh.`);
+								}
+								break;
+							case "cruel retirement counter":
+							case "nice retirement counter":
+								text.push(`${his} retirement counter`);
+								break;
+							default:
+								if (slave.piercing.nose.weight === 2) {
+									text.push(`${his} nose ring`);
+								} else if (slave.piercing.nipple.weight === 2) {
+									text.push(`${his} nipple chain`);
+								} else {
+									text.push(`a collar that is placed on ${his} neck for the occasion, and`);
+								}
+						}
+					} else if (slave.mouthAccessory !== "none") {
+						switch (slave.mouthAccessory) {
+							case "dildo gag":
+								text.push(`a ring on ${his} gag strap`);
+								break;
+							case "massive dildo gag":
+								text.push(`a ring on ${his} gag strap`);
+								break;
+							case "ball gag":
+								text.push(`a ring on the back of ${his} gag`);
+								break;
+							case "bit gag":
+								text.push(`the ring on the side of ${his} bit`);
+								break;
+							case "ring gag":
+								text.push(`a bar in ${his} mouth slightly wider than ${his} ring gag`);
+						}
+					} else if (slave.faceAccessory !== "none") {
+						switch (slave.faceAccessory) {
+							case "porcelain mask":
+								if (slave.piercing.nose.weight === 2) {
+									text.push(`${his} nose ring`);
+								} else if (slave.piercing.nipple.weight === 2) {
+									text.push(`${his} nipple chain`);
+								} else {
+									text.push(`a collar that is placed around ${his} neck`);
+								}
+						}
+					}
+
+					text.push(`to the pole in order to keep ${him} from getting down. Whenever ${he} stops dancing the chain is tightened a bit more,`);
+
+					switch (slave.collar) {
+						case "uncomfortable leather":
+							text.push(`choking ${him} and rubbing ${his} skin raw from the leather;`);
+							break;
+						case "tight steel":
+							text.push(`choking ${him} without mercy;`);
+							break;
+						case "shock punishment":
+							text.push(`and a shock is sent through ${his} collar;`);
+							break;
+						case "neck corset":
+							text.push(`making breathing even more difficult;`);
+							break;
+						case "ancient Egyptian":
+							if (slave.piercing.nose.weight === 2) {
+								text.push(`tugging at ${his} nose ring;`);
+							} else if (slave.piercing.nipple.weight === 2) {
+								text.push(`threatening to tear themselves from ${his} sensitive flesh;`);
+							} else {
+								text.push(`tugging at ${his} throat;`);
+							}
+							break;
+						default:
+							if (slave.piercing.nose.weight === 2) {
+								text.push(`tugging at ${his} nose ring;`);
+							} else if (slave.piercing.nipple.weight === 2) {
+								text.push(`threatening to tear themselves from ${his} sensitive flesh;`);
+							} else {
+								text.push(`choking ${him};`);
+							}
+					}
+
+					text.push(`forcing ${him} to keep moving or face more pain.`);
+				}
+			} else if (slave.devotion <= 20) {
+				text.push(`${He} hates being forced to dance for you, but tries ${his} best in spite of this.`);
+			} else if (slave.devotion <= 50) {
+				text.push(`${He} wants to do ${his} best for you, and tries not to hold back.`);
+			} else if (slave.devotion <= 80) {
+				text.push(`${He} is so eager to please you, and works hard to push ${himself} beyond ${his} skill limit.`);
+			} else if (slave.devotion <= 100) {
+				text.push(`${He} is so honored that you want to use ${him} in this way, and tries eagerly to please you. ${His} eyes are filled with adoration and every move ${he} makes is done with the sole intention of pleasuring ${his} beloved ${getWrittenTitle(slave)}.`);
+			}
+
+			if (slave.devotion <= 20) {
+				if (slave.sexualFlaw === "judgemental") {
+					text.push(`${He} thinks to ${himself} that a real ${womanP} wouldn't need to compensate this way, and judges you harshly.`);
+				} else if (slave.behavioralFlaw === "liberated") {
+					text.push(`${He} can't believe ${he} now lives in a world where women are expected to perform for their ${getWrittenTitle(slave)} whether they consent or not.`);
+				} else if (slave.behavioralFlaw === "bitchy") {
+					text.push(`${He} dances, but makes sure that the disgust on ${his} face shows clearly that ${he} is not into it.`);
+				}
 			}
-	}
 
+			text.push(`The atmosphere of your office is a testament to masculine opulence. Few ${womenP} in the old world would have the pleasure of completing their work while an attractive ${slave.visualAge < 16 ? girl : woman} flaunts ${himself} for ${hisP} pleasure. You allow the situation to continue for about an hour, before deciding it's time to escalate. You look up once more at your slave and take some time to review ${his} dancing performance.`);
 
-	if (slave.devotion < -20) {
-		r.push(`It's clear that ${he} hates being on display for you. ${He} resents you for making ${him} dance for you,`);
-		if (slave.trust < -50) {
-			r.push(`but ${he} is to terrified of you to see what happens if ${he} resists`);
-		} else {
-			r.push(`and refuses to comply. In order to make ${him} obey, a leash is attached from`);
-			if (slave.collar !== "none") {
-				switch (slave.collar) {
-					case "uncomfortable leather":
-						r.push(`the steel ring on ${his} leather collar`);
-						break;
-					case "preg biometrics":
-						r.push(`${his} collar`);
-						break;
-					case "silk ribbon":
-						r.push(`${his} silk ribbon`);
-						break;
-					case "tight steel":
-						r.push(`${his} steel collar`);
-						break;
-					case "shock punishment":
-						r.push(`${his} shock collar`);
-						break;
-					case "neck corset":
-						r.push(`an O-ring at the from of ${his} neck corset`);
-						break;
-					case "stylish leather":
-						r.push(`${his} collar`);
-						break;
-					case "satin choker":
-						r.push(`${his} choker collar`);
-						break;
-					case "heavy gold":
-						r.push(`${He} is wearing a heavy gold collar, an outstanding bit of ostentation.`);
-						break;
-					case "pretty jewelry":
-						r.push(`${his} ornate collar`);
-						break;
-					case "bell collar":
-						r.push(`the ring attaching ${his} bell to ${his} collar, and`);
-						break;
-					case "leather with cowbell":
-						r.push(`the ring attaching ${his} bell to ${his} collar, and`);
-						break;
-					case "bowtie":
-						r.push(`${his} bowtie collar`);
+			if (slave.devotion >= -20) {
+				if (slave.skill.entertainment >= 100) {
+					text.push(`Your slave has a level of skill previously unseen in the old world. Even ${his} blinks have the seductive pull of a goddess. As you watch ${him} perform, you think how no ${womanP} of the old world would ever get to see pure sexuality like this. And not only do you get to watch ${him}, you OWN ${him}. ${His} body moves like water, with hips that ebb and flow as if the tides themselves panged for a rock hard cock to come and take them. You try to get some work done, but can't take your eyes off ${him} for even a second. You promise to reward your slave for bringing so much sensuality and beauty into your office, transforming your place of work into a shrine of masculine dominance.`);
+				} else if (slave.skill.entertainment >= 60) {
+					text.push(`${His} skill would have only been matched by the best of the best old world erotic dancers, but in your Free City expectations are high. ${He} dances with seduction in every move, alternating ${his} style between everything from belly dancing to club twerking, and each with the skill level of a trained professional. You got some work done while ${he} danced, but often found yourself pulled back in by the tide of ${his} rolling hips. You praise your slave for ${his} enriching performance.`);
+				} else if (slave.skill.entertainment >= 40) {
+					text.push(`${He} has impressive skill and would have been a top-tier dancer in the old world. One of the many benefits of being a leader of a Free City is the ability to work in an atmosphere of pure servitude. You were free to continue your work in an office the old world men could only dream of. You tell your slave that you are pleased with ${his} show.`);
+				} else if (slave.skill.entertainment >= 20) {
+					text.push(`Despite being an average entertainer, it is clear that ${he} is doing ${his} best. You enjoyed the sexy ambiance while you worked. You tell your slave that ${his} performance was adequate.`);
+				} else if (slave.skill.entertainment >= 10) {
+					text.push(`${He} is still learning the nuances of seductive dance, but at least able to move with the rhythm. You spent much of the performance distracted, forgetting that ${he} was even there at times and leaving ${him} unable to stop until you remembered about ${him}. You tell ${him} that ${he} will have to work harder if ${he} wishes to please you.`);
+				} else {
+					text.push(`Or, at least, ${his} best attempt at dancing. ${His} arms flail about awkwardly as ${he} crouches and straightens off-beat to the music. You spent much of the dance ignoring ${him} and working on your business. You chide your slave for such a pathetic excuse for a performance, and tell ${him} that ${he} will have to find a place to please you, or you will be forced to make ${him} useful, turning ${his} thoughts to the arcades, dairies, and Fuckdolls common amongst the Free Cities.`);
+				}
+			} else {
+				text.push(`${He} dances poorly on purpose to spite you. Whatever skills ${he} has, they are not on display here. You threaten to`);
+
+				switch (slave.rules.punishment) {
+					case "confinement":
+						text.push(`lock ${him} up in the bad-${girl} box`);
 						break;
-					case "neck tie":
-						r.push(`${his} neck tie`);
+					case "whipping":
+						text.push(`whip ${him} until ${he} screams`);
 						break;
-					case "ancient Egyptian":
-						if (slave.piercing.nose.weight === 2) {
-							r.push(`${his} nose ring.`);
-						} else if (slave.piercing.nipple.weight === 2) {
-							r.push(`${his} nipple chain.`);
+					case "chastity":
+						if (slave.energy > 60) {
+							text.push(`keep ${him} on the edge of orgasm until ${he} loses ${his} mind`);
 						} else {
-							r.push(`${his} wesekh.`);
+							text.push(`fuck ${him} in the ass until ${he}'s unconscious`);
 						}
 						break;
-					case "cruel retirement counter":
-					case "nice retirement counter":
-						r.push(`${his} retirement counter`);
-						break;
-					default:
-						if (slave.piercing.nose.weight === 2) {
-							r.push(`${his} nose ring`);
-						} else if (slave.piercing.nipple.weight === 2) {
-							r.push(`${his} nipple chain`);
-						} else {
-							r.push(`a collar that is placed on ${his} neck for the occasion, and`);
+					case "situational":
+						switch (slave.collar) {
+							case "shock punishment":
+								text.push(`activate ${his} collar, and`);
 						}
-				}
-			} else if (slave.mouthAccessory !== "none") {
-				switch (slave.mouthAccessory) {
-					case "dildo gag":
-						r.push(`a ring on ${his} gag strap`);
+						text.push(`punish ${him}`);
 						break;
-					case "massive dildo gag":
-						r.push(`a ring on ${his} gag strap`);
-						break;
-					case "ball gag":
-						r.push(`a ring on the back of ${his} gag`);
-						break;
-					case "bit gag":
-						r.push(`the ring on the side of ${his} bit`);
-						break;
-					case "ring gag":
-						r.push(`a bar in ${his} mouth slightly wider than ${his} ring gag`);
 				}
-			} else if (slave.faceAccessory !== "none") {
-				switch (slave.faceAccessory) {
-					case "porcelain mask":
-						if (slave.piercing.nose.weight === 2) {
-							r.push(`${his} nose ring`);
-						} else if (slave.piercing.nipple.weight === 2) {
-							r.push(`${his} nipple chain`);
-						} else {
-							r.push(`a collar that is placed around ${his} neck`);
-						}
-				}
-			}
-			r.push(`to the pole in order to keep ${him} from getting down. Whenever ${he} stops dancing the chain is tightened a bit more,`);
-			switch (slave.collar) {
-				case "uncomfortable leather":
-					r.push(`choking ${him} and rubbing ${his} skin raw from the leather;`);
-					break;
-				case "tight steel":
-					r.push(`choking ${him} without mercy;`);
-					break;
-				case "shock punishment":
-					r.push(`and a shock is sent through ${his} collar;`);
-					break;
-				case "neck corset":
-					r.push(`making breathing even more difficult;`);
-					break;
-				case "ancient Egyptian":
-					if (slave.piercing.nose.weight === 2) {
-						r.push(`tugging at ${his} nose ring;`);
-					} else if (slave.piercing.nipple.weight === 2) {
-						r.push(`threatening to tear themselves from ${his} sensitive flesh;`);
-					} else {
-						r.push(`tugging at ${his} throat;`);
-					}
-					break;
-				default:
-					if (slave.piercing.nose.weight === 2) {
-						r.push(`tugging at ${his} nose ring;`);
-					} else if (slave.piercing.nipple.weight === 2) {
-						r.push(`threatening to tear themselves from ${his} sensitive flesh;`);
-					} else {
-						r.push(`choking ${him};`);
-					}
+				text.push(`if ${he} doesn't shape up.`);
 			}
-			r.push(`forcing ${him} to keep moving or face more pain.`);
-		}
-	} else if (slave.devotion <= 20) {
-		r.push(`${He} hates being forced to dance for you, but tries ${his} best in spite of this.`);
-	} else if (slave.devotion <= 50) {
-		r.push(`${He} wants to do ${his} best for you, and tries not to hold back.`);
-	} else if (slave.devotion <= 80) {
-		r.push(`${He} is so eager to please you, and works hard to push ${himself} beyond ${his} skill limit.`);
-	} else if (slave.devotion <= 100) {
-		r.push(`${He} is so honored that you want to use ${him} in this way, and tries eagerly to please you. ${His} eyes are filled with adoration and every move ${he} makes is done with the sole intention of pleasuring ${his} beloved ${getWrittenTitle(slave)}.`);
-	}
 
-	if (slave.devotion <= 20) {
-		if (slave.sexualFlaw === "judgemental") {
-			r.push(`${He} thinks to ${himself} that a real ${womanP} wouldn't need to compensate this way, and judges you harshly.`);
-		} else if (slave.behavioralFlaw === "liberated") {
-			r.push(`${He} can't believe ${he} now lives in a world where women are expected to perform for their ${getWrittenTitle(slave)} whether they consent or not.`);
-		} else if (slave.behavioralFlaw === "bitchy") {
-			r.push(`${He} dances, but makes sure that the disgust on ${his} face shows clearly that ${he} is not into it.`);
-		}
-	}
-	r.push(`The atmosphere of your office is a testament to masculine opulence. Few ${womenP} in the old world would have the pleasure of completing their work while an attractive ${woman} flaunts ${himself} for ${hisP} pleasure. You allow the situation to continue for about an hour, before deciding it's time to escalate. You look up once more at your slave and take some time to review ${his} dancing performance.`);
-	if (slave.devotion >= -20) {
-		if (slave.skill.entertainment >= 100) {
-			r.push(`Your slave has a level of skill previously unseen in the old world. Even ${his} blinks have the seductive pull of a goddess. As you watch ${him} perform, you think how no ${womanP} of the old world would ever get to see pure sexuality like this. And not only do you get to watch ${him}, you OWN ${him}. ${His} body moves like water, with hips that ebb and flow as if the tides themselves panged for a rock hard cock to come and take them. You try to get some work done, but can't take your eyes off ${him} for even a second. You promise to reward your slave for bringing so much sensuality and beauty into your office, transforming your place of work into a shrine of masculine dominance.`);
-		} else if (slave.skill.entertainment >= 60) {
-			r.push(`${His} skill would have only been matched by the best of the best old world erotic dancers, but in your Free City expectations are high. ${He} dances with seduction in every move, alternating ${his} style between everything from belly dancing to club twerking, and each with the skill level of a trained professional. You got some work done while ${he} danced, but often found yourself pulled back in by the tide of ${his} rolling hips. You praise your slave for ${his} enriching performance.`);
-		} else if (slave.skill.entertainment >= 40) {
-			r.push(`${He} has impressive skill and would have been a top-tier dancer in the old world. One of the many benefits of being a leader of a Free City is the ability to work in an atmosphere of pure servitude. You were free to continue your work in an office the old world men could only dream of. You tell your slave that you are pleased with ${his} show.`);
-		} else if (slave.skill.entertainment >= 20) {
-			r.push(`Despite being an average entertainer, it is clear that ${he} is doing ${his} best. You enjoyed the sexy ambiance while you worked. You tell your slave that ${his} performance was adequate.`);
-		} else if (slave.skill.entertainment >= 10) {
-			r.push(`${He} is still learning the nuances of seductive dance, but at least able to move with the rhythm. You spent much of the performance distracted, forgetting that ${he} was even there at times and leaving ${him} unable to stop until you remembered about ${him}. You tell ${him} that ${he} will have to work harder if ${he} wishes to please you.`);
-		} else {
-			r.push(`Or, at least, ${his} best attempt at dancing. ${His} arms flail about awkwardly as ${he} crouches and straightens off-beat to the music. You spent much of the dance ignoring ${him} and working on your business. You chide your slave for such a pathetic excuse for a performance, and tell ${him} that ${he} will have to find a place to please you, or you will be forced to make ${him} useful, turning ${his} thoughts to the arcades, dairies, and Fuckdolls common amongst the Free Cities.`);
-		}
-	} else {
-		r.push(`${He} dances poorly on purpose to spite you. Whatever skills ${he} has, they are not on display here. You threaten to`);
-		switch (slave.rules.punishment) {
-			case "confinement":
-				r.push(`lock ${him} up in the bad-${girl} box`);
-				break;
-			case "whipping":
-				r.push(`whip ${him} until ${he} screams`);
-				break;
-			case "chastity":
-				if (slave.energy > 60) {
-					r.push(`keep ${him} on the edge of orgasm until ${he} loses ${his} mind`);
-				} else {
-					r.push(`fuck ${him} in the ass until ${he}'s unconscious`);
-				}
-				break;
-			case "situational":
-				switch (slave.collar) {
-					case "shock punishment":
-						r.push(`activate ${his} collar, and`);
-				}
-				r.push(`punish ${him}`);
-				break;
+			return text.join(' ');
 		}
-		r.push(`if ${he} doesn't shape up.`);
-	}
 
-	r.push(`It's not over yet, though. You tell your slave that it's time to incorporate some stripping into ${his} dance.`);
+		function face() {
+			const text = [];
 
-	if (slave.sexualFlaw === "shamefast") {
-		if (slave.devotion <= 40) {
-			r.push(`${He} immediately begins to tear up at the thought of being naked. ${His} shame is obvious to you, and you remind ${him} that ${his} comfort is not your concern.`);
-			if (slave.skill.entertainment >= 99) {
-				r.push(`Even though ${he} is crippled by shame, your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. With tears still streaming down ${his} face, ${he} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose, even as ${he} sniffles at the shame of revealing ${himself} for you. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-			} else if (slave.skill.entertainment >= 60) {
-				r.push(`Even though ${he} is crippled by shame, your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
-			} else if (slave.skill.entertainment >= 40) {
-				r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-			} else if (slave.skill.entertainment >= 20) {
-				r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing. ${His} attempts are inhibited by ${his} shame, which makes ${him} shudder and cry whenever it's time for another article of clothing to come off.`);
-			} else if (slave.skill.entertainment >= 10) {
-				r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${He} is too concerned with protecting ${his} nakedness to be obedient and attractive simultaneously, and you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
-			} else {
-				r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to reluctantly, but obediently, remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
-			}
-		} else {
-			r.push(`Even though ${he} is uncomfortable at the thought of being naked, ${he} is so devoted to you that ${he} obeys without question.`);
-			if (slave.skill.entertainment >= 99) {
-				r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. Overcoming ${his} fear of being naked, ${he} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose, even as ${he} sniffles at the shame of revealing ${himself} for you. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-			} else if (slave.skill.entertainment >= 60) {
-				r.push(`Even though ${he} is still ashamed, your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
-			} else if (slave.skill.entertainment >= 40) {
-				r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-			} else if (slave.skill.entertainment >= 20) {
-				r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing. ${His} attempts would be inhibited by ${his} shame, but ${his} devotion to you overrides this and ${he} is able to dance with added skill.`);
-			} else if (slave.skill.entertainment >= 10) {
-				r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. You find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
-			} else {
-				r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to shamefully remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
-			}
-		}
-	} else if (slave.behavioralFlaw === "odd") {
-		if (slave.skill.entertainment >= 99) {
-			r.push(`Even though ${he} is extremely odd, your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. With ${his} ass cheeks straddling the pole ${he} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-		} else if (slave.skill.entertainment >= 60) {
-			r.push(`Even though ${he} is extremely odd, your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
-		} else if (slave.skill.entertainment >= 40) {
-			r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} shouts wildly before upping the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-		} else if (slave.skill.entertainment >= 20) {
-			r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing. ${His} attempts are inhibited by ${his} oddness, which results in ${him} crouching and squealing at inappropriate times. ${He} wonders aloud and you instruct ${him} to be silent the remainder of the dance.`);
-		} else if (slave.skill.entertainment >= 10) {
-			r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${He} is so odd that ${his} moves more resembles the chicken dance than any form of erotic dancing. You find yourself unable to look away, and for all the wrong reasons. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
-		} else {
-			r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. Deciding that the rhythm is to blame, ${he} decides instead to sing ${his} own song to strip to. ${He} proceeds to hum string of off beat notes peppered with random words and scats, all punctuated by the sloppy kicking of clothes from ${his} ankles. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to roughly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
-		}
-	} else if (slave.sexualFlaw === "attention whore") {
-		r.push(`As an attention whore, this is what ${he} lives for.`);
-		if (slave.skill.entertainment >= 99) {
-			r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. Being an attention whore, ${he} is obsessed with attracting the sexual arousal of others. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose, even though ${he} is also fulfilled by the event ${he} knows that your desire is all that matters. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-		} else if (slave.skill.entertainment >= 60) {
-			r.push(`Your slave is a skilled entertainer, well above average. Being an attention whore, ${he} is obsessed with attracting the sexual arousal of others. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} surely wishes ${he} were a better entertainer so you would call on ${him} to strip more often.`);
-		} else if (slave.skill.entertainment >= 40) {
-			r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. The true entertainment comes from ${his} teasing nature, which makes ${him} blush cutely anytime ${he} shows a bit of skin. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-		} else if (slave.skill.entertainment >= 20) {
-			r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing. ${His} attempts are overshadowed by ${his} clear desire to be looked at, and you can tell ${he} is distracted by this.`);
-		} else if (slave.skill.entertainment >= 10) {
-			r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${He} is trying much too hard to get your attention, and is visibly angered whenever ${he} sees that you are not aroused by ${his} fumblings. You find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
-		} else {
-			r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to over-dramatically remove an article of clothing. After each article removed ${he} stops and looks at you to make sure you're watching. ${His} clear desire to be looked at makes ${him} more self-conscious which offsets the rhythm of the dance even more. ${He} decides to pick up the pace, aiming to be naked as quickly as possible so that you can admire ${his} body. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
-		}
-	} else if (slave.sexualQuirk === "tease") {
-		if (slave.skill.entertainment >= 99) {
-			r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. Being a tease, ${he} is able to maintain an attractive blend of shame and arousal at the thought of being naked before you, and this inspires ${him} to tease you endlessly. With cheeks still flushed and red, ${he} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose, even as ${he} blushes at the shame and arousal of revealing ${himself} for you. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-		} else if (slave.skill.entertainment >= 60) {
-			r.push(`Your slave is a skilled entertainer, well above average. Being a tease, ${he} is able to maintain an attractive blend of shame and arousal at the thought of being naked before you, and this inspires ${him} to tease you endlessly. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
-		} else if (slave.skill.entertainment >= 40) {
-			r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. The true entertainment comes from ${his} teasing nature, which makes ${him} blush cutely anytime ${he} shows a bit of skin. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-		} else if (slave.skill.entertainment >= 20) {
-			r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing. ${His} attempts are made more entertaining by ${his} shame, which makes ${him} redden and blush whenever it's time for another article of clothing to come off. Even though ${his} entertainment skill needs improving, you genuinely enjoy the teasing way ${he} tugs at ${his} wear and makes you anticipate the removal of each article.`);
-		} else if (slave.skill.entertainment >= 10) {
-			r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${He} is a tease, which adds a bit of value, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
-		} else {
-			r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
-		}
-	} else {
-		if (slave.fetishKnown === 1) {
-			switch (slave.fetish) {
-				case "submissive":
-					if (slave.skill.entertainment >= 99) {
-						r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-					} else if (slave.skill.entertainment >= 60) {
-						r.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
-					} else if (slave.skill.entertainment >= 40) {
-						r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-					} else if (slave.skill.entertainment >= 20) {
-						r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
-					} else if (slave.skill.entertainment >= 10) {
-						r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+			text.push(`${His} face is`);
+
+			switch (slave.faceShape) {
+				case "masculine":
+					if (slave.face < -95) {
+						text.push(`hideously manly, distracting you from anything positive that may be going on.`);
+					} else if (slave.face < -40) {
+						text.push(`ugly and masculine, and you find it difficult to enjoy looking at ${him}.`);
+					} else if (slave.face < -10) {
+						text.push(`unattractively masculine, distracting you from time to time.`);
+					} else if (slave.face <= 10) {
+						text.push(`masculine, but not distracting.`);
+					} else if (slave.face <= 40) {
+						text.push(`attractive masculine, adding an interesting contrast to the feminine dance.`);
+					} else if (slave.face <= 95) {
+						text.push(`manly and handsome, which adds a flair of intrigue to the dance.`);
 					} else {
-						r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+						text.push(`the height of masculine handsomeness, adding a value to the dance only present in the Free Cities.`);
 					}
 					break;
-				case "dom":
-					if (slave.skill.entertainment >= 99) {
-						r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-					} else if (slave.skill.entertainment >= 60) {
-						r.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
-					} else if (slave.skill.entertainment >= 40) {
-						r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-					} else if (slave.skill.entertainment >= 20) {
-						r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
-					} else if (slave.skill.entertainment >= 10) {
-						r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+				case "androgynous":
+					if (slave.face < -95) {
+						text.push(`disturbingly androgynous and terribly ugly, distracting you from anything positive that may be going on.`);
+					} else if (slave.face < -40) {
+						text.push(`neither masculine nor feminine and quite ugly, and you find it difficult to enjoy looking at ${him}.`);
+					} else if (slave.face < -10) {
+						text.push(`strangely androgynous, distracting you from time to time.`);
+					} else if (slave.face <= 10) {
+						text.push(`strangely androgynous, but not distracting.`);
+					} else if (slave.face <= 40) {
+						text.push(`androgynous, and attractive enough that it adds an interesting flair to the dance.`);
+					} else if (slave.face <= 95) {
+						text.push(`gorgeously androgynous which is distracting and perplexing all at once.`);
 					} else {
-						r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+						text.push(`so gorgeously androgynous that you can't be brought to look away.`);
 					}
 					break;
-				case "sadist":
-					if (slave.skill.entertainment >= 99) {
-						r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-					} else if (slave.skill.entertainment >= 60) {
-						r.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
-					} else if (slave.skill.entertainment >= 40) {
-						r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-					} else if (slave.skill.entertainment >= 20) {
-						r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
-					} else if (slave.skill.entertainment >= 10) {
-						r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+				case "cute":
+					if (slave.face < -95) {
+						text.push(`pitifully cute. ${He}'s so ugly and cute you can't help but be turned off and drawn in simultaneously.`);
+					} else if (slave.face < -40) {
+						text.push(`not attractive, but ${his} cuteness makes ${him} pitifully appealing.`);
+					} else if (slave.face < -10) {
+						text.push(`not attractive, but is still cute enough to keep you entertained.`);
+					} else if (slave.face <= 10) {
+						text.push(`appealingly cute.`);
+					} else if (slave.face <= 40) {
+						text.push(`cute and attractive, adding genuine appeal to ${his} performance.`);
+					} else if (slave.face <= 95) {
+						text.push(`so cute as ${he} dances for you. You appreciate the fullness of ${his} beauty.`);
 					} else {
-						r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+						text.push(`so perfectly cute, you can't help but smile every time ${he} looks your way.`);
 					}
 					break;
-				case "masochist":
-					if (slave.skill.entertainment >= 99) {
-						r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-					} else if (slave.skill.entertainment >= 60) {
-						r.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
-					} else if (slave.skill.entertainment >= 40) {
-						r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-					} else if (slave.skill.entertainment >= 20) {
-						r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
-					} else if (slave.skill.entertainment >= 10) {
-						r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+				case "sensual":
+					if (slave.face < -95) {
+						text.push(`not attractive; not even a little. But the natural "fuck me" look of ${his} face helps give you something to look forward to once ${he}'s naked.`);
+					} else if (slave.face < -40) {
+						text.push(`not attractive, but the natural "fuck me" look of ${his} face helps give you something to look forward to once ${he}'s naked.`);
+					} else if (slave.face < -10) {
+						text.push(`not great looking, but the natural sexiness make's it easier to enjoy.`);
+					} else if (slave.face <= 10) {
+						text.push(`sensuality alone. Neither attractive, nor unattractive. Just sex.`);
+					} else if (slave.face <= 40) {
+						text.push(`begging for sex, being so enticing and sultry.`);
+					} else if (slave.face <= 95) {
+						text.push(`constantly turning you on, with the sensual structure of ${his} beautiful face never letting sex leave your mind.`);
 					} else {
-						r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+						text.push(`making you`);
+						if (V.PC.dick !== 0) {
+							text.push(`rock hard`);
+							if (V.PC.vagina !== -1) {
+								text.push(`and dripping wet`);
+							}
+						} else {
+							text.push(`dripping wet`);
+						}
+						text.push(`as you lust after ${his} sexual beauty.`);
 					}
 					break;
-				case "cumslut":
-					if (slave.skill.entertainment >= 99) {
-						r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-					} else if (slave.skill.entertainment >= 60) {
-						r.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
-					} else if (slave.skill.entertainment >= 40) {
-						r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-					} else if (slave.skill.entertainment >= 20) {
-						r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
-					} else if (slave.skill.entertainment >= 10) {
-						r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+				case "exotic":
+					if (slave.face < -95) {
+						text.push(`hideously unusual, distracting you from anything positive that may be going on.`);
+					} else if (slave.face < -40) {
+						text.push(`ugly and unusual, and you find it difficult to enjoy looking at ${him}.`);
+					} else if (slave.face < -10) {
+						text.push(`not great to look at, but perplexing and abnormal. You try to focus on ${his} body instead.`);
+					} else if (slave.face <= 10) {
+						text.push(`interesting and unusual. It isn't particularly attractive, but none of your slaves have a face quite like ${hers}.`);
+					} else if (slave.face <= 40) {
+						text.push(`exotic and alluring, just attractive enough to make ${him} good office décor, but not so much that it's distracting.`);
+					} else if (slave.face <= 95) {
+						text.push(`a testament to the benefits of a global slave market. It makes ${him} a perfect office trophy.`);
 					} else {
-						r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+						text.push(`an exotic masterpiece. Having ${him} dance in your office is like hanging foreign art on the walls, a perfect trophy of your slaving reach.`);
 					}
 					break;
-				case "humiliation":
-					if (slave.skill.entertainment >= 99) {
-						r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-					} else if (slave.skill.entertainment >= 60) {
-						r.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
-					} else if (slave.skill.entertainment >= 40) {
-						r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-					} else if (slave.skill.entertainment >= 20) {
-						r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
-					} else if (slave.skill.entertainment >= 10) {
-						r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+				case "feline":
+					if (slave.face < -95) {
+						text.push(`revolting in its alien cat-like appearance, the mangy fur distracting you tremendously.`);
+					} else if (slave.face < -40) {
+						text.push(`ugly and feline, making it hard to do anything but stare at ${his} bizarre cat features.`);
+					} else if (slave.face < -10) {
+						text.push(`relatively unattractive in its strange feline appearance, though you try to look more at ${his} furred body.`);
+					} else if (slave.face <= 10) {
+						text.push(`fascinating in its strange cat-like looks. ${His} whiskers twitch about as ${he} moves.`);
+					} else if (slave.face <= 40) {
+						text.push(`attractive and feline, catching your eye and drawing your attention to ${his} soft fur and twitching button nose.`);
+					} else if (slave.face <= 95) {
+						text.push(`gorgeous in its feline construction, a beautiful melody of fur and whiskers that's hard to even look away from.`);
 					} else {
-						r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+						text.push(`a breathtakingly beautiful cat${girl}, a true monument to the wonders of genetic engineering with ${his} perfectly-constructed fur and luxurious feline curves. Just looking at ${him} draws you in intimately, whiskers twitching.`);
 					}
 					break;
-				case "buttslut":
-					if (slave.skill.entertainment >= 99) {
-						r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-					} else if (slave.skill.entertainment >= 60) {
-						r.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
-					} else if (slave.skill.entertainment >= 40) {
-						r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-					} else if (slave.skill.entertainment >= 20) {
-						r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
-					} else if (slave.skill.entertainment >= 10) {
-						r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+				default:
+					if (slave.face < -95) {
+						text.push(`not great to look at. Not even a little. You try to focus on ${his} body instead, finding yourself immediately turned off when ${he} catches your gaze.`);
+					} else if (slave.face < -40) {
+						text.push(`a bit of a turn off. You try to watch ${his} body instead.`);
+					} else if (slave.face < -10) {
+						text.push(`not a highlight. ${He} isn't beautiful, and you would rather watch ${his} body.`);
+					} else if (slave.face <= 10) {
+						text.push(`quite feminine and pleasing. You aren't captivated by ${his} face, but you don't avoid it either.`);
+					} else if (slave.face <= 40) {
+						text.push(`feminine and attractive. You find yourself looking at it from time to time.`);
+					} else if (slave.face <= 95) {
+						text.push(`beautiful and feminine. You often find your eyes locked on ${his} face for long periods of time.`);
 					} else {
-						r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+						text.push(`absolutely stunning. Watching ${his} face is often more pleasing than watching ${him} dance.`);
 					}
-					break;
-				case "pregnancy":
+			}
+
+			return text.join(' ');
+		}
+
+		function strip() {
+			const text = [];
+
+			text.push(`It's not over yet, though. You tell your slave that it's time to incorporate some stripping into ${his} dance.`);
+
+			if (slave.sexualFlaw === "shamefast") {
+				if (slave.devotion <= 40) {
+					text.push(`${He} immediately begins to tear up at the thought of being naked. ${His} shame is obvious to you, and you remind ${him} that ${his} comfort is not your concern.`);
 					if (slave.skill.entertainment >= 99) {
-						r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+						text.push(`Even though ${he} is crippled by shame, your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. With tears still streaming down ${his} face, ${he} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose, even as ${he} sniffles at the shame of revealing ${himself} for you. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
 					} else if (slave.skill.entertainment >= 60) {
-						r.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+						text.push(`Even though ${he} is crippled by shame, your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
 					} else if (slave.skill.entertainment >= 40) {
-						r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+						text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
 					} else if (slave.skill.entertainment >= 20) {
-						r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+						text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing. ${His} attempts are inhibited by ${his} shame, which makes ${him} shudder and cry whenever it's time for another article of clothing to come off.`);
 					} else if (slave.skill.entertainment >= 10) {
-						r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+						text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${He} is too concerned with protecting ${his} nakedness to be obedient and attractive simultaneously, and you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
 					} else {
-						r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+						text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to reluctantly, but obediently, remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
 					}
-					break;
-				case "boobs":
+				} else {
+					text.push(`Even though ${he} is uncomfortable at the thought of being naked, ${he} is so devoted to you that ${he} obeys without question.`);
 					if (slave.skill.entertainment >= 99) {
-						r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+						text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. Overcoming ${his} fear of being naked, ${he} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose, even as ${he} sniffles at the shame of revealing ${himself} for you. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
 					} else if (slave.skill.entertainment >= 60) {
-						r.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+						text.push(`Even though ${he} is still ashamed, your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
 					} else if (slave.skill.entertainment >= 40) {
-						r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+						text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
 					} else if (slave.skill.entertainment >= 20) {
-						r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+						text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing. ${His} attempts would be inhibited by ${his} shame, but ${his} devotion to you overrides this and ${he} is able to dance with added skill.`);
 					} else if (slave.skill.entertainment >= 10) {
-						r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+						text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. You find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
 					} else {
-						r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+						text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to shamefully remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
 					}
-					/*
-					if (slave.boobs >= 10000) {
-						r.push(`weighty mammaries`);
-					} else if (slave.boobs >= 2000) {
-						r.push(`cumbersome udders`);
-					} else if (slave.boobs >= 1000) {
-						r.push(`massive slave tits`);
-					} else if (slave.boobs >= 800) {
-						r.push(`forward-thrust breasts`);
-					} else if (slave.boobs >= 500) {
-						r.push(`meager chest`);
-					} else if (slave.boobs <= 400) {
-						r.push(`pathetic slave boobs`);
-					} else {
-						r.push(`tits`);
+				}
+			} else if (slave.behavioralFlaw === "odd") {
+				if (slave.skill.entertainment >= 99) {
+					text.push(`Even though ${he} is extremely odd, your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. With ${his} ass cheeks straddling the pole ${he} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+				} else if (slave.skill.entertainment >= 60) {
+					text.push(`Even though ${he} is extremely odd, your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+				} else if (slave.skill.entertainment >= 40) {
+					text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} shouts wildly before upping the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+				} else if (slave.skill.entertainment >= 20) {
+					text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing. ${His} attempts are inhibited by ${his} oddness, which results in ${him} crouching and squealing at inappropriate times. ${He} wonders aloud and you instruct ${him} to be silent the remainder of the dance.`);
+				} else if (slave.skill.entertainment >= 10) {
+					text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${He} is so odd that ${his} moves more resembles the chicken dance than any form of erotic dancing. You find yourself unable to look away, and for all the wrong reasons. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+				} else {
+					text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. Deciding that the rhythm is to blame, ${he} decides instead to sing ${his} own song to strip to. ${He} proceeds to hum string of off beat notes peppered with random words and scats, all punctuated by the sloppy kicking of clothes from ${his} ankles. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to roughly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+				}
+			} else if (slave.sexualFlaw === "attention whore") {
+				text.push(`As an attention whore, this is what ${he} lives for.`);
+				if (slave.skill.entertainment >= 99) {
+					text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. Being an attention whore, ${he} is obsessed with attracting the sexual arousal of others. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose, even though ${he} is also fulfilled by the event ${he} knows that your desire is all that matters. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+				} else if (slave.skill.entertainment >= 60) {
+					text.push(`Your slave is a skilled entertainer, well above average. Being an attention whore, ${he} is obsessed with attracting the sexual arousal of others. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} surely wishes ${he} were a better entertainer so you would call on ${him} to strip more often.`);
+				} else if (slave.skill.entertainment >= 40) {
+					text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. The true entertainment comes from ${his} teasing nature, which makes ${him} blush cutely anytime ${he} shows a bit of skin. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+				} else if (slave.skill.entertainment >= 20) {
+					text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing. ${His} attempts are overshadowed by ${his} clear desire to be looked at, and you can tell ${he} is distracted by this.`);
+				} else if (slave.skill.entertainment >= 10) {
+					text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${He} is trying much too hard to get your attention, and is visibly angered whenever ${he} sees that you are not aroused by ${his} fumblings. You find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+				} else {
+					text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to over-dramatically remove an article of clothing. After each article removed ${he} stops and looks at you to make sure you're watching. ${His} clear desire to be looked at makes ${him} more self-conscious which offsets the rhythm of the dance even more. ${He} decides to pick up the pace, aiming to be naked as quickly as possible so that you can admire ${his} body. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+				}
+			} else if (slave.sexualQuirk === "tease") {
+				if (slave.skill.entertainment >= 99) {
+					text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. Being a tease, ${he} is able to maintain an attractive blend of shame and arousal at the thought of being naked before you, and this inspires ${him} to tease you endlessly. With cheeks still flushed and red, ${he} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose, even as ${he} blushes at the shame and arousal of revealing ${himself} for you. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+				} else if (slave.skill.entertainment >= 60) {
+					text.push(`Your slave is a skilled entertainer, well above average. Being a tease, ${he} is able to maintain an attractive blend of shame and arousal at the thought of being naked before you, and this inspires ${him} to tease you endlessly. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+				} else if (slave.skill.entertainment >= 40) {
+					text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. The true entertainment comes from ${his} teasing nature, which makes ${him} blush cutely anytime ${he} shows a bit of skin. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+				} else if (slave.skill.entertainment >= 20) {
+					text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing. ${His} attempts are made more entertaining by ${his} shame, which makes ${him} redden and blush whenever it's time for another article of clothing to come off. Even though ${his} entertainment skill needs improving, you genuinely enjoy the teasing way ${he} tugs at ${his} wear and makes you anticipate the removal of each article.`);
+				} else if (slave.skill.entertainment >= 10) {
+					text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${He} is a tease, which adds a bit of value, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+				} else {
+					text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+				}
+			} else {
+				if (slave.fetishKnown === 1) {
+					switch (slave.fetish) {
+						case "submissive":
+							if (slave.skill.entertainment >= 99) {
+								text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+							} else if (slave.skill.entertainment >= 60) {
+								text.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+							} else if (slave.skill.entertainment >= 40) {
+								text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+							} else if (slave.skill.entertainment >= 20) {
+								text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+							} else if (slave.skill.entertainment >= 10) {
+								text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+							} else {
+								text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+							}
+							break;
+						case "dom":
+							if (slave.skill.entertainment >= 99) {
+								text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+							} else if (slave.skill.entertainment >= 60) {
+								text.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+							} else if (slave.skill.entertainment >= 40) {
+								text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+							} else if (slave.skill.entertainment >= 20) {
+								text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+							} else if (slave.skill.entertainment >= 10) {
+								text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+							} else {
+								text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+							}
+							break;
+						case "sadist":
+							if (slave.skill.entertainment >= 99) {
+								text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+							} else if (slave.skill.entertainment >= 60) {
+								text.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+							} else if (slave.skill.entertainment >= 40) {
+								text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+							} else if (slave.skill.entertainment >= 20) {
+								text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+							} else if (slave.skill.entertainment >= 10) {
+								text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+							} else {
+								text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+							}
+							break;
+						case "masochist":
+							if (slave.skill.entertainment >= 99) {
+								text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+							} else if (slave.skill.entertainment >= 60) {
+								text.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+							} else if (slave.skill.entertainment >= 40) {
+								text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+							} else if (slave.skill.entertainment >= 20) {
+								text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+							} else if (slave.skill.entertainment >= 10) {
+								text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+							} else {
+								text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+							}
+							break;
+						case "cumslut":
+							if (slave.skill.entertainment >= 99) {
+								text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+							} else if (slave.skill.entertainment >= 60) {
+								text.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+							} else if (slave.skill.entertainment >= 40) {
+								text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+							} else if (slave.skill.entertainment >= 20) {
+								text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+							} else if (slave.skill.entertainment >= 10) {
+								text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+							} else {
+								text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+							}
+							break;
+						case "humiliation":
+							if (slave.skill.entertainment >= 99) {
+								text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+							} else if (slave.skill.entertainment >= 60) {
+								text.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+							} else if (slave.skill.entertainment >= 40) {
+								text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+							} else if (slave.skill.entertainment >= 20) {
+								text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+							} else if (slave.skill.entertainment >= 10) {
+								text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+							} else {
+								text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+							}
+							break;
+						case "buttslut":
+							if (slave.skill.entertainment >= 99) {
+								text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+							} else if (slave.skill.entertainment >= 60) {
+								text.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+							} else if (slave.skill.entertainment >= 40) {
+								text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+							} else if (slave.skill.entertainment >= 20) {
+								text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+							} else if (slave.skill.entertainment >= 10) {
+								text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+							} else {
+								text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+							}
+							break;
+						case "pregnancy":
+							if (slave.skill.entertainment >= 99) {
+								text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+							} else if (slave.skill.entertainment >= 60) {
+								text.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+							} else if (slave.skill.entertainment >= 40) {
+								text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+							} else if (slave.skill.entertainment >= 20) {
+								text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+							} else if (slave.skill.entertainment >= 10) {
+								text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+							} else {
+								text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+							}
+							break;
+						case "boobs":
+							if (slave.skill.entertainment >= 99) {
+								text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+							} else if (slave.skill.entertainment >= 60) {
+								text.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+							} else if (slave.skill.entertainment >= 40) {
+								text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+							} else if (slave.skill.entertainment >= 20) {
+								text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+							} else if (slave.skill.entertainment >= 10) {
+								text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+							} else {
+								text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+							}
+
+							// // TODO: use or remove
+							// if (slave.boobs >= 10000) {
+							// 	text.push(`weighty mammaries`);
+							// } else if (slave.boobs >= 2000) {
+							// 	text.push(`cumbersome udders`);
+							// } else if (slave.boobs >= 1000) {
+							// 	text.push(`massive slave tits`);
+							// } else if (slave.boobs >= 800) {
+							// 	text.push(`forward-thrust breasts`);
+							// } else if (slave.boobs >= 500) {
+							// 	text.push(`meager chest`);
+							// } else if (slave.boobs <= 400) {
+							// 	text.push(`pathetic slave boobs`);
+							// } else {
+							// 	text.push(`tits`);
+							// }
+							// text.push(`across your body as ${he} goes down.`);
+							break;
+						default:
+							if (slave.skill.entertainment >= 99) {
+								text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
+							} else if (slave.skill.entertainment >= 80) {
+								text.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+							} else if (slave.skill.entertainment >= 60) {
+								text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+							} else if (slave.skill.entertainment >= 40) {
+								text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+							} else if (slave.skill.entertainment >= 20) {
+								text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+							} else {
+								text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+							}
 					}
-					r.push(`across your body as ${he} goes down.`);
-					*/
-					break;
-				default:
+				} else {
 					if (slave.skill.entertainment >= 99) {
-						r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-					} else if (slave.skill.entertainment >= 80) {
-						r.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
+						text.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
 					} else if (slave.skill.entertainment >= 60) {
-						r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
+						text.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
 					} else if (slave.skill.entertainment >= 40) {
-						r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+						text.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
 					} else if (slave.skill.entertainment >= 20) {
-						r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
+						text.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
+					} else if (slave.skill.entertainment >= 10) {
+						text.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
 					} else {
-						r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
+						text.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
 					}
+				}
 			}
-		} else {
-			if (slave.skill.entertainment >= 99) {
-				r.push(`Your slave is a masterful entertainer, able to keep anyone entertained for even the most lengthy of strip teases. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} knows how to fulfill ${his} purpose. You keep trying to get back to work, but your slave's movements are so enthralling that you cannot seem to break free.`);
-			} else if (slave.skill.entertainment >= 60) {
-				r.push(`Your slave is a skilled entertainer, well above average. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} knows how to use ${his} hips and ass to draw and keep your attention while slowly moving up to ${his} chest. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose.`);
-			} else if (slave.skill.entertainment >= 40) {
-				r.push(`Your slave is a practiced entertainer, not masterful but still able to give an arousing performance. ${He} begins by writhing ${his} hips and rolling ${his} ass. ${He} is able to use ${his} hips and ass to draw your attention before suddenly moving up to ${his} chest. ${He} isn't able to fully keep your attention, but whenever ${he} sees that you are becoming distracted ${he} ups the ante to draw you back in. ${His} body is nothing more than an object for your desire, and ${he} is learning to fulfill ${his} purpose. ${He} does ${his} best to direct your arousal onto ${his} body.`);
-			} else if (slave.skill.entertainment >= 20) {
-				r.push(`Your slave works hard to keep with the rhythm while removing articles of clothing.`);
-			} else if (slave.skill.entertainment >= 10) {
-				r.push(`Your slave is not a skilled performer, and ${his} movements are uninspired. ${His} movements are still attractive, but you find yourself becoming distracted, ${his} dance not enough to keep your attention or draw you back. You take out your tablet and make a note that this slave will need to practice ${his} seduction if ${he} is to be allowed to dance for you again. Even without skill you still can admire ${his} body. You imagine how much more attractive ${his} tits and ass could be if ${he} knew how to move them right.`);
-			} else {
-				r.push(`Your slave has no skills to speak of, and isn't able to keep even the simplest of rhythms. ${He} fumbles about awkwardly and clumsily, stopping abruptly every so often to gracelessly remove an article of clothing. You decide to find ${his} lack of skill amusing, and allow ${him} to continue practicing while you resume your work.`);
-			}
+
+			return text.join(' ');
 		}
-	}
 
-	// The following is formatting for later inclusion
-	/*
+		// function stripClothing() {
+		// The following is formatting for later inclusion
+		// TODO: use or remove
+		/*
 	switch (slave.clothes) {
 		case "a Fuckdoll suit":
-			r.push(`${slave.slaveName}'s Fuckdoll suit`);
+			text.push(`${slave.slaveName}'s Fuckdoll suit`);
 			if (slave.boobs > 24000) {
-				r.push(`fits each of ${his} awe-inspiring masses of breastflesh perfectly.`);
+				text.push(`fits each of ${his} awe-inspiring masses of breastflesh perfectly.`);
 			} else if (slave.boobs > 12000) {
-				r.push(`fits each of ${his} enormous masses of breastflesh perfectly.`);
+				text.push(`fits each of ${his} enormous masses of breastflesh perfectly.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`fits each of ${his} huge breasts individually.`);
+				text.push(`fits each of ${his} huge breasts individually.`);
 			} else if (slave.boobs > 800) {
-				r.push(`fits each of ${his} heavy breasts individually.`);
+				text.push(`fits each of ${his} heavy breasts individually.`);
 			} else if (slave.boobs > 300) {
-				r.push(`fits each of ${his} breasts individually.`);
+				text.push(`fits each of ${his} breasts individually.`);
 			} else {
-				r.push(`is flat across ${his} chest.`);
+				text.push(`is flat across ${his} chest.`);
 			}
 			break;
 		case "conservative clothing":
 			if (slave.boobs > 24000) {
-				r.push(`${slave.slaveName}`);
-				r.push(`is wearing a tent-like sweater tailored to cover ${his} tits.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`is wearing a tent-like sweater tailored to cover ${his} tits.`);
 			} else if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}`);
-				r.push(`is wearing a massively oversized custom sweater since nothing else comes close to modestly covering ${his} tits. Even so, it's stretched taut struggling to contain their immense mass.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`is wearing a massively oversized custom sweater since nothing else comes close to modestly covering ${his} tits. Even so, it's stretched taut struggling to contain their immense mass.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`${slave.slaveName}`);
-				r.push(`is wearing an oversized sweater, since that's the only top that will come close to covering ${his} tits. Even so, it's stretched taut just struggling to cover ${his} nipples.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`is wearing an oversized sweater, since that's the only top that will come close to covering ${his} tits. Even so, it's stretched taut just struggling to cover ${his} nipples.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}`);
-				r.push(`is wearing an oversized sweater, since that's the only top that will cover ${his} tits. Even so, it's stretched taut over them.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`is wearing an oversized sweater, since that's the only top that will cover ${his} tits. Even so, it's stretched taut over them.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s blouse is professional, but can't conceal the gigantic dimensions of ${his} tits.`);
+				text.push(`${slave.slaveName}'s blouse is professional, but can't conceal the gigantic dimensions of ${his} tits.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s blouse is professional, but can't conceal how big ${his} tits are.`);
+				text.push(`${slave.slaveName}'s blouse is professional, but can't conceal how big ${his} tits are.`);
 			} else if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}'s blouse is professional and includes a pleated front over ${his} flat chest.`);
+				text.push(`${slave.slaveName}'s blouse is professional and includes a pleated front over ${his} flat chest.`);
 			} else {
-				r.push(`${slave.slaveName}'s blouse is professional and includes a pleated front over ${his} breasts.`);
+				text.push(`${slave.slaveName}'s blouse is professional and includes a pleated front over ${his} breasts.`);
 			}
 			break;
 		case "chains":
-			r.push(`${slave.slaveName}`);
-			r.push(`has a length of chain painfully`);
+			text.push(`${slave.slaveName}`);
+			text.push(`has a length of chain painfully`);
 			if (slave.boobs > 800) {
-				r.push(`tightened around the base of each breast, forcing them out.`);
+				text.push(`tightened around the base of each breast, forcing them out.`);
 			} else if (slave.boobs < 300) {
 				switch (slave.nipples) {
 					case "huge":
-						r.push(`wrapped around each of ${his} huge nipples, since they are the only things protruding from ${his} chest.`);
+						text.push(`wrapped around each of ${his} huge nipples, since they are the only things protruding from ${his} chest.`);
 						break;
 					case "inverted":
-						r.push(`wrapped tightly across ${his} flat chest, through the cleft of ${his} inverted nipples.`);
+						text.push(`wrapped tightly across ${his} flat chest, through the cleft of ${his} inverted nipples.`);
 						break;
 					default:
-						r.push(`wrapped tightly across ${his} flat chest, directly over ${his} ${slave.nipples} nipples.`);
+						text.push(`wrapped tightly across ${his} flat chest, directly over ${his} ${slave.nipples} nipples.`);
 				}
 			} else {
-				r.push(`looped under ${his} chest, forcing ${his} breasts up.`);
+				text.push(`looped under ${his} chest, forcing ${his} breasts up.`);
 			}
 			break;
 		case "Western clothing":
-			r.push(`${slave.slaveName}'s flannel shirt`);
+			text.push(`${slave.slaveName}'s flannel shirt`);
 			if (slave.boobs > 2000) {
-				r.push(`can't begin to contain ${his} tits, so ${he}'s just tied it under them for support.`);
+				text.push(`can't begin to contain ${his} tits, so ${he}'s just tied it under them for support.`);
 			} else if (slave.boobs > 800) {
-				r.push(`can't close over ${his} tits, so ${he}'s just buttoned it up to where they start and let them fill it out above that.`);
+				text.push(`can't close over ${his} tits, so ${he}'s just buttoned it up to where they start and let them fill it out above that.`);
 			} else if (slave.boobs < 300) {
-				r.push(`tightly hugs ${his} flat chest.`);
+				text.push(`tightly hugs ${his} flat chest.`);
 			} else {
-				r.push(`rests comfortably over ${his} breasts.`);
+				text.push(`rests comfortably over ${his} breasts.`);
 			}
 			break;
 		case "body oil":
 			if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}'s flat chest is covered in a sexy sheen of body oil.`);
+				text.push(`${slave.slaveName}'s flat chest is covered in a sexy sheen of body oil.`);
 			} else {
-				r.push(`${slave.slaveName}'s breasts are covered in a sexy sheen of body oil.`);
+				text.push(`${slave.slaveName}'s breasts are covered in a sexy sheen of body oil.`);
 			}
 			break;
 		case "a toga":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s breasts are too big to cover with ${his} toga, so ${he} leaves them hanging free.`);
+				text.push(`${slave.slaveName}'s breasts are too big to cover with ${his} toga, so ${he} leaves them hanging free.`);
 			} else if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}`);
-				r.push(`is wearing ${his} toga so as to leave one ${slave.nipples} nipple bare.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`is wearing ${his} toga so as to leave one ${slave.nipples} nipple bare.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`is wearing ${his} toga so as to leave one breast bare.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`is wearing ${his} toga so as to leave one breast bare.`);
 			}
 			break;
 		case "a huipil":
 			if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s breasts are so big that they pull up ${his} huipil uncomfortably high, so ${he} needs to fold it between them.`);
+				text.push(`${slave.slaveName}'s breasts are so big that they pull up ${his} huipil uncomfortably high, so ${he} needs to fold it between them.`);
 			} else if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}'s huipil rests on ${his} flat chest.`);
+				text.push(`${slave.slaveName}'s huipil rests on ${his} flat chest.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`is wearing ${his} huipil which accentuates ${his} breasts.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`is wearing ${his} huipil which accentuates ${his} breasts.`);
 			}
 			break;
 		case "a slutty qipao":
-			r.push(`${slave.slaveName}'s qipao`);
+			text.push(`${slave.slaveName}'s qipao`);
 			if (slave.boobs > 12000) {
-				r.push(`can't contain the immense size of ${his} breasts, so ${he} wears a modified variant that lets ${his} tits hang free.`);
+				text.push(`can't contain the immense size of ${his} breasts, so ${he} wears a modified variant that lets ${his} tits hang free.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`barely covers ${his} breasts, it strains to contain their absurd size. Breast flesh spills from any gap it can find.`);
+				text.push(`barely covers ${his} breasts, it strains to contain their absurd size. Breast flesh spills from any gap it can find.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`demurely covers ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`demurely covers ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`demurely hugs ${his} flat chest.`);
+				text.push(`demurely hugs ${his} flat chest.`);
 			} else {
-				r.push(`demurely covers ${his} breasts.`);
+				text.push(`demurely covers ${his} breasts.`);
 			}
 			break;
 		case "uncomfortable straps":
-			r.push(`${slave.slaveName}'s slave`);
+			text.push(`${slave.slaveName}'s slave`);
 			if (slave.boobs > 12000) {
-				r.push(`outfit includes a network of straps to support ${his} breasts, radiating outwards from the steel rings around ${his} nipples.`);
+				text.push(`outfit includes a network of straps to support ${his} breasts, radiating outwards from the steel rings around ${his} nipples.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`outfit has special straps for ${his} massive boobs: one strap down the front of each with steel rings to let ${his} nipples through, and a strap around the base of each, painfully squeezing ${his} breasts out to make them seem even bigger.`);
+				text.push(`outfit has special straps for ${his} massive boobs: one strap down the front of each with steel rings to let ${his} nipples through, and a strap around the base of each, painfully squeezing ${his} breasts out to make them seem even bigger.`);
 			} else if (slave.boobs > 800) {
-				r.push(`outfit's straining straps restrain the flesh of ${his} tits like a string bikini, with steel rings to let ${his} nipples through.`);
+				text.push(`outfit's straining straps restrain the flesh of ${his} tits like a string bikini, with steel rings to let ${his} nipples through.`);
 			} else if (slave.boobs < 300) {
-				r.push(`outfit's straps pass over ${his} flat chest like a string bikini, with steel rings to let ${his} ${slave.nipples} nipples through.`);
+				text.push(`outfit's straps pass over ${his} flat chest like a string bikini, with steel rings to let ${his} ${slave.nipples} nipples through.`);
 			} else {
-				r.push(`outfit's straps pass over ${his} breasts like a string bikini, with steel rings to let ${his} nipples through.`);
+				text.push(`outfit's straps pass over ${his} breasts like a string bikini, with steel rings to let ${his} nipples through.`);
 			}
 			break;
 		case "shibari ropes":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`breasts are restrained by`);
+				text.push(`breasts are restrained by`);
 				if (V.showInches === 2) {
-					r.push(`yards and yards`);
+					text.push(`yards and yards`);
 				} else {
-					r.push(`meters and meters`);
+					text.push(`meters and meters`);
 				}
-				r.push(`of rope.`);
+				text.push(`of rope.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`boobs are tightly bound with rope, soft flesh pushing out from between them.`);
+				text.push(`boobs are tightly bound with rope, soft flesh pushing out from between them.`);
 			} else if (slave.boobs < 300) {
-				r.push(`flat chest is tightly bound with rope, drawing attention to ${his} flat chest.`);
+				text.push(`flat chest is tightly bound with rope, drawing attention to ${his} flat chest.`);
 			} else {
-				r.push(`chest is tightly bound with rope.`);
+				text.push(`chest is tightly bound with rope.`);
 			}
 			break;
 		case "restrictive latex":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 2000) {
-				r.push(`breasts protrude through holes in ${his} latex suit, which are too small for them, painfully constricting ${him} and making them seem even bigger.`);
+				text.push(`breasts protrude through holes in ${his} latex suit, which are too small for them, painfully constricting ${him} and making them seem even bigger.`);
 			} else if (slave.boobs > 800) {
-				r.push(`breasts protrude through holes in ${his} latex suit.`);
+				text.push(`breasts protrude through holes in ${his} latex suit.`);
 			} else if (slave.boobs < 300) {
-				r.push(`${slave.nipples}`);
-				r.push(`nipples poke through holes in ${his} latex suit, since ${he} has nothing else protruding from ${his} chest.`);
+				text.push(`${slave.nipples}`);
+				text.push(`nipples poke through holes in ${his} latex suit, since ${he} has nothing else protruding from ${his} chest.`);
 			} else {
-				r.push(`latex suit leaves ${his} chest bare.`);
+				text.push(`latex suit leaves ${his} chest bare.`);
 			}
 			break;
 		case "attractive lingerie":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`lace bra cannot cover the whole breast; its cups are half-moon shaped, and designed to offer what support they can to the bottom of them. They have disappeared completely under the immense quantity of breast flesh.`);
+				text.push(`lace bra cannot cover the whole breast; its cups are half-moon shaped, and designed to offer what support they can to the bottom of them. They have disappeared completely under the immense quantity of breast flesh.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`lace bra cannot cover the whole breast; its cups are half-moon shaped, and designed to offer what support they can to the bottom of them.`);
+				text.push(`lace bra cannot cover the whole breast; its cups are half-moon shaped, and designed to offer what support they can to the bottom of them.`);
 			} else if (slave.boobs > 800) {
-				r.push(`sturdy lace bra supports ${his} huge breasts.`);
+				text.push(`sturdy lace bra supports ${his} huge breasts.`);
 			} else if (slave.boobs < 300) {
-				r.push(`pretty lace bra hugs ${his} flat chest.`);
+				text.push(`pretty lace bra hugs ${his} flat chest.`);
 			} else {
-				r.push(`pretty lace bra accentuates ${his} breasts.`);
+				text.push(`pretty lace bra accentuates ${his} breasts.`);
 			}
 			break;
 		case "kitty lingerie":
-			r.push(`${slave.slaveName}'s lacy bra features a hole shaped liked a cat's head in the center of ${his} chest;`);
+			text.push(`${slave.slaveName}'s lacy bra features a hole shaped liked a cat's head in the center of ${his} chest;`);
 			if (slave.boobs > 12000) {
-				r.push(`${his} breasts have stretched ${his} bra to the point that the hole is unrecognizable as anything feline.`);
+				text.push(`${his} breasts have stretched ${his} bra to the point that the hole is unrecognizable as anything feline.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`the size of ${his} breasts severely stretches out the hole's shape.`);
+				text.push(`the size of ${his} breasts severely stretches out the hole's shape.`);
 			} else if (slave.boobs > 800) {
-				r.push(`the size of ${his} breasts stretches out the hole's shape.`);
+				text.push(`the size of ${his} breasts stretches out the hole's shape.`);
 			} else if (slave.boobs < 300) {
-				r.push(`it lies flat against ${his} body.`);
+				text.push(`it lies flat against ${his} body.`);
 			} else {
-				r.push(`the hole lies directly over ${his} cleavage.`);
+				text.push(`the hole lies directly over ${his} cleavage.`);
 			}
 			break;
 		case "a succubus outfit":
-			r.push(`${slave.slaveName}'s corset ends just below ${his}`);
+			text.push(`${slave.slaveName}'s corset ends just below ${his}`);
 			if (slave.boobs < 300) {
-				r.push(`non-existent`);
+				text.push(`non-existent`);
 			}
-			r.push(`breasts, leaving them bare.`);
+			text.push(`breasts, leaving them bare.`);
 			if (slave.boobs > 2000) {
-				r.push(`It hugs ${his} tightly and comes up to right under where they start, forcing them to spill over and hide its upper half.`);
+				text.push(`It hugs ${his} tightly and comes up to right under where they start, forcing them to spill over and hide its upper half.`);
 			} else if (slave.boobs > 400) {
-				r.push(`It hugs ${his} tightly and comes up to right under where they start, presenting them like a push-up bra.`);
+				text.push(`It hugs ${his} tightly and comes up to right under where they start, presenting them like a push-up bra.`);
 			}
 			break;
 		case "a slutty maid outfit":
-			r.push(`${slave.slaveName}'s maid dress stops below ${his}`);
+			text.push(`${slave.slaveName}'s maid dress stops below ${his}`);
 			if (slave.boobs < 300) {
-				r.push(`non-existent`);
+				text.push(`non-existent`);
 			}
-			r.push(`breasts, but the outfit includes a thin white blouse`);
+			text.push(`breasts, but the outfit includes a thin white blouse`);
 			if (slave.boobs > 4000) {
-				r.push(`that fails to even come close to covering ${his} immense breasts.`);
+				text.push(`that fails to even come close to covering ${his} immense breasts.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`that covers them to just over ${his} nipples when ${he} pulls it up over them. It's pulled down by ${his} huge chest whenever ${he} moves.`);
+				text.push(`that covers them to just over ${his} nipples when ${he} pulls it up over them. It's pulled down by ${his} huge chest whenever ${he} moves.`);
 			} else if (slave.boobs > 800) {
-				r.push(`that covers them to just over ${his} nipples, leaving a large area of deliciously unsupported and jiggling cleavage.`);
+				text.push(`that covers them to just over ${his} nipples, leaving a large area of deliciously unsupported and jiggling cleavage.`);
 			} else if (slave.boobs < 300) {
-				r.push(`that hugs ${his} flat chest and lets ${his} ${slave.nipples} nipples protrude through the fabric.`);
+				text.push(`that hugs ${his} flat chest and lets ${his} ${slave.nipples} nipples protrude through the fabric.`);
 			} else {
-				r.push(`to cover them.`);
+				text.push(`to cover them.`);
 			}
 			break;
 		case "a nice maid outfit":
-			r.push(`${slave.slaveName}'s maid dress front is almost conservative, covering ${his}`);
+			text.push(`${slave.slaveName}'s maid dress front is almost conservative, covering ${his}`);
 			if (slave.boobs > 12000) {
-				r.push(`immense breasts with a tent-like billow of white fabric.`);
+				text.push(`immense breasts with a tent-like billow of white fabric.`);
 			} else if (slave.boobs > 6000) {
-				r.push(`immense breasts as best it can; it barely succeeds at its task, straining at the seams and allowing breast flesh to spill out of every available gap.`);
+				text.push(`immense breasts as best it can; it barely succeeds at its task, straining at the seams and allowing breast flesh to spill out of every available gap.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`breasts, though it cannot conceal their enormous mass.`);
+				text.push(`breasts, though it cannot conceal their enormous mass.`);
 			} else if (slave.boobs < 300) {
-				r.push(`flat chest, though it does nothing to hide how flat ${he} is.`);
+				text.push(`flat chest, though it does nothing to hide how flat ${he} is.`);
 			} else {
-				r.push(`breasts.`);
+				text.push(`breasts.`);
 			}
 			break;
 		case "a fallen nuns habit":
-			r.push(`${slave.slaveName}'s latex habit includes a`);
+			text.push(`${slave.slaveName}'s latex habit includes a`);
 			if (slave.boobs > 20000) {
-				r.push(`half-corset, but it's completely invisible, being hidden under ${his} inhuman tits.`);
+				text.push(`half-corset, but it's completely invisible, being hidden under ${his} inhuman tits.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`half-corset, but only the bottom edge is visible: the rest is swallowed up under ${his} gigantic tits.`);
+				text.push(`half-corset, but only the bottom edge is visible: the rest is swallowed up under ${his} gigantic tits.`);
 			} else if (slave.boobs > 800) {
-				r.push(`half-corset to force ${his} big boobs up and forward, forming a lot of cleavage even though they're bare.`);
+				text.push(`half-corset to force ${his} big boobs up and forward, forming a lot of cleavage even though they're bare.`);
 			} else if (slave.boobs < 300) {
-				r.push(`half-corset that tightly hugs ${his} flat chest.`);
+				text.push(`half-corset that tightly hugs ${his} flat chest.`);
 			} else {
-				r.push(`half-corset to force ${his} boobs up and forward.`);
+				text.push(`half-corset to force ${his} boobs up and forward.`);
 			}
 			break;
 		case "a chattel habit":
-			r.push(`${slave.slaveName}'s chattel habit's scapular covers ${his} shoulders`);
+			text.push(`${slave.slaveName}'s chattel habit's scapular covers ${his} shoulders`);
 			if (hasAnyArms(slave)) {
-				r.push(`and arm`);
+				text.push(`and arm`);
 				if (hasBothArms(slave)) {
-					r.push(`s`);
+					text.push(`s`);
 				}
 			}
-			r.push(r.pop() + `, but is open in front, leaving ${his}`);
+			text.push(r.pop() + `, but is open in front, leaving ${his}`);
 			if (slave.boobs > 4000) {
-				r.push(`boobs completely bare. It tucks into a golden belt, though this is buried under ${his} breasts.`);
+				text.push(`boobs completely bare. It tucks into a golden belt, though this is buried under ${his} breasts.`);
 			} else if (slave.boobs > 300) {
-				r.push(`boobs completely bare. It tucks into a golden belt, which is cinched up right under ${his} breasts.`);
+				text.push(`boobs completely bare. It tucks into a golden belt, which is cinched up right under ${his} breasts.`);
 			} else {
-				r.push(`flat chest completely bare. It tucks into a golden belt cinched around ${his} middle torso.`);
+				text.push(`flat chest completely bare. It tucks into a golden belt cinched around ${his} middle torso.`);
 			}
 			break;
 		case "a penitent nuns habit":
-			r.push(`If ${he} fails to hold ${his} torso totally still, the coarse cloth of ${his} top agonizingly scrapes across ${his} nipples, bare under ${his} habit.`);
+			text.push(`If ${he} fails to hold ${his} torso totally still, the coarse cloth of ${his} top agonizingly scrapes across ${his} nipples, bare under ${his} habit.`);
 			break;
 		case "a string bikini":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s breasts are so large that the little scraps of cloth intended for ${his} nipples can't really stay centered over them.`);
+				text.push(`${slave.slaveName}'s breasts are so large that the little scraps of cloth intended for ${his} nipples can't really stay centered over them.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s huge breasts constantly pull ${his} nipples out from under the tiny scrap of cloth that ${his} string bikini affords them.`);
+				text.push(`${slave.slaveName}'s huge breasts constantly pull ${his} nipples out from under the tiny scrap of cloth that ${his} string bikini affords them.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s big breasts threaten to break out of ${his} straining string bikini top.`);
+				text.push(`${slave.slaveName}'s big breasts threaten to break out of ${his} straining string bikini top.`);
 			} else if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}'s string bikini top barely covers anything, affording only a tiny scrap of cloth for each nipple; not that there is much else to cover on ${his} flat chest.`);
+				text.push(`${slave.slaveName}'s string bikini top barely covers anything, affording only a tiny scrap of cloth for each nipple; not that there is much else to cover on ${his} flat chest.`);
 			} else {
-				r.push(`${slave.slaveName}'s string bikini top barely covers anything, affording only a tiny scrap of cloth for each nipple.`);
+				text.push(`${slave.slaveName}'s string bikini top barely covers anything, affording only a tiny scrap of cloth for each nipple.`);
 			}
 			break;
 		case "a scalemail bikini":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s breasts are so large that it's a testament to ${his} scalemail top that it hasn't broken yet.`);
+				text.push(`${slave.slaveName}'s breasts are so large that it's a testament to ${his} scalemail top that it hasn't broken yet.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s huge breasts constantly strain ${his} scalemail top.`);
+				text.push(`${slave.slaveName}'s huge breasts constantly strain ${his} scalemail top.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s scalemail top contains ${his} big breasts well.`);
+				text.push(`${slave.slaveName}'s scalemail top contains ${his} big breasts well.`);
 			} else if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}'s scalemail bikini top easily covers everything, as there is not much to cover on ${his} flat chest.`);
+				text.push(`${slave.slaveName}'s scalemail bikini top easily covers everything, as there is not much to cover on ${his} flat chest.`);
 			} else {
-				r.push(`${slave.slaveName}'s scalemail bikini top covers everything, while still flaunting it.`);
+				text.push(`${slave.slaveName}'s scalemail bikini top covers everything, while still flaunting it.`);
 			}
 			break;
 		case "striped panties":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s enormous breasts are completely bare.`);
+				text.push(`${slave.slaveName}'s enormous breasts are completely bare.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s huge breasts are completely bare.`);
+				text.push(`${slave.slaveName}'s huge breasts are completely bare.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s breasts are completely bare.`);
+				text.push(`${slave.slaveName}'s breasts are completely bare.`);
 			} else if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}'s flat breasts are completely bare.`);
+				text.push(`${slave.slaveName}'s flat breasts are completely bare.`);
 			} else {
-				r.push(`${slave.slaveName}'s breasts are completely bare.`);
+				text.push(`${slave.slaveName}'s breasts are completely bare.`);
 			}
 			break;
 		case "clubslut netting":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`immense boobs hang out the holes they tore in ${his} clubslut netting.`);
+				text.push(`immense boobs hang out the holes they tore in ${his} clubslut netting.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`clubslut netting is stretched to the breaking point by ${his} massive boobs.`);
+				text.push(`clubslut netting is stretched to the breaking point by ${his} massive boobs.`);
 			} else if (slave.boobs > 800) {
-				r.push(`clubslut netting is stretched by ${his} big breasts.`);
+				text.push(`clubslut netting is stretched by ${his} big breasts.`);
 			} else if (slave.boobs < 300) {
-				r.push(`clubslut netting hugs ${his} flat chest.`);
+				text.push(`clubslut netting hugs ${his} flat chest.`);
 			} else {
-				r.push(`clubslut netting hugs ${his} chest tightly.`);
+				text.push(`clubslut netting hugs ${his} chest tightly.`);
 			}
 			break;
 		case "a cheerleader outfit":
-			r.push(`${slave.slaveName}'s cheerleader top`);
+			text.push(`${slave.slaveName}'s cheerleader top`);
 			if (slave.boobs > 12000) {
-				r.push(`can't support ${his} giant bust and is lost beneath ${his} immense breasts.`);
+				text.push(`can't support ${his} giant bust and is lost beneath ${his} immense breasts.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`is strongly engineered, but it can barely support ${his} enormous bust.`);
+				text.push(`is strongly engineered, but it can barely support ${his} enormous bust.`);
 			} else if (slave.boobs > 800) {
-				r.push(`gives ${him} an acre of cleavage.`);
+				text.push(`gives ${him} an acre of cleavage.`);
 			} else if (slave.boobs < 300) {
-				r.push(`tightly clings to ${his} flat chest, prominently displaying ${his} ${slave.nipples} nipples.`);
+				text.push(`tightly clings to ${his} flat chest, prominently displaying ${his} ${slave.nipples} nipples.`);
 			} else {
-				r.push(`does its best to make ${his} boobs look bigger than they are.`);
+				text.push(`does its best to make ${his} boobs look bigger than they are.`);
 			}
 			break;
 		case "cutoffs and a t-shirt":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`tits are so huge that ${his} t-shirt rests pathetically atop their mass.`);
+				text.push(`tits are so huge that ${his} t-shirt rests pathetically atop their mass.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`tits are so big that ${his} t-shirt barely comes down over ${his} nipples, leaving a lot of underboob hanging out.`);
+				text.push(`tits are so big that ${his} t-shirt barely comes down over ${his} nipples, leaving a lot of underboob hanging out.`);
 			} else if (slave.boobs > 1200) {
-				r.push(`t-shirt is held out and away from ${his} midriff by ${his} big breasts.`);
+				text.push(`t-shirt is held out and away from ${his} midriff by ${his} big breasts.`);
 			} else if (slave.boobs < 300) {
-				r.push(`t-shirt is tied across ${his} flat chest to bare ${his} midriff.`);
+				text.push(`t-shirt is tied across ${his} flat chest to bare ${his} midriff.`);
 			} else {
-				r.push(`t-shirt is tied up to bare ${his} midriff.`);
+				text.push(`t-shirt is tied up to bare ${his} midriff.`);
 			}
 			break;
 		case "spats and a tank top":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 20000) {
-				r.push(`tank top lies atop ${his} massive rack.`);
+				text.push(`tank top lies atop ${his} massive rack.`);
 			} else if (slave.boobs > 12000) {
-				r.push(`tank top just barely covers ${his} nipples despite its fairly large size.`);
+				text.push(`tank top just barely covers ${his} nipples despite its fairly large size.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`tank top can never completely cover ${his} tits, giving varying amounts of underboob as ${he} moves about.`);
+				text.push(`tank top can never completely cover ${his} tits, giving varying amounts of underboob as ${he} moves about.`);
 			} else if (slave.boobs > 1200) {
-				r.push(`midriff is open to see as ${his} chest makes ${his} tank top ride up.`);
+				text.push(`midriff is open to see as ${his} chest makes ${his} tank top ride up.`);
 			} else {
-				r.push(`tank top is tight against ${his}`);
+				text.push(`tank top is tight against ${his}`);
 				if (slave.boobs < 300) {
-					r.push(`flat`);
+					text.push(`flat`);
 				}
-				r.push(`chest.`);
+				text.push(`chest.`);
 			}
 			break;
 		case "a slutty outfit":
-			r.push(`${slave.slaveName}`);
+			text.push(`${slave.slaveName}`);
 			if (slave.boobs > 12000) {
-				r.push(`has given up trying to contain ${his} immense bust and is now choosing outfits that allow ${his} breasts to hang free.`);
+				text.push(`has given up trying to contain ${his} immense bust and is now choosing outfits that allow ${his} breasts to hang free.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`has to be careful choosing slutty outfits that can restrain ${his} massive breasts.`);
+				text.push(`has to be careful choosing slutty outfits that can restrain ${his} massive breasts.`);
 			} else if (slave.boobs > 800) {
-				r.push(`has to be careful choosing slutty outfits that can handle ${his} big breasts.`);
+				text.push(`has to be careful choosing slutty outfits that can handle ${his} big breasts.`);
 			} else if (slave.boobs < 300) {
-				r.push(`chooses slutty outfits that go well on a ${girl} with no tits.`);
+				text.push(`chooses slutty outfits that go well on a ${girl} with no tits.`);
 			} else {
-				r.push(`chooses slutty outfits that accentuate ${his} breasts.`);
+				text.push(`chooses slutty outfits that accentuate ${his} breasts.`);
 			}
 			break;
 		case "a slave gown":
-			r.push(`${slave.slaveName}'s slave gown`);
+			text.push(`${slave.slaveName}'s slave gown`);
 			if (slave.boobs > 12000) {
-				r.push(`is no longer able to cover ${his} immense breasts. Instead, it has been redesigned to draw the eye to them.`);
+				text.push(`is no longer able to cover ${his} immense breasts. Instead, it has been redesigned to draw the eye to them.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`is carefully engineered and is somehow able to cover the enormous mass of ${his} breasts.`);
+				text.push(`is carefully engineered and is somehow able to cover the enormous mass of ${his} breasts.`);
 			} else if (slave.boobs > 800) {
-				r.push(`is carefully tailored, tastefully covering yet enhancing ${his} big breasts.`);
+				text.push(`is carefully tailored, tastefully covering yet enhancing ${his} big breasts.`);
 			} else if (slave.boobs < 300) {
-				r.push(`is carefully tailored to closely hug ${his} flat chest.`);
+				text.push(`is carefully tailored to closely hug ${his} flat chest.`);
 			} else {
-				r.push(`subtly accentuates ${his} breasts.`);
+				text.push(`subtly accentuates ${his} breasts.`);
 			}
 			break;
 		case "a halter top dress":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s immense breasts are far too big for ${his} dress to contain; instead it has been redesigned to allow them to hang freely.`);
+				text.push(`${slave.slaveName}'s immense breasts are far too big for ${his} dress to contain; instead it has been redesigned to allow them to hang freely.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}'s enormous breasts are spill out from every available space in ${his} beautiful halter top dress.`);
+				text.push(`${slave.slaveName}'s enormous breasts are spill out from every available space in ${his} beautiful halter top dress.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s enormous breasts are bulging inside a beautiful halter top dress.`);
+				text.push(`${slave.slaveName}'s enormous breasts are bulging inside a beautiful halter top dress.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s is draped inside a beautiful halter top dress, making ${his} big breasts the center of attention.`);
+				text.push(`${slave.slaveName}'s ${adjNoun} are draped inside a beautiful halter top dress, making them the center of attention.`);
 			} else if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}`);
-				r.push(`is wearing a beautiful silky halter top dress, almost as if it was sculpted to hug ${his} flat chest.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`is wearing a beautiful silky halter top dress, almost as if it was sculpted to hug ${his} flat chest.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`is wearing a beautiful silky halter top dress, almost as if it was sculpted to match ${his} frame.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`is wearing a beautiful silky halter top dress, almost as if it was sculpted to match ${his} frame.`);
 			}
 			break;
 		case "a ball gown":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}`);
-				r.push(`fabulous silken ball gown is designed to allow ${his} oversized breasts to hang free.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`fabulous silken ball gown is designed to allow ${his} oversized breasts to hang free.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}`);
-				r.push(`somehow managed to cram the immense mass of ${his} breasts inside a fabulous silken ball gown. They spill out of every available gap.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`somehow managed to cram the immense mass of ${his} breasts inside a fabulous silken ball gown. They spill out of every available gap.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}`);
-				r.push(`somehow managed to fit the enormous mass of ${his} breasts inside a fabulous silken ball gown.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`somehow managed to fit the enormous mass of ${his} breasts inside a fabulous silken ball gown.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s fabulous silken ball gown is carefully tailored, beautifully covering yet enhancing ${his} big breasts.`);
+				text.push(`${slave.slaveName}'s fabulous silken ball gown is carefully tailored, beautifully covering yet enhancing ${his} big breasts.`);
 			} else if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}'s fabulous silken ball gown is carefully tailored, beautifully caressing ${his} flat chest.`);
+				text.push(`${slave.slaveName}'s fabulous silken ball gown is carefully tailored, beautifully caressing ${his} flat chest.`);
 			} else {
-				r.push(`${slave.slaveName}'s draped inside a fabulous silken ball gown.`);
+				text.push(`${slave.slaveName}'s draped inside a fabulous silken ball gown.`);
 			}
 			break;
 		case "slutty business attire":
-			r.push(`${slave.slaveName}'s suit jacket`);
+			text.push(`${slave.slaveName}'s suit jacket`);
 			if (slave.boobs > 12000) {
-				r.push(`and blouse are both open in front, leaving ${his} boobs bare, since there's no way ${he} could button ${his} clothes over ${his} tits.`);
+				text.push(`and blouse are both open in front, leaving ${his} boobs bare, since there's no way ${he} could button ${his} clothes over ${his} tits.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`is open in front, and ${his} straining blouse barely restrains ${his} tits.`);
+				text.push(`is open in front, and ${his} straining blouse barely restrains ${his} tits.`);
 			} else if (slave.boobs < 300) {
-				r.push(`is open in front, tightly hugging ${his} flat chest and prominently displaying ${his} ${slave.nipples} nipples.`);
+				text.push(`is open in front, tightly hugging ${his} flat chest and prominently displaying ${his} ${slave.nipples} nipples.`);
 			} else {
-				r.push(`is open in front, and ${his} blouse barely covers ${his} breasts.`);
+				text.push(`is open in front, and ${his} blouse barely covers ${his} breasts.`);
 			}
 			break;
 		case "nice business attire":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`tits are so immense that ${his} specially tailored blouse and jacket are incapable of being buttoned up.`);
+				text.push(`tits are so immense that ${his} specially tailored blouse and jacket are incapable of being buttoned up.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`tits are so huge that they prevent ${his} jacket from closing. Every motion ${he} makes threatens to turn ${his} blouse buttons into ballistics.`);
+				text.push(`tits are so huge that they prevent ${his} jacket from closing. Every motion ${he} makes threatens to turn ${his} blouse buttons into ballistics.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`tits are so big that they strain even ${his} specially tailored blouse and jacket.`);
+				text.push(`tits are so big that they strain even ${his} specially tailored blouse and jacket.`);
 			} else if (slave.boobs > 800) {
-				r.push(`big tits strain against ${his} tailored blouse and jacket.`);
+				text.push(`big tits strain against ${his} tailored blouse and jacket.`);
 			} else if (slave.boobs < 300) {
-				r.push(`suit jacket is fitted tightly to ${his} flat chest.`);
+				text.push(`suit jacket is fitted tightly to ${his} flat chest.`);
 			} else {
-				r.push(`suit jacket conceals a flattering bra that lifts and presents ${his} bosom.`);
+				text.push(`suit jacket conceals a flattering bra that lifts and presents ${his} bosom.`);
 			}
 			break;
 		case "a comfortable bodysuit":
 			if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}'s bodysuit is so tightly form-fitting that it clings to ${his} flat chest and prominently displays ${his} ${slave.nipples} nipples.`);
+				text.push(`${slave.slaveName}'s bodysuit is so tightly form-fitting that it clings to ${his} flat chest and prominently displays ${his} ${slave.nipples} nipples.`);
 			} else {
-				r.push(`${slave.slaveName}'s bodysuit is so tightly form-fitting that ${his} breasts are individually hugged and supported by the material.`);
+				text.push(`${slave.slaveName}'s bodysuit is so tightly form-fitting that ${his} breasts are individually hugged and supported by the material.`);
 			}
 			break;
 		case "a latex catsuit":
 			if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}'s latex catsuit fits ${him} like a second skin, showing off every detail of ${his} ${slave.nipples} nipples and distinct lack of breasts.`);
+				text.push(`${slave.slaveName}'s latex catsuit fits ${him} like a second skin, showing off every detail of ${his} ${slave.nipples} nipples and distinct lack of breasts.`);
 			} else {
-				r.push(`${slave.slaveName}'s latex catsuit fits ${him} like a second skin, showing off every detail of ${his} nipples and breasts.`);
+				text.push(`${slave.slaveName}'s latex catsuit fits ${him} like a second skin, showing off every detail of ${his} nipples and breasts.`);
 			}
 			break;
 		case "a military uniform":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s tits are so immense that ${his} specially tailored shirt and tunic are incapable of being buttoned up.`);
+				text.push(`${slave.slaveName}'s tits are so immense that ${his} specially tailored shirt and tunic are incapable of being buttoned up.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} tunic from closing. Every motion threatens to turn ${his} shirt buttons into shrapnel.`);
+				text.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} tunic from closing. Every motion threatens to turn ${his} shirt buttons into shrapnel.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s tits are so big that they strain even ${his} specially tailored shirt and tunic.`);
+				text.push(`${slave.slaveName}'s tits are so big that they strain even ${his} specially tailored shirt and tunic.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s big tits strain against ${his} tailored shirt and tunic.`);
+				text.push(`${slave.slaveName}'s big tits strain against ${his} tailored shirt and tunic.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`cuts a dashing figure in ${his} tunic.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`cuts a dashing figure in ${his} tunic.`);
 				if (slave.boobs < 300) {
-					r.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
+					text.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
 				}
 			}
 			break;
 		case "a schutzstaffel uniform":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s tits are so immense that ${his} specially tailored shirt and tunic are incapable of being buttoned up.`);
+				text.push(`${slave.slaveName}'s tits are so immense that ${his} specially tailored shirt and tunic are incapable of being buttoned up.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} tunic from closing. Every motion threatens to turn ${his} shirt buttons into shrapnel.`);
+				text.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} tunic from closing. Every motion threatens to turn ${his} shirt buttons into shrapnel.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s tits are so big that they strain even ${his} specially tailored shirt and tunic.`);
+				text.push(`${slave.slaveName}'s tits are so big that they strain even ${his} specially tailored shirt and tunic.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s big tits strain against ${his} tailored shirt and tunic.`);
+				text.push(`${slave.slaveName}'s big tits strain against ${his} tailored shirt and tunic.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`cuts a dashing figure in ${his} tunic.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`cuts a dashing figure in ${his} tunic.`);
 				if (slave.boobs < 300) {
-					r.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
+					text.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
 				}
 			}
 			break;
 		case "a slutty schutzstaffel uniform":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s tits are so immense that ${his} specially tailored shirt and tunic are incapable of being buttoned up.`);
+				text.push(`${slave.slaveName}'s tits are so immense that ${his} specially tailored shirt and tunic are incapable of being buttoned up.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} tunic from closing. Every motion threatens to turn ${his} shirt buttons into shrapnel.`);
+				text.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} tunic from closing. Every motion threatens to turn ${his} shirt buttons into shrapnel.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s tits are so big that they strain even ${his} specially tailored shirt and tunic.`);
+				text.push(`${slave.slaveName}'s tits are so big that they strain even ${his} specially tailored shirt and tunic.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s big tits strain against ${his} tailored shirt and tunic.`);
+				text.push(`${slave.slaveName}'s big tits strain against ${his} tailored shirt and tunic.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`cuts a dashing figure in ${his} tunic.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`cuts a dashing figure in ${his} tunic.`);
 				if (slave.boobs < 300) {
-					r.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
+					text.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
 				}
 			}
 			break;
 		case "a long qipao":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s tits are so immense that ${his} dress is on the verge of bursting open.`);
+				text.push(`${slave.slaveName}'s tits are so immense that ${his} dress is on the verge of bursting open.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}'s tits are so huge that ${his} dress is on the verge of bursting open.`);
+				text.push(`${slave.slaveName}'s tits are so huge that ${his} dress is on the verge of bursting open.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s tits are so big that they strain even ${his} dress greatly.`);
+				text.push(`${slave.slaveName}'s tits are so big that they strain even ${his} dress greatly.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s big tits strain against ${his} dress.`);
+				text.push(`${slave.slaveName}'s big tits strain against ${his} dress.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`cuts a dashing figure in ${his} dress.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`cuts a dashing figure in ${his} dress.`);
 				if (slave.boobs < 300) {
-					r.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
+					text.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
 				}
 			}
 			break;
 		case "battlearmor":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s tits are so immense that ${his} armor is on the verge of bursting open.`);
+				text.push(`${slave.slaveName}'s tits are so immense that ${his} armor is on the verge of bursting open.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}'s tits are so huge that ${his} armor is on the verge of bursting open.`);
+				text.push(`${slave.slaveName}'s tits are so huge that ${his} armor is on the verge of bursting open.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s tits are so big that they armor even ${his} dress greatly.`);
+				text.push(`${slave.slaveName}'s tits are so big that they armor even ${his} dress greatly.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s big tits strain against ${his} armor.`);
+				text.push(`${slave.slaveName}'s big tits strain against ${his} armor.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`cuts a dashing figure in ${his} armor.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`cuts a dashing figure in ${his} armor.`);
 				if (slave.boobs < 300) {
-					r.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
+					text.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
 				}
 			}
 			break;
 		case "Imperial Plate":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s massive tits create almost comical balloons at the front of ${his} ultra-heavy armor, undeniably gargantuan even underneath the tank-like armor.`);
+				text.push(`${slave.slaveName}'s massive tits create almost comical balloons at the front of ${his} ultra-heavy armor, undeniably gargantuan even underneath the tank-like armor.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}'s huge breasts each require an individual plate on ${his} ultra-heavy Imperial armor.`);
+				text.push(`${slave.slaveName}'s huge breasts each require an individual plate on ${his} ultra-heavy Imperial armor.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s fat boobs clearly swell against the front of ${his} ultra-heavy armor.`);
+				text.push(`${slave.slaveName}'s fat boobs clearly swell against the front of ${his} ultra-heavy armor.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s significant breasts create a noticeable swell at the front of ${his} ultra-heavy armor.`);
+				text.push(`${slave.slaveName}'s significant breasts create a noticeable swell at the front of ${his} ultra-heavy armor.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`'s chest appears perfectly flat beneath ${his} ultra-heavy Imperial armor.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`'s chest appears perfectly flat beneath ${his} ultra-heavy Imperial armor.`);
 			}
 			break;
 		case "a mounty outfit":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s tits are so immense that ${his} specially tailored shirt and tunic are incapable of being buttoned up.`);
+				text.push(`${slave.slaveName}'s tits are so immense that ${his} specially tailored shirt and tunic are incapable of being buttoned up.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} tunic from closing. Every motion threatens to turn ${his} shirt buttons into shrapnel.`);
+				text.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} tunic from closing. Every motion threatens to turn ${his} shirt buttons into shrapnel.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s tits are so big that they strain even ${his} specially tailored shirt and tunic.`);
+				text.push(`${slave.slaveName}'s tits are so big that they strain even ${his} specially tailored shirt and tunic.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s big tits strain against ${his} tailored shirt and tunic.`);
+				text.push(`${slave.slaveName}'s big tits strain against ${his} tailored shirt and tunic.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`cuts a dashing figure in ${his} tunic.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`cuts a dashing figure in ${his} tunic.`);
 				if (slave.boobs < 300) {
-					r.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
+					text.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
 				}
 			}
 			break;
 		case "a dirndl":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s tits are so immense that ${his} dress are incapable of being laced up.`);
+				text.push(`${slave.slaveName}'s tits are so immense that ${his} dress are incapable of being laced up.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} dress from being laced up.`);
+				text.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} dress from being laced up.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s tits are so big that they strain ${his} dress.`);
+				text.push(`${slave.slaveName}'s tits are so big that they strain ${his} dress.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s big tits strain against ${his} dress.`);
+				text.push(`${slave.slaveName}'s big tits strain against ${his} dress.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`cuts a dashing figure in ${his} dress.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`cuts a dashing figure in ${his} dress.`);
 				if (slave.boobs < 300) {
-					r.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
+					text.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
 				}
 			}
 			break;
 		case "lederhosen":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s tits are so immense that ${his} specially tailored shirt and tunic are incapable of being buttoned up.`);
+				text.push(`${slave.slaveName}'s tits are so immense that ${his} specially tailored shirt and tunic are incapable of being buttoned up.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} tunic from closing. Every motion threatens to turn ${his} shirt buttons into shrapnel.`);
+				text.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} tunic from closing. Every motion threatens to turn ${his} shirt buttons into shrapnel.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s tits are so big that they strain even ${his} specially tailored shirt and tunic.`);
+				text.push(`${slave.slaveName}'s tits are so big that they strain even ${his} specially tailored shirt and tunic.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s big tits strain against ${his} tailored shirt and tunic.`);
+				text.push(`${slave.slaveName}'s big tits strain against ${his} tailored shirt and tunic.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`cuts a dashing figure in ${his} tunic.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`cuts a dashing figure in ${his} tunic.`);
 				if (slave.boobs < 300) {
-					r.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
+					text.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
 				}
 			}
 			break;
 		case "a biyelgee costume":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s tits are so immense that ${his} dress are incapable of being buttoned up.`);
+				text.push(`${slave.slaveName}'s tits are so immense that ${his} dress are incapable of being buttoned up.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} dress from being buttoned up.`);
+				text.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} dress from being buttoned up.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s tits are so big that they strain ${his} dress.`);
+				text.push(`${slave.slaveName}'s tits are so big that they strain ${his} dress.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s big tits strain against ${his} dress.`);
+				text.push(`${slave.slaveName}'s big tits strain against ${his} dress.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`cuts a dashing figure in ${his} dress.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`cuts a dashing figure in ${his} dress.`);
 				if (slave.boobs < 300) {
-					r.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
+					text.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
 				}
 			}
 			break;
 		case "a red army uniform":
 		case "a police uniform":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s tits are so immense that ${his} specially tailored shirt and tunic are incapable of being buttoned up.`);
+				text.push(`${slave.slaveName}'s tits are so immense that ${his} specially tailored shirt and tunic are incapable of being buttoned up.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} tunic from closing. Every motion threatens to turn ${his} shirt buttons into shrapnel.`);
+				text.push(`${slave.slaveName}'s tits are so huge that they prevent ${his} tunic from closing. Every motion threatens to turn ${his} shirt buttons into shrapnel.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s tits are so big that they strain even ${his} specially tailored shirt and tunic.`);
+				text.push(`${slave.slaveName}'s tits are so big that they strain even ${his} specially tailored shirt and tunic.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s big tits strain against ${his} tailored shirt and tunic.`);
+				text.push(`${slave.slaveName}'s big tits strain against ${his} tailored shirt and tunic.`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`cuts a dashing figure in ${his} tunic.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`cuts a dashing figure in ${his} tunic.`);
 				if (slave.boobs < 300) {
-					r.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
+					text.push(`${His} ${either("androgynous", "flat")} breasts are barely there.`);
 				}
 			}
 			break;
 		case "a nice nurse outfit":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`immense tits are too big for ${his} scrub top, it rests uselessly atop ${his} bust.`);
+				text.push(`immense tits are too big for ${his} scrub top, it rests uselessly atop ${his} bust.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`massive tits strain against ${his} scrub top, it only manages to cover ${his} nipples.`);
+				text.push(`massive tits strain against ${his} scrub top, it only manages to cover ${his} nipples.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`massive tits strain against ${his} scrub top, filling it out completely despite its utilitarian cut.`);
+				text.push(`massive tits strain against ${his} scrub top, filling it out completely despite its utilitarian cut.`);
 			} else if (slave.boobs > 800) {
-				r.push(`sizable tits nicely fill out ${his} scrub top, despite its utilitarian cut.`);
+				text.push(`sizable tits nicely fill out ${his} scrub top, despite its utilitarian cut.`);
 			} else if (slave.boobs < 300) {
-				r.push(`scrub top tightly hugs ${his} flat chest.`);
+				text.push(`scrub top tightly hugs ${his} flat chest.`);
 			} else {
-				r.push(`tits are hidden beneath ${his} scrub top.`);
+				text.push(`tits are hidden beneath ${his} scrub top.`);
 			}
 			break;
 		case "a mini dress":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`mini dress is pulled down to allow ${his} immense breasts to hang free.`);
+				text.push(`mini dress is pulled down to allow ${his} immense breasts to hang free.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`massive breasts stretch ${his} custom tailored dress to its absolute limit.`);
+				text.push(`massive breasts stretch ${his} custom tailored dress to its absolute limit.`);
 			} else if (slave.boobs > 800) {
-				r.push(`big breasts stretch ${his} dress taut, leaving nothing to the imagination.`);
+				text.push(`big breasts stretch ${his} dress taut, leaving nothing to the imagination.`);
 			} else if (slave.boobs < 300) {
-				r.push(`dress tightly hugs ${his} flat chest, prominently displaying ${his} ${slave.nipples} nipples though the fabric.`);
+				text.push(`dress tightly hugs ${his} flat chest, prominently displaying ${his} ${slave.nipples} nipples though the fabric.`);
 			} else {
-				r.push(`chest stretches taut against ${his} dress, leaving little to the imagination.`);
+				text.push(`chest stretches taut against ${his} dress, leaving little to the imagination.`);
 			}
 			break;
 		case "an apron":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`breasts are so immense that ${his} apron can barely contain them, and ${he} has to be careful not to expose one or both of ${his} ${slave.nipples} nipples as ${he} moves.`);
+				text.push(`breasts are so immense that ${his} apron can barely contain them, and ${he} has to be careful not to expose one or both of ${his} ${slave.nipples} nipples as ${he} moves.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`massive breasts fill out ${his} strained apron, occasionally leaving the sides of ${his} ${slave.nipples} nipples bare.`);
+				text.push(`massive breasts fill out ${his} strained apron, occasionally leaving the sides of ${his} ${slave.nipples} nipples bare.`);
 			} else if (slave.boobs > 800) {
-				r.push(`big breasts fill out ${his} stretched apron, only just managing to fully cover ${his} ${slave.nipples} nipples.`);
+				text.push(`big breasts fill out ${his} stretched apron, only just managing to fully cover ${his} ${slave.nipples} nipples.`);
 			} else if (slave.boobs < 300) {
-				r.push(`apron lies flatly against ${his} small chest and ${slave.nipples} nipples.`);
+				text.push(`apron lies flatly against ${his} small chest and ${slave.nipples} nipples.`);
 			} else {
-				r.push(`breasts fill out ${his} apron, which is strategically worn to cover ${his} ${slave.nipples} nipples.`);
+				text.push(`breasts fill out ${his} apron, which is strategically worn to cover ${his} ${slave.nipples} nipples.`);
 			}
 			break;
 		case "overalls":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`breasts are so immense that ${his} overalls can barely contain them, and ${he} has to be careful not to expose one or both of ${his} ${slave.nipples} nipples as ${he} moves.`);
+				text.push(`breasts are so immense that ${his} overalls can barely contain them, and ${he} has to be careful not to expose one or both of ${his} ${slave.nipples} nipples as ${he} moves.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`giant breasts peek out from the sides of ${his} strained overalls, often exposing the sides of ${his} ${slave.nipples} nipples.`);
+				text.push(`giant breasts peek out from the sides of ${his} strained overalls, often exposing the sides of ${his} ${slave.nipples} nipples.`);
 			} else if (slave.boobs > 800) {
-				r.push(`huge breasts fill out ${his} stretched overalls, only just managing to fully cover ${his} ${slave.nipples} nipples.`);
+				text.push(`huge breasts fill out ${his} stretched overalls, only just managing to fully cover ${his} ${slave.nipples} nipples.`);
 			} else if (slave.boobs < 300) {
-				r.push(`overalls lie flatly against ${his} small chest and ${slave.nipples} nipples.`);
+				text.push(`overalls lie flatly against ${his} small chest and ${slave.nipples} nipples.`);
 			} else {
-				r.push(`overalls are filled out by ${his} breasts, offering tantalizing views of their sides.`);
+				text.push(`overalls are filled out by ${his} breasts, offering tantalizing views of their sides.`);
 			}
 			break;
 		case "a leotard":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`tits are so big that even ${his} specially tailored leotard cannot really support them.`);
+				text.push(`tits are so big that even ${his} specially tailored leotard cannot really support them.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`big tits stretch the spandex of ${his} leotard taut across their width.`);
+				text.push(`big tits stretch the spandex of ${his} leotard taut across their width.`);
 			} else if (slave.boobs < 300) {
-				r.push(`leotard tightly hugs ${his} flat chest, prominently displaying ${his} ${slave.nipples} nipples though the spandex.`);
+				text.push(`leotard tightly hugs ${his} flat chest, prominently displaying ${his} ${slave.nipples} nipples though the spandex.`);
 			} else {
-				r.push(`chest is flattered by ${his} leotard.`);
+				text.push(`chest is flattered by ${his} leotard.`);
 			}
 			break;
 		case "a monokini":
-			r.push(`The shoulder straps of ${slave.slaveName}'s monokini cross over in the center of ${his} chest, leaving the rest of ${his}`);
+			text.push(`The shoulder straps of ${slave.slaveName}'s monokini cross over in the center of ${his} chest, leaving the rest of ${his}`);
 			if (slave.boobs > 12000) {
-				r.push(`gigantic breasts totally bare.`);
+				text.push(`gigantic breasts totally bare.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`large breasts totally bare.`);
+				text.push(`large breasts totally bare.`);
 			} else if (slave.boobs < 300) {
-				r.push(`flat chest totally bare.`);
+				text.push(`flat chest totally bare.`);
 			} else {
-				r.push(`breasts totally bare.`);
+				text.push(`breasts totally bare.`);
 			}
 			break;
 		case "a cybersuit":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`gigantic breasts stretch out the bodysuit so tightly that ${his} nipples are clearly visible.`);
+				text.push(`gigantic breasts stretch out the bodysuit so tightly that ${his} nipples are clearly visible.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`large breasts stretch out the bodysuit so tightly that ${his} nipples are nearly visible.`);
+				text.push(`large breasts stretch out the bodysuit so tightly that ${his} nipples are nearly visible.`);
 			} else if (slave.boobs < 300) {
-				r.push(`flat chest is hugged tightly by the bodysuit, ${his} nipples pushing against the material.`);
+				text.push(`flat chest is hugged tightly by the bodysuit, ${his} nipples pushing against the material.`);
 			} else {
-				r.push(`breasts are hugged tightly by the bodysuit, ${his} nipples pushing against the material.`);
+				text.push(`breasts are hugged tightly by the bodysuit, ${his} nipples pushing against the material.`);
 			}
 			break;
 		case "a tight Imperial bodysuit":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`gigantic breasts stretch out the bodysuit so tightly that ${his} nipples are clearly visible.`);
+				text.push(`gigantic breasts stretch out the bodysuit so tightly that ${his} nipples are clearly visible.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`large breasts stretch out the bodysuit so tightly that ${his} nipples are nearly visible.`);
+				text.push(`large breasts stretch out the bodysuit so tightly that ${his} nipples are nearly visible.`);
 			} else if (slave.boobs < 300) {
-				r.push(`flat chest is hugged tightly by the bodysuit, ${his} nipples pushing against the material.`);
+				text.push(`flat chest is hugged tightly by the bodysuit, ${his} nipples pushing against the material.`);
 			} else {
-				r.push(`breasts are hugged tightly by the bodysuit, ${his} nipples pushing against the material.`);
+				text.push(`breasts are hugged tightly by the bodysuit, ${his} nipples pushing against the material.`);
 			}
 			break;
 		case "a bunny outfit":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`tits are so immense that ${his} teddy can't contain them; it's pulled down to allow them to hang free.`);
+				text.push(`tits are so immense that ${his} teddy can't contain them; it's pulled down to allow them to hang free.`);
 			} else if (slave.boobs > 6000) {
-				r.push(`tits are so huge that ${his} teddy conceals special stays to keep them from popping out at the slightest movement. Breast flesh massively overflows ${his} top.`);
+				text.push(`tits are so huge that ${his} teddy conceals special stays to keep them from popping out at the slightest movement. Breast flesh massively overflows ${his} top.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`tits are so big that ${his} teddy conceals special stays to keep them from popping out at the slightest movement.`);
+				text.push(`tits are so big that ${his} teddy conceals special stays to keep them from popping out at the slightest movement.`);
 			} else if (slave.boobs > 800) {
-				r.push(`big tits are perpetually on the verge of spilling out of ${his} top.`);
+				text.push(`big tits are perpetually on the verge of spilling out of ${his} top.`);
 			} else if (slave.boobs < 300) {
-				r.push(`teddy tightly clings to ${his} flat chest somehow making ${him} look even flatter.`);
+				text.push(`teddy tightly clings to ${his} flat chest somehow making ${him} look even flatter.`);
 			} else {
-				r.push(`teddy conceals cunning stays designed to make ${his} bosom look considerably bigger than it actually is.`);
+				text.push(`teddy conceals cunning stays designed to make ${his} bosom look considerably bigger than it actually is.`);
 			}
 			break;
 		case "attractive lingerie for a pregnant woman":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`top has been retailored to fit ${his} enormous bust. The ample breast flesh almost completely consumes ${his} silken lingerie. ${His} silken vest is barely visible behind ${his} massive tits.`);
+				text.push(`top has been retailored to fit ${his} enormous bust. The ample breast flesh almost completely consumes ${his} silken lingerie. ${His} silken vest is barely visible behind ${his} massive tits.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`gigantic tits dwarf ${his} tiny top. It barely manages to cover ${his} nipples. ${His} silken vest is parted to either side of ${his} breasts.`);
+				text.push(`gigantic tits dwarf ${his} tiny top. It barely manages to cover ${his} nipples. ${His} silken vest is parted to either side of ${his} breasts.`);
 			} else if (slave.boobs > 800) {
-				r.push(`large breasts spill out from above and below ${his} tight top.`);
+				text.push(`large breasts spill out from above and below ${his} tight top.`);
 			} else if (slave.boobs < 300) {
-				r.push(`top tightly clings to ${his} flat chest.`);
+				text.push(`top tightly clings to ${his} flat chest.`);
 			} else {
-				r.push(`top tightly clings to ${his} chest.`);
+				text.push(`top tightly clings to ${his} chest.`);
 			}
 			break;
 		case "a maternity dress":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 12000) {
-				r.push(`low cut dress can't contain ${his} enormous breasts, so ${he} keeps it pulled up just below ${his} bust.`);
+				text.push(`low cut dress can't contain ${his} enormous breasts, so ${he} keeps it pulled up just below ${his} bust.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`low cut dress can barely conceal ${his} giant breasts. They bulge over the top and create a deep valley of cleavage.`);
+				text.push(`low cut dress can barely conceal ${his} giant breasts. They bulge over the top and create a deep valley of cleavage.`);
 			} else if (slave.boobs > 1000) {
-				r.push(`dress is low cut and reveals a large amount of cleavage.`);
+				text.push(`dress is low cut and reveals a large amount of cleavage.`);
 			} else if (slave.boobs < 300) {
-				r.push(`dress is low cut, tightly hugs ${his} flat chest and ends just above ${his} nipples.`);
+				text.push(`dress is low cut, tightly hugs ${his} flat chest and ends just above ${his} nipples.`);
 			} else {
-				r.push(`dress is low cut and ends just above ${his} nipples.`);
+				text.push(`dress is low cut and ends just above ${his} nipples.`);
 			}
 			break;
 		case "stretch pants and a crop-top":
 			if (slave.boobs > 20000) {
-				r.push(`${slave.slaveName}`);
-				r.push(`is wearing a massively oversized custom crop-top designed to handle ${his} monumental tits. Even so, it's stretched taut just struggling to cover ${his} nipples, causing acres of breast flesh to spill out from under and above it.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`is wearing a massively oversized custom crop-top designed to handle ${his} monumental tits. Even so, it's stretched taut just struggling to cover ${his} nipples, causing acres of breast flesh to spill out from under and above it.`);
 			} else if (slave.boobs > 10000) {
-				r.push(`${slave.slaveName}'s oversized crop-top struggles to contain even half of ${his} immense breasts leaving plenty of underboob visible alongside with ${his} cleavage. Every motion risks a nipple popping free.`);
+				text.push(`${slave.slaveName}'s oversized crop-top struggles to contain even half of ${his} immense breasts leaving plenty of underboob visible alongside with ${his} cleavage. Every motion risks a nipple popping free.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`${slave.slaveName}'s oversized crop-top struggles to contain ${his} enormous breasts leaving plenty of underboob visible alongside with ${his} cleavage.`);
+				text.push(`${slave.slaveName}'s oversized crop-top struggles to contain ${his} enormous breasts leaving plenty of underboob visible alongside with ${his} cleavage.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`${slave.slaveName}`);
-				r.push(`has swapped up to the largest crop-top available. Even so, it barely covers them and creates plenty of cleavage.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`has swapped up to the largest crop-top available. Even so, it barely covers them and creates plenty of cleavage.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s crop-top struggles to contain ${his} huge breasts leaving plenty of underboob visible alongside with ${his} cleavage.`);
+				text.push(`${slave.slaveName}'s crop-top struggles to contain ${his} huge breasts leaving plenty of underboob visible alongside with ${his} cleavage.`);
 			} else if (slave.boobs > 800) {
-				r.push(`${slave.slaveName}'s crop-top tightly hugs ${his} big breasts creating plenty of cleavage.`);
+				text.push(`${slave.slaveName}'s crop-top tightly hugs ${his} big breasts creating plenty of cleavage.`);
 			} else if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}'s crop-top tightly clings to ${his} flat chest.`);
+				text.push(`${slave.slaveName}'s crop-top tightly clings to ${his} flat chest.`);
 			} else {
-				r.push(`${slave.slaveName}'s crop-top tightly hugs ${his} breasts.`);
+				text.push(`${slave.slaveName}'s crop-top tightly hugs ${his} breasts.`);
 			}
 			switch (slave.sexualFlaw) {
 				case "neglectful":
-					r.push(`"All For You"`);
+					text.push(`"All For You"`);
 					break;
 				case "cum addict":
-					r.push(`"Cum 'ere Sexy"`);
+					text.push(`"Cum 'ere Sexy"`);
 					break;
 				case "anal addict":
-					r.push(`"Reach Around Back"`);
+					text.push(`"Reach Around Back"`);
 					break;
 				case "attention whore":
-					r.push(`"Will Flash For Attention"`);
+					text.push(`"Will Flash For Attention"`);
 					break;
 				case "breast growth":
-					r.push(`"Could Be Bigger"`);
+					text.push(`"Could Be Bigger"`);
 					break;
 				case "abusive":
-					r.push(`"Fondlers May Be Slapped"`);
+					text.push(`"Fondlers May Be Slapped"`);
 					break;
 				case "malicious":
-					r.push(`"Careful, I Bite"`);
+					text.push(`"Careful, I Bite"`);
 					break;
 				case "self hating":
-					r.push(`"Rough 'em Up"`);
+					text.push(`"Rough 'em Up"`);
 					break;
 				case "breeder":
-					r.push(`"Drink Deep"`);
+					text.push(`"Drink Deep"`);
 					break;
 				default:
 					if (slave.fetishKnown === 1) {
 						switch (slave.fetish) {
 							case "submissive":
-								r.push(`"Take Me"`);
+								text.push(`"Take Me"`);
 								break;
 							case "cumslut":
-								r.push(`"Splash Zone"`);
+								text.push(`"Splash Zone"`);
 								break;
 							case "humiliation":
-								r.push(`"Flasher"`);
+								text.push(`"Flasher"`);
 								break;
 							case "buttslut":
-								r.push(`"Reach Around"`);
+								text.push(`"Reach Around"`);
 								break;
 							case "boobs":
-								r.push(`"Your Hands Here"`);
+								text.push(`"Your Hands Here"`);
 								break;
 							case "sadist":
-								r.push(`"Taste the Pain"`);
+								text.push(`"Taste the Pain"`);
 								break;
 							case "masochist":
-								r.push(`"Be Rough"`);
+								text.push(`"Be Rough"`);
 								break;
 							case "dom":
-								r.push(`"Queen Bitch"`);
+								text.push(`"Queen Bitch"`);
 								break;
 							case "pregnancy":
-								r.push(`"Milk Me"`);
+								text.push(`"Milk Me"`);
 								break;
 							case "mindbroken":
-								r.push(`"Free Slut"`);
+								text.push(`"Free Slut"`);
 								break;
 							default:
-								r.push(App.Desc.inscrip(slave));
+								text.push(App.Desc.inscrip(slave));
 						}
 					} else {
-						r.push(App.Desc.inscrip(slave));
+						text.push(App.Desc.inscrip(slave));
 					}
 			}
-			r.push(`is written across ${his} chest in large, vibrant letters.`);
+			text.push(`is written across ${his} chest in large, vibrant letters.`);
 			break;
 		case "harem gauze":
-			r.push(`${slave.slaveName}'s harem girl outfit`);
+			text.push(`${slave.slaveName}'s harem girl outfit`);
 			if (slave.boobs > 12000) {
-				r.push(`lets ${his} inhuman breasts rest beneath`);
+				text.push(`lets ${his} inhuman breasts rest beneath`);
 			} else if (slave.boobs > 800) {
-				r.push(`lets ${his} breasts swing free beneath`);
+				text.push(`lets ${his} breasts swing free beneath`);
 			} else if (slave.boobs < 300) {
-				r.push(`gently covers ${his} flat chest with`);
+				text.push(`gently covers ${his} flat chest with`);
 			} else {
-				r.push(`only covers ${his} breasts with`);
+				text.push(`only covers ${his} breasts with`);
 			}
-			r.push(`a thin film of gauze.`);
+			text.push(`a thin film of gauze.`);
 			break;
 		case "a slutty nurse outfit":
-			r.push(`${slave.slaveName}'s jacket`);
+			text.push(`${slave.slaveName}'s jacket`);
 			if (slave.boobs > 4000) {
-				r.push(`closes beneath ${his} tits, leaving almost everything visible.`);
+				text.push(`closes beneath ${his} tits, leaving almost everything visible.`);
 			} else if (slave.boobs > 800) {
-				r.push(`pushes ${his} tits together to form some great cleavage.`);
+				text.push(`pushes ${his} tits together to form some great cleavage.`);
 			} else if (slave.boobs < 300) {
-				r.push(`tightly hugs ${his} flat chest, since it has no breasts to form cleavage with.`);
+				text.push(`tightly hugs ${his} flat chest, since it has no breasts to form cleavage with.`);
 			} else {
-				r.push(`pushes ${his} tits together to form as much cleavage as possible.`);
+				text.push(`pushes ${his} tits together to form as much cleavage as possible.`);
 			}
 			break;
 		case "a schoolgirl outfit":
-			r.push(`${slave.slaveName}'s`);
+			text.push(`${slave.slaveName}'s`);
 			if (slave.boobs > 4000) {
-				r.push(`breasts are too big for ${his} blouse, so ${he}'s tied it under them; they're so huge that it's buried under them.`);
+				text.push(`breasts are too big for ${his} blouse, so ${he}'s tied it under them; they're so huge that it's buried under them.`);
 			} else if (slave.boobs > 800) {
-				r.push(`breasts are too big for ${his} blouse, so ${he}'s tied it under them and left them totally bare.`);
+				text.push(`breasts are too big for ${his} blouse, so ${he}'s tied it under them and left them totally bare.`);
 			} else if (slave.boobs < 300) {
-				r.push(`blouse tightly hugs ${his} flat chest.`);
+				text.push(`blouse tightly hugs ${his} flat chest.`);
 			} else {
-				r.push(`blouse only barely covers ${his} breasts.`);
+				text.push(`blouse only barely covers ${his} breasts.`);
 			}
 			break;
 		case "a kimono":
-			r.push(`${slave.slaveName}'s kimono`);
+			text.push(`${slave.slaveName}'s kimono`);
 			if (slave.boobs > 12000) {
-				r.push(`can't cover ${his} breasts, so ${he} leaves it hanging loose; allowing them to hang freely.`);
+				text.push(`can't cover ${his} breasts, so ${he} leaves it hanging loose; allowing them to hang freely.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`barely covers ${his} breasts. It reveals most of ${his} chest, just covering the outer edges of ${his} breasts and their nipples.`);
+				text.push(`barely covers ${his} breasts. It reveals most of ${his} chest, just covering the outer edges of ${his} breasts and their nipples.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`demurely covers ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`demurely covers ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`demurely rests over ${his} flat chest.`);
+				text.push(`demurely rests over ${his} flat chest.`);
 			} else {
-				r.push(`demurely covers ${his} breasts.`);
+				text.push(`demurely covers ${his} breasts.`);
 			}
 			break;
 		case "battledress":
 			if (slave.boobs > 12000) {
-				r.push(`${slave.slaveName}'s immense breasts are barely supported by a specially engineered, space-age sports bra.`);
+				text.push(`${slave.slaveName}'s immense breasts are barely supported by a specially engineered, space-age sports bra.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`${slave.slaveName}'s huge breasts are supported by a specially engineered, space-age sports bra under ${his} tank top.`);
+				text.push(`${slave.slaveName}'s huge breasts are supported by a specially engineered, space-age sports bra under ${his} tank top.`);
 			} else if (slave.boobs < 300) {
-				r.push(`${slave.slaveName}`);
-				r.push(`is flat as an ironing board; ${he} wears ${his} tank top without a bra underneath.`);
+				text.push(`${slave.slaveName}`);
+				text.push(`is flat as an ironing board; ${he} wears ${his} tank top without a bra underneath.`);
 			} else {
-				r.push(`${slave.slaveName}'s breasts are supported by a sports bra under ${his} tank top.`);
+				text.push(`${slave.slaveName}'s breasts are supported by a sports bra under ${his} tank top.`);
 			}
 			break;
 		case "slutty jewelry":
-			r.push(`${slave.slaveName}'s bangles include a`);
+			text.push(`${slave.slaveName}'s bangles include a`);
 			if (slave.boobs > 2000) {
-				r.push(`thin chain that runs under ${his} breasts, disappearing entirely.`);
+				text.push(`thin chain that runs under ${his} breasts, disappearing entirely.`);
 			} else if (slave.boobs > 800) {
-				r.push(`thin chain that runs under ${his} breasts, appearing and disappearing enticingly when ${he} moves.`);
+				text.push(`thin chain that runs under ${his} breasts, appearing and disappearing enticingly when ${he} moves.`);
 			} else if (slave.boobs < 300) {
-				r.push(`thin chain that runs across ${his} flat chest.`);
+				text.push(`thin chain that runs across ${his} flat chest.`);
 			} else {
-				r.push(`light chain that loops under ${his} breasts.`);
+				text.push(`light chain that loops under ${his} breasts.`);
 			}
 			break;
 		case "a burqa":
-			r.push(`${slave.slaveName}'s burqa`);
+			text.push(`${slave.slaveName}'s burqa`);
 			if (slave.boobs > 12000) {
-				r.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
+				text.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`entirely conceals ${his} flat chest.`);
+				text.push(`entirely conceals ${his} flat chest.`);
 			} else {
-				r.push(`entirely conceals ${his} breasts.`);
+				text.push(`entirely conceals ${his} breasts.`);
 			}
 			break;
 		case "a tube top and thong":
 		case "a tube top":
 		case "leather pants and a tube top":
-			r.push(`${slave.slaveName}'s tube top`);
+			text.push(`${slave.slaveName}'s tube top`);
 			if (slave.boobs > 12000) {
-				r.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
+				text.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`entirely conceals ${his} flat chest.`);
+				text.push(`entirely conceals ${his} flat chest.`);
 			} else {
-				r.push(`entirely conceals ${his} breasts.`);
+				text.push(`entirely conceals ${his} breasts.`);
 			}
 			break;
 		case "a button-up shirt and panties":
@@ -1663,32 +1742,32 @@ App.Interact.fDance = function(slave) {
 		case "a t-shirt and panties":
 		case "sport shorts and a t-shirt":
 		case "a t-shirt and jeans":
-			r.push(`${slave.slaveName}'s shirt`);
+			text.push(`${slave.slaveName}'s shirt`);
 			if (slave.boobs > 12000) {
-				r.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
+				text.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`entirely conceals ${his} flat chest.`);
+				text.push(`entirely conceals ${his} flat chest.`);
 			} else {
-				r.push(`entirely conceals ${his} breasts.`);
+				text.push(`entirely conceals ${his} breasts.`);
 			}
 			break;
 		case "an oversized t-shirt and boyshorts":
 		case "an oversized t-shirt":
-			r.push(`${slave.slaveName}'s over-sized shirt`);
+			text.push(`${slave.slaveName}'s over-sized shirt`);
 			if (slave.boobs > 12000) {
-				r.push(`entirely conceals ${his} breasts, the fabric easily stretches to cover ${his} expansive mounds of flesh.`);
+				text.push(`entirely conceals ${his} breasts, the fabric easily stretches to cover ${his} expansive mounds of flesh.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`entirely conceals ${his} breasts, the fabric easily covers ${his} absurdly-sized breasts.`);
+				text.push(`entirely conceals ${his} breasts, the fabric easily covers ${his} absurdly-sized breasts.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`entirely conceals ${his} breasts, though it cannot conceal their size.`);
+				text.push(`entirely conceals ${his} breasts, though it cannot conceal their size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`entirely conceals ${his} flat chest.`);
+				text.push(`entirely conceals ${his} flat chest.`);
 			} else {
-				r.push(`entirely conceals ${his} breasts.`);
+				text.push(`entirely conceals ${his} breasts.`);
 			}
 			break;
 		case "a thong":
@@ -1699,63 +1778,63 @@ App.Interact.fDance = function(slave) {
 		case "panties":
 		case "jeans":
 		case "sport shorts":
-			r.push(`${slave.slaveName}'s breasts`);
+			text.push(`${slave.slaveName}'s breasts`);
 			if (slave.boobs > 12000) {
-				r.push(`are completely bare.`);
+				text.push(`are completely bare.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`are completely bare.`);
+				text.push(`are completely bare.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`are completely bare.`);
+				text.push(`are completely bare.`);
 			} else if (slave.boobs < 300) {
-				r.push(`are completely bare.`);
+				text.push(`are completely bare.`);
 			} else {
-				r.push(`are completely bare.`);
+				text.push(`are completely bare.`);
 			}
 			break;
 		case "a tank-top":
 		case "a tank-top and panties":
-			r.push(`${slave.slaveName}'s tank-top`);
+			text.push(`${slave.slaveName}'s tank-top`);
 			if (slave.boobs > 12000) {
-				r.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
+				text.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`entirely conceals ${his} flat chest.`);
+				text.push(`entirely conceals ${his} flat chest.`);
 			} else {
-				r.push(`entirely conceals ${his} breasts.`);
+				text.push(`entirely conceals ${his} breasts.`);
 			}
 			break;
 		case "a sweater":
 		case "a sweater and cutoffs":
 		case "a sweater and panties":
-			r.push(`${slave.slaveName}'s sweater`);
+			text.push(`${slave.slaveName}'s sweater`);
 			if (slave.boobs > 12000) {
-				r.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
+				text.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`entirely conceals ${his} flat chest.`);
+				text.push(`entirely conceals ${his} flat chest.`);
 			} else {
-				r.push(`entirely conceals ${his} breasts.`);
+				text.push(`entirely conceals ${his} breasts.`);
 			}
 			break;
 		case "leather pants and pasties":
 		case "panties and pasties":
-			r.push(`${slave.slaveName}'s breasts`);
+			text.push(`${slave.slaveName}'s breasts`);
 			if (slave.boobs > 12000) {
-				r.push(`are completely bare, except for the pasties covering ${his} nipples.`);
+				text.push(`are completely bare, except for the pasties covering ${his} nipples.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`are completely bare, except for the pasties covering ${his} nipples.`);
+				text.push(`are completely bare, except for the pasties covering ${his} nipples.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`are completely bare, except for the pasties covering ${his} nipples.`);
+				text.push(`are completely bare, except for the pasties covering ${his} nipples.`);
 			} else if (slave.boobs < 300) {
-				r.push(`are completely bare, except for the pasties covering ${his} nipples.`);
+				text.push(`are completely bare, except for the pasties covering ${his} nipples.`);
 			} else {
-				r.push(`are completely bare, except for the pasties covering ${his} nipples.`);
+				text.push(`are completely bare, except for the pasties covering ${his} nipples.`);
 			}
 			break;
 		case "a bra":
@@ -1763,197 +1842,217 @@ App.Interact.fDance = function(slave) {
 		case "a sports bra":
 		case "sport shorts and a sports bra":
 		case "striped underwear":
-			r.push(`${slave.slaveName}'s bra`);
+			text.push(`${slave.slaveName}'s bra`);
 			if (slave.boobs > 12000) {
-				r.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
+				text.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`entirely conceals ${his} flat chest.`);
+				text.push(`entirely conceals ${his} flat chest.`);
 			} else {
-				r.push(`entirely conceals ${his} breasts.`);
+				text.push(`entirely conceals ${his} breasts.`);
 			}
 			break;
 		case "a nice pony outfit":
 		case "a slutty pony outfit":
-			r.push(`${slave.slaveName}'s outfit`);
+			text.push(`${slave.slaveName}'s outfit`);
 			if (slave.boobs > 12000) {
-				r.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
+				text.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`entirely conceals ${his} flat chest.`);
+				text.push(`entirely conceals ${his} flat chest.`);
 			} else {
-				r.push(`entirely conceals ${his} breasts.`);
+				text.push(`entirely conceals ${his} breasts.`);
 			}
 			break;
 		case "a one-piece swimsuit":
-			r.push(`${slave.slaveName}'s swimsuit`);
+			text.push(`${slave.slaveName}'s swimsuit`);
 			if (slave.boobs > 12000) {
-				r.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
+				text.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`entirely conceals ${his} flat chest.`);
+				text.push(`entirely conceals ${his} flat chest.`);
 			} else {
-				r.push(`entirely conceals ${his} breasts.`);
+				text.push(`entirely conceals ${his} breasts.`);
 			}
 			break;
 		case "a gothic lolita dress":
 		case "a hanbok":
-			r.push(`${slave.slaveName}'s blouse`);
+			text.push(`${slave.slaveName}'s blouse`);
 			if (slave.boobs > 12000) {
-				r.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
+				text.push(`entirely conceals ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
 			} else if (slave.boobs > 8000) {
-				r.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`entirely conceals ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`entirely conceals ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`entirely conceals ${his} flat chest.`);
+				text.push(`entirely conceals ${his} flat chest.`);
 			} else {
-				r.push(`entirely conceals ${his} breasts.`);
+				text.push(`entirely conceals ${his} breasts.`);
 			}
 			break;
 		case "a hijab and abaya":
 		case "a niqab and abaya":
-			r.push(`${slave.slaveName}'s abaya`);
+			text.push(`${slave.slaveName}'s abaya`);
 			if (slave.boobs > 12000) {
-				r.push(`modestly covers ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
+				text.push(`modestly covers ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`modestly covers ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`modestly covers ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`modestly covers ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`modestly covers ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`modestly rests over ${his} flat chest.`);
+				text.push(`modestly rests over ${his} flat chest.`);
 			} else {
-				r.push(`modestly covers ${his} breasts.`);
+				text.push(`modestly covers ${his} breasts.`);
 			}
 			break;
 		case "a klan robe":
 		case "a slutty klan robe":
-			r.push(`${slave.slaveName}'s robe`);
+			text.push(`${slave.slaveName}'s robe`);
 			if (slave.boobs > 12000) {
-				r.push(`modestly covers ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
+				text.push(`modestly covers ${his} breasts, although the fabric struggles to ensure they are entirely covered.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`modestly covers ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`modestly covers ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`modestly covers ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`modestly covers ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`modestly rests over ${his} flat chest.`);
+				text.push(`modestly rests over ${his} flat chest.`);
 			} else {
-				r.push(`modestly cover ${his} breasts.`);
+				text.push(`modestly cover ${his} breasts.`);
 			}
 			break;
 		case "a hijab and blouse":
-			r.push(`${slave.slaveName}'s two shirts`);
+			text.push(`${slave.slaveName}'s two shirts`);
 			if (slave.boobs > 12000) {
-				r.push(`modestly cover ${his} breasts, although the fabrics struggle to ensure they are entirely covered.`);
+				text.push(`modestly cover ${his} breasts, although the fabrics struggle to ensure they are entirely covered.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`modestly cover ${his} breasts. They have both been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`modestly cover ${his} breasts. They have both been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`modestly cover ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`modestly cover ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`modestly cover ${his} flat chest.`);
+				text.push(`modestly cover ${his} flat chest.`);
 			} else {
-				r.push(`modestly cover ${his} breasts.`);
+				text.push(`modestly cover ${his} breasts.`);
 			}
 			break;
 		case "a burkini":
-			r.push(`${slave.slaveName}'s burkini`);
+			text.push(`${slave.slaveName}'s burkini`);
 			if (slave.boobs > 12000) {
-				r.push(`modestly covers ${his} breasts, although it struggles to ensure they are entirely covered.`);
+				text.push(`modestly covers ${his} breasts, although it struggles to ensure they are entirely covered.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`modestly covers ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
+				text.push(`modestly covers ${his} breasts. It has been let out a great deal in order to cover the entirety of ${his} chest.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`modestly covers ${his} breasts, though it cannot conceal their absurd size.`);
+				text.push(`modestly covers ${his} breasts, though it cannot conceal their absurd size.`);
 			} else if (slave.boobs < 300) {
-				r.push(`modestly covers ${his} flat chest.`);
+				text.push(`modestly covers ${his} flat chest.`);
 			} else {
-				r.push(`modestly covers ${his} breasts.`);
+				text.push(`modestly covers ${his} breasts.`);
 			}
 			break;
 		case "a Santa dress":
-			r.push(`${slave.slaveName}'s red holiday dress is designed with a dangerously low neckline, which`);
+			text.push(`${slave.slaveName}'s red holiday dress is designed with a dangerously low neckline, which`);
 			if (slave.boobs > 12000) {
-				r.push(`${his} colossal breasts spill out of completely unheeded.`);
+				text.push(`${his} colossal breasts spill out of completely unheeded.`);
 			} else if (slave.boobs > 4000) {
-				r.push(`serves only to prop up ${his} massive, otherwise naked breasts.`);
+				text.push(`serves only to prop up ${his} massive, otherwise naked breasts.`);
 			} else if (slave.boobs > 2000) {
-				r.push(`lies at nipple-level on ${his} big breasts, leaving a decent portion of ${his} areolae uncovered.`);
+				text.push(`lies at nipple-level on ${his} big breasts, leaving a decent portion of ${his} areolae uncovered.`);
 			} else if (slave.boobs < 300) {
-				r.push(`hangs lowly on ${his} flat chest, occasionally revealing one of ${his} nipples.`);
+				text.push(`hangs lowly on ${his} flat chest, occasionally revealing one of ${his} nipples.`);
 			} else {
-				r.push(`accentuates ${his} cleavage, especially since it always appears to be slipping down ${his} body.`);
+				text.push(`accentuates ${his} cleavage, especially since it always appears to be slipping down ${his} body.`);
 			}
 			break;
 		default:
 	}
 	*/
-	// End clothing-specific stripping */
+		// End clothing-specific stripping */
+		// }
 
-	r.push(`Once the last piece of clothing has hit the floor you let your little slut dance naked a little while longer while you finish your last report. Once you have gotten enough of ${his} dancing you snap your fingers to call your slave over.`);
-	if (slave.devotion > 80) {
-		r.push(`Your slave hurries to your side and drops to ${his} ${(hasBothLegs(slave)) ? `knees` : `knee`}. ${He} gladly kneels at your feet, looking up at ${his} ${getWrittenTitle(slave)} in adoration.`);
-	} else if (slave.devotion > 20) {
-		r.push(`Your slave hurries to your side and drops to ${his} ${(hasBothLegs(slave)) ? `knees` : `knee`}. ${He} obediently kneels at your feet.`);
-	} else if (slave.devotion < -50) {
-		if (slave.trust < -50) {
-			r.push(`${He} hurries frantically to your side, and drops quivering to the floor at your feet hoping ${he} was quick enough to avoid`);
-			switch (slave.rules.punishment) {
-				case "confinement":
-					r.push(`confinement.`);
-					break;
-				case "whipping":
-					r.push(`whipping`);
-					break;
-				case "chastity":
-					if (slave.energy > 60) {
-						r.push(`orgasm denial`);
-					} else {
-						r.push(`punishment.`);
+		function conclusion() {
+			const text = [];
+
+
+			text.push(`Once the last piece of clothing has hit the floor you let your little slut dance naked a little while longer while you finish your last report. Once you have gotten enough of ${his} dancing you snap your fingers to call your slave over.`);
+
+			if (slave.devotion > 80) {
+				text.push(`Your slave hurries to your side and drops to ${his} ${(hasBothLegs(slave)) ? `knees` : `knee`}. ${He} gladly kneels at your feet, looking up at ${his} ${getWrittenTitle(slave)} in adoration.`);
+			} else if (slave.devotion > 20) {
+				text.push(`Your slave hurries to your side and drops to ${his} ${(hasBothLegs(slave)) ? `knees` : `knee`}. ${He} obediently kneels at your feet.`);
+			} else if (slave.devotion < -50) {
+				if (slave.trust < -50) {
+					text.push(`${He} hurries frantically to your side, and drops quivering to the floor at your feet hoping ${he} was quick enough to avoid`);
+					switch (slave.rules.punishment) {
+						case "confinement":
+							text.push(`confinement.`);
+							break;
+						case "whipping":
+							text.push(`whipping`);
+							break;
+						case "chastity":
+							if (slave.energy > 60) {
+								text.push(`orgasm denial`);
+							} else {
+								text.push(`punishment.`);
+							}
+							break;
+						case "situational":
+							switch (slave.collar) {
+								case "shock punishment":
+									text.push(`shock`);
+							}
+							text.push(`punishment.`);
+							break;
 					}
-					break;
-				case "situational":
-					switch (slave.collar) {
-						case "shock punishment":
-							r.push(`shock`);
+				} else {
+					text.push(`${He} looks at you angrily, refusing to obey. You are forced to get up from your chair and retrieve ${his} leash, dragging ${him} back by ${his}`);
+					if (slave.piercing.nose.weight === 2) {
+						text.push(`nose ring.`);
+					} else if (slave.piercing.nipple.weight === 2) {
+						text.push(`nipples.`);
+					} else {
+						text.push(`collar.`);
 					}
-					r.push(`punishment.`);
-					break;
-			}
-		} else {
-			r.push(`${He} looks at you angrily, refusing to obey. You are forced to get up from your chair and retrieve ${his} leash, dragging ${him} back by ${his}`);
-			if (slave.piercing.nose.weight === 2) {
-				r.push(`nose ring.`);
-			} else if (slave.piercing.nipple.weight === 2) {
-				r.push(`nipples.`);
+					text.push(`Once seated, you chain ${him} to your desk and force ${him} to ${his} ${(hasBothLegs(slave)) ? `knees` : `knee`}. You may have to start punishing ${him} more severely.`);
+				}
 			} else {
-				r.push(`collar.`);
+				text.push(`Your slave walks slowly to your desk and kneels. ${He} looks up at you, hoping that ${his} life gets easier.`);
 			}
-			r.push(`Once seated, you chain ${him} to your desk and force ${him} to ${his} ${(hasBothLegs(slave)) ? `knees` : `knee`}. You may have to start punishing ${him} more severely.`);
+
+
+			return text.join(' ');
 		}
-	} else {
-		r.push(`Your slave walks slowly to your desk and kneels. ${He} looks up at you, hoping that ${his} life gets easier.`);
 	}
-	// more varied reactions planned.
-	if (random(1, 100) > (100 + slave.devotion)) {
+
+
+	function slaveGainsFlaw() {
+		// TODO: no mention of oral above
+
 		if (slave.fetish !== "humiliation" && slave.energy <= 95 && slave.sexualFlaw !== "shamefast") {
-			r.push(`Being facefucked by force has given ${him} a <span class="red">desire to always be clothed.</span>`);
 			slave.sexualFlaw = "shamefast";
+
+			return `Being facefucked by force has given ${him} a <span class="red">desire to always be clothed.</span>`;
 		}
-	} else if (random(1, 100) > (110 - slave.devotion)) {
+
+		return ``;
+	}
+
+	function slaveGainsQuirk() {
 		if (slave.fetish === "none" && slave.sexualFlaw !== "shamefast") {
-			r.push(`Being on display for your pleasure has <span class="fetish gain">encouraged ${him} to focus exposing ${himself} more often.</span>`);
 			slave.fetish = "humiliation";
 			slave.fetishKnown = 1;
+
+			return `Being on display for your pleasure has <span class="fetish gain">encouraged ${him} to focus exposing ${himself} more often.</span>`;
 		}
+
+		return ``;
 	}
-	App.Events.addParagraph(node, r);
-	return node;
 };
diff --git a/src/npc/interaction/fDick.js b/src/npc/interaction/fDick.js
index a49eea4ef359242d4a39ff7fa186c7afc7a9a061..4926933a2b49a622e879a07f82fc32d3aefd2278 100644
--- a/src/npc/interaction/fDick.js
+++ b/src/npc/interaction/fDick.js
@@ -4,21 +4,21 @@
  * @returns {DocumentFragment}
  */
 App.Interact.fDick = function(slave) {
-	const node = new DocumentFragment();
-	let r = [];
+	const frag = new DocumentFragment();
 
 	const {
 		He, His,
 		he, his, him, himself
 	} = getPronouns(slave);
 
-	/* TODO: .pregMood and more amp variants */
+	// TODO: .pregMood and more amp variants
 
-	addPartner(slave, -1);
+	seX(slave, "penetrative", V.PC);
 
 	const cunt = V.PC.vagina !== -1 ? "cunt" : "rectal";
 	const belly = bellyAdjective(slave);
 	const amount = cumAmount(slave);
+
 	let load;
 	if (amount <= 30) {
 		load = "a few timid spurts";
@@ -88,295 +88,359 @@ App.Interact.fDick = function(slave) {
 		dickAdj = "hypertrophied";
 	}
 
-	/* CHECK*/
+	const text = new SpacedTextAccumulator(frag);
 
-	/* NON-AMPUTEE*/
-	if (!isAmputee(slave)) {
-		r.push(`You direct ${slave.slaveName} to lie down and ready ${himself} as you step over to ${him} and align your`);
-		if (V.PC.vagina !== -1) {
-			r.push(`vagina`);
-		} else {
-			r.push(`ass`);
-		}
-		r.push(`with ${his}`);
-		if (slave.piercing.vagina.weight > 1 && slave.dick !== 0) {
-			r.push(`pierced cock-head.`);
-		} else if (slave.piercing.vagina.weight === 1 && slave.dick !== 0) {
-			r.push(`pierced cock.`);
+	text.push(
+		consummation(),
+		cleanup(),
+	);
+
+	if (canImpreg(V.PC, slave)) {
+		if (slave.diet === "cum production") {
+			const pregChance = (slave.balls * 5 * 1.2);
+			text.push(knockMeUp(V.PC, pregChance, 0, slave.ID));
 		} else {
-			r.push(`cock.`);
+			const pregChance = (slave.balls * 5);
+			text.push(knockMeUp(V.PC, pregChance, 0, slave.ID));
 		}
+	}
 
-		if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
-			if (slave.devotion > 20) {
-				r.push(`${He} thought ${he} would be fucking another slave, not ${his} ${getWrittenTitle(slave)}, so to say ${he}'s pleasantly surprised would be an understatement.`);
-			} else if (slave.devotion >= -20) {
-				r.push(`${He} thought ${he} would fucking another slave, not ${his} ${getWrittenTitle(slave)} ${he} has mixed feelings about this, but ${his} body can't wait to plunge your depths.`);
+	if (V.policies.sexualOpenness === 0) {
+		text.push(rumors());
+
+		V.PC.degeneracy += 2;
+	}
+
+	text.toParagraph();
+
+	return frag;
+
+	function consummation() {
+		const text = [];
+
+
+		if (!isAmputee(slave)) {
+			text.push(`You direct ${slave.slaveName} to lie down and ready ${himself} as you step over to ${him} and align your`);
+
+			if (V.PC.vagina !== -1) {
+				text.push(`vagina`);
 			} else {
-				if (slave.trust < -20) {
-					r.push(`${He} was already horrified at the thought of being ordered to lie down and let another slave rape ${his} dick, but when ${he} realized it would be you instead, that horror turned to a mix of confusion and sheer terror.`);
-				} else {
-					r.push(`${His} dick springs to life at the prospect of plunging into your depths; this may be ${his} chance to one up you for a change.`);
-				}
+				text.push(`ass`);
 			}
-		}
 
-		r.push(`You slowly lower yourself onto ${his} ${dickAdj} dick, savoring every`);
-		if (V.showInches === 2) {
-			r.push(`inch,`);
-		} else {
-			r.push(`centimeter,`);
-		}
-		if (slave.dick <= 6) {
-			r.push(`until you find yourself hilted and sitting on ${his} pelvis.`);
-		} else {
-			r.push(`until you feel that you can't take any more of ${him} inside you.`);
-		}
+			text.push(`with ${his}`);
 
-		r.push(`Making eye contact${!canSee(slave) ? `(inasmuch as you can)` : ``}, you reach`);
-		if (V.PC.belly < 5000 && slave.belly < 5000) {
-			r.push(`back`);
-		} else {
-			r.push(`down`);
-		}
-		if (slave.scrotum > 0) {
-			r.push(`and stroke ${his} ${nutte} balls,`);
-		} else if (slave.vagina > -1) {
-			r.push(`and tease ${his} neglected pussy,`);
-		} else {
-			r.push(`and stroke ${his} soft perineum,`);
-		}
-		r.push(`making it abundantly clear that you want ${his} cum.`);
+			if (slave.piercing.vagina.weight > 1 && slave.dick !== 0) {
+				text.push(`pierced cock-head.`);
+			} else if (slave.piercing.vagina.weight === 1 && slave.dick !== 0) {
+				text.push(`pierced cock.`);
+			} else {
+				text.push(`cock.`);
+			}
 
-		if (slave.fetish === "mindbroken") {
-			r.push(`Like a doll, ${he} dumbly remains still, completely indifferent that ${he}'s deep in ${his} ${getWrittenTitle(slave)}'s`);
+			if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
+				if (slave.devotion > 20) {
+					text.push(`${He} thought ${he} would be fucking another slave, not ${his} ${getWrittenTitle(slave)}, so to say ${he}'s pleasantly surprised would be an understatement.`);
+				} else if (slave.devotion >= -20) {
+					text.push(`${He} thought ${he} would fucking another slave, not ${his} ${getWrittenTitle(slave)} ${he} has mixed feelings about this, but ${his} body can't wait to plunge your depths.`);
+				} else {
+					if (slave.trust < -20) {
+						text.push(`${He} was already horrified at the thought of being ordered to lie down and let another slave rape ${his} dick, but when ${he} realized it would be you instead, that horror turned to a mix of confusion and sheer terror.`);
+					} else {
+						text.push(`${His} dick springs to life at the prospect of plunging into your depths; this may be ${his} chance to one up you for a change.`);
+					}
+				}
+			}
 
-			if (V.PC.vagina !== -1) {
-				r.push(`pussy.`);
+			text.push(`You slowly lower yourself onto ${his} ${dickAdj} dick, savoring every`);
+
+			if (V.showInches === 2) {
+				text.push(`inch,`);
 			} else {
-				r.push(`butt.`);
+				text.push(`centimeter,`);
 			}
-			r.push(`You start moving up and on ${his} shaft, continuing until you climax and lift yourself off of ${him}. A strand of cum slips from your`);
-			if (V.PC.vagina !== -1) {
-				r.push(`slit;`);
+
+			if (slave.dick <= 6) {
+				text.push(`until you find yourself hilted and sitting on ${his} pelvis.`);
 			} else {
-				r.push(`anus;`);
+				text.push(`until you feel that you can't take any more of ${him} inside you.`);
 			}
 
+			text.push(`Making eye contact${!canSee(slave) ? `(inasmuch as you can)` : ``}, you reach`);
 
-			r.push(`it seems ${slave.slaveName} came too.`);
-			r.push(`Since ${he} is mindbroken, ${his} responses to you are purely physiological and your actions have no affect on ${him} mentally. You leave your toy for one of your other slaves to clean and maintain.`);
-		} else if (slave.devotion > 50) {
-			if (slave.trust < -20) {
-				r.push(`Having followed your instructions as quickly as ${he} could in fear of your wrath, ${he} tries ${his} best to please you while you bounce`);
-				if (V.PC.belly >= 5000) {
-					r.push(`your gravid bulk`);
-				}
-				r.push(`on ${his} obedient cock. ${He} timidly warns you that ${he} is about to cum; in response you speed up your pace and clamp down hard on ${his} throbbing shaft. ${He} squeaks lewdly, overwhelmed by your orgasmic ${cunt} spasms, and unloads ${load} inside of you before apologizing submissively.`);
-			} else if (slave.trust <= 20) {
-				r.push(`Having followed your instructions quickly and obediently, ${he} tries ${his} best to please you while you bounce`);
-				if (V.PC.belly >= 5000) {
-					r.push(`your gravid bulk`);
-				}
-				r.push(`on ${his} eager cock. ${He} grabs your hips and warns you ${he} is about to cum; in response you speed up your pace, encouraging ${him} to impale you on ${his} throbbing shaft. ${He} squeals lewdly, overwhelmed by your orgasmic ${cunt} spasms, and unloads ${load} into you before helping you up.`);
+			if (V.PC.belly < 5000 && slave.belly < 5000) {
+				text.push(`back`);
 			} else {
-				r.push(`Having followed your instructions with gusto, ${he} energetically pounds you while you bounce`);
-				if (V.PC.belly >= 5000) {
-					r.push(`your gravid bulk`);
-				}
-				r.push(`on ${his} eager cock. ${He} grabs your hips and desperately warns you ${he} can't hold out any longer; in response you speed up your pace, tipping ${him} over the edge and forcing ${him} to impale you on ${his} twitching shaft. ${He} moans loudly, overwhelmed by your orgasmic ${cunt} spasms, and unloads ${load} into you before pulling you into a post coitus embrace.`);
+				text.push(`down`);
 			}
-		} else if (slave.devotion >= -20) {
-			if (slave.trust < -20) {
-				r.push(`Having hesitatingly followed your instructions, ${he} lies as still as ${he} can beneath you while you bounce`);
-				if (V.PC.belly >= 5000) {
-					r.push(`your gravid bulk`);
-				}
-				r.push(`on ${his} terrified cock. While ${he} is too afraid to enjoy pleasuring you, ${he} obediently thrusts into you. ${He} timidly warns you that ${he} is about to cum; in response you speed up your pace and clamp down hard on ${his} throbbing shaft. ${He} cries out in surprise, overwhelmed by your orgasmic ${cunt} spasms, and blows ${load} in you like a good little slave.`);
-			} else if (slave.trust <= 20) {
-				r.push(`Having obediently followed your instructions, ${he} lies as still as ${he} can beneath you while you bounce`);
-				if (V.PC.belly >= 5000) {
-					r.push(`your gravid bulk`);
-				}
-				r.push(`on ${his} willing cock. While ${he} is too uncertain of ${his} position in the hierarchy to really enjoy ${himself}, ${he} hesitatingly thrusts into you. When ${he} feels ${he} is nearing ${his} limit, ${he} gives you proper warning that ${he} is about to cum; in response you speed up your pace and clamp down hard on ${his} throbbing shaft. ${He} cries out in surprise, overwhelmed by your orgasmic ${cunt} spasms and boldness, and blows ${load} in you during the confusion.`);
+
+			if (slave.scrotum > 0) {
+				text.push(`and stroke ${his} ${nutte} balls,`);
+			} else if (slave.vagina > -1) {
+				text.push(`and tease ${his} neglected pussy,`);
 			} else {
-				r.push(`Having obediently followed your instructions, ${he} energetically pounds you while you bounce`);
-				if (V.PC.belly >= 5000) {
-					r.push(`your gravid bulk`);
-				}
-				r.push(`on ${his} eager cock. ${He} grabs your hips and pounds you a little too eagerly, not even slowing down as you begin to feel ${him} tense with orgasm. Without so much as a warning to you, ${he} trembles with orgasm, pumping ${his} load deep into your ${cunt} and setting off your own. You glare daggers at ${him} as ${he} profusely apologizes for ${his} lack of restraint.`);
+				text.push(`and stroke ${his} soft perineum,`);
 			}
-		} else {
-			if (slave.trust < -20) {
-				r.push(`Having followed your instructions as quickly as ${he} could, ${he} lies as still as ${he} can beneath you while you bounce`);
-				if (V.PC.belly >= 5000) {
-					r.push(`your gravid bulk`);
-				}
-				r.push(`on ${his} reluctant cock. While ${he} is too afraid to be an active participant in pleasuring you, you make do with what ${he}'s giving. ${He} timidly warns you that ${he} is about to cum; in response you speed up your pace and clamp down hard on ${his} throbbing shaft. ${He} cries out lewdly, overwhelmed by your orgasmic ${cunt} spasms, and unloads ${load} inside of you despite ${his} fear.`);
-			} else if (slave.trust <= 20) {
-				r.push(`Having followed your instructions as quickly as ${he} could, ${he} lies as still as ${he} can beneath you while you bounce`);
-				if (V.PC.belly >= 5000) {
-					r.push(`your gravid bulk`);
-				}
-				r.push(`on ${his} reluctant cock. While ${he} is too hateful to be an active participant in pleasuring you, you make do with what ${he}'s got. ${He} cries out lewdly, overwhelmed by your orgasmic ${cunt} spasms, and unloads ${load} deep inside you without warning. ${He} <span class="orangered">smirks a little</span> as you glare daggers at ${him}.`);
-				slave.trust++;
-			} else if (overpowerCheck(slave, V.PC) < random(1, 100)) {
-				r.push(`Without warning, ${he} flips you onto your side and, still hilted,`);
-				if (slave.belly >= 300000) {
-					r.push(`repositions you onto your hands and knees while using ${his} ${belly} belly to pin you under ${him}.`);
-				} else if (V.PC.belly >= 5000) {
-					r.push(`rolls you into missionary while pinning your arms and legs.`);
-				} else if (V.PC.boobs >= 1000) {
-					r.push(`pushes your face down into your`);
-					if (V.PC.boobsImplant > 0) {
-						r.push(`fake`);
-					}
-					r.push(`cleavage while pinning your arms and legs.`);
+
+			text.push(`making it abundantly clear that you want ${his} cum.`);
+
+			if (slave.fetish === "mindbroken") {
+				text.push(`Like a doll, ${he} dumbly remains still, completely indifferent that ${he}'s deep in ${his} ${getWrittenTitle(slave)}'s`);
+
+				if (V.PC.vagina !== -1) {
+					text.push(`pussy.`);
 				} else {
-					r.push(`rolls you into missionary while pinning your arms and forcing you into a mating press.`);
+					text.push(`butt.`);
 				}
-				r.push(`Such audacity takes you entirely by surprise and gives ${him} the edge ${he} needs to pull it off. ${He} vigorously pistons in and out of you with little regard for you${(V.PC.pregKnown === 1) ? ` or your pregnancy` : ``}, fucking you senseless until ${he} has had enough and cums deep inside your`);
+
+				text.push(`You start moving up and on ${his} shaft, continuing until you climax and lift yourself off of ${him}. A strand of cum slips from your`);
+
 				if (V.PC.vagina !== -1) {
-					r.push(`pussy.`);
+					text.push(`slit;`);
 				} else {
-					r.push(`ass.`);
+					text.push(`anus;`);
 				}
-				if (canImpreg(V.PC, slave) && slave.fetish === "pregnancy") {
-					if (hasAnyArms(slave)) {
-						r.push(`Running a hand across`);
-					} else {
-						r.push(`Grinding against`);
+
+				text.push(`it seems ${slave.slaveName} came too. Since ${he} is mindbroken, ${his} responses to you are purely physiological and your actions have no affect on ${him} mentally. You leave your toy for one of your other slaves to clean and maintain.`);
+			} else if (slave.devotion > 50) {
+				if (slave.trust < -20) {
+					text.push(`Having followed your instructions as quickly as ${he} could in fear of your wrath, ${he} tries ${his} best to please you while you bounce`);
+
+					if (V.PC.belly >= 5000) {
+						text.push(`your gravid bulk`);
 					}
-					r.push(`your firm belly, ${he} decides ${his} job is not yet done and begins reaming you once more, dead set on taking this opportunity to <span class="orangered">show you your place by knocking you up with ${his} child.</span> ${He} manages to empty ${his} balls in your womb several more times before exhaustion kicks in, forcing ${him} to leave you twitching and drooling cum.`);
-					r.push(knockMeUp(V.PC, 100, 0, slave.ID));
-					seX(V.PC, "vaginal", slave, "penetrative", 5);
+
+					text.push(`on ${his} obedient cock. ${He} timidly warns you that ${he} is about to cum; in response you speed up your pace and clamp down hard on ${his} throbbing shaft. ${He} squeaks lewdly, overwhelmed by your orgasmic ${cunt} spasms, and unloads ${load} inside of you before apologizing submissively.`);
+				} else if (slave.trust <= 20) {
+					text.push(`Having followed your instructions quickly and obediently, ${he} tries ${his} best to please you while you bounce`);
+
+					if (V.PC.belly >= 5000) {
+						text.push(`your gravid bulk`);
+					}
+
+					text.push(`on ${his} eager cock. ${He} grabs your hips and warns you ${he} is about to cum; in response you speed up your pace, encouraging ${him} to impale you on ${his} throbbing shaft. ${He} squeals lewdly, overwhelmed by your orgasmic ${cunt} spasms, and unloads ${load} into you before helping you up.`);
 				} else {
-					r.push(`Contently sighing, ${he} pulls ${his} still very hard cock from your overwhelmed body and forces it into your mouth, ready to blow a second load and give you a <span class="orangered">taste of your place,</span> before leaving you twitching and drooling cum.`);
-					seX(V.PC, "oral", slave, "penetrative");
+					text.push(`Having followed your instructions with gusto, ${he} energetically pounds you while you bounce`);
+
+					if (V.PC.belly >= 5000) {
+						text.push(`your gravid bulk`);
+					}
+
+					text.push(`on ${his} eager cock. ${He} grabs your hips and desperately warns you ${he} can't hold out any longer; in response you speed up your pace, tipping ${him} over the edge and forcing ${him} to impale you on ${his} twitching shaft. ${He} moans loudly, overwhelmed by your orgasmic ${cunt} spasms, and unloads ${load} into you before pulling you into a post coitus embrace.`);
 				}
-				slave.trust += 5;
-			} else {
-				r.push(`You feel ${him} shift dominantly beneath you and in response`);
-				if (slave.scrotum > 0) {
-					r.push(`clamp down on ${his} balls`);
+			} else if (slave.devotion >= -20) {
+				if (slave.trust < -20) {
+					text.push(`Having hesitatingly followed your instructions, ${he} lies as still as ${he} can beneath you while you bounce`);
+
+					if (V.PC.belly >= 5000) {
+						text.push(`your gravid bulk`);
+					}
+
+					text.push(`on ${his} terrified cock. While ${he} is too afraid to enjoy pleasuring you, ${he} obediently thrusts into you. ${He} timidly warns you that ${he} is about to cum; in response you speed up your pace and clamp down hard on ${his} throbbing shaft. ${He} cries out in surprise, overwhelmed by your orgasmic ${cunt} spasms, and blows ${load} in you like a good little slave.`);
+				} else if (slave.trust <= 20) {
+					text.push(`Having obediently followed your instructions, ${he} lies as still as ${he} can beneath you while you bounce`);
+
+					if (V.PC.belly >= 5000) {
+						text.push(`your gravid bulk`);
+					}
+
+					text.push(`on ${his} willing cock. While ${he} is too uncertain of ${his} position in the hierarchy to really enjoy ${himself}, ${he} hesitatingly thrusts into you. When ${he} feels ${he} is nearing ${his} limit, ${he} gives you proper warning that ${he} is about to cum; in response you speed up your pace and clamp down hard on ${his} throbbing shaft. ${He} cries out in surprise, overwhelmed by your orgasmic ${cunt} spasms and boldness, and blows ${load} in you during the confusion.`);
 				} else {
-					r.push(`twist ${his} dick at an odd angle`);
+					text.push(`Having obediently followed your instructions, ${he} energetically pounds you while you bounce`);
+
+					if (V.PC.belly >= 5000) {
+						text.push(`your gravid bulk`);
+					}
+
+					text.push(`on ${his} eager cock. ${He} grabs your hips and pounds you a little too eagerly, not even slowing down as you begin to feel ${him} tense with orgasm. Without so much as a warning to you, ${he} trembles with orgasm, pumping ${his} load deep into your ${cunt} and setting off your own. You glare daggers at ${him} as ${he} profusely apologizes for ${his} lack of restraint.`);
 				}
-				r.push(`until ${he} behaves. ${He} groans with a mix of disgust and pleasure while you bounce`);
-				if (V.PC.belly >= 5000) {
-					r.push(`your gravid bulk`);
+			} else {
+				if (slave.trust < -20) {
+					text.push(`Having followed your instructions as quickly as ${he} could, ${he} lies as still as ${he} can beneath you while you bounce`);
+
+					if (V.PC.belly >= 5000) {
+						text.push(`your gravid bulk`);
+					}
+
+					text.push(`on ${his} reluctant cock. While ${he} is too afraid to be an active participant in pleasuring you, you make do with what ${he}'s giving. ${He} timidly warns you that ${he} is about to cum; in response you speed up your pace and clamp down hard on ${his} throbbing shaft. ${He} cries out lewdly, overwhelmed by your orgasmic ${cunt} spasms, and unloads ${load} inside of you despite ${his} fear.`);
+				} else if (slave.trust <= 20) {
+					text.push(`Having followed your instructions as quickly as ${he} could, ${he} lies as still as ${he} can beneath you while you bounce`);
+
+					if (V.PC.belly >= 5000) {
+						text.push(`your gravid bulk`);
+					}
+
+					text.push(`on ${his} reluctant cock. While ${he} is too hateful to be an active participant in pleasuring you, you make do with what ${he}'s got. ${He} cries out lewdly, overwhelmed by your orgasmic ${cunt} spasms, and unloads ${load} deep inside you without warning. ${He} <span class="orangered">smirks a little</span> as you glare daggers at ${him}.`);
+
+					slave.trust++;
+				} else if (overpowerCheck(slave, V.PC) < random(1, 100)) {
+					text.push(`Without warning, ${he} flips you onto your side and, still hilted,`);
+
+					if (slave.belly >= 300000) {
+						text.push(`repositions you onto your hands and knees while using ${his} ${belly} belly to pin you under ${him}.`);
+					} else if (V.PC.belly >= 5000) {
+						text.push(`rolls you into missionary while pinning your arms and legs.`);
+					} else if (V.PC.boobs >= 1000) {
+						text.push(`pushes your face down into your`);
+						if (V.PC.boobsImplant > 0) {
+							text.push(`fake`);
+						}
+						text.push(`cleavage while pinning your arms and legs.`);
+					} else {
+						text.push(`rolls you into missionary while pinning your arms and forcing you into a mating press.`);
+					}
+
+					text.push(`Such audacity takes you entirely by surprise and gives ${him} the edge ${he} needs to pull it off. ${He} vigorously pistons in and out of you with little regard for you${(V.PC.pregKnown === 1) ? ` or your pregnancy` : ``}, fucking you senseless until ${he} has had enough and cums deep inside your`);
+					if (V.PC.vagina !== -1) {
+						text.push(`pussy.`);
+					} else {
+						text.push(`ass.`);
+					}
+
+					if (canImpreg(V.PC, slave) && slave.fetish === "pregnancy") {
+						if (hasAnyArms(slave)) {
+							text.push(`Running a hand across`);
+						} else {
+							text.push(`Grinding against`);
+						}
+
+						text.push(`your firm belly, ${he} decides ${his} job is not yet done and begins reaming you once more, dead set on taking this opportunity to <span class="orangered">show you your place by knocking you up with ${his} child.</span> ${He} manages to empty ${his} balls in your womb several more times before exhaustion kicks in, forcing ${him} to leave you twitching and drooling cum.`);
+						text.push(knockMeUp(V.PC, 100, 0, slave.ID));
+						seX(V.PC, "vaginal", slave, "penetrative", 5);
+					} else {
+						text.push(`Contently sighing, ${he} pulls ${his} still very hard cock from your overwhelmed body and forces it into your mouth, ready to blow a second load and give you a <span class="orangered">taste of your place,</span> before leaving you twitching and drooling cum.`);
+						seX(V.PC, "oral", slave, "penetrative");
+					}
+					slave.trust += 5;
+				} else {
+					text.push(`You feel ${him} shift dominantly beneath you and in response`);
+
+					if (slave.scrotum > 0) {
+						text.push(`clamp down on ${his} balls`);
+					} else {
+						text.push(`twist ${his} dick at an odd angle`);
+					}
+
+					text.push(`until ${he} behaves. ${He} groans with a mix of disgust and pleasure while you bounce`);
+
+					if (V.PC.belly >= 5000) {
+						text.push(`your gravid bulk`);
+					}
+
+					text.push(`on ${his} traitorous cock. ${He} might not want to bend to your will, but you have ${his} body wrapped around your little finger, even though it still leaves you doing all the work. ${He} cries out lewdly, overwhelmed by your orgasmic ${cunt} spasms, and unloads deep inside you without warning. ${He} <span class="orangered">smirks a little</span> as you glare daggers at ${him}.`);
+
+					slave.trust++;
 				}
-				r.push(`on ${his} traitorous cock. ${He} might not want to bend to your will, but you have ${his} body wrapped around your little finger, even though it still leaves you doing all the work. ${He} cries out lewdly, overwhelmed by your orgasmic ${cunt} spasms, and unloads deep inside you without warning. ${He} <span class="orangered">smirks a little</span> as you glare daggers at ${him}.`);
-				slave.trust++;
 			}
-		}
-	/* AMPUTEE*/
-	} else {
-		r.push(`You step over to pick up ${slave.slaveName}, lie ${him} down and get ${him} ready. Then you align your`);
-		if (V.PC.vagina !== -1) {
-			r.push(`vagina`);
 		} else {
-			r.push(`ass`);
-		}
-		r.push(`with`);
-		if (slave.piercing.vagina.weight > 1 && slave.dick !== 0) {
-			r.push(`${his} pierced cock-head.`);
-		} else if (slave.piercing.vagina.weight === 1 && slave.dick !== 0) {
-			r.push(`${his} pierced cock`);
-		} else {
-			r.push(`${his} cock`);
-		}
-		r.push(`and lower yourself onto ${his} ${dickAdj} dick`);
-		if (slave.dick <= 6) {
-			r.push(`until you are sitting on ${his} loins.`);
-		} else {
-			r.push(`until you feel that you can't take any more of ${him} inside you.`);
-		}
+			text.push(`You step over to pick up ${slave.slaveName}, lie ${him} down and get ${him} ready. Then you align your`);
 
-		r.push(`You reach back`);
-		if (slave.scrotum > 0) {
-			r.push(`and stroke ${his} ${nutte} balls.`);
-		} else if (slave.vagina > -1) {
-			r.push(`and tease ${his} neglected pussy.`);
-		} else {
-			r.push(`and stroke ${his} soft perineum.`);
-		}
-		if (slave.fetish === "mindbroken") {
-			r.push(`Like a broken doll, ${he} dumbly remains still, watching you without interest.`);
-			r.push(`You start moving up and on ${his} shaft, until you climax and notice that so did ${slave.slaveName}.`);
-			r.push(`Since ${he} is mindbroken, ${his} responses to you are purely physiological and your actions have no affect on ${him} mentally. You leave your toy for one of your other slaves to clean and maintain.`);
-		} else {
-			r.push(`You ride your helpless slave until you both climax.`);
-		}
-	}
+			if (V.PC.vagina !== -1) {
+				text.push(`vagina`);
+			} else {
+				text.push(`ass`);
+			}
 
-	if (canMove(slave) && slave.fetish !== "mindbroken" && V.postSexCleanUp > 0) {
-		switch (slave.assignment) {
-			case "whore":
-				r.push(`${He} heads to the bathroom to clean ${his} dick before returning to selling ${his} body publicly.`);
-				break;
-			case "serve the public":
-				r.push(`${He} heads to the bathroom to clean ${his} dick before returning to allowing the public to use ${his} body.`);
-				break;
-			case "rest":
-				r.push(`${He} heads to the bathroom to clean ${his} dick before crawling back into bed.`);
-				break;
-			case "get milked":
-				r.push(`${He} hurries to the bathroom to clean ${his} dick`);
-				if (slave.lactation > 0) {
-					r.push(`before going to get ${his} uncomfortably milk-filled tits drained.`);
-				} else {
-					r.push(`and then rests until ${his} balls are ready to be drained again.`);
-				}
-				break;
-			case "please you":
-				r.push(`${He} hurries to the bathroom to clean ${his} dick before returning to await your next use of ${his} body, as though nothing had happened.`);
-				break;
-			case "be a subordinate slave":
-				r.push(`${He} moves to the bathroom to clean ${his} dick, though it's only a matter of time before another slave decides to take their turn with ${his} cock.`);
-				break;
-			case "be a servant":
-				r.push(`${He} hurries to the bathroom to clean ${his} dick, since ${his} chores didn't perform themselves while you used ${him}.`);
-				break;
-			case "be your Head Girl":
-				r.push(`${He} hurries to the bathroom to clean ${his} dick, worried that ${his} charges got up to trouble while you were using ${him}.`);
-				break;
-			case "guard you":
-				r.push(`${He} hurries off to wash ${his} dick so you'll be unguarded for as little time as possible.`);
-				break;
-			case "work in the brothel":
-				r.push(`${He} goes to wash ${his} dick so ${his} next customer has no idea what ${he}'s been up to.`);
-				break;
-			case "serve in the club":
-				r.push(`${He} goes to wash ${his} dick to make it appear unused.`);
-				break;
-			case "work in the dairy":
-				r.push(`${He} goes off to carefully wash ${his} dick to avoid besmirching the nice clean dairy.`);
-				break;
-			case "work as a farmhand":
-				r.push(`${He} goes off to wash ${his} dick to avoid tainting the food in ${V.farmyardName}.`);
-				break;
-			case "work as a servant":
-				r.push(`${He} rushes to wash ${his} dick, impatient to get back to ${his} undiminished chores.`);
-				break;
-			case "work as a nanny":
-				r.push(`${He} hurries off to wash off ${his} dick before heading back to the ${V.nurseryName}.`);
+			text.push(`with`);
+
+			if (slave.piercing.vagina.weight > 1 && slave.dick !== 0) {
+				text.push(`${his} pierced cock-head.`);
+			} else if (slave.piercing.vagina.weight === 1 && slave.dick !== 0) {
+				text.push(`${his} pierced cock`);
+			} else {
+				text.push(`${his} cock`);
+			}
+
+			text.push(`and lower yourself onto ${his} ${dickAdj} dick`);
+
+			if (slave.dick <= 6) {
+				text.push(`until you are sitting on ${his} loins.`);
+			} else {
+				text.push(`until you feel that you can't take any more of ${him} inside you.`);
+			}
+
+			text.push(`You reach back`);
+
+			if (slave.scrotum > 0) {
+				text.push(`and stroke ${his} ${nutte} balls.`);
+			} else if (slave.vagina > -1) {
+				text.push(`and tease ${his} neglected pussy.`);
+			} else {
+				text.push(`and stroke ${his} soft perineum.`);
+			}
+
+			if (slave.fetish === "mindbroken") {
+				text.push(`Like a broken doll, ${he} dumbly remains still, watching you without interest. You start moving up and on ${his} shaft, until you climax and notice that so did ${slave.slaveName}. Since ${he} is mindbroken, ${his} responses to you are purely physiological and your actions have no affect on ${him} mentally. You leave your toy for one of your other slaves to clean and maintain.`);
+			} else {
+				text.push(`You ride your helpless slave until you both climax.`);
+			}
 		}
+
+		return text.join(' ');
 	}
 
-	if (canImpreg(V.PC, slave)) {
-		if (slave.diet === "cum production") {
-			const pregChance = (slave.balls * 5 * 1.2);
-			r.push(knockMeUp(V.PC, pregChance, 0, slave.ID));
-		} else {
-			const pregChance = (slave.balls * 5);
-			r.push(knockMeUp(V.PC, pregChance, 0, slave.ID));
+	function cleanup() {
+		const text = [];
+
+
+		if (canMove(slave) && slave.fetish !== "mindbroken" && V.postSexCleanUp > 0) {
+			switch (slave.assignment) {
+				case "whore":
+					text.push(`${He} heads to the bathroom to clean ${his} dick before returning to selling ${his} body publicly.`);
+					break;
+				case "serve the public":
+					text.push(`${He} heads to the bathroom to clean ${his} dick before returning to allowing the public to use ${his} body.`);
+					break;
+				case "rest":
+					text.push(`${He} heads to the bathroom to clean ${his} dick before crawling back into bed.`);
+					break;
+				case "get milked":
+					text.push(`${He} hurries to the bathroom to clean ${his} dick`);
+					if (slave.lactation > 0) {
+						text.push(`before going to get ${his} uncomfortably milk-filled tits drained.`);
+					} else {
+						text.push(`and then rests until ${his} balls are ready to be drained again.`);
+					}
+					break;
+				case "please you":
+					text.push(`${He} hurries to the bathroom to clean ${his} dick before returning to await your next use of ${his} body, as though nothing had happened.`);
+					break;
+				case "be a subordinate slave":
+					text.push(`${He} moves to the bathroom to clean ${his} dick, though it's only a matter of time before another slave decides to take their turn with ${his} cock.`);
+					break;
+				case "be a servant":
+					text.push(`${He} hurries to the bathroom to clean ${his} dick, since ${his} chores didn't perform themselves while you used ${him}.`);
+					break;
+				case "be your Head Girl":
+					text.push(`${He} hurries to the bathroom to clean ${his} dick, worried that ${his} charges got up to trouble while you were using ${him}.`);
+					break;
+				case "guard you":
+					text.push(`${He} hurries off to wash ${his} dick so you'll be unguarded for as little time as possible.`);
+					break;
+				case "work in the brothel":
+					text.push(`${He} goes to wash ${his} dick so ${his} next customer has no idea what ${he}'s been up to.`);
+					break;
+				case "serve in the club":
+					text.push(`${He} goes to wash ${his} dick to make it appear unused.`);
+					break;
+				case "work in the dairy":
+					text.push(`${He} goes off to carefully wash ${his} dick to avoid besmirching the nice clean dairy.`);
+					break;
+				case "work as a farmhand":
+					text.push(`${He} goes off to wash ${his} dick to avoid tainting the food in ${V.farmyardName}.`);
+					break;
+				case "work as a servant":
+					text.push(`${He} rushes to wash ${his} dick, impatient to get back to ${his} undiminished chores.`);
+					break;
+				case "work as a nanny":
+					text.push(`${He} hurries off to wash off ${his} dick before heading back to the ${V.nurseryName}.`);
+			}
 		}
+
+		return text.join(' ');
 	}
-	if (V.policies.sexualOpenness === 0) {
-		r.push(`Rumors spread that you <span class="red">enjoy taking it from slaves.</span>`);
-		V.PC.degeneracy += 2;
+
+	function rumors() {
+		return `Rumors spread that you <span class="red">enjoy taking it from slaves.</span>`;
 	}
-	App.Events.addParagraph(node, r);
-	return node;
 };
diff --git a/src/npc/interaction/fEmbrace.js b/src/npc/interaction/fEmbrace.js
index f4e5edab785854c7e89f3b483bac82363b952116..0b6a8261a70cab9be7140451fd0253935aa358bb 100644
--- a/src/npc/interaction/fEmbrace.js
+++ b/src/npc/interaction/fEmbrace.js
@@ -4,282 +4,332 @@
  * @returns {DocumentFragment}
  */
 App.Interact.fEmbrace = function(slave) {
-	const node = new DocumentFragment();
-	let r = [];
+	const frag = new DocumentFragment();
 
 	const {
 		He, His,
 		he, his, him, himself, wife, hers, woman, girl
 	} = getPronouns(slave);
 
-	const {title: Master, say: say} = getEnunciation(slave);
+	const {title: Master, say} = getEnunciation(slave);
 
-	const {womanP} = getPronouns(V.PC).appendSuffix("P");
+	const {woman: womanP} = getPronouns(V.PC);
 	const bosom = V.PC.boobs >= 300 ? "bosom" : "chest";
 
-	addPartner(slave, -1);
+	const text = new SpacedTextAccumulator(frag);
 
-	r.push(`You tell ${slave.slaveName} to`);
-	if (hasAnyLegs(slave)) {
-		r.push(`stand in front of you.`);
-	} else {
-		r.push(`have another slave set ${him} down on your desk.`);
-	}
+	text.push(
+		intro(),
+		setup(),
+		consummation(),
+		aftermath(),
+	);
+
+	text.toParagraph();
+
+	return frag;
+
+	function intro() {
+		const text = [];
 
-	if (slave.fetish === "mindbroken" && slave.relationship !== -3) {
-		r.push(`${He} complies automatically. ${He} remembers that when ${getWrittenTitle(slave)}'s commands are not obeyed, there is punishment.`);
-	} else if (slave.relationship === -2) {
-		r.push(`${He} excitedly complies, happy to be near the object of ${his} longing. Once ${he}'s close, you take ${his} completely relaxed head in your hands and gaze deeply`);
-		if (canSee(slave)) {
-			r.push(`into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he} loves overwhelming, and ${his} eyes flick downward after a moment.`);
+		text.push(`You tell ${slave.slaveName} to`);
+
+		if (hasAnyLegs(slave)) {
+			text.push(`stand in front of you.`);
 		} else {
-			r.push(`upon ${his} face. ${He} senses the intense look from the ${womanP} ${he} loves and finds it overwhelming, and after a moment glances away.`);
+			text.push(`have another slave set ${him} down on your desk.`);
 		}
-		r.push(`${He} blushes furiously.`);
-	} else if (slave.relationship === -3) {
-		if (slave.fetish === "mindbroken") {
-			r.push(`${He} complies mechanically. ${He} remembers that when ${getWrittenTitle(slave)}'s commands are not obeyed, there is punishment. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} blank ${App.Desc.eyesColor(slave)}. ${He} shows no reaction.`);
-		} else if (slave.devotion+slave.trust >= 175) {
-			r.push(`${He} lovingly complies, hurrying to come close to the ${womanP} who married ${him}. Once ${he}'s close, you take your willing ${wife}'s head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s married to affirming, and looks down with a`);
-			if (canSee(slave)) {
-				r.push(`smile, running ${his} eyes over your ${bosom}.`);
-			} else {
-				r.push(`smile.`);
-			}
-		} else if (slave.devotion < -20 && slave.trust > 20) {
-			r.push(`${He} complies. Once ${he}'s close, you take your reluctant ${wife}'s head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s forcibly married to disturbing, and`);
+
+		if (slave.fetish === "mindbroken" && slave.relationship !== -3) {
+			text.push(`${He} complies automatically. ${He} remembers that when ${getWrittenTitle(slave)}'s commands are not obeyed, there is punishment.`);
+		} else if (slave.relationship === -2) {
+			text.push(`${He} excitedly complies, happy to be near the object of ${his} longing. Once ${he}'s close, you take ${his} completely relaxed head in your hands and gaze deeply`);
+
 			if (canSee(slave)) {
-				r.push(`breaks eye contact.`);
+				text.push(`into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he} loves overwhelming, and ${his} eyes flick downward after a moment.`);
 			} else {
-				r.push(`turns ${his} face away.`);
+				text.push(`upon ${his} face. ${He} senses the intense look from the ${womanP} ${he} loves and finds it overwhelming, and after a moment glances away.`);
 			}
-		} else if (slave.devotion < -20) {
-			r.push(`${He} complies out of fear. Once ${he}'s close, you take your unwilling ${wife}'s head in your hands and gaze deeply into ${his} teary ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s forcibly married to terrifying, and`);
-			if (canSee(slave)) {
-				r.push(`breaks eye contact.`);
+
+			text.push(`${He} blushes furiously.`);
+		} else if (slave.relationship === -3) {
+			if (slave.fetish === "mindbroken") {
+				text.push(`${He} complies mechanically. ${He} remembers that when ${getWrittenTitle(slave)}'s commands are not obeyed, there is punishment. Once ${he}'s close, you hold ${his} face in your palms and look into ${his} blank ${App.Desc.eyesColor(slave)}. ${He} shows no reaction.`);
+			} else if (slave.devotion+slave.trust >= 175) {
+				text.push(`${He} lovingly complies, hurrying to come close to the ${womanP} who married ${him}. Once ${he}'s close, you take your willing ${wife}'s head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s married to affirming, and looks down with a`);
+
+				if (canSee(slave)) {
+					text.push(`smile, running ${his} eyes over your ${bosom}.`);
+				} else {
+					text.push(`smile.`);
+				}
+			} else if (slave.devotion < -20 && slave.trust > 20) {
+				text.push(`${He} complies. Once ${he}'s close, you take your reluctant ${wife}'s head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s forcibly married to disturbing, and`);
+
+				if (canSee(slave)) {
+					text.push(`breaks eye contact.`);
+				} else {
+					text.push(`turns ${his} face away.`);
+				}
+			} else if (slave.devotion < -20) {
+				text.push(`${He} complies out of fear. Once ${he}'s close, you take your unwilling ${wife}'s head in your hands and gaze deeply into ${his} teary ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s forcibly married to terrifying, and`);
+
+				if (canSee(slave)) {
+					text.push(`breaks eye contact.`);
+				} else {
+					text.push(`turns ${his} face away.`);
+				}
 			} else {
-				r.push(`turns ${his} face away.`);
+				text.push(`${He} complies obediently. Once ${he}'s close, you take your willing ${wife}'s head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s married to reassuring, and looks down with a slight`);
+
+				if (canSee(slave)) {
+					text.push(`smile, running ${his} eyes over your ${bosom}.`);
+				} else {
+					text.push(`smile.`);
+				}
 			}
+		} else if (slave.devotion > 75) {
+			text.push(`${He} elatedly complies, joyful at being near to you. Once ${he}'s close, you take ${his} completely relaxed head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from ${his} beloved ${getWrittenTitle(slave)} disconcerting, and ${his} eyes flick downward after a moment. ${He} blushes furiously.`);
+		} else if (slave.devotion > 50) {
+			text.push(`${He} dotingly complies, being near you filling ${him} with delight. Once ${he}'s close, you take ${his} completely relaxed head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense attention from ${his} ${getWrittenTitle(slave)} disconcerting, and ${he} looks down after a moment, blushing.`);
+		} else if (slave.devotion > 20) {
+			text.push(`${He} joyfully complies, happy to be near you. Once ${he}'s close, you take ${his} willing head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense attention from ${his} ${getWrittenTitle(slave)} worrying, and ${he} looks down after a moment, blushing nervously.`);
+		} else if (slave.devotion >= -20 && slave.trust >= -20) {
+			text.push(`${He} visibly considers disobedience, but decides that complying with such an apparently harmless order is safe, for now. Once ${he}'s close, you take ${his} head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense attention from ${his} ${getWrittenTitle(slave)} worrying, and ${he} looks down after a moment, ${his} lower lip trembling with nervousness.`);
+		} else if (slave.trust < -20) {
+			text.push(`The command terrifies ${him}, but ${he}'s more frightened still of the consequences of disobedience, and ${he} complies. Once ${he}'s close, you take ${his} trembling head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)} for a moment. ${He} looks down fearfully, and begins to shake with terror, tears streaking down ${his} cheeks.`);
 		} else {
-			r.push(`${He} complies obediently. Once ${he}'s close, you take your willing ${wife}'s head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from the ${womanP} ${he}'s married to reassuring, and looks down with a slight`);
-			if (canSee(slave)) {
-				r.push(`smile, running ${his} eyes over your ${bosom}.`);
-			} else {
-				r.push(`smile.`);
-			}
+			text.push(`${He} pauses, obviously considering whether to resist, but eventually decides to save ${his} strength to fight more onerous orders, and gives in. Once ${he}'s close, you take a moment to gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} stares back, but after a few moments ${he} loses the contest of wills and looks down.`);
 		}
-	} else if (slave.devotion > 75) {
-		r.push(`${He} elatedly complies, joyful at being near to you. Once ${he}'s close, you take ${his} completely relaxed head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense look from ${his} beloved ${getWrittenTitle(slave)} disconcerting, and ${his} eyes flick downward after a moment. ${He} blushes furiously.`);
-	} else if (slave.devotion > 50) {
-		r.push(`${He} dotingly complies, being near you filling ${him} with delight. Once ${he}'s close, you take ${his} completely relaxed head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense attention from ${his} ${getWrittenTitle(slave)} disconcerting, and ${he} looks down after a moment, blushing.`);
-	} else if (slave.devotion > 20) {
-		r.push(`${He} joyfully complies, happy to be near you. Once ${he}'s close, you take ${his} willing head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense attention from ${his} ${getWrittenTitle(slave)} worrying, and ${he} looks down after a moment, blushing nervously.`);
-	} else if (slave.devotion >= -20 && slave.trust >= -20) {
-		r.push(`${He} visibly considers disobedience, but decides that complying with such an apparently harmless order is safe, for now. Once ${he}'s close, you take ${his} head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} finds the intense attention from ${his} ${getWrittenTitle(slave)} worrying, and ${he} looks down after a moment, ${his} lower lip trembling with nervousness.`);
-	} else if (slave.trust < -20) {
-		r.push(`The command terrifies ${him}, but ${he}'s more frightened still of the consequences of disobedience, and ${he} complies. Once ${he}'s close, you take ${his} trembling head in your hands and gaze deeply into ${his} ${App.Desc.eyesColor(slave)} for a moment. ${He} looks down fearfully, and begins to shake with terror, tears streaking down ${his} cheeks.`);
-	} else {
-		r.push(`${He} pauses, obviously considering whether to resist, but eventually decides to save ${his} strength to fight more onerous orders, and gives in. Once ${he}'s close, you take a moment to gaze deeply into ${his} ${App.Desc.eyesColor(slave)}. ${He} stares back, but after a few moments ${he} loses the contest of wills and looks down.`);
-	}
 
-	r.push(`You walk around ${him} and put your hands around ${his} abdomen,`);
-	if (hasAnyLegs(slave)) {
-		r.push(`to gently pull ${him} close towards you`);
-	} else {
-		r.push(`moving close towards ${him} on your desk`);
-	}
-	r.push(`and then wrap your arms around ${his} shoulders.`);
-	if (hasAnyLegs(slave)) {
-		r.push(`When you press your hips against ${hers},`);
-	} else {
-		r.push(`You use your arms to prop ${him} up against you,`);
-	}
-	r.push(``);
-	if (slave.trust > 20) {
-		r.push(`letting ${him} lean while taking the weight of ${him} against you.`);
-	} else {
-		r.push(`${he} tries to lean away from you, pushing against your arms.`);
+		return text.join(' ');
 	}
-	r.push(`You lovingly squeeze ${him} in your long, cradling embrace.`);
-
-	if (slave.boobs < 2600) {
-		if (slave.nipples === "huge") {
-			r.push(`You feel ${his} large, erect nipples against your`);
-		} else if (slave.nipples === "puffy") {
-			r.push(`You feel ${his} erect, puffy nipples against your`);
-		} else if (slave.nipples === "flat") {
-			r.push(`You feel the bumps of ${his} flat nipples against your`);
-		} else if (slave.nipples === "partially inverted") {
-			r.push(`You feel ${his} partially inverted nipples against your`);
-		} else if (slave.nipples === "inverted") {
-			r.push(`You feel ${his} inverted nipples against your`);
-		} else if (slave.nipples === "fuckable") {
-			r.push(`You feel the slits of ${his} nipples against your`);
+
+	function setup() {
+		const text = [];
+
+		text.push(`You walk around ${him} and put your hands around ${his} abdomen,`);
+
+		if (hasAnyLegs(slave)) {
+			text.push(`to gently pull ${him} close towards you`);
 		} else {
-			r.push(`You feel ${his} erect nipples against your`);
+			text.push(`moving close towards ${him} on your desk`);
 		}
-		r.push(`hands as you move your arms down around ${his} breasts.`);
-		if (slave.devotion > 20) {
-			r.push(`You take your time to stay in this position, feeling ${his} heart beat against you. ${He} starts to breathe faster before you keep one arm wrapped around ${him} as you move to ${his} front.`);
+
+		text.push(`and then wrap your arms around ${his} shoulders.`);
+
+		if (hasAnyLegs(slave)) {
+			text.push(`You press your hips against ${hers},`);
 		} else {
-			r.push(`As you move to ${his} front, with one arm still around ${him}, ${he} again tries to break away but you keep ${him} held tightly and you whisper the alternatives to ${him}, reminding ${him}.`);
+			text.push(`You use your arms to prop ${him} up against you,`);
 		}
-		r.push(`You wrap your arms around ${his} back as you press ${his} breasts against your ${bosom}.`);
-	} else {
-		r.push(`${His} massive tits are too large for you to wrap your arms around so you start to wrap your arms around ${his} waist. You feel ${his} heart beat against your chest, ${he} starts to breathe faster as you press ${his} back against your ${bosom}.`);
-	}
 
-	if (slave.fetish === "mindbroken") {
-		r.push(`${His} posture doesn't change. ${He} initially only reacts slightly to your physical touch but eventually ${he} relaxes in the warmth of your embrace against ${him}. You know that this may only be a physiological reaction, nothing more. For a brief moment you think you detect a spark of life in ${his} dull eyes but just as quickly, it is gone. When you stop, ${his} ${App.Desc.eyesColor(slave)} track the movements of your hands briefly but then ${he} stares blankly ahead of ${him}, not understanding what is happening.`);
-	} else if (slave.relationship === -2) {
-		r.push(`In the warmth of your embrace, ${he} turns towards you, ${his} passionate ${App.Desc.eyesColor(slave)} staring intently at your face. ${He} leans closer to you and kisses you as you hold ${him}. ${His} heart beats faster and then gradually slows as ${he} grows accustomed to your body against ${hers}. Eventually, ${he} relaxes totally and ${his} eyes gradually close, melting in your arms. When you finally stop and relax your embrace, ${his} eyes remain closed and ${his} mouth still in a rapturous shape for a moment before ${he} slowly opens ${his} eyes and smiles at you with a blissful look on ${his} face.`);
-		if (hasAnyArms(slave)) {
-			r.push(`${His} hand reaches to your arms and ${he} strokes them longingly.`);
-		}
-		if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${He} slowly opens them and does ${his} best to communicate love with ${his} ${App.Desc.eyesColor(slave)}.`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs that ${he} loves you.`);
+		if (slave.trust > 20) {
+			text.push(`letting ${him} lean while taking the weight of ${him} against you.`);
 		} else {
-			r.push(
-				Spoken(slave, `"I love you, ${Master},"`),
-				`${he} ${say}s dreamily.`
-			);
+			text.push(`but ${he} tries to lean away from you, pushing against your arms.`);
 		}
-		r.push(`${He} looks at you, almost begging you with ${his} eyes that ${he} wants much more than a mere embrace.`);
-	} else if (slave.devotion > 50 && slave.fetish === "dom" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-		r.push(`In your soft, warm embrace, ${he} tries hard to stop ${himself} from losing ${himself} in your arms.`);
-		if (hasAnyArms(slave)) {
-			r.push(`${He} starts to embrace you`);
-			if (hasBothArms(slave)) {
-				r.push(`in ${his} arms`);
+
+		text.push(`You lovingly squeeze ${him} in your long, cradling embrace.`);
+
+		return text.join(' ');
+	}
+
+	function consummation() {
+		const text = [];
+
+		if (slave.boobs < 2600) {
+			if (slave.nipples === "huge") {
+				text.push(`You feel ${his} large, erect nipples against your`);
+			} else if (slave.nipples === "puffy") {
+				text.push(`You feel ${his} erect, puffy nipples against your`);
+			} else if (slave.nipples === "flat") {
+				text.push(`You feel the bumps of ${his} flat nipples against your`);
+			} else if (slave.nipples === "partially inverted") {
+				text.push(`You feel ${his} partially inverted nipples against your`);
+			} else if (slave.nipples === "inverted") {
+				text.push(`You feel ${his} inverted nipples against your`);
+			} else if (slave.nipples === "fuckable") {
+				text.push(`You feel the slits of ${his} nipples against your`);
 			} else {
-				r.push(`with ${his} arm`);
+				text.push(`You feel ${his} erect nipples against your`);
 			}
-			r.push(`as well. When you gently squeeze ${him} in your arms, ${he} breathes more heavily and starts to lovingly squeeze you as well, ${his} tendency towards sexual dominance encouraging ${him} to compete with you in embraces against each other.`);
-		} else {
-			r.push(`When you gently squeeze ${him} in your arms, ${he} breathes more heavily before relaxing against you.`);
-		}
-		r.push(`When you finally stop and relax your embrace, ${his} eyes are closed and ${he}'s smiling blissfully.`);
-		if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${He} slowly opens them and does ${his} best to communicate excitement with ${his} ${App.Desc.eyesColor(slave)}.`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs that ${he} liked that.`);
-		} else {
-			r.push(
-				Spoken(slave, `"I love you, ${Master},"`),
-				`${he} ${say}s cheerfully.`
-			);
-		}
-		r.push(`${He} eagerly looks at you, ${his} eyes almost seem to say that ${he} wants you to give ${his} ${Master} more than a mere hug.`);
-	} else if (slave.devotion > 50) {
-		r.push(`${He} sighs devotedly in your arms and slowly relaxes. ${He} turns towards you, ${his} doting ${App.Desc.eyesColor(slave)} staring intently at your face. You feel ${his} heart beating faster against your chest as you softly squeeze your arms tighter.`);
-		if (hasAnyArms(slave)) {
-			r.push(`${His} ${hasBothArms(slave) ? `hands` : `hand`} reach to your arms and ${he} strokes them longingly as you squeeze.`);
-		}
-		const firm = V.PC.boobsImplant/V.PC.boobs >= .60 ? "firm" : "soft";
-		r.push(`${He} gradually closes ${his} eyes as ${he} leans ${his} body against yours, melting in your warm embrace, and you feel the intense heat from ${his} body against your`);
-		if (V.PC.boobs >= 1400) {
-			r.push(`expansive ${firm} chest.`);
-		} else if (V.PC.boobs >= 1200) {
-			r.push(`huge ${firm} breasts.`);
-		} else if (V.PC.boobs >= 1000) {
-			r.push(`big ${firm} breasts.`);
-		} else if (V.PC.boobs >= 800) {
-			r.push(`soft breasts.`);
-		} else if (V.PC.boobs >= 500) {
-			r.push(`breasts.`);
-		} else if (V.PC.boobs >= 300) {
-			r.push(`small chest.`);
-		} else if (V.PC.title > 0) {
-			r.push(`manly chest.`);
-		} else {
-			r.push(`flat chest.`);
-		}
-		r.push(`When you finally stop,`);
-		if (hasAnyArms(slave)) {
-			r.push(`${he} reaches to your face with ${his} hand and gently strokes your cheek,`);
-		} else {
-			r.push(`${he} turns to you,`);
-		}
-		r.push(`a euphoric look on ${his} ${slave.skin} face.`);
-		if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${He} does ${his} best to communicate devotion with ${his} ${App.Desc.eyesColor(slave)}.`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs that ${he} loves you.`);
-		} else if (slave.accent >= 3) {
-			r.push(`${He} does ${his} best to communicate devotion with ${his} ${App.Desc.eyesColor(slave)}, since ${he}'s not confident in ${his} ability to express it in ${V.language}.`);
-		} else {
-			r.push(
-				Spoken(slave, `"I love you, ${Master}," ${he} `),
-				`${say}s elatedly.`
-			);
-		}
-		r.push(`${He} looks at you longingly, almost as if ${he}'s bursting to say that ${he} wants more than a mere embrace.`);
-	} else if (slave.devotion > 20) {
-		r.push(`${He} willingly gives ${himself} up to your embracing arms. As you are so close to ${him}, you sense considerable uneasiness in the`);
-		if (slave.physicalAge > 30) {
-			r.push(`${woman};`);
-		} else {
-			r.push(`${girl};`);
-		}
-		r.push(`${he}'s doing ${his} duty as a slave by complying with your wishes, and is probably struggling with the mixture of resistance, obedience and perhaps even devotion forced to the forefront of ${his} mind by your soft embrace against ${his} body. ${He} gradually closes ${his} eyes in the feeling of your gentle arms. When you finally stop and relax your embrace, ${his} 
-	${App.Desc.eyesColor(slave)} open to gaze puzzlingly at you. Even though ${he} has accepted life as a sex slave, ${he} looks as though ${he} is unsure of what to make of this non-sexual physical contact.`);
-		if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${His} eyes beg for an answer: is that it?`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs hesitantly, asking if that's it.`);
-		} else {
-			r.push(
-				`${He} asks hesitantly,`,
-				Spoken(slave, `"I-is that it, ${Master}?"`)
-			);
-		}
-	} else if (slave.devotion >= -20 && slave.trust < -20) {
-		r.push(`${He} shakes at your touch fearfully. As you softly press ${his} trembling body against you, ${his} eagerness to avoid punishment leads ${him} to stiffen in your arms. While ${he} continues to shudder, you continue embracing ${him}, enjoying ${his} fear, and the physical intimacy slowly does its work. ${He} starts to relax, ${his} resistance easing and ${his} eyes start to close. When you relax your arms for a moment, ${he} opens ${his} eyes to look at you for a long moment, ${his} eyes darting up to your face, before visibly catching ${himself} with a reminder that ${he}'s a slave and you're ${his} owner.`);
-		if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${His} eyes beg for an answer: is that it?`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs hesitantly, asking if that's it.`);
-		} else {
-			r.push(
-				`${He} asks hesitantly,`,
-				Spoken(slave, `"I-is that it, ${Master}?"`)
-			);
-		}
-	} else if (slave.trust < -50) {
-		r.push(`${He} is nearly frozen with fear, and does not resist as you start to squeeze your arms around ${him}. In fact, ${he} barely reacts at all. ${He} stares at your arms as they continue squeezing, but it's like touching a statue. ${He} is so filled with terror that ${he} remains stiff even as it becomes clear to ${him} you're not going to hurt ${him}. When you bore of embracing the still`);
-		if (slave.physicalAge > 30) {
-			r.push(`${woman}`);
-		} else {
-			r.push(`${girl}`);
-		}
-		r.push(`and release ${him}, ${he} stares at you in utter incomprehension.`);
-		if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${His} eyes beg for an answer: is that it?`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs spastically, begging fearfully to know if that's it.`);
+
+			text.push(`hands as you move your arms down around ${his} breasts.`);
+
+			if (slave.devotion > 20) {
+				text.push(`You take your time to stay in this position, feeling ${his} heart beat against you. ${He} starts to breathe faster before you keep one arm wrapped around ${him} as you move to ${his} front.`);
+			} else {
+				text.push(`As you move to ${his} front, with one arm still around ${him}, ${he} again tries to break away but you keep ${him} held tightly and you whisper the alternatives to ${him}, reminding ${him}.`);
+			}
+			text.push(`You wrap your arms around ${his} back as you press ${his} breasts against your ${bosom}.`);
 		} else {
-			r.push(
-				`${He} asks nervously,`,
-				Spoken(slave, `"I-is that it, ${Master}?"`)
-			);
+			text.push(`${His} massive tits are too large for you to wrap your arms around so you start to wrap your arms around ${his} waist. You feel ${his} heart beat against your chest, ${he} starts to breathe faster as you press ${his} back against your ${bosom}.`);
 		}
-		r.push(`Then ${he} cringes, unsure of what you are going to do next.`);
-	} else {
-		r.push(`${He} reflexively tries to break free from your arms, but you keep ${him} wrapped in them. Shuddering, ${he} desperately leans away from you, but you tip forward with ${him} and pin ${him} against your desk, continuing your hold on ${him}. ${He} tries to wriggle out of your grasp desperately, but ${his} struggles slowly subside as ${he} realizes that you're not taking this any farther. When you bore of it and release ${him}, ${he} stares at you in utter incomprehension.`);
-		if (!hasAnyArms(slave) && !canTalk(slave)) {
-			r.push(`${His} eyes demand an answer: is that it?`);
-		} else if (!canTalk(slave)) {
-			r.push(`${He} signs irritably, asking whether that's it.`);
+
+		return text.join(' ');
+	}
+
+	function aftermath() {
+		const text = [];
+
+		if (slave.fetish === "mindbroken") {
+			text.push(`${His} posture doesn't change. ${He} initially only reacts slightly to your physical touch but eventually ${he} relaxes in the warmth of your embrace against ${him}. You know that this may only be a physiological reaction, nothing more. For a brief moment you think you detect a spark of life in ${his} dull eyes but just as quickly, it is gone. When you stop, ${his} ${App.Desc.eyesColor(slave)} track the movements of your hands briefly but then ${he} stares blankly ahead of ${him}, not understanding what is happening.`);
+		} else if (slave.relationship === -2) {
+			text.push(`In the warmth of your embrace, ${he} turns towards you, ${his} passionate ${App.Desc.eyesColor(slave)} staring intently at your face. ${He} leans closer to you and kisses you as you hold ${him}. ${His} heart beats faster and then gradually slows as ${he} grows accustomed to your body against ${hers}. Eventually, ${he} relaxes totally and ${his} eyes gradually close, melting in your arms. When you finally stop and relax your embrace, ${his} eyes remain closed and ${his} mouth still in a rapturous shape for a moment before ${he} slowly opens ${his} eyes and smiles at you with a blissful look on ${his} face.`);
+
+			if (hasAnyArms(slave)) {
+				text.push(`${His} hand reaches to your arms and ${he} strokes them longingly.`);
+			}
+
+			if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${He} slowly opens them and does ${his} best to communicate love with ${his} ${App.Desc.eyesColor(slave)}.`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs that ${he} loves you.`);
+			} else {
+				text.push(`${Spoken(slave, `"I love you, ${Master},"`)} ${he} ${say}s dreamily.`);
+			}
+
+			text.push(`${He} looks at you, almost begging you with ${his} eyes that ${he} wants much more than a mere embrace.`);
+		} else if (slave.devotion > 50 && slave.fetish === "dom" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
+			text.push(`In your soft, warm embrace, ${he} tries hard to stop ${himself} from losing ${himself} in your arms.`);
+
+			if (hasAnyArms(slave)) {
+				text.push(`${He} starts to embrace you`);
+
+				if (hasBothArms(slave)) {
+					text.push(`in ${his} arms`);
+				} else {
+					text.push(`with ${his} arm`);
+				}
+
+				text.push(`as well. When you gently squeeze ${him} in your arms, ${he} breathes more heavily and starts to lovingly squeeze you as well, ${his} tendency towards sexual dominance encouraging ${him} to compete with you in embraces against each other.`);
+			} else {
+				text.push(`When you gently squeeze ${him} in your arms, ${he} breathes more heavily before relaxing against you.`);
+			}
+
+			text.push(`When you finally stop and relax your embrace, ${his} eyes are closed and ${he}'s smiling blissfully.`);
+
+			if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${He} slowly opens them and does ${his} best to communicate excitement with ${his} ${App.Desc.eyesColor(slave)}.`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs that ${he} liked that.`);
+			} else {
+				text.push(`${Spoken(slave, `"I love you, ${Master},"`)} ${he} ${say}s cheerfully.`);
+			}
+
+			text.push(`${He} eagerly looks at you, ${his} eyes almost seem to say that ${he} wants you to give ${his} ${Master} more than a mere hug.`);
+		} else if (slave.devotion > 50) {
+			text.push(`${He} sighs devotedly in your arms and slowly relaxes. ${He} turns towards you, ${his} doting ${App.Desc.eyesColor(slave)} staring intently at your face. You feel ${his} heart beating faster against your chest as you softly squeeze your arms tighter.`);
+
+			if (hasAnyArms(slave)) {
+				text.push(`${His} ${hasBothArms(slave) ? `hands` : `hand`} reach to your arms and ${he} strokes them longingly as you squeeze.`);
+			}
+
+			const firm = V.PC.boobsImplant/V.PC.boobs >= .60 ? "firm" : "soft";
+			text.push(`${He} gradually closes ${his} eyes as ${he} leans ${his} body against yours, melting in your warm embrace, and you feel the intense heat from ${his} body against your`);
+
+			if (V.PC.boobs >= 1400) {
+				text.push(`expansive ${firm} chest.`);
+			} else if (V.PC.boobs >= 1200) {
+				text.push(`huge ${firm} breasts.`);
+			} else if (V.PC.boobs >= 1000) {
+				text.push(`big ${firm} breasts.`);
+			} else if (V.PC.boobs >= 800) {
+				text.push(`soft breasts.`);
+			} else if (V.PC.boobs >= 500) {
+				text.push(`breasts.`);
+			} else if (V.PC.boobs >= 300) {
+				text.push(`small chest.`);
+			} else if (V.PC.title > 0) {
+				text.push(`manly chest.`);
+			} else {
+				text.push(`flat chest.`);
+			}
+
+			text.push(`When you finally stop,`);
+
+			if (hasAnyArms(slave)) {
+				text.push(`${he} reaches to your face with ${his} hand and gently strokes your cheek,`);
+			} else {
+				text.push(`${he} turns to you,`);
+			}
+
+			text.push(`a euphoric look on ${his} ${slave.skin} face.`);
+
+			if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${He} does ${his} best to communicate devotion with ${his} ${App.Desc.eyesColor(slave)}.`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs that ${he} loves you.`);
+			} else if (slave.accent >= 3) {
+				text.push(`${He} does ${his} best to communicate devotion with ${his} ${App.Desc.eyesColor(slave)}, since ${he}'s not confident in ${his} ability to express it in ${V.language}.`);
+			} else {
+				text.push(`${Spoken(slave, `"I love you, ${Master}," ${he} `)} ${say}s elatedly.`);
+			}
+
+			text.push(`${He} looks at you longingly, almost as if ${he}'s bursting to say that ${he} wants more than a mere embrace.`);
+		} else if (slave.devotion > 20) {
+			text.push(`${He} willingly gives ${himself} up to your embracing arms. As you are so close to ${him}, you sense considerable uneasiness in the`);
+
+			if (slave.physicalAge > 30) {
+				text.push(`${woman};`);
+			} else {
+				text.push(`${girl};`);
+			}
+
+			text.push(`${he}'s doing ${his} duty as a slave by complying with your wishes, and is probably struggling with the mixture of resistance, obedience and perhaps even devotion forced to the forefront of ${his} mind by your soft embrace against ${his} body. ${He} gradually closes ${his} eyes in the feeling of your gentle arms. When you finally stop and relax your embrace, ${his} ${App.Desc.eyesColor(slave)} open to gaze puzzlingly at you. Even though ${he} has accepted life as a sex slave, ${he} looks as though ${he} is unsure of what to make of this non-sexual physical contact.`);
+
+			if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${His} eyes beg for an answer: is that it?`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs hesitantly, asking if that's it.`);
+			} else {
+				text.push(`${He} asks hesitantly, ${Spoken(slave, `"I-is that it, ${Master}?"`)}`);
+			}
+		} else if (slave.devotion >= -20 && slave.trust < -20) {
+			text.push(`${He} shakes at your touch fearfully. As you softly press ${his} trembling body against you, ${his} eagerness to avoid punishment leads ${him} to stiffen in your arms. While ${he} continues to shudder, you continue embracing ${him}, enjoying ${his} fear, and the physical intimacy slowly does its work. ${He} starts to relax, ${his} resistance easing and ${his} eyes start to close. When you relax your arms for a moment, ${he} opens ${his} eyes to look at you for a long moment, ${his} eyes darting up to your face, before visibly catching ${himself} with a reminder that ${he}'s a slave and you're ${his} owner.`);
+
+			if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${His} eyes beg for an answer: is that it?`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs hesitantly, asking if that's it.`);
+			} else {
+				text.push(`${He} asks hesitantly, ${Spoken(slave, `"I-is that it, ${Master}?"`)}`);
+			}
+		} else if (slave.trust < -50) {
+			text.push(`${He} is nearly frozen with fear, and does not resist as you start to squeeze your arms around ${him}. In fact, ${he} barely reacts at all. ${He} stares at your arms as they continue squeezing, but it's like touching a statue. ${He} is so filled with terror that ${he} remains stiff even as it becomes clear to ${him} you're not going to hurt ${him}. When you bore of embracing the still`);
+
+			if (slave.physicalAge > 30) {
+				text.push(`${woman}`);
+			} else {
+				text.push(`${girl}`);
+			}
+
+			text.push(`and release ${him}, ${he} stares at you in utter incomprehension.`);
+
+			if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${His} eyes beg for an answer: is that it?`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs spastically, begging fearfully to know if that's it.`);
+			} else {
+				text.push(`${He} asks nervously, ${Spoken(slave, `"I-is that it, ${Master}?"`)}`);
+			}
+
+			text.push(`Then ${he} cringes, unsure of what you are going to do next.`);
 		} else {
-			r.push(
-				`${He} splutters,`,
-				Spoken(slave, `"Is that it, ${Master}!?"`)
-			);
+			text.push(`${He} reflexively tries to break free from your arms, but you keep ${him} wrapped in them. Shuddering, ${he} desperately leans away from you, but you tip forward with ${him} and pin ${him} against your desk, continuing your hold on ${him}. ${He} tries to wriggle out of your grasp desperately, but ${his} struggles slowly subside as ${he} realizes that you're not taking this any farther. When you bore of it and release ${him}, ${he} stares at you in utter incomprehension.`);
+
+			if (!hasAnyArms(slave) && !canTalk(slave)) {
+				text.push(`${His} eyes demand an answer: is that it?`);
+			} else if (!canTalk(slave)) {
+				text.push(`${He} signs irritably, asking whether that's it.`);
+			} else {
+				text.push(`${He} splutters, ${Spoken(slave, `"Is that it, ${Master}!?"`)}`);
+			}
+
+			text.push(`${He} shakes uncontrollably, apprehensive at what you are going to do next.`);
 		}
-		r.push(`${He} shakes uncontrollably, apprehensive at what you are going to do next.`);
+
+		return text.join(' ');
 	}
-	App.Events.addParagraph(node, r);
-	return node;
 };
diff --git a/src/npc/interaction/fFeelings.js b/src/npc/interaction/fFeelings.js
index ca6ebbf5ad8eff95eace6a619230b433a0380bc9..134e5c6e6a8f4df940d39b1d578c8b6f305a88d6 100644
--- a/src/npc/interaction/fFeelings.js
+++ b/src/npc/interaction/fFeelings.js
@@ -1,2186 +1,2329 @@
+// TODO: expand this to have slaves with low devotion / trust speak more
+
 /**
  *
  * @param {App.Entity.SlaveState} slave
  * @returns {DocumentFragment}
  */
-App.Interact.feelings = function(slave) {
-	/* Slaves are expected to be either able to talk or to sign when entering this passage. */
-	const el = new DocumentFragment();
-	let r = [];
+App.Interact.fFeelings = function(slave) {
+	const frag = new DocumentFragment();
+
 	const {
 		He,
 		he, his, him, wife, woman, girl
 	} = getPronouns(slave);
-	const {title: Master, say: say} = getEnunciation(slave);
-	if (!canTalk(slave) && !hasAnyArms(slave)) {
-		r.push(`${slave.slaveName} is unable to communicate and thus this place should have been unreachable. Please report this.`);
+
+	const {title: Master, say} = getEnunciation(slave);
+
+	const lisps = canTalk(slave) && SlaveStatsChecker.checkForLisp(slave);
+
+	const text = new SpacedTextAccumulator(frag);
+	text.push(
+		intro(),
+		setup(),
+	);
+
+	if (slave.devotion > 20) {
+		text.push(
+			consummation(),
+			aftermath(),
+		);
 	}
-	const willLisp = canTalk(slave) && SlaveStatsChecker.checkForLisp(slave);
 
-	/* TODO: clean up this passage - lots of repeating blocks */
-	if (slave.devotion < -50) {
-		r.push(`${He}`);
-		if (slave.trust >= -20) {
-			if (!canTalk(slave)) {
-				r.push(`gestures`);
-			} else if (willLisp) {
-				r.push(`lisps`);
-			} else {
-				r.push(`declares`);
-			}
-			r.push(`angrily that it's wrong to keep ${him} a slave, and that you should free ${him}.`);
-		} else if (slave.trust >= -50) {
-			if (!canTalk(slave)) {
-				r.push(`gestures`);
-			} else if (willLisp) {
-				r.push(`lisps`);
-			} else {
-				r.push(`mutters`);
-			}
-			r.push(`hesitantly that it's wrong to keep ${him} a slave, and that you should free ${him}.`);
-		} else {
-			if (!canTalk(slave)) {
-				r.push(`gestures a perfunctory plea not to hurt ${him}.`);
+	text.toParagraph();
+
+	return frag;
+
+	function intro() {
+		return `The next time you see ${him} you ask ${him}, in a voice that brooks no dishonesty, how ${he} really feels about you and life as a slave.`;
+	}
+
+	function setup() {
+		const text = [];
+
+		if (slave.devotion < -50) {
+			text.push(`${He}`);
+
+			if (slave.trust >= -20) {
+				if (!canTalk(slave)) {
+					text.push(`gestures`);
+				} else if (lisps) {
+					text.push(`lisps`);
+				} else {
+					text.push(`declares`);
+				}
+
+				text.push(`angrily that it's wrong to keep ${him} a slave, and that you should free ${him}.`);
+			} else if (slave.trust >= -50) {
+				if (!canTalk(slave)) {
+					text.push(`gestures`);
+				} else if (lisps) {
+					text.push(`lisps`);
+				} else {
+					text.push(`mutters`);
+				}
+
+				text.push(`hesitantly that it's wrong to keep ${him} a slave, and that you should free ${him}.`);
 			} else {
-				r.push(`mutters a perfunctory`);
-				r.push(Spoken(slave, `"Please don't hurt me, ${(slave.rudeTitle === 1) ? PoliteRudeTitle(slave) : Master}."`));
+				if (!canTalk(slave)) {
+					text.push(`gestures a perfunctory plea not to hurt ${him}.`);
+				} else {
+					text.push(`mutters a perfunctory ${Spoken(slave, `"Please don't hurt me, ${(slave.rudeTitle === 1) ? PoliteRudeTitle(slave) : Master}."`)}`);
+				}
 			}
-		}
-	} else if (slave.devotion < -20) {
-		r.push(`${He}`);
-		if (!canTalk(slave)) {
-			r.push(`gestures`);
-		} else if (willLisp) {
-			r.push(`lisps`);
-		} else {
-			r.push(`mutters`);
-		}
-		if (slave.trust >= -20) {
-			r.push(`hesitantly that ${he} does not like being a slave, and then`);
+		} else if (slave.devotion < -20) {
+			text.push(`${He}`);
+
 			if (!canTalk(slave)) {
-				r.push(`lets ${his} ${(hasBothArms(slave)) ? `hands` : `hand`} fall to ${his} sides.`);
+				text.push(`gestures`);
+			} else if (lisps) {
+				text.push(`lisps`);
 			} else {
-				r.push(`falls silent.`);
+				text.push(`mutters`);
 			}
-		} else if (slave.trust >= -50) {
-			r.push(`fearfully that ${he} does not like being a slave, and then`);
-			if (!canTalk(slave)) {
-				r.push(`lets ${his} ${(hasBothArms(slave)) ? `hands` : `hand`} fall to ${his} sides, shaking a little.`);
+
+			if (slave.trust >= -20) {
+				text.push(`hesitantly that ${he} does not like being a slave, and then`);
+
+				if (!canTalk(slave)) {
+					text.push(`lets ${his} ${(hasBothArms(slave)) ? `hands` : `hand`} fall to ${his} sides.`);
+				} else {
+					text.push(`falls silent.`);
+				}
+			} else if (slave.trust >= -50) {
+				text.push(`fearfully that ${he} does not like being a slave, and then`);
+
+				if (!canTalk(slave)) {
+					text.push(`lets ${his} ${(hasBothArms(slave)) ? `hands` : `hand`} fall to ${his} sides, shaking a little.`);
+				} else {
+					text.push(`falls silent, shaking a little.`);
+				}
 			} else {
-				r.push(`falls silent, shaking a little.`);
+				text.push(`a perfunctory`);
+
+				if (!canTalk(slave)) {
+					text.push(`plea not to hurt ${him}.`);
+				} else {
+					text.push(`${Spoken(slave, `"Please don't hurt me, ${Master}."`)}`);
+				}
 			}
-		} else {
-			r.push(`a perfunctory`);
+		} else if (slave.devotion <= 20) {
+			text.push(`${He}`);
+
 			if (!canTalk(slave)) {
-				r.push(`plea not to hurt ${him}.`);
+				text.push(`gestures`);
 			} else {
-				r.push(Spoken(slave, `"Please don't hurt me, ${Master}."`));
+				text.push(`${say}s`);
 			}
-		}
-	} else if (slave.devotion <= 20) {
-		r.push(`${He}`);
-		if (!canTalk(slave)) {
-			r.push(`gestures`);
-		} else {
-			r.push(`${say}s`);
-		}
-		if (slave.trust >= -20) {
-			r.push(`earnestly`);
-		} else if (slave.trust >= -50) {
-			r.push(`fearfully`);
-		} else {
-			r.push(`shakily`);
-		}
-		r.push(`that ${he} will do whatever you order ${him} to, since ${he} does not want to be`);
-		switch (slave.rules.punishment) {
-			case "confinement":
-				r.push(`shut up in the dark, which is of course ${his} standard punishment.`);
-				break;
-			case "whipping":
-				r.push(`whipped, which is of course ${his} standard punishment.`);
-				break;
-			case "chastity":
-				r.push(`put in restrictive chastity, which is of course ${his} standard punishment.`);
-				break;
-			default:
-				r.push(`punished, not knowing what to expect when ${he}'s bad.`);
-				break;
-		}
-		r.push(`Once ${he} learns to accept slavery, ${he} will be better able to open up.`);
-	} else {
-		if (slave.devotion <= 50) {
-			if (!canTalk(slave)) {
-				r.push(`${He} gestures that you're ${his} ${getWrittenTitle(slave)}, and ${he} will do ${his} best to obey you. ${He} continues to sign${(slave.accent === 3 && slave.voice !== 0) ? `, using gestures to supplant ${his} poor ${V.language}` : ``}:`);
+
+			if (slave.trust >= -20) {
+				text.push(`earnestly`);
+			} else if (slave.trust >= -50) {
+				text.push(`fearfully`);
 			} else {
-				r.push(Spoken(slave, `"You're my ${Master}, and I'll do my best to obey you,"`));
-				r.push(`${he} ${say}s.`);
+				text.push(`shakily`);
 			}
-		} else if (slave.devotion <= 95) {
-			if (!canTalk(slave)) {
-				r.push(`${He} gestures that you're ${his} beloved ${Master}. ${He} continues to sign${(slave.accent === 3) ? `, using gestures to supplant ${his} poor ${V.language}` : ``}:`);
-			} else {
-				r.push(Spoken(slave, `"${(slave.relationship === -3) ? `I'm content with being your ${wife},` : `You're`} my beloved ${Master}, and you know what's best for me,"`));
-				r.push(`${he} ${say}s.`);
+
+			text.push(`that ${he} will do whatever you order ${him} to, since ${he} does not want to be`);
+
+			switch (slave.rules.punishment) {
+				case "confinement":
+					text.push(`shut up in the dark, which is of course ${his} standard punishment.`);
+					break;
+				case "whipping":
+					text.push(`whipped, which is of course ${his} standard punishment.`);
+					break;
+				case "chastity":
+					text.push(`put in restrictive chastity, which is of course ${his} standard punishment.`);
+					break;
+				default:
+					text.push(`punished, not knowing what to expect when ${he}'s bad.`);
+					break;
 			}
+
+			text.push(`Once ${he} learns to accept slavery, ${he} will be better able to open up.`);
 		} else {
-			if (!canTalk(slave)) {
-				r.push(`${He} makes a simple gesture, meaning "I love you." ${He} continues to sign${(slave.accent === 3) ? `, using gestures to supplant ${his} poor ${V.language}` : ``}:`);
+			if (slave.devotion <= 50) {
+				if (!canTalk(slave)) {
+					text.push(`${He} gestures that you're ${his} ${getWrittenTitle(slave)}, and ${he} will do ${his} best to obey you. ${He} continues to sign${(slave.accent === 3 && slave.voice !== 0) ? `, using gestures to supplant ${his} poor ${V.language}` : ``}:`);
+				} else {
+					text.push(`${Spoken(slave, `"You're my ${Master}, and I'll do my best to obey you,"`)} ${he} ${say}s.`);
+				}
+			} else if (slave.devotion <= 95) {
+				if (!canTalk(slave)) {
+					text.push(`${He} gestures that you're ${his} beloved ${Master}. ${He} continues to sign${(slave.accent === 3) ? `, using gestures to supplant ${his} poor ${V.language}` : ``}:`);
+				} else {
+					text.push(`${Spoken(slave, `"${(slave.relationship === -3) ? `I'm content with being your ${wife},` : `You're`} my beloved ${Master}, and you know what's best for me,"`)} ${he} ${say}s.`);
+				}
 			} else {
-				r.push(Spoken(slave, `"I love you,"`));
-				r.push(`${he} ${say}s in ${his}`);
-				if (slave.voice === 1) {
-					if (slave.voiceImplant < 0) {
-						r.push(`guttural`);
-					} else {
-						r.push(`deep`);
-					}
-				} else if (slave.voice === 2) {
-					r.push(`pretty`);
+				if (!canTalk(slave)) {
+					text.push(`${He} makes a simple gesture, meaning "I love you." ${He} continues to sign${(slave.accent === 3) ? `, using gestures to supplant ${his} poor ${V.language}` : ``}:`);
 				} else {
-					if (slave.voiceImplant > 0) {
-						r.push(`high bimbo`);
+					text.push(`${Spoken(slave, `"I love you,"`)} ${he} ${say}s in ${his}`);
+
+					if (slave.voice === 1) {
+						if (slave.voiceImplant < 0) {
+							text.push(`guttural`);
+						} else {
+							text.push(`deep`);
+						}
+					} else if (slave.voice === 2) {
+						text.push(`pretty`);
 					} else {
-						r.push(`girly`);
+						if (slave.voiceImplant > 0) {
+							text.push(`high bimbo`);
+						} else {
+							text.push(`girly`);
+						}
 					}
+
+					text.push(`voice.`);
 				}
-				r.push(`voice.`);
 			}
 		}
-		App.Events.addNode(el, r, "span");
-
-		// Begin block of mostly "Spoken()".
-		r = [];
-		if (slave.trust < -50) {
-			r.push(`"I'm terrified of you.`);
-		} else if (slave.trust < -20) {
-			r.push(`"You frighten me, sometimes.`);
-		} else if (slave.trust < 20) {
-			r.push(`"I know you have total power over me.`);
-		} else if (slave.trust < 50) {
-			r.push(`"You know what's best for me.`);
-		} else if (slave.trust < 95) {
-			r.push(`"I trust you to know what's best for me.`);
-		} else {
-			r.push(`"I trust you completely.`);
-		}
 
-		if (slave.rules.speech === "restrictive") {
-			if (slave.devotion > 20) {
-				r.push(`Thank you so much for a chance to talk a little, ${Master}. I understand why I must be silent, but it's nice to get the chance.`);
+		return text.join(' ');
+	}
+
+	function consummation() {
+		const text = [];
+
+		const spoken = [
+			trust(),
+			speech(),
+			health(),
+			pregnancy(),
+			fetish(),
+			sexuality(),
+			favoriteBodyPart(),
+			futa(),
+			need(),
+			favoritePCBodyPart(),
+		]
+			.filter(t => t !== ``)
+			.map(t => Spoken(slave, t));
+
+		text.push(
+			...spoken,
+			fantasies(),
+			hormones(),
+			curatives(),
+			inflation(),
+			diet(),
+			drugs(),
+			assignment(),
+			skills(),
+			relationships(),
+			FS(),
+			devotion(),
+		);
+
+		return text.join(' ');
+
+		function trust() {
+			if (slave.trust < -50) {
+				return `"I'm terrified of you.`;
+			} else if (slave.trust < -20) {
+				return `"You frighten me, sometimes.`;
+			} else if (slave.trust < 20) {
+				return `"I know you have total power over me.`;
+			} else if (slave.trust < 50) {
+				return `"You know what's best for me.`;
+			} else if (slave.trust < 95) {
+				return `"I trust you to know what's best for me.`;
 			} else {
-				r.push(`Thank you so much for a chance to talk a little, ${Master}. It's hard, never speaking.`);
+				return `"I trust you completely.`;
 			}
 		}
 
-		if (slave.devotion > 50 && slave.health.condition < -20) {
-			r.push(`I feel`);
-			if (slave.health.condition < -50) {
-				r.push(`really`);
-			}
-			r.push(`sick, ${Master}.`);
-			if (slave.trust > 20) {
-				r.push(`I wish you could give me something to ease the pain.`);
-			}
-		}
-		if (slave.devotion > 20 && slave.devotion <= 90 && slave.trust >= -20 && slave.fetish !== "pregnancy" && slave.bellyPreg > (slave.pregAdaptation * 2000)) {
-			if (slave.belly > (slave.pregAdaptation * 4500)) {
-				r.push(`${Master}, my body is full...`);
-				if (slave.geneticQuirks.uterineHypersensitivity === 2) {
-					r.push(`I can't fit anymore... So than why does every near rupture feel so fucking good?`);
-				} else if (slave.sexualFlaw === "self hating") {
-					r.push(`I surely couldn't even`);
-					if (V.PC.dick > 2) {
-						r.push(`find room to fit your dick in me right now.`);
-					} else if (V.PC.dick === 0) {
-						r.push(`find room to stick that hulking strap-on in me right now.`);
-					} else {
-						r.push(`fit the slightest amount more inside me right now; even you'll feel positively enormous in me.`);
-					}
-					r.push(`Maybe you should just shove me down and force it in? Send me right over the edge? Please?`);
+		function speech() {
+			if (slave.rules.speech === "restrictive") {
+				if (slave.devotion > 20) {
+					return `Thank you so much for a chance to talk a little, ${Master}. I understand why I must be silent, but it's nice to get the chance.`;
 				} else {
-					r.push(`I'm just going to explode at some point, aren't I?`);
+					return `Thank you so much for a chance to talk a little, ${Master}. It's hard, never speaking.`;
 				}
-			} else if (slave.belly > (slave.pregAdaptation * 3200)) {
-				r.push(`My body feels full,`);
-				if (slave.geneticQuirks.uterineHypersensitivity === 2) {
-					r.push(`like a balloon ready to explode into the biggest orgasm I've ever had. Am I losing my mind?`);
-				} else {
-					r.push(`almost like I'm going to pop if I get any bigger. ${Master}, am... am I going to be alright?`);
+			}
+
+			return ``;
+		}
+
+		function health() {
+			const text = [];
+
+			if (slave.devotion > 50 && slave.health.condition < -20) {
+				text.push(`I feel`);
+
+				if (slave.health.condition < -50) {
+					text.push(`really`);
 				}
-			} else {
-				r.push(`My body feels tight, like really tight.`);
-				if (slave.geneticQuirks.uterineHypersensitivity === 2) {
-					r.push(`And kind of good, like I'm could come at any moment.`);
-				} else {
-					r.push(`I get that I'm super pregnant, but should it hurt like this?`);
+
+				text.push(`sick, ${Master}.`);
+
+				if (slave.trust > 20) {
+					text.push(`I wish you could give me something to ease the pain.`);
 				}
 			}
+
+			return text.join(' ');
 		}
 
-		if (slave.fetishKnown === 1) {
-			if (slave.energy > 95) {
-				r.push(`I love being your nympho slut.`);
-			} else if (slave.fetishStrength > 60) {
-				switch (slave.fetish) {
-					case "submissive":
-						r.push(`I love it when you use me.`);
-						break;
-					case "dom":
-						r.push(`I love fucking the other slaves.`);
-						break;
-					case "sadist":
-						r.push(`I love hurting the other slaves.`);
-						break;
-					case "masochist":
-						r.push(`I love it when you hurt me.`);
-						break;
-					case "cumslut":
-						r.push(`I love`);
-						if (V.PC.dick !== 0) {
-							r.push(`sucking on your cock${(V.PC.vagina !== -1) ? ` and eating you out` : ``}.`);
-						} else {
-							r.push(`eating you out.`);
-						}
-						break;
-					case "humiliation":
-						r.push(`I love it when you use me in public.`);
-						break;
-					case "buttslut":
-						r.push(`I love it when you use my ass.`);
-						break;
-					case "pregnancy":
-						if (slave.counter.births > 0) {
-							r.push(`I love being your breeder.`);
-						} else if (slave.counter.birthsTotal > 0) {
-							r.push(`I love being bred.`);
+		function pregnancy() {
+			const text = [];
+
+			if (slave.devotion > 20 && slave.devotion <= 90 && slave.trust >= -20 && slave.fetish !== "pregnancy" && slave.bellyPreg > (slave.pregAdaptation * 2000)) {
+				if (slave.belly > (slave.pregAdaptation * 4500)) {
+					text.push(`${Master}, my body is full...`);
+
+					if (slave.geneticQuirks.uterineHypersensitivity === 2) {
+						text.push(`I can't fit anymore... So than why does every near rupture feel so fucking good?`);
+					} else if (slave.sexualFlaw === "self hating") {
+						text.push(`I surely couldn't even`);
+
+						if (V.PC.dick > 2) {
+							text.push(`find room to fit your dick in me right now.`);
+						} else if (V.PC.dick === 0) {
+							text.push(`find room to stick that hulking strap-on in me right now.`);
 						} else {
-							r.push(`I can't wait to be bred.`);
+							text.push(`fit the slightest amount more inside me right now; even you'll feel positively enormous in me.`);
 						}
-						break;
-					case "boobs":
-						r.push(`I love it when you pinch my nipples.`);
-						break;
-					default:
-						r.push(`It's boring of me, ${Master}, but I really do love normal sex.`);
+
+						text.push(`Maybe you should just shove me down and force it in? Send me right over the edge? Please?`);
+					} else {
+						text.push(`I'm just going to explode at some point, aren't I?`);
+					}
+				} else if (slave.belly > (slave.pregAdaptation * 3200)) {
+					text.push(`My body feels full,`);
+
+					if (slave.geneticQuirks.uterineHypersensitivity === 2) {
+						text.push(`like a balloon ready to explode into the biggest orgasm I've ever had. Am I losing my mind?`);
+					} else {
+						text.push(`almost like I'm going to pop if I get any bigger. ${Master}, am... am I going to be alright?`);
+					}
+				} else {
+					text.push(`My body feels tight, like really tight.`);
+
+					if (slave.geneticQuirks.uterineHypersensitivity === 2) {
+						text.push(`And kind of good, like I'm could cum at any moment.`);
+					} else {
+						text.push(`I get that I'm super pregnant, but should it hurt like this?`);
+					}
 				}
 			}
+
+			return text.join(' ');
 		}
-		if (slave.attrKnown === 1) {
-			if (slave.attrXX > 80) {
-				r.push(`I love fucking the other girls.`);
-			} else if (slave.attrXX > 60) {
-				r.push(`It's nice, fucking the other girls.`);
+
+		function fetish() {
+			const text = [];
+
+			if (slave.fetishKnown === 1) {
+				if (slave.energy > 95) {
+					return `I love being your nympho slut.`;
+				} else if (slave.fetishStrength > 60) {
+					switch (slave.fetish) {
+						case "submissive":
+							return `I love it when you use me.`;
+						case "dom":
+							return `I love fucking the other slaves.`;
+						case "sadist":
+							return `I love hurting the other slaves.`;
+						case "masochist":
+							return `I love it when you hurt me.`;
+						case "cumslut":
+							text.push(`I love`);
+							if (V.PC.dick !== 0) {
+								text.push(`sucking on your cock${(V.PC.vagina !== -1) ? ` and eating you out` : ``}.`);
+							} else {
+								text.push(`eating you out.`);
+							}
+
+							return text.join(' ');
+						case "humiliation":
+							return `I love it when you use me in public.`;
+						case "buttslut":
+							return `I love it when you use my ass.`;
+						case "pregnancy":
+							if (slave.counter.births > 0) {
+								return `I love being your breeder.`;
+							} else if (slave.counter.birthsTotal > 0) {
+								return `I love being bred.`;
+							} else {
+								return `I can't wait to be bred.`;
+							}
+						case "boobs":
+							return `I love it when you pinch my nipples.`;
+						default:
+							return `It's boring of me, ${Master}, but I really do love normal sex.`;
+					}
+				}
 			}
-			if (slave.attrXY > 80 && V.seeDicks > 0) {
-				r.push(`I love spending time with slaves with dicks, ${Master}.`);
-			} else if (slave.attrXY > 60 && V.seeDicks > 0) {
-				r.push(`It's nice, spending time with slaves with dicks, ${Master}.`);
+
+			return text.join(' ');
+		}
+
+		function sexuality() {
+			const text = [];
+
+			if (slave.attrKnown === 1) {
+				if (slave.attrXX > 80) {
+					text.push(`I love fucking the other girls.`);
+				} else if (slave.attrXX > 60) {
+					text.push(`It's nice, fucking the other girls.`);
+				}
+
+				if (slave.attrXY > 80 && V.seeDicks > 0) {
+					text.push(`I love spending time with slaves with dicks, ${Master}.`);
+				} else if (slave.attrXY > 60 && V.seeDicks > 0) {
+					text.push(`It's nice, spending time with slaves with dicks, ${Master}.`);
+				}
+			} else {
+				text.push(`I wish I understood my own sexuality better.`);
 			}
-		} else {
-			r.push(`I wish I understood my own sexuality better.`);
+
+			return text.join(' ');
 		}
 
-		r.push(`My favorite part of my body`);
-		if (slave.fetishKnown === 1) {
-			if (slave.sexualFlaw === "neglectful" && slave.fetishStrength > 95) {
-				r.push(`is unimportant, ${Master}. What part of me do <span class="note">you</span> like? N-not that I'm telling you that you need to like me! I'm just so happy when you're happy.`);
-			} else if (slave.sexualFlaw === "malicious" && slave.fetishStrength > 95 && slave.muscles > 30) {
-				r.push(`is my muscles, I like how I can use them to force the slutty bitches around here to do what I want. The way they squeal when I flex what I've got gets me hot every time.`);
-			} else if (slave.sexualFlaw === "abusive" && slave.fetishStrength > 95 && slave.muscles > 30) {
-				r.push(`is my muscles. I like how I can use them to hurt the other slaves, ${Master}. The way they cry, their tears, their blood. How long has it been since I beat a bitch senseless? I can't wait to work out some stress on my next toy.`);
-			} else if (slave.sexualFlaw === "self hating" && slave.fetishStrength > 95) {
-				r.push(`is my blood. It's so pretty and red, and there's so much of it when you and the other slaves <span class="note">really</span> lay into me. I'm so fucking hot right now, thinking about the things you can do to my slutty body.`);
-			} else if (slave.sexualFlaw === "cum addict" && slave.fetishStrength > 95) {
-				if (slave.lips > 40) {
-					r.push(`is my`);
-					if (slave.lips > 70) {
-						r.push(`huge`);
+		function favoriteBodyPart() {
+			const text = [];
+
+			text.push(`My favorite part of my body`);
+
+			if (slave.fetishKnown === 1) {
+				if (slave.sexualFlaw === "neglectful" && slave.fetishStrength > 95) {
+					text.push(`is unimportant, ${Master}. What part of me do <span class="note">you</span> like? N-not that I'm telling you that you need to like me! I'm just so happy when you're happy.`);
+				} else if (slave.sexualFlaw === "malicious" && slave.fetishStrength > 95 && slave.muscles > 30) {
+					text.push(`is my muscles, I like how I can use them to force the slutty bitches around here to do what I want. The way they squeal when I flex what I've got gets me hot every time.`);
+				} else if (slave.sexualFlaw === "abusive" && slave.fetishStrength > 95 && slave.muscles > 30) {
+					text.push(`is my muscles. I like how I can use them to hurt the other slaves, ${Master}. The way they cry, their tears, their blood. How long has it been since I beat a bitch senseless? I can't wait to work out some stress on my next toy.`);
+				} else if (slave.sexualFlaw === "self hating" && slave.fetishStrength > 95) {
+					text.push(`is my blood. It's so pretty and red, and there's so much of it when you and the other slaves <span class="note">really</span> lay into me. I'm so fucking hot right now, thinking about the things you can do to my slutty body.`);
+				} else if (slave.sexualFlaw === "cum addict" && slave.fetishStrength > 95) {
+					if (slave.lips > 40) {
+						text.push(`is my`);
+						if (slave.lips > 70) {
+							text.push(`huge`);
+						}
+						text.push(`lips, I like how everyone expects to facefuck me, and how my lips wrap around their dicks to keep all that`);
+						if (canTaste(slave)) {
+							text.push(`yummy`);
+						} else {
+							text.push(`warm`);
+						}
+						text.push(`cum in my belly. Oh! I like my belly, too, and that warm, sloshy feeling as it's packed full of baby juice. It's so — I'm sorry, ${Master}. I think my mouth is watering. Please give me a moment to collect myself.`);
+					} else if (V.PC.dick !== 0) {
+						text.push(`is my tummy${(slave.vagina > -1) ? ` — and my womb` : ``}! The sloshy feeling when I'm all packed full of cum in both ends gets me so incredibly horny. sometimes I wonder what it would be like if I were just a puffed up cum-balloon of a ${woman}, helpless and filled with cum, over, and over, and — I'm sorry, ${Master}. I'm being weird again, aren't I?`);
+					} else {
+						text.push(`is my mouth, I love how it feels to — to eat pussy, ${Master}. I love eating out your pussy. Especially when it's been filled up with some`);
+						if (canTaste(slave)) {
+							text.push(`yummy`);
+						} else {
+							text.push(`warm`);
+						}
+						text.push(`cum. Maybe you could let me eat cum out of your pussy soon?`);
 					}
-					r.push(`lips, I like how everyone expects to facefuck me, and how my lips wrap around their dicks to keep all that`);
-					if (canTaste(slave)) {
-						r.push(`yummy`);
+				} else if (slave.sexualFlaw === "attention whore" && slave.fetishStrength > 95) {
+					text.push(`is my whole ${slave.skin} body, and whatever part of me is best used to make me look like a total slut.`);
+				} else if (slave.sexualFlaw === "anal addict" && slave.fetishStrength > 95) {
+					if (slave.anus > 3) {
+						text.push(`is my gaping butthole. It's <span class="note">so</span> fucked out and beautiful. I can barely remember what anal pain feels like, but thinking about the sorts of things we can put in me, now, gets me so hot.`);
+					} else if (slave.anus > 2) {
+						text.push(`is my asspussy — I can take anything! It's <span class="note">so</span> much better than my`);
+						if (slave.dick > 0) {
+							text.push(`cock.`);
+						} else {
+							text.push(`pussy.`);
+						}
+						text.push(`It brings me so much pleasure... and pain... and... I'm sorry, ${Master} what were we talking about again? Oh! Right.`);
+					} else if (slave.anus > 1) {
+						text.push(`is my asshole, I like how I can take anyone's cock. It's <span class="note">so</span> much better than my`);
+						if (slave.dick > 0) {
+							text.push(`cock.`);
+						} else {
+							text.push(`pussy.`);
+						}
+						text.push(`It brings me so much pleasure... and pain... and... I'm sorry, ${Master} what were we talking about again? Oh! Right.`);
+					} else if (slave.anus === 1) {
+						text.push(`is my tight little anus, I like feeling it stretch to take a fuck. It's <span class="note">so</span> much better than my`);
+						if (slave.dick > 0) {
+							text.push(`cock.`);
+						} else {
+							text.push(`pussy.`);
+						}
+						text.push(`It brings me so much pleasure... and pain... and... I'm sorry, ${Master} what were we talking about again? Oh! Right.`);
+					} else if (slave.anus === 0) {
+						text.push(`is my little virgin butthole. I can't wait for the first time you fuck me in the ass — I wonder if it'll hurt.`);
+					}
+				} else if (slave.sexualFlaw === "breeder" && slave.fetishStrength > 95) {
+					if (slave.bellyPreg >= 600000) {
+						text.push(`is... um... our impossibly pregnant belly, of course. We love being so packed full with life that we're more baby than ${woman}, now. And the way our belly keeps our slutty preggo bodies stuck to the floor! We're so hot just thinking about it.`);
+						if (slave.pregSource === -1) {
+							text.push(`Thank you for breeding us, ${Master}! Our womb is yours to impregnate.`);
+						}
+						text.push(`What? Oh, I'm thinking of myself and my`);
+						if (slave.pregType >= 2 || slave.broodmother >= 1) {
+							text.push(`babies`);
+						} else {
+							text.push(`baby`);
+						}
+						text.push(`as one person again, aren't I? I'm sorry, ${Master}. It's just so hard to remember when my womb is so much more than I am in every way.`);
+					} else if (slave.bellyPreg >= 300000) {
+						text.push(`is... um... our massive pregnant belly, of course. We love feeling our womb swell with life. It's so hard to move now! We're so hot just thinking about it.`);
+						if (slave.pregSource === -1) {
+							text.push(`Thank you for breeding us, ${Master}! Our womb is yours to impregnate.`);
+						}
+						text.push(`What? Oh, I'm thinking of myself and my`);
+						if (slave.pregType >= 2 || slave.broodmother >= 1) {
+							text.push(`babies`);
+						} else {
+							text.push(`baby`);
+						}
+						text.push(`as one person again, aren't I? I'm sorry, ${Master}. It's just so hard to remember when my womb is so much more than I am in every way.`);
+					} else if (slave.bellyPreg >= 15000) {
+						text.push(`is... um... our bulging pregnant belly, of course. We love feeling our womb swell with life.`);
+						if (slave.pregSource === -1) {
+							text.push(`Thank you for breeding us, ${Master}! Our womb is yours to impregnate.`);
+						}
+						text.push(`What? Oh, I'm thinking of myself and my`);
+						if (slave.pregType >= 2 || slave.broodmother >= 1) {
+							text.push(`babies`);
+						} else {
+							text.push(`baby`);
+						}
+						text.push(`as one person again, aren't I? I'm sorry, ${Master}. It's just so hard to remember when my womb is so much more than I am in every way.`);
+					} else if (slave.bellyPreg >= 100) {
+						text.push(`is... um... our pregnant belly, of course.`);
+						if (slave.pregSource === -1) {
+							text.push(`Thank you for breeding us, ${Master}! Our womb is yours to impregnate.`);
+						}
+						text.push(`What? Oh, I'm thinking of myself and my`);
+						if (slave.pregType >= 2) {
+							text.push(`babies`);
+						} else {
+							text.push(`baby`);
+						}
+						text.push(`as one person again, aren't I? I'm sorry, ${Master}. It's just so hard to remember when my womb is so much more than I am in every way.`);
+					} else if (slave.pregKnown === 1) {
+						text.push(`is my belly, now that it has`);
+						if (slave.pregType >= 2) {
+							text.push(`the babies`);
+						} else {
+							text.push(`a baby`);
+						}
+						text.push(`growing in it. Just thinking about swelling up bigger and bigger has me quivering. I wish we could keep filling me with babies forever.`);
+						if (slave.pregSource === -1) {
+							text.push(`Thank you for impregnating me, ${Master}!`);
+						}
+					} else if (slave.dick > 0 && slave.balls > 4) {
+						text.push(`is my big breeder balls. I just want to fill other slaves with babies forever.`);
+					} else if (slave.dick > 0 && slave.balls > 0) {
+						text.push(`is my cock. I just want to fill other slaves with babies forever.`);
+					} else if (slave.weight > 95) {
+						text.push(`is my big tummy. Think of how many babies we could stretch it over! No, really. Please, ${Master}. Think about it.`);
+					} else if (slave.weight > 10) {
+						text.push(`is my plush tummy. Think of how many babies we could stretch it over! No, really. Please, ${Master}. Think about it.`);
+					} else if (slave.counter.birthsTotal > 10 && isFertile(slave)) {
+						text.push(`is my womb. It's made so many babies. It feels so sad and empty right now. I really wish we could just keep it stuffed full of babies forever.`);
+					} else if (isFertile(slave)) {
+						text.push(`is my womb. It's ready, ${Master}. It feels so sad and empty right now. I really wish we could just keep it stuffed full of babies forever.`);
 					} else {
-						r.push(`warm`);
+						text.push(`is my tight tummy, I like to imagine how it would swell if I got pregnant. I... I really wish we could put a baby in me, ${Master}.`);
 					}
-					r.push(`cum in my belly. Oh! I like my belly, too, and that warm, sloshy feeling as it's packed full of baby juice. It's so — I'm sorry, ${Master}. I think my mouth is watering. Please give me a moment to collect myself.`);
-				} else if (V.PC.dick !== 0) {
-					r.push(`is my tummy${(slave.vagina > -1) ? ` — and my womb` : ``}! The sloshy feeling when I'm all packed full of cum in both ends gets me so incredibly horny. sometimes I wonder what it would be like if I were just a puffed up cum-balloon of a ${woman}, helpless and filled with cum, over, and over, and — I'm sorry, ${Master}. I'm being weird again, aren't I?`);
-				} else {
-					r.push(`is my mouth, I love how it feels to — to eat pussy, ${Master}. I love eating out your pussy. Especially when it's been filled up with some`);
-					if (canTaste(slave)) {
-						r.push(`yummy`);
+					if (slave.geneticQuirks.superfetation === 2 && slave.womb.length > 0 && slave.pregKnown === 1) {
+						if (slave.intelligence + slave.intelligenceImplant > 15) {
+							if (slave.belly < (slave.pregAdaptation * 1750)) {
+								if (V.PC.dick !== 0) {
+									text.push(`You know, ${Master}, I think I could fit another baby or two in here if you wanted to take advantage of my condition...`);
+								} else {
+									text.push(`You know, I think I could fit a few more babies in here if you wanted me to...`);
+								}
+							} else {
+								text.push(`Oh ${Master}, I feel it's that awful time when I have to let an egg go to waste for the sake of the rest of us. I wish it didn't have to be this way and I could just keep swelling larger and larger with children.`);
+							}
+						} else {
+							if (V.PC.dick !== 0) {
+								text.push(`You know, ${Master}, I think I can feel that tingle deep inside me... You know, the one that gets me even more pregnant... Don't you think I need another baby inside me?`);
+							} else {
+								text.push(`I think it's time, actually... Oh yes, it's surely time to use my gift and make even more babies in me.`);
+							}
+						}
+					}
+				} else if (slave.sexualFlaw === "breast growth" && slave.fetishStrength > 95) {
+					if (slave.boobs > 10000) {
+						text.push(`is my colossal boobies, ${Master}. Sometimes, I think I <span class="note">am</span> my boobies. I mean, they're so much more me than the rest of 'me,' right? Literally. They're bigger than the rest of my body and the only thing that would make me happier is if they were even <span class="note">bigger.</span>`);
+					} else if (slave.boobs > 2000) {
+						text.push(`is my huge boobies, ${Master}. Sometimes, I think I <span class="note">am</span> my boobies. I mean, they're so much more me than the rest of 'me,' right? So big, and so beautiful, and so heavy... I'm sorry, ${Master}, what were we talking about? Oh, yes!`);
+					} else if (slave.nipples === "fuckable") {
+						text.push(`is my nipple pussies of course. It's so hot when they get abused, and I'm always trying to think of new ways to use them to pleasure you.`);
+					} else if (slave.lactation > 0) {
+						text.push(`is my milky nipples of course. Especially when you don't touch them for a while and my breasts bloat up nice and big.`);
+					} else if (slave.nipples === "huge" || slave.nipples === "puffy") {
+						text.push(`is my big nipples, it's like having clits on my chest. My only wish is that they were even bigger.`);
+					} else if (slave.boobs > 700) {
+						text.push(`is my big boobs. I like how they feel wrapped around a dick, and they are the center of my world. Sometimes, I think I <span class="note">am</span> my boobies. I mean, they're so much more me than the rest of 'me,' right?`);
 					} else {
-						r.push(`warm`);
+						text.push(`is my boobs, of course. They're so beautiful, and the center of my world.`);
 					}
-					r.push(`cum. Maybe you could let me eat cum out of your pussy soon?`);
-				}
-			} else if (slave.sexualFlaw === "attention whore" && slave.fetishStrength > 95) {
-				r.push(`is my whole ${slave.skin} body, and whatever part of me is best used to make me look like a total slut.`);
-			} else if (slave.sexualFlaw === "anal addict" && slave.fetishStrength > 95) {
-				if (slave.anus > 3) {
-					r.push(`is my gaping butthole. It's <span class="note">so</span> fucked out and beautiful. I can barely remember what anal pain feels like, but thinking about the sorts of things we can put in me, now, gets me so hot.`);
-				} else if (slave.anus > 2) {
-					r.push(`is my asspussy — I can take anything! It's <span class="note">so</span> much better than my`);
-					if (slave.dick > 0) {
-						r.push(`cock.`);
+				} else if (slave.energy > 95) {
+					text.push(`is — is — I can't decide!`);
+					if (slave.vagina > -1) {
+						text.push(`I love my pussy of course.`);
+						if (slave.clit > 0) {
+							text.push(`Having another slave suck my big clit is incredible.`);
+						}
+						text.push(`But`);
 					} else {
-						r.push(`pussy.`);
+						text.push(`Of course`);
 					}
-					r.push(`It brings me so much pleasure... and pain... and... I'm sorry, ${Master} what were we talking about again? Oh! Right.`);
-				} else if (slave.anus > 1) {
-					r.push(`is my asshole, I like how I can take anyone's cock. It's <span class="note">so</span> much better than my`);
-					if (slave.dick > 0) {
-						r.push(`cock.`);
+					if (slave.anus > 1) {
+						text.push(`taking big dicks up my ass is lots of fun.`);
+					} else if (slave.anus > 0) {
+						text.push(`taking cock in my tight ass is lots of fun.`);
 					} else {
-						r.push(`pussy.`);
+						text.push(`I love my little virgin butthole, but I can't wait to get assraped for the first time.`);
 					}
-					r.push(`It brings me so much pleasure... and pain... and... I'm sorry, ${Master} what were we talking about again? Oh! Right.`);
-				} else if (slave.anus === 1) {
-					r.push(`is my tight little anus, I like feeling it stretch to take a fuck. It's <span class="note">so</span> much better than my`);
-					if (slave.dick > 0) {
-						r.push(`cock.`);
-					} else {
-						r.push(`pussy.`);
-					}
-					r.push(`It brings me so much pleasure... and pain... and... I'm sorry, ${Master} what were we talking about again? Oh! Right.`);
-				} else if (slave.anus === 0) {
-					r.push(`is my little virgin butthole. I can't wait for the first time you fuck me in the ass — I wonder if it'll hurt.`);
-				}
-			} else if (slave.sexualFlaw === "breeder" && slave.fetishStrength > 95) {
-				if (slave.bellyPreg >= 600000) {
-					r.push(`is... um... our impossibly pregnant belly, of course. We love being so packed full with life that we're more baby than ${woman}, now. And the way our belly keeps our slutty preggo bodies stuck to the floor! We're so hot just thinking about it.`);
-					if (slave.pregSource === -1) {
-						r.push(`Thank you for breeding us, ${Master}! Our womb is yours to impregnate.`);
-					}
-					r.push(`What? Oh, I'm thinking of myself and my`);
-					if (slave.pregType >= 2 || slave.broodmother >= 1) {
-						r.push(`babies`);
-					} else {
-						r.push(`baby`);
-					}
-					r.push(`as one person again, aren't I? I'm sorry, ${Master}. It's just so hard to remember when my womb is so much more than I am in every way.`);
-				} else if (slave.bellyPreg >= 300000) {
-					r.push(`is... um... our massive pregnant belly, of course. We love feeling our womb swell with life. It's so hard to move now! We're so hot just thinking about it.`);
-					if (slave.pregSource === -1) {
-						r.push(`Thank you for breeding us, ${Master}! Our womb is yours to impregnate.`);
-					}
-					r.push(`What? Oh, I'm thinking of myself and my`);
-					if (slave.pregType >= 2 || slave.broodmother >= 1) {
-						r.push(`babies`);
-					} else {
-						r.push(`baby`);
-					}
-					r.push(`as one person again, aren't I? I'm sorry, ${Master}. It's just so hard to remember when my womb is so much more than I am in every way.`);
-				} else if (slave.bellyPreg >= 15000) {
-					r.push(`is... um... our bulging pregnant belly, of course. We love feeling our womb swell with life.`);
-					if (slave.pregSource === -1) {
-						r.push(`Thank you for breeding us, ${Master}! Our womb is yours to impregnate.`);
-					}
-					r.push(`What? Oh, I'm thinking of myself and my`);
-					if (slave.pregType >= 2 || slave.broodmother >= 1) {
-						r.push(`babies`);
-					} else {
-						r.push(`baby`);
-					}
-					r.push(`as one person again, aren't I? I'm sorry, ${Master}. It's just so hard to remember when my womb is so much more than I am in every way.`);
-				} else if (slave.bellyPreg >= 100) {
-					r.push(`is... um... our pregnant belly, of course.`);
-					if (slave.pregSource === -1) {
-						r.push(`Thank you for breeding us, ${Master}! Our womb is yours to impregnate.`);
-					}
-					r.push(`What? Oh, I'm thinking of myself and my`);
-					if (slave.pregType >= 2) {
-						r.push(`babies`);
-					} else {
-						r.push(`baby`);
-					}
-					r.push(`as one person again, aren't I? I'm sorry, ${Master}. It's just so hard to remember when my womb is so much more than I am in every way.`);
-				} else if (slave.pregKnown === 1) {
-					r.push(`is my belly, now that it has`);
-					if (slave.pregType >= 2) {
-						r.push(`the babies`);
-					} else {
-						r.push(`a baby`);
-					}
-					r.push(`growing in it. Just thinking about swelling up bigger and bigger has me quivering. I wish we could keep filling me with babies forever.`);
-					if (slave.pregSource === -1) {
-						r.push(`Thank you for impregnating me, ${Master}!`);
-					}
-				} else if (slave.dick > 0 && slave.balls > 4) {
-					r.push(`is my big breeder balls. I just want to fill other slaves with babies forever.`);
-				} else if (slave.dick > 0 && slave.balls > 0) {
-					r.push(`is my cock. I just want to fill other slaves with babies forever.`);
-				} else if (slave.weight > 95) {
-					r.push(`is my big tummy. Think of how many babies we could stretch it over! No, really. Please, ${Master}. Think about it.`);
-				} else if (slave.weight > 10) {
-					r.push(`is my plush tummy. Think of how many babies we could stretch it over! No, really. Please, ${Master}. Think about it.`);
-				} else if (slave.counter.birthsTotal > 10 && isFertile(slave)) {
-					r.push(`is my womb. It's made so many babies. It feels so sad and empty right now. I really wish we could just keep it stuffed full of babies forever.`);
-				} else if (isFertile(slave)) {
-					r.push(`is my womb. It's ready, ${Master}. It feels so sad and empty right now. I really wish we could just keep it stuffed full of babies forever.`);
-				} else {
-					r.push(`is my tight tummy, I like to imagine how it would swell if I got pregnant. I... I really wish we could put a baby in me, ${Master}.`);
-				}
-				if (slave.geneticQuirks.superfetation === 2 && slave.womb.length > 0 && slave.pregKnown === 1) {
-					if (slave.intelligence + slave.intelligenceImplant > 15) {
-						if (slave.belly < (slave.pregAdaptation * 1750)) {
-							if (V.PC.dick !== 0) {
-								r.push(`You know, ${Master}, I think I could fit another baby or two in here if you wanted to take advantage of my condition...`);
-							} else {
-								r.push(`You know, I think I could fit a few more babies in here if you wanted me to...`);
-							}
+					if (slave.dick > 3) {
+						text.push(`My big cock swings around when I get sodomized from behind, it's great.`);
+					} else if (slave.dick > 1) {
+						text.push(`My dick flops around when I get sodomized from behind, it's great.`);
+					} else if (slave.dick > 0) {
+						text.push(`My tiny little bitch dick is good for encouraging people to molest my butthole.`);
+					}
+					if (slave.nipples === "fuckable") {
+						text.push(`I love my fuckable nipples, it really feels like I've got a pair of pussies on my chest.`);
+					} else if (slave.nipples === "huge" || slave.nipples === "puffy") {
+						text.push(`I love my big nipples, it's like having clits on my chest.`);
+					}
+					if (slave.lactation > 0) {
+						text.push(`Being able to nurse is really sexy, I always want to fuck right after. Or during.`);
+					}
+					if (slave.boobs > 2000) {
+						text.push(`My huge boobs are great, they're like an advertisement I want to fuck.`);
+					} else if (slave.boobs > 700) {
+						text.push(`I like showing off my big boobs.`);
+					}
+					if (slave.lips > 40) {
+						text.push(`Can't forget my dick sucking lips, I don't know what I'd do without them.`);
+					} else {
+						text.push(`Can't forget my lips and tongue, getting people off with them is fun too.`);
+					}
+				} else if (slave.fetish === "submissive" && slave.fetishStrength > 60) {
+					text.push(`is my bare ${slave.skin} skin, I like how it feels when you look me all over before you take me.`);
+				} else if (slave.fetish === "dom" && slave.fetishStrength > 60 && slave.muscles > 30) {
+					text.push(`is my muscles, I like how it feels to be strong, forcing another slave.`);
+				} else if (slave.fetish === "sadist" && slave.fetishStrength > 60 && slave.muscles > 30) {
+					text.push(`is my muscles, I like how it feels to be strong, forcing another slave.`);
+				} else if (slave.fetish === "masochist" && slave.fetishStrength > 60) {
+					text.push(`is my ${slave.skin} skin, I like how it looks when it bruises.`);
+				} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60) {
+					if (slave.lips > 40) {
+						text.push(`is my`);
+						if (slave.lips > 70) {
+							text.push(`huge`);
+						}
+						text.push(`lips, I like how everyone expects to facefuck me.`);
+					} else if (V.PC.dick !== 0) {
+						text.push(`is my mouth, I love how it feels to suck dicks and drink all the cum.`);
+					} else {
+						text.push(`is my mouth, I love how it feels to eat pussy.`);
+					}
+				} else if (slave.fetish === "humiliation" && slave.fetishStrength > 60) {
+					text.push(`is my whole ${slave.skin} body, I like how it feels when everyone stares at me getting fucked.`);
+				} else if (slave.fetish === "buttslut" && slave.fetishStrength > 60) {
+					if (slave.anus > 3) {
+						text.push(`is my gaping butthole, though I'm sad it's so fucked out. I can barely remember what anal pain feels like.`);
+					} else if (slave.anus > 2) {
+						text.push(`is my asspussy — I can take anything! It's basically replaced my`);
+						if (slave.dick > 0) {
+							text.push(`cock`);
+						} else {
+							text.push(`pussy`);
+						}
+						text.push(`as my main sex organ.`);
+					} else if (slave.anus > 1) {
+						text.push(`is my asshole, I like how I can take anyone's cock. It's basically replaced my`);
+						if (slave.dick > 0) {
+							text.push(`cock`);
 						} else {
-							r.push(`Oh ${Master}, I feel it's that awful time when I have to let an egg go to waste for the sake of the rest of us. I wish it didn't have to be this way and I could just keep swelling larger and larger with children.`);
+							text.push(`pussy`);
 						}
+						text.push(`as my main sex organ.`);
 					} else {
-						if (V.PC.dick !== 0) {
-							r.push(`You know, ${Master}, I think I can feel that tingle deep inside me... You know, the one that gets me even more pregnant... Don't you think I need another baby inside me?`);
+						text.push(`is my tight little anus, I like feeling it stretch to take a fuck. It's basically replaced my`);
+						if (slave.dick > 0) {
+							text.push(`cock`);
 						} else {
-							r.push(`I think it's time, actually... Oh yes, it's surely time to use my gift and make even more babies in me.`);
-						}
-					}
-				}
-			} else if (slave.sexualFlaw === "breast growth" && slave.fetishStrength > 95) {
-				if (slave.boobs > 10000) {
-					r.push(`is my colossal boobies, ${Master}. sometimes, I think I <span class="note">am</span> my boobies. I mean, they're so much more me than the rest of 'me,' right? Literally. They're bigger than the rest of my body and the only thing that would make me happier is if they were even <span class="note">bigger.</span>`);
-				} else if (slave.boobs > 2000) {
-					r.push(`is my huge boobies, ${Master}. Sometimes, I think I <span class="note">am</span> my boobies. I mean, they're so much more me than the rest of 'me,' right? So big, and so beautiful, and so heavy... I'm sorry, ${Master}, what were we talking about? Oh, yes!`);
-				} else if (slave.nipples === "fuckable") {
-					r.push(`is my nipple pussies of course. It's so hot when they get abused, and I'm always trying to think of new ways to use them to pleasure you.`);
-				} else if (slave.lactation > 0) {
-					r.push(`is my milky nipples of course. Especially when you don't touch them for a while and my breasts bloat up nice and big.`);
-				} else if (slave.nipples === "huge" || slave.nipples === "puffy") {
-					r.push(`is my big nipples, it's like having clits on my chest. My only wish is that they were even bigger.`);
-				} else if (slave.boobs > 700) {
-					r.push(`is my big boobs. I like how they feel wrapped around a dick, and they are the center of my world. Sometimes, I think I <span class="note">am</span> my boobies. I mean, they're so much more me than the rest of 'me,' right?`);
-				} else {
-					r.push(`is my boobs, of course. They're so beautiful, and the center of my world.`);
-				}
-			} else if (slave.energy > 95) {
-				r.push(`is — is — I can't decide!`);
-				if (slave.vagina > -1) {
-					r.push(`I love my pussy of course.`);
-					if (slave.clit > 0) {
-						r.push(`Having another slave suck my big clit is incredible.`);
+							text.push(`pussy`);
+						}
+						text.push(`as my main sex organ.`);
 					}
-					r.push(`But`);
-				} else {
-					r.push(`Of course`);
-				}
-				if (slave.anus > 1) {
-					r.push(`taking big dicks up my ass is lots of fun.`);
-				} else if (slave.anus > 0) {
-					r.push(`taking cock in my tight ass is lots of fun.`);
-				} else {
-					r.push(`I love my little virgin butthole, but I can't wait to get assraped for the first time.`);
-				}
-				if (slave.dick > 3) {
-					r.push(`My big cock swings around when I get sodomized from behind, it's great.`);
-				} else if (slave.dick > 1) {
-					r.push(`My dick flops around when I get sodomized from behind, it's great.`);
-				} else if (slave.dick > 0) {
-					r.push(`My tiny little bitch dick is good for encouraging people to molest my butthole.`);
-				}
-				if (slave.nipples === "fuckable") {
-					r.push(`I love my fuckable nipples, it really feels like I've got a pair of pussies on my chest.`);
-				} else if (slave.nipples === "huge" || slave.nipples === "puffy") {
-					r.push(`I love my big nipples, it's like having clits on my chest.`);
-				}
-				if (slave.lactation > 0) {
-					r.push(`Being able to nurse is really sexy, I always want to fuck right after. Or during.`);
-				}
-				if (slave.boobs > 2000) {
-					r.push(`My huge boobs are great, they're like an advertisement I want to fuck.`);
-				} else if (slave.boobs > 700) {
-					r.push(`I like showing off my big boobs.`);
-				}
-				if (slave.lips > 40) {
-					r.push(`Can't forget my dick sucking lips, I don't know what I'd do without them.`);
-				} else {
-					r.push(`Can't forget my lips and tongue, getting people off with them is fun too.`);
-				}
-			} else if (slave.fetish === "submissive" && slave.fetishStrength > 60) {
-				r.push(`is my bare ${slave.skin} skin, I like how it feels when you look me all over before you take me.`);
-			} else if (slave.fetish === "dom" && slave.fetishStrength > 60 && slave.muscles > 30) {
-				r.push(`is my muscles, I like how it feels to be strong, forcing another slave.`);
-			} else if (slave.fetish === "sadist" && slave.fetishStrength > 60 && slave.muscles > 30) {
-				r.push(`is my muscles, I like how it feels to be strong, forcing another slave.`);
-			} else if (slave.fetish === "masochist" && slave.fetishStrength > 60) {
-				r.push(`is my ${slave.skin} skin, I like how it looks when it bruises.`);
-			} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60) {
-				if (slave.lips > 40) {
-					r.push(`is my`);
-					if (slave.lips > 70) {
-						r.push(`huge`);
+				} else if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
+					if (slave.bellyPreg >= 600000) {
+						text.push(`is my hypermassive pregnant belly, of course. I love being debilitatingly filled with life.`);
+						if (slave.pregSource === -1) {
+							text.push(`Thank you for breeding me, ${Master}! My womb is yours to impregnate. I can't think of anything better than getting bred by you forever.`);
+						}
+					} else if (slave.bellyPreg >= 300000) {
+						text.push(`is my massive pregnant belly, of course. I love being so packed full of life.`);
+						if (slave.pregSource === -1) {
+							text.push(`Thank you for breeding me, ${Master}! My womb is yours to impregnate. I can't think of anything better than getting bred by you forever.`);
+						}
+					} else if (slave.bellyPreg >= 15000) {
+						text.push(`is my bulging pregnant belly, of course. I love feeling my womb swell with life.`);
+						if (slave.pregSource === -1) {
+							text.push(`Thank you for breeding me, ${Master}! My womb is yours to impregnate. I can't think of anything better than getting bred by you forever.`);
+						}
+					} else if (slave.bellyPreg >= 100) {
+						text.push(`is my pregnant belly, of course.`);
+						if (slave.pregSource === -1) {
+							text.push(`Thank you for breeding me, ${Master}! Please use me to make babies whenever you want.`);
+						}
+					} else if (slave.pregKnown === 1) {
+						text.push(`is my belly, now that it has a baby growing in it. I can't wait for it to start showing.`);
+						if (slave.pregSource === -1) {
+							text.push(`Thank you for impregnating me, ${Master}!`);
+						}
+					} else if (slave.dick > 0 && slave.balls > 4) {
+						text.push(`is my big breeder balls, I imagine knocking another slave up all the time.`);
+					} else if (slave.dick > 0 && slave.balls > 0) {
+						text.push(`is my cock, I imagine knocking another slave up all the time.`);
+					} else if (slave.weight > 95) {
+						text.push(`is my big tummy, I can imagine myself pregnant.`);
+					} else if (slave.weight > 10) {
+						text.push(`is my plush tummy, I can imagine myself pregnant.`);
+					} else if (slave.counter.birthsTotal > 10 && isFertile(slave)) {
+						text.push(`is my womb, it's made so many babies and I can't wait to make more.`);
+					} else if (isFertile(slave)) {
+						text.push(`is my fertile pussy, I want to get filled with cum so badly.`);
+					} else {
+						text.push(`is my tight tummy, I like to imagine how it would swell if I got pregnant.`);
 					}
-					r.push(`lips, I like how everyone expects to facefuck me.`);
-				} else if (V.PC.dick !== 0) {
-					r.push(`is my mouth, I love how it feels to suck dicks and drink all the cum.`);
-				} else {
-					r.push(`is my mouth, I love how it feels to eat pussy.`);
-				}
-			} else if (slave.fetish === "humiliation" && slave.fetishStrength > 60) {
-				r.push(`is my whole ${slave.skin} body, I like how it feels when everyone stares at me getting fucked.`);
-			} else if (slave.fetish === "buttslut" && slave.fetishStrength > 60) {
-				if (slave.anus > 3) {
-					r.push(`is my gaping butthole, though I'm sad it's so fucked out. I can barely remember what anal pain feels like.`);
-				} else if (slave.anus > 2) {
-					r.push(`is my asspussy — I can take anything! It's basically replaced my`);
-					if (slave.dick > 0) {
-						r.push(`cock`);
+				} else if (slave.fetish === "boobs" && slave.fetishStrength > 60) {
+					if (slave.boobs > 2000) {
+						text.push(`is my huge tits, I like how they're so big they're the center of attention.`);
+					} else if (slave.nipples === "fuckable") {
+						text.push(`is my nipple pussies of course.`);
+					} else if (slave.lactation > 0) {
+						text.push(`is my milky nipples of course.`);
+					} else if (slave.nipples === "huge" || slave.nipples === "puffy") {
+						text.push(`is my big nipples, it's like having clits on my chest.`);
+					} else if (slave.boobs > 700) {
+						text.push(`is my big boobs, I like how they feel wrapped around a dick.`);
 					} else {
-						r.push(`pussy`);
+						text.push(`is my boobs, of course.`);
 					}
-					r.push(`as my main sex organ.`);
-				} else if (slave.anus > 1) {
-					r.push(`is my asshole, I like how I can take anyone's cock. It's basically replaced my`);
-					if (slave.dick > 0) {
-						r.push(`cock`);
+				} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+					if (slave.lips > 70) {
+						text.push(`is my huge lips, I like how the other girls will do anything for oral from me.`);
+					} else if (slave.dick > 1 && slave.balls > 0) {
+						text.push(`is my cock; I still do like slaying pussy.`);
+					} else if (slave.lips > 40) {
+						text.push(`is my kissy lips, I like how it feels to make out with the other girls.`);
 					} else {
-						r.push(`pussy`);
+						text.push(`is my lips, I guess. They're the best way I have of getting girls to like me.`);
+					}
+				} else if (slave.attrKnown === 1 && slave.attrXY > 80) {
+					if (slave.lips > 70) {
+						text.push(`is my huge lips, I like how anyone with a dick wants oral from me.`);
+					} else if (slave.dick > 1 && slave.balls > 0) {
+						text.push(`is my cock. It's fun having sex with two dicks involved!`);
+					} else if (slave.lips > 40) {
+						text.push(`is my kissy lips, I like how anyone with a dick sees them and wants to fuck them.`);
+					} else if (slave.vagina > -1) {
+						text.push(`is my pussy, I love getting fucked by strong cocks.`);
+					} else {
+						text.push(`is my butt, I guess. It's the best way I have of getting boys to like me.`);
 					}
-					r.push(`as my main sex organ.`);
-				} else {
-					r.push(`is my tight little anus, I like feeling it stretch to take a fuck. It's basically replaced my`);
-					if (slave.dick > 0) {
-						r.push(`cock`);
-					} else {
-						r.push(`pussy`);
-					}
-					r.push(`as my main sex organ.`);
-				}
-			} else if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
-				if (slave.bellyPreg >= 600000) {
-					r.push(`is my hypermassive pregnant belly, of course. I love being debilitatingly filled with life.`);
-					if (slave.pregSource === -1) {
-						r.push(`Thank you for breeding me, ${Master}! My womb is yours to impregnate. I can't think of anything better than getting bred by you forever.`);
-					}
-				} else if (slave.bellyPreg >= 300000) {
-					r.push(`is my massive pregnant belly, of course. I love being so packed full of life.`);
-					if (slave.pregSource === -1) {
-						r.push(`Thank you for breeding me, ${Master}! My womb is yours to impregnate. I can't think of anything better than getting bred by you forever.`);
-					}
-				} else if (slave.bellyPreg >= 15000) {
-					r.push(`is my bulging pregnant belly, of course. I love feeling my womb swell with life.`);
-					if (slave.pregSource === -1) {
-						r.push(`Thank you for breeding me, ${Master}! My womb is yours to impregnate. I can't think of anything better than getting bred by you forever.`);
-					}
-				} else if (slave.bellyPreg >= 100) {
-					r.push(`is my pregnant belly, of course.`);
-					if (slave.pregSource === -1) {
-						r.push(`Thank you for breeding me, ${Master}! Please use me to make babies whenever you want.`);
-					}
-				} else if (slave.pregKnown === 1) {
-					r.push(`is my belly, now that it has a baby growing in it. I can't wait for it to start showing.`);
-					if (slave.pregSource === -1) {
-						r.push(`Thank you for impregnating me, ${Master}!`);
-					}
-				} else if (slave.dick > 0 && slave.balls > 4) {
-					r.push(`is my big breeder balls, I imagine knocking another slave up all the time.`);
-				} else if (slave.dick > 0 && slave.balls > 0) {
-					r.push(`is my cock, I imagine knocking another slave up all the time.`);
-				} else if (slave.weight > 95) {
-					r.push(`is my big tummy, I can imagine myself pregnant.`);
-				} else if (slave.weight > 10) {
-					r.push(`is my plush tummy, I can imagine myself pregnant.`);
-				} else if (slave.counter.birthsTotal > 10 && isFertile(slave)) {
-					r.push(`is my womb, it's made so many babies and I can't wait to make more.`);
-				} else if (isFertile(slave)) {
-					r.push(`is my fertile pussy, I want to get filled with cum so badly.`);
-				} else {
-					r.push(`is my tight tummy, I like to imagine how it would swell if I got pregnant.`);
-				}
-			} else if (slave.fetish === "boobs" && slave.fetishStrength > 60) {
-				if (slave.boobs > 2000) {
-					r.push(`is my huge tits, I like how they're so big they're the center of attention.`);
-				} else if (slave.nipples === "fuckable") {
-					r.push(`is my nipple pussies of course.`);
-				} else if (slave.lactation > 0) {
-					r.push(`is my milky nipples of course.`);
-				} else if (slave.nipples === "huge" || slave.nipples === "puffy") {
-					r.push(`is my big nipples, it's like having clits on my chest.`);
-				} else if (slave.boobs > 700) {
-					r.push(`is my big boobs, I like how they feel wrapped around a dick.`);
-				} else {
-					r.push(`is my boobs, of course.`);
-				}
-			} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-				if (slave.lips > 70) {
-					r.push(`is my huge lips, I like how the other girls will do anything for oral from me.`);
-				} else if (slave.dick > 1 && slave.balls > 0) {
-					r.push(`is my cock; I still do like slaying pussy.`);
-				} else if (slave.lips > 40) {
-					r.push(`is my kissy lips, I like how it feels to make out with the other girls.`);
-				} else {
-					r.push(`is my lips, I guess. They're the best way I have of getting girls to like me.`);
-				}
-			} else if (slave.attrKnown === 1 && slave.attrXY > 80) {
-				if (slave.lips > 70) {
-					r.push(`is my huge lips, I like how anyone with a dick wants oral from me.`);
-				} else if (slave.dick > 1 && slave.balls > 0) {
-					r.push(`is my cock. It's fun having sex with two dicks involved!`);
-				} else if (slave.lips > 40) {
-					r.push(`is my kissy lips, I like how anyone with a dick sees them and wants to fuck them.`);
-				} else if (slave.vagina > -1) {
-					r.push(`is my pussy, I love getting fucked by strong cocks.`);
 				} else {
-					r.push(`is my butt, I guess. It's the best way I have of getting boys to like me.`);
+					text.push(`is my face,`);
+					if (slave.face > 10) {
+						text.push(`it's nice to be pretty.`);
+					} else {
+						text.push(`I guess.`);
+					}
 				}
 			} else {
-				r.push(`is my face,`);
+				text.push(`is my face,`);
 				if (slave.face > 10) {
-					r.push(`it's nice to be pretty.`);
+					text.push(`it's nice to be pretty.`);
 				} else {
-					r.push(`I guess.`);
+					text.push(`I guess.`);
 				}
 			}
-		} else {
-			r.push(`is my face,`);
-			if (slave.face > 10) {
-				r.push(`it's nice to be pretty.`);
-			} else {
-				r.push(`I guess.`);
-			}
+
+			return text.join(' ');
 		}
 
-		if (slave.pregSource === -9 && slave.bellyPreg >= 5000 && slave.devotion > 0) {
-			r.push(`My little sister is getting big; do you think she'll be a good little futa like me someday?`);
+		function futa() {
+			if (slave.pregSource === -9 && slave.bellyPreg >= 5000 && slave.devotion > 0) {
+				return `My little sister is getting big; do you think she'll be a good little futa like me someday?`;
+			}
+
+			return ``;
 		}
 
-		if (slave.need) {
-			const touch = (hasAnyArms(slave)) ? "touch myself," : "rub myself against stuff,";
-			if (slave.rules.release.masturbation === 1) {
-				r.push(`Thank you for letting me`);
-				if (slave.fetishKnown === 1) {
-					if (slave.energy > 95 && !canSee(slave)) {
-						r.push(`${touch} ${Master}. It's a good thing I can't get any more blind from it.`);
-					} else if (slave.energy > 95) {
-						r.push(`${touch} ${Master}. It's a good thing I can't actually go blind from it.`);
-					} else if (slave.fetish === "humiliation" && slave.fetishStrength > 60) {
-						r.push(`${touch} ${Master}. I love doing it where people can see me.`);
-					} else if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
-						r.push(`${touch} ${Master}. I try to be nearby when a bitch gets punished so I can masturbate to it.`);
-					} else if (slave.fetish === "buttslut" && slave.fetishStrength > 60) {
-						r.push(`fuck my own asshole, ${Master}.`);
-					} else if (slave.fetish === "boobs" && slave.fetishStrength > 60) {
-						r.push(`pamper my own breasts, ${Master}.`);
-					} else if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
-						r.push(`${touch} ${Master}.`);
-						if (slave.bellyPreg >= 5000) {
-							r.push(`I love feeling my big pregnant belly as I masturbate to it.`);
-						} else if (slave.dick > 1 && slave.balls > 0) {
-							r.push(`I love picturing my cock getting all the hot girls pregnant.`);
+		function need() {
+			const text = [];
+
+			if (slave.need) {
+				const touch = (hasAnyArms(slave)) ? `touch myself,` : `rub myself against stuff,`;
+
+				if (slave.rules.release.masturbation === 1) {
+					text.push(`Thank you for letting me`);
+
+					if (slave.fetishKnown === 1) {
+						if (slave.energy > 95 && !canSee(slave)) {
+							text.push(`${touch} ${Master}. It's a good thing I can't get any more blind from it.`);
+						} else if (slave.energy > 95) {
+							text.push(`${touch} ${Master}. It's a good thing I can't actually go blind from it.`);
+						} else if (slave.fetish === "humiliation" && slave.fetishStrength > 60) {
+							text.push(`${touch} ${Master}. I love doing it where people can see me.`);
+						} else if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
+							text.push(`${touch} ${Master}. I try to be nearby when a bitch gets punished so I can masturbate to it.`);
+						} else if (slave.fetish === "buttslut" && slave.fetishStrength > 60) {
+							text.push(`fuck my own asshole, ${Master}.`);
+						} else if (slave.fetish === "boobs" && slave.fetishStrength > 60) {
+							text.push(`pamper my own breasts, ${Master}.`);
+						} else if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
+							text.push(`${touch} ${Master}.`);
+
+							if (slave.bellyPreg >= 5000) {
+								text.push(`I love feeling my big pregnant belly as I masturbate to it.`);
+							} else if (slave.dick > 1 && slave.balls > 0) {
+								text.push(`I love picturing my cock getting all the hot girls pregnant.`);
+							} else {
+								text.push(`I love imagining how I'd look with a tummy swollen with babies.`);
+							}
+						} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60) {
+							text.push(`${touch} ${Master}.`);
+
+							if (slave.dick > 0 && slave.balls > 0) {
+								text.push(`Being able to drink my own cum is really fun too.`);
+							} else if (slave.dietCum === 1 || slave.dietCum === 2 ) {
+								text.push(`I love having cum in my food, being able to masturbate right after eating cum is so satisfying.`);
+							}
+						} else if (slave.attrKnown === 1 && slave.attrXX > 80 && !canSee(slave)) {
+							text.push(`${touch} ${Master}. With all these hot girls around, it's a good thing I can't get any more blind from it.`);
+						} else if (slave.attrKnown === 1 && slave.attrXY > 80 && !canSee(slave)) {
+							text.push(`${touch} ${Master}. With all these hot cocks around, it's a good thing I can't get any more blind from it.`);
+						} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+							text.push(`${touch} ${Master}. With all these hot girls around, it's a good thing I can't actually go blind from it.`);
+						} else if (slave.attrKnown === 1 && slave.attrXY > 80) {
+							text.push(`${touch} ${Master}. With all these hot cocks around, it's a good thing I can't actually go blind from it.`);
 						} else {
-							r.push(`I love imagining how I'd look with a tummy swollen with babies.`);
+							text.push(`${touch} ${Master}.`);
 						}
-					} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60) {
-						r.push(`${touch} ${Master}.`);
-						if (slave.dick > 0 && slave.balls > 0) {
-							r.push(`Being able to drink my own cum is really fun too.`);
-						} else if (slave.dietCum === 1 || slave.dietCum === 2 ) {
-							r.push(`I love having cum in my food, being able to masturbate right after eating cum is so satisfying.`);
-						}
-					} else if (slave.attrKnown === 1 && slave.attrXX > 80 && !canSee(slave)) {
-						r.push(`${touch} ${Master}. With all these hot girls around, it's a good thing I can't get any more blind from it.`);
-					} else if (slave.attrKnown === 1 && slave.attrXY > 80 && !canSee(slave)) {
-						r.push(`${touch} ${Master}. With all these hot cocks around, it's a good thing I can't get any more blind from it.`);
-					} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-						r.push(`${touch} ${Master}. With all these hot girls around, it's a good thing I can't actually go blind from it.`);
-					} else if (slave.attrKnown === 1 && slave.attrXY > 80) {
-						r.push(`${touch} ${Master}. With all these hot cocks around, it's a good thing I can't actually go blind from it.`);
 					} else {
-						r.push(`${touch} ${Master}.`);
+						text.push(`${touch} ${Master}.`);
 					}
-				} else {
-					r.push(`${touch} ${Master}.`);
-				}
-			} else if (slave.rules.release.slaves === 1) {
-				r.push(`Thank you for letting`);
-				if (slave.fetishKnown === 1) {
-					if (slave.energy > 95) {
-						r.push(`me fuck everyone,`);
-					} else if (slave.fetish === "humiliation" && slave.fetishStrength > 60) {
-						r.push(`the other slaves fuck me, I love doing it in the dormitory where they can all see me.`);
-					} else if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
-						r.push(`me abuse the other slaves,`);
-					} else if (slave.fetish === "buttslut" && slave.fetishStrength > 60) {
-						r.push(`the other slaves fuck my butthole,`);
-					} else if (slave.fetish === "boobs" && slave.fetishStrength > 60) {
-						r.push(`the other slaves play with my boobs,`);
-					} else if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
-						if (slave.bellyPreg >= 5000) {
-							r.push(`the other slaves fuck me, being pregnant and getting fucked is amazing,`);
-						} else if (slave.dick > 1 && slave.balls > 0) {
-							r.push(`me fuck other slaves, I cum so hard whenever I imagine filling them with babies,`);
+				} else if (slave.rules.release.slaves === 1) {
+					text.push(`Thank you for letting`);
+
+					if (slave.fetishKnown === 1) {
+						if (slave.energy > 95) {
+							text.push(`me fuck everyone,`);
+						} else if (slave.fetish === "humiliation" && slave.fetishStrength > 60) {
+							text.push(`the other slaves fuck me, I love doing it in the dormitory where they can all see me.`);
+						} else if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
+							text.push(`me abuse the other slaves,`);
+						} else if (slave.fetish === "buttslut" && slave.fetishStrength > 60) {
+							text.push(`the other slaves fuck my butthole,`);
+						} else if (slave.fetish === "boobs" && slave.fetishStrength > 60) {
+							text.push(`the other slaves play with my boobs,`);
+						} else if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
+							if (slave.bellyPreg >= 5000) {
+								text.push(`the other slaves fuck me, being pregnant and getting fucked is amazing,`);
+							} else if (slave.dick > 1 && slave.balls > 0) {
+								text.push(`me fuck other slaves, I cum so hard whenever I imagine filling them with babies,`);
+							} else {
+								text.push(`the other slaves fuck me, I love imagining how I'd look with a tummy swollen with babies,`);
+							}
+						} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60) {
+							text.push(`other slaves use my mouth to cum.`);
+
+							if (slave.dick > 0 && slave.balls > 0) {
+								text.push(`Being able to drink my own cum is really fun too,`);
+							} else if (slave.dietCum === 1 || slave.dietCum === 2 ) {
+								text.push(`I love having cum in my food, and sometimes I get an extra load on top from a friend,`);
+							}
+						} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+							text.push(`me bone the ladies,`);
 						} else {
-							r.push(`the other slaves fuck me, I love imagining how I'd look with a tummy swollen with babies,`);
-						}
-					} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60) {
-						r.push(`other slaves use my mouth to cum.`);
-						if (slave.dick > 0 && slave.balls > 0) {
-							r.push(`Being able to drink my own cum is really fun too,`);
-						} else if (slave.dietCum === 1 || slave.dietCum === 2 ) {
-							r.push(`I love having cum in my food, and sometimes I get an extra load on top from a friend,`);
+							text.push(`me get off with the other girls,`);
 						}
-					} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-						r.push(`me bone the ladies,`);
 					} else {
-						r.push(`me get off with the other girls,`);
+						text.push(`me get off with the other girls,`);
 					}
-				} else {
-					r.push(`me get off with the other girls,`);
-				}
-				r.push(`${Master}.`);
-			} else if (App.Utils.hasFamilySex(slave)) {
-				r.push(`Thank you for letting`);
-				if (slave.fetishKnown === 1) {
-					if (slave.energy > 95) {
-						r.push(`me fuck my family,`);
-					} else if (slave.fetish === "humiliation" && slave.fetishStrength > 60) {
-						r.push(`my family fuck me, I love doing it in the dormitory where everyone can see us.`);
-					} else if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
-						r.push(`me abuse my family,`);
-					} else if (slave.fetish === "buttslut" && slave.fetishStrength > 60) {
-						r.push(`my family fuck my butthole,`);
-					} else if (slave.fetish === "boobs" && slave.fetishStrength > 60) {
-						r.push(`my family play with my boobs,`);
-					} else if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
-						if (slave.bellyPreg >= 5000) {
-							r.push(`my family fuck me, being pregnant and getting fucked is amazing,`);
-						} else if (slave.dick > 1 && slave.balls > 0) {
-							r.push(`me fuck my family, I cum so hard whenever I imagine filling them with babies,`);
+
+					text.push(`${Master}.`);
+				} else if (App.Utils.hasFamilySex(slave)) {
+					text.push(`Thank you for letting`);
+
+					if (slave.fetishKnown === 1) {
+						if (slave.energy > 95) {
+							text.push(`me fuck my family,`);
+						} else if (slave.fetish === "humiliation" && slave.fetishStrength > 60) {
+							text.push(`my family fuck me, I love doing it in the dormitory where everyone can see us.`);
+						} else if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
+							text.push(`me abuse my family,`);
+						} else if (slave.fetish === "buttslut" && slave.fetishStrength > 60) {
+							text.push(`my family fuck my butthole,`);
+						} else if (slave.fetish === "boobs" && slave.fetishStrength > 60) {
+							text.push(`my family play with my boobs,`);
+						} else if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
+							if (slave.bellyPreg >= 5000) {
+								text.push(`my family fuck me, being pregnant and getting fucked is amazing,`);
+							} else if (slave.dick > 1 && slave.balls > 0) {
+								text.push(`me fuck my family, I cum so hard whenever I imagine filling them with babies,`);
+							} else {
+								text.push(`my family fuck me, I love imagining how I'd look with a tummy swollen with babies,`);
+							}
+						} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60) {
+							text.push(`my family use my mouth to cum.`);
+
+							if (slave.dick > 0 && slave.balls > 0) {
+								text.push(`Being able to drink my own cum is really fun too,`);
+							} else if (slave.dietCum === 1 || slave.dietCum === 2 ) {
+								text.push(`I love having cum in my food, and sometimes I get an extra load on top from a relative,`);
+							}
+						} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+							text.push(`me bone the ladies in my family,`);
 						} else {
-							r.push(`my family fuck me, I love imagining how I'd look with a tummy swollen with babies,`);
-						}
-					} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60) {
-						r.push(`my family use my mouth to cum.`);
-						if (slave.dick > 0 && slave.balls > 0) {
-							r.push(`Being able to drink my own cum is really fun too,`);
-						} else if (slave.dietCum === 1 || slave.dietCum === 2 ) {
-							r.push(`I love having cum in my food, and sometimes I get an extra load on top from a relative,`);
+							text.push(`me get off with the other girls in my family,`);
 						}
-					} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-						r.push(`me bone the ladies in my family,`);
 					} else {
-						r.push(`me get off with the other girls in my family,`);
+						text.push(`me get off with the other girls in my family,`);
 					}
+
+					text.push(`${Master}.`);
 				} else {
-					r.push(`me get off with the other girls in my family,`);
-				}
-				r.push(`${Master}.`);
-			} else {
-				if (slave.fetishKnown === 1) {
-					if (slave.energy > 95) {
-						r.push(`I feel like I'm going crazy, ${Master}, I'm so horny.`);
-					} else if (slave.fetishStrength > 60) {
-						switch (slave.fetish) {
-							case "submissive":
-								r.push(`I'm so horny, ${Master}. I can't stop thinking about you holding me down and fucking me.`);
-								break;
-							case "masochist":
-								r.push(`I'm so horny, ${Master}. I can't stop thinking about you spanking my worthless bottom.`);
-								break;
-							case "humiliation":
-								r.push(`I'm so horny, ${Master}. I can't stop thinking about everyone staring at my lewd body.`);
-								break;
-							case "dom":
-								r.push(`I'm so horny, ${Master}. I can't stop thinking about the other slaves, how it would feel to fuck them.`);
-								break;
-							case "sadist":
-								r.push(`I'm so horny, ${Master}. I can't stop thinking about the other slaves, how it would feel to hurt them.`);
-								break;
-							case "cumslut":
-								r.push(`I'm so horny, ${Master}. I can't stop staring at`);
-								if (V.PC.dick !== 0) {
-									r.push(`cocks and imagining them down my throat, cumming and cumming.`);
-								} else {
-									r.push(`pussies and imagining how their juices`);
-									if (canTaste(slave)) {
-										r.push(`taste.`);
+					if (slave.fetishKnown === 1) {
+						if (slave.energy > 95) {
+							text.push(`I feel like I'm going crazy, ${Master}, I'm so horny.`);
+						} else if (slave.fetishStrength > 60) {
+							switch (slave.fetish) {
+								case "submissive":
+									text.push(`I'm so horny, ${Master}. I can't stop thinking about you holding me down and fucking me.`);
+									break;
+								case "masochist":
+									text.push(`I'm so horny, ${Master}. I can't stop thinking about you spanking my worthless bottom.`);
+									break;
+								case "humiliation":
+									text.push(`I'm so horny, ${Master}. I can't stop thinking about everyone staring at my lewd body.`);
+									break;
+								case "dom":
+									text.push(`I'm so horny, ${Master}. I can't stop thinking about the other slaves, how it would feel to fuck them.`);
+									break;
+								case "sadist":
+									text.push(`I'm so horny, ${Master}. I can't stop thinking about the other slaves, how it would feel to hurt them.`);
+									break;
+								case "cumslut":
+									text.push(`I'm so horny, ${Master}. I can't stop staring at`);
+									if (V.PC.dick !== 0) {
+										text.push(`cocks and imagining them down my throat, cumming and cumming.`);
 									} else {
-										r.push(`feel on my skin.`);
+										text.push(`pussies and imagining how their juices`);
+										if (canTaste(slave)) {
+											text.push(`taste.`);
+										} else {
+											text.push(`feel on my skin.`);
+										}
 									}
-								}
-								break;
-							case "buttslut":
-								r.push(`I'm so horny, ${Master}.`);
-								if (plugWidth(slave) === 1 && slave.anus > 2) {
-									r.push(`I wear the buttplug you gave me, but it is so small... It reminds me of being fucked in the ass, but I can barely feel it. It drives me crazy.`);
-								} else if (
-									(plugWidth(slave) === 1 && slave.anus < 3) ||
-									(plugWidth(slave) === 2 && slave.anus === 3) ||
-									(plugWidth(slave) === 3 && slave.anus >= 4)
-								) {
-									r.push(`Thank you for the buttplug. It is really fun to have my ass filled all day long.`);
-								} else if (
-									(plugWidth(slave) === 2 && slave.anus < 3) ||
-									(plugWidth(slave) > 2 && slave.anus < 4)
-								) {
-									r.push(`I like it up the ass, but the plug you make me wear is too big. It really hurts. Not in the good way.`);
-								} else {
-									r.push(`My anus is killing me, all I want to do is touch it and massage it and fill it.`);
-								}
-								break;
-							case "boobs":
-								r.push(`I'm so horny, ${Master}. I want to rub my nipples against everything.`);
-								break;
-							case "pregnancy":
-								r.push(`I wish I could${touch} ${Master}. I can't get these thoughts of`);
-								if (slave.preg < 30) {
-									r.push(`pregnancy`);
-								} else {
-									r.push(`birth`);
-								}
-								r.push(`out of my head.`);
-								break;
+									break;
+								case "buttslut":
+									text.push(`I'm so horny, ${Master}.`);
+									if (plugWidth(slave) === 1 && slave.anus > 2) {
+										text.push(`I wear the buttplug you gave me, but it is so small... It reminds me of being fucked in the ass, but I can barely feel it. It drives me crazy.`);
+									} else if (
+										(plugWidth(slave) === 1 && slave.anus < 3) ||
+												(plugWidth(slave) === 2 && slave.anus === 3) ||
+												(plugWidth(slave) === 3 && slave.anus >= 4)
+									) {
+										text.push(`Thank you for the buttplug. It is really fun to have my ass filled all day long.`);
+									} else if (
+										(plugWidth(slave) === 2 && slave.anus < 3) ||
+												(plugWidth(slave) > 2 && slave.anus < 4)
+									) {
+										text.push(`I like it up the ass, but the plug you make me wear is too big. It really hurts. Not in the good way.`);
+									} else {
+										text.push(`My anus is killing me, all I want to do is touch it and massage it and fill it.`);
+									}
+									break;
+								case "boobs":
+									text.push(`I'm so horny, ${Master}. I want to rub my nipples against everything.`);
+									break;
+								case "pregnancy":
+									text.push(`I wish I could${touch} ${Master}. I can't get these thoughts of`);
+
+									if (slave.preg < 30) {
+										text.push(`pregnancy`);
+									} else {
+										text.push(`birth`);
+									}
+
+									text.push(`out of my head.`);
+									break;
+							}
+						} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+							text.push(`I'm so horny, ${Master}. I can't stop thinking about the other slaves' beautiful pussies and boobs and, and I want to fuck them so bad.`);
+						} else {
+							text.push(`I haven't been touching myself, ${Master}, just like you said, but I'm really horny.`);
 						}
-					} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-						r.push(`I'm so horny, ${Master}. I can't stop thinking about the other slaves' beautiful pussies and boobs and, and I want to fuck them so bad.`);
 					} else {
-						r.push(`I haven't been touching myself, ${Master}, just like you said, but I'm really horny.`);
+						text.push(`I haven't been touching myself, ${Master}, just like you said, but I'm really horny.`);
 					}
-				} else {
-					r.push(`I haven't been touching myself, ${Master}, just like you said, but I'm really horny.`);
 				}
 			}
-		}// Closes release check
-		r = r.map(t => Spoken(slave, t));
-		r.push (``);
-		App.Events.addNode(el, r, "span");
-		r = [];
 
-		if (slave.fetishKnown === 1) {
-			if (slave.energy > 95) {
-				r.push(Spoken(slave, `I love your`));
-				if (V.PC.dick !== 0) {
-					if (canDoAnal(slave) && canDoVaginal(slave)) {
-						if (slave.vagina === 0) {
-							if (V.PC.vagina !== -1) {
-								r.push(Spoken(slave, `body, ${Master},"`));
-								r.push(`${he} ${say}s eagerly.`);
-								r.push(Spoken(slave, `"I can't wait to have you in me, and your pussy is so delicious.`));
+			return text.join(' ');
+		}
+
+		function favoritePCBodyPart() {
+			const text = [];
+
+			if (slave.fetishKnown === 1) {
+				if (slave.energy > 95) {
+					text.push(`${Spoken(slave, `I love your`)}`);
+
+					if (V.PC.dick !== 0) {
+						if (canDoAnal(slave) && canDoVaginal(slave)) {
+							if (slave.vagina === 0) {
+								if (V.PC.vagina !== -1) {
+									text.push(`${Spoken(slave, `body, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I can't wait to have you in me, and your pussy is so delicious.`)}`);
+								} else {
+									text.push(`${Spoken(slave, `cock, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I can't wait to have you in me.`)}`);
+								}
 							} else {
-								r.push(Spoken(slave, `cock, ${Master},"`));
-								r.push(`${he} ${say}s eagerly.`);
-								r.push(Spoken(slave, `"I can't wait to have you in me.`));
+								if (V.PC.vagina !== -1) {
+									text.push(`${Spoken(slave, `body, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I love your cock in my holes, and your pussy is so delicious.`)}`);
+								} else {
+									text.push(`${Spoken(slave, `cock, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I love it inside my holes.`)}`);
+								}
 							}
 						} else {
 							if (V.PC.vagina !== -1) {
-								r.push(Spoken(slave, `body, ${Master},"`));
-								r.push(`${he} ${say}s eagerly.`);
-								r.push(Spoken(slave, `"I love your cock in my holes, and your pussy is so delicious.`));
+								text.push(`${Spoken(slave, `body, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I just need you inside me, and your pussy is so delicious.`)}`);
 							} else {
-								r.push(Spoken(slave, `cock, ${Master},"`));
-								r.push(`${he} ${say}s eagerly.`);
-								r.push(Spoken(slave, `"I love it inside my holes.`));
+								text.push(`${Spoken(slave, `cock, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I just need you inside me.`)}`);
 							}
 						}
 					} else {
-						if (V.PC.vagina !== -1) {
-							r.push(Spoken(slave, `body, ${Master},"`));
-							r.push(`${he} ${say}s eagerly.`);
-							r.push(Spoken(slave, `"I just need you inside me, and your pussy is so delicious.`));
+						text.push(`${Spoken(slave, `pussy, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I can just imagine your clit against my tongue.`)}`);
+					}
+				} else if (slave.fetish === "submissive" && slave.fetishStrength > 60) {
+					if (V.PC.boobs < 300) {
+						text.push(`Your strong arms feels so good when you hold me down.`);
+					} else {
+						if (V.PC.boobs >= 1000) {
+							text.push(`${Spoken(slave, `The weight of your boobs on my back feels so good when you pin me down.`)}`);
 						} else {
-							r.push(Spoken(slave, `cock, ${Master},"`));
-							r.push(`${he} ${say}s eagerly.`);
-							r.push(Spoken(slave, `"I just need you inside me.`));
+							text.push(`${Spoken(slave, `Your tits feel so good on my back when you pin me down.`)}`);
 						}
 					}
-				} else {
-					r.push(Spoken(slave, `pussy, ${Master},"`));
-					r.push(`${he} ${say}s eagerly.`);
-					r.push(Spoken(slave, `"I can just imagine your clit against my tongue.`));
-				}
-			} else if (slave.fetish === "submissive" && slave.fetishStrength > 60) {
-				if (V.PC.boobs < 300) {
-					r.push(`Your strong arms feels so good when you hold me down.`);
-				} else {
-					if (V.PC.boobs >= 1000) {
-						r.push(Spoken(slave, `The weight of your boobs on my back feels so good when you pin me down.`));
-					} else {
-						r.push(Spoken(slave, `Your tits feel so good on my back when you pin me down.`));
+				} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60) {
+					if (V.PC.balls !== 0) {
+						text.push(`${Spoken(slave, `Your cum is incredible, ${Master}. I would drink every drop of it, if I could.`)}`);
+						if (V.PC.scrotum > 0) {
+							text.push(`${Spoken(slave, `Your`)}`);
+
+							if (V.PC.balls >= 14) {
+								text.push(`${Spoken(slave, `massive`)}`);
+							} else if (V.PC.balls >= 9) {
+								text.push(`${Spoken(slave, `huge`)}`);
+							} else {
+								text.push(`${Spoken(slave, `big`)}`);
+							}
+
+							text.push(`${Spoken(slave, `balls are amazing; I want to be under your cock kissing and kneading whenever`)}`);
+
+							if (canSee(slave)) {
+								text.push(`${Spoken(slave, `I see you.`)}`);
+							} else {
+								text.push(`${Spoken(slave, `I'm near you.`)}`);
+							}
+						}
+
+						if (V.PC.vagina === 1) {
+							text.push(`${Spoken(slave, `Oh, I love your femcum, too!`)}`);
+						}
 					}
-				}
-			} else if (slave.fetish === "cumslut" && slave.fetishStrength > 60) {
-				if (V.PC.balls !== 0) {
-					r.push(Spoken(slave, `Your cum is incredible, ${Master}. I would drink every drop of it, if I could.`));
-					if (V.PC.scrotum > 0) {
-						r.push(Spoken(slave, `Your`));
-						if (V.PC.balls >= 14) {
-							r.push(Spoken(slave, `massive`));
-						} else if (V.PC.balls >= 9) {
-							r.push(Spoken(slave, `huge`));
-						} else {
-							r.push(Spoken(slave, `big`));
+				} else if (slave.fetish === "humiliation" && slave.fetishStrength > 60) {
+					if (V.PC.dick !== 0) {
+						text.push(`${Spoken(slave, `I love, uh."`)} ${He} looks down, hesitating. ${Spoken(slave, `"I love your cock, ${Master}.`)}`);
+
+						if (V.PC.vagina !== -1) {
+							text.push(`${Spoken(slave, `Um, and your vagina, too.`)}`);
 						}
-						r.push(Spoken(slave, `balls are amazing; I want to be under your cock kissing and kneading whenever`));
-						if (canSee(slave)) {
-							r.push(Spoken(slave, `I see you.`));
-						} else {
-							r.push(Spoken(slave, `I'm near you.`));
-						}
-					}
-					if (V.PC.vagina === 1) {
-						r.push(Spoken(slave, `Oh, I love your femcum, too!`));
-					}
-				}
-			} else if (slave.fetish === "humiliation" && slave.fetishStrength > 60) {
-				if (V.PC.dick !== 0) {
-					r.push(Spoken(slave, `I love, uh."`));
-					r.push(`${He} looks down, hesitating.`);
-					r.push(Spoken(slave, `"I love your cock, ${Master}.`));
-					if (V.PC.vagina !== -1) {
-						r.push(Spoken(slave, `Um, and your vagina, too.`));
-					}
-				}
-			} else if (slave.fetish === "buttslut" && slave.fetishStrength > 60) {
-				if (V.PC.dick !== 0) {
-					r.push(Spoken(slave, `I love your cock, ${Master},"`));
-					r.push(`${he} ${say}s eagerly.`);
-					r.push(Spoken(slave, `"I${(slave.anus === 0 || !canDoAnal(slave)) ? `'d` : ``} love it in my backdoor.`));
-				}
-			} else if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
-				if (V.PC.belly >= 10000) {
-					r.push(Spoken(slave, `You, uh."`));
-					r.push(`${He} looks down, hesitating.`);
-					r.push(Spoken(slave, `"Your belly is so big and wonderful, I just want to feel it,`));
-				} else if (V.PC.belly >= 5000) {
-					r.push(Spoken(slave, `You, uh."`));
-					r.push(`${He} looks down, hesitating.`);
-					r.push(Spoken(slave, `"You have a really lovely belly,`));
-				} else if (V.PC.boobs >= 300) {
-					r.push(Spoken(slave, `You, uh."`));
-					r.push(`${He} looks down, hesitating.`);
-					r.push(Spoken(slave, `"You have really nice breasts,`));
-				} else if (V.PC.dick !== 0 && V.PC.scrotum > 0) {
-					r.push(Spoken(slave, `You, uh."`));
-					r.push(`${He} looks down, hesitating.`);
-					r.push(Spoken(slave, `"You have really nice balls,`));
-				} else if (V.PC.dick !== 0) {
-					r.push(Spoken(slave, `You, uh."`));
-					r.push(`${He} looks down, hesitating.`);
-					r.push(Spoken(slave, `"You have a lovely cock,`));
-				} else {
-					r.push(Spoken(slave, `You, um."`));
-					r.push(`${He} looks down, hesitating.`);
-					r.push(Spoken(slave, `"You would make a lovely mother,`));
-				}
-				r.push(Spoken(slave, `${Master}.`));
-			} else if (slave.fetish === "boobs" && slave.fetishStrength > 60) {
-				if (V.PC.boobs >= 1400) {
-					r.push(Spoken(slave, `Your breasts are giant, ${Master},"`));
-					r.push(`${he} ${say}s eagerly.`);
-					r.push(Spoken(slave, `"I just want to bury my face in them.`));
-				} else if (V.PC.boobs >= 1200) {
-					r.push(Spoken(slave, `Your breasts are huge, ${Master},"`));
-					r.push(`${he} ${say}s eagerly.`);
-					r.push(Spoken(slave, `"I love them.`));
-				} else if (V.PC.boobs >= 1000) {
-					r.push(Spoken(slave, `Your breasts are so big and lovely, ${Master},"`));
-					r.push(`${he} ${say}s eagerly.`);
-					r.push(Spoken(slave, `"I love them.`));
-				} else if (V.PC.boobs >= 800) {
-					r.push(Spoken(slave, `Your breasts are incredible, ${Master},"`));
-					r.push(`${he} ${say}s eagerly.`);
-					r.push(Spoken(slave, `"I love them.`));
-				} else if (V.PC.boobs >= 300) {
-					r.push(Spoken(slave, `Your breasts are so cute, ${Master},"`));
-					r.push(`${he} ${say}s eagerly.`);
-					r.push(Spoken(slave, `"I just want to squeeze them.`));
-				}
-			} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-				if (V.PC.boobs >= 300) {
-					r.push(Spoken(slave, `You're, uh."`));
-					r.push(`${He} looks down, hesitating.`);
-					r.push(Spoken(slave, `"You're really hot, ${Master}.`));
-				}
-			} else if (slave.attrKnown === 1 && slave.attrXY > 80) {
-				if (V.PC.dick !== 0) {
-					r.push(Spoken(slave, `Your, uh."`));
-					r.push(`${He} looks down, hesitating.`);
-					r.push(Spoken(slave, `"Your cock is really hot, ${Master}.`));
-				}
-			} else {
-				r.push(Spoken(slave, `You're, uh."`));
-				r.push(`${He} looks down, hesitating.`);
-				r.push(Spoken(slave, `"You're really`));
-				if (V.PC.title === 1) {
-					r.push(Spoken(slave, `handsome,`));
+					}
+				} else if (slave.fetish === "buttslut" && slave.fetishStrength > 60) {
+					if (V.PC.dick !== 0) {
+						text.push(`${Spoken(slave, `I love your cock, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I${(slave.anus === 0 || !canDoAnal(slave)) ? `'d` : ``} love it in my backdoor.`)}`);
+					}
+				} else if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
+					if (V.PC.belly >= 10000) {
+						text.push(`${Spoken(slave, `You, uh."`)} ${He} looks down, hesitating. ${Spoken(slave, `"Your belly is so big and wonderful, I just want to feel it,`)}`);
+					} else if (V.PC.belly >= 5000) {
+						text.push(`${Spoken(slave, `You, uh."`)} ${He} looks down, hesitating. ${Spoken(slave, `"You have a really lovely belly,`)}`);
+					} else if (V.PC.boobs >= 300) {
+						text.push(`${Spoken(slave, `You, uh."`)} ${He} looks down, hesitating. ${Spoken(slave, `"You have really nice breasts,`)}`);
+					} else if (V.PC.dick !== 0 && V.PC.scrotum > 0) {
+						text.push(`${Spoken(slave, `You, uh."`)} ${He} looks down, hesitating. ${Spoken(slave, `"You have really nice balls,`)}`);
+					} else if (V.PC.dick !== 0) {
+						text.push(`${Spoken(slave, `You, uh."`)} ${He} looks down, hesitating. ${Spoken(slave, `"You have a lovely cock,`)}`);
+					} else {
+						text.push(`${Spoken(slave, `You, um."`)} ${He} looks down, hesitating. ${Spoken(slave, `"You would make a lovely mother,`)}`);
+					}
+					text.push(`${Spoken(slave, `${Master}.`)}`);
+				} else if (slave.fetish === "boobs" && slave.fetishStrength > 60) {
+					if (V.PC.boobs >= 1400) {
+						text.push(`${Spoken(slave, `Your breasts are giant, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I just want to bury my face in them.`)}`);
+					} else if (V.PC.boobs >= 1200) {
+						text.push(`${Spoken(slave, `Your breasts are huge, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I love them.`)}`);
+					} else if (V.PC.boobs >= 1000) {
+						text.push(`${Spoken(slave, `Your breasts are so big and lovely, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I love them.`)}`);
+					} else if (V.PC.boobs >= 800) {
+						text.push(`${Spoken(slave, `Your breasts are incredible, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I love them.`)}`);
+					} else if (V.PC.boobs >= 300) {
+						text.push(`${Spoken(slave, `Your breasts are so cute, ${Master},"`)} ${he} ${say}s eagerly. ${Spoken(slave, `"I just want to squeeze them.`)}`);
+					}
+				} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+					if (V.PC.boobs >= 300) {
+						text.push(`${Spoken(slave, `You're, uh."`)} ${He} looks down, hesitating. ${Spoken(slave, `"You're really hot, ${Master}.`)}`);
+					}
+				} else if (slave.attrKnown === 1 && slave.attrXY > 80) {
+					if (V.PC.dick !== 0) {
+						text.push(`${Spoken(slave, `Your, uh."`)} ${He} looks down, hesitating. ${Spoken(slave, `"Your cock is really hot, ${Master}.`)}`);
+					}
 				} else {
-					r.push(Spoken(slave, `pretty,`));
+					text.push(`${Spoken(slave, `You're, uh."`)} ${He} looks down, hesitating. ${Spoken(slave, `"You're really`)}`);
+
+					if (V.PC.title === 1) {
+						text.push(`${Spoken(slave, `handsome,`)}`);
+					} else {
+						text.push(`${Spoken(slave, `pretty,`)}`);
+					}
+
+					text.push(`${Spoken(slave, `${Master}.`)}`);
 				}
-				r.push(Spoken(slave, `${Master}.`));
 			}
+
+			return text.join(' ');
 		}
 
-		if (slave.dick > 0) {
-			if (slave.balls === 0) {
-				if (slave.fetishKnown === 1) {
-					if (slave.energy > 95) {
-						r.push(Spoken(slave, `I like being gelded."`));
-						r.push(`${He} giggles.`);
-						r.push(Spoken(slave, `"I don't have to be hard to get fucked!`));
-					} else if (slave.fetishStrength > 60) {
-						switch (slave.fetish) {
-							case "submissive":
-								r.push(Spoken(slave, `I don't mind being clipped. I like belong on the bottom.`));
-								break;
-							case "masochist":
-								r.push(Spoken(slave, `Being gelded," ${he} shivers, "hurts sometimes. Makes people want to hurt you. I like it.`));
-								break;
-							case "humiliation":
-								r.push(Spoken(slave, `I don't mind being clipped." ${He} shivers. "Everyone knows! It's so embarrassing.`));
-								break;
-							case "dom":
-								r.push(Spoken(slave, `I sometimes miss my balls. It's harder to be dominant without them.`));
-								break;
-							case "sadist":
-								r.push(Spoken(slave, `I sometimes miss my balls. I still fantasize about raping the other girls.`));
-								break;
-							case "pregnancy":
-								r.push(Spoken(slave, `I sometimes miss my balls. I still fantasize about getting the other girls pregnant.`));
-								break;
-							case "cumslut":
-								r.push(Spoken(slave, `I barely cum without my balls. I miss, you know, cleaning up after myself. With my mouth.`));
-								break;
-							case "buttslut":
-								r.push(Spoken(slave, `I really like being clipped. I think it's less distracting, you know, from my butthole.`));
-								if (slave.prostate > 0) {
-									r.push(Spoken(slave, `And I still have my prostate which is what matters.`));
-								}
-								break;
-							case "boobs":
-								r.push(Spoken(slave, `I don't mind being clipped. Between that and my boobs I feel like a nice little slave ${girl}.`));
-								break;
+		function fantasies() {
+			const text = [];
+
+			if (slave.dick > 0) {
+				if (slave.balls === 0) {
+					if (slave.fetishKnown === 1) {
+						if (slave.energy > 95) {
+							text.push(`${Spoken(slave, `I like being gelded."`)} ${He} giggles. ${Spoken(slave, `"I don't have to be hard to get fucked!`)}`);
+						} else if (slave.fetishStrength > 60) {
+							switch (slave.fetish) {
+								case "submissive":
+									text.push(`${Spoken(slave, `I don't mind being clipped. I like belong on the bottom.`)}`);
+									break;
+								case "masochist":
+									text.push(`${Spoken(slave, `Being gelded," ${he} shivers, "hurts sometimes. Makes people want to hurt you. I like it.`)}`);
+									break;
+								case "humiliation":
+									text.push(`${Spoken(slave, `I don't mind being clipped." ${He} shivers. "Everyone knows! It's so embarrassing.`)}`);
+									break;
+								case "dom":
+									text.push(`${Spoken(slave, `I sometimes miss my balls. It's harder to be dominant without them.`)}`);
+									break;
+								case "sadist":
+									text.push(`${Spoken(slave, `I sometimes miss my balls. I still fantasize about raping the other girls.`)}`);
+									break;
+								case "pregnancy":
+									text.push(`${Spoken(slave, `I sometimes miss my balls. I still fantasize about getting the other girls pregnant.`)}`);
+									break;
+								case "cumslut":
+									text.push(`${Spoken(slave, `I barely cum without my balls. I miss, you know, cleaning up after myself. With my mouth.`)}`);
+									break;
+								case "buttslut":
+									text.push(`${Spoken(slave, `I really like being clipped. I think it's less distracting, you know, from my butthole.`)}`);
+
+									if (slave.prostate > 0) {
+										text.push(`${Spoken(slave, `And I still have my prostate which is what matters.`)}`);
+									}
+									break;
+								case "boobs":
+									text.push(`${Spoken(slave, `I don't mind being clipped. Between that and my boobs I feel like a nice little slave ${girl}.`)}`);
+									break;
+							}
+						} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+							text.push(`${Spoken(slave, `I sometimes miss my balls. I still fantasize about boning the other girls.`)}`);
+						} else {
+							if (slave.devotion > 75) {
+								text.push(`${Spoken(slave, `I love being your gelded slave ${girl}, ${Master}.`)}`);
+							} else {
+								text.push(`${Spoken(slave, `To be honest, ${Master}, I do miss having balls, sometimes.`)}`);
+							}
 						}
-					} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-						r.push(Spoken(slave, `I sometimes miss my balls. I still fantasize about boning the other girls.`));
 					} else {
 						if (slave.devotion > 75) {
-							r.push(Spoken(slave, `I love being your gelded slave ${girl}, ${Master}.`));
+							text.push(`${Spoken(slave, `I love being your gelded slave ${girl}, ${Master}.`)}`);
 						} else {
-							r.push(Spoken(slave, `To be honest, ${Master}, I do miss having balls, sometimes.`));
+							text.push(`${Spoken(slave, `To be honest, ${Master}, I do miss having balls, sometimes.`)}`);
 						}
 					}
-				} else {
-					if (slave.devotion > 75) {
-						r.push(Spoken(slave, `I love being your gelded slave ${girl}, ${Master}.`));
-					} else {
-						r.push(Spoken(slave, `To be honest, ${Master}, I do miss having balls, sometimes.`));
-					}
-				}
-			} else if (slave.hormoneBalance >= 200) {
-				if (slave.fetishKnown === 1) {
-					if (slave.energy > 95) {
-						r.push(Spoken(slave, `I sometimes wish I could still get hard."`));
-						r.push(`${He} looks pensive.`);
-						r.push(Spoken(slave, `"Actually, I don't really care, getting fucked is nice too.`));
-					} else if (slave.fetishStrength > 60) {
-						switch (slave.fetish) {
-							case "submissive":
-								r.push(Spoken(slave, `I don't mind the hormones keeping me soft. I like getting fucked, anyway.`));
-								break;
-							case "masochist":
-								r.push(Spoken(slave, `I don't mind the hormones keeping me soft. I think it encourages people to treat me like I deserve.`));
-								break;
-							case "humiliation":
-								r.push(Spoken(slave, `I don't mind being impotent." ${He} shivers. "Everyone knows! It's so embarrassing.`));
-								break;
-							case "dom":
-								r.push(Spoken(slave, `I wish the hormones didn't stop me from getting hard. It's tough to be dominant when I'm all soft.`));
-								break;
-							case "sadist":
-								r.push(Spoken(slave, `I wish the hormones didn't stop me from getting hard. I still fantasize about raping the other girls.`));
-								break;
-							case "cumslut":
-								r.push(Spoken(slave, `I cum a lot less on these hormones. I miss, you know, cleaning up after myself. With my mouth.`));
-								break;
-							case "buttslut":
-								r.push(Spoken(slave, `I don't mind the hormones keeping me soft. I prefer taking it, anyway." ${He} turns and sticks ${his} ass out. "Up the butt.`));
-								break;
-							case "boobs":
-								r.push(Spoken(slave, `I don't mind the hormones keeping me soft. Between that and my boobs I feel like a cute slave girl.`));
-								break;
-							case "pregnancy":
-								r.push(Spoken(slave, `I wish the hormones didn't stop me from getting hard. I still fantasize about getting the other girls pregnant.`));
-								break;
+				} else if (slave.hormoneBalance >= 200) {
+					if (slave.fetishKnown === 1) {
+						if (slave.energy > 95) {
+							text.push(`${Spoken(slave, `I sometimes wish I could still get hard."`)} ${He} looks pensive. ${Spoken(slave, `"Actually, I don't really care, getting fucked is nice too.`)}`);
+						} else if (slave.fetishStrength > 60) {
+							switch (slave.fetish) {
+								case "submissive":
+									text.push(`${Spoken(slave, `I don't mind the hormones keeping me soft. I like getting fucked, anyway.`)}`);
+									break;
+								case "masochist":
+									text.push(`${Spoken(slave, `I don't mind the hormones keeping me soft. I think it encourages people to treat me like I deserve.`)}`);
+									break;
+								case "humiliation":
+									text.push(`${Spoken(slave, `I don't mind being impotent." ${He} shivers. "Everyone knows! It's so embarrassing.`)}`);
+									break;
+								case "dom":
+									text.push(`${Spoken(slave, `I wish the hormones didn't stop me from getting hard. It's tough to be dominant when I'm all soft.`)}`);
+									break;
+								case "sadist":
+									text.push(`${Spoken(slave, `I wish the hormones didn't stop me from getting hard. I still fantasize about raping the other girls.`)}`);
+									break;
+								case "cumslut":
+									text.push(`${Spoken(slave, `I cum a lot less on these hormones. I miss, you know, cleaning up after myself. With my mouth.`)}`);
+									break;
+								case "buttslut":
+									text.push(`${Spoken(slave, `I don't mind the hormones keeping me soft. I prefer taking it, anyway." ${He} turns and sticks ${his} ass out. "Up the butt.`)}`);
+									break;
+								case "boobs":
+									text.push(`${Spoken(slave, `I don't mind the hormones keeping me soft. Between that and my boobs I feel like a cute slave girl.`)}`);
+									break;
+								case "pregnancy":
+									text.push(`${Spoken(slave, `I wish the hormones didn't stop me from getting hard. I still fantasize about getting the other girls pregnant.`)}`);
+									break;
+							}
+						} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+							text.push(`${Spoken(slave, `I wish the hormones didn't stop me from getting hard. I still fantasize about boning the other girls.`)}`);
+						} else {
+							if (slave.devotion > 75) {
+								text.push(`${Spoken(slave, `I love you, ${Master}, so I don't mind how the hormones I'm on keep me soft, if that's how you want me.`)}`);
+							} else {
+								text.push(`${Spoken(slave, `I sometimes wish the hormones I'm on would let me get hard.`)}`);
+							}
 						}
-					} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-						r.push(Spoken(slave, `I wish the hormones didn't stop me from getting hard. I still fantasize about boning the other girls.`));
 					} else {
 						if (slave.devotion > 75) {
-							r.push(Spoken(slave, `I love you, ${Master}, so I don't mind how the hormones I'm on keep me soft, if that's how you want me.`));
+							text.push(`${Spoken(slave, `I love you, ${Master}, so I don't mind how the hormones I'm on keep me soft, if that's how you want me.`)}`);
 						} else {
-							r.push(Spoken(slave, `I sometimes wish the hormones I'm on would let me get hard.`));
+							text.push(`${Spoken(slave, `I sometimes wish the hormones I'm on would let me get hard.`)}`);
 						}
 					}
-				} else {
-					if (slave.devotion > 75) {
-						r.push(Spoken(slave, `I love you, ${Master}, so I don't mind how the hormones I'm on keep me soft, if that's how you want me.`));
-					} else {
-						r.push(Spoken(slave, `I sometimes wish the hormones I'm on would let me get hard.`));
-					}
 				}
-			}// closes balls check
-		} else if (slave.pubertyXX === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) {
-			if (slave.fetishKnown === 1) {
-				if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
-					r.push(Spoken(slave, `I fantasize about my belly getting heavy with pregnancy and my only wish is that you never let one of my eggs go to waste.`));
+			} else if (slave.pubertyXX === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) {
+				if (slave.fetishKnown === 1) {
+					if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
+						text.push(`${Spoken(slave, `I fantasize about my belly getting heavy with pregnancy and my only wish is that you never let one of my eggs go to waste.`)}`);
+					}
 				}
-			}
-		} else if (slave.mpreg === 1) {
-			if (slave.fetishKnown === 1) {
-				if (slave.fetish === "pregnancy" && slave.fetishStrength > 0) {
-					r.push(Spoken(slave, `I fantasize about my belly getting heavy with pregnancy, and I'm so glad you made me able to get pregnant!`));
-					if (slave.preg === -1) {
-						r.push(Spoken(slave, `Now if only someone were to forget to give me my contraceptives before we got to doing it...`));
+			} else if (slave.mpreg === 1) {
+				if (slave.fetishKnown === 1) {
+					if (slave.fetish === "pregnancy" && slave.fetishStrength > 0) {
+						text.push(`${Spoken(slave, `I fantasize about my belly getting heavy with pregnancy, and I'm so glad you made me able to get pregnant!`)}`);
+
+						if (slave.preg === -1) {
+							text.push(`${Spoken(slave, `Now if only someone were to forget to give me my contraceptives before we got to doing it...`)}`);
+						}
 					}
 				}
-			}
-		} else if (slave.preg === -1) {
-			if (slave.fetishKnown === 1) {
-				if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
-					r.push(Spoken(slave, `I fantasize about my belly getting heavy with pregnancy, but I know it won't happen while I'm on contraceptives.`));
+			} else if (slave.preg === -1) {
+				if (slave.fetishKnown === 1) {
+					if (slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
+						text.push(`${Spoken(slave, `I fantasize about my belly getting heavy with pregnancy, but I know it won't happen while I'm on contraceptives.`)}`);
+					}
 				}
 			}
-		}// closes dick check
 
-		if (Math.abs(slave.hormoneBalance) >= 200) {
-			if (slave.physicalAge > 35) {
-				if (slave.devotion > 50) {
-					if (slave.energy > 40) {
-						r.push(Spoken(slave, `On all these hormones I'm almost going through puberty all over again. Kind of a surprise at my age." ${He} grins suggestively. "I'll do my best to fuck like a teenager, ${Master}.`));
+			return text.join(' ');
+		}
+
+		function hormones() {
+			if (Math.abs(slave.hormoneBalance) >= 200) {
+				if (slave.physicalAge > 35) {
+					if (slave.devotion > 50) {
+						if (slave.energy > 40) {
+							return `${Spoken(slave, `On all these hormones I'm almost going through puberty all over again. Kind of a surprise at my age." ${He} grins suggestively. "I'll do my best to fuck like a teenager, ${Master}.`)}`;
+						}
 					}
 				}
 			}
+
+			return ``;
 		}
 
-		if (slave.curatives > 1 || slave.inflationType === "curative") {
-			if (slave.inflationType === "curative") {
-				if (slave.health.condition < 0) {
-					r.push(Spoken(slave, `I don't feel good, but I can almost feel the curatives fixing me, even if the belly is a little uncomfortable. Thank you, ${Master}.`));
-				} else if (slave.physicalAge > 35) {
-					r.push(Spoken(slave, `I can almost feel the curatives working. They make me feel like a young, pregnant ${girl}! Thank you, ${Master}.`));
-				} else {
-					r.push(Spoken(slave, `I can almost feel the curatives working. They're pretty incredible, even if the belly is a little uncomfortable. Thank you, ${Master}.`));
-				}
-			} else {
-				if (slave.health.condition < 0) {
-					r.push(Spoken(slave, `I don't feel good, but I can almost feel the curatives fixing me. Thank you, ${Master}.`));
-				} else if (slave.physicalAge > 35) {
-					r.push(Spoken(slave, `I can almost feel the curatives working. They make me feel so young! Thank you, ${Master}.`));
+		function curatives() {
+			if (slave.curatives > 1 || slave.inflationType === "curative") {
+				if (slave.inflationType === "curative") {
+					if (slave.health.condition < 0) {
+						return `${Spoken(slave, `I don't feel good, but I can almost feel the curatives fixing me, even if the belly is a little uncomfortable. Thank you, ${Master}.`)}`;
+					} else if (slave.physicalAge > 35) {
+						return `${Spoken(slave, `I can almost feel the curatives working. They make me feel like a young, pregnant ${girl}! Thank you, ${Master}.`)}`;
+					} else {
+						return `${Spoken(slave, `I can almost feel the curatives working. They're pretty incredible, even if the belly is a little uncomfortable. Thank you, ${Master}.`)}`;
+					}
 				} else {
-					r.push(Spoken(slave, `I can almost feel the curatives working. They're pretty incredible. Thank you, ${Master}.`));
+					if (slave.health.condition < 0) {
+						return `${Spoken(slave, `I don't feel good, but I can almost feel the curatives fixing me. Thank you, ${Master}.`)}`;
+					} else if (slave.physicalAge > 35) {
+						return `${Spoken(slave, `I can almost feel the curatives working. They make me feel so young! Thank you, ${Master}.`)}`;
+					} else {
+						return `${Spoken(slave, `I can almost feel the curatives working. They're pretty incredible. Thank you, ${Master}.`)}`;
+					}
 				}
 			}
-		}
 
-		if (slave.inflationType === "aphrodisiac") {
-			r.push(Spoken(slave, `This belly is so hot! I feel so hot... You just have to fuck me ${Master}! I need a dick in me, please!`));
+			return ``;
 		}
 
-		if (slave.inflationType === "tightener") {
-			r.push(Spoken(slave, `I can practically feel my butt getting tighter. This is great, I'll be like new soon. Thank you, ${Master}.`));
-		}
+		function inflation() {
+			const text = [];
 
-		if (slave.inflation > 0) {
-			let fluid;
-			if (SlaveStatsChecker.checkForLisp(slave)) {
-				fluid = lispReplace(slave.inflationType);
-			} else {
-				fluid = slave.inflationType;
+			if (slave.inflationType === "aphrodisiac") {
+				text.push(`${Spoken(slave, `This belly is so hot! I feel so hot... You just have to fuck me ${Master}! I need a dick in me, please!`)}`);
+			}
+
+			if (slave.inflationType === "tightener") {
+				text.push(`${Spoken(slave, `I can practically feel my butt getting tighter. This is great, I'll be like new soon. Thank you, ${Master}.`)}`);
 			}
-			if (slave.behavioralFlaw === "gluttonous" && ["food", "milk"].includes(fluid) && [1, 3].includes(slave.inflationMethod) && slave.fetish === "humiliation" && slave.fetishStrength > 60) {
-				if (slave.bellyFluid >= 10000) {
-					r.push(Spoken(slave, `My belly hurts a bit, but it's worth it to let everybody know what a disgraceful, gluttonous <span class="note">pig</span> I am.`));
-				} else if (slave.bellyFluid >= 5000) {
-					r.push(Spoken(slave, `I can't believe I get to gorge myself silly on ${fluid} and show it off! Thank you, ${Master}.`));
-				} else if (slave.bellyFluid >= 2000) {
-					r.push(Spoken(slave, `This ${fluid} is delicious, but wouldn't it be hot if your little piggy had an even <span class="note">bigger</span> belly for people to stare at?`));
-				}
-			} else if (slave.behavioralFlaw === "gluttonous" && ["food", "milk"].includes(fluid) && [1, 3].includes(slave.inflationMethod)) {
-				if (slave.bellyFluid >= 10000 && slave.fetish === "masochist" && slave.fetishStrength > 60) {
-					r.push(Spoken(slave, `This ${fluid} is so tasty, and my belly hurts so <span class="note">good...</span> I wish I really could stuff myself to bursting.`));
-				} else if (slave.bellyFluid >= 10000) {
-					r.push(Spoken(slave, `My belly hurts a little, but it feels so good to gorge myself...`));
-				} else if (slave.bellyFluid >= 5000) {
-					r.push(Spoken(slave, `I can't believe I get to stuff myself like this! Thank you, ${Master}.`));
-				} else if (slave.bellyFluid >= 2000) {
-					r.push(Spoken(slave, `Thank you for letting me have so much delicious ${fluid}, ${Master}.`));
-				}
-			} else if (slave.sexualFlaw === "cum addict" && fluid === "cum" && [1, 3].includes(slave.inflationMethod)) {
-				if (slave.bellyFluid >= 10000 && slave.fetish === "masochist" && slave.fetishStrength > 60) {
-					r.push(Spoken(slave, `I'm so full of tasty cum it <span class="note">hurts,</span> ${Master}. I think this is what heaven feels like...`));
-				} else if (slave.bellyFluid >= 10000) {
-					r.push(Spoken(slave, `It hurts a little, but I feel so <span class="note">complete</span> being so full of hot, delicious cum.`));
-				} else if (slave.bellyFluid >= 5000) {
-					r.push(Spoken(slave, `Being able to drink all this wonderful hot cum all the time is like a dream come true, ${Master}.`));
-				} else if (slave.bellyFluid >= 2000) {
-					r.push(Spoken(slave, `Thank you for letting me have so much delicious cum, ${Master}.`));
-				}
-			} else if (slave.sexualFlaw === "cum addict" && fluid === "cum" && slave.inflationMethod === 2) {
-				if (slave.bellyFluid >= 10000 && slave.fetish === "masochist" && slave.fetishStrength > 60) {
-					r.push(Spoken(slave, `It feels like I'm <span class="note">bursting</span> with cum, ${Master}. It's wonderful, even if I can't taste it.`));
-				} else if (slave.bellyFluid >= 10000) {
-					r.push(Spoken(slave, `It hurts a little, but I feel so <span class="note">complete</span> being so full of cum. I just wish I could taste it...`));
-				} else if (slave.bellyFluid >= 5000) {
-					r.push(Spoken(slave, `I love being so full of hot cum, ${Master}. I'd be even happier if I could taste it.`));
-				} else if (slave.bellyFluid >= 2000) {
-					r.push(Spoken(slave, `This cum is nice and warm inside me, ${Master}, I'd love to have some more. Maybe I could drink it next time...`));
-				}
-			} else if (slave.fetish === "humiliation" && slave.fetishStrength > 60) {
-				if (slave.bellyFluid >= 2000) {
-					r.push(Spoken(slave, `This bloated gut is so <span class="note">disgraceful...</span>`));
+
+			if (slave.inflation > 0) {
+				let fluid;
+
+				if (SlaveStatsChecker.checkForLisp(slave)) {
+					fluid = lispReplace(slave.inflationType);
+				} else {
+					fluid = slave.inflationType;
+				}
+
+				if (slave.behavioralFlaw === "gluttonous" && ["food", "milk"].includes(fluid) && [1, 3].includes(slave.inflationMethod) && slave.fetish === "humiliation" && slave.fetishStrength > 60) {
 					if (slave.bellyFluid >= 10000) {
-						r.push(Spoken(slave, `It hurts a little, but`));
+						text.push(`${Spoken(slave, `My belly hurts a bit, but it's worth it to let everybody know what a disgraceful, gluttonous <span class="note">pig</span> I am.`)}`);
+					} else if (slave.bellyFluid >= 5000) {
+						text.push(`${Spoken(slave, `I can't believe I get to gorge myself silly on ${fluid} and show it off! Thank you, ${Master}.`)}`);
+					} else if (slave.bellyFluid >= 2000) {
+						text.push(`${Spoken(slave, `This ${fluid} is delicious, but wouldn't it be hot if your little piggy had an even <span class="note">bigger</span> belly for people to stare at?`)}`);
+					}
+				} else if (slave.behavioralFlaw === "gluttonous" && ["food", "milk"].includes(fluid) && [1, 3].includes(slave.inflationMethod)) {
+					if (slave.bellyFluid >= 10000 && slave.fetish === "masochist" && slave.fetishStrength > 60) {
+						text.push(`${Spoken(slave, `This ${fluid} is so tasty, and my belly hurts so <span class="note">good...</span> I wish I really could stuff myself to bursting.`)}`);
+					} else if (slave.bellyFluid >= 10000) {
+						text.push(`${Spoken(slave, `My belly hurts a little, but it feels so good to gorge myself...`)}`);
+					} else if (slave.bellyFluid >= 5000) {
+						text.push(`${Spoken(slave, `I can't believe I get to stuff myself like this! Thank you, ${Master}.`)}`);
+					} else if (slave.bellyFluid >= 2000) {
+						text.push(`${Spoken(slave, `Thank you for letting me have so much delicious ${fluid}, ${Master}.`)}`);
+					}
+				} else if (slave.sexualFlaw === "cum addict" && fluid === "cum" && [1, 3].includes(slave.inflationMethod)) {
+					if (slave.bellyFluid >= 10000 && slave.fetish === "masochist" && slave.fetishStrength > 60) {
+						text.push(`${Spoken(slave, `I'm so full of tasty cum it <span class="note">hurts,</span> ${Master}. I think this is what heaven feels like...`)}`);
+					} else if (slave.bellyFluid >= 10000) {
+						text.push(`${Spoken(slave, `It hurts a little, but I feel so <span class="note">complete</span> being so full of hot, delicious cum.`)}`);
+					} else if (slave.bellyFluid >= 5000) {
+						text.push(`${Spoken(slave, `Being able to drink all this wonderful hot cum all the time is like a dream come true, ${Master}.`)}`);
+					} else if (slave.bellyFluid >= 2000) {
+						text.push(`${Spoken(slave, `Thank you for letting me have so much delicious cum, ${Master}.`)}`);
+					}
+				} else if (slave.sexualFlaw === "cum addict" && fluid === "cum" && slave.inflationMethod === 2) {
+					if (slave.bellyFluid >= 10000 && slave.fetish === "masochist" && slave.fetishStrength > 60) {
+						text.push(`${Spoken(slave, `It feels like I'm <span class="note">bursting</span> with cum, ${Master}. It's wonderful, even if I can't taste it.`)}`);
+					} else if (slave.bellyFluid >= 10000) {
+						text.push(`${Spoken(slave, `It hurts a little, but I feel so <span class="note">complete</span> being so full of cum. I just wish I could taste it...`)}`);
+					} else if (slave.bellyFluid >= 5000) {
+						text.push(`${Spoken(slave, `I love being so full of hot cum, ${Master}. I'd be even happier if I could taste it.`)}`);
+					} else if (slave.bellyFluid >= 2000) {
+						text.push(`${Spoken(slave, `This cum is nice and warm inside me, ${Master}, I'd love to have some more. Maybe I could drink it next time...`)}`);
+					}
+				} else if (slave.fetish === "humiliation" && slave.fetishStrength > 60) {
+					if (slave.bellyFluid >= 2000) {
+						text.push(`${Spoken(slave, `This bloated gut is so <span class="note">disgraceful...</span>`)}`);
+						if (slave.bellyFluid >= 10000) {
+							text.push(`${Spoken(slave, `It hurts a little, but`)}`);
+						}
+						text.push(`${Spoken(slave, `I love the way people <span class="note">stare</span> at it.`)}`);
+					}
+				} else {
+					if (slave.bellyFluid >= 10000 && slave.fetish === "masochist" && slave.fetishStrength > 60) {
+						text.push(`${Spoken(slave, `My guts are so full, ${Master}, it hurts so <span class="note">good...</span>`)}`);
+					} else if (slave.bellyFluid >= 10000) {
+						text.push(`${Spoken(slave, `I feel really full, can I let the ${fluid} out now?`)}`);
+					} else if (slave.bellyFluid >= 5000) {
+						text.push(`${Spoken(slave, `I feel so full, can I let the ${fluid} out now?`)}`);
+					} else if (slave.bellyFluid >= 2000) {
+						text.push(`${Spoken(slave, `I feel so uncomfortable, can I let the ${fluid} out now?`)}`);
 					}
-					r.push(Spoken(slave, `I love the way people <span class="note">stare</span> at it.`));
-				}
-			} else {
-				if (slave.bellyFluid >= 10000 && slave.fetish === "masochist" && slave.fetishStrength > 60) {
-					r.push(Spoken(slave, `My guts are so full, ${Master}, it hurts so <span class="note">good...</span>`));
-				} else if (slave.bellyFluid >= 10000) {
-					r.push(Spoken(slave, `I feel really full, can I let the ${fluid} out now?`));
-				} else if (slave.bellyFluid >= 5000) {
-					r.push(Spoken(slave, `I feel so full, can I let the ${fluid} out now?`));
-				} else if (slave.bellyFluid >= 2000) {
-					r.push(Spoken(slave, `I feel so uncomfortable, can I let the ${fluid} out now?`));
 				}
 			}
+
+			return text.join(' ');
 		}
 
-		switch (slave.diet) {
-			case "fertility":
-				r.push(Spoken(slave, `My stomach feels tingly, especially when I think of dicks, but that's normal, right?`));
-				if (V.PC.dick > 0) {
-					r.push(Spoken(slave, `Oh! It's happening now! I bet we both know why...`));
-				}
-				break;
-			case "cum production":
-				r.push(Spoken(slave, `My loads have been bigger lately. That diet must be having an effect on me.`));
-				break;
-			case "cleansing":
-				r.push(Spoken(slave, `I'm feeling really good, ${Master}, the diet must be working.`));
-				if (canTaste(slave)) {
-					r.push(Spoken(slave, `It really tastes horrible, though...`));
-				}
-				break;
+		function diet() {
+			const text = [];
+
+			switch (slave.diet) {
+				case "fertility":
+					text.push(`${Spoken(slave, `My stomach feels tingly, especially when I think of dicks, but that's normal, right?`)}`);
+
+					if (V.PC.dick > 0) {
+						text.push(`${Spoken(slave, `Oh! It's happening now! I bet we both know why...`)}`);
+					}
+					break;
+				case "cum production":
+					text.push(`${Spoken(slave, `My loads have been bigger lately. That diet must be having an effect on me.`)}`);
+					break;
+				case "cleansing":
+					text.push(`${Spoken(slave, `I'm feeling really good, ${Master}, the diet must be working.`)}`);
+
+					if (canTaste(slave)) {
+						text.push(`${Spoken(slave, `It really tastes horrible, though...`)}`);
+					}
+					break;
+			}
+
+			return text.join(' ');
 		}
 
-		switch (slave.drugs) {
-			case "intensive penis enhancement":
-				if (slave.dick > 0) {
-					if (slave.balls === 0) {
-						r.push(Spoken(slave, `I can feel my dick growing, ${Master}, but it's still so soft. I guess it'll just flop around more when I get buttfucked.`));
-					} else if (slave.fetishKnown === 1) {
-						if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
-							r.push(Spoken(slave, `I can feel my dick growing, ${Master}. I can just imagine pushing it into some poor struggling girl's asshole.`));
-						} else if (slave.fetish === "dom" && slave.fetishStrength > 60) {
-							r.push(Spoken(slave, `I can feel my dick growing, ${Master}. I can just imagine pushing it into some little slut's face.`));
-						} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-							r.push(Spoken(slave, `I can feel my dick growing, ${Master}. I can just imagine pushing it into a warm, wet pussy.`));
+		function drugs() {
+			const text = [];
+
+			switch (slave.drugs) {
+				case "intensive penis enhancement":
+					if (slave.dick > 0) {
+						if (slave.balls === 0) {
+							text.push(`${Spoken(slave, `I can feel my dick growing, ${Master}, but it's still so soft. I guess it'll just flop around more when I get buttfucked.`)}`);
+						} else if (slave.fetishKnown === 1) {
+							if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
+								text.push(`${Spoken(slave, `I can feel my dick growing, ${Master}. I can just imagine pushing it into some poor struggling girl's asshole.`)}`);
+							} else if (slave.fetish === "dom" && slave.fetishStrength > 60) {
+								text.push(`${Spoken(slave, `I can feel my dick growing, ${Master}. I can just imagine pushing it into some little slut's face.`)}`);
+							} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+								text.push(`${Spoken(slave, `I can feel my dick growing, ${Master}. I can just imagine pushing it into a warm, wet pussy.`)}`);
+							} else {
+								text.push(`${Spoken(slave, `I can almost feel my dick growing, ${Master}. It's kind of uncomfortable.`)}`);
+							}
 						} else {
-							r.push(Spoken(slave, `I can almost feel my dick growing, ${Master}. It's kind of uncomfortable.`));
+							text.push(`${Spoken(slave, `I can almost feel my dick growing, ${Master}. It's kind of uncomfortable.`)}`);
 						}
 					} else {
-						r.push(Spoken(slave, `I can almost feel my dick growing, ${Master}. It's kind of uncomfortable.`));
-					}
-				} else {
-					if (slave.fetishKnown === 1) {
-						if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
-							r.push(Spoken(slave, `I can feel my clit growing, ${Master}. I can just imagine pushing it into some poor struggling girl's asshole.`));
-						} else if (slave.fetish === "dom" && slave.fetishStrength > 60) {
-							r.push(Spoken(slave, `I can feel my clit growing, ${Master}. I can just imagine pushing it into some little slut's face.`));
-						} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-							r.push(Spoken(slave, `I can feel my clit growing, ${Master}. I can just imagine pushing it into a warm, wet pussy.`));
+						if (slave.fetishKnown === 1) {
+							if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
+								text.push(`${Spoken(slave, `I can feel my clit growing, ${Master}. I can just imagine pushing it into some poor struggling girl's asshole.`)}`);
+							} else if (slave.fetish === "dom" && slave.fetishStrength > 60) {
+								text.push(`${Spoken(slave, `I can feel my clit growing, ${Master}. I can just imagine pushing it into some little slut's face.`)}`);
+							} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+								text.push(`${Spoken(slave, `I can feel my clit growing, ${Master}. I can just imagine pushing it into a warm, wet pussy.`)}`);
+							} else {
+								text.push(`${Spoken(slave, `I can almost feel my clit growing, ${Master}. It's kind of uncomfortable.`)}`);
+							}
 						} else {
-							r.push(Spoken(slave, `I can almost feel my clit growing, ${Master}. It's kind of uncomfortable.`));
+							text.push(`${Spoken(slave, `I can almost feel my clit growing, ${Master}. It's kind of uncomfortable.`)}`);
 						}
-					} else {
-						r.push(Spoken(slave, `I can almost feel my clit growing, ${Master}. It's kind of uncomfortable.`));
 					}
-				}
-				break;
-			case "hyper penis enhancement":
-				if (slave.dick > 0) {
-					if (slave.balls === 0) {
-						r.push(Spoken(slave, `I can feel my dick growing, ${Master}, but it's still so soft. I guess it'll just flop around more when you buttfuck me, until it touches the floor, that is.`));
-					} else if (slave.fetishKnown === 1) {
-						if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
-							r.push(Spoken(slave, `I can feel my dick growing, ${Master}. I can just imagine pushing it into some poor struggling girl's asshole and having it swell more and more in them.`));
-						} else if (slave.fetish === "dom" && slave.fetishStrength > 60) {
-							r.push(Spoken(slave, `I can feel my dick growing, ${Master}. I can just imagine pinning some poor little slut to the floor with it.`));
-						} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-							r.push(Spoken(slave, `I can feel my dick growing, ${Master}. I can just imagine shoving it into a warm, wet pussy.`));
+					break;
+				case "hyper penis enhancement":
+					if (slave.dick > 0) {
+						if (slave.balls === 0) {
+							text.push(`${Spoken(slave, `I can feel my dick growing, ${Master}, but it's still so soft. I guess it'll just flop around more when you buttfuck me, until it touches the floor, that is.`)}`);
+						} else if (slave.fetishKnown === 1) {
+							if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
+								text.push(`${Spoken(slave, `I can feel my dick growing, ${Master}. I can just imagine pushing it into some poor struggling girl's asshole and having it swell more and more in them.`)}`);
+							} else if (slave.fetish === "dom" && slave.fetishStrength > 60) {
+								text.push(`${Spoken(slave, `I can feel my dick growing, ${Master}. I can just imagine pinning some poor little slut to the floor with it.`)}`);
+							} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+								text.push(`${Spoken(slave, `I can feel my dick growing, ${Master}. I can just imagine shoving it into a warm, wet pussy.`)}`);
+							} else {
+								text.push(`${Spoken(slave, `I can feel my dick growing, ${Master}. It's kind of painful.`)}`);
+							}
 						} else {
-							r.push(Spoken(slave, `I can feel my dick growing, ${Master}. It's kind of painful.`));
+							text.push(`${Spoken(slave, `I can feel my dick growing, ${Master}. It's kind of painful.`)}`);
 						}
 					} else {
-						r.push(Spoken(slave, `I can feel my dick growing, ${Master}. It's kind of painful.`));
-					}
-				} else {
-					if (slave.fetishKnown === 1) {
-						if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
-							r.push(Spoken(slave, `I can feel my clit growing, ${Master}. I can just imagine pushing it into some poor struggling girl's asshole and having it swell more and more in them.`));
-						} else if (slave.fetish === "dom" && slave.fetishStrength > 60) {
-							r.push(Spoken(slave, `I can feel my clit growing, ${Master}. I can just imagine plugging some slut's face with it.`));
-						} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-							r.push(Spoken(slave, `I can feel my clit growing, ${Master}. I can just imagine shoving it into a warm, wet pussy.`));
+						if (slave.fetishKnown === 1) {
+							if (slave.fetish === "sadist" && slave.fetishStrength > 60) {
+								text.push(`${Spoken(slave, `I can feel my clit growing, ${Master}. I can just imagine pushing it into some poor struggling girl's asshole and having it swell more and more in them.`)}`);
+							} else if (slave.fetish === "dom" && slave.fetishStrength > 60) {
+								text.push(`${Spoken(slave, `I can feel my clit growing, ${Master}. I can just imagine plugging some slut's face with it.`)}`);
+							} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+								text.push(`${Spoken(slave, `I can feel my clit growing, ${Master}. I can just imagine shoving it into a warm, wet pussy.`)}`);
+							} else {
+								text.push(`${Spoken(slave, `I can almost feel my clit growing, ${Master}. It's kind of painful.`)}`);
+							}
 						} else {
-							r.push(Spoken(slave, `I can almost feel my clit growing, ${Master}. It's kind of painful.`));
+							text.push(`${Spoken(slave, `I can almost feel my clit growing, ${Master}. It's kind of painful.`)}`);
 						}
+					}
+					break;
+				case "intensive testicle enhancement":
+					text.push(`${Spoken(slave, `My balls feel incredibly full, ${Master}. They're really uncomfortable.`)}`);
+					if (
+						slave.fetishKnown === 1 &&
+							(slave.fetish === "dom" || slave.fetish === "sadist") &&
+							slave.fetishStrength > 60
+					) {
+						text.push(`${Spoken(slave, `But I can't wait to force a bitch to take the whole load.`)}`);
+					} else if (slave.fetishKnown === 1 && slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
+						text.push(`${Spoken(slave, `I feel like I could fill a girl's womb with cum with one orgasm.`)}`);
 					} else {
-						r.push(Spoken(slave, `I can almost feel my clit growing, ${Master}. It's kind of painful.`));
+						text.push(`${Spoken(slave, `I really need to cum. After we finish talking, would you please, please fuck me so I can cum? I can barely stand it.`)}`);
 					}
-				}
-				break;
-			case "intensive testicle enhancement":
-				r.push(Spoken(slave, `My balls feel incredibly full, ${Master}. They're really uncomfortable.`));
-				if (
-					slave.fetishKnown === 1 &&
-					(slave.fetish === "dom" || slave.fetish === "sadist") &&
-					slave.fetishStrength > 60
-				) {
-					r.push(Spoken(slave, `But I can't wait to force a bitch to take the whole load.`));
-				} else if (slave.fetishKnown === 1 && slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
-					r.push(Spoken(slave, `I feel like I could fill a girl's womb with cum with one orgasm.`));
-				} else {
-					r.push(Spoken(slave, `I really need to cum. After we finish talking, would you please, please fuck me so I can cum? I can barely stand it.`));
-				}
-				break;
-			case "hyper testicle enhancement":
-				r.push(Spoken(slave, `My balls feel so incredibly full, ${Master}. They're really painful.`));
-				if (
-					slave.fetishKnown === 1 &&
-					(slave.fetish === "dom" || slave.fetish === "sadist") &&
-					slave.fetishStrength > 60
-				) {
-					r.push(Spoken(slave, `But I can't wait to fill a bitch with my load. Bet they'll look pregnant when I'm done.`));
-				} else if (slave.fetishKnown === 1 && slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
-					r.push(Spoken(slave, `I feel like I could fertilize all of a girl's eggs with my cum.`));
-				} else {
-					r.push(Spoken(slave, `I really need to cum. After I finish, would you please, please fuck me? I can barely stand it.`));
-				}
-				break;
-			case "intensive breast injections":
-				if (slave.fetishKnown === 1 && (slave.fetish === "boobs" || slave.energy > 95)) {
-					r.push(Spoken(slave, `I can almost feel my boobs swelling, ${Master}. Thank you for injecting them with hormones, and please, never stop.`));
-				} else {
-					r.push(Spoken(slave, `I can almost feel my boobs swelling, ${Master}. It's kind of uncomfortable.`));
-				}
-				break;
-			case "hyper breast injections":
-				if (slave.fetishKnown === 1) {
-					if (slave.fetish === "boobs" || slave.energy > 95) {
-						r.push(Spoken(slave, `I can feel my boobs swelling, ${Master}. Thank you for injecting them with hormones, and please, never stop.`));
+					break;
+				case "hyper testicle enhancement":
+					text.push(`${Spoken(slave, `My balls feel so incredibly full, ${Master}. They're really painful.`)}`);
+					if (
+						slave.fetishKnown === 1 &&
+							(slave.fetish === "dom" || slave.fetish === "sadist") &&
+							slave.fetishStrength > 60
+					) {
+						text.push(`${Spoken(slave, `But I can't wait to fill a bitch with my load. Bet they'll look pregnant when I'm done.`)}`);
+					} else if (slave.fetishKnown === 1 && slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
+						text.push(`${Spoken(slave, `I feel like I could fertilize all of a girl's eggs with my cum.`)}`);
 					} else {
-						r.push(Spoken(slave, `I can feel my boobs swelling, ${Master}. It's kind of painful.`));
+						text.push(`${Spoken(slave, `I really need to cum. After I finish, would you please, please fuck me? I can barely stand it.`)}`);
 					}
-				} else {
-					r.push(Spoken(slave, `I can feel my boobs swelling, ${Master}. It's kind of painful.`));
-				}
-				break;
-			case "intensive butt injections":
-				if (slave.fetishKnown === 1 && (slave.fetish === "buttslut" || slave.energy > 95)) {
-					r.push(Spoken(slave, `I can almost feel my butt growing, ${Master}. I can't wait to feel a dick sliding up in between my buttocks.`));
-				} else {
-					r.push(Spoken(slave, `I can almost feel my butt growing, ${Master}. It's kind of uncomfortable.`));
-				}
-				break;
-			case "hyper butt injections":
-				if (slave.fetishKnown === 1) {
-					if (slave.fetish === "buttslut" || slave.energy > 95) {
-						r.push(Spoken(slave, `I can feel my butt growing, ${Master}. I can't wait for a dick to get lost in between my buttocks.`));
+					break;
+				case "intensive breast injections":
+					if (slave.fetishKnown === 1 && (slave.fetish === "boobs" || slave.energy > 95)) {
+						text.push(`${Spoken(slave, `I can almost feel my boobs swelling, ${Master}. Thank you for injecting them with hormones, and please, never stop.`)}`);
 					} else {
-						r.push(Spoken(slave, `I can feel my butt growing, ${Master}. It's kind of painful.`));
+						text.push(`${Spoken(slave, `I can almost feel my boobs swelling, ${Master}. It's kind of uncomfortable.`)}`);
 					}
-				} else {
-					r.push(Spoken(slave, `I can feel my butt growing, ${Master}. It's kind of painful.`));
-				}
-				break;
-			case "lip injections":
-				if (slave.fetishKnown === 1 && (slave.fetish === "cumslut" || slave.energy > 95)) {
-					r.push(Spoken(slave, `I can almost feel my lips swelling, ${Master}. I can't wait to wrap them around a cock.`));
-				} else {
-					r.push(Spoken(slave, `I can almost feel my lips swelling, ${Master}. It's kind of uncomfortable.`));
-				}
-				break;
-			case "fertility drugs":
-				if (isFertile(slave)) {
-					r.push(Spoken(slave, `I feel like I need to have a baby, ${Master}, like right now.`));
-					if (slave.fetishKnown === 1 && slave.fetish === "submissive" && slave.fetishStrength > 60) {
-						r.push(Spoken(slave, `I can't wait for someone to pin me down and fuck me pregnant.`));
-					} else if (slave.fetishKnown === 1 && slave.fetish === "dom" && slave.fetishStrength > 60) {
-						r.push(Spoken(slave, `Makes me want to pin down a cute little`));
-						if (V.seeDicks !== 0) {
-							r.push(Spoken(slave, `dickslave`));
+					break;
+				case "hyper breast injections":
+					if (slave.fetishKnown === 1) {
+						if (slave.fetish === "boobs" || slave.energy > 95) {
+							text.push(`${Spoken(slave, `I can feel my boobs swelling, ${Master}. Thank you for injecting them with hormones, and please, never stop.`)}`);
 						} else {
-							r.push(Spoken(slave, `citizen`));
+							text.push(`${Spoken(slave, `I can feel my boobs swelling, ${Master}. It's kind of painful.`)}`);
 						}
-						r.push(Spoken(slave, `and claim their sperm.`));
-					} else if (slave.fetishKnown === 1 && slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
-						r.push(Spoken(slave, `I can't wait till my belly gets big enough to hold me down.`));
 					} else {
-						r.push(Spoken(slave, `These will get me pregnant, right?`));
+						text.push(`${Spoken(slave, `I can feel my boobs swelling, ${Master}. It's kind of painful.`)}`);
 					}
-				}
-				break;
-			case "super fertility drugs":
-				if (isFertile(slave)) {
-					r.push(Spoken(slave, `My womb feels so full, ${Master}, I need to be fertilized!`));
-					if (slave.fetishKnown === 1 && slave.fetish === "submissive" && slave.fetishStrength > 60) {
-						r.push(Spoken(slave, `I can't wait to be pinned to the floor by my life swollen belly.`));
-					} else if (slave.fetishKnown === 1 && slave.fetish === "dom" && slave.fetishStrength > 60) {
-						r.push(Spoken(slave, `I can't wait till my belly is huge enough to really demand worship.`));
-					} else if (slave.fetishKnown === 1 && slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
-						r.push(Spoken(slave, `I can't wait till my belly swells as big as me.`));
+					break;
+				case "intensive butt injections":
+					if (slave.fetishKnown === 1 && (slave.fetish === "buttslut" || slave.energy > 95)) {
+						text.push(`${Spoken(slave, `I can almost feel my butt growing, ${Master}. I can't wait to feel a dick sliding up in between my buttocks.`)}`);
 					} else {
-						r.push(Spoken(slave, `These will get me pregnant, right? Like, so pregnant I won't be able to stand in the end?`));
+						text.push(`${Spoken(slave, `I can almost feel my butt growing, ${Master}. It's kind of uncomfortable.`)}`);
 					}
-				}
-				break;
-			case "psychostimulants":
-				r.push(Spoken(slave, `My thoughts are so sharp ${Master}, I feel like I'm actually getting smarter.`));
-				break;
-			case "anti-aging cream":
-				if (slave.visualAge+20 < slave.actualAge) {
-					r.push(Spoken(slave, `I look so young, ${Master}, I can barely recognize myself anymore.`));
-				} else {
-					r.push(Spoken(slave, `I can practically feel the years peeling off me, ${Master}.`));
-				}
-				break;
-			case "sag-B-gone":
-				if (slave.fetishKnown === 1) {
-					if (slave.fetish === "boobs" || slave.energy > 95) {
-						r.push(Spoken(slave, `I love all the breast massages, but I don't think the cream is doing anything. They look the same as always, not that that means I want you to stop, ${Master}!`));
+					break;
+				case "hyper butt injections":
+					if (slave.fetishKnown === 1) {
+						if (slave.fetish === "buttslut" || slave.energy > 95) {
+							text.push(`${Spoken(slave, `I can feel my butt growing, ${Master}. I can't wait for a dick to get lost in between my buttocks.`)}`);
+						} else {
+							text.push(`${Spoken(slave, `I can feel my butt growing, ${Master}. It's kind of painful.`)}`);
+						}
 					} else {
-						r.push(Spoken(slave, `I think you might have been ripped off on this sag cream, ${Master}; my breasts don't feel any different.`));
+						text.push(`${Spoken(slave, `I can feel my butt growing, ${Master}. It's kind of painful.`)}`);
 					}
-				} else {
-					r.push(Spoken(slave, `I think you might have been ripped off on this sag cream, ${Master}; my breasts don't feel any different.`));
-				}
-		}
-
-		switch (slave.assignment) {
-			case "whore":
-			case "work in the brothel":
-				if (slave.fetishKnown === 1) {
-					if (slave.energy > 95) {
-						r.push(Spoken(slave, `It's great being a whore. I can't imagine being satisfied doing anything else.`));
-					} else if (slave.fetishStrength > 60) {
-						switch (slave.fetish) {
-							case "submissive":
-								r.push(Spoken(slave, `It's nice being a whore, I get treated like I deserve.`));
-								break;
-							case "dom":
-								r.push(Spoken(slave, `Being a whore is okay, sometimes somebody wants to be dommed.`));
-								break;
-							case "sadist":
-								r.push(Spoken(slave, `Being a whore is okay, sometimes somebody wants me to hurt one of their slaves for them.`));
-								break;
-							case "masochist":
-								r.push(Spoken(slave, `It's nice being a whore, I get hurt like I deserve.`));
-								break;
-							case "cumslut":
-								r.push(Spoken(slave, `It's great being a whore. If I was still free, I would fantasize about getting to suck this many dicks.`));
-								break;
-							case "humiliation":
-								r.push(Spoken(slave, `It's great being a whore, the shame keeps me really horny.`));
-								break;
-							case "buttslut":
-								r.push(Spoken(slave, `It's great being a whore. If I was still free, I would fantasize about taking this much anal.`));
-								break;
-							case "boobs":
-								r.push(Spoken(slave, `It's nice being a whore, sometimes customers just play with my boobs for hours.`));
-								break;
-							case "pregnancy":
-								if (slave.belly >= 5000) {
-									r.push(Spoken(slave, `It's nice being a whore, sometimes customers just play with my belly for hours.`));
-								} else if (isFertile(slave)) {
-									r.push(Spoken(slave, `It's great being a whore, I'm going to get pregnant and there's nothing I can do to stop it.`));
-								} else if (slave.preg > slave.pregData.normalBirth/4) {
-									r.push(Spoken(slave, `It's great being a pregnant whore, I get to watch my belly swell as I get fucked. Every week it gets a little bigger.`));
-								} else if (slave.pregKnown === 1) {
-									r.push(Spoken(slave, `Being a whore is okay, but it will be great once my belly gets bigger.`));
-								} else if (slave.preg > 0) {
-									r.push(Spoken(slave, `Being a whore is okay, I just wish I'd get knocked up already.`));
-								} else {
-									r.push(Spoken(slave, `Being a whore is okay, sometimes I can pretend I can get pregnant.`));
-								}
+					break;
+				case "lip injections":
+					if (slave.fetishKnown === 1 && (slave.fetish === "cumslut" || slave.energy > 95)) {
+						text.push(`${Spoken(slave, `I can almost feel my lips swelling, ${Master}. I can't wait to wrap them around a cock.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I can almost feel my lips swelling, ${Master}. It's kind of uncomfortable.`)}`);
+					}
+					break;
+				case "fertility drugs":
+					if (isFertile(slave)) {
+						text.push(`${Spoken(slave, `I feel like I need to have a baby, ${Master}, like right now.`)}`);
+						if (slave.fetishKnown === 1 && slave.fetish === "submissive" && slave.fetishStrength > 60) {
+							text.push(`${Spoken(slave, `I can't wait for someone to pin me down and fuck me pregnant.`)}`);
+						} else if (slave.fetishKnown === 1 && slave.fetish === "dom" && slave.fetishStrength > 60) {
+							text.push(`${Spoken(slave, `Makes me want to pin down a cute little`)}`);
+							if (V.seeDicks !== 0) {
+								text.push(`${Spoken(slave, `dickslave`)}`);
+							} else {
+								text.push(`${Spoken(slave, `citizen`)}`);
+							}
+							text.push(`${Spoken(slave, `and claim their sperm.`)}`);
+						} else if (slave.fetishKnown === 1 && slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
+							text.push(`${Spoken(slave, `I can't wait till my belly gets big enough to hold me down.`)}`);
+						} else {
+							text.push(`${Spoken(slave, `These will get me pregnant, right?`)}`);
 						}
-					} else if (slave.attrKnown === 1 && slave.attrXY > 60) {
-						r.push(Spoken(slave, `It's nice being a whore, I get fucked by a lot of hot guys.`));
-					} else if (slave.attrKnown === 1 && slave.attrXX > 60) {
-						r.push(Spoken(slave, `It's okay being a whore, I get female customers sometimes.`));
 					}
-				}
-				break;
-			case "serve the public":
-			case "serve in the club":
-				if (slave.fetishKnown === 1) {
-					if (slave.energy > 95) {
-						r.push(Spoken(slave, `It's great being a public slut. I can't imagine being satisfied doing anything else.`));
-					} else if (slave.fetishStrength > 60) {
-						switch (slave.fetish) {
-							case "submissive":
-								r.push(Spoken(slave, `It's nice being a public slut, I get treated like I deserve.`));
-								break;
-							case "dom":
-								r.push(Spoken(slave, `Being a public slut is okay, sometimes somebody wants to be dommed.`));
-								break;
-							case "sadist":
-								r.push(Spoken(slave, `Being a public slut is okay, sometimes somebody wants me to hurt one of their slaves for them.`));
-								break;
-							case "masochist":
-								r.push(Spoken(slave, `It's nice being a public slut, I get hurt like I deserve.`));
-								break;
-							case "cumslut":
-								r.push(Spoken(slave, `It's great being a public slut. If I was still free, I would fantasize about getting to suck this many dicks.`));
-								break;
-							case "humiliation":
-								r.push(Spoken(slave, `It's great being a public slut, the shame keeps me really horny.`));
-								break;
-							case "buttslut":
-								r.push(Spoken(slave, `It's great being a public slut. If I was still free, I would fantasize about taking this much anal.`));
-								break;
-							case "boobs":
-								r.push(Spoken(slave, `It's nice being a public slut, sometimes citizens just play with my boobs for hours.`));
-								break;
-							case "pregnancy":
-								if (slave.belly >= 5000) {
-									r.push(Spoken(slave, `It's nice being a public slut, sometimes citizens just play with my belly for hours.`));
-								} else if (isFertile(slave)) {
-									r.push(Spoken(slave, `It's great being a public slut, I'm going to get pregnant and there's nothing I can do to stop it.`));
-								} else if (slave.preg > slave.pregData.normalBirth/4) {
-									r.push(Spoken(slave, `It's great being a pregnant public slut, I get to show off my belly all the time.`));
-								} else if (slave.pregKnown === 1) {
-									r.push(Spoken(slave, `Being a public slut is okay, but it will be great once my belly gets bigger.`));
-								} else if (slave.preg > 0) {
-									r.push(Spoken(slave, `Being a public slut is okay, I just wish I'd get knocked up already.`));
-								} else {
-									r.push(Spoken(slave, `Being a public slut is okay, sometimes I can pretend I can get pregnant.`));
-								}
+					break;
+				case "super fertility drugs":
+					if (isFertile(slave)) {
+						text.push(`${Spoken(slave, `My womb feels so full, ${Master}, I need to be fertilized!`)}`);
+						if (slave.fetishKnown === 1 && slave.fetish === "submissive" && slave.fetishStrength > 60) {
+							text.push(`${Spoken(slave, `I can't wait to be pinned to the floor by my life swollen belly.`)}`);
+						} else if (slave.fetishKnown === 1 && slave.fetish === "dom" && slave.fetishStrength > 60) {
+							text.push(`${Spoken(slave, `I can't wait till my belly is huge enough to really demand worship.`)}`);
+						} else if (slave.fetishKnown === 1 && slave.fetish === "pregnancy" && slave.fetishStrength > 60) {
+							text.push(`${Spoken(slave, `I can't wait till my belly swells as big as me.`)}`);
+						} else {
+							text.push(`${Spoken(slave, `These will get me pregnant, right? Like, so pregnant I won't be able to stand in the end?`)}`);
 						}
-					} else if (slave.attrKnown === 1 && slave.attrXY > 60) {
-						r.push(Spoken(slave, `It's nice being a public slut, I get fucked by a lot of hot guys.`));
-					} else if (slave.attrKnown === 1 && slave.attrXX > 60) {
-						r.push(Spoken(slave, `It's okay being a public slut; I get female citizens sometimes.`));
 					}
-				}
-				break;
-			case "get milked":
-			case "work in the dairy":
-				if (slave.balls === 0) {
+					break;
+				case "psychostimulants":
+					text.push(`${Spoken(slave, `My thoughts are so sharp ${Master}, I feel like I'm actually getting smarter.`)}`);
+					break;
+				case "anti-aging cream":
+					if (slave.visualAge+20 < slave.actualAge) {
+						text.push(`${Spoken(slave, `I look so young, ${Master}, I can barely recognize myself anymore.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I can practically feel the years peeling off me, ${Master}.`)}`);
+					}
+					break;
+				case "sag-B-gone":
 					if (slave.fetishKnown === 1) {
-						if (slave.energy > 95) {
-							r.push(Spoken(slave, `It's pretty nice, being milked.`));
-						} else if (slave.fetish === "submissive" && slave.fetishStrength > 60) {
-							r.push(Spoken(slave, `It's nice being milked, I get treated like I deserve.`));
-						} else if (slave.fetish === "boobs" && slave.fetishStrength > 60) {
-							r.push(Spoken(slave, `It's so, so wonderful being milked.`));
-						} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-							r.push(Spoken(slave, `It's okay being milked, with all the girls and boobs around.`));
+						if (slave.fetish === "boobs" || slave.energy > 95) {
+							text.push(`${Spoken(slave, `I love all the breast massages, but I don't think the cream is doing anything. They look the same as always, not that that means I want you to stop, ${Master}!`)}`);
 						} else {
-							r.push(Spoken(slave, `Being milked is hard work.`));
+							text.push(`${Spoken(slave, `I think you might have been ripped off on this sag cream, ${Master}; my breasts don't feel any different.`)}`);
 						}
+					} else {
+						text.push(`${Spoken(slave, `I think you might have been ripped off on this sag cream, ${Master}; my breasts don't feel any different.`)}`);
 					}
-				} else {
+			}
+
+			return text.join(' ');
+		}
+
+		function assignment() {
+			const text = [];
+
+			switch (slave.assignment) {
+				case Job.WHORE:
+				case Job.BROTHEL:
 					if (slave.fetishKnown === 1) {
-						if (slave.fetish === "buttslut" || slave.energy > 95) {
-							r.push(Spoken(slave, `Getting buttfucked to orgasm whenever I can get hard is a dream come true. Actually, getting buttfucked until I cum`));
-							if (slave.prostate > 0) {
-								r.push(Spoken(slave, `even when I'm soft`));
+						if (slave.energy > 95) {
+							text.push(`${Spoken(slave, `It's great being a whore. I can't imagine being satisfied doing anything else.`)}`);
+						} else if (slave.fetishStrength > 60) {
+							switch (slave.fetish) {
+								case "submissive":
+									text.push(`${Spoken(slave, `It's nice being a whore; I get treated like I deserve.`)}`);
+									break;
+								case "dom":
+									text.push(`${Spoken(slave, `Being a whore is okay, sometimes somebody wants to be dommed.`)}`);
+									break;
+								case "sadist":
+									text.push(`${Spoken(slave, `Being a whore is okay, sometimes somebody wants me to hurt one of their slaves for them.`)}`);
+									break;
+								case "masochist":
+									text.push(`${Spoken(slave, `It's nice being a whore; I get hurt like I deserve.`)}`);
+									break;
+								case "cumslut":
+									text.push(`${Spoken(slave, `It's great being a whore. If I was still free, I would fantasize about getting to suck this many dicks.`)}`);
+									break;
+								case "humiliation":
+									text.push(`${Spoken(slave, `It's great being a whore; the shame keeps me really horny.`)}`);
+									break;
+								case "buttslut":
+									text.push(`${Spoken(slave, `It's great being a whore. If I was still free, I would fantasize about taking this much anal.`)}`);
+									break;
+								case "boobs":
+									text.push(`${Spoken(slave, `It's nice being a whore; sometimes customers just play with my boobs for hours.`)}`);
+									break;
+								case "pregnancy":
+									if (slave.belly >= 5000) {
+										text.push(`${Spoken(slave, `It's nice being a whore; sometimes customers just play with my belly for hours.`)}`);
+									} else if (isFertile(slave)) {
+										text.push(`${Spoken(slave, `It's great being a whore; I'm going to get pregnant and there's nothing I can do to stop it.`)}`);
+									} else if (slave.preg > slave.pregData.normalBirth/4) {
+										text.push(`${Spoken(slave, `It's great being a pregnant whore; I get to watch my belly swell as I get fucked. Every week it gets a little bigger.`)}`);
+									} else if (slave.pregKnown === 1) {
+										text.push(`${Spoken(slave, `Being a whore is okay, but it will be great once my belly gets bigger.`)}`);
+									} else if (slave.preg > 0) {
+										text.push(`${Spoken(slave, `Being a whore is okay, I just wish I'd get knocked up already.`)}`);
+									} else {
+										text.push(`${Spoken(slave, `Being a whore is okay, sometimes I can pretend I can get pregnant.`)}`);
+									}
 							}
-							r.push(Spoken(slave, `is pretty nice too.`));
-						} else if (slave.attrKnown === 1 && slave.attrXY > 80) {
-							r.push(Spoken(slave, `It's okay getting cockmilked, I like all the dicks around.`));
-						} else {
-							r.push(Spoken(slave, `It's surprisingly hard work, coming all day.`));
+						} else if (slave.attrKnown === 1 && slave.attrXY > 60) {
+							text.push(`${Spoken(slave, `It's nice being a whore; I get fucked by a lot of hot guys.`)}`);
+						} else if (slave.attrKnown === 1 && slave.attrXX > 60) {
+							text.push(`${Spoken(slave, `It's okay being a whore; I get female customers sometimes.`)}`);
 						}
 					}
-				}
-				break;
-			case "work as a farmhand":
-				// TODO: add a description for this
-				break;
-			case "please you":
-			case "serve in the master suite":
-			case "be your Concubine":
-				if (slave.fetishKnown === 1) {
-					if (slave.toyHole === "mouth" && (slave.fetish === "cumslut" && slave.fetishStrength > 60 && V.PC.dick !== 0)) {
-						r.push(Spoken(slave, `I love sucking your cock every`));
-						if (V.PC.balls >= 14) {
-							r.push(Spoken(slave, `day, and I love every opportunity I get to worship your balls, they're so huge and make so much cum and I just want to spend my life kissing your balls and sucking your cock, and live off your cum...`));
-						} else if (V.PC.balls >= 9) {
-							r.push(Spoken(slave, `day, and I love worshipping your massive balls.`));
-							if (hasAnyArms(slave)) {
-								r.push(Spoken(slave, `Your balls are so big that one testicle fills my hand; I even cum without touching myself so I can properly serve you.`));
-							} else {
-								r.push(Spoken(slave, `Feeling you rest your balls on my face in between facefucks is heaven for me.`));
+					break;
+				case Job.PUBLIC:
+				case Job.CLUB:
+					if (slave.fetishKnown === 1) {
+						if (slave.energy > 95) {
+							text.push(`${Spoken(slave, `It's great being a public slut. I can't imagine being satisfied doing anything else.`)}`);
+						} else if (slave.fetishStrength > 60) {
+							switch (slave.fetish) {
+								case "submissive":
+									text.push(`${Spoken(slave, `It's nice being a public slut, I get treated like I deserve.`)}`);
+									break;
+								case "dom":
+									text.push(`${Spoken(slave, `Being a public slut is okay, sometimes somebody wants to be dommed.`)}`);
+									break;
+								case "sadist":
+									text.push(`${Spoken(slave, `Being a public slut is okay, sometimes somebody wants me to hurt one of their slaves for them.`)}`);
+									break;
+								case "masochist":
+									text.push(`${Spoken(slave, `It's nice being a public slut, I get hurt like I deserve.`)}`);
+									break;
+								case "cumslut":
+									text.push(`${Spoken(slave, `It's great being a public slut. If I was still free, I would fantasize about getting to suck this many dicks.`)}`);
+									break;
+								case "humiliation":
+									text.push(`${Spoken(slave, `It's great being a public slut, the shame keeps me really horny.`)}`);
+									break;
+								case "buttslut":
+									text.push(`${Spoken(slave, `It's great being a public slut. If I was still free, I would fantasize about taking this much anal.`)}`);
+									break;
+								case "boobs":
+									text.push(`${Spoken(slave, `It's nice being a public slut, sometimes citizens just play with my boobs for hours.`)}`);
+									break;
+								case "pregnancy":
+									if (slave.belly >= 5000) {
+										text.push(`${Spoken(slave, `It's nice being a public slut, sometimes citizens just play with my belly for hours.`)}`);
+									} else if (isFertile(slave)) {
+										text.push(`${Spoken(slave, `It's great being a public slut, I'm going to get pregnant and there's nothing I can do to stop it.`)}`);
+									} else if (slave.preg > slave.pregData.normalBirth/4) {
+										text.push(`${Spoken(slave, `It's great being a pregnant public slut, I get to show off my belly all the time.`)}`);
+									} else if (slave.pregKnown === 1) {
+										text.push(`${Spoken(slave, `Being a public slut is okay, but it will be great once my belly gets bigger.`)}`);
+									} else if (slave.preg > 0) {
+										text.push(`${Spoken(slave, `Being a public slut is okay, I just wish I'd get knocked up already.`)}`);
+									} else {
+										text.push(`${Spoken(slave, `Being a public slut is okay, sometimes I can pretend I can get pregnant.`)}`);
+									}
 							}
-						} else if (V.PC.balls >= 5) {
-							r.push(Spoken(slave, `day, and I love pleasuring your big balls too. They're the perfect size to fill my mouth as I suck on them, and I love feeling them tense against my chin when you shoot cum down my throat.`));
-						} else if (V.PC.scrotum > 0) {
-							r.push(Spoken(slave, `day, and I love playing with your balls too.`));
-						} else {
-							r.push(Spoken(slave, `day.`));
+						} else if (slave.attrKnown === 1 && slave.attrXY > 60) {
+							text.push(`${Spoken(slave, `It's nice being a public slut, I get fucked by a lot of hot guys.`)}`);
+						} else if (slave.attrKnown === 1 && slave.attrXX > 60) {
+							text.push(`${Spoken(slave, `It's okay being a public slut; I get female citizens sometimes.`)}`);
 						}
-					} else if (slave.toyHole !== "dick") {
-						if (slave.energy > 95 && V.PC.dick !== 0) {
-							r.push(Spoken(slave, `I love how taking your cock is my only job, and I love having your other toys to have sex with too.`));
-						} else {
-							r.push(Spoken(slave, `It's nice being your ${girl}.`));
+					}
+					break;
+				case Job.MILKED:
+				case Job.DAIRY:
+					if (slave.balls === 0) {
+						if (slave.fetishKnown === 1) {
+							if (slave.energy > 95) {
+								text.push(`${Spoken(slave, `It's pretty nice, being milked.`)}`);
+							} else if (slave.fetish === "submissive" && slave.fetishStrength > 60) {
+								text.push(`${Spoken(slave, `It's nice being milked, I get treated like I deserve.`)}`);
+							} else if (slave.fetish === "boobs" && slave.fetishStrength > 60) {
+								text.push(`${Spoken(slave, `It's so, so wonderful being milked.`)}`);
+							} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+								text.push(`${Spoken(slave, `It's okay being milked, with all the girls and boobs around.`)}`);
+							} else {
+								text.push(`${Spoken(slave, `Being milked is hard work.`)}`);
+							}
 						}
 					} else {
-						if (slave.energy > 95 && V.PC.vagina !== -1) {
-							r.push(Spoken(slave, `I love how fucking your`));
-							if (V.PC.vagina !== -1) {
-								r.push(Spoken(slave, `pussy`));
+						if (slave.fetishKnown === 1) {
+							if (slave.fetish === "buttslut" || slave.energy > 95) {
+								text.push(`${Spoken(slave, `Getting buttfucked to orgasm whenever I can get hard is a dream come true. Actually, getting buttfucked until I cum`)}`);
+								if (slave.prostate > 0) {
+									text.push(`${Spoken(slave, `even when I'm soft`)}`);
+								}
+								text.push(`${Spoken(slave, `is pretty nice too.`)}`);
+							} else if (slave.attrKnown === 1 && slave.attrXY > 80) {
+								text.push(`${Spoken(slave, `It's okay getting cockmilked, I like all the dicks around.`)}`);
+							} else {
+								text.push(`${Spoken(slave, `It's surprisingly hard work, coming all day.`)}`);
+							}
+						}
+					}
+					break;
+				case Job.FARMYARD:
+					// TODO: expand this with devotion, trust, etc
+					if (V.farmyardShows === 0) {
+						text.push(Spoken(slave, `Working the fields is a hard job, ${Master}, but I know we need the food to survive.`));
+					} else if (V.farmyardShows === 1) {
+						text.push(Spoken(slave, `Working the fields is a hard job, ${Master}, especially after ${V.seeBestiality ? `fucking animals` : `putting on shows with animals`} for hours on end.`));
+					} else if (V.farmyardShows === 2) {
+						text.push(Spoken(slave, `I love that ${V.seeBestiality ? `fucking your animals` : `putting on shows with your animals`} is my only job.`));
+					}
+					break;
+				case Job.FUCKTOY:
+				case Job.MASTERSUITE:
+				case Job.CONCUBINE:
+					if (slave.fetishKnown === 1) {
+						if (slave.toyHole === "mouth" && (slave.fetish === "cumslut" && slave.fetishStrength > 60 && V.PC.dick !== 0)) {
+							text.push(`${Spoken(slave, `I love sucking your cock every`)}`);
+							if (V.PC.balls >= 14) {
+								text.push(`${Spoken(slave, `day, and I love every opportunity I get to worship your balls; they're so huge and make so much cum and I just want to spend my life kissing your balls and sucking your cock, and live off your cum...`)}`);
+							} else if (V.PC.balls >= 9) {
+								text.push(`${Spoken(slave, `day, and I love worshipping your massive balls.`)}`);
+								if (hasAnyArms(slave)) {
+									text.push(`${Spoken(slave, `Your balls are so big that one testicle fills my hand; I even cum without touching myself so I can properly serve you.`)}`);
+								} else {
+									text.push(`${Spoken(slave, `Feeling you rest your balls on my face in between facefucks is heaven for me.`)}`);
+								}
+							} else if (V.PC.balls >= 5) {
+								text.push(`${Spoken(slave, `day, and I love pleasuring your big balls too. They're the perfect size to fill my mouth as I suck on them, and I love feeling them tense against my chin when you shoot cum down my throat.`)}`);
+							} else if (V.PC.scrotum > 0) {
+								text.push(`${Spoken(slave, `day, and I love playing with your balls too.`)}`);
+							} else {
+								text.push(`${Spoken(slave, `day.`)}`);
+							}
+						} else if (slave.toyHole !== "dick") {
+							if (slave.energy > 95 && V.PC.dick !== 0) {
+								text.push(`${Spoken(slave, `I love how taking your cock is my only job${fuckSlavesLength() > 0 ? `, and I love having your other toys to have sex with too` : ``}.`)}`);
 							} else {
-								r.push(Spoken(slave, `ass`));
+								text.push(`${Spoken(slave, `It's nice being your ${girl}.`)}`);
 							}
-							r.push(Spoken(slave, `is my only job, and I'm so happy you trust me enough to cum inside you.`));
 						} else {
-							r.push(Spoken(slave, `I like letting you use my cock as your toy, and I'm happy you trust me enough to cum with you.`));
+							if (slave.energy > 95 && V.PC.vagina !== -1) {
+								text.push(`${Spoken(slave, `I love how fucking your`)}`);
+								if (V.PC.vagina !== -1) {
+									text.push(`${Spoken(slave, `pussy`)}`);
+								} else {
+									text.push(`${Spoken(slave, `ass`)}`);
+								}
+								text.push(`${Spoken(slave, `is my only job, and I'm so happy you trust me enough to cum inside you.`)}`);
+							} else {
+								text.push(`${Spoken(slave, `I like letting you use my cock as your toy, and I'm happy you trust me enough to cum with you.`)}`);
+							}
 						}
 					}
-				}
-				break;
-			case "rest":
-			case "rest in the spa":
-				r.push(Spoken(slave, `Thank you for letting me rest.`));
-				break;
-			case "work as a nanny":
-				r.push(Spoken(slave, `I love taking care of the babies. I hope I get to`));
-				if (canSee(slave)) {
-					r.push(Spoken(slave, `see`));
-				} else {
-					r.push(Spoken(slave, `have`));
-				}
-				r.push(Spoken(slave, `them grow up to into good slaves for you.`));
-				break;
-			default:
-				r.push(Spoken(slave, `Being a sex slave is hard work.`));
+					break;
+				case Job.REST:
+				case Job.SPA:
+					text.push(`${Spoken(slave, `Thank you for letting me rest.`)}`);
+					break;
+				case Job.NURSERY:
+					text.push(`${Spoken(slave, `I love taking care of the babies. I hope I get to`)}`);
+					if (canSee(slave)) {
+						text.push(`${Spoken(slave, `see`)}`);
+					} else {
+						text.push(`${Spoken(slave, `have`)}`);
+					}
+					text.push(`${Spoken(slave, `them grow up to into good slaves for you.`)}`);
+					break;
+				default:
+					text.push(`${Spoken(slave, `Being a sex slave is hard work.`)}`);
+			}
+
+			return text.join(' ');
 		}
 
-		if ((slave.skill.oral + slave.skill.anal) >= 120 && slave.vagina === -1) {
-			r.push(Spoken(slave, `I'm really proud of my sex skills, it's nice to be good at what you do. Without a cunt my poor`));
-			if (slave.anus > 2) {
-				r.push(Spoken(slave, `asspussy`));
-			} else if (slave.anus === 2) {
-				r.push(Spoken(slave, `butthole`));
-			} else {
-				r.push(Spoken(slave, `little anus`));
-			}
-			r.push(Spoken(slave, `does double duty, but I can take it.`));
-		} else if ((slave.skill.oral + slave.skill.vaginal + slave.skill.anal) >= 180) {
-			r.push(Spoken(slave, `I'm really proud of my sex skills, it's nice to be good at what you do.`));
-		} else if (slave.skill.whoring >= 100) {
-			r.push(Spoken(slave, `I'm really proud of my whoring skills, prostitution is just a job like any other to me.`));
-		} else if (slave.skill.entertainment >= 100) {
-			r.push(Spoken(slave, `I'm really proud of my skills, I feel like I can make anyone want me.`));
-		} else if (slave.skill.anal >= 100) {
-			if (slave.vagina === -1) {
-				r.push(Spoken(slave, `I'm really proud of my anal skills, I can take a dick as well as anyone.`));
-			} else {
-				r.push(Spoken(slave, `I'm really proud of my anal skills, it's fun having three fuckholes.`));
+		function skills() {
+			const text = [];
+
+			if ((slave.skill.oral + slave.skill.anal) >= 120 && slave.vagina === -1) {
+				text.push(`${Spoken(slave, `I'm really proud of my sex skills; it's nice to be good at what you do. Without a cunt my poor`)}`);
+				if (slave.anus > 2) {
+					text.push(`${Spoken(slave, `asspussy`)}`);
+				} else if (slave.anus === 2) {
+					text.push(`${Spoken(slave, `butthole`)}`);
+				} else {
+					text.push(`${Spoken(slave, `little anus`)}`);
+				}
+				text.push(`${Spoken(slave, `does double duty, but I can take it.`)}`);
+			} else if ((slave.skill.oral + slave.skill.vaginal + slave.skill.anal) >= 180) {
+				text.push(`${Spoken(slave, `I'm really proud of my sex skills; it's nice to be good at what you do.`)}`);
+			} else if (slave.skill.whoring >= 100) {
+				text.push(`${Spoken(slave, `I'm really proud of my whoring skills; prostitution is a job I know I can do well.`)}`);
+			} else if (slave.skill.entertainment >= 100) {
+				text.push(`${Spoken(slave, `I'm really proud of my skills; I feel like I can make anyone want me.`)}`);
+			} else if (slave.skill.anal >= 100) {
+				if (slave.vagina === -1) {
+					text.push(`${Spoken(slave, `I'm really proud of my anal skills; I can take a dick as well as anyone.`)}`);
+				} else {
+					text.push(`${Spoken(slave, `I'm really proud of my anal skills; it's fun having three fuckholes.`)}`);
+				}
+			} else if (slave.skill.anal <= 30 && slave.anus > 0) {
+				text.push(`${Spoken(slave, `I wish I were better at anal; if I could learn to relax getting buttfucked wouldn't hurt so much.`)}`);
+			} else if (slave.skill.vaginal <= 30 && slave.vagina > 0) {
+				text.push(`${Spoken(slave, `I wish I were better at sex; sometimes all I can think to do is just lie there.`)}`);
+			} else if (slave.skill.oral <= 30) {
+				if (slave.counter.oral > 0) {
+					text.push(`${Spoken(slave, `I wish I were better at blowjobs; it would be nice not to gag so much.`)}`);
+				} else {
+					text.push(`${Spoken(slave, `I wish I knew more about giving head; I feel like I'll have no idea what I'm doing when I get the chance.`)}`);
+				}
 			}
-		} else if (slave.skill.anal <= 30 && slave.anus > 0) {
-			r.push(Spoken(slave, `I wish I were better at anal, if I could learn to relax getting buttfucked wouldn't hurt so much.`));
-		} else if (slave.skill.vaginal <= 30 && slave.vagina > 0) {
-			r.push(Spoken(slave, `I wish I were better at sex, sometimes all I can think to do is just lie there.`));
-		} else if (slave.skill.oral <= 30) {
-			r.push(Spoken(slave, `I wish I were better at blowjobs; it would be nice not to gag so much.`));
+
+			return text.join(' ');
 		}
 
-		if (slave.relationship > 0) {
-			const partner = getSlave(slave.relationshipTarget);
-			const {
-				He2, His2,
-				he2, his2, him2, daughter2, sister2,
-			} = getPronouns(partner).appendSuffix("2");
-			let partnerName;
-			if (partner) {
-				if (willLisp) {
-					partnerName = lispReplace(partner.slaveName);
+		function relationships() {
+			 const text = [];
+
+			if (slave.relationship > 0) {
+				const partner = getSlave(slave.relationshipTarget);
+				const {
+					He: He2, His: His2,
+					he: he2, his: his2, him: him2, daughter: daughter2, sister: sister2,
+				} = getPronouns(partner);
+
+				let partnerName;
+
+				if (partner) {
+					if (lisps) {
+						partnerName = lispReplace(partner.slaveName);
+					} else {
+						partnerName = partner.slaveName;
+					}
 				} else {
-					partnerName = partner.slaveName;
+					text.push(`${Spoken(slave, `<span class="red">Error, relationshipTarget not found.</span>`)}`);
 				}
-			} else {
-				r.push(Spoken(slave, `<span class="red">Error, relationshipTarget not found.</span>`));
-			}
-			if (slave.relationship <= 2) {
-				r.push(Spoken(slave, `I really like`));
-				if (canSee(slave)) {
-					r.push(Spoken(slave, `seeing`));
-				} else {
-					r.push(Spoken(slave, `hanging out with`));
+				if (slave.relationship <= 2) {
+					text.push(`${Spoken(slave, `I really like`)}`);
+					if (canSee(slave)) {
+						text.push(`${Spoken(slave, `seeing`)}`);
+					} else {
+						text.push(`${Spoken(slave, `hanging out with`)}`);
+					}
+					text.push(Spoken(slave, `${partnerName} every day, ${he2}'s a good friend."`));
+					if (partner.face > 40) {
+						text.push(`${He} blushes. ${Spoken(slave, `"${He2}'s kind of hot, too.`)}`);
+					}
+				} else if (slave.relationship <= 3) {
+					text.push(`${Spoken(slave, `I really like`)}`);
+					if (canSee(slave)) {
+						text.push(`${Spoken(slave, `seeing`)}`);
+					} else {
+						text.push(`${Spoken(slave, `hanging out with`)}`);
+					}
+					text.push(`${Spoken(slave, `${partnerName} every day, ${he2}'s a good friend —" ${He} blushes. "— even when we're not fucking.`)}`);
+				} else if (slave.relationship <= 4) {
+					text.push(`${Spoken(slave, `I really love ${partnerName}." ${He} blushes. "Thank you for letting us be together, ${Master}.`)}`);
+				} else {
+					text.push(`${Spoken(slave, `I'm so happy with ${partnerName}." ${He} blushes. "Thank you for ${him2}, ${Master}.`)}`);
+				}
+				if (slave.relationship >= 3) {
+					if (slave.mother === partner.ID) {
+						text.push(`${Spoken(slave, `"I — I'm fucking my mother,"`)} ${he} bursts out, blushing even harder. ${Spoken(slave, `"It's so fucking wrong, but ${he2}'s such a hot MILF, I can't stop.`)}`);
+					} else if (slave.father === partner.ID) {
+						text.push(`${Spoken(slave, `I — I'm fucking my father,"`)} ${he} bursts out, blushing even harder. ${Spoken(slave, `"It's so fucking wrong, but ${he2} knows so much about penetration, I can't stop.`)}`);
+					} else if (partner.mother === slave.ID) {
+						text.push(`${Spoken(slave, `I — I'm fucking my ${daughter2},"`)} ${he} bursts out, blushing even harder. ${Spoken(slave, `"It's so fucking wrong, but ${he2} has such a hot little body, I can't stop.`)}`);
+					} else if (partner.father === slave.ID) {
+						text.push(`${Spoken(slave, `I — I'm fucking my ${daughter2},"`)} ${he} bursts out, blushing even harder. ${Spoken(slave, `"It's so fucking wrong, but ${he2} has such a hot little body. ${He2} looks so much like ${his2} mother, I can't stop.`)}`);
+					} else if (areSisters(slave, partner) === 1) {
+						text.push(`${Spoken(slave, `I — I'm fucking my twin ${sister2},"`)} ${he} bursts out, blushing even harder. ${Spoken(slave, `"It's so fucking wrong, but ${he2}'s so hot, I can't stop.`)}`);
+					} else if (areSisters(slave, partner) === 2) {
+						text.push(`${Spoken(slave, `I — I'm fucking my ${sister2},"`)} ${he} bursts out, blushing even harder. ${Spoken(slave, `"It's so fucking wrong, but ${he2}'s so hot, I can't stop.`)}`);
+					} else if (areSisters(slave, partner) === 3) {
+						text.push(`${Spoken(slave, `I — I'm fucking my half-${sister2},"`)} ${he} bursts out, blushing even harder. ${Spoken(slave, `"It's so fucking wrong, but ${he2}'s so hot, I can't stop.`)}`);
+					} else if ((slave.actualAge + 14) < partner.actualAge) {
+						text.push(`${Spoken(slave, `${He2}'s old enough to be my mother."`)} ${He} looks down, blushing a little harder. ${Spoken(slave, `"But I'm lucky, ${he2}'s such a hot MILF.`)}`);
+					} else if ((slave.actualAge - 14) > partner.actualAge) {
+						text.push(`${Spoken(slave, `${He2}'s young enough to be my ${daughter2}."`)} ${He} looks down, blushing a little harder. ${Spoken(slave, `"But I love ${his2} hot young body.`)}`);
+					}
+					if ((slave.actualAge - 5) > partner.actualAge && partner.actualAge < 13) {
+						text.push(`${Spoken(slave, `${He2}'s very immature at times, of course, but ${he2} has so much energy!`)}`);
+					} else if ((slave.actualAge - 5) > partner.actualAge && partner.actualAge < 20) {
+						text.push(`${Spoken(slave, `${He2}'s a little immature at times, but having sex with a teenager is so awesome, it's worth it.`)}`);
+					}
+					if (hasAnyProstheticLimbs(partner)) {
+						const sex = getLimbCount(partner, 103);
+						const beauty = getLimbCount(partner, 104);
+						const combat = getLimbCount(partner, 105);
+						if (sex > 0 && beauty > 0 && combat > 0) {
+							text.push(`${Spoken(slave, `${His2} P-Limbs do look cool and I like how strong they can make ${him2} but they scare me a little, sometimes. Though of course ${he2} disables the weapons when we're together."`)} ${He} giggles. ${Spoken(slave, `"${He2} has vibe fingers, so that's awesome.`)}`);
+						} else if (sex > 0 && beauty > 0) {
+							text.push(`${Spoken(slave, `I really like ${his2} P-Limbs. They're very pretty, but kind of cold. That's just how ${he2} is."`)} ${He} giggles. ${Spoken(slave, `" ${He2} has vibe fingers. so that's awesome.`)}`);
+						} else if (beauty > 0 && combat > 0) {
+							text.push(`${Spoken(slave, `${His2} P-Limbs do look cool and I like how strong they can make ${him2} but they scare me a little, sometimes. Though of course ${he2} disables the weapons when we're together.`)}`);
+						} else if (sex > 0 && combat > 0) {
+							text.push(`${Spoken(slave, `${His2} P-Limbs do scare me a little, sometimes. Though of course ${he2} disables the weapons when we're together."`)} ${He} giggles. ${Spoken(slave, `"${He2} has vibe fingers. so that's awesome.`)}`);
+						} else if (sex > 0) {
+							text.push(`${Spoken(slave, `And, um."`)} ${He} giggles. ${Spoken(slave, `"${He2} has vibe fingers. so that's awesome.`)}`);
+						} else if (beauty > 0) {
+							text.push(`${Spoken(slave, `I really like ${his2} P-Limbs. They're very pretty, but kind of cold. That's just how ${he2} is.`)}`);
+						} else if (combat > 0) {
+							text.push(`${Spoken(slave, `${His2} P-Limbs do scare me a little, sometimes. Though of course ${he2} disables the weapons when we're together."`)} ${He} giggles. ${Spoken(slave, `"Though I did get ${him2} to extend ${his2} blades once, so I could kiss them for luck.`)}`);
+						} else {
+							text.push(`${Spoken(slave, `I really do like ${his2} P-Limbs. They're a little awkward, and kind of cold, but that's just how ${he2} is.`)}`);
+						}
+					} else if (getLimbCount(partner, 0) > 0) {
+						text.push(`${Spoken(slave, `${He2}'s an amputee, of course, so that's a little sad.`)}`);
+					}
 				}
-				r.push(Spoken(slave, `${partnerName} every day, ${he2}'s a good friend." ${He} blushes. "${He2}'s kind of hot, too.`));
-			} else if (slave.relationship <= 3) {
-				r.push(Spoken(slave, `I really like`));
-				if (canSee(slave)) {
-					r.push(Spoken(slave, `seeing`));
+			} else if (slave.relationship === -3) {
+				if (slave.devotion+slave.trust >= 175) {
+					text.push(`${Spoken(slave, `Of course, I'm your ${wife}, ${Master}."`)} ${He} laughs. ${Spoken(slave, `"Not exactly traditional married life, but I'll do my best to help redefine it.`)}`);
+				} else if (slave.devotion < -20 && slave.trust > 20) {
+					text.push(`${Spoken(slave, `Of course, I'm your ${wife}, ${Master}." `)} ${He} sighs. ${Spoken(slave, `"Any other questions?`)}`);
+				} else if (slave.devotion < -20) {
+					text.push(`${Spoken(slave, `I'm your ${wife},`)}`);
+
+					if (slave.rudeTitle === 1) {
+						text.push(`${Spoken(slave, `${PoliteRudeTitle(slave)},"`)}`);
+					} else {
+						text.push(`${Spoken(slave, `${Master},"`)}`);
+					}
+
+					text.push(`${he} ${say}s, ${his} voice wavering. ${Spoken(slave, `"Please let me go...`)}`);
 				} else {
-					r.push(Spoken(slave, `hanging out with`));
+					text.push(`${Spoken(slave, `Of course, I'm your ${wife}, ${Master},"`)} ${he} ${say}s. ${Spoken(slave, `"It isn't so bad, I'm starting to like it.`)}`);
 				}
-				r.push(Spoken(slave, `${partnerName} every day, ${he2}'s a good friend —" ${He} blushes. "— even when we're not fucking.`));
-			} else if (slave.relationship <= 4) {
-				r.push(Spoken(slave, `I really love ${partnerName}." ${He} blushes. "Thank you for letting us be together, ${Master}.`));
-			} else {
-				r.push(Spoken(slave, `I'm so happy with ${partnerName}." ${He} blushes. "Thank you for ${him2}, ${Master}.`));
-			}
-			if (slave.relationship >= 3) {
-				if (slave.mother === partner.ID) {
-					r.push(Spoken(slave, `"I — I'm fucking my mother,"`));
-					r.push(`${he} bursts out, blushing even harder.`);
-					r.push(Spoken(slave, `"It's so fucking wrong, but ${he2}'s such a hot MILF, I can't stop.`));
-				} else if (slave.father === partner.ID) {
-					r.push(Spoken(slave, `I — I'm fucking my father,"`));
-					r.push(`${he} bursts out, blushing even harder.`);
-					r.push(Spoken(slave, `"It's so fucking wrong, but ${he2} knows so much about penetration, I can't stop.`));
-				} else if (partner.mother === slave.ID) {
-					r.push(Spoken(slave, `I — I'm fucking my ${daughter2},"`));
-					r.push(`${he} bursts out, blushing even harder.`);
-					r.push(Spoken(slave, `"It's so fucking wrong, but ${he2} has such a hot little body, I can't stop.`));
-				} else if (partner.father === slave.ID) {
-					r.push(Spoken(slave, `I — I'm fucking my ${daughter2},"`));
-					r.push(`${he} bursts out, blushing even harder.`);
-					r.push(Spoken(slave, `"It's so fucking wrong, but ${he2} has such a hot little body. ${He2} looks so much like ${his2} mother, I can't stop.`));
-				} else if (areSisters(slave, partner) === 1) {
-					r.push(Spoken(slave, `I — I'm fucking my twin ${sister2},"`));
-					r.push(`${he} bursts out, blushing even harder.`);
-					r.push(Spoken(slave, `"It's so fucking wrong, but ${he2}'s so hot, I can't stop.`));
-				} else if (areSisters(slave, partner) === 2) {
-					r.push(Spoken(slave, `I — I'm fucking my ${sister2},"`));
-					r.push(`${he} bursts out, blushing even harder.`);
-					r.push(Spoken(slave, `"It's so fucking wrong, but ${he2}'s so hot, I can't stop.`));
-				} else if (areSisters(slave, partner) === 3) {
-					r.push(Spoken(slave, `I — I'm fucking my half-${sister2},"`));
-					r.push(`${he} bursts out, blushing even harder.`);
-					r.push(Spoken(slave, `"It's so fucking wrong, but ${he2}'s so hot, I can't stop.`));
-				} else if ((slave.actualAge + 14) < partner.actualAge) {
-					r.push(Spoken(slave, `${He2}'s old enough to be my mother."`));
-					r.push(`${He} looks down, blushing a little harder.`);
-					r.push(Spoken(slave, `"But I'm lucky, ${he2}'s such a hot MILF.`));
-				} else if ((slave.actualAge - 14) > partner.actualAge) {
-					r.push(Spoken(slave, `${He2}'s young enough to be my ${daughter2}."`));
-					r.push(`${He} looks down, blushing a little harder.`);
-					r.push(Spoken(slave, `"But I love ${his2} hot young body.`));
-				}
-				if ((slave.actualAge - 5) > partner.actualAge && partner.actualAge < 20) {
-					r.push(Spoken(slave, `${He2}'s a little immature at times, but having sex with a teenager is so awesome, it's worth it.`));
-				}
-				if (hasAnyProstheticLimbs(partner)) {
-					const sex = getLimbCount(partner, 103);
-					const beauty = getLimbCount(partner, 104);
-					const combat = getLimbCount(partner, 105);
-					if (sex > 0 && beauty > 0 && combat > 0) {
-						r.push(Spoken(slave, `${His2} P-Limbs do look cool and I like how strong they can make ${him2} but they scare me a little, sometimes. Though of course ${he2} disables the weapons when we're together."`));
-						r.push(`${He} giggles.`);
-						r.push(Spoken(slave, `"${He2} has vibe fingers, so that's awesome.`));
-					} else if (sex > 0 && beauty > 0) {
-						r.push(Spoken(slave, `I really like ${his2} P-Limbs. They're very pretty, but kind of cold. That's just how ${he2} is."`));
-						r.push(`${He} giggles.`);
-						r.push(Spoken(slave, `" ${He2} has vibe fingers. so that's awesome.`));
-					} else if (beauty > 0 && combat > 0) {
-						r.push(Spoken(slave, `${His2} P-Limbs do look cool and I like how strong they can make ${him2} but they scare me a little, sometimes. Though of course ${he2} disables the weapons when we're together.`));
-					} else if (sex > 0 && combat > 0) {
-						r.push(Spoken(slave, `${His2} P-Limbs do scare me a little, sometimes. Though of course ${he2} disables the weapons when we're together."`));
-						r.push(`${He} giggles.`);
-						r.push(Spoken(slave, `"${He2} has vibe fingers. so that's awesome.`));
-					} else if (sex > 0) {
-						r.push(Spoken(slave, `And, um."`));
-						r.push(`${He} giggles.`);
-						r.push(Spoken(slave, `"${He2} has vibe fingers. so that's awesome.`));
-					} else if (beauty > 0) {
-						r.push(Spoken(slave, `I really like ${his2} P-Limbs. They're very pretty, but kind of cold. That's just how ${he2} is.`));
-					} else if (combat > 0) {
-						r.push(Spoken(slave, `${His2} P-Limbs do scare me a little, sometimes. Though of course ${he2} disables the weapons when we're together."`));
-						r.push(`${He} giggles.`);
-						r.push(Spoken(slave, `"Though I did get ${him2} to extend ${his2} blades once, so I could kiss them for luck.`));
-					} else {
-						r.push(Spoken(slave, `I really do like ${his2} P-Limbs. They're a little awkward, and kind of cold, but that's just how ${he2} is.`));
-					}
-				} else if (getLimbCount(partner, 0) > 0) {
-					r.push(Spoken(slave, `${He2}'s an amputee, of course, so that's a little sad.`));
+			} else if (slave.relationship === -2) {
+				text.push(`${Spoken(slave, `I'm good friends with some of the other slaves,"`)}`);
+
+				if (!canTalk(slave)) {
+					text.push(`${he} gestures`);
+				} else {
+					text.push(`${he} mutters`);
 				}
-			}
-		} else if (slave.relationship === -3) {
-			if (slave.devotion+slave.trust >= 175) {
-				r.push(Spoken(slave, `Of course, I'm your ${wife}, ${Master}."`));
-				r.push(`${He} laughs.`);
-				r.push(Spoken(slave, `"Not exactly traditional married life, but I'll do my best to help redefine it.`));
-			} else if (slave.devotion < -20 && slave.trust > 20) {
-				r.push(Spoken(slave, `Of course, I'm your ${wife}, ${Master}." `));
-				r.push(`${He} sighs.`);
-				r.push(Spoken(slave, `"Any other questions?`));
-			} else if (slave.devotion < -20) {
-				r.push(Spoken(slave, `I'm your ${wife},`));
-				if (slave.rudeTitle === 1) {
-					r.push(Spoken(slave, `${PoliteRudeTitle(slave)},"`));
+
+				text.push(`hesitantly, looking suddenly embarrassed. ${Spoken(slave, `"I really like you, though, ${Master}. Like, <span class="note">like</span> you, like you."`)} ${He} clears ${his} throat`);
+
+				if (!canTalk(slave)) {
+					text.push(`silently and pointlessly`);
 				} else {
-					r.push(Spoken(slave, `${Master},"`));
+					text.push(`nervously`);
 				}
-				r.push(`${he} ${say}s, ${his} voice wavering.`);
-				r.push(Spoken(slave, `"Please let me go...`));
-			} else {
-				r.push(Spoken(slave, `Of course, I'm your ${wife}, ${Master},"`));
-				r.push(`${he} ${say}s.`);
-				r.push(Spoken(slave, `"It isn't so bad, I'm starting to like it.`));
-			}
-		} else if (slave.relationship === -2) {
-			r.push(Spoken(slave, `I'm good friends with some of the other slaves,"`));
-			if (!canTalk(slave)) {
-				r.push(`${he} gestures`);
-			} else {
-				r.push(`${he} mutters`);
-			}
-			r.push(`hesitantly, looking suddenly embarrassed.`);
-			r.push(Spoken(slave, `"I really like you, though, ${Master}. Like, <span class="note">like</span> you, like you."`));
-			r.push(`${He} clears ${his} throat`);
-			if (!canTalk(slave)) {
-				r.push(`silently and pointlessly`);
-			} else {
-				r.push(`nervously`);
+
+				text.push(`before hurrying on to safer subjects. ${Spoken(slave, `"Yeah.`)}`);
+			} else if (slave.relationship === -1) {
+				text.push(`${Spoken(slave, `As far as relationships go, ${Master},"`)} ${he} laughs, ${Spoken(slave, `"I'm such a fucking slut. It's so liberating, not having to worry about any of that crap anymore.`)}`);
 			}
-			r.push(`before hurrying on to safer subjects.`);
-			r.push(Spoken(slave, `"Yeah.`));
-		} else if (slave.relationship === -1) {
-			r.push(Spoken(slave, `As far as relationships go, ${Master},"`));
-			r.push(`${he} laughs,`);
-			r.push(Spoken(slave, `"I'm such a fucking slut. It's so liberating, not having to worry about any of that crap anymore.`));
+
+			return text.join(' ');
 		}
 
-		if (FutureSocieties.HighestDecoration() >= 60) {
-			if (slave.devotion > 75) {
-				r.push(Spoken(slave, `I'll do everything I can to support your vision for the future.`));
-			} else if (slave.devotion > 50) {
-				r.push(Spoken(slave, `I do my best to support your vision for the future.`));
-			} else {
-				r.push(Spoken(slave, `I try to conform to your vision for the future.`));
-			}
+		function FS() {
+			const text = [];
 
-			if (V.arcologies[0].FSRomanRevivalist >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 50) {
-					r.push(Spoken(slave, `The new Rome is fascinating, ${Master}. I'm glad to be a part of it.`));
-				} else if (slave.devotion > 20) {
-					r.push(Spoken(slave, `I'm proud to be a slave in the new Rome.`));
+			if (FutureSocieties.HighestDecoration() >= 60) {
+				if (slave.devotion > 75) {
+					text.push(`${Spoken(slave, `I'll do everything I can to support your vision for the future.`)}`);
+				} else if (slave.devotion > 50) {
+					text.push(`${Spoken(slave, `I do my best to support your vision for the future.`)}`);
 				} else {
-					r.push(Spoken(slave, `Being a slave in the new Rome is a little scary, ${Master}. I hear slaves fighting sometimes.`));
+					text.push(`${Spoken(slave, `I try to conform to your vision for the future.`)}`);
 				}
-			}
-			if (V.arcologies[0].FSNeoImperialist >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 50) {
-					r.push(Spoken(slave, `This new Empire is strange, but fascinating, ${Master}. It feels like I'm part of history in the making.`));
-				} else if (slave.devotion > 20) {
-					r.push(Spoken(slave, `I am proud to serve your Empire, ${Master}.`));
-				} else {
-					r.push(Spoken(slave, `I don't know about this new Empire, ${Master}... being property is one thing, but being a serf is something else entirely.`));
+
+				if (V.arcologies[0].FSRomanRevivalist >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 50) {
+						text.push(`${Spoken(slave, `The new Rome is fascinating, ${Master}. I'm glad to be a part of it.`)}`);
+					} else if (slave.devotion > 20) {
+						text.push(`${Spoken(slave, `I'm proud to be a slave in the new Rome.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `Being a slave in the new Rome is a little scary, ${Master}. I hear slaves fighting sometimes.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSAztecRevivalist >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 50) {
-					r.push(Spoken(slave, `The new Aztec Empire is enthralling, ${Master}. I'm amazed at how easily people jump to sacrifice and debauchery when they're offered.`));
-				} else if (slave.devotion > 20) {
-					r.push(Spoken(slave, `I'm proud to serve the will of the gods, and you.`));
-				} else {
-					r.push(Spoken(slave, `Please, don't sacrifice me ${Master}, I'll do anything.`));
+				if (V.arcologies[0].FSNeoImperialist >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 50) {
+						text.push(`${Spoken(slave, `This new Empire is strange, but fascinating, ${Master}. It feels like I'm part of history in the making.`)}`);
+					} else if (slave.devotion > 20) {
+						text.push(`${Spoken(slave, `I am proud to serve your Empire, ${Master}.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I don't know about this new Empire, ${Master}... being property is one thing, but being a serf is something else entirely.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSEgyptianRevivalist >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 50) {
-					r.push(Spoken(slave, `This new Egypt is fascinating, ${Master}. I'm glad to be a part of it.`));
-				} else if (slave.devotion > 20) {
-					r.push(Spoken(slave, `I'm proud to be a slave of the new Pharaoh.`));
-				} else {
-					r.push(Spoken(slave, `Being a slave in this new Egypt is a little reassuring. some of the other slavs say they used to use slaves for great things, anyway.`));
+				if (V.arcologies[0].FSAztecRevivalist >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 50) {
+						text.push(`${Spoken(slave, `The new Aztec Empire is enthralling, ${Master}. I'm amazed at how easily people jump to sacrifice and debauchery when they're offered.`)}`);
+					} else if (slave.devotion > 20) {
+						text.push(`${Spoken(slave, `I'm proud to serve the will of the gods, and you.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `Please, don't sacrifice me ${Master}, I'll do anything.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSChattelReligionist >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 50) {
-					r.push(Spoken(slave, `It's interesting, seeing how fast a new faith can take hold.`));
-				} else if (slave.fetishKnown === 1 && slave.fetish === "masochist" && slave.fetishStrength > 60) {
-					r.push(Spoken(slave, `I — I always thought pain was good for me. It's so nice to be told that it's true at last.`));
-				} else if (slave.devotion > 20) {
-					r.push(Spoken(slave, `I'm proud to be a slave, since that's what's right for me.`));
-				} else {
-					r.push(Spoken(slave, `sometimes I have doubts about the new faith, but I do my best to ignore them.`));
+				if (V.arcologies[0].FSEgyptianRevivalist >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 50) {
+						text.push(`${Spoken(slave, `This new Egypt is fascinating, ${Master}. I'm glad to be a part of it.`)}`);
+					} else if (slave.devotion > 20) {
+						text.push(`${Spoken(slave, `I'm proud to be a slave of the new Pharaoh.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `Being a slave in this new Egypt is a little reassuring. some of the other slavs say they used to use slaves for great things, anyway.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSIntellectualDependency >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 10) {
-					r.push(Spoken(slave, `I just wish I could share in simplicity of things.`));
-				} else if (slave.intelligence+slave.intelligenceImplant <= -50) {
-					r.push(Spoken(slave, `It's so nice not having to think for myself anymore.`));
-				} else if (slave.energy > 50) {
-					r.push(Spoken(slave, `I'm so glad that this culture encourages being a horny little slut.`));
-				} else {
-					r.push(Spoken(slave, `I feel out of place here, but I'll try to relax and not overthink things so much.`));
+				if (V.arcologies[0].FSChattelReligionist >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 50) {
+						text.push(`${Spoken(slave, `It's interesting, seeing how fast a new faith can take hold.`)}`);
+					} else if (slave.fetishKnown === 1 && slave.fetish === "masochist" && slave.fetishStrength > 60) {
+						text.push(`${Spoken(slave, `I — I always thought pain was good for me. It's so nice to be told that it's true at last.`)}`);
+					} else if (slave.devotion > 20) {
+						text.push(`${Spoken(slave, `I'm proud to be a slave, since that's what's right for me.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `sometimes I have doubts about the new faith, but I do my best to ignore them.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSDegradationist >= 10) {
-				if (slave.fetishKnown === 1 && slave.fetish === "submissive" && slave.fetishStrength > 60) {
-					r.push(Spoken(slave, `I — I always knew I was a useless bitch, so it's easy to accept being degraded.`));
-				} else if (slave.devotion > 20) {
-					r.push(Spoken(slave, `I'm your worthless little degraded fuckpuppet, ${Master}.`));
-				} else {
-					r.push(Spoken(slave, `I'm trying to accept the degradation, ${Master}.`));
+				if (V.arcologies[0].FSIntellectualDependency >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 10) {
+						text.push(`${Spoken(slave, `I just wish I could share in simplicity of things.`)}`);
+					} else if (slave.intelligence+slave.intelligenceImplant <= -50) {
+						text.push(`${Spoken(slave, `It's so nice not having to think for myself anymore.`)}`);
+					} else if (slave.energy > 50) {
+						text.push(`${Spoken(slave, `I'm so glad that this culture encourages being a horny little slut.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I feel out of place here, but I'll try to relax and not overthink things so much.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSSlaveProfessionalism >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 100) {
-					r.push(Spoken(slave, `I'm so glad that I can be of such service to you. I never thought slavery could be so intellectually stimulating, I expected so much less.`));
-				} else if (slave.intelligence+slave.intelligenceImplant > 10) {
-					r.push(Spoken(slave, `sometimes it's tough here, but at least it keeps my wits sharp.`));
-				} else {
-					r.push(Spoken(slave, `I kind of hate it here, ${Master}. Everything's so complicated and people always laugh at me when I need help. You don't think I'm stupid too, do you?`));
+				if (V.arcologies[0].FSDegradationist >= 10) {
+					if (slave.fetishKnown === 1 && slave.fetish === "submissive" && slave.fetishStrength > 60) {
+						text.push(`${Spoken(slave, `I — I always knew I was a useless bitch, so it's easy to accept being degraded.`)}`);
+					} else if (slave.devotion > 20) {
+						text.push(`${Spoken(slave, `I'm your worthless little degraded fuckpuppet, ${Master}.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I'm trying to accept the degradation, ${Master}.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSAssetExpansionist >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 50) {
-					r.push(Spoken(slave, `I've been watching all the body dysphoria on display lately; it's certainly novel.`));
-				} else if (slave.energy > 95) {
-					r.push(Spoken(slave, `Thank you so much for supporting this new T&A expansion culture, ${Master}. It's like you made it just for me. So much eye candy!`));
-				} else if (slave.boobs > 1000) {
-					r.push(Spoken(slave, `It's almost strange, being in a place where these tits don't make me stand out.`));
-				} else {
-					r.push(Spoken(slave, `I'm a little worried I don't have the tits for this new expansion culture though.`));
+				if (V.arcologies[0].FSSlaveProfessionalism >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 100) {
+						text.push(`${Spoken(slave, `I'm so glad that I can be of such service to you. I never thought slavery could be so intellectually stimulating, I expected so much less.`)}`);
+					} else if (slave.intelligence+slave.intelligenceImplant > 10) {
+						text.push(`${Spoken(slave, `Sometimes it's tough here, but at least it keeps my wits sharp.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I kind of hate it here, ${Master}. Everything's so complicated and people always laugh at me when I need help. You don't think I'm stupid too, do you?`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSTransformationFetishist >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 50) {
-					r.push(Spoken(slave, `I'm learning a lot about men, just watching how what's beautiful is changing.`));
-				} else if (slave.energy > 95) {
-					r.push(Spoken(slave, `The arcology is like, a bimbo land now, ${Master}. It's so hot`));
-				} else {
-					r.push(Spoken(slave, `I like getting hotter, ${Master}, but all the surgery is still a little scary.`));
+				if (V.arcologies[0].FSAssetExpansionist >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 50) {
+						text.push(`${Spoken(slave, `I've been watching all the body dysphoria on display lately; it's certainly novel.`)}`);
+					} else if (slave.energy > 95) {
+						text.push(`${Spoken(slave, `Thank you so much for supporting this new T&A expansion culture, ${Master}. It's like you made it just for me. So much eye candy!`)}`);
+					} else if (slave.boobs > 1000) {
+						text.push(`${Spoken(slave, `It's almost strange, being in a place where these tits don't make me stand out.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I'm a little worried I don't have the tits for this new expansion culture though.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSGenderRadicalist >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 50) {
-					r.push(Spoken(slave, `I suppose it was inevitable that a place where anyone can be a slave would start treating anyone who's a slave as a girl.`));
-				} else if (slave.attrKnown === 1 && slave.attrXY > 80) {
-					r.push(Spoken(slave, `I really like how you're encouraging slavery to focus on cocks."`));
-					r.push(`${He} giggles.`);
-					r.push(Spoken(slave, `"I like cocks!`));
-				} else if (slave.dick > 0) {
-					r.push(Spoken(slave, `It isn't always easy being a slave ${girl}, but it's nice being in a place where that's normal.`));
-				} else {
-					r.push(Spoken(slave, `It's kind of nice, being a slave in a place where, you know, anyone can be a slave.`));
+				if (V.arcologies[0].FSTransformationFetishist >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 50) {
+						text.push(`${Spoken(slave, `I'm learning a lot about men, just watching how what's beautiful is changing.`)}`);
+					} else if (slave.energy > 95) {
+						text.push(`${Spoken(slave, `The arcology is like, a bimbo land now, ${Master}. It's so hot`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I like getting hotter, ${Master}, but all the surgery is still a little scary.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSGenderFundamentalist >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 50) {
-					r.push(Spoken(slave, `I shouldn't be surprised at how easy it is to reinforce traditional values in a new, slavery focused culture.`));
-				} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-					r.push(Spoken(slave, `I really like how you're encouraging slavery to focus on girls."`));
-					r.push(`${He} giggles.`);
-					r.push(Spoken(slave, `"I like girls!`));
-				} else if (slave.dick > 0) {
-					r.push(Spoken(slave, `I know I'm not a perfect fit for your vision of the future, but I'll do my best to be a good girl.`));
-				} else {
-					r.push(Spoken(slave, `I'm relieved I fit into your vision of the future of slavery.`));
+				if (V.arcologies[0].FSGenderRadicalist >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 50) {
+						text.push(`${Spoken(slave, `I suppose it was inevitable that a place where anyone can be a slave would start treating anyone who's a slave as a girl.`)}`);
+					} else if (slave.attrKnown === 1 && slave.attrXY > 80) {
+						text.push(`${Spoken(slave, `I really like how you're encouraging slavery to focus on cocks."`)} ${He} giggles. ${Spoken(slave, `"I like cocks!`)}`);
+					} else if (slave.dick > 0) {
+						text.push(`${Spoken(slave, `It isn't always easy being a slave ${girl}, but it's nice being in a place where that's normal.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `It's kind of nice, being a slave in a place where, you know, anyone can be a slave.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSRepopulationFocus >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 50) {
-					r.push(Spoken(slave, `I really hope we can save humanity like this.`));
-				} else if (slave.fetishKnown === 1 && slave.fetish === "pregnancy") {
-					r.push(Spoken(slave, `I really like how you are encouraging girls to get pregnant."`));
-					r.push(`${He} giggles.`);
-					r.push(Spoken(slave, `"I really like big, pregnant bellies!`));
-				} else if (slave.preg > slave.pregData.normalBirth/4) {
-					r.push(Spoken(slave, `I'm relieved I fit into your vision of the future. I hope I can give you lots of healthy children.`));
-				} else {
-					r.push(Spoken(slave, `I know I'm not a perfect fit for your vision of the future, but I'll do my best to be a good ${girl}.`));
+				if (V.arcologies[0].FSGenderFundamentalist >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 50) {
+						text.push(`${Spoken(slave, `I shouldn't be surprised at how easy it is to reinforce traditional values in a new, slavery focused culture.`)}`);
+					} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
+						text.push(`${Spoken(slave, `I really like how you're encouraging slavery to focus on girls."`)} ${He} giggles. ${Spoken(slave, `"I like girls!`)}`);
+					} else if (slave.dick > 0) {
+						text.push(`${Spoken(slave, `I know I'm not a perfect fit for your vision of the future, but I'll do my best to be a good girl.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I'm relieved I fit into your vision of the future of slavery.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSRestart >= 10) {
-				if (slave.intelligence+slave.intelligenceImplant > 50) {
-					r.push(Spoken(slave, `I really hope we can save humanity like this.`));
-				} else if (slave.preg < 0 || slave.ovaries === 0) {
-					r.push(Spoken(slave, `I'm relieved I fit into your vision of the future.`));
-				} else {
-					r.push(Spoken(slave, `I know I'm not a perfect fit for your vision of the future, but I'll do my best to be a good ${girl}.`));
+				if (V.arcologies[0].FSRepopulationFocus >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 50) {
+						text.push(`${Spoken(slave, `I really hope we can save humanity like this.`)}`);
+					} else if (slave.fetishKnown === 1 && slave.fetish === "pregnancy") {
+						text.push(`${Spoken(slave, `I really like how you are encouraging girls to get pregnant."`)} ${He} giggles. ${Spoken(slave, `"I really like big, pregnant bellies!`)}`);
+					} else if (slave.preg > slave.pregData.normalBirth/4) {
+						text.push(`${Spoken(slave, `I'm relieved I fit into your vision of the future. I hope I can give you lots of healthy children.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I know I'm not a perfect fit for your vision of the future, but I'll do my best to be a good ${girl}.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSPhysicalIdealist >= 10) {
-				if (slave.muscles <= 5) {
-					r.push(Spoken(slave, `I know I'm not a perfect fit for your vision of the future, but I'll do my best to serve everyone who's built.`));
-				} else {
-					r.push(Spoken(slave, `I'm relieved I fit into your vision of the future of the human body.`));
+				if (V.arcologies[0].FSRestart >= 10) {
+					if (slave.intelligence+slave.intelligenceImplant > 50) {
+						text.push(`${Spoken(slave, `I really hope we can save humanity like this.`)}`);
+					} else if (slave.preg < 0 || slave.ovaries === 0) {
+						text.push(`${Spoken(slave, `I'm relieved I fit into your vision of the future.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I know I'm not a perfect fit for your vision of the future, but I'll do my best to be a good ${girl}.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSHedonisticDecadence >= 10) {
-				if (slave.weight < 10 && slave.behavioralFlaw === "anorexic") {
-					r.push(Spoken(slave, `I want to keep food down for you, but I can't. I'm sorry, I just can't get fat for anyone.`));
-				} else if (slave.weight < 10) {
-					r.push(Spoken(slave, `I know I'm not a perfect fit for your vision of the future, but I'll do my best to eat more and get fatter for you.`));
-				} else {
-					r.push(Spoken(slave, `I'm relieved I fit into your vision of the future of the human body. Can I have some more food now? I'm hungry.`));
+				if (V.arcologies[0].FSPhysicalIdealist >= 10) {
+					if (slave.muscles <= 5) {
+						text.push(`${Spoken(slave, `I know I'm not a perfect fit for your vision of the future, but I'll do my best to serve everyone who's built.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I'm relieved I fit into your vision of the future of the human body.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSPetiteAdmiration >= 10) {
-				if (!heightPass(slave)) {
-					if (V.arcologies[0].FSPetiteAdmirationLaw === 0) {
-						r.push(Spoken(slave, `I know I stand out in a bad way from all the other slaves thanks to my height, but I'll do my best to put it to good use for my betters.`));
+				if (V.arcologies[0].FSHedonisticDecadence >= 10) {
+					if (slave.weight < 10 && slave.behavioralFlaw === "anorexic") {
+						text.push(`${Spoken(slave, `I want to keep food down for you, but I can't. I'm sorry, I just can't get fat for anyone.`)}`);
+					} else if (slave.weight < 10) {
+						text.push(`${Spoken(slave, `I know I'm not a perfect fit for your vision of the future, but I'll do my best to eat more and get fatter for you.`)}`);
 					} else {
-						r.push(Spoken(slave, `I know I'm too tall to be considered hot here, but I swear I'll try even harder to keep up.`));
+						text.push(`${Spoken(slave, `I'm relieved I fit into your vision of the future of the human body. Can I have some more food now? I'm hungry.`)}`);
 					}
-				} else {
-					r.push(Spoken(slave, `I'm glad I fit in with all the other slaves. It's a relief to not be singled out for my height.`));
 				}
-			}
-			if (V.arcologies[0].FSStatuesqueGlorification >= 10) {
-				if (!heightPass(slave)) {
-					if (V.arcologies[0].FSStatuesqueGlorificationLaw === 0) {
-						r.push(Spoken(slave, `I know I'm too short to be paid any attention to, but I'll still try my hardest to keep up with my betters.`));
+				if (V.arcologies[0].FSPetiteAdmiration >= 10) {
+					if (!heightPass(slave)) {
+						if (V.arcologies[0].FSPetiteAdmirationLaw === 0) {
+							text.push(`${Spoken(slave, `I know I stand out in a bad way from all the other slaves thanks to my height, but I'll do my best to put it to good use for my betters.`)}`);
+						} else {
+							text.push(`${Spoken(slave, `I know I'm too tall to be considered hot here, but I swear I'll try even harder to keep up.`)}`);
+						}
 					} else {
-						r.push(Spoken(slave, `I know I'm too short to be considered attractive here, but I swear I'll do my best to measure up.`));
+						text.push(`${Spoken(slave, `I'm glad I fit in with all the other slaves. It's a relief to not be singled out for my height.`)}`);
 					}
-				} else {
-					r.push(Spoken(slave, `I'm glad I fit in with everyone. It's a relief to not be mocked for being short.`));
 				}
-			}
-			if (V.arcologies[0].FSSubjugationist >= 10) {
-				if (slave.race === V.arcologies[0].FSSubjugationistRace) {
-					r.push(Spoken(slave, `I know that as ${addA(V.arcologies[0].FSSubjugationistRace)} slave, it's my proper place to serve.`));
-				} else {
-					r.push(Spoken(slave, `since I'm not ${addA(V.arcologies[0].FSSubjugationistRace)} slave, I'm a little afraid I don't fit into your vision of the future.`));
+				if (V.arcologies[0].FSStatuesqueGlorification >= 10) {
+					if (!heightPass(slave)) {
+						if (V.arcologies[0].FSStatuesqueGlorificationLaw === 0) {
+							text.push(`${Spoken(slave, `I know I'm too short to be paid any attention to, but I'll still try my hardest to keep up with my betters.`)}`);
+						} else {
+							text.push(`${Spoken(slave, `I know I'm too short to be considered attractive here, but I swear I'll do my best to measure up.`)}`);
+						}
+					} else {
+						text.push(`${Spoken(slave, `I'm glad I fit in with everyone. It's a relief to not be mocked for being short.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSSupremacist >= 10) {
-				if (slave.race !== V.arcologies[0].FSSupremacistRace) {
-					r.push(Spoken(slave, `I know that it's my proper place to serve my ${V.arcologies[0].FSSupremacistRace} betters.`));
-				} else {
-					r.push(Spoken(slave, `I know that ${V.arcologies[0].FSSupremacistRace} slaves are rare now, so I'll do my best to bring credit to the ${V.arcologies[0].FSSupremacistRace} race.`));
+				if (V.arcologies[0].FSSubjugationist >= 10) {
+					if (slave.race === V.arcologies[0].FSSubjugationistRace) {
+						text.push(`${Spoken(slave, `I know that as ${addA(V.arcologies[0].FSSubjugationistRace)} slave, it's my proper place to serve.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `since I'm not ${addA(V.arcologies[0].FSSubjugationistRace)} slave, I'm a little afraid I don't fit into your vision of the future.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSPaternalist >= 10) {
-				r.push(Spoken(slave, `I'm so lucky to be a slave here. The future looks better all the time.`));
-			}
-			if (V.arcologies[0].FSBodyPurist >= 10) {
-				if (slave.boobsImplant > 0) {
-					r.push(Spoken(slave, `I know I'm not a perfect fit for your vision of the future, since my tits are ugly and fake.`));
-				} else {
-					r.push(Spoken(slave, `I'm relieved my boobs won't need implants here.`));
+				if (V.arcologies[0].FSSupremacist >= 10) {
+					if (slave.race !== V.arcologies[0].FSSupremacistRace) {
+						text.push(`${Spoken(slave, `I know that it's my proper place to serve my ${V.arcologies[0].FSSupremacistRace} betters.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I know that ${V.arcologies[0].FSSupremacistRace} slaves are rare now, so I'll do my best to bring credit to the ${V.arcologies[0].FSSupremacistRace} race.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSSlimnessEnthusiast >= 10) {
-				if (slave.weight > 30) {
-					r.push(Spoken(slave, `I know I'm an ugly fat slut. I wish I were slim.`));
-				} else if (slave.belly >= 1500 && V.arcologies[0].FSRepopulationFocus !== "unset" && V.propOutcome === 0 && slave.breedingMark === 0) {
-					r.push(Spoken(slave, `I know I'm an ugly fat slut. I wish my belly wasn't so big.`));
-				} else if (slave.butt > 3) {
-					r.push(Spoken(slave, `I know I'm an ugly, fat assed slut. I wish it was smaller.`));
-				} else if (slave.boobs > 500) {
-					r.push(Spoken(slave, `I know I'm an ugly, big boobed slut. I wish my chest was smaller.`));
-				} else {
-					r.push(Spoken(slave, `It's nice, living in a place where I don't need big boobs to be pretty.`));
+				if (V.arcologies[0].FSPaternalist >= 10) {
+					text.push(`${Spoken(slave, `I'm so lucky to be a slave here. The future looks better all the time.`)}`);
 				}
-			}
-			if (V.arcologies[0].FSMaturityPreferentialist >= 10) {
-				if (slave.actualAge < 30) {
-					r.push(Spoken(slave, `I know I'm just a young bitch. I try to be good to my elders.`));
-				} else {
-					r.push(Spoken(slave, `It's nice, living in a place that appreciates an older lady.`));
+				if (V.arcologies[0].FSBodyPurist >= 10) {
+					if (slave.boobsImplant > 0) {
+						text.push(`${Spoken(slave, `I know I'm not a perfect fit for your vision of the future, since my tits are ugly and fake.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I'm relieved my boobs won't need implants here.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSYouthPreferentialist >= 10) {
-				if (slave.actualAge < 30) {
-					r.push(Spoken(slave, `It's nice, being young here.`));
-				} else {
-					r.push(Spoken(slave, `I know I'm just an old bitch. I try to serve younger and better slaves well.`));
+				if (V.arcologies[0].FSSlimnessEnthusiast >= 10) {
+					if (slave.weight > 30) {
+						text.push(`${Spoken(slave, `I know I'm an ugly fat slut. I wish I were slim.`)}`);
+					} else if (slave.belly >= 1500 && V.arcologies[0].FSRepopulationFocus !== "unset" && V.propOutcome === 0 && slave.breedingMark === 0) {
+						text.push(`${Spoken(slave, `I know I'm an ugly fat slut. I wish my belly wasn't so big.`)}`);
+					} else if (slave.butt > 3) {
+						text.push(`${Spoken(slave, `I know I'm an ugly, fat assed slut. I wish it was smaller.`)}`);
+					} else if (slave.boobs > 500) {
+						text.push(`${Spoken(slave, `I know I'm an ugly, big boobed slut. I wish my chest was smaller.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `It's nice, living in a place where I don't need big boobs to be pretty.`)}`);
+					}
 				}
-			}
-			if (V.arcologies[0].FSPastoralist >= 10) {
-				if (slave.lactation > 0 && slave.balls > 0) {
-					r.push(Spoken(slave, `I'll do my best to make as much milk and cum for the arcology as I can.`));
-				} else if (slave.lactation > 0) {
-					r.push(Spoken(slave, `I'll do my best to make as much milk for the arcology as I can.`));
-				} else if (slave.dick > 0 && slave.balls > 0) {
-					r.push(Spoken(slave, `I'll do my best to make as much cum for the arcology as I can.`));
-				} else {
-					r.push(Spoken(slave, `I wish I could make milk for the arcology.`));
+				if (V.arcologies[0].FSMaturityPreferentialist >= 10) {
+					if (slave.actualAge < 30) {
+						text.push(`${Spoken(slave, `I know I'm just a young bitch. I try to be good to my elders.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `It's nice, living in a place that appreciates an older lady.`)}`);
+					}
+				}
+				if (V.arcologies[0].FSYouthPreferentialist >= 10) {
+					if (slave.actualAge < 30) {
+						text.push(`${Spoken(slave, `It's nice, being young here.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I know I'm just an old bitch. I try to serve younger and better slaves well.`)}`);
+					}
+				}
+				if (V.arcologies[0].FSPastoralist >= 10) {
+					if (slave.lactation > 0 && slave.balls > 0) {
+						text.push(`${Spoken(slave, `I'll do my best to make as much milk and cum for the arcology as I can.`)}`);
+					} else if (slave.lactation > 0) {
+						text.push(`${Spoken(slave, `I'll do my best to make as much milk for the arcology as I can.`)}`);
+					} else if (slave.dick > 0 && slave.balls > 0) {
+						text.push(`${Spoken(slave, `I'll do my best to make as much cum for the arcology as I can.`)}`);
+					} else {
+						text.push(`${Spoken(slave, `I wish I could make milk for the arcology.`)}`);
+					}
 				}
 			}
-		} // closes FS
-
-		if (slave.devotion > 75) {
-			if (slave.tankBaby > 0 || isParentP(slave, V.PC) || (areSisters(slave, V.PC) && slave.actualAge <= V.PC.actualAge)) {
-				r.push(Spoken(slave, `I've known you my whole life, ${Master}, I can't really think of any times you weren't there for me.`));
-			} else if ((areSisters(slave, V.PC) && slave.actualAge > V.PC.actualAge) || isParentP(V.PC, slave)) {
-				r.push(Spoken(slave, `You're my dear ${Master}. I've known you since you were born, and I will always be watching out for you, no matter what.`));
-			} else if (slave.weekAcquired === 0 && V.week > 104) {
-				r.push(Spoken(slave, `I feel like I've known you my whole life, ${Master}, and I would follow you to the end of the earth.`));
-			} else if ((V.week - slave.weekAcquired) > 104) {
-				r.push(Spoken(slave, `I feel like I know you pretty well, ${Master}.`));
+
+			return text.join(' ');
+		}
+
+		function devotion() {
+			const text = [];
+
+			if (slave.devotion > 75) {
+				if (slave.tankBaby > 0 || isParentP(slave, V.PC) || (areSisters(slave, V.PC) && slave.actualAge <= V.PC.actualAge)) {
+					text.push(`${Spoken(slave, `I've known you my whole life, ${Master}, I can't really think of any times you weren't there for me.`)}`);
+				} else if ((areSisters(slave, V.PC) && slave.actualAge > V.PC.actualAge) || isParentP(V.PC, slave)) {
+					text.push(`${Spoken(slave, `You're my dear ${Master}. I've known you since you were born, and I will always be watching out for you, no matter what.`)}`);
+				} else if (slave.weekAcquired === 0 && V.week > 104) {
+					text.push(`${Spoken(slave, `I feel like I've known you my whole life, ${Master}, and I would follow you to the end of the earth.`)}`);
+				} else if ((V.week - slave.weekAcquired) > 104) {
+					text.push(`${Spoken(slave, `I feel like I know you pretty well, ${Master}.`)}`);
+				}
 			}
+
+			return text.join(' ');
 		}
+	}
+
+	function aftermath() {
+		const text = [];
+
+		text.push(`${Spoken(slave, `So, ${Master},"`)} ${he} concludes,`);
 
-		r.push(Spoken(slave, `So, ${Master},"`));
-		r.push(`${he} concludes,`);
 		if (slave.fetishKnown === 1) {
 			if (slave.fetishStrength > 60) {
 				switch (slave.fetish) {
 					case "submissive":
-						r.push(Spoken(slave, `"Can I serve you somehow?"`));
+						text.push(`${Spoken(slave, `"Can I serve you somehow?"`)}`);
 						break;
 					case "dom":
-						r.push(Spoken(slave, `"Can I hold a bitch down for you?"`));
+						text.push(`${Spoken(slave, `"Can I hold a bitch down for you?"`)}`);
 						break;
 					case "sadist":
-						r.push(Spoken(slave, `"Can I spank a bitch for you?"`));
+						text.push(`${Spoken(slave, `"Can I spank a bitch for you?"`)}`);
 						break;
 					case "masochist":
-						r.push(Spoken(slave, `"Can I be your pain slave now?"`));
+						text.push(`${Spoken(slave, `"Can I be your pain slave now?"`)}`);
 						break;
 					case "cumslut":
-						r.push(Spoken(slave, `"Can I blow you now?"`));
+						text.push(`${Spoken(slave, `"Can I blow you now?"`)}`);
 						break;
 					case "humiliation":
-						r.push(Spoken(slave, `"Can I be humiliated now?"`));
+						text.push(`${Spoken(slave, `"Can I be humiliated now?"`)}`);
 						break;
 					case "boobs":
-						r.push(Spoken(slave, `"Can I give you a titjob now?"`));
+						text.push(`${Spoken(slave, `"Can I give you a titjob now?"`)}`);
 						break;
 					case "buttslut":
-						r.push(Spoken(slave, `"Can I be your anal cocksleeve now?"`));
+						text.push(`${Spoken(slave, `"Can I be your anal cocksleeve now?"`)}`);
 						break;
 					case "pregnancy":
 						if (slave.dick > 0 && slave.balls > 0) {
-							r.push(Spoken(slave, `"Are there any slaves you want knocked up?"`));
+							text.push(`${Spoken(slave, `"Are there any slaves you want knocked up?"`)}`);
 						} else if (slave.preg > -2 && slave.ovaries > 0) {
 							if (slave.pregKnown === 1) {
-								r.push(Spoken(slave, `"Can I have some more cum in my pregnant pussy?"`));
+								text.push(`${Spoken(slave, `"Can I have some more cum in my pregnant pussy?"`)}`);
 							} else {
 								if (V.PC.dick) {
-									r.push(Spoken(slave, `"Can you breed me now?"`));
+									text.push(`${Spoken(slave, `"Can you breed me now?"`)}`);
 								} else {
-									r.push(Spoken(slave, `"Can I be bred?"`));
+									text.push(`${Spoken(slave, `"Can I be bred?"`)}`);
 								}
 							}
 						} else {
-							r.push(Spoken(slave, `"Are there any pregnant slaves I could, you know, spend time with?"`));
+							text.push(`${Spoken(slave, `"Are there any pregnant slaves I could, you know, spend time with?"`)}`);
 						}
 						break;
 					default:
-						r.push(Spoken(slave, `"Can I serve you somehow?"`));
+						text.push(`${Spoken(slave, `"Can I serve you somehow?"`)}`);
 				}
 			} else if (slave.energy > 95) {
-				r.push(Spoken(slave, `"Please fuck me. Please."`));
+				text.push(`${Spoken(slave, `"Please fuck me. Please."`)}`);
 			} else if (slave.attrKnown === 1 && slave.attrXX > 80) {
-				r.push(Spoken(slave, `"Can I hang around and get oral from the next slave in here?"`));
+				text.push(`${Spoken(slave, `"Can I hang around and get oral from the next slave in here?"`)}`);
 			} else if (slave.attrKnown === 1 && slave.attrXY > 80) {
-				r.push(Spoken(slave, `"Can I hang around and suck the next dick in here?"`));
+				text.push(`${Spoken(slave, `"Can I hang around and suck the next dick in here?"`)}`);
 			} else {
-				r.push(Spoken(slave, `"Can I serve you somehow?"`));
+				text.push(`${Spoken(slave, `"Can I serve you somehow?"`)}`);
 			}
 		} else {
-			r.push(Spoken(slave, `"Can I serve you somehow?"`));
+			text.push(`${Spoken(slave, `"Can I serve you somehow?"`)}`);
 		}
-	} // Closes fearful and below exempt
-	App.Events.addNode(el, r, "span");
-	return el;
+
+		return text.join(' ');
+	}
 };
diff --git a/src/npc/interaction/fFeet.js b/src/npc/interaction/fFeet.js
index f0e7eae423bbb5dbc614a4684c1b8ee498a2e76d..f0e00c72c324272599c92342589622de6cfa0ead 100644
--- a/src/npc/interaction/fFeet.js
+++ b/src/npc/interaction/fFeet.js
@@ -13,8 +13,6 @@ App.Interact.fFeet = function(slave) {
 	} = getPronouns(slave);
 	const {title: Master} = getEnunciation(slave);
 
-	addPartner(slave, -1);
-
 	const footSeed = random(1, 100);
 	let thighsAdj;
 	let belly;
@@ -342,7 +340,7 @@ App.Interact.fFeet = function(slave) {
 				r.push(`${He} enjoys the massage, moaning in pleasure at your touch.`);
 			}
 		}
-	} // close lube and reaction
+	}
 
 	// Part 3: Actions, attraction/devotion and fetishes
 	if (slave.fetish === "mindbroken") {
diff --git a/src/npc/interaction/fLickPussy.js b/src/npc/interaction/fLickPussy.js
index a79fa78e90310e9f45708987dd2733f342af8caf..630657285f437f2973b64e0e0b53398f18fc1726 100644
--- a/src/npc/interaction/fLickPussy.js
+++ b/src/npc/interaction/fLickPussy.js
@@ -14,8 +14,6 @@ App.Interact.fLickPussy = function(slave) {
 
 	const {womanP} = getPronouns(V.PC).appendSuffix("P");
 
-	addPartner(slave, -1);
-
 	if (canWalk(slave) || (canMove(slave) && slave.rules.mobility === "permissive")) {
 		r.push(`You summon ${slave.slaveName} to your office and order ${him} to lie down on the couch. ${He} does so`);
 		if (slave.devotion > 95) {
@@ -136,8 +134,8 @@ App.Interact.fLickPussy = function(slave) {
 	}
 	r.push(`You send ${him} back to ${his} assignment before calling in another slave to clean up the mess.`);
 
-	slave.counter.vaginal++;
-	V.vaginalTotal++;
+	seX(slave, "vaginal", V.PC, "oral");
+
 	App.Events.addParagraph(node, r);
 	return node;
 };
diff --git a/src/npc/interaction/fLips.js b/src/npc/interaction/fLips.js
index d01ce9b6e517c5262b1fbae24fb7fa48fdf991c3..86c07f360a994ee0612c88a57607013775186228 100644
--- a/src/npc/interaction/fLips.js
+++ b/src/npc/interaction/fLips.js
@@ -12,7 +12,6 @@ App.Interact.fLips = function(slave) {
 		he, his, him, himself, girl
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
 	seX(slave, "oral", V.PC, "penetrative");
 
 	r.push(`You tell ${slave.slaveName} to`);
@@ -302,7 +301,12 @@ App.Interact.fLips = function(slave) {
 			if (V.seeRace === 1) {
 				r.push(slave.race);
 			}
-			r.push(`face instead${(V.PC.vagina !== -1) ? `, occasionally jerking your dick free to shove your pussy against ${his} face instead` : ``}. ${He} does ${his} best to follow your motions but still splutters and gags. You pull free to cum across ${his} ${slave.skin} face and hair.`);
+			r.push(`face instead${(V.PC.vagina !== -1) ? `, occasionally jerking your dick free to shove your pussy against ${his} face instead` : ``}. ${He} does ${his} best to follow your motions but still splutters and gags.`);
+			if (random(100) > 50) {
+				r.push(`You pull free to cum across ${his} ${slave.skin} face and hair.`);
+			} else {
+				r.push(`When you feel your climax approaching, you push ${his} head down to come as far down ${his} throat as you can.`);
+			}
 		} else {
 			r.push(`eat you out. Deciding that ${he} isn't showing the necessary enthusiasm, you hold ${his} head and grind your pussy against ${his}`);
 			if (V.seeRace === 1) {
diff --git a/src/npc/interaction/fNippleFuck.js b/src/npc/interaction/fNippleFuck.js
index 496ec559d49b0057efd881c7eaba92b3d5a6f10c..9e73aa0c2d1b909f0570a14689de1d26ab8e00c9 100644
--- a/src/npc/interaction/fNippleFuck.js
+++ b/src/npc/interaction/fNippleFuck.js
@@ -12,9 +12,7 @@ App.Interact.fNippleFuck = function(slave) {
 		he, his, him, himself
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
-
-	slave.counter.mammary += 2;
+	seX(slave, "mammary", V.PC, "penetrative", 2);
 	V.mammaryTotal += 2;
 
 	r.push(`You call ${him} over to make use of ${his} lewd nipple cunts.`);
diff --git a/src/npc/interaction/fPCImpreg.js b/src/npc/interaction/fPCImpreg.js
index 0a730d4e9259816d90b08bf7b9fc459c080f757f..f1da2c0338c90f74da73865209f75cadddb46158 100644
--- a/src/npc/interaction/fPCImpreg.js
+++ b/src/npc/interaction/fPCImpreg.js
@@ -284,7 +284,6 @@ App.Interact.fPCImpreg = function(slave) {
 	}
 
 	seX(slave, slave.mpreg ? `anal` : `vaginal`, V.PC, "penetrative");
-	addPartner(slave, -1);
 	knockMeUp(slave, 100, 2, -1);
 
 	App.Events.addNode(frag, text);
diff --git a/src/npc/interaction/fPoolSex.js b/src/npc/interaction/fPoolSex.js
index 78d888f6c313f2a76859c38fb825e387d3f99cc6..aeec33d65ebc0cdca4c0dbfa3069bac2df5c9a58 100644
--- a/src/npc/interaction/fPoolSex.js
+++ b/src/npc/interaction/fPoolSex.js
@@ -16,8 +16,6 @@ App.Interact.fPoolSex = function(slave) {
 		he, his, him, himself, hers
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
-
 	r.push(`You order ${him} to meet you in the spa for some quality time in the penthouse's rejuvenating gelatin pool. When you get there, ${he}'s already in ${his} bathing attire, reclined at the side of the pool farthest from you with ${his} massive ${slave.skin} stomach hanging over the edge and half sunk in the thick, steaming ooze, flushed and sweaty.`);
 	if (slave.devotion > 95) {
 		if (!isAmputee(slave)) {
@@ -109,8 +107,7 @@ App.Interact.fPoolSex = function(slave) {
 				r.push(`Satisfied that the angles are right, you grab hold of ${his} hips and slide half on top of ${him}, resting your lower half on the rear swell of ${his} obscenely bloated belly. Pressing your strap-on to ${his} needy hole, you tease ${him} for a moment before ramming home, driving the both of you to repeated orgasm.`);
 			} else {
 				r.push(`When you feel yourself at the edge of orgasm, you have the pool's mobility aids rotate ${him} into a position level with the pool's edge, then hop up on that ledge yourself so that your pussies are level. Satisfied that the angles are right, you grab hold of ${his} hips and slide half on top of ${him}, resting your lower half on the rear swell of ${his} obscenely bloated belly. Pressing your lower lips to ${hers}, you rub your clits together, driving the both of you to repeated orgasm.`);
-				slave.counter.vaginal++;
-				V.vaginalTotal++;
+				seX(slave, "vaginal", V.PC);
 			}
 		}
 	} else if (slave.trust < -20 && slave.devotion > -10) {
@@ -187,8 +184,7 @@ App.Interact.fPoolSex = function(slave) {
 				r.push(`Satisfied that the angles are right, you grab hold of ${his} hips and slide half on top of ${him}, resting your lower half on the rear swell of ${his} obscenely bloated belly. Pressing your strap-on to ${his} needy hole, you tease ${him} for a moment before ramming home, driving the both of you to repeated orgasm.`);
 			} else {
 				r.push(`When you feel yourself at the edge of orgasm, you have the pool's mobility aids rotate ${him} into a position level with the pool's edge, then hop up on that ledge yourself so that your pussies are level. Satisfied that the angles are right, you grab hold of ${his} hips and slide half on top of ${him}, resting your lower half on the rear swell of ${his} obscenely bloated belly. Pressing your lower lips to ${hers}, you rub your clits together, driving the both of you to repeated orgasm.`);
-				slave.counter.vaginal++;
-				V.vaginalTotal++;
+				seX(slave, "vaginal", V.PC);
 			}
 		}
 	} else {
@@ -260,8 +256,7 @@ App.Interact.fPoolSex = function(slave) {
 				r.push(VCheck.Anal(slave, 1));
 			} else {
 				r.push(`When you feel yourself at the edge of orgasm, you have the pool's mobility aids rotate ${him} into a position level with the pool's edge, then hop up on that ledge yourself so that your pussies are level. Satisfied that the angles are right, you grab hold of ${his} hips and slide half on top of ${him}, resting your lower half on the rear swell of ${his} obscenely bloated belly. Pressing your lower lips to ${hers}, you rub your clits together, driving the both of you to repeated orgasm.`);
-				slave.counter.vaginal++;
-				V.vaginalTotal++;
+				seX(slave, "vaginal", V.PC);
 			}
 		}
 	}
diff --git a/src/npc/interaction/fRelation.js b/src/npc/interaction/fRelation.js
index 5b7649f352a278dbef9c6f73f1e66c0a3207ff9c..246c6d3123f0573f0a5a30a9b955772ee7df2537 100644
--- a/src/npc/interaction/fRelation.js
+++ b/src/npc/interaction/fRelation.js
@@ -1,7 +1,25 @@
+App.Interact.fRelationChoosePartner = class extends App.Interact.BaseChoosePartnerRenderer {
+	constructor(slave) {
+		super(slave);
+		this.intro = `${this.slave.slaveName} has several relatives available; pick one to start a threesome.`;
+		this.execute = App.Interact.fRelation;
+	}
+
+	eligible(candidate) {
+		return isSlaveAvailable(candidate) && areRelated(this.slave, candidate);
+	}
+
+	renderDetail(candidate, container) {
+		if (canImpreg(this.slave, candidate) || canImpreg(candidate, this.slave)) {
+			App.UI.DOM.appendNewElement("span", container, ` Pregnancy risk`, ["green"]);
+		}
+	}
+};
+
 /**
  * @param {App.Entity.SlaveState} slave - slave to fuck with partner.
  * @param {App.Entity.SlaveState} partner - partner to fuck slave with. Must be a close relative or relationship target of slave.
- * @returns {DocumentFragment|HTMLElement}
+ * @returns {DocumentFragment}
  */
 App.Interact.fRelation = function(slave, partner) {
 	const r = new SpacedTextAccumulator();
@@ -43,14 +61,18 @@ App.Interact.fRelation = function(slave, partner) {
 	} else {
 		throw new Error(`Invalid partner for fRelation: main ${slave ? slave.ID : "undefined"}, partner ${partner ? partner.ID : "undefined"}.`);
 	}
-	addPartner(slave, -1);
-	addPartner(slave, partner);
 	const {
-		He2,
-		he2, his2, him2, himself2, daughter2
-	} = getPronouns(partner).appendSuffix("2");
+		He: He2,
+		he: he2, his: his2, him: him2, himself: himself2, daughter: daughter2
+	} = getPronouns(partner);
 
-	r.push(`You call both ${slave.slaveName} and ${partner.slaveName} to your office.`);
+	r.push(
+		`You call both`,
+		App.UI.DOM.slaveDescriptionDialog(slave, slave.slaveName),
+		`and`,
+		App.UI.DOM.slaveDescriptionDialog(partner, partner.slaveName),
+		`to your office.`
+	);
 	if (canMove(slave) && canMove(partner) && (slave.devotion > 50 && partner.devotion > 50) && canPenetrate(slave) && canPenetrate(partner) && (partner.anus > 0 && slave.anus > 0 && V.PC.dick !== 0)) {
 		r.push(`There are three stiff pricks available. Since ${slave.slaveName} was already in your office, ${he} goes on the bottom. ${He} lies on the floor, spreads ${his}`);
 		if (V.seeRace === 1) {
@@ -230,8 +252,7 @@ App.Interact.fRelation = function(slave, partner) {
 		slave.devotion > 20 &&
 		partner.devotion > 20
 	) {
-		r.push(`${slave.slaveName}`);
-		r.push(`and ${partner.slaveName} line up next to one another on the couch next to your desk`);
+		r.push(`${slave.slaveName} and ${partner.slaveName} line up next to one another on the couch next to your desk`);
 		if (V.PC.dick === 0) {
 			r.push(`while you don a strap-on,`);
 		}
diff --git a/src/npc/interaction/fRival.js b/src/npc/interaction/fRival.js
index af4ea07ef32fe87c1fbff92e2b6cb45e89f80dc4..050ad49e95cacef5f07104f3e0c3e6cca81f0312 100644
--- a/src/npc/interaction/fRival.js
+++ b/src/npc/interaction/fRival.js
@@ -17,8 +17,6 @@ App.Interact.fRival = function(slave) {
 		He2,
 		he2, his2, him2
 	} = getPronouns(rival).appendSuffix("2");
-	addPartner(slave, -1);
-	addPartner(slave, slave.rivalryTarget);
 
 	r.push(`You call ${slave.slaveName} to your office and let ${him} know you'll be abusing ${rival.slaveName} together.`);
 	if (slave.fetish === "sadist" && slave.fetishStrength > 60 && slave.fetishKnown === 1) {
diff --git a/src/npc/interaction/fSlaveSelfImpreg.js b/src/npc/interaction/fSlaveSelfImpreg.js
index 8586ceb48ff4edd3e4e9f7c27d810d4a7524ebac..8d85793f0c7018e35a2351e2b12cb8d30d42832d 100644
--- a/src/npc/interaction/fSlaveSelfImpreg.js
+++ b/src/npc/interaction/fSlaveSelfImpreg.js
@@ -12,16 +12,13 @@ App.Interact.fSlaveSelfImpreg = function(slave) {
 		he, his, him, himself
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
-
 	const pfh = (slave.fetish === "pregnancy" && slave.fetishStrength > 50);
 	const pfk = (pfh && slave.fetishKnown === 1) || slave.sexualFlaw === "breeder";
 	let coop = true;
 	let enjoy = true;
 	const superfetation = (slave.geneticQuirks.superfetation === 2 && slave.pregKnown === 1) ? 1 : 0;
 
-	if (slave.fetish === "mindbroken") {
-	} else {
+	if (slave.fetish !== "mindbroken") {
 		if (slave.devotion <= 20) {
 			if (slave.devotion < -20) {
 				r.push(`${slave.slaveName}`);
@@ -371,15 +368,7 @@ App.Interact.fSlaveSelfImpreg = function(slave) {
 	}
 
 	const actCount = random(2, 8)+1;
-	slave.counter.penetrative += actCount;
-	V.penetrativeTotal += actCount;
-	if (slave.mpreg === 1) {
-		slave.counter.anal += actCount;
-		V.analTotal += actCount;
-	} else {
-		slave.counter.vaginal += actCount;
-		V.vaginalTotal += actCount;
-	}
+	seX(slave, slave.mpreg ? "anal" : "vaginal", slave, "penetrative", actCount);
 
 	r.push(`You repeat this ritual throughout the week, ensuring that ${slave.slaveName}`);
 
@@ -400,9 +389,9 @@ App.Interact.fSlaveSelfImpreg = function(slave) {
 
 	if (V.arcologies[0].FSRepopulationFocus !== "unset" && (V.arcologies[0].FSGenderFundamentalist === "unset" || V.arcologies[0].FSRepopulationFocus >= V.arcologies[0].FSGenderFundamentalist)) {
 		// seems logical that repop would trump anything else if it's equal-or-more advanced than fundamentalism.
-		const delt = (V.arcologies[0].FSGenderFundamentalist !== "unset") ?
-			V.arcologies[0].FSRepopulationFocus - V.arcologies[0].FSGenderFundamentalist :
-			V.arcologies[0].FSRepopulationFocus;
+		const delt = (V.arcologies[0].FSGenderFundamentalist !== "unset")
+			? V.arcologies[0].FSRepopulationFocus - V.arcologies[0].FSGenderFundamentalist
+			: V.arcologies[0].FSRepopulationFocus;
 
 		if (delt > 0) {
 			r.push(`Society is <span class="green">pleased</span> by the addition of a new slave, no matter the means by which it was produced.`);
diff --git a/src/npc/interaction/fVagina.js b/src/npc/interaction/fVagina.js
index 3d5228f948df5b6f7e771e4551c08ec1397543b3..ffb19c8059544de97d1e29ef5c5ba2c6196fc38f 100644
--- a/src/npc/interaction/fVagina.js
+++ b/src/npc/interaction/fVagina.js
@@ -14,8 +14,6 @@ App.Interact.fVagina = function(slave) {
 
 	const hands = hasBothArms(slave) ? 'hands' : 'hand';
 
-	addPartner(slave, -1);
-
 	r.push(`You call ${him} over so you can`);
 	if (slave.vagina >= 10) {
 		r.push(`tickle ${his} cavernous hole.`);
@@ -649,11 +647,7 @@ App.Interact.fVagina = function(slave) {
 		}
 		r.push(`you can feel`);
 		if (slave.bellyPreg >= 300000) {
-			r.push(`${his} child`);
-			if (slave.pregType > 0) {
-				r.push(`ren`);
-			}
-			r.push(`begin to squirm in reaction to their mother's lust.`);
+			r.push(`${his} ${onlyPlural(slave.pregType, 'child', 'children')} begin to squirm in reaction to their mother's lust.`);
 		} else {
 			r.push(`${his} heart beating hard.`);
 		}
@@ -1077,11 +1071,7 @@ App.Interact.fVagina = function(slave) {
 			}
 			r.push(`you can feel`);
 			if (slave.bellyPreg >= 300000) {
-				r.push(`${his} child`);
-				if (slave.pregType > 0) {
-					r.push(`ren`);
-				}
-				r.push(`begin to squirm in reaction to their mother's lust.`);
+				r.push(`${his} ${onlyPlural(slave.pregType, 'child', 'children')} begin to squirm in reaction to their mother's lust.`);
 			} else {
 				r.push(`${his} heart beating hard.`);
 			}
diff --git a/src/npc/interaction/forceFeeding.js b/src/npc/interaction/forceFeeding.js
index da30d589b1429276525d777bc7e441f4bf6a0bcb..1fd95e2d9f4407536d0806ad2b27cfa242ed8464 100644
--- a/src/npc/interaction/forceFeeding.js
+++ b/src/npc/interaction/forceFeeding.js
@@ -12,7 +12,6 @@ App.Interact.forceFeeding = function(slave) {
 		he, his, him, himself, girl
 	} = getPronouns(slave);
 
-	addPartner(slave, -1);
 	let doMe;
 
 	const belly = bellyAdjective(slave);
@@ -630,8 +629,8 @@ App.Interact.forceFeeding = function(slave) {
 					}
 				}
 				r.push(`Once you are spent, you slide down beside ${him} and rest your head against ${his} belly; it almost feels like a water-filled pillow, albeit a little noisy. You and ${slave.slaveName} doze off together for a much needed nap. You don't get much rest; ${his} stomach's constant groaning and burbling keeping you up, so you send ${him} on ${his} way. ${He} blows you one last kiss and eagerly looks forward to next time.`);
-				slave.counter.oral += 2;
-				V.oralTotal += 2;
+
+				seX(slave, "oral", V.PC, "penetrative", 2);
 			}
 		}
 	}
diff --git a/src/npc/interaction/killSlave.js b/src/npc/interaction/killSlave.js
index 05211401bb8f49ebf29c060f4a0d2b824d3cb042..b6bed51be6b16c580b90ee88f6f894215ab3bc2c 100644
--- a/src/npc/interaction/killSlave.js
+++ b/src/npc/interaction/killSlave.js
@@ -44,183 +44,169 @@ App.UI.SlaveInteract.killSlave = function(slave) {
 
 	return frag;
 
-	function introFuckdoll() {
-		const text = [];
-
-		text.push(`It's hard to tell the expression on the Fuckdoll's face, but your guess is it's`);
+	function intro() {
+		const introDiv = document.createElement("div");
 
-		if (slave.fetish !== "mindbroken") {
-			text.push(`one of`);
+		introDiv.append(`You ${canWalk(slave)
+			? `call ${slave.slaveName}`
+			: `have ${slave.slaveName} brought`} into your office. `);
 
-			if (slave.devotion > 50) {
-				text.push(`adoration.`);
-			} else if (slave.devotion > 20) {
-				text.push(`calm.`);
-			} else if (slave.devotion > -20) {
-				text.push(`apprehension.`);
-			} else {
-				text.push(`hatred.`);
-			}
+		if (slave.fuckdoll) {
+			introDiv.append(introFuckdoll());
 		} else {
-			text.push(`blank.`);
+			introDiv.append(introStandard());
 		}
 
-		text.push(`You tell ${him} that you've gotten tired of having ${him} around and that you decided it is time to get rid of ${him}. ${He} simply nods, not being able to see you ${canHear(slave) ? `quietly ` : ``}reach behind your desk and pull out your trusty ${weapon}.`);
+		return introDiv;
 
-		return text.join(' ');
-	}
+		function introFuckdoll() {
+			const text = [];
 
-	function introStandard() {
-		const text = [];
+			text.push(`It's hard to tell the expression on the Fuckdoll's face, but your guess is it's`);
 
-		text.push(`${He} looks at you`);
+			if (slave.fetish !== "mindbroken") {
+				text.push(`one of`);
 
-		if (slave.devotion > 50) {
-			text.push(`with adoration`);
-		} else if (slave.devotion > 20) {
-			text.push(`calmly`);
-		} else if (slave.devotion > -20) {
-			text.push(`with apprehension`);
-		} else {
-			text.push(`with hatred`);
+				if (slave.devotion > 50) {
+					text.push(`adoration.`);
+				} else if (slave.devotion > 20) {
+					text.push(`calm.`);
+				} else if (slave.devotion > -20) {
+					text.push(`apprehension.`);
+				} else {
+					text.push(`hatred.`);
+				}
+			} else {
+				text.push(`blank.`);
+			}
+
+			text.push(`You tell ${him} that you've gotten tired of having ${him} around and that you decided it is time to get rid of ${him}. ${He} simply nods, not being able to see you ${canHear(slave) ? `quietly ` : ``}reach behind your desk and pull out your trusty ${weapon}.`);
+
+			return text.join(' ');
 		}
 
-		text.push(`and waits for you to continue. You tell ${him} that you've gotten tired of having ${him} around and that you decided it is time to get rid of ${him}.`);
+		function introStandard() {
+			const text = [];
 
-		if (slave.fetish !== "mindbroken") {
-			text.push(`${His} expression changes to one of`);
+			text.push(`${He} looks at you`);
 
 			if (slave.devotion > 50) {
-				text.push(`pure sorrow`);
+				text.push(`with adoration`);
 			} else if (slave.devotion > 20) {
-				text.push(`sadness`);
+				text.push(`calmly`);
+			} else if (slave.devotion > -20) {
+				text.push(`with apprehension`);
 			} else {
-				text.push(`relief`);
+				text.push(`with hatred`);
 			}
 
-			text.push(`until you`);
-		} else {
-			text.push(`${He} just nods dumbly and continues to watch you with a vacant expression, even as`);
-		}
+			text.push(`and waits for you to continue. You tell ${him} that you've gotten tired of having ${him} around and that you decided it is time to get rid of ${him}.`);
 
-		text.push(`${canHear(slave) ? `quietly ` : ``}reach behind your desk and pull out your trusty ${weapon}${introReaction()}`);
+			if (slave.fetish !== "mindbroken") {
+				text.push(`${His} expression changes to one of`);
 
-		return text.join(' ');
+				if (slave.devotion > 50) {
+					text.push(`pure sorrow`);
+				} else if (slave.devotion > 20) {
+					text.push(`sadness`);
+				} else {
+					text.push(`relief`);
+				}
 
-		function introReaction() {
-			if (oneWeek.includes(slave.ID)) {
-				return introReactionOneWeek();
-			}
-			if (twoWeeks.includes(slave.ID)) {
-				return introReactionTwoWeeks();
-			}
-			if (threeWeeks.includes(slave.ID)) {
-				return introReactionThreeWeeks();
-			}
-			if (fourWeeks.includes(slave.ID)) {
-				return introReactionFourWeeks();
+				text.push(`until you`);
+			} else {
+				text.push(`${He} just nods dumbly and continues to watch you with a vacant expression, even as`);
 			}
 
-			return introReactionOther();
-		}
+			text.push(`${canHear(slave) ? `quietly ` : ``}reach behind your desk and pull out your trusty ${weapon}${introReaction()}`);
 
-		function introReactionOneWeek() {
-			if (isDevoted) {
-				return `. ${He} just looks at you warily; you threatened ${him} just last week, and ${he}'s suspecting you won't go through with it this time either.`;
-			} else if (isAccepting) {
-				return `, at which a brief moment of confusion flashes across ${his} face. You threatened ${him} only a week ago, and ${he}'s beginning to think you won't actually do it.`;
-			} else if (isCareful) {
-				return `. You can just barely detect a brief moment of scorn cross ${his} face – you threatened ${him} just last week, and ${he}'s starting to think you won't actually go through with it.`;
-			} else {
-				return `, at which ${he} laughs with derision. You threatened ${him} only last week, and ${he}'s calling your bluff.`;
-			}
-		}
+			return text.join(' ');
 
-		function introReactionTwoWeeks() {
-			if (isDevoted) {
-				return `. ${He} looks at you with a hint of trepidation in ${his} eyes, but it seems for the most part ${he} thinks you won't do it – you did give ${him} an empty threat a couple of weeks ago, after all.`;
-			} else if (isAccepting) {
-				return `, to which ${he} just raises one eyebrow. You threatened ${him} just a few weeks ago, so why wouldn't you be bluffing now?`;
-			} else if (isCareful) {
-				return `. ${He} says nothing, but you can tell ${he} seems to think you're bluffing – you did threaten ${him} only a couple of weeks ago, after all.`;
-			} else {
-				return `, at which ${he} scoffs. You threatened ${him} a couple of weeks ago, and you're probably bluffing again.`;
-			}
-		}
+			function introReaction() {
+				if (oneWeek.includes(slave.ID)) {
+					return introReactionOneWeek();
+				}
+				if (twoWeeks.includes(slave.ID)) {
+					return introReactionTwoWeeks();
+				}
+				if (threeWeeks.includes(slave.ID)) {
+					return introReactionThreeWeeks();
+				}
+				if (fourWeeks.includes(slave.ID)) {
+					return introReactionFourWeeks();
+				}
 
-		function introReactionThreeWeeks() {
-			if (isDevoted) {
-				return `, at which concern covers ${his} features. You threatened ${him} three weeks ago; surely you're bluffing again – right?`;
-			} else if (isAccepting) {
-				return `. ${He} looks slightly worried, but also seems to think you might be bluffing. After all, you did threaten ${him} three weeks ago, so why would this threat be any less empty?`;
-			} else if (isCareful) {
-				return `. ${He} looks somewhat concerned, but mostly seems to think you're probably bluffing. You did threaten ${him} only three weeks ago, after all, so you're probably not going to do it today either... right?`;
-			} else {
-				return `. ${He} says nothing, but you can tell ${he}'s thinking you're bluffing again. You threatened ${him} three weeks ago, and ${he} seems to doubt you're going to kill ${him} now, either.`;
+				return introReactionOther();
 			}
-		}
 
-		function introReactionFourWeeks() {
-			if (isDevoted) {
-				return `. A look of panic covers ${his} face, but you didn't kill ${him} four weeks ago, so maybe you won't do it now, either. Right?`;
-			} else if (isAccepting) {
-				return `, at which ${he} becomes visibly nervous. You threatened ${him} four weeks ago and ${he} seems to think you might be bluffing again, but ${he} can't tell.`;
-			} else if (isCareful) {
-				return `, at which ${he} looks rather unsettled. ${He} seems to think you might be bluffing, like you did four weeks ago when you last threatened ${him}.`;
-			} else {
-				return `, to which panic flashes across ${his} face. ${He} quickly recovers and puts on a brave face, though – you threatened ${his} life four weeks ago, so you're probably bluffing again. Right?`;
+			function introReactionOneWeek() {
+				if (isDevoted) {
+					return `. ${He} just looks at you warily; you threatened ${him} just last week, and ${he}'s suspecting you won't go through with it this time either.`;
+				} else if (isAccepting) {
+					return `, at which a brief moment of confusion flashes across ${his} face. You threatened ${him} only a week ago, and ${he}'s beginning to think you won't actually do it.`;
+				} else if (isCareful) {
+					return `. You can just barely detect a brief moment of scorn cross ${his} face – you threatened ${him} just last week, and ${he}'s starting to think you won't actually go through with it.`;
+				} else {
+					return `, at which ${he} laughs with derision. You threatened ${him} only last week, and ${he}'s calling your bluff.`;
+				}
 			}
-		}
 
-		function introReactionOther() {
-			return `, at which point abject terror fills ${his} face. ${He} immediately ${hasBothLegs(slave) ? `drops to ${his} knees and ` : ``}begins openly begging for you to show mercy.`;
-		}
-	}
+			function introReactionTwoWeeks() {
+				if (isDevoted) {
+					return `. ${He} looks at you with a hint of trepidation in ${his} eyes, but it seems for the most part ${he} thinks you won't do it – you did give ${him} an empty threat a couple of weeks ago, after all.`;
+				} else if (isAccepting) {
+					return `, to which ${he} just raises one eyebrow. You threatened ${him} just a few weeks ago, so why wouldn't you be bluffing now?`;
+				} else if (isCareful) {
+					return `. ${He} says nothing, but you can tell ${he} seems to think you're bluffing – you did threaten ${him} only a couple of weeks ago, after all.`;
+				} else {
+					return `, at which ${he} scoffs. You threatened ${him} a couple of weeks ago, and you're probably bluffing again.`;
+				}
+			}
 
-	function intro() {
-		const introDiv = document.createElement("div");
+			function introReactionThreeWeeks() {
+				if (isDevoted) {
+					return `, at which concern covers ${his} features. You threatened ${him} three weeks ago; surely you're bluffing again – right?`;
+				} else if (isAccepting) {
+					return `. ${He} looks slightly worried, but also seems to think you might be bluffing. After all, you did threaten ${him} three weeks ago, so why would this threat be any less empty?`;
+				} else if (isCareful) {
+					return `. ${He} looks somewhat concerned, but mostly seems to think you're probably bluffing. You did threaten ${him} only three weeks ago, after all, so you're probably not going to do it today either... right?`;
+				} else {
+					return `. ${He} says nothing, but you can tell ${he}'s thinking you're bluffing again. You threatened ${him} three weeks ago, and ${he} seems to doubt you're going to kill ${him} now, either.`;
+				}
+			}
 
-		introDiv.append(`You ${canWalk(slave)
-			? `call ${slave.slaveName}`
-			: `have ${slave.slaveName} brought`} into your office. `);
+			function introReactionFourWeeks() {
+				if (isDevoted) {
+					return `. A look of panic covers ${his} face, but you didn't kill ${him} four weeks ago, so maybe you won't do it now, either. Right?`;
+				} else if (isAccepting) {
+					return `, at which ${he} becomes visibly nervous. You threatened ${him} four weeks ago and ${he} seems to think you might be bluffing again, but ${he} can't tell.`;
+				} else if (isCareful) {
+					return `, at which ${he} looks rather unsettled. ${He} seems to think you might be bluffing, like you did four weeks ago when you last threatened ${him}.`;
+				} else {
+					return `, to which panic flashes across ${his} face. ${He} quickly recovers and puts on a brave face, though – you threatened ${his} life four weeks ago, so you're probably bluffing again. Right?`;
+				}
+			}
 
-		if (slave.fuckdoll) {
-			introDiv.append(introFuckdoll());
-		} else {
-			introDiv.append(introStandard());
+			function introReactionOther() {
+				return `, at which point abject terror fills ${his} face. ${He} immediately ${hasBothLegs(slave) ? `drops to ${his} knees and ` : ``}begins openly begging for you to show mercy.`;
+			}
 		}
-
-		return introDiv;
 	}
 
-	function getDisabledReasons() {
-		const arr = [];
-
-		if (V.pit && V.pit.slaveFightingBodyguard) {
-			arr.push(`You already have a slave fighting your bodyguard this week.`);
-		}
-
-		if (slave.fuckdoll) {
-			arr.push(`Fuckdolls cannot properly fight.`);
-		}
-
-		if (slave.fetish === "mindbroken") {
-			arr.push(`Mindbroken slaves cannot properly fight.`);
-		}
+	function plannedFight() {
+		const plannedFightsDiv = document.createElement("div");
 
-		if (!S.Bodyguard) {
-			arr.push(`You must have a bodyguard for ${slave.slaveName} to fight.`);
-		}
+		plannedFightsDiv.append(`${!slave.fuckdoll && slave.fetish !== "mindbroken" ? `You abruptly cut ${his} begging short once you` : `You change your mind as you suddenly`} remember ${getSlave(V.pit.slaveFightingBodyguard).slaveName} is already fighting your bodyguard ${S.Bodyguard.slaveName} for ${his} life this week.`);
 
-		if (!V.pit) {
-			arr.push(`You must first build a pit for combat.`);
-		}
+		App.UI.DOM.appendNewElement("div", plannedFightsDiv, App.UI.DOM.passageLink(`Cancel the fight`, V.returnTo, () => {
+			V.pit.slaveFightingBodyguard = null;
+		}), ['margin-top']);
 
-		return arr;
+		return plannedFightsDiv;
 	}
 
 	function links() {
-		const linksDiv = App.UI.DOM.makeElement("div", null, "margin-top");
+		const linksDiv = App.UI.DOM.makeElement("div", null, ["margin-top"]);
 
 		const links = [];
 		const disabledReasons = getDisabledReasons();
@@ -247,667 +233,681 @@ App.UI.SlaveInteract.killSlave = function(slave) {
 		linksDiv.appendChild(App.UI.DOM.generateLinksStrip(links));
 
 		return linksDiv;
-	}
-
-	function kill() {
-		const killDiv = document.createElement("div");
 
-		if (!slave.fuckdoll && slave.fetish !== "mindbroken") {
-			killDiv.append(`You simply smile at ${him} and tell ${him} not to worry `);
-		} else {
-			killDiv.append(`You say nothing `);
-		}
+		function getDisabledReasons() {
+			const arr = [];
 
-		killDiv.append(`as you continue ${qualifiedFS
-			? `sharpening your ${weapon}.`
-			: `threading on a suppressor.`} ${slave.slaveName} ${!slave.fuckdoll && slave.fetish !== "mindbroken"
-			? `gives an audible sigh of relief and begins to thank you profusely, though ${his} thanks are cut short as the sound of`
-			: `continues to stand there ${slave.fetish === "mindbroken" ? `dumbly` : ``} until the sound of`} ${qualifiedFS
-			? `a sharp edge slicing through flesh`
-			: `a suppressed gunshot`} rings through the room. You have another servant clean up the mess as you continue with what you were previously doing.`);
+			if (V.pit && V.pit.slaveFightingBodyguard) {
+				arr.push(`You already have a slave fighting your bodyguard this week.`);
+			}
 
-		killDiv.append(relations(), resetCounters());
+			if (slave.fuckdoll) {
+				arr.push(`Fuckdolls cannot properly fight.`);
+			}
 
-		removeSlave(slave);
+			if (slave.fetish === "mindbroken") {
+				arr.push(`Mindbroken slaves cannot properly fight.`);
+			}
 
-		return killDiv;
-	}
+			if (!S.Bodyguard) {
+				arr.push(`You must have a bodyguard for ${slave.slaveName} to fight.`);
+			}
 
-	function resetCounters() {
-		V.threatened = [[], [], [], [], []];
+			if (!V.pit) {
+				arr.push(`You must first build a pit for combat.`);
+			}
 
-		if (V.threatened[1].length +
-			V.threatened[2].length +
-			V.threatened[3].length +
-			V.threatened[4].length > 0) {
-			return `All the slaves you had threatened before know now that you mean business.`;
+			return arr;
 		}
 
-		return '';
-	}
+		function kill() {
+			const killDiv = document.createElement("div");
 
-	function mercy() {
-		const mercyDiv = document.createElement("div");
+			if (!slave.fuckdoll && slave.fetish !== "mindbroken") {
+				killDiv.append(`You simply smile at ${him} and tell ${him} not to worry `);
+			} else {
+				killDiv.append(`You say nothing `);
+			}
 
-		if (!slave.fuckdoll && slave.fetish !== "mindbroken") {
-			App.Events.addParagraph(mercyDiv, [mercyReaction()]);
-		} else {
-			mercyDiv.append(`You change your mind, and with a wave of your hand, send ${slave.slaveName} back to ${his} duties. Maybe some other time.`);
-		}
+			killDiv.append(`as you continue ${qualifiedFS
+				? `sharpening your ${weapon}.`
+				: `threading on a suppressor.`} ${slave.slaveName} ${!slave.fuckdoll && slave.fetish !== "mindbroken"
+				? `gives an audible sigh of relief and begins to thank you profusely, though ${his} thanks are cut short as the sound of`
+				: `continues to stand there ${slave.fetish === "mindbroken" ? `dumbly` : ``} until the sound of`} ${qualifiedFS
+				? `a sharp edge slicing through flesh`
+				: `a suppressed gunshot`} rings through the room. You have another servant clean up the mess as you continue with what you were previously doing.`);
 
-		oneWeek.push(slave.ID);
+			killDiv.append(relations(), resetCounters());
 
-		return mercyDiv;
-	}
+			removeSlave(slave);
 
-	function mercyReaction() {
-		if (oneWeek.includes(slave.ID)) {
-			return mercyReactionOneWeek();
-		}
-		if (twoWeeks.includes(slave.ID)) {
-			return mercyReactionTwoWeeks();
-		}
-		if (threeWeeks.includes(slave.ID)) {
-			return mercyReactionThreeWeeks();
-		}
-		if (fourWeeks.includes(slave.ID)) {
-			return mercyReactionFourWeeks();
-		}
+			return killDiv;
 
-		return mercyReactionOther();
-	}
+			function relations() {
+				// TODO: potentially expand to allow for checking for more than one relation (i.e. sister/mother/lover, etc)
+				const relationsDiv = App.UI.DOM.makeElement("div", null, ['margin-top']);
 
-	// TODO: not sure about some of this text
-	function mercyReactionOneWeek() {
-		if (isDevoted) {
-			slave.devotion -= 5;
-			slave.trust -= 10;
+				const halfSisters = [];
+				const sisters = [];
+				const twins = [];
+				const daughters = [];
 
-			return `You tell ${him} that you've decided to spare ${him} today. ${He} just looks at you with confusion – you've threatened ${him} for weeks in a row now, and you haven't gone through with it. ${He}'s beginning to think you're just <span class="devotion dec">full of it</span> and <span class="trust dec">not to be trusted.</span>`;
-		} else if (isAccepting) {
-			slave.devotion -= 7;
-			slave.trust -= 15;
+				const isWife = slave.relationship === -3;
 
-			return `You tell ${him} that, at least for the time being, you've decided to keep ${him} around. ${He} just looks at you warily – if you didn't kill ${him} last week or this week, you must just be <span class="devotion dec">full of it,</span> and <span class="trust dec">not to be trusted.</span>`;
-		} else if (isCareful) {
-			slave.devotion -= 10;
-			slave.trust -= 20;
+				let mother = null;
+				let father = null;
+				let relationshipTarget = null;
+				let rival = null;
 
-			return `You tell ${him} that you've changed your mind and decided to keep ${him} around, to which ${he} doesn't reply. Clearly, if you're just bluffing for weeks in a row, you're just <span class="devotion dec">full of it</span> and <span class="trust dec">not to be trusted.</span>`;
-		} else {
-			const man = ["XY", "XXY", "XYY", "X0", "X"].includes(V.PC.genes) ? `man` : `woman`;
-
-			slave.devotion -= 15;
-			slave.trust -= 25;
+				for (const target of V.slaves) {
+					if (target.devotion > 50 && isWife) {
+						target.trust -= 25;
+					}
 
-			return `You tell ${him} that you've decided to spare ${him} today. ${He} simply scoffs and rolls ${his} eyes – of course you wouldn't; <span class="devotion dec">you're full of it.</span> You're obviously not a ${man} of your word, <span class="trust dec">and not someone to be trusted.</span>`;
-		}
-	}
+					if (slave.mother === target.ID) {
+						mother = target.ID;
+						continue;
+					}
 
-	function mercyReactionTwoWeeks() {
-		if (isDevoted) {
-			slave.devotion -= 3;
-			slave.trust -= 7;
+					if (slave.father === target.ID) {
+						father = target.ID;
+						continue;
+					}
 
-			return `You've decided to spare ${his} life for the time being, you tell ${him}. ${He} nods and ${canTalk(slave) ? `mumbles` : `signs`} a quick "thank you". You didn't kill ${him} last time you threatened ${him}, and ${he}'s pretty sure <span class="devotion dec">you're just full of it</span> and <span class="trust dec">not someone to be trusted.</span>`;
-		} else if (isAccepting) {
-			slave.devotion -= 5;
-			slave.trust -= 10;
+					if (target.mother === slave.ID || target.father === slave.ID) {
+						daughters.push(target.ID);
+						continue;
+					}
 
-			return `You tell ${him} that you've decided to spare ${him} for now. ${He} ${canTalk(slave) ? `mumbles` : `signs`} a quick "thank you", though you can tell ${he} didn't really mean it – you didn't kill ${his} last time you threatened ${him}, and ${he}'s pretty sure <span class="devotion dec">you're just full of it</span> and <span class="trust dec">not someone to be trusted.</span>`;
-		} else if (isCareful) {
-			slave.devotion -= 7;
-			slave.trust -= 15;
+					if (areSisters(slave, target)) {
+						switch (areSisters(slave, target)) {
+							case 1:
+								twins.push(target.ID);
+								continue;
+							case 2:
+								sisters.push(target.ID);
+								continue;
+							case 3:
+								halfSisters.push(target.ID);
+								continue;
+							default:
+								throw new Error(`Unexpected value '${areSisters(slave, target)}' found in relations()`);
+						}
+					}
 
-			return `You tell ${him} you've changed your mind for the time being, to which ${he} doesn't reply. You threatened ${him} a couple of weeks ago, and if you didn't go through with it then, why would you now? As far as ${he}'s concerned, you're obviously <span class="devotion dec">just full of it</span> and <span class="trust dec">not someone to be trusted.</span>`;
-		} else {
-			slave.devotion -= 10;
-			slave.trust -= 15;
+					if (slave.relationship > 0 && slave.relationshipTarget === target.ID) {
+						relationshipTarget = target.ID;
+						continue;
+					}
 
-			return `You tell ${him} that you've decided to spare ${him} today. ${He} simply scoffs and rolls ${his} eyes – of course you wouldn't; <span class="devotion dec">you're full of it.</span> You're obviously someone who makes empty threats, <span class="trust dec">and not someone to be trusted.</span>`;
-		}
-	}
+					if (slave.rivalry && slave.rivalryTarget === target.ID) {
+						rival = target.ID;
+						continue;
+					}
 
-	function mercyReactionThreeWeeks() {
-		if (isDevoted) {
-			slave.devotion -= 2;
-			slave.trust -= 5;
+					if (target.devotion > 50) {
+						target.devotion -= 15;
+						continue;
+					}
+				}
 
-			return `You tell ${him} that you've decided to spare ${his} life for now. ${He} replies with a "thank you", though you can tell ${he} is obviously <span class="devotion dec">quite troubled</span> by the fact that you would threaten one of your devoted slaves. <span class="trust dec">Obviously ${he} means very little to you.</span>`;
-		} else if (isAccepting) {
-			slave.devotion -= 3;
-			slave.trust -= 7;
+				if (mother) {
+					relationsDiv.appendChild(getMotherEffects(mother));
+				}
 
-			return `You've decided to spare ${him} for now, you tell ${him}. ${He} hesitantly gives you a quick "thank you", but you can tell ${he} is obviously <span class="devotion dec">quite troubled</span> by the fact that you would threaten ${him} in the first place. <span class="trust dec">Obviously ${he} means very little to you.</span>`;
-		} else if (isCareful) {
-			slave.devotion -= 5;
-			slave.trust -= 10;
+				if (father) {
+					relationsDiv.appendChild(getFatherEffects(father));
+				}
 
-			return `You tell ${him} that you've changed your mind for now. ${He} nods, seemingly <span class="trust dec">afraid</span> to${canTalk(slave) ? ` say or` : ``} do anything that would make you change your mind. The fact that you value your slaves' lives so little also <span class="devotion dec">worries ${him}.</span>`;
-		} else {
-			slave.devotion -= 7;
-			slave.trust -= 10;
+				if (daughters.length) {
+					relationsDiv.appendChild(getDaughtersEffects(daughters));
+				}
 
-			return `You inform that you've changed your mind and are willing to give ${him} another chance. ${He} doesn't seems very grateful, but then, ${he} didn't look too worried to begin with, either – you didn't kill ${him} last time you threatened, so you must just be <span class="devotion dec">all bluster and no balls.</span> <span class="trust dec">${He} obviously can't trust someone who can't keep their word, either.</span>`;
-		}
-	}
+				if (twins.length) {
+					relationsDiv.appendChild(getTwinsEffects(twins));
+				}
 
-	function mercyReactionFourWeeks() {
-		if (isDevoted) {
-			slave.devotion -= 2;
-			slave.trust -= 3;
+				if (sisters.length) {
+					relationsDiv.appendChild(getSistersEffects(sisters));
+				}
 
-			return `You tell ${him} that you've decided to spare ${him} for the time being. You tell ${him} as much, to which ${he} replies with profuse thanks. That you would threaten one of your devoted slaves at all <span class="devotion dec">troubles ${him},</span> though, and ${he} begins to <span class="trust dec">fear how little you value ${his} life.</span>`;
-		} else if (isAccepting) {
-			slave.devotion--;
-			slave.trust -= 5;
+				if (halfSisters.length) {
+					relationsDiv.appendChild(getHalfSistersEffects(halfSisters));
+				}
 
-			return `You inform ${him} that you've changed your mind for the time being. You can see relief fill ${his} features, and ${he} begins to thank you profusely. Threatening ${him} has given ${him} <span class="devotion dec">second thoughts</span> about how much ${he}'s willing to accept you as ${his} owner, though, and ${he} begins to <span class="trust dec">fear how little you value ${his} life.</span>`;
-		} else if (isCareful) {
-			slave.devotion += 3;
-			slave.trust -= 7;
+				if (relationshipTarget) {
+					relationsDiv.appendChild(getRelationshipEffects(relationshipTarget));
+				}
 
-			return `You decide to spare ${him} for now, and you tell ${him} as much. ${He} seems somewhat <span class="devotion inc">genuinely grateful</span> for another chance, but also <span class="trust dec">afraid</span> that ${he} means so little to you.`;
-		} else {
-			slave.devotion += 5;
-			slave.trust -= 7;
+				if (isWife) {
+					relationsDiv.appendChild(getWifeEffects());
+				}
 
-			return `You've decided to give ${him} another chance, you tell ${him}. ${He} looks <span class="devotion inc">genuinely grateful</span> for another chance, but also <span class="trust dec">afraid</span> that ${he} might${canTalk(slave) ? ` say or` : ``} do something to make you change your mind.`;
-		}
-	}
+				if (rival) {
+					relationsDiv.appendChild(getRivalEffects(rival));
+				}
 
-	function mercyReactionOther() {
-		if (isDevoted) {
-			slave.devotion += 5;
-			slave.trust -= 15;
-		} else if (isAccepting) {
-			slave.devotion += 10;
-			slave.trust -= 25;
-		} else if (isCareful) {
-			slave.devotion += 15;
-			slave.trust -= 30;
-		} else {
-			slave.devotion += 20;
-			slave.trust -= 35;
-		}
+				if (V.arcologies[0].FSPaternalist !== "unset") {
+					relationsDiv.appendChild(getFSEffects());
+				}
 
-		return `You make a show of considering sparing ${his} life, then, with a heavy sigh, unbuckle your pants and sit down at your desk. You beckon to ${him}, and ${he} just about trips over ${himself} as ${he} hastily makes ${his} way over to you. ${His} blowjob isn't the best you've ever had, ${him} <span class="trust dec">sobbing</span> as much as ${he} is, but ${his} enthusiasm more than makes up for it. After you finish deep in ${his} throat, ${he} sits back and wipes away ${his} tears, sniffling and <span class="devotion inc">thanking you again</span> for giving ${him} another chance.`;
-	}
+				return relationsDiv;
 
-	function combat() {
-		const combatDiv = document.createElement("div");
+				function getMotherEffects(ID) {
+					const subDiv = document.createElement("div");
 
-		let reactionText = `The fear on ${his} face is palpable, though ${he} nods slowly and agrees, not seeing another choice.`;
+					const mother = getSlave(ID);
 
-		if (slave.skill.combat) {
-			reactionText = `${He} nods ${his} head and straightens up, as though mentally preparing ${himself} for the fight for ${his} life.`;
-		}
+					App.Events.addParagraph(subDiv, [
+						`${His} mother ${mother.slaveName} is <span class="devotion dec">grief-stricken</span> that you would take ${his} ${daughter} from ${getPronouns(mother).him}.`
+					]);
 
-		if (V.animals.canine.length || V.animals.hooved.length || V.animals.feline.length) {
-			combatDiv.append(animals());
-		} else {
-			combatDiv.append(bodyguard());
-		}
+					mother.devotion -= 30;
 
-		return combatDiv;
+					return subDiv;
+				}
 
-		function animals() {
-			const subDiv = document.createElement("div");
-			const linksDiv = App.UI.DOM.makeElement("div", null, ['kill-slave-options']);
+				function getFatherEffects(ID) {
+					const subDiv = document.createElement("div");
 
-			const links = [];
+					const father = getSlave(ID);
 
-			const moreThanOneAnimal = V.active.canine && V.active.hooved ||
-				V.active.canine && V.active.feline ||
-				V.active.hooved && V.active.feline;
+					App.Events.addParagraph(subDiv, [
+						`${His} father ${father.slaveName} is <span class="devotion dec">grief-stricken</span> that you would take ${his} ${daughter} from ${getPronouns(father).him}.`
+					]);
 
-			let activeAnimal;
+					father.devotion -= 30;
 
-			if (!moreThanOneAnimal) {
-				if (V.active.canine) {
-					activeAnimal = V.active.canine;
-				} else if (V.active.hooved) {
-					activeAnimal = V.active.hooved;
-				} else {
-					activeAnimal = V.active.feline;
+					return subDiv;
 				}
-			}
 
-			subDiv.append(`You tell ${him} you'll give ${him} the chance to win ${his} life in combat – if ${he} wants to live, ${he} can either fight your bodyguard or one of your beasts.`);
+				function getDaughtersEffects(arr) {
+					if (arr.length === 1) {
+						const subDiv = document.createElement("div");
 
-			links.push(App.UI.DOM.link(`Have ${him} fight ${S.Bodyguard.slaveName}`, () => {
-				V.pit.slaveFightingBodyguard = slave.ID;
-				V.pit.slaveFightingAnimal = null;
-				V.pit.lethal = true;
-				V.pit.animal = null;
+						const daughter = getSlave(arr[0]);
+						const mother = getPronouns(slave).mother;
+						const {him: him2, daughter: daughter2} = getPronouns(daughter);
 
-				App.UI.DOM.replace(linksDiv, `It's decided. ${He} will fight your bodyguard, ${S.Bodyguard.slaveName}. ${reactionText}`);
-			}));
+						App.Events.addParagraph(subDiv, [
+							`${His} ${daughter2} ${daughter.slaveName} is <span class="devotion dec">horrified</span> that you would take ${his} ${mother} from ${him2}.`
+						]);
 
-			if (V.active.canine && getAnimal(V.active.canine).species === "dog" && !V.active.hooved && !V.active.feline) {
-				links.push(App.UI.DOM.disabledLink(`Have ${him} fight one of your animals`, [`A dog isn't a proper challenge.`]));
-			} else if (V.active.feline && getAnimal(V.active.feline).species === "cat" && !V.active.hooved && !V.active.canine) {
-				links.push(App.UI.DOM.disabledLink(`Have ${him} fight one of your animals`, [`Housecats are much too small to fight.`]));
-			} else {
-				links.push(App.UI.DOM.link(`Have ${him} fight one of your animals`, () => {
-					const animalOptions = [];
+						daughter.devotion -= 25;
 
-					if (V.active.canine && getAnimal(V.active.canine).species !== "dog") {
-						animalOptions.push(V.active.canine);
-					}
-					if (V.active.hooved) {
-						animalOptions.push(V.active.hooved);
-					}
-					if (V.active.feline && getAnimal(V.active.feline).species !== "cat") {
-						animalOptions.push(V.active.feline);
-					}
+						return subDiv;
+					} else {
+						const subDiv = document.createElement("div");
 
-					V.pit.slaveFightingAnimal = slave.ID;
-					V.pit.slaveFightingBodyguard = null;
-					V.pit.lethal = true;
-					V.pit.animal = animalOptions.random();
+						const daughters = [];
+						const mother = getPronouns(slave).mother;
 
-					App.UI.DOM.replace(linksDiv, `It's decided. ${He} will fight ${moreThanOneAnimal ? ` one of your animals.` : ` your ${activeAnimal.species}.`} ${reactionText}`);
-				}));
-			}
+						if (arr.length > 2) {
+							daughters.push(toSentence(arr));
+						} else {
+							daughters.push(`${getSlave(arr[0]).slaveName} and ${getSlave(arr[1]).slaveName}`);
+						}
 
-			App.UI.DOM.appendNewElement("div", linksDiv, App.UI.DOM.generateLinksStrip(links));
+						arr.forEach(i => getSlave(i).devotion -= 25);
 
-			subDiv.append(linksDiv);
+						App.Events.addParagraph(subDiv, [
+							`${His} children, ${daughters}, are <span class="devotion dec">horrified</span> that you would take their ${mother} from them.`
+						]);
 
-			return subDiv;
-		}
+						return subDiv;
+					}
+				}
 
-		function bodyguard() {
-			const subDiv = document.createElement("div");
+				function getTwinsEffects(arr) {
+					if (arr.length === 1) {
+						const subDiv = document.createElement("div");
 
-			subDiv.append(`You tell ${him} you'll let your bodyguard decide ${his} fate — if ${he} wants to live, ${he}'ll have to beat ${S.Bodyguard.slaveName} in hand-to-hand combat in ${V.pit.name}. `, reactionText);
+						const twin = getSlave(arr[0]);
+						const sister = getPronouns(slave).sister;
+						const {him: him2, his: his2} = getPronouns(twin);
 
-			V.pit.slaveFightingBodyguard = slave.ID;
-			V.pit.lethal = true;
-			V.pit.animal = null;
+						App.Events.addParagraph(subDiv, [
+							`${His} twin ${twin.slaveName} is <span class="devotion dec">devastated</span> that you would take ${his2} ${sister} from ${him2}.`
+						]);
 
-			return subDiv;
-		}
-	}
+						twin.devotion -= 30;
 
-	function relations() {
-		// TODO: potentially expand to allow for checking for more than one relation (i.e. sister/mother/lover, etc)
-		const relationsDiv = App.UI.DOM.makeElement("div", null, 'margin-top');
+						return subDiv;
+					} else {
+						const subDiv = document.createElement("div");
 
-		const halfSisters = [];
-		const sisters = [];
-		const twins = [];
-		const daughters = [];
+						const twins = [];
 
-		const isWife = slave.relationship === -3;
+						const sister = getPronouns(slave).sister;
 
-		let mother = null;
-		let father = null;
-		let relationshipTarget = null;
-		let rival = null;
+						if (arr.length > 2) {
+							let lastTwin = arr.pop();
 
-		for (const target of V.slaves) {
-			if (target.devotion > 50 && isWife) {
-				target.trust -= 25;
-			}
+							for (const twin of arr) {
+								twins.push(`${getSlave(twin).slaveName},`);
 
-			if (slave.mother === target.ID) {
-				mother = target.ID;
-				continue;
-			}
+								getSlave(twin).devotion -= 30;
+							}
 
-			if (slave.father === target.ID) {
-				father = target.ID;
-				continue;
-			}
+							twins.push(`and ${getSlave(lastTwin).slaveName}`);
+						} else {
+							twins.push(`${getSlave(arr[0]).slaveName} and ${getSlave(arr[1]).slaveName}`);
+						}
 
-			if (target.mother === slave.ID || target.father === slave.ID) {
-				daughters.push(target.ID);
-				continue;
-			}
+						arr.forEach(i => getSlave(i).devotion -= 30);
 
-			if (areSisters(slave, target)) {
-				switch (areSisters(slave, target)) {
-					case 1:
-						twins.push(target.ID);
-						continue;
-					case 2:
-						sisters.push(target.ID);
-						continue;
-					case 3:
-						halfSisters.push(target.ID);
-						continue;
-					default:
-						throw new Error(`Unexpected value '${areSisters(slave, target)}' found in relations()`);
+						App.Events.addParagraph(subDiv, [
+							`${His} twins, ${twins.join(' ')} are <span class="devotion dec">devastated</span> that you would take their ${sister} from them.`
+						]);
+
+						return subDiv;
+					}
 				}
-			}
 
-			if (slave.relationship > 0 && slave.relationshipTarget === target.ID) {
-				relationshipTarget = target.ID;
-				continue;
-			}
+				function getSistersEffects(arr) {
+					if (arr.length === 1) {
+						const subDiv = document.createElement("div");
 
-			if (slave.rivalry && slave.rivalryTarget === target.ID) {
-				rival = target.ID;
-				continue;
-			}
+						const firstSister = getSlave(arr[0]);
+						const sister = getPronouns(slave).sister;
+						const {him: him2, his: his2} = getPronouns(firstSister);
 
-			if (target.devotion > 50) {
-				target.devotion -= 15;
-				continue;
-			}
-		}
+						App.Events.addParagraph(subDiv, [
+							`${His} sister ${firstSister.slaveName} is <span class="devotion dec">grief-stricken</span> that you would take ${his2} ${sister} from ${him2}.`
+						]);
 
-		if (mother) {
-			relationsDiv.appendChild(getMotherEffects(mother));
-		}
+						firstSister.devotion -= 25;
 
-		if (father) {
-			relationsDiv.appendChild(getFatherEffects(father));
-		}
+						return subDiv;
+					} else {
+						const subDiv = document.createElement("div");
 
-		if (daughters.length) {
-			relationsDiv.appendChild(getDaughtersEffects(daughters));
-		}
+						const sisters = [];
 
-		if (twins.length) {
-			relationsDiv.appendChild(getTwinsEffects(twins));
-		}
+						const sister = getPronouns(slave).sister;
 
-		if (sisters.length) {
-			relationsDiv.appendChild(getSistersEffects(sisters));
-		}
+						if (arr.length > 2) {
+							let lastSister = arr.pop();
 
-		if (halfSisters.length) {
-			relationsDiv.appendChild(getHalfSistersEffects(halfSisters));
-		}
+							for (const sister of arr) {
+								sisters.push(`${getSlave(sister).slaveName},`);
+							}
 
-		if (relationshipTarget) {
-			relationsDiv.appendChild(getRelationshipEffects(relationshipTarget));
-		}
+							sisters.push(`and ${getSlave(lastSister).slaveName}`);
+						} else {
+							sisters.push(`${getSlave(arr[0]).slaveName} and ${getSlave(arr[1]).slaveName}`);
+						}
 
-		if (isWife) {
-			relationsDiv.appendChild(getWifeEffects());
-		}
+						arr.forEach(i => getSlave(i).devotion -= 25);
 
-		if (rival) {
-			relationsDiv.appendChild(getRivalEffects(rival));
-		}
+						App.Events.addParagraph(subDiv, [
+							`${His} sister, ${sisters.join(' ')} are <span class="devotion dec">grief-stricken</span> that you would take their ${sister} from them.`
+						]);
 
-		if (V.arcologies[0].FSPaternalist !== "unset") {
-			relationsDiv.appendChild(getFSEffects());
-		}
+						return subDiv;
+					}
+				}
 
-		return relationsDiv;
-	}
+				function getHalfSistersEffects(arr) {
+					if (arr.length === 1) {
+						const subDiv = document.createElement("div");
 
-	function getMotherEffects(ID) {
-		const subDiv = document.createElement("div");
+						const halfSister = getSlave(arr[0]);
+						const sister = getPronouns(slave).sister;
+						const {him: him2} = getPronouns(halfSister);
 
-		const mother = getSlave(ID);
+						App.Events.addParagraph(subDiv, [
+							`${His} half-sister ${halfSister.slaveName} is <span class="devotion dec">saddened</span> that you would take ${his} ${sister} from ${him2}.`
+						]);
 
-		App.Events.addParagraph(subDiv, [
-			`${His} mother ${mother.slaveName} is <span class="devotion dec">grief-stricken</span> that you would take ${his} ${daughter} from ${getPronouns(mother).him}.`
-		]);
+						halfSister.devotion -= 20;
 
-		mother.devotion -= 30;
+						return subDiv;
+					} else {
+						const subDiv = document.createElement("div");
 
-		return subDiv;
-	}
+						const halfSisters = [];
 
-	function getFatherEffects(ID) {
-		const subDiv = document.createElement("div");
+						const sister = getPronouns(slave).sister;
 
-		const father = getSlave(ID);
+						if (arr.length > 2) {
+							let lastHalfSister = arr.pop();
 
-		App.Events.addParagraph(subDiv, [
-			`${His} father ${father.slaveName} is <span class="devotion dec">grief-stricken</span> that you would take ${his} ${daughter} from ${getPronouns(father).him}.`
-		]);
+							for (const sister of arr) {
+								halfSisters.push(`${getSlave(sister).slaveName},`);
+							}
 
-		father.devotion -= 30;
+							halfSisters.push(`and ${getSlave(lastHalfSister).slaveName}`);
+						} else {
+							halfSisters.push(`${getSlave(arr[0]).slaveName} and ${getSlave(arr[1]).slaveName}`);
+						}
 
-		return subDiv;
-	}
+						arr.forEach(i => getSlave(i).devotion -= 20);
 
-	function getDaughtersEffects(arr) {
-		if (arr.length === 1) {
-			const subDiv = document.createElement("div");
+						App.Events.addParagraph(subDiv, [
+							`${His} half-sisters, ${halfSisters.join(' ')}, are <span class="devotion dec">saddened</span> that you would take their ${sister} from them.`
+						]);
 
-			const daughter = getSlave(arr[0]);
-			const mother = getPronouns(slave).mother;
-			const {him: him2, daughter: daughter2} = getPronouns(daughter);
+						return subDiv;
+					}
+				}
 
-			App.Events.addParagraph(subDiv, [
-				`${His} ${daughter2} ${daughter.slaveName} is <span class="devotion dec">horrified</span> that you would take ${his} ${mother} from ${him2}.`
-			]);
+				function getRelationshipEffects(ID) {
+					if (getSlave(ID).fetish !== "mindbroken") {
+						const subDiv = document.createElement("div");
 
-			daughter.devotion -= 25;
+						const target = getSlave(ID);
 
-			return subDiv;
-		} else {
-			const subDiv = document.createElement("div");
+						App.Events.addParagraph(subDiv, [
+							`${target.slaveName} is <span class="devotion dec">grief-stricken</span> that you have killed ${getPronouns(target).his} best source of comfort and companionship in a life of bondage.`
+						]);
 
-			const daughters = [];
-			const mother = getPronouns(slave).mother;
+						target.devotion -= target.relationship * 10;
 
-			if (arr.length > 2) {
-				daughters.push(toSentence(arr));
-			} else {
-				daughters.push(`${getSlave(arr[0]).slaveName} and ${getSlave(arr[1]).slaveName}`);
-			}
+						return subDiv;
+					}
+				}
 
-			arr.forEach(i => getSlave(i).devotion -= 25);
+				function getWifeEffects() {
+					const subDiv = document.createElement("div");
 
-			App.Events.addParagraph(subDiv, [
-				`${His} children, ${daughters}, are <span class="devotion dec">horrified</span> that you would take their ${mother} from them.`
-			]);
+					V.slaves
+						.filter(slave => slave.devotion > 50)
+						.forEach(slave => slave.devotion -= 15);
 
-			return subDiv;
-		}
-	}
+					App.Events.addParagraph(subDiv, [
+						`Killing one of your slave wives is socially <span class="reputation dec">unacceptable.</span> In addition, your other devoted slaves are <span class="devotion dec">worried</span> that you might not respect their status.`
+					]);
 
-	function getTwinsEffects(arr) {
-		if (arr.length === 1) {
-			const subDiv = document.createElement("div");
+					repX(-200, "event", slave);
 
-			const twin = getSlave(arr[0]);
-			const sister = getPronouns(slave).sister;
-			const {him: him2, his: his2} = getPronouns(twin);
+					return subDiv;
+				}
 
-			App.Events.addParagraph(subDiv, [
-				`${His} twin ${twin.slaveName} is <span class="devotion dec">devastated</span> that you would take ${his2} ${sister} from ${him2}.`
-			]);
+				function getRivalEffects(ID) {
+					const subDiv = document.createElement("div");
 
-			twin.devotion -= 30;
+					const rival = getSlave(ID);
 
-			return subDiv;
-		} else {
-			const subDiv = document.createElement("div");
+					App.Events.addParagraph(subDiv, [
+						`${slave.slaveName}'s rival, ${rival.slaveName}, is <span class="devotion inc">pleased</span> that ${getPronouns(rival).he} won't have to see ${him} anymore.`
+					]);
 
-			const twins = [];
+					rival.devotion += rival.rivalry * 5;
 
-			const sister = getPronouns(slave).sister;
+					return subDiv;
+				}
 
-			if (arr.length > 2) {
-				let lastTwin = arr.pop();
+				function getFSEffects() {
+					const subDiv = document.createElement("div");
 
-				for (const twin of arr) {
-					twins.push(`${getSlave(twin).slaveName},`);
+					App.Events.addParagraph(subDiv, [
+						`Taking the life of one of your own slaves is <span class="reputation dec">a shocking notion</span> to your Paternalist society.`
+					]);
 
-					getSlave(twin).devotion -= 30;
-				}
+					FutureSocieties.Change("Paternalist", -20);
 
-				twins.push(`and ${getSlave(lastTwin).slaveName}`);
-			} else {
-				twins.push(`${getSlave(arr[0]).slaveName} and ${getSlave(arr[1]).slaveName}`);
+					return subDiv;
+				}
 			}
 
-			arr.forEach(i => getSlave(i).devotion -= 30);
+			function resetCounters() {
+				V.threatened = [[], [], [], [], []];
 
-			App.Events.addParagraph(subDiv, [
-				`${His} twins, ${twins.join(' ')} are <span class="devotion dec">devastated</span> that you would take their ${sister} from them.`
-			]);
+				if (V.threatened[1].length +
+					V.threatened[2].length +
+					V.threatened[3].length +
+					V.threatened[4].length > 0) {
+					return `All the slaves you had threatened before know now that you mean business.`;
+				}
 
-			return subDiv;
+				return '';
+			}
 		}
-	}
 
-	function getSistersEffects(arr) {
-		if (arr.length === 1) {
-			const subDiv = document.createElement("div");
+		function mercy() {
+			const mercyDiv = document.createElement("div");
 
-			const firstSister = getSlave(arr[0]);
-			const sister = getPronouns(slave).sister;
-			const {him: him2, his: his2} = getPronouns(firstSister);
+			if (!slave.fuckdoll && slave.fetish !== "mindbroken") {
+				App.Events.addParagraph(mercyDiv, [mercyReaction()]);
+			} else {
+				mercyDiv.append(`You change your mind, and with a wave of your hand, send ${slave.slaveName} back to ${his} duties. Maybe some other time.`);
+			}
 
-			App.Events.addParagraph(subDiv, [
-				`${His} sister ${firstSister.slaveName} is <span class="devotion dec">grief-stricken</span> that you would take ${his2} ${sister} from ${him2}.`
-			]);
+			oneWeek.push(slave.ID);
 
-			firstSister.devotion -= 25;
+			return mercyDiv;
 
-			return subDiv;
-		} else {
-			const subDiv = document.createElement("div");
+			function mercyReaction() {
+				if (oneWeek.includes(slave.ID)) {
+					return mercyReactionOneWeek();
+				}
+				if (twoWeeks.includes(slave.ID)) {
+					return mercyReactionTwoWeeks();
+				}
+				if (threeWeeks.includes(slave.ID)) {
+					return mercyReactionThreeWeeks();
+				}
+				if (fourWeeks.includes(slave.ID)) {
+					return mercyReactionFourWeeks();
+				}
 
-			const sisters = [];
+				return mercyReactionOther();
 
-			const sister = getPronouns(slave).sister;
+				// TODO: not sure about some of this text
+				function mercyReactionOneWeek() {
+					if (isDevoted) {
+						slave.devotion -= 5;
+						slave.trust -= 10;
 
-			if (arr.length > 2) {
-				let lastSister = arr.pop();
+						return `You tell ${him} that you've decided to spare ${him} today. ${He} just looks at you with confusion – you've threatened ${him} for weeks in a row now, and you haven't gone through with it. ${He}'s beginning to think you're just <span class="devotion dec">full of it</span> and <span class="trust dec">not to be trusted.</span>`;
+					} else if (isAccepting) {
+						slave.devotion -= 7;
+						slave.trust -= 15;
 
-				for (const sister of arr) {
-					sisters.push(`${getSlave(sister).slaveName},`);
-				}
+						return `You tell ${him} that, at least for the time being, you've decided to keep ${him} around. ${He} just looks at you warily – if you didn't kill ${him} last week or this week, you must just be <span class="devotion dec">full of it,</span> and <span class="trust dec">not to be trusted.</span>`;
+					} else if (isCareful) {
+						slave.devotion -= 10;
+						slave.trust -= 20;
 
-				sisters.push(`and ${getSlave(lastSister).slaveName}`);
-			} else {
-				sisters.push(`${getSlave(arr[0]).slaveName} and ${getSlave(arr[1]).slaveName}`);
-			}
+						return `You tell ${him} that you've changed your mind and decided to keep ${him} around, to which ${he} doesn't reply. Clearly, if you're just bluffing for weeks in a row, you're just <span class="devotion dec">full of it</span> and <span class="trust dec">not to be trusted.</span>`;
+					} else {
+						const man = ["XY", "XXY", "XYY", "X0", "X"].includes(V.PC.genes) ? `man` : `woman`;
 
-			arr.forEach(i => getSlave(i).devotion -= 25);
+						slave.devotion -= 15;
+						slave.trust -= 25;
 
-			App.Events.addParagraph(subDiv, [
-				`${His} sister, ${sisters.join(' ')} are <span class="devotion dec">grief-stricken</span> that you would take their ${sister} from them.`
-			]);
+						return `You tell ${him} that you've decided to spare ${him} today. ${He} simply scoffs and rolls ${his} eyes – of course you wouldn't; <span class="devotion dec">you're full of it.</span> You're obviously not a ${man} of your word, <span class="trust dec">and not someone to be trusted.</span>`;
+					}
+				}
 
-			return subDiv;
-		}
-	}
+				function mercyReactionTwoWeeks() {
+					if (isDevoted) {
+						slave.devotion -= 3;
+						slave.trust -= 7;
 
-	function getHalfSistersEffects(arr) {
-		if (arr.length === 1) {
-			const subDiv = document.createElement("div");
+						return `You've decided to spare ${his} life for the time being, you tell ${him}. ${He} nods and ${canTalk(slave) ? `mumbles` : `signs`} a quick "thank you". You didn't kill ${him} last time you threatened ${him}, and ${he}'s pretty sure <span class="devotion dec">you're just full of it</span> and <span class="trust dec">not someone to be trusted.</span>`;
+					} else if (isAccepting) {
+						slave.devotion -= 5;
+						slave.trust -= 10;
 
-			const halfSister = getSlave(arr[0]);
-			const sister = getPronouns(slave).sister;
-			const {him: him2} = getPronouns(halfSister);
+						return `You tell ${him} that you've decided to spare ${him} for now. ${He} ${canTalk(slave) ? `mumbles` : `signs`} a quick "thank you", though you can tell ${he} didn't really mean it – you didn't kill ${his} last time you threatened ${him}, and ${he}'s pretty sure <span class="devotion dec">you're just full of it</span> and <span class="trust dec">not someone to be trusted.</span>`;
+					} else if (isCareful) {
+						slave.devotion -= 7;
+						slave.trust -= 15;
 
-			App.Events.addParagraph(subDiv, [
-				`${His} half-sister ${halfSister.slaveName} is <span class="devotion dec">saddened</span> that you would take ${his} ${sister} from ${him2}.`
-			]);
+						return `You tell ${him} you've changed your mind for the time being, to which ${he} doesn't reply. You threatened ${him} a couple of weeks ago, and if you didn't go through with it then, why would you now? As far as ${he}'s concerned, you're obviously <span class="devotion dec">just full of it</span> and <span class="trust dec">not someone to be trusted.</span>`;
+					} else {
+						slave.devotion -= 10;
+						slave.trust -= 15;
 
-			halfSister.devotion -= 20;
+						return `You tell ${him} that you've decided to spare ${him} today. ${He} simply scoffs and rolls ${his} eyes – of course you wouldn't; <span class="devotion dec">you're full of it.</span> You're obviously someone who makes empty threats, <span class="trust dec">and not someone to be trusted.</span>`;
+					}
+				}
 
-			return subDiv;
-		} else {
-			const subDiv = document.createElement("div");
+				function mercyReactionThreeWeeks() {
+					if (isDevoted) {
+						slave.devotion -= 2;
+						slave.trust -= 5;
 
-			const halfSisters = [];
+						return `You tell ${him} that you've decided to spare ${his} life for now. ${He} replies with a "thank you", though you can tell ${he} is obviously <span class="devotion dec">quite troubled</span> by the fact that you would threaten one of your devoted slaves. <span class="trust dec">Obviously ${he} means very little to you.</span>`;
+					} else if (isAccepting) {
+						slave.devotion -= 3;
+						slave.trust -= 7;
 
-			const sister = getPronouns(slave).sister;
+						return `You've decided to spare ${him} for now, you tell ${him}. ${He} hesitantly gives you a quick "thank you", but you can tell ${he} is obviously <span class="devotion dec">quite troubled</span> by the fact that you would threaten ${him} in the first place. <span class="trust dec">Obviously ${he} means very little to you.</span>`;
+					} else if (isCareful) {
+						slave.devotion -= 5;
+						slave.trust -= 10;
 
-			if (arr.length > 2) {
-				let lastHalfSister = arr.pop();
+						return `You tell ${him} that you've changed your mind for now. ${He} nods, seemingly <span class="trust dec">afraid</span> to${canTalk(slave) ? ` say or` : ``} do anything that would make you change your mind. The fact that you value your slaves' lives so little also <span class="devotion dec">worries ${him}.</span>`;
+					} else {
+						slave.devotion -= 7;
+						slave.trust -= 10;
 
-				for (const sister of arr) {
-					halfSisters.push(`${getSlave(sister).slaveName},`);
+						return `You inform that you've changed your mind and are willing to give ${him} another chance. ${He} doesn't seems very grateful, but then, ${he} didn't look too worried to begin with, either – you didn't kill ${him} last time you threatened, so you must just be <span class="devotion dec">all bluster and no balls.</span> <span class="trust dec">${He} obviously can't trust someone who can't keep their word, either.</span>`;
+					}
 				}
 
-				halfSisters.push(`and ${getSlave(lastHalfSister).slaveName}`);
-			} else {
-				halfSisters.push(`${getSlave(arr[0]).slaveName} and ${getSlave(arr[1]).slaveName}`);
-			}
+				function mercyReactionFourWeeks() {
+					if (isDevoted) {
+						slave.devotion -= 2;
+						slave.trust -= 3;
 
-			arr.forEach(i => getSlave(i).devotion -= 20);
+						return `You tell ${him} that you've decided to spare ${him} for the time being. You tell ${him} as much, to which ${he} replies with profuse thanks. That you would threaten one of your devoted slaves at all <span class="devotion dec">troubles ${him},</span> though, and ${he} begins to <span class="trust dec">fear how little you value ${his} life.</span>`;
+					} else if (isAccepting) {
+						slave.devotion--;
+						slave.trust -= 5;
 
-			App.Events.addParagraph(subDiv, [
-				`${His} half-sisters, ${halfSisters.join(' ')}, are <span class="devotion dec">saddened</span> that you would take their ${sister} from them.`
-			]);
+						return `You inform ${him} that you've changed your mind for the time being. You can see relief fill ${his} features, and ${he} begins to thank you profusely. Threatening ${him} has given ${him} <span class="devotion dec">second thoughts</span> about how much ${he}'s willing to accept you as ${his} owner, though, and ${he} begins to <span class="trust dec">fear how little you value ${his} life.</span>`;
+					} else if (isCareful) {
+						slave.devotion += 3;
+						slave.trust -= 7;
 
-			return subDiv;
-		}
-	}
+						return `You decide to spare ${him} for now, and you tell ${him} as much. ${He} seems somewhat <span class="devotion inc">genuinely grateful</span> for another chance, but also <span class="trust dec">afraid</span> that ${he} means so little to you.`;
+					} else {
+						slave.devotion += 5;
+						slave.trust -= 7;
 
-	function getRelationshipEffects(ID) {
-		if (getSlave(ID).fetish !== "mindbroken") {
-			const subDiv = document.createElement("div");
+						return `You've decided to give ${him} another chance, you tell ${him}. ${He} looks <span class="devotion inc">genuinely grateful</span> for another chance, but also <span class="trust dec">afraid</span> that ${he} might${canTalk(slave) ? ` say or` : ``} do something to make you change your mind.`;
+					}
+				}
 
-			const target = getSlave(ID);
+				function mercyReactionOther() {
+					if (isDevoted) {
+						slave.devotion += 5;
+						slave.trust -= 15;
+					} else if (isAccepting) {
+						slave.devotion += 10;
+						slave.trust -= 25;
+					} else if (isCareful) {
+						slave.devotion += 15;
+						slave.trust -= 30;
+					} else {
+						slave.devotion += 20;
+						slave.trust -= 35;
+					}
 
-			App.Events.addParagraph(subDiv, [
-				`${target.slaveName} is <span class="devotion dec">grief-stricken</span> that you have killed ${getPronouns(target).his} best source of comfort and companionship in a life of bondage.`
-			]);
+					return `You make a show of considering sparing ${his} life, then, with a heavy sigh, unbuckle your pants and sit down at your desk. You beckon to ${him}, and ${he} just about trips over ${himself} as ${he} hastily makes ${his} way over to you. ${His} blowjob isn't the best you've ever had, ${him} <span class="trust dec">sobbing</span> as much as ${he} is, but ${his} enthusiasm more than makes up for it. After you finish deep in ${his} throat, ${he} sits back and wipes away ${his} tears, sniffling and <span class="devotion inc">thanking you again</span> for giving ${him} another chance.`;
+				}
+			}
+		}
 
-			target.devotion -= target.relationship * 10;
+		function combat() {
+			const combatDiv = document.createElement("div");
 
-			return subDiv;
-		}
-	}
+			let reactionText = `The fear on ${his} face is palpable, though ${he} nods slowly and agrees, not seeing another choice.`;
 
-	function getWifeEffects() {
-		const subDiv = document.createElement("div");
+			if (slave.skill.combat) {
+				reactionText = `${He} nods ${his} head and straightens up, as though mentally preparing ${himself} for the fight for ${his} life.`;
+			}
 
-		V.slaves
-			.filter(slave => slave.devotion > 50)
-			.forEach(slave => slave.devotion -= 15);
+			if (V.animals.canine.length || V.animals.hooved.length || V.animals.feline.length) {
+				combatDiv.append(animals());
+			} else {
+				combatDiv.append(bodyguard());
+			}
 
-		App.Events.addParagraph(subDiv, [
-			`Killing one of your slave wives is socially <span class="reputation dec">unacceptable.</span> In addition, your other devoted slaves are <span class="devotion dec">worried</span> that you might not respect their status.`
-		]);
+			return combatDiv;
 
-		repX(-200, "event", slave);
+			function animals() {
+				const subDiv = document.createElement("div");
+				const linksDiv = App.UI.DOM.makeElement("div", null, ['kill-slave-options']);
 
-		return subDiv;
-	}
+				const links = [];
+
+				const moreThanOneAnimal = V.active.canine && V.active.hooved ||
+					V.active.canine && V.active.feline ||
+					V.active.hooved && V.active.feline;
 
-	function getRivalEffects(ID) {
-		const subDiv = document.createElement("div");
+				let activeAnimal;
 
-		const rival = getSlave(ID);
+				if (!moreThanOneAnimal) {
+					if (V.active.canine) {
+						activeAnimal = V.active.canine;
+					} else if (V.active.hooved) {
+						activeAnimal = V.active.hooved;
+					} else {
+						activeAnimal = V.active.feline;
+					}
+				}
 
-		App.Events.addParagraph(subDiv, [
-			`${slave.slaveName}'s rival, ${rival.slaveName}, is <span class="devotion inc">pleased</span> that ${getPronouns(rival).he} won't have to see ${him} anymore.`
-		]);
+				subDiv.append(`You tell ${him} you'll give ${him} the chance to win ${his} life in combat – if ${he} wants to live, ${he} can either fight your bodyguard or one of your beasts.`);
 
-		rival.devotion += rival.rivalry * 5;
+				links.push(App.UI.DOM.link(`Have ${him} fight ${S.Bodyguard.slaveName}`, () => {
+					V.pit.slaveFightingBodyguard = slave.ID;
+					V.pit.slaveFightingAnimal = null;
+					V.pit.lethal = true;
+					V.pit.animal = null;
 
-		return subDiv;
-	}
+					App.UI.DOM.replace(linksDiv, `It's decided. ${He} will fight your bodyguard, ${S.Bodyguard.slaveName}. ${reactionText}`);
+				}));
 
-	function getFSEffects() {
-		const subDiv = document.createElement("div");
+				if (V.active.canine && getAnimal(V.active.canine).species === "dog" && !V.active.hooved && !V.active.feline) {
+					links.push(App.UI.DOM.disabledLink(`Have ${him} fight one of your animals`, [`A dog isn't a proper challenge.`]));
+				} else if (V.active.feline && getAnimal(V.active.feline).species === "cat" && !V.active.hooved && !V.active.canine) {
+					links.push(App.UI.DOM.disabledLink(`Have ${him} fight one of your animals`, [`Housecats are much too small to fight.`]));
+				} else {
+					links.push(App.UI.DOM.link(`Have ${him} fight one of your animals`, () => {
+						const animalOptions = [];
+
+						if (V.active.canine && getAnimal(V.active.canine).species !== "dog") {
+							animalOptions.push(V.active.canine);
+						}
+						if (V.active.hooved) {
+							animalOptions.push(V.active.hooved);
+						}
+						if (V.active.feline && getAnimal(V.active.feline).species !== "cat") {
+							animalOptions.push(V.active.feline);
+						}
+
+						V.pit.slaveFightingAnimal = slave.ID;
+						V.pit.slaveFightingBodyguard = null;
+						V.pit.lethal = true;
+						V.pit.animal = animalOptions.random();
+
+						App.UI.DOM.replace(linksDiv, `It's decided. ${He} will fight ${moreThanOneAnimal ? ` one of your animals.` : ` your ${activeAnimal.species}.`} ${reactionText}`);
+					}));
+				}
 
-		App.Events.addParagraph(subDiv, [
-			`Taking the life of one of your own slaves is <span class="reputation dec">a shocking notion</span> to your Paternalist society.`
-		]);
+				App.UI.DOM.appendNewElement("div", linksDiv, App.UI.DOM.generateLinksStrip(links));
 
-		FutureSocieties.Change("Paternalist", -20);
+				subDiv.append(linksDiv);
 
-		return subDiv;
-	}
+				return subDiv;
+			}
 
-	function plannedFight() {
-		const plannedFightsDiv = document.createElement("div");
+			function bodyguard() {
+				const subDiv = document.createElement("div");
 
-		plannedFightsDiv.append(`${!slave.fuckdoll && slave.fetish !== "mindbroken" ? `You abruptly cut ${his} begging short once you` : `You change your mind as you suddenly`} remember ${getSlave(V.pit.slaveFightingBodyguard).slaveName} is already fighting your bodyguard ${S.Bodyguard.slaveName} for ${his} life this week.`);
+				subDiv.append(`You tell ${him} you'll let your bodyguard decide ${his} fate — if ${he} wants to live, ${he}'ll have to beat ${S.Bodyguard.slaveName} in hand-to-hand combat in ${V.pit.name}. `, reactionText);
 
-		App.UI.DOM.appendNewElement("div", plannedFightsDiv, App.UI.DOM.passageLink(`Cancel the fight`, V.returnTo, () => {
-			V.pit.slaveFightingBodyguard = null;
-		}), ['margin-top']);
+				V.pit.slaveFightingBodyguard = slave.ID;
+				V.pit.lethal = true;
+				V.pit.animal = null;
 
-		return plannedFightsDiv;
+				return subDiv;
+			}
+		}
 	}
 };
diff --git a/src/npc/interaction/passage/fSlaveImpreg.js b/src/npc/interaction/passage/fSlaveImpreg.js
index 6131562b403424ef97cc5d716bbe62b1e9f8ee1a..ca912b74ee684874bb5970a0b80110f10c1ca26b 100644
--- a/src/npc/interaction/passage/fSlaveImpreg.js
+++ b/src/npc/interaction/passage/fSlaveImpreg.js
@@ -1,545 +1,503 @@
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {HTMLElement}
- */
-App.Interact.fSlaveImpreg = function(slave) {
-	const node = document.createElement("div");
-
-	App.UI.DOM.appendNewElement("p", node, `${slave.slaveName} is fertile; now you must select a slave with both a penis and potent testicles.`, "scene-intro");
+App.Interact.fSlaveImpregChoosePartner = class extends App.Interact.BaseChoosePartnerRenderer {
+	constructor(slave) {
+		super(slave);
+		this.intro = `${slave.slaveName} is fertile; now you must select a slave with both a penis and potent testicles.`;
+		this.noneEligible = `You have no slaves capable of inseminating others.`;
+		this.execute = App.Interact.fSlaveImpreg;
+	}
 
-	App.UI.DOM.appendNewElement("h3", node, `Select an eligible slave to serve as the semen donatrix`);
+	eligible(candidate) {
+		return canImpreg(this.slave, candidate) && canPenetrate(candidate);
+	}
 
-	const eligibles = V.slaves.filter((s) => (s.ID !== slave.ID) && canImpreg(slave, s) && canPenetrate(s));
-	const kinship = ibc.kinship_one_many(slave, eligibles);
-	for (const impregnatrix of eligibles) {
-		const div = App.UI.DOM.appendNewElement("div", node);
-		div.append(
-			App.UI.DOM.link(
-				SlaveFullName(impregnatrix),
-				() => {
-					jQuery(node).empty().append(consummate(impregnatrix));
-				}
-			)
-		);
-		if (impregnatrix.custom.label) {
-			App.UI.DOM.appendNewElement("span", div, ` ${impregnatrix.custom.label}`, "yellow");
-		}
-		if (totalRelatives(slave) > 0) {
-			const relTerm = relativeTerm(slave, impregnatrix);
-			if (relTerm !== null) {
-				App.UI.DOM.appendNewElement("span", div, ` ${capFirstChar(relTerm)}`, "lightgreen");
-			}
-		}
-		if (V.inbreeding && kinship[impregnatrix.ID] > 0) {
-			const thisKinship = kinship[impregnatrix.ID];
+	renderDetail(candidate, container) {
+		const kinship = ibc.kinship(candidate, this.slave);
+		if (V.inbreeding && kinship > 0) {
 			let adj = "";
-			if (thisKinship >= 0.5) {
+			if (kinship >= 0.5) {
 				adj = `Extreme`;
-			} else if (thisKinship >= 0.25) {
+			} else if (kinship >= 0.25) {
 				adj = `Major`;
-			} else if (thisKinship >= 0.125) {
+			} else if (kinship >= 0.125) {
 				adj = `Some`;
-			} else if (thisKinship >= 0.0625) {
+			} else if (kinship >= 0.0625) {
 				adj = `Minor`;
 			} else {
 				adj = `Slight`;
 			}
-			App.UI.DOM.appendNewElement("span", div, ` (${adj} inbreeding, CoI of ${thisKinship})`);
+			App.UI.DOM.appendNewElement("span", container, ` (${adj} inbreeding, CoI of ${kinship})`);
 		}
 	}
-	if (eligibles.length === 0) {
-		App.UI.DOM.appendNewElement("div", node, `You have no slaves capable of inseminating others.`, "note");
-	}
-	return node;
+}
 
-	/**
-	 * @param {App.Entity.SlaveState} impregnatrix
-	 * @returns {HTMLElement|DocumentFragment}
-	 */
-	function consummate(impregnatrix) {
-		const r = new SpacedTextAccumulator();
-		V.nextLink = "Slave Interact";
-		V.nextButton = "Back";
-
-		const {
-			He,
-			he, his, him, himself, girl
-		} = getPronouns(slave);
-
-		const {
-			He2, His2,
-			he2, his2, him2, himself2, hers2
-		} = getPronouns(impregnatrix).appendSuffix("2");
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @param {App.Entity.SlaveState} impregnatrix
+ * @returns {DocumentFragment}
+ */
+App.Interact.fSlaveImpreg = function(slave, impregnatrix) {
+	const r = new SpacedTextAccumulator();
+	V.nextLink = "Slave Interact";
+	V.nextButton = "Back";
+
+	const {
+		He,
+		he, his, him, himself, girl
+	} = getPronouns(slave);
+
+	const {
+		He2, His2,
+		he2, his2, him2, himself2, hers2
+	} = getPronouns(impregnatrix).appendSuffix("2");
+
+	const {
+		himP
+	} = getPronouns(V.PC).appendSuffix("P");
+
+	r.push(`The first necessary step is to prepare the donatrix.`);
+	const belly = bellyAdjective(slave);
+	const superfetation = (slave.geneticQuirks.superfetation === 2 && slave.pregKnown === 1) ? 1 : 0;
+	const penCountBonus = random(6, 20);
+	seX(slave, slave.mpreg ? "anal" : "vaginal", impregnatrix, "penetrative", penCountBonus + 1);
+
+	const assPussy = (slave.mpreg === 1) ? `ass` : `pussy`;
+	const assCunt = (slave.mpreg === 1) ? `ass` : `cunt`;
+	const prostate = (impregnatrix.prostate !== 0) ? `prostate` : `internals`;
+
+	if (impregnatrix.fetish === "pregnancy" && impregnatrix.fetishKnown === 1 && impregnatrix.fetishStrength > 60 && impregnatrix.devotion >= -20) {
+		r.push(`This is very easy, since ${impregnatrix.slaveName} has an impregnation fetish.`);
+		if (impregnatrix.pregKnown === 1) {
+			r.push(`${He2}'s pregnant, and as far as ${he2}'s concerned, everyone should be pregnant. ${He}'s <span class="hotpink">happy to spread the love.</span>`);
+		} else if (isFertile(impregnatrix)) {
+			r.push(`${He2}'d love to get pregnant ${himself2}, but as far as ${he2}'s concerned, putting a baby in someone else is the <span class="hotpink">next best thing.</span>`);
+		} else {
+			r.push(`${He2}'s been deeply unhappy that there's no prospect of ${him2} ever being able to carry a child, and this is the <span class="hotpink">next best thing</span> for ${him2}.`);
+		}
+		impregnatrix.devotion += 4;
+		if (impregnatrix.preg === -3) {
+			r.push(`${His2} member remains limp despite the prospect of getting another slave pregnant, but a direct injection of vasodilators quickly fixes that for this special occasion.`);
+		} else {
+			r.push(`${His2} member springs instantly to attention at the prospect of getting another slave pregnant.`);
+		}
+	} else if (impregnatrix.attrXX > 65 && impregnatrix.attrKnown === 1 && impregnatrix.devotion >= -20) {
+		r.push(`Since ${impregnatrix.slaveName} likes sticking ${his2} cock in girls, ${he2} doesn't take much convincing.`);
+		if (impregnatrix.preg === -3) {
+			r.push(`${His2} member remains limp despite the prospect of ${assPussy}, but a direct injection of vasodilators quickly fixes that for this special occasion.`);
+		} else {
+			r.push(`${His2} member springs instantly to attention at the prospect of pussy.`);
+		}
+	} else if (impregnatrix.devotion > 50) {
+		r.push(`Since ${impregnatrix.slaveName} is devoted to you, ${he2}'ll eagerly fuck anything you tell ${him2} to fuck.`);
+		if (impregnatrix.preg === -3) {
+			r.push(`${He2} accepts a direct injection of vasodilators to counteract the hormones keeping ${him2} soft,`);
+		} else {
+			r.push(`${He2} quickly gets ${himself2} hard,`);
+		}
+		r.push(`only a certain confusion in ${his2} look betraying that ${he2} realizes how special an occasion this is.`);
+	} else if (impregnatrix.devotion > 20) {
+		r.push(`Since ${impregnatrix.slaveName} is obedient, ${he2}'ll fuck anything you tell ${him2} to fuck.`);
+		if (impregnatrix.preg === -3) {
+			r.push(`${He2} accepts a direct injection of vasodilators to counteract the hormones keeping ${him2} soft,`);
+		} else {
+			r.push(`${He2} hurriedly gets ${himself2} hard,`);
+		}
+		r.push(`only a slight hesitation betraying ${his2} realization that this is a special occasion.`);
+	} else if (impregnatrix.devotion >= -20) {
+		r.push(`Since ${impregnatrix.slaveName} does not resist your will, ${he2} should comply reasonably well.`);
+		if (impregnatrix.preg === -3) {
+			r.push(`${He2} accepts a direct injection of vasodilators to counteract the hormones keeping ${him2} soft,`);
+		} else {
+			r.push(`${He2} has to work to get ${himself2} hard despite ${his2} doubts,`);
+		}
+		r.push(`fear and disgust showing on ${his2} face as ${he2} absorbs the perversion of the natural order of things ${he2}'s about to experience.`);
+	} else {
+		r.push(`Since ${impregnatrix.slaveName} is unlikely to comply willingly, you simply restrain ${him2} and administer a massive dose of vasodilators, directly where they will do the most good. ${impregnatrix.slaveName} writhes with the pain of the injection, which is compounded as ${he2} springs agonizingly erect.`);
+	}
 
-		const {
-			himP
-		} = getPronouns(V.PC).appendSuffix("P");
+	r.toParagraph();
 
-		r.push(`The first necessary step is to prepare the donatrix.`);
-		addPartner(slave, impregnatrix);
-		const belly = bellyAdjective(slave);
-		const superfetation = (slave.geneticQuirks.superfetation === 2 && slave.pregKnown === 1) ? 1 : 0;
-		const penCountBonus = random(6, 20);
-		const analCountBonus = penCountBonus;
-		const vagCountBonus = penCountBonus;
-		impregnatrix.counter.penetrative += penCountBonus + 1;
-		V.penetrativeTotal += penCountBonus + 1;
+	r.push(`Next, you see to ${slave.slaveName}.`);
 
-		const assPussy = (slave.mpreg === 1) ? `ass` : `pussy`;
-		const assCunt = (slave.mpreg === 1) ? `ass` : `cunt`;
-		const prostate = (impregnatrix.prostate !== 0) ? `prostate` : `internals`;
+	seX(slave, slave.mpreg ? "anal" : "vaginal", V.PC, "penetrative", penCountBonus);
 
-		if (impregnatrix.fetish === "pregnancy" && impregnatrix.fetishKnown === 1 && impregnatrix.fetishStrength > 60 && impregnatrix.devotion >= -20) {
-			r.push(`This is very easy, since ${impregnatrix.slaveName} has an impregnation fetish.`);
-			if (impregnatrix.pregKnown === 1) {
-				r.push(`${He2}'s pregnant, and as far as ${he2}'s concerned, everyone should be pregnant. ${He}'s <span class="hotpink">happy to spread the love.</span>`);
-			} else if (isFertile(impregnatrix)) {
-				r.push(`${He2}'d love to get pregnant ${himself2}, but as far as ${he2}'s concerned, putting a baby in someone else is the <span class="hotpink">next best thing.</span>`);
-			} else {
-				r.push(`${He2}'s been deeply unhappy that there's no prospect of ${him2} ever being able to carry a child, and this is the <span class="hotpink">next best thing</span> for ${him2}.`);
-			}
-			impregnatrix.devotion += 4;
-			if (impregnatrix.preg === -3) {
-				r.push(`${His2} member remains limp despite the prospect of getting another slave pregnant, but a direct injection of vasodilators quickly fixes that for this special occasion.`);
-			} else {
-				r.push(`${His2} member springs instantly to attention at the prospect of getting another slave pregnant.`);
-			}
-		} else if (impregnatrix.attrXX > 65 && impregnatrix.attrKnown === 1 && impregnatrix.devotion >= -20) {
-			r.push(`Since ${impregnatrix.slaveName} likes sticking ${his2} cock in girls, ${he2} doesn't take much convincing.`);
-			if (impregnatrix.preg === -3) {
-				r.push(`${His2} member remains limp despite the prospect of ${assPussy}, but a direct injection of vasodilators quickly fixes that for this special occasion.`);
-			} else {
-				r.push(`${His2} member springs instantly to attention at the prospect of pussy.`);
-			}
-		} else if (impregnatrix.devotion > 50) {
-			r.push(`Since ${impregnatrix.slaveName} is devoted to you, ${he2}'ll eagerly fuck anything you tell ${him2} to fuck.`);
-			if (impregnatrix.preg === -3) {
-				r.push(`${He2} accepts a direct injection of vasodilators to counteract the hormones keeping ${him2} soft,`);
-			} else {
-				r.push(`${He2} quickly gets ${himself2} hard,`);
-			}
-			r.push(`only a certain confusion in ${his2} look betraying that ${he2} realizes how special an occasion this is.`);
-		} else if (impregnatrix.devotion > 20) {
-			r.push(`Since ${impregnatrix.slaveName} is obedient, ${he2}'ll fuck anything you tell ${him2} to fuck.`);
-			if (impregnatrix.preg === -3) {
-				r.push(`${He2} accepts a direct injection of vasodilators to counteract the hormones keeping ${him2} soft,`);
-			} else {
-				r.push(`${He2} hurriedly gets ${himself2} hard,`);
-			}
-			r.push(`only a slight hesitation betraying ${his2} realization that this is a special occasion.`);
-		} else if (impregnatrix.devotion >= -20) {
-			r.push(`Since ${impregnatrix.slaveName} does not resist your will, ${he2} should comply reasonably well.`);
-			if (impregnatrix.preg === -3) {
-				r.push(`${He2} accepts a direct injection of vasodilators to counteract the hormones keeping ${him2} soft,`);
-			} else {
-				r.push(`${He2} has to work to get ${himself2} hard despite ${his2} doubts,`);
-			}
-			r.push(`fear and disgust showing on ${his2} face as ${he2} absorbs the perversion of the natural order of things ${he2}'s about to experience.`);
+	if ((slave.fetish === "pregnancy" && slave.fetishStrength > 60 && slave.fetishKnown === 1 && slave.vagina === 0) || (slave.anus === 0 && slave.mpreg === 1)) {
+		r.push(`${He} cries with joy and presents ${his} virgin ${assPussy} to ${impregnatrix.slaveName} for`);
+		if (superfetation === 1) {
+			r.push(`repeat`);
+		}
+		r.push(`fertilization. <span class="hotpink">${He} is grateful</span> for this fulfillment of ${his} fondest wish and naturally <span class="lime">will break in ${his} ${assPussy}.</span>`);
+		if (slave.mpreg === 1) {
+			slave.anus = 1;
 		} else {
-			r.push(`Since ${impregnatrix.slaveName} is unlikely to comply willingly, you simply restrain ${him2} and administer a massive dose of vasodilators, directly where they will do the most good. ${impregnatrix.slaveName} writhes with the pain of the injection, which is compounded as ${he2} springs agonizingly erect.`);
+			slave.vagina = 1;
 		}
-
-		r.toParagraph();
-
-		r.push(`Next, you see to ${slave.slaveName}.`);
-
+		slave.devotion += 10;
+	} else if (slave.fetish === "pregnancy" && slave.fetishStrength > 60 && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
+		r.push(`${He} cries with joy and presents ${his} fertile ${assPussy} to ${impregnatrix.slaveName} for`);
+		if (superfetation === 1) {
+			r.push(`further`);
+		}
+		r.push(`breeding. <span class="hotpink">${He} is grateful</span> for this fulfillment of ${his} fondest wish.`);
+		slave.devotion += 4;
+	} else if (slave.devotion > 20 && (slave.vagina === 0 || (slave.anus === 0 && slave.mpreg === 1))) {
+		r.push(`${He} accepts your orders without comment and presents ${his} virgin ${assPussy} to ${impregnatrix.slaveName} for fertilization. ${He} gasps in shock when ${he} feels ${his2} hot seed. <span class="hotpink">${He} is broken to slavery</span> by this application of ${his} body, which naturally <span class="lime">will break in ${his} ${assPussy}.</span>`);
 		if (slave.mpreg === 1) {
-			slave.counter.anal += analCountBonus + 1;
-			V.analTotal += analCountBonus + 1;
+			slave.anus = 1;
 		} else {
-			slave.counter.vaginal += vagCountBonus + 1;
-			V.vaginalTotal += vagCountBonus + 1;
+			slave.vagina = 1;
 		}
-
-		if ((slave.fetish === "pregnancy" && slave.fetishStrength > 60 && slave.fetishKnown === 1 && slave.vagina === 0) || (slave.anus === 0 && slave.mpreg === 1)) {
-			r.push(`${He} cries with joy and presents ${his} virgin ${assPussy} to ${impregnatrix.slaveName} for`);
-			if (superfetation === 1) {
-				r.push(`repeat`);
-			}
-			r.push(`fertilization. <span class="hotpink">${He} is grateful</span> for this fulfillment of ${his} fondest wish and naturally <span class="lime">will break in ${his} ${assPussy}.</span>`);
-			if (slave.mpreg === 1) {
-				slave.anus = 1;
-			} else {
-				slave.vagina = 1;
-			}
-			slave.devotion += 10;
-		} else if (slave.fetish === "pregnancy" && slave.fetishStrength > 60 && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
-			r.push(`${He} cries with joy and presents ${his} fertile ${assPussy} to ${impregnatrix.slaveName} for`);
-			if (superfetation === 1) {
-				r.push(`further`);
-			}
-			r.push(`breeding. <span class="hotpink">${He} is grateful</span> for this fulfillment of ${his} fondest wish.`);
-			slave.devotion += 4;
-		} else if (slave.devotion > 20 && (slave.vagina === 0 || (slave.anus === 0 && slave.mpreg === 1))) {
-			r.push(`${He} accepts your orders without comment and presents ${his} virgin ${assPussy} to ${impregnatrix.slaveName} for fertilization. ${He} gasps in shock when ${he} feels ${his2} hot seed. <span class="hotpink">${He} is broken to slavery</span> by this application of ${his} body, which naturally <span class="lime">will break in ${his} ${assPussy}.</span>`);
-			if (slave.mpreg === 1) {
-				slave.anus = 1;
-			} else {
-				slave.vagina = 1;
-			}
-			slave.devotion += 10;
-		} else if (slave.devotion >= -20 && (slave.vagina === 0 || (slave.anus === 0 && slave.mpreg === 1))) {
-			r.push(`${He} is clearly unhappy at the idea of losing ${his} pearl of great price to ${impregnatrix.slaveName}; this probably isn't what ${he} imagined ${his} first real sex would be like. Worse, ${he} knows ${he}'s fertile and realizes`);
-			if (superfetation === 1) {
-				r.push(`${his} existing pregnancy is of little concern to the new life likely to take root in ${him}.`);
-			} else {
-				r.push(`${he}'ll likely get pregnant.`);
-			}
-			r.push(`Nevertheless, <span class="hotpink">${he} is broken to slavery</span> by this application of ${his} body, which naturally <span class="lime">will break in ${his} ${assPussy}.</span>`);
-			if (slave.mpreg === 1) {
-				slave.anus = 1;
-			} else {
-				slave.vagina = 1;
-			}
-			slave.devotion += 4;
-		} else if (slave.vagina === 0 || (slave.anus === 0 && slave.mpreg === 1)) {
-			r.push(`As you anticipated, ${he} refuses to give ${impregnatrix.slaveName} ${his} virginity. You restrain ${him} despite ${his} <span class="mediumorchid">horrified tears</span> and <span class="gold">frightened begging.</span> Naturally, this cruel tableau <span class="lime">will break in ${his} ${assPussy}.</span>`);
-			slave.devotion -= 5;
-			slave.trust -= 5;
-			if (slave.mpreg === 1) {
-				slave.anus = 1;
-			} else {
-				slave.vagina = 1;
-			}
-		} else if (isAmputee(slave)) {
-			r.push(`You set ${his} limbless torso up for ${impregnatrix.slaveName}.`);
-		} else if (tooBigBelly(slave)) {
-			r.push(`You set ${him} up for ${impregnatrix.slaveName}, face-down so ${he} may rest helplessly against ${his} ${belly} belly.`);
-		} else if (tooBigBreasts(slave)) {
-			r.push(`You set ${him} up for ${impregnatrix.slaveName}, face-${(slave.belly >= 60000) ? `up` : `down`} so the weight of ${his} tits pins ${him} helplessly in place.`);
-		} else if (tooBigButt(slave)) {
-			r.push(`You set ${him} up for ${impregnatrix.slaveName}, face-down so the weight of ${his} giant ass pins ${him} helplessly in place and gives ${impregnatrix.slaveName} a lovely cushion to thrust against.`);
-		} else if (tooBigDick(slave)) {
-			r.push(`You set ${him} up for ${impregnatrix.slaveName}, face-up so ${he} is pinned under the weight of ${his} giant cock.`);
-		} else if (tooBigBalls(slave)) {
-			r.push(`You set ${him} up for ${impregnatrix.slaveName}, face-${(slave.belly >= 60000) ? `up` : `down`} so the weight of ${his} giant balls anchor ${him} helplessly in place.`);
-		} else if (slave.fetish === "submissive" && slave.fetishStrength > 60 && slave.fetishStrength > 60 && slave.fetishKnown === 1) {
-			r.push(`${He} is accustomed to submit to you, but as a natural submissive ${he} doesn't have much trouble submitting to ${impregnatrix.slaveName}'s seed instead.`);
-		} else if (slave.devotion < -20) {
-			r.push(`${He} tries to refuse, so you restrain ${him} despite ${his} resistance to the idea of being made a breeder.`);
-		} else if (slave.devotion <= 20) {
-			r.push(`${He} obeys your orders reluctantly, arranging ${himself} for ${(slave.mpreg === 1) ? `anal` : `vaginal`} sex despite ${his} obvious hesitation to be made a breeder.`);
-		} else if (slave.devotion < 10) {
-			r.push(`${He} obeys your orders, arranging ${himself} for ${(slave.mpreg === 1) ? `anal` : `vaginal`} sex despite ${his} slight hesitation at the idea of being made a breeder.`);
+		slave.devotion += 10;
+	} else if (slave.devotion >= -20 && (slave.vagina === 0 || (slave.anus === 0 && slave.mpreg === 1))) {
+		r.push(`${He} is clearly unhappy at the idea of losing ${his} pearl of great price to ${impregnatrix.slaveName}; this probably isn't what ${he} imagined ${his} first real sex would be like. Worse, ${he} knows ${he}'s fertile and realizes`);
+		if (superfetation === 1) {
+			r.push(`${his} existing pregnancy is of little concern to the new life likely to take root in ${him}.`);
+		} else {
+			r.push(`${he}'ll likely get pregnant.`);
+		}
+		r.push(`Nevertheless, <span class="hotpink">${he} is broken to slavery</span> by this application of ${his} body, which naturally <span class="lime">will break in ${his} ${assPussy}.</span>`);
+		if (slave.mpreg === 1) {
+			slave.anus = 1;
 		} else {
-			r.push(`${He} happily obeys your orders, getting ready to serve ${his} ${getWrittenTitle(slave)} by making ${himP} another slave.`);
+			slave.vagina = 1;
 		}
+		slave.devotion += 4;
+	} else if (slave.vagina === 0 || (slave.anus === 0 && slave.mpreg === 1)) {
+		r.push(`As you anticipated, ${he} refuses to give ${impregnatrix.slaveName} ${his} virginity. You restrain ${him} despite ${his} <span class="mediumorchid">horrified tears</span> and <span class="gold">frightened begging.</span> Naturally, this cruel tableau <span class="lime">will break in ${his} ${assPussy}.</span>`);
+		slave.devotion -= 5;
+		slave.trust -= 5;
+		if (slave.mpreg === 1) {
+			slave.anus = 1;
+		} else {
+			slave.vagina = 1;
+		}
+	} else if (isAmputee(slave)) {
+		r.push(`You set ${his} limbless torso up for ${impregnatrix.slaveName}.`);
+	} else if (tooBigBelly(slave)) {
+		r.push(`You set ${him} up for ${impregnatrix.slaveName}, face-down so ${he} may rest helplessly against ${his} ${belly} belly.`);
+	} else if (tooBigBreasts(slave)) {
+		r.push(`You set ${him} up for ${impregnatrix.slaveName}, face-${(slave.belly >= 60000) ? `up` : `down`} so the weight of ${his} tits pins ${him} helplessly in place.`);
+	} else if (tooBigButt(slave)) {
+		r.push(`You set ${him} up for ${impregnatrix.slaveName}, face-down so the weight of ${his} giant ass pins ${him} helplessly in place and gives ${impregnatrix.slaveName} a lovely cushion to thrust against.`);
+	} else if (tooBigDick(slave)) {
+		r.push(`You set ${him} up for ${impregnatrix.slaveName}, face-up so ${he} is pinned under the weight of ${his} giant cock.`);
+	} else if (tooBigBalls(slave)) {
+		r.push(`You set ${him} up for ${impregnatrix.slaveName}, face-${(slave.belly >= 60000) ? `up` : `down`} so the weight of ${his} giant balls anchor ${him} helplessly in place.`);
+	} else if (slave.fetish === "submissive" && slave.fetishStrength > 60 && slave.fetishStrength > 60 && slave.fetishKnown === 1) {
+		r.push(`${He} is accustomed to submit to you, but as a natural submissive ${he} doesn't have much trouble submitting to ${impregnatrix.slaveName}'s seed instead.`);
+	} else if (slave.devotion < -20) {
+		r.push(`${He} tries to refuse, so you restrain ${him} despite ${his} resistance to the idea of being made a breeder.`);
+	} else if (slave.devotion <= 20) {
+		r.push(`${He} obeys your orders reluctantly, arranging ${himself} for ${(slave.mpreg === 1) ? `anal` : `vaginal`} sex despite ${his} obvious hesitation to be made a breeder.`);
+	} else if (slave.devotion < 10) {
+		r.push(`${He} obeys your orders, arranging ${himself} for ${(slave.mpreg === 1) ? `anal` : `vaginal`} sex despite ${his} slight hesitation at the idea of being made a breeder.`);
+	} else {
+		r.push(`${He} happily obeys your orders, getting ready to serve ${his} ${getWrittenTitle(slave)} by making ${himP} another slave.`);
+	}
 
-		knockMeUp(slave, 100, 2, impregnatrix.ID);
+	knockMeUp(slave, 100, 2, impregnatrix.ID);
 
-		r.toParagraph();
+	r.toParagraph();
 
-		if (slave.devotion < -20 && impregnatrix.devotion < -20) {
-			r.push(`Since you have two restrained slaves, it's up to you to do all the work. You put ${slave.slaveName} on the couch with ${his} ${assPussy} available, and then maneuver ${impregnatrix.slaveName}'s dick into place. The two slaves make no further moves until you deal ${impregnatrix.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. After watching them mechanically go at it for a while, you stop ${impregnatrix.slaveName}, insert an electrostimulator up ${his2} rectum, and administer a shock to ${his2} ${prostate} that forces ${him2} to empty ${his2} nuts into ${slave.slaveName}. Both slaves <span class="mediumorchid">resent</span> what you made them do and <span class="gold">fear you</span> as a result.`);
-			slave.devotion -= 5;
-			slave.trust -= 5;
+	if (slave.devotion < -20 && impregnatrix.devotion < -20) {
+		r.push(`Since you have two restrained slaves, it's up to you to do all the work. You put ${slave.slaveName} on the couch with ${his} ${assPussy} available, and then maneuver ${impregnatrix.slaveName}'s dick into place. The two slaves make no further moves until you deal ${impregnatrix.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. After watching them mechanically go at it for a while, you stop ${impregnatrix.slaveName}, insert an electrostimulator up ${his2} rectum, and administer a shock to ${his2} ${prostate} that forces ${him2} to empty ${his2} nuts into ${slave.slaveName}. Both slaves <span class="mediumorchid">resent</span> what you made them do and <span class="gold">fear you</span> as a result.`);
+		slave.devotion -= 5;
+		slave.trust -= 5;
+		impregnatrix.devotion -= 5;
+		impregnatrix.trust -= 5;
+		seX(impregnatrix, "anal", V.PC);
+		V.analTotal += 1;
+		if (impregnatrix.anus === 0) {
+			r.push(`${impregnatrix.slaveName} would have been reluctant to <span class="lime">lose ${his2} anal virginity</span> in any case, but being assraped by a metal probe that shocked ${him2} into orgasm so that ${he2} would impregnate another slave is <span class="mediumorchid">a special level</span> of violation for ${him2}.`);
 			impregnatrix.devotion -= 5;
-			impregnatrix.trust -= 5;
-			impregnatrix.counter.anal += 1;
-			V.analTotal += 1;
-			if (impregnatrix.anus === 0) {
-				r.push(`${impregnatrix.slaveName} would have been reluctant to <span class="lime">lose ${his2} anal virginity</span> in any case, but being assraped by a metal probe that shocked ${him2} into orgasm so that ${he2} would impregnate another slave is <span class="mediumorchid">a special level</span> of violation for ${him2}.`);
-				impregnatrix.devotion -= 5;
-				impregnatrix.anus = 1;
-			}
-		} else if (impregnatrix.devotion < -20) {
-			r.push(`Since your semen donatrix is restrained, you order ${slave.slaveName} to present ${himself} on the couch, and then maneuver ${impregnatrix.slaveName}'s dick into place. ${slave.slaveName} does ${his} best to hump ${himself} against the unwilling cock until you deal ${impregnatrix.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. After watching ${him2} mechanically fuck for a while, you stop ${him2}, push an electrostimulator up ${his2} butt, and administer a shock to ${his2} ${prostate} that forces ${him2} to empty ${his2} nuts into ${slave.slaveName}. ${He} <span class="mediumorchid">resents</span> what you made ${him2} do and <span class="gold">fears you</span> as a result. Though ${slave.slaveName} accepts the situation, ${he} looks into ${impregnatrix.slaveName}'s eyes with obvious apology.`);
+			impregnatrix.anus = 1;
+		}
+	} else if (impregnatrix.devotion < -20) {
+		r.push(`Since your semen donatrix is restrained, you order ${slave.slaveName} to present ${himself} on the couch, and then maneuver ${impregnatrix.slaveName}'s dick into place. ${slave.slaveName} does ${his} best to hump ${himself} against the unwilling cock until you deal ${impregnatrix.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. After watching ${him2} mechanically fuck for a while, you stop ${him2}, push an electrostimulator up ${his2} butt, and administer a shock to ${his2} ${prostate} that forces ${him2} to empty ${his2} nuts into ${slave.slaveName}. ${He} <span class="mediumorchid">resents</span> what you made ${him2} do and <span class="gold">fears you</span> as a result. Though ${slave.slaveName} accepts the situation, ${he} looks into ${impregnatrix.slaveName}'s eyes with obvious apology.`);
+		impregnatrix.devotion -= 5;
+		impregnatrix.trust -= 5;
+		seX(impregnatrix, "anal", V.PC);
+		V.analTotal += 1;
+		if (impregnatrix.anus === 0) {
+			r.push(`${impregnatrix.slaveName} would have been reluctant to <span class="lime">lose ${his2} anal virginity</span> in any case, but being assraped by a metal probe that shocked ${him2} into orgasm so that ${he2} would impregnate another slave is <span class="mediumorchid">a special level</span> of violation for ${him2}.`);
 			impregnatrix.devotion -= 5;
-			impregnatrix.trust -= 5;
-			impregnatrix.counter.anal += 1;
-			V.analTotal += 1;
-			if (impregnatrix.anus === 0) {
-				r.push(`${impregnatrix.slaveName} would have been reluctant to <span class="lime">lose ${his2} anal virginity</span> in any case, but being assraped by a metal probe that shocked ${him2} into orgasm so that ${he2} would impregnate another slave is <span class="mediumorchid">a special level</span> of violation for ${him2}.`);
-				impregnatrix.devotion -= 5;
-				impregnatrix.anus = 1;
-			}
-		} else if (impregnatrix.fetish === "pregnancy" && impregnatrix.fetishStrength > 60 && impregnatrix.devotion > 20 && slave.devotion < -20) {
-			r.push(`You arrange ${slave.slaveName} on the couch with ${his} fertile pussy defenseless and available, and then tell the randy ${impregnatrix.slaveName} that it's all ${hers2}. The slave life has so affected ${impregnatrix.slaveName} that ${he2} is quite eager to rape another slave pregnant${(superfetation === 1) ? `, even more so since ${he} is already with child` : ``} to fulfill ${his2} desire to reproduce. ${He2} finishes with indecent speed and looks almost disappointed until you tell ${him2} to take ${his2} time and be thorough. By the end of the day ${slave.slaveName}'s ${assCunt} is dripping cum, to ${his} <span class="gold">horror</span> and <span class="mediumorchid">resentment,</span> while ${impregnatrix.slaveName} is lying next to ${him} on the couch in a state of obvious <span class="hotpink">satiation and bliss.</span> ${impregnatrix.slaveName} kisses ${slave.slaveName}'s ${belly} stomach and expresses the hope that ${he}'ll produce a good new slave.`);
-
-			slave.devotion -= 5;
-			slave.trust -= 5;
-			impregnatrix.devotion += 4;
-		} else if (impregnatrix.energy > 95 && impregnatrix.devotion > 20 && slave.devotion < -20) {
-			r.push(`You arrange ${slave.slaveName} on the couch with ${his} fertile ${assPussy} defenseless and available, and then tell the randy ${impregnatrix.slaveName} that it's all ${hers2}. The slave life has so affected ${impregnatrix.slaveName} that ${he2} is quite eager to rape another slave pregnant${(superfetation === 1) ? `, especially since ${he} is already with child` : ``}, just for the perverted novelty of the act. ${He2} blows ${his2} load with indecent speed and looks crushed until you tell ${him2} to take ${his2} time and be thorough. By the end of the day ${slave.slaveName}'s ${(slave.mpreg === 1) ? `anus` : `cunt`} is dripping cum, to ${his} <span class="gold">horror</span> and <span class="mediumorchid">resentment,</span> while ${impregnatrix.slaveName} is lying next to ${him} on the couch in a state of obvious <span class="hotpink">satiation and bliss.</span> ${impregnatrix.slaveName} kisses ${slave.slaveName}'s ${belly} stomach and expresses the hope that you'll let ${him2} do this again ${(superfetation === 1) ? `soon` : `sometime`}.`);
-			slave.devotion -= 5;
-			slave.trust -= 5;
-			impregnatrix.devotion += 4;
-		} else if (slave.devotion <= 20 || impregnatrix.devotion <= 20) {
-			r.push(`You order ${slave.slaveName} onto the couch and tell ${impregnatrix.slaveName} to get on with it. They fuck mechanically, gazing with roiling emotions into each others' eyes. They do seem to come to some sort of a nonverbal understanding on the necessity of getting it done, and there is no real unhappiness in either of them when they finish and disentangle themselves, with ${impregnatrix.slaveName}'s rapidly softening dick slipping easily out of ${slave.slaveName}'s cum-filled ${assPussy}.`);
-		} else if (slave.devotion <= 50 || impregnatrix.devotion <= 50) {
-			r.push(`You order ${slave.slaveName} and ${impregnatrix.slaveName} to get on with it. They fuck mechanically at first, gazing with roiling emotions into each others' eyes. Eventually, they begin to enjoy the extreme intimacy of the act, finding between themselves a hint of a life before slavery, when men and women had sex within the bonds of marriage for the purpose of procreation${(superfetation === 1) ? `, even though one of them is already heavy with child` : ``}. They finish and resume life as slaves, the light of this intimacy diminishing, softening with ${impregnatrix.slaveName}'s dick and dripping away with the contents of ${slave.slaveName}'s cum-filled ${assPussy}.`);
-		} else if (slave.mpreg === 1) {
-			r.push(`The parents-to-be need little encouragement. They embrace happily and turn eagerly to the business of anal sex in`);
-			if (slave.belly + impregnatrix.belly >= 5000) {
-				r.push(`an awkward`);
-			} else {
-				r.push(`the`);
-			}
-			r.push(`cowgirl position. They take their time, humping slowly and gazing into each others' eyes. After a little while, though, ${slave.slaveName} looks over to where you're sitting, the invitation clear in ${his} eyes. As soon as you stand to come over, ${slave.slaveName} turns around on ${impregnatrix.slaveName}'s cock and opens wide for you. You and ${impregnatrix.slaveName} enjoy the`);
-			if (superfetation === 1) {
-				r.push(`gravid ${girl}`);
-			} else {
-				r.push(`mother-to-be`);
-			}
-			r.push(`gently until ${he} climaxes, ${his} eager oral reaching a fever pitch, bringing you to your own climax.`);
-			if (V.PC.dick !== 0) {
-				if (canDoVaginal(impregnatrix)) {
-					r.push(`Pulling out, you flip them again so that ${impregnatrix.slaveName} is on top and switch to ${his2} pussy instead, stimulating ${his2} ${prostate} with a good fucking until ${he2} blows ${his2} load into ${slave.slaveName}'s fertile ${assCunt}. The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh with three loads inside them.`);
-					if (impregnatrix.vagina === 0) {
-						r.push(`${impregnatrix.slaveName} will certainly remember this <span class="hotpink">very special</span> day for many reasons, including it being ${his2} <span class="lime">first time</span> as ${he2} inseminated ${slave.slaveName}.`);
-						impregnatrix.devotion += 4;
-						impregnatrix.vagina = 1;
-					}
-					if (canImpreg(impregnatrix, V.PC)) {
-						knockMeUp(impregnatrix, 10, 0, -1);
-					}
-					impregnatrix.counter.vaginal += penCountBonus;
-					V.vaginalTotal += penCountBonus;
-				} else if (canDoAnal(impregnatrix)) {
-					r.push(`Pulling out, you flip them again so that ${impregnatrix.slaveName} is on top and switch to ${his2} ass instead, stimulating ${his2} ${prostate} with a good assfuck until ${he2} blows ${his2} load into ${slave.slaveName}'s fertile ${assCunt}. The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh with three loads inside them.`);
-					if (impregnatrix.anus === 0) {
-						r.push(`${impregnatrix.slaveName} will certainly remember this <span class="hotpink">very special</span> day for many reasons, including taking ${his2} <span class="lime">first buttfuck</span> as ${he2} inseminated ${slave.slaveName}.`);
-						impregnatrix.devotion += 4;
-						impregnatrix.anus = 1;
-					}
-					if (canImpreg(impregnatrix, V.PC)) {
-						knockMeUp(impregnatrix, 10, 1, -1);
-					}
-					impregnatrix.counter.anal += penCountBonus;
-					V.analTotal += penCountBonus;
-				} else {
-					r.push(`The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh.`);
-				}
-			} else {
-				if (canDoVaginal(impregnatrix)) {
-					r.push(`Pulling back, you flip them again so that ${impregnatrix.slaveName} is on top and don a strap-on. You begin stimulating ${his2} ${prostate} with a good fucking until ${he2} blows ${his2} load into ${slave.slaveName}'s fertile ${assCunt}. The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh.`);
-					if (impregnatrix.vagina === 0) {
-						r.push(`${impregnatrix.slaveName} will certainly remember this <span class="hotpink">very special</span> day for many reasons, including it being ${his2} <span class="lime">first time</span> as ${he2} inseminated ${slave.slaveName}.`);
-						impregnatrix.devotion += 4;
-						impregnatrix.vagina = 1;
-					}
-					impregnatrix.counter.vaginal += penCountBonus;
-					V.vaginalTotal += penCountBonus;
-				} else if (canDoAnal(impregnatrix)) {
-					r.push(`Pulling back, you flip them again so that ${impregnatrix.slaveName} is on top and don a strap-on. You begin stimulating ${his2} ${prostate} with a good assfuck until ${he2} blows ${his2} load into ${slave.slaveName}'s fertile ${assCunt}. The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh.`);
-					impregnatrix.counter.anal += penCountBonus;
-					V.analTotal += penCountBonus;
-					if (impregnatrix.anus === 0) {
-						r.push(`${impregnatrix.slaveName} will certainly remember this <span class="hotpink">very special</span> day for many reasons, including taking ${his2} <span class="lime">first buttfuck</span> as ${he2} inseminated ${slave.slaveName}.`);
-						impregnatrix.devotion += 4;
-						impregnatrix.anus = 1;
-					}
-				} else {
-					r.push(`The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh.`);
-				}
-			}
-			impregnatrix.counter.oral += penCountBonus;
-			V.oralTotal += penCountBonus;
-			slave.devotion += 4;
-			impregnatrix.devotion += 4;
+			impregnatrix.anus = 1;
+		}
+	} else if (impregnatrix.fetish === "pregnancy" && impregnatrix.fetishStrength > 60 && impregnatrix.devotion > 20 && slave.devotion < -20) {
+		r.push(`You arrange ${slave.slaveName} on the couch with ${his} fertile pussy defenseless and available, and then tell the randy ${impregnatrix.slaveName} that it's all ${hers2}. The slave life has so affected ${impregnatrix.slaveName} that ${he2} is quite eager to rape another slave pregnant${(superfetation === 1) ? `, even more so since ${he} is already with child` : ``} to fulfill ${his2} desire to reproduce. ${He2} finishes with indecent speed and looks almost disappointed until you tell ${him2} to take ${his2} time and be thorough. By the end of the day ${slave.slaveName}'s ${assCunt} is dripping cum, to ${his} <span class="gold">horror</span> and <span class="mediumorchid">resentment,</span> while ${impregnatrix.slaveName} is lying next to ${him} on the couch in a state of obvious <span class="hotpink">satiation and bliss.</span> ${impregnatrix.slaveName} kisses ${slave.slaveName}'s ${belly} stomach and expresses the hope that ${he}'ll produce a good new slave.`);
+
+		slave.devotion -= 5;
+		slave.trust -= 5;
+		impregnatrix.devotion += 4;
+	} else if (impregnatrix.energy > 95 && impregnatrix.devotion > 20 && slave.devotion < -20) {
+		r.push(`You arrange ${slave.slaveName} on the couch with ${his} fertile ${assPussy} defenseless and available, and then tell the randy ${impregnatrix.slaveName} that it's all ${hers2}. The slave life has so affected ${impregnatrix.slaveName} that ${he2} is quite eager to rape another slave pregnant${(superfetation === 1) ? `, especially since ${he} is already with child` : ``}, just for the perverted novelty of the act. ${He2} blows ${his2} load with indecent speed and looks crushed until you tell ${him2} to take ${his2} time and be thorough. By the end of the day ${slave.slaveName}'s ${(slave.mpreg === 1) ? `anus` : `cunt`} is dripping cum, to ${his} <span class="gold">horror</span> and <span class="mediumorchid">resentment,</span> while ${impregnatrix.slaveName} is lying next to ${him} on the couch in a state of obvious <span class="hotpink">satiation and bliss.</span> ${impregnatrix.slaveName} kisses ${slave.slaveName}'s ${belly} stomach and expresses the hope that you'll let ${him2} do this again ${(superfetation === 1) ? `soon` : `sometime`}.`);
+		slave.devotion -= 5;
+		slave.trust -= 5;
+		impregnatrix.devotion += 4;
+	} else if (slave.devotion <= 20 || impregnatrix.devotion <= 20) {
+		r.push(`You order ${slave.slaveName} onto the couch and tell ${impregnatrix.slaveName} to get on with it. They fuck mechanically, gazing with roiling emotions into each others' eyes. They do seem to come to some sort of a nonverbal understanding on the necessity of getting it done, and there is no real unhappiness in either of them when they finish and disentangle themselves, with ${impregnatrix.slaveName}'s rapidly softening dick slipping easily out of ${slave.slaveName}'s cum-filled ${assPussy}.`);
+	} else if (slave.devotion <= 50 || impregnatrix.devotion <= 50) {
+		r.push(`You order ${slave.slaveName} and ${impregnatrix.slaveName} to get on with it. They fuck mechanically at first, gazing with roiling emotions into each others' eyes. Eventually, they begin to enjoy the extreme intimacy of the act, finding between themselves a hint of a life before slavery, when men and women had sex within the bonds of marriage for the purpose of procreation${(superfetation === 1) ? `, even though one of them is already heavy with child` : ``}. They finish and resume life as slaves, the light of this intimacy diminishing, softening with ${impregnatrix.slaveName}'s dick and dripping away with the contents of ${slave.slaveName}'s cum-filled ${assPussy}.`);
+	} else if (slave.mpreg === 1) {
+		r.push(`The parents-to-be need little encouragement. They embrace happily and turn eagerly to the business of anal sex in`);
+		if (slave.belly + impregnatrix.belly >= 5000) {
+			r.push(`an awkward`);
 		} else {
-			let didImpregnatrix = 0;
-			r.push(`The parents-to-be need little encouragement. They embrace happily and turn eagerly to the business of vanilla sex in`);
-			if (slave.belly + impregnatrix.belly >= 5000) {
-				r.push(`an awkward`);
-			} else {
-				r.push(`the`);
-			}
-			r.push(`missionary position. They take their time, humping slowly and gazing into each others' eyes. After a little while, though, ${slave.slaveName} looks over ${impregnatrix.slaveName}'s shoulder to where you're sitting, the invitation clear in ${his} eyes. As soon as you stand to come over, they roll over without being ordered to`);
-			if (canDoAnal(slave)) {
-				r.push(`present ${slave.slaveName}'s butthole.`);
-
-				slave.counter.anal += penCountBonus;
-				V.analTotal += penCountBonus;
-			} else {
-				r.push(`invite you into ${slave.slaveName}'s crowded pussy.`);
-
-				slave.counter.vaginal += penCountBonus;
-				V.vaginalTotal += penCountBonus;
-			}
-			r.push(`You and ${impregnatrix.slaveName} double penetrate the`);
-			if (superfetation === 1) {
-				r.push(`gravid ${girl}`);
-			} else {
-				r.push(`mother-to-be`);
-			}
-			r.push(`gently until ${he} climaxes, clenching you to orgasm in turn with ${his} spasms. Pulling out, you offer`);
-			if (V.PC.dick !== 0) {
-				r.push(`yourself`);
-			} else {
-				r.push(`your strap-on`);
-			}
-			r.push(`to ${slave.slaveName}'s gasping mouth so ${he} can`);
-
-			if (V.PC.dick !== 0) {
-				r.push(`suck you hard again`);
-			} else {
-				r.push(`lube the phallus with some saliva`);
-			}
-			r.push(`as ${he} continues riding cock. Once`);
-			if (V.PC.dick !== 0) {
-				r.push(`stiff,`);
-			} else {
-				r.push(`the strap-on is nice and wet,`);
-			}
-			r.push(`you flip them again so that ${impregnatrix.slaveName} is back on top and switch to ${his2}`);
+			r.push(`the`);
+		}
+		r.push(`cowgirl position. They take their time, humping slowly and gazing into each others' eyes. After a little while, though, ${slave.slaveName} looks over to where you're sitting, the invitation clear in ${his} eyes. As soon as you stand to come over, ${slave.slaveName} turns around on ${impregnatrix.slaveName}'s cock and opens wide for you. You and ${impregnatrix.slaveName} enjoy the`);
+		if (superfetation === 1) {
+			r.push(`gravid ${girl}`);
+		} else {
+			r.push(`mother-to-be`);
+		}
+		r.push(`gently until ${he} climaxes, ${his} eager oral reaching a fever pitch, bringing you to your own climax.`);
+		if (V.PC.dick !== 0) {
 			if (canDoVaginal(impregnatrix)) {
-				r.push(`feminine slit instead, stimulating ${his2} ${prostate} with a hard fucking`);
-				didImpregnatrix = 1;
-			} else if (canDoAnal(impregnatrix)) {
-				r.push(`ass instead, stimulating ${his2} ${prostate} with a good assfuck`);
-				didImpregnatrix = 2;
-			} else {
-				r.push(`mouth instead, giving ${him2} a good facefuck`);
-				impregnatrix.counter.oral += penCountBonus;
-				V.oralTotal += penCountBonus;
-			}
-			r.push(`until ${he2} blows ${his2} load into ${slave.slaveName}'s fertile cunt. The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh with three loads inside them.`);
-			slave.devotion += 4;
-			impregnatrix.devotion += 4;
-			if (didImpregnatrix === 1) {
+				r.push(`Pulling out, you flip them again so that ${impregnatrix.slaveName} is on top and switch to ${his2} pussy instead, stimulating ${his2} ${prostate} with a good fucking until ${he2} blows ${his2} load into ${slave.slaveName}'s fertile ${assCunt}. The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh with three loads inside them.`);
 				if (impregnatrix.vagina === 0) {
-					r.push(`${impregnatrix.slaveName} will certainly remember this <span class="hotpink">very special</span> day for many reasons, including losing ${his2} <span class="lime">virginity</span> as ${he2} inseminated ${slave.slaveName}.`);
+					r.push(`${impregnatrix.slaveName} will certainly remember this <span class="hotpink">very special</span> day for many reasons, including it being ${his2} <span class="lime">first time</span> as ${he2} inseminated ${slave.slaveName}.`);
 					impregnatrix.devotion += 4;
 					impregnatrix.vagina = 1;
 				}
-				impregnatrix.counter.vaginal += penCountBonus;
-				V.vaginalTotal += penCountBonus;
 				if (canImpreg(impregnatrix, V.PC)) {
 					knockMeUp(impregnatrix, 10, 0, -1);
 				}
-			} else if (didImpregnatrix === 2) {
+				seX(impregnatrix, "vaginal", V.PC, "penetrative", penCountBonus);
+			} else if (canDoAnal(impregnatrix)) {
+				r.push(`Pulling out, you flip them again so that ${impregnatrix.slaveName} is on top and switch to ${his2} ass instead, stimulating ${his2} ${prostate} with a good assfuck until ${he2} blows ${his2} load into ${slave.slaveName}'s fertile ${assCunt}. The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh with three loads inside them.`);
 				if (impregnatrix.anus === 0) {
 					r.push(`${impregnatrix.slaveName} will certainly remember this <span class="hotpink">very special</span> day for many reasons, including taking ${his2} <span class="lime">first buttfuck</span> as ${he2} inseminated ${slave.slaveName}.`);
 					impregnatrix.devotion += 4;
 					impregnatrix.anus = 1;
 				}
-				impregnatrix.counter.anal += penCountBonus;
-				V.analTotal += penCountBonus;
 				if (canImpreg(impregnatrix, V.PC)) {
 					knockMeUp(impregnatrix, 10, 1, -1);
 				}
+				seX(impregnatrix, "anal", V.PC, "penetrative", penCountBonus);
+			} else {
+				r.push(`The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh.`);
 			}
-			if (slave.anus === 0 && canDoAnal(slave)) {
-				r.push(`${slave.slaveName}`);
-				r.push(`has been used as a slave in a truly thorough way today: ${he} has <span class="hotpink">accepted</span> both ${his} <span class="lime">first anal</span> and insemination by ${impregnatrix.slaveName}.`);
-				slave.devotion += 4;
-				slave.anus = 1;
+		} else {
+			if (canDoVaginal(impregnatrix)) {
+				r.push(`Pulling back, you flip them again so that ${impregnatrix.slaveName} is on top and don a strap-on. You begin stimulating ${his2} ${prostate} with a good fucking until ${he2} blows ${his2} load into ${slave.slaveName}'s fertile ${assCunt}. The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh.`);
+				if (impregnatrix.vagina === 0) {
+					r.push(`${impregnatrix.slaveName} will certainly remember this <span class="hotpink">very special</span> day for many reasons, including it being ${his2} <span class="lime">first time</span> as ${he2} inseminated ${slave.slaveName}.`);
+					impregnatrix.devotion += 4;
+					impregnatrix.vagina = 1;
+				}
+				seX(impregnatrix, "vaginal", V.PC, "penetrative", penCountBonus);
+			} else if (canDoAnal(impregnatrix)) {
+				r.push(`Pulling back, you flip them again so that ${impregnatrix.slaveName} is on top and don a strap-on. You begin stimulating ${his2} ${prostate} with a good assfuck until ${he2} blows ${his2} load into ${slave.slaveName}'s fertile ${assCunt}. The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh.`);
+				seX(impregnatrix, "anal", V.PC, "penetrative", penCountBonus);
+				if (impregnatrix.anus === 0) {
+					r.push(`${impregnatrix.slaveName} will certainly remember this <span class="hotpink">very special</span> day for many reasons, including taking ${his2} <span class="lime">first buttfuck</span> as ${he2} inseminated ${slave.slaveName}.`);
+					impregnatrix.devotion += 4;
+					impregnatrix.anus = 1;
+				}
+			} else {
+				r.push(`The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh.`);
 			}
 		}
+		seX(impregnatrix, "oral", V.PC, "penetrative", penCountBonus);
+		slave.devotion += 4;
+		impregnatrix.devotion += 4;
+	} else {
+		let didImpregnatrix = 0;
+		r.push(`The parents-to-be need little encouragement. They embrace happily and turn eagerly to the business of vanilla sex in`);
+		if (slave.belly + impregnatrix.belly >= 5000) {
+			r.push(`an awkward`);
+		} else {
+			r.push(`the`);
+		}
+		r.push(`missionary position. They take their time, humping slowly and gazing into each others' eyes. After a little while, though, ${slave.slaveName} looks over ${impregnatrix.slaveName}'s shoulder to where you're sitting, the invitation clear in ${his} eyes. As soon as you stand to come over, they roll over without being ordered to`);
+		if (canDoAnal(slave)) {
+			r.push(`present ${slave.slaveName}'s butthole.`);
+
+			seX(slave, "anal", V.PC, "penetrative", penCountBonus);
+		} else {
+			r.push(`invite you into ${slave.slaveName}'s crowded pussy.`);
 
-		r.push(`Throughout the week, you keep ${slave.slaveName}'s ${assPussy} intimate with ${impregnatrix.slaveName}'s cock. In the end, you are certain ${slave.slaveName}`);
+			seX(slave, "vaginal", V.PC, "penetrative", penCountBonus);
+		}
+		r.push(`You and ${impregnatrix.slaveName} double penetrate the`);
 		if (superfetation === 1) {
-			r.push(`has <span class="lime">added ${impregnatrix.slaveName}'s child</span> to ${his} pregnancy.`);
+			r.push(`gravid ${girl}`);
 		} else {
-			r.push(`is <span class="lime">carrying ${impregnatrix.slaveName}'s child.</span>`);
+			r.push(`mother-to-be`);
 		}
-
-		if (V.arcologies[0].FSRestart !== "unset" && V.eugenicsFullControl !== 1) {
-			r.push(`Rumors spread about you breeding your slaves; the Societal Elite are <span class="red">displeased</span> by these rumors.`);
-			V.failedElite += 1;
+		r.push(`gently until ${he} climaxes, clenching you to orgasm in turn with ${his} spasms. Pulling out, you offer`);
+		if (V.PC.dick !== 0) {
+			r.push(`yourself`);
+		} else {
+			r.push(`your strap-on`);
 		}
+		r.push(`to ${slave.slaveName}'s gasping mouth so ${he} can`);
 
-		if (V.arcologies[0].FSGenderRadicalist !== 'unset' && slave.mpreg) {
-			r.push(`Society <span class="reputation inc">approves</span> of your breeding your slave's ass; this advances the ideal all a slave needs is ${his} rear.`);
-			FutureSocieties.Change("FSGenderRadicalist", 1);
-		} else if (V.arcologies[0].FSGenderFundamentalist !== 'unset') {
-			if (slave.mpreg) {
-				r.push(`Society <span class="reputation dec">is disgusted</span> by this degenerate form of reproduction.`);
-				FutureSocieties.Change("FSGenderFundamentalist", -1);
-			} else {
-				r.push(`Society <span class="reputation inc">approves</span> of your breeding your slaves; this advances the ideal of a durable, self propagating race of slaves`);
-				FutureSocieties.Change("FSGenderFundamentalist", 1);
-			}
+		if (V.PC.dick !== 0) {
+			r.push(`suck you hard again`);
+		} else {
+			r.push(`lube the phallus with some saliva`);
 		}
-
-		r.toParagraph();
-
-		r.push(`You prepare the necessary file on their possible offspring. Upon birth, it will be remanded to a slave orphanage to be raised to the age of ${V.minimumSlaveAge} and then sold, but its likely appearance and traits are already worth noting. ${slave.slaveName} and ${impregnatrix.slaveName} are likely to produce`);
-
-		if (V.seeRace === 1) {
-			if (slave.race === "white" && impregnatrix.race === "white") {
-				r.push(`a pure white,`);
-			} else if (slave.race === "asian" && impregnatrix.race === "asian") {
-				r.push(`a pure Asian,`);
-			} else if (slave.race === "latina" && impregnatrix.race === "latina") {
-				r.push(`a pure latina,`);
-			} else if (slave.race === "black" && impregnatrix.race === "black") {
-				r.push(`a pure black,`);
-			} else if (slave.race === "middle eastern" && impregnatrix.race === "middle eastern") {
-				r.push(`a pure Middle Eastern,`);
-			} else if (slave.race === "malay" && impregnatrix.race === "malay") {
-				r.push(`a pure malay,`);
-			} else if (slave.race === "white" && impregnatrix.race === "black") {
-				r.push(`a mulatto,`);
-			} else if (slave.race === "black" && impregnatrix.race === "white") {
-				r.push(`a mulatto,`);
-			} else if (slave.race === "white" && impregnatrix.race === "latina") {
-				r.push(`a mestizo,`);
-			} else if (slave.race === "latina" && impregnatrix.race === "white") {
-				r.push(`a mestizo,`);
-			} else if (slave.race === "asian" && impregnatrix.race === "black") {
-				r.push(`an Afro-Asian,`);
-			} else if (slave.race === "black" && impregnatrix.race === "asian") {
-				r.push(`an Afro-Asian,`);
-			} else if (slave.race === "middle eastern" && impregnatrix.race === "black") {
-				r.push(`an Afro-Arab,`);
-			} else if (slave.race === "black" && impregnatrix.race === "middle eastern") {
-				r.push(`an Afro-Arab,`);
-			} else if (slave.race === "indo-aryan" && impregnatrix.race === "black") {
-				r.push(`an Afro-Indian,`);
-			} else if (slave.race === "black" && impregnatrix.race === "indo-aryan") {
-				r.push(`an Afro-Indian,`);
-			} else if (slave.race === "amerindian" && impregnatrix.race === "white") {
-				r.push(`a mestizo,`);
-			} else if (slave.race === "white" && impregnatrix.race === "amerindian") {
-				r.push(`a mestizo,`);
-			} else if (slave.race === "catgirl" || impregnatrix.race === "catgirl") {
-				r.push(`a catgirl,`);
-			} else if (slave.race === impregnatrix.race && slave.race !== "mixed race" && impregnatrix.race !== "mixed race") {
-				r.push(`an ethnically pure,`);
-			} else if (slave.race !== impregnatrix.race && slave.race !== "mixed race" && impregnatrix.race !== "mixed race") {
-				r.push(`a biracial,`);
-			} else {
-				r.push(`mixed ethnicity,`);
+		r.push(`as ${he} continues riding cock. Once`);
+		if (V.PC.dick !== 0) {
+			r.push(`stiff,`);
+		} else {
+			r.push(`the strap-on is nice and wet,`);
+		}
+		r.push(`you flip them again so that ${impregnatrix.slaveName} is back on top and switch to ${his2}`);
+		if (canDoVaginal(impregnatrix)) {
+			r.push(`feminine slit instead, stimulating ${his2} ${prostate} with a hard fucking`);
+			didImpregnatrix = 1;
+		} else if (canDoAnal(impregnatrix)) {
+			r.push(`ass instead, stimulating ${his2} ${prostate} with a good assfuck`);
+			didImpregnatrix = 2;
+		} else {
+			r.push(`mouth instead, giving ${him2} a good facefuck`);
+			seX(impregnatrix, "oral", V.PC, "penetrative", penCountBonus);
+		}
+		r.push(`until ${he2} blows ${his2} load into ${slave.slaveName}'s fertile cunt. The two of them collapse into an exhausted, <span class="hotpink">happy</span> pile of slave flesh with three loads inside them.`);
+		slave.devotion += 4;
+		impregnatrix.devotion += 4;
+		if (didImpregnatrix === 1) {
+			if (impregnatrix.vagina === 0) {
+				r.push(`${impregnatrix.slaveName} will certainly remember this <span class="hotpink">very special</span> day for many reasons, including losing ${his2} <span class="lime">virginity</span> as ${he2} inseminated ${slave.slaveName}.`);
+				impregnatrix.devotion += 4;
+				impregnatrix.vagina = 1;
+			}
+			seX(impregnatrix, "vaginal", V.PC, "penetrative", penCountBonus);
+			if (canImpreg(impregnatrix, V.PC)) {
+				knockMeUp(impregnatrix, 10, 0, -1);
+			}
+		} else if (didImpregnatrix === 2) {
+			if (impregnatrix.anus === 0) {
+				r.push(`${impregnatrix.slaveName} will certainly remember this <span class="hotpink">very special</span> day for many reasons, including taking ${his2} <span class="lime">first buttfuck</span> as ${he2} inseminated ${slave.slaveName}.`);
+				impregnatrix.devotion += 4;
+				impregnatrix.anus = 1;
+			}
+			seX(impregnatrix, "anal", V.PC, "penetrative", penCountBonus);
+			if (canImpreg(impregnatrix, V.PC)) {
+				knockMeUp(impregnatrix, 10, 1, -1);
 			}
 		}
-
-		if ((slave.intelligence + impregnatrix.intelligence) / 2 > 95) {
-			r.push(`brilliant,`);
-		} else if ((slave.intelligence + impregnatrix.intelligence) / 2 > 15) {
-			r.push(`smart,`);
-		} else if ((slave.intelligence + impregnatrix.intelligence) / 2 < -95) {
-			r.push(`cretinous,`);
-		} else if ((slave.intelligence + impregnatrix.intelligence) / 2 < -15) {
-			r.push(`stupid,`);
+		if (slave.anus === 0 && canDoAnal(slave)) {
+			r.push(`${slave.slaveName}`);
+			r.push(`has been used as a slave in a truly thorough way today: ${he} has <span class="hotpink">accepted</span> both ${his} <span class="lime">first anal</span> and insemination by ${impregnatrix.slaveName}.`);
+			slave.devotion += 4;
+			slave.anus = 1;
 		}
+	}
 
-		if ((slave.height + impregnatrix.height) > 185) {
-			r.push(`tall,`);
-		} else if ((slave.height + impregnatrix.height) < 160) {
-			r.push(`short,`);
-		} else {
-			r.push(`middle height,`);
-		}
+	r.push(`Throughout the week, you keep ${slave.slaveName}'s ${assPussy} intimate with ${impregnatrix.slaveName}'s cock. In the end, you are certain ${slave.slaveName}`);
+	if (superfetation === 1) {
+		r.push(`has <span class="lime">added ${impregnatrix.slaveName}'s child</span> to ${his} pregnancy.`);
+	} else {
+		r.push(`is <span class="lime">carrying ${impregnatrix.slaveName}'s child.</span>`);
+	}
 
-		if ((slave.boobs + impregnatrix.boobs - slave.boobsImplant - impregnatrix.boobsImplant - impregnatrix.boobsMilk) > 1500) {
-			r.push(`big-titted`);
-		} else if ((slave.boobs + impregnatrix.boobs - slave.boobsImplant - impregnatrix.boobsImplant - impregnatrix.boobsMilk) < 700) {
-			r.push(`flat-chested`);
+	if (V.arcologies[0].FSRestart !== "unset" && V.eugenicsFullControl !== 1) {
+		r.push(`Rumors spread about you breeding your slaves; the Societal Elite are <span class="red">displeased</span> by these rumors.`);
+		V.failedElite += 1;
+	}
+
+	if (V.arcologies[0].FSGenderRadicalist !== 'unset' && slave.mpreg) {
+		r.push(`Society <span class="reputation inc">approves</span> of your breeding your slave's ass; this advances the ideal all a slave needs is ${his} rear.`);
+		FutureSocieties.Change("FSGenderRadicalist", 1);
+	} else if (V.arcologies[0].FSGenderFundamentalist !== 'unset') {
+		if (slave.mpreg) {
+			r.push(`Society <span class="reputation dec">is disgusted</span> by this degenerate form of reproduction.`);
+			FutureSocieties.Change("FSGenderFundamentalist", -1);
 		} else {
-			r.push(`moderately-breasted`);
+			r.push(`Society <span class="reputation inc">approves</span> of your breeding your slaves; this advances the ideal of a durable, self propagating race of slaves`);
+			FutureSocieties.Change("FSGenderFundamentalist", 1);
 		}
+	}
 
-		if ((slave.butt + impregnatrix.butt - slave.buttImplant - impregnatrix.buttImplant) > 9) {
-			r.push(`slave with a huge ass.`);
-		} else if ((slave.butt + impregnatrix.butt - slave.buttImplant - impregnatrix.buttImplant) < 5) {
-			r.push(`slave with a flat ass.`);
+	r.toParagraph();
+
+	r.push(`You prepare the necessary file on their possible offspring. Upon birth, it will be remanded to a slave orphanage to be raised to the age of ${V.minimumSlaveAge} and then sold, but its likely appearance and traits are already worth noting. ${slave.slaveName} and ${impregnatrix.slaveName} are likely to produce`);
+
+	if (V.seeRace === 1) {
+		if (slave.race === "white" && impregnatrix.race === "white") {
+			r.push(`a pure white,`);
+		} else if (slave.race === "asian" && impregnatrix.race === "asian") {
+			r.push(`a pure Asian,`);
+		} else if (slave.race === "latina" && impregnatrix.race === "latina") {
+			r.push(`a pure latina,`);
+		} else if (slave.race === "black" && impregnatrix.race === "black") {
+			r.push(`a pure black,`);
+		} else if (slave.race === "middle eastern" && impregnatrix.race === "middle eastern") {
+			r.push(`a pure Middle Eastern,`);
+		} else if (slave.race === "malay" && impregnatrix.race === "malay") {
+			r.push(`a pure malay,`);
+		} else if (slave.race === "white" && impregnatrix.race === "black") {
+			r.push(`a mulatto,`);
+		} else if (slave.race === "black" && impregnatrix.race === "white") {
+			r.push(`a mulatto,`);
+		} else if (slave.race === "white" && impregnatrix.race === "latina") {
+			r.push(`a mestizo,`);
+		} else if (slave.race === "latina" && impregnatrix.race === "white") {
+			r.push(`a mestizo,`);
+		} else if (slave.race === "asian" && impregnatrix.race === "black") {
+			r.push(`an Afro-Asian,`);
+		} else if (slave.race === "black" && impregnatrix.race === "asian") {
+			r.push(`an Afro-Asian,`);
+		} else if (slave.race === "middle eastern" && impregnatrix.race === "black") {
+			r.push(`an Afro-Arab,`);
+		} else if (slave.race === "black" && impregnatrix.race === "middle eastern") {
+			r.push(`an Afro-Arab,`);
+		} else if (slave.race === "indo-aryan" && impregnatrix.race === "black") {
+			r.push(`an Afro-Indian,`);
+		} else if (slave.race === "black" && impregnatrix.race === "indo-aryan") {
+			r.push(`an Afro-Indian,`);
+		} else if (slave.race === "amerindian" && impregnatrix.race === "white") {
+			r.push(`a mestizo,`);
+		} else if (slave.race === "white" && impregnatrix.race === "amerindian") {
+			r.push(`a mestizo,`);
+		} else if (slave.race === "catgirl" || impregnatrix.race === "catgirl") {
+			r.push(`a catgirl,`);
+		} else if (slave.race === impregnatrix.race && slave.race !== "mixed race" && impregnatrix.race !== "mixed race") {
+			r.push(`an ethnically pure,`);
+		} else if (slave.race !== impregnatrix.race && slave.race !== "mixed race" && impregnatrix.race !== "mixed race") {
+			r.push(`a biracial,`);
 		} else {
-			r.push(`slave with a decent ass.`);
+			r.push(`mixed ethnicity,`);
 		}
+	}
+
+	if ((slave.intelligence + impregnatrix.intelligence) / 2 > 95) {
+		r.push(`brilliant,`);
+	} else if ((slave.intelligence + impregnatrix.intelligence) / 2 > 15) {
+		r.push(`smart,`);
+	} else if ((slave.intelligence + impregnatrix.intelligence) / 2 < -95) {
+		r.push(`cretinous,`);
+	} else if ((slave.intelligence + impregnatrix.intelligence) / 2 < -15) {
+		r.push(`stupid,`);
+	}
 
-		r.toParagraph();
-		return r.container();
+	if ((slave.height + impregnatrix.height) > 185) {
+		r.push(`tall,`);
+	} else if ((slave.height + impregnatrix.height) < 160) {
+		r.push(`short,`);
+	} else {
+		r.push(`middle height,`);
 	}
+
+	if ((slave.boobs + impregnatrix.boobs - slave.boobsImplant - impregnatrix.boobsImplant - impregnatrix.boobsMilk) > 1500) {
+		r.push(`big-titted`);
+	} else if ((slave.boobs + impregnatrix.boobs - slave.boobsImplant - impregnatrix.boobsImplant - impregnatrix.boobsMilk) < 700) {
+		r.push(`flat-chested`);
+	} else {
+		r.push(`moderately-breasted`);
+	}
+
+	if ((slave.butt + impregnatrix.butt - slave.buttImplant - impregnatrix.buttImplant) > 9) {
+		r.push(`slave with a huge ass.`);
+	} else if ((slave.butt + impregnatrix.butt - slave.buttImplant - impregnatrix.buttImplant) < 5) {
+		r.push(`slave with a flat ass.`);
+	} else {
+		r.push(`slave with a decent ass.`);
+	}
+
+	r.toParagraph();
+	return r.container();
 };
diff --git a/src/npc/interaction/passage/fSlaveSlaveAss.js b/src/npc/interaction/passage/fSlaveSlaveAss.js
index 2215b946ad51b345e2113083df759e79601cccc7..a9a66a751b21dd8b60e48cd374e6e42fe39edf41 100644
--- a/src/npc/interaction/passage/fSlaveSlaveAss.js
+++ b/src/npc/interaction/passage/fSlaveSlaveAss.js
@@ -1,467 +1,436 @@
+App.Interact.fSlaveSlaveAssChoosePartner = class extends App.Interact.BaseChoosePartnerRenderer {
+	constructor(slave) {
+		super(slave);
+		this.intro = `Select the slave that will fuck ${this.slave.slaveName}'s ass.`;
+		this.execute = App.Interact.fSlaveSlaveAss;
+	}
+
+	eligible(candidate) {
+		return isSlaveAvailable(candidate) && (canPenetrate(candidate) || candidate.clit >= 4);
+	}
+}
+
 /**
  * @param {App.Entity.SlaveState} slave
- * @returns {HTMLElement}
+ * @param {App.Entity.SlaveState} rapist
+ * @returns {DocumentFragment}
  */
-App.Interact.fSlaveSlaveAss = function(slave) {
-	const node = document.createElement("div");
+App.Interact.fSlaveSlaveAss = function(slave, rapist) {
+	const el = new DocumentFragment();
+	let r = [];
+	const {
+		He, His,
+		he, his, him, himself
+	} = getPronouns(slave);
 
-	App.UI.DOM.appendNewElement("div", node, `Select a slave that will fuck ${slave.slaveName}.`);
-	App.UI.DOM.appendNewElement("h2", node, `Select an eligible slave`);
+	const {
+		He2, His2,
+		he2, his2, him2, himself2, hers2, wife2
+	} = getPronouns(rapist).appendSuffix("2");
+	let incestMood;
 
-	const eligibles = V.slaves.filter((s) => (s.ID !== slave.ID) && isSlaveAvailable(s) && (canPenetrate(s) || s.clit >= 4));
-	for (const eligible of eligibles) {
-		const div = App.UI.DOM.appendNewElement("div", node);
-		div.append(App.UI.DOM.link(
-			SlaveFullName(eligible),
-			() => {
-				App.UI.DOM.replace(node, content(eligible));
-			}
-		));
-		if (eligible.custom.label) {
-			App.UI.DOM.appendNewElement("span", div, ` ${eligible.custom.label}`, ["yellow", "bold"]);
-		}
-		if (totalRelatives(slave) > 0) {
-			const relTerm = relativeTerm(slave, eligible);
-			if (relTerm !== null) {
-				App.UI.DOM.appendNewElement("span", div, ` ${capFirstChar(relTerm)}`, "lightgreen");
-			}
-		}
-	}
-	if (eligibles.length === 0) {
-		App.UI.DOM.appendNewElement("div", node, `You have no slaves capable of this act.`, "note");
-	}
-	return node;
-	/**
-	 *
-	 * @param {App.Entity.SlaveState} rapist
-	 * @returns {DocumentFragment}
-	 */
-	function content(rapist) {
-		const el = new DocumentFragment();
-		let r = [];
-		const {
-			He, His,
-			he, his, him, himself
-		} = getPronouns(slave);
+	seX(slave, "anal", rapist, "penetrative");
 
-		const {
-			He2, His2,
-			he2, his2, him2, himself2, hers2, wife2
-		} = getPronouns(rapist).appendSuffix("2");
-		let incestMood;
+	let dickSize;
+	if (rapist.dick === 1) {
+		dickSize = "pathetic";
+	} else if (rapist.dick === 2) {
+		dickSize = "tiny";
+	} else if (rapist.dick === 3) {
+		dickSize = "average";
+	} else if (rapist.dick === 4) {
+		dickSize = "big";
+	} else if (rapist.dick === 5) {
+		dickSize = "huge";
+	} else if (rapist.dick === 6) {
+		dickSize = "gigantic";
+	} else if (rapist.dick === 7) {
+		dickSize = "titanic";
+	} else if (rapist.dick === 8) {
+		dickSize = "absurd";
+	} else if (rapist.dick === 9) {
+		dickSize = "inhuman";
+	} else {
+		dickSize = "obscene";
+	}
 
-		addPartner(slave, -1);
+	const isIncest = areRelated(slave, rapist);
 
-		slave.counter.anal += 1;
-		V.analTotal += 1;
-		rapist.counter.penetrative++;
-		V.penetrativeTotal++;
+	r.push(`You take a look at the slave you selected.`);
 
-		let dickSize;
-		if (rapist.dick === 1) {
-			dickSize = "pathetic";
-		} else if (rapist.dick === 2) {
-			dickSize = "tiny";
-		} else if (rapist.dick === 3) {
-			dickSize = "average";
-		} else if (rapist.dick === 4) {
-			dickSize = "big";
-		} else if (rapist.dick === 5) {
-			dickSize = "huge";
-		} else if (rapist.dick === 6) {
-			dickSize = "gigantic";
-		} else if (rapist.dick === 7) {
-			dickSize = "titanic";
-		} else if (rapist.dick === 8) {
-			dickSize = "absurd";
-		} else if (rapist.dick === 9) {
-			dickSize = "inhuman";
+	if (rapist.fetish === "dom" && rapist.fetishStrength > 20 && rapist.devotion >= -20) {
+		r.push(`Since ${rapist.slaveName} loves to dominate others it's not hard to get ${his2}`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} dick`);
 		} else {
-			dickSize = "obscene";
+			r.push(`massive clit`);
 		}
+		r.push(`ready. ${His2}`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} cock`);
+		} else {
+			r.push(`massive clit`);
+		}
+		r.push(`quickly swells to a throbbing erection at the prospect of forcing ${himself2} on another slave.`);
+	} else if (rapist.fetish === "sadist" && rapist.fetishStrength > 20 && rapist.devotion >= -20) {
+		r.push(`With the prospect of torturing another slave`);
+		if (rapist.dick > 0) {
+			r.push(`${his2} ${dickSize} cock swells to a throbbing erection in seconds.`);
+		} else {
+			r.push(`${his2} huge clit becomes fully engorged in seconds.`);
+		}
+	} else if ((rapist.fetish === "pregnancy" && rapist.fetishStrength > 20 && rapist.devotion >= -20) && rapist.dick > 0) {
+		r.push(`With the prospect of raping another slave bareback, ${his2} ${dickSize} cock swells to a throbbing erection in seconds.`);
+	} else if (rapist.attrXX > 65 && rapist.devotion >= -20) {
+		r.push(`Since ${rapist.slaveName} likes sticking ${his2}`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} penis`);
+		} else {
+			r.push(`massive clit`);
+		}
+		r.push(`in girls, ${he2} doesn't take much convincing.`);
+	} else if (rapist.devotion > 50) {
+		r.push(`Since ${rapist.slaveName} is devoted to you, ${he2}'ll eagerly fuck anything you tell ${him2} to fuck.`);
+	} else if (rapist.devotion > 20) {
+		r.push(`Since ${rapist.slaveName} is obedient, ${he2}'ll fuck anything you tell ${him2} to fuck.`);
+	} else if (rapist.devotion >= -20) {
+		r.push(`Since ${rapist.slaveName} does not resist your will, ${he2} should comply reasonably well. ${He2} has to work to get ${his2}`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} penis`);
+		} else {
+			r.push(`massive clit`);
+		}
+		r.push(`hard despite ${his2} doubts, visibly disturbed that you are ordering ${him2} to fuck someone for your entertainment.`);
+	} else {
+		r.push(`Since ${rapist.slaveName} is unlikely to comply willingly, you simply restrain ${him2} and administer a massive dose of vasodilators, directly where they will do the most good. ${rapist.slaveName} writhes with the pain of the injection, which is compounded as ${his2}`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} penis`);
+		} else {
+			r.push(`massive clit`);
+		}
+		r.push(`quickly reaches an agonizingly full erection.`);
+	}
 
-		const isIncest = areRelated(slave, rapist);
-
-		r.push(`You take a look at the slave you selected.`);
-
-		if (rapist.fetish === "dom" && rapist.fetishStrength > 20 && rapist.devotion >= -20) {
-			r.push(`Since ${rapist.slaveName} loves to dominate others it's not hard to get ${his2}`);
-			if (rapist.dick > 0) {
-				r.push(`${dickSize} dick`);
+	if (isIncest) {
+		r.push(`${rapist.slaveName} is well aware that ${he2} is about to rape`);
+		if (rapist.father === slave.ID && rapist.mother === slave.ID) {
+			r.push(`the slave that is both ${his2} mother and ${his2} father,`);
+		} else if (slave.mother === rapist.ID || slave.father === rapist.ID) {
+			r.push(`${his2} own ${relativeTerm(rapist, slave)},`);
+		} else if (rapist.mother === slave.ID) {
+			r.push(`${his2} own mother,`);
+		} else if (rapist.father === slave.ID) {
+			r.push(`the slave that fathered ${him2},`);
+		} else {
+			r.push(`${his2} ${relativeTerm(rapist, slave)},`);
+		}
+		if (rapist.sexualQuirk === "perverted" || rapist.behavioralQuirk === "sinful") {
+			if (rapist.energy > 60) {
+				r.push(`and seems quite aroused at just how`);
+				if (rapist.sexualQuirk === "perverted") {
+					r.push(`perverted`);
+				} else {
+					r.push(`sinful`);
+				}
+				r.push(`that is.`);
+				if (canSee(rapist)) {
+					r.push(`${rapist.slaveName}'s eyes seemed locked on ${slave.slaveName}'s inviting asshole, thoroughly aroused and waiting for your order.`);
+				}
 			} else {
-				r.push(`massive clit`);
+				r.push(`but despite ${his2} conflicted feelings ${his2} arousal is clear.`);
 			}
-			r.push(`ready. ${His2}`);
-			if (rapist.dick > 0) {
-				r.push(`${dickSize} cock`);
+			incestMood = "Top";
+		} else if (rapist.relationshipTarget === slave.ID && rapist.relationship > 2) {
+			r.push(`but since ${he2}'s already in a sexual relationship with ${him}, it's only special because ${his2} ${getWrittenTitle(rapist)} is watching.`);
+			incestMood = "Top";
+		} else {
+			if (rapist.devotion > 95) {
+				r.push(`but ${his2} deep acceptance of slavery means ${he2} can't help but be eager to please everyone involved with ${his2} performance.`);
+				incestMood = "Top";
+			} else if (rapist.devotion > 60) {
+				r.push(`but ${his2} experience as a slave means ${he2} can mostly ignore it and focus on sex.`);
 			} else {
-				r.push(`massive clit`);
+				r.push(`and is understandably disturbed.`);
 			}
-			r.push(`quickly swells to a throbbing erection at the prospect of forcing ${himself2} on another slave.`);
-		} else if (rapist.fetish === "sadist" && rapist.fetishStrength > 20 && rapist.devotion >= -20) {
-			r.push(`With the prospect of torturing another slave`);
-			if (rapist.dick > 0) {
-				r.push(`${his2} ${dickSize} cock swells to a throbbing erection in seconds.`);
+		}
+	}
+
+	App.Events.addParagraph(el, r);
+	r = [];
+
+	r.push(`Next, you see to ${slave.slaveName}.`);
+
+	if (isIncest) {
+		r.push(`${slave.slaveName} is fully naked and`);
+		if (canSee(slave)) {
+			r.push(`looking up at`);
+		} else {
+			r.push(`waiting in front of`);
+		}
+		if (slave.father === rapist.ID && slave.mother === rapist.ID) {
+			r.push(`the slave that is both ${his} mother and ${his} father,`);
+		} else if (rapist.mother === slave.ID || rapist.father === slave.ID) {
+			r.push(`${his} own ${relativeTerm(slave, rapist)},`);
+		} else if (slave.mother === rapist.ID) {
+			r.push(`${his} own mother,`);
+		} else if (slave.father === rapist.ID) {
+			r.push(`the slave that fathered ${him},`);
+		} else {
+			r.push(`${his} ${relativeTerm(slave, rapist)},`);
+		}
+		if (slave.sexualQuirk === "perverted" || slave.behavioralQuirk === "sinful") {
+			if (slave.energy > 60) {
+				r.push(`whose`);
+				if (rapist.dick > 0) {
+					r.push(`${dickSize} penis`);
+				} else {
+					r.push(`massive clit`);
+				}
+				r.push(`is standing firm above ${him}. ${He} seems indecently aroused, flushed and shivering in anticipation.`);
 			} else {
-				r.push(`${his2} huge clit becomes fully engorged in seconds.`);
+				r.push(`but despite ${his} conflicted feelings ${his} growing arousal is clear as ${he}`);
+				if (canSee(slave)) {
+					r.push(`stares at`);
+				} else {
+					r.push(`imagines`);
+				}
+				r.push(`the`);
+				if (rapist.dick > 0) {
+					r.push(`${dickSize} penis`);
+				} else {
+					r.push(`massive clit`);
+				}
+				r.push(`that's soon going inside ${him}.`);
 			}
-		} else if ((rapist.fetish === "pregnancy" && rapist.fetishStrength > 20 && rapist.devotion >= -20) && rapist.dick > 0) {
-			r.push(`With the prospect of raping another slave bareback, ${his2} ${dickSize} cock swells to a throbbing erection in seconds.`);
-		} else if (rapist.attrXX > 65 && rapist.devotion >= -20) {
-			r.push(`Since ${rapist.slaveName} likes sticking ${his2}`);
-			if (rapist.dick > 0) {
-				r.push(`${dickSize} penis`);
+			if (incestMood === "Top") {
+				incestMood = "Both";
 			} else {
-				r.push(`massive clit`);
+				incestMood = "Bottom";
 			}
-			r.push(`in girls, ${he2} doesn't take much convincing.`);
-		} else if (rapist.devotion > 50) {
-			r.push(`Since ${rapist.slaveName} is devoted to you, ${he2}'ll eagerly fuck anything you tell ${him2} to fuck.`);
-		} else if (rapist.devotion > 20) {
-			r.push(`Since ${rapist.slaveName} is obedient, ${he2}'ll fuck anything you tell ${him2} to fuck.`);
-		} else if (rapist.devotion >= -20) {
-			r.push(`Since ${rapist.slaveName} does not resist your will, ${he2} should comply reasonably well. ${He2} has to work to get ${his2}`);
-			if (rapist.dick > 0) {
-				r.push(`${dickSize} penis`);
+		} else if (slave.relationshipTarget === rapist.ID && slave.relationship > 2) {
+			r.push(`and seems calm and inviting to ${his}`);
+			if (slave.relationship === 3) {
+				r.push(`sex friend's`);
+			} else if (slave.relationship === 4) {
+				r.push(`lover's`);
 			} else {
-				r.push(`massive clit`);
+				r.push(`slave ${wife2}'s`);
 			}
-			r.push(`hard despite ${his2} doubts, visibly disturbed that you are ordering ${him2} to fuck someone for your entertainment.`);
-		} else {
-			r.push(`Since ${rapist.slaveName} is unlikely to comply willingly, you simply restrain ${him2} and administer a massive dose of vasodilators, directly where they will do the most good. ${rapist.slaveName} writhes with the pain of the injection, which is compounded as ${his2}`);
 			if (rapist.dick > 0) {
 				r.push(`${dickSize} penis`);
 			} else {
 				r.push(`massive clit`);
 			}
-			r.push(`quickly reaches an agonizingly full erection.`);
-		}
-
-		if (isIncest) {
-			r.push(`${rapist.slaveName} is well aware that ${he2} is about to rape`);
-			if (rapist.father === slave.ID && rapist.mother === slave.ID) {
-				r.push(`the slave that is both ${his2} mother and ${his2} father,`);
-			} else if (slave.mother === rapist.ID || slave.father === rapist.ID) {
-				r.push(`${his2} own ${relativeTerm(rapist, slave)},`);
-			} else if (rapist.mother === slave.ID) {
-				r.push(`${his2} own mother,`);
-			} else if (rapist.father === slave.ID) {
-				r.push(`the slave that fathered ${him2},`);
+			r.push(`that will be penetrating ${him}.`);
+			if (incestMood === "Top") {
+				incestMood = "Both";
 			} else {
-				r.push(`${his2} ${relativeTerm(rapist, slave)},`);
+				incestMood = "Bottom";
 			}
-			if (rapist.sexualQuirk === "perverted" || rapist.behavioralQuirk === "sinful") {
-				if (rapist.energy > 60) {
-					r.push(`and seems quite aroused at just how`);
-					if (rapist.sexualQuirk === "perverted") {
-						r.push(`perverted`);
-					} else {
-						r.push(`sinful`);
-					}
-					r.push(`that is.`);
-					if (canSee(rapist)) {
-						r.push(`${rapist.slaveName}'s eyes seemed locked on ${slave.slaveName}'s inviting asshole, thoroughly aroused and waiting for your order.`);
-					}
-				} else {
-					r.push(`but despite ${his2} conflicted feelings ${his2} arousal is clear.`);
-				}
-				incestMood = "Top";
-			} else if (rapist.relationshipTarget === slave.ID && rapist.relationship > 2) {
-				r.push(`but since ${he2}'s already in a sexual relationship with ${him}, it's only special because ${his2} ${getWrittenTitle(rapist)} is watching.`);
-				incestMood = "Top";
-			} else {
-				if (rapist.devotion > 95) {
-					r.push(`but ${his2} deep acceptance of slavery means ${he2} can't help but be eager to please everyone involved with ${his2} performance.`);
-					incestMood = "Top";
-				} else if (rapist.devotion > 60) {
-					r.push(`but ${his2} experience as a slave means ${he2} can mostly ignore it and focus on sex.`);
+		} else {
+			if (slave.devotion > 95) {
+				r.push(`and ${his} deep acceptance of ${his} status as a slave has ${him} staring`);
+				if (canSee(slave)) {
+					r.push(`at`);
 				} else {
-					r.push(`and is understandably disturbed.`);
+					r.push(`blindly towards`);
 				}
-			}
-		}
-
-		App.Events.addParagraph(el, r);
-		r = [];
-
-		r.push(`Next, you see to ${slave.slaveName}.`);
-
-		if (isIncest) {
-			r.push(`${slave.slaveName} is fully naked and`);
-			if (canSee(slave)) {
-				r.push(`looking up at`);
-			} else {
-				r.push(`waiting in front of`);
-			}
-			if (slave.father === rapist.ID && slave.mother === rapist.ID) {
-				r.push(`the slave that is both ${his} mother and ${his} father,`);
-			} else if (rapist.mother === slave.ID || rapist.father === slave.ID) {
-				r.push(`${his} own ${relativeTerm(slave, rapist)},`);
-			} else if (slave.mother === rapist.ID) {
-				r.push(`${his} own mother,`);
-			} else if (slave.father === rapist.ID) {
-				r.push(`the slave that fathered ${him},`);
-			} else {
-				r.push(`${his} ${relativeTerm(slave, rapist)},`);
-			}
-			if (slave.sexualQuirk === "perverted" || slave.behavioralQuirk === "sinful") {
-				if (slave.energy > 60) {
-					r.push(`whose`);
-					if (rapist.dick > 0) {
-						r.push(`${dickSize} penis`);
-					} else {
-						r.push(`massive clit`);
-					}
-					r.push(`is standing firm above ${him}. ${He} seems indecently aroused, flushed and shivering in anticipation.`);
+				r.push(`the`);
+				if (rapist.dick > 0) {
+					r.push(`${dickSize} penis`);
 				} else {
-					r.push(`but despite ${his} conflicted feelings ${his} growing arousal is clear as ${he}`);
-					if (canSee(slave)) {
-						r.push(`stares at`);
-					} else {
-						r.push(`imagines`);
-					}
-					r.push(`the`);
-					if (rapist.dick > 0) {
-						r.push(`${dickSize} penis`);
-					} else {
-						r.push(`massive clit`);
-					}
-					r.push(`that's soon going inside ${him}.`);
+					r.push(`massive clit`);
 				}
+				r.push(`above ${him} with a lusty smile.`);
 				if (incestMood === "Top") {
 					incestMood = "Both";
 				} else {
 					incestMood = "Bottom";
 				}
-			} else if (slave.relationshipTarget === rapist.ID && slave.relationship > 2) {
-				r.push(`and seems calm and inviting to ${his}`);
-				if (slave.relationship === 3) {
-					r.push(`sex friend's`);
-				} else if (slave.relationship === 4) {
-					r.push(`lover's`);
-				} else {
-					r.push(`slave ${wife2}'s`);
-				}
+			} else if (slave.devotion > 60) {
+				r.push(`and if ${he} focuses, ${he} can forget the`);
 				if (rapist.dick > 0) {
 					r.push(`${dickSize} penis`);
 				} else {
 					r.push(`massive clit`);
 				}
-				r.push(`that will be penetrating ${him}.`);
-				if (incestMood === "Top") {
-					incestMood = "Both";
-				} else {
-					incestMood = "Bottom";
-				}
+				r.push(`standing erect in front of ${him} belongs to someone related to ${him}.`);
 			} else {
-				if (slave.devotion > 95) {
-					r.push(`and ${his} deep acceptance of ${his} status as a slave has ${him} staring`);
-					if (canSee(slave)) {
-						r.push(`at`);
-					} else {
-						r.push(`blindly towards`);
-					}
-					r.push(`the`);
+				r.push(`and is understandably disturbed,`);
+				if (canSee(slave)) {
+					r.push(`eyes glued to the`);
 					if (rapist.dick > 0) {
 						r.push(`${dickSize} penis`);
 					} else {
 						r.push(`massive clit`);
 					}
-					r.push(`above ${him} with a lusty smile.`);
-					if (incestMood === "Top") {
-						incestMood = "Both";
-					} else {
-						incestMood = "Bottom";
-					}
-				} else if (slave.devotion > 60) {
-					r.push(`and if ${he} focuses, ${he} can forget the`);
+					r.push(`throbbing before ${him}.`);
+				} else if (canHear(slave)) {
+					r.push(`listening to the heavy breathing of ${his} relative whose`);
 					if (rapist.dick > 0) {
 						r.push(`${dickSize} penis`);
 					} else {
 						r.push(`massive clit`);
 					}
-					r.push(`standing erect in front of ${him} belongs to someone related to ${him}.`);
+					r.push(`will be entering ${him} soon.`);
 				} else {
-					r.push(`and is understandably disturbed,`);
-					if (canSee(slave)) {
-						r.push(`eyes glued to the`);
-						if (rapist.dick > 0) {
-							r.push(`${dickSize} penis`);
-						} else {
-							r.push(`massive clit`);
-						}
-						r.push(`throbbing before ${him}.`);
-					} else if (canHear(slave)) {
-						r.push(`listening to the heavy breathing of ${his} relative whose`);
-						if (rapist.dick > 0) {
-							r.push(`${dickSize} penis`);
-						} else {
-							r.push(`massive clit`);
-						}
-						r.push(`will be entering ${him} soon.`);
+					r.push(`imagining how the`);
+					if (rapist.dick > 0) {
+						r.push(`${dickSize} penis`);
 					} else {
-						r.push(`imagining how the`);
-						if (rapist.dick > 0) {
-							r.push(`${dickSize} penis`);
-						} else {
-							r.push(`massive clit`);
-						}
-						r.push(`of ${his} relative will feel inside ${him}`);
+						r.push(`massive clit`);
 					}
+					r.push(`of ${his} relative will feel inside ${him}`);
 				}
 			}
 		}
+	}
 
-		if (slave.fetish === "submissive" && slave.fetishStrength > 60 && slave.fetishKnown === 1 && slave.anus === 0) {
-			r.push(`${He} presents ${his} virgin asshole to ${rapist.slaveName} without protest. This act <span class="virginity loss"> breaks in ${his} asshole,</span> and <span class="hotpink">reminds ${him}</span> of ${his} status as a submissive slave.`);
-			slave.anus = 1;
-			slave.devotion += 4;
-			slave.fetishStrength += 1;
-		} else if (slave.fetish === "submissive" && slave.fetishStrength > 60 && slave.fetishKnown === 1) {
-			r.push(`${He} smiles as ${he} lays back and presents ${his} asshole to ${rapist.slaveName}. ${He} openly enjoys submitting ${himself} for others to make use of.`);
-		} else if ((slave.devotion > 20 && slave.anus === 0) ) {
-			r.push(`${He} accepts your orders without comment and presents ${his} virgin asshole to ${rapist.slaveName}. ${He} gasps in shock when ${he} feels the`);
-			if (rapist.dick > 0) {
-				r.push(`${dickSize} dick`);
-			} else {
-				r.push(`massive clit`);
-			}
-			r.push(`enter ${him}. <span class="hotpink">${He} is broken to slavery</span> by this application of ${his} body, which naturally <span class="virginity loss">will break in ${his} asshole.</span>`);
-			slave.anus = 1;
-			slave.devotion += 10;
-		} else if (slave.devotion >= -20 && slave.anus === 0) {
-			r.push(`${He} is clearly unhappy at the idea of losing ${his} pearl of great price to ${rapist.slaveName}; this probably isn't what ${he} imagined ${his} first real sexual encounter would be like. Nevertheless, ${he} is <span class="hotpink">broken to slavery</span> by this application of ${his} body, which naturally <span class="virginity loss">will break in ${his} asshole.</span>`);
-			slave.anus = 1;
-			slave.devotion += 4;
-		} else if (slave.anus === 0) {
-			r.push(`As you anticipated, ${he} refuses to give ${rapist.slaveName} ${his} virginity. Since ${he} is restrained, ${his} <span class="devotion dec">horrified tears</span> and <span class="trust dec">frightened begging</span> are ${his} only signs of rebellion. Naturally, this cruel act <span class="virginity loss">will break in ${his} asshole.</span>`);
-			slave.devotion -= 5;
-			slave.trust -= 5;
-			slave.anus = 1;
-		}
-
-		if (isAmputee(slave)) {
-			r.push(`You set ${his} limbless torso up for ${rapist.slaveName}.`);
-		} else if (tooBigBreasts(slave)) {
-			r.push(`You set ${him} up for ${rapist.slaveName}, face-down so the weight of ${his} tits pins ${him} helplessly in place.`);
-		} else if (tooBigButt(slave)) {
-			r.push(`You set ${him} up for ${rapist.slaveName}, face-down so the weight of ${his} giant ass pins ${him} helplessly in place and gives ${rapist.slaveName} a lovely cushion to thrust against.`);
-		} else if (tooBigDick(slave)) {
-			r.push(`You set ${him} up for ${rapist.slaveName}, face-up so ${he} is pinned under the weight of ${his} giant cock.`);
-		} else if (tooBigBalls(slave)) {
-			r.push(`You set ${him} up for ${rapist.slaveName}, face-down so the weight of ${his} giant balls anchor ${him} helplessly in place.`);
-		} else if (slave.devotion < -20) {
-			r.push(`${He} tries to refuse, so you restrain ${him} despite ${his} resistance to the idea of being raped by another slave.`);
-		} else if (slave.devotion <= 20) {
-			r.push(`${He} obeys your orders reluctantly, arranging ${himself} for anal sex despite ${his} obvious hesitation to be raped by another slave.`);
-		} else if (slave.devotion < 10) {
-			r.push(`${He} obeys your orders, arranging ${himself} for anal sex despite ${his} slight hesitation at the idea of being another's slave sex toy.`);
+	if (slave.fetish === "submissive" && slave.fetishStrength > 60 && slave.fetishKnown === 1 && slave.anus === 0) {
+		r.push(`${He} presents ${his} virgin asshole to ${rapist.slaveName} without protest. This act <span class="virginity loss"> breaks in ${his} asshole,</span> and <span class="hotpink">reminds ${him}</span> of ${his} status as a submissive slave.`);
+		slave.anus = 1;
+		slave.devotion += 4;
+		slave.fetishStrength += 1;
+	} else if (slave.fetish === "submissive" && slave.fetishStrength > 60 && slave.fetishKnown === 1) {
+		r.push(`${He} smiles as ${he} lays back and presents ${his} asshole to ${rapist.slaveName}. ${He} openly enjoys submitting ${himself} for others to make use of.`);
+	} else if ((slave.devotion > 20 && slave.anus === 0) ) {
+		r.push(`${He} accepts your orders without comment and presents ${his} virgin asshole to ${rapist.slaveName}. ${He} gasps in shock when ${he} feels the`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} dick`);
 		} else {
-			r.push(`${He} happily obeys your orders, getting ready to serve another slave.`);
+			r.push(`massive clit`);
 		}
+		r.push(`enter ${him}. <span class="hotpink">${He} is broken to slavery</span> by this application of ${his} body, which naturally <span class="virginity loss">will break in ${his} asshole.</span>`);
+		slave.anus = 1;
+		slave.devotion += 10;
+	} else if (slave.devotion >= -20 && slave.anus === 0) {
+		r.push(`${He} is clearly unhappy at the idea of losing ${his} pearl of great price to ${rapist.slaveName}; this probably isn't what ${he} imagined ${his} first real sexual encounter would be like. Nevertheless, ${he} is <span class="hotpink">broken to slavery</span> by this application of ${his} body, which naturally <span class="virginity loss">will break in ${his} asshole.</span>`);
+		slave.anus = 1;
+		slave.devotion += 4;
+	} else if (slave.anus === 0) {
+		r.push(`As you anticipated, ${he} refuses to give ${rapist.slaveName} ${his} virginity. Since ${he} is restrained, ${his} <span class="devotion dec">horrified tears</span> and <span class="trust dec">frightened begging</span> are ${his} only signs of rebellion. Naturally, this cruel act <span class="virginity loss">will break in ${his} asshole.</span>`);
+		slave.devotion -= 5;
+		slave.trust -= 5;
+		slave.anus = 1;
+	}
 
-		App.Events.addParagraph(el, r);
-		r = [];
+	if (isAmputee(slave)) {
+		r.push(`You set ${his} limbless torso up for ${rapist.slaveName}.`);
+	} else if (tooBigBreasts(slave)) {
+		r.push(`You set ${him} up for ${rapist.slaveName}, face-down so the weight of ${his} tits pins ${him} helplessly in place.`);
+	} else if (tooBigButt(slave)) {
+		r.push(`You set ${him} up for ${rapist.slaveName}, face-down so the weight of ${his} giant ass pins ${him} helplessly in place and gives ${rapist.slaveName} a lovely cushion to thrust against.`);
+	} else if (tooBigDick(slave)) {
+		r.push(`You set ${him} up for ${rapist.slaveName}, face-up so ${he} is pinned under the weight of ${his} giant cock.`);
+	} else if (tooBigBalls(slave)) {
+		r.push(`You set ${him} up for ${rapist.slaveName}, face-down so the weight of ${his} giant balls anchor ${him} helplessly in place.`);
+	} else if (slave.devotion < -20) {
+		r.push(`${He} tries to refuse, so you restrain ${him} despite ${his} resistance to the idea of being raped by another slave.`);
+	} else if (slave.devotion <= 20) {
+		r.push(`${He} obeys your orders reluctantly, arranging ${himself} for anal sex despite ${his} obvious hesitation to be raped by another slave.`);
+	} else if (slave.devotion < 10) {
+		r.push(`${He} obeys your orders, arranging ${himself} for anal sex despite ${his} slight hesitation at the idea of being another's slave sex toy.`);
+	} else {
+		r.push(`${He} happily obeys your orders, getting ready to serve another slave.`);
+	}
 
-		if (slave.devotion < -20 && rapist.devotion < -20) {
-			r.push(`Since you have two restrained slaves, it's up to you to do all the work. ${slave.slaveName} is tied up on the bed with ${his} asshole available, so you maneuver ${rapist.slaveName}'s`);
-			if (rapist.dick > 0) {
-				r.push(`${dickSize} dick`);
-			} else {
-				r.push(`strap-on`);
-			}
-			r.push(`into place. The two slaves make no further moves until you deal ${rapist.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. ${rapist.slaveName} starts moving very slowly, barely prodding. After watching them mechanically go at it for a while, you use your leg to suddenly push ${him2} deep into ${slave.slaveName}, fully hilting ${him2} in one motion. You occasionally prod them with an electrical jolt to keep them going at a faster pace. Both slaves resent what you made them do for you and fear you'll make them do it again.`);
-		} else if (rapist.devotion < -20) {
-			r.push(`Since your dick slave is restrained, you order ${slave.slaveName} to present ${himself} on the bed, and then maneuver ${rapist.slaveName}'s`);
-			if (rapist.dick > 0) {
-				r.push(`${dickSize} dick`);
-			} else {
-				r.push(`strap-on`);
-			}
-			r.push(`into place. ${slave.slaveName} does ${his} best to hump ${himself} against the unwilling cock until you deal ${rapist.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. ${He2} is still unenthusiastic, so you have ${him2} lie down and have ${slave.slaveName} ride ${himself} to orgasm. ${He2} resents what you made ${him2} do and fears you'll force ${him2} to do it again. Though ${slave.slaveName} accepts the situation, ${he} looks into ${rapist.slaveName}'s eyes with obvious apology.`);
-		} else if (rapist.fetish === "dom" && rapist.fetishStrength > 20 && rapist.devotion > 20) {
-			r.push(`${slave.slaveName} is tied and placed on the bed with ${his} asshole defenseless and available, and then you tell the randy ${rapist.slaveName} that it's all ${hers2}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to rape another slave for ${his2} pleasure. ${He2} penetrates ${him} immediately, fondling, pinching and licking while pistoning away, fully enjoying ${his2} dominant role, edging ${his2} poor toy again and again and making ${him} beg for release.`);
-			if (slave.fetish === "dom") {
-				if (slave.devotion < -20) {
-					r.push(`By the end of the day ${slave.slaveName}'s abused backdoor is`);
+	App.Events.addParagraph(el, r);
+	r = [];
 
-					if (rapist.dick > 0) {
-						r.push(`dripping with cum,`);
-					} else {
-						r.push(`overflowing with juices,`);
-					}
-					r.push(`leaving ${him} horrified and disgusted at ${his} lack of control.`);
-				} else {
-					r.push(`By the end of the day ${slave.slaveName}'s abused backdoor is`);
+	if (slave.devotion < -20 && rapist.devotion < -20) {
+		r.push(`Since you have two restrained slaves, it's up to you to do all the work. ${slave.slaveName} is tied up on the bed with ${his} asshole available, so you maneuver ${rapist.slaveName}'s`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} dick`);
+		} else {
+			r.push(`strap-on`);
+		}
+		r.push(`into place. The two slaves make no further moves until you deal ${rapist.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. ${rapist.slaveName} starts moving very slowly, barely prodding. After watching them mechanically go at it for a while, you use your leg to suddenly push ${him2} deep into ${slave.slaveName}, fully hilting ${him2} in one motion. You occasionally prod them with an electrical jolt to keep them going at a faster pace. Both slaves resent what you made them do for you and fear you'll make them do it again.`);
+	} else if (rapist.devotion < -20) {
+		r.push(`Since your dick slave is restrained, you order ${slave.slaveName} to present ${himself} on the bed, and then maneuver ${rapist.slaveName}'s`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} dick`);
+		} else {
+			r.push(`strap-on`);
+		}
+		r.push(`into place. ${slave.slaveName} does ${his} best to hump ${himself} against the unwilling cock until you deal ${rapist.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. ${He2} is still unenthusiastic, so you have ${him2} lie down and have ${slave.slaveName} ride ${himself} to orgasm. ${He2} resents what you made ${him2} do and fears you'll force ${him2} to do it again. Though ${slave.slaveName} accepts the situation, ${he} looks into ${rapist.slaveName}'s eyes with obvious apology.`);
+	} else if (rapist.fetish === "dom" && rapist.fetishStrength > 20 && rapist.devotion > 20) {
+		r.push(`${slave.slaveName} is tied and placed on the bed with ${his} asshole defenseless and available, and then you tell the randy ${rapist.slaveName} that it's all ${hers2}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to rape another slave for ${his2} pleasure. ${He2} penetrates ${him} immediately, fondling, pinching and licking while pistoning away, fully enjoying ${his2} dominant role, edging ${his2} poor toy again and again and making ${him} beg for release.`);
+		if (slave.fetish === "dom") {
+			if (slave.devotion < -20) {
+				r.push(`By the end of the day ${slave.slaveName}'s abused backdoor is`);
 
-					if (rapist.dick > 0) {
-						r.push(`dripping with cum,`);
-					} else {
-						r.push(`overflowing with juices,`);
-					}
-					r.push(`leaving ${him} annoyed at ${his} lack of control, though ${he} still somewhat enjoyed ${himself}.`);
+				if (rapist.dick > 0) {
+					r.push(`dripping with cum,`);
+				} else {
+					r.push(`overflowing with juices,`);
 				}
-			} else if (slave.fetish === "submissive") {
-				if (slave.devotion < -20) {
-					r.push(`By the end of the day ${slave.slaveName}'s abused backdoor is`);
+				r.push(`leaving ${him} horrified and disgusted at ${his} lack of control.`);
+			} else {
+				r.push(`By the end of the day ${slave.slaveName}'s abused backdoor is`);
 
-					if (rapist.dick > 0) {
-						r.push(`dripping with cum,`);
-					} else {
-						r.push(`overflowing with juices,`);
-					}
-					r.push(`leaving the submissive slave horrified that ${he} found the experience sexually satisfying.`);
+				if (rapist.dick > 0) {
+					r.push(`dripping with cum,`);
 				} else {
-					r.push(`By the end of the day ${slave.slaveName}'s abused backdoor is`);
-
-					if (rapist.dick > 0) {
-						r.push(`dripping with cum.`);
-					} else {
-						r.push(`overflowing with juices.`);
-					}
-					r.push(`This sexual encounter is everything ${he} dreamed of, leaving ${him} utterly satisfied.`);
+					r.push(`overflowing with juices,`);
 				}
+				r.push(`leaving ${him} annoyed at ${his} lack of control, though ${he} still somewhat enjoyed ${himself}.`);
 			}
-			r.push(`${rapist.slaveName} is lying next to ${him} on the bed in a state of obvious satiation and bliss.`);
-		} else if (rapist.energy > 95 && rapist.devotion > 20 && slave.devotion < -20) {
-			r.push(`${slave.slaveName} is tied and placed on the bed with ${his} asshole defenseless and available, and then you tell the randy ${rapist.slaveName} that it's all ${hers2}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to rape another slave, just for the perverted novelty of the act. ${His} high libido keeps ${him} going for a long time, bringing the helpless toy to one forced orgasm after another. By the end of the day ${slave.slaveName} is lying on the bed, all worn out, ${his} backdoor`);
-			if (rapist.dick > 0) {
-				r.push(`dripping with cum`);
-			} else {
-				r.push(`overflowing with juices`);
-			}
-			r.push(`to ${his} horror and resentment, while ${rapist.slaveName} is sleeping next to ${him} in a state of obvious satiation and bliss.`);
-		} else if (slave.devotion <= 20 || rapist.devotion <= 20) {
-			r.push(`You order ${slave.slaveName} onto the couch and tell ${rapist.slaveName} to get on with it. They fuck mechanically, gazing with roiling emotions into each others' eyes. They do seem to come to some sort of a non-verbal understanding on the necessity of getting it done, and there is no real unhappiness in either of them when they finish and disentangle themselves. As they clean themselves and exit, you notice ${rapist.slaveName} is looking a little more longingly at ${slave.slaveName}.`);
-		} else if (slave.devotion <= 50 || rapist.devotion <= 50) {
-			r.push(`You order ${slave.slaveName} and ${rapist.slaveName} to get on with it. They fuck mechanically at first, gazing with roiling emotions into each others' eyes. Eventually, they begin to enjoy the intimacy of the act, finding the shared pleasure between them comforting. They finish and resume life as slaves, the light of this intimacy diminishing, softening with rapist.slaveName's dick and dripping away with the contents of ${slave.slaveName}'s cum-filled asshole.`);
-		} else {
-			r.push(`The two slaves happily and eagerly get down to business. They take their time with foreplay, humping slowly and gazing into each others' eyes, exchanging kisses almost constantly. After a little while, ${slave.slaveName} looks over ${rapist.slaveName}'s shoulder to where you're sitting, the invitation clear in ${his} eyes. As soon as you stand to come over, they roll over without being ordered to`);
-			if (canDoAnal(slave) && slave.anus > 0) {
-				r.push(`present ${slave.slaveName}'s butthole.`);
+		} else if (slave.fetish === "submissive") {
+			if (slave.devotion < -20) {
+				r.push(`By the end of the day ${slave.slaveName}'s abused backdoor is`);
 
-				slave.counter.anal++;
-				V.analTotal++;
+				if (rapist.dick > 0) {
+					r.push(`dripping with cum,`);
+				} else {
+					r.push(`overflowing with juices,`);
+				}
+				r.push(`leaving the submissive slave horrified that ${he} found the experience sexually satisfying.`);
 			} else {
-				r.push(`invite you into ${slave.slaveName}'s crowded asshole.`);
+				r.push(`By the end of the day ${slave.slaveName}'s abused backdoor is`);
 
-				slave.counter.anal++;
-				V.analTotal++;
-			}
-			r.push(`You take up the offer and penetrate ${slave.slaveName} with your`);
-			if (V.PC.dick > 0) {
-				r.push(`dick.`);
-			} else {
-				r.push(`strap-on.`);
+				if (rapist.dick > 0) {
+					r.push(`dripping with cum.`);
+				} else {
+					r.push(`overflowing with juices.`);
+				}
+				r.push(`This sexual encounter is everything ${he} dreamed of, leaving ${him} utterly satisfied.`);
 			}
-			r.push(`With the added stimulus of penetrating a tight hole alongside ${his2} dear ${getWrittenTitle(rapist)}, ${rapist.slaveName} comes indecently hard, but no where near as hard as the completely overloaded ${slave.slaveName}. All of you collapse into an exhausted, happy pile of flesh.`);
 		}
-
-		if (canImpreg(slave, rapist)) {
-			knockMeUp(slave, 25, 0, rapist.ID);
+		r.push(`${rapist.slaveName} is lying next to ${him} on the bed in a state of obvious satiation and bliss.`);
+	} else if (rapist.energy > 95 && rapist.devotion > 20 && slave.devotion < -20) {
+		r.push(`${slave.slaveName} is tied and placed on the bed with ${his} asshole defenseless and available, and then you tell the randy ${rapist.slaveName} that it's all ${hers2}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to rape another slave, just for the perverted novelty of the act. ${His} high libido keeps ${him} going for a long time, bringing the helpless toy to one forced orgasm after another. By the end of the day ${slave.slaveName} is lying on the bed, all worn out, ${his} backdoor`);
+		if (rapist.dick > 0) {
+			r.push(`dripping with cum`);
+		} else {
+			r.push(`overflowing with juices`);
+		}
+		r.push(`to ${his} horror and resentment, while ${rapist.slaveName} is sleeping next to ${him} in a state of obvious satiation and bliss.`);
+	} else if (slave.devotion <= 20 || rapist.devotion <= 20) {
+		r.push(`You order ${slave.slaveName} onto the couch and tell ${rapist.slaveName} to get on with it. They fuck mechanically, gazing with roiling emotions into each others' eyes. They do seem to come to some sort of a non-verbal understanding on the necessity of getting it done, and there is no real unhappiness in either of them when they finish and disentangle themselves. As they clean themselves and exit, you notice ${rapist.slaveName} is looking a little more longingly at ${slave.slaveName}.`);
+	} else if (slave.devotion <= 50 || rapist.devotion <= 50) {
+		r.push(`You order ${slave.slaveName} and ${rapist.slaveName} to get on with it. They fuck mechanically at first, gazing with roiling emotions into each others' eyes. Eventually, they begin to enjoy the intimacy of the act, finding the shared pleasure between them comforting. They finish and resume life as slaves, the light of this intimacy diminishing, softening with rapist.slaveName's dick and dripping away with the contents of ${slave.slaveName}'s cum-filled asshole.`);
+	} else {
+		r.push(`The two slaves happily and eagerly get down to business. They take their time with foreplay, humping slowly and gazing into each others' eyes, exchanging kisses almost constantly. After a little while, ${slave.slaveName} looks over ${rapist.slaveName}'s shoulder to where you're sitting, the invitation clear in ${his} eyes. As soon as you stand to come over, they roll over without being ordered to`);
+		if (canDoAnal(slave) && slave.anus > 0) {
+			r.push(`present ${slave.slaveName}'s butthole.`);
+		} else {
+			r.push(`invite you into ${slave.slaveName}'s crowded asshole.`);
 		}
+		r.push(`You take up the offer and penetrate ${slave.slaveName} with your`);
+		if (V.PC.dick > 0) {
+			r.push(`dick.`);
+		} else {
+			r.push(`strap-on.`);
+		}
+		r.push(`With the added stimulus of penetrating a tight hole alongside ${his2} dear ${getWrittenTitle(rapist)}, ${rapist.slaveName} comes indecently hard, but no where near as hard as the completely overloaded ${slave.slaveName}. All of you collapse into an exhausted, happy pile of flesh.`);
+	}
 
-		App.Events.addParagraph(el, r);
-		return el;
+	seX(slave, "anal", rapist);
+
+	if (canImpreg(slave, rapist)) {
+		knockMeUp(slave, 25, 0, rapist.ID);
 	}
+
+	App.Events.addParagraph(el, r);
+	return el;
 };
diff --git a/src/npc/interaction/passage/fSlaveSlaveDick.js b/src/npc/interaction/passage/fSlaveSlaveDick.js
index c853c5804431ee5f1de7fd554c5e20f0ceb8d46c..347894c22c7aa1bbf2b58d9d697463b717a923df 100644
--- a/src/npc/interaction/passage/fSlaveSlaveDick.js
+++ b/src/npc/interaction/passage/fSlaveSlaveDick.js
@@ -1,1269 +1,1254 @@
+App.Interact.fSlaveSlaveDickChoosePartner = class extends App.Interact.BaseChoosePartnerRenderer {
+	constructor(slave) {
+		super(slave);
+		this.intro = `Select the slave that will ride ${this.slave.slaveName}.`;
+		this.execute = App.Interact.fSlaveSlaveDick;
+	}
+
+	eligible(candidate) {
+		/* amp-amp scene is not written */
+		return isSlaveAvailable(candidate) && canDoVaginal(candidate) && canStand(candidate);
+	}
+
+	renderDetail(candidate, container) {
+		if (canImpreg(candidate, this.slave)) {
+			App.UI.DOM.appendNewElement("span", container, ` Fertile`, ["green"]);
+		}
+	}
+};
+
 /**
- *
  * @param {App.Entity.SlaveState} slave
- * @returns {HTMLElement}
+ * @param {App.Entity.SlaveState} rapist
+ * @returns {DocumentFragment}
  */
-App.Interact.fSlaveSlaveDick = function(slave) {
-	const node = document.createElement("div");
+App.Interact.fSlaveSlaveDick = function(slave, rapist) {
+	const el = new DocumentFragment();
+	let r = [];
+	const {
+		He, His,
+		he, his, him, himself, hers
+	} = getPronouns(slave);
 
-	App.UI.DOM.appendNewElement("div", node, `Select a slave that will ride ${slave.slaveName}.`);
-	App.UI.DOM.appendNewElement("h2", node, `Select an eligible slave`);
+	const {
+		He2,
+		he2, his2, him2, himself2, hers2
+	} = getPronouns(rapist).appendSuffix("2");
+	let bottomDrugged;
+	let incestMood;
 
-	const eligibles = V.slaves.filter((s) => (s.ID !== slave.ID) && isSlaveAvailable(s) && canDoVaginal(s) && canStand(s) /* amp-amp scene is not written */);
-	for (const eligible of eligibles) {
-		const div = App.UI.DOM.appendNewElement("div", node);
-		div.append(App.UI.DOM.link(
-			SlaveFullName(eligible),
-			() => {
-				jQuery(node).empty().append(content(eligible));
-			}
-		));
-		if (eligible.custom.label) {
-			App.UI.DOM.appendNewElement("span", div, ` ${eligible.custom.label}`, ["yellow", "bold"]);
-		}
-		if (canImpreg(eligible, slave)) {
-			App.UI.DOM.appendNewElement("span", div, ` Fertile`, "green");
-		}
-		if (totalRelatives(slave) > 0) {
-			const relTerm = relativeTerm(slave, eligible);
-			if (relTerm !== null) {
-				App.UI.DOM.appendNewElement("span", div, ` ${capFirstChar(relTerm)}`, "lightgreen");
-			}
+	let dickSize;
+	if (slave.dick) {
+		if (slave.dick === 1) {
+			dickSize = "tiny";
+		} else if (slave.dick === 2) {
+			dickSize = "tiny";
+		} else if (slave.dick === 3) {
+			dickSize = "average";
+		} else if (slave.dick === 4) {
+			dickSize = "big";
+		} else if (slave.dick === 5) {
+			dickSize = "huge";
+		} else if (slave.dick === 6) {
+			dickSize = "gigantic";
+		} else if (slave.dick === 7) {
+			dickSize = "titanic";
+		} else if (slave.dick === 8) {
+			dickSize = "absurd";
+		} else if (slave.dick >= 9) {
+			dickSize = "inhuman";
 		}
 	}
-	if (eligibles.length === 0) {
-		App.UI.DOM.appendNewElement("div", node, `You have no slaves capable of this act.`, "note");
-	}
-	return node;
 
-	function content(rapist) {
-		const el = new DocumentFragment();
-		let r = [];
-		const {
-			He, His,
-			he, his, him, himself, hers
-		} = getPronouns(slave);
+	const isIncest = areRelated(slave, rapist);
 
-		const {
-			He2,
-			he2, his2, him2, himself2, hers2
-		} = getPronouns(rapist).appendSuffix("2");
-		let bottomDrugged;
-		let incestMood;
+	r.push(`You take a look at the bound cock toy.`);
 
-		let dickSize;
-		if (slave.dick) {
-			if (slave.dick === 1) {
-				dickSize = "tiny";
-			} else if (slave.dick === 2) {
-				dickSize = "tiny";
-			} else if (slave.dick === 3) {
-				dickSize = "average";
-			} else if (slave.dick === 4) {
-				dickSize = "big";
-			} else if (slave.dick === 5) {
-				dickSize = "huge";
-			} else if (slave.dick === 6) {
-				dickSize = "gigantic";
-			} else if (slave.dick === 7) {
-				dickSize = "titanic";
-			} else if (slave.dick === 8) {
-				dickSize = "absurd";
-			} else if (slave.dick >= 9) {
-				dickSize = "inhuman";
-			}
+	if (slave.fetish === "mindbroken" && slave.career !== "a dairy cow" && slave.career !== "a breeding bull") {
+		r.push(`Since ${slave.slaveName} is mentally broken, the restraints don't do anything but set the scene.`);
+	} else if (slave.devotion > 50) {
+		r.push(`Since ${slave.slaveName} is devoted, ${his} restraints are more for the show than for practical purposes.`);
+	} else if (slave.devotion > 20) {
+		r.push(`${slave.slaveName} is obedient but not devoted, so ${his} restraints are firm for ${his} own good.`);
+	} else {
+		r.push(`${slave.slaveName} is unlikely to comply willingly, and is tied down tight, unable to budge more than`);
+		if (V.showInches === 2) {
+			r.push(`an inch.`);
+		} else {
+			r.push(`a centimeter.`);
 		}
+	}
 
-		const isIncest = areRelated(slave, rapist);
-
-		r.push(`You take a look at the bound cock toy.`);
-
-		if (slave.fetish === "mindbroken" && slave.career !== "a dairy cow" && slave.career !== "a breeding bull") {
-			r.push(`Since ${slave.slaveName} is mentally broken, the restraints don't do anything but set the scene.`);
-		} else if (slave.devotion > 50) {
-			r.push(`Since ${slave.slaveName} is devoted, ${his} restraints are more for the show than for practical purposes.`);
-		} else if (slave.devotion > 20) {
-			r.push(`${slave.slaveName} is obedient but not devoted, so ${his} restraints are firm for ${his} own good.`);
+	if (isAmputee(slave)) {
+		r.push(`${His} limbless torso lies on the bed, ready for ${rapist.slaveName}.`);
+	} else if (tooBigBelly(slave)) {
+		r.push(`${His} huge belly will limit the number of possible positions for ${rapist.slaveName} to take ${him} in.`);
+	} else if (tooBigBreasts(slave)) {
+		r.push(`The weight of ${his} tits pins ${him} helplessly in place.`);
+	} else if (tooBigButt(slave)) {
+		r.push(`${His} huge ass pushes ${his} pelvis further up, making it look as if ${he}'s trying to fuck the air.`);
+	} else if (tooBigDick(slave)) {
+		r.push(`${His} huge cock is clearly going to be a challenge.`);
+	} else if (tooBigBalls(slave)) {
+		r.push(`${His} huge balls might get a bit in the way in this position.`);
+	} else if (tooFatSlave(slave)) {
+		r.push(`${His} huge gut threatens to envelope ${his}`);
+		if (slave.clit >= 4) {
+			r.push(`massive clit.`);
 		} else {
-			r.push(`${slave.slaveName} is unlikely to comply willingly, and is tied down tight, unable to budge more than`);
-			if (V.showInches === 2) {
-				r.push(`an inch.`);
-			} else {
-				r.push(`a centimeter.`);
-			}
+			r.push(`${dickSize} cock.`);
 		}
+	}
 
-		if (isAmputee(slave)) {
-			r.push(`${His} limbless torso lies on the bed, ready for ${rapist.slaveName}.`);
-		} else if (tooBigBelly(slave)) {
-			r.push(`${His} huge belly will limit the number of possible positions for ${rapist.slaveName} to take ${him} in.`);
-		} else if (tooBigBreasts(slave)) {
-			r.push(`The weight of ${his} tits pins ${him} helplessly in place.`);
-		} else if (tooBigButt(slave)) {
-			r.push(`${His} huge ass pushes ${his} pelvis further up, making it look as if ${he}'s trying to fuck the air.`);
-		} else if (tooBigDick(slave)) {
-			r.push(`${His} huge cock is clearly going to be a challenge.`);
-		} else if (tooBigBalls(slave)) {
-			r.push(`${His} huge balls might get a bit in the way in this position.`);
-		} else if (tooFatSlave(slave)) {
-			r.push(`${His} huge gut threatens to envelope ${his}`);
+	if (slave.fetish === "mindbroken" && slave.career !== "a dairy cow" && slave.career !== "a breeding bull") {
+		if (slave.energy > 40) {
+			r.push(`${slave.slaveName}`);
+			r.push(`is broken mentally, but has a serviceable libido. After a bit of stimulation ${he}'s good to go without any further reaction on ${his} own.`);
+		} else {
+			r.push(`${slave.slaveName}`);
+			r.push(`is broken mentally, and ${his} low libido prevents ${his}`);
 			if (slave.clit >= 4) {
-				r.push(`massive clit.`);
+				r.push(`massive clit`);
 			} else {
-				r.push(`${dickSize} cock.`);
+				r.push(`${dickSize} penis`);
 			}
+			r.push(`from becoming erect. A massive dose of vasodilators fixes this, and you think you see ${his} face twitch with the pain, but there is no further reaction.`);
 		}
-
-		if (slave.fetish === "mindbroken" && slave.career !== "a dairy cow" && slave.career !== "a breeding bull") {
-			if (slave.energy > 40) {
-				r.push(`${slave.slaveName}`);
-				r.push(`is broken mentally, but has a serviceable libido. After a bit of stimulation ${he}'s good to go without any further reaction on ${his} own.`);
+	} else if (slave.fetish === "mindbroken" && slave.career === "a dairy cow") {
+		if (slave.energy > 40) {
+			r.push(`${slave.slaveName}, as a good cow with a good libido, takes only a little fondling before ${his}`);
+			if (slave.clit >= 4) {
+				r.push(`massive clit`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				r.push(`is broken mentally, and ${his} low libido prevents ${his}`);
-				if (slave.clit >= 4) {
-					r.push(`massive clit`);
-				} else {
-					r.push(`${dickSize} penis`);
-				}
-				r.push(`from becoming erect. A massive dose of vasodilators fixes this, and you think you see ${his} face twitch with the pain, but there is no further reaction.`);
+				r.push(`${dickSize} penis`);
 			}
-		} else if (slave.fetish === "mindbroken" && slave.career === "a dairy cow") {
-			if (slave.energy > 40) {
-				r.push(`${slave.slaveName}, as a good cow with a good libido, takes only a little fondling before ${his}`);
-				if (slave.clit >= 4) {
-					r.push(`massive clit`);
-				} else {
-					r.push(`${dickSize} penis`);
-				}
-				r.push(`becomes erect. When you let go, ${he} gives a needy moo with a sad expression to ask you to keep going.`);
+			r.push(`becomes erect. When you let go, ${he} gives a needy moo with a sad expression to ask you to keep going.`);
+		} else {
+			r.push(`${slave.slaveName} may be a cow, but ${his} low libido keeps ${his} mostly soft despite plenty of fondling. You inject ${him} with vasodilators so ${his}`);
+			if (slave.clit >= 4) {
+				r.push(`massive clit`);
 			} else {
-				r.push(`${slave.slaveName} may be a cow, but ${his} low libido keeps ${his} mostly soft despite plenty of fondling. You inject ${him} with vasodilators so ${his}`);
-				if (slave.clit >= 4) {
-					r.push(`massive clit`);
-				} else {
-					r.push(`${dickSize} cock`);
-				}
-				r.push(`becomes erect, and ${he} moos in discomfort and struggles against ${his} restraints.`);
-				bottomDrugged = 1;
+				r.push(`${dickSize} cock`);
 			}
-		} else if (slave.fetish === "mindbroken" && slave.career === "a breeding bull") {
-			r.push(`${slave.slaveName}, as a good bull, was already erect while being tied down. It seems ${he} knows what's going to happen to ${him} soon. Maybe someone at the Cattle Ranch has been sampling their bulls?`);
-		} else {
-			if (slave.devotion >= -20) {
-				if (slave.energy > 40) {
-					if (slave.fetishKnown === 1) {
-						if (slave.fetish === "submissive") {
-							r.push(`${slave.slaveName}`);
-							r.push(`is a known sub, and seconds after ${he} is ordered to lie down to be restrained ${his}`);
-							if (slave.clit >= 4) {
-								r.push(`massive clit`);
-							} else {
-								r.push(`${dickSize} cock`);
-							}
-							r.push(`is erect. ${He} knows ${he}'s going to get used, and can't hide ${his} excitement.`);
-						} else if (slave.fetish === "dom") {
-							r.push(`${slave.slaveName} is a known dom, and needs some stimulation before ${his}`);
-							if (slave.clit >= 4) {
-								r.push(`massive clit`);
-							} else {
-								r.push(`${dickSize} cock`);
-							}
-							r.push(`becomes hard. Despite knowing ${he}'s going to be used, ${he} can't hide ${his} curiosity to experience what the other side feels.`);
-						} else if (slave.fetish === "masochist") {
-							r.push(`${slave.slaveName} almost gets off on being tied down tight, sporting a`);
-							if (slave.clit >= 4) {
-								r.push(`massive clit`);
-							} else {
-								r.push(`${dickSize} erection`);
-							}
-							r.push(`once you have finished. ${His} nipples are firm as well, and ${he} struggles against ${his} restraints to feel them dig into ${him} tighter.`);
-						} else if (slave.fetish === "sadist") {
-							r.push(`${slave.slaveName} is a sadist, and finds ${himself} in the exact opposite position ${he}'d want to be in to get off. It's obvious ${he}'s not going to get aroused soon, so you inject ${him} with vasodilators so ${his}`);
-							if (slave.clit >= 4) {
-								r.push(`massive clit`);
-							} else {
-								r.push(`${dickSize} cock`);
-							}
-							r.push(`becomes erect and hope ${he} at least learns something from being on the receiving end for once.`);
-							bottomDrugged = 1;
-						} else if (slave.fetish === "humiliation") {
-							r.push(`${slave.slaveName} gets off on humiliation, and after being ordered to lay naked on a bed to be tied down, becomes flushed with arousal with ${his}`);
-							if (slave.clit >= 4) {
-								r.push(`massive clit`);
-							} else {
-								r.push(`${dickSize} cock`);
-							}
-							r.push(`throbbing in anticipation at being used like a toy.`);
-						} else if (slave.fetish === "pregnancy" && V.arcologies[0].FSRepopulationFocus !== "unset" && canPenetrate(slave)) {
-							r.push(`${slave.slaveName} gets off thinking about pregnancy, and in your arcology most women are pregnant or fertile. ${He} knows someone's pussy will be around ${his} ${dickSize} cock soon, and is clearly lost in ${his} fantasies as ${his} cock swells to a throbbing erection.`);
-						}
-					} else if (slave.attrXX > 65) {
-						r.push(`${slave.slaveName} has a good sex drive and likes pussy, even before ${he}'s fully bound ${his}`);
+			r.push(`becomes erect, and ${he} moos in discomfort and struggles against ${his} restraints.`);
+			bottomDrugged = 1;
+		}
+	} else if (slave.fetish === "mindbroken" && slave.career === "a breeding bull") {
+		r.push(`${slave.slaveName}, as a good bull, was already erect while being tied down. It seems ${he} knows what's going to happen to ${him} soon. Maybe someone at the Cattle Ranch has been sampling their bulls?`);
+	} else {
+		if (slave.devotion >= -20) {
+			if (slave.energy > 40) {
+				if (slave.fetishKnown === 1) {
+					if (slave.fetish === "submissive") {
+						r.push(`${slave.slaveName}`);
+						r.push(`is a known sub, and seconds after ${he} is ordered to lie down to be restrained ${his}`);
 						if (slave.clit >= 4) {
 							r.push(`massive clit`);
 						} else {
 							r.push(`${dickSize} cock`);
 						}
-						r.push(`is throbbing in anticipation.`);
-					} else {
-						r.push(`Despite ${his} adequate sex drive, since ${slave.slaveName} isn't turned on by the prospect of pussy, ${he} takes some manual stimulation before ${his}`);
+						r.push(`is erect. ${He} knows ${he}'s going to get used, and can't hide ${his} excitement.`);
+					} else if (slave.fetish === "dom") {
+						r.push(`${slave.slaveName} is a known dom, and needs some stimulation before ${his}`);
 						if (slave.clit >= 4) {
 							r.push(`massive clit`);
 						} else {
 							r.push(`${dickSize} cock`);
 						}
-						r.push(`stands erect.`);
-					}
-				} else {
-					if (slave.attrXX > 65) {
-						r.push(`${slave.slaveName} isn't known for ${his} high libido, but since ${he} likes pussy all it takes is some teasing to get ${his}`);
+						r.push(`becomes hard. Despite knowing ${he}'s going to be used, ${he} can't hide ${his} curiosity to experience what the other side feels.`);
+					} else if (slave.fetish === "masochist") {
+						r.push(`${slave.slaveName} almost gets off on being tied down tight, sporting a`);
 						if (slave.clit >= 4) {
 							r.push(`massive clit`);
 						} else {
-							r.push(`${dickSize} cock`);
+							r.push(`${dickSize} erection`);
 						}
-						r.push(`erect and ready.`);
-					} else {
-						r.push(`${slave.slaveName} doesn't have a high libido, and also isn't attracted to female slaves. A dose of vasodilators injected at the base of ${his}`);
+						r.push(`once you have finished. ${His} nipples are firm as well, and ${he} struggles against ${his} restraints to feel them dig into ${him} tighter.`);
+					} else if (slave.fetish === "sadist") {
+						r.push(`${slave.slaveName} is a sadist, and finds ${himself} in the exact opposite position ${he}'d want to be in to get off. It's obvious ${he}'s not going to get aroused soon, so you inject ${him} with vasodilators so ${his}`);
 						if (slave.clit >= 4) {
 							r.push(`massive clit`);
 						} else {
 							r.push(`${dickSize} cock`);
 						}
-						r.push(`causes ${him} to quickly reach painful readiness, and the unnatural pain makes ${him} strain at ${his} bonds.`);
+						r.push(`becomes erect and hope ${he} at least learns something from being on the receiving end for once.`);
 						bottomDrugged = 1;
-					}
-				}
-			} else {
-				if (slave.energy > 60) {
-					if (slave.attrXX > 65) {
-						r.push(`Although ${slave.slaveName} does not like being a slave, ${his} high libido and love for pussy have ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} erection`);
-						}
-						r.push(`ready for sex despite ${his} negative feelings.`);
-					} else {
-						r.push(`${slave.slaveName} does not like being a slave, and isn't attracted to women, but with ${his} high libido all it takes is simple teasing for ${his}`);
+					} else if (slave.fetish === "humiliation") {
+						r.push(`${slave.slaveName} gets off on humiliation, and after being ordered to lay naked on a bed to be tied down, becomes flushed with arousal with ${his}`);
 						if (slave.clit >= 4) {
 							r.push(`massive clit`);
 						} else {
 							r.push(`${dickSize} cock`);
 						}
-						r.push(`to be ready for sex.`);
+						r.push(`throbbing in anticipation at being used like a toy.`);
+					} else if (slave.fetish === "pregnancy" && V.arcologies[0].FSRepopulationFocus !== "unset" && canPenetrate(slave)) {
+						r.push(`${slave.slaveName} gets off thinking about pregnancy, and in your arcology most women are pregnant or fertile. ${He} knows someone's pussy will be around ${his} ${dickSize} cock soon, and is clearly lost in ${his} fantasies as ${his} cock swells to a throbbing erection.`);
+					}
+				} else if (slave.attrXX > 65) {
+					r.push(`${slave.slaveName} has a good sex drive and likes pussy, even before ${he}'s fully bound ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} cock`);
+					}
+					r.push(`is throbbing in anticipation.`);
+				} else {
+					r.push(`Despite ${his} adequate sex drive, since ${slave.slaveName} isn't turned on by the prospect of pussy, ${he} takes some manual stimulation before ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} cock`);
+					}
+					r.push(`stands erect.`);
+				}
+			} else {
+				if (slave.attrXX > 65) {
+					r.push(`${slave.slaveName} isn't known for ${his} high libido, but since ${he} likes pussy all it takes is some teasing to get ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} cock`);
 					}
+					r.push(`erect and ready.`);
 				} else {
-					r.push(`${slave.slaveName} does not like being a slave, and without a high sex drive ${he} is able to resist stimulation and stay soft. A quick dose of vasodilators changes that, and ${he} moans in pain and struggles against ${his} bonds in vain as ${his}`);
+					r.push(`${slave.slaveName} doesn't have a high libido, and also isn't attracted to female slaves. A dose of vasodilators injected at the base of ${his}`);
 					if (slave.clit >= 4) {
 						r.push(`massive clit`);
 					} else {
 						r.push(`${dickSize} cock`);
 					}
-					r.push(`becomes painfully hard.`);
+					r.push(`causes ${him} to quickly reach painful readiness, and the unnatural pain makes ${him} strain at ${his} bonds.`);
 					bottomDrugged = 1;
 				}
 			}
+		} else {
+			if (slave.energy > 60) {
+				if (slave.attrXX > 65) {
+					r.push(`Although ${slave.slaveName} does not like being a slave, ${his} high libido and love for pussy have ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} erection`);
+					}
+					r.push(`ready for sex despite ${his} negative feelings.`);
+				} else {
+					r.push(`${slave.slaveName} does not like being a slave, and isn't attracted to women, but with ${his} high libido all it takes is simple teasing for ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} cock`);
+					}
+					r.push(`to be ready for sex.`);
+				}
+			} else {
+				r.push(`${slave.slaveName} does not like being a slave, and without a high sex drive ${he} is able to resist stimulation and stay soft. A quick dose of vasodilators changes that, and ${he} moans in pain and struggles against ${his} bonds in vain as ${his}`);
+				if (slave.clit >= 4) {
+					r.push(`massive clit`);
+				} else {
+					r.push(`${dickSize} cock`);
+				}
+				r.push(`becomes painfully hard.`);
+				bottomDrugged = 1;
+			}
 		}
+	}
 
-		App.Events.addParagraph(el, r);
-		r = [];
+	App.Events.addParagraph(el, r);
+	r = [];
 
-		r.push(`You call ${rapist.slaveName} into the room.`);
+	r.push(`You call ${rapist.slaveName} into the room.`);
 
-		App.Events.addParagraph(el, r);
-		r = [];
+	App.Events.addParagraph(el, r);
+	r = [];
 
-		if (slave.fetish === "mindbroken" && slave.career !== "a dairy cow" && slave.career !== "a breeding bull") {
-			r.push(`${slave.slaveName} doesn't even notice`);
-			if (isIncest) {
-				if (slave.father === rapist.ID && slave.mother === rapist.ID) {
-					r.push(`the slave that is both ${his} mother and ${his} father,`);
-				} else if (rapist.mother === slave.ID || rapist.father === slave.ID) {
-					r.push(`${his} own ${relativeTerm(slave, rapist)},`);
-				} else if (slave.mother === rapist.ID) {
-					r.push(`${his} own mother,`);
-				} else if (slave.father === rapist.ID) {
-					r.push(`the slave that fathered ${him},`);
-				} else {
-					r.push(`${his} ${relativeTerm(slave, rapist)},`);
-				}
+	if (slave.fetish === "mindbroken" && slave.career !== "a dairy cow" && slave.career !== "a breeding bull") {
+		r.push(`${slave.slaveName} doesn't even notice`);
+		if (isIncest) {
+			if (slave.father === rapist.ID && slave.mother === rapist.ID) {
+				r.push(`the slave that is both ${his} mother and ${his} father,`);
+			} else if (rapist.mother === slave.ID || rapist.father === slave.ID) {
+				r.push(`${his} own ${relativeTerm(slave, rapist)},`);
+			} else if (slave.mother === rapist.ID) {
+				r.push(`${his} own mother,`);
+			} else if (slave.father === rapist.ID) {
+				r.push(`the slave that fathered ${him},`);
 			} else {
-				r.push(`the other slave,`);
+				r.push(`${his} ${relativeTerm(slave, rapist)},`);
 			}
-			r.push(`and simply lays still.`);
-		} else if (slave.fetish === "mindbroken" && (slave.career === "a dairy cow" || slave.career === "a breeding bull")) {
-			if (isIncest) {
-				r.push(`${slave.slaveName}'s simple mind does not even acknowledge that ${rapist.slaveName} is`);
-				if (slave.father === rapist.ID && slave.mother === rapist.ID) {
-					r.push(`the slave that is both ${his} mother and ${his} father,`);
-				} else if (rapist.mother === slave.ID || rapist.father === slave.ID) {
-					r.push(`${his} own ${relativeTerm(slave, rapist)},`);
-				} else if (slave.mother === rapist.ID) {
-					r.push(`${his} own mother,`);
-				} else if (slave.father === rapist.ID) {
-					r.push(`the slave that fathered ${him},`);
-				} else {
-					r.push(`${his} ${relativeTerm(slave, rapist)},`);
-				}
+		} else {
+			r.push(`the other slave,`);
+		}
+		r.push(`and simply lays still.`);
+	} else if (slave.fetish === "mindbroken" && (slave.career === "a dairy cow" || slave.career === "a breeding bull")) {
+		if (isIncest) {
+			r.push(`${slave.slaveName}'s simple mind does not even acknowledge that ${rapist.slaveName} is`);
+			if (slave.father === rapist.ID && slave.mother === rapist.ID) {
+				r.push(`the slave that is both ${his} mother and ${his} father,`);
+			} else if (rapist.mother === slave.ID || rapist.father === slave.ID) {
+				r.push(`${his} own ${relativeTerm(slave, rapist)},`);
+			} else if (slave.mother === rapist.ID) {
+				r.push(`${his} own mother,`);
+			} else if (slave.father === rapist.ID) {
+				r.push(`the slave that fathered ${him},`);
 			} else {
-				r.push(`${slave.slaveName}`);
-				if (canSee(slave)) {
-					r.push(`sees`);
-				} else if (canHear(slave)) {
-					r.push(`hears`);
-				} else {
-					r.push(`dimly acknowledges`);
-				}
-				r.push(`the newcomer, and with ${his} simple mind`);
+				r.push(`${his} ${relativeTerm(slave, rapist)},`);
 			}
-			r.push(`${he} only knows that they have a pussy and ${his}`);
-			if (slave.clit >= 4) {
-				r.push(`swollen clit`);
+		} else {
+			r.push(`${slave.slaveName}`);
+			if (canSee(slave)) {
+				r.push(`sees`);
+			} else if (canHear(slave)) {
+				r.push(`hears`);
 			} else {
-				r.push(`${dickSize} penis`);
+				r.push(`dimly acknowledges`);
 			}
-			r.push(`is erect. Naturally, ${he} seems quite eager to put them together.`);
-			incestMood = "Bottom";
+			r.push(`the newcomer, and with ${his} simple mind`);
+		}
+		r.push(`${he} only knows that they have a pussy and ${his}`);
+		if (slave.clit >= 4) {
+			r.push(`swollen clit`);
 		} else {
-			r.push(`${slave.slaveName} is fully naked and`);
-			if (canSee(slave)) {
-				r.push(`looking up at`);
+			r.push(`${dickSize} penis`);
+		}
+		r.push(`is erect. Naturally, ${he} seems quite eager to put them together.`);
+		incestMood = "Bottom";
+	} else {
+		r.push(`${slave.slaveName} is fully naked and`);
+		if (canSee(slave)) {
+			r.push(`looking up at`);
+		} else {
+			r.push(`waiting in front of`);
+		}
+		if (isIncest) {
+			if (slave.father === rapist.ID && slave.mother === rapist.ID) {
+				r.push(`the slave that is both ${his} mother and ${his} father,`);
+			} else if (rapist.mother === slave.ID || rapist.father === slave.ID) {
+				r.push(`${his} own ${relativeTerm(slave, rapist)},`);
+			} else if (slave.mother === rapist.ID) {
+				r.push(`${his} own mother,`);
+			} else if (slave.father === rapist.ID) {
+				r.push(`the slave that fathered ${him},`);
 			} else {
-				r.push(`waiting in front of`);
+				r.push(`${his} ${relativeTerm(slave, rapist)},`);
 			}
-			if (isIncest) {
-				if (slave.father === rapist.ID && slave.mother === rapist.ID) {
-					r.push(`the slave that is both ${his} mother and ${his} father,`);
-				} else if (rapist.mother === slave.ID || rapist.father === slave.ID) {
-					r.push(`${his} own ${relativeTerm(slave, rapist)},`);
-				} else if (slave.mother === rapist.ID) {
-					r.push(`${his} own mother,`);
-				} else if (slave.father === rapist.ID) {
-					r.push(`the slave that fathered ${him},`);
+			if (slave.sexualQuirk === "perverted" || slave.behavioralQuirk === "sinful") {
+				incestMood = "Bottom";
+				r.push(`unable to hide ${his} intense arousal at the impending`);
+				if (rapist.sexualQuirk === "perverted") {
+					r.push(`perverted`);
 				} else {
-					r.push(`${his} ${relativeTerm(slave, rapist)},`);
+					r.push(`sinful`);
+				}
+				r.push(`act.`);
+				if (canSee(slave)) {
+					r.push(`${His} eyes are locked on ${rapist.slaveName}'s pussy, and`);
 				}
-				if (slave.sexualQuirk === "perverted" || slave.behavioralQuirk === "sinful") {
+				r.push(`${rapist.slaveName} can hear ${him} moan in anticipation${(!canSee(slave)) ? ", which surprises the blind slave" : ""}.`);
+			} else if (slave.relationshipTarget === rapist.ID && slave.relationship > 2) {
+				incestMood = "Both";
+				r.push(`but since they're already in a sexual relationship, ${he} just shows a relaxed smile as ${he} waits for ${rapist.slaveName} to mount ${him}.`);
+			} else {
+				if (slave.devotion > 95) {
 					incestMood = "Bottom";
-					r.push(`unable to hide ${his} intense arousal at the impending`);
-					if (rapist.sexualQuirk === "perverted") {
-						r.push(`perverted`);
+					r.push(`but ${his} deep acceptance of slavery means ${he} is eager to please you,`);
+					if (slave.clit >= 4) {
+						r.push(`leaving ${his} massive clit flushed.`);
 					} else {
-						r.push(`sinful`);
+						r.push(`making ${his} ${dickSize} cock drip precum.`);
 					}
-					r.push(`act.`);
-					if (canSee(slave)) {
-						r.push(`${His} eyes are locked on ${rapist.slaveName}'s pussy, and`);
+				} else if (slave.devotion > 60) {
+					r.push(`and is clearly struggling between keeping ${himself} hard and acknowledging the incest. A small dose of vasodilators and ${his} impressive desire to please you should keep ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`clit`);
+					} else {
+						r.push(`penis`);
 					}
-					r.push(`${rapist.slaveName} can hear ${him} moan in anticipation${(!canSee(slave)) ? ", which surprises the blind slave" : ""}.`);
-				} else if (slave.relationshipTarget === rapist.ID && slave.relationship > 2) {
-					incestMood = "Both";
-					r.push(`but since they're already in a sexual relationship, ${he} just shows a relaxed smile as ${he} waits for ${rapist.slaveName} to mount ${him}.`);
+					r.push(`up for ${rapist.slaveName}.`);
+					incestMood = "BottomFragile";
 				} else {
-					if (slave.devotion > 95) {
-						incestMood = "Bottom";
-						r.push(`but ${his} deep acceptance of slavery means ${he} is eager to please you,`);
-						if (slave.clit >= 4) {
-							r.push(`leaving ${his} massive clit flushed.`);
-						} else {
-							r.push(`making ${his} ${dickSize} cock drip precum.`);
-						}
-					} else if (slave.devotion > 60) {
-						r.push(`and is clearly struggling between keeping ${himself} hard and acknowledging the incest. A small dose of vasodilators and ${his} impressive desire to please you should keep ${his}`);
+					if (!bottomDrugged) {
+						r.push(`and once it becomes clear to ${him} that ${rapist.slaveName} will be the one mounting ${him}, ${his}`);
 						if (slave.clit >= 4) {
-							r.push(`clit`);
+							r.push(`massive clit`);
 						} else {
-							r.push(`penis`);
+							r.push(`${dickSize} penis`);
 						}
-						r.push(`up for ${rapist.slaveName}.`);
-						incestMood = "BottomFragile";
+						r.push(`shrinks away. A direct injection of vasodilators changes that, bringing ${him} back to readiness to ${his} horror.`);
+						bottomDrugged = 1;
 					} else {
-						if (!bottomDrugged) {
-							r.push(`and once it becomes clear to ${him} that ${rapist.slaveName} will be the one mounting ${him}, ${his}`);
-							if (slave.clit >= 4) {
-								r.push(`massive clit`);
-							} else {
-								r.push(`${dickSize} penis`);
-							}
-							r.push(`shrinks away. A direct injection of vasodilators changes that, bringing ${him} back to readiness to ${his} horror.`);
-							bottomDrugged = 1;
+						r.push(`and to ${his} own horror the drugs ${he} was injected with keep ${his}`);
+						if (slave.clit >= 4) {
+							r.push(`massive clit`);
 						} else {
-							r.push(`and to ${his} own horror the drugs ${he} was injected with keep ${his}`);
-							if (slave.clit >= 4) {
-								r.push(`massive clit`);
-							} else {
-								r.push(`${dickSize} penis`);
-							}
-							r.push(`ready and waiting.`);
+							r.push(`${dickSize} penis`);
 						}
+						r.push(`ready and waiting.`);
 					}
 				}
-			} else {
-				if (slave.relationshipTarget === rapist.ID) {
-					r.push(`${his} ${relationshipTerm(rapist)},`);
-					if (slave.relationship > 2) {
-						r.push(`but since they're already in a sexual relationship, ${he} just shows a relaxed smile as ${he} waits for ${rapist.slaveName} to mount ${him}.`);
-					} else if (slave.partners.has(rapist.ID)) {
-						r.push(`but since they're already done it before, ${he} just shows a relaxed smile as ${he} waits for ${rapist.slaveName} to mount ${him}.`);
+			}
+		} else {
+			if (slave.relationshipTarget === rapist.ID) {
+				r.push(`${his} ${relationshipTerm(rapist)},`);
+				if (slave.relationship > 2) {
+					r.push(`but since they're already in a sexual relationship, ${he} just shows a relaxed smile as ${he} waits for ${rapist.slaveName} to mount ${him}.`);
+				} else if (slave.partners.has(rapist.ID)) {
+					r.push(`but since they're already done it before, ${he} just shows a relaxed smile as ${he} waits for ${rapist.slaveName} to mount ${him}.`);
+				} else {
+					r.push(`whom ${he} hasn't had sex with yet. ${He} smiles nervously as ${he} waits for ${rapist.slaveName} to mount ${him}.`);
+				}
+			} else if (slave.rivalryTarget === rapist.ID) {
+				r.push(`${his} ${rivalryTerm(rapist)}, ${rapist.slaveName}.`);
+				if (slave.partners.has(rapist.ID)) {
+					r.push(`They've already fucked in the past, and by ${his} reaction, unwillingly. A`);
+				} else {
+					r.push(`${He} doesn't much like what is to come, but a`);
+				}
+				r.push(`direct injection of vasodilators fixes that, forcing ${him} to readiness, much to ${his} chagrin.`);
+			} else if (slave.origBodyOwnerID === rapist.ID) {
+				r.push(`${rapist.slaveName}, who inhabits ${his} prior body.`);
+				if (slave.sexualQuirk === "perverted") {
+					r.push(`${He}'s enough of a pervert to get off over getting mounted by ${his} own form,`);
+					if (slave.clit >= 4) {
+						r.push(`leaving ${his} massive clit flushed.`);
 					} else {
-						r.push(`whom ${he} hasn't had sex with yet. ${He} smiles nervously as ${he} waits for ${rapist.slaveName} to mount ${him}.`);
+						r.push(`making ${his} ${dickSize} cock drip precum.`);
 					}
-				} else if (slave.rivalryTarget === rapist.ID) {
-					r.push(`${his} ${rivalryTerm(rapist)}, ${rapist.slaveName}.`);
-					if (slave.partners.has(rapist.ID)) {
-						r.push(`They've already fucked in the past, and by ${his} reaction, unwillingly. A`);
+				} else if (slave.devotion > 95) {
+					r.push(`${His} deep acceptance of slavery means ${he} is eager to please you,`);
+					if (slave.clit >= 4) {
+						r.push(`leaving ${his} massive clit flushed,`);
 					} else {
-						r.push(`${He} doesn't much like what is to come, but a`);
+						r.push(`making ${his} ${dickSize} cock drip precum,`);
 					}
-					r.push(`direct injection of vasodilators fixes that, forcing ${him} to readiness, much to ${his} chagrin.`);
-				} else if (slave.origBodyOwnerID === rapist.ID) {
-					r.push(`${rapist.slaveName}, who inhabits ${his} prior body.`);
-					if (slave.sexualQuirk === "perverted") {
-						r.push(`${He}'s enough of a pervert to get off over getting mounted by ${his} own form,`);
-						if (slave.clit >= 4) {
-							r.push(`leaving ${his} massive clit flushed.`);
-						} else {
-							r.push(`making ${his} ${dickSize} cock drip precum.`);
-						}
-					} else if (slave.devotion > 95) {
-						r.push(`${His} deep acceptance of slavery means ${he} is eager to please you,`);
+					r.push(`despite how odd it is to fuck one's own body.`);
+				} else if (slave.devotion > 60) {
+					r.push(`${He} is clearly struggling to keep ${himself} hard while acknowledging ${he} is expected to fuck ${his} former body. A small dose of vasodilators and ${his} impressive desire to please you should keep ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`clit`);
+					} else {
+						r.push(`penis`);
+					}
+					r.push(`at attention.`);
+				} else {
+					if (!bottomDrugged) {
+						r.push(`Once it becomes clear to ${him} that "${he}'ll" be the one mounting ${him}, ${his}`);
 						if (slave.clit >= 4) {
-							r.push(`leaving ${his} massive clit flushed,`);
+							r.push(`massive clit`);
 						} else {
-							r.push(`making ${his} ${dickSize} cock drip precum,`);
+							r.push(`${dickSize} penis`);
 						}
-						r.push(`despite how odd it is to fuck one's own body.`);
-					} else if (slave.devotion > 60) {
-						r.push(`${He} is clearly struggling to keep ${himself} hard while acknowledging ${he} is expected to fuck ${his} former body. A small dose of vasodilators and ${his} impressive desire to please you should keep ${his}`);
+						r.push(`shrinks away. A direct injection of vasodilators changes that, bringing ${him} back to readiness to ${his} horror.`);
+						bottomDrugged = 1;
+					} else {
+						r.push(`To ${his} own horror the drugs ${he} was injected with keep ${his}`);
 						if (slave.clit >= 4) {
-							r.push(`clit`);
+							r.push(`massive clit`);
 						} else {
-							r.push(`penis`);
+							r.push(`${dickSize} penis`);
 						}
-						r.push(`at attention.`);
+						r.push(`ready and waiting.`);
+					}
+				}
+			} else {
+				r.push(`${his} chosen partner.`);
+				if (slave.devotion > 95) {
+					r.push(`${His} deep acceptance of slavery means ${he} is eager to please you,`);
+					if (slave.clit >= 4) {
+						r.push(`leaving ${his} massive clit flushed,`);
 					} else {
-						if (!bottomDrugged) {
-							r.push(`Once it becomes clear to ${him} that "${he}'ll" be the one mounting ${him}, ${his}`);
-							if (slave.clit >= 4) {
-								r.push(`massive clit`);
-							} else {
-								r.push(`${dickSize} penis`);
-							}
-							r.push(`shrinks away. A direct injection of vasodilators changes that, bringing ${him} back to readiness to ${his} horror.`);
-							bottomDrugged = 1;
-						} else {
-							r.push(`To ${his} own horror the drugs ${he} was injected with keep ${his}`);
-							if (slave.clit >= 4) {
-								r.push(`massive clit`);
-							} else {
-								r.push(`${dickSize} penis`);
-							}
-							r.push(`ready and waiting.`);
-						}
+						r.push(`making ${his} ${dickSize} cock drip precum,`);
+					}
+					r.push(`eager for ${rapist.slaveName}.`);
+				} else if (slave.devotion > 60) {
+					r.push(`${He} is eager enough to please you that ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`clit`);
+					} else {
+						r.push(`penis`);
 					}
+					r.push(`is at attention and waiting for ${rapist.slaveName}.`);
 				} else {
-					r.push(`${his} chosen partner.`);
-					if (slave.devotion > 95) {
-						r.push(`${His} deep acceptance of slavery means ${he} is eager to please you,`);
-						if (slave.clit >= 4) {
-							r.push(`leaving ${his} massive clit flushed,`);
-						} else {
-							r.push(`making ${his} ${dickSize} cock drip precum,`);
-						}
-						r.push(`eager for ${rapist.slaveName}.`);
-					} else if (slave.devotion > 60) {
-						r.push(`${He} is eager enough to please you that ${his}`);
+					if (!bottomDrugged) {
+						r.push(`Once it becomes clear to ${him} that ${rapist.slaveName} be the one mounting ${him}, ${his}`);
 						if (slave.clit >= 4) {
-							r.push(`clit`);
+							r.push(`massive clit`);
 						} else {
-							r.push(`penis`);
+							r.push(`${dickSize} penis`);
 						}
-						r.push(`is at attention and waiting for ${rapist.slaveName}.`);
+						r.push(`shrinks away. A direct injection of vasodilators changes that, bringing ${him} back to a proper hardness.`);
+						bottomDrugged = 1;
 					} else {
-						if (!bottomDrugged) {
-							r.push(`Once it becomes clear to ${him} that ${rapist.slaveName} be the one mounting ${him}, ${his}`);
-							if (slave.clit >= 4) {
-								r.push(`massive clit`);
-							} else {
-								r.push(`${dickSize} penis`);
-							}
-							r.push(`shrinks away. A direct injection of vasodilators changes that, bringing ${him} back to a proper hardness.`);
-							bottomDrugged = 1;
+						r.push(`To ${his} own horror the drugs ${he} was injected with keep ${his}`);
+						if (slave.clit >= 4) {
+							r.push(`massive clit`);
 						} else {
-							r.push(`To ${his} own horror the drugs ${he} was injected with keep ${his}`);
-							if (slave.clit >= 4) {
-								r.push(`massive clit`);
-							} else {
-								r.push(`${dickSize} penis`);
-							}
-							r.push(`ready and waiting.`);
+							r.push(`${dickSize} penis`);
 						}
+						r.push(`ready and waiting.`);
 					}
 				}
 			}
 		}
+	}
 
-		App.Events.addParagraph(el, r);
-		r = [];
+	App.Events.addParagraph(el, r);
+	r = [];
 
-		if (rapist.fetish === "mindbroken" && rapist.career !== "a dairy cow" && rapist.career !== "a breeding bull") {
-			r.push(`${rapist.slaveName} stares blankly, and needs to be deliberately guided to straddle ${slave.slaveName}.`);
-			if (isIncest) {
-				r.push(`Naturally, ${he2} isn't even aware of the impending incest.`);
-			}
-			if (slave.fetish === "mindbroken" && slave.career !== "a dairy cow" && slave.career !== "a breeding bull") {
-				r.push(`Since both slaves are essentially vegetables, this is shaping up to be a rather contrived sexual demonstration. The parts are all there, but the actors aren't going to contribute much to the show.`);
-			}
-		} else if (rapist.fetish === "mindbroken" && (rapist.career === "a dairy cow")) {
-			r.push(`${rapist.slaveName} sees the`);
-			if (slave.clit >= 4) {
-				r.push(`massive clit`);
-			} else {
-				r.push(`${dickSize} penis`);
-			}
-			r.push(`ready and waiting, and catches on to why ${he2}'s here quickly. ${He2} takes it into ${his2} mouth before you stop ${him2} and tap ${his2} pussy, and after a few seconds of thinking ${he2} straddles ${slave.slaveName}'s hips with a moo.`);
-			if (isIncest) {
-				r.push(`Naturally, since ${he2} thinks ${he2}'s a cow, incest means nothing to ${him2}.`);
-			}
-		} else if (rapist.fetish === "mindbroken" && (rapist.career === "a breeding bull")) {
-			r.push(`${rapist.slaveName} sees the`);
-			if (slave.clit >= 4) {
-				r.push(`massive clit`);
+	if (rapist.fetish === "mindbroken" && rapist.career !== "a dairy cow" && rapist.career !== "a breeding bull") {
+		r.push(`${rapist.slaveName} stares blankly, and needs to be deliberately guided to straddle ${slave.slaveName}.`);
+		if (isIncest) {
+			r.push(`Naturally, ${he2} isn't even aware of the impending incest.`);
+		}
+		if (slave.fetish === "mindbroken" && slave.career !== "a dairy cow" && slave.career !== "a breeding bull") {
+			r.push(`Since both slaves are essentially vegetables, this is shaping up to be a rather contrived sexual demonstration. The parts are all there, but the actors aren't going to contribute much to the show.`);
+		}
+	} else if (rapist.fetish === "mindbroken" && (rapist.career === "a dairy cow")) {
+		r.push(`${rapist.slaveName} sees the`);
+		if (slave.clit >= 4) {
+			r.push(`massive clit`);
+		} else {
+			r.push(`${dickSize} penis`);
+		}
+		r.push(`ready and waiting, and catches on to why ${he2}'s here quickly. ${He2} takes it into ${his2} mouth before you stop ${him2} and tap ${his2} pussy, and after a few seconds of thinking ${he2} straddles ${slave.slaveName}'s hips with a moo.`);
+		if (isIncest) {
+			r.push(`Naturally, since ${he2} thinks ${he2}'s a cow, incest means nothing to ${him2}.`);
+		}
+	} else if (rapist.fetish === "mindbroken" && (rapist.career === "a breeding bull")) {
+		r.push(`${rapist.slaveName} sees the`);
+		if (slave.clit >= 4) {
+			r.push(`massive clit`);
+		} else {
+			r.push(`${dickSize} penis`);
+		}
+		r.push(`ready and waiting, but isn't quite sure what to do with it. ${He2}'s been brought up to use ${his2} dick when thinking, after all. It takes a few minutes to get ${him2} to straddle ${slave.slaveName}'s hips with the intent to get ${his2} pussy penetrated.`);
+		if (isIncest) {
+			r.push(`Naturally, since ${he2} thinks ${he2}'s a breeding bull, incest means nothing to ${him2}.`);
+		}
+	} else {
+		r.push(`${rapist.slaveName} sees`);
+		if (isIncest) {
+			if (rapist.father === slave.ID && rapist.mother === slave.ID) {
+				r.push(`the slave that is both ${his2} mother and ${his2} father`);
+			} else if (slave.mother === rapist.ID || slave.father === rapist.ID) {
+				r.push(`${his2} own ${relativeTerm(rapist, slave)}`);
+			} else if (rapist.mother === slave.ID) {
+				r.push(`${his2} own mother`);
+			} else if (rapist.father === slave.ID) {
+				r.push(`the slave that fathered ${him2}`);
 			} else {
-				r.push(`${dickSize} penis`);
+				r.push(`${his2} ${relativeTerm(rapist, slave)}`);
 			}
-			r.push(`ready and waiting, but isn't quite sure what to do with it. ${He2}'s been brought up to use ${his2} dick when thinking, after all. It takes a few minutes to get ${him2} to straddle ${slave.slaveName}'s hips with the intent to get ${his2} pussy penetrated.`);
-			if (isIncest) {
-				r.push(`Naturally, since ${he2} thinks ${he2}'s a breeding bull, incest means nothing to ${him2}.`);
-			}
-		} else {
-			r.push(`${rapist.slaveName} sees`);
-			if (isIncest) {
-				if (rapist.father === slave.ID && rapist.mother === slave.ID) {
-					r.push(`the slave that is both ${his2} mother and ${his2} father`);
-				} else if (slave.mother === rapist.ID || slave.father === rapist.ID) {
-					r.push(`${his2} own ${relativeTerm(rapist, slave)}`);
-				} else if (rapist.mother === slave.ID) {
-					r.push(`${his2} own mother`);
-				} else if (rapist.father === slave.ID) {
-					r.push(`the slave that fathered ${him2}`);
+			r.push(`tied to the bed,`);
+			if (rapist.sexualQuirk === "perverted" || rapist.behavioralQuirk === "sinful") {
+				if (incestMood === "Bottom") {
+					r.push(`and can't hide ${his2}`);
+					if (rapist.sexualQuirk === "perverted") {
+						r.push(`perverted`);
+					} else {
+						r.push(`sinful`);
+					}
+					r.push(`arousal at the excited glances they share.`);
+					incestMood = "Both";
 				} else {
-					r.push(`${his2} ${relativeTerm(rapist, slave)}`);
+					incestMood = "Top";
+					r.push(`and becomes indecently aroused at their horrified expressions for the`);
+					if (rapist.sexualQuirk === "perverted") {
+						r.push(`perverted`);
+					} else {
+						r.push(`sinful`);
+					}
+					r.push(`incest to come.`);
 				}
-				r.push(`tied to the bed,`);
-				if (rapist.sexualQuirk === "perverted" || rapist.sexualQuirk === "sinful") {
+			} else if (rapist.relationshipTarget === slave.ID && rapist.relationship > 2) {
+				r.push(`and licks ${his2} lips involuntarily.`);
+			} else {
+				if (rapist.devotion > 95) {
 					if (incestMood === "Bottom") {
-						r.push(`and can't hide ${his2}`);
-						if (rapist.sexualQuirk === "perverted") {
-							r.push(`perverted`);
-						} else {
-							r.push(`sinful`);
-						}
-						r.push(`arousal at the excited glances they share.`);
+						r.push(`as well as ${his} apparent lust. Since ${he2} is a perfect slave for you, ${his2} vagina becomes flushed with arousal quickly.`);
 						incestMood = "Both";
 					} else {
 						incestMood = "Top";
-						r.push(`and becomes indecently aroused at their horrified expressions for the`);
-						if (rapist.sexualQuirk === "perverted") {
-							r.push(`perverted`);
-						} else {
-							r.push(`sinful`);
-						}
-						r.push(`incest to come.`);
+						r.push(`as well as ${his} worried expression. ${rapist.slaveName} seems aroused and determined to show ${him} how a proper slave should act.`);
 					}
-				} else if (rapist.relationshipTarget === slave.ID && rapist.relationship > 2) {
-					r.push(`and licks ${his2} lips involuntarily.`);
+				} else if (rapist.devotion > 60) {
+					if (incestMood === "BottomFragile") {
+						incestMood = "";
+					}
+					r.push(`and after figuring out they're just as superficially prepared as ${he2} is, resolves ${himself2} to forget they're related to stay aroused.`);
 				} else {
-					if (rapist.devotion > 95) {
-						if (incestMood === "Bottom") {
-							r.push(`as well as ${his2} apparent lust. Since ${he2} is a perfect slave for you, ${his2} vagina becomes flushed with arousal quickly.`);
-							incestMood = "Both";
+					r.push(`and can't hide the look of horror that crosses ${his2} face. You assure ${him2} this is what ${he2} needs to do.`);
+					if (incestMood === "Bottom") {
+						r.push(`To ${his2} growing disgust, ${he2} can tell ${slave.slaveName}'s`);
+						if (slave.clit >= 4) {
+							r.push(`erect clit`);
 						} else {
-							incestMood = "Top";
-							r.push(`as well as ${his} worried expression. ${rapist.slaveName} seems aroused and determined to show ${him} how a proper slave should act.`);
-						}
-					} else if (rapist.devotion > 60) {
-						if (incestMood === "BottomFragile") {
-							incestMood = "";
+							r.push(`${dickSize} erection`);
 						}
-						r.push(`and after figuring out they're just as superficially prepared as ${he2} is, resolves ${himself2} to forget they're related to stay aroused.`);
+						r.push(`shows off genuine arousal despite their blood relation.`);
 					} else {
-						r.push(`and can't hide the look of horror that crosses ${his2} face. You assure ${him2} this is what ${he2} needs to do.`);
-						if (incestMood === "Bottom") {
-							r.push(`To ${his2} growing disgust, ${he2} can tell ${slave.slaveName}'s`);
-							if (slave.clit >= 4) {
-								r.push(`erect clit`);
-							} else {
-								r.push(`${dickSize} erection`);
-							}
-							r.push(`shows off genuine arousal despite their blood relation.`);
+						r.push(`${He2} might find solace in the fact that the owner of the`);
+						if (slave.clit >= 4) {
+							r.push(`erect clit`);
 						} else {
-							r.push(`${He2} might find solace in the fact that the owner of the`);
-							if (slave.clit >= 4) {
-								r.push(`erect clit`);
-							} else {
-								r.push(`${dickSize} erection`);
-							}
-							r.push(`on display doesn't seem thrilled as well.`);
+							r.push(`${dickSize} erection`);
 						}
+						r.push(`on display doesn't seem thrilled as well.`);
 					}
 				}
+			}
+		} else {
+			if (slave.relationshipTarget === rapist.ID) {
+				r.push(`${his} ${relationshipTerm(rapist)}`);
+			} else if (slave.rivalryTarget === rapist.ID) {
+				r.push(`${his} ${rivalryTerm(rapist)}`);
+			} else if (slave.origBodyOwnerID === rapist.ID) {
+				r.push(`${his} former body`);
 			} else {
-				if (slave.relationshipTarget === rapist.ID) {
-					r.push(`${his} ${relationshipTerm(rapist)}`);
-				} else if (slave.rivalryTarget === rapist.ID) {
-					r.push(`${his} ${rivalryTerm(rapist)}`);
-				} else if (slave.origBodyOwnerID === rapist.ID) {
-					r.push(`${his} former body`);
-				} else {
-					r.push(`${slave.slaveName}`);
-				}
-				r.push(`tied to the bed,`);
-				if ((rapist.relationshipTarget === slave.ID && rapist.relationship > 2) || rapist.rivalryTarget === slave.ID) {
-					r.push(`and licks ${his2} lips involuntarily.`);
+				r.push(`${slave.slaveName}`);
+			}
+			r.push(`tied to the bed,`);
+			if ((rapist.relationshipTarget === slave.ID && rapist.relationship > 2) || rapist.rivalryTarget === slave.ID) {
+				r.push(`and licks ${his2} lips involuntarily.`);
+			} else {
+				if (rapist.devotion > 95) {
+					if (incestMood === "Bottom") {
+						r.push(`as well as ${his2} apparent lust. Since ${he2} is a perfect slave for you, ${his2} vagina becomes flushed with arousal quickly.`);
+						incestMood = "Both";
+					} else {
+						incestMood = "Top";
+						r.push(`as well as ${his} worried expressions. ${rapist.slaveName} seems aroused and determined to show ${him} how a proper slave should act.`);
+					}
+				} else if (rapist.devotion > 20) {
+					if (incestMood === "BottomFragile") {
+						incestMood = "";
+					}
+					r.push(`and after figuring out they're just as superficially prepared as ${he2} is, resolves ${himself2} to try and make it pleasurable.`);
 				} else {
-					if (rapist.devotion > 95) {
-						if (incestMood === "Bottom") {
-							r.push(`as well as ${his2} apparent lust. Since ${he2} is a perfect slave for you, ${his2} vagina becomes flushed with arousal quickly.`);
-							incestMood = "Both";
+					r.push(`and can't hide the look of horror that crosses ${his2} face. You assure ${him2} this is what ${he2} needs to do.`);
+					if (incestMood === "Bottom") {
+						r.push(`To ${his2} growing disgust, ${he2} can tell ${slave.slaveName}'s`);
+						if (slave.clit >= 4) {
+							r.push(`erect clit`);
 						} else {
-							incestMood = "Top";
-							r.push(`as well as ${his} worried expressions. ${rapist.slaveName} seems aroused and determined to show ${him} how a proper slave should act.`);
-						}
-					} else if (rapist.devotion > 20) {
-						if (incestMood === "BottomFragile") {
-							incestMood = "";
+							r.push(`${dickSize} erection`);
 						}
-						r.push(`and after figuring out they're just as superficially prepared as ${he2} is, resolves ${himself2} to try and make it pleasurable.`);
+						r.push(`shows off genuine arousal despite ${his2} unwillingness.`);
 					} else {
-						r.push(`and can't hide the look of horror that crosses ${his2} face. You assure ${him2} this is what ${he2} needs to do.`);
-						if (incestMood === "Bottom") {
-							r.push(`To ${his2} growing disgust, ${he2} can tell ${slave.slaveName}'s`);
-							if (slave.clit >= 4) {
-								r.push(`erect clit`);
-							} else {
-								r.push(`${dickSize} erection`);
-							}
-							r.push(`shows off genuine arousal despite ${his2} unwillingness.`);
+						r.push(`${He2} might find solace in the fact that the owner of the`);
+						if (slave.clit >= 4) {
+							r.push(`erect clit`);
 						} else {
-							r.push(`${He2} might find solace in the fact that the owner of the`);
-							if (slave.clit >= 4) {
-								r.push(`erect clit`);
-							} else {
-								r.push(`${dickSize} erection`);
-							}
-							r.push(`on display doesn't seem thrilled as well.`);
+							r.push(`${dickSize} erection`);
 						}
+						r.push(`on display doesn't seem thrilled as well.`);
 					}
 				}
 			}
+		}
 
-			if (incestMood === "Top" || incestMood === "Both" || !(isIncest)) {
-				if (rapist.fetishKnown === 1) {
-					if (rapist.fetish === "submissive") {
-						r.push(`${rapist.slaveName} usually prefers to be underneath someone with a`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} cock`);
-						}
-						r.push(`like that, which is obvious in ${his2} expressions. Knowing ${he2}'s riding it due to someone's orders is just about the only detail that plays to ${his2} fetish.`);
-					} else if (rapist.fetish === "dom") {
-						r.push(`${rapist.slaveName} can't hide ${his2} domineering smile at the`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} cock`);
-						}
-						r.push(`tied up and presented to ${him2}. Being on top and controlling everything is what gets ${him2} off, and you just gave ${him2} a nice human dildo to dominate.`);
-					} else if (rapist.fetish === "masochist") {
-						r.push(`${rapist.slaveName} usually prefers to be the one being abused, which is clear from ${his2} disappointed reaction as ${he2} considers the`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} erection`);
-						}
-						r.push(`tied before ${him2}. Maybe ${he2} can delude ${himself2} into thinking this is a denial play for ${himself2} and enjoy the human dildo, or maybe not.`);
-					} else if (rapist.fetish === "sadist") {
-						r.push(`${rapist.slaveName} is a sadist, and seeing a human dildo tied town for ${him2} to abuse and enjoy has ${him2} almost panting in arousal. The ecstatic look of devotion ${he2} flashes you makes it clear ${he2}'s going to enjoy ${himself2}, regardless of how the`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit's`);
-						} else {
-							r.push(`${dickSize} cock's`);
-						}
-						r.push(`owner feels.`);
-					} else if (rapist.fetish === "humiliation") {
-						r.push(`${rapist.slaveName} usually gets off on humiliation, and you know ${he2} wishes the roles were reversed here. Despite that, having ${his2} ${getWrittenTitle(rapist)} order ${him2} to get ${himself2} off with the human dildo beneath ${him2} is quite thrilling, sexually.`);
+		if (incestMood === "Top" || incestMood === "Both" || !(isIncest)) {
+			if (rapist.fetishKnown === 1) {
+				if (rapist.fetish === "submissive") {
+					r.push(`${rapist.slaveName} usually prefers to be underneath someone with a`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} cock`);
+					}
+					r.push(`like that, which is obvious in ${his2} expressions. Knowing ${he2}'s riding it due to someone's orders is just about the only detail that plays to ${his2} fetish.`);
+				} else if (rapist.fetish === "dom") {
+					r.push(`${rapist.slaveName} can't hide ${his2} domineering smile at the`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} cock`);
+					}
+					r.push(`tied up and presented to ${him2}. Being on top and controlling everything is what gets ${him2} off, and you just gave ${him2} a nice human dildo to dominate.`);
+				} else if (rapist.fetish === "masochist") {
+					r.push(`${rapist.slaveName} usually prefers to be the one being abused, which is clear from ${his2} disappointed reaction as ${he2} considers the`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} erection`);
 					}
+					r.push(`tied before ${him2}. Maybe ${he2} can delude ${himself2} into thinking this is a denial play for ${himself2} and enjoy the human dildo, or maybe not.`);
+				} else if (rapist.fetish === "sadist") {
+					r.push(`${rapist.slaveName} is a sadist, and seeing a human dildo tied town for ${him2} to abuse and enjoy has ${him2} almost panting in arousal. The ecstatic look of devotion ${he2} flashes you makes it clear ${he2}'s going to enjoy ${himself2}, regardless of how the`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit's`);
+					} else {
+						r.push(`${dickSize} cock's`);
+					}
+					r.push(`owner feels.`);
+				} else if (rapist.fetish === "humiliation") {
+					r.push(`${rapist.slaveName} usually gets off on humiliation, and you know ${he2} wishes the roles were reversed here. Despite that, having ${his2} ${getWrittenTitle(rapist)} order ${him2} to get ${himself2} off with the human dildo beneath ${him2} is quite thrilling, sexually.`);
 				}
 			}
 		}
+	}
 
-		App.Events.addParagraph(el, r);
-		r = [];
+	App.Events.addParagraph(el, r);
+	r = [];
 
-		if (slave.devotion < -20 && rapist.devotion < -20) {
-			r.push(`Since you have two restrained slaves, it's up to you to do all the work. Since ${slave.slaveName} is already lying on the bed, you maneuver ${rapist.slaveName}'s pussy into place. The two slaves make no further moves until you deal ${rapist.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. ${rapist.slaveName} starts lowering ${himself2} very slowly, pulling back every time ${slave.slaveName}'s dick prods ${his2} womanhood. After watching the sad display for a while, you grab ${him2} by the hips and slam ${him2} down onto ${slave.slaveName}, hilting ${him2} in one, scream-inducing move.`);
-			if (rapist.vagina === 0) { /* losing virginity */
-				if (rapist.devotion > 20) {
-					r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
+	if (slave.devotion < -20 && rapist.devotion < -20) {
+		r.push(`Since you have two restrained slaves, it's up to you to do all the work. Since ${slave.slaveName} is already lying on the bed, you maneuver ${rapist.slaveName}'s pussy into place. The two slaves make no further moves until you deal ${rapist.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. ${rapist.slaveName} starts lowering ${himself2} very slowly, pulling back every time ${slave.slaveName}'s dick prods ${his2} womanhood. After watching the sad display for a while, you grab ${him2} by the hips and slam ${him2} down onto ${slave.slaveName}, hilting ${him2} in one, scream-inducing move.`);
+		if (rapist.vagina === 0) { /* losing virginity */
+			if (rapist.devotion > 20) {
+				r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
 
+				if (slave.clit >= 4) {
+					r.push(`massive clit.`);
+				} else {
+					r.push(`${dickSize} dick.`);
+				}
+				r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion += 10;
+			} else if (rapist.devotion >= -20) {
+				r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion += 4;
+			} else {
+				r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion -= 5;
+				rapist.trust -= 5;
+			}
+			if (rapist.mother === slave.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
 					if (slave.clit >= 4) {
-						r.push(`massive clit.`);
+						r.push(`massive clit`);
 					} else {
-						r.push(`${dickSize} dick.`);
+						r.push(`${dickSize} dick`);
 					}
-					r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 10;
-				} else if (rapist.devotion >= -20) {
-					r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 4;
+					r.push(`for the first time.`);
 				} else {
-					r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion -= 5;
-					rapist.trust -= 5;
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} dick`);
+					}
+					r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
 				}
-				if (rapist.mother === slave.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+			} else if (slave.mother === rapist.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
+						r.push(`${dickSize} dick`);
 					}
-				} else if (slave.mother === rapist.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+					r.push(`for the first time.`);
+				} else {
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} mother's vagina.`);
+						r.push(`${dickSize} dick`);
 					}
+					r.push(`disappears into ${his} mother's vagina.`);
 				}
-			}/* closes losing virginity */
-			r.push(`${rapist.slaveName} seems more cooperative after that and you only have to occasionally prod them with an electrical jolt to keep them going at a faster pace. Both slaves resent what you made them do and fear you as a result.`);
-		} else if (rapist.fetish === "sadist" && rapist.fetishStrength > 20 && slave.devotion < -20) {
-			r.push(`You tell the grinning ${rapist.slaveName} that ${slave.slaveName}'s`);
-			if (slave.clit >= 4) {
-				r.push(`massive clit`);
+			}
+		}/* closes losing virginity */
+		r.push(`${rapist.slaveName} seems more cooperative after that and you only have to occasionally prod them with an electrical jolt to keep them going at a faster pace. Both slaves resent what you made them do and fear you as a result.`);
+	} else if (rapist.fetish === "sadist" && rapist.fetishStrength > 20 && slave.devotion < -20) {
+		r.push(`You tell the grinning ${rapist.slaveName} that ${slave.slaveName}'s`);
+		if (slave.clit >= 4) {
+			r.push(`massive clit`);
+		} else {
+			r.push(`${dickSize} dick`);
+		}
+		r.push(`is all ${hers2}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to hurt and rape another slave for ${his2} pleasure.`);
+		if (rapist.vagina === 0) { /* losing virginity */
+			if (rapist.devotion > 20) {
+				r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
+
+				if (slave.clit >= 4) {
+					r.push(`massive clit.`);
+				} else {
+					r.push(`${dickSize} dick.`);
+				}
+				r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion += 10;
+			} else if (rapist.devotion >= -20) {
+				r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
+
+				rapist.vagina = 1;
+				rapist.devotion += 4;
 			} else {
-				r.push(`${dickSize} dick`);
+				r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion -= 5;
+				rapist.trust -= 5;
 			}
-			r.push(`is all ${hers2}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to hurt and rape another slave for ${his2} pleasure.`);
-			if (rapist.vagina === 0) { /* losing virginity */
-				if (rapist.devotion > 20) {
-					r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
+			if (rapist.mother === slave.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
 
 					if (slave.clit >= 4) {
-						r.push(`massive clit.`);
+						r.push(`massive clit`);
 					} else {
-						r.push(`${dickSize} dick.`);
+						r.push(`${dickSize} dick`);
 					}
-					r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 10;
-				} else if (rapist.devotion >= -20) {
-					r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
-
-					rapist.vagina = 1;
-					rapist.devotion += 4;
+					r.push(`for the first time.`);
 				} else {
-					r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion -= 5;
-					rapist.trust -= 5;
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} dick`);
+					}
+					r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
 				}
-				if (rapist.mother === slave.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
-
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+			} else if (slave.mother === rapist.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
+						r.push(`${dickSize} dick`);
 					}
-				} else if (slave.mother === rapist.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+					r.push(`for the first time.`);
+				} else {
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} mother's vagina.`);
+						r.push(`${dickSize} dick`);
 					}
+					r.push(`disappears into ${his} mother's vagina.`);
 				}
-			}/* closes losing virginity */
+			}
+		}/* closes losing virginity */
 
-			r.push(`${He2} begins playing with ${him} immediately, slapping, pinching and licking ${his} boobs while bouncing on the meaty shaft. Occasionally ${he2} stops, denying ${slave.slaveName} release by painfully squeezing and smacking the sensitive shaft. By the end of the session ${slave.slaveName}'s abused, pent-up penis has shot several massive and painful loads into the blissfully satisfied ${rapist.slaveName}, leaving ${him} lying on the bed, shaking in horror and <span class="health dec">utter exhaustion,</span> while ${rapist.slaveName} reaps the opportunity to continue painfully tormenting ${him}.`);
+		r.push(`${He2} begins playing with ${him} immediately, slapping, pinching and licking ${his} boobs while bouncing on the meaty shaft. Occasionally ${he2} stops, denying ${slave.slaveName} release by painfully squeezing and smacking the sensitive shaft. By the end of the session ${slave.slaveName}'s abused, pent-up penis has shot several massive and painful loads into the blissfully satisfied ${rapist.slaveName}, leaving ${him} lying on the bed, shaking in horror and <span class="health dec">utter exhaustion,</span> while ${rapist.slaveName} reaps the opportunity to continue painfully tormenting ${him}.`);
+
+		healthDamage(slave, 10);
+		seX(slave, "penetrative", rapist, "vaginal", 3);
+	} else if (slave.devotion < -20) {
+		r.push(`Since your dick slave is restrained, you order ${rapist.slaveName} to kneel on the bed on top of ${slave.slaveName}, and then maneuver ${his2} pussy into place. ${slave.slaveName} is uncooperative, so you prod and slap ${him} until ${he} starts to thrust ${his} cock into ${rapist.slaveName} with urgency.`);
+		if (rapist.vagina === 0) { /* losing virginity */
+			if (rapist.devotion > 20) {
+				r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
+				if (slave.clit >= 4) {
+					r.push(`massive clit.`);
+				} else {
+					r.push(`${dickSize} dick.`);
+				}
+				r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion += 10;
+			} else if (rapist.devotion >= -20) {
+				r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion += 4;
+			} else {
+				r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion -= 5;
+				rapist.trust -= 5;
+			}
+			if (rapist.mother === slave.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
 
-			healthDamage(slave, 10);
-			seX(slave, "penetrative", rapist, "vaginal", 3);
-		} else if (slave.devotion < -20) {
-			r.push(`Since your dick slave is restrained, you order ${rapist.slaveName} to kneel on the bed on top of ${slave.slaveName}, and then maneuver ${his2} pussy into place. ${slave.slaveName} is uncooperative, so you prod and slap ${him} until ${he} starts to thrust ${his} cock into ${rapist.slaveName} with urgency.`);
-			if (rapist.vagina === 0) { /* losing virginity */
-				if (rapist.devotion > 20) {
-					r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
 					if (slave.clit >= 4) {
-						r.push(`massive clit.`);
+						r.push(`massive clit`);
 					} else {
-						r.push(`${dickSize} dick.`);
+						r.push(`${dickSize} dick`);
 					}
-					r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 10;
-				} else if (rapist.devotion >= -20) {
-					r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 4;
+					r.push(`for the first time.`);
 				} else {
-					r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion -= 5;
-					rapist.trust -= 5;
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} dick`);
+					}
+					r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
 				}
-				if (rapist.mother === slave.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
-
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+			} else if (slave.mother === rapist.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
+						r.push(`${dickSize} dick`);
 					}
-				} else if (slave.mother === rapist.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+					r.push(`for the first time.`);
+				} else {
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} mother's vagina.`);
+						r.push(`${dickSize} dick`);
 					}
+					r.push(`disappears into ${his} mother's vagina.`);
 				}
-			}/* closes losing virginity */
-			r.push(`It doesn't take long for ${slave.slaveName} to orgasm. ${He} resents what you made ${him} do and fears you as a result.`);
-		} else if (rapist.fetish === "dom" && rapist.fetishStrength > 20 && rapist.devotion > 20) {
-			r.push(`You tell the randy ${rapist.slaveName} that ${slave.slaveName}'s`);
+			}
+		}/* closes losing virginity */
+		r.push(`It doesn't take long for ${slave.slaveName} to orgasm. ${He} resents what you made ${him} do and fears you as a result.`);
+	} else if (rapist.fetish === "dom" && rapist.fetishStrength > 20 && rapist.devotion > 20) {
+		r.push(`You tell the randy ${rapist.slaveName} that ${slave.slaveName}'s`);
 
+		if (slave.clit >= 4) {
+			r.push(`massive clit`);
+		} else {
+			r.push(`${dickSize} dick`);
+		}
+		r.push(`is all ${hers2}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to rape another slave for ${his2} pleasure.`);
+		if (rapist.vagina === 0) {
+			r.push(`Without further instruction, ${rapist.slaveName} lowers ${his2} virgin pussy onto ${slave.slaveName} waiting`);
 			if (slave.clit >= 4) {
-				r.push(`massive clit`);
+				r.push(`clit-dick,`);
 			} else {
-				r.push(`${dickSize} dick`);
+				r.push(`${dickSize} dick,`);
 			}
-			r.push(`is all ${hers2}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to rape another slave for ${his2} pleasure.`);
-			if (rapist.vagina === 0) {
-				r.push(`Without further instruction, ${rapist.slaveName} lowers ${his2} virgin pussy onto ${slave.slaveName} waiting`);
+			r.push(`impaling ${himself2} slowly and teasing ${his2} bound victim. This act <span class="lime">breaks in ${his2} pussy.</span>`);
+			rapist.vagina = 1;
+			rapist.fetishStrength += 1;
+		}
+		r.push(`${He2} begins playing with ${him2} immediately, fondling, pinching and licking while bouncing on the meaty shaft. Occasionally ${he2} stops, denying ${slave.slaveName} release and teasing ${him}, fully enjoying ${his2} dominant role.`);
+		if (slave.dick > 0) {
+			if (slave.fetish === "submissive") {
+				r.push(`By the end of the session ${slave.slaveName}'s abused, pent-up penis has shot a massive load into ${rapist.slaveName}'s welcoming pussy. ${He} is glad to be dominated.`);
+			} else {
+				r.push(`By the end of the session ${slave.slaveName}'s abused, pent-up penis has shot a massive load, to ${his} horror and resentment, into the blissfully satisfied ${rapist.slaveName}.`);
+			}
+		}
+	} else if (rapist.energy > 95 && rapist.devotion > 20) {
+		r.push(`You tell the randy ${rapist.slaveName} that ${slave.slaveName}'s`);
+
+		if (slave.clit >= 4) {
+			r.push(`massive clit`);
+		} else {
+			r.push(`${dickSize} dick`);
+		}
+		r.push(`is all ${hers}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to rape another slave, just for the perverted novelty of the act.`);
+		if (rapist.vagina === 0) { /* losing virginity */
+			if (rapist.devotion > 20) {
+				r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
 				if (slave.clit >= 4) {
-					r.push(`clit-dick,`);
+					r.push(`massive clit.`);
 				} else {
-					r.push(`${dickSize} dick,`);
+					r.push(`${dickSize} dick.`);
 				}
-				r.push(`impaling ${himself2} slowly and teasing ${his2} bound victim. This act <span class="lime">breaks in ${his2} pussy.</span>`);
+				r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
 				rapist.vagina = 1;
-				rapist.fetishStrength += 1;
-			}
-			r.push(`${He2} begins playing with ${him2} immediately, fondling, pinching and licking while bouncing on the meaty shaft. Occasionally ${he2} stops, denying ${slave.slaveName} release and teasing ${him}, fully enjoying ${his2} dominant role.`);
-			if (slave.dick > 0) {
-				if (slave.fetish === "submissive") {
-					r.push(`By the end of the session ${slave.slaveName}'s abused, pent-up penis has shot a massive load into ${rapist.slaveName}'s welcoming pussy. ${He} is glad to be dominated.`);
-				} else {
-					r.push(`By the end of the session ${slave.slaveName}'s abused, pent-up penis has shot a massive load, to ${his} horror and resentment, into the blissfully satisfied ${rapist.slaveName}.`);
-				}
-			}
-		} else if (rapist.energy > 95 && rapist.devotion > 20) {
-			r.push(`You tell the randy ${rapist.slaveName} that ${slave.slaveName}'s`);
-
-			if (slave.clit >= 4) {
-				r.push(`massive clit`);
+				rapist.devotion += 10;
+			} else if (rapist.devotion >= -20) {
+				r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion += 4;
 			} else {
-				r.push(`${dickSize} dick`);
+				r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion -= 5;
+				rapist.trust -= 5;
 			}
-			r.push(`is all ${hers}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to rape another slave, just for the perverted novelty of the act.`);
-			if (rapist.vagina === 0) { /* losing virginity */
-				if (rapist.devotion > 20) {
-					r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
+			if (rapist.mother === slave.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
+
 					if (slave.clit >= 4) {
-						r.push(`massive clit.`);
+						r.push(`massive clit`);
 					} else {
-						r.push(`${dickSize} dick.`);
+						r.push(`${dickSize} dick`);
 					}
-					r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 10;
-				} else if (rapist.devotion >= -20) {
-					r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 4;
+					r.push(`for the first time.`);
 				} else {
-					r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion -= 5;
-					rapist.trust -= 5;
-				}
-				if (rapist.mother === slave.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
-
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
+						r.push(`${dickSize} dick`);
 					}
-				} else if (slave.mother === rapist.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+					r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
+				}
+			} else if (slave.mother === rapist.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} mother's vagina.`);
+						r.push(`${dickSize} dick`);
 					}
-				}
-			}/* closes losing virginity */
-
-			r.push(`${He2} rides the helpless ${slave.slaveName} through several ejaculating orgasms. ${slave.vagina > -1 ? `In the short breaks between them, ${he2} teases ${his} pussy. ` : ``}By the end of the session ${rapist.slaveName}'s cunt is dripping cum, to ${his2} obvious satiation and bliss. ${slave.slaveName} is lying next to ${him2} on the bed in a state of fatigue, the entire experience having thoroughly exhausted ${him}.`);
-			seX(slave, "penetrative", rapist, "vaginal", 3);
-		} else if (slave.devotion <= 20 || rapist.devotion <= 20) {
-			r.push(`You toss ${slave.slaveName} onto the bed and tell ${rapist.slaveName} to get on with it.`);
-			if (rapist.vagina === 0) { /* losing virginity */
-				if (rapist.devotion > 20) {
-					r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
+					r.push(`for the first time.`);
+				} else {
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
 					if (slave.clit >= 4) {
-						r.push(`massive clit.`);
+						r.push(`massive clit`);
 					} else {
-						r.push(`${dickSize} dick.`);
+						r.push(`${dickSize} dick`);
 					}
-					r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 10;
-				} else if (rapist.devotion >= -20) {
-					r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he2} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 4;
+					r.push(`disappears into ${his} mother's vagina.`);
+				}
+			}
+		}/* closes losing virginity */
+
+		r.push(`${He2} rides the helpless ${slave.slaveName} through several ejaculating orgasms. ${slave.vagina > -1 ? `In the short breaks between them, ${he2} teases ${his} pussy. ` : ``}By the end of the session ${rapist.slaveName}'s cunt is dripping cum, to ${his2} obvious satiation and bliss. ${slave.slaveName} is lying next to ${him2} on the bed in a state of fatigue, the entire experience having thoroughly exhausted ${him}.`);
+		seX(slave, "penetrative", rapist, "vaginal", 3);
+	} else if (slave.devotion <= 20 || rapist.devotion <= 20) {
+		r.push(`You toss ${slave.slaveName} onto the bed and tell ${rapist.slaveName} to get on with it.`);
+		if (rapist.vagina === 0) { /* losing virginity */
+			if (rapist.devotion > 20) {
+				r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
+				if (slave.clit >= 4) {
+					r.push(`massive clit.`);
 				} else {
-					r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion -= 5;
-					rapist.trust -= 5;
+					r.push(`${dickSize} dick.`);
 				}
-				if (rapist.mother === slave.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+				r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion += 10;
+			} else if (rapist.devotion >= -20) {
+				r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he2} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion += 4;
+			} else {
+				r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion -= 5;
+				rapist.trust -= 5;
+			}
+			if (rapist.mother === slave.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
+						r.push(`${dickSize} dick`);
 					}
-				} else if (slave.mother === rapist.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+					r.push(`for the first time.`);
+				} else {
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} mother's vagina.`);
+						r.push(`${dickSize} dick`);
 					}
+					r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
 				}
-			}/* closes losing virginity */
-			r.push(`They fuck mechanically, gazing with roiling emotions into each others' eyes. They do seem to come to some sort of a nonverbal understanding on the necessity of getting it done, and there is no real unhappiness in either of them when they finish and disentangle themselves. As they clean themselves and exit, you notice ${rapist.slaveName} is looking a little more longingly at ${slave.slaveName}.`);
-		} else if (slave.devotion <= 50 || rapist.devotion <= 50) {
-			r.push(`You order ${slave.slaveName} and ${rapist.slaveName} to get on with it.`);
-			if (rapist.vagina === 0) { /* losing virginity */
-				if (rapist.devotion > 20) {
-					r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
+			} else if (slave.mother === rapist.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
 					if (slave.clit >= 4) {
-						r.push(`massive clit.`);
+						r.push(`massive clit`);
 					} else {
-						r.push(`${dickSize} dick.`);
+						r.push(`${dickSize} dick`);
 					}
-					r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 10;
-				} else if (rapist.devotion >= -20) {
-					r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 4;
+					r.push(`for the first time.`);
 				} else {
-					r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion -= 5;
-					rapist.trust -= 5;
-				}
-				if (rapist.mother === slave.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
-					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
-					}
-				} else if (slave.mother === rapist.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} mother's vagina.`);
+						r.push(`${dickSize} dick`);
 					}
+					r.push(`disappears into ${his} mother's vagina.`);
 				}
-			}/* closes losing virginity */
-			r.push(`They fuck mechanically at first, gazing with roiling emotions into each others' eyes. Eventually, they begin to enjoy the intimacy of the act, finding the shared pleasure between them comforting. They finish and resume life as slaves, the light of this intimacy diminishing, softening with ${slave.slaveName}'s`);
-			if (slave.clit >= 4) {
-				r.push(`massive clit`);
+			}
+		}/* closes losing virginity */
+		r.push(`They fuck mechanically, gazing with roiling emotions into each others' eyes. They do seem to come to some sort of a nonverbal understanding on the necessity of getting it done, and there is no real unhappiness in either of them when they finish and disentangle themselves. As they clean themselves and exit, you notice ${rapist.slaveName} is looking a little more longingly at ${slave.slaveName}.`);
+	} else if (slave.devotion <= 50 || rapist.devotion <= 50) {
+		r.push(`You order ${slave.slaveName} and ${rapist.slaveName} to get on with it.`);
+		if (rapist.vagina === 0) { /* losing virginity */
+			if (rapist.devotion > 20) {
+				r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
+				if (slave.clit >= 4) {
+					r.push(`massive clit.`);
+				} else {
+					r.push(`${dickSize} dick.`);
+				}
+				r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion += 10;
+			} else if (rapist.devotion >= -20) {
+				r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion += 4;
 			} else {
-				r.push(`${dickSize} dick`);
+				r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion -= 5;
+				rapist.trust -= 5;
 			}
-			r.push(`and dripping away with the contents of ${rapist.slaveName}'s cum-filled pussy. You notice ${rapist.slaveName}'s looking a little more longingly at ${slave.slaveName}.`);
-		} else {
-			r.push(`The two slaves turn eagerly to the business of sex.`);
-			if (rapist.vagina === 0) { /* losing virginity */
-				if (rapist.devotion > 20) {
-					r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
+			if (rapist.mother === slave.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
 					if (slave.clit >= 4) {
-						r.push(`massive clit.`);
+						r.push(`massive clit`);
 					} else {
-						r.push(`${dickSize} dick.`);
+						r.push(`${dickSize} dick`);
 					}
-					r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 10;
-				} else if (rapist.devotion >= -20) {
-					r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion += 4;
+					r.push(`for the first time.`);
 				} else {
-					r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
-					rapist.vagina = 1;
-					rapist.devotion -= 5;
-					rapist.trust -= 5;
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} dick`);
+					}
+					r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
 				}
-				if (rapist.mother === slave.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+			} else if (slave.mother === rapist.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
+						r.push(`${dickSize} dick`);
 					}
-				} else if (slave.mother === rapist.ID) {
-					if (slave.counter.penetrative === 0) {
-						r.push(`${slave.slaveName}`);
-						r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`for the first time.`);
+					r.push(`for the first time.`);
+				} else {
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
 					} else {
-						r.push(`${slave.slaveName}'s breath quickens as ${his}`);
-						if (slave.clit >= 4) {
-							r.push(`massive clit`);
-						} else {
-							r.push(`${dickSize} dick`);
-						}
-						r.push(`disappears into ${his} mother's vagina.`);
+						r.push(`${dickSize} dick`);
 					}
+					r.push(`disappears into ${his} mother's vagina.`);
 				}
-			}/* closes losing virginity */
-			r.push(`${rapist.slaveName} happily rides ${slave.slaveName}, who occasionally thrusts ${his} hips up. After a little while, when ${rapist.slaveName} bends down to engage in passionate kissing, you come over and`);
-			if (canDoAnal(rapist) && rapist.anus > 0) {
-				r.push(`penetrate ${rapist.slaveName}'s free asshole with your`);
-				if (V.PC.dick !== 0) {
-					r.push(`dick.`);
+			}
+		}/* closes losing virginity */
+		r.push(`They fuck mechanically at first, gazing with roiling emotions into each others' eyes. Eventually, they begin to enjoy the intimacy of the act, finding the shared pleasure between them comforting. They finish and resume life as slaves, the light of this intimacy diminishing, softening with ${slave.slaveName}'s`);
+		if (slave.clit >= 4) {
+			r.push(`massive clit`);
+		} else {
+			r.push(`${dickSize} dick`);
+		}
+		r.push(`and dripping away with the contents of ${rapist.slaveName}'s cum-filled pussy. You notice ${rapist.slaveName}'s looking a little more longingly at ${slave.slaveName}.`);
+	} else {
+		r.push(`The two slaves turn eagerly to the business of sex.`);
+		if (rapist.vagina === 0) { /* losing virginity */
+			if (rapist.devotion > 20) {
+				r.push(`${rapist.slaveName} accepts your orders without comment and lowers ${his2} virgin pussy on ${slave.slaveName}'s ready`);
+				if (slave.clit >= 4) {
+					r.push(`massive clit.`);
 				} else {
-					r.push(`strap-on.`);
+					r.push(`${dickSize} dick.`);
 				}
-				r.push(`With the extra stimulus of double penetration, ${he} comes indecently hard. The two of them collapse into an exhausted, satisfied pile of slave flesh.`);
-				seX(rapist, "anal", V.PC, "penetrative", 1);
-				if (canImpreg(rapist, V.PC)) {
-					knockMeUp(rapist, 5, 1, -1);
-				}
-			} else if (canDoVaginal(slave)) {
-				r.push(`penetrate ${slave.slaveName}'s free pussy with your`);
-				if (V.PC.dick !== 0) {
-					r.push(`dick.`);
+				r.push(`<span class="devotion inc">${rapist.slaveName} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">will break in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion += 10;
+			} else if (rapist.devotion >= -20) {
+				r.push(`${rapist.slaveName} is clearly unhappy at the idea of losing ${his2} pearl of great price to ${slave.slaveName}; this probably isn't what ${he2} imagined ${his2} first real sex would be like. ${He2} fears ${he2} might get pregnant. Nevertheless, <span class="devotion inc">${he} is further broken to slavery</span> by this application of ${his2} body, which naturally <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion += 4;
+			} else {
+				r.push(`As you anticipated, ${rapist.slaveName} refuses to give ${slave.slaveName} ${his2} virginity. However, since ${rapist.slaveName} is restrained ${his2} resistance amounts to <span class="mediumorchid">horrified tears</span> and <span class="trust dec">frightened begging.</span> Naturally, this cruel act <span class="lime">breaks in ${his2} pussy.</span>`);
+				rapist.vagina = 1;
+				rapist.devotion -= 5;
+				rapist.trust -= 5;
+			}
+			if (rapist.mother === slave.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} ${relativeTerm(slave, rapist)}'s — embracing ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} dick`);
+					}
+					r.push(`for the first time.`);
 				} else {
-					r.push(`strap-on.`);
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} dick`);
+					}
+					r.push(`disappears into ${his} ${relativeTerm(slave, rapist)}'s vagina.`);
 				}
-				r.push(`With the double stimulus of penetrating a tight vagina and being penetrated while restrained, ${he} comes indecently hard. The two of them collapse into an exhausted, satisfied pile of slave flesh.`);
-				r.push(VCheck.Vaginal(slave, 1));
-			} else if (canDoAnal(slave)) {
-				r.push(`penetrate ${slave.slaveName}'s free asshole with your`);
-				if (V.PC.dick !== 0) {
-					r.push(`dick.`);
+			} else if (slave.mother === rapist.ID) {
+				if (slave.counter.penetrative === 0) {
+					r.push(`${slave.slaveName}`);
+					r.push(`gasps and ${his} eyes widen as ${he} feels the tender folds of a pussy — and none other than ${his} mother's — embracing ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} dick`);
+					}
+					r.push(`for the first time.`);
 				} else {
-					r.push(`strap-on.`);
+					r.push(`${slave.slaveName}'s breath quickens as ${his}`);
+					if (slave.clit >= 4) {
+						r.push(`massive clit`);
+					} else {
+						r.push(`${dickSize} dick`);
+					}
+					r.push(`disappears into ${his} mother's vagina.`);
 				}
-				r.push(`With the double stimulus of penetrating a tight vagina and being penetrated while restrained, ${he} comes indecently hard. The two of them collapse into an exhausted, satisfied pile of slave flesh.`);
-				r.push(VCheck.Anal(slave, 1));
+			}
+		}/* closes losing virginity */
+		r.push(`${rapist.slaveName} happily rides ${slave.slaveName}, who occasionally thrusts ${his} hips up. After a little while, when ${rapist.slaveName} bends down to engage in passionate kissing, you come over and`);
+		if (canDoAnal(rapist) && rapist.anus > 0) {
+			r.push(`penetrate ${rapist.slaveName}'s free asshole with your`);
+			if (V.PC.dick !== 0) {
+				r.push(`dick.`);
 			} else {
-				r.push(`pull ${his2} face to your crotch. All this penetration has got you horny and there are no free holes to fuck, so a little oral will have to do. It doesn't take long for all three of you to collapse into an exhausted, satisfied pile of flesh.`);
-				seX(rapist, "oral", V.PC, "penetrative", 1);
+				r.push(`strap-on.`);
 			}
+			r.push(`With the extra stimulus of double penetration, ${he} comes indecently hard. The two of them collapse into an exhausted, satisfied pile of slave flesh.`);
+			seX(rapist, "anal", V.PC, "penetrative", 1);
+			if (canImpreg(rapist, V.PC)) {
+				knockMeUp(rapist, 5, 1, -1);
+			}
+		} else if (canDoVaginal(slave)) {
+			r.push(`penetrate ${slave.slaveName}'s free pussy with your`);
+			if (V.PC.dick !== 0) {
+				r.push(`dick.`);
+			} else {
+				r.push(`strap-on.`);
+			}
+			r.push(`With the double stimulus of penetrating a tight vagina and being penetrated while restrained, ${he} comes indecently hard. The two of them collapse into an exhausted, satisfied pile of slave flesh.`);
+			r.push(VCheck.Vaginal(slave, 1));
+		} else if (canDoAnal(slave)) {
+			r.push(`penetrate ${slave.slaveName}'s free asshole with your`);
+			if (V.PC.dick !== 0) {
+				r.push(`dick.`);
+			} else {
+				r.push(`strap-on.`);
+			}
+			r.push(`With the double stimulus of penetrating a tight vagina and being penetrated while restrained, ${he} comes indecently hard. The two of them collapse into an exhausted, satisfied pile of slave flesh.`);
+			r.push(VCheck.Anal(slave, 1));
+		} else {
+			r.push(`pull ${his2} face to your crotch. All this penetration has got you horny and there are no free holes to fuck, so a little oral will have to do. It doesn't take long for all three of you to collapse into an exhausted, satisfied pile of flesh.`);
+			seX(rapist, "oral", V.PC, "penetrative", 1);
 		}
+	}
 
-		/* Friendship/lust? */
-		if (([2].includes(slave.relationship) && slave.relationshipTarget === rapist.ID) && ([2].includes(rapist.relationship) && rapist.relationshipTarget === slave.ID)) {
-			r.push(`You keep ${slave.slaveName}'s dick intimate with ${rapist.slaveName}'s pussy for awhile, something the two friends haven't been sharing with each other. In the end, you are certain they got closer, becoming <span class="lightgreen">friends with benefits.</span>`);
-			slave.relationship++;
-			rapist.relationship++;
-		}
+	/* Friendship/lust? */
+	if (([2].includes(slave.relationship) && slave.relationshipTarget === rapist.ID) && ([2].includes(rapist.relationship) && rapist.relationshipTarget === slave.ID)) {
+		r.push(`You keep ${slave.slaveName}'s dick intimate with ${rapist.slaveName}'s pussy for awhile, something the two friends haven't been sharing with each other. In the end, you are certain they got closer, becoming <span class="lightgreen">friends with benefits.</span>`);
+		slave.relationship++;
+		rapist.relationship++;
+	}
 
-		/* pregnancy test */
-		if (canImpreg(rapist, slave)) {
-			r.push(knockMeUp(rapist, 25, 0, slave.ID));
-		}
+	/* pregnancy test */
+	if (canImpreg(rapist, slave)) {
+		r.push(knockMeUp(rapist, 25, 0, slave.ID));
+	}
 
-		/* save changes */
-		seX(slave, "penetrative", rapist, "vaginal", 1);
+	/* save changes */
+	seX(slave, "penetrative", rapist, "vaginal", 1);
 
-		App.Events.addParagraph(el, r);
+	App.Events.addParagraph(el, r);
 
-		return el;
-	}
+	return el;
 };
diff --git a/src/npc/interaction/passage/fSlaveSlaveVag.js b/src/npc/interaction/passage/fSlaveSlaveVag.js
index 3d97db7d6b7893ba8bfd644f1e3a1ed5a83791e2..0203e8790bb50be5b255c2f9f7d0c2c43e46e051 100644
--- a/src/npc/interaction/passage/fSlaveSlaveVag.js
+++ b/src/npc/interaction/passage/fSlaveSlaveVag.js
@@ -1,475 +1,449 @@
-/**
- * @param {App.Entity.SlaveState} slave
- * @returns {HTMLElement}
- */
-App.Interact.fSlaveSlaveVag = function(slave) {
-	const node = document.createElement("div");
+App.Interact.fSlaveSlaveVagChoosePartner = class extends App.Interact.BaseChoosePartnerRenderer {
+	constructor(slave) {
+		super(slave);
+		this.intro = `Select the slave that will fuck ${this.slave.slaveName}.`;
+		this.execute = App.Interact.fSlaveSlaveVag;
+	}
 
-	App.UI.DOM.appendNewElement("div", node, `Select a slave that will fuck ${slave.slaveName}.`);
-	App.UI.DOM.appendNewElement("h2", node, `Select an eligible slave`);
+	eligible(candidate) {
+		return isSlaveAvailable(candidate) && (canPenetrate(candidate) || candidate.clit >= 4);
+	}
 
-	const eligibles = V.slaves.filter((s) => (s.ID !== slave.ID) && isSlaveAvailable(s) && (canPenetrate(s) || s.clit >= 4));
-	for (const eligible of eligibles) {
-		const div = App.UI.DOM.appendNewElement("div", node);
-		div.append(App.UI.DOM.link(
-			SlaveFullName(eligible),
-			() => {
-				App.UI.DOM.replace(node, content(eligible));
-			}
-		));
-		if (eligible.custom.label) {
-			App.UI.DOM.appendNewElement("span", div, ` ${eligible.custom.label}`, ["yellow", "bold"]);
-		}
-		if (canImpreg(eligible, slave)) {
-			App.UI.DOM.appendNewElement("span", div, ` Virile`, "green");
-		}
-		if (totalRelatives(slave) > 0) {
-			const relTerm = relativeTerm(slave, eligible);
-			if (relTerm !== null) {
-				App.UI.DOM.appendNewElement("span", div, ` ${capFirstChar(relTerm)}`, "lightgreen");
-			}
+	renderDetail(candidate, container) {
+		if (canImpreg(candidate, this.slave)) {
+			App.UI.DOM.appendNewElement("span", container, ` Virile`, ["green"]);
 		}
 	}
-	if (eligibles.length === 0) {
-		App.UI.DOM.appendNewElement("div", node, `You have no slaves capable of this act.`, "note");
-	}
-	return node;
-	/**
-	 *
-	 * @param {App.Entity.SlaveState} rapist
-	 * @returns {DocumentFragment}
-	 */
-	function content(rapist) {
-		const el = new DocumentFragment();
-		let r = [];
-		const {
-			He, His,
-			he, his, him, himself
-		} = getPronouns(slave);
+}
 
-		const {
-			He2, His2,
-			he2, his2, him2, himself2, hers2, wife2
-		} = getPronouns(rapist).appendSuffix("2");
-		let incestMood;
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @param {App.Entity.SlaveState} rapist
+ * @returns {DocumentFragment}
+ */
+App.Interact.fSlaveSlaveVag = function(slave, rapist) {
+	const el = new DocumentFragment();
+	let r = [];
+	const {
+		He, His,
+		he, his, him, himself
+	} = getPronouns(slave);
 
-		addPartner(slave, -1);
+	const {
+		He2, His2,
+		he2, his2, him2, himself2, hers2, wife2
+	} = getPronouns(rapist).appendSuffix("2");
+	let incestMood;
 
-		slave.counter.vaginal += 1;
-		V.vaginalTotal += 1;
-		rapist.counter.penetrative++;
-		V.penetrativeTotal++;
+	seX(slave, "vaginal", rapist, "penetrative");
 
-		let dickSize;
-		if (rapist.dick === 1) {
-			dickSize = "pathetic";
-		} else if (rapist.dick === 2) {
-			dickSize = "tiny";
-		} else if (rapist.dick === 3) {
-			dickSize = "average";
-		} else if (rapist.dick === 4) {
-			dickSize = "big";
-		} else if (rapist.dick === 5) {
-			dickSize = "huge";
-		} else if (rapist.dick === 6) {
-			dickSize = "gigantic";
-		} else if (rapist.dick === 7) {
-			dickSize = "titanic";
-		} else if (rapist.dick === 8) {
-			dickSize = "absurd";
-		} else if (rapist.dick === 9) {
-			dickSize = "inhuman";
-		} else {
-			dickSize = "obscene";
-		}
+	let dickSize;
+	if (rapist.dick === 1) {
+		dickSize = "pathetic";
+	} else if (rapist.dick === 2) {
+		dickSize = "tiny";
+	} else if (rapist.dick === 3) {
+		dickSize = "average";
+	} else if (rapist.dick === 4) {
+		dickSize = "big";
+	} else if (rapist.dick === 5) {
+		dickSize = "huge";
+	} else if (rapist.dick === 6) {
+		dickSize = "gigantic";
+	} else if (rapist.dick === 7) {
+		dickSize = "titanic";
+	} else if (rapist.dick === 8) {
+		dickSize = "absurd";
+	} else if (rapist.dick === 9) {
+		dickSize = "inhuman";
+	} else {
+		dickSize = "obscene";
+	}
 
-		const isIncest = areRelated(slave, rapist);
+	const isIncest = areRelated(slave, rapist);
 
-		r.push(`You take a look at the slave you selected.`);
+	r.push(`You take a look at the slave you selected.`);
 
-		if (rapist.fetish === "dom" && rapist.fetishStrength > 20 && rapist.devotion >= -20) {
-			r.push(`Since ${rapist.slaveName} loves to dominate others it's not hard to get ${his2}`);
+	if (rapist.fetish === "dom" && rapist.fetishStrength > 20 && rapist.devotion >= -20) {
+		r.push(`Since ${rapist.slaveName} loves to dominate others it's not hard to get ${his2}`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} dick`);
+		} else {
+			r.push(`massive clit`);
+		}
+		r.push(`ready.`);
+		if (rapist.attrXX > 65) {
+			r.push(`With ${his2} love of pussy, ${he2} becomes aroused indecently fast.`);
+		} else {
+			r.push(`${His2}`);
 			if (rapist.dick > 0) {
-				r.push(`${dickSize} dick`);
+				r.push(`${dickSize} cock`);
 			} else {
 				r.push(`massive clit`);
 			}
-			r.push(`ready.`);
-			if (rapist.attrXX > 65) {
-				r.push(`With ${his2} love of pussy, ${he2} becomes aroused indecently fast.`);
+			r.push(`quickly swells to a throbbing erection at the prospect of forcing ${himself2} on another slave.`);
+		}
+	} else if (rapist.fetish === "sadist" && rapist.fetishStrength > 20 && rapist.devotion >= -20) {
+		r.push(`With the prospect of torturing another slave`);
+		if (rapist.dick > 0) {
+			r.push(`${his2} ${dickSize} cock swells to a throbbing erection in seconds.`);
+		} else {
+			r.push(`${his2} huge clit becomes fully engorged in seconds.`);
+		}
+	} else if ((rapist.fetish === "pregnancy" && rapist.fetishStrength > 20 && rapist.devotion >= -20) && rapist.dick > 0) {
+		r.push(`With the prospect of raping another slave bareback, ${his2} ${dickSize} cock swells to a throbbing erection in seconds.`);
+	} else if (rapist.attrXX > 65 && rapist.devotion >= -20) {
+		r.push(`Since ${rapist.slaveName} likes sticking ${his2}`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} penis`);
+		} else {
+			r.push(`massive clit`);
+		}
+		r.push(`in girls, ${he2} doesn't take much convincing.`);
+	} else if (rapist.devotion > 50) {
+		r.push(`Since ${rapist.slaveName} is devoted to you, ${he2}'ll eagerly fuck anything you tell ${him2} to fuck.`);
+	} else if (rapist.devotion > 20) {
+		r.push(`Since ${rapist.slaveName} is obedient, ${he2}'ll fuck anything you tell ${him2} to fuck.`);
+	} else if (rapist.devotion >= -20) {
+		r.push(`Since ${rapist.slaveName} does not resist your will, ${he2} should comply reasonably well. ${He2} has to work to get ${his2}`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} penis`);
+		} else {
+			r.push(`massive clit`);
+		}
+		r.push(`hard despite ${his2} doubts, visibly disturbed that you are ordering ${him2} to fuck someone for your entertainment.`);
+	} else {
+		r.push(`Since ${rapist.slaveName} is unlikely to comply willingly, you simply restrain ${him2} and administer a massive dose of vasodilators, directly where they will do the most good. ${rapist.slaveName} writhes with the pain of the injection, which is compounded as ${his2}`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} penis`);
+		} else {
+			r.push(`massive clit`);
+		}
+		r.push(`quickly reaches an agonizingly full erection.`);
+	}
+
+	if (isIncest) {
+		r.push(`${rapist.slaveName} is well aware that ${he2} is about to rape`);
+		if (rapist.father === slave.ID && rapist.mother === slave.ID) {
+			r.push(`the slave that is both ${his2} mother and ${his2} father,`);
+		} else if (slave.mother === rapist.ID || slave.father === rapist.ID) {
+			r.push(`${his2} own ${relativeTerm(rapist, slave)},`);
+		} else if (rapist.mother === slave.ID) {
+			r.push(`${his2} own mother,`);
+		} else if (rapist.father === slave.ID) {
+			r.push(`the slave that fathered ${him2},`);
+		} else {
+			r.push(`${his2} ${relativeTerm(rapist, slave)},`);
+		}
+		if (rapist.sexualQuirk === "perverted" || rapist.behavioralQuirk === "sinful") {
+			if (rapist.energy > 60) {
+				r.push(`and seems quite aroused at just how`);
+				if (rapist.sexualQuirk === "perverted") {
+					r.push(`perverted`);
+				} else {
+					r.push(`sinful`);
+				}
+				r.push(`that is.`);
+				if (canSee(rapist)) {
+					r.push(`${rapist.slaveName}'s eyes seemed locked on ${slave.slaveName}'s inviting pussy, thoroughly aroused and waiting for your order.`);
+				}
+			} else {
+				r.push(`but despite ${his2} conflicted feelings ${his2} arousal is clear.`);
+			}
+			incestMood = "Top";
+		} else if (rapist.relationshipTarget === slave.ID && rapist.relationship > 2) {
+			r.push(`but since ${he2}'s already in a sexual relationship with ${him}, it's only special because ${his2} ${getWrittenTitle(rapist)} is watching.`);
+			incestMood = "Top";
+		} else {
+			if (rapist.devotion > 95) {
+				r.push(`but ${his2} deep acceptance of slavery means ${he2} can't help but be eager to please everyone involved with ${his2} performance.`);
+				incestMood = "Top";
+			} else if (rapist.devotion > 60) {
+				r.push(`but ${his2} experience as a slave means ${he2} can mostly ignore it and focus on sex.`);
 			} else {
-				r.push(`${His2}`);
+				r.push(`and is understandably disturbed.`);
+			}
+		}
+	}
+
+	App.Events.addParagraph(el, r);
+	r = [];
+
+	r.push(`Next, you see to ${slave.slaveName}.`);
+
+	if (isIncest) {
+		r.push(`${slave.slaveName} is fully naked and`);
+		if (canSee(slave)) {
+			r.push(`looking up at`);
+		} else {
+			r.push(`waiting in front of`);
+		}
+		if (slave.father === rapist.ID && slave.mother === rapist.ID) {
+			r.push(`the slave that is both ${his} mother and ${his} father,`);
+		} else if (rapist.mother === slave.ID || rapist.father === slave.ID) {
+			r.push(`${his} own ${relativeTerm(slave, rapist)},`);
+		} else if (slave.mother === rapist.ID) {
+			r.push(`${his} own mother,`);
+		} else if (slave.father === rapist.ID) {
+			r.push(`the slave that fathered ${him},`);
+		} else {
+			r.push(`${his} ${relativeTerm(slave, rapist)},`);
+		}
+		if (slave.sexualQuirk === "perverted" || slave.behavioralQuirk === "sinful") {
+			if (slave.energy > 60) {
+				r.push(`whose`);
 				if (rapist.dick > 0) {
-					r.push(`${dickSize} cock`);
+					r.push(`${dickSize} penis`);
 				} else {
 					r.push(`massive clit`);
 				}
-				r.push(`quickly swells to a throbbing erection at the prospect of forcing ${himself2} on another slave.`);
-			}
-		} else if (rapist.fetish === "sadist" && rapist.fetishStrength > 20 && rapist.devotion >= -20) {
-			r.push(`With the prospect of torturing another slave`);
-			if (rapist.dick > 0) {
-				r.push(`${his2} ${dickSize} cock swells to a throbbing erection in seconds.`);
+				r.push(`is standing firm above ${him}. ${He} seems indecently aroused, flushed and shivering in anticipation.`);
 			} else {
-				r.push(`${his2} huge clit becomes fully engorged in seconds.`);
+				r.push(`but despite ${his} conflicted feelings ${his} growing arousal is clear as ${he}`);
+				if (canSee(slave)) {
+					r.push(`stares at`);
+				} else {
+					r.push(`imagines`);
+				}
+				r.push(`the`);
+				if (rapist.dick > 0) {
+					r.push(`${dickSize} penis`);
+				} else {
+					r.push(`massive clit`);
+				}
+				r.push(`that's soon going inside ${him}.`);
 			}
-		} else if ((rapist.fetish === "pregnancy" && rapist.fetishStrength > 20 && rapist.devotion >= -20) && rapist.dick > 0) {
-			r.push(`With the prospect of raping another slave bareback, ${his2} ${dickSize} cock swells to a throbbing erection in seconds.`);
-		} else if (rapist.attrXX > 65 && rapist.devotion >= -20) {
-			r.push(`Since ${rapist.slaveName} likes sticking ${his2}`);
-			if (rapist.dick > 0) {
-				r.push(`${dickSize} penis`);
+			if (incestMood === "Top") {
+				incestMood = "Both";
 			} else {
-				r.push(`massive clit`);
+				incestMood = "Bottom";
 			}
-			r.push(`in girls, ${he2} doesn't take much convincing.`);
-		} else if (rapist.devotion > 50) {
-			r.push(`Since ${rapist.slaveName} is devoted to you, ${he2}'ll eagerly fuck anything you tell ${him2} to fuck.`);
-		} else if (rapist.devotion > 20) {
-			r.push(`Since ${rapist.slaveName} is obedient, ${he2}'ll fuck anything you tell ${him2} to fuck.`);
-		} else if (rapist.devotion >= -20) {
-			r.push(`Since ${rapist.slaveName} does not resist your will, ${he2} should comply reasonably well. ${He2} has to work to get ${his2}`);
-			if (rapist.dick > 0) {
-				r.push(`${dickSize} penis`);
+		} else if (slave.relationshipTarget === rapist.ID && slave.relationship > 2) {
+			r.push(`and seems calm and inviting to ${his}`);
+			if (slave.relationship === 3) {
+				r.push(`sex friend's`);
+			} else if (slave.relationship === 4) {
+				r.push(`lover's`);
 			} else {
-				r.push(`massive clit`);
+				r.push(`slave ${wife2}'s`);
 			}
-			r.push(`hard despite ${his2} doubts, visibly disturbed that you are ordering ${him2} to fuck someone for your entertainment.`);
-		} else {
-			r.push(`Since ${rapist.slaveName} is unlikely to comply willingly, you simply restrain ${him2} and administer a massive dose of vasodilators, directly where they will do the most good. ${rapist.slaveName} writhes with the pain of the injection, which is compounded as ${his2}`);
 			if (rapist.dick > 0) {
 				r.push(`${dickSize} penis`);
 			} else {
 				r.push(`massive clit`);
 			}
-			r.push(`quickly reaches an agonizingly full erection.`);
-		}
-
-		if (isIncest) {
-			r.push(`${rapist.slaveName} is well aware that ${he2} is about to rape`);
-			if (rapist.father === slave.ID && rapist.mother === slave.ID) {
-				r.push(`the slave that is both ${his2} mother and ${his2} father,`);
-			} else if (slave.mother === rapist.ID || slave.father === rapist.ID) {
-				r.push(`${his2} own ${relativeTerm(rapist, slave)},`);
-			} else if (rapist.mother === slave.ID) {
-				r.push(`${his2} own mother,`);
-			} else if (rapist.father === slave.ID) {
-				r.push(`the slave that fathered ${him2},`);
+			r.push(`that will be penetrating ${him}.`);
+			if (incestMood === "Top") {
+				incestMood = "Both";
 			} else {
-				r.push(`${his2} ${relativeTerm(rapist, slave)},`);
+				incestMood = "Bottom";
 			}
-			if (rapist.sexualQuirk === "perverted" || rapist.behavioralQuirk === "sinful") {
-				if (rapist.energy > 60) {
-					r.push(`and seems quite aroused at just how`);
-					if (rapist.sexualQuirk === "perverted") {
-						r.push(`perverted`);
-					} else {
-						r.push(`sinful`);
-					}
-					r.push(`that is.`);
-					if (canSee(rapist)) {
-						r.push(`${rapist.slaveName}'s eyes seemed locked on ${slave.slaveName}'s inviting pussy, thoroughly aroused and waiting for your order.`);
-					}
-				} else {
-					r.push(`but despite ${his2} conflicted feelings ${his2} arousal is clear.`);
-				}
-				incestMood = "Top";
-			} else if (rapist.relationshipTarget === slave.ID && rapist.relationship > 2) {
-				r.push(`but since ${he2}'s already in a sexual relationship with ${him}, it's only special because ${his2} ${getWrittenTitle(rapist)} is watching.`);
-				incestMood = "Top";
-			} else {
-				if (rapist.devotion > 95) {
-					r.push(`but ${his2} deep acceptance of slavery means ${he2} can't help but be eager to please everyone involved with ${his2} performance.`);
-					incestMood = "Top";
-				} else if (rapist.devotion > 60) {
-					r.push(`but ${his2} experience as a slave means ${he2} can mostly ignore it and focus on sex.`);
+		} else {
+			if (slave.devotion > 95) {
+				r.push(`and ${his} deep acceptance of ${his} status as a slave has ${him} staring`);
+				if (canSee(slave)) {
+					r.push(`at`);
 				} else {
-					r.push(`and is understandably disturbed.`);
+					r.push(`blindly towards`);
 				}
-			}
-		}
-
-		App.Events.addParagraph(el, r);
-		r = [];
-
-		r.push(`Next, you see to ${slave.slaveName}.`);
-
-		if (isIncest) {
-			r.push(`${slave.slaveName} is fully naked and`);
-			if (canSee(slave)) {
-				r.push(`looking up at`);
-			} else {
-				r.push(`waiting in front of`);
-			}
-			if (slave.father === rapist.ID && slave.mother === rapist.ID) {
-				r.push(`the slave that is both ${his} mother and ${his} father,`);
-			} else if (rapist.mother === slave.ID || rapist.father === slave.ID) {
-				r.push(`${his} own ${relativeTerm(slave, rapist)},`);
-			} else if (slave.mother === rapist.ID) {
-				r.push(`${his} own mother,`);
-			} else if (slave.father === rapist.ID) {
-				r.push(`the slave that fathered ${him},`);
-			} else {
-				r.push(`${his} ${relativeTerm(slave, rapist)},`);
-			}
-			if (slave.sexualQuirk === "perverted" || slave.behavioralQuirk === "sinful") {
-				if (slave.energy > 60) {
-					r.push(`whose`);
-					if (rapist.dick > 0) {
-						r.push(`${dickSize} penis`);
-					} else {
-						r.push(`massive clit`);
-					}
-					r.push(`is standing firm above ${him}. ${He} seems indecently aroused, flushed and shivering in anticipation.`);
+				r.push(`the`);
+				if (rapist.dick > 0) {
+					r.push(`${dickSize} penis`);
 				} else {
-					r.push(`but despite ${his} conflicted feelings ${his} growing arousal is clear as ${he}`);
-					if (canSee(slave)) {
-						r.push(`stares at`);
-					} else {
-						r.push(`imagines`);
-					}
-					r.push(`the`);
-					if (rapist.dick > 0) {
-						r.push(`${dickSize} penis`);
-					} else {
-						r.push(`massive clit`);
-					}
-					r.push(`that's soon going inside ${him}.`);
+					r.push(`massive clit`);
 				}
+				r.push(`above ${him} with a lusty smile.`);
 				if (incestMood === "Top") {
 					incestMood = "Both";
 				} else {
 					incestMood = "Bottom";
 				}
-			} else if (slave.relationshipTarget === rapist.ID && slave.relationship > 2) {
-				r.push(`and seems calm and inviting to ${his}`);
-				if (slave.relationship === 3) {
-					r.push(`sex friend's`);
-				} else if (slave.relationship === 4) {
-					r.push(`lover's`);
-				} else {
-					r.push(`slave ${wife2}'s`);
-				}
+			} else if (slave.devotion > 60) {
+				r.push(`and if ${he} focuses, ${he} can forget the`);
 				if (rapist.dick > 0) {
 					r.push(`${dickSize} penis`);
 				} else {
 					r.push(`massive clit`);
 				}
-				r.push(`that will be penetrating ${him}.`);
-				if (incestMood === "Top") {
-					incestMood = "Both";
-				} else {
-					incestMood = "Bottom";
-				}
+				r.push(`standing erect in front of ${him} belongs to someone related to ${him}.`);
 			} else {
-				if (slave.devotion > 95) {
-					r.push(`and ${his} deep acceptance of ${his} status as a slave has ${him} staring`);
-					if (canSee(slave)) {
-						r.push(`at`);
-					} else {
-						r.push(`blindly towards`);
-					}
-					r.push(`the`);
+				r.push(`and is understandably disturbed,`);
+				if (canSee(slave)) {
+					r.push(`eyes glued to the`);
 					if (rapist.dick > 0) {
 						r.push(`${dickSize} penis`);
 					} else {
 						r.push(`massive clit`);
 					}
-					r.push(`above ${him} with a lusty smile.`);
-					if (incestMood === "Top") {
-						incestMood = "Both";
-					} else {
-						incestMood = "Bottom";
-					}
-				} else if (slave.devotion > 60) {
-					r.push(`and if ${he} focuses, ${he} can forget the`);
+					r.push(`throbbing before ${him}.`);
+				} else if (canHear(slave)) {
+					r.push(`listening to the heavy breathing of ${his} relative whose`);
 					if (rapist.dick > 0) {
 						r.push(`${dickSize} penis`);
 					} else {
 						r.push(`massive clit`);
 					}
-					r.push(`standing erect in front of ${him} belongs to someone related to ${him}.`);
+					r.push(`will be entering ${him} soon.`);
 				} else {
-					r.push(`and is understandably disturbed,`);
-					if (canSee(slave)) {
-						r.push(`eyes glued to the`);
-						if (rapist.dick > 0) {
-							r.push(`${dickSize} penis`);
-						} else {
-							r.push(`massive clit`);
-						}
-						r.push(`throbbing before ${him}.`);
-					} else if (canHear(slave)) {
-						r.push(`listening to the heavy breathing of ${his} relative whose`);
-						if (rapist.dick > 0) {
-							r.push(`${dickSize} penis`);
-						} else {
-							r.push(`massive clit`);
-						}
-						r.push(`will be entering ${him} soon.`);
+					r.push(`imagining how the`);
+					if (rapist.dick > 0) {
+						r.push(`${dickSize} penis`);
 					} else {
-						r.push(`imagining how the`);
-						if (rapist.dick > 0) {
-							r.push(`${dickSize} penis`);
-						} else {
-							r.push(`massive clit`);
-						}
-						r.push(`of ${his} relative will feel inside ${him}`);
+						r.push(`massive clit`);
 					}
+					r.push(`of ${his} relative will feel inside ${him}`);
 				}
 			}
 		}
+	}
 
-		if (slave.fetish === "submissive" && slave.fetishStrength > 60 && slave.fetishKnown === 1 && slave.vagina === 0) {
-			r.push(`${He} presents ${his} virgin pussy to ${rapist.slaveName} without protest. This act <span class="virginity loss"> breaks in ${his} pussy,</span> and <span class="devotion inc">reminds ${him}</span> of ${his} status as a submissive slave.`);
-			slave.vagina = 1;
-			slave.devotion += 4;
-			slave.fetishStrength += 1;
-		} else if (slave.fetish === "submissive" && slave.fetishStrength > 60 && slave.fetishKnown === 1) {
-			r.push(`${He} smiles as ${he} lays back and presents ${his} pussy to ${rapist.slaveName}. ${He} openly enjoys submitting ${himself} for others to make use of.`);
-		} else if ((slave.devotion > 20 && slave.vagina === 0) ) {
-			r.push(`${He} accepts your orders without comment and presents ${his} virgin pussy to ${rapist.slaveName}. ${He} gasps in shock when ${he} feels the`);
-			if (rapist.dick > 0) {
-				r.push(`${dickSize} dick`);
-			} else {
-				r.push(`massive clit`);
-			}
-			r.push(`enter ${him}. <span class="devotion inc">${He} is broken to slavery</span> by this application of ${his} body, which naturally <span class="virginity loss">will break in ${his} pussy.</span>`);
-			slave.vagina = 1;
-			slave.devotion += 10;
-		} else if (slave.devotion >= -20 && slave.vagina === 0) {
-			r.push(`${He} is clearly unhappy at the idea of losing ${his} pearl of great price to ${rapist.slaveName}; this probably isn't what ${he} imagined ${his} first real sexual encounter would be like. Nevertheless, ${he} is <span class="devotion inc">broken to slavery</span> by this application of ${his} body, which naturally <span class="virginity loss">will break in ${his} pussy.</span>`);
-			slave.vagina = 1;
-			slave.devotion += 4;
-		} else if (slave.vagina === 0) {
-			r.push(`As you anticipated, ${he} refuses to give ${rapist.slaveName} ${his} virginity. Since ${he} is restrained, ${his} <span class="devotion dec">horrified tears</span> and <span class="trust dec">frightened begging</span> are ${his} only signs of rebellion. Naturally, this cruel act <span class="virginity loss">will break in ${his} pussy.</span>`);
-			slave.devotion -= 5;
-			slave.trust -= 5;
-			slave.vagina = 1;
+	if (slave.fetish === "submissive" && slave.fetishStrength > 60 && slave.fetishKnown === 1 && slave.vagina === 0) {
+		r.push(`${He} presents ${his} virgin pussy to ${rapist.slaveName} without protest. This act <span class="virginity loss"> breaks in ${his} pussy,</span> and <span class="devotion inc">reminds ${him}</span> of ${his} status as a submissive slave.`);
+		slave.vagina = 1;
+		slave.devotion += 4;
+		slave.fetishStrength += 1;
+	} else if (slave.fetish === "submissive" && slave.fetishStrength > 60 && slave.fetishKnown === 1) {
+		r.push(`${He} smiles as ${he} lays back and presents ${his} pussy to ${rapist.slaveName}. ${He} openly enjoys submitting ${himself} for others to make use of.`);
+	} else if ((slave.devotion > 20 && slave.vagina === 0) ) {
+		r.push(`${He} accepts your orders without comment and presents ${his} virgin pussy to ${rapist.slaveName}. ${He} gasps in shock when ${he} feels the`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} dick`);
+		} else {
+			r.push(`massive clit`);
 		}
+		r.push(`enter ${him}. <span class="devotion inc">${He} is broken to slavery</span> by this application of ${his} body, which naturally <span class="virginity loss">will break in ${his} pussy.</span>`);
+		slave.vagina = 1;
+		slave.devotion += 10;
+	} else if (slave.devotion >= -20 && slave.vagina === 0) {
+		r.push(`${He} is clearly unhappy at the idea of losing ${his} pearl of great price to ${rapist.slaveName}; this probably isn't what ${he} imagined ${his} first real sexual encounter would be like. Nevertheless, ${he} is <span class="devotion inc">broken to slavery</span> by this application of ${his} body, which naturally <span class="virginity loss">will break in ${his} pussy.</span>`);
+		slave.vagina = 1;
+		slave.devotion += 4;
+	} else if (slave.vagina === 0) {
+		r.push(`As you anticipated, ${he} refuses to give ${rapist.slaveName} ${his} virginity. Since ${he} is restrained, ${his} <span class="devotion dec">horrified tears</span> and <span class="trust dec">frightened begging</span> are ${his} only signs of rebellion. Naturally, this cruel act <span class="virginity loss">will break in ${his} pussy.</span>`);
+		slave.devotion -= 5;
+		slave.trust -= 5;
+		slave.vagina = 1;
+	}
+
+	if (isAmputee(slave)) {
+		r.push(`You set ${his} limbless torso up for ${rapist.slaveName}.`);
+	} else if (tooBigBreasts(slave)) {
+		r.push(`You set ${him} up for ${rapist.slaveName}, face-down so the weight of ${his} tits pins ${him} helplessly in place.`);
+	} else if (tooBigButt(slave)) {
+		r.push(`You set ${him} up for ${rapist.slaveName}, face-down so the weight of ${his} giant ass pins ${him} helplessly in place and gives ${rapist.slaveName} a lovely cushion to thrust against.`);
+	} else if (tooBigDick(slave)) {
+		r.push(`You set ${him} up for ${rapist.slaveName}, face-up so ${he} is pinned under the weight of ${his} giant cock.`);
+	} else if (tooBigBalls(slave)) {
+		r.push(`You set ${him} up for ${rapist.slaveName}, face-down so the weight of ${his} giant balls anchor ${him} helplessly in place.`);
+	} else if (slave.devotion < -20) {
+		r.push(`${He} tries to refuse, so you restrain ${him} despite ${his} resistance to the idea of being raped by another slave.`);
+	} else if (slave.devotion <= 20) {
+		r.push(`${He} obeys your orders reluctantly, arranging ${himself} for vaginal sex despite ${his} obvious hesitation to be raped by another slave.`);
+	} else if (slave.devotion < 10) {
+		r.push(`${He} obeys your orders, arranging ${himself} for vaginal sex despite ${his} slight hesitation at the idea of being another's slave sex toy.`);
+	} else {
+		r.push(`${He} happily obeys your orders, getting ready to serve another slave.`);
+	}
+
+	App.Events.addParagraph(el, r);
+	r = [];
 
-		if (isAmputee(slave)) {
-			r.push(`You set ${his} limbless torso up for ${rapist.slaveName}.`);
-		} else if (tooBigBreasts(slave)) {
-			r.push(`You set ${him} up for ${rapist.slaveName}, face-down so the weight of ${his} tits pins ${him} helplessly in place.`);
-		} else if (tooBigButt(slave)) {
-			r.push(`You set ${him} up for ${rapist.slaveName}, face-down so the weight of ${his} giant ass pins ${him} helplessly in place and gives ${rapist.slaveName} a lovely cushion to thrust against.`);
-		} else if (tooBigDick(slave)) {
-			r.push(`You set ${him} up for ${rapist.slaveName}, face-up so ${he} is pinned under the weight of ${his} giant cock.`);
-		} else if (tooBigBalls(slave)) {
-			r.push(`You set ${him} up for ${rapist.slaveName}, face-down so the weight of ${his} giant balls anchor ${him} helplessly in place.`);
-		} else if (slave.devotion < -20) {
-			r.push(`${He} tries to refuse, so you restrain ${him} despite ${his} resistance to the idea of being raped by another slave.`);
-		} else if (slave.devotion <= 20) {
-			r.push(`${He} obeys your orders reluctantly, arranging ${himself} for vaginal sex despite ${his} obvious hesitation to be raped by another slave.`);
-		} else if (slave.devotion < 10) {
-			r.push(`${He} obeys your orders, arranging ${himself} for vaginal sex despite ${his} slight hesitation at the idea of being another's slave sex toy.`);
+	if (slave.devotion < -20 && rapist.devotion < -20) {
+		r.push(`Since you have two restrained slaves, it's up to you to do all the work. ${slave.slaveName} is tied up on the bed with ${his} pussy available, so you maneuver ${rapist.slaveName}'s`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} dick`);
 		} else {
-			r.push(`${He} happily obeys your orders, getting ready to serve another slave.`);
+			r.push(`strap-on`);
 		}
+		r.push(`into place. The two slaves make no further moves until you deal ${rapist.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. ${rapist.slaveName} starts moving very slowly, barely prodding. After watching them mechanically go at it for a while, you use your leg to suddenly push ${him2} deep into ${slave.slaveName}, fully hilting ${him2} in one motion. You occasionally prod them with an electrical jolt to keep them going at a faster pace. Both slaves resent what you made them do for you and fear you'll make them do it again.`);
+	} else if (rapist.devotion < -20) {
+		r.push(`Since your dick slave is restrained, you order ${slave.slaveName} to present ${himself} on the bed, and then maneuver ${rapist.slaveName}'s`);
+		if (rapist.dick > 0) {
+			r.push(`${dickSize} dick`);
+		} else {
+			r.push(`strap-on`);
+		}
+		r.push(`into place. ${slave.slaveName} does ${his} best to hump ${himself} against the unwilling cock until you deal ${rapist.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. ${He2} is still unenthusiastic, so you have ${him2} lie down and have ${slave.slaveName} ride ${himself} to orgasm. ${He2} resents what you made ${him2} do and fears you'll force ${him2} to do it again. Though ${slave.slaveName} accepts the situation, ${he} looks into ${rapist.slaveName}'s eyes with obvious apology.`);
+	} else if (rapist.fetish === "dom" && rapist.fetishStrength > 20 && rapist.devotion > 20) {
+		r.push(`${slave.slaveName} is tied and placed on the bed with ${his} pussy defenseless and available, and then you tell the randy ${rapist.slaveName} that it's all ${hers2}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to rape another slave for ${his2} pleasure. ${He2} penetrates ${him} immediately, fondling, pinching and licking while pistoning away, fully enjoying ${his2} dominant role, edging ${his2} poor toy again and again and making ${him} beg for release.`);
+		if (slave.fetish === "dom") {
+			if (slave.devotion < -20) {
+				r.push(`By the end of the day ${slave.slaveName}'s abused cunt is`);
 
-		App.Events.addParagraph(el, r);
-		r = [];
-
-		if (slave.devotion < -20 && rapist.devotion < -20) {
-			r.push(`Since you have two restrained slaves, it's up to you to do all the work. ${slave.slaveName} is tied up on the bed with ${his} pussy available, so you maneuver ${rapist.slaveName}'s`);
-			if (rapist.dick > 0) {
-				r.push(`${dickSize} dick`);
-			} else {
-				r.push(`strap-on`);
-			}
-			r.push(`into place. The two slaves make no further moves until you deal ${rapist.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. ${rapist.slaveName} starts moving very slowly, barely prodding. After watching them mechanically go at it for a while, you use your leg to suddenly push ${him2} deep into ${slave.slaveName}, fully hilting ${him2} in one motion. You occasionally prod them with an electrical jolt to keep them going at a faster pace. Both slaves resent what you made them do for you and fear you'll make them do it again.`);
-		} else if (rapist.devotion < -20) {
-			r.push(`Since your dick slave is restrained, you order ${slave.slaveName} to present ${himself} on the bed, and then maneuver ${rapist.slaveName}'s`);
-			if (rapist.dick > 0) {
-				r.push(`${dickSize} dick`);
+				if (rapist.dick > 0) {
+					r.push(`dripping with cum,`);
+				} else {
+					r.push(`overflowing with juices,`);
+				}
+				r.push(`leaving ${him} horrified and disgusted at ${his} lack of control.`);
 			} else {
-				r.push(`strap-on`);
-			}
-			r.push(`into place. ${slave.slaveName} does ${his} best to hump ${himself} against the unwilling cock until you deal ${rapist.slaveName} a terrific swat across the ass and promise to give ${him2} more of the same until ${he2} gets going. ${He2} is still unenthusiastic, so you have ${him2} lie down and have ${slave.slaveName} ride ${himself} to orgasm. ${He2} resents what you made ${him2} do and fears you'll force ${him2} to do it again. Though ${slave.slaveName} accepts the situation, ${he} looks into ${rapist.slaveName}'s eyes with obvious apology.`);
-		} else if (rapist.fetish === "dom" && rapist.fetishStrength > 20 && rapist.devotion > 20) {
-			r.push(`${slave.slaveName} is tied and placed on the bed with ${his} pussy defenseless and available, and then you tell the randy ${rapist.slaveName} that it's all ${hers2}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to rape another slave for ${his2} pleasure. ${He2} penetrates ${him} immediately, fondling, pinching and licking while pistoning away, fully enjoying ${his2} dominant role, edging ${his2} poor toy again and again and making ${him} beg for release.`);
-			if (slave.fetish === "dom") {
-				if (slave.devotion < -20) {
-					r.push(`By the end of the day ${slave.slaveName}'s abused cunt is`);
+				r.push(`By the end of the day ${slave.slaveName}'s abused cunt is`);
 
-					if (rapist.dick > 0) {
-						r.push(`dripping with cum,`);
-					} else {
-						r.push(`overflowing with juices,`);
-					}
-					r.push(`leaving ${him} horrified and disgusted at ${his} lack of control.`);
+				if (rapist.dick > 0) {
+					r.push(`dripping with cum,`);
 				} else {
-					r.push(`By the end of the day ${slave.slaveName}'s abused cunt is`);
-
-					if (rapist.dick > 0) {
-						r.push(`dripping with cum,`);
-					} else {
-						r.push(`overflowing with juices,`);
-					}
-					r.push(`leaving ${him} annoyed at ${his} lack of control, though ${he} still somewhat enjoyed ${himself}.`);
+					r.push(`overflowing with juices,`);
 				}
-			} else if (slave.fetish === "submissive") {
-				if (slave.devotion < -20) {
-					r.push(`By the end of the day ${slave.slaveName}'s abused cunt is`);
+				r.push(`leaving ${him} annoyed at ${his} lack of control, though ${he} still somewhat enjoyed ${himself}.`);
+			}
+		} else if (slave.fetish === "submissive") {
+			if (slave.devotion < -20) {
+				r.push(`By the end of the day ${slave.slaveName}'s abused cunt is`);
 
-					if (rapist.dick > 0) {
-						r.push(`dripping with cum,`);
-					} else {
-						r.push(`overflowing with juices,`);
-					}
-					r.push(`leaving the submissive slave horrified that ${he} found the experience sexually satisfying.`);
+				if (rapist.dick > 0) {
+					r.push(`dripping with cum,`);
 				} else {
-					r.push(`By the end of the day ${slave.slaveName}'s abused cunt is`);
-
-					if (rapist.dick > 0) {
-						r.push(`dripping with cum.`);
-					} else {
-						r.push(`overflowing with juices.`);
-					}
-					r.push(`This sexual encounter is everything ${he} dreamed of, leaving ${him} utterly satisfied.`);
+					r.push(`overflowing with juices,`);
 				}
-			}
-			r.push(`${rapist.slaveName} is lying next to ${him} on the bed in a state of obvious satiation and bliss.`);
-		} else if (rapist.energy > 95 && rapist.devotion > 20 && slave.devotion < -20) {
-			r.push(`${slave.slaveName} is tied and placed on the bed with ${his} pussy defenseless and available, and then you tell the randy ${rapist.slaveName} that it's all ${hers2}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to rape another slave, just for the perverted novelty of the act. ${His} high libido keeps ${him} going for a long time, bringing the helpless toy to one forced orgasm after another. By the end of the day ${slave.slaveName} is lying on the bed, all worn out, ${his} cunt`);
-			if (rapist.dick > 0) {
-				r.push(`dripping with cum`);
+				r.push(`leaving the submissive slave horrified that ${he} found the experience sexually satisfying.`);
 			} else {
-				r.push(`overflowing with juices`);
+				r.push(`By the end of the day ${slave.slaveName}'s abused cunt is`);
+
+				if (rapist.dick > 0) {
+					r.push(`dripping with cum.`);
+				} else {
+					r.push(`overflowing with juices.`);
+				}
+				r.push(`This sexual encounter is everything ${he} dreamed of, leaving ${him} utterly satisfied.`);
 			}
-			r.push(`to ${his} horror and resentment, while ${rapist.slaveName} is sleeping next to ${him} in a state of obvious satiation and bliss.`);
-		} else if (slave.devotion <= 20 || rapist.devotion <= 20) {
-			r.push(`You order ${slave.slaveName} onto the couch and tell ${rapist.slaveName} to get on with it. They fuck mechanically, gazing with roiling emotions into each others' eyes. They do seem to come to some sort of a non-verbal understanding on the necessity of getting it done, and there is no real unhappiness in either of them when they finish and disentangle themselves. As they clean themselves and exit, you notice ${rapist.slaveName} is looking a little more longingly at ${slave.slaveName}.`);
-		} else if (slave.devotion <= 50 || rapist.devotion <= 50) {
-			r.push(`You order ${slave.slaveName} and ${rapist.slaveName} to get on with it. They fuck mechanically at first, gazing with roiling emotions into each others' eyes. Eventually, they begin to enjoy the intimacy of the act, finding the shared pleasure between them comforting. They finish and resume life as slaves, the light of this intimacy diminishing, softening with ${rapist.slaveName}'s dick and dripping away with the contents of ${slave.slaveName}'s cum-filled pussy.`);
+		}
+		r.push(`${rapist.slaveName} is lying next to ${him} on the bed in a state of obvious satiation and bliss.`);
+	} else if (rapist.energy > 95 && rapist.devotion > 20 && slave.devotion < -20) {
+		r.push(`${slave.slaveName} is tied and placed on the bed with ${his} pussy defenseless and available, and then you tell the randy ${rapist.slaveName} that it's all ${hers2}. The slave life has so affected ${rapist.slaveName} that ${he2} is quite eager to rape another slave, just for the perverted novelty of the act. ${His} high libido keeps ${him} going for a long time, bringing the helpless toy to one forced orgasm after another. By the end of the day ${slave.slaveName} is lying on the bed, all worn out, ${his} cunt`);
+		if (rapist.dick > 0) {
+			r.push(`dripping with cum`);
 		} else {
-			r.push(`The two slaves happily and eagerly get down to business. They take their time with foreplay, humping slowly and gazing into each others' eyes, exchanging kisses almost constantly. After a little while, ${slave.slaveName} looks over ${rapist.slaveName}'s shoulder to where you're sitting, the invitation clear in ${his} eyes. As soon as you stand to come over, they roll over without being ordered to`);
-			if (canDoAnal(slave) && slave.anus > 0) {
-				r.push(`present ${slave.slaveName}'s butthole.`);
+			r.push(`overflowing with juices`);
+		}
+		r.push(`to ${his} horror and resentment, while ${rapist.slaveName} is sleeping next to ${him} in a state of obvious satiation and bliss.`);
+	} else if (slave.devotion <= 20 || rapist.devotion <= 20) {
+		r.push(`You order ${slave.slaveName} onto the couch and tell ${rapist.slaveName} to get on with it. They fuck mechanically, gazing with roiling emotions into each others' eyes. They do seem to come to some sort of a non-verbal understanding on the necessity of getting it done, and there is no real unhappiness in either of them when they finish and disentangle themselves. As they clean themselves and exit, you notice ${rapist.slaveName} is looking a little more longingly at ${slave.slaveName}.`);
+	} else if (slave.devotion <= 50 || rapist.devotion <= 50) {
+		r.push(`You order ${slave.slaveName} and ${rapist.slaveName} to get on with it. They fuck mechanically at first, gazing with roiling emotions into each others' eyes. Eventually, they begin to enjoy the intimacy of the act, finding the shared pleasure between them comforting. They finish and resume life as slaves, the light of this intimacy diminishing, softening with ${rapist.slaveName}'s dick and dripping away with the contents of ${slave.slaveName}'s cum-filled pussy.`);
+	} else {
+		r.push(`The two slaves happily and eagerly get down to business. They take their time with foreplay, humping slowly and gazing into each others' eyes, exchanging kisses almost constantly. After a little while, ${slave.slaveName} looks over ${rapist.slaveName}'s shoulder to where you're sitting, the invitation clear in ${his} eyes. As soon as you stand to come over, they roll over without being ordered to`);
+		if (canDoAnal(slave) && slave.anus > 0) {
+			r.push(`present ${slave.slaveName}'s butthole.`);
 
-				slave.counter.anal++;
-				V.analTotal++;
-			} else {
-				r.push(`invite you into ${slave.slaveName}'s crowded pussy.`);
+			seX(slave, "anal", V.PC);
+		} else {
+			r.push(`invite you into ${slave.slaveName}'s crowded pussy.`);
 
-				slave.counter.vaginal++;
-				V.vaginalTotal++;
-			}
-			r.push(`You take up the offer and penetrate ${slave.slaveName} with your`);
-			if (V.PC.dick > 0) {
-				r.push(`dick.`);
-			} else {
-				r.push(`strap-on.`);
-			}
-			r.push(`With the added stimulus of penetrating a tight hole alongside ${his2} dear ${getWrittenTitle(rapist)}, ${rapist.slaveName} comes indecently hard, but no where near as hard as the completely overloaded ${slave.slaveName}. All of you collapse into an exhausted, happy pile of flesh.`);
+			seX(slave, "vaginal", V.PC);
 		}
-
-		if (canImpreg(slave, rapist)) {
-			knockMeUp(slave, 25, 0, rapist.ID);
+		r.push(`You take up the offer and penetrate ${slave.slaveName} with your`);
+		if (V.PC.dick > 0) {
+			r.push(`dick.`);
+		} else {
+			r.push(`strap-on.`);
 		}
+		r.push(`With the added stimulus of penetrating a tight hole alongside ${his2} dear ${getWrittenTitle(rapist)}, ${rapist.slaveName} comes indecently hard, but no where near as hard as the completely overloaded ${slave.slaveName}. All of you collapse into an exhausted, happy pile of flesh.`);
+	}
 
-		App.Events.addParagraph(el, r);
-		return el;
+	if (canImpreg(slave, rapist)) {
+		knockMeUp(slave, 25, 0, rapist.ID);
 	}
+
+	App.Events.addParagraph(el, r);
+	return el;
 };
diff --git a/src/npc/interaction/passage/matchmaking.js b/src/npc/interaction/passage/matchmaking.js
index 1328f2b2d94964fd156479047c3823303308c314..fd94da123ca3adade9c6b0a54773539f67ca56f3 100644
--- a/src/npc/interaction/passage/matchmaking.js
+++ b/src/npc/interaction/passage/matchmaking.js
@@ -111,13 +111,13 @@ App.Interact.matchmaking = function(slave) {
 		} else if (subSlave.fetish === "boobs" && slave.boobs > 4000) {
 			r.push(`${subSlave.slaveName} fetishized breasts so much that ${he2} thinks ${slave.slaveName}'s udders are one of the sexiest things ${he2}'s ever seen.`);
 		} else if ((slave.fetish === "pregnancy" && subSlave.fetish === "pregnancy") && subSlave.bellyPreg >= 300000 && slave.bellyPreg >= 300000) {
-			r.push(`${slave.slaveName} and ${subSlave.slaveName} are both enormously laden with children, much to the other's delight. They can't wait to explore each other's baby filled middle.`);
+			r.push(`${slave.slaveName} and ${subSlave.slaveName} are both enormously laden with children, much to the other's delight. They can't wait to explore each other's baby-filled middles.`);
 		} else if ((slave.fetish === "pregnancy" && subSlave.fetish === "pregnancy") && subSlave.preg > subSlave.pregData.normalBirth/2 && slave.preg > slave.pregData.normalBirth/2) {
 			r.push(`${slave.slaveName} and ${subSlave.slaveName} are both heavily pregnant, much to the other's delight.`);
 		} else if ((subSlave.fetish === "pregnancy") && slave.bellyPreg >= 300000) {
-			r.push(`${subSlave.slaveName} fetishizes pregnant bellies so much that ${he2} is awestruck by ${slave.slaveName}'s enormous, baby filled middle.`);
+			r.push(`${subSlave.slaveName} fetishizes pregnant bellies so much that ${he2} is awestruck by ${slave.slaveName}'s enormous, baby-filled middle.`);
 		} else if ((slave.fetish === "pregnancy") && subSlave.bellyPreg >= 300000) {
-			r.push(`${slave.slaveName} fetishizes pregnant bellies so much that ${he} is awestruck by ${subSlave.slaveName}'s enormous, baby filled middle.`);
+			r.push(`${slave.slaveName} fetishizes pregnant bellies so much that ${he} is awestruck by ${subSlave.slaveName}'s enormous, baby-filled middle.`);
 		} else if ((subSlave.fetish === "pregnancy") && slave.preg > slave.pregData.normalBirth/2) {
 			r.push(`${subSlave.slaveName} fetishizes pregnant bellies so much that ${he2} thinks ${slave.slaveName} gravid middle is one of the sexiest things ${he2}'s ever seen.`);
 		} else if ((slave.fetish === "pregnancy") && subSlave.preg > subSlave.pregData.normalBirth/2) {
diff --git a/src/npc/interaction/slaveOnSlaveFeeding/fSlaveFeed.js b/src/npc/interaction/slaveOnSlaveFeeding/fSlaveFeed.js
index f79ca53142c4819dd4ce51a7647899ee6f7d0e8a..7f6d4b3ddf81e1fed545568dac6973fe4bf596fe 100644
--- a/src/npc/interaction/slaveOnSlaveFeeding/fSlaveFeed.js
+++ b/src/npc/interaction/slaveOnSlaveFeeding/fSlaveFeed.js
@@ -63,7 +63,7 @@ globalThis.FSlaveFeed = function(slave, milkTap) {
 				r.push(`It takes minimal effort to get ${his2} milk flowing.`);
 			}
 		} else if ((milkTap.fetish === "boobs") && (milkTap.fetishKnown === 1) && (milkTap.fetishStrength > 60) && (milkTap.devotion >= -20)) {
-			r.push(`This is very easy, since ${milkTap.slaveName} loves ${his2} tits played with and can't wait to get suckled.`);
+			r.push(`This is very easy, since ${milkTap.slaveName} loves having ${his2} tits played with and can't wait to get suckled.`);
 			if (milkTap.lactation > 1) {
 				r.push(`${He2} is practically gushing milk with excitement.`);
 			} else {
@@ -559,7 +559,6 @@ globalThis.FSlaveFeed = function(slave, milkTap) {
 			} else {
 				r.push(`big`);
 			}
-			r.push();
 			r.push(`${relativeTerm(milkTap, slave)} suckles from ${his2} breasts. You enjoy the show, specifically the sight of ${slave.slaveName}'s belly steadily growing larger until`);
 			if (slave.inflation === 3) {
 				r.push(`${his} belly is round and taut, making ${him} look pregnant. ${He} pops off ${his} ${relative}'s nipple and settles into ${his2} breasts for a short rest while hiccupping`);
diff --git a/src/npc/startingGirls/startingGirls.js b/src/npc/startingGirls/startingGirls.js
index 0d9ed58d2837caa395ef9ada7e3716877d9f1d40..73fad95f2684224b713ed6f611e399b89f4f159e 100644
--- a/src/npc/startingGirls/startingGirls.js
+++ b/src/npc/startingGirls/startingGirls.js
@@ -275,8 +275,8 @@ App.StartingGirls.uncommittedFamilyTree = function(slave) {
  * @param {App.Entity.SlaveState} slave
  */
 App.StartingGirls.playerOrigin = function(slave) {
-	/** @type {{origin: FC.Zeroable<string>, tattoo?: string, nonPCpregSource?: number}} */
-	const data = {origin: 0};
+	/** @type {{origin: string, tattoo?: string, nonPCpregSource?: number}} */
+	const data = {origin: ""};
 	switch (V.PC.career) {
 		case "wealth":
 		case "trust fund":
@@ -795,7 +795,11 @@ App.StartingGirls.physical = function(slave, cheat = false) {
 					options.addCustomOption(`${capFirstChar(side)} ${limb}: amputated`)
 						.addButton("Restore",
 							() => {
-								slave[limb][side] = new App.Entity.LimbState();
+								if (limb === "arm") {
+									slave[limb][side] = new App.Entity.ArmState();
+								} else {
+									slave[limb][side] = new App.Entity.LegState();
+								}
 							},
 							""
 						);
@@ -1604,20 +1608,15 @@ App.StartingGirls.makeCareerFilterPulldown = function() {
 	const frag = new DocumentFragment();
 	frag.append(`Filter by desired bonus: `);
 
-	const select = document.createElement("select");
-	select.style.fontStyle = "normal";
+	const options = [];
 	for (const cat of App.StartingGirls.careerBonusFilters.keys()) {
-		const choice = App.UI.DOM.appendNewElement("option", select, cat);
-		if (App.StartingGirls.careerFilter === cat) {
-			choice.selected = true;
-		}
+		options.push({key: cat, name: cat});
 	}
-
-	select.onchange = () => {
-		App.StartingGirls.careerFilter = select.value;
+	frag.append(App.UI.DOM.makeSelect(options, App.StartingGirls.careerFilter, cat => {
+		App.StartingGirls.careerFilter = cat;
 		App.UI.reload();
-	};
-	frag.append(select);
+	}));
+
 	return frag;
 };
 
@@ -1800,7 +1799,7 @@ App.StartingGirls.profile = function(slave, cheat = false) {
 		const origin = this.playerOrigin(slave).preview;
 		options.addOption("Origin story", "origin", slave)
 			.customButton("Customize", () => this.playerOrigin(slave).apply(), "")
-			.addComment(origin === 0 ? "No origin available" : pronounsForSlaveProp(slave, origin));
+			.addComment(origin === "" ? "No origin available" : pronounsForSlaveProp(slave, origin));
 	}
 
 	if (slave.prestige) {
@@ -1961,7 +1960,7 @@ App.StartingGirls.skills = function(slave, cheat = false) {
 
 	option = options.addOption("Vaginal sex", "vaginal", slave.skill);
 	if (slave.vagina === 0 && !cheat) {
-		option.addComment("Virgins cannot be given anal skills.");
+		option.addComment("Virgins cannot be given vaginal skills.");
 	} else if (slave.vagina === -1) {
 		option.addComment("Must have a vagina to have vaginal skills.");
 	} else {
@@ -2064,8 +2063,15 @@ App.StartingGirls.finalize = function(slave) {
 			if (slave.pregSource === -1) {
 				V.PC.counter.slavesKnockedUp++;
 			}
+			// Make newSlave keep certain changes
+			slave.override_H_Color = 1;
+			slave.override_Arm_H_Color = 1;
+			slave.override_Brow_H_Color = 1;
+			slave.override_Skin = 1;
+
 			newSlave(clone(slave));
 		};
+
 		if (V.cash - cost > minimumSlaveCost()) {
 			const {him} = getPronouns(slave);
 			App.UI.DOM.appendNewElement("div", el,
diff --git a/src/npc/startingGirls/startingGirlsPassage.js b/src/npc/startingGirls/startingGirlsPassage.js
index 9d158c14c4e70a6bfc10cafd181ab34ea1d00071..668db1063c71b147d6a1649753737de23945ed06 100644
--- a/src/npc/startingGirls/startingGirlsPassage.js
+++ b/src/npc/startingGirls/startingGirlsPassage.js
@@ -115,16 +115,13 @@ App.StartingGirls.passage = function() {
 				App.UI.DOM.appendNewElement("div", el, App.UI.DOM.link(
 					"Novice",
 					() => {
-						V.activeSlave = App.StartingGirls.generate();
+						V.activeSlave = App.StartingGirls.generate({minAge: 18, maxAge: 18});
 						V.activeSlave.skill.anal = 0;
 						V.activeSlave.skill.oral = 0;
 						V.activeSlave.skill.vaginal = 0;
 						V.activeSlave.skill.whoring = 0;
 						V.activeSlave.skill.entertainment = 0;
 						V.activeSlave.skill.combat = 0;
-						V.activeSlave.actualAge = 18;
-						V.activeSlave.visualAge = 18;
-						V.activeSlave.physicalAge = 18;
 						V.activeSlave.fetishKnown = 0;
 						V.activeSlave.attrKnown = 0;
 					},
@@ -339,18 +336,20 @@ App.StartingGirls.passage = function() {
 				`Start over with a finalized slave's relative`,
 				() => {
 					const el = new DocumentFragment();
-					const select = App.UI.DOM.appendNewElement("select", el);
+
+					const options = [];
 					for (const slave of newSlaves) {
-						const option = App.UI.DOM.appendNewElement("option", select, `${SlaveFullName(slave)} (${slave.genes}, ${slave.actualAge})`);
-						option.value = slave.ID.toString();
+						options.push({
+							key: slave.ID.toString(),
+							name: `${SlaveFullName(slave)} (${slave.genes}, ${slave.actualAge})`
+						});
 					}
-					select.selectedIndex = -1;
-					select.onchange = () => {
-						const ID = Number.parseInt(select.options[select.selectedIndex].value);
-						const srcSlave = getSlave(ID);
+					const select = App.UI.DOM.makeSelect(options, null, slaveID => {
+						const srcSlave = getSlave(Number.parseInt(slaveID));
 						jQuery(linkDiv).empty().append(relativeLinkStrip(srcSlave, srcSlave));
-					};
+					});
 					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.combineNodes(`Relative of slave: `, select));
+
 					const linkDiv = App.UI.DOM.appendNewElement("div", el, ``);
 					App.UI.DOM.appendNewElement("div", el, "Warning: related slaves will influence each others' opinion of you, and may become difficult to control if not properly broken.", "note");
 					App.UI.DOM.appendNewElement("div", el, App.UI.DOM.passageLink("Back", "Starting Girls"));
@@ -402,7 +401,7 @@ App.StartingGirls.passage = function() {
 	tabBar.addTab("Stats", "stats", App.StartingGirls.stats(V.activeSlave));
 	tabBar.addTab("Family", "family", App.Intro.editFamily(V.activeSlave));
 	tabBar.addTab("Body Mods", "body-mods", App.UI.bodyModification(V.activeSlave, true));
-	tabBar.addTab("Salon", "salon", App.UI.salon(V.activeSlave, true));
+	tabBar.addTab("Salon", "salon", App.UI.salon(V.activeSlave, true, true));
 	tabBar.addTab("Finalize", "finalize", App.StartingGirls.finalize(V.activeSlave),
 		startingSlaveCost(V.activeSlave) > V.cash ? "show-warning" : undefined);
 	el.append(tabBar.render());
diff --git a/src/npc/surgery/bodySwap/bodySwap.js b/src/npc/surgery/bodySwap/bodySwap.js
index 3d64769a492d9fb53803cb8573bb999c4e2014b7..b532dae1485c0e8cc3918711863375bb596e012e 100644
--- a/src/npc/surgery/bodySwap/bodySwap.js
+++ b/src/npc/surgery/bodySwap/bodySwap.js
@@ -217,7 +217,7 @@ globalThis.bodySwapName = function(soul, body) {
 		} else if (body.birthName) {
 			if (body.slaveSurname) {
 				if (
-					(V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(body.nationality)) ||
+					(V.surnameOrder !== 1 && ["Cambodian", "Chinese", "Ancient Chinese Revivalist", "Hungarian", "Japanese", "Edo Revivalist", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(body.nationality)) ||
 					V.surnameOrder === 2
 				) {
 					soul.origBodyOwner = body.slaveSurname + " " + body.birthName;
@@ -253,6 +253,9 @@ globalThis.bodySwapSelection = function(soul) {
 		if (body.ID === soul.ID) { // Do not allow slave to be swapped with themselves
 			continue;
 		}
+		if (body.indenture !== -1) {
+			continue;
+		}
 		const slaveDiv = document.createElement("div");
 		slaveDiv.append(
 			App.UI.DOM.link(
diff --git a/src/npc/surgery/surgery.js b/src/npc/surgery/surgery.js
index cf8d53b2014ab39900ca9b2a1f75b2846eda819c..b35aaa749cd9e9d47e89c3811534bea1600bffae 100644
--- a/src/npc/surgery/surgery.js
+++ b/src/npc/surgery/surgery.js
@@ -1,89 +1,3 @@
-/**
- * Composes the Procedure object from its parts
- *
- * This function has the only purpose to ensure the result object has all required properties
- * @param {string} typeId
- * @param {string} label
- * @param {number} effect
- * @param {string} desc
- * @param {slaveOperation} [action]
- * @param {number} [costs] money costs
- * @param {number} [hCosts] health costs
- * @param {string} [surgeryType]
- * @param {boolean} [cheat]
- * @returns {FC.Medicine.Surgery.Procedure}
- */
-App.Medicine.Surgery.makeOption = function(typeId, label, effect, desc, action, costs, hCosts, surgeryType, cheat = false) {
-	return {
-		typeId: typeId,
-		label: label,
-		targetEffect: effect,
-		description: desc,
-		costs: (cheat) ? 0 : costs,
-		healthCosts: (cheat) ? 0 : hCosts,
-		action: action,
-		surgeryType: surgeryType
-	};
-};
-
-/**
- * Composes the procedure option with empty .action, i.e. a procedure that can't be applied
- * @param {string} typeId
- * @param {string} label
- * @param {string} desc
- * @returns {FC.Medicine.Surgery.Procedure}
- */
-App.Medicine.Surgery.makeImpossibleOption = function(typeId, label, desc) {
-	return this.makeOption(typeId, label, 0, desc);
-};
-
-/**
- * Various constants for procedures
- */
-App.Medicine.Keys = {
-	Surgery: {
-		Target: {
-			/**
-			 * Type id's for breast-related procedures
-			 */
-			breast: {
-				installImplant: "breast.implant.install",
-				removeImplant: "breast.implant.remove",
-				fillUp: "breast.implant.fill",
-				drain: "breast.implant.drain",
-				changeImplant: "breast.implant.replace",
-				reduction: "breast.tissue.reduce",
-			},
-			/**
-			 * Type id's for butt-related procedures
-			 */
-			butt: {
-				installImplant: "butt.implant.install",
-				removeImplant: "butt.implant.remove",
-				fillUp: "butt.implant.fill",
-				drain: "butt.implant.drain",
-				changeImplant: "but.implant.replace",
-				reduction: "butt.tissue.reduce",
-			}
-		}
-	}
-};
-
-/**
- * Commit procedure, executing its action and subtracting its costs
- * @param {FC.Medicine.Surgery.Procedure} surgery
- * @param {App.Entity.SlaveState} slave
- * @param {boolean} [cheat]
- */
-App.Medicine.Surgery.commit = function(surgery, slave, cheat = false) {
-	V.surgeryType = surgery.surgeryType;
-	surgery.action(slave);
-	if (!cheat) {
-		cashX(forceNeg(surgery.costs), "slaveSurgery", slave);
-		surgeryDamage(slave, surgery.healthCosts, cheat);
-	}
-};
-
 /**
  * @param {App.Medicine.Surgery.Procedure} procedure
  * @param {function():void} refresh
@@ -96,8 +10,13 @@ App.Medicine.Surgery.makeLink = function(procedure, refresh, cheat, onApply) {
 		return App.UI.DOM.disabledLink(procedure.name, procedure.disabledReasons);
 	}
 
+	const note = procedure.note;
 	const slave = procedure.originalSlave;
-	return App.UI.DOM.link(procedure.name, apply, [], "", tooltip());
+	const res = App.UI.DOM.link(procedure.name, apply, [], "", tooltip());
+	if (note) {
+		res.classList.add("with-note");
+	}
+	return res;
 
 	function healthCosts() {
 		const hc = (V.PC.skill.medicine >= 100) ? Math.round(procedure.healthCost / 2) : procedure.healthCost;
@@ -115,13 +34,17 @@ App.Medicine.Surgery.makeLink = function(procedure, refresh, cheat, onApply) {
 
 	function tooltip() {
 		const tooltip = new DocumentFragment();
-		if (procedure.description !== "") {
-			App.UI.DOM.appendNewElement("div", tooltip, `${capFirstChar(procedure.description)}.`);
+		const desc = procedure.description;
+		if (desc !== "") {
+			App.UI.DOM.appendNewElement("div", tooltip, `${capFirstChar(desc)}.`);
 		}
 		if (!cheat) {
 			App.UI.DOM.appendNewElement("div", tooltip, `Surgery costs: ${cashFormat(procedure.cost)}.`);
 			App.UI.DOM.appendNewElement("div", tooltip, `Projected health damage: ${healthCosts()}.`);
 		}
+		if (note) {
+			App.UI.DOM.appendNewElement("div", tooltip, typeof note === "string" ? `${capFirstChar(note)}.` : note);
+		}
 		return tooltip;
 	}
 
@@ -220,21 +143,19 @@ App.Medicine.Surgery.apply = function(procedure, cheat) {
  */
 App.Medicine.Surgery.allSizingOptions = function() {
 	return {
-		augmentation: true,
-		reduction: true,
-		strings: true,
-		replace: true
+		replace: true,
 	};
 };
 
 App.Medicine.Surgery.sizingProcedures = function() {
 	class ForbiddenDummy extends App.Medicine.Surgery.Procedure {
 		/**
+		 * @param {App.Entity.SlaveState} slave
 		 * @param {string} name
 		 * @param {string} forbidden why the surgery can't be used
 		 */
-		constructor(name, forbidden) {
-			super(null);
+		constructor(slave, name, forbidden) {
+			super(slave);
 			this._name = name;
 			this._forbidden = forbidden;
 		}
@@ -244,170 +165,260 @@ App.Medicine.Surgery.sizingProcedures = function() {
 		}
 
 		get disabledReasons() {
-			return [this._forbidden];
+			return super.disabledReasons.concat(this._forbidden);
 		}
 	}
 
 	return {
 		bodyPart: bodyPart,
 		boobs: boobSizingProcedures,
-		butt: buttSizingProcedures
+		butt: buttSizingProcedures,
+		lips: lipsSizingProcedures,
 	};
 
 	/**
 	 * Returns list of available surgeries targeted at changing size of the given body part
-	 * @param {string} bodyPart
+	 * @template {FC.SizingImplantTarget} T
+	 * @param {FC.SizingImplantTarget} bodyPart
 	 * @param {App.Entity.SlaveState} slave
-	 * @param {FC.Medicine.Surgery.SizingOptions} [options]
+	 * @param {FC.Medicine.Surgery.SizingOptions<T>} [options]
 	 * @returns {App.Medicine.Surgery.Procedure[]}
 	 */
 	function bodyPart(bodyPart, slave, options) {
-		if (bodyPart === "boobs") {
-			return boobSizingProcedures(slave, options);
+		switch (bodyPart) {
+			case "boobs":
+				return boobSizingProcedures(slave, options);
+			case "butt":
+				return buttSizingProcedures(slave, options);
+			case "lips":
+				return lipsSizingProcedures(slave, options);
+			default:
+				throw Error(`No sizing procedures for ${bodyPart}`);
+		}
+	}
+
+	/**
+	 * @template {FC.SizingImplantTarget} T
+	 * @param {FC.BodyPartInstalledImplantType<T>} type
+	 * @param {FC.Data.Medicine.SizingImplants.ImplantType} implantData
+	 * @param {number} volume
+	 * @param {FC.Medicine.ImplantInfo<T>} implantInfo
+	 * @returns {boolean}
+	 */
+	function implantsAreSame(type, implantData, volume, implantInfo) {
+		if (implantInfo.type !== type) {
+			return false;
 		}
-		if (bodyPart === "butt") {
-			return buttSizingProcedures(slave, options);
+		if (!implantData.fill) {
+			return volume === implantInfo.volume;
 		}
-		throw Error(`No sizing procedures for ${bodyPart}`);
+		return implantInfo.volume.isBetween(volume, implantData.fill.limit, true);
 	}
 
 	/**
-	 * @param {App.Entity.SlaveState} slave
-	 * @param {FC.Medicine.Surgery.SizingOptions} [options]
+	 * @template {FC.SizingImplantTarget} Target
+	 * @param {FC.Medicine.Surgery.SizingOptions<Target>} options
+	 * @param {FC.SizingImplantTarget} target
+	 * @returns {FC.Medicine.Surgery.DefinitiveSizedOptions<Target>}
+	 */
+	function substituteImplicitOptions(options, target) {
+		return {
+			allowedTypes: options.allowedTypes || new Set(["none", ...App.Medicine.implantTypesForTarget(target)]),
+			replace: options.replace || false,
+			// reversed range to include all sizing options
+			targetSize: options.targetSize || App.Utils.makeRange(App.Medicine.maxAssetSize(target), 0),
+		};
+	}
+
+	/**
+	 * @param {number} value
+	 * @param {FC.NumericRange} range
+	 * @returns {number}
+	 */
+	function distanceToRange(value, range) {
+		if (range.max >= range.min) {
+			return App.Utils.distanceToRange(value, range);
+		} else { // reversed range
+			return App.Utils.distanceToRange(value, App.Utils.makeRange(range.max, range.min));
+		}
+	}
+
+	/**
+	 * @param {number} d1
+	 * @param {number} d2
+	 * @param {FC.NumericRange} range
+	 * @returns {boolean}
+	 */
+	function distanceToRangeDecreased(d1, d2, range) {
+		return range.max >= range.min ? d2 < d1 : d2 <= d1;
+	}
+
+	/**
+	 * @param {number} p1
+	 * @param {number} p2
+	 * @param {FC.NumericRange} range
+	 * @returns {boolean}
+	 */
+	function pointIsCloserToRange(p1, p2, range) {
+		return distanceToRangeDecreased(distanceToRange(p1, range), distanceToRange(p2, range), range);
+	}
+
+	/**
+	 * @template {FC.SizingImplantTarget} T
+	 * @param {FC.SlaveState} slave
+	 * @param {T} target
+	 * @param {FC.Medicine.Surgery.DefinitiveSizedOptions<T>} options
+	 * @param {FC.Medicine.ImplantProcedureCreators} creators
 	 * @returns {App.Medicine.Surgery.Procedure[]}
 	 */
-	function boobSizingProcedures(slave, options = {}) {
-		const thisArcology = V.arcologies[0];
-		const largeImplantsAvailable = thisArcology.FSTransformationFetishistResearch === 1;
-		const advancedSurgeryAvailable = V.ImplantProductionUpgrade === 1;
-		const {he, His} = getPronouns(slave);
+	function implantSizingProcedures(slave, target, options, creators) {
+		/** @type {App.Medicine.Surgery.Procedure[]} */
+		const procedures = [];
+
+		const current = App.Medicine.implantInfo(slave, target);
+		const currentDistance = distanceToRange(current.volume, options.targetSize);
+		const curImplantData = current.type !== "none" ? App.Data.Medicine.sizingImplants[target][current.type] : null;
+		const curFleshSize = App.Medicine.fleshSize(slave, target);
+		const maxVolume = App.Medicine.pocketVolume[target](slave);
+		const maxPureImplantVolume = maxVolume - curFleshSize;
+		const maxAssetVolume = App.Medicine.maxAssetSize(target);
+
+		const addMaxAssetSizeReachedDummy = (name) => {
+			const {His} = getPronouns(slave);
+			procedures.push(new ForbiddenDummy(slave, name, `${His} ${target} size reached the limit.`));
+		};
+
+		const distanceDecreased = (newValue) => {
+			return distanceToRangeDecreased(currentDistance, distanceToRange(newValue, options.targetSize), options.targetSize);
+		};
 
-		const areStringsInstalled = slave.boobsImplantType === "string";
-		const areFillablesInstalled = ["fillable", "advanced fillable", "hyper fillable"].includes(slave.boobsImplantType);
-		const curSize = slave.boobsImplant;
-		const implantType = slave.boobsImplantType;
+		/**
+		 * @param {FC.Data.Medicine.SizingImplants.ImplantType} data
+		 * @returns {number[]}
+		 */
+		const availableSizes = (data) => {
+			const sizes = data.availableSizes;
+			return typeof sizes === "function" ? sizes() : sizes;
+		};
 
 		/**
-		 * @type {Array<App.Medicine.Surgery.Procedure>}
+		 * @param {FC.Data.Medicine.SizingImplants.FillDrainData} fd
 		 */
-		let procedures = [];
-		if (options.augmentation) {
-			if (slave.indentureRestrictions >= 2) {
-				procedures.push(new ForbiddenDummy("Change boob size", `${His} indenture forbids elective surgery.`));
-			} else if (slave.breastMesh === 1) {
-				procedures.push(new ForbiddenDummy("Put implants", `${His} supportive mesh implant blocks implantation.`));
-			} else if (curSize === 0) {
-				if (options.strings) {
-					procedures.push(new App.Medicine.Surgery.Procedures.InstallBoobImplants(slave, "string", "string", 400));
-				}
-				if (advancedSurgeryAvailable) {
-					procedures.push(new App.Medicine.Surgery.Procedures.InstallBoobImplants(slave, "large", "normal", 600));
-				}
-				procedures.push(new App.Medicine.Surgery.Procedures.InstallBoobImplants(slave, "standard", "normal", 400));
-				procedures.push(new App.Medicine.Surgery.Procedures.InstallBoobImplants(slave, "small", "normal", 200));
-			} else if (implantType === "normal") {
-				if (curSize > 400) {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "fillable", "fillable", 800));
-				} else if (curSize > 200) {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "large", "normal", 600));
-				} else {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "standard", "normal", 400));
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "large", "normal", 600));
+		const indenturePermitsFillDrain = (fd) => {
+			return slave.indentureRestrictions < 2 || fd.healthCost === 0;
+		};
+
+		// filling/draining the current implants go first
+		if (curImplantData && options.allowedTypes.has(current.type)) {
+			if (curImplantData.fill && current.volume < options.targetSize.min && indenturePermitsFillDrain(curImplantData.fill)) {
+				let maxVolumeReached = true;
+				let fillingPossible = false;
+				for (const fillVolume of curImplantData.fill.step) {
+					const newVolume = current.volume + fillVolume;
+					if (curImplantData.fill.limit >= newVolume && distanceDecreased(newVolume)) {
+						if (slave[target] + fillVolume <= maxAssetVolume) {
+							maxVolumeReached = false;
+							if (newVolume <= maxPureImplantVolume) {
+								procedures.push(creators.fill(slave, fillVolume));
+								fillingPossible = true;
+							}
+						}
+					}
 				}
-			} else if (implantType === "hyper fillable") {
-				if (slave.boobs >= 50000) {
-					procedures.push(new ForbiddenDummy("Increase boobs", `${His} breasts are as large as ${he} can physically support.`));
-				} else {
-					procedures.push(new App.Medicine.Surgery.Procedures.FillBoobImplants(slave, 1000));
+				if (!fillingPossible) {
+					const {His} = getPronouns(slave);
+					procedures.push(new ForbiddenDummy(slave, "Fill up", `${His} ${target} implants are filled to capacity.`));
+				} else if (maxVolumeReached) {
+					addMaxAssetSizeReachedDummy("Fill up");
 				}
-			} else if (implantType === "advanced fillable") {
-				if (curSize >= 10000) {
-					procedures.push(new ForbiddenDummy("Increase boobs", `${His} implants are filled to capacity.`));
-					if (largeImplantsAvailable) {
-						procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "hyper fillable", "hyper fillable", 11000));
+			}
+			if (curImplantData.drain && indenturePermitsFillDrain(curImplantData.drain)) {
+				for (const drainVolume of curImplantData.drain.step) {
+					if (curImplantData.drain.limit <= current.volume - drainVolume && distanceDecreased(current.volume - drainVolume)) {
+						procedures.push(creators.drain(slave, drainVolume));
 					}
-				} else {
-					procedures.push(new App.Medicine.Surgery.Procedures.FillBoobImplants(slave, 400));
-				}
-			} else if (implantType === "fillable") {
-				if (curSize >= 1800) {
-					procedures.push(new ForbiddenDummy("Add inert filler", `${His} implants are filled to capacity.`));
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "advanced fillable", "advanced fillable", 2200, true));
-				} else {
-					procedures.push(new App.Medicine.Surgery.Procedures.FillBoobImplants(slave, 200));
 				}
 			}
 		}
 
-		if (options.replace && slave.indentureRestrictions < 2 && curSize > 0) {
-			if (!areStringsInstalled && curSize < 600) {
-				procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "string", "string", 400));
-			} else if (areStringsInstalled) {
-				// we have engorged string implants, suggest replacing with normal implants of similar size
-				if (curSize > 10000) {
-					if (largeImplantsAvailable) {
-						if (slave.boobs < 50000) {
-							procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "hyper fillable", "hyper fillable", Math.round(curSize / 1000) * 1000));
+		// all the other procedures require indentureRestrictions < 2
+		if (slave.indentureRestrictions >= 2) {
+			const {His} = getPronouns(slave);
+			procedures.push(new ForbiddenDummy(slave, "Implantation", `${His} indenture forbids invasive surgery.`));
+			return procedures;
+		}
+
+		// change implant type if required
+		if (curImplantData && options.replace && !options.allowedTypes.has(current.type)) {
+			for (const type of options.allowedTypes.values()) {
+				if (type === "none") {
+					continue; // handled below
+				}
+				const data = App.Data.Medicine.sizingImplants[target][type];
+				for (const volume of availableSizes(data)) {
+					if (App.Utils.distanceToRange(volume, options.targetSize) === 0) {
+						const fleshExcess = Math.ceil(volume - maxPureImplantVolume);
+						if (volume <= maxPureImplantVolume || options.allowedTypes.has("none")) {
+							procedures.push(creators.replace(slave, type, volume, fleshExcess));
 						}
 					}
-				} else if (curSize > 2200) {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "advanced fillable", "advanced fillable", Math.round(curSize / 400) * 400, true));
-				} else if (curSize > 400) {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "fillable", "fillable", Math.round(curSize / 200) * 200));
-				} else {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceBoobImplants(slave, "standard", "normal", 400));
 				}
 			}
 		}
 
-		if (options.reduction && (slave.boobs > 300 || curSize > 0)) {
-			if (curSize > 0) {
-				if (areStringsInstalled && curSize > 400) {
-					if (curSize > 8000) {
-						procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 1000));
-					} else if (curSize > 5000) {
-						procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 750));
-					} else if (curSize > 2000) {
-						procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 500));
-					} else if (curSize > 1000) {
-						procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 250));
-					} else if (curSize > 500) {
-						procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 100));
+		// install an implant or replace with a bigger one
+		if (distanceDecreased(current.volume + 1)) {
+			let maxVolumeReached = true;
+			const curAssetSize = App.Medicine.assetSize(slave, target);
+			const currentCanBeReplaced = options.replace || options.allowedTypes.has(current.type);
+			for (const [type, data] of Object.entries(App.Data.Medicine.sizingImplants[target])) {
+				if (!options.allowedTypes.has(type)) {
+					continue;
+				}
+				for (const volume of availableSizes(data)) {
+					if (!distanceDecreased(volume)) {
+						continue;
 					}
-				} else if (areFillablesInstalled) {
-					if (implantType === "hyper fillable") {
-						if (curSize <= 10000) {
-							procedures.push(new ForbiddenDummy("Remove filler", `${His} implants are empty.`));
-						} else {
-							procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 1000));
-						}
-					} else if (implantType === "advanced fillable") {
-						if (curSize <= 1000) {
-							procedures.push(new ForbiddenDummy("Remove filler", `${His} implants are empty.`));
-						} else {
-							procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 500));
-						}
-					} else if (implantType === "fillable") {
-						if (curSize <= 500) {
-							procedures.push(new ForbiddenDummy("Remove filler", `${His} implants are empty.`));
+					if (curAssetSize - current.volume + volume <= maxVolume) {
+						maxVolumeReached = false;
+					} else {
+						continue;
+					}
+					const fleshExcess = Math.ceil(volume - maxPureImplantVolume);
+					if (volume >= current.volume && distanceDecreased(volume) && (volume <= maxPureImplantVolume ||
+						(options.allowedTypes.has("none")))) {
+						maxVolumeReached = false;
+						if (current.volume > 0) {
+							if (currentCanBeReplaced && !implantsAreSame(type, data, volume, current)) {
+								procedures.push(creators.replace(slave, type, volume, fleshExcess));
+							}
 						} else {
-							procedures.push(new App.Medicine.Surgery.Procedures.DrainBoobImplants(slave, 100));
+							procedures.push(creators.install(slave, type, volume, fleshExcess));
 						}
 					}
 				}
-				if (slave.indentureRestrictions < 2) {
-					procedures.push(new App.Medicine.Surgery.Procedures.RemoveBoobImplants(slave));
-				}
 			}
-			if ((slave.boobs > 300) && (curSize === 0) && slave.indentureRestrictions < 2) {
-				procedures.push(new App.Medicine.Surgery.Procedures.ReduceBoobs(slave, "reduce", 200));
-				if (slave.boobs < 675) {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReduceBoobs(slave, "slightly reduce", 25));
-				}
+			if (maxVolumeReached) {
+				addMaxAssetSizeReachedDummy("Bigger implants");
 			}
-			if ((curSize === 0) && slave.indentureRestrictions < 2 && (slave.breedingMark !== 1 || V.propOutcome !== 1 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) {
-				if (slave.boobs >= 2000) {
-					procedures.push(new App.Medicine.Surgery.Procedures.Mastectomy(slave));
+		}
+
+		// remove the current implant or replace with a smaller one
+		if (current.volume > 0 && distanceDecreased(current.volume - 1)) {
+			if (options.targetSize.max <= 0) {
+				procedures.push(creators.remove(slave));
+			}
+
+			if (options.replace) {
+				for (const [type, data] of Object.entries(App.Data.Medicine.sizingImplants[target])) {
+					if (!options.allowedTypes.has(type)) {
+						continue;
+					}
+					for (const volume of availableSizes(data).filter(s => s < current.volume && distanceDecreased(s))) {
+						if (!implantsAreSame(type, data, volume, current)) {
+							procedures.push(creators.replace(slave, type, volume, 0));
+						}
+					}
 				}
 			}
 		}
@@ -416,126 +427,73 @@ App.Medicine.Surgery.sizingProcedures = function() {
 
 	/**
 	 * @param {App.Entity.SlaveState} slave
-	 * @param {FC.Medicine.Surgery.SizingOptions} [options]
+	 * @param {FC.Medicine.Surgery.SizingOptions<"boobs">} [options]
 	 * @returns {App.Medicine.Surgery.Procedure[]}
 	 */
-	function buttSizingProcedures(slave, options = {}) {
-		const thisArcology = V.arcologies[0];
-		const largeImplantsAvailable = thisArcology.FSTransformationFetishistResearch === 1;
-		const advancedSurgeryAvailable = V.ImplantProductionUpgrade === 1;
-		const {His} = getPronouns(slave);
+	function boobSizingProcedures(slave, options = {}) {
+		// check if implant-related surgeries are allowed for this slave
+		if (slave.breastMesh === 1) {
+			const {his, His} = getPronouns(slave);
+			return [new ForbiddenDummy(slave, "Implants", `${His} supportive mesh implant blocks resizing ${his} boobs.`)];
+		}
 
-		const areStringsInstalled = slave.buttImplantType === "string";
-		const areFillablesInstalled = ["fillable", "advanced fillable", "hyper fillable"].includes(slave.buttImplantType);
-		const curSize = slave.buttImplant;
-		const implantType = slave.buttImplantType;
+		const p = App.Medicine.Surgery.Procedures.boobImplantsProcedure;
+		const dOptions = substituteImplicitOptions(options, "boobs");
 
-		/**
-		 * @type {Array<App.Medicine.Surgery.Procedure>}
-		 */
-		let procedures = [];
-		if (options.augmentation) {
-			if (slave.indentureRestrictions >= 2) {
-				procedures.push(new ForbiddenDummy("Change butt size", `${His} indenture forbids elective surgery.`));
-			} else if (slave.butt > 19 && areFillablesInstalled) {
-				procedures.push(new ForbiddenDummy("Increase butt", `${His} butt is as large as it can possibly get.`));
-			} else if (curSize === 0) {
-				if (options.strings) {
-					procedures.push(new App.Medicine.Surgery.Procedures.InstallButtImplants(slave, "string", "string", 1));
-				}
-				if (advancedSurgeryAvailable) {
-					procedures.push(new App.Medicine.Surgery.Procedures.InstallButtImplants(slave, "big", "normal", 2));
-				}
-				procedures.push(new App.Medicine.Surgery.Procedures.InstallButtImplants(slave, "standard", "normal", 1));
-			} else if (implantType === "normal") {
-				if (curSize >= 5) {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "advanced fillable", "advanced fillable", curSize, true));
-				} else if (curSize >= 2) {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "fillable", "fillable", 3));
-				} else if (curSize === 1) {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "bigger", "normal", 2));
-				}
-			} else if (implantType === "hyper fillable") {
-				if (curSize > 19) {
-					procedures.push(new ForbiddenDummy("Increase butt", `${His} butt implants are filled to capacity.`));
-				} else {
-					procedures.push(new App.Medicine.Surgery.Procedures.FillButtImplants(slave, 1));
+		const procedures = implantSizingProcedures(slave, "boobs", dOptions, p);
+
+		// boob-specific reduction procedures
+		if (slave.indentureRestrictions < 2 && slave.boobsImplant === 0 && dOptions.allowedTypes.has("none")) {
+			if (App.Medicine.fleshSize(slave, "boobs") > 300) {
+				if (pointIsCloserToRange(slave.boobs, slave.boobs - 200, dOptions.targetSize)) {
+					procedures.push(p.reduce(slave, "reduce", 200));
 				}
-			} else if (implantType === "advanced fillable") {
-				if (curSize > 7) {
-					procedures.push(new ForbiddenDummy("Increase butt", `${His} butt implants are filled to capacity.`));
-					if (largeImplantsAvailable) {
-						procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "hyper fillable", "hyper fillable", 9));
+				if (App.Medicine.fleshSize(slave, "boobs") < 675) {
+					if (pointIsCloserToRange(slave.boobs, slave.boobs - 25, dOptions.targetSize)) {
+						procedures.push(p.reduce(slave, "slightly reduce", 25));
 					}
-				} else {
-					procedures.push(new App.Medicine.Surgery.Procedures.FillButtImplants(slave, 1));
 				}
-			} else if (implantType === "fillable") {
-				if (curSize >= 4) {
-					procedures.push(new ForbiddenDummy("Increase size", `${His} implants are filled to capacity.`));
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "advanced fillable", "advanced fillable", 5, true));
-				} else {
-					procedures.push(new App.Medicine.Surgery.Procedures.FillButtImplants(slave, 1));
+			}
+			if ((slave.breedingMark !== 1 || V.propOutcome !== 1 || V.eugenicsFullControl === 1 || V.arcologies[0].FSRestart === "unset")) {
+				if (App.Medicine.fleshSize(slave, "boobs") >= 2000 && pointIsCloserToRange(slave.boobs, 0, dOptions.targetSize)) {
+					procedures.push(new App.Medicine.Surgery.Procedures.Mastectomy(slave));
 				}
 			}
 		}
+		return procedures;
+	}
 
-		if (options.replace && slave.indentureRestrictions < 2 && curSize > 0) {
-			if (!areStringsInstalled && curSize === 1) {
-				procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "string", "string", 1));
-			} else if (areStringsInstalled) {
-				// we have engorged string implants, suggest replacing with normal implants of similar size
-				if (curSize >= 9) {
-					if (largeImplantsAvailable) {
-						procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "hyper fillable", "hyper fillable", curSize));
-					}
-				} else if (curSize >= 5) {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "advanced fillable", "advanced fillable", curSize, true));
-				} else if (curSize >= 3) {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "fillable", "fillable", curSize));
-				} else if (curSize === 2) {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "big", "normal", curSize));
-				} else {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReplaceButtImplants(slave, "standard", "normal", curSize));
-				}
-			}
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {FC.Medicine.Surgery.SizingOptions<"butt">} [options]
+	 * @returns {App.Medicine.Surgery.Procedure[]}
+	 */
+	function buttSizingProcedures(slave, options = {}) {
+		const dOptions = substituteImplicitOptions(options, "butt");
+		const p = App.Medicine.Surgery.Procedures.buttImplantsProcedure;
+		const procedures = implantSizingProcedures(slave, "butt", dOptions, p);
+
+		if (slave.buttImplant === 0 && slave.butt > 1 && dOptions.allowedTypes.has("none") &&
+			slave.indentureRestrictions < 2 && pointIsCloserToRange(slave.butt, slave.butt - 1, dOptions.targetSize)) {
+			procedures.push(p.reduce(slave, "reduce", 1));
 		}
+		return procedures;
+	}
 
-		if (options.reduction) {
-			if (curSize > 0) {
-				if (areStringsInstalled && curSize > 1) {
-					procedures.push(new App.Medicine.Surgery.Procedures.DrainButtImplants(slave, 1));
-				} else if (areFillablesInstalled) {
-					if (implantType === "hyper fillable") {
-						if (curSize <= 5) {
-							procedures.push(new ForbiddenDummy("Remove filler", `${His} implants are empty.`));
-						} else {
-							procedures.push(new App.Medicine.Surgery.Procedures.DrainButtImplants(slave, 1));
-						}
-					} else if (implantType === "advanced fillable") {
-						if (curSize <= 3) {
-							procedures.push(new ForbiddenDummy("Remove filler", `${His} implants are empty.`));
-						} else {
-							procedures.push(new App.Medicine.Surgery.Procedures.DrainButtImplants(slave, 1));
-						}
-					} else if (implantType === "fillable") {
-						if (curSize <= 1) {
-							procedures.push(new ForbiddenDummy("Remove filler", `${His} implants are empty.`));
-						} else {
-							procedures.push(new App.Medicine.Surgery.Procedures.DrainButtImplants(slave, 1));
-						}
-					}
-				}
-				if (slave.indentureRestrictions < 2) {
-					procedures.push(new App.Medicine.Surgery.Procedures.RemoveButtImplants(slave));
-				}
-			}
-			if ((slave.butt > 1) && (curSize === 0)) {
-				if (slave.indentureRestrictions < 2) {
-					procedures.push(new App.Medicine.Surgery.Procedures.ReduceButt(slave, "reduce", 1));
-				}
-			}
+	/**
+	 * @param {App.Entity.SlaveState} slave
+	 * @param {FC.Medicine.Surgery.SizingOptions<"lips">} [options]
+	 * @returns {App.Medicine.Surgery.Procedure[]}
+	 */
+	function lipsSizingProcedures(slave, options) {
+		const dOptions = substituteImplicitOptions(options, "lips");
+		const p = App.Medicine.Surgery.Procedures.lipImplantProcedure;
+		const procedures = implantSizingProcedures(slave, "lips", dOptions, p);
+
+		if (slave.lips >= 10 && slave.lipsImplant === 0 && slave.indentureRestrictions < 2) {
+			procedures.push(p.reduce(slave, "reduce", 10));
 		}
+
 		return procedures;
 	}
 }();
@@ -550,14 +508,14 @@ App.Medicine.Surgery.sizingProcedures = function() {
 globalThis.surgeryAmp = function(slave, part, cheat = false) {
 	switch (part) {
 		case "left ear":
-			delete slave.brand["left ear"];
+			App.Medicine.Modification.removeBrand(slave, "left ear");
 			slave.earShape = "none";
 			slave.earT = "none";
 			slave.piercing.ear.weight = 0;
 			surgeryDamage(slave, 10, cheat);
 			break;
 		case "right ear":
-			delete slave.brand["right ear"];
+			App.Medicine.Modification.removeBrand(slave, "right ear");
 			slave.earShape = "none";
 			slave.earT = "none";
 			slave.piercing.ear.weight = 0;
@@ -567,10 +525,16 @@ globalThis.surgeryAmp = function(slave, part, cheat = false) {
 			slave.dick = 0;
 			slave.foreskin = 0;
 			slave.skill.vaginal = 0;
-			slave.piercing.dick.weight = 0;
 			slave.dickTat = 0;
 			slave.dickAccessory = "none";
 			slave.chastityPenis = 0;
+			if (slave.vagina === -1) {
+				slave.piercing.genitals.weight = 0;
+				slave.piercing.genitals.smart = false;
+			}
+			if (slave.drugs === "penis enhancement" || slave.drugs === "hyper penis enhancement" || slave.drugs === "breast redistributors") {
+				slave.drugs = "no drugs";
+			}
 			surgeryDamage(slave, 20, cheat);
 			break;
 		case "vagina":
@@ -739,7 +703,7 @@ globalThis.setGeneticEyeColor = function(slave, color, heterochromia = false) {
  * Takes heterochromia and albinism into account.
  *
  * @param {FC.HumanState} slave
- * @param {string} [side]
+ * @param {FC.BodySideAll} [side="both"]
  */
 globalThis.resetEyeColor = function(slave, side = "both") {
 	if (side === "both") {
@@ -752,9 +716,9 @@ globalThis.resetEyeColor = function(slave, side = "both") {
 		return;
 	}
 
-	slave.eye[side].iris = getGeneticEyeColor(slave, side);
-	slave.eye[side].pupil = "circular";
-	slave.eye[side].sclera = "white";
+	slave.eye[side].iris = getGeneticEyeColor(slave, side, "iris");
+	slave.eye[side].pupil = getGeneticEyeColor(slave, side, "pupil");
+	slave.eye[side].sclera = getGeneticEyeColor(slave, side, "sclera");
 };
 
 /**
@@ -807,10 +771,6 @@ globalThis.removeLimbs = function(slave, limb) {
 				return;
 			}
 			remove("arm", "left");
-			delete slave.brand["left upper arm"];
-			delete slave.brand["left lower arm"];
-			delete slave.brand["left wrist"];
-			delete slave.brand["left hand"];
 			// slave.armsTat = 0;
 			if (!hasAnyArms(slave)) {
 				slave.armAccessory = "none";
@@ -822,10 +782,6 @@ globalThis.removeLimbs = function(slave, limb) {
 				return;
 			}
 			remove("arm", "right");
-			delete slave.brand["right upper arm"];
-			delete slave.brand["right lower arm"];
-			delete slave.brand["right wrist"];
-			delete slave.brand["right hand"];
 			// slave.armsTat = 0;
 			if (!hasAnyArms(slave)) {
 				slave.armAccessory = "none";
@@ -837,10 +793,6 @@ globalThis.removeLimbs = function(slave, limb) {
 				return;
 			}
 			remove("leg", "left");
-			delete slave.brand["left thigh"];
-			delete slave.brand["left calf"];
-			delete slave.brand["left ankle"];
-			delete slave.brand["left foot"];
 			cleanLegs();
 			break;
 		case "right leg":
@@ -848,10 +800,6 @@ globalThis.removeLimbs = function(slave, limb) {
 				return;
 			}
 			remove("leg", "right");
-			delete slave.brand["right thigh"];
-			delete slave.brand["right calf"];
-			delete slave.brand["right ankle"];
-			delete slave.brand["right foot"];
 			cleanLegs();
 			break;
 		case "all":
@@ -874,13 +822,21 @@ globalThis.removeLimbs = function(slave, limb) {
  * @param {number} id
  */
 globalThis.attachLimbs = function(slave, limb, id) {
+	/**
+	 * @param {"arm"|"leg"} limb
+	 * @param {FC.BodySide} side
+	 */
 	function attach(limb, side) {
 		let prosthetic = findProsthetic(slave, limbToProsthetic(id));
 
 		if (prosthetic) {
 			slave[limb][side] = prosthetic[limb][side];
 		} else {
-			slave[limb][side] = new App.Entity.LimbState();
+			if (limb === "arm") {
+				slave[limb][side] = new App.Entity.ArmState();
+			} else {
+				slave[limb][side] = new App.Entity.LegState();
+			}
 			slave[limb][side].type = id;
 		}
 	}
@@ -1087,7 +1043,7 @@ globalThis.beginFuckdoll = function(slave) {
  * @returns {number}
  */
 globalThis.faceSurgeryArtificiality = function() {
-	return 25
-		- (5 * Math.trunc(V.PC.skill.medicine / 50))
-		- (10 * V.surgeryUpgrade);
+	return 25 -
+		(5 * Math.trunc(V.PC.skill.medicine / 50)) -
+		(10 * V.surgeryUpgrade);
 };
diff --git a/src/personalAssistant/assistantAppearance.js b/src/personalAssistant/assistantAppearance.js
index e713166e86c5b3cec0dcb9fc1afcef2b61a1bae4..27c9f3d2e606b204bc98d0dd94023a6a3bb61af2 100644
--- a/src/personalAssistant/assistantAppearance.js
+++ b/src/personalAssistant/assistantAppearance.js
@@ -1960,21 +1960,18 @@ globalThis.availableAssistantAppearances = function() {
 	const el = document.createElement("div");
 	const {hisA} = getPronouns(assistant.pronouns().main).appendSuffix('A');
 	el.append(`Select ${hisA} appearance: `);
-	const select = App.UI.DOM.appendNewElement("select", el);
+
+	const options = [];
 	for (const [appearance, obj] of App.Data.Assistant.appearances) {
 		if (obj.requirements) {
-			const option = App.UI.DOM.appendNewElement("option", select, capFirstChar(appearance));
-			option.value = appearance;
-			if (V.assistant.appearance === appearance) {
-				option.selected = true;
-			}
+			options.push({key: appearance, name: capFirstChar(appearance)});
 		}
 	}
-	select.onchange = () => {
-		const O = select.options[select.selectedIndex];
-		V.assistant.appearance = /** @type {assistantAppearance} */ (O.value);
+	el.append(App.UI.DOM.makeSelect(options, V.assistant.appearance, appearance => {
+		V.assistant.appearance =/** @type {assistantAppearance} */ (appearance);
 		App.UI.reload();
-	};
+	}));
+
 	return el;
 };
 
diff --git a/src/personalAssistant/assistantOptions.js b/src/personalAssistant/assistantOptions.js
index 21211544daa5c96cd76cb28f9a73609ea50832d2..1d5a50918b1c162b465bdf2a49e90bdf102ad061 100644
--- a/src/personalAssistant/assistantOptions.js
+++ b/src/personalAssistant/assistantOptions.js
@@ -15,23 +15,22 @@ App.UI.personalAssistantOptions = function() {
 	let r = [];
 	r.push(`Seated at your desk, you glance at the visual representation of`);
 	if (V.assistant.announcedName) {
-		r.push(App.UI.DOM.combineNodes(
-			App.UI.DOM.makeTextBox(V.assistant.name, (v) => V.assistant.name = v), ","
-		));
-		if (V.assistant.name !== "your personal assistant") {
-			r.push(App.UI.DOM.link(
-				"(Stop using a custom name)",
-				() => {
-					V.assistant.name = "your personal assistant";
-					App.UI.reload();
-				}
-			));
-		}
+		r.push(App.UI.DOM.makeTextBox(V.assistant.name, (v) => V.assistant.name = v));
 	} else {
-		r.push(`${V.assistant.name},`);
+		r.push(`${V.assistant.name}`);
 	}
 	r.push(`in a corner of your desk's glass top.`);
 
+	if (V.assistant.name !== "your personal assistant") {
+		r.push(App.UI.DOM.makeElement("div", App.UI.DOM.link(
+			`Stop using a custom name`,
+			() => {
+				V.assistant.name = "your personal assistant";
+				App.UI.reload();
+			}
+		), ['indent']));
+	}
+
 	App.Events.addParagraph(node, r);
 
 	App.UI.DOM.appendNewElement("p", node, PersonalAssistantAppearance());
@@ -60,55 +59,41 @@ App.UI.personalAssistantOptions = function() {
 			const memoryCost = Math.trunc(20000 * V.upgradeMultiplierArcology * V.HackingSkillMultiplier);
 			App.Events.addParagraph(frag, [
 				`The first upgrade needed is a switch to a holographic memory core to store the immense quantity of data ${V.assistant.name} gathers.`,
-				App.UI.DOM.link(
-					"Install holographic memory core",
-					() => {
-						cashX(forceNeg(memoryCost), "capEx");
-						V.assistant.power += 1;
+				makePurchase(`Install holographic memory core`, memoryCost, "capEx", {
+					handler: () => {
+						V.assistant.power++;
 						V.PC.skill.engineering += 1;
 						V.PC.skill.hacking += 1;
 						App.UI.reload();
-					},
-					[],
-					"",
-					`Will cost ${cashFormat(memoryCost)}`
-				)
+					}
+				}),
 			]);
 		} else if (V.assistant.power === 1) {
 			const coolingCost = Math.trunc(35000 * V.upgradeMultiplierArcology * V.HackingSkillMultiplier);
 			App.Events.addParagraph(frag, [
 				`The next upgrade needed is a liquid nitrogen cooling system to allow for extensive overclocking.`,
-				App.UI.DOM.link(
-					"Install upgraded cooling system",
-					() => {
-						cashX(forceNeg(coolingCost), "capEx");
-						V.assistant.power += 1;
+				makePurchase(`Install upgraded cooling system`, coolingCost, "capEx", {
+					notes: [`will allow you to upgrade the smart piercings in ${V.arcologies[0].name}`],
+					handler: () => {
+						V.assistant.power++;
 						V.PC.skill.engineering += 1;
 						V.PC.skill.hacking += 1;
 						App.UI.reload();
-					},
-					[],
-					"",
-					`Will cost ${cashFormat(coolingCost)} and will allow you to upgrade the smart piercings in ${V.arcologies[0].name}`
-				)
+					}
+				}),
 			]);
 		} else if (V.assistant.power === 2) {
 			const opticalCost = Math.trunc(50000 * V.upgradeMultiplierArcology * V.HackingSkillMultiplier);
 			App.Events.addParagraph(frag, [
 				`The final upgrade needed is a transition to optical RAM.`,
-				App.UI.DOM.link(
-					"Install optical RAM",
-					() => {
-						cashX(forceNeg(opticalCost), "capEx");
-						V.assistant.power += 1;
+				makePurchase(`Install optical RAM`, opticalCost, "capEx", {
+					handler: () => {
+						V.assistant.power++;
 						V.PC.skill.engineering += 1;
 						V.PC.skill.hacking += 1;
 						App.UI.reload();
-					},
-					[],
-					"",
-					`Will cost ${cashFormat(opticalCost)}`
-				)
+					}
+				}),
 			]);
 		} else {
 			App.Events.addParagraph(frag, [`The arcology's computer core is fully upgraded.`]);
@@ -122,25 +107,25 @@ App.UI.personalAssistantOptions = function() {
 		if (V.assistant.personality <= 0) {
 			App.Events.addParagraph(frag, [
 				`Your assistant is using ${hisA} default settings, and is not behaving as though ${heA} has a libido.`,
-				App.UI.DOM.link(
+				App.UI.DOM.makeElement("div", App.UI.DOM.link(
 					`Instruct ${himA} to simulate a sex drive`,
 					() => {
 						V.assistant.personality = 1;
 						App.UI.reload();
 					},
-				)
+				), ["indent"]),
 			]);
 		} else {
 			App.Events.addParagraph(frag, [
 				`Your assistant is simulating preferences and a sex drive.`,
-				App.UI.DOM.link(
+				App.UI.DOM.makeElement("div", App.UI.DOM.link(
 					`Revert ${himA} to normal settings`,
 					() => {
 						V.assistant.personality = 0;
 						V.assistant.appearance = "normal";
 						App.UI.reload();
 					},
-				)
+				), ["indent"]),
 			]);
 		}
 
@@ -162,7 +147,6 @@ App.UI.personalAssistantOptions = function() {
 					]);
 			} else {
 				App.UI.DOM.appendNewElement("p", frag, `${kowalski} Although technically an expanded subroutine within the same app, ${V.assistant.name} uses a distinct icon to identify these alerts and improve your workflow.`);
-				r.push();
 			}
 			V.assistant.market.limit = Math.clamp(V.assistant.market.limit, 0, 10000000);
 			options.addOption("Use excess liquid assets to play the menial slave market.", "limit", V.assistant.market)
@@ -188,7 +172,7 @@ App.UI.personalAssistantOptions = function() {
 		frag.append(availableAssistantAppearances());
 
 		if (V.policies.publicPA === 1) {
-			App.UI.DOM.appendNewElement("span", frag, `${HeA} is currently part of your public image, so you may wish to select an appearance that complements your Future Societies:`, "note");
+			App.UI.DOM.appendNewElement("span", frag, `${HeA} is currently part of your public image, so you may wish to select an appearance that complements your Future Societies:`, ["note"]);
 			frag.append(assistantFS());
 		}
 		App.UI.DOM.appendNewElement("h3", frag, "Downloadable Content (DLC):");
@@ -235,7 +219,7 @@ App.UI.personalAssistantOptions = function() {
 			if (V.assistant.fsAppearance !== "default") {
 				r.push(
 					`profile; ${hisA} current variation shows`,
-					App.UI.DOM.makeElement("span", V.assistant.fsAppearance, "bold"),
+					App.UI.DOM.makeElement("span", V.assistant.fsAppearance, ["bold"]),
 					`touches.`
 				);
 			} else {
diff --git a/src/player/MpregSelf.js b/src/player/MpregSelf.js
index d6a2803daf50f7e095228997b27198c5b04d1a32..64e87b4bd4d3d98c74f1f1fbacbbf330c747fd46 100644
--- a/src/player/MpregSelf.js
+++ b/src/player/MpregSelf.js
@@ -153,6 +153,8 @@ globalThis.MpregSelf = function() {
 			r.push(`You feel ${hisU} soft lips pressed to your vulva as ${heU} works to retrieve ${hisU} treat. You hear some soft slurping noises and feel a warm tongue worming its way inside you to retrieve any lingering cum. You relax and enjoy the afterglow of your orgasms while ${heU} works, proud of your ingenious idea to take advantage of your own balls for a satisfying creampie. There's always a slave to do that, of course, but why use slave cum when you have such obviously superior material available?`);
 		}
 		r.push(knockMeUp(V.PC, 100, 0, -1));
+		
 	}
+	App.Events.addParagraph(node, r);
 	return node;
 };
diff --git a/src/player/desc/pLongBelly.js b/src/player/desc/pLongBelly.js
index f4d87cc4b61d9c344b2d89f08bf3ca1f6855c967..0f98c51dd222010a44d41c24e2f2a2c0f69caa6f 100644
--- a/src/player/desc/pLongBelly.js
+++ b/src/player/desc/pLongBelly.js
@@ -1554,11 +1554,31 @@ App.Desc.Player.belly = function(PC = V.PC) {
 				r.push(`You pat your middle as it starts to growl; your appetite is proportionate to your waistline these days.`);
 			}
 		}
-		if ((PC.dick > 0 || PC.genes === "XY") && PC.prostate > 0 && PC.preg > 0 && PC.preg > PC.pregData.normalBirth * .75) { // Do this here for dicks and males, otherwise do it in the special vagina description
+		if (PC.geneticQuirks.uterineHypersensitivity === 2) {
+			if (PC.bellyImplant >= 10000) {
+				r.push(`The sensation of the implant pushing against your uterine walls drives you wild; even something as simple as stroking it can lead to orgasm.`);
+			} else if (PC.belly > (PC.pregAdaptation * 4500)) {
+				r.push(`Your womb and body are breaking from the sheer amount stuffed inside them, leaving you trapped between overwhelming pain and pleasure.`);
+			} else if (PC.belly > (PC.pregAdaptation * 3200)) {
+				r.push(`Your womb and body are fit to burst, but the pressure feels absolutely amazing. Every breath risks setting off another orgasm.`);
+			} else if (PC.bellyPreg >= 750000) {
+				r.push(`While the massive pressure is arousing enough, the real pleasure are the endless vibrations caused by the minute motions of your brood. It's practically impossible to get anything done when chaining orgasm after orgasm until you risk passing out.`);
+			} else if (PC.bellyPreg >= 600000) {
+				r.push(`Between the constant movement and the pressure against your sensetive womb, it's impossible to not be constantly aroused. The quivering never ends, trapping you in a game of orgasm roulette.`);
+			} else if (PC.bellyPreg >= 450000) {
+				r.push(`Between the movement and the pressure against your sensetive womb, it's impossible to not be constantly aroused. Any kick can send you over the edge, and there are just so many of them…`);
+			} else if (PC.wombImplant === "restraint" && PC.belly >= 400000) {
+				r.push(`Your womb is so full that the restraining mesh designed to support it has begun to strangle it, but thanks to your overly sensetive uterus, this feels way better than it should.`);
+			} else if (PC.bellyPreg >= 10000) {
+				r.push(`Between the movement and the pressure in your sensetive womb, you find it difficult to not be in a state of constant arousal.`);
+			}
+		} else if ((PC.dick > 0 || PC.genes === "XY") && PC.prostate > 0 && PC.preg > 0 && PC.preg > PC.pregData.normalBirth * .75) { // Do this here for dicks and males, otherwise do it in the special vagina description
 			r.push(`Not only is your bladder under constant pressure from your advanced pregnancy, but your prostate is too. Between that and your baby's movements, you find it difficult to not be in a state of constant arousal.`);
 		}
 		if (onBedRest(PC)) {
-			if ((PC.bellyPreg >= PC.pregAdaptation * 2200) || (PC.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20))) {
+			if (isInduced(PC)) {
+				r.push(`You've taken drugs to induce labor and are already feeling the effects. The birth is coming up fast!`);
+			} else if ((PC.bellyPreg >= PC.pregAdaptation * 2200) || (PC.womb.find((ft) => ft.genetics.geneticQuirks.polyhydramnios === 2 && ft.age >= 20))) {
 				r.push(`You are undergoing a <span class="red">very high risk pregnancy,</span> so to avoid giving birth prematurely, you have been placed on medical bed rest.`);
 			} else if (PC.preg > PC.pregData.normalBirth / 1.05) {
 				r.push(`You're far enough along at this point that it's in your best interest to stay in the nest and wait things out instead of risking going to labor at an inopportune time.`);
diff --git a/src/player/desc/pLongBody.js b/src/player/desc/pLongBody.js
index 992b02e4815075c4c84eb7a9f7187f8be194fee8..78e6ed0113ffa1f03ed51884a84ee7fb9b1ee7ea 100644
--- a/src/player/desc/pLongBody.js
+++ b/src/player/desc/pLongBody.js
@@ -1,4 +1,4 @@
-App.Desc.Player.body = function(PC) {
+App.Desc.Player.body = function(PC = V.PC) {
 	const r = [];
 
 	const averageHeight = Height.mean(PC);
@@ -255,7 +255,7 @@ App.Desc.Player.body = function(PC) {
 				}
 			} else if (hasAnyProstheticArms(PC)) {
 				if (hasBothProstheticArms(PC)) {
-					r.push(`Both your arms are artificial.`);
+					r.push(`Both of your arms are artificial.`);
 					// expand this
 				} else {
 					r.push(`Your ${getLeftArmID(PC) > 1 ? "left" : "right"} arm is artificial.`);
diff --git a/src/player/desc/pLongCrotch.js b/src/player/desc/pLongCrotch.js
index 0449d0f4a9c19d489ce099f38c4e884c97a48971..c9e3981593c4bcbc97178bc6b08440d84eed0196 100644
--- a/src/player/desc/pLongCrotch.js
+++ b/src/player/desc/pLongCrotch.js
@@ -3,7 +3,18 @@ App.Desc.Player.crotch = function(PC = V.PC) {
 	const {girlP} = getPronouns(PC).appendSuffix('P');
 	const legs = hasBothLegs(PC) ? "legs" : "leg";
 	const hands = hasBothArms(PC) ? "hands" : "hand";
-	const isAroused = ((PC.prostate > 0 && PC.preg > 0 && PC.preg > PC.pregData.normalBirth * .75) || (PC.preg > 0 && PC.preg > PC.pregData.normalBirth * .66 && PC.pregMood === 2) || (PC.need > 0) || (PC.energy > 95) || (PC.aphrodisiacs > 0) || (PC.inflationType === "aphrodisiac") || (PC.drugs === "priapism agents"));
+	const isAroused = ((PC.prostate > 0 && PC.preg > 0 && PC.preg > PC.pregData.normalBirth * .75) ||
+		(PC.preg > 0 && PC.preg > PC.pregData.normalBirth * .66 && PC.pregMood === 2) ||
+		(PC.geneticQuirks.uterineHypersensitivity === 2 &&
+			(PC.bellyPreg >= 10000) ||
+			(PC.belly > (PC.pregAdaptation * 1000)) ||
+			(PC.wombImplant === "restraint" && PC.belly >= 400000)
+		) ||
+		(PC.need > 0) ||
+		(PC.energy > 95) ||
+		(PC.aphrodisiacs > 0) ||
+		(PC.inflationType === "aphrodisiac") ||
+		(PC.drugs === "priapism agents"));
 	const isVirile = (PC.balls > 0 && PC.pubertyXY === 1 && PC.vasectomy === 0 && PC.ballType !== "sterile");
 	const cumTotal = (cumAmount(PC) / 70) || 0;
 	const foreskinRatio = (PC.foreskin - PC.dick);
diff --git a/src/player/desc/pLongFace.js b/src/player/desc/pLongFace.js
index ab74dc819ef00aeb74c084ebdef5e924adcc6326..283276ed0b21ac6477839bddc39ed612ccd8e485 100644
--- a/src/player/desc/pLongFace.js
+++ b/src/player/desc/pLongFace.js
@@ -1,4 +1,4 @@
-App.Desc.Player.face = function(PC) {
+App.Desc.Player.face = function(PC = V.PC) {
 	const r = [];
 	let hairLength = '';
 
diff --git a/src/player/electiveSurgery.js b/src/player/electiveSurgery.js
index cbf10edda6d16cc2f851a948b245a282766ed020..b78f705dac0f6716aad0e81e99a503f17b265af3 100644
--- a/src/player/electiveSurgery.js
+++ b/src/player/electiveSurgery.js
@@ -29,118 +29,33 @@ App.UI.electiveSurgery = function() {
 			`"You sure you want to mess with that lovely face?" ${heU} teases, caressing your cheek. "<span class="cash">${cashFormat(5000)}.</span> Also wouldn't recommend changing your eyes, face shape or skin color; some security systems get real uppity over things like that. Though I s'pose race and hair can fall under that as well, but hey, we don't handle racial surgery and this isn't a hair salon, so nothing to worry about, right? Yes, I'm certain your systems will recognize you after we finish working on you — give us some credit."`
 		], "div");
 		r.push(`You're <span class="intro question">${V.PC.actualAge} years old.</span>`);
-		if (V.PC.actualAge >= 65) {
+		if (V.PC.faceImplant) {
 			if (V.PC.visualAge > V.PC.actualAge) {
-				r.push(`You've had surgery to make yourself <span class="lime">look older.</span>`);
+				r.push(`You've had surgery to make yourself <span class="lime">look ${V.PC.visualAge > V.PC.actualAge ? 'older' : 'younger'}.</span>`);
 				linkArray.push(surgeryLink("Undo Facial surgery", "restoreFace", () => {
 					V.PC.faceImplant = 0;
 					V.PC.visualAge = V.PC.physicalAge;
 					cashX(forceNeg(5000), "PCmedical");
 				}));
-			} else if (V.PC.visualAge < V.PC.actualAge) {
-				r.push(`You've had surgery to make yourself <span class="lime">look younger.</span>`);
-				linkArray.push(surgeryLink("Undo Facial surgery", "restoreFace", () => {
-					V.PC.faceImplant = 0;
-					V.PC.visualAge = V.PC.physicalAge;
-					cashX(forceNeg(5000), "PCmedical");
-				}));
-			} else {
-				r.push(`You could benefit from a face lift.`);
-				if (V.PC.visualAge >= 25) {
-					linkArray.push(surgeryLink("Get a face lift", "ageDown", () => {
-						V.PC.faceImplant = 1;
-						cashX(forceNeg(5000), "PCmedical");
-					}));
-				}
-				linkArray.push(surgeryLink("Remodel your face to appear older", "ageUp", () => {
-					V.PC.faceImplant = 1;
-					cashX(forceNeg(5000), "PCmedical");
-				}));
 			}
-		} else if (V.PC.actualAge >= 50) {
-			if (V.PC.visualAge > V.PC.actualAge) {
-				r.push(`You've had surgery to make yourself <span class="lime">look older.</span>`);
-				linkArray.push(surgeryLink("Undo Facial surgery", "restoreFace", () => {
-					V.PC.faceImplant = 0;
-					V.PC.visualAge = V.PC.physicalAge;
-					cashX(forceNeg(5000), "PCmedical");
-				}));
-			} else if (V.PC.visualAge < V.PC.actualAge) {
-				r.push(`You've had surgery to make yourself <span class="lime">look younger.</span>`);
-				linkArray.push(surgeryLink("Undo Facial surgery", "restoreFace", () => {
-					V.PC.faceImplant = 0;
-					V.PC.visualAge = V.PC.physicalAge;
-					cashX(forceNeg(5000), "PCmedical");
-				}));
-			} else {
+		} else {
+			if (V.PC.actualAge >= 65 || V.PC.actualAge >= 50) {
 				r.push(`You could benefit from a face lift.`);
-				if (V.PC.visualAge >= 25) {
-					linkArray.push(surgeryLink("Get a face lift", "ageDown", () => {
-						V.PC.faceImplant = 1;
-						cashX(forceNeg(5000), "PCmedical");
-					}));
-				}
-				linkArray.push(surgeryLink("Remodel your face to appear older", "ageUp", () => {
-					V.PC.faceImplant = 1;
-					cashX(forceNeg(5000), "PCmedical");
-				}));
-			}
-		} else if (V.PC.actualAge >= 35) {
-			if (V.PC.visualAge > V.PC.actualAge) {
-				r.push(`You've had surgery to make yourself <span class="lime">look older.</span>`);
-				linkArray.push(surgeryLink("Undo Facial surgery", "restoreFace", () => {
-					V.PC.faceImplant = 0;
-					V.PC.visualAge = V.PC.physicalAge;
-					cashX(forceNeg(5000), "PCmedical");
-				}));
-			} else if (V.PC.visualAge < V.PC.actualAge) {
-				r.push(`You've had surgery to make yourself <span class="lime">look younger.</span>`);
-				linkArray.push(surgeryLink("Undo Facial surgery", "restoreFace", () => {
-					V.PC.faceImplant = 0;
-					V.PC.visualAge = V.PC.physicalAge;
-					cashX(forceNeg(5000), "PCmedical");
-				}));
-			} else {
+			} else if (V.PC.actualAge >= 35) {
 				r.push(`You could go for a face lift, though making yourself look older could be useful.`);
-				if (V.PC.visualAge >= 25) {
-					linkArray.push(surgeryLink("Get a face lift", "ageDown", () => {
-						V.PC.faceImplant = 1;
-						cashX(forceNeg(5000), "PCmedical");
-					}));
-				}
-				linkArray.push(surgeryLink("Remodel your face to appear older", "ageUp", () => {
-					V.PC.faceImplant = 1;
-					cashX(forceNeg(5000), "PCmedical");
-				}));
-			}
-		} else {
-			if (V.PC.visualAge > V.PC.actualAge) {
-				r.push(`You've had surgery to make yourself <span class="lime">look older.</span>`);
-				linkArray.push(surgeryLink("Undo Facial surgery", "restoreFace", () => {
-					V.PC.faceImplant = 0;
-					V.PC.visualAge = V.PC.physicalAge;
-					cashX(forceNeg(5000), "PCmedical");
-				}));
-			} else if (V.PC.visualAge < V.PC.actualAge) {
-				r.push(`You've had surgery to make yourself <span class="lime">look younger.</span>`);
-				linkArray.push(surgeryLink("Undo Facial surgery", "restoreFace", () => {
-					V.PC.faceImplant = 0;
-					V.PC.visualAge = V.PC.physicalAge;
-					cashX(forceNeg(5000), "PCmedical");
-				}));
 			} else {
 				r.push(`You could undergo facial surgery to make yourself look older${(V.PC.visualAge >= 25) ? ", though you could also make yourself look even younger" : ""}.`);
-				if (V.PC.visualAge >= 25) {
-					linkArray.push(surgeryLink("Remodel your face to appear younger", "ageDown", () => {
-						V.PC.faceImplant = 1;
-						cashX(forceNeg(5000), "PCmedical");
-					}));
-				}
-				linkArray.push(surgeryLink("Remodel your face to appear older", "ageUp", () => {
+			}
+			if (V.PC.visualAge >= 25) {
+					linkArray.push(surgeryLink(`${V.PC.actualAge < 35 ? 'Remodel your face to appear younger' : 'Get a face lift'}`, "ageDown", () => {
 					V.PC.faceImplant = 1;
 					cashX(forceNeg(5000), "PCmedical");
 				}));
 			}
+			linkArray.push(surgeryLink("Remodel your face to appear older", "ageUp", () => {
+				V.PC.faceImplant = 1;
+				cashX(forceNeg(5000), "PCmedical");
+			}));
 		}
 		App.Events.addNode(p, r, "div");
 		p.append(App.UI.DOM.makeElement("div", App.UI.DOM.generateLinksStrip(linkArray)));
@@ -161,34 +76,22 @@ App.UI.electiveSurgery = function() {
 		App.Events.addNode(p, r, "div");
 
 		const choiceDiv = document.createElement("div");
-		const choices = new Map([]);
+		/**
+		 * @type {selectOption[]}
+		 */
+		const choices = [];
 		if (V.PC.skin !== V.PC.origSkin) {
-			choices.set(V.PC.origSkin, capFirstChar(`Restore natural ${V.PC.origSkin}`));
+			choices.push({key: V.PC.origSkin, name: capFirstChar(`Restore natural ${V.PC.origSkin}`)});
 		}
-		for (const skin of App.Medicine.Modification.naturalSkins) {
-			choices.set(skin, capFirstChar(skin));
+		for (const skin of [...App.Medicine.Modification.naturalSkins, ...App.Medicine.Modification.dyedSkins]) {
+			choices.push({key: skin, name: capFirstChar(skin)});
 		}
 
-		const select = document.createElement("select");
-		let matchFound;
-		for (const [value, text] of choices) {
-			const option = document.createElement("option");
-			option.text = text;
-			option.value = value;
-			if (V.PC.skin === option.value) {
-				option.selected = true;
-				matchFound = true;
-			}
-			select.append(option);
-		}
-		if (!matchFound) {
-			select.selectedIndex = -1;
-		}
-		select.onchange = () => {
-			V.PC.skin = select.options[select.selectedIndex].value;
+		const select = App.UI.DOM.makeSelect(choices, V.PC.skin, value => {
+			V.PC.skin = value;
 			cashX(forceNeg(2000), "PCmedical");
 			showDegradation("skinTone");
-		};
+		});
 
 		choiceDiv.append(select, " or custom ", App.UI.DOM.makeTextBox(
 			V.PC.skin, v => {
diff --git a/src/player/js/PlayerState.js b/src/player/js/PlayerState.js
index f11ed16acd972375d15b25f9f5b93c9324354535..473896486426854ee720a4a22c19451aa37ff69f 100644
--- a/src/player/js/PlayerState.js
+++ b/src/player/js/PlayerState.js
@@ -526,15 +526,15 @@ App.Entity.PlayerState = class PlayerState {
 		 * your legs
 		 */
 		this.leg = {
-			left: new App.Entity.LimbState(),
-			right: new App.Entity.LimbState()
+			left: new App.Entity.LegState(),
+			right: new App.Entity.LegState()
 		};
 		/**
 		 * your arms
 		 */
 		this.arm = {
-			left: new App.Entity.LimbState(),
-			right: new App.Entity.LimbState()
+			left: new App.Entity.ArmState(),
+			right: new App.Entity.ArmState()
 		};
 		/** are your heels clipped
 		 * @type {FC.Bool}
@@ -635,7 +635,7 @@ App.Entity.PlayerState = class PlayerState {
 		 * * "fillable"
 		 * * "advanced fillable"
 		 * * "hyper fillable"
-		 * @type {FC.SizingImplantType}
+		 * @type {FC.InstalledSizingImplantType}
 		 */
 		this.boobsImplantType = "none";
 		/**
@@ -753,7 +753,7 @@ App.Entity.PlayerState = class PlayerState {
 		 * * "fillable"
 		 * * "advanced fillable"
 		 * * "hyper fillable"
-		 * @type {FC.SizingImplantType}
+		 * @type {FC.InstalledSizingImplantType}
 		 */
 		this.buttImplantType = "none";
 		/**
@@ -1944,8 +1944,14 @@ App.Entity.PlayerState = class PlayerState {
 			/** Are you immortal?
 			 * @type {FC.Bool}
 			 * 0: no; 1: yes */
-			immortality: 0
-		};
+			 immortality: 0,
+			 /** Is your milk flavored?
+			  * @type {FC.Bool}
+			  * 0: no; 1: yes */
+			 flavoring: 0
+		 };
+		/** flavor of their milk*/
+		 this.milkFlavor = "none";
 		/** erratic weight gain
 		 *
 		 * 0: stable; 1: gaining; -1: losing */
diff --git a/src/player/managePersonalAffairs.js b/src/player/managePersonalAffairs.js
index eafd96b4ff7bbed42fd04e2db2ab1743bcba7489..7116135f2fbda70706c9623b40e98705ae70ae6f 100644
--- a/src/player/managePersonalAffairs.js
+++ b/src/player/managePersonalAffairs.js
@@ -514,8 +514,8 @@ App.UI.managePersonalAffairs = function() {
 						App.UI.DOM.replace(reputationDiv, reputation);
 					}),
 					App.UI.DOM.link(`Stop using a custom title`, () => {
-						V.PC.customTitle = null;
-						V.PC.customTitleLisp = null;
+						V.PC.customTitle = undefined;
+						V.PC.customTitleLisp = undefined;
 
 						App.UI.DOM.replace(reputationDiv, reputation);
 					}),
@@ -713,23 +713,20 @@ App.UI.managePersonalAffairs = function() {
 				ownedSlavesSpan.append(innerSpan);
 			}
 
-			if (PC.partners.has(-2)) {
-				other.push(`citizens of ${V.arcologies[0].name}`);
-			}
-			if (PC.partners.has(-3)) {
-				other.push(`your former master`);
-			}
-			if (PC.partners.has(-4)) {
-				other.push(`another arcology owner`);
-			}
-			if (PC.partners.has(-6)) {
-				other.push(`members of the Societal Elite`);
-			}
-			if (PC.partners.has(-8)) {
-				other.push(`some of your animals`);
-			}
-			if (PC.partners.has(-9)) {
-				other.push(`members of the Futanari Sisters`);
+			const partners = new Map([
+				[-1, "you"],
+				[-2, `citizens of ${V.arcologies[0].name}`],
+				[-3, `your former master`],
+				[-4, `another arcology owner`],
+				[-6, `members of the Societal Elite`],
+				[-8, `your animals`],
+				[-9, `members of the Futanari Sisters`],
+			]);
+
+			for (const [ID, name] of partners) {
+				if (V.PC.partners.has(ID)) {
+					other.push(name);
+				}
 			}
 
 			const link = App.UI.DOM.link(`${num(slaves.length)} of your slaves`, () => {
@@ -807,14 +804,10 @@ App.UI.managePersonalAffairs = function() {
 					App.UI.DOM.generateLinksStrip([
 						App.UI.DOM.link(`List your womb as available`, () => {
 							V.playerBred = 1;
-							V.playerBredTube = 0;
-
 							App.UI.DOM.replace(breedingDiv, breeding);
 						}),
 						App.UI.DOM.link(`Sign up for artificial insemination`, () => {
-							V.playerBred = 1;
-							V.playerBredTube = 1;
-
+							V.playerBred = 2;
 							App.UI.DOM.replace(breedingDiv, breeding);
 						})
 					]),
@@ -1134,7 +1127,7 @@ App.UI.managePersonalAffairs = function() {
 	function breederExam() {
 		App.UI.DOM.appendNewElement("h2", breederExamDiv, `Elite Breeder Qualifications`);
 
-		breederExamDiv.append(eliteBreedingExam());
+		breederExamDiv.append(App.Interact.eliteBreedingExam());
 
 		return breederExamDiv;
 	}
diff --git a/src/player/personalAttentionSelect.js b/src/player/personalAttentionSelect.js
index 96afc06f2c93106ec864b2540756a49d5cfa1287..a7b4e8ae543de07adad55e1c1f3e7f2c7edb6371 100644
--- a/src/player/personalAttentionSelect.js
+++ b/src/player/personalAttentionSelect.js
@@ -7,11 +7,7 @@ App.UI.Player.personalAttention = function() {
 	V.nextLink = "Main";
 
 	// set up div for refreshing options
-	const refreshDiv = document.createElement("div");
-	refreshDiv.append(content());
-	frag.append(
-		refreshDiv,
-	);
+	const refreshDiv = App.UI.DOM.appendNewElement("div", frag, content());
 
 	return frag;
 
@@ -40,7 +36,7 @@ App.UI.Player.personalAttention = function() {
 			const r = [];
 			for (const slave of V.personalAttention.slaves) {
 				slave.objective = slave.objective || getRegimen(getSlave(slave.ID));
-				r.push(`<span class="slave-name">${SlaveFullName(getSlave(slave.ID))}</span> to <span class="bold">${App.personalAttention.getText(slave.objective, getSlave(slave.ID))}</span>`);
+				r.push(`<span class="slave-name">${SlaveFullName(getSlave(slave.ID))}</span> to <span class="bold">${App.PersonalAttention.getText(slave.objective, getSlave(slave.ID))}</span>`);
 			}
 			text.push(`training ${toSentence(r)}.`);
 		} else {
@@ -481,7 +477,7 @@ App.UI.Player.personalAttention = function() {
 				text.push(
 					`You will give`,
 					App.UI.DOM.referenceSlaveWithPreview(slave, SlaveFullName(slave)),
-					`your personal attention this week to ${App.personalAttention.getText(V.personalAttention.slaves[i].objective, slave)}.`,
+					`your personal attention this week to ${App.PersonalAttention.getText(V.personalAttention.slaves[i].objective, slave)}.`,
 					App.UI.DOM.link(`Stop`, () => {
 						if (V.personalAttention.slaves.length === 1) {
 							V.personalAttention = {task: PersonalAttention.SEX};
@@ -505,7 +501,7 @@ App.UI.Player.personalAttention = function() {
 						attentionLink(i, `Use enhanced breaking techniques`, "harshly break will"),
 					);
 				} else {
-					links.push(attentionLink(i, `Build`, "build devotion"));
+					links.push(attentionLink(i, `Build ${his} devotion`, "build devotion"));
 				}
 
 				// Sexuality
@@ -846,7 +842,7 @@ App.UI.Player.personalAttention = function() {
 		}
 
 		div.append(App.UI.SlaveList.slaveSelectionList(
-			s => assignmentVisible(s) && s.fuckdoll === 0,
+			s => (assignmentVisible(s) || App.Entity.facilities.masterSuite.isHosted(s)) && s.fuckdoll === 0,
 			s => App.UI.DOM.link(SlaveFullName(s),
 				(id) => { selectSlave(id); }, [s.ID]
 			),
diff --git a/src/pregmod/FCTV/FCTVshows.js b/src/pregmod/FCTV/FCTVshows.js
index 4c36f4463a6ddd65432bb0a15c4c27b483dac9ca..3fed92388bc648ed31c802b18b9cdf01cbc0ff7b 100644
--- a/src/pregmod/FCTV/FCTVshows.js
+++ b/src/pregmod/FCTV/FCTVshows.js
@@ -11,7 +11,7 @@ App.Data.FCTV.actors = {
 		slave.hLength = 50;
 		slave.skin = "dark olive";
 		slave.hStyle = "luxurious";
-		slave.hColor = "strawberry blonde";
+		slave.hColor = "strawberry-blonde";
 		slave.clothes = "a leotard";
 		return slave;
 	},
@@ -382,7 +382,7 @@ App.Data.FCTV.actors = {
 		slave.trust = 100;
 		slave.hLength = 50;
 		slave.hStyle = "luxurious";
-		slave.hColor = "strawberry blonde";
+		slave.hColor = "strawberry-blonde";
 		slave.boobs = 1400;
 		slave.nipples = "huge";
 		slave.boobShape = "perky";
@@ -399,7 +399,7 @@ App.Data.FCTV.actors = {
 		slave.trust = 100;
 		slave.hLength = 50;
 		slave.hStyle = "luxurious";
-		slave.hColor = "strawberry blonde";
+		slave.hColor = "strawberry-blonde";
 		slave.boobs = 1400;
 		slave.nipples = "huge";
 		slave.boobShape = "perky";
@@ -657,7 +657,7 @@ App.Data.FCTV.channels = {
 			{
 				get text() {
 					const r = [];
-					const MSL = App.Entity.facilities.dairy.employeesIDs().size;
+					const MSL = App.Entity.facilities.masterSuite.employeesIDs().size;
 
 					r.push(`<p>The intro sequence shows a succession of beautiful ladies either participating in a mixture of contrived competitions, or talking and going about their lives in a sorority-like setting.</p>`);
 					r.push(`<p>The montage is overlaid with a narrator's voice: "12 of Canadia Arcology's most attractive women are all competing for the privilege of having the arcology owner's children. Clint Miles has desirable genes, and these ladies are determined to prove their worth as gestators. And here in Canadia, there are no restrictions on fertility drugs for the winner, so the competition this season is fierce! ${V.FCTV.channel.two} ladies have already been sent packing, who will be Canadia's... Next Top Breeder!?" The title finally pops up, redundantly labeling the show as 'Next Top Breeder: Canadia'.`);
@@ -2000,8 +2000,9 @@ App.Data.FCTV.channels = {
 						if (S.Concubine && S.Concubine.vagina > 0 && canDoVaginal(S.Concubine)) {
 							const {him} = getPronouns(S.Concubine);
 							r.push(`grab ${S.Concubine.slaveName} and recreate the entire ending with ${him}.`);
-							S.Concubine.counter.vaginal++;
-							V.vaginalTotal++;
+
+							seX(S.Concubine, "vaginal", V.PC);
+
 							if (canImpreg(S.Concubine, V.PC)) {
 								knockMeUp(S.Concubine, 10, 0, -1);
 							}
@@ -2016,9 +2017,10 @@ App.Data.FCTV.channels = {
 						if (S.Concubine && canPenetrate(S.Concubine) && canImpreg(V.PC, S.Concubine) && (V.policies.sexualOpenness === 1 || S.Concubine.toyHole === "dick")) {
 							const {him} = getPronouns(S.Concubine);
 							r.push(`get ${S.Concubine.slaveName} nice and hard before recreating the entire ending with ${him}. You've never had a more hope-filled orgasm.`);
+
+							seX(V.PC, "vaginal", S.Concubine);
+
 							knockMeUp(V.PC, 10, 0, S.Concubine.ID);
-							S.Concubine.counter.penetrative++;
-							V.penetrativeTotal++;
 						} else if (V.policies.sexualOpenness === 1) {
 							r.push(`find your favorite cock to get a creampie from. You've never had a more lust-filled orgasm.`);
 						} else {
diff --git a/src/pregmod/theBlackMarket.js b/src/pregmod/blackMarket.js
similarity index 91%
rename from src/pregmod/theBlackMarket.js
rename to src/pregmod/blackMarket.js
index 55e1c1c9fe4c2f2c243c50b29678dc7ec039cf43..87070aeeea7308626e30361e0c3a1285664beadc 100644
--- a/src/pregmod/theBlackMarket.js
+++ b/src/pregmod/blackMarket.js
@@ -1,4 +1,4 @@
-App.UI.theBlackMarket = function() {
+App.UI.blackMarket = function() {
 	const node = new DocumentFragment();
 
 	// App.UI.DOM.appendNewElement("h1", node, `The Black Market`);
@@ -7,9 +7,11 @@ App.UI.theBlackMarket = function() {
 		He,
 		he, his
 	} = getPronouns(S.Bodyguard ? S.Bodyguard : {pronoun: App.Data.Pronouns.Kind.neutral});
+
 	const {
-		hisP
-	} = getPronouns(V.PC).appendSuffix("P");
+		his: hisP
+	} = getPronouns(V.PC);
+
 	let r = [];
 
 	r.push(`You board your VTOL bird for the trip to the current location of the particularly exclusive, and quite lucrative, Black Market knowing full well that the trip may take far longer than anticipated; the market frequently relocates to shake the unwanted attention it inevitably gains. It's far easier than paying off authorities, especially with how outrageous their demands have become with the decline of the old world. You're greeted by a gruff bouncer, already fully aware of just who you are and your permission to be there. "Check your weapons — no firearms allowed inside.`);
@@ -55,7 +57,7 @@ App.UI.theBlackMarket = function() {
 
 	// <br><br>
 
-	App.Events.addParagraph(node, [`The main draw, however, is the prominent stage to the rear of the building where the most desirable and less than legal slaves are auctioned off. Enslaved celebrities, kidnapped royalty, the daughters of warlords and all manner of slaves outlawed for sale in most arcologies frequently make appearances before the hungry crowd. It's usually not worth the added risk or the price to buy these girls yourself, however.`]); // This could use a variety of scenes for who is currently at auction, possibly even with slave purchase
+	App.Events.addParagraph(node, [`The main draw, however, is the prominent stage to the rear of the building where the most desirable and less than legal slaves are auctioned off. Enslaved celebrities, kidnapped royalty, the daughters of warlords and all manner of slaves outlawed for sale in most arcologies frequently make appearances before the hungry crowd. It's usually not worth the added risk or the price to buy these girls yourself, however.`]); // TODO: This could use a variety of scenes for who is currently at auction, possibly even with slave purchase
 
 	App.Events.addParagraph(node, [`Of all the wonders present, the thing that catches your eye the most is a shady looking stall with a somehow even shadier looking merchant — a merchant who is beckoning you to come over. "A prominent arcology owner like yourself wandering around in here can only be looking for one thing: new and exciting ways to spice up ${hisP} slaves! I've got the hottest research and tech straight from the labs waiting for you to peruse and some of the 'hottest' tech straight out of the research labs, if you catch my drift." He shuffles around behind the counter, pulling out a stack of papers.`]);
 
@@ -617,78 +619,82 @@ App.UI.theBlackMarket = function() {
 					}
 					break;
 				case "AnimalOrgans":
-					if (V.experimental.animalOvaries) {
-						if (V.animalOvaries === 0 || V.animalTesticles === 0 || V.animalMpreg === 0) {
-							if (V.organFarmUpgrade > 0) {
-								const animalGonadsCash = 25000;
-								if (V.cash >= animalGonadsCash) {
-									if (V.animalOvaries === 0) {
-										App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
-											"Purchase schematics for animal ovaries",
-											() => {
-												cashX(-animalGonadsCash, "capEx");
-												V.animalOvaries = 1;
-												App.UI.reload();
-											},
-											[],
-											"",
-											`Costs ${(cashFormat(animalGonadsCash))} and allows you to implant animal ovaries into slaves.`
-										));
+					if (V.seeBestiality) {
+						if (V.experimental.animalOvaries) {
+							if (V.animalOvaries === 0 || V.animalTesticles === 0 || V.animalMpreg === 0) {
+								if (V.organFarmUpgrade > 0) {
+									const animalGonadsCash = 25000;
+									if (V.cash >= animalGonadsCash) {
+										if (V.animalOvaries === 0) {
+											App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
+												"Purchase schematics for animal ovaries",
+												() => {
+													cashX(-animalGonadsCash, "capEx");
+													V.animalOvaries = 1;
+													App.UI.reload();
+												},
+												[],
+												"",
+												`Costs ${(cashFormat(animalGonadsCash))} and allows you to implant animal ovaries into slaves.`
+											));
+										} else {
+											r.push(`You already possess schematics for implanting animal ovaries.`);
+										}
 									} else {
-										r.push(`You already possess schematics for implanting animal ovaries.`);
+										r.push(`You cannot afford the asking price of <span class="cash dec">${(cashFormat(animalGonadsCash))}</span> for animal ovaries.`);
 									}
-								} else {
-									r.push(`You cannot afford the asking price of <span class="cash dec">${(cashFormat(animalGonadsCash))}</span> for animal ovaries.`);
-								}
-								if (V.cash >= animalGonadsCash) {
-									if (V.animalTesticles === 0) {
-										App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
-											"Purchase schematics for animal testicles",
-											() => {
-												cashX(-animalGonadsCash, "capEx");
-												V.animalTesticles = 1;
-												App.UI.reload();
-											},
-											[],
-											"",
-											`Costs ${(cashFormat(animalGonadsCash))} and allows you to implant animal testicles into slaves.`
-										));
+									if (V.cash >= animalGonadsCash) {
+										if (V.animalTesticles === 0) {
+											App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
+												"Purchase schematics for animal testicles",
+												() => {
+													cashX(-animalGonadsCash, "capEx");
+													V.animalTesticles = 1;
+													App.UI.reload();
+												},
+												[],
+												"",
+												`Costs ${(cashFormat(animalGonadsCash))} and allows you to implant animal testicles into slaves.`
+											));
+										} else {
+											r.push(`You already possess schematics for implanting animal testicles.`);
+										}
 									} else {
-										r.push(`You already possess schematics for implanting animal testicles.`);
+										r.push(`You cannot afford the asking price of <span class="cash dec">${(cashFormat(animalGonadsCash))}</span> for animal testicles.`);
 									}
-								} else {
-									r.push(`You cannot afford the asking price of <span class="cash dec">${(cashFormat(animalGonadsCash))}</span> for animal testicles.`);
-								}
-								if (V.cash >= animalGonadsCash) {
-									if (V.animalMpreg === 0) {
-										App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
-											"Purchase schematics for animal anal wombs and ovaries",
-											() => {
-												cashX(-animalGonadsCash, "capEx");
-												V.animalMpreg = 1;
-												App.UI.reload();
-											},
-											[],
-											"",
-											`Costs ${(cashFormat(animalGonadsCash))} and allows you to implant animal anal wombs and ovaries into slaves.`
-										));
+									if (V.cash >= animalGonadsCash) {
+										if (V.animalMpreg === 0) {
+											App.UI.DOM.appendNewElement("div", node, App.UI.DOM.link(
+												"Purchase schematics for animal anal wombs and ovaries",
+												() => {
+													cashX(-animalGonadsCash, "capEx");
+													V.animalMpreg = 1;
+													App.UI.reload();
+												},
+												[],
+												"",
+												`Costs ${(cashFormat(animalGonadsCash))} and allows you to implant animal anal wombs and ovaries into slaves.`
+											));
+										} else {
+											r.push(`You already possess schematics for implanting animal anal wombs and ovaries.`);
+										}
 									} else {
-										r.push(`You already possess schematics for implanting animal anal wombs and ovaries.`);
+										r.push(`You cannot afford the asking price of <span class="cash dec">${(cashFormat(animalGonadsCash))}</span> for animal anal wombs and ovaries.`);
 									}
+									/* TODO: flesh this out some more */
+									App.Events.addNode(node, r, "div");
+									r = [];
+									r.push(`"Got something real special this week. These are schematics for implanting non-human organs into humans. My supplier told me they came from some military experiments or something — maybe they were trying to make some kind of super soldier. Not my business, though."`);
 								} else {
-									r.push(`You cannot afford the asking price of <span class="cash dec">${(cashFormat(animalGonadsCash))}</span> for animal anal wombs and ovaries.`);
+									r.push(`You lack the facilities required to grow organs.`);
 								}
-								/* TODO: flesh this out some more */
-								App.Events.addNode(node, r, "div");
-								r = [];
-								r.push(`"Got something real special this week. These are schematics for implanting non-human organs into humans. My supplier told me they came from some military experiments or something — maybe they were trying to make some kind of super soldier. Not my business, though."`);
-							} else {
-								r.push(`You lack the facilities required to grow organs.`);
+							} else { /* if all schematics have already been purchased */
+								r.push(`You already possess all of the schematics for implanting animal organs.`);
+								V.merchantIllegalWares.delete("AnimalOrgans");
 							}
-						} else { /* if all schematics have already been purchased */
-							r.push(`You already possess all of the schematics for implanting animal organs.`);
-							V.merchantIllegalWares.delete("AnimalOrgans");
 						}
+					} else {
+						V.merchantIllegalWares.delete("AnimalOrgans");
 					}
 			}
 			App.Events.addNode(node, r, "div");
diff --git a/src/pregmod/editGenetics.js b/src/pregmod/editGenetics.js
index f7c5edb02856e13dbd147506adbef6252809ee97..9d82241e4ddd6aea8302d49123b8657178bcf502 100644
--- a/src/pregmod/editGenetics.js
+++ b/src/pregmod/editGenetics.js
@@ -59,7 +59,7 @@ App.UI.editGenetics = function() {
 	function birthFullName(s) {
 		let r = [];
 		if (V.surnameOrder !== 1) {
-			if (["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(s.nationality)) {
+			if (["Cambodian", "Chinese", "Ancient Chinese Revivalist", "Hungarian", "Japanese", "Edo Revivalist", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(s.nationality)) {
 				if (s.birthSurname || s.surname) {
 					r.push(s.birthSurname || s.surname);
 				}
@@ -81,7 +81,7 @@ App.UI.editGenetics = function() {
 	function currentFullName(s) {
 		let r = [];
 		if (V.surnameOrder !== 1) {
-			if (["Cambodian", "Chinese", "Hungarian", "Japanese", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(s.nationality)) {
+			if (["Cambodian", "Chinese", "Ancient Chinese Revivalist", "Hungarian", "Japanese", "Edo Revivalist", "Korean", "Mongolian", "Taiwanese", "Vietnamese"].includes(s.nationality)) {
 				if (s.slaveSurname) {
 					r.push(s.slaveSurname);
 				}
diff --git a/src/pregmod/eliteBreedingExam.js b/src/pregmod/eliteBreedingExam.js
index 88d6900f3df4762eb58dddb155491f609e671d2d..b58842e53a15c52fe960575e320f738317bcd34b 100644
--- a/src/pregmod/eliteBreedingExam.js
+++ b/src/pregmod/eliteBreedingExam.js
@@ -1,248 +1,277 @@
-globalThis.eliteBreedingExam = function(slave = null) {
+App.Interact.eliteBreedingExam = function(slave = null) {
 	const frag = new DocumentFragment();
 	const eliteAngered = V.failedElite > 100;
 	const SlaveProfessionalismEstablished = V.arcologies[0].FSSlaveProfessionalism > 20;
-	const preferYounger = V.arcologies[0].FSYouthPreferentialist > 20;
-	const partyAnimal = V.arcologies[0].FSHedonisticDecadence > 20;
-	const implantsExpected = V.arcologies[0].FSTransformationFetishist > 20;
 	const cost = 5000;
-	let r = [];
-	let test;
-	let passing = 0;
-	let fixable;
 
-	const result = function() {
-		if (slave) {
-			if (test === true) {
-				return App.UI.DOM.makeElement("span", "PASSED", "lime");
-			} else if (fixable) {
-				return App.UI.DOM.makeElement("span", "Within fixable range.", "yellow");
-			} else {
-				passing--;
-				return App.UI.DOM.makeElement("span", "FAILED", "red");
-			}
-		}
-		return ``;
-	};
+	let r = [];
 
-	r.push(`For each slave be to examined, a fee of <span class='yellowgreen'>${cashFormat(cost)}</span> will be deducted from your account.`);
-	r.push(`Updates will be posted periodically. It is your responsibility to keep up to date.`);
-	r.push(`Failures will be sterilized. Please make sure your slave fits the following criteria before submitting them for testing. We shall not be held responsible for time wasted.`);
 	if (!slave) {
-		r.push(`Must be not; already be marked as a breeding slave, inside a fuckdoll suit, infertile and already with child.`);
+		r.push(`A fee of <span class='yellowgreen'>${cashFormat(cost)}</span> will be deducted from your account for each slave be to examined.`);
+	}
+	r.push(
+		`Updates will be posted periodically. It is your responsibility to keep up to date.`,
+		`Failures will be sterilized. Please make sure your slave fits the following criteria before submitting them for testing. We shall not be held responsible for time wasted.`,
+	);
+	if (!slave) {
+		r.push(`The slave must not be inside a fuckdoll suit, infertile or already pregnant.`);
 	} else {
 		r.push(`${slave.slaveName} is up for review:`);
 	}
 	App.Events.addNode(frag, r, "div");
 	r = [];
-	const list = App.UI.DOM.appendNewElement("ul", frag);
-	if (slave) {
-		test = slave.intelligence + slave.intelligenceImplant >= (eliteAngered ? 95 : 50);
-	}
-	App.UI.DOM.appendNewElement("li", list, `Must be ${eliteAngered ? 'highly intelligent' : 'very smart'}. `).append(result());
 
-	if (slave) {
-		test = Beauty(slave) >= (eliteAngered ? 120 : 100);
-	}
-	App.UI.DOM.appendNewElement("li", list, `Must be ${eliteAngered ? 'unbelievably' : ''} beautiful. `).append(result());
-
-	if (slave) {
-		test = slave.face >= (eliteAngered ? 95 : 40);
-	}
-	App.UI.DOM.appendNewElement("li", list, `Their face must be ${eliteAngered ? 'breathtaking' : 'gorgeous'}. `).append(result());
-
-	if (slave) {
-		test = slave.chem <= 20;
-	}
-	App.UI.DOM.appendNewElement("li", list, `Their health must not be overly impacted by drug use. `).append(result());
+	const table = App.UI.DOM.appendNewElement("table", frag, null, ["padded-columns"]);
+	/** @type {[(slave: FC.SlaveState) => boolean, string][]} */
+	const checks = [];
 
-	if (slave) {
-		test = slave.addict === 0;
-	}
-	App.UI.DOM.appendNewElement("li", list, `They must not be addicted to drugs. `).append(result());
+	checks.push(
+		[
+			slave => slave.intelligence + slave.intelligenceImplant >= (eliteAngered ? 95 : 50),
+			`Must be ${eliteAngered ? 'highly intelligent' : 'very smart'}`
+		],
+		[
+			slave => Beauty(slave) >= (eliteAngered ? 120 : 100),
+			`Must be ${eliteAngered ? 'unbelievably' : ''} beautiful`
+		],
+		[
+			slave => slave.face >= (eliteAngered ? 95 : 40),
+			`Must have a ${eliteAngered ? 'breathtaking' : 'gorgeous'} face`
+		],
+		[
+			slave => slave.chem <= 20,
+			`Must not be overly impacted by drug use`
+		],
+		[
+			slave => slave.addict === 0,
+			`Must not be addicted to drugs`
+		],
+	);
 
 	if (V.arcologies[0].FSMaturityPreferentialist > 20 || V.arcologies[0].FSYouthPreferentialist > 20) {
 		const targetAge = 24;
-		if (slave) {
-			if (V.arcologies[0].FSMaturityPreferentialist > 20) {
-				test = slave.physicalAge > targetAge;
-			} else {
-				test = slave.physicalAge < targetAge;
-			}
+
+		if (V.arcologies[0].FSMaturityPreferentialist > 20) {
+			checks.push([
+				slave => slave.physicalAge > targetAge,
+				`Must be older than ${targetAge}`
+			]);
+		} else {
+			checks.push([
+				slave => slave.physicalAge <= targetAge,
+				`Must be ${targetAge} or younger`
+			]);
 		}
-		App.UI.DOM.appendNewElement("li", list, `Must be ${preferYounger ? 'younger' : 'older'} than ${targetAge}. `).append(result());
 	}
 
 	if (V.arcologies[0].FSIntellectualDependency > 20) {
-		if (slave) {
-			test = slave.energy >= 96;
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must be sexually receptive at all times. `).append(result());
+		checks.push([
+			slave => slave.energy >= 96,
+			`Must be sexually receptive at all times`
+		]);
 	} else if (V.arcologies[0].FSSlaveProfessionalism > 20) {
-		if (slave) {
-			test = slave.skill.vaginal + slave.skill.anal + slave.skill.oral + slave.skill.entertainment + slave.skill.whoring >= (eliteAngered ? 500 : 400);
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must be capable of mastering skills. `).append(result());
-		if (slave) {
-			test = slave.accent <= 1;
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must be capable of eloquent and accurate speech. `).append(result());
+		checks.push(
+			[
+				slave => slave.skill.vaginal + slave.skill.anal + slave.skill.oral + slave.skill.entertainment + slave.skill.whoring >= (eliteAngered ? 500 : 400),
+				`Must be capable of mastering skills`
+			],
+			[
+				slave => slave.accent <= 1,
+				`Must be capable of eloquent and accurate speech`
+			],
+		);
 	}
+
 	if (V.arcologies[0].FSPetiteAdmiration > 20 || V.arcologies[0].FSStatuesqueGlorification > 20) {
 		const targetHeight = V.arcologies[0].FSPetiteAdmiration > 20 ? 150 : 186;
 		if (V.arcologies[0].FSPetiteAdmiration > 20) {
-			if (slave) {
-				test = (slave.height - (slave.heightImplant * 10)) < targetHeight;
-			}
-			App.UI.DOM.appendNewElement("li", list, `Must naturally be very short. (${targetHeight} cm) `).append(result());
-			if (slave) {
-				test = (slave.height - (slave.heightImplant * 10)) < Height.mean(slave) - 15;
-			}
-			App.UI.DOM.appendNewElement("li", list, `Must naturally be very short for their age. `).append(result());
+			checks.push(
+				[
+					slave => (slave.height - (slave.heightImplant * 10)) < targetHeight,
+					`Must naturally be very short (${targetHeight}cm)`
+				],
+				[
+					slave => (slave.height - (slave.heightImplant * 10)) < Height.mean(slave) - 15,
+					`Must naturally be very short for their age`
+				],
+			);
 		} else if (V.arcologies[0].FSStatuesqueGlorification > 20) {
-			if (slave) {
-				test = (slave.height - (slave.heightImplant * 10)) > targetHeight;
-			}
-			App.UI.DOM.appendNewElement("li", list, `Must naturally be very tall. (${targetHeight} cm) `).append(result());
+			checks.push([
+				slave => (slave.height - (slave.heightImplant * 10)) > targetHeight,
+				`Must naturally be very tall (${targetHeight}cm)`
+			]);
 		}
 	}
 
 	if (V.arcologies[0].FSSupremacist > 20 || V.arcologies[0].FSSubjugationist > 20) {
 		const targetRace = V.arcologies[0].FSSupremacist > 20 ? V.arcologies[0].FSSupremacistRace : V.arcologies[0].FSSubjugationistRace;
 		if (V.arcologies[0].FSSupremacist > 20) {
-			if (slave) {
-				test = slave.race === targetRace;
-			}
-			App.UI.DOM.appendNewElement("li", list, `Must be ${targetRace}. `).append(result());
+			checks.push([
+				slave => slave.race === targetRace,
+				`Must be ${targetRace}`
+			]);
 		} else {
-			if (slave) {
-				test = slave.race !== targetRace;
-			}
-			App.UI.DOM.appendNewElement("li", list, `Must not be ${targetRace}. `).append(result());
+			checks.push([
+				slave => slave.race !== targetRace,
+				`Must not be ${targetRace}`
+			]);
 		}
 	}
 
 	if (V.arcologies[0].FSGenderRadicalist > 20) {
-		if (slave) {
-			test = slave.dick >= 1 && slave.balls >= 1;
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must have a functional penis. `).append(result());
+		checks.push([
+			slave => slave.dick >= 1 && slave.balls >= 1,
+			`Must have a functional penis`
+		]);
 	} else if (V.arcologies[0].FSGenderFundamentalist > 20) {
-		if (slave) {
-			test = slave.dick === 0 && slave.balls === 0;
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must be physically female. `).append(result());
+		checks.push([
+			slave => slave.dick === 0 && slave.balls === 0,
+			`Must be physically female`
+		]);
 	}
+
 	if (V.arcologies[0].FSPaternalist > 20) {
-		if (slave) {
-			test = slave.intelligenceImplant >= (SlaveProfessionalismEstablished ? 30 : 15);
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must be ${SlaveProfessionalismEstablished ? 'well' : ''} educated. `).append(result());
-		if (slave) {
-			test = slave.health.condition >= 60;
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must be in good health. `).append(result());
-	// } else if (V.arcologies[0].FSDegradationist > 20) {
+		checks.push([
+			slave => slave.intelligenceImplant >= (SlaveProfessionalismEstablished ? 30 : 15),
+			`Must be ${SlaveProfessionalismEstablished ? 'well' : ''} educated`
+		]);
+		checks.push([
+			slave => slave.health.condition >= 60,
+			`Must be in good health`
+		]);
 	}
 
 	if (SlaveProfessionalismEstablished) {
-		if (slave) {
-			test = slave.intelligenceImplant >= 15;
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must be well educated. `).append(result());
+		checks.push([
+			slave => slave.intelligenceImplant >= 15,
+			`Must be well educated`
+		]);
 	}
 
 	if (V.arcologies[0].FSBodyPurist > 20) {
-		if (slave) {
-			test = slave.chem <= (eliteAngered ? 0 : 15);
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must have low carcinogen levels. `).append(result());
-		if (slave) {
-			test = slave.boobsImplant + slave.buttImplant + slave.lipsImplant + slave.hipsImplant + slave.shouldersImplant === 0 && slave.faceImplant <= 5 && slave.bellyImplant === -1;
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must be implant free. `).append(result());
-	// } else if (V.arcologies[0].FSTransformationFetishist > 20) {
-	//	idealSlave.chem = 20;
+		checks.push([
+			slave => slave.chem <= (eliteAngered ? 0 : 15),
+			`Must have low carcinogen levels`
+		]);
+		checks.push([
+			slave => slave.boobsImplant + slave.buttImplant + slave.lipsImplant + slave.hipsImplant + slave.shouldersImplant === 0 && slave.faceImplant <= 5 && slave.bellyImplant === -1,
+			`Must be implant free`
+		]);
 	}
+
 	if (V.arcologies[0].FSSlimnessEnthusiast > 20) {
-		if (slave) {
-			test = slave.weight <= (partyAnimal ? 30 : 0);
-		}
-		if (partyAnimal) {
-			App.UI.DOM.appendNewElement("li", list, `May be no larger than "plush". `).append(result());
+		if (V.arcologies[0].FSHedonisticDecadence > 20) {
+			checks.push([
+				slave => slave.weight <= 30,
+				`May be no larger than "plush"`
+			]);
 		} else {
-			App.UI.DOM.appendNewElement("li", list, `Must be thin. `).append(result());
-		}
-		if (slave) {
-			test = slave.butt <= 2;
+			checks.push([
+				slave => slave.weight <= 0,
+				`Must be thin`
+			]);
 		}
-		App.UI.DOM.appendNewElement("li", list, `Must have a trim rear. `).append(result());
-		if (slave) {
-			test = slave.boobs <= 400;
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must have a sleek chest. `).append(result());
+		checks.push([
+			slave => slave.butt <= 2,
+			`Must have a trim rear`
+		]);
+		checks.push([
+			slave => slave.boobs <= 400,
+			`Must have a sleek chest`
+		]);
 	} else if (V.arcologies[0].FSAssetExpansionist > 20) {
-		if (slave) {
-			test = (implantsExpected ? (slave.butt) : (slave.butt - slave.buttImplant)) >= 6;
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must have a ${implantsExpected ? '' : 'naturally'} gigantic rear. `).append(result());
-		if (slave) {
-			test = (implantsExpected ? (slave.boobs) : (slave.boobs - slave.boobsImplant)) >= 1000;
+		if (V.arcologies[0].FSTransformationFetishist > 20) {
+			checks.push(
+				[
+					slave => slave.butt >= 6,
+					`Must have a gigantic rear`
+				],
+				[
+					slave => slave.boobs >= 1000,
+					`Must be busty`
+				],
+			);
+		} else {
+			checks.push(
+				[
+					slave => slave.butt - slave.buttImplant >= 6,
+					`Must have a naturally gigantic rear`
+				],
+				[
+					slave => slave.boobs - slave.boobsImplant >= 1000,
+					`Must be naturally busty`
+				],
+			);
 		}
-		App.UI.DOM.appendNewElement("li", list, `Must be ${implantsExpected ? '' : 'naturally'} busty. `).append(result());
 	}
+
 	if (V.arcologies[0].FSPastoralist > 20) {
-		if (slave) {
-			test = slave.lactation === 1;
-		}
-		App.UI.DOM.appendNewElement("li", list, `Must be lactating naturally. `).append(result());
+		checks.push([
+			slave => slave.lactation === 1,
+			`Must be lactating naturally`
+		]);
 	}
 	if (V.arcologies[0].FSPhysicalIdealist > 20) {
 		if (V.arcologies[0].FSPhysicalIdealistLaw === 1) {
 			const musclesMin = 20;
 			const musclesMax = 50;
-			if (slave) {
-				test = slave.weight <= 30;
-			}
-			App.UI.DOM.appendNewElement("li", list, `Must not be overweight. `).append(result());
-			if (slave) {
-				test = slave.muscles.isBetween(musclesMin, musclesMax);
-				fixable = (slave.muscles <= musclesMin && slave.muscles > musclesMax - musclesMin) || (slave.muscles >= musclesMax && slave.muscles < musclesMin + 30);
-				if (fixable && passing === 0) {
-					passing = 2;
-				}
-			}
-			App.UI.DOM.appendNewElement("li", list, `Must be fit, but not too muscular. `).append(result());
+
+			checks.push(
+				[
+					slave => slave.weight <= 30,
+					`Must not be overweight`
+				],
+				[
+					slave => slave.muscles.isBetween(musclesMin, musclesMax),
+					`Must be fit, but not too muscular`
+				],
+			);
 		} else {
-			if (slave) {
-				test = slave.muscles > 95;
-			}
-			App.UI.DOM.appendNewElement("li", list, `Must be extremely muscular. `).append(result());
+			checks.push([
+				slave => slave.muscles > 95,
+				`Must be extremely muscular`
+			]);
 		}
 	} else if (V.arcologies[0].FSHedonisticDecadence > 20) {
 		const targetWeight = V.arcologies[0].FSSlimnessEnthusiast > 20 ? 10 : 95;
-		if (slave) {
-			test = slave.weight > targetWeight;
-		}
+
 		if (V.arcologies[0].FSSlimnessEnthusiast > 20) {
-			App.UI.DOM.appendNewElement("li", list, `Must be more than "trim". `).append(result());
+			checks.push([
+				slave => slave.weight > targetWeight,
+				`Must be more than "trim"`
+			]);
 		} else {
-			App.UI.DOM.appendNewElement("li", list, `Must be big, soft and fat. `).append(result());
+			checks.push([
+				slave => slave.weight > targetWeight,
+				`Must be big, soft and fat`
+			]);
 		}
 	}
 
 	if (slave) {
-		if (passing === 2) {
-			r.push(`The aforementioned slave has been deemed <span class="yellow">currently unsuitable</span> for breeding, but may be resubmitted after corrections are applied. We understand the subjective nature of "fit" and do not wish to preclude the use a viable breeder over such a trivial fix. A contraceptive routine has been applied to protect against "accidents" in the interim.`);
-			slave.preg = -1;
-		} else if (passing !== 0) {
+		checks.forEach(check => {
+			const tr = App.UI.DOM.appendNewElement("tr", table);
+
+			App.UI.DOM.appendNewElement("td", tr, `• ${check[1]}`);
+
+			if (!check[0](slave)) {
+				App.UI.DOM.appendNewElement("td", tr, `FAILED`, ["red"]);
+			} else {
+				App.UI.DOM.appendNewElement("td", tr, `PASSED`, ["lime"]);
+			}
+		});
+
+		if (checks.some(check => !check[0](slave))) {
 			r.push(`The aforementioned slave has been deemed <span class="red">unsuitable</span> for breeding.`);
+
 			slave.preg = -3;
 		} else {
 			r.push(`The aforementioned slave has been deemed <span class="green">worthy</span> of being used for breeding and has been marked as such. Please note the increased restrictions on breeding slaves.`);
 			r.push(`They are not permitted for public use or anything that may harm their growing child. The child within them is considered a member of the Elite class and as such, any harm that comes to them will result in severe penalties to the breeder's owner. Development of the child will be closely monitored; should the fetus be identified as not of the owner's blood (or any other member of the Elite class), said owner shall face severe fines.`);
+
 			slave.breedingMark = 1;
 			slave.pregControl = "none";
+
 			const job = App.Utils.jobForAssignment(slave.assignment);
 			const consequences = [];
 			if (slave.assignment === Job.BODYGUARD || (job && job.desc.publicSexUse)) {
@@ -260,8 +289,20 @@ globalThis.eliteBreedingExam = function(slave = null) {
 				r.push(`${He} has been automatically ${toSentence(consequences)}.`);
 			}
 		}
+
 		cashX(-cost, "capEx");
+	} else {
+		checks.forEach(check => {
+			const tr = App.UI.DOM.appendNewElement("tr", table);
+
+			App.UI.DOM.appendNewElement("td", tr, check[1]);
+		});
 	}
+
+	// hack to circumvent default SugarCube styling
+	table.style.marginLeft = "1em";
+
 	App.Events.addNode(frag, r, "div");
+
 	return frag;
 };
diff --git a/src/uncategorized/dairy.tw b/src/uncategorized/dairy.tw
deleted file mode 100644
index 27ec66d4bcadc5017202d0edfd029de9f63b8da3..0000000000000000000000000000000000000000
--- a/src/uncategorized/dairy.tw
+++ /dev/null
@@ -1,824 +0,0 @@
-:: Dairy [nobr jump-to-safe jump-from-safe]
-
-<<set _slaves = App.Utils.sortedEmployees(App.Entity.facilities.dairy)>>
-<<set $nextButton = "Back to Main", $nextLink = "Main", $returnTo = "Dairy", $encyclopedia = "Dairy", _SL = $slaves.length, _DL = _slaves.length>>
-
-<<set _dairyNameCaps = capFirstChar($dairyName)>>
-
-<<if ($dairyRestraintsSetting != 2) || ($dairyRestraintsUpgrade != 1)>>
-	<<if $dairyStimulatorsSetting == 2>>
-		<<set $dairyStimulatorsSetting = 1>>
-	<</if>>
-	<<if $dairyPregSetting >= 2>>
-		<<set $dairyPregSetting = 1>>
-	<</if>>
-	<<if $dairyFeedersSetting == 2>>
-		<<set $dairyFeedersSetting = 1>>
-	<</if>>
-<</if>>
-
-<p>
-	<<if ($MilkmaidID != 0) && ($dairyRestraintsSetting == 2)>>
-		<<run App.Utils.setLocalPronouns(_S.Milkmaid)>>
-		_S.Milkmaid.slaveName has been removed from $his position as Milkmaid, since an industrialized dairy automates $his duties.
-		<<= removeJob(_S.Milkmaid, "be the Milkmaid")>>
-	<</if>>
-</p>
-
-<<if (_DL > 1)>>
-	<p>
-		<<if $dairyFeedersSettingChanged == 1>>
-			In unison, the milking machines press their feeding phalli into the slaves' mouths and down their throats. Once situated, they begin to facefuck the slaves, who gag and struggle as they figure out how to breathe while this is going on. Once each slave is no longer panicking and is inhaling and exhaling regularly, there is a hydraulic sound and the transparent reservoir of feeding fluid near their head begins to drain. The slaves swallow desperately, their bellies beginning to swell with nutrition and drugs.
-		<<elseif $dairyFeedersSettingChanged == -1>>
-			In unison, the milking machines withdraw their feeders from the slaves' throats. The slaves gag and cough, strings of feeding fluid and saliva running between their lips and the heads of the feeding phalli. These remain close to their faces so that the slaves can suck them off once they get hungry, which they will, very soon. The slaves' mouths and tongues are very tired, and most of them rest with their mouths open and their tongues hanging out.
-		<</if>>
-	</p>
-	<p>
-		<<if $dairyPregSettingChanged == 1>>
-			<<set _purgedSlaves = false>>
-			<<for _slave range _slaves>>
-				<<run App.Utils.setLocalPronouns(_slave)>>
-				<<if (_slave.vagina > -1) && (_slave.vagina < 3)>>
-					_slave.slaveName's milking machine ejects $him, since it cannot fit the mandated dildo into $his tight cunt.
-					<<= removeJob(_slave, Job.DAIRY)>>
-					<<set _purgedSlaves = true>>
-					<<continue>>
-				<</if>>
-				<<if ($dairyPregSetting > 0)>>
-					<<set WombCleanGenericReserve(_slave, "incubator", 9999)>>
-					<<set WombCleanGenericReserve(_slave, "nursery", 9999)>>
-					<<if ((_slave.broodmother > 0) || (_slave.bellyImplant != -1))>>
-						_slave.slaveName's milking machine ejects $him, since it detected a foreign body in $his womb blocking its required functions.
-						<<= removeJob(_slave, Job.DAIRY)>>
-						<<set _purgedSlaves = true>>
-					<</if>>
-				<</if>>
-			<</for>>
-			<<if _purgedSlaves>>
-				<<set _slaves = App.Utils.sortedEmployees(App.Entity.facilities.dairy)>>
-				<<set _DL = _slaves.length>>
-			<</if>>
-			In unison, the milking machines withdraw their dildos from the pregnant slaves' vaginas. The auxiliary drug injectors hiss as the slaves are filled with drugs that promote natural lubrication. The slaves begin to shift awkwardly as they feel their pussies begin to drool slick female fluids. Once a machine judges that its slave's cunt is sufficiently wet, it readies a gigantic dildo. The slaves cannot see their own groins, but as soon as the heads of the dildos touch their pussylips, they begin to
-			<<if $dairyFeedersSetting < 2>>
-				struggle instinctively against their restraints, and the more energetic ones begin to weep.
-			<<else>>
-				struggle instinctively against their restraints.
-			<</if>>
-			As the massive phalli begin to ejaculate fertility drugs and semen, they drive all resistance out of the poor girls.
-		<<elseif $dairyPregSettingChanged == -1>>
-			In unison, the milking machines withdraw their monstrous dildos from the pregnant slaves' stretched cunts. Their pussies' overcharged production of natural lubricant produces a gush of pent-up female fluids from each loose vagina as the phalli slide clear.
-			<<if $dairyFeedersSetting < 2>>
-				The slaves moan with relief at the sudden reduction in fullness. Being penetrated like that while pregnant must be quite uncomfortable.
-			<<else>>
-				The slaves are silent, since their mouths and throats are being fucked by the feeders, but most of them relax a little in their restraints.
-			<</if>>
-			The machines do replace the withdrawn dildos with more reasonably sized phalli and resume thrusting, but the slaves are relieved anyway.
-		<</if>>
-	</p>
-	<p>
-		<<if $dairyStimulatorsSettingChanged == 1>>
-			<<set _purgedSlaves = false>>
-			<<for _slave range _slaves>>
-				<<if (_slave.anus < 3)>>
-					<<run App.Utils.setLocalPronouns(_slave)>>
-					_slave.slaveName's milking machine ejects $him, since it cannot fit its massive anal dildo up $his tight asshole.
-					<<= removeJob(_slave, Job.DAIRY)>>
-					<<set _purgedSlaves = true>>
-				<</if>>
-			<</for>>
-			<<if _purgedSlaves>>
-				<<set _slaves = App.Utils.sortedEmployees(App.Entity.facilities.dairy)>>
-				<<set _DL = _slaves.length>>
-			<</if>>
-			In unison, the milking machines shove their dildos deep into slaves' anuses, ejaculating large quantities of lubricant deep inside their rectums. The slaves start in surprise at the sudden rush of warm slick fluid, and then relax as the phalli withdraw themselves from their butts. Their relief is short-lived, however, as their assholes are only empty for a moment. The reasonably sized dildos are replaced with dildos the size of horse cocks. As soon as the slaves feel the heads of these monstrous phalli press inexorably against their sphincters,
-			<<if $dairyFeedersSetting < 2>>
-				they begin to scream and struggle instinctively. As the constant assrape that will define their existences for the foreseeable future begins in earnest, their whining
-			<<else>>
-				they begin to struggle wildly. As the constant assrape that will define their existences for the foreseeable future begins in earnest, their wriggling
-			<</if>>
-			gradually diminishes as each slave is exhausted and slumps within their restraints. The machines take no notice, and continue the relentless sodomy.
-		<<elseif $dairyStimulatorsSettingChanged == -1>>
-			In unison, the milking machines withdraw their gargantuan dildos from the slaves' loosened anuses.
-			<<if $dairyFeedersSetting < 2>>
-				Several of the more energetic slaves begin to cry quietly with relief
-			<<else>>
-				The slaves are silent, since their mouths and throats are being fucked by the feeders, but most of them slump against their machines with relief
-			<</if>>
-			as their sphincters gradually recover from wide open to merely gaping. The machines switch out the withdrawn dildos for phalli that are just large, but the slaves barely react at all as they are penetrated. After what their sphincters have been through, a merely big dick is nothing to them.
-		<</if>>
-	</p>
-	/* a fake slave object, we need the .pronoun attribute only */
-	<<set _fSlave = {pronoun: App.Data.Pronouns.Kind.female}>>
-	/* Used for generic slaves, citizens, security, etc. */
-	<<if $diversePronouns == 1>>
-		<<if $seeDicks === 100>>
-			<<set _fSlave.pronoun = App.Data.Pronouns.Kind.male>>
-		<<elseif ($seeDicks > 0) && (random(1,100) <= $seeDicks)>>
-			<<set _fSlave.pronoun = App.Data.Pronouns.Kind.male>>
-		<</if>>
-	<</if>>
-	<<run App.Utils.setLocalPronouns(_fSlave, 'U')>>
-	<p>
-		<<if $dairyRestraintsSettingChanged == 1>>
-			<<if $dairyRestraintsSetting == 1>>
-				<<set _purgedSlaves = false>>
-				<<for _slave range _slaves>>
-					<<run App.Utils.setLocalPronouns(_slave)>>
-					<<if (_slave.indentureRestrictions >= 2)>>
-						_slave.slaveName's milking machine declines to restrain $him, since $he is encoded as an indentured servant protected from restraint for milking.
-						<<= removeJob(_slave, Job.DAIRY)>>
-						<<set _purgedSlaves = true>>
-					<</if>>
-				<</for>>
-				<<if _purgedSlaves>>
-					<<set _slaves = App.Utils.sortedEmployees(App.Entity.facilities.dairy)>>
-					<<set _DL = _slaves.length>>
-				<</if>>
-				The next cow to stumble over to a milking machine to be drained is gently but firmly embraced by its restraints, allowing it to suck _himU dry and violate _himU without any regard for _hisU feelings. Most of the cows accept this new wrinkle in their lives, since the restraints let them go afterward, and the milking machines bring temporary relief. Some, however, begin to regard the machines with concern.
-			<<else>>
-				The next cow to stumble over to a milking machine to be drained finds to _hisU surprise that _heU is not restrained while it sucks _himU dry. _HeU wiggles around experimentally, verifying that _heU is indeed free to pull _himselfU away from its ministrations if _heU wishes. There's little actual impact on the cows' behavior, since they still need the relief the machines offer.
-			<</if>>
-		<<elseif $dairyRestraintsSettingChanged == -1>>
-			<<if $dairyRestraintsSetting == 1>>
-				<<set _purgedSlaves = false>>
-				<<for _slave range _slaves>>
-					<<if (_slave.indentureRestrictions >= 1)>>
-						<<run App.Utils.setLocalPronouns(_slave)>>
-						_slave.slaveName's milking machine declines to restrain $him, since $he is encoded as an indentured servant protected from being restrained for milking.
-						<<= removeJob(_slave, "work in the dairy")>>
-						<<set _purgedSlaves = true>>
-					<</if>>
-				<</for>>
-				<<if _purgedSlaves>>
-					<<set _slaves = App.Utils.sortedEmployees(App.Entity.facilities.dairy)>>
-					<<set _DL = _slaves.length>>
-				<</if>>
-				The next time a cow tries to get up after being milked, _heU finds to _hisU sudden terror that the machine will not let _himU go. It continues to add fluids to _hisU body, and remove them from _hisU nipples, ignoring _hisU mounting panic as _heU realizes that it's to be _hisU new partner and lover, on a level far more intimate than any possible human relationship. The other cows approach their machines with trepidation, but the mounting pressure in their udders forces them to embrace their immurement despite their terror.
-			<<else>>
-				The next time a cow finishes an intensive milking period, _hisU restraints loosen. _HeU does not move for a long time, as though _heU is unable to believe that _heU is, at least in an immediate and local sense, free. Finally, _heU prises _himselfU out of _hisU milking machine's embrace, thick strings of fluid leading from it to _hisU orifices as _heU pulls each one off of its corresponding port.
-			<</if>>
-		<</if>>
-	</p>
-<</if>>
-
-<<set $dairyStimulatorsSettingChanged = 0, $dairyFeedersSettingChanged = 0, $dairyPregSettingChanged = 0, $dairyRestraintsSettingChanged = 0>>
-
-<p class="scene-intro">
-	<<if ($dairyRestraintsSetting > 1)>>
-		_dairyNameCaps is an industrial facility, but there's a viewing gallery for visitors.
-		<<switch $dairyDecoration>>
-			<<case "Roman Revivalist">>
-				The screens there review each slave's liquid contributions to the state in minute detail.
-			<<case "Neo-Imperialist">>
-				The sleek screens display a variety of statistics on each slave's vitals and production.
-			<<case "Aztec Revivalist">>
-				The strange sight of the milking machines, designed to look like fertility statues gives the space an imposing feeling.
-			<<case "Egyptian Revivalist">>
-				The screens there list a tally of each slave's contributions to the harvest this season. They also identify related slaves who occupy multi-slave milking machines so that they may feed each other directly.
-			<<case "Edo Revivalist">>
-				It looks out on a strangely contradictory sight: a beautiful and terrible combination of modern slavery and technology, placed amongst tatami mats and rice paper partitions.
-			<<case "Arabian Revivalist">>
-				It looks out on a strangely contradictory sight: a beautiful and terrible combination of modern slavery and technology, placed inside brightly tiled walls.
-			<<case "Chinese Revivalist">>
-				The milking machines are fascinating: they're encased in decorative carvings, making it look like the slaves are in the embrace of traditional Chinese depictions of lions, bears, and dragons.
-			<<case "Chattel Religionist">>
-				It presents the inmates as lessons, here to expiate their sins in a purgatory created by technology.
-			<<case "Degradationist">>
-				The screens there feature, among a sea of facts and figures about each slave, their most recent brain scan.
-			<<case "Repopulationist">>
-				The gallery is placed for a good view of each slave's swelling breasts and growing pregnancy. A screen is prominently displayed before each slave, detailing the number of babies she produced and the current number occupying their womb.
-			<<case "Eugenics">>
-				The screens there tell very little about the slaves within. That information is privy only to Society's Elite.
-			<<case "Asset Expansionist">>
-				It's designed for VIP visits, since this place is arguably the present apogee of expansionism. Nowhere else can breasts become so large. This is a place for pride.
-			<<case "Transformation Fetishist">>
-				It's designed for VIP visits, since this place is arguably the present apogee of transformationism. Nowhere else can slaves be so radically changed, from humans into something less — and something more.
-			<<case "Gender Radicalist">>
-				The gallery is placed for a good view of each slave's front, from their head to what's between their spread legs.
-			<<case "Gender Fundamentalist">>
-				The gallery is placed for a good view of each slave's breasts, belly, and cunt. Visitors can critically compare each feminine advantage.
-			<<case "Physical Idealist">>
-				The gallery is placed for a good view of each slave's body. Though muscles are at a lower premium here, there is intense interest in such radical changes to human biology.
-			<<case "Supremacist">>
-				The screens there give information about each cow, but the data they present is also predictive. They imply a vision for a world in which more subhumans serve in this way. Many more.
-			<<case "Subjugationist">>
-				The screens there give information about each cow, but the data they present is also predictive. They imply a vision for a world in which more milking machines have $arcologies[0].FSSubjugationistRace components. Many more.
-			<<case "Paternalist">>
-				The screens there include feeds that show what media is being pumped into the slaves through their machines. It's designed to provide as much mental stimulation as possible.
-			<<case "Pastoralist">>
-				The screens there let the production figures speak for themselves. There may be more personable cows out there, but they don't produce milk like these do.
-			<<case "Maturity Preferentialist">>
-				The screens there give each slave's productivity and forecast it into the future. The facility is unmatched at extracting value from mature bodies.
-			<<case "Youth Preferentialist">>
-				The screens there give each slave's productivity and forecast it into the future. The best bodies here have many, many years of productivity ahead of them.
-			<<case "Body Purist">>
-				The screens there offer reams of data on each slave's product purity. Drugs are necessary here, and each body's balance results in a different grade of product.
-			<<case "Slimness Enthusiast">>
-				The screens there alternate live views of the fashionably slim cows in their stalls with brief infomercials on the specialized techniques and equipment $dairyName uses to extract milk from such modest udders.
-			<<case "Hedonistic">>
-				The gallery is placed for a good view of each slave's fattened body and the undulations running through them from the force of the milkers<<if $dairyPregSetting || $dairyFeedersSetting || $dairyStimulatorsSetting>> and other assorted tubes and dildos<</if>>.
-			<<case "Intellectual Dependency">>
-				The screens there feature an active scan showcasing each slave's diminishing brain activity.
-			<<case "Slave Professionalism">>
-				It serves as a dire warning to what happens to unskilled, moronic slaves.
-			<<case "Petite Admiration">>
-				The gallery is placed for a good view of each slave's petite body. Those that don't fit in a standard milking unit are kept well out of sight.
-			<<case "Statuesque Glorification">>
-				The gallery is placed for a good view of each slave's body. Fascinated visitors may peruse each slave's productivity statistics contrasted against their height on a corresponding touchscreen.
-			<<default>>
-				Fascinated visitors may peruse each slave's productivity statistics on a corresponding touchscreen.
-		<</switch>>
-	<<else>>
-		_dairyNameCaps
-		<<switch $dairyDecoration>>
-			<<case "Roman Revivalist">>
-				is functional and clean, using traditional methods wherever possible. At one end of the long row of stalls there is an alcove with a shrine to the Roman goddess of bountiful harvests.
-			<<case "Neo-Imperialist">>
-				is cold and industrial, filled with the latest in industrial harvesting technology. The slaves do their duty underneath the hanging banners of your house, reminding them who owns their very bodies and all they produce.
-			<<case "Aztec Revivalist">>
-				is sterile and organized, using traditional methods wherever possible. At one end of the long row of stalls there is an alcove with a shrine to the Aztec god of the Earth.
-			<<case "Egyptian Revivalist">>
-				is functional and clean, using traditional methods wherever possible. At one end of the long row of stalls there is an alcove with a shrine to the Egyptian god of bountiful harvests.
-			<<case "Edo Revivalist">>
-				is clean and traditional. The stalls are constructed of bamboo and carefully shaped wood, and muscle power is used wherever possible. Cows exercise and help out by walking on a wooden wheel that raises fresh water to $dairyName.
-			<<case "Arabian Revivalist">>
-				is clean and traditional. Its dusky stone walls keep it so warm that the cows go nude, basking in the hot sun between milkings.
-			<<case "Chinese Revivalist">>
-				is clean and traditional. The stalls are constructed of bamboo and carefully shaped wood, and muscle power is used wherever possible. Cows exercise and help out by fetching and carrying as best they can.
-			<<case "Chattel Religionist">>
-				is functional and clean. There are nice quotations from the holy book on the walls, and there is a little shrine designed to allow a cow who has difficulty standing to make their devotions comfortably.
-			<<case "Degradationist">>
-				is harsh and utilitarian. There are stands to restrain cows who aren't being milked for dosing, punishment, or sexual use. There are cattle prods here and there to use on resistant cows, unproductive cows, or cows one wishes to hear scream.
-			<<case "Repopulationist">>
-				is comfortable and well-kept. The milking machines are specially designed to maximize a pregnant cow's comfort. After a milking, cows have a wide selection of soft furniture to choose from, so comfortable that most fall fast asleep.
-			<<case "Eugenics">>
-				is comfortable, well-kept and well-monitored. Cows are kept track of at all times to make sure no-one tries to increase milk production via pregnancy.
-			<<case "Asset Expansionist">>
-				looks misleadingly industrial at first glance. Though the cows here are free-range, the facility mounts a system of slings and cranes to allow slaves with massive udders to walk around with their tits suspended from the ceiling.
-			<<case "Transformation Fetishist">>
-				looks like a medical facility at first glance. Transformation is just as much a priority as production: there are surgical and drug injection machines right here.
-			<<case "Gender Radicalist">>
-				is comfortable and well-kept. The milking machines include perianal vibrators to massage slaves from butthole to cock while they give cum.
-			<<case "Gender Fundamentalist">>
-				is comfortable and well-kept. The milking machines include vibrators so that cows can get off while they're milked.
-			<<case "Physical Idealist">>
-				could be mistaken for a gym with milking machines. Cows here are expected to keep fit between milkings, since the best milk comes from cattle who are healthy, muscular, and strong.
-			<<case "Supremacist">>
-				is spartan, since that's all subhuman cows need. There are cattle prods here and there to use on resistant cows, unproductive cows, or subhuman cows one wishes to hear scream.
-			<<case "Subjugationist">>
-				is spartan, since that's all $arcologies[0].FSSubjugationistRace cows need. There are cattle prods here and there to use on resistant cows, unproductive cows, or $arcologies[0].FSSubjugationistRace cows one wishes to hear scream.
-			<<case "Paternalist">>
-				is comfortable and well-kept. Rather than stalls, $dairyName has an open arrangement of machines cows can use freely, and a lovely common area they can relax in afterward.
-			<<case "Pastoralist">>
-				is state of the art, but is also brilliantly designed to look like a barn. All the advanced machinery retracts when not in use, leaving the cows in a clean, airy pastoral paradise. It smells of summer.
-			<<case "Maturity Preferentialist">>
-				is inviting and homelike. After a milking, cows have a wide selection of soft furniture to choose from, so comfortable that most fall fast asleep.
-			<<case "Youth Preferentialist">>
-				is functional, but fun. There are all sorts of fun activities to keep the cows amused between milkings, cleverly adapted for girls with massive mammaries.
-			<<case "Body Purist">>
-				is state of the art, and spotlessly clean. All attention here is on the cows, to keep them happy, productive, and pure.
-			<<case "Slimness Enthusiast">>
-				is quite unusual. Since the cows it milks may not necessarily have gigantic boobs, the milking machines here can adapt to drain cream from any body.
-			<<case "Hedonistic">>
-				is comfortable and fun. The stalls are filled with thick, soft pillows to lounge on while hooked to the milking machines and with plenty of toys to make use of while getting milked. Cows here are expected to binge eat between milkings, since the best milk comes from cattle who are immobile, stuffed with food and hugely fat.
-			<<case "Intellectual Dependency">>
-				is simple and fun. Getting situated for milking is easy enough for even the dumbest cow to figure out and there are all sorts of activities to keep the cows amused between milkings.
-			<<case "Slave Professionalism">>
-				is functional and clean. A wide selection of informative documentaries and books are available for cows to keep their minds sharp while the milker does its business.
-			<<case "Petite Admiration">>
-				is comfortable and well-kept. While designed for miniature cows, accommodations for large udders allow even the lankiest of cattle to make use of the machinery.
-			<<case "Statuesque Glorification">>
-				is comfortable and well-kept. While designed for towering cows, accommodations for large udders allow even the shortest of cattle to make use of the machinery; even if they need help to reach it.
-			<<default>>
-				is comfortable and well-kept. It features nice rest areas for cows to lounge in after a milking, and exercise equipment to keep them healthy.
-		<</switch>>
-	<</if>>
-
-	<<if _DL > 2>>
-		_dairyNameCaps is working steadily.
-		<<if ($dairyRestraintsUpgrade == 1) && ($dairyRestraintsSetting > 1)>>
-			Each cow is strapped into their own milking machine. The machines are set up in rows, alternating forward and backward so that the cows are interleaved as closely as possible without touching.
-			<<if ($dairyFeedersUpgrade == 1) && ($dairyFeedersSetting > 0)>>
-				<<if $dairyFeedersSetting == 2>>
-					A phallic feeding tube completely fills each cow's mouth and throat, making it eerily quiet in there. Occasionally one of the cows convulses when a particularly long rush of food and drugs flows down their gullet.
-				<<else>>
-					When feeding is required, a phallus extends into cows' mouths.
-				<</if>>
-			<</if>>
-			<<if ($dairyStimulatorsUpgrade == 1) && ($dairyStimulatorsSetting > 0)>>
-				<<if $dairyStimulatorsSetting == 2>>
-					Every cow is being sodomized by a massive phallus. Most are pumping away gently, the strokes taking a long time to push the half-<<if $showInches == 2>>yard<<else>>meter<</if>> of shaft into each slave's rectum and pull it out again. When a slave's balls are ready to give cum, however, the pace quickens, and the agonized slave wriggles in involuntary desperation to escape until they finally stiffen, squirt, and slump in exhaustion.
-				<<else>>
-					Each cow's anus is periodically fucked by a machine phallus that ejaculates hydration directly up their butt. When a slave's balls are ready to give cum, they are mercilessly sodomized until prostate stimulation forces an orgasm.
-				<</if>>
-			<</if>>
-			<<if ($dairyPregUpgrade == 1) && ($dairyPregSetting > 0)>>
-				<<if $dairyPregSetting == 3>>
-					Fertile cows' vaginas are constantly penetrated by huge dildos that ejaculate extra strong fertility drugs into their progressively distending wombs. The drugs induce intense arousal and excessive female lubrication, so the constant dildo rape fills $dairyName with occasional gushing noises and nonstop moaning.
-				<<elseif $dairyPregSetting == 2>>
-					Fertile cows' vaginas are constantly penetrated by huge dildos that ejaculate fertility drugs. The drugs produce excessive female lubrication, so the constant dildo rape fills $dairyName with occasional gushing noises.
-				<<else>>
-					The fertile cows are visibly pregnant.
-				<</if>>
-			<</if>>
-		<<else>>
-			The row of milking machines is available for cows to use.
-			<<if ($dairyRestraintsSetting > 0)>>
-				When they do, the machines gently restrain them until they are completely done.
-			<</if>>
-			<<if ($dairyFeedersUpgrade == 1) && ($dairyFeedersSetting > 0)>>
-				The machines mount convenient phallic feeders for slaves to suck for tasty food while they're milked.
-			<</if>>
-			<<if ($dairyPregUpgrade == 1) && ($dairyPregSetting > 0)>>
-				The fertile cows are visibly pregnant.
-			<</if>>
-			<<if ($dairyStimulatorsUpgrade == 1) && ($dairyStimulatorsSetting > 0)>>
-				The machines gently sodomize cows who need the extra nutrition and treatment the dildos can ejaculate into them<<if $seeDicks > 0>>, and fuck them more vigorously when they need help ejaculating.<</if>>
-			<</if>>
-		<</if>>
-	<<elseif $bioreactorsXY+$bioreactorsXX+$bioreactorsHerm+$bioreactorsBarren > 0>>
-		_dairyNameCaps is quiet and calm. The only sounds are faint sucking and gushing noises.
-	<<elseif _DL > 0>>
-		_dairyNameCaps is sparsely populated.
-	<<elseif $MilkmaidID != 0>>
-		_S.Milkmaid.slaveName is alone in $dairyName, and has nothing to do but clean and maintain the equipment.
-	<<else>>
-		_dairyNameCaps is empty and desolate.
-		<div class="choices" style="font-style:normal">
-			<<link "Decommission the dairy" "Main">>
-				<<set $dairy = 0, $dairyFeedersUpgrade = 0, $dairyPregUpgrade = 0, $dairyStimulatorsUpgrade = 0, $dairyDecoration = "standard", $dairyFeedersSetting = 0, $dairyPregSetting = 0, $dairyStimulatorsSetting = 0, $dairyHyperPregRemodel = 0, $cumPipeline = 0, $milkPipeline = 0>>
-				<<run App.Arcology.cellUpgrade($building, App.Arcology.Cell.Manufacturing, "Dairy", "Manufacturing")>>
-			<</link>>
-		</div>
-	<</if>>
-</p>
-
-<div>
-	<<set _Tmult0 = Math.trunc($dairy*1000*$upgradeMultiplierArcology)>>
-	_dairyNameCaps can support $dairy milkers.
-	There <<if _DL == 1>>is<<else>>are<</if>> currently _DL cow<<if _DL != 1>>s<</if>>.
-	<div class="choices">
-		[[Expand the dairy|Dairy][cashX(forceNeg(_Tmult0), "capEx"), $dairy += 5, $PC.skill.engineering += .1]]
-		<span class="note">
-			Costs <<print cashFormat(_Tmult0)>> and will increase upkeep costs
-		</span>
-	</div>
-	<div class="choices">
-		<<if _DL > 0>>
-			<<includeDOM removeFacilityWorkers(App.Entity.facilities.dairy, "rest", "get milked")>>
-		<</if>>
-	</div>
-</div>
-
-<div>
-	<<set _Tmult1 = Math.trunc(10000*$upgradeMultiplierArcology)>>
-	<<if $dairyFeedersUpgrade == 1>>
-		The milking machines can hold feeders in slaves' mouths and inject drugs into their bodies, ensuring ideal nutrition and production.
-		<div class="choices">
-			The feeders are
-			<<if $dairyFeedersSetting == 2>>
-				''industrial.''
-				[[Moderate|Dairy][$dairyFeedersSetting = 1, $dairyFeedersSettingChanged = -1]]
-			<<elseif $dairyFeedersSetting == 1>>
-				''active.''
-				[[Inactive|Dairy][$dairyFeedersSetting = 0]]
-				<<if ($seeExtreme != 0) && ($dairyRestraintsSetting == 2)>>
-					| [[Industrial|Dairy][$dairyFeedersSetting = 2, $dairyFeedersSettingChanged = 1]]
-				<</if>>
-			<<else>>
-				''inactive.''
-				[[Active|Dairy][$dairyFeedersSetting = 1]]
-			<</if>>
-		</div>
-	<<else>>
-		_dairyNameCaps is equipped to feed and clean slaves normally.
-		<div class="choices">
-			[[Upgrade the milking machines with intubators|Dairy][cashX(forceNeg(_Tmult1), "capEx"), $dairyFeedersUpgrade = 1, $PC.skill.engineering += 0.1]]
-			<span class="note">
-				Costs <<print cashFormat(_Tmult1)>> and will increase upkeep costs
-			</span>
-		</div>
-	<</if>>
-</div>
-
-<div>
-	<<if $seePreg != 0>>
-		<<set _Tmult3 = Math.trunc(2500*$upgradeMultiplierArcology)>>
-		<<if $dairyPregUpgrade == 1>>
-			_dairyNameCaps can support cow pregnancies.
-			<div class="choices">
-				Fertile cows' wombs are
-				<<if $dairyPregSetting == 3>>
-					''worked to capacity.'' [[Industrial|Dairy][$dairyPregSetting = 2]]
-				<<elseif $dairyPregSetting == 2>>
-					''industrially employed.''
-					<<if ($seeExtreme != 0) && ($seeHyperPreg == 1) && ($dairyRestraintsSetting == 2) && ($dairyHyperPregRemodel == 1)>>
-						[[Mass Production|Dairy][$dairyPregSetting = 3]] |
-					<</if>>
-					[[Moderate|Dairy][$dairyPregSetting = 1, $dairyPregSettingChanged = -1]]
-				<<elseif $dairyPregSetting == 1>>
-					''for hire.''
-					[[Not for hire|Dairy][$dairyPregSetting = 0]]
-					<<if ($seeExtreme != 0) && ($dairyRestraintsSetting == 2)>>
-						| [[Industrial|Dairy][$dairyPregSetting = 2, $dairyPregSettingChanged = 1]]
-					<</if>>
-				<<else>>
-					''not for hire.''
-					[[For hire|Dairy][$dairyPregSetting = 1]]
-				<</if>>
-			</div>
-		<<else>>
-			_dairyNameCaps is not prepared to support cow pregnancies, and therefore cannot be used to contract out fertile slaves' wombs.
-			<div class="choices">
-				[[Upgrade the dairy to support pregnancies|Dairy][cashX(forceNeg(_Tmult3), "capEx"), $dairyPregUpgrade = 1]]
-				<span class="note">
-					Costs <<print cashFormat(_Tmult3)>> and will increase upkeep costs
-				</span>
-			</div>
-		<</if>>
-	<</if>>
-</div>
-
-<div>
-	<<if $dairyStimulatorsUpgrade == 1>>
-		The milking machines mount reciprocating dildos that can sodomize the slaves, delivering extra nutrition and pharmaceuticals. <<if $seeDicks > 0>>The prostate stimulation also serves to increase semen production, where appropriate.<</if>>
-		<div class="choices">
-			The sodomizers are
-			<<if $dairyStimulatorsSetting == 2>>
-				''industrial,''employing dildos the size of horse phalli.
-				[[Moderate|Dairy][$dairyStimulatorsSetting = 1, $dairyStimulatorsSettingChanged = -1]]
-			<<elseif $dairyStimulatorsSetting == 1>>
-				''active.''
-				[[Deactivate|Dairy][$dairyStimulatorsSetting = 0]]
-				<<if ($seeExtreme != 0) && ($dairyRestraintsSetting == 2)>>
-					| [[Industrial|Dairy][$dairyStimulatorsSetting = 2, $dairyStimulatorsSettingChanged = 1]]
-				<</if>>
-			<<else>>
-				''inactive.''
-				[[Activate|Dairy][$dairyStimulatorsSetting = 1]]
-			<</if>>
-		</div>
-	<<else>>
-		_dairyNameCaps does not automatically sodomize.
-		<div class="choices">
-			[[Upgrade the cockmilking machines with sodomizers|Dairy][cashX(forceNeg(_Tmult1), "capEx"), $dairyStimulatorsUpgrade = 1, $PC.skill.engineering += 0.1]]
-			<span class="note">
-				Costs <<print cashFormat(_Tmult1)>> and will increase upkeep costs
-			</span>
-		</div>
-	<</if>>
-</div>
-
-<div>
-	<<set _Tmult2 = Math.trunc(5000*$upgradeMultiplierArcology)>>
-	<<if ($dairyPregSetting == 2) || ($dairyStimulatorsSetting == 2)>>
-		<<if $dairyPrepUpgrade == 1>>
-			_dairyNameCaps features a preparatory raper designed to gape slaves for integration.
-		<<else>>
-			_dairyNameCaps's industrial machines can only accept slaves with loose holes.
-			<div class="choices">
-				[[Install a preparatory raper|Dairy][cashX(forceNeg(_Tmult2), "capEx"), $dairyPrepUpgrade = 1, $PC.skill.engineering += 0.1]]
-				<span class="note">
-					Costs <<print cashFormat(_Tmult2)>>
-				</span>
-			</div>
-		<</if>>
-	<</if>>
-</div>
-
-<div>
-	<<if $dairyRestraintsUpgrade == 1>>
-		_dairyNameCaps is equipped to restrain cows.
-		<div class="choices">
-			The cows are restrained
-			<<if $dairyRestraintsSetting == 2>>
-				''permanently,'' allowing use of industrial techniques even devoted cows would flinch at.
-				[[Only during milking|Dairy][$dairyRestraintsSetting = 1, $dairyRestraintsSettingChanged = -1]]
-			<<elseif $dairyRestraintsSetting == 1>>
-				''when being milked,'' giving the machines full play.
-				[[Free range|Dairy][$dairyRestraintsSetting = 0, $dairyRestraintsSettingChanged = -1]] |
-				[[Permanent machine milking|Dairy][$dairyRestraintsSetting = 2, $dairyRestraintsSettingChanged = 1]]
-			<<else>>
-				''only when necessary,'' allowing obedient cows freedom to range around.
-				[[Restrain the cows|Dairy][$dairyRestraintsSetting = 1, $dairyRestraintsSettingChanged = 1]]
-			<</if>>
-		</div>
-	<<else>>
-		_dairyNameCaps is not equipped to restrain recalcitrant cows.
-		<div class="choices">
-			[[Equip the dairy with milking racks|Dairy][cashX(forceNeg(_Tmult2), "capEx"), $dairyRestraintsUpgrade = 1]]
-			<span class="note">
-				Costs <<print cashFormat(_Tmult2)>>
-			</span>
-		</div>
-	<</if>>
-</div>
-
-<div>
-	<<if ($seeHyperPreg == 1) && ($dairyRestraintsSetting == 2) && ($dairyStimulatorsSetting == 2) && ($dairyFeedersSetting == 2) && ($dairyPregSetting >= 1)>>
-		<<if $dairyHyperPregRemodel == 1>>
-			_dairyNameCaps's milking racks have been remodeled to allow cows' abnormal pregnancies room to grow.
-		<<else>>
-			_dairyNameCaps's milking racks can be remodeled to hold hyper-pregnant cattle.
-			<div class="choices">
-				[[Expand the milking racks|Dairy][cashX(forceNeg(_Tmult1), "capEx"), $dairyHyperPregRemodel = 1]]
-				<span class="note">
-					Costs <<print cashFormat(_Tmult1)>>
-				</span>
-			</div>
-		<</if>>
-	<</if>>
-</div>
-
-<div>
-	<<if ($bioreactorsAnnounced != 0) && ($dairyRestraintsSetting == 2) && ($dairyStimulatorsSetting == 2) && ($dairyFeedersSetting == 2)>>
-		_dairyNameCaps will
-		<div class="choices">
-			<<if $createBioreactors == 1>>
-				''convert perfected cows into equipment,'' removing them from slave status, permanently.
-				[[Cancel conversion|Dairy][$createBioreactors = 0]]
-			<<else>>
-				''leave perfected cows as slaves.''
-				[[Convert them into equipment|Dairy][$createBioreactors = 1]]
-			<</if>>
-		</div>
-	<</if>>
-</div>
-
-<div>
-	<<if $arcologies[0].FSSlimnessEnthusiast > 80>>
-		<<if $dairySlimMaintainUpgrade == 1>>
-			Thanks to advances precipitated by the arcology's commitment to the fashion of slimmer slaves, $dairyName has been updated with optimized milkers for small breasts, and a customized drug regimen to extract maximum output while maintaining small breast sizes.
-			<<if $dairySlimMaintain == 1>>
-				_dairyNameCaps is currently set to limit the breast growth of slimmer slaves while maximizing their milk output.
-				<div class="choices">
-					[[Return to Normal Operation|Dairy][$dairySlimMaintain = 0]]
-					<span class="note">
-						NOTE: This may allow the automatic administration of lactation inducing drugs
-					</span>
-				</div>
-			<<else>>
-				_dairyNameCaps is currently set to normal operation, and will allow the breasts of slimmer slaves to expand due to milking.
-				<div class="choices">
-					[[Set milkers to preserve small breast sizes|Dairy][$dairySlimMaintain = 1]]
-					<span class="note">
-						NOTE: This will NOT remove existing lactation implants
-					</span>
-				</div>
-			<</if>>
-		<<else>>
-			Dairy cows' breasts will expand normally as a result of the milking process.
-			<div class="choices">
-				[[Optimize the milking process to preserve small breast sizes|Dairy][cashX(forceNeg(_Tmult2), "capEx"), $dairySlimMaintainUpgrade = 1, $dairySlimMaintain = 1, $PC.skill.engineering += 0.1]]
-				<span class="note">
-					Costs <<print cashFormat(_Tmult2)>>
-				</span>
-			</div>
-		<</if>>
-	<<elseif $arcologies[0].FSSlimnessEnthusiast > 20>>
-		<<if $dairySlimMaintainUpgrade == 1>>
-			Thanks to advances precipitated by the arcology's commitment to the fashion of slimmer slaves, $dairyName has been re-engineered so that its milking process can now prevent the unwanted breast expansion of fashionably slim slaves.
-			<<if $dairySlimMaintain == 1>>
-				_dairyNameCaps is currently set to limit the breast growth of slimmer slaves.
-				<div class="choices">
-					[[Return to Normal Operation|Dairy][$dairySlimMaintain = 0]]
-					<span class="note">
-						NOTE: This may allow the automatic administration of lactation inducing drugs
-					</span>
-				</div>
-			<<else>>
-				_dairyNameCaps is currently set to normal operation, and will allow the breasts of slimmer slaves to expand due to milking.
-				<div class="choices">
-					[[Set milkers to preserve small breast sizes|Dairy][$dairySlimMaintain = 1]]
-					<span class="note">
-						NOTE: This will NOT remove existing lactation implants
-					</span>
-				</div>
-			<</if>>
-		<<else>>
-			Dairy cows' breasts will expand normally as a result of the milking process.
-			<div class="choices">
-				[[Optimize the milking process to preserve small breast sizes|Dairy][cashX(forceNeg(_Tmult2), "capEx"), $dairySlimMaintainUpgrade = 1, $dairySlimMaintain = 1, $PC.skill.engineering += 0.1]]
-				<span class="note">
-					Costs <<print cashFormat(_Tmult2)>>
-				</span>
-			</div>
-		<</if>>
-	<</if>>
-</div>
-
-<div>
-	<<if $dairySlimMaintain == 0>>
-		<<if $dairyImplantsSetting == 1>>
-			All cows will undergo lactation implant surgery to increase their milk output.
-			<div class="choices">
-				[[Restrict lactation surgery on cum-cows|Dairy][$dairyImplantsSetting = 0]] |
-				[[Restrict maximization surgery on cattle|Dairy][$dairyImplantsSetting = 2]] |
-				[[Encourage natural lactation in cattle|Dairy][$dairyImplantsSetting = 3]]
-			</div>
-		<<elseif $dairyImplantsSetting == 2>>
-			Cows will not undergo surgical procedures to maximize production.
-			<div class="choices">
-				[[Maximize production in all cattle|Dairy][$dairyImplantsSetting = 1]] |
-				[[Maximize production in only milkable cows|Dairy][$dairyImplantsSetting = 0]] |
-				[[Encourage natural lactation in cattle|Dairy][$dairyImplantsSetting = 3]]
-			</div>
-		<<elseif $dairyImplantsSetting == 3>>
-			Non-lactating cows incapable of producing cum will undergo manual stimulation to promote natural production.
-			<div class="choices">
-				[[Maximize production in all cattle|Dairy][$dairyImplantsSetting = 1]] |
-				[[Maximize production in only milkable cows|Dairy][$dairyImplantsSetting = 0]] |
-				[[Restrict maximization surgery on cattle|Dairy][$dairyImplantsSetting = 2]]
-			</div>
-		<<else>>
-			Naturally lactating cows, cows with non-lactating breasts, and cows incapable of producing cum will undergo lactation implant surgery to increase their milk output. Cows with working prostates will have them enhanced.
-			<div class="choices">
-				[[Maximize lactation in all cattle|Dairy][$dairyImplantsSetting = 1]] |
-				[[Restrict maximization surgery on cattle|Dairy][$dairyImplantsSetting = 2]] |
-				[[Encourage natural lactation in cattle|Dairy][$dairyImplantsSetting = 3]]
-			</div>
-		<</if>>
-	<<else>>
-		Current settings do not implant lactation implants into cows.
-	<</if>>
-</div>
-
-<div>
-	<<if $dairySlimMaintainUpgrade == 1 || $arcologies[0].FSSlimnessEnthusiast > 20>>
-		<<set _note = "<span class='note'>NOTE: Slimness controls will override all weight settings</span>">>
-	<<else>>
-		<<set _note = "">>
-	<</if>>
-	<<if $dairyWeightSetting == 0>>
-		_dairyNameCaps is keeping cows at least chubby.
-		<div class="choices">
-			[[Increase Weight Target|Dairy][$dairyWeightSetting = 1]] |
-			[[Disable Dietary Control|Dairy][$dairyWeightSetting = -1]]
-			<<print _note>>
-		</div>
-	<<elseif $dairyWeightSetting == 1>>
-		_dairyNameCaps aims to keep cows overweight.
-		<div class="choices">
-			[[Increase Weight Target|Dairy][$dairyWeightSetting = 2]] |
-			[[Decrease Weight Target|Dairy][$dairyWeightSetting = 0]] |
-			[[Disable Dietary Control|Dairy][$dairyWeightSetting = -1]]
-			<<print _note>>
-		</div>
-	<<elseif $dairyWeightSetting == 2>>
-		_dairyNameCaps aims to keep cows fat.
-		<div class="choices">
-			[[Increase Weight Target|Dairy][$dairyWeightSetting = 3]] |
-			[[Decrease Weight Target|Dairy][$dairyWeightSetting = 1]] |
-			[[Disable Dietary Control|Dairy][$dairyWeightSetting = -1]]
-			<<print _note>>
-		</div>
-	<<elseif $dairyWeightSetting == 3>>
-		_dairyNameCaps aims to keep cows very fat.
-		<div class="choices">
-			[[Increase Weight Target|Dairy][$dairyWeightSetting = 4]] |
-			[[Decrease Weight Target|Dairy][$dairyWeightSetting = 2]] |
-			[[Disable Dietary Control|Dairy][$dairyWeightSetting = -1]]
-			<<print _note>>
-		</div>
-	<<elseif $dairyWeightSetting == 4>>
-		_dairyNameCaps aims to keep cows so fat they can barely move.
-		<div class="choices">
-			[[Decrease Weight Target|Dairy][$dairyWeightSetting = 3]] |
-			[[Disable Dietary Control|Dairy][$dairyWeightSetting = -1]]
-			<<print _note>>
-		</div>
-	<<else>>
-		_dairyNameCaps is currently not monitoring slave diets and will allow you full control.
-		<div class="choices">
-			[[Enable Dietary Control|Dairy][$dairyWeightSetting = 0]]
-			<<print _note>>
-		</div>
-	<</if>>
-</div>
-
-<div>
-	<<set _note = "<span class='note'>NOTE: Favors milk production if available</span>">>
-	<<if $dairyHormonesSetting == 0>>
-		Cows will not be given hormones.
-		<div class="choices">
-			[[Apply Hormones|Dairy][$dairyHormonesSetting = 1]] |
-			[[Apply Intense Hormones|Dairy][$dairyHormonesSetting = 2]] |
-			[[Disable Hormone Control|Dairy][$dairyHormonesSetting = -1]]
-			<<print _note>>
-		</div>
-	<<elseif $dairyHormonesSetting == 1>>
-		Cows will be given hormones.
-		<div class="choices">
-			[[Increase Hormone Dosage|Dairy][$dairyHormonesSetting = 2]] |
-			[[Hormone Free|Dairy][$dairyHormonesSetting = 0]] |
-			[[Disable Hormone Control|Dairy][$dairyHormonesSetting = -1]]
-			<<print _note>>
-		</div>
-	<<elseif $dairyHormonesSetting == 2>>
-		Cows will undergo intense hormone treatment.
-		<div class="choices">
-			[[Decrease Hormone Dosage|Dairy][$dairyHormonesSetting = 1]] |
-			[[Hormone Free|Dairy][$dairyHormonesSetting = 0]] |
-			[[Disable Hormone Control|Dairy][$dairyHormonesSetting = -1]]
-			<<print _note>>
-		</div>
-	<<else>>
-		Hormone application is left to your discretion.
-		<div class="choices">
-			[[Apply Hormones|Dairy][$dairyHormonesSetting = 1]] |
-			[[Apply Intense Hormones|Dairy][$dairyHormonesSetting = 2]] |
-			[[Hormone Free|Dairy][$dairyHormonesSetting = 0]]
-			<<print _note>>
-		</div>
-	<</if>>
-</div>
-
-<div>
-	<<if $arcologies[0].FSPaternalist == "unset">>
-		<<if $dairyUpgradeMenials == 1>>
-			<<if $menialBioreactors > 0>>
-				Menial Bioreactors are restrained here and there, in every unused space. Hoses run from their nipples
-				<<if $seeDicks != 0>>
-					and penises
-				<</if>>
-				into the machinery, and from the machinery into their mouths<<if $seeDicks != 100>>, anuses, and the pussies beneath their pregnant bellies<<else>> and anuses<</if>>.
-			<<else>>
-				In addition to the standard milking machines, $dairyName includes numerous hose hookups for menial Bioreactors. When there's space, any menial milkers you own can be placed in any empty space and connected.
-			<</if>>
-		<<else>>
-			There is no provision for milking menial Bioreactors.
-			<div class="choices">
-				[[Add hose hookups|Dairy][cashX(forceNeg(_Tmult1), "capEx"), $dairyUpgradeMenials = 1]]
-				<span class="note">
-					Costs <<print cashFormat(_Tmult1)>>
-				</span>
-			</div>
-		<</if>>
-	<</if>>
-</div>
-
-<<if ($dairyPregSetting > 1) || ($dairyFeedersSetting > 1) || ($dairyStimulatorsSetting > 1)>>
-	<p>
-		@@.yellow;WARNING:@@ current milking machine settings will have dramatic and possibly irreversible effects on cow bodies and minds.
-	</p>
-<</if>>
-
-<!-- Statistics output -->
-<<includeDOM App.Facilities.Dairy.Stats(true)>>
-
-<p>
-	<<set _facility = App.Entity.facilities.dairy>>
-	<<if (_S.Milkmaid)>>
-		<<includeDOM App.UI.SlaveList.displayManager(_facility)>>
-		<<if canAchieveErection(_S.Milkmaid) && _S.Milkmaid.pubertyXY == 1>>
-			<<run App.Utils.setLocalPronouns(_S.Milkmaid)>>
-			<<if $milkmaidImpregnates == 1>>
-				Keeping the cows pregnant is part of $his job.
-				<div class="choices">
-					<<link "Order $him to stop impregnating" "Dairy">>
-						<<set $milkmaidImpregnates = 0>>
-					<</link>>
-				</div>
-			<<elseif $seePreg != 0>>
-				$He could be directed to keep the cows pregnant $himself.
-				<div class="choices">
-					<<link "Order $him to impregnate" "Dairy">>
-						<<set $milkmaidImpregnates = 1>>
-					<</link>>
-				</div>
-			<</if>>
-		<</if>>
-	<<elseif $dairyRestraintsSetting > 1>>
-		<span class="note">
-			Current milking machine settings make a Milkmaid superfluous by replacing their duties with automation
-		</span>
-	<<else>>
-		You do not have a slave serving as a Milkmaid. [[Appoint one|Milkmaid Select]]
-	<</if>>
-	<<set _seed = $bioreactorsXY+$bioreactorsXX+$bioreactorsHerm+$bioreactorsBarren>>
-	<<if _seed > 0>>
-		<<if _seed > 1>>
-			<span class="note">
-				In addition, _seed milking machines have biological components installed in them.
-			</span>
-		<<else>>
-		<span class="note">
-			In addition, one milking machine has biological components installed in it.
-		</span>
-		<</if>>
-	<</if>>
-</p>
-
-
-<p>
-	<<includeDOM App.UI.SlaveList.listSJFacilitySlaves(_facility)>>
-</p>
-
-<p>
-	Rename $dairyName: <<textbox "$dairyName" $dairyName "Dairy">>
-	<span class="note">
-		Use a noun or similar short phrase
-	</span>
-</p>
-
-<<run App.UI.SlaveList.ScrollPosition.restore()>>
diff --git a/src/zz1-last/init.js b/src/zz1-last/init.js
index e92d5bb79e823e29e756a2f17a6b5e8912fa4c70..05063454484bb3c67df767e69bd48478884facd9 100644
--- a/src/zz1-last/init.js
+++ b/src/zz1-last/init.js
@@ -1,5 +1,6 @@
 App.Art.cacheArtData();
 App.Corporate.Init();
+App.RA.Activation.populateGetters();
 
 // TODO: remove once setup object is no longer required.
 for (let key in App.Data.misc) {
diff --git a/tests/diffProxy.js b/tests/diffProxy.js
new file mode 100644
index 0000000000000000000000000000000000000000..c991c2756307c933f3f726b03c323c91d8791420
--- /dev/null
+++ b/tests/diffProxy.js
@@ -0,0 +1,223 @@
+{
+	const getProxy = App.Utils.Diff.getProxy;
+
+	App.Testing.executeTest("Overwrite first level", () => {
+	}, () => {
+		let proxy = getProxy({a: 1});
+
+		proxy.a = 2;
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {a: 1});
+		App.Testing.equals(proxy.a, 2);
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original, {a: 2});
+	}, () => {
+	});
+
+	App.Testing.executeTest("Overwrite second level", () => {
+	}, () => {
+		let proxy = getProxy({c: {a: 1}});
+
+		proxy.c.a = 2;
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {c: {a: 1}});
+		App.Testing.equals(proxy.c.a, 2);
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original, {c: {a: 2}});
+	}, () => {
+	});
+
+	App.Testing.executeTest("Delete first level", () => {
+	}, () => {
+		let proxy = getProxy({a: 1});
+
+		delete proxy.a;
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {a: 1});
+		App.Testing.hasNoProperty(proxy, "a");
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original, {});
+	}, () => {
+	});
+
+	App.Testing.executeTest("Delete in second level", () => {
+	}, () => {
+		let proxy = getProxy({c: {a: 1}});
+
+		delete proxy.c.a;
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {c: {a: 1}});
+		App.Testing.hasProperty(proxy, "c");
+		App.Testing.hasNoProperty(proxy.c, "a");
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original, {c: {}});
+	}, () => {
+	});
+
+	App.Testing.executeTest("Delete with second level", () => {
+	}, () => {
+		let proxy = getProxy({c: {a: 1}});
+
+		delete proxy.c;
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {c: {a: 1}});
+		App.Testing.hasNoProperty(proxy, "c");
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original, {});
+	}, () => {
+	});
+
+	App.Testing.executeTest("add value", () => {
+	}, () => {
+		let proxy = getProxy({});
+
+		proxy.d = 7;
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {});
+		App.Testing.hasProperty(proxy, "d");
+		App.Testing.equals(proxy.d, 7);
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original, {d: 7});
+	}, () => {
+	});
+
+	App.Testing.executeTest("add object", () => {
+	}, () => {
+		let proxy = getProxy({});
+
+		proxy.d = {a: 5};
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {});
+		App.Testing.hasProperty(proxy, "d");
+		App.Testing.hasProperty(proxy.d, "a");
+		App.Testing.equals(proxy.d.a, 5);
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original, {d: {a: 5}});
+	}, () => {
+	});
+
+	App.Testing.executeTest("Overwrite array entry", () => {
+	}, () => {
+		let proxy = getProxy({b: [1, 2]});
+
+		proxy.b[1] = 5;
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {b: [1, 2]});
+		App.Testing.equals(proxy.b, [1, 5]);
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original, {b: [1, 5]});
+	}, () => {
+	});
+
+	App.Testing.executeTest("array push", () => {
+	}, () => {
+		let proxy = getProxy({b: [1, 2]});
+
+		proxy.b.push(5);
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {b: [1, 2]});
+		App.Testing.equals(proxy.b, [1, 2, 5]);
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original, {b: [1, 2, 5]});
+	}, () => {
+	});
+
+	App.Testing.executeTest("array pop", () => {
+	}, () => {
+		let proxy = getProxy({b: [1, 2]});
+
+		proxy.b.pop();
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {b: [1, 2]});
+		App.Testing.equals(proxy.b, [1]);
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original, {b: [1]});
+	}, () => {
+	});
+
+	App.Testing.executeTest("new array unshift", () => {
+	}, () => {
+		let proxy = getProxy({});
+
+		proxy.d = {a: [5]};
+		proxy.d.a.unshift(9);
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {});
+		App.Testing.hasProperty(proxy.d, "a");
+		App.Testing.equals(proxy.d.a, [9, 5]);
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original, {d: {a: [9, 5]}});
+	}, () => {
+	});
+
+
+	App.Testing.executeTest("remove one eye", () => {
+	}, () => {
+		let proxy = getProxy({eye: new App.Entity.EyeState()});
+
+		eyeSurgery(proxy, "left", "remove");
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {eye: new App.Entity.EyeState()});
+		App.Testing.equals(proxy.eye.left, null);
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original.eye.left, null);
+	}, () => {
+	});
+
+	App.Testing.executeTest("remove both eyes", () => {
+	}, () => {
+		let proxy = getProxy({eye: new App.Entity.EyeState()});
+
+		eyeSurgery(proxy, "both", "remove");
+
+		const original = proxy.diffOriginal;
+
+		App.Testing.equals(original, {eye: new App.Entity.EyeState()});
+		App.Testing.equals(proxy.eye.left, null);
+		App.Testing.equals(proxy.eye.right, null);
+
+		App.Utils.Diff.applyDiff(original, proxy.diffChange);
+		App.Testing.equals(original.eye.left, null);
+		App.Testing.equals(original.eye.right, null);
+	}, () => {
+	});
+
+	// Do this last
+	App.Testing.unitDone();
+}
diff --git a/tests/ibc.js b/tests/ibc.js
new file mode 100644
index 0000000000000000000000000000000000000000..0199220e0897a61714af05573a7856e37c55bb77
--- /dev/null
+++ b/tests/ibc.js
@@ -0,0 +1,131 @@
+{
+	class MockSlave {
+		ID;
+		mother;
+		father;
+
+		constructor(id) {
+			this.ID = id;
+		}
+	}
+
+	class MockMating {
+		constructor(fatherId, motherId, ...childrenIds) {
+			for (let id of childrenIds) {
+				if (id === fatherId || id === motherId) {
+					throw new Error("cannot give birth to self");
+				}
+			}
+
+			this.fatherId = fatherId;
+			this.motherId = motherId;
+			this.childrenIds = childrenIds;
+		}
+	}
+
+	class MockWorld {
+		slavesArray;
+
+		constructor(matings) {
+			this.slavesArray = [];
+
+			let slavesById = {};
+			let meetSlave = (id) => {
+				if (!slavesById[id]) {
+					let slave = new MockSlave(id);
+					this.slavesArray.push(slave);
+					slavesById[id] = slave;
+				}
+
+				return slavesById[id];
+			};
+
+			for (let mating of matings) {
+				let father = meetSlave(mating.fatherId);
+				let mother = meetSlave(mating.motherId);
+				for (let id of mating.childrenIds) {
+					let child = meetSlave(id);
+					child.father = father.ID;
+					child.mother = mother.ID;
+				}
+			}
+		}
+
+		findSlaveState(id) {
+			return this.slavesArray.find(slave => slave.ID === id) || null;
+		}
+	}
+
+	let testCoefficientForSlave = function(name, mockMatings, slaveId, expectedCoefficientOfInbreeding) {
+		App.Testing.executeTest(name, () => {}, () => {
+			let tolerance = .00000000001;
+
+			let world = new MockWorld(mockMatings);
+			let c = ibc._test.coeff_slave(world, world.findSlaveState(slaveId));
+			App.Testing.isType(c, "number");
+			App.Testing.notNaN(c);
+			App.Testing.inRange(c, expectedCoefficientOfInbreeding, tolerance);
+		}, () => {});
+	};
+
+	// references:
+	// Introduction to Quantitative Genetics - Doulas S. Falconer, 1989
+	// Genetic and Quantitative Aspects of Genealogy - F.M. Lancaster, 2015
+	testCoefficientForSlave("basic outbred mating, 1",[new MockMating(1, 2, 3, 4)], 1, 0);
+	testCoefficientForSlave("basic outbred mating, 2",[new MockMating(1, 2, 3, 4)], 4, 0);
+	testCoefficientForSlave("basic self-mating, 1", [new MockMating(1, 1, 3, 4)], 4, 1 / 2);
+	testCoefficientForSlave("basic self-mating, 2", [new MockMating(1, 1, 3, 4)], 1, 0);
+	testCoefficientForSlave("basic child-parent mating",[new MockMating(1, 2, 3), new MockMating(2, 3, 4)], 4, 1 / 4);
+	testCoefficientForSlave("basic sibling mating",[new MockMating(1, 2, 3, 4), new MockMating(3, 4, 5)], 5, 1 / 4);
+	testCoefficientForSlave("basic half-sibling mating",[new MockMating(1, 2, 3), new MockMating(2, 4, 5), new MockMating(3, 5, 6)], 6, 1 / 8);
+	testCoefficientForSlave("basic first cousin mating",[new MockMating(1, 2, 3, 4), new MockMating(5, 3, 6), new MockMating(4, 7, 8), new MockMating(6, 8, 9)], 9, 1 / 16);
+	testCoefficientForSlave("double first cousin mating",[new MockMating(1, 2, 3, 4), new MockMating(5, 6, 7, 8),
+		new MockMating(3, 7, 9), new MockMating(4, 8, 10), new MockMating(9, 10, 11)], 11, 1 / 8);
+	testCoefficientForSlave("aunt-niece mating",[new MockMating(1, 2, 3, 4), new MockMating(4, 5, 6), new MockMating(3, 6, 7)], 7, 1 / 8);
+	let scenario53 = [new MockMating(1, 2, 3, 4), new MockMating(5, 6, 7, 8), new MockMating(3, 7, 9, 10), new MockMating(4, 8, 11),
+		new MockMating(12, 9, 13), new MockMating(10, 11, 14), new MockMating(13, 14, 15)];
+	testCoefficientForSlave("problem 5.3 from Falconer, 1",scenario53, 14, 1 / 8);  //
+	testCoefficientForSlave("problem 5.3 from Falconer, 2",scenario53, 15, 3 / 32);
+	testCoefficientForSlave("example in figure 64 from Lancaster",[new MockMating(1, 2, 4, 5), new MockMating(3, 4, 7), new MockMating(5, 6, 8), new MockMating(7, 8, 9), new MockMating(9, 10, 12, 13),
+		new MockMating(11, 12, 15), new MockMating(13, 14, 16), new MockMating(15, 16, 17, 18)], 17, 33 / 512);
+	testCoefficientForSlave("example in figure 65 from Lancaster",[new MockMating(1, 2, 4, 5), new MockMating(3, 4, 7), new MockMating(5, 6, 8), new MockMating(7, 8, 10, 11),
+		new MockMating(9, 10, 13), new MockMating(11, 12, 14), new MockMating(13, 14, 15)], 15, 9 / 128);
+	testCoefficientForSlave("example in figure 66 from Lancaster",[new MockMating(1, 2, 3, 4), new MockMating(3, 4, 5, 6), new MockMating(5, 6, 7, 8), new MockMating(7, 8, 9)], 9, 1 / 2);
+	testCoefficientForSlave("example in figure 66 from Lancaster, extended by one more generation's worth of mating between siblings",[new MockMating(1, 2, 3, 4), new MockMating(3, 4, 5, 6), new MockMating(5, 6, 7, 8), new MockMating(7, 8, 9, 10),
+		new MockMating(9, 10, 11)], 11, 19 / 32);
+	// from here the preceding scenario of regular sibling-mating is extended by several more steps; by rules given in Falconer, the coefficient ck for step k, where step k follows
+	// step j which follows step i, should be ck = 1/4 + cj/2 + ci/4, and so that is how the expected values used in the next few tests were calculated
+	testCoefficientForSlave("extended, 1: 43/64 = 1/4 + (19/32) / 2 + (1/2) / 4",[new MockMating(1, 2, 3, 4), new MockMating(3, 4, 5, 6), new MockMating(5, 6, 7, 8), new MockMating(7, 8, 9, 10),
+		new MockMating(9, 10, 11, 12), new MockMating(11, 12, 13)], 13, 43 / 64);
+	testCoefficientForSlave("extended, 2",[new MockMating(1, 2, 3, 4), new MockMating(3, 4, 5, 6), new MockMating(5, 6, 7, 8), new MockMating(7, 8, 9, 10),
+		new MockMating(9, 10, 11, 12), new MockMating(11, 12, 13, 14), new MockMating(13, 14, 15)], 15, 94 / 128);
+	testCoefficientForSlave("extended, 3", [new MockMating(1, 2, 3, 4), new MockMating(3, 4, 5, 6), new MockMating(5, 6, 7, 8), new MockMating(7, 8, 9, 10),
+		new MockMating(9, 10, 11, 12), new MockMating(11, 12, 13, 14), new MockMating(13, 14, 15, 16), new MockMating(15, 16, 17)], 17, 201 / 256);
+	testCoefficientForSlave("extended, 4", [new MockMating(1, 2, 3, 4), new MockMating(3, 4, 5, 6), new MockMating(5, 6, 7, 8), new MockMating(7, 8, 9, 10),
+		new MockMating(9, 10, 11, 12), new MockMating(11, 12, 13, 14), new MockMating(13, 14, 15, 16), new MockMating(15, 16, 17, 18), new MockMating(17, 18, 19)], 19, 423 / 512);
+	testCoefficientForSlave("extended, 5", [new MockMating(1, 2, 3, 4), new MockMating(3, 4, 5, 6), new MockMating(5, 6, 7, 8), new MockMating(7, 8, 9, 10),
+		new MockMating(9, 10, 11, 12), new MockMating(11, 12, 13, 14), new MockMating(13, 14, 15, 16), new MockMating(15, 16, 17, 18), new MockMating(17, 18, 19, 20),
+		new MockMating(19, 20, 21)], 21, 880 / 1024);
+	// Does not apply to current algorithm: as of this writing, the ten-generations-of-sisterfucking test immediately above is enough to occupy the game's coefficient-of-inbreeding calculation algorithm for a few minutes
+	// on a ~4Ghz CPU.  this is very silly.  when you read this, that algorithm should have been replaced by a much faster one, allowing the above test to be comfortably run again.
+	let scenario70 = [new MockMating(1, 2, 6), new MockMating(2, 3, 7), new MockMating(3, 4, 8), new MockMating(5, 6, 9), new MockMating(7, 8, 10),
+		new MockMating(9, 10, 12), new MockMating(10, 11, 13), new MockMating(12, 13, 14), new MockMating(12, 14, 15)];  // example in figure 70 from Lancaster
+	testCoefficientForSlave("example in figure 70 from Lancaster, 1", scenario70, 2, 0);
+	testCoefficientForSlave("example in figure 70 from Lancaster, 2", scenario70, 10, 1 / 8);
+	testCoefficientForSlave("example in figure 70 from Lancaster, 3", scenario70, 12, 1 / 32);
+	testCoefficientForSlave("example in figure 70 from Lancaster, 4", scenario70, 15, 85 / 256);
+	let scenarioXXX = [new MockMating(1, 2, 5, 6), new MockMating(3, 4, 7, 8), new MockMating(5, 6, 9, 10), new MockMating(5, 7, 11), new MockMating(5, 8, 12),
+		new MockMating(5, 9, 13), new MockMating(9, 10, 14), new MockMating(5, 11, 15), new MockMating(10, 12, 16), new MockMating(13, 16, 17),
+		new MockMating(4, 16, 18), new MockMating(14, 15, 19), new MockMating(6, 17, 20), new MockMating(6, 18, 21), new MockMating(6, 19, 22),
+		new MockMating(20, 21, 23), new MockMating(22, 23, 24)];  // an invented example meant to represent a typical situation in a respectable arcology
+	testCoefficientForSlave("change, 1",scenarioXXX, 24, 633 / 2048);  // here the expected coefficient was retrieved from the algorithm being tested and was not separately verified by hand,
+	// so this test could conceivably be wrong, but at least it can catch changes...
+	testCoefficientForSlave("change, 2",[new MockMating(1, 2, 3, 4), new MockMating(3, 4, 5, 6), new MockMating(5, 6, 7, 8), new MockMating(7, 8, 9, 10), new MockMating(9, 10, 11, 12),
+		new MockMating(11, 12, 13), new MockMating(13, 14, 15),
+		new MockMating(5, 5, 16), new MockMating(15, 16, 17)], 17, 1 / 4);  // an example in which the old and new algorithms actually gave different results - the first one such to have been observed! It seems that the old algorithm was wrong
+	testCoefficientForSlave("negative IDs, 1",[new MockMating(-120, -120, 87)], 87, 1 / 2);  // negative IDs need to be accepted (not bothering to test any weird special IDs like -1 here though)
+	testCoefficientForSlave("negative IDs, 2",[new MockMating(-999, -998, -300), new MockMating(-300, -998, 300)], 300, 1 / 4);
+
+	// Do this last
+	App.Testing.unitDone();
+}
diff --git a/tests/index.js b/tests/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..91d932d6e1689fabe0e5a365a22a747bb68eb477
--- /dev/null
+++ b/tests/index.js
@@ -0,0 +1,133 @@
+// Define Test framework and register all tests
+
+// To run all tests, type 'App.Loader.executeTests()' in the browser console. Make sure the HTML file has not been
+// moved from the 'bin/' directory
+
+// First, create the test framework
+App.Testing = (function() {
+	// First, abstract away anything test unrelated
+	const group = App.Loader.getGroup("../tests");
+
+	function addTestUnit(path) {
+		group.queueSubscript(path);
+	}
+
+	let unitTotal = 0;
+	let unitSuccesses = 0;
+
+	function start() {
+		App.Loader.nextScript();
+	}
+
+	function unitDone() {
+		console.log("Group '" + App.Loader.lastScript + "' done. Successful tests:", unitSuccesses, "of", unitTotal);
+		unitTotal = 0;
+		unitSuccesses = 0;
+		App.Loader.nextScript();
+	}
+
+	// Actual Testing functionality
+	class TestError extends Error {
+	}
+
+	/**
+	 * @param {string} name Unique test name
+	 * @param {null|(()=>void)} prepare Prepare the global state
+	 * @param {!(()=>void)} test Do the actual testing
+	 * @param {null|(()=>void)} cleanup Clean the global state up
+	 */
+	function executeTest(name, prepare, test, cleanup) {
+		unitTotal++;
+		try {
+			if (prepare != null) {
+				prepare();
+			}
+		} catch (e) {
+			console.log("PREPARE_FAILED", name, e);
+			tryCleanup(name, cleanup);
+			return;
+		}
+		try {
+			test();
+		} catch (e) {
+			console.log("TEST_FAILED", name, e);
+			tryCleanup(name, cleanup);
+			return;
+		}
+		if (tryCleanup(name, cleanup)) {
+			unitSuccesses++;
+		}
+	}
+
+	/**
+	 * @param {string} name Unique test name
+	 * @param {null|(()=>void)} cleanup Clean the global state up
+	 */
+	function tryCleanup(name, cleanup) {
+		try {
+			if (cleanup != null) {
+				cleanup();
+			}
+		} catch (e) {
+			console.log("CLEANUP_FAILED", name, e);
+			return false;
+		}
+		return true;
+	}
+
+	function equals(actual, expected) {
+		if (!_.isEqual(actual, expected)) {
+			throw new TestError("Actual value does not match expected value");
+		}
+	}
+
+	/**
+	 * @param {Object} obj
+	 * @param {string} property
+	 */
+	function hasProperty(obj, property) {
+		if (obj[property] === undefined) {
+			throw new TestError("Expected property does not exist");
+		}
+	}
+
+	/**
+	 * @param {Object} obj
+	 * @param {string} property
+	 */
+	function hasNoProperty(obj, property) {
+		if (obj[property] !== undefined) {
+			throw new TestError("Unexpected property exists");
+		}
+	}
+
+	function isType(value, expected) {
+		if (!(typeof value === expected)) {
+			throw new TestError("Actual type does not match expected type");
+		}
+	}
+
+	function notNaN(value) {
+		if (Number.isNaN(value)) {
+			throw new TestError("Expected valid number, got NaN.");
+		}
+	}
+
+	function inRange(value, target, tolerance) {
+		if (Math.abs(value - target) > tolerance) {
+			throw new TestError(`Value ${value} outside range. Expected ${target} with tolerance ${tolerance}.`);
+		}
+	}
+
+	return {
+		addTestUnit, start, unitDone, executeTest,
+		equals, hasProperty, hasNoProperty: hasNoProperty, isType, notNaN, inRange,
+	};
+})();
+
+// Now load all tests
+App.Testing.addTestUnit("diffProxy");
+App.Testing.addTestUnit("ibc");
+
+// Finally, execute the tests
+App.Testing.start();
diff --git a/tsconfig.json b/tsconfig.json
index bd2df2c88db402e947cf31ad8ee5edf5fcc49b78..39224e2d7b9efd8dc5070d43163114cb992d8a13 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -5,9 +5,10 @@
 		"allowJs": true,
 		"checkJs": true,
 		"noEmit": true,
-		"target": "ESNext",
+		"target": "es2021",
 		"noImplicitAny": false,
-		"disableSizeLimit": true
+		"disableSizeLimit": true,
+		"strictBindCallApply": true
 	},
 	"include": [
 		"js/**/*.js",