code:
artist notes
-------------
TO USE: SELECT VECTOR ART BY NOX/DEEPMURK

CREDITS
-------------
Nov_X/NoX (Original Artist, whose work I built off of)
skinAnon (For doing the color hexes on hundreds of skin/nipple tones.)
@prndev (For dynamic belly scaling magic)
@klorpa (For fixing many of my mistakes/spaghetti art code)
@kopareigns (For fixing many of my mistakes/spaghetti art code)
@pregmodder (Fixes and more art)

FOR MANUAL USE
-------------
1. Split source_vector_ndmain.svg and source_vector_ndextras.svg into src/art/vector/layer.
Note#1 source_vector.svg is a legacy version (before the art was changed) and is not used for anything.
Note#2 vector_revamp_source.svg not related and belongs to the other artist.

TO PLAY WITHOUT FACES
-------------
1. Go to pregmod/src/art/vector
2. Open head.tw in notepad/notepad++
3. Delete everything from Line 30 to Line 979... you'll see it says faceShape, eyebrowFullness, etc-- all of those are related to faces and can be deleted. (AKA just delete everything between the lines that says /* FACIAL APPEARANCE */ and /* END FACIAL APPEARANCE */)
4. Compile and play game.

known issues
-------------
	-minor clipping issue leg/ass outfits due to their outfit transparency effects
	-not all outfit art works with amputees
	-minor hair clipping on some outfits
	-heavy lip piercings look wonky on open mouth art
	-heavy/light piercings on face seem to override each other

---------------------------------------------------------------------------------------------------------------------------------------------
pending requests/suggestions
-------------
	-loli/shota bodies

pending outfit requests
-------------
	-opaque stockings with ribbons

