code:
App.Events.recFSStatuesqueGlorificationTwo = class recFSStatuesqueGlorificationTwo extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => V.FSAnnounced === 1,
			() => V.arcologies[0].FSStatuesqueGlorification > random(1, 100) || (V.debugMode > 0 && V.debugModeEventSelection > 0)
		];
	}

	execute(node) {
		let r = [];
		const slave = GenerateNewSlave(null, {disableDisability: 1});
		slave.origin = "$He offered $himself for voluntary enslavement knowing $he would only fit in with your help.";
		slave.natural.height = 165;
		slave.height = Height.forAge(slave.natural.height, slave);
		setHealth(slave, jsRandom(20, 40), undefined, undefined, 0, 0);
		slave.shoes = "extreme heels";
		slave.devotion = random(30, 45);
		slave.trust = random(-20, 0);

		const {
			He,
			his, he, him, himself, girl
		} = getPronouns(slave);
		const {HeA} = getPronouns(assistant.pronouns().main).appendSuffix("A");
		const contractCost = 1000;
		const cost = slaveCost(slave) - contractCost;
		r.push(`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, r);
		r = [];
		r.push(`This one is interesting, even by the standards of messages from people who want to become slaves. The individual is neither sick nor abused, and speaks with directness.`);
		r.push(Spoken(slave, `"I'm going to be out of a home by the end of the week and more than likely falling into slavery not long after,"`));
		r.push(`${he} sighs.`);
		r.push(Spoken(slave, `"And, well, I heard you like tall ${girl}s and ${V.arcologies[0].name} can be lenient when it comes to high heels pushing people over the height threshold, so I was hoping you'd take pity on a ${girl} down on his luck even though ${he}'s not quite up to standards."`));

		App.Events.addParagraph(node, r);

		node.append(App.Desc.longSlave(slave, {market: "generic"}));

		const choices = [];

		if (V.cash >= contractCost) {
			choices.push(new App.Events.Result(`Enslave ${him}`, enslave, `This will cost ${cashFormat(contractCost)}`));
			choices.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));
		} else {
			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}.`));
		}
		App.Events.addResponses(node, choices);

		function enslave() {
			const frag = new DocumentFragment();
			r = [];
			r.push(`When ${he} arrives, ${he} is the very picture of someone in over ${his} head. The only thing separating ${him} from ridicule is a pair of high heels; a fact ${he} is very aware of as ${he} struggles with doubts through the enslavement process.`);

			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addParagraph(frag, r);
			return frag;
		}

		function sell() {
			cashX(cost, "slaveTransfer");
			return `When ${he} arrives, ${he} comes directly to your penthouse for enslavement. ${He} wears an expression of doubt, fear, and wonder as ${he} takes in the sights and sounds of the magnificent beast that is the new society taking shape in ${V.arcologies[0].name}. A purchaser's agent arrives to take charge of ${him}, and ${he} asks politely who bought ${him}. A man with a means to fix ${his} height issue, you tell ${him}. ${He} should be able to walk again within a year, assuming the surgery is a success. ${He} shudders at the concept and steels ${himself}; not everyone has access to the high end technology you do after all.`;
		}
	}
};


code:
App.Events.recFSSubjugationist = class recFSSubjugationist extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => V.FSAnnounced === 1,
		];
	}

	actorPrerequisites() {
		return [];
	}

	get weight() {
		return V.arcologies[0].FSSubjugationist > random(1, 100) ? 1 : 0;
	}

	execute(node) {
		let r = [];
		const slave = GenerateNewSlave(null, {
			minAge: 18, maxAge: 42, disableDisability: 1, race: V.arcologies[0].FSSubjugationistRace
		});
		generateSalonModifications(slave);
		slave.origin = "$He was beaten, sexually assaulted, and finally enslaved for being stupid enough to visit an arcology that doesn't like $his kind.";
		setHealth(slave, jsRandom(-80, -60), jsRandom(20, 30), jsRandom(0, 10), Math.max(normalRandInt(1, 0.5), 0), jsRandom(40, 90));
		slave.trust = random(-45, -25);
		slave.devotion = random(-75, -65);
		slave.anus = random(1, 2);
		const {
			his, he, him
		} = getPronouns(slave);
		const {hisA} = getPronouns(assistant.pronouns().main).appendSuffix("A");
		const contractCost = 1000;
		const cost = slaveCost(slave) - contractCost;
		if (V.arcologyUpgrade.drones > 0) {
			r.push(`Your security drones`);
		} else {
			r.push(`Security guards in your employ`);
		}
		r.push(`break up a minor disturbance on the lowest, poorest levels of the arcology without needing your direction, or indeed without even informing you. ${capFirstChar(V.assistant.name)} is good enough at filtering incidents down to what you need to know that you typically leave minor things to ${hisA} discretion. This time ${V.assistant.name} only informs you once it's apparent that that brawl left someone injured and unconscious.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`It seems the violence was racially motivated. The ${V.arcologies[0].FSSubjugationistRace} victim was publicly sodomized and left bruised and bleeding, ${his} clothes torn off, beaten into insensibility, with anti-${V.arcologies[0].FSSubjugationistRace} slogans written crudely across ${his} ${slave.skin} skin. It seems ${he} came into the arcology despite the strong penalties for free ${V.arcologies[0].FSSubjugationistRace} subhumans found here. You can easily enslave ${him} in return for ${his} medical costs, though no one is likely to object to your enslaving one of ${his} kind, whatever the situation.`);

		App.Events.addParagraph(node, r);

		node.append(App.Desc.longSlave(slave, {market: "generic"}));

		const choices = [];

		if (V.cash >= contractCost) {
			choices.push(new App.Events.Result(`Enslave ${him}`, enslave, `This will cost ${cashFormat(contractCost)}`));
			choices.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));
		} else {
			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}.`));
		}
		App.Events.addResponses(node, choices);

		function enslave() {
			const frag = new DocumentFragment();
			r = [];
			r.push(`The enslavement process is disappointingly quiet, since ${he}'s still unconscious. As of this morning ${he} was one of the last free ${V.arcologies[0].FSSubjugationistRace} people in the arcology. Now ${he}'s simply the newest sex slave of the inferior race to take ${his} proper place.`);

			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addParagraph(frag, r);
			return frag;
		}

		function sell() {
			cashX(cost, "slaveTransfer");
			return `The purchasing agent is businesslike, even hurried. The inert slave receives a simple check, with some industrious fingering of orifices, and is bundled off. As is appropriate.`;
		}
	}
};

repo_name: Arkerthan/fc

license: mit


code:
App.Events.recFSSubjugationistTwo = class recFSSubjugationistTwo extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => V.FSAnnounced === 1,
			() => V.arcologies[0].FSSubjugationist > random(1, 100) || (V.debugMode > 0 && V.debugModeEventSelection > 0)
		];
	}

	execute(node) {
		let r = [];
		const slave = GenerateNewSlave(null, {maxAge: 42, disableDisability: 1, race: V.arcologies[0].FSSubjugationistRace});
		generateSalonModifications(slave);
		slave.origin = "$He came to your arcology to be enslaved out of a sense of self-loathing for $his kind.";
		setHealth(slave, jsRandom(-40, 0), undefined, undefined, 0, 0);
		slave.trust = random(-25, -15);
		slave.devotion = random(-45, -25);
		slave.anus = random(1, 2);

		const {
			He,
			his, he, him
		} = getPronouns(slave);
		const {HeA} = getPronouns(assistant.pronouns().main).appendSuffix("A");
		const contractCost = 1000;
		const cost = slaveCost(slave) - contractCost;
		r.push(`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, r);
		r = [];
		r.push(`The caller is ${V.arcologies[0].FSSubjugationistRace}, and a particularly self-hating one at that. It seems ${he} came into the arcology despite the strong penalties for free ${V.arcologies[0].FSSubjugationistRace} subhumans found here in order to seek enslavement, a curious turn of events. You can easily enslave ${him}; no one is likely to object to your enslaving one of ${his} kind, especially when ${he} came so willingly.`);

		App.Events.addParagraph(node, r);

		node.append(App.Desc.longSlave(slave, {market: "generic"}));

		const choices = [];

		if (V.cash >= contractCost) {
			choices.push(new App.Events.Result(`Enslave ${him}`, enslave, `This will cost ${cashFormat(contractCost)}`));
			choices.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));
		} else {
			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}.`));
		}
		App.Events.addResponses(node, choices);

		function enslave() {
			const frag = new DocumentFragment();
			r = [];
			r.push(`The enslavement process is disappointingly quiet, since ${he} does little more than stare blankly ahead and respond to any orders. As of this morning ${he} was one of the last free ${V.arcologies[0].FSSubjugationistRace} people in the arcology. Now ${he}'s simply the newest, and perhaps most willing, sex slave of the inferior race to take ${his} proper place.`);

			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addParagraph(frag, r);
			return frag;
		}

		function sell() {
			cashX(cost, "slaveTransfer");
			return `The enslavement process is disappointingly quiet, since ${he} does little more than stare blankly ahead and respond to any orders. As of this morning ${he} was one of the last free ${V.arcologies[0].FSSubjugationistRace} people in the arcology. Now ${he}'s simply the newest, and perhaps most willing, sex slave of the inferior race to take ${his} proper place. ${He}'s taken away by a purchasing agent soon after.`;
		}
	}
};


code:
App.Events.recFSSupremacist = class recFSSupremacist extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => V.FSAnnounced === 1,
		];
	}

	actorPrerequisites() {
		return [];
	}

	get weight() {
		return V.arcologies[0].FSSupremacist > random(1, 100) ? 1 : 0;
	}

	execute(node) {
		let r = [];
		const pram = {disableDisability: 1};
		if (V.arcologies[0].FSSubjugationistRace !== 0) {
			pram.race = V.arcologies[0].FSSubjugationistRace;
		} else {
			const races = App.Utils.getRaceArrayWithoutParamRace(V.arcologies[0].FSSupremacistRace);
			pram.race = races.random();
		}
		const slave = GenerateNewSlave(null, pram);
		generateSalonModifications(slave);
		slave.origin = "$He was captured and enslaved in a conflict zone and fenced to you by a mercenary group.";
		slave.devotion -= 40;
		slave.trust = random(-45, -25);
		const contractCost = 1000;
		const cost = slaveCost(slave) - contractCost;
		const {him} = getPronouns(slave);
		r.push(`Ever since you have been steering ${V.arcologies[0].name} towards a belief in ${V.arcologies[0].FSSupremacistRace} supremacy, you've been receiving increasingly useful communications from groups that share your ideals. Many rebel, mercenary, and paramilitary groups active in conflict zones have racial beliefs of one stripe or other, and by taking the ${V.arcologies[0].FSSupremacistRace} side, you've automatically inserted yourself into a worldwide network of like-minded organizations. You receive an urgent communication from one such private military company.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`It seems that they've run into a serious cash flow problem. They may not have liquid assets, but they do have human assets. What they lack is the slaveholding and selling infrastructure to translate the latter into the former. They're interested in fencing some merchandise to you, no questions asked, on a flat fee basis. Included in the message is a slave dossier detailing the piece of human chattel they're offering.`);
		App.Events.addParagraph(node, r);

		node.append(App.Desc.longSlave(slave, {market: "generic"}));

		const choices = [];

		if (V.cash >= contractCost) {
			choices.push(new App.Events.Result(`Enslave ${him}`, enslave, `This will cost ${cashFormat(contractCost)}`));
			choices.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));
		} else {
			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}.`));
		}
		App.Events.addResponses(node, choices);

		function enslave() {
			const frag = new DocumentFragment();
			r = [];
			r.push(`A battered VTOL craft arrives at ${V.arcologies[0].name}, broadcasting obviously bogus IFF codes. It seems this mercenary group is playing fast and loose in an attempt to get back on their feet. The aircraft doesn't even touch down on the pad they're directed to: it simply hovers`);
			if (V.showInches === 2) {
				r.push(`six feet`);
			} else {
				r.push(`two meters`);
			}
			r.push(`off the pad for the five seconds it takes to shove a canvas bag that obviously contains a struggling human form out of the side door.`);

			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addParagraph(frag, r);
			return frag;
		}

		function sell() {
			const frag = new DocumentFragment();
			r = [];
			cashX(cost, "slaveTransfer");
			r.push(`A battered VTOL craft arrives at ${V.arcologies[0].name}, broadcasting obviously bogus IFF codes. It seems this mercenary group is playing fast and loose in an attempt to get back on their feet. The aircraft doesn't even touch down on the pad they're directed to: it simply hovers`);
			if (V.showInches === 2) {
				r.push(`six feet`);
			} else {
				r.push(`two meters`);
			}
			r.push(`off the pad for the five seconds it takes to shove a canvas bag that obviously contains a struggling human form out of the side door. You decide to do the simple thing, and leave the bag where it is. The purchaser's agent can deal with it.`);
			App.Events.addParagraph(frag, r);
			return frag;
		}
	}
};


