code:
// Scheduled/nonrandom events are run sequentially, in order.
// They should always return to Nonrandom Event to ensure that none are skipped.

/** get a list of possible scheduled events
 * @returns {Array<App.Events.BaseEvent>}
 */
App.Events.getNonrandomEvents = function() {
	return [
		// instantiate all possible scheduled/nonrandom events here
		// ORDER MATTERS - if multiple events from this list trigger in a single week, they are executed in this order

		new App.Events.pLoanshark(),
		new App.Events.conflictOptions(),
		new App.Events.SEPlayerBirth(),
		new App.Events.SEpcBirthday(),
		new App.Events.SEIndependenceDay(),
		new App.Events.SEWedding(),
		new App.Events.PInsemination(),
		new App.Events.SERetire(),
		new App.Events.SEExpiration(),
		new App.Events.SEBurst(),
		new App.Events.SEDeath(),
		new App.Events.SEBirth(),
		new App.Events.SEfctvWatch(),
		new App.Events.SEfctvRemote(),
		new App.Events.TimeGatedPlotEvent(),
		new App.Events.assistantAwakens(),
		new App.Events.assistantSP(),
		new App.Events.assistantFS(),
		new App.Events.assistantName(),
		new App.Events.assistantMarket(),
		new App.Events.assistantBody(),
		new App.Events.pBadCuratives(),
		new App.Events.pBadBreasts(),
		new App.Events.pAidInvitation(),
		new App.Events.SERecruiterSuccess(),
		new App.Events.SEcustomSlaveDelivery(),
		new App.Events.JobFulfillmentCenterDelivery(),
		new App.Events.SEHuskSlaveDelivery(),
		new App.Events.SECoursing(),
		new App.Events.SERaiding(),
		new App.Events.SEPitFight(),
		new App.Events.PBioreactorPerfected(),
		new App.Events.RESFailure(),
		new App.Events.TFSFarmUpgrade(),
		new App.Events.SENicaeaAnnouncement(),
		new App.Events.SENicaeaPreparation(),
		new App.Events.SENicaeaCouncil(),
		new App.Events.MurderAttempt(),
		new App.Events.MurderAttemptFollowup(),
		new App.Events.pRaped(),
		new App.Events.pAbducted(),
		new App.Events.pFoodCrisisLowerClass(),
		new App.Events.PSchoolSuggestion(),

		// secExp
		new App.Events.secExpSmilingMan0(),

		new App.Events.PMercsHelpCorp(),
		new App.Events.PMercenaryRomeo(),

		new App.Events.SecurityForceProposal(),

		// Peacekeepers
		new App.Events.PPeacekeepersIndependence(),
		new App.Events.PPeacekeepersInfluence(),
		new App.Events.PPeacekeepersIntro(),

		// Cats
		new App.Events.SEVatCatGirl(),
		new App.Events.SEVatCatBoy(),
		new App.Events.SEBodyPuristProtest(),
		new App.Events.SEBodyPuristRiot(),
		new App.Events.SEProjectNblowingthelid(),
		new App.Events.SEProjectNbubbles(),
		new App.Events.SEProjectNComplete(),
		new App.Events.SEProjectNInitialized(),
		new App.Events.SEProjectNMoMoney(),
		new App.Events.SEProjectNSaboteur(),
		new App.Events.SEProjectNTechRelease(),

		// Elite
		new App.Events.eliteTakeOver(),

		new App.Events.SEAssholeKnight(),
		new App.Events.SENewBaron(),
		new App.Events.SEPoorKnight(),
		new App.Events.SEFcnnStation(),
		new App.Events.SEFctvInstall(),
		new App.Events.PFSAnnouncement(),
		new App.Events.PBodyswapReveal(),
		new App.Events.PCorpAnnouncement(),

		// rivalry events
		new App.Events.PRivalInitiation(),
		new App.Events.PRivalryDispatch(),
		new App.Events.pHostageAcquisition()
	];
};

/** get the next nonrandom event which should fire
 * @returns {App.Events.BaseEvent}
 */
App.Events.getNextNonrandomEvent = function() {
	return App.Events.getNonrandomEvents()
		.find(e => App.Events.canExecute(e));
};

/** get all the nonrandom events which should fire this week
 * @returns {Array<App.Events.BaseEvent>}
 */
App.Events.getWeekNonrandomEvents = function() {
	return App.Events.getNonrandomEvents()
		.filter(e => App.Events.canExecute(e));
};

/** get the next queued event which should fire, and remove it from the queue
 * @returns {App.Events.BaseEvent}
 */
App.Events.dequeueNextQueuedEvent = function() {
	const event = (V.eventQueue[0] || [])
		.find(e => App.Events.canExecute(e));
	if (event) {
		V.eventQueue[0].delete(event);
	}
	return event;
};

/** get all the queued events which should fire this week
 * @returns {Array<App.Events.BaseEvent>}
 */
App.Events.getWeekQueuedEvents = function() {
	return (V.eventQueue[0] || [])
		.filter(e => App.Events.canExecute(e));
};

App.Events.playNonrandomEvent = function() {
	const d = document.createElement("div");
	V.nextLink = passage();
	V.nextButton = "Continue";

	if (V.event instanceof App.Events.BaseEvent) {
		// we've deserialized a saved game with an event active, or a player has picked one, so just play it immediately
		App.Events.runPassageEvent(V.event, d);
	} else {
		if (V.debugMode > 0 && V.debugModeEventSelection > 0) {
			V.nextButton = "Refresh";
			// show all the scheduled, nonrandom, and queued events, and allow the player to play them in any order and skip the remainder
			App.UI.DOM.appendNewElement("h2", d, "Scheduled and Nonrandom Events");
			App.UI.DOM.appendNewElement("div", d, "These scheduled and nonrandom events still need to play this week, in this order.");
			App.UI.DOM.appendNewElement("div", d, "WARNING: playing certain scheduled events out of order, or skipping them, can break your game! Be careful!", ["note", "warning"]);
			const events = App.Events.getWeekNonrandomEvents();
			const linkList = App.UI.DOM.appendNewElement("div", d, '', "event-section");
			for (const event of events) {
				App.UI.DOM.appendNewElement("div", linkList, App.UI.DOM.passageLink(event.eventName, passage(), () => { V.event = event; }));
			}
			const queuedEvents = App.Events.getWeekQueuedEvents();
			for (const event of queuedEvents) {
				App.UI.DOM.appendNewElement("div", linkList, App.UI.DOM.passageLink(event.eventName, passage(), () => { V.event = event; V.eventQueue[0].delete(event); }));
			}
			if (events.length + queuedEvents.length > 0) {
				App.UI.DOM.appendNewElement("div", d, App.UI.DOM.passageLink("SKIP remaining events and proceed", "Random Nonindividual Event"));
			} else {
				App.UI.DOM.appendNewElement("div", d, App.UI.DOM.passageLink("No more events. Proceed.", "Random Nonindividual Event"));
			}
			d.append(App.Events.renderEventDebugger("Scheduled Event"));
		} else {
			// pick the next scheduled or nonrandom event, if there is one
			const event = App.Events.getNextNonrandomEvent();
			if (event) {
				// record the chosen event in 'current' (pre-play!) history as well as current state so that it will serialize out correctly if saved from this passage
				// WARNING: THIS IS ***NOT*** THE ACTIVE STATE PAGE!
				// @ts-ignore - under-defined object
				State.current.variables.event = V.event = event;
				App.Events.runPassageEvent(event, d);
			} else {
				// play the next queued event, if there is one
				const qEvent = App.Events.dequeueNextQueuedEvent();
				if (qEvent) {
					// we don't need to alter history when playing queued events, because the event instance is deterministically at the head of the queue already
					App.Events.runPassageEvent(qEvent, d);
				} else {
					// no more events for this week, move on to random events
					const plotDiscount = V.plot ? 0 : 25; // if plot is enabled, somewhat fewer nonindividual events appear in the first 75 weeks
					if (random(1, 200) > V.week + 125 + plotDiscount) {
						// skip nonindividual event, go straight to individual event
						// week 0: 50% chance to skip with plot disabled, 62.5% with plot enabled.
						// reaches 0% chance at week 50 with plot disabled, or week 75 with plot enabled.
						setTimeout(() => Engine.play("Random Individual Event"), Engine.minDomActionDelay);
					} else {
						setTimeout(() => Engine.play("Random Nonindividual Event"), Engine.minDomActionDelay);
					}
				}
			}
		}
	}
	return d;
};


code:
/* Note that we use a much more strict delineation between individual and nonindividual events here than in the old event system.
 * Individual events always trigger for the chosen event slave, and the first actor is always the event slave.
 * Nonindividual events are not provided any event slave and should cast one themselves.
 */

/** get a list of possible individual events
 * @returns {Array<App.Events.BaseEvent>}
 */