planned additions
-------------
	-more hair styles
	-facepaint
	-alternate makeup options
	-rework all AI avatars
	-dick piercings (stalled due to planned code change)
	-more outfits, see current queue ( https://gitgud.io/deepmurk/fc-pregmod/issues/1 )

---------------------------------------------------------------------------------------------------------------------------------------------

v1.7 (12/22/2018)
-------------
	-added muscle definition (heavy)
	-added colorable sclera
	-added colorable eyebrows
	-added purple hair color
	-added dark orchid hair color
	-added sea green hair color
	-added green-yellow hair color
	-added dark blue hair color
	-added missing AI avatars
	-fixed faces & skintones not showing on custom ethnicities
	-added jet black hair color
	-changed black hair color
	-changed auburn hair color
	-alphabetized some options in the salon
	-miscellaneous tweaks to some other colors

v1.6 (11/18/2018)
-------------
	-misc art fixes
	-added muscle definition (low)
	-added muscle definition (medium)
	-shibari rope outfit is now red for better contrast on some skins
	-fixed hair showing when ability to grow hair was surgically removed
	-fixed muscles showing on amputated slave limbs
	-fixed faces showing on Fuckdolls
	-fixed "mixed race" skin tone/face issues
	-fixed some issues related to belly outfits

v1.5 (10/21/2018)
-------------
	-removed penis head piercing light flaccid (art only)
	-removed penis head piercing light erect (art only)
	-removed penis head piercing heavy flaccid (art only)
	-removed penis head piecing heavy erect (art only)
	-corrected ku klux klan robe description grammar
	-added burkini outfit
	-added hijab and blouse outfit
	-changed the code that affects art layer names due to conflicts with new outfits
	-changed art layer name of cutoffs to cutoffsandatshirt
	-changed art layer name of niqab to niqabandabaya
	-changed art layer name of hijab to hijabandabaya
	-changed art layer name of spats to spatsandatanktop
	-changed art layer name of stretchpants to stretchpantsandacroptop
	-changed art layer name of blouse to hijabandblouse
	-changed blouse and hijab outfit string name to hijab and blouse
	-changed shimapan panties outfit string name to striped panties
	-added bra outfit
	-added button-up shirt outfit
	-added button-up shirt and panties outfit
	-added gothic lolita dress outfit
	-added hanbok outfit
		-added nice pony outfit (no art yet)
	-added one-piece swimsuit outfit
	-added police uniform outfit
	-added skimpy loincloth outfit
	-added slutty klan robe outfit
		-added slutty pony outfit (no art yet)
	-added sports bra outfit
	-added striped bra outfit
	-added sweater outfit
	-added sweater and cutoffs outfit
	-added sweater and panties outfit
	-added t-shirt outfit
	-added t-shirt and jeans outfit
	-added t-shirt and panties outfit
	-added t-shirt and thong outfit
	-added tank-top outfit
	-added tank-top and panties outfit
	-added thong outfit
	-added tube top outfit
	-added tube top and thong outfit
	-added oversized t-shirt outfit
	-added oversized t-shirt and boyshorts outfit
	-added boyshorts outfit
	-added cutoffs outfit
	-added jeans outfit
	-added leather pants outfit
	-added leather pants and a tube top outfit
	-added leather pants and pasties outfit
	-added panties outfit
	-added panties and pasties outfit
	-added sport shorts outfit
	-added sport shorts and a sports bra outfit
	-added sport shorts and a t-shirt outfit
	-added striped underwear outfit
	-increased size of armpit hair art
	-changed minidress outfit to black color (per request)
	-misc art fixes
	-added kitty lingerie outfit

v1.4 (09/29/2018)
-------------
	-fixed facial markings showing on restrictive latex
	-fixed error on certain clothes when slave is an amputee
	-added ku klux klan outfit
	-added burqa outfit
	-added hijab and abaya outfit
	-changed niqab and abaya outfit
	-added shimapan panty outfit
	-fixed malay race not having faces
	-added penis head piercing light flaccid (art only)
	-added penis head piercing light erect (art only)
	-added penis head piercing heavy flaccid (art only)
	-added penis head piecing heavy erect (art only)
	-added nose piercing light
	-added nose piercing heavy
	-added lip piercing light
	-added lip piercing heavy
	-added eyebrow piercing light
	-added eyebrow piercing heavy
	-fixed some eyebrow types not coloring correctly when dyeing
	-fixed chastity belt showing incorrectly on some bodies (chubby, fat, obese)
	-fixed hijab head outfit showing incorrectly on faces
	-added cybernetic feet basic
	-added cybernetic leg narrow basic
	-added cybernetic leg normal basic
	-added cybernetic leg wide basic
	-added cybernetic leg thick basic
	-added cybernetic butt 0 basic
	-added cybernetic butt 1 basic
	-added cybernetic butt 2 basic
	-added cybernetic butt 3 basic
	-added cybernetic butt 4 basic
	-added cybernetic butt 5 basic
	-added cybernetic butt 6 basic
	-added cybernetic arm left thumb down basic
	-added cybernetic arm left rebel basic
	-added cybernetic arm left high basic
	-added cybernetic arm left mid basic
	-added cybernetic arm left low basic
	-added cybernetic arm right high basic
	-added cybernetic arm right mid basic
	-added cybernetic arm right low basic
	-added cybernetic feet sexy
	-added cybernetic leg narrow sexy
	-added cybernetic leg normal sexy
	-added cybernetic leg wide sexy
	-added cybernetic leg thick sexy
	-added cybernetic butt 0 sexy
	-added cybernetic butt 1 sexy
	-added cybernetic butt 2 sexy
	-added cybernetic butt 3 sexy
	-added cybernetic butt 4 sexy
	-added cybernetic butt 5 sexy
	-added cybernetic butt 6 sexy
	-added cybernetic arm left thumb down sexy
	-added cybernetic arm left rebel sexy
	-added cybernetic arm left high sexy
	-added cybernetic arm left mid sexy
	-added cybernetic arm left low sexy
	-added cybernetic arm right high sexy
	-added cybernetic arm right mid sexy
	-added cybernetic arm right low sexy
	-added cybernetic feet beauty
	-added cybernetic leg narrow beauty
	-added cybernetic leg normal beauty
	-added cybernetic leg wide beauty
	-added cybernetic leg thick beauty
	-added cybernetic butt 0 beauty
	-added cybernetic butt 1 beauty
	-added cybernetic butt 2 beauty
	-added cybernetic butt 3 beauty
	-added cybernetic butt 4 beauty
	-added cybernetic butt 5 beauty
	-added cybernetic butt 6 beauty
	-added cybernetic arm left thumb down beauty
	-added cybernetic arm left rebel beauty
	-added cybernetic arm left high beauty
	-added cybernetic arm left mid beauty
	-added cybernetic arm left low beauty
	-added cybernetic arm right high beauty
	-added cybernetic arm right mid beauty
	-added cybernetic arm right low beauty
	-added cybernetic feet combat
	-added cybernetic leg narrow combat
	-added cybernetic leg normal combat
	-added cybernetic leg wide combat
	-added cybernetic leg thick combat
	-added cybernetic butt 0 combat
	-added cybernetic butt 1 combat
	-added cybernetic butt 2 combat
	-added cybernetic butt 3 combat
	-added cybernetic butt 4 combat
	-added cybernetic butt 5 combat
	-added cybernetic butt 6 combat
	-added cybernetic arm left thumb down combat
	-added cybernetic arm left rebel combat
	-added cybernetic arm left high combat
	-added cybernetic arm left mid combat
	-added cybernetic arm left low combat
	-added cybernetic arm right high combat
	-added cybernetic arm right mid combat
	-added cybernetic arm right low combat
	-added cybernetic feet swiss
	-added cybernetic leg narrow swiss
	-added cybernetic leg normal swiss
	-added cybernetic leg wide swiss
	-added cybernetic leg thick swiss
	-added cybernetic butt 0 swiss
	-added cybernetic butt 1 swiss
	-added cybernetic butt 2 swiss
	-added cybernetic butt 3 swiss
	-added cybernetic butt 4 swiss
	-added cybernetic butt 5 swiss
	-added cybernetic butt 6 swiss
	-added cybernetic arm left thumb down swiss
	-added cybernetic arm left rebel swiss
	-added cybernetic arm left high swiss
	-added cybernetic arm left mid swiss
	-added cybernetic arm left low swiss
	-added cybernetic arm right high swiss
	-added cybernetic arm right mid swiss
	-added cybernetic arm right low swiss
	-added penis flaccid circumcised 0
	-added penis flaccid circumcised 1
	-added penis flaccid circumcised 2
	-added penis flaccid circumcised 3
	-added penis flaccid circumcised 4
	-added penis flaccid circumcised 5
	-added penis flaccid circumcised 6
	-added penis flaccid circumcised 7
	-added penis flaccid circumcised 8
	-added penis flaccid circumcised 9
	-added penis flaccid circumcised 10
	-added penis erect circumcised 0
	-added penis erect circumcised 1
	-added penis erect circumcised 2
	-added penis erect circumcised 3
	-added penis erect circumcised 4
	-added penis erect circumcised 5
	-added penis erect circumcised 6
	-added penis erect circumcised 7
	-added penis erect circumcised 8
	-added penis erect circumcised 9
	-added penis erect circumcised 10

v1.3 (09/22/2018)
-------------
	-fixed shaved sides hairstyle showing incorrectly
	-fixed faces showing on restrictive latex
	-fixed restrictive latex not showing on bodies (chubby, fat, obese)
	-fixed accent band not showing on kimono belly outfits
	-fixed facial markings showing incorrectly on faces (birthmark,etc)
	-added eye coloring (irises only)
	-fixed lips showing only one color
	-added fox ears and tail
	-added cat ears and tail
	-fixed nipples not showing on attractive lingerie for a pregnant woman outfit
	-fixed black colored nipples showing on latex and bodysuits
	-fixed head accessory alignment to new faces (ball gag, dildo gag, etc)
	-changed art on porcelain mask
	-added eyes type-d
	-added mouth type-d
	-added nose type-d
	-added eyebrows type-d pencilthin
	-added eyebrows type-d thin
	-added eyebrows type-d threaded
	-added eyebrows type-d natural
	-added eyebrows type-d tapered
	-added eyebrows type-d thick
	-added eyebrows type-d bushy
	-added eyes type-e
	-added mouth type-e
	-added nose type-e
	-added eyebrows type-e pencilthin
	-added eyebrows type-e thin
	-added eyebrows type-e threaded
	-added eyebrows type-e natural
	-added eyebrows type-e tapered
	-added eyebrows type-e thick
	-added eyebrows type-e bushy
	-added eyes type-f
	-added mouth type-f
	-added nose type-f
	-added eyebrows type-f pencilthin
	-added eyebrows type-f thin
	-added eyebrows type-f threaded
	-added eyebrows type-f natural
	-added eyebrows type-f tapered
	-added eyebrows type-f thick
	-added eyebrows type-f bushy
	-separated faces by race/head shape (eg: white/exotic is different from asian/exotic)
	-made some eye types smaller
	-fixed stockings not covering thick thighs properly

v1.2 (09/16/2018)
-------------
	-added naked apron outfit (chubby, fat, obese)
	-added attractive lingerie (chubby, fat, obese)
	-added ballgown outfit (chubby, fat, obese)
	-added battlearmor outfit (chubby, fat, obese)
	-added battledress outfit (chubby, fat, obese)
	-added biyelgee costume (chubby, fat, obese)
	-added body oil outfit (chubby, fat, obese)
	-added bunny outfit (chubby, fat, obese)
	-added chains outfit (chubby, fat, obese)
	-added chattel habit outfit (chubby, fat, obese)
	-added cheerleader outfit (chubby, fat, obese)
	-added clubslut outfit (chubby, fat, obese)
	-added comfortable bodysuit outfit (chubby, fat, obese)
	-added conservative outfit (chubby, fat, obese)
	-added cutoffs and tshirt outfit (chubby, fat, obese)
	-added dirndl outfit (chubby, fat, obese)
	-added fallennun habit outfit (chubby, fat, obese)
	-added haltertop dress outfit (chubby, fat, obese)
	-added harem gauze outfit (chubby, fat, obese)
	-added hijab and abaya outfit (chubby, fat, obese)
	-added huipil outfit (chubby, fat, obese)
	-added kimono outfit (chubby, fat, obese)
	-added latex outfit (chubby, fat, obese)
	-added attractive lingerie for pregnant woman outfit (chubby, fat, obese)
	-added leotard outfit (chubby, fat, obese)
	-added lederhosen outfit (chubby, fat, obese)
	-added long qipao outfit (chubby, fat, obese)
	-added maternity dress outfit (chubby, fat, obese)
	-added military uniform outfit (chubby, fat, obese)
	-added minidress outfit (chubby, fat, obese)
	-added monikini outfit (chubby, fat, obese)
	-added mounty outfit (chubby, fat, obese)
	-added nice business attire outfit (chubby, fat, obese)
	-added nice maid outfit (chubby, fat, obese)
	-added nice nurse outfit (chubby, fat, obese)
	-added penitent nuns habit outfit (chubby, fat, obese)
	-added red army uniform outfit (chubby, fat, obese)
	-added scalemail bikini outfit (chubby, fat, obese)
	-added schoolgirl outfit (chubby, fat, obese)
	-added schutzstaffel uniform outfit (chubby, fat, obese)
	-added schutzstaffel uniform slutty outfit (chubby, fat, obese)
	-added shine outfit [Only applies to latex] (chubby, fat, obese)
	-added shibari rope outfit (chubby, fat, obese)
	-added slutty outfit (chubby, fat, obese)
	-reworked slutty outfit (changed to pasties)
	-added slave gown outfit (chubby, fat, obese)
	-added slutty business attire outfit (chubby, fat, obese)
	-added slutty jewelry outfit (chubby, fat, obese)
	-added slutty maid outfit (chubby, fat, obese)
	-added slutty nurse outfit (chubby, fat, obese)
	-updated slutty nurse outfit (now with 100% more hat)
	-added slutty qipao outfit (chubby, fat, obese)
	-added spats outfit (chubby, fat, obese)
	-added stretch pants outfit (chubby, fat, obese)
	-added string bikini outfit (chubby, fat, obese)
	-added succubus outfit (chubby, fat, obese)
	-added toga outfit (chubby, fat, obese)
	-added uncomfortable strap outfit (chubby, fat, obese)
	-added western outfit (chubby, fat, obese)
	-added eyes type-a
	-added mouth type-a
	-added nose type-a
	-added eyebrows type-a pencilthin
	-added eyebrows type-a thin
	-added eyebrows type-a threaded
	-added eyebrows type-a natural
	-added eyebrows type-a tapered
	-added eyebrows type-a thick
	-added eyebrows type-a bushy
	-added eyes type-b
	-added mouth type-b
	-added nose type-b
	-added eyebrows type-b pencilthin
	-added eyebrows type-b thin
	-added eyebrows type-b threaded
	-added eyebrows type-b natural
	-added eyebrows type-b tapered
	-added eyebrows type-b thick
	-added eyebrows type-b bushy
	-added eyes type-c
	-added mouth type-c
	-added nose type-c
	-added eyebrows type-c pencilthin
	-added eyebrows type-c thin
	-added eyebrows type-c threaded
	-added eyebrows type-c natural
	-added eyebrows type-c tapered
	-added eyebrows type-c thick
	-added eyebrows type-c bushy

v1.1 (07-11-2018)
-------------
	-added torso chubby
	-added torso fat
	-added torso obese
	-added butt enormous
	-added butt gigantic
	-added butt massive
	-added legs thick
	-added butt outfits enormous (x56)
	-added butt outfits gigantic (x56)
	-added butt outfits massive (x56)
	-fixed crotch coloring for dicks on dirndl
	-fixed crotch coloring for dicks on lederhosen
	-fixed crotch coloring for dicks on battlearmor
	-fixed crotch coloring for dicks on mounty outfit
	-fixed crotch coloring for dicks on long qipao
	-fixed crotch coloring for dicks on biyelgee costume
	-added leg outfits thick (x56)

v1.0 (07-03-2018)
-------------
	-added long qipao outfit
	-added battlearmor outfit
	-added mounty outfit
	-added dirndl outfit
	-added lederhosen outfit
	-added biyelgee costume outfit
	-added tiny nipple art
	-added cute nipple art
	-added puffy nipple art
	-added inverted nipple art
	-added huge nipple art
	-added fuckable nipple art
	-added partially inverted nipple art

v0.9 (05-05-2018)
-------------
	-added dynamic belly scaling (courtesy of @prndev)
	-added belly button art
	-fixed belly piercings not showing
	-updated belly piercing art
	-added belly outfit apron
	-added belly outfit bodysuit
	-added belly outfit cheerleader
	-added belly outfit clubslut
	-added belly outfit cutoffs (base only)
	-added belly outfit cybersuit
	-added belly outfit fallen nun (base only)
	-added belly outfit haltertop dress
	-added belly outfit hijab and ayaba
	-added belly outfit latex catsuit
	-added belly outfit leotard
	-added belly outfit nice maid
	-added belly outfit slutty maid
	-added belly outfit military (base only)
	-added belly outfit minidress
	-added belly outfit monokini (base only)
	-added belly outfit nice nurse
	-added belly outfit slutty nurse (base only)
	-added belly outfit red army uniform (base only)
	-added belly outfit schoolgirl (base only)
	-added belly outfit schutzstaffel (base only)
	-added belly outfit silken ballgown
	-added belly outfit skimpy battldress (base only)
	-added belly outfit slave gown
	-added belly outfit spats and a tank top (base only)
	-added belly outfit succubus (base only)
	-added belly outfit suit nice (base only)
	-added belly outfit suit slutty (base only)
	-added belly outfit bunny outfit
	-added belly outfit chattel habit (base only)
	-added belly outfit conservative clothing (base only)
	-added belly outfit harem gauze (base only)
	-added belly outfit huipil
	-added belly outfit kimono (base only)
	-added belly outfit maternity dress
	-added belly outfit slutty qipao
	-added belly outfit toga
	-added belly outfit western clothing
	-added belly outfit penitent nun (base only)
	-added belly outfit restrictive latex
	-added freckles as misc facial feature
	-added heavy freckles as misc facial feature
	-added beauty mark as misc facial feature
	-added birthmark as misc facial feature
	-minor outfit polishing on some outfits
	-polished outlines on torso art (normal, narrow, absurd)
	-reworked naked apron outfit
	-updated bangles outfit
	-fixed problems when surgically altering a slave's race
	-reworked clubslut netting outfit
	-updated cheerleader outfit
	-added AI personal assistant art
	-added blue-violet hair color
	-updated deep red hair color
	-added shaved armpit hair
	-added neat armpit hair
	-added bushy armpit hair
	-fixed male genitalia showing over large bellies
	-added porcelain mask accessory
	-added ability to custom color porcelain mask
	-added ability to custom color glasses
	-added slutty schutzstaffel uniform

v0.8 (04-21-2018)
-------------
	-added wispy pubic hair
	-added areola normal art
	-added areola large art
	-added areola wide art
	-added areola huge art
	-added areola star-shaped art
	-added areola heart-shaped art
	-converted stockings to a leg accessory
	-fixed issue that allowed stockings to be shown/selected on amputees
	-added visor hat to military outfit (per request)
	-fixed tilted neat pubic hair
	-fixed bellies/corsets showing at the same time if present/selected
	-major overhaul of skin tones
	-tweaked leg/hipsize/weight art distribution
	-fixed vaginal piercings not showing
	-updated vaginal piercing art
	-created porcelain mask accessory art
	-added cybersuit outfit
	-added skin/nipple tones for every race (courtesy of skinAnon)
	-added naked apron outfit
	-added schutzstaffel uniform
	-added red army uniform
	-darkened stocking art slightly (per request)

v0.7 (04-14-2018)
-------------
	-added sleeves to hijab and abaya outfit
	-added sleeves to cutoffs and a t-shirt outfit
	-added sleeves to skimpy battledress outfit
	-added sleeves to conservative outfit
	-added sleeves to huipil outfit
	-added sleeves to kimono outfit
	-added sleeves to nice maid outfit
	-added sleeves to military uniform outfit
	-added sleeves to nice nurse outfit
	-added sleeves to slutty nurse outfit
	-added sleeves to slutty qipao outfit
	-added sleeves to schoolgirl outfit
	-added sleeves to nice suit outfit
	-added sleeves to slutty suit outfit
	-added sleeves to western clothing outfit
	-removed thigh-highs/stockings on most outfits
	-fixed nipple piercings showing incorrectly
	-fixed boots showing incorrectly on some outfits
	-fixed 'invisible balls' on one of the scrotum sizes (the shadow was showing as skin color, removing the outline)
	-slutty nurse outfit now better matches the description
	-updated thigh boot art
	-updated extreme heel art
	-added bare feet stocking outfits (Long/short)
	-added additional flat shoe outfits (bare/stockings short/stockings long)
	-added additional heel shoe outfits (bare/stockings short/stockings long)
	-added additional pump shoe outfits (bare/stockings short/stockings long)

v0.6 (04-07-2018)
-------------
	-fixed bodysuit outfit color issue on non-default colors
	-fixed restrictive latex color issue on non-default colors
	-added hairstyle 'messy bun' (long/medium/short)
	-added hairstyle 'dreadlocks' (long/medium/short)
	-added hairstyle 'cornrows' (long/medium/short)
	-added hairstyle 'braided' (long/medium/short)
	-added hairstyle 'twintails' (long/medium/short)
	-added hairstyle 'shavedsides' (long/medium/short)
	-added chains outfit
	-added penitent nun outfit
	-reworked male genitalia
	-added bulge outfits for the appropriate outfits
	-removed transparency on clubslut, harem, and slutty torso outfits due to multiple issues
	-overhauled clubslut outfit to fix numerous art issues.
	-changed extreme heels
	-changed thigh high boots
	-overhauled breasts
	-reworked all breast outfits due to breast overhauled
	-changed breast positioning relative to the overall body
	-reworked corset lengths
	-reworked all breast and torso outfits for new breast compatibility

v0.5 (03-31-2018)
-------------
	-added belly scaling w/pregnancy+overfeeding
	-minor polishing on all outfits
	-fixed piercings not showing correctly
	-added nipple light piercings
	-added areola light piercings
	-added nipple heavy piercings
	-added areola heavy piercings
	-added vaginal dildo accessory
	-added vaginal long dildo accessory
	-added vaginal large dildo accessory
	-added vaginal long, large dildo accessory
	-added vaginal huge dildo accessory
	-added vaginal long, huge dildo accessory
	-added anal long plug accessory
	-added anal large plug accessory
	-added anal long, large plug accessory
	-added anal huge plug accessory
	-added anal long, huge accessory
	-added anal tail plug accessory (anal hook/bunny tail)
	-added first trimester pregnancy empathy belly
	-added second trimester pregnancy empathy belly
	-added third trimester pregnancy empathy belly
	-added third trimester twin pregnancy empathy belly
	-added tight corset torso accessory
	-added extreme corset torso accessory
	-cleaned up changelog wording for clarity purposes
	-added uncomfortable leather collar outfit
	-updated dildo gag collar graphic art
	-added massive dildo gag collar outfit
	-added ball gag collar outfit
	-added bit gag collar outfit
	-added silken ribbon collar outfit
	-added bowtie collar outfit
	-added ancient egyptian collar outfit
	-added hairstyle 'neat' (long/medium/short)
	-added hairstyle 'up' (long/medium/short)
	-added hairstyle 'ponytail' (long/medium/short)
	-added hairstyle 'bun' (long/medium/short)
	-added hairstyle 'curled' (long/medium/short)
	-added hairstyle 'messy' (long/medium/short)
	-added hairstyle 'permed' (long/medium/short)
	-added hairstyle 'eary' (long/medium/short)
	-added hairstyle 'luxurious' (long/medium/short)
	-added hairstyle 'afro' (long/medium/short)
	-fixed cowboy hat not showing on western outfit
	-fixed baldness on generic/generated non-selectable hairstyles

v0.4 (03-24-2018)
-------------
	-added nice lingerie outfit
	-fixed immersion breaking art on specific flat-chested outfits (somewhat)
	-added nurse slutty outfit
	-added silken ballgown outfit
	-added skimpy battledress outfit
	-minor polishing on all outfits
	-added slutty outfit
	-added spats and a tank top outfit
	-fixed graphical issues on mini dress
	-added succubus outfit
	-added nice suit outfit
	-added slutty suit outfit
	-added attractive lingerie for a pregnant woman outfit
	-added bunny outfit
	-added chattel habit outfit
	-updated fallen nun outfit (headdress added)
	-added conservative clothing outfit
	-added harem gauze outfit
	-added huipil outfit
	-added kimono outfit
	-added slave gown outfit
	-added stretch pants and a crop top outfit
	-updated schoolgirl outfit (sweater vest added)
	-added slutty qipao outfit
	-added toga outfit
	-added western clothing outfit (no cowboy hat)
	-fixed dick/ball clipping issues on all relevant outfits
	-added natural color nipples to match racial skin tones

v0.3 (03-17-2018)
-------------
	-added schoolgirl outfit
	-added fallennun outfit
	-added nice maid outfit
	-added slutty maid outfit
	-updated minidress outfit (changed color+fixes)
	-minor polishing on some outfits
	-added niqab and abaya outfit (niqab > hijab)
	-changed white colors on outfits to grey for increased contrast on light skin tones.
	-added nice nurse outfit
	-fixed outline issues on boots/extreme heels
	-fixed ultra black hair color issue (vanilla only)
	-added military uniform outfit
	-updated to latest pregmod git

v0.2 (03-10-2018)
-------------

	-added string bikini outfit
	-added scalemail bikini outfit
	-updated male genitalia display position
	-set default shoe colors to neutral (per request)
	-added some natural color nipples to match racial skin tones

v0.1 (03-03-2018)
-------------
	-updated boob graphic art
	-updated nipple graphic art
	-updated arm graphic art
	-updated female genitalia graphic art
	-updated waist graphic art
	-updated butt graphic art
	-added bushy pubic hair
	-added very bushy pubic hair
	-updated vaginal chastity belt
	-updated anal chastity belt
	-added uncomfortable strap outfit
	-added shibari rope outfit
	-updated restrictive latex outfit
	-updated latex catsuit outfit
	-updated extreme heel graphic art
	-updated pump shoes graphic art (not selectable in-game yet)
	-added bodysuit outfit
	-added body oil outfit
	-added haltertop dress outfit
	-added bangles outfit
	-added mini dress outfit
	-added leotard outfit
	-added t-shirt and cutoffs outfit
	-added cheerleader outfit
	-added clubslut netting outfit


code:
This document gives an overview of some of the economic mechanics, especially the ones spread across multiple files and functions.

Determining the prices for whoring;

The general principle behind the pricing is one of supply and demand.
Getting our hands on the appropriate information takes some doing due to how the game operates.
Supply and demand needs to be determined before the slave reports are generated, as such it takes place at the top of `slaveAssignmentsReport.tw`.
Finding the demand is relatively straightforward, as it depends on the current arcology population of the various classes as well as visitors.
Finding the supply requires more work as all slaves tasked with sexually serving the populace need to be considered.
The function `slaveJobValues()` takes care of pretty much all of that and can be found in `economyJS.js`.

`slaveJobValues()` takes into account gloryholes/arcade, public sluts/club sluts and street whores/brothel whores separately.
Gloryhole prices aren't too involved, since the 'product' is very homogenous and sluts don't get paid for their services.
Whores on the other hand have variable skills and appearance and may appeal to different classes of citizens.

`SJVBrothel()` takes care of general bonuses/penalties that all jobs have to some degree.
Near the end it determines the `value` of the whore by taking the above bonus, their `beauty()` and their `FResult()` score.
Previously `beauty()` determined the number of sexual acts and `FResult()` the price for them.
With the distinction between classes and the kind of sexual services they demand it became glaring that the best quality whores were used most heavily.
Shouldn't these talented slaves should be MORE exclusive, not less?

The function whoreScore() will be taking care of this oddity and it uses `beauty() * FResult()` as well as applicable modifiers to give us an `income` variable.
This `income` is the basis for the money the slave will be making, but will still be going through some modifications before the actual figure is produced later.
This is the amount of money they used to make and are still expected to make under standard circumstances but now it will be divided between sexual acts and their value in a different fashion.
whoreScore() also takes care of some slave sorting according to supply and demand.
Whenever the demand of the class a slave is trying to service is already met the function will determine if the slave should perhaps service a lower class instead.
It uses effectiveWhoreClass() to find out the maximum possible class a slave can service (or is allowed to service by the player), and demotes a slave for the week as needed.
After the class of citizens the slave will service is set the function takes care of the specific `sexAmount` and `sexQuality` the slave is providing.
The higher the class the more time and attention they demand from their whores. Generally a better slave servicing a higher class will fuck less than a lesser slave servicing a lower class.
The price per service is adjusted to compensate; `income` is the basis, `sexAmount` is partially set by the class serviced and `sexQuality` is `income / sexAmount`.
There is a maximum for the `sexAmount` and `sexQuality` for each class; On the one hand the slave only has so much time in the day and on the other citizens will only pay a particular amount of money.
There is also a minimum for `sexAmount`; a slave assigned to whore is expected to be working hard for the entire assignment, if needed the price will be adjusted to ensure a full work week for every slave.
The maximum amount of money a citizen is willing to pay depends on the rent they need to pay. Less rent means they have more spending money for other things, including whores.
Additionally servicing a higher class also comes with a little bonus in and of itself.

`slaveJobValues()` aggregates all sexual services done by a player's slaves, thus at the end of this function we know the supply provided by the player.
We must also consider the supply by other providers operating within the arcology, but this is relatively straightforward.
Combine the two and we now have the total supply for that week and we can finally compare supply and demand to provide a final price modifier.
Each class of citizens has their own demand and supply statistics and thus their own price modifier as well.
All of this once again takes place within the top part of `slaveAssignmentsReport.tw`.
When demand outstrips supply, a whore will receive a premium for their services, but not proportionally.
Supplying only half of what is demanded does not mean prices are doubled, they'll be increased by less than that.
Likewise when supply outstrips the demand a whore will receive less for their services, but not proportionally.
Doubling the demand reduces the price by significantly more than 50%.
There is however an absolute minimum of 30% of the standard price.

Finally, as each slave has their report generated they will actually be earning `sexAmount * sexQuality * supply/demand modifier`.

repo_name: Arkerthan/fc

path: devNotes/Economy notes.md

license: mit


code:
# Extended family mode (mod) #

In short, extended family mode replaces the old .relation + .relationTarget system with a completely new system capable of handling a limitless number of relatives. Or at least until your game crashes from trying to handle it all. Fully incompatible with the old system and fully functional with ng+.

## The backbone of the system: .father and .mother ##

Everything about a slave's family can be gathered by looking into her mother and father. Beyond the obvious mother-daughter relation, you can check two separate slaves' parents to see if they are related to each other, allowing for sisters, half-sisters, and with a .birthWeek check, twins with little effort.
The following values are used with .mother and .father:
Valid slave IDs (in other words, a value > 0) - Serves as both a target for checks and as a check itself to see if effort should be expended to search for the parent.
0 - Slave has no known parent. A slave with a parent value of 0 is capable of having a parent added via reRelativeRecruiter
MissingParentIDs (in other words, a value < -2) - Serves as a placeholder to preserve sibling relations in the case of a parent being sold or lost. Outside of extreme cases, this value will never be restored to its previous value. $missingParentID starts at -10000 and decrements after application. On NG+, positive values are incremented the same as a normal slave and checked for validity. Should it be invalid, it will be replaced with $missingParentID. Negative values, on the other hand, are decremented by 1200000. Values of -1 and -2 are ignored by the JS, so don't use them. Also -9999 through -9994 are used by hero slaves to preserve their sibling status no matter when they are purchased or obtained during the same game.

## The limiters: .sisters and .daughters ##
Extended family mode is VERY for loop intensive, and as such, has limiters to prevent it from needlessly looping. A value greater than 0 for either of these slave variables signals that slave has a sibling/daughter for various checks. Furthermore, the value of .sisters and .daughters accurately tracks the number of sisters and daughters, particularly for checks that require all of them to be found. You'll learn to hate these, but on the plus side, they can safely be recalculated with no side effects. Nearly entirely handled by <<AddSlave>> and removeActiveSlave, you do not understand how huge of a plus this is.

## The recruiting check: .canRecruit ##

Checked by reRelativeRecruiter to see if a slave is eligible to have relatives added. Hero slaves, special slaves, and often event slaves are ineligible for recruiting. Gets disabled if the slave is called into the recruiting event but fails to qualify for additional relatives due to unaddable slots or too many existing relatives.

## A quick list of the JS that gets things done and various useful JS calls: ##
```js
sameDad(slave1, slave2) // checks if the slaves share the same father and returns true/false.
sameMom(slave1, slave2) // checks if the slaves share the same mother and returns true/false.
sameTParent(slave1, slave2) // an exception catcher that handles such things as "slave1 knocked up slave2 and got impregnated by slave2, their children will be sisters" and returns the sister variable (0 - not related, 1 - twins, 2 - sisters, 3 - half-sisters). (subJS, never call on its own)
areTwins(slave1, slave2) // checks if the slaves are twins and returns true/false.
areSisters(slave1, slave2) // combines all of the above and returns the sister variable (0 - not related, 1 - twins, 2 - sisters, 3 - half-sisters). A widely used check to identify sister relatives. Generally gated by a .sisters check. Recommended to use in a <<switch>> macro instead of calling it for each outcome.

totalRelatives(slave) // returns how many relatives a slave has as an integer. Useful both as a check and for its value. Recommended to use as a check in instances where you want a relative, but don't care what it is.

mutualChildren(slave1, slave2, slaves) // checks the slave array for children shared by the two slave arguments and returns the number of mutual children as an integer. Currently used solely to encourage two slaves into a relationship if they have kids together.
```
The utility JS, courtesy of FCGudder. This JS should only be called if you know it will find something, use your limiters! These will always return the only relative if only one outcome is possible, so technically they can be used creatively. randomAvailable JS should be followed with random JS as a fallback for circumstances where you must find something, but would prefer it to be sensible if possible.
```js
randomRelatedSlave(slave, filterFunction) // returns a random related slave to the slave passed into it. filterFunction is called in the following JS but not needed if you just want a random relative.
randomRelatedAvailableSlave(slave) // returns a random available related slave.
randomSister(slave) // returns a random sister.
randomAvailableSister(slave) // returns a random available sister.
randomTwinSister(slave) // returns a random twin.
randomAvailableTwinSister(slave) // returns a random available twin.
randomDaughter(slave) // returns a random daughter.
randomAvailableDaughter(slave) // returns a random available daughter.
randomParent(slave) // returns a random parent.
randomAvailableParent(slave) // returns a random available parent.
```

path: devNotes/Extended Family Mode Explained.md


code:
# The pronouns system #
All references to scene actors shall be made via the pronouns object, returned by the `getPronouns()` function. The properties of the returned object contains strings to be used for referring to the actor or his actions. The object presents three property groups. The first one refers to pronouns by their grammatical names ('noun', 'object', 'pronoun', etc.). The rest of the groups provide the same values, but referred using gender-dependent names: he/she, his/her, etc. They are meant to be used in passage texts, and you can choose any group you like, the actual strings will be based on the slave object, which was passed as argument in the `getPronouns()` call.

## Usage examples ##

```js
const s = getPronouns(aSlave);
`Use ${s.his} mouth`
`Fuck ${s.him}`
`${s.He} is ready`
```

```
<<set _p = getPronouns(aSlave)>>
<<= _p.Girl>>s' butts are for loving
```

## Extending the pronouns system. ##

Consider a degradationism-based society where a slave is a thing. To extend the pronouns system, we create a successor of the `App.Utils.Pronouns` class:

```js
App.Utils.ThingPronouns = class extends App.Utils.Pronouns {
	get pronoun() { return "it" }
	get possessivePronoun() { return "its"; }
	get possessive() { return "its"; }
	get object() { return "its"; }
	get objectReflexive() { return "itself"; }
	get noun() { return "thing"; }
};
```
Notice, we override only the basic gender-neutral properties, and the rest of them use these values. Then we modify the `getPronouns()` code:

```js
if (/*degradationist society condition*/) {
	return new App.Utils.ThingPronouns(slave);
}
return new App.Utils.Pronouns(slave);
```


code:
QuickList is built from the interaction of six parts.

1. The Quick List option enable/disable control.
2. The list context, basically if there are more than one, and the
	context is correct, the toggle, the table will be available.
3. The Slave Summary Passage contains the Quick List toggle button,
	clicking it either shows or hides the quick list table.
4. The Slave Summary Passage contains the actual quick list table, which
	if shown has a button for each slave name in the list, in columns up
	to 5 wide.
5. The Slave Summary Passage contains invisible `<a>` links or any other
	html element nearby or tied to each slave's name. These are
	generated with an html attribute id set to "slave-##" where ## is the
	slave's ID.
6. The JS code to tie a scroll animation from the visible name buttons
	in the quick list table down to the invisible links/elements.

The slave summary passage is called in many strange contexts, and for
this reason, there is some serious complexity in getting consistent
results. As it stands now, the passage sometimes calls itself
recursively (for facilities), but it doesn't do that for the Main
penthouse page.

The list context is duplicated, so that we can quickly loop over the
list context to get the slave names in the list, all without disturbing
the principal list context for the slave data.

If the list context has more than one slave, and is either the first
call for the Main/penthouse list, or the recursive call for any other
facility, And we haven't *already* built a quick list table, then we
proceed to build the quick list table.

We use special attributes on the built button to name the invisible
link to which we'll navigate, the speed that we'll animate our
navigation and an offset.


code:
# Passages that require a go over for adding clothing and accessories. #

## Hair ##

	Definite:
		descriptionWidgetsStyle.tw
		salon.tw
		cosmeticRulesAssistant.tw

	Possible:
		generateXXSlave.tw
		generateXYSlave.tw
		artWidgets.tw
		saLiveWithHG.tw

		(mostly shaved/bald hairstyle checks, probably not worth checking)
		fPat.tw
		remoteSurgery.tw
		surgeryDegradation.tw
		saLongTermEffects.tw
		saAgent.tw
		rulesAutosurgery.tw
		autoSurgerySettings.tw
		ptWorkaround.tw
		newSlaveIntro.tw
		newChildIntro.tw
		RESS.tw

## Clothes ##

	Definite:
		descriptionWidgetsStyle.tw
		descriptionWidgetsFlesh.tw
		descriptionWidgetsPiercing.tw
		boobs.js
		fAbuse.tw
		walkPast.js
		slaveInteract.tw
		wardrobeUse.tw
		slaveSummaryWidgets.js
		rulesAssistantOptions.js
		toyChest.js
		useGuard.js
		birthWidgets.tw
		peConcubineInterview.tw
		PESS.tw
		RESS.tw

	Possible:
		artWidgets.tw
		saClothes.tw
		saChoosesOwnClothes.tw
		eventSelectionJS.js
		saLiveWithHG.tw
		setupVars.tw
		longSlaveDescription.tw

## Shoes ##

	Definite:
		descriptionWidgetsStyle.tw
		descriptionWidgetsFlesh.tw
		slaveInteract.tw
		walkPast.tw
		wardrobeUse.tw
		slaveSummaryWidgets.js
		rulesAssistant.tw

	Possible:
		saLongTermEffects.tw
		saClothes.tw
		saChoosesOwnClothes.tw
		eventSelectionJS.js
		RESS.tw
		REFI.tw
		saServeThePublic.js
		saWhore.js
		saLiveWithHG.tw
		artWidgets.tw
		reStandardPunishment.tw
		setupVars.tw
		fAnus.tw
		seBirthWidgets.tw
		raWidgets.tw

## Collars ##

	Definite:
		descriptionWidgetsStyle.tw
		fLips.tw
		walkPast.js
		slaveInteract.tw
		fKiss.tw
		wardrobeUse.tw
		rulesAssistant.tw
		RESS.tw

	Possible:
		saLongTermEffects.tw
		saClothes.tw
		saDevotion.tw
		raWidgets.tw
		artWidgets.tw
		reStandardPunishment.tw
		saChoosesOwnClothes.tw
		eventSelectionJS.tw
		assayWidgets.tw

--------------------------------------------------------------------------------------
OUTFITS BY TYPE — FOR REFERENCE ONLY

SEXUAL/EROTIC
=============
	Kitty Lingerie
	Slutty Jewelry
	Fallen Nun
	Chattel Habit
	Body Oil
	Pregnant Lingerie
	Nice Lingerie
	Latex Catsuit
	Bodysuit
	Skimpy Loincloth
	BDSM Pony outfit

FESTIVE/ENTERTAINMENT/TRADITIONAL/CULTURAL
=================================
	Kimono
	Qipao nice/slutty
	Biyelgee Costume
	Harem Gauze
	Dirndl
	Klan Robes
	Lederhosen
	Western Clothing
	Toga
	Huipil
	Bunny Outfit
	Succubus Costume
	Ballgown
	Slavegown
	Minidress
	Haltertop Dress
	Clubslut Netting
	Santa Dress
	Hanbok
	Gothic Lolita

EXERCISE/ATHLETICS
==================
	Leotard
	Monokini
	Stretch pants + croptop
	Spats and tank-top
	String Bikini
	Scalemail Bikini
	Cheerleader

CASUAL/DAILY
============
	Shimapan panties
	Hijab and Abaya
	Hijab and Blouse
	Niqab and Abaya
	Burqa
	Burkini
	Conservative Clothing
	Maternity Dress
	Schoolgirl
	Cutoffs + T-shirt
	Apron

PROFESSIONAL/OTHER
==================
	Maid Nice/Maid Slutty
	Suit nice/slutty
	Nurse nice/slutty

MILITARY/LAW ENFORCEMENT
========================
	Mounty
	Schutzstaffel Uniform nice/slutty
	Red Army Uniform
	Battledress
	Military Uniform
	Battlearmor
	Cybersuit
	Police outfit [Not in-game yet]

path: devNotes/clothing hair and accessory passages.md


code:
# JavaScript Exceptions

## Who captures exceptions?
If we don't catch the error manually, there are three different places where the error ends up being displayed to the
user. The exact place depends on the context of the executed code. These error messages show roughly the same information.

1. Captured and printed by us: `App.UI.DOM.formatException()`, hides path & shows version information.
    * Usually code which displays a passage.
2. Captured and printed by SugarCube: custom modification, hides path & shows version information.
    * Usually old twine passages
3. Captured and printed by Browser: Not hiding anything & does not show version information.
    * Usually callbacks

## Manual exception handling

With the movement away from passages as .tw files error handling is getting more important, especially proper cleanup.

A good example is [this issue](https://gitgud.io/pregmodfan/fc-pregmod/-/issues/2654), the end week animation did not stop because `App.EndWeek.slaveAssignmentReport()` failed, which
meant that the endweek animation stop call wasn't executed.

### Finally

Example of the proper way to handle code that cleans up something and should therefore always be executed:

```js
try {
    // setup code

    // other code, may fail
} finally {
    // cleanup code
}
```

Do note that this will still propagate the error up, it will just execute `cleanup code` first. If you want to handle
the error use `catch`

### Catch

If needed a catch clause can be used as well, but it is usually advisable to only catch specific errors and only if you
know they can be thrown and there is no easy way to prevent them.

Example with catch:

```js
try {
    // code that may throw a RangeError
}  catch (ex instanceof RangeError) {
    // error handling code
}
```

### Reference

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch


code:
## Eye Functions

In all functions `side` can be `left`, `right` or `both` unless stated otherwise.

Eye types: `1`: normal; `2`: glass; `3`: cybernetic
`0` is used as return value if there is no eye, but is never stored in the slave object.

Vision: `0`: blind; `1`: nearsighted (or impaired/blurred); `2`: normal

### Read-only functions

* `hasAnyEyes(slave)`:
    True if slave has at least one eye.

* `hasAnyNaturalEyes(slave)`:
    True if slave has at least one eye that is natural.

* `hasAnyProstheticEyes(slave)`:
    True if slave has at least one eye that is prosthetic (cybernetic or glass).

* `hasAnyCyberneticEyes(slave)`:
    True if slave has at least one eye that is cybernetic.

* `hasBothEyes(slave)`:
    True if slave has both eyes.

* `hasBothNaturalEyes(slave)`:
    True if slave has both eyes and they are natural.

* `hasBothProstheticEyes(slave)`:
    True if slave has both eyes and they are prosthetic (cybernetic or glass).

* `hasBothCyberneticEyes(slave)`:
    True if slave has both eyes and they are cybernetic.

* `hasLeftEye(slave)`:
    True if slave has left eye.

* `hasRightEye(slave)`:
    True if slave has right eye.

* `getLeftEyeType(slave)`:
    Returns type of the left eye.

* `getRightEyeType(slave)`:
    Returns type of the right eye.

* `getLeftEyeVision(slave)`:
    Returns vision of the left eye.

* `getRightEyeVision(slave)`:
    Returns vision of the right eye.

* `getBestVision(slave)`:
    Returns highest vision of both eyes.

* `getWorstVision(slave)`:
    Returns lowest vision of both eyes.

* `anyVisionEquals(slave, vision)`:
    True if one eye has the specified vision.

* `getLeftEyeColor(slave)`:
    Returns color of the left eye. If there is no eye `empty` is returned.

* `getRightEyeColor(slave)`:
    Returns color of the right eye. If there is no eye `empty` is returned.

* `getLeftEyePupil(slave)`:
    Returns the shape of pupil of the left eye. If there is no eye `circular` is returned.

* `getRightEyePupil(slave)`:
    Returns the shape of pupil of the right eye. If there is no eye `circular` is returned.

* `hasVisibleHeterochromia(slave)`:
    True if left and right eye colors are different. Does NOT relate to the genetic quirk.

* `getGeneticEyeColor(slave, side)`:
    Gives the genetic color of the specified eye.
    `both` is not allowed as value of `side`.

* `getLenseCount(slave)`:
    Counts the number of eyes that are not the genetic color.

### Description

* `App.Desc.eyesType(slave)`:
    Fits in a sentence like this: She has {return}.

* `App.Desc.eyeTypeToString(type)`:
    Converts an eye type to a string.
    `1` -> `natural`
    `2` -> `glass`
    `3` -> `artificial`

* `App.Desc.eyesColor(slave, adj = "", eye = "eye", eyes = "eyes")`:
    Fits in a sentence like this: She has {return}.
    `adj` is added in between color and eye like this: `brown wet eyes`.

* `App.Desc.eyeColor(slave)`:
    Fits in a sentence like this: She has {return} eyes.
    Prefer App.Desc.eyesColor if possible as it works reliably with only one eye. Example where this is better: {return}-eyed gaze

* `App.Desc.eyesVision(slave)`:
    Fits in a sentence like this: She has {return}.

* `App.Desc.eyesToVision(slave)`:
    Converts an eye vision to a string.
    `0` -> `blind`
    `1` -> `nearsighted`
    `2` -> `normal`

### Modification

* `eyeSurgery(slave, side, action)`:
    Modifies a slaves eyes.
    Allowed values for `action`:
    No Existing eyes required: `normal`, `glass`, `cybernetic`
    Existing eyes required: `remove`, `blind`, `blur`, `fix`

* `setEyeColor(slave, color, side = "both")`:
    Changes the visible eye color.

* `setEyeColorFull(slave, iris, pupil, sclera, side)`:
    Changes all visible parts of the eye.

* `setGeneticEyeColor(slave, color, heterochromia = false)`:
    Changes the genetic eye color. WARNING: If `heterochromia` is `true`, the function will add the genetic quirk, even if the slave did not have it before.

* `resetEyeColor(slave, side)`:
    Sets the eye color to the genetic color. Takes heterochromia and albinism into account.


code:
# Git setup & work cycle

## First time setup

0. [Install Git for terminal](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) or a Git GUI of your
   choice.
   * If you are on Linux Git is usually preinstalled.

1. Create an account on gitgud if you don't have a usable one.
    * (optional) Add an SSH key to your account for easier pushing. This allows you to connect to gitgud through SHH,
      which doesn't require your credentials every time.

2. Fork the main repository through gitgud interface.
   * (optional) Delete all branches other than pregmod-master, so you don't get them locally when fetching.

3. Clone the repo
   * Clicking on the dropdown arrow on the far right blue clone button in the GitGud interface on your fork gives you
     the relevant URLs. If you added an SSH key in step 2, use the SSH URL, otherwise use the HTTPS one.
   * Via terminal: `git clone --depth 1 <url-to-your-fork>`

4. Change into the new directory
   * Via terminal: `cd fc-pregmod`

5. Add the main repository as a remote target
   * Via terminal: `git remote add upstream https://gitgud.io/pregmodfan/fc-pregmod.git`

6. Make your local `pregmod-master` track the main repository, makes getting future updates easier.
   * Via terminal `git branch --set-upstream-to=upstream/pregmod-master`

## Typical cycle with Git:

0. Switch to the `pregmod-master` branch, then apply any updates from upstream
   * Via terminal: `git checkout pregmod-master && git pull upstream`

1. Checkout a new branch for your work
   * Via terminal: `git checkout -b <branch-name>`

2. Make desired changes

3. Add your changes to be committed
   * Via terminal: `git add *`

4. Commit your changes
   * Via terminal: `git commit`
   * Make the commit message useful (`Fix X`, `Add Y`, etc.)

5. (optional, but recommended) Run sanityCheck before final push to catch any errors you missed.
   * You can ignore errors that already existed

6. Push result into your forked repository
   * Via terminal:
      * Initially: `git push -u origin $(git rev-parse --abbrev-ref HEAD)`
      * Afterwards `git push` will suffice.

7. Create merge request through gitgud interface.
   * Suggestion: Tick `Delete source branch when merge request is accepted.` to help automatically tidy up your fork.

8. Checkout `pregmod-master` in preparation of next change.
   * Via terminal: `git checkout pregmod-master`

9. Once the merge request was accepted, delete your local branch.
   * Via terminal: `git branch -d <branch-name>`

## Tips

* Never commit anything on the main `pregmod-master` branch, always use feature branches.
* To check the current state of your local copy, use `git status`.
* To get a list of all current branches run `git branch --list` via terminal.


code:
Induced NCS:
		The idea is a genetic change that you can't undo, once done. It is an expensive damaging process, and the
		first time it is run many of the secondary sexual characteristics development will reverse strongly:
		including height, hips width, shoulders width, dick or clit size, labia or scrotum size, and breast size.
		In addition, from then on, every week a small chance of shrinking any of these items. In addition, growth
		features (drugs, hormones, food) work at a disadvantage, while growth-reversal features (drugs, hormones,
		food) work at an advantage. Finally, precocious puberty is generically incremented, such that drugs,
		hormones or treatments that advance puberty are heightened while simultaneously drugs, hormones or
		treatments that work against puberty are lowered, with the exception of hormone blockers, which work as
		advertised.

Slaves generated with `.inducedNCS` set to 0, and added to the backwards compatibility.

Purchased only in the black market.
		Implemented a skeleton 'illegal goods' black market patterning it after the existing FS shopping in the
		black market.

Added description in the Encyclopedia.

Updated Surgery, unlike most surgery, can't be applied to unhealthy slaves `(health > 0)`.

Updated Surgery Degradation.

Updated sa Drugs.

Updated sa Hormones.

Updated sa Long Term Effects.

Added NCS youthening.

NCS youthening, NCS will youthen slave appearances towards 8 years old if older, while younger slaves will
simply, not appear to age at all.
1. every slave visually appearing less than 9 will not be affected.
2. visually 45 yrs and over will always look 1 year younger each week.
3. from 44 down to 9, the slave accumulates NCSyouthening points every week building towards a sliding youthening value which starts at 2 weeks for 44, and evenly progresses towards 10 weeks for slaves 12 and under.

Formula, slaves <= 8 are ignored.

Calculate `_youtheningDifference` the slaves visual age less 8, yielding 0 to say 38 or so, more than that will be dealt with further down the line. Take the `_youthDifference` divide by four and add .25 to evenly break into 0 below 9, and 10 at 45, round to int to get the `_youtheningLevel`. Subtract `_youtheningLevel` from 11 to find out the `_youtheningRequirement`

Every week, slaves that appear older than 8 year old lolis or shotas will have their NCSyouthening incremented. Then this youthening is tested against the `_youtheningRequirement`, if at or better, the NCS youthens the slave, and resets the `NCSyouthening`.

Slaves generated with `.NCSyouthening` set to `0`, and added to the backwards compatibility.


code:
# Creating your event

It would be useful to have the [JS functions Documentation](devNotes/usefulJSFunctionDocumentation.txt) open and in particular the "Core Slave Functions" section.

First decide your events name (e.g. `MyEvent`)

```js
App.Events.MyEvent = class MyEvent extends App.Events.BaseEvent {
	// The event only fires if the optional conditions listed in this array are met. This can be empty/not present.
	eventPrerequisites() {
		// Conditional example
		return [
			() => V.plot === 1
		];
		return []; // empty example
	}

	// Each position in the array correlates to conditions that a slave must meet to be selected. This can be empty/not present.
	actorPrerequisites() {
		// Single slave
		return [
			[
				s => canWalk(s),
				s => s.fetish !== Fetish.MINDBROKEN,
				s => s.devotion >= 50,
				s => s.trust <= 20
			]
		];

		// Dual slave
		return [
			[ // first actor
				s => canWalk(s),
				s => s.fetish !== Fetish.MINDBROKEN,
				s => s.devotion >= 50,
				s => s.trust <= 20
			],
			[ // second actor
				s => s.ID === getSlave(this.actors[0]).mother
			]
		];

		return [[]]; // One actor, but any slave will do
		return []; // Empty (no actors at all, see plot events and about half or individual events)
	}

	execute(node) {
		/** @type {Array<App.Entity.SlaveState>} */
		let [eventSlave] = this.actors.map(a => getSlave(a));
		const { He, he, His, his, him, himself } = getPronouns(eventSlave); // In this example we assign the left hand local variables to already defined output of the same name from the getPronouns function. Said function is designed to handle the PC object as well.
		const { HeU, heU, hisU, himU, himselfU } = getNonlocalPronouns(V.seeDicks).appendSuffix('U'); // This line handles none actor objects e.g. background characters based on both V.seeDicks (which is the ratio of slaves with dicks vs true females) and if the player has enabled diverse pronouns else the background character will always be considered female. Using 'U' is simply a convention.
		App.Events.drawEventArt(node, eventSlave, "no clothing"); // show slave art, temporarily rendering the chosen slave nude, just for the purposes of this code path within this event.

		// It is a best practice to organize event text into paragraphs.
		// That way you don't have to worry about funky spacing problems.
		// addParagraph (or the equivalent SpacedTextAccumulator.toParagraph) should be by FAR the majority case for text.

		App.Events.addNode(node, [`${He} shoves ${himU} to the ground.`], "span", ["yellow"]); // This would be rendered in yellow as "He/She (slave A) shoves she/him (none slave) to the ground.", depending how the player has configured their game.

		// Event branches
		App.Events.addResponses(node, [
		new App.Events.Result(`Text shown to user`, choiceA),
		...
		]);

		function choiceA() {
			App.Events.addNode(node, [
				`Bla bla.`,
				`Some more words.`,
			], "p"); // The above is rendered as a new paragraph with the content of "Bla bla. Some more words." - please note how spacing it automatically handled for you.
			// additional code if needed
			// effects on the actors
			eventSlave.devotion += 4;
			eventSlave.trust += 4;
			// To insert a few words of coloured text you have two main options, the later being preferred. Regardless, generally full stops and other natural break points should be included in any coloring.
			return App.Events.addNode(node, [
				`Bla bla.`,
				`<span class="yellow">Milk and cheese</span>.`, // Option A
				App.UI.DOM.makeElement("span", `Moon rocks are heavy.`, ["blue"]), // Option B
			], "p"); // Renders the above as a new paragraph with the content as: "Bla bla. Milk and cheese. (yellow) Moon rocks are heavy. (blue)" e.g. https://gitgud.io/pregmodfan/fc-pregmod/uploads/764ef42ac966f2551ac826aebac1f2aa/image.png
		}
	}
};
```

## Dealing with lisping

Use `getEnunciation()` and `Spoken()` when dealing with slave dialog. For example:

```js
const {say, title: Master} = getEnunciation(eventSlave);

return `"${Spoken(eventSlave, `Some text, ${Master},`)}" says ${eventSlave.slaveName}.`;
```

## Adding your event to the pool

Now that your event has been created, it needs to be added to the pool of possible events for its type.
For most events, as well as for our example, this is in Random Individual Event.
This pool can be found at `src/events/randomEvent.js`.
Simply add your event to the array in `App.Events.getIndividualEvents`.

## Testing

In the Options menu, open the "Debug & cheating" tab and enable “Cheat Mode”.
Once you get to "Random Individual Event" select any slave and at the bottom under DEBUG: there should be
 a input box with "Check Prerequisites and Casting" link next to it.
Per the example under it, place your event's full name into it e.g. App.Events.myEvent and then hit said link.
If everything works as intended you should see output

## Examples

### Single slave

- [src/events/RESS/devotedFearfulSlave.js](src/events/RESS/devotedFearfulSlave.js)

### Dual slave

- [src/events/reDevotedTwins.js](src/events/reDevotedTwins.js)


code:
// switch (V.surgeryType) {
/*

case "amp1":
V.nextLink = "Surgery Degradation", V.surgeryType = "amp";
r.push(`Since you have already have a prosthetic interface prepared for this slave, you can install it during the operation.<br>`);
r.push(`The procedure will put additional strain on ${his} health but less so than if you were to perform the procedures separately.`);
if (isProstheticAvailable(slave, "interfaceP1")) {

[[Install basic interface|Surgery Degradation][slave.PLimb = 1, slave.health.condition -= 10, V.surgeryType = "amp2", V.nextLink = "Surgery Degradation"]]
}
if (isProstheticAvailable(slave, "interfaceP2")) {

[[Install advanced interface|Surgery Degradation][slave.PLimb = 2, slave.health.condition -= 10, V.surgeryType = "amp2", V.nextLink = "Surgery Degradation"]]
}

break;
case "amp2":
if (slave.fetish === "mindbroken") {
r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. ${He} squirms the entire time trying to move the arms and legs ${he} now lacks, never noticing the ports in ${his} stumps. Since the surgery was invasive, ${his} health has been greatly affected.`);
} else if (slave.devotion > 50) {
r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. ${He} knows what a slave's life is, but ${he} did not really expect that it would ever come to this for ${him}. Anesthesia has yet to completely wear off so it takes ${him} a while to notice ports in ${his} stumps. When ${he} does, ${he} visibly relaxes, realizing ${he} may yet walk again. ${He} squares ${his} shoulders and visibly resolves to carry on being a good slave as best ${he} can. Since the surgery was invasive, ${his} health has been greatly affected.`);
} else if (slave.devotion > 20) {
r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. Despite ${his} obedience, ${he} cries softly the whole time, shoulder and hip stumps moving occasionally as ${he} reflexively tries to stand — to walk — to touch ${himself} — to gesture — all things that ${he} will never do again. ${He} slightly calms down when ${he}`);
if (canSee(slave)) {
r.push(`sees`);
} else {
r.push(`feels`);
}
r.push(`ports installed in ${his} stumps and realizes ${his} immobility is not permanent. Even so, ${he} is still terrified of your total power over ${his} body. ${He} will struggle greatly with ${his} medically created disability. Since the surgery was invasive, ${his} health has been greatly affected.`);
slave.trust -= 10;
slave.devotion -= 10;
} else {
r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. You had a good idea what ${his} reaction would be, so`);
if (slave.teeth === "removable") {
r.push(`you removed ${his} teeth`);
} else {
r.push(`${he}'s muzzled`);
}
r.push(`to prevent ${him} from trying to bite. ${He} sobs convulsively, and ${his}`);
if (canSee(slave)) {
r.push(`eyes dart desperately from side to side through ${his} tears, hopelessly imploring the mirror to show ${him} something other than this.`);
} else {
r.push(`stumps twitch pathetically with ${his} desperate efforts to move ${his} limbs, to prove there is something other than this.`);
}
r.push(`Anything other than this. The surgical invasion has filled ${him} with horror and anger. Since the surgery was invasive, ${his} health has been greatly affected. ${He} is terrified to the point of insanity of your total power over ${his} body.`);
slave.trust -= 50;
slave.devotion -= 50;
}

V.prostheticsConfig = "interface";
<<include "Prosthetics Configuration">>
V.nextLink = "Remote Surgery";
break;
*/
/* This was moved to prostheticsConfig.tw
case "basicPLimbs":
r.push(`${He} exits the surgery hesitantly, the software of ${his} prosthetic limbs and the wetware of ${his} brain working together to figure out how to walk together under the tutelage of a prescribed tutorial. Recovery will be significant, since the surgical implantation of anchor points for the limbs themselves and the installation of nerve impulse detectors constituted major surgery.`);
if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
	if (slave.devotion > 20) {
		r.push(`Nevertheless, ${he}'s overwhelmed with gratitude, and thanks you profusely the first chance ${he} gets. ${He} follows the acclimation program diligently, doing ${his} best to learn how to be a good slave despite, or sometimes even because of, ${his} artificial arms and legs. ${He} places more trust in you, too, since you obviously have ${his} best interests at heart.`);
		slave.devotion += 5;
slave.trust += 5;
	} else if (slave.devotion >= -20) {
		r.push(`${He}'s overwhelmed with gratitude, in part because ${he} didn't think you'd do something like this for ${him}. ${He} thanks you profusely the first chance ${he} gets, and follows the acclimation program diligently, trying to deserve the expense you went to. ${He} places more trust in you, too, since you seem to have a plan for ${him}.`);
		slave.devotion += 5;
slave.trust += 5;
	} else {
		r.push(`Despite ${his} hatred of you, ${he} can't help but trust you a bit more, since you clearly have a plan that involves putting a good deal of value into ${him}. Your goals might not be ${hers}, but at least ${he} has an indication that you're not toying with ${him}.`);
		slave.trust += 5;
	}
}

break;
case "sexPLimbs":
r.push(`${His} Limb upgrades took place in the surgery, since its manipulators are well suited to delicate work on circuitry and ceramics as well as on flesh. ${He} exits the surgery experimenting with ${his} new arms and legs.`);
if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
	if (slave.devotion <= 20) {
		r.push(`${He} rapidly discovers that ${his} fingertips are now vibrators, and then makes a mess when ${he} figures out that ${his} hands can dispense lube without figuring out how to make them stop dispensing lube. ${He}'s frustrated and frightened, realizing that even ${his} prosthetics are now customized to suit ${his} purpose as a human sex toy. ${He} knew ${he} was a toy before, but somehow, being a literal vibrator is a bit much for ${him}.`);
		slave.trust -= 5;
	} else if (slave.energy > 95) {
		r.push(`Since ${he}'s a nympho, ${he} discovers ${his} new sexual functions in a hurry. They trigger in part is based on arousal, and ${he}'s never not aroused, so they activate one by one as ${he} leaves the surgery. The vibration, lube, and other dirty functions surprise ${him}, and it takes ${him} a moment to realize what's going on, but ${he} begins to breathe hard when ${he} understands. ${He} runs off to try them out, and thanks you profusely, if tiredly, the next time ${he} sees you.`);
		slave.devotion += 5;
	} else {
		r.push(`${He} discovers ${his} sexy new functions one by one. The vibration, lube, and other dirty functions surprise ${him}, and it takes ${him} a moment to realize what's going on, but ${he} begins to shake with amusement when ${he} understands. ${He} heads off to try them out, and thanks you politely the next time ${he} sees you.`);
		slave.devotion += 3;
	}
}

break;
case "beautyPLimbs":
r.push(`${His} Limb upgrades took place in the surgery, since its manipulators are well suited to delicate work on circuitry and ceramics as well as on flesh. ${He} exits the surgery`);
if (canSee(slave)) {
r.push(`marveling at the beautiful, natural appearance of ${his} new arms and legs.`);
} else {
r.push(`thanking you for ${his} new arms and legs, unaware of how natural they look.`);
}
if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
	if (slave.devotion <= 20) {
		r.push(`${He}'s <span class="mediumaquamarine">more willing to trust you</span> after this. If ${he} doubts that you have some sort of long term plan for ${him}, all ${he} has to do is`);
if (canSee(slave)) {
r.push(`look down and examine`);
} else {
r.push(`feel`);
}
r.push(`${his} elegant, natural prosthetics, which are often mistaken for the genuine article. Even ${he} makes the mistake at times as ${he} gets used to them.`);
		slave.trust += 5;
	} else if (slave.skill.entertainment >= 100) {
		r.push(`Since ${he}'s a masterful entertainer, ${he} knows multiple styles of dance, though ${his} straightforward modern prosthetics never allowed ${him} to be anything more than a mechanically competent dancer. ${He} finds that ${he} has far better balance now, in addition to looking more natural. Before long, ${he} goes //en pointe// and holds the position, before collapsing in a heap. It soon becomes apparent that this wasn't due to clumsiness: ${he}'s sobbing so hard ${he} can barely breathe. ${He} thanks you profusely the next time ${he} sees you, eyes still puffy with tears of joy.`);
		slave.devotion += 5;
	} else {
		r.push(`When ${he} first`);
if (canSee(slave)) {
r.push(`catches sight of ${himself} in a mirror,`);
} else {
r.push(`runs a new finger over ${his} natural feeling skin,`);
}
r.push(`${he} begins to cry. Terribly complex emotions war across ${his} face: gratitude, joy, regret, and something undefinable. Blinking, ${he} uses newly elegant fingertips to trace the scarcely visible seams where ${his} artificial and natural skin meet. ${He} thanks you profusely the next time ${he} sees you, eyes still puffy with tears.`);
		slave.devotion += 3;
	}
}

break;
case "combatPLimbs":
r.push(`${His} Limb upgrades took place in the surgery, since its manipulators are well suited to delicate work on circuitry and ceramics as well as on flesh. ${He} exits the surgery wondering at the bulky`);
if (canSee(slave)) {
r.push(`appearance`);
} else {
r.push(`weight`);
}
r.push(`of ${his} reinforced arms and legs.`);
if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
	if (slave.devotion <= 20) {
		r.push(`${He}'s frightened, once ${he} discovers what ${he} can do, and what ${he} is. ${His} integral weapons are locked out by the arcology systems, for now, but ${he} quickly realizes what they are. ${He} is not, to say the least, thrilled by the revelation that ${he} is now a living weapon, and is kept awake by thoughts of what you might be planning for ${him}.`);
		slave.trust -= 5;
	} else if (slave.skill.combat === 1) && (slave.devotion > 75) {
		r.push(`${He} leaves the surgery with a purpose, ${his} footsteps a bit heavier than before. ${He} heads down to the armory's range, still naked, and when ${he} gets there, ${he} places ${his} dominant hand over ${his} thigh on that side. It folds open, revealing a handgun, which ${he} draws and empties into a`);
if (canSee(slave)) {
r.push(`target`);
} else {
r.push(`beeping target`);
}; as ${he} fires the last rounds, ${he} uses ${his} off hand to reach down to that thigh, which folds open and reveals spare magazines. ${He} thanks you profusely the next time ${he} sees you. ${He} knows that ${his} prosthetics are a wash, at best, in terms of actual combat effectiveness; they'll never match the reliability and dexterity of the genuine article. But ${he} thinks they are //cool.//
		slave.devotion += 5;
	} else {
		r.push(`${He} has mixed feelings about what ${he} soon discovers. ${He}'s a living weapon now, and has to live with the constant knowledge that ${he} can incapacitate or kill with nothing more than what's contained within ${his} arms and legs. ${He}'s touched, though, by the tremendous trust this shows. ${He} knows that the arcology would instantly lock out ${his} weapons if ${he} were to misbehave, but ${he}'s still affected.`);
		slave.devotion += 3;
	}
}

break;
case "cyberPLimbs":
r.push(`${His} Limb upgrades were performed in the surgery, since its manipulators are well suited to delicate work on their circuitry as well as on flesh. ${He} exits the surgery marveling`);
if (canSee(slave)) {
r.push(`at the shiny artificial skin of ${his} new arms and legs.`);
} else {
r.push(`at the feel of the artificial skin of ${his} new arms and legs under ${his} new fingers.`);
}
if (slave.fetish !== "mindbroken" && slave.fuckdoll === 0) {
	if (slave.devotion <= 20) {
		r.push(`${He}'s frightened, once ${he} discovers what ${he} can do, and what ${he} is. ${His} cybernetic limbs are restricted by the arcology systems, for now, but ${he} quickly realizes what they are. ${He} is not, to say the least, thrilled by the revelation that ${he} is now a living weapon, and is kept awake by thoughts of what you might be planning for ${him}.`);
		slave.trust -= 5;
	} else if (slave.skill.combat === 1) && (slave.devotion > 75) {
		r.push(`${He} leaves the surgery with a purpose, ${his} footsteps a bit heavier than before. ${He} heads down to the armory's range, still naked, and when ${he} gets there, ${he} places ${his} dominant hand over ${his} thigh on that side. It folds open, revealing a handgun, which ${he} draws and empties into a`);
if (canSee(slave)) {
r.push(`target`);
} else {
r.push(`beeping target`);
}; as ${he} fires the last rounds, ${he} uses ${his} off hand to reach down to that thigh, which folds open and reveals spare magazines. ${He} thanks you profusely the next time ${he} sees you. ${He} knows that ${his} prosthetics will enhance ${his} combat effectiveness and ${he} thinks they are //cool.//
		slave.devotion += 5;
	} else {
		r.push(`${He} has mixed feelings about what ${he} soon discovers. ${He}'s a living weapon now, and has to live with the constant knowledge that ${he} can incapacitate or kill with nothing more than ${his} arms and legs themselves. ${He}'s touched, though, by the tremendous trust this shows. ${He} knows that the arcology would instantly lock out ${his} limbs if ${he} were to misbehave, but ${he}'s still affected.`);
		slave.devotion += 3;
	}
}

break;
case "removeLimbs":
if (slave.fetish === "mindbroken") {
	r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. ${He} squirms the entire time trying to move the arms and legs that ${he} used to have. As with all surgery ${his} health has been slightly affected.`);
} else if (slave.devotion > 50) {
	r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. ${He} knows what a slave's life is, but ${he} did not really expect ${his} artificial limbs would be removed again so suddenly. After a long, silent`);
if (canSee(slave)) {
r.push(`stare at`);
} else {
r.push(`consideration of`);
}
r.push(`${his} limbless torso, ${he} squares ${his} shoulders and visibly resolves to carry on being a good slave as best ${he} can. As ${he} was already amputated, there was no lasting effect. As with all surgery ${his} health has been slightly affected.`);
} else if (slave.devotion > 20) {
	r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. Despite ${his} obedience, ${he} cries softly the whole time, shoulder and hip stumps moving occasionally as ${he} reflexively tries to stand — to walk — to touch ${himself} — to gesture — all things that ${he} had to learn to do again. Your removal of ${his} prosthetic limbs has caused ${his} devotion to drop and ${his} trust to drop. As with all surgery ${his} health has been slightly affected.`);
	slave.trust -= 5;
slave.devotion -= 5;
} else {
	r.push(`Of course, ${he} could not walk out of the surgery; you carried ${him}. It seems that ${his} mistrust of you was well founded and this removal of ${his} artificial limbs has caused ${his} devotion to drop and ${his} trust to drop. As with all surgery ${his} health has been slightly affected.`);
	slave.trust -= 5;
slave.devotion -= 5;
}
break;
*/
//	default:
//		r.push(`ERROR bad/missing surgery description`);
//		r.push(`surgeryType: ${V.surgeryType}`);
//		r.push(`Devotion: ${slave.devotion}`);
//


code:
:: art widgets [nobr widget]

/%
Call as <<AssistantArt>>
Displays assistant images. Currently passage-based.
$args[0]: Image size/center.
	3: Large, right. Example: description.
	2: Medium, right. Example: random events.
%/
<<widget "AssistantArt">>

<<if $imageChoice == 0>> /* RENDERED IMAGES BY SHOKUSHU */

<<switch $assistantAppearance>>
<<case "monstergirl">>
	<<set _fileName = "'resources/renders/assistant monstergirl.png' ">>
<<case "shemale">>
	<<set _fileName = "'resources/renders/assistant shemale.png' ">>
<<case "amazon">>
	<<set _fileName = "'resources/renders/assistant amazon.png' ">>
<<case "businesswoman">>
	<<set _fileName = "'resources/renders/assistant businesswoman.png' ">>
<<case "goddess">>
	<<set _fileName = "'resources/renders/assistant goddess.png' ">>
<<case "schoolgirl">>
	<<set _fileName = "'resources/renders/assistant schoolgirl.png' ">>
<<default>>
	<<set _fileName = "'resources/renders/assistant default.png' ">>
<</switch>>
<<if $args[1] == 3>>
	<<print "">>
<<else>>
	<<print "">>
<</if>>

<</if>> /* CLOSES IMAGE CHOICE */

<</widget>>

/%
Call as <<SlaveArt>>
Displays slave images. Currently passage-based.
$args[0]: Slave.
$args[1]: Image size/center.
	3: Large, right. Example: long slave description.
	2: Medium, right. Example: random events.
	1: Small, left. Example: lists.
	0: Tiny, left. Example: facilities
$args[2]: icon UI Display for vector art, 1 for on.
%/
<<widget "SlaveArt">>
/* This is a nasty workaround for Chrome not rendering overlaid SVG images properly */
<<run jQuery(function() { jQuery('.imageRef').imagesLoaded().always(function() { jQuery('.imageRef').fadeTo(1, 0.999); }); })>>
<<if ndef $args[0].customImage>><<set $args[0].customImage = 0>><</if>>
<<if $args[0].customImage != 0>>

<<set _fileFormat = ($args[0].customImageFormat || "png"),
	_fileName = "'resources/" + $args[0].customImage + "." + _fileFormat + "' ",
	_fileTypeStart = (_fileFormat === "webm" ? "video loop autoplay" : "img"),
	_fileTypeEnd = (_fileFormat === "webm" ? "</video>" : "")>>

<<if $args[1] == 3>>
	<<print "<" + _fileTypeStart + " src=" + _fileName + "style='float:right; border:3px hidden'>" + _fileTypeEnd>>
<<elseif $args[1] == 2>>
	<<print "<" + _fileTypeStart + " src=" + _fileName + "style='float:right; border:3px hidden' width='300' height='300'>" + _fileTypeEnd>>
<<elseif $args[1] == 1>>
	<<print "<" + _fileTypeStart + " src=" + _fileName + "style='float:left; border:3px hidden' width='150' height='150'>" + _fileTypeEnd>>
<<else>>
	<<print "<" + _fileTypeStart + " src=" + _fileName + "style='float:left; border:3px hidden' width='120' height='120'>" + _fileTypeEnd>>
<</if>>

<<elseif $imageChoice == 1>> /* VECTOR ART BY NOX */
<<SVGFilters>>

/* 000-250-006 */
/*
 */
/* 000-250-006 */

<<set _folderLoc = "'resources/vector">>

<<if $args[2] == 1>>
	<<print "">>
<</if>>

/% Set skin color %/
<<set _skinFilter = "filter: url(#skin-" + _.kebabCase($args[0].skin) + ");">>
/% Set hair color %/
<<set _hairFilter = "filter: url(#hair-" + _.kebabCase($args[0].hColor) + ");">>
<<set _pubesFilter = "filter: url(#hair-" + _.kebabCase($args[0].pubicHColor) + ");">>
<<set _axillaryFilter = "filter: url(#hair-" + _.kebabCase($args[0].underArmHColor) + ");">>
<<if $args[0].customHairVector>>
	<<set _hairStyle = $args[0].customHairVector>>
<<else>>
	<<set _hairStyle = ["neat", "ponytail", "messy"].includes($args[0].hStyle) ? $args[0].hStyle : "neat">>
<</if>>

<<set _imgSkinLoc = _folderLoc + "/body/white">>

/% Shoulder width and arm or no arm %/
<<if $args[0].amp != 1>>
<<if $args[0].devotion > 50>>
	<<set _leftArmType = "high">>
	<<set _rightArmType = "high">>
<<elseif $args[0].trust >= -20>>
	<<if $args[0].devotion < -20>>
		<<set _leftArmType = "rebel">>
		<<set _rightArmType = "low">>
	<<elseif $args[0].devotion <= 20>>
		<<set _leftArmType = "low">>
		<<set _rightArmType = "low">>
	<<else>>
		<<set _leftArmType = "mid">>
		<<set _rightArmType = "high">>
	<</if>>
<<else>>
	<<set _leftArmType = "mid">>
	<<set _rightArmType = "mid">>
<</if>>
<<if $args[0].fuckdoll == 0 && $args[0].clothes != "restrictive latex" && $args[0].clothes != "a latex catsuit">>
	<<print "">>
	<<print "">>
<<else>>
	<<if $args[0].fuckdoll != 0>>
		<<set _leftArmType = "mid">>
		<<set _rightArmType = "mid">>
	<</if>>
	<<print "">>
	<<print "">>
<</if>>
<</if>>

/% Hair Aft %/
<<if $args[0].hStyle != "shaved" && $args[0].fuckdoll == 0>>
	<<= "">>
<</if>>

/% Butt %/
<<if $args[0].amp != 1>>
<<if $args[0].butt > 6>>
	<<set _buttSize = 3>>
<<elseif $args[0].butt > 4>>
	<<set _buttSize = 2>>
<<elseif $args[0].butt > 2>>
	<<set _buttSize = 1>>
<<else>>
	<<set _buttSize = 0>>
<</if>>
<<if $args[0].fuckdoll != 0 || $args[0].clothes == "restrictive latex" || $args[0].clothes == "a latex catsuit">>
	<<set _buttSize = _buttSize + " latex">>
	<<print "">>
<<else>>
	<<print "">>
<</if>>
<</if>>

/% Leg + 1 size up when chubby or fat%/
<<if $args[0].hips < 0>>
	<<if $args[0].weight <= 95>>/%Chubby%/
		<<set _legSize = "normal">>
	<<else>>
		<<set _legSize = "narrow">>
	<</if>>
<<elseif $args[0].hips == 0>>
	<<if $args[0].weight <= 95>>/%Chubby%/
		<<set _legSize = "wide">>
	<<else>>
		<<set _legSize = "normal">>
	<</if>>
<<elseif $args[0].hips > 0>>
	<<set _legSize = "wide">>
<</if>>
<<if $args[0].amp == 1>>
	<<set _legSize = "stump " + _legSize>>
<</if>>
<<if ($args[0].fuckdoll != 0 || $args[0].clothes == "restrictive latex" || $args[0].clothes == "a latex catsuit") && $args[0].amp != 1>>
	<<set _legSize = _legSize + " latex">>
	<<print "">>
<<else>>
	<<print "">>
<</if>>

/% Feet %/
<<if $args[0].amp != 1>>
<<if $args[0].shoes == "heels">>
	<<set _shoesType = "heel">>
<<elseif $args[0].shoes == "extreme heels">>
	<<if $args[0].weight <= 95>>/%Chubby%/
		<<set _shoesType = "extreme heel wide">>
	<<else>>
		<<set _shoesType = "extreme heel">>
	<</if>>
<<elseif $args[0].shoes == "boots">>
	<<if $args[0].weight <= 95>>/%Chubby%/
		<<set _shoesType = "boot wide">>
	<<else>>
		<<set _shoesType = "boot">>
	<</if>>
<<elseif $args[0].shoes == "flats">>
	<<set _shoesType = "flat">>
<<else>>
	<<print "">>
<</if>>
<<if $args[0].shoes == "extreme heels" or $args[0].shoes == "boots">>
	<<if $args[0].fuckdoll != 0 || $args[0].clothes == "restrictive latex" || $args[0].clothes == "a latex catsuit">>
		<<set _shoesType = _shoesType + " latex">>
	<</if>>
	<<print "">>
<</if>>
<<if $args[0].shoes == "heels" or $args[0].shoes == "flats">>
	<<if $args[0].fuckdoll != 0 || $args[0].clothes == "restrictive latex" || $args[0].clothes == "a latex catsuit">>
		<<set _shoesType = _shoesType + " latex">>
		<<print "">>
	<<else>>
		<<print "">>
	<</if>>
<</if>>
<</if>>

/% Torso %/
<<if $args[0].waist < -40>>/*Unnatural*/
	<<if $args[0].weight <= 30>>/%Chubby%/
		<<set _torsoSize = "hourglass">>
	<<else>>
		<<set _torsoSize = "unnatural">>
	<</if>>
<<elseif $args[0].waist <= 10>>/%Hour glass%/
	<<if $args[0].weight <= 30>>/%Chubby%/
		<<set _torsoSize = "normal">>
	<<else>>
		<<set _torsoSize = "hourglass">>
	<</if>>
<<else>>/*Normal*/
	<<set _torsoSize = "normal">>
<</if>>
<<print "">>
<<if $args[0].fuckdoll != 0 || $args[0].clothes == "restrictive latex" || $args[0].clothes == "a latex catsuit">>
	<<set _torsoOutfit = " latex">>
<<elseif $args[0].clothes == "uncomfortable straps">>
	<<set _torsoOutfit = " straps">>
<</if>>
<<if _torsoOutfit>>
	<<print "">>
<</if>>

/*Navel Piercing*/
<<if $args[0].navelPiercing >= 1>>
	<<print "">>
<</if>>
<<if $args[0].navelPiercing == 2>>
	<<print "">>
<</if>>

/% Vagina %/
<<if $args[0].vagina >= 0>>
	<<print "">>
	<<if $args[0].clitPiercing == 1>>
		<<print "">>
	<<elseif $args[0].clitPiercing == 2>>
		<<print "">>
	<<elseif $args[0].clitPiercing == 3>>
		<<print "">>
	<</if>>
	<<if $args[0].vaginaPiercing == 1>>
		<<print "">>
	<<elseif $args[0].vaginaPiercing == 2>>
		<<print "">>
	<</if>>
<</if>>

/% Collar %/
<<switch $args[0].collar>>
<<case "bowtie">>
<<case "ancient Egyptian">>
<<case "nice retirement counter" "cruel retirement counter" "leather with cowbell" "pretty jewelry" "heavy gold" "satin choker" "stylish leather" "neck corset" "shock punishment" "tight steel" "uncomfortable leather" "dildo gag">>
	<<print "">>
<</switch>>

/% Head base image %/
<<if $args[0].fuckdoll != 0 || $args[0].clothes == "restrictive latex" || $args[0].clothes == "a latex catsuit">>
	<<print "">>
<<else>>
	<<print "">>
<</if>>

/% Glasses %/
<<if $args[0].eyewear == "corrective glasses" or $args[0].eyewear == "glasses" or $args[0].eyewear == "blurring glasses">>
	<<print "">>
<</if>>

/% Chastity belt or Pubic hair %/
<<if $args[0].dickAccessory == "chastity" || $args[0].dickAccessory == "anal chastity" || $args[0].dickAccessory == "combined chastity" || $args[0].vaginalAccessory == "chastity belt" || $args[0].vaginalAccessory == "anal chastity" || $args[0].vaginalAccessory == "combined chastity">>
	<<if $args[0].dickAccessory == "chastity" || $args[0].dickAccessory == "combined chastity">>
		<<print "">>
	<</if>>
	<<if $args[0].vaginalAccessory == "chastity belt" || $args[0].vaginalAccessory == "combined chastity">>
		<<print "">>
	<</if>>
	<<print "">>
<<else>>
	<<if $args[0].pubicHStyle != "waxed">>
		<<set _pubicHStyle = ($args[0].pubicHStyle == "in a strip" ? "strip" : $args[0].pubicHStyle)>>
		<<= "">>
	<</if>>
<</if>>

/%if pregnant%/
<<if $args[0].preg > 0>>
	<<print "">>
	<<if $args[0].navelPiercing >= 1>>/*Navel Piercing*/
		<<print "">>
	<</if>>
	<<if $args[0].navelPiercing == 2>>
		<<print "">>
	<</if>>
<</if>>

/% Boob %/
<<if $args[0].boobs < 250>>
	<<set _boobSize = 0>>
<<elseif $args[0].boobs < 500>>
	<<set _boobSize = 1>>
<<elseif $args[0].boobs < 800>>
	<<set _boobSize = 2>>
<<elseif $args[0].boobs < 1600>>
	<<set _boobSize = 3>>
<<elseif $args[0].boobs < 3200>>
	<<set _boobSize = 4>>
<<elseif $args[0].boobs < 6400>>
	<<set _boobSize = 5>>
<<elseif $args[0].boobs < 12000>>
	<<set _boobSize = 6>>
<<else>>
	<<set _boobSize = 7>>
<</if>>

/% Scrotum %/
<<if $args[0].scrotum > 0>>
	<<if $args[0].scrotum >= 6>>
		<<set _ballSize = 4>>
	<<elseif $args[0].scrotum >= 4>>
		<<set _ballSize = 3>>
	<<elseif $args[0].scrotum >= 3>>
		<<set _ballSize = 2>>
	<<elseif $args[0].scrotum >= 2>>
		<<set _ballSize = 1>>
	<<else>>
		<<set _ballSize = 0>>
	<</if>>
<</if>>

/% Penis %/
<<if $args[0].dick > 0>>
	<<if $args[0].dick >= 8>>
		<<set _penisSize = 6>>
	<<elseif $args[0].dick >= 7>>
		<<set _penisSize = 5>>
	<<elseif $args[0].dick >= 6>>
		<<set _penisSize = 4>>
	<<elseif $args[0].dick >= 5>>
		<<set _penisSize = 3>>
	<<elseif $args[0].dick >= 4>>
		<<set _penisSize = 2>>
	<<elseif $args[0].dick >= 2>>
		<<set _penisSize = 1>>
	<<else>>
		<<set _penisSize = 0>>
	<</if>>
<</if>>

/% Boob %/
<<set _needBoobs = 1>>
<<if $args[0].dick > 0>>
<<if canAchieveErection($args[0])>>
<<if _boobSize < 6>>
	<<if $args[0].fuckdoll != 0 || $args[0].clothes == "restrictive latex" || $args[0].clothes == "a latex catsuit">>
		/* normal case: outfit hides boobs */
		<<set _boobOutfit = " latex" >>
	<</if>>
	<<if _boobOutfit >>
		<<print "">>
		<<if $args[0].lactation > 0>>
			<<print "">>
		<</if>>
	<<else>>
		<<print "">>
		<<print "">>
	<</if>>
	/* special case: straps are actually dawn over the boobs */
	<<if $args[0].clothes == "uncomfortable straps">>
		<<set _boobOutfit = " straps" >>
		<<print "">>
	<</if>>
	<<set _needBoobs = 0>>
<</if>>
<</if>>
<</if>>
<<if $args[0].vagina > 0>>
	<<if $args[0].dick > 0>>

		<<if $args[0].scrotum > 0>>
			<<print "">>
		<</if>>
		<<if canAchieveErection($args[0])>>
			<<print "">>
		<<else>>
			<<print "">>
			<<if $args[0].dickAccessory == "chastity" || $args[0].dickAccessory == "combined chastity">>
				<<print "">>
			<</if>>
		<</if>>

	<</if>>
<<else>>
	<<if $args[0].dick > 0>>

		<<if $args[0].scrotum > 0>>
			<<print "">>
		<</if>>
		<<if canAchieveErection($args[0])>>
			<<print "">>
		<<else>>
			<<print "">>
			<<if $args[0].dickAccessory == "chastity" || $args[0].dickAccessory == "combined chastity">>
				<<print "">>
			<</if>>
		<</if>>

	<</if>>
<</if>>
<<if _needBoobs>>
	<<if $args[0].fuckdoll != 0 || $args[0].clothes == "restrictive latex" || $args[0].clothes == "a latex catsuit">>
		<<print "">>
		<<if $args[0].lactation > 0>><<print "">><</if>>
	<<else>>
		<<print "">>
		<<print "">>
	<</if>>
	/* special case: straps are actually dawn over the boobs */
	<<if $args[0].clothes == "uncomfortable straps">>
		<<set _boobOutfit = " straps" >>
		<<print "">>
	<</if>>
<</if>>

/% piercings %/
<<if $args[0].nipplesPiercing == 1>>
	<<print "">>
<<elseif $args[0].nipplesPiercing == 2>>
	<<print "">>
<</if>>
<<if $args[0].areolaePiercing == 1>>
	<<print "">>
<</if>>

/% clavicle %/
<<print "">>

/% Hair Foreground %/
<<if $args[0].hStyle != "shaved" && $args[0].fuckdoll == 0>>
	<<= "">>
<</if>>

<<else>> /* RENDERED IMAGES BY SHOKUSHU */

<<if $args[0].vagina > -1>>
	<<if $args[0].dick > 0>>
		<<if $args[0].balls > 0>>
			<<set _fileName = "futanari">>
		<<else>>
			<<set _fileName = "herm">>
		<</if>>
	<<else>>
		<<set _fileName = "female">>
	<</if>>
<<else>>
	<<if $args[0].balls > 0>>
		<<set _fileName = "shemale">>
	<<else>>
		<<set _fileName = "gelding">>
	<</if>>
<</if>>
<<if $args[0].preg > 10>>
	<<set _fileName = "preg " + _fileName>>
<</if>>
<<if $args[0].boobs < 400>>
	<<set _fileName = _fileName + " small">>
<<elseif $args[0].boobs < 800>>
	<<set _fileName = _fileName + " big">>
<<elseif $args[0].boobs < 6000>>
	<<set _fileName = _fileName + " huge">>
<<else>>
	<<set _fileName = _fileName + " hyper">>
<</if>>
<<if $args[0].muscles > 30>>
	<<set _fileName = _fileName + " muscle">>
<<else>>
	<<set _fileName = _fileName + " soft">>
<</if>>
<<if $args[0].fuckdoll > 0>>
	<<set _fileName = _fileName + " rebellious">>
<<elseif $args[0].devotion <= 20>>
	<<if $args[0].trust < -20>>
		<<set _fileName = _fileName + " reluctant">>
	<<else>>
		<<set _fileName = _fileName + " rebellious">>
	<</if>>
<<elseif $args[0].fetish == "mindbroken">>
	<<set _fileName = _fileName + " reluctant">>
<<elseif $args[0].devotion <= 50 || $args[0].fetishKnown != 1 || ($seeMainFetishes == 0 && $args[1] < 2)>>
	<<set _fileName = _fileName + " obedient">>
<<else>>
	<<if $args[0].fetish == "none">>
		<<set _fileName = _fileName + " obedient">>
	<<else>>
		<<set _fileName = _fileName + " " + $args[0].fetish>>
	<</if>>
<</if>>

<<set _fileName = "'resources/renders/" + _fileName + ".png' ">>
<<if $args[1] == 3>>
	<<print "">>
<<elseif $args[1] == 2>>
	<<print "">>
<<elseif $args[1] == 1>>
	<<print "">>
<<else>>
	<<print "">>
<</if>>

<</if>> /* CLOSES IMAGE CHOICE */

<</widget>>

path: devNotes/legacy files/artWidgets-legacy


code:
:: AssayJS [script]

window.slimCount = function(slaves) {
	var slim = 0;
	var ArcologyZero = State.variables.arcologies[0];

	for (var i = 0; i < slaves.length; i++) {
		var slave = slaves[i];
		if ((slave.boobs < 500) && (slave.butt < 3)) {
			if ((slave.muscles <= 30) && (ArcologyZero.FSPhysicalIdealist == "unset") && (slave.weight <= 10) && (ArcologyZero.FSHedonisticDecadence == "unset")) {
				slim += 1;
			} else if (ArcologyZero.FSPhysicalIdealist != "unset") {
				if ((ArcologyZero.FSPhysicalIdealistStrongFat == 1) && (slave.weight <= 30)) {
					slim += 1;
				}
			} else if ((ArcologyZero.FSHedonisticDecadence != "unset") && (slave.weight <= 30)) {
				if (ArcologyZero.FSHedonisticDecadenceStrongFat == 1) {
					slim += 1;
				} else if (slave.muscles <= 30) {
					slim += 1;
				}
			}
		}
	}

	return slim;
}

window.stackedCount = function(slaves) {
	var stacked = 0;

	for (var i = 0; i < slaves.length; i++) {
		var slave = slaves[i];
		if ((slave.butt > 4) && (slave.boobs > 800)) {
			stacked += 1;
		}
	}

	return stacked;
}

window.moddedCount = function(slaves) {
	var modded = 0;

	for (var i = 0; i < slaves.length; i++) {
		var slave = slaves[i];
		var modScore = ModScore(slave);
		var tatScore = TatScore(slave);
		var piercingScore = PiercingScore(slave);
		if ((modScore > 15) || (piercingScore > 8) && (tatScore > 5)) {
			modded += 1;
		}
	}
	return modded;
}

window.unmoddedCount = function(slaves) {
	var unmodded = 0;

	for (var i = 0; i < slaves.length; i++) {
		var slave = slaves[i];
		var modScore = ModScore(slave);
		var tatScore = TatScore(slave);
		var piercingScore = PiercingScore(slave);
		if ((modScore > 15) || (piercingScore > 8) && (tatScore > 5))
		; else {
			unmodded += 1;
		}
	}

	return unmodded;
}

window.XYCount = function(slaves) {
	var XY = 0;

	for (var i = 0; i < slaves.length; i++) {
		var slave = slaves[i];
		if (slave.vagina == -1) {
			XY += 1;
		}
	}
	return XY;
}

window.XXCount = function(slaves) {
	var XX = 0;

	for (var i = 0; i < slaves.length; i++) {
		var slave = slaves[i];
		if (slave.vagina != -1) {
			State.variables.XX += 1;
		}
	}
	return XX;
}

window.youngCount = function(slaves) {
	var young = 0;

	for (var i = 0; i < slaves.length; i++) {
		var slave = slaves[i];
		if (slave.visualAge < 30) {
			State.variables.young += 1;
		}
	}
	return young;
}

window.oldCount = function(slaves) {
	var old = 0;

	for (var i = 0; i < slaves.length; i++) {
		var slave = slaves[i];
		if (slave.visualAge >= 30) {
			State.variables.old += 1;
		}
	}
	return old;
}

window.pregYesCount = function(slaves) {
	var pregYes = 0;

	for (var i = 0; i < slaves.length; i++) {
		var slave = slaves[i];
		if ((slave.bellyPreg >= 5000) || (slave.bellyImplant >= 5000)) {
			pregYes += 1;
		}
	}
	return pregYes;
}

window.pregNoCount = function(slaves) {
	var pregNo = 0;

	for (var i = 0; i < slaves.length; i++) {
		var slave = slaves[i];
		if ((slave.bellyPreg >= 5000) || (slave.bellyImplant >= 5000))
		; else if ((slave.belly < 100) && (slave.weight < 30) && (!setup.fakeBellies.includes(slave.bellyAccessory))) {
			pregNo += 1;
		}
	}
	return pregNo;
}

window.implantedCount = function(slaves) {
	var implanted = 0;
	for (var i = 0; i < slaves.length; i++) {
		var slave = slaves[i];
		if ((slave.boobsImplant == 0) && (slave.buttImplant == 0) && (slave.waist >= -95) && (slave.lipsImplant == 0) && (slave.faceImplant < 30) && (slave.bellyImplant == -1) && (Math.abs(slave.shouldersImplant) < 2) && (Math.abs(slave.hipsImplant) < 2))
		; else {
			implanted += 1;
		}
	}
	return implanted;
}

window.pureCount = function(slaves) {
	var pure = 0;
	for (var i = 0; i < slaves.length; i++) {
		var slave = slaves[i];
		if ((slave.boobsImplant == 0) && (slave.buttImplant == 0) && (slave.waist >= -95) && (slave.lipsImplant == 0) && (slave.faceImplant < 30) && (slave.bellyImplant == -1) && (Math.abs(slave.shouldersImplant) < 2) && (Math.abs(slave.hipsImplant) < 2)) {
			pure += 1;
		}
	}
	return pure;
}

path: devNotes/legacy files/assayJS.txt