code:
App.Events.recFSSupremacistTwo = class recFSSupremacistTwo extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => V.FSAnnounced === 1,
			() => V.arcologies[0].FSSupremacist > random(1, 100) || (V.debugMode > 0 && V.debugModeEventSelection > 0)
		];
	}

	execute(node) {
		let r = [];
		const pram = {disableDisability: 1};
		if (V.arcologies[0].FSSubjugationistRace !== 0) {
			pram.race = V.arcologies[0].FSSubjugationistRace;
		} else {
			const races = App.Utils.getRaceArrayWithoutParamRace(V.arcologies[0].FSSupremacistRace);
			pram.race = races.random();
		}
		const slave = GenerateNewSlave(null, pram);
		slave.origin = `$He made the mistake of marrying into a ${V.arcologies[0].FSSupremacistRace} neighborhood and was kidnapped then sold to you.`;
		slave.devotion -= 40;
		slave.trust = random(-45, -25);
		const contractCost = 1000;
		const cost = slaveCost(slave) - contractCost;
		const {
			him, woman, wife
		} = getPronouns(slave);
		r.push(`Ever since you have been steering ${V.arcologies[0].name} towards a belief in ${V.arcologies[0].FSSupremacistRace} supremacy, you've been receiving increasingly useful communications from groups that share your ideals. With much of the old world in freefall many groups with particularly vehement racial beliefs are expanding unchecked by the mores of big government, and by taking the ${V.arcologies[0].FSSupremacistRace} side, you've automatically inserted yourself into a worldwide network of like-minded organizations. You receive a communication from one such group.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`It seems that in a man in their town made the mistake of marrying a ${woman} of an undesirable racial background, and this group has stepped in to put an end to such a distasteful union. However, though they may be ruthless vigilantes, they don't consider themselves murderers. They're interested in fencing this former ${wife} to you, no questions asked, on a flat fee basis. Included in the message is a slave dossier detailing the piece of human chattel they're offering.`);

		App.Events.addParagraph(node, r);

		node.append(App.Desc.longSlave(slave, {market: "generic"}));

		const choices = [];

		if (V.cash >= contractCost) {
			choices.push(new App.Events.Result(`Enslave ${him}`, enslave, `This will cost ${cashFormat(contractCost)}`));
			choices.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));
		} else {
			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}.`));
		}
		App.Events.addResponses(node, choices);

		function enslave() {
			const frag = new DocumentFragment();
			r = [];
			r.push(`A clearly improvised VTOL craft arrives at ${V.arcologies[0].name}, broadcasting an erratic array of IFF codes. It seems this group hasn't quite mastered the intricacies of air travel. The aircraft doesn't seem capable of the delicate feat of landing on the pad it had been directed to: it simply hovers`);
			if (V.showInches === 2) {
				r.push(`six feet`);
			} else {
				r.push(`two meters`);
			}
			r.push(`off the pad for the five seconds it takes to shove a canvas bag that obviously contains a struggling human form out of the side door.`);

			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addParagraph(frag, r);
			return frag;
		}

		function sell() {
			const frag = new DocumentFragment();
			r = [];
			cashX(cost, "slaveTransfer");
			r.push(`A clearly improvised VTOL craft arrives at ${V.arcologies[0].name}, broadcasting an erratic array of IFF codes. It seems this group hasn't quite mastered the intricacies of air travel. The aircraft doesn't seem capable of the delicate feat of landing on the pad it had been directed to: it simply hovers`);
			if (V.showInches === 2) {
				r.push(`six feet`);
			} else {
				r.push(`two meters`);
			}
			r.push(`off the pad for the five seconds it takes to shove a canvas bag that obviously contains a struggling human form out of the side door. You decide to do the simple thing, and leave the bag where it is. The purchaser's agent can deal with it.`);
			App.Events.addParagraph(frag, r);
			return frag;
		}
	}
};


code:
App.Events.recFSTransformationFetishist = class recFSTransformationFetishist extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => V.FSAnnounced === 1,
		];
	}

	actorPrerequisites() {
		return [];
	}

	get weight() {
		return V.arcologies[0].FSTransformationFetishist > random(1, 100) ? 1 : 0;
	}

	execute(node) {
		let r = [];
		const slave = GenerateNewSlave(null, {maxAge: 42, disableDisability: 1, race: "nonslave"});
		generateSalonModifications(slave);
		slave.origin = "You received $him from a surgeon who botched an implant operation on $him and needed to get $him out of sight.";
		slave.boobsImplant += random(10, 20)*200;
		slave.boobs += slave.boobsImplant;
		slave.boobsImplantType = "advanced fillable";
		if (slave.boobsImplant / slave.boobs >= 0.90) {
			slave.boobShape = "spherical";
			slave.nipples = "flat";
		} else {
			slave.boobShape = "normal";
			slave.nipples = "tiny";
		}
		slave.areolae = 2;
		slave.buttImplant += random(2, 4);
		slave.buttImplantType = "fillable";
		slave.butt += slave.buttImplant;
		slave.lipsImplant += random(15, 25);
		slave.lips += slave.lipsImplant;
		slave.face = Math.clamp(slave.face+20, -100, 100);
		slave.faceImplant += 40;
		slave.devotion = random(-100, -75);
		slave.trust = random(-45, -25);
		setHealth(slave, jsRandom(-50, -20), normalRandInt(20, 4), normalRandInt(10, 3), 0, 0);
		slave.pubicHStyle = "waxed";
		slave.underArmHStyle = "waxed";
		slave.behavioralFlaw = either("anorexic", "arrogant", "bitchy", "odd");

		const {
			He,
			his, he, him, woman
		} = getPronouns(slave);
		const contractCost = 1000;
		const cost = slaveCost(slave) - contractCost;
		r.push(`You receive a message coded urgent from a surgeon who you've hired in the past. You are on the point of opening the a call with a friendly businesslike salutation when you see his haggard, worried face, and change your greeting to one of commiseration and understanding. He pours out his troubles to you in a rush.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`It seems he botched an implant operation on a free ${woman}. ${He}'s still out, and the implants are in successfully, but ${he}'s not too far from dead and will remain so for some time. He needs ${him} out of sight, now. With your pull, you could easily manipulate the financial situation to enslave ${him} and get ${him} out of the doctor's area at the same time. It would be a favor to him, and by the medical records, a favor to you too, once you nurse ${him} back to health. ${He}'s quite the implant queen.`);

		App.Events.addParagraph(node, r);

		node.append(App.Desc.longSlave(slave, {market: "generic"}));

		const choices = [];

		if (V.cash >= contractCost) {
			choices.push(new App.Events.Result(`Enslave ${him}`, enslave, `This will cost ${cashFormat(contractCost)}`));
			choices.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));
		} else {
			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}.`));
		}
		App.Events.addResponses(node, choices);

		function enslave() {
			const frag = new DocumentFragment();
			r = [];
			r.push(`${He} arrives with various medical devices still attached to ${him}, wrapped up in supportive hospital clothing. Despite this, it's obvious that you've made a good decision. The new tits that got ${him} into this situation are so cartoonish that some of the medical tubing has been hastily routed between them. After a few weeks on curatives and a few more in training, ${he}'ll be ready to bounce those fake boobs up and down as ${he} takes dick.`);

			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addParagraph(frag, r);
			return frag;
		}

		function sell() {
			cashX(cost, "slaveTransfer");
			return `The only downside to ${his} condition is that reselling ${him} is utterly anticlimactic. A purchaser's agent arrives and takes charge of ${him}, transferring ${him} to a medical transport bed. He takes ${him} away, and it's done.`;
		}
	}
};