App.Events.getIndividualEvents = function() {
	return [
		// instantiate all possible random individual events here
		// example: new App.Events.TestEvent(),
		new App.Events.RESSAgeDifferenceOldPC(),
		new App.Events.RESSAgeDifferenceYoungPC(),
		new App.Events.RESSAgeImplant(),
		new App.Events.RESSAGift(),
		new App.Events.RESSAmpDevoted(),
		new App.Events.RESSAmpResting(),
		new App.Events.RESSAraAra(),
		new App.Events.RESSArcadeSadist(),
		new App.Events.RESSAssFitting(),
		new App.Events.RESSBackStretch(),
		new App.Events.RESSBadDream(),
		new App.Events.RESSBedSnuggle(),
		new App.Events.RESSBirthday(),
		new App.Events.RESSBirthdaySex(),
		new App.Events.RESSBondageGear(),
		new App.Events.RESSBondedLove(),
		new App.Events.RESSBreastExpansionBlues(),
		new App.Events.RESSBreedingBull(),
		new App.Events.RESSCageRelief(),
		new App.Events.RESSCockFeederResistance(),
		new App.Events.RESSComfortableSeat(),
		new App.Events.RESSConfidentTanning(),
		new App.Events.RESSCoolerLockin(),
		new App.Events.RESSCowMilking(),
		new App.Events.RESSCumslutWhore(),
		new App.Events.RESSDesperatelyHorny(),
		new App.Events.RESSDesperateNull(),
		new App.Events.RESSDevotedAnalVirgin(),
		new App.Events.RESSDevotedEducated(),
		new App.Events.RESSDevotedExhibition(),
		new App.Events.RESSDevotedFearfulSlave(),
		new App.Events.RESSDevotedLotion(),
		new App.Events.RESSDevotedNympho(),
		new App.Events.RESSDevotedOld(),
		new App.Events.RESSDevotedShortstack(),
		new App.Events.RESSDevotedVirgin(),
		new App.Events.RESSDevotedWaist(),
		new App.Events.RESSDickgirlPC(),
		new App.Events.RESSDickWringing(),
		new App.Events.RESSDiet(),
		new App.Events.RESSEliteBreederPlease(),
		new App.Events.RESSEscapee(),
		new App.Events.RESSExtremeAphrodisiacs(),
		new App.Events.RESSFearfulBalls(),
		new App.Events.RESSFearfulHumiliation(),
		new App.Events.RESSFirstPeriod(),
		new App.Events.RESSForbiddenMasturbation(),
		new App.Events.RESSFrighteningDick(),
		new App.Events.RESSFucktoyTribbing(),
		new App.Events.RESSGaggedSlave(),
		new App.Events.RESSGapedAsshole(),
		new App.Events.RESSGorging(),
		new App.Events.RESSHappyDance(),
		new App.Events.RESSHatesOral(),
		new App.Events.RESSHeavyPiercing(),
		new App.Events.RESSHeels(),
		new App.Events.RESSHormoneDysfunction(),
		new App.Events.RESSHotPC(),
		new App.Events.RESSHugelyPregnant(),
		new App.Events.RESSHugeNaturals(),
		new App.Events.RESSHugeTits(),
		new App.Events.RESSHyperpregStuck(),
		new App.Events.RESSIgnorantHorny(),
		new App.Events.RESSImplantInspection(),
		new App.Events.RESSImpregnationPlease(),
		new App.Events.RESSImScared(),
		new App.Events.RESSInconvenientLabia(),
		new App.Events.RESSInjectionsPlease(),
		new App.Events.RESSKitchenMolestation(),
		new App.Events.RESSLanguageLesson(),
		new App.Events.RESSLazyEvening(),
		new App.Events.RESSLikeMe(),
		new App.Events.RESSLooseButtslut(),
		new App.Events.RESSMasterfulEntertainer(),
		new App.Events.RESSMasterfulWhore(),
		new App.Events.RESSMeanGirls(),
		new App.Events.RESSMilkgasm(),
		new App.Events.RESSMillenary(),
		new App.Events.RESSMindbrokenMorning(),
		new App.Events.RESSModestClothes(),
		new App.Events.RESSModsPlease(),
		new App.Events.RESSMoistPussy(),
		new App.Events.RESSMuscles(),
		new App.Events.RESSMutinyAttempt(),
		new App.Events.RESSNewlyDevotedSunrise(),
		new App.Events.RESSNiceGuys(),
		new App.Events.RESSNightVisit(),
		new App.Events.RESSNotMyName(),
		new App.Events.RESSNymphoWithAssistant(),
		new App.Events.RESSObedientAddict(),
		new App.Events.RESSObedientBitchy(),
		new App.Events.RESSObedientGirlish(),
		new App.Events.RESSObedientIdiot(),
		new App.Events.RESSObedientShemale(),
		new App.Events.RESSObjectifyingVisit(),
		new App.Events.RESSOrchiectomyPlease(),
		new App.Events.RESSPAFlirting(),
		new App.Events.RESSPAServant(),
		new App.Events.RESSPassingDeclaration(),
		new App.Events.RESSPenitent(),
		new App.Events.RESSPermittedMasturbation(),
		new App.Events.RESSPlimbHelp(),
		new App.Events.RESSPlugDisobedience(),
		new App.Events.RESSRebelliousArrogant(),
		new App.Events.RESSRefreshmentDelivery(),
		new App.Events.RESSResistantAnalVirgin(),
		new App.Events.RESSResistantGelding(),
		new App.Events.RESSResistantShower(),
		new App.Events.RESSRestrictedProfession(),
		new App.Events.RESSRestrictedSmart(),
		new App.Events.RESSRetchingCum(),
		new App.Events.RESSScrubbing(),
		new App.Events.RESSServantMaid(),
		new App.Events.RESSServeThePublicDevoted(),
		new App.Events.RESSSexySuccubus(),
		new App.Events.RESSShapedAreolae(),
		new App.Events.RESSShiftDoorframe(),
		new App.Events.RESSShiftMasturbation(),
		new App.Events.RESSShiftSleep(),
		new App.Events.RESSShowerSlip(),
		new App.Events.RESSSlaveDickHuge(),
		new App.Events.RESSSlaveOnSlaveClit(),
		new App.Events.RESSSlaveOnSlaveDick(),
		new App.Events.RESSSleepingAmbivalent(),
		new App.Events.RESSSolitaryDesperation(),
		new App.Events.RESSSoreAss(),
		new App.Events.RESSSoreShoulders(),
		new App.Events.RESSSpaBoobs(),
		new App.Events.RESSSubjugationBlues(),
		new App.Events.RESSSuppositoryResistance(),
		new App.Events.RESSSurgeryAddict(),
		new App.Events.RESSSurprisingWakeup(),
		new App.Events.RESSTendonFall(),
		new App.Events.RESSTerrifiedInspection(),
		new App.Events.RESSTittymonsterInspection(),
		new App.Events.RESSTooThinForCumDiet(),
		new App.Events.RESSTorpedoSqueeze(),
		new App.Events.RESSTransitionAnxiety(),
		new App.Events.RESSTrustingHG(),
		new App.Events.RESSUnhappyVirgin(),
		new App.Events.RESSUsedWhore(),
		new App.Events.RESSVocalDisobedience(),
		new App.Events.RESSWaistlineWoes(),
		new App.Events.RESSWetDreams(),
		new App.Events.RESSWhoreRebellious(),

		new App.Events.RECIButthole(),
		new App.Events.RECIFeminization(),
		new App.Events.RECIFuta(),
		new App.Events.RECIMilf(),
		new App.Events.RECIOrientation(),
		new App.Events.RECIUgly(),

		new App.Events.RETSAnalCowgirl(),
		new App.Events.RETSBoobCollision(),
		new App.Events.RETSCockmilkInterception(),
		new App.Events.RETSDatePlease(),
		new App.Events.RETSFucktoyPrefersRelative(),
		new App.Events.RETSIfYouEnjoyIt(),
		new App.Events.RETSIncestuousNursing(),
		new App.Events.RETSInterslaveBegging(),
		new App.Events.RETSAnalRepressedVirgin(),
		new App.Events.RETSSadisticDescription(),
		new App.Events.RETSShowerForce(),
		new App.Events.RETSSiblingTussle(),
		new App.Events.RETSSimpleAssault(),
		new App.Events.RETSTasteTest(),
		new App.Events.RETSTopExhaustion(),

		new App.Events.RENickname().setType("RIE"),

		new App.Events.CMRESSAnnoyingCat(),
		new App.Events.CMRESSLazyCat(),
		new App.Events.CMRESSSpoiledCat(),
		new App.Events.CMRESSCatWorship(),
		new App.Events.CMRESSCatLove(),
		new App.Events.CMRESSCatPresent(),

		new App.Events.rePregInventorInvite(),
		new App.Events.rePregInventorShowOff(),
		new App.Events.rePregInventorFCTV(),

		new App.Events.REStandardPunishment(),
		new App.Events.REAnalPunishment(),
		new App.Events.REShowerPunishment(),
		new App.Events.REHGReplacement(),
		new App.Events.RESnatchAndGrabFollowup(),

		// Relationship Events
		new App.Events.REDevotedMotherDaughter(),
		new App.Events.REResistantMotherDaughter(),
		new App.Events.RESiblingRevenge(),
		new App.Events.RERelationshipAdvice(),
		new App.Events.RESlaveMarriage(),
		new App.Events.RESiblingPlease(),
	];
};

/** get a list of possible nonindividual events
 * Note: recruitment events should NOT be added to this list; they go in getNonindividualRecruitmentEvents instead.
 * @returns {Array<App.Events.BaseEvent>}
 */
App.Events.getNonindividualEvents = function() {
	return [
		// instantiate all possible random nonindividual events here
		// example: new App.Events.TestEvent(),
		new App.Events.PEConcubineInterview(),
		new App.Events.PEUnderageConcubine(),
		new App.Events.PEHeadgirlConcubine(),
		new App.Events.PEPitFightInvite(),
		new App.Events.PECombatTraining(),
		new App.Events.PELonelyBodyguard(),
		new App.Events.PEAssociatesPublicSlut(),
		new App.Events.PEFoodplay(),

		new App.Events.REDevotees(),
		new App.Events.RERelativeRecruiter(),
		new App.Events.REStaffedMorning(),
		new App.Events.REFullBed(),
		new App.Events.REDevotedTwins(),
		new App.Events.RERoyalBlood(),
		new App.Events.REArcologyInspection(),
		new App.Events.REShelterInspection(),

		new App.Events.REFIBoobslut(),
		new App.Events.REFIButtslut(),
		new App.Events.REFICumslut(),
		new App.Events.REFIDominant(),
		new App.Events.REFIHumiliation(),
		new App.Events.REFIMasochist(),
		new App.Events.REFIPregnancy(),
		new App.Events.REFISadist(),
		new App.Events.REFISubmissive(),

		new App.Events.RENickname().setType("RNIE"),

		new App.Events.REMaleCitizenHookup(),
		new App.Events.RECitizenHookup(),
		new App.Events.REMaleArcologyOwner(),
		new App.Events.REBoomerang(),
		new App.Events.REMilfTourist(),
		new App.Events.REAWOL(),
		new App.Events.REPokerNight(),
		new App.Events.TrickShotNight(),
		new App.Events.REShippingContainer(),
		new App.Events.REFemaleArcologyOwner(),
		new App.Events.REBrothelFunction(),
		new App.Events.RERebels(),

		// schools
		new App.Events.RESEndowment(),
		new App.Events.RESMove(),
		new App.Events.RESSale(),

		// legendary
		new App.Events.RELegendaryFormerAbolitionist(),
		new App.Events.RELegendaryCow(),
		new App.Events.RELegendaryBalls(),
		new App.Events.RELegendaryWhore(),
		new App.Events.RELegendaryEntertainer(),
		new App.Events.RELegendaryWomb(),

		new App.Events.REBusyClub(),
		new App.Events.REBusyArcade(),
		new App.Events.REBusyDairy(),
		new App.Events.REBusyBrothel(),
		new App.Events.REBusyServantsQuarters(),
		new App.Events.REBusyMasterSuite(),

		// refs
		new App.Events.refsBaronDemand(),
		new App.Events.refsBodyPurismEncounter(),
		new App.Events.refsDeadBaron(),
		new App.Events.refsDegradationistEncounter(),
		new App.Events.refsFeast(),
		new App.Events.refsKnightlyDuel(),
		new App.Events.refsMaturityPreferentialistEncounter(),
		new App.Events.refsPastoralistEncounter(),
		new App.Events.refsPaternalistEncounter(),
		new App.Events.refsPhysicalIdealistEncounter(),
		new App.Events.refsRomanStoicism(),
		new App.Events.refsTotallyLegitCatgirls(),
		new App.Events.refsTransformationFetishismEncounter(),
		new App.Events.refsWarhound(),
		new App.Events.refsYouthPreferentialistEncounter(),
		new App.Events.REFSNonconformist(),

		// Justice Event
		new App.Events.JESlaveDisputeBreedingDeal(),
		new App.Events.JESlaveDisputeIndentureDeal(),
		new App.Events.JESlaveDisputeMajorityDeal(),
		new App.Events.JESlaveDisputeSlaveDeal(),
		new App.Events.JESlaveDisputeSlaveTraining(),
		new App.Events.JESlaveVirginityDeal(),

		// Random Market Events
		new App.Events.REMFluctuations(),
		new App.Events.REMMerger(),

		// SoS
		new App.Events.RESosSniper(),
		new App.Events.RESosAssassin(),
		new App.Events.RESosBombing(),

		// PETS
		new App.Events.petsAggressiveSchoolteacher(),
		new App.Events.petsAggressiveWardeness(),
		new App.Events.petsComfortingAttendant(),
		new App.Events.petsNurseMolestation(),
		new App.Events.petsStewardessBeating(),

		// PESS
		new App.Events.pessBodyguardBeatdown(),
		new App.Events.pessBodyguardBedtime(),
		new App.Events.pessDjPublicity(),
		new App.Events.pessHeadgirlDickgirl(),
		new App.Events.pessLovingConcubine(),
		new App.Events.pessLovingHeadgirl(),
		new App.Events.pessMadamStrategy(),
		new App.Events.pessTiredCollectrix(),
		new App.Events.pessTiredMilkmaid(),
		new App.Events.pessWorriedHeadgirl(),
		new App.Events.pessWorshipfulImpregnatrix(),
	];
};

/** get a list of possible nonindividual recruitment events
 * The probability of selecting recruitment events is capped, to allow the above events to trigger more frequently
 * @returns {Array<App.Events.BaseEvent>}
 */