code:
App.Events.recFSTransformationFetishistTwo = class recFSTransformationFetishistTwo extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => V.FSAnnounced === 1,
			() => V.arcologies[0].FSTransformationFetishist > random(1, 100) || (V.debugMode > 0 && V.debugModeEventSelection > 0)
		];
	}

	execute(node) {
		let r = [];
		const slave = GenerateNewSlave(null, {
			minAge: 32, maxAge: 42, ageOverridesPedoMode: 1, disableDisability: 1
		});
		slave.origin = "$His husband sold $him into slavery to escape his debts.";
		slave.career = "a trophy wife";
		slave.boobsImplant += random(5, 10)*200;
		slave.boobs += slave.boobsImplant;
		slave.boobsImplantType = "fillable";
		if (slave.boobsImplant / slave.boobs >= 0.90) {
			slave.boobShape = "spherical";
			slave.nipples = "flat";
		} else {
			slave.boobShape = "normal";
			slave.nipples = "tiny";
		}
		slave.areolae = 2;
		slave.buttImplant += random(2, 4);
		slave.butt += slave.buttImplant;
		slave.buttImplantType = "normal";
		slave.lipsImplant += random(15, 25);
		slave.lips += slave.lipsImplant;
		slave.face = Math.clamp(slave.face+20, -100, 100);
		slave.faceImplant += 40;
		slave.devotion = random(-100, -75);
		slave.trust = random(-45, -25);
		setHealth(slave, jsRandom(20, 60), normalRandInt(10, 3), normalRandInt(10, 3), 0, 20);
		slave.pubicHStyle = "waxed";
		slave.behavioralFlaw = either("anorexic", "arrogant", "bitchy", "odd");

		const {
			His, He,
			his, he, him, himself, wife, woman
		} = getPronouns(slave);
		const {HeA} = getPronouns(assistant.pronouns().main).appendSuffix("A");
		const contractCost = 1000;
		const cost = slaveCost(slave) - contractCost;
		r.push(`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, r);
		r = [];
		r.push(`The call comes in from an unusually well-to-do area. It appears that an aristocratic-looking man placing the call has fallen on hard times, and is doing the intelligent thing and staying ahead of his creditors by offering his trophy ${wife} into slavery. Enslaving ${him} will be costlier than usual, but it seems likely to be worth it. ${He}'s finely aged and completed worked over under a surgeon's knife. ${He}'s quite the implant queen, in fact.`);

		App.Events.addParagraph(node, r);

		node.append(App.Desc.longSlave(slave, {market: "generic"}));

		const choices = [];

		if (V.cash >= contractCost) {
			choices.push(new App.Events.Result(`Enslave ${him}`, enslave, `This will cost ${cashFormat(contractCost)}`));
			choices.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));
		} else {
			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}.`));
		}
		App.Events.addResponses(node, choices);

		function enslave() {
			const frag = new DocumentFragment();
			r = [];
			r.push(`${He} arrives unapologetically in ${his} fine clothing.`);
			r.push(Spoken(slave, `"I'm not sorry,"`));
			r.push(`${he} says harshly,`);
			r.push(Spoken(slave, `"but I'm wearing my best one last time whether you like it or not."`));
			r.push(`Eventually ${he} sighs, squares ${his} shoulders, and visibly steels ${himself}.`);
			r.push(Spoken(slave, `"I'll say as a free ${woman}, since it's my last chance to say anything as a free ${woman}, you're good-looking, for an evil slaveholding oligarch."`));
			r.push(`${He} delivers this last with a little smile on ${his} plush lips and a sense of bitter irony in ${his} voice.`);
			r.push(Spoken(slave, `"If we'd met at a nice party last week I might have made a pass at you. You'd be a better choice than my ex-husband at least."`));

			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addParagraph(frag, r);
			return frag;
		}

		function sell() {
			const frag = new DocumentFragment();
			r = [];
			cashX(cost, "slaveTransfer");
			r.push(`${He} arrives unapologetically in ${his} fine clothing.`);
			r.push(Spoken(slave, `"I'm not sorry,"`));
			r.push(`${he} says harshly,`);
			r.push(Spoken(slave, `"but I'm wearing my best one last time whether you like it or not."`));
			r.push(`Eventually ${he} sighs, squares ${his} shoulders, and visibly steels ${himself}. ${He}'s about to declaim something when a purchaser's agent arrives to bundle ${him} off. ${His} face darkens and ${he} mulls something over, probably preparing a really cutting remark, but before ${he} can deliver it the agent fastens a bag over ${his} head and ${he} is heard no more.`);
			App.Events.addParagraph(frag, r);
			return frag;
		}
	}
};


code:
App.Events.recFSYouthPreferentialist = class recFSYouthPreferentialist extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => V.FSAnnounced === 1,
		];
	}

	actorPrerequisites() {
		return [];
	}

	get weight() {
		return V.arcologies[0].FSYouthPreferentialist > random(1, 100) ? 1 : 0;
	}

	execute(node) {
		let r = [];
		const slave = GenerateNewSlave(null, {maxAge: 18, disableDisability: 1});
		generateSalonModifications(slave);
		slave.origin = "$He came to you for enslavement out of desperation, terrified that $he was about to be enslaved into a worse situation by $his abusive family.";
		setHealth(slave, jsRandom(-40, 30), undefined, undefined, 0, 70);
		slave.devotion = random(10, 15);
		slave.trust = random(-55, -75);
		slave.birthWeek = 0; // turns {age} this week
		slave.behavioralFlaw = either("anorexic", "devout", "gluttonous", "hates men", "hates women", "odd");
		slave.sexualFlaw = either("apathetic", "hates anal", "hates oral", "repressed", "shamefast");

		const {
			He,
			his, he, him, girl
		} = getPronouns(slave);
		const {HeA} = getPronouns(assistant.pronouns().main).appendSuffix("A");
		const contractCost = 1000;
		const cost = slaveCost(slave) - contractCost;
		r.push(`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, r);
		r = [];
		r.push(`This one, unusually, is voice-only. The caller explains why in a painfully quiet voice: ${he}'s turning ${slave.actualAge} in the next few days, and ${he}'s fairly certain ${his} family is about to sell ${him} into slavery. The mixed notes of despair, apathy, and fear in ${his} voice are heartrending, even to you. ${He} begs you to make the necessary arrangements to enslave ${him}. ${He}'s heard about you and how you like young ${girl}s, and ${he}'s also heard about brothels and arcades. There is very little hope discernible in ${his} tone or the pictures ${he} sends you.`);

		App.Events.addParagraph(node, r);

		node.append(App.Desc.longSlave(slave, {market: "generic"}));

		const choices = [];

		if (V.cash >= contractCost) {
			choices.push(new App.Events.Result(`Enslave ${him}`, enslave, `This will cost ${cashFormat(contractCost)}`));
			choices.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));
		} else {
			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}.`));
		}
		App.Events.addResponses(node, choices);

		function enslave() {
			const frag = new DocumentFragment();
			r = [];
			r.push(`Your slaving network gets ${him} out of ${his} difficult situation without trouble, forwarding ${him} the necessary travel documents. When ${he} arrives, ${he} displays the clear signs of someone who has learned to avoid abuse: ${he} takes no initiative and does nothing without instructions, just standing dumbly until ordered; when told what to do, ${he} does it quickly and carefully. Though ${his} mind is not broken, there is something dead lurking in ${his} eyes. When ${he} looks at you, it is with the watchful caution of an abused animal.`);

			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addParagraph(frag, r);
			return frag;
		}

		function sell() {
			cashX(cost, "slaveTransfer");
			return `Your slaving network gets ${him} out of ${his} difficult situation without trouble, forwarding ${him} the necessary travel documents. When ${he} arrives, ${he} displays the clear signs of someone who has learned to avoid abuse: ${he} takes no initiative and does nothing without instructions, just standing dumbly until ordered; when told what to do, ${he} does it quickly and carefully. When a buyer's agent arrives to take ${him} away, ${he} follows him without a backward glance.`;
		}
	}
};


code:
App.Events.recFSYouthPreferentialistTwo = class recFSYouthPreferentialistTwo extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => V.FSAnnounced === 1,
			() => V.arcologies[0].FSYouthPreferentialist > random(1, 100) || (V.debugMode > 0 && V.debugModeEventSelection > 0)
		];
	}

	execute(node) {
		let r = [];
		const slave = GenerateNewSlave(null, {
			minAge: 18, maxAge: 18, ageOverridesPedoMode: 1, disableDisability: 1
		});
		generateSalonModifications(slave);
		slave.origin = "$He came to you for enslavement out of desperation, terrified that $he was about to be asked to do something with $his life by $his family.";
		setHealth(slave, jsRandom(-40, 30), 0, 0, 0, jsRandom(20, 40));
		slave.devotion = random(10, 15);
		slave.trust = random(-55, -75);
		slave.intelligence = random(-95, -51);
		slave.anus = random(2, 3);
		slave.weight = random(-80, -20);
		slave.boobs -= 50*random(1, 2);
		slave.butt -= random(0, 1);
		slave.behavioralFlaw = either("anorexic", "gluttonous", "odd");
		slave.sexualFlaw = either("apathetic", "repressed");
		const {
			He,
			his, he, him, girl
		} = getPronouns(slave);
		const {HeA} = getPronouns(assistant.pronouns().main).appendSuffix("A");
		const contractCost = 1000;
		const cost = slaveCost(slave) - contractCost;
		r.push(`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, r);
		r = [];
		r.push(`This one, unusually, is voice-only. The caller explains why in an unusually upbeat voice: ${he} turned 18 a few days ago, and ${he}'s fairly certain ${his} family is expecting ${him} to make something of ${his} life to help support them. The apathy to ${his} family's wishes is readily evident in ${his} tone of voice. ${He} begs you to make the necessary arrangements to enslave ${him}. ${He}'s heard about you and how you like younger ${girl}s, and that you take care of all the decision-making for your slaves. There's a lot of hope in ${his} tone, ${he} clearly wants an escape from responsibility — even if that means becoming a slave.`);

		App.Events.addParagraph(node, r);

		node.append(App.Desc.longSlave(slave, {market: "generic"}));

		const choices = [];

		if (V.cash >= contractCost) {
			choices.push(new App.Events.Result(`Enslave ${him}`, enslave, `This will cost ${cashFormat(contractCost)}`));
			choices.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));
		} else {
			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}.`));
		}
		App.Events.addResponses(node, choices);

		function enslave() {
			const frag = new DocumentFragment();
			r = [];
			r.push(`Your slaving network extracts ${him} from ${his} family's grasp easily, forwarding ${him} the necessary travel documents. When ${he} arrives, ${he} displays the clear signs of someone who's never had to think for themselves: ${he} takes no initiative and does nothing without instructions, just standing dumbly until ordered; when told what to do, ${he} does it quickly and carefully. Though ${his} mind is not broken, there's clearly not a lot in there. Being a slave may actually be ${his} most fitting vocation.`);

			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addParagraph(frag, r);
			return frag;
		}

		function sell() {
			cashX(cost, "slaveTransfer");
			return `Your slaving network extracts ${him} from ${his} family's grasp easily, forwarding ${him} the necessary travel documents. When ${he} arrives, ${he} displays the clear signs of someone who's never had to think for themselves: ${he} takes no initiative and does nothing without instructions, just standing dumbly until ordered; when told what to do, ${he} does it quickly and carefully. Though ${his} mind is not broken, there's clearly not a lot in there. Being a slave may actually be ${his} most fitting vocation. When a buyer's agent arrives to take ${him} away, ${he} follows him without a backward glance, clearly unaware of who he is.`;
		}
	}
};


code:
App.Events.JobFulfillmentCenterDelivery = class JobFulfillmentCenterDelivery extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => V.JFC.order === 1,
			() => V.JFC.reorder !== 1
		];
	}

	execute(node) {
		V.JFC.order = 0;
		App.UI.StoryCaption.encyclopedia = "Enslaving People";
		const slave = generateLeadershipSlave(V.JFC.role, 'Job Fulfillment Center');
		const {
			He,
			he, him
		} = getPronouns(slave);
		const cost = slaveCost(slave) * 6;

		App.Events.addParagraph(node, [
			`A slave dealer has submitted a slave to satisfy your`,
			App.UI.DOM.makeElement("span", V.JFC.role, "bold"),
			`order for ${cashFormat(cost)}.`
		]);

		App.UI.DOM.appendNewElement("span", node, `As usual, the asking price is quite high, to cover training costs. However, you can freely decline the slave should ${he} not meet your standards or the job has already been filled.`, "note");

		node.append(App.Desc.longSlave(slave, {market: "generic"}));

		const choices = [];
		if (V.cash >= cost) {
			choices.push(new App.Events.Result(`Accept the offered slave`, accept));
		} else {
			choices.push(new App.Events.Result(null, null, `You lack the necessary funds to accept the offered slave.`));
		}
		choices.push(new App.Events.Result(`Reject and repost this offer`, reject));
		App.Events.addResponses(node, choices);

		function accept() {
			V.JFC = {order: 0, reorder: 0};
			cashX(-cost, "slaveTransfer", slave);

			return [
				`${He} has been very well trained by the dealer that offered ${him} to you. ${He} has also picked up on the fact that ${he} was specially selected, and is a little hopeful that this means ${he} may be treated well. ${He} is now eagerly awaiting your instructions.`,
				App.UI.newSlaveIntro(slave)
			];
		}

		function reject() {
			V.JFC.order = 1;
			V.JFC.reorder = 1;
			return `The current slave is not to your satisfaction. No matter. There are always more slaves.`;
		}
	}
};