App.Events.getNonindividualRecruitmentEvents = function() {
	return [
		new App.Events.RERecruit(),
		new App.Events.REMalefactor(),

		// recFS
		new App.Events.recFSArabianRevivalist(),
		new App.Events.recFSAssetExpansionist(),
		new App.Events.recFSAssetExpansionistTwo(),
		new App.Events.recFSAztecRevivalist(),
		new App.Events.recFSBodyPurist(),
		new App.Events.recFSBodyPuristTwo(),
		new App.Events.recFSChattelReligionist(),
		new App.Events.recFSChattelReligionistTwo(),
		new App.Events.recFSChineseRevivalist(),
		new App.Events.recFSDegradationist(),
		new App.Events.recFSDegradationistTwo(),
		new App.Events.recFSEdoRevivalist(),
		new App.Events.recFSEgyptianRevivalist(),
		new App.Events.recFSGenderFundamentalist(),
		new App.Events.recFSGenderFundamentalistTwo(),
		new App.Events.recFSGenderRadicalist(),
		new App.Events.recFSGenderRadicalistTwo(),
		new App.Events.recFSHedonisticDecadence(),
		new App.Events.recFSHedonisticDecadenceTwo(),
		new App.Events.recFSIntellectualDependency(),
		new App.Events.recFSIntellectualDependencyTwo(),
		new App.Events.recFSMaturityPreferentialist(),
		new App.Events.recFSMaturityPreferentialistTwo(),
		new App.Events.recFSNeoImperialist(),
		new App.Events.recFSPastoralist(),
		new App.Events.recFSPastoralistTwo(),
		new App.Events.recFSPaternalist(),
		new App.Events.recFSPaternalistTwo(),
		new App.Events.recFSPetiteAdmiration(),
		new App.Events.recFSPetiteAdmirationTwo(),
		new App.Events.recFSPhysicalIdealist(),
		new App.Events.recFSPhysicalIdealistTwo(),
		new App.Events.recFSRepopulationEfforts(),
		new App.Events.recFSRepopulationEffortsTwo(),
		new App.Events.recFSRestart(),
		new App.Events.recFSRestartTwo(),
		new App.Events.recFSRomanRevivalist(),
		new App.Events.recFSSlaveProfessionalism(),
		new App.Events.recFSSlaveProfessionalismTwo(),
		new App.Events.recFSSlimnessEnthusiast(),
		new App.Events.recFSSlimnessEnthusiastTwo(),
		new App.Events.recFSStatuesqueGlorification(),
		new App.Events.recFSStatuesqueGlorificationTwo(),
		new App.Events.recFSSubjugationist(),
		new App.Events.recFSSubjugationistTwo(),
		new App.Events.recFSSupremacist(),
		new App.Events.recFSSupremacistTwo(),
		new App.Events.recFSTransformationFetishist(),
		new App.Events.recFSTransformationFetishistTwo(),
		new App.Events.recFSYouthPreferentialist(),
		new App.Events.recFSYouthPreferentialistTwo(),

		// recets
		new App.Events.recetsAddictMotherDaughter(),
		new App.Events.recetsDesperateBroodmother(),
		new App.Events.recetsIdenticalHermPair(),
		new App.Events.recetsIdenticalPair(),
		new App.Events.recetsIncestBrotherBrother(),
		new App.Events.recetsIncestBrotherSister(),
		new App.Events.recetsIncestFatherDaughter(),
		new App.Events.recetsIncestFatherSon(),
		new App.Events.recetsIncestMotherDaughter(),
		new App.Events.recetsIncestMotherSon(),
		new App.Events.recetsIncestSisterSister(),
		new App.Events.recetsIncestTwinBrother(),
		new App.Events.recetsIncestTwinSister(),
		new App.Events.recetsIncestTwinsMixed(),
		new App.Events.recetsMatchedPair(),
		new App.Events.recetsMismatchedPair(),
		new App.Events.recetsPoshMotherDaughter(),
	];
};

/** choose a valid, castable event from the given event list
 * @param {Array<App.Events.BaseEvent>} eventList - list of events to filter
 * @param {App.Entity.SlaveState} [slave] - event slave (mandatory to cast in first actor slot). omit for nonindividual events.
 * @returns {Array<App.Events.BaseEvent>}
 */
App.Events.getValidEvents = function(eventList, slave) {
	return eventList
		.filter(e => App.Events.canExecute(e, slave))
		.reduce((res, cur) => res.concat(Array(cur.weight).fill(cur)), []);
};

App.Events.playRandomIndividualEvent = function() {
	const d = document.createElement("div");

	const makeNoEvent = (/** @type {number} */ id) => {
		const noEvent = new App.Events.RENoEvent();
		noEvent.actors = [id];
		return noEvent;
	};

	if (V.event instanceof App.Events.BaseEvent) {
		// we've deserialized a saved game with an event active, or a player has picked one, so just play it immediately
		App.Events.runPassageEvent(V.event, d);
		V.RIESkip.push(V.event.actors[0]);
	} else {
		const eligibleSlaves = getRieEligibleSlaves();
		if (eligibleSlaves.length === 0) {
			// no eligible slaves, move on to next week
			setTimeout(() => Engine.play("Next Week"), Engine.minDomActionDelay);
		} else if (V.debugMode > 0 && V.debugModeEventSelection > 0) {
			V.nextButton = "Refresh";
			V.nextLink = passage();
			V.RIERemaining++; // we've consumed one of our event possibilities already, but we haven't played the event yet, so put it back

			// show all the possible random individual events
			App.UI.DOM.appendNewElement("h2", d, "Random Individual Events");
			const countPara = App.UI.DOM.appendNewElement("p", d, `At most ${numberWithPluralOne(V.RIEPerWeek, "slave")} will get Random Individual Events per week, and you have ${num(V.RIERemaining)} left.`);
			if (V.RIESkip.length > 0) {
				countPara.append(` An event has already played for ${toSentence(V.RIESkip.map(s => SlaveFullName(getSlave(s))))}, so they are not eligible to play another.`);
			}

			const slaveDiv = App.UI.DOM.appendNewElement("div", d, "Show events for this slave: ");
			const options = [];
			const startingSlave = eligibleSlaves.random();
			for (const s of eligibleSlaves) {
				options.push({key: s.ID.toString(), name: SlaveFullName(s)});
			}
			slaveDiv.append(App.UI.DOM.makeSelect(options, startingSlave.ID.toString(), slaveID => {
				writeEventList(getSlave(parseInt(slaveID)));
			}));

			App.UI.DOM.appendNewElement("p", d, "One of the following individual events would have been chosen for this slave.");

			const linkList = App.UI.DOM.appendNewElement("div", d, '', "event-section");
			const writeEventList = (/** @type {App.Entity.SlaveState} */eventSlave) => {
				$(linkList).empty();
				const events = App.Events.getValidEvents(App.Events.getIndividualEvents(), eventSlave);
				if (events.length === 0) {
					events.push(makeNoEvent(eventSlave.ID));
				}
				for (const event of events) {
					App.UI.DOM.appendNewElement("div", linkList, App.UI.DOM.passageLink(event.eventName, passage(), () => { V.event = event; }));
				}
			};
			writeEventList(startingSlave);

			App.UI.DOM.appendNewElement("div", d, App.UI.DOM.passageLink("Back to Random Nonindividual Event", "Random Nonindividual Event"));
			App.UI.DOM.appendNewElement("div", d, App.UI.DOM.passageLink("Skip week-end events", "Next Week"));
			d.append(App.Events.renderEventDebugger("Random Individual Event"));
		} else {
			// pick a slave for a random individual event
			const eventSlave = eligibleSlaves.random();

			// pick a random individual event for that slave. Use RE No Event if there are none she's eligible for.
			const events = App.Events.getValidEvents(App.Events.getIndividualEvents(), eventSlave);
			const event = events.random() || makeNoEvent(eventSlave.ID);

			// record the chosen event in 'current' (pre-play!) history as well as current state so that it will serialize out correctly if saved from this passage
			// WARNING: THIS IS ***NOT*** THE ACTIVE STATE PAGE!
			// @ts-ignore - under-defined object
			State.current.variables.event = V.event = event;
			App.Events.runPassageEvent(event, d);
			V.RIESkip.push(event.actors[0]);
		}
	}
	return d;
};

App.Events.playRandomNonindividualEvent = function() {
	const d = document.createElement("div");

	if (V.event instanceof App.Events.BaseEvent) {
		// we've deserialized a saved game with an event active, or a player has picked one, so just play it immediately
		App.Events.runPassageEvent(V.event, d);
	} else {
		let nonRecEvents = App.Events.getValidEvents(App.Events.getNonindividualEvents());
		let recEvents = App.Events.getValidEvents(App.Events.getNonindividualRecruitmentEvents());
		if (V.debugMode > 0 && V.debugModeEventSelection > 0) {
			V.nextButton = "Refresh";
			V.nextLink = passage();

			// show all the possible nonindividual random events
			App.UI.DOM.appendNewElement("h2", d, "Random Nonindividual Events");
			App.UI.DOM.appendNewElement("p", d, "One of the following nonindividual events would have been chosen.");
			const linkList = App.UI.DOM.appendNewElement("div", d, '', "event-section");
			for (const event of nonRecEvents.concat(recEvents)) {
				App.UI.DOM.appendNewElement("div", linkList, App.UI.DOM.passageLink(event.eventName, passage(), () => { V.event = event; }));
			}

			App.UI.DOM.appendNewElement("div", d, App.UI.DOM.passageLink("Skip to Random Individual Event", "Random Individual Event"));
			App.UI.DOM.appendNewElement("div", d, App.UI.DOM.passageLink("Skip week-end events", "Next Week"));
			d.append(App.Events.renderEventDebugger("Random Nonindividual Event"));
		} else {
			// pick a random nonindividual event. there should always be at least one.
			const maxRecruitNumber = Math.min(10, Math.floor(nonRecEvents.length/4) + 1);
			if (recEvents.length > maxRecruitNumber) {
				recEvents = recEvents.pluckMany(maxRecruitNumber);
			}
			const event = nonRecEvents.concat(recEvents).random();
			if (event) {
				// record the chosen event in 'current' (pre-play!) history as well as current state so that it will serialize out correctly if saved from this passage
				// WARNING: THIS IS ***NOT*** THE ACTIVE STATE PAGE!
				// @ts-ignore - under-defined object
				State.current.variables.event = V.event = event;
				App.Events.runPassageEvent(event, d);
			} else {
				throw new Error("There should always be at least one eligible nonindividual event.");
			}
		}
	}
	return d;
};

repo_name: Fanatey/fc

license: mit