code:
App.Events.SEAssholeKnight = class SEAssholeKnight extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => App.Events.effectiveWeek() >= 15,
			() => V.arcologies[0].FSNeoImperialistLaw1 === 1,
			() => V.assholeKnight !== 1
		];
	}

	execute(node) {
		V.assholeKnight = 1;
		V.imperialEventWeek = App.Events.effectiveWeek();

		const assholeKnight = GenerateNewSlave(V.seeDicks > 0 ? "XY" : "XX", {minAge: 22, maxAge: 34, disableDisability: 1});
		assholeKnight.prestige = 1;
		assholeKnight.prestigeDesc = "$He was formerly an Imperial Knight, a highly prestigious position indicating both nobility and exceptional combat prowess. Although $he has had $his coat of arms stripped, many still recognize $him from his former Knighthood.";
		assholeKnight.origin = "$He used to be a Knight within your arcology, until you had $him stripped of $his title and summarily enslaved for cruelly abusing citizens beneath $his stature.";
		assholeKnight.career = "spec ops";
		assholeKnight.devotion = random(-80, -60);
		assholeKnight.muscles = random(50, 75);
		assholeKnight.skill.combat = 100;
		assholeKnight.sexualFlaw = "malicious";
		assholeKnight.behavioralQuirk = "none";
		assholeKnight.trust = random(-30, -20);
		assholeKnight.butt = random(0, 1);
		assholeKnight.natural.height = random(175, 195);
		assholeKnight.height = assholeKnight.natural.height;
		assholeKnight.fetish = "sadist";
		assholeKnight.fetishStrength = 80;
		assholeKnight.preg = 0;
		if (assholeKnight.genes === "XY") {
			assholeKnight.faceShape = "masculine";
			assholeKnight.dick = random(3, 5);
			assholeKnight.balls = random(2, 4);
			assholeKnight.scrotum = assholeKnight.balls;
			assholeKnight.boobs = 150;
		} else {
			assholeKnight.faceShape = "androgynous";
			assholeKnight.vagina = 0;
			assholeKnight.boobs = Math.min(assholeKnight.boobs, 450);
			assholeKnight.natural.boobs = assholeKnight.boobs;
		}
		assholeKnight.accent = random(0, 1);

		const {he, his, him, woman} = getPronouns(assholeKnight);

		App.Events.drawEventArt(node, assholeKnight, "Imperial Plate");

		App.Events.addParagraph(node, [`The group of citizens you hand-picked as your Knights have quickly proven themselves a reliable staple of the Arcology. Being visibly a league above the common citizen with their heavy Imperial Plate decorated with glimmering pendants and marks of their individual, flowery coats of arms, their mere presence is enough to make most common criminals cower and keep merchants selling their wares at fair prices. The tenets of neo-Imperial hierarchy and their own social prestige have already gone to their heads, and many Knights are now recognized immediately by the common citizens as heroic, uncowed citizen-soldiers.`]);

		App.Events.addParagraph(node, [`Despite the noble reputations of many of your Knights, their image as defenders of the downtrodden and honest protectors of the Arcology is not universal. Although you Knighted every last one of them yourself, it seems you might have made a misjudgment on the character of one of your new servants; a stream of minor offenses from one Knight in particular has been building up in your inbox for quite some time, and reviewing the whole dossier now paints a portrait of abuses and misconduct.`]);

		App.Events.addParagraph(node, [`This singular Knight has apparently been using ${his} position to extort and bully the populace, demanding unreasonably steep discounts from merchants and regularly beating the peasantry - often for no reason other than momentary amusement, and treating them as "less than even slaves". A number of frustrated citizens have sent you a petition demanding that you denounce and punish ${him} for ${his} petty offenses - a picture of a woman with her face blurred out and a trail of bruises over every inch of her naked body is attached. No names have been attached to the petition, apparently for fear of what the Knight in question will do to them should their attempts be uncovered. Whatever you decide to do with this ${woman} will undoubtedly set the precedent for how you deal with Knights who abuse their station in the future.`]);

		const choices = [];
		choices.push(new App.Events.Result(`Remove ${his} title and confiscate ${his} weapons`, demTitles));
		choices.push(new App.Events.Result(`Have ${him} publicly flogged, then enslaved`, flogMeat));
		choices.push(new App.Events.Result(`Turn a blind eye`, blindInjustice));
		App.Events.addResponses(node, choices);

		function demTitles() {
			repX(2500, "event");
			return `You have the insolent Knight's plate armor confiscated, ${his} apartment seized and ${his} right to bear a coat of arms redacted. The knight is nothing short of utterly furious, but puts up no fight as your guards seize ${his} advanced weaponry; to do so would be suicidal. While ${he} swears revenge against you for taking away ${his} "noble rights", you receive a letter from a relieved merchant thanking you for putting the jumped-up bandit down.`;
		}

		function flogMeat() {
			const frag = new DocumentFragment();
			let r = [];
			r.push(`You have the insolent Knight's gear and weapons confiscated, then publicly flog ${him} in the plaza and announce that ${he}'s to be enslaved for crimes against the people of ${V.arcologies[0].name}. Although the watching peasants are clearly relieved that the cruel bully is off the streets, some of them, those who did not feel the fist of the howling ${woman} on their own neck, recoil somewhat at the sudden brutality against a class that most of them idolize and romanticize.`);
			repX(1000, "event");
			r.push(App.UI.newSlaveIntro(assholeKnight));
			App.Events.addParagraph(frag, r);
			return frag;
		}

		function blindInjustice() {
			cashX(500, "event");
			repX(-2000, "event");
			return `You opt to ignore the abuses of the cruel knight completely. Every few weeks, you receive another pleading message in your inbox about the Knight, until they simply stop coming as the lower class accepts the random abuse of their betters. A few days later, as you socialize with your upper-class, the Knight in question passes you a full envelope and winks with no further explanation.`;
		}
	}
};


code:
App.Events.SEBurst = class SEBurst extends App.Events.BaseEvent {
	constructor(actors, params) {
		super(actors, params);
	}

	/** Custom casting: all bursting slaves are cast automatically. If no slaves are cast, casting fails and the event does not run. */
	castActors() {
		this.actors = V.slaves.filter(s => burstCheck(s)).map(s => s.ID);
		return this.actors.length > 0;
	}

	execute(node) {
		const artRenderer = V.seeImages && V.seeReportImages ? new App.Art.SlaveArtBatch(this.actors, 2, 0) : null;
		if (artRenderer) {
			node.append(artRenderer.writePreamble());
		}

		for (const slave of this.actors.map(id => getSlave(id))) {
			if (slave.womb.length > 0) {
				node.append(birth(slave, {artRenderer}));
			} else if (getPersonalAttention(slave.ID, "torture") && !onBedRest(V.PC, true)) {
				node.append(torture(slave));
			} else if (getPersonalAttention(slave.ID, "ravish") && !onBedRest(V.PC, true)) {
				node.append(ravish(slave));
			} else {
				node.append(pop(slave));
			}
			removeSlave(slave);
			node.append(sectionBreak());
		}

		/**
		 *
		 * @param {App.Entity.SlaveState} slave
		 * @returns {DocumentFragment}
		 */
		function pop(slave) {
			const el = new DocumentFragment();
			const r = [];
			const {
				He, His,
				he, his, him
			} = getPronouns(slave);
			if (artRenderer) {
				App.UI.DOM.drawOneSlaveRight(el, slave, artRenderer);
			}
			r.push(`As ${slave.slaveName} is going about ${his} business with ${his} overfilled`);
			if (slave.inflation !== 0) {
				r.push(slave.inflationType);
			}
			r.push(`belly, ${he} can't help but feel exhausted. ${His} health has been poor lately and the pressure in ${his} organs is not helping things. ${He} immediately knows something is wrong when an intense pain runs through ${his} middle and ${his} load shifts threateningly.`);
			if (slave.inflation !== 0) {
				r.push(`Blood and ${slave.inflationType} leak`);
			} else {
				r.push(`Blood leaks`);
			}
			r.push(`from ${his} rear as ${his} body cavity fills with the contents of ${his} digestive tract. The skin of ${his} taut belly reddens as the pressure against it builds. As ${he} takes ${his} last breath, ${he} falls forward, ${his} weight landing upon ${his} straining stomach. With a gush, ${he} ruptures, flooding the area around ${him} with`);
			if (slave.inflation !== 0) {
				r.push(`blood, guts and ${slave.inflationType}.`);
			} else {
				r.push(`blood and guts.`);
			}
			el.append(r.join(" "));
			el.append(horrifiedSlaves(slave));
			return el;
		}

		/**
		 *
		 * @param {App.Entity.SlaveState} slave
		 * @returns {DocumentFragment}
		 */
		function torture(slave) {
			const el = new DocumentFragment();
			const r = [];
			const {
				he, his, him
			} = getPronouns(slave);
			if (artRenderer) {
				App.UI.DOM.drawOneSlaveRight(el, slave, artRenderer);
			}
			r.push(`${slave.slaveName}'s belly is positively bursting`);
			if (slave.inflation !== 0) {
				r.push(`with ${slave.inflationType},`);
			} else {
				r.push(`as is,`);
			}
			r.push(`so it's extra fun to punch and strike at it to see ${his} pained reactions. You land a solid blow to ${his} straining gut and, like the world's worst piñata, ${he} bursts, showering the area around ${him} with`);
			if (slave.inflation !== 0) {
				r.push(`blood, guts and ${slave.inflationType}.`);
			} else {
				r.push(`blood and guts.`);
			}
			r.push(`It seems you'll need a new toy to play with.`);
			el.append(r.join(" "));
			el.append(horrifiedSlaves(slave));
			return el;
		}

		/**
		 *
		 * @param {App.Entity.SlaveState} slave
		 * @returns {DocumentFragment}
		 */
		function ravish(slave) {
			const el = new DocumentFragment();
			const r = [];
			const {
				he, his, him
			} = getPronouns(slave);
			if (artRenderer) {
				App.UI.DOM.drawOneSlaveRight(el, slave, artRenderer);
			}
			r.push(`Fucking ${slave.slaveName} with ${his} overfilled`);
			if (slave.inflation !== 0) {
				r.push(slave.inflationType);
			}
			r.push(`belly bouncing around every which way is a blast, though ${he} begins to wince and groan more than usual as the week nears its end. As you finish up a particularly intense`);
			if (canAchieveErection(V.PC)) {
				r.push(`session by blowing a huge load into ${him}, you notice ${his} belly slowly starting to swell. As you ponder this development with a few extra thrusts to get out that last bit of cum, ${his} middle bursts beneath you, sending you crashing onto ${his} lifeless body from the sudden shift and into a pool of`);
				if (slave.inflation !== 0) {
					r.push(`blood, guts and ${slave.inflationType}.`);
				} else {
					r.push(`blood and guts.`);
				}
				r.push(`That was not what you expected to happen, and you probably shouldn't keep humping what's left of ${him} instead of cleaning up.`);
			} else {
				r.push(`session, you can't help but notice ${his} belly slowly starting to swell; an oddity, given you aren't unloading anything into ${him}. You ponder this development as you shift ${him} into a favorable position for another round, only to have ${his} middle burst on top of you, covering you with a deluge of`);
				if (slave.inflation !== 0) {
					r.push(`blood, guts and ${slave.inflationType}.`);
				} else {
					r.push(`blood and guts.`);
				}
				r.push(`You lay there, stunned and holding ${his} corpse upright over you, dumbfounded by what just happened.`);
			}
			el.append(r.join(" "));
			el.append(horrifiedSlaves(slave));
			return el;
		}

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

/**
 *
 * @param {App.Entity.SlaveState} slave
 * @returns {HTMLElement}
 */
globalThis.horrifiedSlaves = function(slave) {
	const el = document.createElement("p");
	const {his} = getPronouns(slave);
	el.append(`Word of the late slave and ${his} gruesome fate spread fast, `);
	App.UI.DOM.appendNewElement("span", el, "terrifying", "gold");
	el.append(` your untrusting slaves.`);
	for (const bystander of V.slaves) {
		if (bystander.trust <= 50) {
			if (slave.inflation > 0) {
				bystander.trust -= (Math.pow(slave.inflation, 3) * 5);
			} else {
				bystander.trust -= 10;
			}
		}
	}
	return el;
};


code:
App.Events.MurderAttempt = class MurderAttempt extends App.Events.BaseEvent {
	constructor(actors, params) {
		super(actors, params);
	}

	eventPrerequisites() {
		return [
			() => V.plot === 1,
			() => App.Events.effectiveWeek() >= V.murderAttemptWeek
		];
	}

	execute(node) {
		// setup next time, 2-4 months
		V.murderAttemptWeek = V.week + 26 + Math.floor(Math.random() * 26);
		// disable Continue
		V.nextButton = " ";
		const perceptiveCareers = ["escort", "gang", "hoodlum", "mercenary", "prostitute", "street urchin"];
		// event unique
		const variation = jsEither(["trade", "slave", "drug", "military"]);
		let isSincere = Math.random() > 0.6;
		// actual deals can only trigger once
		if (isSincere) {
			switch (variation) {
				case "trade":
					isSincere = V.illegalDeals.trade === 0;
					break;
				case "slave":
					isSincere = V.illegalDeals.slave === 0;
					break;
				case "drug":
					isSincere = V.illegalDeals.menialDrug === 0;
					break;
				case "military":
					isSincere = V.illegalDeals.military === 0;
					break;
			}
		}
		const companyName = ["RealTec", "Horizons Unlimited", "Dix Trade", "TA Technology"].random() + ["", " Inc."].random();
		const {he, He, his, him, woman, himself} = getPronouns((FutureSocieties.isActive('FSGenderFundamentalist') || V.seeDicks > random(0, 99))
			? {pronoun: App.Data.Pronouns.Kind.male} : {pronoun: App.Data.Pronouns.Kind.female});
		const {womanPC} = getPronouns(V.PC).appendSuffix("PC");

		intro(node);

		function perceptionChance() {
			return (perceptiveCareers.includes(V.PC.career) || V.PC.skill.warfare >= 60 || V.PC.skill.slaving >= 60 || V.PC.skill.medicine >= 60);
		}

		function intro(fragment) {
			const r = [];
			r.push(`As per routine, you are sifting through the messages ${V.assistant.name} has flagged as relevant from the mass that fills your inbox each day.`);
			r.push(`One is a request from a company called ${companyName} for a personal meeting to propose some kind of`);
			switch (variation) {
				case "trade":
					r.push("business venture.");
					break;
				case "slave":
					r.push("unique slave trade.");
					break;
				case "drug":
					r.push("deal for a new drug.");
					break;
				case "military":
					r.push("military endeavor.");
					break;
			}
			r.push("Despite being incredibly vague about the details of said business opportunity, they have references from multiple reputable businesses in the");
			switch (variation) {
				case "trade":
					r.push("trading");
					break;
				case "slave":
					r.push("arcology");
					break;
				case "drug":
					r.push("medical");
					break;
				case "military":
					r.push("military");
					break;
			}
			r.push("and slavery sectors. Some of them are known for dealing in less than legal business regularly, so the lack of information may just be either an attempt to distance themselves from seedy dealings or something truly lucrative, if slightly dirty.");
			App.Events.addParagraph(fragment, r);

			let yesText;
			let noText;
			switch (variation) {
				case "trade":
					yesText = "New business is always good";
					noText = "profitable business venture";
					break;
				case "slave":
					yesText = "Unique slaves are always interesting";
					noText = "special slave";
					break;
				case "drug":
					yesText = "Special drugs unavailable to the public are always interesting";
					noText = "new drug";
					break;
				case "military":
					yesText = "A profitable use for your mercenary troops is always good";
					noText = "profitable military venture";
					break;
			}
			App.Events.addResponses(fragment, [
				new App.Events.Result(`${yesText}; invite them to a private meeting`, invite),
				new App.Events.Result(`You are not going to waste your time on something as vague as a "${noText}"`, endEvent)
			]);
		}

		function invite() {
			const fragment = document.createDocumentFragment();

			let r = [];
			r.push(`${capFirstChar(V.assistant.name)} schedules a meeting a few days later to take place in your personal office, an oddity given these meetings are usually conducted in a more neutral, albeit less secure location, but ${companyName} insisted on it.`);
			if (["capitalist", "engineer", "escort", "mercenary", "recruit", "slave overseer", "slaver"].includes(V.PC.career)) {
				r.push("You should prepare for anything; it's better to be prepared in case something goes awry.");
			} else {
				r.push("You can't really complain; it's easier for you and cheaper should nothing come of it.");
			}
			App.Events.addParagraph(fragment, r);

			r = [];
			r.push(`When it comes time for the meeting, a ${woman} arrives at the entryway of the penthouse and is escorted to your office by one of your slaves as you watch ${him} on your monitor. The ${woman} is distinctively average looking, as if you took all business men that did their job well, but did not overachieve, and created the perfect average of it. Someone trying this hard to appear average is certainly anything but average.`);
			App.Events.addParagraph(fragment, r);

			r = [];
			r.push(`Once ${he} reaches your office, you settle down after a short greeting for ${him} to begin`);
			switch (variation) {
				case "trade":
				case "military":
					r.push("showing you the plans they have.");
					break;
				case "slave":
					r.push("explaining the uniqueness of their slaves.");
					break;
				case "drug":
					r.push("showing you the effects of their new drug.");
					break;
			}

			if (S.Bodyguard) {
				const {HeBG} = getPronouns(S.Bodyguard).appendSuffix("BG");
				r.push(`Before getting anywhere though, ${he} interrupts ${himself}, gesturing at your bodyguard.`);
				r.push(`"I'm sorry, this is meant only for your ears, can you please send your bodyguard outside?"`);
				App.Events.addParagraph(fragment, r);

				App.Events.addResponses(fragment, [
					new App.Events.Result(`Order ${him} to leave for making such a request`, sentOutRoute),
					new App.Events.Result(`${S.Bodyguard.slaveName} goes everywhere and does everything with you. ${HeBG} stays`, bgStaysRoute),
					new App.Events.Result(`This better be worth it. Order ${S.Bodyguard.slaveName} to leave`, bgLeavesRoute)
				]);
			} else {
				noSlaveRoute(fragment, r, false);
			}

			return fragment;
		}

		/**
		 * @param {DocumentFragment} fragment
		 * @param {Array<string>} paragraphStart
		 * @param {boolean} slaveLeft only relevant for murder attempt
		 */
		function noSlaveRoute(fragment, paragraphStart, slaveLeft) {
			if (isSincere) {
				sincereProposal(fragment, paragraphStart);
			} else {
				paragraphStart.push(`For the next few hours ${he} talks in circles, making grand gestures here and there but not really saying anything of substance to the point it starts to bore you.`);
				if (perceptionChance()) {
					paragraphStart.push(`That is, up until one of ${his} wide motions drops something in your drink. When you confront ${him} about it, ${he} draws a weapon and shoots you before you have a chance to react.`);
					if (V.PC.career === "gang") {
						paragraphStart.push(`You have the last laugh, though, as you draw your own weapon and gun ${him} down before you succumb to your wound.`);
					// } else if (V.PC.skill.medicine >= 100) {
						// allow for gravely wounded state during player update
					} else if (slaveLeft) { // BG must be able to walk, so we should assume that if this is true, she is actually lurking
						paragraphStart.push(`While ${S.Bodyguard.slaveName} may storm in and cut ${him} down, it will not bring you back to life.`);
					} else {
						paragraphStart.push(`Before ${he} can leave the building, your security detains ${him}, but this won't help a dead ${womanPC}.`);
					}
					App.Events.addParagraph(fragment, paragraphStart);
					App.Events.LocalGameOver(fragment);
				} else {
					poisoned(fragment, paragraphStart);
				}
			}
		}

		function sentOutRoute() {
			const fragment = document.createDocumentFragment();
			const r = [`Grumbling under ${his} breath ${he} quickly leaves.`];
			App.Events.addParagraph(fragment, r);
			continueButton(fragment);
			return fragment;
		}

		function bgStaysRoute() {
			const fragment = document.createDocumentFragment();

			if (isSincere) {
				let r = [];
				r.push(`"Very good," ${he} smiles, seeing your confused look, "We are not interested in dealing with someone who isn't in control of their own affairs." Seems like you just passed some sort of test.`);
				App.Events.addParagraph(fragment, r);
				r = [];
				r.push(`Satisfied, ${he} begins explaining:`);
				sincereProposal(fragment, r);
			} else {
				let r = [];
				r.push(`"If you say so..." ${He} continues and starts ${his} explanation anew, sometimes with great gestures, but never actually getting to the point. You start to grow bored of ${his} drivel`);
				if (S.Bodyguard.intelligence + S.Bodyguard.intelligenceImplant + (S.Bodyguard.skill.combat/2) > 60) {
					r.push(`until ${he} does one of ${his} grand motions again and ${S.Bodyguard.slaveName} jumps forward,`);
					if (perceptionChance()) {
						r.push("just a moment faster than you,");
					}
					if (canTalk(S.Bodyguard)) {
						r.push(`demanding to know what ${he} just put in your drink.`);
					} else {
						r.push(`snatching the glass and taking an aggressive stance.`);
					}
					bgDefense(fragment, r);
				} else if (perceptionChance()) {
					r.push(`until, on of ${his} grand motions, you notice ${he} slips something in your drink and you confront ${him} about what ${he} just did.`);
					bgDefense(fragment, r);
				} else {
					r.push(r.pop() + ".");
					poisoned(fragment, r);
				}
			}
			return fragment;
		}

		function bgDefense(fragment, paragraphStart) {
			paragraphStart.push(`Before you can react, the ${woman} draws a weapon and`);
			const {HeBG, heBG, hisBG, himBG} = getPronouns(S.Bodyguard).appendSuffix("BG");
			if ((S.Bodyguard.muscles > 95 && S.Bodyguard.height < 185) || S.Bodyguard.muscles < -30 || S.Bodyguard.boobs > 4000 || S.Bodyguard.weight > 130 || S.Bodyguard.health.tired > 30 || S.Bodyguard.belly >= 100000) { // BG is too big or weak to draw fast enough to matter
				paragraphStart.push("shoots you through the heart; having a bodyguard who cannot actually defend you might have been a poor choice in retrospect.");
				paragraphStart.push(`With you dead, ${S.Bodyguard.slaveName} knows ${heBG} has to put this to rest.`);
				if (deadliness(S.Bodyguard).value > 1) {
					paragraphStart.push(`Out of ammo, your murderer moves to grab ${himBG} by the head and introduce ${hisBG} skull to the corner of your table. ${S.Bodyguard.slaveName} may have been slow on the draw, but is not incompetent. ${HeBG} subdues ${him}, pinning ${him} down until security may collect ${him}, but it's all in vain when ${he} starts convulsing and quickly perishes to the contents of a false tooth. With nothing left, ${S.Bodyguard.slaveName} readies ${hisBG} weapon, puts it under ${hisBG} chin, and pulls the trigger.`);
				} else {
					paragraphStart.push(`Alas, ${heBG} is too incompetent to even do that. By the time ${heBG} manages to get a steady grip on ${hisBG} weapon, your murderer is already introducing ${hisBG} skull to the corner of your table. Sure ${he} is detained before ${he} makes it out of the building, but does that really matter when you're dead?`);
				}
				App.Events.addParagraph(fragment, paragraphStart);
				App.Events.LocalGameOver(fragment);
			} else {
				paragraphStart.push(paragraphStart.pop() + ",");
				if (deadliness(S.Bodyguard).value > 1 || (S.Bodyguard.muscles > 95 && S.Bodyguard.height >= 185)) {
					if (deadliness(S.Bodyguard).value > 1) {
						paragraphStart.push(`just a little quicker, ${S.Bodyguard.slaveName} draws ${hisBG} own, shooting ${him} in the shoulder. Screaming in pain, ${he} drops ${his} weapon and ${S.Bodyguard.slaveName} swiftly moves to secure ${him}.`);
					} else {
						paragraphStart.push(`to your surprise and later annoyance, find ${S.Bodyguard.slaveName} has used ${hisBG} impressive strength to flip your desk at ${him}. Crushed beneath the heavy piece of furniture and writhing in pain, ${he} is in no position to take any further actions against you.`);
					}
					App.Events.addParagraph(fragment, paragraphStart);
					let r = [];
					r.push(`After the initial shock has waned and you ready to begin interrogating ${him}, ${he} clamps ${his} jaw down hard, foams for several seconds and dies. Seems like whomever sent ${him} cares a lot about not being tracked down. And indeed, all the already sparse information about ${companyName} is gone and any leads you may have had are useless. You task ${V.assistant.name} to continue searching for the one behind this, but you don't expect anything to come out of it. Someone wanting you dead isn't all that surprising, and without any idea as to why, there are thousands of small groups and individuals who want arcology owners, owners like you, or maybe just you personally, dead.`);
					App.Events.addParagraph(fragment, r);
					continueButton(fragment);
				} else {
					paragraphStart.push(`just a moment too slow, ${S.Bodyguard.slaveName} draws ${hisBG} own, shooting ${him} in the chest, but not before you already have a bullet through your heart. Seeing you fall down, ${heBG} sets ${hisBG} weapon to automatic, puts it under ${hisBG} chin, and pulls the trigger.`);
					App.Events.addParagraph(fragment, paragraphStart);
					App.Events.LocalGameOver(fragment);
				}
			}
		}

		function bgLeavesRoute() {
			const fragment = document.createDocumentFragment();
			if (isSincere) {
				let r = [];
				r.push(`After your bodyguard leaves, ${he} stares at you for a while, before stating, "I don't believe you are ready to do business with us." When questioned why, ${he} answers, "If you can't trust your bodyguard with sensitive information, you clearly have bigger problems to worry about than our small proposal." ${He} leaves your office without waiting for anyone to see ${him} off.`);
				App.Events.addParagraph(fragment, r);
				continueButton(fragment);
			} else {
				let r = [];
				r.push(`"Thank you," ${he} states, before continuing.`);
				noSlaveRoute(fragment, r, true);
			}
			return fragment;
		}

		function poisoned(fragment, paragraphStart) {
			let r = paragraphStart;
			r.push(`After a while, ${he} finishes ${his} seemingly unending pitch, begins packing up and tells you to call ${him} if you are interested. You certainly will not be; if you wanted to hear someone talk for hours without saying anything, you would tune into a political debate out of one of the nearby old world counties.`);
			App.Events.addParagraph(fragment, r);
			r = [];
			r.push("Several hours later you start to feel strange. A few minutes after that, you collapse. You are dead long before help can arrive. Later autopsy reveals your cause of death to be poisoning.");
			App.Events.addParagraph(fragment, r);
			App.Events.LocalGameOver(fragment);
		}

		function sincereProposal(fragment, paragraphStart) {
			const options = [];
			switch (variation) {
				case "trade":
					paragraphStart.push(`${companyName} is planning a trade deal with an old world corporation that wants to expand into the Free Cities, but with the added twist of effectively robbing them during this. Their problem is they need something to show them and your arcology would be ideal for this. Your role would be simple, just follow a short script before leaving both sides to negotiate. If everything goes well, your share could be in the six digit realm, but if something goes wrong, your reputation would be severely damaged.`);
					options.push(
						new App.Events.Result("A windfall like this doesn't come by every day. Of course you'll take this opportunity.", accept()),
						new App.Events.Result("The potential winnings are not worth the risk. You will not be a part of their plans.", refused)
					);
					break;
				case "slave":
					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 && V.PC.actualAge >= 12) {
						options.push(new App.Events.Result(
							`Enslaving that annoying thorn in your side from ${V.PC.actualAge >= 18 ? "high" : "elementary"} school might be petty, but it will be worth it nonetheless.`,
							accept("school"), `Costs ${cashFormat(50000)}`));
					}
					if (V.cash >= 250000) {
						options.push(new App.Events.Result(
							"There is a rising star in the music industry that would fit perfectly in your stable.",
							accept("star"), `Costs ${cashFormat(250000)}`));
					}
					if (V.cash < 50000) {
						options.push(new App.Events.Result("You couldn't afford to enslave someone even if you wanted to.", refused));
					} else {
						options.push(new App.Events.Result(`You'll pass on the offer.`, refused));
					}
					break;
				case "drug":
					paragraphStart.push(`${companyName} has developed a new performance enhancing drug that can greatly improve one's productivity. It does however come with serious drawbacks, making it unsuitable for sex slaves, but it could immensely boost the efficiency of your menial slaves.`);
					if (V.cash >= 100000) {
						options.push(new App.Events.Result("Making more money from your menials is always good. Buy the drug.", accept(), `Costs ${cashFormat(100000)}`));
					} else {
						options.push(new App.Events.Result(null, null, "You don't have the cash required to buy the drug."));
					}
					options.push(
						new App.Events.Result("The downsides are not worth it.", refused)
					);
					break;
				case "military":
					paragraphStart.push(`${companyName} is part of an endeavor to carve out a new Free City in the old world. While being too far away to influence your local political climate, it is certainly a new milestone in their growing dominance over the old world. Your mercenaries are known to be veterans in fighting in such territory and that you supply them with state-of-the-art equipment, so it is only natural for the company to ask you to join in this operation. Shipping your mercenaries around the globe would be a big expense, but all participants who don't get a share of the colony itself will receive hefty compensation.`);
					options.push(
						new App.Events.Result("This is a worthy endeavor. Of course you will help out.", accept()),
						new App.Events.Result("Military operations tend to be a net loss most of the time. You will watch with interest, but not a vested one.", refused)
					);
					break;
			}
			App.Events.addParagraph(fragment, paragraphStart);
			App.Events.addResponses(fragment, options);
		}

		/**
		 * @param {string} [argument]
		 * @returns {function(): DocumentFragment}
		 */
		function accept(argument) {
			return function() {
				const r = [];
				switch (variation) {
					case "trade":
						r.push(`You discuss the details of the operation before ${he} leaves. You will have a guest soon.`);
						V.illegalDeals.trade = {week: V.week + 2, company: companyName};
						break;
					case "slave":
						r.push(`You tell ${him} your target and he nods. "A great idea. It should take no longer than a few weeks."`);
						V.illegalDeals.slave = {week: V.week + 1, type: argument, company: companyName};
						break;
					case "drug":
						r.push("The drug will be delivered within the week.");
						cashX(-100000, "event");
						V.illegalDeals.menialDrug = 1;
						break;
					case "military":
						r.push("You order your mercenaries to prepare and a few days later they depart, leaving enough men behind to keep your arcology secure. You'll keep in contact with the mercenary captain, but you don't expect to hear any real results in the next few months; military operations of this size simply take time.");
						V.illegalDeals.military = {week: V.week + 16, company: companyName};
						break;
				}
				const fragment = document.createDocumentFragment();
				App.Events.addParagraph(fragment, r);
				continueButton(fragment);
				return fragment;
			};
		}

		function refused() {
			// TODO: flavor text
			return endEvent();
		}

		/* End event functions */

		function endEvent() {
			Engine.play(V.nextLink);
			return [];
		}

		function continueButton(fragment) {
			fragment.append(App.UI.DOM.passageLink("Continue", V.nextLink));
			V.nextButton = "Continue";
			App.Utils.scheduleSidebarRefresh();
		}
	}
};

App.Events.MurderAttemptFollowup = class MurderAttemptFollowup extends App.Events.BaseEvent {
	constructor(actors, params) {
		super(actors, params);
	}

	eventPrerequisites() {
		return [
			() => V.plot === 1,
			() => this.trySetup()
		];
	}

	trySetup() {
		const effectiveWeek = App.Events.effectiveWeek();
		if (V.illegalDeals.slave !== 0 && V.illegalDeals.slave !== -1 && effectiveWeek >= V.illegalDeals.slave.week) {
			this.params.variation = "slave";
			this.params.company = V.illegalDeals.slave.company;
			this.params.slaveType = V.illegalDeals.slave.type;
			return true;
		} else if (V.illegalDeals.trade !== 0 && V.illegalDeals.trade !== -1 && effectiveWeek >= V.illegalDeals.trade.week) {
			this.params.variation = "trade";
			this.params.company = V.illegalDeals.trade.company;
			return true;
		} else if (V.illegalDeals.military !== 0 && V.illegalDeals.military !== -1 && effectiveWeek >= V.illegalDeals.military.week) {
			this.params.variation = "military";
			this.params.company = V.illegalDeals.military.company;
			return true;
		}
		return false;
	}

	execute(node) {
		const that = this;
		switch (this.params.variation) {
			case "trade":
				App.Events.addParagraph(node, tradeDeal());
				break;
			case "slave":
				App.Events.addParagraph(node, slaveDeal(this.params.slaveType));
				break;
			case "military":
				App.Events.addParagraph(node, militaryDeal());
				break;
		}

		function tradeDeal() {
			V.illegalDeals.trade = -1;
			let r = [];
			r.push(`Today you are receiving the delegation from the old world company wanting to buy into the lucrative Free Cities market. After showing them around your logistic centers and the cleaner industry areas, you leave them alone with the representatives from ${that.params.company}.`);
			const failChance = 20 - (V.PC.skill.trading / 10);
			if (random(1, 100) > failChance) {
				r.push(`The next day you receive a transaction of ${cashFormatColor(270000)}.`);
				cashX(270000, "event");
			} else {
				r.push("A few hours later you receive a message that tricking the old world company into giving them money for nothing didn't quite work out as hoped. And truly, the next day your uncompetitive behavior is all over the media. This inflicts <span class='reputation dec'>lasting harm on your reputation</span> and <span class='red'>severely damages your economy</span> as your arcology is now seen as a place to go to be cheated.");
				repX(-20000, "event");
				V.enduringRep *= 0.5;
				V.arcologies[0].prosperity *= 0.7;
			}
			return r;
		}

		function slaveDeal(type) {
			V.illegalDeals.slave = -1;
			let slave;
			let relation;
			let contractCost;
			if (type === "school") {
				/** @type {FC.Zeroable<string>} */
				let race = 0;
				// Normally schoolmate race would be based on the shared nationality, if that is not possible because PC
				// is "Stateless" let them share race as well. But not if player chose "catgirl" as race since that
				// shouldn't be available outside the mod.
				if (V.PC.nationality === "Stateless" &&
					V.PC.race !== "catgirl") {
					race = V.PC.race;
				}
				slave = GenerateNewSlave(null, {
					minAge: V.PC.actualAge - 1,
					maxAge: V.PC.actualAge + 1,
					mature: 0,
					ageOverridesPedoMode: 1,
					nationality: V.PC.nationality,
					race: race
				});
				slave.origin = "You were in the same class and seeing $him as your slave fills you with endless satisfaction.";
				slave.behavioralFlaw = "arrogant";
				relation = "your former schoolmate";
				contractCost = 50000;
			} else if (type === "star") {
				slave = GenerateNewSlave('XX');
				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
				slave.intelligence = Math.abs(slave.intelligence); // never dumb, but no guarantee on smart
				slave.weight = Math.clamp(slave.weight, -30, 30);
				slave.waist = Math.clamp(slave.waist, -50, 10);
				slave.career = "an actress";
				slave.prestige = 2;
				slave.prestigeDesc = "$He was once a rising star in the music business, but was illegally enslaved on your command.";
				relation = "the former rising star";
				contractCost = 250000;
			}
			let r = [];
			r.push(`Today ${relation}, whose enslavement you purchased, arrives at your penthouse complete with forged documents and no connections to their past life. You promptly send the agreed-upon ${cashFormat(contractCost)} to the specialist slave company.`);
			cashX(forceNeg(contractCost), "slaveTransfer", slave);
			r.push(App.UI.newSlaveIntro(slave));
			return r;
		}

		function militaryDeal() {
			V.illegalDeals.military = -1;
			let r = [];
			const failChance = 10 - (V.PC.skill.warfare / 20);
			if (random(1, 100) > failChance) {
				r.push(`After several months of fighting, the new Free City in the old world is finally established. While small scale conflicts will likely continue for years to come, local forces can easily manage them, leaving external forces, like your own mercenaries, to withdraw with their spoils. For your participation you get ${cashFormatColor(1000000)} and several hundred new bodies to add to your menial stock.`);
				cashX(1000000, "event");
				V.menials += 500;
			} else {
				r.push(`The coalition of forces you'd joined to establish a new Free City in the old world admitted defeat this week. The target nation-state's military proved to be less decrepit than your allies assumed, and they've fended off the Free Cities' mercenary forces for now. Of course your allies all blame each other for mismanaging the coalition's resources, a debate you have no interest and no stakes in. In the end, this war proved to be a waste of your time. Luckily you didn't invest too much in the war effort, so it only cost you ${cashFormatColor(40000, true)} and some <span class='reputation dec'>reputation.</span>`);
				cashX(-40000, "event");
				repX(forceNeg(V.rep / 8), "event");
			}
			return r;
		}
	}
};


code:
App.Events.SENewBaron = class SENewBaron extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => App.Events.effectiveWeek() >= 40,
			() => V.arcologies[0].prosperity > 80,
			() => V.arcologies[0].FSNeoImperialistLaw2 === 1,
			() => V.newBaron !== 1,
			() => App.Events.effectiveWeek() >= V.imperialEventWeek + 3
		];
	}

	execute(node) {
		V.newBaron = 1;
		V.imperialEventWeek = App.Events.effectiveWeek();

		App.Events.addParagraph(node, [`${V.arcologies[0].name} is prospering. New citizens flood to your gates, filling out the marketplaces and houses with new goods, slaves, and desires. Although every new citizen and visitor on the bustling trams lines more money into your pocket, it also comes with the challenge of new bureaucracy. The original group of Barons you appointed to micromanage each district has been valiantly struggling to manage increasingly larger clusters of people, but it has become quite clear, even if the Barons refuse to admit it, that a new addition to their hallowed ranks is needed to manage your ever-expanding arcology.`]);

		App.Events.addParagraph(node, [`The appointment of a new Baron is not something to be taken lightly; it is undoubtedly the most desired title in your arcology, and a veritable horde of citizens and millionaires hound your inbox and parties with hints and implications, subtly attempting to display their qualifications, because the Barons possess something even the wealthiest trillionaire in the Free Cities does not – security. The golden band of office of an Imperial Baron brings with it a penthouse, a sense of nobility, and a guaranteed sector of people to rule; so long as the arcology continues to exist, the Barons will rule in your name, free from worries about petty market fluctuations and slave prices. Short of your personal intervention or the total collapse of the arcology, nothing can unseat a Baron once they're appointed.`]);

		App.Events.addParagraph(node, [`The hunger for such security among your upper class leaves you in an interesting position. You have dozens of citizens that you could give the title to, with various skills and proficiencies from your diverse arcology, and anyone who's handed a noble title will be certain to show their gratitude. The only real question on your mind – and on the minds of the waiting elites – is who you plan to promote.`]);

		const choices = [];
		choices.push(new App.Events.Result(`Appoint a wealthy executive`, executive));
		choices.push(new App.Events.Result(`Appoint a competent bureaucrat`, bureaucrat));
		choices.push(new App.Events.Result(`Appoint a veteran Knight`, veteran));
		App.Events.addResponses(node, choices);

		function executive() {
			cashX(5000, "event");
			V.arcologies[0].prosperity -= 1;
			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 next day, the newly-appointed Baron sends you a platter of expensive gifts and foreign candies, complimented with a massive direct deposit to your bank account. You can't help but feel that such a crafty fox might use his new power to corner the market in his barony, though.`;
		}

		function bureaucrat() {
			V.arcologies[0].prosperity += 3;
			return `You select an unimportant but accomplished bureaucrat within the lower ranks of your administration, one of the cornerstone accountants that keeps the trains running on time. The rail-thin woman is clearly surprised that you'd choose her over a wealthier, more influential elite, but nevertheless accepts the golden band with overflowing joy. Although she may not turn any eyebrows, you can tell without a fact that she'll keep your arcology efficient and prosperous – after all, if it collapses, then her 'guaranteed' barony vanishes too.`;
		}

		function veteran() {
			repX(+2500, "event");
			V.arcologies[0].prosperity += 1;
			return `You select one of your Imperial Knights, a heavily scarred and muscular man who bears his rose-and-hawk coat of arms like a purple heart on his broad chest. The grizzled soldier is somewhat taken aback at your decision, but regains his composure almost immediately and accepts the golden band of a Baron with a scarred-over smirk. The ex-Knight takes to his new duty with surprising gusto, and quickly proves himself an extraordinarily popular figure among the commoners, who see the scarred and athletic figure both as proof that duty is rewarded in your arcology and as an example of what a proper Imperial noble should be – martial, confident, and nearly unbeatable in a duel.`;
		}
	}
};