code:
App.Events.RERecruit = class RERecruit extends App.Events.BaseEvent {
	constructor(actors, params) {
		super(actors, params);
		// we build all the delegate events here
		this.eventList = [
			new App.Events.recBlessedVessel,
			new App.Events.recBlessedVirgin,
			new App.Events.recBlindHomeless,
			new App.Events.recCapturedTeen,
			new App.Events.recCcsAngel,
			new App.Events.recCcsDA,
			new App.Events.recCleaningHouse,
			new App.Events.recDesperateBirth,
			new App.Events.recDesperateMILF,
			new App.Events.recDesperatePreg,
			new App.Events.recDesperateUniversityMILF,
			new App.Events.recDgRunaway,
			new App.Events.recDGSE,
			new App.Events.recEmbryoAppropriation,
			new App.Events.recFarmBull,
			new App.Events.recFarmCow,
			new App.Events.recFarmVirginCow,
			new App.Events.recFemaleDebtor,
			new App.Events.recFemaleRecruit,
			new App.Events.recFemaleRunaway,
			new App.Events.recFemaleSD,
			new App.Events.recFemaleSD2,
			new App.Events.recFemaleSE,
			new App.Events.recForbiddenLove,
			new App.Events.recGangLeader,
			new App.Events.recHandsomePC,
			new App.Events.recHeldPOW,
			new App.Events.recHermRunaway,
			new App.Events.recHomelessBreakIn,
			new App.Events.recImmigrant,
			new App.Events.recMaleDebtor,
			new App.Events.recMaleRecruit,
			new App.Events.recMaleSD,
			new App.Events.recMTFSE,
			new App.Events.recOrphanFemboy,
			new App.Events.recOrphanRebelliousFemale,
			new App.Events.recOverwhelmedFarmgirl,
			new App.Events.recPaternalistSwanSong,
			new App.Events.recPrincelyBetrayal,
			new App.Events.recPunkFemcat,
			new App.Events.recPunkSissycat,
			new App.Events.recRacerDgChaser,
			new App.Events.recRacerLoser,
			new App.Events.recRacerWinner,
			new App.Events.recRepoHousekeeper,
			new App.Events.recRepoMilfHousekeeper,
			new App.Events.recRepoNanny,
			new App.Events.recRogueCyborg,
			new App.Events.recRunawayCat,
			new App.Events.recSchoolSale,
			new App.Events.recSchoolTrap,
			new App.Events.recShemalePC,
			new App.Events.recSpoiledDaughter,
			new App.Events.recStarvingArtist,
			new App.Events.recStarvingMigrant,
			new App.Events.recTgAddict,
			new App.Events.recWanderingHomeless,
			new App.Events.recWhoreRecruit,
			new App.Events.recWomanlyPC,
		];
	}

	eventPrerequisites() {
		// filter and weight the delegate events based on their prerequisites, casting requirements, and weight
		/** @type {App.Events.BaseEvent[]} */
		const validEvents = this.eventList
			.filter(e => App.Events.canExecute(e))
			.reduce((res, cur) => res.concat(Array(cur.weight).fill(cur)), []);

		// we randomly select a qualifying event and immediately write it onto this.params so that
		// a saved game will resume with the same event, rather than choosing a new one at random
		this.params.event = validEvents.random();

		// if a qualifying delegate event was selected, RE Recruit can run; otherwise it can't
		return [() => !!this.params.event];
	}

	get weight() {
		let weight = 1; // one generic recruit event guaranteed to always be possible
		if ((random(1, 100) < V.rep/200) || (V.debugMode && V.debugModeEventSelection)) {
			weight++;
		}
		if (V.policies.proRecruitment === 1) {
			if ((random(1, 100) < V.rep/200) || (V.debugMode && V.debugModeEventSelection)) {
				weight++;
			}
		}
		if (V.policies.enslavementRep !== -1) {
			if ((random(1, 100) < V.rep/300) || (V.debugMode && V.debugModeEventSelection)) {
				weight++;
			}
		}
		if (V.policies.enslavementCash !== -1) {
			if ((random(1, 100) < V.rep/300) || (V.debugMode && V.debugModeEventSelection)) {
				weight++;
			}
		}
		return weight;
	}

	get eventName() {
		return "Recruit " + (this.params.event ? this.params.event.eventName : "");
	}

	execute(node) {
		V.encyclopedia = "Enslaving People";
		if (V.debugMode && V.debugModeEventSelection) {
			const el = App.UI.DOM.appendNewElement("span", node);
			App.UI.DOM.appendNewElement("span", el, `One of the following recruitment events would have appeared: `);
			const evList = this.eventList.filter(e => App.Events.canExecute(e));
			el.append(App.UI.DOM.makeSelect(evList.map(e => {
				return {key: e.eventName, name: e.eventName};
			}), null, e => {
				el.remove();
				evList.find(ev => ev.eventName === e).execute(node);
			}));
		} else {
			// forward execution to the delegate event
			this.params.event.execute(node);
		}
	}
};


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

	eventPrerequisites() {
		return [
			() => V.seeDicks !== 0
		];
	}

	get eventName() {
		return "Dick Girl Self Enslavement";
	}

	execute(node) {
		const slave = makeSlave();
		const {he, his, him, girl} = getPronouns(slave);
		let r = [];

		r.push(`A (quite unrealistic) blockbuster movie took your arcology by storm recently, causing some curious side effects among the more idealistic type of young people here. The movie plot is about a young woman who sells herself into slavery to be close to a love interest... then wins his adoration and her freedom in the process. Of course, just because it works like that in a movie doesn't mean real life will be the same — which didn't seem to occur to several young women who actually try to put such a plan in action. Mostly, the sudden spike of self-enslavement does lead to a number of handsome college students getting their dicks wet as they enjoy their new status as slaveowners — and not a one freed his love-sick slavegirl either.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`It isn't just all natural females either, as a few men also jumped on the bandwagon, throwing in a little bit of transformative surgery in the mix. Either going all the way to making themselves into female slaves or hoping to be accepted as dick-girls after making the target of their affection fall for a pretty face and breasts. One of latter cases gets flagged by your assistant as a business opportunity, as the new slaveowner wasn't impressed by a former male and wants to get rid of the dickgirl as quickly as possible. A video attached to the 'sale offer' online post does show a relatively pretty young dickgirl, sniffling quietly as ${he} gets ordered to show off ${his} body to prospective buyers.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(App.UI.DOM.makeElement("span", `The dickgirl should go pretty cheap, just ${cashFormat(1500)}. Sounds like the owner mostly wants to not be bothered by ${him} anymore.`, "note"));

		App.Events.addParagraph(node, r);

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

		const contractCost = 1500;
		const responses = [];
		if (V.cash >= contractCost) {
			responses.push(new App.Events.Result(`Enslave ${him}`, enslave));
		} else {
			responses.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}`));
		}
		App.Events.addResponses(node, responses);

		function enslave() {
			const el = new DocumentFragment();
			let r = [];
			cashX(forceNeg(contractCost), "slaveTransfer", slave);
			r.push(`Sending an offer to buy the dickgirl, you get a confirmation from the student very shortly afterward. It doesn't take much longer before he appears at the security office leading into your penthouse to drop off his slave, leaving ${him} behind without even saying goodbye. The sniffling and dejected ${girl} is brought into your office so you can check ${him} out in person afterward. On your orders, ${he} strips and submits to biometric scanning, registering ${him} as your property.`);
			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addNode(el, r);
			return el;
		}

		function makeSlave() {
			const slave = GenerateNewSlave("XY", {maxAge: 21, disableDisability: 1, race: "nonslave"});
			slave.origin = "$He enslaved $himself to be with a man $he loved, only to be sold to you afterward.";
			slave.devotion = random(-30, -5);
			slave.trust = random(-25, -5);
			setHealth(slave, jsRandom(10, 30), undefined, undefined, 0, 0);
			slave.face = random(20, 60);
			slave.faceImplant = 15;
			slave.skill.vaginal = 0;
			slave.skill.anal = 0;
			slave.skill.oral = 35;
			slave.skill.whoring = 0;
			slave.boobsImplant = random(2, 6) * 100;
			slave.boobs = 150 + slave.boobsImplant;
			slave.boobsImplantType = "normal";
			slave.vagina = -1;
			slave.ovaries = 0;
			slave.preg = -1;
			slave.anus = 0;
			slave.dick = random(1, 4);
			slave.balls = random(1, 4);
			slave.scrotum = slave.balls;
			slave.weight = 0;
			slave.muscles = 20;
			slave.intelligence = random(-50, 50);
			slave.intelligenceImplant = 15;
			if (slave.physicalAge >= 12) {
				slave.teeth = "normal";
			}
			slave.career = "a student";
			slave.behavioralFlaw = "devout";
			slave.sexualFlaw = "idealistic";
			return slave;
		}
	}
};


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

	eventPrerequisites() {
		return [
			() => V.seeDicks !== 0
		];
	}

	get eventName() {
		return "MtF Self Enslavement";
	}

	execute(node) {
		const slave = makeSlave();
		const {he, his, him, girl, woman} = getPronouns(slave);
		let r = [];

		r.push(`A (quite unrealistic) blockbuster movie took your arcology by storm recently, causing some curious side effects among the more idealistic type of young people here. The movie plot is about a young woman who sells herself into slavery to be close to a love interest... then wins his adoration and her freedom in the process. Of course, just because it works like that in a movie doesn't mean real life will be the same — which didn't seem to occur to several young women who actually try to put such a plan in action. Mostly, the sudden spike of self-enslavement does lead to a number of handsome college students getting their dicks wet as they enjoy their new status as slaveowners — and not a one freed his love-sick slavegirl either.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`It isn't just all natural females either, as a few men also jumped on the bandwagon, throwing in a little bit of transformative surgery in the mix. Either going all the way to making themselves into female slaves or hoping to be accepted as dick-girls after making the target of their affection fall for a pretty face and breasts. One of former cases gets flagged by your assistant as a business opportunity, as the new slaveowner wasn't impressed by a former male — despite ${his} good looks and virgin pussy, he can't forget ${he} originally was a man. A video attached to the 'sale offer' online post does show a relatively pretty young ${woman}, sniffling quietly as ${he} gets ordered to show off ${his} body to prospective buyers.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(App.UI.DOM.makeElement("span", `The ${girl} should go pretty cheap, just ${cashFormat(2000)}. Sounds like the owner mostly wants to not be bothered by ${him} anymore.`, "note"));

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

		App.Events.addParagraph(node, r);
		const contractCost = 2000;
		const responses = [];
		if (V.cash >= contractCost) {
			responses.push(new App.Events.Result(`Enslave ${him}`, enslave));
		} else {
			responses.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}`));
		}
		App.Events.addResponses(node, responses);

		function enslave() {
			const el = new DocumentFragment();
			let r = [];
			cashX(forceNeg(contractCost), "slaveTransfer", slave);
			r.push(`Sending an offer to buy the slave ${girl}, you get a confirmation from the student very shortly afterward. It doesn't take much longer before he appears at the security office leading into your penthouse to drop off his slave, leaving ${him} behind without even saying goodbye. The sniffling and dejected ${girl} is brought into your office so you can check ${him} out in person afterward. On your orders, ${he} strips and submits to biometric scanning, registering ${him} as your property.`);
			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addNode(el, r);
			return el;
		}

		function makeSlave() {
			const slave = GenerateNewSlave("XY", {maxAge: 21, disableDisability: 1, race: "nonslave"});
			slave.origin = "$He enslaved $himself to be with a man $he loved, only to be sold to you afterward.";
			slave.devotion = random(-30, -5);
			slave.trust = random(-25, -5);
			setHealth(slave, jsRandom(10, 30), undefined, undefined, 0, 0);
			slave.face = random(20, 60);
			slave.faceImplant = 15;
			slave.skill.vaginal = 0;
			slave.skill.anal = 0;
			slave.skill.oral = random(15, 40);
			slave.skill.whoring = 0;
			slave.boobsImplant = random(3, 6) * 100;
			slave.boobsImplantType = "normal";
			slave.boobs = slave.boobsImplant + 150;
			slave.vagina = 0;
			slave.skill.vaginal = 0;
			slave.ovaries = 0;
			slave.preg = 0;
			slave.anus = 0;
			slave.dick = 0;
			slave.balls = 0;
			slave.weight = 0;
			slave.muscles = 20;
			slave.intelligence = random(-50, 50);
			slave.intelligenceImplant = 15;
			if (slave.physicalAge >= 12) {
				slave.teeth = "normal";
			}
			slave.career = "a student";
			slave.behavioralFlaw = "devout";
			slave.sexualFlaw = "idealistic";
			return slave;
		}
	}
};


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

	eventPrerequisites() {
		return [
			() => V.seeDicks !== 100,
			() => V.seePreg !== 0,
			() => V.seeHyperPreg === 1
		];
	}

	get eventName() {
		return "Blessed Vessel";
	}

	execute(node) {
		const slave = makeSlave();
		const {
			He,
			he, his, him, girl, woman
		} = getPronouns(slave);
		let r = [];

		r.push(`As a minor point of information on your daily news download, you see that yet another of the new religions (cults really) that tend to spring up like weeds in the Free Cities has met its almost inevitable fate. Even with the most charismatic leader, starry-eyed idealism or boundless greed in milking the followers usually put a sudden end to the various self-declared churches, temples and holy places. In this case, the cult leader successfully made a hasty getaway, leaving his creditors and conned believers behind. Repo men are sent out in force, carting off the contents of the 'house of worship' and the luxurious apartment the man kept.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`Wondering what sorts of strange paraphernalia or weird sex toys the grifter might have kept himself amused with, you casually select the feed of one of the surveillance cameras that overlooks the area. And indeed, the contents of many boxes being carried out of there do have a certain perverted look to them, prompting you to zoom in — which is when the obscenely child-filled body of a`);
		if (slave.actualAge >= 18) {
			r.push(`${woman}`);
		} else if (slave.actualAge >= 13) {
			r.push(`${girl}`);
		} else {
			r.push(`little ${girl}`);
		}
		r.push(`is slowly carted through the image, pushed along by several repo men. Immediately directing the camera to follow ${him}, you see that they scan and log ${him} like any of the other items in the household liquidation — ${he} must have been a slave used by the cult leader for religious rituals. ${He} caught your interest just enough to check the slave markets for a potential better look at that cult's tastes — and indeed, half an hour later ${he}'s being listed as for sale.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`The`);
		if (slave.actualAge >= 18) {
			r.push(`young ${woman}`);
		} else if (slave.actualAge >= 13) {
			r.push(`${girl}`);
		} else {
			r.push(`child`);
		}
		r.push(`isn't in the greatest of shape, which is understandable when one is ready to burst at the seams with child, and completely devoid of any semblance of awareness of the current situation. ${He} was likely nothing more than a sacrifice to act as a conduit for their Lord to enter the world; in other words, an excuse to load a ${girl} up with fertility drugs and fuck ${him} ridiculously pregnant before your followers while they shout praise to the heavens to every load of cum. Going by how distinctly you can see the life inside ${him} pushing against the thinning walls of ${his} abdomen, ${he}'s likely going to either give birth or explode into crying babies at any time, something not lost on those looking to pick up a cheap bundle of future prospects.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(App.UI.DOM.makeElement("span", `Someone already started bidding for ${him} and more bids are coming in fast. As such things usually go, you guess that the price will come out to about ${cashFormat(5000)} in the end.`, "note"));

		App.Events.addParagraph(node, r);

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

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

		function enslave() {
			const el = new DocumentFragment();
			let r = [];
			cashX(forceNeg(contractCost), "slaveTransfer", slave);
			r.push(`Winning out in the auction, you have the ${girl} brought to you straight away. ${He} is rolled into your penthouse completely nude giving you a full view of ${his} cavernous pussy and how it is barely holding back a flood of life from being released upon your floor. Pondering whether or not this was worth it, you submit ${him} to biometric scanning, registering ${him}, and ${his} coming brood, as your property.`);
			newSlave(slave); // silent
			App.Events.addNode(el, r);
			return el;
		}

		function sell() {
			const el = new DocumentFragment();
			let r = [];
			cashX(cost, "slaveTransfer");
			r.push(`Winning out in the auction, you have the ${girl} brought to you straight away. ${He} is rolled into your penthouse completely nude giving you a full view of ${his} cavernous pussy and how it is barely holding back a flood of life from being released upon your floor. Pondering whether or not this was worth it, you submit ${him} to biometric scanning, registering ${him}, and ${his} coming brood, as your property. The purchasing agent groans at the sight of ${him}, not eager at the amount of effort it will take him to roll ${him} to the volume breeder that purchased ${him}.`);
			App.Events.addNode(el, r);
			return el;
		}

		function makeSlave() {
			const slave = GenerateNewSlave("XX", {
				minAge: V.fertilityAge,
				maxAge: (V.pedo_mode === 1 ? 18 : 22),
				ageOverridesPedoMode: 1, disableDisability: 1
			});
			slave.origin = "$He was the holy vessel of a new religion and 'blessed' by their Lord to bring forth His servants.";
			setHealth(slave, 100, 0, 0, 0, 0);
			slave.face = random(20, 90);
			slave.boobs = random(4, 7) * 300;
			slave.lactation = 1;
			slave.lactationDuration = 2;
			slave.vagina = 10;
			slave.vaginaLube = 2;
			slave.ovaries = 1;
			slave.pubertyXX = 1;
			slave.preg = 43;
			slave.pregWeek = 40;
			slave.pregType = 50;
			slave.pregKnown = 1;
			slave.bellySag = 100;
			slave.bellySagPreg = 100;
			SetBellySize(slave);
			slave.pubicHStyle = "waxed";
			slave.underArmHStyle = "waxed";
			slave.weight = 90;
			slave.muscles = random(-100, -50);
			slave.career = "a breeder";
			applyMindbroken(slave, slave.intelligence);
			return slave;
		}
	}
};


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

	eventPrerequisites() {
		return [
			() => V.seeDicks !== 100,
			() => V.seePreg !== 0
		];
	}

	get eventName() {
		return "Blessed Virgin";
	}

	execute(node) {
		const slave = makeSlave();
		const {
			He,
			he, his, him, girl, woman,
		} = getPronouns(slave);
		let r = [];

		r.push(`As a minor point of information on your daily news download, you see that yet another of the new religions (cults really) that tend to spring up like weeds in the Free Cities has met its almost inevitable fate. Even with the most charismatic leader, starry-eyed idealism or boundless greed in milking the followers usually put a sudden end to the various self-declared churches, temples and holy places. In this case, the cult leader successfully made a hasty getaway, leaving his creditors and conned believers behind. Repo men are sent out in force, carting off the contents of the 'house of worship' and the luxurious apartment the man kept.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`Wondering what sorts of strange paraphernalia or weird sex toys the grifter might have kept himself amused with, you casually select the feed of one of the surveillance cameras that overlooks the area. And indeed, the contents of many boxes being carried out of there do have a certain perverted look to them, prompting you to zoom in — which is when a pretty, young, naked and extremely pregnant`);
		if (slave.actualAge >= 18) {
			r.push(`${woman}`);
		} else if (slave.actualAge >= 13) {
			r.push(`${girl}`);
		} else {
			r.push(`little ${girl}`);
		}
		r.push(`slowly waddles through the image, escorted by two repo men. Immediately directing the camera to follow ${him}, you see that they scan and log ${him} like any of the other items in the household liquidation — ${he} must have been the cult leader's personal slave. ${He} caught your interest just enough to check the slave markets for a potential better look at that cult's tastes — and indeed, half an hour later ${he}'s being listed as for sale.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`The`);
		if (slave.actualAge >= 18) {
			r.push(`young ${woman}`);
		} else if (slave.actualAge >= 13) {
			r.push(`${girl}`);
		} else {
			r.push(`child`);
		}
		r.push(`is likely a virgin, given ${his} obvious discomfort at being poked and prodded for display and is trying ${his} hardest to cover ${his} shame. Quickly reading through the details, your suspicions are confirmed; ${he} is indeed a heavily pregnant virgin. Odds are high that ${he} was treated as a "Virgin Mary" for the cult and is likely going to catch the eye of any collectors of religious objects.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(App.UI.DOM.makeElement("span", `Someone already started bidding for ${him} and more bids are coming in fast. As such things usually go, you guess that the price will come out to about ${cashFormat(10000)} in the end.`, "note"));

		App.Events.addParagraph(node, r);
		const contractCost = 10000;
		const cost = slaveCost(slave) - contractCost;
		const responses = [];
		if (V.cash >= contractCost) {
			responses.push(new App.Events.Result(`Enslave ${him}`, enslave));
		} else {
			responses.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}`));
		}
		responses.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));

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

		App.Events.addResponses(node, responses);

		function enslave() {
			const el = new DocumentFragment();
			let r = [];
			cashX(forceNeg(contractCost), "slaveTransfer", slave);
			r.push(`Winning out in the auction, you have the ${girl} brought to you straight away. ${He} is helped into your penthouse in semitransparent shimmering gown — some sort of cult garb that was thrown into the sale as a bonus. It certainly looks amazing on ${him}, but you want to see all of your new acquisition so you order ${him} to strip. With quivering hands, ${he} slides the fabric off and lets it fall to the floor, then submits to biometric scanning, registering ${him} as your property.`);
			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addNode(el, r);
			return el;
		}

		function sell() {
			const el = new DocumentFragment();
			let r = [];
			cashX(cost, "slaveTransfer");
			r.push(`Winning out in the auction, you have the young ${woman} brought to you straight away. ${He} is helped into your penthouse in semitransparent shimmering gown — some sort of cult garb that was thrown into the sale as a bonus. It certainly looks amazing on ${him}, but you want to see all of your new acquisition so you order ${him} to strip. With shaking hands, ${he} slides the fabric off and lets it fall to the floor, then submits to biometric scanning, registering ${him} as your property. When ${he}'s taken away to the office of the slave broker you sold ${him} on to, the young ${woman} lets out a little sob, as if fearful of ${his} future.`);
			App.Events.addNode(el, r);
			return el;
		}

		function makeSlave() {
			const slave = GenerateNewSlave("XX", {
				minAge: V.fertilityAge,
				maxAge: (V.pedo_mode === 1 ? 18 : 22),
				ageOverridesPedoMode: 1, disableDisability: 1
			});
			slave.origin = "$He was the virgin figurehead of a new religion and 'blessed' by their Lord.";
			slave.devotion = random(-20, 20);
			slave.trust = random(25, 50);
			setHealth(slave, jsRandom(60, 100), 0, 0, 0, 0);
			slave.face = random(20, 90);
			slave.skill.vaginal = 0;
			slave.skill.anal = 0;
			slave.skill.oral = 0;
			slave.skill.whoring = 0;
			slave.skill.entertainment = 20;
			slave.boobs = random(4, 7) * 100;
			slave.lactation = 1;
			slave.lactationDuration = 2;
			slave.vagina = 0;
			slave.trueVirgin = 1;
			slave.vaginaLube = 2;
			slave.ovaries = 1;
			slave.pubertyXX = 1;
			slave.preg = 40;
			slave.pregWeek = 40;
			slave.pregType = 1;
			slave.pregKnown = 1;
			SetBellySize(slave);
			slave.pubicHStyle = "waxed";
			slave.underArmHStyle = "waxed";
			slave.anus = 0;
			slave.weight = 0;
			slave.waist = -20;
			slave.muscles = random(-20, 10);
			slave.intelligence = random(0, 90);
			slave.career = "a missionary";
			slave.fetish = "submissive";
			slave.fetishStrength = 100;
			slave.behavioralFlaw = "devout";
			slave.sexualFlaw = "repressed";
			slave.voice = random(2, 3);
			return slave;
		}
	}
};


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

	eventPrerequisites() {
		return [
			() => V.seeDicks !== 100,
			() => V.seePreg !== 0,
		];
	}

	get eventName() {
		return "Homeless Blind";
	}

	execute(node) {
		const slave = makeSlave();
		const {
			He,
			he, his, him, himself, girl, woman
		} = getPronouns(slave);
		const title = (V.PC.title !== 0) ? `Sir` : `Ma'am`;
		let r = [];

		r.push(`A young`);
		if (slave.physicalAge < 13) {
			r.push(girl);
		} else if (slave.physicalAge < 18) {
			r.push(`teen`);
		} else {
			r.push(woman);
		}
		r.push(
			`struggles into your penthouse for an interview. You accepted ${his} request to see you because ${he} took the unusual step of promising to sell ${himself} to you if you would admit ${him}. The reason for this odd behavior becomes clear when ${he} enters. ${He} is gingerly feeling ${his} way towards your desk, before finding it and straightening up, giving you a good look at ${his} body. ${He} is clothed in rags and dangerously thin, save for a notable roundness in ${his} middle. ${He} shakily makes ${his} case.`,
			Spoken(slave, `"${title}, I'm desperate. My home was repossessed and I was forced onto the street. And the street is no place for a blind ${girl}. T-they",`),
			`${he} places a hand on ${his} stomach,`,
			Spoken(slave, `"took advantage of my helplessness. For months, they fucked me whenever they wanted, and in return they gave me next to no food and this child!"`),
			`${He} stamps ${his} foot angrily, before continuing,`,
			Spoken(slave, `"but, I thought, you would be far better than that life, a slow death on the streets." ${He} tears up and awaits your response.`)
		);

		App.Events.addParagraph(node, r);

		const contractCost = 1000;
		const cost = slaveCost(slave) - contractCost;
		const responses = [];
		if (V.cash >= contractCost) {
			responses.push(new App.Events.Result(`Enslave ${him}`, enslave));
		} else {
			responses.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}`));
		}
		responses.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));

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

		App.Events.addResponses(node, responses);

		function enslave() {
			const el = new DocumentFragment();
			let r = [];
			cashX(forceNeg(contractCost), "slaveTransfer", slave);
			r.push(`${He} cooperates as the biometric scanners scrupulously record ${his} every particular as belonging not to a person but to a piece of human property. ${He} willingly places ${his} biometric signature in testament to the truth of ${his} voluntary enslavement. The process is completed with a distinct anticlimax: ${he} is one of your slaves now. ${He} gives you a smile, knowing ${he}'ll have a belly full of food before long.`);
			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addNode(el, r);
			return el;
		}

		function sell() {
			const el = new DocumentFragment();
			let r = [];
			cashX(cost, "slaveTransfer");

			r.push(`${He} cooperates as the biometric scanners scrupulously record ${his} every particular as belonging not to a person but to a piece of human property. ${He} willingly places ${his} biometric signature in testament to the truth of ${his} voluntary enslavement. When a purchaser's agent arrives to take ${him} away, though, ${he} becomes uneasy.`);
			r.push(Spoken(slave, `"Will they have food?"`));
			r.push(`${he} asks plaintively. You tell ${him} yes, all ${he} can hold, ${he}'s been bought by a slave dairy. ${He}'ll be fattened up and forced to carry ${his} pregnancy to term, since it'll enhance ${his} milk production; and within a few weeks after that, ${he}'ll be impregnated again. And again. But ${he} won't be on the streets anymore.`);

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

		function makeSlave() {
			const pram = new GenerateNewSlavePram();
			pram.maxAge = 22;
			pram.ageOverridesPedoMode = 1;
			pram.disableDisability = 1;
			pram.race = "nonslave";
			if (V.pedo_mode === 1) {
				pram.minAge = V.fertilityAge;
			} else {
				pram.minAge = 18;
			}
			const slave = GenerateNewSlave("XX", pram);
			slave.origin = "$He offered $himself as a slave to escape the horrors a blind $girl faces on the streets.";
			slave.devotion = random(20, 30);
			slave.trust = random(0, 15);
			if (slave.behavioralFlaw === "anorexic") {
				slave.behavioralFlaw = "none";
			}
			slave.boobs = 300;
			slave.butt++;
			slave.vagina = 2;
			slave.anus = 1;
			slave.skill.anal = 0;
			slave.preg = 20;
			slave.pregType = 1;
			slave.pregWeek = slave.preg;
			slave.pregKnown = 1;
			SetBellySize(slave);
			eyeSurgery(slave, "both", "blind");
			slave.weight = -100;
			slave.fetish = "none";
			slave.fetishKnown = 0;
			setHealth(slave, jsRandom(-60, -20), undefined, undefined, undefined, 60);
			return slave;
		}
	}
};


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

	eventPrerequisites() {
		return [
			() => V.seeDicks !== 100,
			() => V.terrain !== "oceanic",
		];
	}

	get eventName() {
		return "Captured Teen";
	}

	execute(node) {
		const slave = makeSlave();
		const {
			He,
			he, his, him, girl, daughter,
		} = getPronouns(slave);
		let r = [];

		r.push(`You've been kept busy until late at night. The warm blue glow of your desk screen illuminates your work. Suddenly, your assistant flags an incoming vidcall as urgent. The call had decent encryption, but could be traced to a rural location several`);
		if (V.showInches === 2) {
			r.push(`miles`);
		} else {
			r.push(`kilometers`);
		}
		r.push(`away from your arcology. The callers only specified that they had a good deal to offer.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`With apprehension, you decide to let the call through. The screen switches from your work to the vidcall. Several armed men, cloaked in black, are standing around a pretty young ${girl}. ${He}'s gagged and bound to a chair.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`The men explain that they've captured the young ${daughter} of a wealthy old-world businessman, by abducting ${him} straight from a gated community. It's far from uncommon for ${girl}s to be captured and sold as slaves, but that these men had the balls to raid a gated community is something else. There are still some places in the world that are considered safe, where the world's deterioration isn't readily apparent. Showing that these places aren't safe from the predations of slavers upsets what little balance that the old world still has left, and that isn't always a good thing for the Free Cities.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`At any rate, ${he}'s a fine capture. And unsurprisingly, they want to get rid of ${him}. Fast. They're willing to offer a below-market price for ${his} enslavement.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(App.UI.DOM.makeElement("span", `You can buy out ${his} auction for ${cashFormat(10000)}.`, "note"));

		App.Events.addParagraph(node, r);
		const contractCost = 10000;
		const cost = slaveCost(slave) - contractCost;
		const responses = [];
		if (V.cash >= contractCost) {
			responses.push(new App.Events.Result(`Enslave ${him}`, enslave));
		} else {
			responses.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}`));
		}
		responses.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));

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

		App.Events.addResponses(node, responses);

		function enslave() {
			const el = new DocumentFragment();
			let r = [];
			cashX(forceNeg(contractCost), "slaveTransfer", slave);
			r.push(`You agree to the purchase. The men give a hushed thank you, and the call ends, cutting you off from the light. They arrive outside the city just a few hours later, and you send your VTOL to pick up the ${girl}. When ${he} arrives, you see that ${he} was kept in the same bindings. ${He}'s awake, and ${his} eyes make ${his} hatred of you unmistakable.`);
			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addNode(el, r);
			return el;
		}

		function sell() {
			const el = new DocumentFragment();
			let r = [];
			cashX(cost, "slaveTransfer");
			r.push(`You agree to the purchase. The men give a hushed thank you, and the call ends, cutting you off from the light. They arrive outside the city just a few hours later, and you send your VTOL to pick up the ${girl}. When ${he} arrives, you see that ${he} was kept in the same bindings. ${He}'s awake, and ${his} eyes make ${his} hatred of you unmistakable; fortunately, that's not your problem. You have a buyer with a taste for spoiled ${girl}s raised on a diet of false security lined up and eager to meet his new toy. ${He} struggles against ${his} bindings as his agent carries ${him} off, but quickly loses hope when ${he} finds there is no chance of mercy.`);
			App.Events.addNode(el, r);
			return el;
		}

		function makeSlave() {
			const slave = GenerateNewSlave("XX", {
				minAge: 13, maxAge: 18,
				race: "white", disableDisability: 1
			});
			generateSalonModifications(slave);
			slave.origin = "$He was captured in a raid on a gated community and quickly sold off.";
			slave.devotion = -20;
			slave.trust = 0;
			setHealth(slave, 20, undefined, undefined, 0, 40);
			slave.face = random(20, 60);
			slave.skill.vaginal = 0;
			slave.skill.anal = 0;
			slave.skill.oral = 0;
			slave.skill.entertainment = 0;
			slave.skill.whoring = 0;
			slave.boobs = random(3, 10) * 100;
			slave.vagina = 1;
			slave.vaginaLube = random(1, 2);
			slave.labia = 1;
			slave.ovaries = 1;
			slave.pubicHStyle = "waxed";
			slave.underArmHStyle = "waxed";
			slave.hips = random(0, 2);
			slave.butt = random(1, 4);
			slave.anus = 1;
			slave.weight = random(-20, 0);
			slave.muscles = 0;
			slave.shoulders = random(-2, 0);
			slave.intelligence = random(-50, -16);
			slave.career = "from an upper class family";
			slave.fetish = "humiliation";
			slave.behavioralFlaw = "arrogant";
			slave.voice = 3;
			slave.boobShape = "perky";
			slave.origSkin = "light";
			slave.eye.origColor = "blue";
			slave.origHColor = "blonde";
			applyGeneticColor(slave);
			slave.teeth = "normal";
			slave.prestige = 1;
			slave.prestigeDesc = "$He is the notoriously spoiled $daughter of a wealthy old world businessman.";
			return slave;
		}
	}
};


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

	eventPrerequisites() {
		return [
			() => V.seeDicks !== 100
		];
	}

	get eventName() {
		return "CCS Angel";
	}

	execute(node) {
		const slave = makeSlave();
		const {
			He,
			he, his, him, girl, woman,
		} = getPronouns(slave);
		let r = [];

		r.push(`As a minor point of information on your daily news download, you see that yet another of the new religions (cults really) that tend to spring up like weeds in the Free Cities has met its almost inevitable fate. Even with the most charismatic leader, starry-eyed idealism or boundless greed in milking the followers usually put a sudden end to the various self-declared churches, temples and holy places. In this case, the cult leader successfully made a hasty getaway, leaving his creditors and conned believers behind. Repo men are sent out in force, carting off the contents of the 'house of worship' and the luxurious apartment the man kept.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`Wondering what sorts of strange paraphernalia or weird sex toys the grifter might have kept himself amused with, you casually select the feed of one of the surveillance cameras that overlooks the area. And indeed, the contents of many boxes being carried out of there do have a certain perverted look to them, prompting you to zoom in — which is when a pretty, young and almost naked`);
		if (slave.actualAge >= 18) {
			r.push(woman);
		} else if (slave.actualAge >= 13) {
			r.push(girl);
		} else {
			r.push(`little ${girl}`);
		}
		r.push(`walks through the image, escorted by two repo men. Immediately directing the camera to follow ${him}, you see that they scan and log ${him} like any of the other items in the household liquidation — ${he} must have been the cult leader's personal slave. ${He} certainly has a unique look, waking your interest enough to check the slave markets for ${him} — and indeed, half an hour later ${he}'s being listed as for sale.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`The`);
		if (slave.actualAge >= 18) {
			r.push(`young ${woman}`);
		} else {
			r.push(girl);
		}
		r.push(`is best described as being 'angelic', in a stereotypical Western view of the mythical divine messengers. Blonde-haired, blue-eyed, and with milky-white skin, ${he} has had a pair of beautifully detailed wings tattooed on ${his} back. The small icon of two cherries next to one another also designates ${him} to be a complete virgin.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(App.UI.DOM.makeElement("span", `Someone already started bidding for ${him} and more bids are coming in fast. As such things usually go, you guess that the price will come out to about ${cashFormat(5000)} in the end.`, "note"));

		App.Events.addParagraph(node, r);
		const contractCost = 5000;
		const cost = slaveCost(slave) - contractCost;
		const responses = [];
		if (V.cash >= contractCost) {
			responses.push(new App.Events.Result(`Enslave ${him}`, enslave));
		} else {
			responses.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}`));
		}
		responses.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));

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

		App.Events.addResponses(node, responses);

		function enslave() {
			const el = new DocumentFragment();
			let r = [];
			cashX(forceNeg(contractCost), "slaveTransfer", slave);
			r.push(`Winning out in the auction, you have the young ${woman} brought to you straight away. ${He} is led into your penthouse in semitransparent shimmering gown — some sort of cult garb that was thrown into the sale as a bonus. It certainly looks amazing on ${him}, but you want to see all of your new acquisition so you order ${him} to strip. Obediently, ${he} slides the fabric off and lets it fall to the floor, then submits to biometric scanning, registering ${him} as your property.`);
			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addNode(el, r);
			return el;
		}

		function sell() {
			const el = new DocumentFragment();
			let r = [];
			cashX(cost, "slaveTransfer");
			r.push(`Winning out in the auction, you have the young ${woman} brought to you straight away. ${He} is led into your penthouse in semitransparent shimmering gown — some sort of cult garb that was thrown into the sale as a bonus. It certainly looks amazing on ${him}, but you want to see all of your new acquisition so you order ${him} to strip. Obediently, ${he} slides the fabric off and lets it fall to the floor, then submits to biometric scanning, registering ${him} as your property. When ${he}'s taken away to the office of the slave broker you sold ${him} on to, the young ${woman} sighs, sad that ${he}'s not staying as yours in the luxurious penthouse you call your own.`);
			App.Events.addNode(el, r);
			return el;
		}

		function makeSlave() {
			const slave = GenerateNewSlave("XX", {maxAge: 24, disableDisability: 1, race: "white"});
			slave.origin = "$He was the private slave of a con artist cult leader before he had to abandon $him and flee.";
			slave.devotion = random(25, 50);
			slave.trust = random(25, 50);
			setHealth(slave, jsRandom(30, 60), undefined, undefined, 0, 0);
			slave.face = random(25, 100);
			slave.skill.vaginal = 0;
			slave.skill.anal = 0;
			slave.skill.oral = 35;
			slave.skill.whoring = 0;
			slave.skill.entertainment = 35;
			slave.boobs = random(2, 7) * 100;
			slave.vagina = 0;
			slave.trueVirgin = 1;
			slave.vaginaLube = 1;
			slave.ovaries = 1;
			slave.preg = -1;
			slave.pubicHStyle = "waxed";
			slave.underArmHStyle = "waxed";
			slave.shoulders = random(-1, 1);
			slave.hips = -1;
			slave.butt = 0;
			slave.anus = 0;
			slave.weight = 0;
			slave.waist = -20;
			slave.muscles = random(10, 50);
			slave.intelligence = random(-15, 50);
			slave.career = "a dancer";
			slave.fetish = "submissive";
			slave.behavioralFlaw = "devout";
			slave.sexualFlaw = "idealistic";
			slave.custom.tattoo = "$He has beautifully detailed set of angel wings tattooed on $his back.";
			slave.voice = 3;
			slave.eye.origColor = "blue";
			slave.origHColor = "blonde";
			slave.origSkin = "pale";
			applyGeneticColor(slave);
			slave.hLength = 40;
			slave.hStyle = "neat";
			slave.slaveName = either("Angel", "Angelica", "Gabriela", "Layla", "Liel", "Seraph");
			return slave;
		}
	}
};


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

	eventPrerequisites() {
		return [
			() => V.seeDicks !== 100
		];
	}

	get eventName() {
		return "CCS Angel (dark hair)";
	}

	execute(node) {
		const slave = makeSlave();
		const {
			He,
			he, his, him, himself, girl, woman,
		} = getPronouns(slave);
		let r = [];

		r.push(`As a minor point of information on your daily news download, you see that yet another of the new religions (cults really) that tend to spring up like weeds in the Free Cities has met its almost inevitable fate. Even with the most charismatic leader, starry-eyed idealism or boundless greed in milking the followers usually put a sudden end to the various self-declared churches, temples and holy places. In this case, the cult leader successfully made a hasty getaway, leaving his creditors and conned believers behind. Repo men are sent out in force, carting off the contents of the 'house of worship' and the luxurious apartment the man kept.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`Wondering what sorts of strange paraphernalia or weird sex toys the grifter might have kept himself amused with, you casually select the feed of one of the surveillance cameras that overlooks the area. And indeed, the contents of many boxes being carried out of there do have a certain perverted look to them, prompting you to zoom in — which is when a pretty, young and almost naked`);
		if (slave.actualAge >= 18) {
			r.push(`${woman}`);
		} else if (slave.actualAge >= 13) {
			r.push(`${girl}`);
		} else {
			r.push(`little ${girl}`);
		}
		r.push(`walks through the image, escorted by two repo men. Immediately directing the camera to follow ${him}, you see that they scan and log ${him} like any of the other items in the household liquidation — ${he} must have been the cult leader's personal slave. ${He} certainly has a unique look, waking your interest enough to check the slave markets for ${him} — and indeed, half an hour later ${he}'s being listed as for sale.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`The`);
		if (slave.actualAge >= 18) {
			r.push(`young ${woman}`);
		} else {
			r.push(`${girl}`);
		}
		r.push(`is best described as being 'angelic', in a stereotypical Western view of the mythical divine messengers. Having jet-black hair and amber eyes, coupled with milky-white skin, there is a pair of beautifully detailed wings tattooed on ${his} back. A whole row of icons depicting stylized sex acts mark ${him} as being well versed in sexual matters.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(App.UI.DOM.makeElement("span", `Someone already started bidding for ${him} and more bids are coming in fast. As such things usually go, you guess that the price will come out to about ${cashFormat(7500)} in the end.`, "note"));

		App.Events.addParagraph(node, r);
		const contractCost = 7500;
		const cost = slaveCost(slave) - contractCost;
		const responses = [];
		if (V.cash >= contractCost) {
			responses.push(new App.Events.Result(`Enslave ${him}`, enslave));
		} else {
			responses.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}`));
		}
		responses.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));

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

		App.Events.addResponses(node, responses);

		function enslave() {
			const el = new DocumentFragment();
			let r = [];
			cashX(forceNeg(contractCost), "slaveTransfer", slave);
			r.push(`Winning out in the auction, you have the young ${woman} brought to you straight away. ${He} is led into your penthouse in semitransparent shimmering gown — some sort of cult garb that was thrown into the sale as a bonus. It certainly looks amazing on ${him}, but you want to see all of your new acquisition so you order ${him} to strip. Obediently, ${he} slides the fabric off and lets it fall to the floor, then submits to biometric scanning, registering ${him} as your property.`);
			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addNode(el, r);
			return el;
		}

		function sell() {
			const el = new DocumentFragment();
			let r = [];
			cashX(cost, "slaveTransfer");
			r.push(`Winning out in the auction, you have the young ${woman} brought to you straight away. ${He} is led into your penthouse in semitransparent shimmering gown — some sort of cult garb that was thrown into the sale as a bonus. It certainly looks amazing on ${him}, but you want to see all of your new acquisition so you order ${him} to strip. Obediently, ${he} slides the fabric off and lets it fall to the floor, then submits to biometric scanning, registering ${him} as your property. When ${he}'s taken away to the office of the slave broker you sold ${him} on to, the young ${woman} lets out a little huff, as if telling ${himself} that your luxurious penthouse can't be that good if you're not keeping ${him} for it.`);
			App.Events.addNode(el, r);
			return el;
		}

		function makeSlave() {
			const slave = GenerateNewSlave("XX", {maxAge: 22, disableDisability: 1, race: "white"});
			slave.origin = "$He was the private slave of a con artist cult leader before he had to abandon $him and flee.";
			slave.devotion = random(-45, 15);
			slave.trust = random(25, 50);
			setHealth(slave, jsRandom(30, 60), undefined, undefined, 0, 0);
			slave.face = random(20, 60);
			slave.skill.vaginal = random(50, 100);
			slave.skill.anal = random(50, 100);
			slave.skill.oral = random(50, 100);
			slave.skill.whoring = random(50, 100);
			slave.skill.entertainment = 35;
			slave.boobs = random(2, 7) * 100;
			slave.vagina = 2;
			slave.vaginaLube = 2;
			slave.ovaries = 1;
			slave.preg = -1;
			slave.pubicHStyle = "waxed";
			slave.underArmHStyle = "waxed";
			slave.shoulders = random(-1, 1);
			slave.hips = -1;
			slave.butt = 0;
			slave.anus = 2;
			slave.weight = 0;
			slave.waist = -20;
			slave.muscles = random(10, 50);
			slave.intelligence = random(-15, 50);
			slave.career = "a dancer";
			slave.fetish = "dom";
			slave.behavioralQuirk = "sinful";
			slave.sexualFlaw = "judgemental";
			slave.custom.tattoo = "$He has beautifully detailed set of angel wings tattooed on $his back.";
			slave.voice = random(2, 3);
			slave.eye.origColor = "amber";
			slave.origHColor = "black";
			slave.origSkin = "pale";
			applyGeneticColor(slave);
			slave.hLength = 40;
			slave.hStyle = "neat";
			slave.slaveName = either("Eve", "Jezebel", "Lileli", "Lilith", "Lucy", "Malicia");
			return slave;
		}
	}
};


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

	eventPrerequisites() {
		return [
			() => V.seeDicks !== 100,
			() => V.seePreg !== 0,
			() => V.rep > 16000,
			() => (random(1, 100) < V.rep/1000) || (V.debugMode > 0 && V.debugModeEventSelection > 0),
			() => V.cash >= 50000
		];
	}

	get eventName() {
		return "Cleaning House";
	}

	execute(node) {
		const slave = makeSlave();
		const {his, girl} = getPronouns(slave);
		const {HeA} = getPronouns(assistant.pronouns().main).appendSuffix("A");
		let r = [];

		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, are lucrative deals with powerful individuals.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`This call is coming from a public kiosk, which is usually an indication that the person on the other end is a transient individual who has decided to take slavery over homelessness and not someone of high society. This call, as you would expect, is different. The moment the person on the other end introduces themselves you immediately recognize why your assistant brought this to your attention. The caller is the King of an old world kingdom, contacting you by an untraceable means due of the conspiratorial nature of his proposal.`);
		App.Events.addParagraph(node, r);
		r = [];
		r.push(`He explains that one of his servant ${girl}s, ${slave.slaveName}, was impregnated by his fool of a son, and that he wants to sell you the ${girl} and ${his} nosy coworkers to clean house and cover it up.`);
		if (V.arcologies[0].FSRepopulationFocus !== "unset") {
			r.push(`You relish at the opportunity to obtain an expectant mother and some decent slaves.`);
		} else {
			r.push(`You aren't particularly concerned with the pregnancy, but it sounds like you could get a several decent slaves out of this.`);
		}
		App.Events.addParagraph(node, r);
		r = [];
		r.push(App.UI.DOM.makeElement("span", `His offer stands at ${cashFormat(10000)} per head for a total of ${cashFormat(50000)}.`, "note"));

		App.Events.addParagraph(node, r);
		const contractCost = 50000;
		const responses = [];
		responses.push(new App.Events.Result(`Accept the offer`, accept));
		const newSlaves = [slave];
		for (let reRec = 0; reRec < 4; reRec++) {
			const s = GenerateNewSlave("XX", {minAge: 8, maxAge: 32, disableDisability: 1});
			s.face = random(20, 100);
			s.intelligence = random(20, 60);
			s.intelligenceImplant = 0;
			s.origin = "You purchased $him from a King after $he expressed knowledge of the prince's affair with another servant.";
			s.career = "a maid";
			s.clothes = "a nice maid outfit";
			s.devotion = random(-20, 20);
			s.trust = random(-20, 20);
			setHealth(s, jsRandom(0, 20), undefined, undefined, 0, 0);
			s.weight = random(-20, 60);
			s.waist = random(-40, 0);
			newSlaves.push(s);
		}

		node.append(App.UI.MultipleInspect(newSlaves, true, "generic"));

		App.Events.addResponses(node, responses);

		function accept() {
			const node = new DocumentFragment();
			let r = [];
			r.push(`You agree to purchase the servants and wire the money. The next day, a rather expensive-looking VTOL comes and drops off a group of confused and terrified slaves fitted with maid outfits and a pair of shackles on each set of limbs.`);
			for (const slave of newSlaves) {
				cashX(forceNeg(contractCost/5), "slaveTransfer", slave);
				newSlave(slave);
			}
			App.Events.addNode(node, r);
			return node;
		}

		function makeSlave() {
			const slave = GenerateNewSlave("XX", {minAge: V.fertilityAge, maxAge: 22, disableDisability: 1});
			slave.face = random(60, 100);
			slave.intelligence = random(30, 100);
			slave.intelligenceImplant = 15;
			slave.origin = "You purchased $him from a King after his son put an illegitimate heir in $his womb.";
			slave.career = "a maid";
			slave.clothes = "a nice maid outfit";
			slave.devotion = random(-20, 20);
			slave.trust = random(-90, -80);
			setHealth(slave, jsRandom(0, 20), undefined, undefined, 0, 10);
			slave.skill.vaginal = 30;
			slave.skill.anal = 15;
			slave.skill.oral = 50;
			slave.skill.entertainment = 0;
			slave.skill.whoring = 0;
			slave.vagina = 1;
			slave.anus = 1;
			slave.pubicHStyle = "waxed";
			slave.underArmHStyle = "waxed";
			slave.weight = random(-20, 0);
			slave.waist = random(-40, 0);
			slave.muscles = 0;
			slave.shoulders = random(-2, 0);
			slave.boobs += 100;
			slave.canRecruit = 0;
			slave.pubertyXX = 1;
			slave.preg = 20;
			slave.pregWeek = 20;
			slave.pregType = 1;
			slave.pregKnown = 1;
			SetBellySize(slave);
			return slave;
		}
	}
};


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

	eventPrerequisites() {
		return [
			() => V.seeDicks !== 100,
			() => V.seePreg !== 0,
			() => V.PC.skill.medicine >= 50
		];
	}

	get eventName() {
		return "Desperate Birth";
	}

	execute(node) {
		const slave = makeSlave();
		const {
			He,
			he, his, him, girl, woman,
		} = getPronouns(slave);
		let r = [];

		r.push(`As you are heading back to your penthouse from inspecting a new line of sex shops, you hear a pained moan emanate from a nearby alley. Looking in, you find a heavily pregnant`);
		if (slave.visualAge > 17) {
			r.push(`${girl}`);
		} else if (slave.visualAge > 12) {
			r.push(`teenager`);
		} else {
			r.push(`little ${girl}`);
		}
		r.push(`seated, legs spread as wide as ${he} can, in a pool of ${his} own fluids. Your medical training kicks in and you descend on the laboring ${woman}, only to find ${he} is well into giving birth. Judging by ${his} exhaustion and the ever drying amniotic fluid and blood, ${he} has been struggling for quite some time. The reason is evident,`);
		if (slave.visualAge <= 12) {
			r.push(`${his} body is far too young to birth ${his} child and it has become firmly wedged in ${his} pelvis.`);
		} else {
			r.push(`${his} body is ill-suited for childbirth and the unfortunate thing has lodged in ${his} pelvis.`);
		}
		r.push(`Every push, every desperate contraction must be agonizing to ${him}. Fortunately you know what to do, however, it will not come cheap. Hour after hour you work with the ${girl}, ${his} debt to you growing ever higher, until you finally manage to coax the newborn from ${his} battered body. ${He} smiles at ${his} baby before losing consciousness; ${he} is in really bad shape. Odds are ${his} child will grow up an orphan, even if you call in ${his} debt.`);

		App.Events.addParagraph(node, r);

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

		const contractCost = 1000;
		const responses = [];
		if (V.cash >= contractCost) {
			responses.push(new App.Events.Result(`Enslave ${him}`, enslave));
		} else {
			responses.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}`));
		}
		App.Events.addResponses(node, responses);

		function enslave() {
			const el = new DocumentFragment();
			let r = [];
			cashX(forceNeg(contractCost), "slaveTransfer", slave);
			r.push(`You complete the legalities and biometric scanning quickly before`);
			if (App.Entity.facilities.clinic.hasFreeSpace) {
				r.push(`rushing ${him} to ${V.clinicName},`);
				slave.assignment = "get treatment in the clinic";
			} else {
				r.push(`putting ${him} to bed,`);
			}
			r.push(`in the hopes that ${he} will pull through.`);
			newSlave(slave); // No intro for them
			App.Events.addNode(el, r);
			return el;
		}

		function makeSlave() {
			const pram = new GenerateNewSlavePram();
			pram.minAge = V.fertilityAge;
			pram.maxAge = 22;
			pram.ageOverridesPedoMode = 1;
			pram.disableDisability = 1;
			pram.race = "nonslave";
			const slave = GenerateNewSlave("XX", pram);
			generateSalonModifications(slave);
			slave.origin = "You helped $him give birth, leaving $him deeply indebted to you.";
			slave.devotion = random(0, 20);
			slave.trust = random(0, 20);
			setHealth(slave, -90, undefined, undefined, undefined, 100);
			slave.weight = random(-100, -50);
			slave.hips = -1;
			slave.boobs += random(3, 6) * 100;
			slave.lactation = 1;
			slave.lactationDuration = 2;
			if (slave.actualAge < 13) {
				slave.career = App.Data.Careers.General.veryYoung.random();
			} else {
				slave.career = App.Data.Careers.General.uneducated.random();
			}
			slave.vagina = 3;
			slave.anus = 0;
			slave.accent = 0;
			slave.geneticQuirks.uterineHypersensitivity = 0;
			slave.preg = 0;
			slave.pregWeek = -4;
			slave.counter.births = 1;
			slave.counter.birthsTotal = 1;
			slave.bellySag = 5;
			slave.bellySagPreg = 5;
			slave.pubertyXX = 1;
			return slave;
		}
	}
};


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

	eventPrerequisites() {
		return [
			() => V.seeDicks !== 100
		];
	}

	get eventName() {
		return "Desperate MILF";
	}

	execute(node) {
		const slave = makeSlave();
		const {
			He,
			he, his, him, girl, woman, loli
		} = getPronouns(slave);
		const title = (V.PC.title !== 0) ? `Sir` : `Ma'am`;
		let r = [];
		if (slave.physicalAge > 50) {
			r.push(`An old ${woman}`);
		} else if (slave.physicalAge > 30) {
			r.push(`A middle-aged ${woman}`);
		} else if (slave.physicalAge >= 18) {
			r.push(`A young ${woman}`);
		} else if (slave.physicalAge >= 13) {
			r.push(`A teenage ${girl}`);
		} else if (slave.physicalAge >= 7) {
			r.push(`A ${loli}`);
		} else {
			r.push(`A little ${girl}`);
		}
		r.push(`comes to your penthouse for an interview. ${He}'s clearly unwell. Instead of standing in front of your desk, ${he} kneels and looks at the floor as ${he} speaks.`);

		r.push(Spoken(slave, `"${title}, I'm desperate. I came to the Free Cities to build a better life, but... it hasn't worked out for me. I can't afford medical care, and I guess I'm too scared to try street-walking yet, though I'll have to soon. I hear you're a known slaveowner, and that you give your slaves good medical care... could you enslave me, ${title.toLowerCase()}? I know I'm still pretty enough, so I'd be used as a sex slave."`));
		r.push(`${He} weeps quietly as ${he} talks, but ${he}'s brave enough to get through ${his} little speech.`);
		App.Events.addParagraph(node, r);

		const contractCost = 1000;
		const cost = slaveCost(slave) - contractCost;
		const responses = [];
		if (V.cash >= contractCost) {
			responses.push(new App.Events.Result(`Enslave ${him}`, enslave));
		} else {
			responses.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}`));
		}
		responses.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));

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

		App.Events.addResponses(node, responses);

		function enslave() {
			const el = new DocumentFragment();
			let r = [];
			cashX(forceNeg(contractCost), "slaveTransfer", slave);
			r.push(`${He} cooperates as the biometric scanners scrupulously record ${his} every particular as belonging not to a person but to a piece of human property. ${He} willingly places ${his} biometric signature in testament to the truth of ${his} voluntary enslavement. The process is completed with a distinct anticlimax: ${he} is one of your slaves now. ${He} looks almost relaxed, as though ${he}'s at peace, now.`);
			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addNode(el, r);
			return el;
		}

		function sell() {
			const el = new DocumentFragment();
			let r = [];
			cashX(cost, "slaveTransfer");
			r.push(`${He} cooperates as the biometric scanners scrupulously record ${his} every particular as belonging not to a person but to a piece of human property. ${He} willingly places ${his} biometric signature in testament to the truth of ${his} voluntary enslavement. A purchasing agent appears to take ${him} away, which ${he} accepts resignedly, though ${he} does ask you who purchased ${him}. You tell ${him} that ${his} ample breasts have gotten ${him} bought by a slave dairy; ${he} looks thoughtful.`);
			r.push(Spoken(slave, `"I'm going to be a cow?"`));
			r.push(`${He} turns ${his} torso a little, sloshing ${his} breasts from side to side.`);
			r.push(Spoken(slave, `"Well, that doesn't sound <span style="italic">too</span> bad. Thank you."`));
			App.Events.addNode(el, r);
			return el;
		}

		function makeSlave() {
			const pram = new GenerateNewSlavePram();
			pram.minAge = V.fertilityAge + V.minimumSlaveAge;
			pram.ageOverridesPedoMode = 1;
			pram.disableDisability = 1;
			pram.race = "nonslave";
			pram.maxAge = Math.max(pram.minAge, V.retirementAge - 2);
			const slave = GenerateNewSlave("XX", pram);
			slave.origin = "$He sold $himself into slavery to escape life on the streets.";
			slave.devotion = random(0, 15);
			slave.trust = random(0, 15);
			slave.boobs += 650;
			slave.butt++;
			slave.anus++;
			slave.face = 15;
			slave.fetish = "none";
			slave.fetishKnown = 0;
			setHealth(slave, jsRandom(-70, -60), normalRandInt(10, 3), normalRandInt(10, 3), Math.max(normalRandInt(1, 0.5), 0));
			return slave;
		}
	}
};


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

	eventPrerequisites() {
		return [
			() => V.arcologies[0].FSRestart === "unset"
		];
	}

	get eventName() {
		return "Desperate Pregnancy";
	}

	execute(node) {
		const slave = makeSlave();
		const {
			He,
			he, his, him, himself, woman,
		} = getPronouns(slave);
		const title = (V.PC.title !== 0) ? `Sir` : `Ma'am`;
		let r = [];
		r.push(`A young ${woman} comes to your penthouse for an interview. You accepted ${his} request to see you because ${he} took the unusual step of promising to sell ${himself} to you if you would admit ${him}. The reason for this odd behavior becomes clear when ${he} enters. ${He}'s dressed in torn old clothes, is obviously unhealthy, and is massively pregnant. Instead of standing in front of your desk, ${he} kneels and looks at the floor as ${he} speaks.`);

		r.push(Spoken(slave, `"${title}, I'm desperate. I understand slaves' babies must be sent to orphanages at birth. But I'm on the streets and I'm so sick and hungry I'm afraid I'll miscarry. Could you enslave me, ${title.toLowerCase()}? I'm still pretty enough, and... I know some men like pregnant women. My ass is — well, I hear slaves are more valuable if they're tight back there and I've never done it there. I'm also starting to give a little milk. I know I'll have to give up the baby. I guess that's all."`));
		r.push(`${He} weeps quietly as ${he} talks, but ${he}'s brave enough to get through ${his} little speech.`);
		App.Events.addParagraph(node, r);

		const contractCost = 1000;
		const cost = slaveCost(slave) - contractCost;
		const responses = [];
		if (V.cash >= contractCost) {
			responses.push(new App.Events.Result(`Enslave ${him}`, enslave));
		} else {
			responses.push(new App.Events.Result(null, null, `You lack the necessary funds to enslave ${him}`));
		}
		responses.push(new App.Events.Result(`Sell ${him} immediately`, sell, `This will bring in ${cashFormat(cost)}`));

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

		App.Events.addResponses(node, responses);

		function enslave() {
			const el = new DocumentFragment();
			let r = [];
			cashX(forceNeg(contractCost), "slaveTransfer", slave);
			r.push(`${He} cooperates as the biometric scanners scrupulously record ${his} every particular as belonging not to a person but to a piece of human property. ${He} willingly places ${his} biometric signature in testament to the truth of ${his} voluntary enslavement. The process is completed with a distinct anticlimax: ${he} is one of your slaves now. ${He} looks almost relaxed, as though ${he}'s at peace, now.`);
			r.push(App.UI.newSlaveIntro(slave));
			App.Events.addNode(el, r);
			return el;
		}

		function sell() {
			const el = new DocumentFragment();
			let r = [];
			cashX(cost, "slaveTransfer");
			r.push(`${He} cooperates as the biometric scanners scrupulously record ${his} every particular as belonging not to a person but to a piece of human property. ${He} willingly places ${his} biometric signature in testament to the truth of ${his} voluntary enslavement. When a purchaser's agent arrives to take ${him} away, though, ${he} becomes afraid.`);
			r.push(Spoken(slave, `"W-will they h-hurt my baby?"`));
			r.push(`${he} asks plaintively. You tell ${him} no, ${he}'s been bought by a slave dairy. ${He}'ll be permitted to carry ${his} pregnancy to term, since it'll enhance ${his} milk production; and within a few weeks after that, ${he}'ll be impregnated again. And again.`);
			App.Events.addNode(el, r);
			return el;
		}

		function makeSlave() {
			const pram = new GenerateNewSlavePram();
			pram.ageOverridesPedoMode = 1;
			pram.disableDisability = 1;
			pram.race = "nonslave";
			if (V.pedo_mode === 1) {
				pram.minAge = V.fertilityAge;
			} else if (V.minimumSlaveAge < 18) {
				pram.minAge = Math.min(25, V.fertilityAge);
				pram.maxAge = Math.max(30, pram.minAge + 1);
			} else {
				pram.minAge = 25;
				pram.maxAge = 30;
			}
			const slave = GenerateNewSlave("XX", pram);
			generateSalonModifications(slave);
			slave.origin = "$He sold $himself into slavery out of fear that life on the streets was endangering $his pregnancy.";
			slave.devotion = random(0, 15);
			slave.trust = random(0, 15);
			slave.boobs += 100;
			slave.lactation = 1;
			slave.lactationDuration = 2;
			slave.butt++;
			slave.vagina = 1;
			slave.anus = 0;
			slave.skill.anal = 0;
			slave.preg = random(30, 39);
			slave.pregType = 1;
			slave.pregWeek = slave.preg;
			slave.pregKnown = 1;
			SetBellySize(slave);
			slave.fetish = "none";
			slave.fetishKnown = 0;
			setHealth(slave, random(-40, -20), undefined, undefined, undefined, 50);
			slave.face = normalRandInt(50, 50, 10, 95);
			return slave;
		}
	}
};