code:
App.Events.SEPitFight = class SEPitFight extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => !!V.pit,
			() => V.pit.active,
			() => !V.pit.fought,
		];
	}

	/** @param {DocumentFragment} node */
	execute(node) {
		V.pit.fought = true;
		V.nextButton = " ";

		node.append(intro());

		const maxFights = 3 + (V.pit.fightsBase * 2);
		let completedFights = 0;
		let totalSuccess = 0;
		let lethalFights = 0;

		const fighterMap = new App.Facilities.Pit.Fights.FighterMap();

		const interactionSpan = document.createElement("span");
		interactionSpan.append(selectFight());
		node.append(interactionSpan);

		function selectFight() {
			const f = new DocumentFragment();

			App.Events.addParagraph(f, [`Select a fight. You have ${maxFights - completedFights} left.`]);

			const availableFights = App.Facilities.Pit.getFights()
				.filter(f => f.fightPrerequisites().every(p => p()) && f.castActors());

			const choices = [];
			for (const fight of availableFights) {
				App.UI.DOM.appendNewElement("div", f, fight.fightDescription());
				const div = document.createElement("div");
				div.classList.add("indent");
				div.append(App.UI.DOM.link("Fight!", () => runFight(fight)));
				div.append(" Impact: ", expectedImpact(fight.impact), " ");
				if (fight.lethal) {
					App.UI.DOM.appendNewElement("span", div, "Lethal", "warning");
				} else {
					App.UI.DOM.appendNewElement("span", div, "Safe", "green");
				}
				for (const si of fight.actors) {
					const count = fighterMap.fightCount(si);
					if (count > 0) {
						div.append(" ");
						const span = document.createElement("span");
						span.classList.add("orange");

						span.append(getSlave(si).slaveName, " already fought ");
						if (count > 1) {
							span.append(count + " times today.");
						} else {
							span.append("once today.");
						}

						div.append(span);
					}
				}
				f.append(div);
			}
			if (availableFights.length === 0) {
				App.UI.DOM.appendNewElement("div", f, "No fights available");
			}
			App.UI.DOM.appendNewElement("div", f, App.UI.DOM.link("Select different fighters", () => refreshInteractionSpan(selectFight())));
			App.UI.DOM.appendNewElement("div", f, App.UI.DOM.link("Head back to the penthouse and cancel all the remaining fights", () => refreshInteractionSpan(finishEvent())));
			App.Events.addResponses(f, choices);

			return f;
		}

		/**
		 * @param {DocumentFragment|HTMLElement} content
		 */
		function refreshInteractionSpan(content) {
			$(interactionSpan).empty().append(content);
		}

		/**
		 * @param {number} impact
		 * @returns {string}
		 */
		function expectedImpact(impact) {
			if (impact === 0) {
				return "None";
			} else if (impact < 0.8) {
				return "Small";
			} else if (impact < 1.5) {
				return "Average";
			} else if (impact < 8) {
				return "High";
			} else {
				return "Very High";
			}
		}

		/**
		 * @param {App.Facilities.Pit.Fights.BaseFight} fight
		 */
		function runFight(fight) {
			const f = new DocumentFragment();
			App.UI.DOM.appendNewElement("span", f, `The ${ordinalSuffixWords(completedFights + 1)} fight this day:`, "bold");
			const success = fight.execute(f, fighterMap);
			for (const si of fight.actors) {
				fighterMap.addFight(si);
			}
			const impact = success * fight.impact;
			const p = document.createElement("p");
			p.append(fightSuccess(success), " ", fightImpact(impact));
			f.append(p);
			totalSuccess += impact;
			completedFights++;
			if (fight.lethal) {
				lethalFights++;
			}

			if (completedFights < maxFights) {
				f.append(selectFight());
			} else {
				f.append(finishEvent());
			}

			// automatically scroll to the top of the fight.
			setTimeout(() => window.scrollTo(0, 0), 0);

			refreshInteractionSpan(f);
		}

		/**
		 * @param {number} success
		 * @returns {DocumentFragment}
		 */
		function fightSuccess(success) {
			const f = new DocumentFragment();

			if (success < 0) {
				f.append("The fight was an embarrassment.");
			} else if (success === 0) {
				f.append("The fight had no success.");
			} else if (success < 0.2) {
				f.append("The fight had little success.");
			} else if (success < 0.8) {
				f.append("The fight had normal success.");
			} else if (success <= 1) {
				f.append("The fight had good success.");
			} else {
				f.append("The fight had unexpectedly high success.");
			}

			return f;
		}

		/**
		 * @param {number} impact
		 * @returns {DocumentFragment}
		 */
		function fightImpact(impact) {
			const f = new DocumentFragment();

			impact = Math.abs(impact);

			if (impact === 0) {
				f.append("The fight had no impact on the total event.");
			} else if (impact < 0.2) {
				f.append("The fight had little impact on the total event.");
			} else if (impact < 0.8) {
				f.append("The fight had normal impact on the total event.");
			} else if (impact < 2) {
				f.append("The fight had high impact on the total event.");
			} else {
				f.append("The fight had extreme impact on the total event.");
			}

			return f;
		}

		/**
		 * @param {number} success
		 * @returns {string}
		 */
		function eventSuccess(success) {
			if (success < 0) {
				return "The event was an embarrassment.";
			} else if (success === 0) {
				return "The event had no success.";
			} else if (success < 0.2) {
				return "The event had little success.";
			} else if (success < 0.8) {
				return "The event had normal success.";
			} else if (success < 1.1) {
				return "The event had high success.";
			} else {
				return "The event had extremely high success.";
			}
		}

		function intro() {
			let r = [];
			if (V.pit.audience === "none") {
				r.push(`You are alone above the pit, left to watch them square off in private.`);
				return r[0];
			} else if (V.pit.audience === "free") {
				r.push(`Your guests line the rim of the pit, joking and betting.`);
			} else {
				r.push(`The attendees line the rim of the pit, betting and arguing.`);
			}

			if (V.pit.lethal === 1) {
				r.push("They expect to see a mix of lethal and nonlethal fights.");
			}

			if (FutureSocieties.isActive('FSRomanRevivalist')) {
				r.push(`They `, App.UI.DOM.makeElement("span", 'strongly approve', ["reputation",
					"inc"]), ` of your hosting combat between slaves; this advances ideas from antiquity about what public events should be.`);

				repX(10 * V.FSSingleSlaveRep * (V.arcologies[0].FSRomanRevivalist / V.FSLockinLevel), "pit");
				V.arcologies[0].FSRomanRevivalist += (0.2 * V.FSSingleSlaveRep);
			}

			if (V.pit.minimumHealth) {
				if (FutureSocieties.isActive('FSPaternalist')) {
					r.push(`They `, App.UI.DOM.makeElement("span", 'strongly approve', ["reputation",
						"inc"]), ` of restricting fights to healthy slaves; this advances ideas about slave well-being.`);

					repX(10 * V.FSSingleSlaveRep * (V.arcologies[0].FSPaternalist / V.FSLockinLevel), "pit");
					V.arcologies[0].FSPaternalist += (0.2 * V.FSSingleSlaveRep);
				} else if (FutureSocieties.isActive('FSDegradationist')) {
					r.push(`They `, App.UI.DOM.makeElement("span", 'strongly disapprove', ["reputation",
						"dec"]), ` of restricting fights to healthy slaves; this hampers ideas about slave degradation.`);

					repX(-10 * V.FSSingleSlaveRep * (V.arcologies[0].FSDegradationist / V.FSLockinLevel), "pit");
					V.arcologies[0].FSDegradationist -= (0.2 * V.FSSingleSlaveRep);
				}
			} else {
				if (FutureSocieties.isActive('FSPaternalist')) {
					r.push(`They `, App.UI.DOM.makeElement("span", 'strongly disapprove', ["reputation",
						"dec"]), ` of allowing ill slaves to fight; this hampers ideas about slave well-being.`);

					repX(-10 * V.FSSingleSlaveRep * (V.arcologies[0].FSPaternalist / V.FSLockinLevel), "pit");
					V.arcologies[0].FSPaternalist -= (0.2 * V.FSSingleSlaveRep);
				} else if (FutureSocieties.isActive('FSDegradationist')) {
					r.push(`They `, App.UI.DOM.makeElement("span", 'strongly approve', ["reputation",
						"inc"]), ` of allowing ill slaves to fight; this advances ideas about slave degradation.`);

					repX(10 * V.FSSingleSlaveRep * (V.arcologies[0].FSDegradationist / V.FSLockinLevel), "pit");
					V.arcologies[0].FSDegradationist += (0.2 * V.FSSingleSlaveRep);
				}
			}

			const f = new DocumentFragment();
			App.Events.addParagraph(f, r);
			return f;
		}

		function finishEvent() {
			V.nextButton = "Continue";
			App.Utils.scheduleSidebarRefresh();

			if (V.pit.audience === "none") {
				return new DocumentFragment();
			}

			const r = [];
			if (completedFights === 0) {
				r.push("Opening the arena without hosting fights hurt your reputation.");
				repX(-100 * maxFights, "pit");
				const f = new DocumentFragment();
				App.Events.addParagraph(f, r);
				return f;
			}

			if (completedFights < maxFights) {
				r.push("The audience is disappointed in the few fights this week.");
				totalSuccess -= (maxFights - completedFights) * 0.2;
			}

			if (V.pit.lethal === 1) {
				if (lethalFights === 0) {
					r.push("The audience expected to see blood and did not get any.");
					totalSuccess -= 0.1 * Math.abs(totalSuccess);
				} else if (lethalFights === completedFights) {
					r.push("The audience only saw blood today and is missing some other outcomes.");
					totalSuccess -= 0.1 * Math.abs(totalSuccess);
				}
			}

			const fighterRatio = fighterMap.fighterCount() / fighterMap.fightsCount();
			if (fighterRatio > 0.95) {
				r.push("The audience is happy seeing a lot of different fighters.");
				totalSuccess *= 1.1;
			} else if (fighterRatio > 0.8) {
				// no reaction
			} else {
				if (fighterRatio > 0.5) {
					r.push("The audience is unhappy seeing a lot the same fighters.");
				} else {
					r.push("Almost every fight had repeat fighters, boring the audience.");
				}
				totalSuccess *= 0.5 + 0.5 * (fighterRatio + 0.1);
			}

			totalSuccess *= 0.5 + 0.5 * V.pit.seats;
			if (V.pit.seats === 0) {
				r.push("The small visitors section limited the impact today's fights had.");
			} else if (V.pit.seats === 2) {
				r.push("The large visitors section greatly enhanced the impact today's fights had.");
			}

			const averageSuccess = totalSuccess / maxFights;
			r.push(eventSuccess(averageSuccess));

			r.push("At the end of the day you");

			const repGain = 100 * totalSuccess;
			const cashGain = 2000 * totalSuccess;
			const direction = totalSuccess > 0 ? "gained" : "lost";
			const cssDir = totalSuccess > 0 ? "inc" : "dec";
			if (V.pit.audience === "free") {
				r.push(`<span class='reputation ${cssDir}'>${direction} reputation.</span>`);
				repX(repGain, "pit");
			} else if (V.pit.audience === "paid") {
				r.push(`<span class='cash ${cssDir}'>${direction} credits.</span>`);
				cashX(cashGain, "pit");
			}

			console.log("PIT:");
			console.log("fighter count:", fighterMap.fighterCount(), "fight count:", fighterMap.fightsCount(), "ratio:", fighterRatio);
			console.log("total success:", totalSuccess, "avg:", averageSuccess);
			console.log("possible rep gain: ", repGain);
			console.log("possible cash gain:", cashGain);

			const f = new DocumentFragment();
			App.Events.addParagraph(f, r);
			return f;
		}
	}
};


code:
App.Events.SEPoorKnight = class SEPoorKnight extends App.Events.BaseEvent {
	eventPrerequisites() {
		return [
			() => App.Events.effectiveWeek() >= 37,
			() => V.arcologies[0].FSNeoImperialistLaw1 === 1,
			() => V.arcologies[0].FSNeoImperialistLaw2 === 1,
			() => V.poorKnight !== 1,
			() => App.Events.effectiveWeek() >= V.imperialEventWeek + 3,
		];
	}

	execute(node) {
		V.poorKnight = 1;
		V.imperialEventWeek = App.Events.effectiveWeek();

		App.Events.addParagraph(node, [`Word reaches your ears through the idle gossip of your well-to-do Barons of a particular citizen whose name has been on everyone's lips the last few days. During the visit of a wealthy trader from a neighboring arcology, the merchant, supposedly at the prompting of one particularly pompous Knight of yours who referred to the peasantry as "little more than mindless toys", had his guards beat some of your lower-class citizens for amusement, molesting a young girl and treating them generally as slaves.`]);

		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.`]);

		const festiveCost = 5000;
		const quietCost = 500;
		const choices = [];
		if (V.cash >= festiveCost) {
			choices.push(new App.Events.Result(`Knight him in a grand festival`, festival, `Costs ${cashFormat(festiveCost)}.`));
		} else {
			choices.push(new App.Events.Result(null, null, `Cannot afford a grand festival.`));
		}
		if (V.cash >= quietCost) {
			choices.push(new App.Events.Result(`Knight him in a quiet ceremony`, quiet, `Costs ${cashFormat(quietCost)}.`));
		} else {
			choices.push(new App.Events.Result(null, null, `Cannot afford even a quiet ceremony. Maybe, uh, Valentin could spot you a few ¤?`));
		}
		choices.push(new App.Events.Result(`Have him flogged for attacking your honored guests`, floggingMeat));
		App.Events.addResponses(node, choices);

		function festival() {
			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, cheering your name 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 never return to your arcology, and the Barons grumble about the wildly dancing and celebrating peasants undermining your authority.`;
		}

		function quiet() {
			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 celebrate 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 hike his prices for you.`;
		}

		function floggingMeat() {
			repX(-2000, "event");
			V.arcologies[0].prosperity += 1;
			return `You have the uppity peasant flogged for a few hours in the marketplace where he beat the merchant's guards. He accepts the punishment quietly and without any protest, submitting his muscled back to the bite of the lash as your Barons nod their head in agreement with your decision. The watching peasants are utterly horrified at your treatment of one of their heroes, but a day later you receive a message from the pleased merchant saying that he'll be sure to give you a steep discount the next time he visits your arcology for 'putting that uppity vermin in its place - beneath us.'`;
		}
	}
};