diff --git a/artTools/normalize_svg.py b/artTools/normalize_svg.py old mode 100644 new mode 100755 diff --git a/compile.sh b/compile.sh index ebc27c41a500f9d9b6f4fbadfb0160b9175449b3..ca18ce3d5cb1a0dae61f6e61ddaa9ad6b813d767 100755 --- a/compile.sh +++ b/compile.sh @@ -137,4 +137,4 @@ if [[ "$dry" ]]; then else compile echoMessage "Compilation finished." -fi \ No newline at end of file +fi diff --git a/devTools/sugarcube.d.ts b/devTools/sugarcube.d.ts index 1239e18b202abb406ce70b66c0a7b258a28b4f3a..d989bf9da5a7b35d2da4cb183a6462bf3bbd14e5 100644 --- a/devTools/sugarcube.d.ts +++ b/devTools/sugarcube.d.ts @@ -1346,6 +1346,7 @@ declare global { */ const settings: SugarCubeLib.Settings; const Config: SugarCubeLib.Config; + const Engine: SugarCubeLib.Engine; const Macro: SugarCubeLib.Macro; let State: SugarCubeLib.State; let Story: SugarCubeLib.Story; @@ -1718,7 +1719,7 @@ declare global { * //Do something * } */ - function variables(): object; + function variables(): any; /** * Returns the number of times that the passage with the given title occurred within the story history. If multiple passage diff --git a/src/002-config/fc-js-init.js b/src/002-config/fc-js-init.js index f72c839f781d59d8ab0bd4132a07806d460af06b..7293afed2c1ac9780c936521a973c22cc5bab968 100644 --- a/src/002-config/fc-js-init.js +++ b/src/002-config/fc-js-init.js @@ -9,11 +9,13 @@ window.App = { }; // the same declaration for code parsers that don't like the line above var App = window.App || {}; /* eslint-disable-line no-var*/ +App.Art = {}; App.Data = {}; App.Debug = {}; App.Entity = {}; App.Entity.Utils = {}; App.UI = {}; +App.UI.DOM = {}; App.UI.View = {}; App.Utils = {}; App.Interact = {}; @@ -36,3 +38,9 @@ App.Facilities = { App.Medicine = {}; App.RA = {}; App.SF = {}; + + +Object.defineProperty(App, "activeSlave", { + get: () => State.variables.activeSlave, + set: (slave) => { State.variables.activeSlave = slave; } +}); diff --git a/src/003-assets/CSS/slaveList.css b/src/003-assets/CSS/slaveList.css new file mode 100644 index 0000000000000000000000000000000000000000..c0750f9317c2a1b8e535123baa1716d621df1786 --- /dev/null +++ b/src/003-assets/CSS/slaveList.css @@ -0,0 +1,35 @@ +div.slaveSummary { + clear: both; +} + +/* slave summary paragraph when "see images" is enabled */ +p.si { + margin-bottom: 0; + margin-top: 0; + text-indent: 1.5em; +} + +span.freeAssignment { + color: lawngreen; + text-decoration: underline; + font-weight: bold; +} + +/* Slave Summary Item */ +.ssi { + margin-right: 0.25em; +} + +/* Slave Summary Block */ +.ssb { + margin-right: 2em; +} + +.strong { + font-weight: bold; +} + +.emphasizedSlave{ + font-weight: bold; + text-decoration: underline; +} diff --git a/src/004-base/facility.js b/src/004-base/facility.js index 450d54fffa950ce81d85e83b5064d553d89726d7..1298e01d2001f7ef8cc026f1952a01b00120c284 100644 --- a/src/004-base/facility.js +++ b/src/004-base/facility.js @@ -104,6 +104,12 @@ App.Entity.Facilities.Job = class { * @returns {string} code to include into the <<link>><</link>> */ + /** + * @callback assignmentCallback + * @param {string} assignment new assignment + * @returns {void} + */ + /** * Returns link text for the penthouse assignment * @param {number} i slave index @@ -118,6 +124,19 @@ App.Entity.Facilities.Job = class { return `<<link "${linkText}"${passage !== undefined ? ' "' + passage + '"' : ''}>><<= assignJob(${App.Utils.slaveRefString(i)}, "${this.desc.assignment}")>>${linkAction}<</link>>`; } + /** + * Returns link text for the penthouse assignment + * @param {number} i slave index + * @param {string} [passage] passage to go to + * @param {assignmentCallback} [callback] + * @param {string} [linkText] + * @returns {HTMLAnchorElement} + */ + assignmentLinkElement(i, passage, callback, linkText) { + linkText = linkText || this.desc.position; + return App.UI.DOM.assignmentLink(State.variables.slaves[i], this.desc.assignment, passage, callback, linkText); + } + /** * all slaves that are employed at this job * @returns {App.Entity.SlaveState[]} @@ -391,6 +410,32 @@ App.Entity.Facilities.Facility = class { return res; } + /** + * Returns link text for the job assignments + * @param {number} i slave index + * @param {string} [job] generate link only for this job + * @param {string} [passage] + * @param {assignmentCallback} callback + * @returns {HTMLElement[]} + */ + assignmentLinkElements(i, job, passage, callback) { + /** @type {App.Entity.SlaveState} */ + const slave = App.Utils.slaveByIndex(i); + const jobs = job === undefined ? this._jobs : {job: this._jobs[job]}; + + let res = []; + for (const jn in jobs) { + const j = jobs[jn]; + let rejects = j.canEmploy(slave); + if (rejects.length === 0) { + res.push(j.assignmentLinkElement(i, passage, callback)); + } else { + res.push(App.UI.DOM.disabledLink(j.desc.position, rejects)); + } + } + return res; + } + /** * Returns link text for the facility transfer * @param {number} i slave index @@ -404,6 +449,19 @@ App.Entity.Facilities.Facility = class { return this._jobs[job].assignmentLink(i, passage, callback, this.genericName); } + /** + * Returns link text for the facility transfer + * @param {number} i slave index + * @param {string} [job] transfer to this job (uses default job if this is undefined) + * @param {string} [passage] + * @param {linkCallback} [callback] + * @returns {HTMLElement} + */ + transferLinkElement(i, job, passage, callback) { + job = job || this.desc.defaultJob; + return this._jobs[job].assignmentLinkElement(i, passage, callback, this.genericName); + } + /** * all slaves that are employed at this job * @returns {App.Entity.SlaveState[]} diff --git a/src/Mods/DinnerParty/dinnerPartyPreparations.tw b/src/Mods/DinnerParty/dinnerPartyPreparations.tw index 4ae279d4fbcac7cb993bf4533599fb7934edf310..35000125b472aca6e9a630e0e52af4b2f878de55 100644 --- a/src/Mods/DinnerParty/dinnerPartyPreparations.tw +++ b/src/Mods/DinnerParty/dinnerPartyPreparations.tw @@ -35,6 +35,7 @@ __Select Your Meat:__ null, (s, i) => { const p = getPronouns(s); - return App.UI.passageLink(`Make ${p.him} the main course`, "Dinner Party Execution", `$activeSlave = $slaves[${i}]`) + return App.UI.DOM.passageLink(`Make ${p.him} the main course`, "Dinner Party Execution", + () => { App.Utils.setActiveSlaveByIndex(i); }) } )>> diff --git a/src/art/artJS.js b/src/art/artJS.js index fbe02537297fbef4ca7ecedd771cfaeb829f4340..d21cb483ecd31631a5e827b96c79f77f37f75431 100644 --- a/src/art/artJS.js +++ b/src/art/artJS.js @@ -26,9 +26,52 @@ window.SlaveArt = function(artSlave, artSize, UIDisplay) { } }; +/** + * @param {App.Entity.SlaveState} artSlave Slave + * @param {number} artSize 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 + * @param {number} [UIDisplay] (optional, only used by legacy art): icon UI Display for vector art, 1 for on + * @returns {DocumentFragment|HTMLElement} + */ +App.Art.SlaveArtElement = function(artSlave, artSize, UIDisplay) { + const imageChoice = State.variables.imageChoice; + if (artSlave.custom.image !== null && artSlave.custom.image.filename !== "") { + return App.Art.customArtElement(artSlave, artSize); + } else if (imageChoice === 1) { /* VECTOR ART BY NOX/DEEPMURK */ + return App.Art.vectorArtElement(artSlave, artSize); + } else if (imageChoice === 2) { /* VECTOR ART BY NOX - Pregmod Legacy Version */ + return App.Art.legacyVectorArtElement(artSlave, UIDisplay); + } else if (imageChoice === 3) { /* VECTOR ART REVAMP*/ + return App.Art.revampedVectorArtElement(artSlave); + } else { /* RENDERED IMAGES BY SHOKUSHU */ + return App.Art.renderedArtElement(artSlave, artSize); + } +}; + window.ArtControlRendered = function ArtControlRendered(slave, sizePlacement) { + return App.Art.elementToMarkup(App.Art.renderedArtElement(slave, sizePlacement)); +}; + +/** + * @param {App.Entity.SlaveState} slave + * @param {number} imageSize + * @returns {string} + */ +window.CustomArt = function(slave, imageSize) { + return App.Art.elementToMarkup(App.Art.customArtElement(slave, imageSize)); +}; + +/** + * @param {App.Entity.SlaveState} slave + * @param {number} artSize + * @returns {HTMLElement} + */ +App.Art.renderedArtElement = function(slave, artSize) { const V = State.variables; - let fileName = "'resources/renders/"; + let fileName = "resources/renders/"; if (slave.belly > 1500) { fileName += "preg "; @@ -74,7 +117,7 @@ window.ArtControlRendered = function ArtControlRendered(slave, sizePlacement) { } } else if (slave.fetish === "mindbroken") { fileName = `${fileName} reluctant`; - } else if (slave.devotion <= 50 || slave.fetishKnown !== 1 || (V.seeMainFetishes === 0 && sizePlacement < 2)) { + } else if (slave.devotion <= 50 || slave.fetishKnown !== 1 || (V.seeMainFetishes === 0 && artSize < 2)) { fileName = `${fileName} obedient`; } else { if (slave.fetish === "none") { @@ -83,38 +126,55 @@ window.ArtControlRendered = function ArtControlRendered(slave, sizePlacement) { fileName = `${fileName} ${slave.fetish}`; } } + fileName += ".png"; - fileName += ".png'"; - if (sizePlacement === 3) { - return `<img src=${fileName} style='float:right; border:3px hidden'>`; - } else if (sizePlacement === 2) { - return `<img src=${fileName} style='float:right; border:3px hidden' width='300' height='300'>`; - } else if (sizePlacement === 1) { - return `<img src=${fileName} style='float:left; border:3px hidden' width='150' height='150'>`; - } else { - return `<img src=${fileName} style='float:left; border:3px hidden' width='120' height='120'>`; + const res = document.createElement("img"); + res.setAttribute("src", fileName); + const sz = this.artSizeToPx(artSize); + if (sz) { + res.setAttribute("width", sz); + res.setAttribute("height", sz); } -}; + return res; +} /** * @param {App.Entity.SlaveState} slave * @param {number} imageSize - * @returns {string} + * @returns {HTMLElement} */ -window.CustomArt = function(slave, imageSize) { +App.Art.customArtElement = function(slave, imageSize) { const fileType = slave.custom.image.format || "png"; - const fileName = `'resources/${slave.custom.image.filename}.${fileType}'`; - const displayTypeStart = (fileType === "webm" ? "video loop autoplay" : "img"); - const displayTypeEnd = (fileType === "webm" ? "</video>" : ""); + const fileName = `resources/${slave.custom.image.filename}.${fileType}`; + const elementType = fileType === "webm" ? "video" : "img"; + const attributes = fileType === "webm" ? ["loop", "autoplay"] : []; - if (imageSize === 3) { - return `<${displayTypeStart} src=${fileName} style='float:right; border:3px hidden'>${displayTypeEnd}`; - } else if (imageSize === 2) { - return `<${displayTypeStart} src=${fileName} style='float:right; border:3px hidden' width='300' height='300'>${displayTypeEnd}`; - } else if (imageSize === 1) { - return `<${displayTypeStart} src=${fileName} style='float:right; border:3px hidden' width='150' height='150'>${displayTypeEnd}`; - } else { - return `<${displayTypeStart} src=${fileName} style='float:right; border:3px hidden' width='120' height='120'>${displayTypeEnd}`; + const res = document.createElement(elementType); + attributes.forEach((an) => { + res.setAttribute(an, ""); + }); + + res.setAttribute("src", fileName); + res.setAttribute("style", "'float:right; border:3px hidden'"); + + const sz = this.artSizeToPx(imageSize); + if (sz) { + res.setAttribute("width", sz); + res.setAttribute("height", sz); + } + return res; +}; + +App.Art.artSizeToPx = function(artSize) { + switch (artSize) { + case 3: + return null; + case 2: + return "300"; + case 1: + return "150"; + default: + return "120"; } }; @@ -1815,3 +1875,43 @@ window.skinColorCatcher = function(artSlave) { } return colorSlave; }; + + +App.Art.cacheArtData = function() { + /** + * @param {NodeListOf<Element>} imagePassages + * @param {Object} obj + */ + function cacheImages(imagePassages, obj) { + obj.nodes = document.createDocumentFragment(); + obj.dict = new Map(); + + for (const ip of imagePassages) { + const name = ip.attributes.getNamedItem("name").value; + let div = document.createElement("div"); + div.id = "div-" + name; + const svgData = atob(ip.innerHTML.replace(/data:image\/svg\+xml;base64,/, '')); + div.innerHTML = svgData; + obj.nodes.appendChild(div); + obj.dict.set(name, obj.dict.size); + } + } + App.Data.Art = {}; + + App.Data.Art.Vector = {}; + cacheImages(document.querySelectorAll('[tags="Twine.image"][name^="Art_Vector"]:not([ame^="Art_Vector_Revamp"])'), App.Data.Art.Vector); + App.Data.Art.VectorRevamp = {}; + cacheImages(document.querySelectorAll('[tags="Twine.image"][name^="Art_Vector_Revamp"]'), App.Data.Art.VectorRevamp); +}; + +/** + * @param {Element|DocumentFragment} e + * @returns {string} + */ +App.Art.elementToMarkup = function(e) { + const div = document.createElement("div"); + div.appendChild(e); + // stripping <div>...</div>. This is probably not the wiser approach + let s = div.outerHTML; + return s.substr(5, s.length - 11); +}; diff --git a/src/art/vector/VectorArtJS.js b/src/art/vector/VectorArtJS.js index e208250d74e2e01ab89cc766c876c0ad7a43f7fe..2ffbc4002047ec8c59b788154d8f755f6e17dccd 100644 --- a/src/art/vector/VectorArtJS.js +++ b/src/art/vector/VectorArtJS.js @@ -1,11 +1,20 @@ -window.VectorArt = (function() { +window.VectorArt = function(artSlave, artSize) { + return App.Art.elementToMarkup(App.Art.SlaveArtElement(artSlave, artSize)); +}; + +window.LegacyVectorArt = function(slave, artSize) { + return App.Art.elementToMarkup(App.Art.legacyVectorArtElement(slave, artSize)); +}; + +App.Art.vectorArtElement = (function() { "use strict"; let V, T, slave; - let r; let leftArmType, rightArmType, legSize, torsoSize, buttSize, penisSize, hairLength, wearingLatex; let bellyScaleFactor, artBoobScaleFactor, heightScaleFactor; let artTranslationX, artTranslationY; - let penisDrawtime, penisArtString; + let penisDrawtime, penisArt; + /** @type {DocumentFragment} */ + let res; function VectorArt(artSlave, artSize) { /* set constants */ @@ -19,6 +28,7 @@ window.VectorArt = (function() { // eslint-disable-next-line camelcase T.art_transform = ""; /* in case other files are trying to use this, and expecting a string */ + res = document.createDocumentFragment(); setStylesheet(artSize); /* initializes the stylesheet, and r */ setArmType(); setBoobScaling(); @@ -54,13 +64,13 @@ window.VectorArt = (function() { ArtVectorBalls(); } if (penisDrawtime === 0) { /* for dicks behind boobs */ - r += penisArtString; + res.appendChild(penisArt); } ArtVectorBelly(); /* includes navel piercing and belly-related clothing options */ ArtVectorBoob(); /* includes areolae and piercings */ if (penisDrawtime === 1) { /* for dicks in front of boobs */ - r += penisArtString; + res.appendChild(penisArt); } ArtVectorBoobAddons(); /* piercings always appear in front of boobs AND dick */ @@ -68,7 +78,35 @@ window.VectorArt = (function() { ArtVectorHead(); /* glasses are drawn here */ ArtVectorHairFore(); - return r; + return res; + } + + function useSvg(id) { + const cache = App.Data.Art.Vector; + /** @type {HTMLElement} */ + const res = cache.nodes.children.item(cache.dict.get(id)).children.item(0).cloneNode(true); + res.setAttribute("class", T.art_display_class); + let transformNodes = res.querySelectorAll('g[data-transform]'); + for (const node of transformNodes) { + switch (node.getAttribute("data-transform")) { + case "boob": + node.setAttribute("transform", T.artTransformBoob); + break; + case "belly": + node.setAttribute("transform", T.artTransformBelly); + break; + case "balls": + node.setAttribute("transform", T.artTransformBalls); + break; + case "art": + if (T.art_transform) { + node.setAttribute("transform", T.art_transform); + } + break; + } + } + + return res; } function setStylesheet(artSize) { @@ -106,7 +144,8 @@ window.VectorArt = (function() { margin = Math.max(50 - (50 * slaveHeightScale), 0); } - r = `<style>.${displayClass} {\ + let st = document.createElement("style"); + st.innerHTML = `.${displayClass} {\ position: absolute;\ height: 100%;\ transform: scale(${slaveHeightScale});\ @@ -142,7 +181,8 @@ window.VectorArt = (function() { .${displayClass} .glasses{ fill:${T.glassesColor}; }\ .${displayClass} .eye{ fill:${T.eyeColor}; }\ .${displayClass} .sclera{ fill:${T.sclerae}; }\ - </style>`; + `; + res.appendChild(st); } function setArmType() { @@ -262,7 +302,7 @@ window.VectorArt = (function() { } function penisArtControl() { - penisArtString = ""; + penisArt = document.createDocumentFragment(); if (penisSize === undefined) { penisDrawtime = -1; /* no penis to draw */ } else if (State.variables.showClothingErection) { @@ -302,7 +342,7 @@ window.VectorArt = (function() { case "a toga": case "a penitent nuns habit": if ((canAchieveErection(slave)) && (slave.chastityPenis !== 1)) { - penisArtString = jsInclude(`Art_Vector_Bulge_Outfit_Hard_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_Bulge_Outfit_Hard_${penisSize}`)); break; /* IN CASE OF NO ERECTION, SKIP TO A NORMAL BULGE */ // FIXME: having a break in an if is bad code } /* BULGE OUTFITS LONG OUTFITS */ @@ -338,7 +378,7 @@ window.VectorArt = (function() { case "a tank-top and panties": case "conservative clothing": case "stretch pants and a crop-top": - penisArtString = jsInclude(`Art_Vector_Bulge_Outfit_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_Bulge_Outfit_${penisSize}`)); break; /* SMALL BULGE ONLY (SHORT) OUTFITS */ case "boyshorts": @@ -360,9 +400,9 @@ window.VectorArt = (function() { case "harem gauze": if (slave.belly <= 4000) { if (slave.dick > 3) { - penisArtString = jsInclude("Art_Vector_Bulge_Outfit_3"); + penisArt.appendChild(useSvg("Art_Vector_Bulge_Outfit_3")); } else { - penisArtString = jsInclude(`Art_Vector_Bulge_Outfit_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_Bulge_Outfit_${penisSize}`)); } } break; @@ -377,21 +417,21 @@ window.VectorArt = (function() { penisDrawtime = 1; /* draw erect penis over boobs if boobs do not hide the penis' base */ if (artBoobScaleFactor < 3.7) { if (slave.foreskin !== 0) { - penisArtString = jsInclude(`Art_Vector_Penis_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_Penis_${penisSize}`)); } else { - penisArtString = jsInclude(`Art_Vector_PenisCirc_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_PenisCirc_${penisSize}`)); } } } else { /* flaccid penises are drawn behind the boobs/belly */ if (slave.foreskin !== 0) { - penisArtString = jsInclude(`Art_Vector_Flaccid_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_Flaccid_${penisSize}`)); } else { - penisArtString = jsInclude(`Art_Vector_FlaccidCirc_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_FlaccidCirc_${penisSize}`)); } /* this draws chastity OVER latex catsuit. prndev finds this alright. */ if (slave.chastityPenis === 1) { - penisArtString += jsInclude(`Art_Vector_Chastity_Cage_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_Chastity_Cage_${penisSize}`)); } } } @@ -441,7 +481,7 @@ window.VectorArt = (function() { case "sport shorts and a sports bra": case "sport shorts and a t-shirt": case "stretch pants and a crop-top": - penisArtString = jsInclude(`Art_Vector_Bulge_Outfit_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_Bulge_Outfit_${penisSize}`)); break; /* BULGE OUTFITS SHORT OUTFITS */ case "a bunny outfit": @@ -479,9 +519,9 @@ window.VectorArt = (function() { case "striped underwear": if (slave.belly <= 4000) { if (slave.dick > 3) { - penisArtString = jsInclude("Art_Vector_Bulge_Outfit_3"); + penisArt.appendChild(useSvg("Art_Vector_Bulge_Outfit_3")); } else { - penisArtString = jsInclude(`Art_Vector_Bulge_Outfit_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_Bulge_Outfit_${penisSize}`)); } } break; @@ -497,21 +537,21 @@ window.VectorArt = (function() { penisDrawtime = 1; /* draw erect penis over boobs if boobs do not hide the penis' base */ if (artBoobScaleFactor < 3.7) { if (slave.foreskin !== 0) { - penisArtString = jsInclude(`Art_Vector_Penis_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_Penis_${penisSize}`)); } else { - penisArtString = jsInclude(`Art_Vector_PenisCirc_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_PenisCirc_${penisSize}`)); } } } else { /* flaccid penises are drawn behind the boobs/belly */ if (slave.foreskin !== 0) { - penisArtString = jsInclude(`Art_Vector_Flaccid_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_Flaccid_${penisSize}`)); } else { - penisArtString = jsInclude(`Art_Vector_FlaccidCirc_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_FlaccidCirc_${penisSize}`)); } /* this draws chastity OVER latex catsuit. prndev finds this alright. */ if (slave.chastityPenis === 1) { - penisArtString += jsInclude(`Art_Vector_Chastity_Cage_${penisSize}`); + penisArt.appendChild(useSvg(`Art_Vector_Chastity_Cage_${penisSize}`)); } } } @@ -607,21 +647,21 @@ window.VectorArt = (function() { function ArtVectorAnalAccessories() { if (slave.buttplug === "long plug") { - r += jsInclude("Art_Vector_Plug_Long"); + res.appendChild(useSvg("Art_Vector_Plug_Long")); } else if (slave.buttplug === "large plug") { - r += jsInclude("Art_Vector_Plug_Large"); + res.appendChild(useSvg("Art_Vector_Plug_Large")); } else if (slave.buttplug === "long, large plug") { - r += jsInclude("Art_Vector_Plug_Large_Long"); + res.appendChild(useSvg("Art_Vector_Plug_Large_Long")); } else if (slave.buttplug === "huge plug") { - r += jsInclude("Art_Vector_Plug_Huge"); + res.appendChild(useSvg("Art_Vector_Plug_Huge")); } else if (slave.buttplug === "long, huge plug") { - r += jsInclude("Art_Vector_Plug_Huge_Long"); + res.appendChild(useSvg("Art_Vector_Plug_Huge_Long")); } if (slave.buttplugAttachment === "tail") { - r += jsInclude("Art_Vector_Plug_Tail"); + res.appendChild(useSvg("Art_Vector_Plug_Tail")); } else if (slave.buttplugAttachment === "cat tail") { - r += jsInclude("Art_Vector_Cat_Tail"); + res.appendChild(useSvg("Art_Vector_Cat_Tail")); } } @@ -632,48 +672,48 @@ window.VectorArt = (function() { /* - added brackets to make boolean logic run */ if (slave.amp === 1) { /* Many amputee clothing art files exist, but draw nothing.They are excluded for now to reduce on rendering time - r += jsInclude("Art_Vector_Arm_Right_None"); - r += jsInclude("Art_Vector_Arm_Left_None"); + res.appendChild(useSvg("Art_Vector_Arm_Right_None")); + res.appendChild(useSvg("Art_Vector_Arm_Left_None")); */ } else { /* is not amputee or has limbs equipped so running arm calculation block */ if (slave.amp === 0) { - r += jsInclude(`Art_Vector_Arm_Right_${rightArmType}`); - r += jsInclude(`Art_Vector_Arm_Left_${leftArmType}`); + res.appendChild(useSvg(`Art_Vector_Arm_Right_${rightArmType}`)); + res.appendChild(useSvg(`Art_Vector_Arm_Left_${leftArmType}`)); if (slave.muscles >= 6) { if (leftArmType === "High") { - r += jsInclude("Art_Vector_Arm_Left_High_MLight"); + res.appendChild(useSvg("Art_Vector_Arm_Left_High_MLight")); } else if (leftArmType === "Mid") { - r += jsInclude("Art_Vector_Arm_Left_Mid_MLight"); + res.appendChild(useSvg("Art_Vector_Arm_Left_Mid_MLight")); } else if (leftArmType === "Low") { - r += jsInclude("Art_Vector_Arm_Left_Low_MLight"); + res.appendChild(useSvg("Art_Vector_Arm_Left_Low_MLight")); } else if (leftArmType === "Rebel") { - r += jsInclude("Art_Vector_Arm_Left_Rebel_MLight"); + res.appendChild(useSvg("Art_Vector_Arm_Left_Rebel_MLight")); } if (rightArmType === "High") { - r += jsInclude("Art_Vector_Arm_Right_High_MLight"); + res.appendChild(useSvg("Art_Vector_Arm_Right_High_MLight")); } else if (rightArmType === "Mid") { - r += jsInclude("Art_Vector_Arm_Right_Mid_MLight"); + res.appendChild(useSvg("Art_Vector_Arm_Right_Mid_MLight")); } else if (rightArmType === "Low") { - r += jsInclude("Art_Vector_Arm_Right_Low_MLight"); + res.appendChild(useSvg("Art_Vector_Arm_Right_Low_MLight")); } } } else if (slave.PLimb === 1 || slave.PLimb === 2) { /* slave is an amputee and has PLimbs equipped */ if (slave.amp === -1) { - r += jsInclude(`Art_Vector_Arm_Right_ProstheticBasic_${rightArmType}`); - r += jsInclude(`Art_Vector_Arm_Left_ProstheticBasic_${leftArmType}`); + res.appendChild(useSvg(`Art_Vector_Arm_Right_ProstheticBasic_${rightArmType}`)); + res.appendChild(useSvg(`Art_Vector_Arm_Left_ProstheticBasic_${leftArmType}`)); } else if (slave.amp === -2) { - r += jsInclude(`Art_Vector_Arm_Right_ProstheticSexy_${rightArmType}`); - r += jsInclude(`Art_Vector_Arm_Left_ProstheticSexy_${leftArmType}`); + res.appendChild(useSvg(`Art_Vector_Arm_Right_ProstheticSexy_${rightArmType}`)); + res.appendChild(useSvg(`Art_Vector_Arm_Left_ProstheticSexy_${leftArmType}`)); } else if (slave.amp === -3) { /* Reverting beauty limbs to regular SVG */ - r += jsInclude(`Art_Vector_Arm_Right_ProstheticBeauty_${rightArmType}`); - r += jsInclude(`Art_Vector_Arm_Left_ProstheticBeauty_${leftArmType}`); + res.appendChild(useSvg(`Art_Vector_Arm_Right_ProstheticBeauty_${rightArmType}`)); + res.appendChild(useSvg(`Art_Vector_Arm_Left_ProstheticBeauty_${leftArmType}`)); } else if (slave.amp === -4) { - r += jsInclude(`Art_Vector_Arm_Right_ProstheticCombat_${rightArmType}`); - r += jsInclude(`Art_Vector_Arm_Left_ProstheticCombat_${leftArmType}`); + res.appendChild(useSvg(`Art_Vector_Arm_Right_ProstheticCombat_${rightArmType}`)); + res.appendChild(useSvg(`Art_Vector_Arm_Left_ProstheticCombat_${leftArmType}`)); } else if (slave.amp === -5) { - r += jsInclude(`Art_Vector_Arm_Right_ProstheticSwiss_${rightArmType}`); - r += jsInclude(`Art_Vector_Arm_Left_ProstheticSwiss_${leftArmType}`); + res.appendChild(useSvg(`Art_Vector_Arm_Right_ProstheticSwiss_${rightArmType}`)); + res.appendChild(useSvg(`Art_Vector_Arm_Left_ProstheticSwiss_${leftArmType}`)); } } /* shiny clothing */ @@ -681,11 +721,11 @@ window.VectorArt = (function() { if (wearingLatex === true || slave.clothes === "body oil") { /* only some arm positions have art (feel free to add more) */ if (leftArmType === "High") { - r += jsInclude("Art_Vector_Arm_Outfit_Shine_Left_High"); + res.appendChild(useSvg("Art_Vector_Arm_Outfit_Shine_Left_High")); } else if (leftArmType === "Mid") { - r += jsInclude("Art_Vector_Arm_Outfit_Shine_Left_Mid"); + res.appendChild(useSvg("Art_Vector_Arm_Outfit_Shine_Left_Mid")); } else if (leftArmType === "Low") { - r += jsInclude("Art_Vector_Arm_Outfit_Shine_Left_Low"); + res.appendChild(useSvg("Art_Vector_Arm_Outfit_Shine_Left_Low")); } } } @@ -734,25 +774,25 @@ window.VectorArt = (function() { case "slutty jewelry": case "sport shorts and a t-shirt": case "Western clothing": - r += jsInclude(`Art_Vector_Arm_Outfit_${clothing2artSuffix(slave.clothes)}_Right_${rightArmType}`); - r += jsInclude(`Art_Vector_Arm_Outfit_${clothing2artSuffix(slave.clothes)}_Left_${leftArmType}`); + res.appendChild(useSvg(`Art_Vector_Arm_Outfit_${clothing2artSuffix(slave.clothes)}_Right_${rightArmType}`)); + res.appendChild(useSvg(`Art_Vector_Arm_Outfit_${clothing2artSuffix(slave.clothes)}_Left_${leftArmType}`)); break; /* manually handle special cases */ case "a schutzstaffel uniform": case "a slutty schutzstaffel uniform": - r += jsInclude(`Art_Vector_Arm_Outfit_SchutzstaffelUniform_Right_${rightArmType}`); - r += jsInclude(`Art_Vector_Arm_Outfit_SchutzstaffelUniform_Left_${leftArmType}`); + res.appendChild(useSvg(`Art_Vector_Arm_Outfit_SchutzstaffelUniform_Right_${rightArmType}`)); + res.appendChild(useSvg(`Art_Vector_Arm_Outfit_SchutzstaffelUniform_Left_${leftArmType}`)); break; case "a hijab and abaya": case "a niqab and abaya": case "a burqa": - r += jsInclude(`Art_Vector_Arm_Outfit_HijabAndAbaya_Right_${rightArmType}`); - r += jsInclude(`Art_Vector_Arm_Outfit_HijabAndAbaya_Left_${leftArmType}`); + res.appendChild(useSvg(`Art_Vector_Arm_Outfit_HijabAndAbaya_Right_${rightArmType}`)); + res.appendChild(useSvg(`Art_Vector_Arm_Outfit_HijabAndAbaya_Left_${leftArmType}`)); break; case "a slave gown": /* only some arm positions have art (feel free to add more) */ if (leftArmType !== "Rebel") { - r += jsInclude(`Art_Vector_Arm_Outfit_SlaveGown_Left_${leftArmType}`); + res.appendChild(useSvg(`Art_Vector_Arm_Outfit_SlaveGown_Left_${leftArmType}`)); } } } /* close .amp check */ @@ -790,7 +830,7 @@ window.VectorArt = (function() { artTranslationX = -271 * (ballsScaleFactor - 1); artTranslationY = -453 * (ballsScaleFactor - 1); T.artTransformBalls = `matrix(${ballsScaleFactor},0,0,${ballsScaleFactor},${artTranslationX},${artTranslationY})`; - r += jsInclude("Art_Vector_Balls"); + res.appendChild(useSvg("Art_Vector_Balls")); } } @@ -804,11 +844,11 @@ window.VectorArt = (function() { T.artTransformBelly = `matrix(${bellyScaleFactor},0,0,${bellyScaleFactor},${artTranslationX},${artTranslationY})`; if (slave.navelPiercing === 1) { - r += jsInclude("Art_Vector_Belly_Pregnant_Piercing"); + res.appendChild(useSvg("Art_Vector_Belly_Pregnant_Piercing")); } else if (slave.navelPiercing === 2) { - r += jsInclude("Art_Vector_Belly_Pregnant_Piercing_Heavy"); + res.appendChild(useSvg("Art_Vector_Belly_Pregnant_Piercing_Heavy")); } else { - r += jsInclude("Art_Vector_Belly"); + res.appendChild(useSvg("Art_Vector_Belly")); } switch (slave.clothes) { @@ -858,47 +898,47 @@ window.VectorArt = (function() { break; /* do nothing for these choices */ /* manually handle special cases */ case "a slutty schutzstaffel uniform": - r += jsInclude("Art_Vector_Belly_Outfit_SchutzstaffelUniform"); + res.appendChild(useSvg("Art_Vector_Belly_Outfit_SchutzstaffelUniform")); break; case "a niqab and abaya": case "a burqa": - r += jsInclude("Art_Vector_Belly_Outfit_HijabAndAbaya"); + res.appendChild(useSvg("Art_Vector_Belly_Outfit_HijabAndAbaya")); break; default: - r += jsInclude(`Art_Vector_Belly_Outfit_${clothing2artSuffix(slave.clothes)}`); + res.appendChild(useSvg(`Art_Vector_Belly_Outfit_${clothing2artSuffix(slave.clothes)}`)); } /* shiny clothing */ if (V.seeVectorArtHighlights === 1) { if (wearingLatex === true || slave.clothes === "body oil") { - r += jsInclude("Art_Vector_Belly_Outfit_Shine"); + res.appendChild(useSvg("Art_Vector_Belly_Outfit_Shine")); } } } /* belly piercings for flat bellies */ if (slave.belly === 0) { if (slave.navelPiercing === 1) { - r += jsInclude("Art_Vector_Belly_Piercing"); + res.appendChild(useSvg("Art_Vector_Belly_Piercing")); } else if (slave.navelPiercing === 2) { - r += jsInclude("Art_Vector_Belly_Piercing_Heavy"); + res.appendChild(useSvg("Art_Vector_Belly_Piercing_Heavy")); } } /* Torso Accessories */ if ((slave.bellyAccessory === "a corset" || slave.bellyAccessory === "an extreme corset") && slave.belly <= 1500) { if (torsoSize === "Normal") { - r += jsInclude("Art_Vector_Corsetnormal"); + res.appendChild(useSvg("Art_Vector_Corsetnormal")); } else if (torsoSize === "Hourglass") { - r += jsInclude("Art_Vector_Corsethourglass"); + res.appendChild(useSvg("Art_Vector_Corsethourglass")); } else if (torsoSize === "Unnatural") { - r += jsInclude("Art_Vector_Corsetunnatural"); + res.appendChild(useSvg("Art_Vector_Corsetunnatural")); } } else if (slave.bellyAccessory === "a small empathy belly") { - r += jsInclude("Art_Vector_Empathy_Belly_Small"); + res.appendChild(useSvg("Art_Vector_Empathy_Belly_Small")); } else if (slave.bellyAccessory === "a medium empathy belly") { - r += jsInclude("Art_Vector_Empathy_Belly_Medium"); + res.appendChild(useSvg("Art_Vector_Empathy_Belly_Medium")); } else if (slave.bellyAccessory === "a large empathy belly") { - r += jsInclude("Art_Vector_Empathy_Belly_Large"); + res.appendChild(useSvg("Art_Vector_Empathy_Belly_Large")); } else if (slave.bellyAccessory === "a huge empathy belly") { - r += jsInclude("Art_Vector_Empathy_Belly_Huge"); + res.appendChild(useSvg("Art_Vector_Empathy_Belly_Huge")); } } @@ -907,11 +947,11 @@ window.VectorArt = (function() { /* BEWARE: this threshold may be used in other art-related code, too */ /* boobs too small - draw areolae directly onto torso */ } else { - r += jsInclude("Art_Vector_Boob_Alt"); + res.appendChild(useSvg("Art_Vector_Boob_Alt")); /* shiny clothing */ if (V.seeVectorArtHighlights === 1) { if (slave.fuckdoll !== 0 || slave.clothes === "a latex catsuit" || slave.clothes === "body oil") { - r += jsInclude("Art_Vector_Boob_Outfit_Shine"); + res.appendChild(useSvg("Art_Vector_Boob_Outfit_Shine")); } } } @@ -947,33 +987,33 @@ window.VectorArt = (function() { case "striped panties": case "uncomfortable straps": if (slave.areolaeShape === "star") { - r += jsInclude("Art_Vector_Boob_Areola_Star"); + res.appendChild(useSvg("Art_Vector_Boob_Areola_Star")); } else if (slave.areolaeShape === "heart") { - r += jsInclude("Art_Vector_Boob_Areola_Heart"); + res.appendChild(useSvg("Art_Vector_Boob_Areola_Heart")); } else if (slave.areolae === 0) { - r += jsInclude("Art_Vector_Boob_Areola"); + res.appendChild(useSvg("Art_Vector_Boob_Areola")); } else if (slave.areolae === 1) { - r += jsInclude("Art_Vector_Boob_Areola_Large"); + res.appendChild(useSvg("Art_Vector_Boob_Areola_Large")); } else if (slave.areolae === 2) { - r += jsInclude("Art_Vector_Boob_Areola_Wide"); + res.appendChild(useSvg("Art_Vector_Boob_Areola_Wide")); } else if (slave.areolae >= 3) { - r += jsInclude("Art_Vector_Boob_Areola_Huge"); + res.appendChild(useSvg("Art_Vector_Boob_Areola_Huge")); } if (slave.nipples === "tiny") { - r += jsInclude("Art_Vector_Boob_NippleTiny"); + res.appendChild(useSvg("Art_Vector_Boob_NippleTiny")); } else if (slave.nipples === "cute") { - r += jsInclude("Art_Vector_Boob_NippleCute"); + res.appendChild(useSvg("Art_Vector_Boob_NippleCute")); } else if (slave.nipples === "puffy") { - r += jsInclude("Art_Vector_Boob_NipplePuffy"); + res.appendChild(useSvg("Art_Vector_Boob_NipplePuffy")); } else if (slave.nipples === "inverted") { - r += jsInclude("Art_Vector_Boob_NippleInverted"); + res.appendChild(useSvg("Art_Vector_Boob_NippleInverted")); } else if (slave.nipples === "huge") { - r += jsInclude("Art_Vector_Boob_NippleHuge"); + res.appendChild(useSvg("Art_Vector_Boob_NippleHuge")); } else if (slave.nipples === "partially inverted") { - r += jsInclude("Art_Vector_Boob_NipplePartiallyInverted"); + res.appendChild(useSvg("Art_Vector_Boob_NipplePartiallyInverted")); } else if (slave.nipples === "fuckable") { - r += jsInclude("Art_Vector_Boob_NippleFuckable"); + res.appendChild(useSvg("Art_Vector_Boob_NippleFuckable")); } } } @@ -1011,17 +1051,17 @@ window.VectorArt = (function() { break; /* do nothing for these choices */ /* manually handle special cases */ case "a slutty schutzstaffel uniform": - r += jsInclude("Art_Vector_Boob_Outfit_SchutzstaffelUniform"); + res.appendChild(useSvg("Art_Vector_Boob_Outfit_SchutzstaffelUniform")); break; case "a niqab and abaya": case "a burqa": - r += jsInclude("Art_Vector_Boob_Outfit_HijabAndAbaya"); + res.appendChild(useSvg("Art_Vector_Boob_Outfit_HijabAndAbaya")); break; case "pasties": - r += jsInclude("Art_Vector_Boob_Outfit_PantiesAndPasties"); + res.appendChild(useSvg("Art_Vector_Boob_Outfit_PantiesAndPasties")); break; default: - r += jsInclude(`Art_Vector_Boob_Outfit_${clothing2artSuffix(slave.clothes)}`); + res.appendChild(useSvg(`Art_Vector_Boob_Outfit_${clothing2artSuffix(slave.clothes)}`)); } } if (V.showBodyMods === 1 && (slave.nipplesPiercing > 0 || slave.areolaePiercing > 0)) { @@ -1063,15 +1103,15 @@ window.VectorArt = (function() { case "striped panties": case "uncomfortable straps": if (slave.nipplesPiercing === 1) { - r += jsInclude("Art_Vector_Boob_Piercing"); + res.appendChild(useSvg("Art_Vector_Boob_Piercing")); } else if (slave.nipplesPiercing > 1) { - r += jsInclude("Art_Vector_Boob_Piercing_Heavy"); + res.appendChild(useSvg("Art_Vector_Boob_Piercing_Heavy")); } if (slave.areolaePiercing === 1) { - r += jsInclude("Art_Vector_Boob_Areola_Piercing"); + res.appendChild(useSvg("Art_Vector_Boob_Areola_Piercing")); } else if (slave.areolaePiercing > 1) { - r += jsInclude("Art_Vector_Boob_Areola_Piercingheavy"); + res.appendChild(useSvg("Art_Vector_Boob_Areola_Piercingheavy")); } } } @@ -1079,17 +1119,17 @@ window.VectorArt = (function() { function ArtVectorButt() { if (slave.amp === 0) { - r += jsInclude(`Art_Vector_Butt_${buttSize}`); + res.appendChild(useSvg(`Art_Vector_Butt_${buttSize}`)); } else if (slave.amp === -1) { - r += jsInclude(`Art_Vector_Butt_ProstheticBasic_${buttSize}`); + res.appendChild(useSvg(`Art_Vector_Butt_ProstheticBasic_${buttSize}`)); } else if (slave.amp === -2) { - r += jsInclude(`Art_Vector_Butt_ProstheticSexy_${buttSize}`); + res.appendChild(useSvg(`Art_Vector_Butt_ProstheticSexy_${buttSize}`)); } else if (slave.amp === -3) { /* reverted to regular SVG to match description */ - r += jsInclude(`Art_Vector_Butt_ProstheticBeauty_${buttSize}`); + res.appendChild(useSvg(`Art_Vector_Butt_ProstheticBeauty_${buttSize}`)); } else if (slave.amp === -4) { - r += jsInclude(`Art_Vector_Butt_ProstheticCombat_${buttSize}`); + res.appendChild(useSvg(`Art_Vector_Butt_ProstheticCombat_${buttSize}`)); } else if (slave.amp === -5) { - r += jsInclude(`Art_Vector_Butt_ProstheticSwiss_${buttSize}`); + res.appendChild(useSvg(`Art_Vector_Butt_ProstheticSwiss_${buttSize}`)); } } @@ -1139,18 +1179,18 @@ window.VectorArt = (function() { if (slave.chastityAnus === 1) { if (bodySize === "Fat") { - r += jsInclude("Art_Vector_Chastity_Vagina_Fat"); + res.appendChild(useSvg("Art_Vector_Chastity_Vagina_Fat")); } else { - r += jsInclude("Art_Vector_Chastity_Anus"); - r += jsInclude(`Art_Vector_Chastity_Base${bodySize}`); + res.appendChild(useSvg("Art_Vector_Chastity_Anus")); + res.appendChild(useSvg(`Art_Vector_Chastity_Base${bodySize}`)); } } if (slave.chastityVagina === 1) { if (bodySize === "Fat") { - r += jsInclude("Art_Vector_Chastity_Vagina_Fat"); + res.appendChild(useSvg("Art_Vector_Chastity_Vagina_Fat")); } else { - r += jsInclude("Art_Vector_Chastity_Vagina"); - r += jsInclude(`Art_Vector_Chastity_Base${bodySize}`); + res.appendChild(useSvg("Art_Vector_Chastity_Vagina")); + res.appendChild(useSvg(`Art_Vector_Chastity_Base${bodySize}`)); } } if (slave.vaginalAccessory !== "none") { @@ -1203,21 +1243,21 @@ window.VectorArt = (function() { case "striped underwear": case "uncomfortable straps": if (slave.vaginalAccessory === "dildo") { - r += jsInclude("Art_Vector_Dildo_Short"); + res.appendChild(useSvg("Art_Vector_Dildo_Short")); } else if (slave.vaginalAccessory === "long dildo") { - r += jsInclude("Art_Vector_Dildo_Long"); + res.appendChild(useSvg("Art_Vector_Dildo_Long")); } else if (slave.clothes !== "a comfortable bodysuit" && slave.clothes !== "a string bikini" && slave.clothes !== "attractive lingerie for a pregnant woman" && slave.clothes !== "restrictive latex") { if (slave.vaginalAccessory === "large dildo") { /* additional outfits disabled due to the art breaking with the larger accessories */ - r += jsInclude("Art_Vector_Dildo_Large"); + res.appendChild(useSvg("Art_Vector_Dildo_Large")); } else if (slave.vaginalAccessory === "long, large dildo") { - r += jsInclude("Art_Vector_Dildo_Large_Long"); + res.appendChild(useSvg("Art_Vector_Dildo_Large_Long")); } else if (slave.vaginalAccessory === "huge dildo") { - r += jsInclude("Art_Vector_Dildo_Huge"); + res.appendChild(useSvg("Art_Vector_Dildo_Huge")); } else if (slave.vaginalAccessory === "long, huge dildo") { - r += jsInclude("Art_Vector_Dildo_Huge_Long"); + res.appendChild(useSvg("Art_Vector_Dildo_Huge_Long")); } } /* else if (slave.vaginalAccessory === "bullet vibrator" || slave.vaginalAccessory === "smart bullet vibrator") { - r += jsInclude("Art_Vector_Bullet_Vibrator"); + res.appendChild(useSvg("Art_Vector_Bullet_Vibrator")); } */ } } @@ -1621,50 +1661,50 @@ window.VectorArt = (function() { } function ArtVectorCollar() { - r += jsInclude("Art_Vector_Clavicle"); + res.appendChild(useSvg("Art_Vector_Clavicle")); /* TODO: find out where "uncomfortable leather" collar art went */ switch (slave.collar) { case "leather with cowbell": - r += jsInclude("Art_Vector_Collar_Cowbell"); + res.appendChild(useSvg("Art_Vector_Collar_Cowbell")); break; case "heavy gold": - r += jsInclude("Art_Vector_Collar_Gold_Heavy"); + res.appendChild(useSvg("Art_Vector_Collar_Gold_Heavy")); break; case "neck corset": - r += jsInclude("Art_Vector_Collar_Neck_Corset"); + res.appendChild(useSvg("Art_Vector_Collar_Neck_Corset")); break; case "pretty jewelry": - r += jsInclude("Art_Vector_Collar_Pretty_Jewelry"); + res.appendChild(useSvg("Art_Vector_Collar_Pretty_Jewelry")); break; case "cruel retirement counter": - r += jsInclude("Art_Vector_Collar_Retirement_Cruel"); + res.appendChild(useSvg("Art_Vector_Collar_Retirement_Cruel")); break; case "nice retirement counter": - r += jsInclude("Art_Vector_Collar_Retirement_Nice"); + res.appendChild(useSvg("Art_Vector_Collar_Retirement_Nice")); break; case "satin choker": - r += jsInclude("Art_Vector_Collar_Satin_Choker"); + res.appendChild(useSvg("Art_Vector_Collar_Satin_Choker")); break; case "shock punishment": - r += jsInclude("Art_Vector_Collar_Shock_Punishment"); + res.appendChild(useSvg("Art_Vector_Collar_Shock_Punishment")); break; case "stylish leather": - r += jsInclude("Art_Vector_Collar_Stylish_Leather"); + res.appendChild(useSvg("Art_Vector_Collar_Stylish_Leather")); break; case "tight steel": - r += jsInclude("Art_Vector_Collar_Tight_Steel"); + res.appendChild(useSvg("Art_Vector_Collar_Tight_Steel")); break; case "uncomfortable leather": - r += jsInclude("Art_Vector_Collar_Leather_Cruel"); + res.appendChild(useSvg("Art_Vector_Collar_Leather_Cruel")); break; case "silk ribbon": - r += jsInclude("Art_Vector_Collar_Silk_Ribbon"); + res.appendChild(useSvg("Art_Vector_Collar_Silk_Ribbon")); break; case "bowtie": - r += jsInclude("Art_Vector_Collar_Bowtie"); + res.appendChild(useSvg("Art_Vector_Collar_Bowtie")); break; case "ancient Egyptian": - r += jsInclude("Art_Vector_Collar_Ancientegyptian"); + res.appendChild(useSvg("Art_Vector_Collar_Ancientegyptian")); } } @@ -1679,41 +1719,41 @@ window.VectorArt = (function() { /* Updated 2018-10-25 by Fr0g */ /* - added brackets to make boolean logic run */ if (slave.shoes === "heels") { - r += jsInclude("Art_Vector_Shoes_Heel"); + res.appendChild(useSvg("Art_Vector_Shoes_Heel")); } else if (slave.shoes === "pumps") { - r += jsInclude("Art_Vector_Shoes_Pump"); + res.appendChild(useSvg("Art_Vector_Shoes_Pump")); } else if (slave.shoes === "extreme heels") { - r += jsInclude(`Art_Vector_Shoes_Extreme_Heel_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Shoes_Extreme_Heel_${legSize}`)); } else if (slave.shoes === "boots") { - r += jsInclude(`Art_Vector_Shoes_Boot_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Shoes_Boot_${legSize}`)); } else if (slave.shoes === "flats") { - r += jsInclude("Art_Vector_Shoes_Flat"); + res.appendChild(useSvg("Art_Vector_Shoes_Flat")); } else { if (slave.amp === 0) { - r += jsInclude("Art_Vector_Feet_Normal"); + res.appendChild(useSvg("Art_Vector_Feet_Normal")); } else if (slave.PLimb === 1 || slave.PLimb === 2) { if (slave.amp === -1) { - r += jsInclude("Art_Vector_Feet_ProstheticBasic"); + res.appendChild(useSvg("Art_Vector_Feet_ProstheticBasic")); } else if (slave.amp === -2) { - r += jsInclude("Art_Vector_Feet_ProstheticSexy"); + res.appendChild(useSvg("Art_Vector_Feet_ProstheticSexy")); } else if (slave.amp === -3) { - r += jsInclude("Art_Vector_Feet_ProstheticBeauty"); + res.appendChild(useSvg("Art_Vector_Feet_ProstheticBeauty")); } else if (slave.amp === -4) { - r += jsInclude("Art_Vector_Feet_ProstheticCombat"); + res.appendChild(useSvg("Art_Vector_Feet_ProstheticCombat")); } else if (slave.amp === -5) { - r += jsInclude("Art_Vector_Feet_ProstheticSwiss"); + res.appendChild(useSvg("Art_Vector_Feet_ProstheticSwiss")); } } } if (stockings !== undefined && slave.amp !== 1) { if (slave.shoes === "heels") { - r += jsInclude(`Art_Vector_Shoes_Heel_${stockings}_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Shoes_Heel_${stockings}_${legSize}`)); } else if (slave.shoes === "pumps") { - r += jsInclude(`Art_Vector_Shoes_Pump_${stockings}_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Shoes_Pump_${stockings}_${legSize}`)); } else if (slave.shoes === "flats") { - r += jsInclude(`Art_Vector_Shoes_Flat_${stockings}_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Shoes_Flat_${stockings}_${legSize}`)); } else if (slave.shoes === "none") { - r += jsInclude(`Art_Vector_Shoes_Stockings_${stockings}_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Shoes_Stockings_${stockings}_${legSize}`)); } } switch (slave.clothes) { @@ -1777,14 +1817,14 @@ window.VectorArt = (function() { if (outfit !== undefined) { if (slave.amp !== 1) { if (slave.clothes !== "a slutty qipao" && slave.clothes !== "harem gauze" && slave.clothes !== "slutty jewelry" && slave.clothes !== "Western clothing") { /* these clothes have a stump/leg outfit, but no butt outfit */ - r += jsInclude(`Art_Vector_Butt_Outfit_${outfit}_${buttSize}`); + res.appendChild(useSvg(`Art_Vector_Butt_Outfit_${outfit}_${buttSize}`)); } if (slave.clothes !== "a schoolgirl outfit") { /* file is there, but contains no artwork */ - r += jsInclude(`Art_Vector_Leg_Outfit_${outfit}_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Leg_Outfit_${outfit}_${legSize}`)); } } else { if (outfit === "Shine") { /* the only stump outfit that does not draw an empty svg */ - r += jsInclude(`Art_Vector_Leg_Outfit_${outfit}_Stump`); + res.appendChild(useSvg(`Art_Vector_Leg_Outfit_${outfit}_Stump`)); } } } @@ -1793,7 +1833,7 @@ window.VectorArt = (function() { function ArtVectorHairBack() { if (hairLength !== undefined) { /* Don't draw hair if it isn't there */ if (slave.fuckdoll !== 0 || (slave.bald !== 0 && slave.hStyle === "bald")) { - r += jsInclude("Art_Vector_Hair_Back_NoHair"); + res.appendChild(useSvg("Art_Vector_Hair_Back_NoHair")); } else { switch (slave.clothes) { case "a biyelgee costume": @@ -1824,20 +1864,20 @@ window.VectorArt = (function() { case "buzzcut": case "shaved": case "shaved bald": - r += jsInclude("Art_Vector_Hair_Back_NoHair"); + res.appendChild(useSvg("Art_Vector_Hair_Back_NoHair")); break; case "afro": if (slave.hLength >= 150) { - r += jsInclude("Art_Vector_Hair_Back_Afro_Giant"); + res.appendChild(useSvg("Art_Vector_Hair_Back_Afro_Giant")); } else { - r += jsInclude(`Art_Vector_Hair_Back_Afro_${hairLength}`); + res.appendChild(useSvg(`Art_Vector_Hair_Back_Afro_${hairLength}`)); } break; case "messy bun": - r += jsInclude(`Art_Vector_Hair_Back_Ninja_${hairLength}`); + res.appendChild(useSvg(`Art_Vector_Hair_Back_Ninja_${hairLength}`)); break; case "strip": - r += jsInclude("Art_Vector_Hair_Back_NoHair"); + res.appendChild(useSvg("Art_Vector_Hair_Back_NoHair")); break; case "braided": case "bun": @@ -1852,24 +1892,24 @@ window.VectorArt = (function() { case "ponytail": case "tails": case "up": - r += jsInclude(`Art_Vector_Hair_Back_${capFirstChar(slave.hStyle)}_${hairLength}`); + res.appendChild(useSvg(`Art_Vector_Hair_Back_${capFirstChar(slave.hStyle)}_${hairLength}`)); break; default: - r += jsInclude("Art_Vector_Hair_Back_Messy_Medium"); + res.appendChild(useSvg("Art_Vector_Hair_Back_Messy_Medium")); } } } } /* note: latex clothing actually shows some hair, but there is no appropriate art for it */ if (slave.collar === "cat ears") { - r += jsInclude("Art_Vector_Cat_Ear_Back"); + res.appendChild(useSvg("Art_Vector_Cat_Ear_Back")); } } function ArtVectorHairFore() { if (hairLength !== undefined) { /* Don't draw hair if it isn't there */ if (slave.fuckdoll !== 0 || (slave.bald !== 0 && slave.hStyle === "bald")) { - r += jsInclude("Art_Vector_Hair_Fore_NoHair"); + res.appendChild(useSvg("Art_Vector_Hair_Fore_NoHair")); } else { switch (slave.clothes) { case "a biyelgee costume": @@ -1900,22 +1940,22 @@ window.VectorArt = (function() { case "buzzcut": case "shaved": case "shaved bald": - r += jsInclude("Art_Vector_Hair_Fore_NoHair"); + res.appendChild(useSvg("Art_Vector_Hair_Fore_NoHair")); break; case "afro": if (slave.hLength >= 150) { - r += jsInclude("Art_Vector_Hair_Fore_Afro_Giant"); + res.appendChild(useSvg("Art_Vector_Hair_Fore_Afro_Giant")); } else { - r += jsInclude(`Art_Vector_Hair_Fore_Afro_${hairLength}`); + res.appendChild(useSvg(`Art_Vector_Hair_Fore_Afro_${hairLength}`)); } break; case "messy bun": - r += jsInclude(`Art_Vector_Hair_Fore_Ninja_${hairLength}`); + res.appendChild(useSvg(`Art_Vector_Hair_Fore_Ninja_${hairLength}`)); break; case "bun": case "neat": case "ponytail": - r += jsInclude(`Art_Vector_Hair_Fore_${capFirstChar(slave.hStyle)}`); + res.appendChild(useSvg(`Art_Vector_Hair_Fore_${capFirstChar(slave.hStyle)}`)); break; case "braided": case "cornrows": @@ -1928,17 +1968,17 @@ window.VectorArt = (function() { case "strip": case "tails": case "up": - r += jsInclude(`Art_Vector_Hair_Fore_${capFirstChar(slave.hStyle)}_${hairLength}`); + res.appendChild(useSvg(`Art_Vector_Hair_Fore_${capFirstChar(slave.hStyle)}_${hairLength}`)); break; default: - r += jsInclude("Art_Vector_Hair_Fore_Messy_Medium"); + res.appendChild(useSvg("Art_Vector_Hair_Fore_Messy_Medium")); } } } } /* note: latex clothing actually shows some hair, but there is no appropriate art for it */ if (slave.collar === "cat ears") { - r += jsInclude("Art_Vector_Cat_Ear_Fore"); + res.appendChild(useSvg("Art_Vector_Cat_Ear_Fore")); } } @@ -1946,24 +1986,24 @@ window.VectorArt = (function() { const eyebrowFullness = clothing2artSuffix(slave.eyebrowFullness); /* designed for clothing but works for eyebrows too. If other eyebrow styles are added, this may need to be changed. */ const hasEyebrows = slave.eyebrowHStyle !== "bald" && slave.eyebrowHStyle !== "shaved"; - r += jsInclude("Art_Vector_Head"); + res.appendChild(useSvg("Art_Vector_Head")); /* shiny clothing */ if (V.seeVectorArtHighlights === 1) { if (wearingLatex === true) { - r += jsInclude("Art_Vector_Head_Outfit_Shine"); + res.appendChild(useSvg("Art_Vector_Head_Outfit_Shine")); } } if (slave.clothes !== "restrictive latex") { if (slave.markings === "beauty mark") { - r += jsInclude("Art_Vector_Beauty_Mark"); + res.appendChild(useSvg("Art_Vector_Beauty_Mark")); } else if (slave.markings === "freckles") { - r += jsInclude("Art_Vector_Freckles"); + res.appendChild(useSvg("Art_Vector_Freckles")); } else if (slave.markings === "heavily freckled") { - r += jsInclude("Art_Vector_Freckles_Heavy"); + res.appendChild(useSvg("Art_Vector_Freckles_Heavy")); } else if (slave.markings === "birthmark") { - r += jsInclude("Art_Vector_Birthmark"); + res.appendChild(useSvg("Art_Vector_Birthmark")); } else if (slave.minorInjury === "black eye") { - r += jsInclude("Art_Vector_Black_Eye"); + res.appendChild(useSvg("Art_Vector_Black_Eye")); } } /* FACIAL APPEARANCE */ @@ -1973,46 +2013,46 @@ window.VectorArt = (function() { case "southern european": case "white": if (slave.faceShape === "normal") { - r += jsInclude("Art_Vector_Eyes_TypeB"); - r += jsInclude("Art_Vector_Mouth_TypeA"); - r += jsInclude("Art_Vector_Nose_TypeA"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeB")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeA")); + res.appendChild(useSvg("Art_Vector_Nose_TypeA")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`)); } } else if (slave.faceShape === "masculine") { - r += jsInclude("Art_Vector_Eyes_TypeD"); - r += jsInclude("Art_Vector_Mouth_TypeF"); - r += jsInclude("Art_Vector_Nose_TypeF"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeD")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeF")); + res.appendChild(useSvg("Art_Vector_Nose_TypeF")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`)); } } else if (slave.faceShape === "androgynous") { - r += jsInclude("Art_Vector_Eyes_TypeE"); - r += jsInclude("Art_Vector_Mouth_TypeE"); - r += jsInclude("Art_Vector_Nose_TypeE"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeE")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeE")); + res.appendChild(useSvg("Art_Vector_Nose_TypeE")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`)); } } else if (slave.faceShape === "cute") { - r += jsInclude("Art_Vector_Eyes_TypeB"); - r += jsInclude("Art_Vector_Mouth_TypeB"); - r += jsInclude("Art_Vector_Nose_TypeD"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeB")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeB")); + res.appendChild(useSvg("Art_Vector_Nose_TypeD")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`)); } } else if (slave.faceShape === "sensual") { - r += jsInclude("Art_Vector_Eyes_TypeC"); - r += jsInclude("Art_Vector_Mouth_TypeC"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeC")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeC")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } else if (slave.faceShape === "exotic") { - r += jsInclude("Art_Vector_Eyes_TypeA"); - r += jsInclude("Art_Vector_Mouth_TypeC"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeA")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeC")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } break; @@ -2020,366 +2060,366 @@ window.VectorArt = (function() { case "malay": case "pacific islander": if (slave.faceShape === "normal") { - r += jsInclude("Art_Vector_Eyes_TypeA"); - r += jsInclude("Art_Vector_Mouth_TypeC"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeA")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeC")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`)); } } else if (slave.faceShape === "masculine") { - r += jsInclude("Art_Vector_Eyes_TypeD"); - r += jsInclude("Art_Vector_Mouth_TypeD"); - r += jsInclude("Art_Vector_Nose_TypeB"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeD")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeD")); + res.appendChild(useSvg("Art_Vector_Nose_TypeB")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } else if (slave.faceShape === "androgynous") { - r += jsInclude("Art_Vector_Eyes_TypeE"); - r += jsInclude("Art_Vector_Mouth_TypeE"); - r += jsInclude("Art_Vector_Nose_TypeA"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeE")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeE")); + res.appendChild(useSvg("Art_Vector_Nose_TypeA")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } else if (slave.faceShape === "cute") { - r += jsInclude("Art_Vector_Eyes_TypeC"); - r += jsInclude("Art_Vector_Mouth_TypeC"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeC")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeC")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`)); } } else if (slave.faceShape === "sensual") { - r += jsInclude("Art_Vector_Eyes_TypeA"); - r += jsInclude("Art_Vector_Mouth_TypeA"); - r += jsInclude("Art_Vector_Nose_TypeE"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeA")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeA")); + res.appendChild(useSvg("Art_Vector_Nose_TypeE")); if (slave.eyebrowFullness === "pencil-thin") { - r += jsInclude("Art_Vector_Eyebrow_TypeC_Pencilthin"); + res.appendChild(useSvg("Art_Vector_Eyebrow_TypeC_Pencilthin")); } else if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`)); } } else if (slave.faceShape === "exotic") { - r += jsInclude("Art_Vector_Eyes_TypeB"); - r += jsInclude("Art_Vector_Mouth_TypeC"); - r += jsInclude("Art_Vector_Nose_TypeF"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeB")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeC")); + res.appendChild(useSvg("Art_Vector_Nose_TypeF")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`)); } } break; case "amerindian": case "latina": if (slave.faceShape === "normal") { - r += jsInclude("Art_Vector_Eyes_TypeB"); - r += jsInclude("Art_Vector_Mouth_TypeE"); - r += jsInclude("Art_Vector_Nose_TypeD"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeB")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeE")); + res.appendChild(useSvg("Art_Vector_Nose_TypeD")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeB_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeB_${eyebrowFullness}`)); } } else if (slave.faceShape === "masculine") { - r += jsInclude("Art_Vector_Eyes_TypeE"); - r += jsInclude("Art_Vector_Mouth_TypeD"); - r += jsInclude("Art_Vector_Nose_TypeF"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeE")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeD")); + res.appendChild(useSvg("Art_Vector_Nose_TypeF")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } else if (slave.faceShape === "androgynous") { - r += jsInclude("Art_Vector_Eyes_TypeA"); - r += jsInclude("Art_Vector_Mouth_TypeD"); - r += jsInclude("Art_Vector_Nose_TypeB"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeA")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeD")); + res.appendChild(useSvg("Art_Vector_Nose_TypeB")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`)); } } else if (slave.faceShape === "cute") { - r += jsInclude("Art_Vector_Eyes_TypeF"); - r += jsInclude("Art_Vector_Mouth_TypeB"); - r += jsInclude("Art_Vector_Nose_TypeB"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeF")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeB")); + res.appendChild(useSvg("Art_Vector_Nose_TypeB")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`)); } } else if (slave.faceShape === "sensual") { - r += jsInclude("Art_Vector_Eyes_TypeB"); - r += jsInclude("Art_Vector_Mouth_TypeE"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeB")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeE")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`)); } } else if (slave.faceShape === "exotic") { - r += jsInclude("Art_Vector_Eyes_TypeC"); - r += jsInclude("Art_Vector_Mouth_TypeA"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeC")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeA")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`)); } } break; case "black": if (slave.faceShape === "normal") { - r += jsInclude("Art_Vector_Eyes_TypeD"); - r += jsInclude("Art_Vector_Mouth_TypeB"); - r += jsInclude("Art_Vector_Nose_TypeF"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeD")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeB")); + res.appendChild(useSvg("Art_Vector_Nose_TypeF")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`)); } } else if (slave.faceShape === "masculine") { - r += jsInclude("Art_Vector_Eyes_TypeA"); - r += jsInclude("Art_Vector_Mouth_TypeD"); - r += jsInclude("Art_Vector_Nose_TypeF"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeA")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeD")); + res.appendChild(useSvg("Art_Vector_Nose_TypeF")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`)); } } else if (slave.faceShape === "androgynous") { - r += jsInclude("Art_Vector_Eyes_TypeF"); - r += jsInclude("Art_Vector_Mouth_TypeE"); - r += jsInclude("Art_Vector_Nose_TypeB"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeF")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeE")); + res.appendChild(useSvg("Art_Vector_Nose_TypeB")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`)); } } else if (slave.faceShape === "cute") { - r += jsInclude("Art_Vector_Eyes_TypeC"); - r += jsInclude("Art_Vector_Mouth_TypeE"); - r += jsInclude("Art_Vector_Nose_TypeD"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeC")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeE")); + res.appendChild(useSvg("Art_Vector_Nose_TypeD")); if (slave.eyebrowFullness === "natural") { - r += jsInclude("Art_Vector_Eyebrow_TypeB_Natural"); + res.appendChild(useSvg("Art_Vector_Eyebrow_TypeB_Natural")); } else if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`)); } } else if (slave.faceShape === "sensual") { - r += jsInclude("Art_Vector_Eyes_TypeC"); - r += jsInclude("Art_Vector_Mouth_TypeF"); - r += jsInclude("Art_Vector_Nose_TypeA"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeC")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeF")); + res.appendChild(useSvg("Art_Vector_Nose_TypeA")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } else if (slave.faceShape === "exotic") { - r += jsInclude("Art_Vector_Eyes_TypeE"); - r += jsInclude("Art_Vector_Mouth_TypeE"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeE")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeE")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`)); } } break; case "middle eastern": if (slave.faceShape === "normal") { - r += jsInclude("Art_Vector_Eyes_TypeB"); - r += jsInclude("Art_Vector_Mouth_TypeA"); - r += jsInclude("Art_Vector_Nose_TypeA"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeB")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeA")); + res.appendChild(useSvg("Art_Vector_Nose_TypeA")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`)); } } else if (slave.faceShape === "masculine") { - r += jsInclude("Art_Vector_Eyes_TypeD"); - r += jsInclude("Art_Vector_Mouth_TypeF"); - r += jsInclude("Art_Vector_Nose_TypeA"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeD")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeF")); + res.appendChild(useSvg("Art_Vector_Nose_TypeA")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeB_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeB_${eyebrowFullness}`)); } } else if (slave.faceShape === "androgynous") { - r += jsInclude("Art_Vector_Eyes_TypeF"); - r += jsInclude("Art_Vector_Mouth_TypeB"); - r += jsInclude("Art_Vector_Nose_TypeF"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeF")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeB")); + res.appendChild(useSvg("Art_Vector_Nose_TypeF")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`)); } } else if (slave.faceShape === "cute") { - r += jsInclude("Art_Vector_Eyes_TypeB"); - r += jsInclude("Art_Vector_Mouth_TypeB"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeB")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeB")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`)); } } else if (slave.faceShape === "sensual") { - r += jsInclude("Art_Vector_Eyes_TypeA"); - r += jsInclude("Art_Vector_Mouth_TypeD"); - r += jsInclude("Art_Vector_Nose_TypeA"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeA")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeD")); + res.appendChild(useSvg("Art_Vector_Nose_TypeA")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } else if (slave.faceShape === "exotic") { - r += jsInclude("Art_Vector_Eyes_TypeE"); - r += jsInclude("Art_Vector_Mouth_TypeE"); - r += jsInclude("Art_Vector_Nose_TypeE"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeE")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeE")); + res.appendChild(useSvg("Art_Vector_Nose_TypeE")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`)); } } break; case "semitic": if (slave.faceShape === "normal") { - r += jsInclude("Art_Vector_Eyes_TypeB"); - r += jsInclude("Art_Vector_Mouth_TypeA"); - r += jsInclude("Art_Vector_Nose_TypeA"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeB")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeA")); + res.appendChild(useSvg("Art_Vector_Nose_TypeA")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`)); } } else if (slave.faceShape === "masculine") { - r += jsInclude("Art_Vector_Eyes_TypeD"); - r += jsInclude("Art_Vector_Mouth_TypeF"); - r += jsInclude("Art_Vector_Nose_TypeA"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeD")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeF")); + res.appendChild(useSvg("Art_Vector_Nose_TypeA")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeB_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeB_${eyebrowFullness}`)); } } else if (slave.faceShape === "androgynous") { - r += jsInclude("Art_Vector_Eyes_TypeF"); - r += jsInclude("Art_Vector_Mouth_TypeB"); - r += jsInclude("Art_Vector_Nose_TypeF"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeF")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeB")); + res.appendChild(useSvg("Art_Vector_Nose_TypeF")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`)); } } else if (slave.faceShape === "cute") { - r += jsInclude("Art_Vector_Eyes_TypeB"); - r += jsInclude("Art_Vector_Mouth_TypeB"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeB")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeB")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`)); } } else if (slave.faceShape === "sensual") { - r += jsInclude("Art_Vector_Eyes_TypeA"); - r += jsInclude("Art_Vector_Mouth_TypeD"); - r += jsInclude("Art_Vector_Nose_TypeA"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeA")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeD")); + res.appendChild(useSvg("Art_Vector_Nose_TypeA")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } else if (slave.faceShape === "exotic") { - r += jsInclude("Art_Vector_Eyes_TypeE"); - r += jsInclude("Art_Vector_Mouth_TypeE"); - r += jsInclude("Art_Vector_Nose_TypeE"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeE")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeE")); + res.appendChild(useSvg("Art_Vector_Nose_TypeE")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`)); } } break; case "indo-aryan": if (slave.faceShape === "normal") { - r += jsInclude("Art_Vector_Eyes_TypeE"); - r += jsInclude("Art_Vector_Mouth_TypeA"); - r += jsInclude("Art_Vector_Nose_TypeD"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeE")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeA")); + res.appendChild(useSvg("Art_Vector_Nose_TypeD")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`)); } } else if (slave.faceShape === "masculine") { - r += jsInclude("Art_Vector_Eyes_TypeF"); - r += jsInclude("Art_Vector_Mouth_TypeD"); - r += jsInclude("Art_Vector_Nose_TypeE"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeF")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeD")); + res.appendChild(useSvg("Art_Vector_Nose_TypeE")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } else if (slave.faceShape === "androgynous") { - r += jsInclude("Art_Vector_Eyes_TypeC"); - r += jsInclude("Art_Vector_Mouth_TypeB"); - r += jsInclude("Art_Vector_Nose_TypeD"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeC")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeB")); + res.appendChild(useSvg("Art_Vector_Nose_TypeD")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`)); } } else if (slave.faceShape === "cute") { - r += jsInclude("Art_Vector_Eyes_TypeC"); - r += jsInclude("Art_Vector_Mouth_TypeD"); - r += jsInclude("Art_Vector_Nose_TypeA"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeC")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeD")); + res.appendChild(useSvg("Art_Vector_Nose_TypeA")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`)); } } else if (slave.faceShape === "sensual") { - r += jsInclude("Art_Vector_Eyes_TypeA"); - r += jsInclude("Art_Vector_Mouth_TypeE"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeA")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeE")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`)); } } else if (slave.faceShape === "exotic") { - r += jsInclude("Art_Vector_Eyes_TypeA"); - r += jsInclude("Art_Vector_Mouth_TypeC"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeA")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeC")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } break; case "mixed race": if (slave.faceShape === "normal") { - r += jsInclude("Art_Vector_Eyes_TypeE"); - r += jsInclude("Art_Vector_Mouth_TypeA"); - r += jsInclude("Art_Vector_Nose_TypeD"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeE")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeA")); + res.appendChild(useSvg("Art_Vector_Nose_TypeD")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`)); } } else if (slave.faceShape === "masculine") { - r += jsInclude("Art_Vector_Eyes_TypeF"); - r += jsInclude("Art_Vector_Mouth_TypeD"); - r += jsInclude("Art_Vector_Nose_TypeE"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeF")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeD")); + res.appendChild(useSvg("Art_Vector_Nose_TypeE")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } else if (slave.faceShape === "androgynous") { - r += jsInclude("Art_Vector_Eyes_TypeC"); - r += jsInclude("Art_Vector_Mouth_TypeB"); - r += jsInclude("Art_Vector_Nose_TypeD"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeC")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeB")); + res.appendChild(useSvg("Art_Vector_Nose_TypeD")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`)); } } else if (slave.faceShape === "cute") { - r += jsInclude("Art_Vector_Eyes_TypeC"); - r += jsInclude("Art_Vector_Mouth_TypeD"); - r += jsInclude("Art_Vector_Nose_TypeA"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeC")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeD")); + res.appendChild(useSvg("Art_Vector_Nose_TypeA")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`)); } } else if (slave.faceShape === "sensual") { - r += jsInclude("Art_Vector_Eyes_TypeA"); - r += jsInclude("Art_Vector_Mouth_TypeE"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeA")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeE")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeD_${eyebrowFullness}`)); } } else if (slave.faceShape === "exotic") { - r += jsInclude("Art_Vector_Eyes_TypeA"); - r += jsInclude("Art_Vector_Mouth_TypeC"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeA")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeC")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } break; default: if (slave.faceShape === "normal") { - r += jsInclude("Art_Vector_Eyes_TypeB"); - r += jsInclude("Art_Vector_Mouth_TypeA"); - r += jsInclude("Art_Vector_Nose_TypeA"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeB")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeA")); + res.appendChild(useSvg("Art_Vector_Nose_TypeA")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`)); } } else if (slave.faceShape === "masculine") { - r += jsInclude("Art_Vector_Eyes_TypeD"); - r += jsInclude("Art_Vector_Mouth_TypeF"); - r += jsInclude("Art_Vector_Nose_TypeF"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeD")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeF")); + res.appendChild(useSvg("Art_Vector_Nose_TypeF")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeE_${eyebrowFullness}`)); } } else if (slave.faceShape === "androgynous") { - r += jsInclude("Art_Vector_Eyes_TypeE"); - r += jsInclude("Art_Vector_Mouth_TypeE"); - r += jsInclude("Art_Vector_Nose_TypeE"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeE")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeE")); + res.appendChild(useSvg("Art_Vector_Nose_TypeE")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeF_${eyebrowFullness}`)); } } else if (slave.faceShape === "cute") { - r += jsInclude("Art_Vector_Eyes_TypeB"); - r += jsInclude("Art_Vector_Mouth_TypeB"); - r += jsInclude("Art_Vector_Nose_TypeD"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeB")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeB")); + res.appendChild(useSvg("Art_Vector_Nose_TypeD")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeA_${eyebrowFullness}`)); } } else if (slave.faceShape === "sensual") { - r += jsInclude("Art_Vector_Eyes_TypeC"); - r += jsInclude("Art_Vector_Mouth_TypeC"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeC")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeC")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } else if (slave.faceShape === "exotic") { - r += jsInclude("Art_Vector_Eyes_TypeA"); - r += jsInclude("Art_Vector_Mouth_TypeC"); - r += jsInclude("Art_Vector_Nose_TypeC"); + res.appendChild(useSvg("Art_Vector_Eyes_TypeA")); + res.appendChild(useSvg("Art_Vector_Mouth_TypeC")); + res.appendChild(useSvg("Art_Vector_Nose_TypeC")); if (hasEyebrows === true) { - r += jsInclude(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`); + res.appendChild(useSvg(`Art_Vector_Eyebrow_TypeC_${eyebrowFullness}`)); } } } @@ -2388,39 +2428,39 @@ window.VectorArt = (function() { /* END FACIAL APPEARANCE */ if (slave.eyebrowPiercing === 1) { - r += jsInclude("Art_Vector_Eyebrow_Light"); + res.appendChild(useSvg("Art_Vector_Eyebrow_Light")); } else if (slave.eyebrowPiercing === 2) { - r += jsInclude("Art_Vector_Eyebrow_Heavy"); + res.appendChild(useSvg("Art_Vector_Eyebrow_Heavy")); } if (slave.nosePiercing === 1) { - r += jsInclude("Art_Vector_Nose_Light"); + res.appendChild(useSvg("Art_Vector_Nose_Light")); } else if (slave.nosePiercing === 2) { - r += jsInclude("Art_Vector_Nose_Heavy"); + res.appendChild(useSvg("Art_Vector_Nose_Heavy")); } if (slave.lipsPiercing === 1) { - r += jsInclude("Art_Vector_Lip_Light"); + res.appendChild(useSvg("Art_Vector_Lip_Light")); } else if (slave.lipsPiercing === 2) { - r += jsInclude("Art_Vector_Lip_Heavy"); + res.appendChild(useSvg("Art_Vector_Lip_Heavy")); } /* ADDONS */ if (slave.fuckdoll === 0) { /* Fuckdolls cannot be decorated */ if (slave.collar === "dildo gag") { - r += jsInclude("Art_Vector_Dildo_Gag"); + res.appendChild(useSvg("Art_Vector_Dildo_Gag")); } else if (slave.collar === "ball gag") { - r += jsInclude("Art_Vector_Ball_Gag"); + res.appendChild(useSvg("Art_Vector_Ball_Gag")); } else if (slave.collar === "bit gag") { - r += jsInclude("Art_Vector_Bit_Gag"); + res.appendChild(useSvg("Art_Vector_Bit_Gag")); } else if (slave.collar === "massive dildo gag") { - r += jsInclude("Art_Vector_Massive_Dildo_Gag"); + res.appendChild(useSvg("Art_Vector_Massive_Dildo_Gag")); } else if (slave.collar === "porcelain mask") { - r += jsInclude("Art_Vector_Porcelain_Mask"); + res.appendChild(useSvg("Art_Vector_Porcelain_Mask")); } if (slave.eyewear === "corrective glasses" || slave.eyewear === "glasses" || slave.eyewear === "blurring glasses") { - r += jsInclude("Art_Vector_Glasses"); + res.appendChild(useSvg("Art_Vector_Glasses")); } /* head clothing */ @@ -2447,15 +2487,15 @@ window.VectorArt = (function() { case "battlearmor": case "harem gauze": case "Western clothing": - r += jsInclude(`Art_Vector_Head_Outfit_${clothing2artSuffix(slave.clothes)}`); + res.appendChild(useSvg(`Art_Vector_Head_Outfit_${clothing2artSuffix(slave.clothes)}`)); break; case "a schutzstaffel uniform": case "a slutty schutzstaffel uniform": - r += jsInclude("Art_Vector_Head_Outfit_SchutzstaffelUniform"); + res.appendChild(useSvg("Art_Vector_Head_Outfit_SchutzstaffelUniform")); break; case "kitty lingerie": - r += jsInclude("Art_Vector_Cat_Ear_Fore"); - r += jsInclude("Art_Vector_Cat_Ear_Back"); + res.appendChild(useSvg("Art_Vector_Cat_Ear_Fore")); + res.appendChild(useSvg("Art_Vector_Cat_Ear_Back")); } } } @@ -2463,27 +2503,27 @@ window.VectorArt = (function() { function ArtVectorLeg() { /* Selection of matching SVG based on amputee level */ if (slave.amp === 0) { - r += jsInclude(`Art_Vector_Leg_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Leg_${legSize}`)); if (slave.muscles >= 97) { - r += jsInclude(`Art_Vector_Leg_${legSize}_MHeavy`); + res.appendChild(useSvg(`Art_Vector_Leg_${legSize}_MHeavy`)); } else if (slave.muscles >= 62) { - r += jsInclude(`Art_Vector_Leg_${legSize}_MMedium`); + res.appendChild(useSvg(`Art_Vector_Leg_${legSize}_MMedium`)); } else if (slave.muscles >= 30) { - r += jsInclude(`Art_Vector_Leg_${legSize}_MLight`); + res.appendChild(useSvg(`Art_Vector_Leg_${legSize}_MLight`)); } } else if (slave.amp === 1) { - r += jsInclude("Art_Vector_Stump"); + res.appendChild(useSvg("Art_Vector_Stump")); } else if (slave.PLimb === 1 || slave.PLimb === 2) { /* slave is an amputee and has PLimbs equipped */ if (slave.amp === -1) { - r += jsInclude(`Art_Vector_Leg_ProstheticBasic_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Leg_ProstheticBasic_${legSize}`)); } else if (slave.amp === -2) { - r += jsInclude(`Art_Vector_Leg_ProstheticSexy_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Leg_ProstheticSexy_${legSize}`)); } else if (slave.amp === -3) { - r += jsInclude(`Art_Vector_Leg_ProstheticBeauty_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Leg_ProstheticBeauty_${legSize}`)); } else if (slave.amp === -4) { - r += jsInclude(`Art_Vector_Leg_ProstheticCombat_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Leg_ProstheticCombat_${legSize}`)); } else { /* slave.amp === -5 */ - r += jsInclude(`Art_Vector_Leg_ProstheticSwiss_${legSize}`); + res.appendChild(useSvg(`Art_Vector_Leg_ProstheticSwiss_${legSize}`)); } } } @@ -2498,16 +2538,16 @@ window.VectorArt = (function() { // eslint-disable-next-line camelcase T.art_pussy_tattoo_text = "Fucktoy"; } - r += jsInclude("Art_Vector_Pussy_Tattoo"); + res.appendChild(useSvg("Art_Vector_Pussy_Tattoo")); } if (slave.physicalAge < 11) { /* these art files exist, but draw empty svg's. Commented out for now to save on rendering time - r += jsInclude("Art_Vector_Pubic_Hair_None"); - r += jsInclude("Art_Vector_Pubic_Hair_Underarm_None"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_None")); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_Underarm_None")); */ } else if (slave.physicalAge <= 13) { if (slave.pubicHStyle !== "waxed") { - r += jsInclude("Art_Vector_Pubic_Hair_Wispy"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_Wispy")); } } else if (slave.clothes !== "a comfortable bodysuit") { switch (slave.pubicHStyle) { @@ -2515,43 +2555,43 @@ window.VectorArt = (function() { case "hairless": case "waxed": /* commented out to save on rendering time - r += jsInclude("Art_Vector_Pubic_Hair_None"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_None")); */ break; case "strip": case "in a strip": if (torsoSize === "Obese" || torsoSize === "Fat") { - r += jsInclude("Art_Vector_Pubic_Hair_StripFat"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_StripFat")); } else { - r += jsInclude("Art_Vector_Pubic_Hair_Strip"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_Strip")); } break; case "neat": if (torsoSize === "Obese" || torsoSize === "Fat") { - r += jsInclude("Art_Vector_Pubic_Hair_NeatFat"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_NeatFat")); } else { - r += jsInclude("Art_Vector_Pubic_Hair_Neat"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_Neat")); } break; case "bushy in the front and neat in the rear": if (torsoSize === "Obese" || torsoSize === "Fat") { - r += jsInclude("Art_Vector_Pubic_Hair_BushFat"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_BushFat")); } else { - r += jsInclude("Art_Vector_Pubic_Hair_Bush"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_Bush")); } break; case "bushy": if (torsoSize === "Obese" || torsoSize === "Fat") { - r += jsInclude("Art_Vector_Pubic_Hair_BushyFat"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_BushyFat")); } else { - r += jsInclude("Art_Vector_Pubic_Hair_Bushy"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_Bushy")); } break; case "very bushy": if (torsoSize === "Obese" || torsoSize === "Fat") { - r += jsInclude("Art_Vector_Pubic_Hair_Very_BushyFat"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_Very_BushyFat")); } else { - r += jsInclude("Art_Vector_Pubic_Hair_Very_Bushy"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_Very_Bushy")); } } switch (slave.underArmHStyle) { @@ -2559,17 +2599,17 @@ window.VectorArt = (function() { case "waxed": case "bald": /* commented out to save on rendering time - r += jsInclude("Art_Vector_Pubic_Hair_Underarm_None"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_Underarm_None")); */ break; case "shaved": - r += jsInclude("Art_Vector_Pubic_Hair_Underarm_Shaved"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_Underarm_Shaved")); break; case "neat": - r += jsInclude("Art_Vector_Pubic_Hair_Underarm_Neat"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_Underarm_Neat")); break; case "bushy": - r += jsInclude("Art_Vector_Pubic_Hair_Underarm_Bushy"); + res.appendChild(useSvg("Art_Vector_Pubic_Hair_Underarm_Bushy")); } } } @@ -2577,7 +2617,7 @@ window.VectorArt = (function() { function ArtVectorPussy() { if (slave.vagina >= 0 && slave.clothes !== "a latex catsuit" && slave.clothes !== "a comfortable bodysuit" && slave.clothes !== "a cybersuit") { - r += jsInclude("Art_Vector_Pussy"); + res.appendChild(useSvg("Art_Vector_Pussy")); } } @@ -2611,29 +2651,29 @@ window.VectorArt = (function() { case "Western clothing": /* piercinglevel = 1, Light; piercinglevel = 2, Heavy; piercinglevel = 3, Smart; piercinglevel = 0, None */ if (slave.vaginaPiercing === 1) { - r += jsInclude("Art_Vector_Pussy_Piercing"); + res.appendChild(useSvg("Art_Vector_Pussy_Piercing")); } else if (slave.vaginaPiercing === 2) { - r += jsInclude("Art_Vector_Pussy_Piercing_Heavy"); + res.appendChild(useSvg("Art_Vector_Pussy_Piercing_Heavy")); } if (slave.clitPiercing === 1) { - r += jsInclude("Art_Vector_Clit_Piercing"); + res.appendChild(useSvg("Art_Vector_Clit_Piercing")); } else if (slave.clitPiercing === 2) { - r += jsInclude("Art_Vector_Clit_Piercing_Heavy"); + res.appendChild(useSvg("Art_Vector_Clit_Piercing_Heavy")); } else if (slave.clitPiercing === 3) { - r += jsInclude("Art_Vector_Clit_Piercing_Smart"); + res.appendChild(useSvg("Art_Vector_Clit_Piercing_Smart")); } } } function ArtVectorTorso() { - r += jsInclude(`Art_Vector_Torso_${torsoSize}`); + res.appendChild(useSvg(`Art_Vector_Torso_${torsoSize}`)); if (slave.muscles >= 97) { - r += jsInclude(`Art_Vector_Torso_${torsoSize}_MHeavy`); + res.appendChild(useSvg(`Art_Vector_Torso_${torsoSize}_MHeavy`)); } else if (slave.muscles >= 62) { - r += jsInclude(`Art_Vector_Torso_${torsoSize}_MMedium`); + res.appendChild(useSvg(`Art_Vector_Torso_${torsoSize}_MMedium`)); } else if (slave.muscles >= 30) { - r += jsInclude(`Art_Vector_Torso_${torsoSize}_MLight`); + res.appendChild(useSvg(`Art_Vector_Torso_${torsoSize}_MLight`)); } } @@ -2652,472 +2692,508 @@ window.VectorArt = (function() { break; /* no torso outfit */ /* manually handle special cases */ case "a cybersuit": - r += jsInclude(`Art_Vector_Torso_Outfit_Latex_${torsoSize}`); + res.appendChild(useSvg(`Art_Vector_Torso_Outfit_Latex_${torsoSize}`)); break; case "a slutty schutzstaffel uniform": - r += jsInclude(`Art_Vector_Torso_Outfit_SchutzstaffelUniform_${torsoSize}`); + res.appendChild(useSvg(`Art_Vector_Torso_Outfit_SchutzstaffelUniform_${torsoSize}`)); break; case "a niqab and abaya": case "a burqa": - r += jsInclude(`Art_Vector_Torso_Outfit_HijabAndAbaya_${torsoSize}`); + res.appendChild(useSvg(`Art_Vector_Torso_Outfit_HijabAndAbaya_${torsoSize}`)); break; default: - r += jsInclude(`Art_Vector_Torso_Outfit_${clothing2artSuffix(slave.clothes)}_${torsoSize}`); + res.appendChild(useSvg(`Art_Vector_Torso_Outfit_${clothing2artSuffix(slave.clothes)}_${torsoSize}`)); } if (V.seeVectorArtHighlights === 1) { if (wearingLatex === true) { if (slave.amp !== 0) { - r += jsInclude("Art_Vector_Torso_Outfit_Shine_Shoulder"); + res.appendChild(useSvg("Art_Vector_Torso_Outfit_Shine_Shoulder")); } if (slave.preg <= 0) { - r += jsInclude(`Art_Vector_Torso_Outfit_Shine_${torsoSize}`); + res.appendChild(useSvg(`Art_Vector_Torso_Outfit_Shine_${torsoSize}`)); } } } } return VectorArt; -})(); +}) (); -window.LegacyVectorArt = function(slave, artSize) { - const filePath = "'resources/vector"; + +App.Art.legacyVectorArtElement = function() { + const filePath = "resources/vector"; const skinFilePath = `${filePath}/body/white`; - const wearingLatex = slave.clothes === "a Fuckdoll suit" || slave.clothes === "restrictive latex" || slave.clothes === "a latex catsuit"; - let hairStyle, underArmHStyle, leftArmType, rightArmType, buttSize, legSize, shoesType, torsoSize, boobSize, ballSize, penisSize; - let needBoobs = true; - let r = jsInclude("SVG filters"); - - /* Set skin color */ - let skinFilter = `filter: url(#skin-${_.kebabCase(slave.skin)});`; - /* Set hair color */ - let hairFilter = `filter: url(#hair-${_.kebabCase(slave.hColor)});`; - let underArmFilter = `filter: url(#hair-${_.kebabCase(slave.underArmHColor)});`; - let pubesFilter = `filter: url(#hair-${_.kebabCase(slave.pubicHColor)});`; - - if (artSize === 1) { - r += `<img class='paperdoll' src=${filePath}/test ui.svg'/`; - } - if (slave.custom.hairVector) { - hairStyle = slave.custom.hairVector; - } else { - hairStyle = (["afro", "braided", "bun", "buzzcut", "dreadlocks", "eary", "luxurious", "messy", "neat", "ponytail", "strip", "tails", "trimmed", "up"].includes(slave.hStyle) ? slave.hStyle : "neat"); - } + /** + * @param {App.Entity.SlaveState} slave + * @param {number} artSize + * @returns {DocumentFragment} + */ + function render(slave, artSize) { + const wearingLatex = slave.clothes === "a Fuckdoll suit" || slave.clothes === "restrictive latex" || slave.clothes === "a latex catsuit"; + let hairStyle, underArmHStyle, leftArmType, rightArmType, buttSize, legSize, shoesType, torsoSize, boobSize, ballSize, penisSize; + let needBoobs = true; - underArmHStyle = slave.underArmHStyle; - - /* Shoulder width and arm or no arm */ - if (slave.amp !== 1) { - if (slave.devotion > 50) { - leftArmType = "high"; - rightArmType = "high"; - } else if (slave.trust >= -20) { - if (slave.devotion < -20) { - leftArmType = "rebel"; - rightArmType = "low"; - } else if (slave.devotion <= 20) { - leftArmType = "low"; - rightArmType = "low"; - } else { - leftArmType = "mid"; - rightArmType = "high"; - } - } else { - leftArmType = "mid"; - rightArmType = "mid"; + const res = document.createDocumentFragment(); + res.appendChild(App.Utils.htmlToElement(App.Utils.passageElement("SVG filters").textContent)); + + /* Set skin color */ + let skinFilter = `filter: url(#skin-${_.kebabCase(slave.skin)});`; + /* Set hair color */ + let hairFilter = `filter: url(#hair-${_.kebabCase(slave.hColor)});`; + let underArmFilter = `filter: url(#hair-${_.kebabCase(slave.underArmHColor)});`; + let pubesFilter = `filter: url(#hair-${_.kebabCase(slave.pubicHColor)});`; + + if (artSize === 1) { + addImg(res, "test ui"); } - if (wearingLatex === false) { - r += `<img class='paperdoll' src=${skinFilePath}/arm right ${rightArmType}.svg' style='${skinFilter}'>`; - if (slave.underArmHStyle === "bushy") { - r += `<img class='paperdoll' src=${filePath}/hair/underArm ${underArmHStyle} right.svg' style='{underArmFilter}'/>`; - } + if (slave.custom.hairVector) { + hairStyle = slave.custom.hairVector; } else { - if (slave.fuckdoll !== 0) { - rightArmType = "mid"; - } - r += `<img class='paperdoll' src=${filePath}/outfit/arm right ${rightArmType} latex.svg'/>`; + hairStyle = (["afro", "braided", "bun", "buzzcut", "dreadlocks", "eary", "luxurious", "messy", "neat", "ponytail", "strip", "tails", "trimmed", "up"].includes(slave.hStyle) ? slave.hStyle : "neat"); } - } else if (wearingLatex === false && slave.underArmHStyle === "bushy") { - r += `<img class='paperdoll' src=${filePath}/hair/underArm ${underArmHStyle} right.svg' style='{underArmFilter}'/>`; - } - /* Hair Aft */ - if (slave.fuckdoll === 0) { - switch (slave.hStyle) { - case "eary": - case "luxurious": - case "messy": - case "neat": - case "tails": - case "trimmed": - r += `<img class='paperdoll' src=${filePath}/hair/${hairStyle} back.svg' style='${hairFilter}'/>`; - } - } + underArmHStyle = slave.underArmHStyle; - /* Tailed Plug */ - if (slave.buttplugAttachment === "tail") { - r += `<img class='paperdoll' src=${filePath}/outfit/tail plug.svg' style='${hairFilter}'/>`; - } + /* Shoulder width and arm or no arm */ + if (slave.amp !== 1) { + if (slave.devotion > 50) { + leftArmType = "high"; + rightArmType = "high"; + } else if (slave.trust >= -20) { + if (slave.devotion < -20) { + leftArmType = "rebel"; + rightArmType = "low"; + } else if (slave.devotion <= 20) { + leftArmType = "low"; + rightArmType = "low"; + } else { + leftArmType = "mid"; + rightArmType = "high"; + } + } else { + leftArmType = "mid"; + rightArmType = "mid"; + } - /* Butt */ - if (slave.amp !== 1) { - if (slave.butt > 6) { - buttSize = 3; - } else if (slave.butt > 4) { - buttSize = 2; - } else if (slave.butt > 2) { - buttSize = 1; - } else { - buttSize = 0; + if (wearingLatex === false) { + addSkinImg(res, `arm right ${rightArmType}`, skinFilter); + if (slave.underArmHStyle === "bushy") { + addImg(res, `hair/underArm ${underArmHStyle} right`, underArmFilter); + } + } else { + if (slave.fuckdoll !== 0) { + rightArmType = "mid"; + } + addImg(res, `outfit/arm right ${rightArmType} latex`); + } + } else if (wearingLatex === false && slave.underArmHStyle === "bushy") { + addImg(res, `hair/underArm ${underArmHStyle} right`, underArmFilter); } - if (wearingLatex === true) { - r += `<img class='paperdoll' src=${filePath}/outfit/butt ${buttSize} latex.svg' style='${skinFilter}'>`; - } else { - r += `<img class='paperdoll' src=${skinFilePath}/butt ${buttSize}.svg' style='${skinFilter}'>`; + /* Hair Aft */ + if (slave.fuckdoll === 0) { + switch (slave.hStyle) { + case "eary": + case "luxurious": + case "messy": + case "neat": + case "tails": + case "trimmed": + addImg(res, `hair/${hairStyle} back`, hairFilter); + } } - } - /* Leg + 1 size up when chubby or fat */ - if (slave.hips < 0) { - if (slave.weight > 95) { /* Chubby */ - legSize = "normal"; - } else { - legSize = "narrow"; - } - } else if (slave.hips === 0) { - if (slave.weight > 95) { /* Chubby */ - legSize = "wide"; - } else { - legSize = "normal"; + /* Tailed Plug */ + if (slave.buttplugAttachment === "tail") { + addImg(res, "outfit/tail plug", hairFilter); } - } else { - legSize = "wide"; - } - if (slave.amp === 1) { - legSize = `stump ${legSize}`; - } - if (wearingLatex === true && slave.amp !== 1) { - r += `<img class='paperdoll' src=${filePath}/outfit/leg ${legSize} latex.svg'/>`; - } else { - r += `<img class='paperdoll' src=${skinFilePath}/leg ${legSize}.svg' style='${skinFilter}'>`; - } + /* Butt */ + if (slave.amp !== 1) { + if (slave.butt > 6) { + buttSize = 3; + } else if (slave.butt > 4) { + buttSize = 2; + } else if (slave.butt > 2) { + buttSize = 1; + } else { + buttSize = 0; + } - /* Feet */ - if (slave.amp !== 1) { - if (slave.shoes === "heels") { - shoesType = "heel"; - } else if (slave.shoes === "extreme heels") { + if (wearingLatex === true) { + addImg(res, `outfit/butt ${buttSize} latex`, skinFilter); + } else { + addSkinImg(res, `butt ${buttSize}`, skinFilter); + } + } + + /* Leg + 1 size up when chubby or fat */ + if (slave.hips < 0) { if (slave.weight > 95) { /* Chubby */ - shoesType = "extreme heel wide"; + legSize = "normal"; } else { - shoesType = "extreme heel"; + legSize = "narrow"; } - } else if (slave.shoes === "boots") { + } else if (slave.hips === 0) { if (slave.weight > 95) { /* Chubby */ - shoesType = "boot wide"; + legSize = "wide"; } else { - shoesType = "boot"; + legSize = "normal"; } - } else if (slave.shoes === "flats") { - shoesType = "flat"; } else { - r += `<img class='paperdoll' src=${skinFilePath}/feet.svg' style='${skinFilter}'>`; + legSize = "wide"; } - if (slave.shoes === "extreme heels" || slave.shoes === "boots") { - if (wearingLatex === true) { - r += `<img class='paperdoll' src=${filePath}/outfit/${shoesType} latex.svg'/>`; + if (slave.amp === 1) { + legSize = `stump ${legSize}`; + } + + if (wearingLatex === true && slave.amp !== 1) { + addImg(res, `outfit/leg ${legSize} latex`); + } else { + addSkinImg(res, `leg ${legSize}`, skinFilter); + } + + /* Feet */ + if (slave.amp !== 1) { + if (slave.shoes === "heels") { + shoesType = "heel"; + } else if (slave.shoes === "extreme heels") { + if (slave.weight > 95) { /* Chubby */ + shoesType = "extreme heel wide"; + } else { + shoesType = "extreme heel"; + } + } else if (slave.shoes === "boots") { + if (slave.weight > 95) { /* Chubby */ + shoesType = "boot wide"; + } else { + shoesType = "boot"; + } + } else if (slave.shoes === "flats") { + shoesType = "flat"; } else { - r += `<img class='paperdoll' src=${filePath}/outfit/${shoesType}.svg'/>`; + addSkinImg(res, "feet", skinFilter); } - } else if (slave.shoes === "heels" || slave.shoes === "flats") { - if (wearingLatex === true) { - r += `<img class='paperdoll' src=${filePath}/outfit/${shoesType} latex.svg'/>`; - } else { - r += `<img class='paperdoll' src=${skinFilePath}/${shoesType}.svg' style='${skinFilter}'>`; + if (slave.shoes === "extreme heels" || slave.shoes === "boots") { + addImg(res, `outfit/${shoesType}${wearingLatex ? " latex": ""}`); + } else if (slave.shoes === "heels" || slave.shoes === "flats") { + if (wearingLatex === true) { + addImg(res, `outfit/${shoesType} latex`); + } else { + addSkinImg(res, `${shoesType}`, skinFilter); + } } } - } - /* Torso */ - if (slave.waist < -40) { - if (slave.weight > 30) { - torsoSize = "hourglass"; + /* Torso */ + if (slave.waist < -40) { + if (slave.weight > 30) { + torsoSize = "hourglass"; + } else { + torsoSize = "unnatural"; + } + } else if (slave.waist <= 10) { + if (slave.weight > 30) { + torsoSize = "normal"; + } else { + torsoSize = "hourglass"; + } } else { - torsoSize = "unnatural"; - } - } else if (slave.waist <= 10) { - if (slave.weight > 30) { torsoSize = "normal"; - } else { - torsoSize = "hourglass"; } - } else { - torsoSize = "normal"; - } - r += `<img class='paperdoll' src=${skinFilePath}/torso ${torsoSize}.svg' style='${skinFilter}'>`; - if (wearingLatex === true) { - r += `<img class='paperdoll' src=${filePath}/outfit/torso ${torsoSize} latex.svg'/>`; - } else if (slave.clothes === "uncomfortable straps") { - r += `<img class='paperdoll' src=${filePath}/outfit/torso ${torsoSize} straps.svg'/>`; - } + addSkinImg(res, `torso ${torsoSize}`, skinFilter); + if (wearingLatex === true) { + addImg(res, `outfit/torso ${torsoSize} latex`); + } else if (slave.clothes === "uncomfortable straps") { + addImg(res, `outfit/torso ${torsoSize} straps`); + } - if (slave.amp !== 1) { - if (wearingLatex === false) { - if (leftArmType === "high") { - r += `<img class='paperdoll' src=${skinFilePath}/arm left ${leftArmType}.svg' style='${skinFilter}'>`; - if (slave.underArmHStyle === "bushy") { - r += `<img class='paperdoll' src=${filePath}/hair/underArm ${underArmHStyle} left.svg' style='${underArmFilter}'/>`; + if (slave.amp !== 1) { + if (wearingLatex === false) { + if (leftArmType === "high") { + addSkinImg(res, `arm left ${leftArmType}`, skinFilter); + if (slave.underArmHStyle === "bushy") { + addImg(res, `hair/underArm ${underArmHStyle} left`, underArmFilter); + } + } else { + if (slave.underArmHStyle === "bushy") { + addImg(res, `hair/underArm ${underArmHStyle} left`, underArmFilter); + } + addSkinImg(res, `arm left ${leftArmType}`, skinFilter); } + addSkinImg(res, `arm left ${leftArmType}`, skinFilter); } else { - if (slave.underArmHStyle === "bushy") { - r += `<img class='paperdoll' src=${filePath}/hair/underArm ${underArmHStyle} left.svg' style='${underArmFilter}'/>`; + if (slave.fuckdoll !== 0) { + leftArmType = "mid"; } - r += `<img class='paperdoll' src=${skinFilePath}/arm left ${leftArmType}.svg' style='${skinFilter}'>`; + addImg(res, `outfit/arm left ${leftArmType} latex`); } - r += `<img class='paperdoll' src=${skinFilePath}/arm left ${leftArmType}.svg' style='${skinFilter}'>`; - } else { - if (slave.fuckdoll !== 0) { - leftArmType = "mid"; - } - r += `<img class='paperdoll' src=${filePath}/outfit/arm left ${leftArmType} latex.svg'/>`; + } else if (wearingLatex === false && slave.underArmHStyle === "bushy") { + addImg(res, `hair/underArm ${underArmHStyle} left`, underArmFilter); } - } else if (wearingLatex === false && slave.underArmHStyle === "bushy") { - r += `<img class='paperdoll' src=${filePath}/hair/underArm ${underArmHStyle} left.svg' style='${underArmFilter}'/>`; - } - /* Vagina */ - if (slave.vagina >= 0) { - r += `<img class='paperdoll' src=${skinFilePath}/vagina.svg' style='${skinFilter}'>`; - if (slave.clitPiercing === 1) { - r += `<img class='paperdoll' src=${filePath}/body/addon/clit piercing.svg'/>`; - } else if (slave.clitPiercing === 2) { - r += `<img class='paperdoll' src=${filePath}/body/addon/clit piercing heavy.svg'/>`; - } else if (slave.clitPiercing === 3) { - r += `<img class='paperdoll' src=${filePath}/body/addon/clit piercing smart.svg'/>`; - } + /* Vagina */ + if (slave.vagina >= 0) { + addSkinImg(res, "vagina", skinFilter); + if (slave.clitPiercing === 1) { + addImg(res, "body/addon/clit piercing"); + } else if (slave.clitPiercing === 2) { + addImg(res, "body/addon/clit piercing heavy"); + } else if (slave.clitPiercing === 3) { + addImg(res, "body/addon/clit piercing smart"); + } - if (slave.vaginaPiercing === 1) { - r += `<img class='paperdoll' src=${filePath}/body/addon/pussy piercing.svg'/>`; - } else if (slave.vaginaPiercing === 2) { - r += `<img class='paperdoll' src=${filePath}/body/addon/pussy piercing heavy.svg'/>`; + if (slave.vaginaPiercing === 1) { + addImg(res, "body/addon/pussy piercing"); + } else if (slave.vaginaPiercing === 2) { + addImg(res, "body/addon/pussy piercing heavy"); + } } - } - - /* Collar */ - switch (slave.collar) { - case "nice retirement counter": - case "cruel retirement counter": - case "leather with cowbell": - case "pretty jewelry": - case "heavy gold": - case "satin choker": - case "stylish leather": - case "neck corset": - case "shock punishment": - case "tight steel": - case "uncomfortable leather": - case "dildo gag": - r += `<img class='paperdoll' src=${filePath}/outfit/${slave.collar}.svg'/>`; - } - /* Head base image */ - if (wearingLatex === true) { - r += `<img class='paperdoll' src=${filePath}/outfit/head latex.svg'/>`; - } else { - r += `<img class='paperdoll' src=${skinFilePath}/head.svg' style='${skinFilter}'>`; - } - - /* Glasses */ - if (slave.eyewear === "corrective glasses" || slave.eyewear === "glasses" || slave.eyewear === "blurring glasses") { - r += `<img class='paperdoll' src=${filePath}/outfit/glasses.svg'/>`; - } - - /* Chastity belt or Pubic hair */ - if (slave.chastityPenis === 1 || slave.chastityVagina === 1 || slave.chastityAnus === 1) { - if (slave.chastityPenis === 1) { - r += `<img class='paperdoll' src=${filePath}/outfit/chastity male aft.svg'/>`; - } - if (slave.chastityVagina === 1) { - r += `<img class='paperdoll' src=${filePath}/outfit/chastity female.svg'/>`; + /* Collar */ + switch (slave.collar) { + case "nice retirement counter": + case "cruel retirement counter": + case "leather with cowbell": + case "pretty jewelry": + case "heavy gold": + case "satin choker": + case "stylish leather": + case "neck corset": + case "shock punishment": + case "tight steel": + case "uncomfortable leather": + case "dildo gag": + addImg(res, `outfit/${slave.collar}`); } - r += `<img class='paperdoll' src=${filePath}/outfit/chastity base.svg'/>`; - } else if (slave.pubicHStyle !== "waxed" && slave.pubicHStyle !== "bald" && slave.pubicHStyle !== "hairless") { - let pubicHStyle = (slave.pubicHStyle === "in a strip" ? "strip" : slave.pubicHStyle); - r += `<img class='paperdoll' src=${filePath}/hair/pubes ${pubicHStyle}.svg' style='${pubesFilter}'/>`; - } - /* if pregnant or has a belly */ - if (slave.belly >= 5000) { - r += `<img class='paperdoll' src=${skinFilePath}/preg belly 5000.svg' style='${skinFilter}'>`; - if (slave.navelPiercing >= 1) { /* Navel Piercing*/ - r += `<img class='paperdoll' src=${filePath}/body/addon/preg navel piercing.svg'/>`; - } - if (slave.navelPiercing === 2) { - r += `<img class='paperdoll' src=${filePath}/body/addon/preg navel piercing heavy.svg'/>`; - } - } else if (slave.belly <= -100) { /* condition is currently reversed until the vector can be fixed */ - r += `<img class='paperdoll' src=${skinFilePath}/preg belly 100.svg' style='${skinFilter}'>`; - /* - if (slave.navelPiercing >= 1)/Navel Piercing/ - r += `<img class='paperdoll' src=${filePath}/body/addon/preg navel piercing.svg'/>`; - if (slave.navelPiercing === 2) - r += `<img class='paperdoll' src=${filePath}/body/addon/preg navel piercing heavy.svg'/>`; - */ - } else { - if (slave.navelPiercing >= 1) { /* Navel Piercing*/ - r += `<img class='paperdoll' src=${filePath}/body/addon/navel piercing.svg'/>`; + /* Head base image */ + if (wearingLatex === true) { + addImg(res, "outfit/head latex"); + } else { + addSkinImg(res, "head", skinFilter); } - if (slave.navelPiercing === 2) { - r += `<img class='paperdoll' src=${filePath}/body/addon/navel piercing heavy.svg'/>`; + + /* Glasses */ + if (slave.eyewear === "corrective glasses" || slave.eyewear === "glasses" || slave.eyewear === "blurring glasses") { + addImg(res, "outfit/glasses"); } - } - /* Boob */ - if (slave.boobs < 300) { - boobSize = 0; - } else if (slave.boobs < 500) { - boobSize = 1; - } else if (slave.boobs < 800) { - boobSize = 2; - } else if (slave.boobs < 1600) { - boobSize = 3; - } else if (slave.boobs < 3200) { - boobSize = 4; - } else if (slave.boobs < 6400) { - boobSize = 5; - } else if (slave.boobs < 12000) { - boobSize = 6; - } else { - boobSize = 7; - } + /* Chastity belt or Pubic hair */ + if (slave.chastityPenis === 1 || slave.chastityVagina === 1 || slave.chastityAnus === 1) { + if (slave.chastityPenis === 1) { + addImg(res, "outfit/chastity male aft"); + } + if (slave.chastityVagina === 1) { + addImg(res, "outfit/chastity female"); + } + addImg(res, "outfit/chastity base"); + } else if (slave.pubicHStyle !== "waxed" && slave.pubicHStyle !== "bald" && slave.pubicHStyle !== "hairless") { + let pubicHStyle = (slave.pubicHStyle === "in a strip" ? "strip" : slave.pubicHStyle); + addImg(res, `hair/pubes ${pubicHStyle}`, pubesFilter); + } - /* Scrotum */ - if (slave.scrotum > 0) { - if (slave.scrotum >= 6) { - ballSize = 4; - } else if (slave.scrotum >= 4) { - ballSize = 3; - } else if (slave.scrotum >= 3) { - ballSize = 2; - } else if (slave.scrotum >= 2) { - ballSize = 1; + /* if pregnant or has a belly */ + if (slave.belly >= 5000) { + addSkinImg(res, "preg belly 5000", skinFilter); + if (slave.navelPiercing >= 1) { /* Navel Piercing*/ + addImg(res, "body/addon/preg navel piercing"); + } + if (slave.navelPiercing === 2) { + addImg(res, "body/addon/preg navel piercing heavy"); + } + } else if (slave.belly <= -100) { /* condition is currently reversed until the vector can be fixed */ + addSkinImg(res, "preg belly 100", skinFilter); + /* + if (slave.navelPiercing >= 1)/Navel Piercing/ + r += `<img class='paperdoll' src=${filePath}/body/addon/preg navel piercing.svg'/>`; + if (slave.navelPiercing === 2) + r += `<img class='paperdoll' src=${filePath}/body/addon/preg navel piercing heavy.svg'/>`; + */ } else { - ballSize = 0; + if (slave.navelPiercing >= 1) { /* Navel Piercing*/ + addImg(res, "body/addon/navel piercing"); + } + if (slave.navelPiercing === 2) { + addImg(res, "body/addon/navel piercing heavy"); + } } - } - /* Penis */ - if (slave.dick > 0) { - if (slave.dick >= 8) { - penisSize = 6; - } else if (slave.dick >= 7) { - penisSize = 5; - } else if (slave.dick >= 6) { - penisSize = 4; - } else if (slave.dick >= 5) { - penisSize = 3; - } else if (slave.dick >= 4) { - penisSize = 2; - } else if (slave.dick >= 2) { - penisSize = 1; + /* Boob */ + if (slave.boobs < 300) { + boobSize = 0; + } else if (slave.boobs < 500) { + boobSize = 1; + } else if (slave.boobs < 800) { + boobSize = 2; + } else if (slave.boobs < 1600) { + boobSize = 3; + } else if (slave.boobs < 3200) { + boobSize = 4; + } else if (slave.boobs < 6400) { + boobSize = 5; + } else if (slave.boobs < 12000) { + boobSize = 6; } else { - penisSize = 0; + boobSize = 7; + } + + /* Scrotum */ + if (slave.scrotum > 0) { + if (slave.scrotum >= 6) { + ballSize = 4; + } else if (slave.scrotum >= 4) { + ballSize = 3; + } else if (slave.scrotum >= 3) { + ballSize = 2; + } else if (slave.scrotum >= 2) { + ballSize = 1; + } else { + ballSize = 0; + } } - } - - /* Boob */ - if (slave.dick > 0) { - if (canAchieveErection(slave)) { - if (boobSize < 6) { - if (wearingLatex === true) { - /* normal case: outfit hides boobs */ - r += `<img class='paperdoll' src=${filePath}/outfit/boob ${boobSize} latex.svg'/>`; - if (slave.lactation > 0) { - r += `<img class='paperdoll' src=${skinFilePath}/boob ${boobSize} areola.svg' style='${skinFilter}'>`; - } - } else { - r += `<img class='paperdoll' src=${skinFilePath}/boob ${boobSize}.svg' style='${skinFilter}'>`; - r += `<img class='paperdoll' src=${skinFilePath}/boob ${boobSize} areola.svg' style='${skinFilter}'>`; - } - /* special case: straps are actually dawn over the boobs */ - if (slave.clothes === "uncomfortable straps") { - r += `<img class='paperdoll' src=${filePath}/outfit/boob ${boobSize} straps.svg'/>`; - } - needBoobs = false; + /* Penis */ + if (slave.dick > 0) { + if (slave.dick >= 8) { + penisSize = 6; + } else if (slave.dick >= 7) { + penisSize = 5; + } else if (slave.dick >= 6) { + penisSize = 4; + } else if (slave.dick >= 5) { + penisSize = 3; + } else if (slave.dick >= 4) { + penisSize = 2; + } else if (slave.dick >= 2) { + penisSize = 1; + } else { + penisSize = 0; } } - } - if (slave.vagina > 0) { + + /* Boob */ if (slave.dick > 0) { - r += '<div class="highPenis">'; - if (slave.scrotum > 0) { - r += `<img class='paperdoll' src=${skinFilePath}/ball ${ballSize}.svg' style='${skinFilter}'>`; - } if (canAchieveErection(slave)) { - r += `<img class='paperdoll' src=${skinFilePath}/penis ${penisSize}.svg' style='${skinFilter}'>`; - } else { - r += `<img class='paperdoll' src=${skinFilePath}/flaccid ${penisSize}.svg' style='${skinFilter}'>`; - if (slave.chastityPenis === 1) { - r += `<img class='paperdoll' src=${filePath}/outfit/chastity male fore ${penisSize}.svg'/>`; + if (boobSize < 6) { + if (wearingLatex === true) { + /* normal case: outfit hides boobs */ + addImg(res, `outfit/boob ${boobSize} latex`); + if (slave.lactation > 0) { + addSkinImg(res, `boob ${boobSize} areola`, skinFilter); + } + } else { + addSkinImg(res, `boob ${boobSize}`, skinFilter); + addSkinImg(res, `boob ${boobSize} areola`, skinFilter); + } + /* special case: straps are actually dawn over the boobs */ + if (slave.clothes === "uncomfortable straps") { + addImg(res, `outfit/boob ${boobSize} straps`); + } + + needBoobs = false; } } - r += '</div>'; } - } else { - if (slave.dick > 0) { - r += '<div class="lowPenis">'; - if (slave.scrotum > 0) { - r += `<img class='paperdoll' src=${skinFilePath}/ball ${ballSize}.svg' style='${skinFilter}'>`; + if (slave.vagina > 0) { + if (slave.dick > 0) { + const divPenis = document.createElement("div"); + divPenis.className = "highPenis"; + res.appendChild(divPenis); + if (slave.scrotum > 0) { + addSkinImg(divPenis, `ball ${ballSize}`, skinFilter); + } + if (canAchieveErection(slave)) { + addSkinImg(divPenis, `penis ${penisSize}`, skinFilter); + } else { + addSkinImg(divPenis, `flaccid ${penisSize}`, skinFilter); + if (slave.chastityPenis === 1) { + addImg(divPenis, `outfit/chastity male fore ${penisSize}`); + } + } } - if (canAchieveErection(slave)) { - r += `<img class='paperdoll' src=${skinFilePath}/penis ${penisSize}.svg' style='${skinFilter}'>`; - } else { - r += `<img class='paperdoll' src=${skinFilePath}/flaccid ${penisSize}.svg' style='${skinFilter}'>`; - if (slave.chastityPenis === 1) { - r += `<img class='paperdoll' src=${filePath}/outfit/chastity male fore ${penisSize}.svg'/>`; + } else { + if (slave.dick > 0) { + const divPenis = document.createElement("div"); + divPenis.className = "lowPenis"; + res.appendChild(divPenis); + if (slave.scrotum > 0) { + addSkinImg(divPenis, `ball ${ballSize}`, skinFilter); + } + if (canAchieveErection(slave)) { + addSkinImg(divPenis, `penis ${penisSize}`, skinFilter); + } else { + addSkinImg(divPenis, `flaccid ${penisSize}`, skinFilter); + if (slave.chastityPenis === 1) { + addImg(divPenis, `outfit/chastity male fore ${penisSize}`); + } } } - r += '</div>'; } - } - if (needBoobs === true) { - if (wearingLatex === true) { - r += `<img class='paperdoll' src=${filePath}/outfit/boob ${boobSize} latex.svg'/>`; - if (slave.lactation > 0) { - r += `<img class='paperdoll' src=${skinFilePath}/boob ${boobSize} areola.svg' style='${skinFilter}'>`; + if (needBoobs === true) { + if (wearingLatex === true) { + addImg(res, `outfit/boob ${boobSize} latex`); + if (slave.lactation > 0) { + addSkinImg(res, `boob ${boobSize} areola`, skinFilter); + } + } else { + addSkinImg(res, `boob ${boobSize}`, skinFilter); + addSkinImg(res, `boob ${boobSize} areola`, skinFilter); + } + /* special case: straps are actually dawn over the boobs */ + if (slave.clothes === "uncomfortable straps") { + addImg(res, `outfit/boob ${boobSize} straps`); } - } else { - r += `<img class='paperdoll' src=${skinFilePath}/boob ${boobSize}.svg' style='${skinFilter}'>`; - r += `<img class='paperdoll' src=${skinFilePath}/boob ${boobSize} areola.svg' style='${skinFilter}'>`; } - /* special case: straps are actually dawn over the boobs */ - if (slave.clothes === "uncomfortable straps") { - r += `<img class='paperdoll' src=${filePath}/outfit/boob ${boobSize} straps.svg'/>`; + + /* piercings */ + if (slave.nipplesPiercing === 1) { + addImg(res, `body/addon/boob ${boobSize} piercing`); + } else if (slave.nipplesPiercing === 2) { + addImg(res, `body/addon/boob ${boobSize} piercing heavy`); } - } - /* piercings */ - if (slave.nipplesPiercing === 1) { - r += `<img class='paperdoll' src=${filePath}/body/addon/boob ${boobSize} piercing.svg'/>`; - } else if (slave.nipplesPiercing === 2) { - r += `<img class='paperdoll' src=${filePath}/body/addon/boob ${boobSize} piercing heavy.svg'/>`; - } + if (slave.areolaePiercing === 1) { + addImg(res, `body/addon/boob ${boobSize} areola piercing`); + } + + /* clavicle */ + addImg(res, "body/addon/clavicle"); + + /* Hair Foreground */ + if (slave.hStyle !== "shaved" && slave.fuckdoll === 0) { + addImg(res, `/hair/${hairStyle} front`, hairFilter); + } - if (slave.areolaePiercing === 1) { - r += `<img class='paperdoll' src=${filePath}/body/addon/boob ${boobSize} areola piercing.svg'/>`; + return res; } - /* clavicle */ - r += `<img class='paperdoll' src=${filePath}/body/addon/clavicle.svg'/>`; + /** + * @param {Node} container + * @param {string} artFile + * @param {string} [style] + */ + function addImg(container, artFile, style) { + const res = document.createElement("img"); + res.setAttribute("class", "paperdoll"); + res.setAttribute("src", `${filePath}/${artFile}.svg`); + if (style !== undefined) { + res.setAttribute("style", style); + } + container.appendChild(res); + return res; + } - /* Hair Foreground */ - if (slave.hStyle !== "shaved" && slave.fuckdoll === 0) { - r += `<img class='paperdoll' src=${filePath}/hair/${hairStyle} front.svg' style='${hairFilter}'/>`; + /** + * @param {Node} container + * @param {string} artFile + * @param {string} [style] + */ + function addSkinImg(container, artFile, style) { + return addImg(container, 'body/white/' + artFile, style); } - return r; -}; + return render; +}(); diff --git a/src/art/vector_revamp/vectorRevampedArtControl.js b/src/art/vector_revamp/vectorRevampedArtControl.js index 6c4c727da020657212c1315b56f6c3e214d4dd19..1786cd21cdfb5bb364a92734b259f18dcd6a76c0 100644 --- a/src/art/vector_revamp/vectorRevampedArtControl.js +++ b/src/art/vector_revamp/vectorRevampedArtControl.js @@ -1,8 +1,46 @@ /* eslint-disable camelcase */ window.RevampedVectorArt = function(slave) { + return App.Art.elementToMarkup(App.Art.revampedVectorArtElement(slave)); +}; + +/** + * @param {App.Entity.SlaveState} slave + * @returns {DocumentFragment} + */ +App.Art.revampedVectorArtElement = function(slave) { + /** + * @param {string} id + * @returns {HTMLElement} + */ + function useSvg(id) { + const cache = App.Data.Art.VectorRevamp; + /** @type {HTMLElement} */ + const res = cache.nodes.children.item(cache.dict.get(id)).children.item(0).cloneNode(true); + res.setAttribute("class", T.art_display_class); + let transformNodes = res.querySelectorAll('g[data-transform]'); + for (const node of transformNodes) { + switch (node.getAttribute("data-transform")) { + case "boob_left": + node.setAttribute("transform", T.revampedVectorArtControl.boobLeftArtTransform); + break; + case "boob_right": + node.setAttribute("transform", T.revampedVectorArtControl.boobRightArtTransform); + break; + case "boob_outfit": + node.setAttribute("transform", T.revampedVectorArtControl.boobOutfitArtTransform); + break; + case "pussy_tattoo_text": + node.textContent = T.revampedVectorArtControl.pubicTattooText; + break; + // seem to be no default art transform? + } + } + + return res; + } + const V = State.variables; const T = State.temporary; - let r; if (T.art_display_id > 0) { T.art_display_id++; @@ -14,7 +52,11 @@ window.RevampedVectorArt = function(slave) { /* Using JS from vectorRevampedArtControl.tw*/ T.revampedVectorArtControl = getVectorArtRevampedControl(T.art_display_class, slave, V.seeVectorArtHighlights, V.showBodyMods); - r = `<style>${T.revampedVectorArtControl.StylesCss}</style>`; + const res = document.createDocumentFragment(); + const style = document.createElement("style"); + style.innerHTML = T.revampedVectorArtControl.StylesCss; + res.appendChild(style); + T.revampedArtLayers = T.revampedVectorArtControl.Layers; T.art_transform = T.revampedVectorArtControl.artTransform; T.boob_right_art_transform = T.revampedVectorArtControl.boobRightArtTransform; @@ -22,9 +64,9 @@ window.RevampedVectorArt = function(slave) { T.boob_outfit_art_transform = T.revampedVectorArtControl.boobOutfitArtTransform; T.art_pussy_tattoo_text = T.revampedVectorArtControl.pubicTattooText; - T.revampedArtLayers.forEach(function(s) { r += jsInclude(s); }); + T.revampedArtLayers.forEach(function(s) { res.appendChild(useSvg(s)); }); - return r; + return res; }; window.getVectorArtRevampedControl = function(artDisplayClass, artSlave, globalShowHighlights, globalShowBodyMods) { diff --git a/src/debugging/debugJS.js b/src/debugging/debugJS.js index 6b8110b7a06ef57f3de857ed2fea157d267d6e4c..efce11a2103f244ac1a8ab41e25fe42acf783e38 100644 --- a/src/debugging/debugJS.js +++ b/src/debugging/debugJS.js @@ -118,3 +118,9 @@ App.Debug.dumpGameState = function() { SugarCube.Config.saves.onSave = oldHandler; } }; + +App.Debug.slaveSummaryText = function(idx) { + let span = document.createElement("span"); + span.appendChild(SlaveSummaryUncached(State.variables.slaves[idx])); + return span.outerHTML; +}; diff --git a/src/gui/svgFilters.tw b/src/gui/svgFilters.tw index 42e0b12951599b547d7562aeff5ca1a93c23ba12..14dd0a0cdb527e8a2a7cedbdf6967cf7238dc1f3 100644 --- a/src/gui/svgFilters.tw +++ b/src/gui/svgFilters.tw @@ -1,6 +1,5 @@ :: SVG filters -<html> <svg class="defs-only" style="width: 0; height: 0; position: absolute;"> <filter id="skin-black" color-interpolation-filters="sRGB"> <feColorMatrix type="matrix" values="0.15 0 0 0 0 0 0.1 0 0 0 0 0 0.05 0 0 0 0 0 1 0"/> @@ -213,4 +212,3 @@ <feColorMatrix type="matrix" values="0.7 0 0 0 0.5 0 0.7 0 0 0.5 0 0 0.5 0 0.4 0 0 0 1 0"/> </filter> </svg> -</html> diff --git a/src/init/setupVars.tw b/src/init/setupVars.tw index 6f437d960e46d5937951aacf190f83397a3bfdc0..4e730e52c070eeff2364720216a3a43317c4363b 100644 --- a/src/init/setupVars.tw +++ b/src/init/setupVars.tw @@ -2278,3 +2278,5 @@ Then pick _namePool.random(), or display those names as possible choices, or do "yellow":"yellow", "yellowgreen":"yellowgreen" }>> + +<<run App.Art.cacheArtData()>> diff --git a/src/js/assignJS.js b/src/js/assignJS.js index e75c3a4fc7432fdb98cdef6442a8afedab23f3b1..ad44b9a7a4dec3834c58f4018187a20521b650fc 100644 --- a/src/js/assignJS.js +++ b/src/js/assignJS.js @@ -614,7 +614,12 @@ App.UI.jobLinks = function() { App.Entity.facilities.servantsQuarters ]; - return {assignments: assignmentLinks, transfers: transferLinks}; + return { + assignments: assignmentLinks, + transfers: transferLinks, + assignmentsFragment: assignmentsFragment, + transfersFragment: transfersFragment + }; /** * Generates assignment links @@ -658,6 +663,63 @@ App.UI.jobLinks = function() { return transfers.join(' | '); } + + /** + * + * @param {number} index + * @param {string} passage + * @param {assignmentCallback} [callback] + * @returns {DocumentFragment} + */ + function assignmentsFragment(index, passage, callback) { + let penthouseJobs = App.Entity.facilities.penthouse.assignmentLinkElements(index, undefined, passage, callback); + const slave = App.Utils.slaveByIndex(index); + const sp = getPronouns(slave); + + if (slave.fuckdoll === 0) { + const assignment = "choose her own job"; + if (slave.assignment !== assignment) { + penthouseJobs.push( + App.UI.DOM.assignmentLink(State.variables.slaves[index], + assignment, passage, callback, `Let ${sp.object} choose`)); + } + } else { + penthouseJobs.push(App.UI.DOM.disabledLink(`Let ${sp.object} choose`, ["Fuckdolls can't choose their job"])); + } + let res = document.createDocumentFragment(); + // there is always at least one job + res.appendChild(penthouseJobs[0]); + for (let i = 1; i < penthouseJobs.length; ++i) { + res.appendChild(document.createTextNode(" | ")); + res.appendChild(penthouseJobs[i]); + } + return res; + } + + function transfersFragment(index) { + /** @type {HTMLElement[]} */ + const transfers = []; + const slave = App.Utils.slaveByIndex(index); + + for (const f of facilitiesOrder) { + if (!f.established) { continue; } + const rejects = f.canHostSlave(slave); + if (rejects.length === 0) { + transfers.push(f.transferLinkElement(index, undefined, passage())); + } else { + transfers.push(App.UI.DOM.disabledLink(f.genericName, rejects)); + } + } + + let res = document.createDocumentFragment(); + // there is always at least one job + res.appendChild(transfers[0]); + for (let i = 1; i < transfers.length; ++i) { + res.appendChild(document.createTextNode(" | ")); + res.appendChild(transfers[i]); + } + return res; + } }(); App.UI.SlaveInteract = { diff --git a/src/js/quickListJS.js b/src/js/quickListJS.js index f8c514eb9f238acf52d3aa0932a9ce04d846a173..fe4e110b654bbef3eba912082f63d337e127313b 100644 --- a/src/js/quickListJS.js +++ b/src/js/quickListJS.js @@ -30,18 +30,20 @@ window.sortButtonsByTrust = function() { }; window.quickListBuildLinks = function() { - $("[data-scroll-to]").click(function() { - let $this = $(this), - $toElement = $this.attr('data-scroll-to'); - // note the * 1 enforces $offset to be an integer, without - // it we scroll to True, which goes nowhere fast. - let $offset = $this.attr('data-scroll-offset') * 1 || 0; - let $speed = $this.attr('data-scroll-speed') * 1 || 500; - // Use javascript scrollTop animation for in page navigation. - $('html, body').animate({ - scrollTop: $($toElement).offset().top + $offset - }, $speed); - }); + $("[data-scroll-to]").click(App.UI.quickBtnScrollToHandler); +}; + +App.UI.quickBtnScrollToHandler = function() { + let $this = $(this), + $toElement = $this.attr('data-scroll-to'); + // note the * 1 enforces $offset to be an integer, without + // it we scroll to True, which goes nowhere fast. + let $offset = $this.attr('data-scroll-offset') * 1 || 0; + let $speed = $this.attr('data-scroll-speed') * 1 || 500; + // Use javascript scrollTop animation for in page navigation. + $('html, body').animate({ + scrollTop: $($toElement).offset().top + $offset + }, $speed); }; window.sortIncubatorPossiblesByName = function() { diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js index ab3d2b8d0a9e33b330fd047b6eb847be2041a593..7e8f527d4f7b763b8e252349452b2fad8f98ce16 100644 --- a/src/js/slaveListing.js +++ b/src/js/slaveListing.js @@ -13,6 +13,14 @@ App.UI.SlaveList = {}; * @param {number} index * @returns {string} */ + + /** + * @callback slaveToElement + * @param {App.Entity.SlaveState} slave + * @param {number} index + * @returns {HTMLElement|DocumentFragment} + */ + App.UI.SlaveList.render = function() { 'use strict'; let V; @@ -26,25 +34,36 @@ App.UI.SlaveList.render = function() { // potentially can be a problem if played long enough to reach Number.MAX_SAFE_INTEGER let listID = Number.MIN_SAFE_INTEGER; - return renderList; + const tabStr = "    "; // 4 * + + /** @type {Object.<number, Node>}*/ + const readyResults = { + + }; + + return { + listMarkup: listMarkup, + listDOM: listDOM + }; /** * @param {number[]} indices * @param {Array.<{index: number, rejects: string[]}>} rejectedSlaves - * @param {slaveTextGenerator} interactionLink - * @param {slaveTextGenerator} [postNote] - * @returns {string} + * @param {slaveToElement} interactionLink + * @param {slaveToElement} [postNote] + * @returns {DocumentFragment} */ - function renderList(indices, rejectedSlaves, interactionLink, postNote) { + function listDOM(indices, rejectedSlaves, interactionLink, postNote) { V = State.variables; passageName = passage(); slaves = V.slaves; V.assignTo = passageName; // would be passed to the "Assign" passage slaveImagePrinted = (V.seeImages === 1) && (V.seeSummaryImages === 1); - let res = []; + let res = document.createDocumentFragment(); + if (V.useSlaveListInPageJSNavigation === 1) { - res.push(createQuickList(indices)); + res.appendChild(createQuickList(indices)); } const fcs = App.Entity.facilities; @@ -62,49 +81,96 @@ App.UI.SlaveList.render = function() { for (const _si of indices) { let ss = renderSlave(_si, interactionLink, showTransfers, postNote); - res.push(`<div id="slave-${slaves[_si].ID}" style="clear:both">${ss}</div>`); + let slaveDiv = document.createElement("div"); + slaveDiv.id = `slave-${slaves[_si].ID}`; + slaveDiv.classList.add("slaveSummary"); + slaveDiv.appendChild(ss); + res.appendChild(slaveDiv); } for (const rs of rejectedSlaves) { const slave = slaves[rs.index]; const rejects = rs.rejects; const slaveName = SlaveFullName(slave); - let rejectString = rejects.length === 1 ? - rejects[0] : - `${slaveName}: <ul>${rejects.map(e => `<li>${e}</li>`).join('')}</ul>`; - res.push(`<div id="slave_${slave.ID}" style="clear:both">${rejectString}</div>`); + let slaveDiv = document.createElement("div"); + slaveDiv.id = `slave-${slave.ID}`; + slaveDiv.style.setProperty("clear", "both"); + if (rejects.length === 1) { + slaveDiv.innerHTML = rejects[0]; + } else { + slaveDiv.appendChild(document.createTextNode(`${slaveName}: `)); + let ul = document.createElement("ul"); + for (const rr of rejects) { + const li = document.createElement("li"); + li.innerHTML = rr; + ul.appendChild(li); + } + slaveDiv.appendChild(ul); + } + res.appendChild(slaveDiv); } + return res; + } + + /** + * @param {number[]} indices + * @param {Array.<{index: number, rejects: string[]}>} rejectedSlaves + * @param {slaveToElement} interactionLink + * @param {slaveToElement} [postNote] + * @returns {string} + */ + function listMarkup(indices, rejectedSlaves, interactionLink, postNote) { + const listIDStr = `slave-list-${listID}`; + readyResults[listID] = listDOM(indices, rejectedSlaves, interactionLink, postNote); + $(document).one(':passagedisplay', function() { - $('[data-quick-index]').unbind().click(function() { - let which = this.attributes["data-quick-index"].value; - let quick = $("div#list_index" + which); - quick.toggleClass("hidden"); - }); - quickListBuildLinks(); + for (const e of document.querySelectorAll('[id^=slave-list]')) { + const id = e.getAttribute("data-listId"); + if (readyResults.hasOwnProperty(id)) { + if (e.childNodes.length > 0) { + e.innerHTML = ''; + } + e.appendChild(readyResults[id]); + delete readyResults[id]; + } + } }); - if (V.useSlaveListInPageJSNavigation === 1) { - listID++; - } + let resMarkup = `<div id="${listIDStr}" data-listId="${listID}"></div>`; + ++listID; - return res.join(""); + return resMarkup; } /** * @param {number} index - * @param {slaveTextGenerator} interactionLink + * @param {slaveToElement} interactionLink * @param {boolean} showTransfers - * @param {slaveTextGenerator} [postNote] - * @returns {string} + * @param {slaveToElement} [postNote] + * @returns {DocumentFragment} */ function renderSlave(index, interactionLink, showTransfers, postNote) { - let res = []; + let res = document.createDocumentFragment(); + if (V.lineSeparations === 0) { + res.appendChild(document.createElement("br")); + } else { + const hr = document.createElement("hr"); + hr.style.margin = "0"; + res.appendChild(hr); + } const slave = slaves[index]; - res.push(dividerAndImage(slave)); - res.push(interactionLink(slave, index)); + if ((V.seeImages === 1) && (V.seeSummaryImages === 1)) { + let imgDiv = document.createElement("div"); + imgDiv.classList.add("imageRef"); + imgDiv.classList.add("smlImg"); + imgDiv.appendChild(App.Art.SlaveArtElement(slave, 1)); + res.appendChild(imgDiv); + } + // res.push(dividerAndImage(slave)); + res.appendChild(interactionLink(slave, index)); if ((slave.choosesOwnClothes === 1) && (slave.clothes === "choosing her own clothes")) { const _oldDevotion = slave.devotion; @@ -116,53 +182,86 @@ App.UI.SlaveList.render = function() { slave.trust = Math.trunc(slave.trust); slave.devotion = Math.trunc(slave.devotion); slave.health = Math.trunc(slave.health); - res.push(' will '); + res.appendChild(document.createTextNode(' will ')); + const assignment = document.createElement("span"); if ((slave.assignment === "rest") && (slave.health >= -20)) { - res.push(`<strong><u><span class="lawngreen">rest</span></u></strong>`); + assignment.className = "freeAssignment"; + assignment.innerText = slave.assignment; } else if ((slave.assignment === "stay confined") && ((slave.devotion > 20) || ((slave.trust < -20) && (slave.devotion >= -20)) || ((slave.trust < -50) && (slave.devotion >= -50)))) { - res.push(`<strong><u><span class="lawngreen">stay confined.</span></u></strong>`); + assignment.innerText = slave.assignment; if (slave.sentence > 0) { - res.push(` (${slave.sentence} weeks)`); + assignment.innerText += ` (${slave.sentence} weeks)`; } } else if (slave.choosesOwnAssignment === 1) { - res.push('choose her own job'); + assignment.innerText = 'choose her own job'; } else { - res.push(slave.assignment); + assignment.innerText = slave.assignment; if (slave.sentence > 0) { - res.push(` ${slave.sentence} weeks`); + assignment.innerText += ` ${slave.sentence} weeks`; } } - res.push('. '); + assignment.innerText += ". "; + res.appendChild(assignment); if ((V.displayAssignments === 1) && (passageName === "Main") && (slave.ID !== V.HeadGirl.ID) && (slave.ID !== V.Recruiter.ID) && (slave.ID !== V.Bodyguard.ID)) { - res.push(App.UI.jobLinks.assignments(index, "Main")); + res.appendChild(App.UI.jobLinks.assignmentsFragment(index, "Main")); } if (showTransfers) { - res.push('<br>Transfer to: ' + App.UI.jobLinks.transfers(index)); - } - res.push('<br/>'); - - if (slaveImagePrinted) { - res.push(' '); + res.appendChild(document.createElement("br")); + res.appendChild(document.createTextNode('Transfer to: ')); + res.appendChild(App.UI.jobLinks.transfersFragment(index)); } - clearSummaryCache(); - res.push(SlaveSummary(slave)); + res.appendChild(SlaveSummaryUncached(slave)); if (postNote !== undefined) { - res.push('<br>'); - res.push(postNote(slave, index)); + const pn = postNote(slave, index); + if (pn) { + res.appendChild(document.createElement('br')); + res.appendChild(pn); + } } - return res.join(''); + return res; } /** * @param {number[]} indices - * @returns {string} + * @returns {DocumentFragment} */ function createQuickList(indices) { - let res = ""; + /** + * + * @param {Node} container + * @param {string} tagName + * @param {string} [content] + * @param {string|string[]} [classNames] + * @param {Object.<string, any>} [attributes] + * @returns {HTMLElement} + */ + function makeElement(container, tagName, content, classNames, attributes) { + let res = document.createElement(tagName); + container.appendChild(res); + if (content) { + res.textContent = content; + } + if (Array.isArray(classNames)) { + for (const c of classNames) { + res.classList.add(c); + } + } else if (classNames !== undefined) { + res.classList.add(classNames); + } + + if (attributes) { + for (const [k, v] of Object.entries(attributes)) { + res.setAttribute(k, v); + } + } + return res; + } + + const res = document.createDocumentFragment(); /* Useful for finding weird combinations — usages of this passage that don't yet generate the quick index. * <<print 'pass/count/indexed/flag::[' + passageName + '/' + _Count + '/' + _indexed + '/' + $SlaveSummaryFiler + ']'>> @@ -174,19 +273,24 @@ App.UI.SlaveList.render = function() { if (/Select/i.test(passageName)) { _offset = -25; } - res += "<br />"; + res.appendChild(document.createElement("br")); /* * we want <button data-quick-index="<<= listID>>">... */ - const _buttonAttributes = { - 'id': `quick-list-toggle${listID}`, - 'data-quick-index': listID + const quickIndexBtn = document.createElement("button"); + res.appendChild(quickIndexBtn); + quickIndexBtn.id = `quick-list-toggle${listID}`; + quickIndexBtn.setAttribute('data-quick-index', listID.toString()); + quickIndexBtn.onclick = function(ev) { + let which = ev.target.attributes["data-quick-index"].value; + let quick = $("div#list_index" + which); + quick.toggleClass("hidden"); }; - res += App.UI.htag("Quick Index", _buttonAttributes, 'button'); /* * we want <div id="list_index3" class=" hidden">... */ - let listIndexContent = ""; + const listIndex = makeElement(res, "div", undefined, "hidden"); + listIndex.id = `list_index${listID}`; for (const _ssii of indices) { const _IndexSlave = slaves[_ssii]; @@ -204,71 +308,59 @@ App.UI.SlaveList.render = function() { } if (_buttons.length > 0) { V.sortQuickList = V.sortQuickList || 'Devotion'; - listIndexContent += `//Sorting:// ''<span id="qlSort">$sortQuickList</span>.'' `; - listIndexContent += '<<link "Sort by Devotion">>' + - '<<set $sortQuickList = "Devotion" >>' + - '<<replace "#qlSort">> $sortQuickList <</replace>>' + - '<<run' + '$("#qlWrapper").removeClass("trust").addClass("devotion");' + 'sortButtonsByDevotion();' + '>>' + - '<</link>> | ' + - '<<link "Sort by Trust">>' + - '<<set $sortQuickList = "Trust">>' + - '<<replace "#qlSort">> $sortQuickList <</replace>>' + - '<<run' + '$("#qlWrapper").removeClass("devotion").addClass("trust");' + 'sortButtonsByTrust();' + '>>' + - '<</link>>' + - '<br/>'; - listIndexContent += '<div id="qlWrapper" class="quicklist devotion">'; + makeElement(listIndex, "em", "Sorting: "); + const qlSort = makeElement(listIndex, "span", V.sortQuickList, "strong"); + qlSort.id = "qlSort"; + listIndex.appendChild(document.createTextNode(". ")); + const linkSortByDevotion = makeElement(listIndex, "a", "Sort by Devotion"); + linkSortByDevotion.onclick = (ev) => { + ev.preventDefault(); + State.variables.sortQuickList = "Devotion"; + $("#qlSort").text(State.variables.sortQuickList); + $("#qlWrapper").removeClass("trust").addClass("devotion"); + sortButtonsByDevotion(); + }; + const linkSortByTrust = makeElement(listIndex, "a", "Sort by Trust"); + linkSortByTrust.onclick = (ev) => { + ev.preventDefault(); + State.variables.sortQuickList = "Trust"; + $("#qlSort").text(State.variables.sortQuickList); + $("#qlWrapper").removeClass("devotion").addClass("trust"); + sortButtonsByTrust(); + }; + makeElement(listIndex, "br"); + const qlWrapper = makeElement(listIndex, "div", undefined, ["quicklist", "devotion"]); + qlWrapper.id = "qlWrapper"; for (const _button of _buttons) { - const _buttonSlaveName = _button['data-name']; - listIndexContent += App.UI.htag(_buttonSlaveName, _button, 'button'); + const btn = makeElement(listIndex, 'button', _button['data-name'], undefined, _button); + btn.onclick = App.UI.quickBtnScrollToHandler; } - listIndexContent += '</div>'; } - res += App.UI.htag(listIndexContent, { - id: `list_index${listID}`, - class: 'hidden' - }); } return res; } - - function SlaveArt(slave, option) { - return `<<SlaveArtById ${slave.ID} ${option}>>`; - } - - function slaveImage(s) { - return `<div class="imageRef smlImg">${SlaveArt(s, 1)}</div>`; - } - - function dividerAndImage(s, showImage) { - showImage = showImage || true; - const r = [V.lineSeparations === 0 ? "<br>" : "<hr style=\"margin:0\">"]; - if (showImage && (V.seeImages === 1) && (V.seeSummaryImages === 1)) { - r.push(slaveImage(s)); - } - return r.join(""); - } }(); App.UI.SlaveList.Decoration = {}; /** * returns "HG", "BG", "PA", and "RC" prefixes * @param {App.Entity.SlaveState} slave - * @returns {string} + * @returns {HTMLElement} */ App.UI.SlaveList.Decoration.penthousePositions = (slave) => { if (App.Data.Facilities.headGirlSuite.manager.assignment === slave.assignment) { - return '<strong><span class="lightcoral">HG</span></strong>'; + return App.UI.DOM.makeSpan('HG', ['lightcoral', 'strong']); } if (App.Data.Facilities.penthouse.manager.assignment === slave.assignment) { - return '<strong><span class="lightcoral">RC</span></strong>'; + return App.UI.DOM.makeSpan('RC', ['lightcoral', 'strong']); } if (App.Data.Facilities.armory.manager.assignment === slave.assignment) { - return '<strong><span class="lightcoral">BG</span></strong>'; + return App.UI.DOM.makeSpan('BG', ['lightcoral', 'strong']); } if (Array.isArray(State.variables.personalAttention) && State.variables.personalAttention.findIndex(s => s.ID === slave.ID) !== -1) { - return '<strong><span class="lightcoral">PA</span></strong>'; + return App.UI.DOM.makeSpan('PA', ['lightcoral', 'strong']); } - return ''; + return null; }; App.UI.SlaveList.SlaveInteract = {}; @@ -276,27 +368,37 @@ App.UI.SlaveList.SlaveInteract = {}; /** * @param {App.Entity.SlaveState} slave * @param {number} index - * @returns {string} + * @returns {HTMLElement} */ App.UI.SlaveList.SlaveInteract.stdInteract = (slave, index) => - App.UI.passageLink(SlaveFullName(slave), 'Slave Interact', `$activeSlave = $slaves[${index}]`); + App.UI.DOM.passageLink(SlaveFullName(slave), 'Slave Interact', () => { App.Utils.setActiveSlaveByIndex(index); }); /** * @param {App.Entity.SlaveState} slave * @param {number} index - * @returns {string} + * @returns {DocumentFragment|HTMLElement} */ App.UI.SlaveList.SlaveInteract.penthouseInteract = (slave, index) => { - return App.UI.SlaveList.Decoration.penthousePositions(slave) + ' ' + App.UI.SlaveList.SlaveInteract.stdInteract(slave, index); + let decoration = App.UI.SlaveList.Decoration.penthousePositions(slave); + let stdLink = App.UI.SlaveList.SlaveInteract.stdInteract(slave, index); + if (decoration) { + let fr = document.createDocumentFragment(); + fr.appendChild(decoration); + fr.appendChild(document.createTextNode(' ')); + fr.appendChild(stdLink); + return fr; + } + return stdLink; }; /** * @param {App.Entity.SlaveState} slave - * @returns {string} + * @returns {HTMLElement} */ App.UI.SlaveList.SlaveInteract.personalAttention = (slave) => - App.UI.passageLink(SlaveFullName(slave), undefined, `App.UI.selectSlaveForPersonalAttention(${slave.ID});`); + App.UI.DOM.passageLink(SlaveFullName(slave), undefined, + () => { App.UI.selectSlaveForPersonalAttention(slave.ID); }); /** * Adds/removes a slave with the given id to/from the personal attention array @@ -382,9 +484,10 @@ App.UI.SlaveList.listSJFacilitySlaves = function(facility, facilityPassage, show if (facility.hostedSlaves > 0) { let facilitySlaves = job.employeesIndices(); SlaveSort.indices(facilitySlaves); - r += App.UI.tabbar.makeTab("remove", App.UI.SlaveList.render(facilitySlaves, [], + r += App.UI.tabbar.makeTab("remove", App.UI.SlaveList.render.listMarkup(facilitySlaves, [], App.UI.SlaveList.SlaveInteract.stdInteract, - (slave, index) => App.UI.passageLink(`Retrieve ${getPronouns(slave).object} from ${facility.name}`, "Retrieve", `$i = ${index}`))); + (slave, index) => App.UI.DOM.passageLink(`Retrieve ${getPronouns(slave).object} from ${facility.name}`, "Retrieve", + () => { variables().i = index; }))); } else { r += App.UI.tabbar.makeTab("remove", `<em>${capFirstChar(facility.name)} is empty for the moment</em>`); } @@ -406,9 +509,10 @@ App.UI.SlaveList.listSJFacilitySlaves = function(facility, facilityPassage, show passedSlaves.push(idx); } }, []); - return App.UI.SlaveList.render(passedSlaves, rejectedSlaves, + return App.UI.SlaveList.render.listMarkup(passedSlaves, rejectedSlaves, App.UI.SlaveList.SlaveInteract.stdInteract, - (slave, index) => App.UI.passageLink(`Send ${getPronouns(slave).object} to ${facility.name}`, "Assign", `$i = ${index}`)); + (slave, index) => App.UI.DOM.passageLink(`Send ${getPronouns(slave).object} to ${facility.name}`, "Assign", + () => { variables().i = index; })); } if (facility.hasFreeSpace) { const assignableSlaveIdxs = job.desc.partTime ? @@ -438,6 +542,20 @@ App.UI.SlaveList.listSJFacilitySlaves = function(facility, facilityPassage, show return r; }; +/** + * @param {string[]} classNames + */ +App.UI.SlaveList.makeNameDecorator = function(classNames) { + return (slave) => { + const r = document.createElement("span"); + for (const c of classNames) { + r.classList.add(c); + } + r.textContent = SlaveFullName(slave); + return r; + }; +}; + /** * @returns {string} */ @@ -458,10 +576,11 @@ App.UI.SlaveList.listNGPSlaves = function() { if (V.slavesToImport > 0) { const importedSlavesIndices = slaves.reduce((acc, s, i) => { if (s.assignment === NGPassignment) { acc.push(i); } return acc; }, []); SlaveSort.indices(importedSlavesIndices); - r += App.UI.tabbar.makeTab("remove", App.UI.SlaveList.render(importedSlavesIndices, [], - (s) => `<u><strong><span class="pink">${SlaveFullName(s)}</span></strong></u>`, - (s, i) => App.UI.passageLink('Remove from import list', thisPassage, - `$slavesToImport -= 1, removeJob(${App.Utils.slaveRefString(i)}, "${NGPassignment}")`))); + r += App.UI.tabbar.makeTab("remove", App.UI.SlaveList.render.listMarkup(importedSlavesIndices, [], + App.UI.SlaveList.makeNameDecorator(["emphasizedSlave", "pink"]), + (s, i) => App.UI.DOM.passageLink('Remove from import list', thisPassage, + () => { variables().slavesToImport -= 1; removeJob(variables().slaves[i], NGPassignment); } + ))); } else { r += App.UI.tabbar.makeTab("remove", `<em>No slaves will go with you to the new game</em>`); } @@ -469,10 +588,11 @@ App.UI.SlaveList.listNGPSlaves = function() { if (V.slavesToImport < V.slavesToImportMax) { const slavesToImportIndices = slaves.reduce((acc, s, i) => { if (s.assignment !== NGPassignment) { acc.push(i); } return acc; }, []); SlaveSort.indices(slavesToImportIndices); - r += App.UI.tabbar.makeTab("assign", App.UI.SlaveList.render(slavesToImportIndices, [], - (s) => `<u><strong><span class="pink">${SlaveFullName(s)}</span></strong></u>`, - (s, i) => App.UI.passageLink('Add to import list', thisPassage, - `$slavesToImport += 1, assignJob(${App.Utils.slaveRefString(i)}, "${NGPassignment}")`))); + r += App.UI.tabbar.makeTab("assign", App.UI.SlaveList.render.listMarkup(slavesToImportIndices, [], + App.UI.SlaveList.makeNameDecorator(["emphasizedSlave", "pink"]), + (s, i) => App.UI.DOM.passageLink('Add to import list', thisPassage, + () => { variables().slavesToImport += 1; assignJob(variables().slaves[i], NGPassignment); } + ))); } else { r += App.UI.tabbar.makeTab("assign", `<strong>Slave import limit reached</strong>`); } @@ -492,9 +612,9 @@ App.UI.SlaveList.displayManager = function(facility, selectionPassage) { selectionPassage = selectionPassage || `${managerCapName} Select`; const manager = facility.manager.currentEmployee; if (manager) { - return this.render([App.Utils.slaveIndexForId(manager.ID)], [], + return this.render.listMarkup([App.Utils.slaveIndexForId(manager.ID)], [], App.UI.SlaveList.SlaveInteract.stdInteract, - () => App.UI.passageLink(`Change or remove ${managerCapName}`, selectionPassage, "")); + () => App.UI.DOM.passageLink(`Change or remove ${managerCapName}`, selectionPassage)); } else { return `You do not have a slave serving as a ${managerCapName}. ${App.UI.passageLink(`Appoint one`, selectionPassage, "")}`; } @@ -526,12 +646,12 @@ App.UI.SlaveList.penthousePage = function() { if (V.HeadGirl) { /** @type {App.Entity.SlaveState} */ const HG = V.HeadGirl; - r += `<strong><u>${span(SlaveFullName(HG), "pink")}</u></strong> is serving as your Head Girl`; + r += `${span(SlaveFullName(HG), "emphasizedSlave pink")} is serving as your Head Girl`; if (thisArcology.FSEgyptianRevivalistLaw === 1) { r += ' and Consort'; } r += `. <strong> ${span(App.UI.passageLink("Manage Head Girl", "HG Select"), null, "manageHG")}</strong> ${span("[H]", "cyan")}`; - r += App.UI.SlaveList.render([App.Utils.slaveIndexForId(HG.ID)], [], + r += App.UI.SlaveList.render.listMarkup([App.Utils.slaveIndexForId(HG.ID)], [], App.UI.SlaveList.SlaveInteract.penthouseInteract); } else { if (V.slaves.length > 1) { @@ -550,7 +670,7 @@ App.UI.SlaveList.penthousePage = function() { /** @type {App.Entity.SlaveState} */ const RC = V.Recruiter; const p = getPronouns(RC); - r += `<strong><u>${span(SlaveFullName(RC), "pink")}</u></strong> is working `; + r += `${span(SlaveFullName(RC), "emphasizedSlave pink")} is working `; if (V.recruiterTarget !== "other arcologies") { r += 'to recruit girls'; } else { @@ -563,7 +683,7 @@ App.UI.SlaveList.penthousePage = function() { } } r += `${span('. <strong>' + App.UI.passageLink("Manage Recruiter", "Recruiter Select") + '</strong>', null, "manageRecruiter")} ${span("[U]", "cyan")}`; - r += App.UI.SlaveList.render([App.Utils.slaveIndexForId(RC.ID)], [], + r += App.UI.SlaveList.render.listMarkup([App.Utils.slaveIndexForId(RC.ID)], [], App.UI.SlaveList.SlaveInteract.penthouseInteract); } else { r += `You have ${span("not", "red")} selected a Recruiter. `; @@ -575,14 +695,14 @@ App.UI.SlaveList.penthousePage = function() { /** @type {App.Entity.SlaveState} */ const BG = V.Bodyguard; if (BG) { - r += `<strong><u>${span(SlaveFullName(BG), "pink")}</u></strong> is serving as your bodyguard. `; - r += span(`<strong>${App.UI.passageLink("Manage Bodyguard", "BG Select")}</strong>`, null, "manageBG") + + r += `${span(SlaveFullName(BG), "emphasizedSlave pink")} is serving as your bodyguard. `; + r += span(`<strong>${App.UI.passageLink("Manage Bodyguard", "BG Select")}</strong> `, null, "manageBG") + span("[B]", "cyan"); - r += App.UI.SlaveList.render([App.Utils.slaveIndexForId(BG.ID)], [], + r += App.UI.SlaveList.render.listMarkup([App.Utils.slaveIndexForId(BG.ID)], [], App.UI.SlaveList.SlaveInteract.penthouseInteract); } else { r += `You have ${span("not", "red")} selected a Bodyguard. `; - r += span(`<strong>${App.UI.passageLink("Select one", "BG Select")}</strong>`, null, "manageBG") + + r += span(`<strong>${App.UI.passageLink("Select one", "BG Select")}</strong> `, null, "manageBG") + span("[B]", "cyan"); } @@ -633,7 +753,7 @@ App.UI.SlaveList.penthousePage = function() { SlaveSort.indices(employeesIndices); return { n: employeesIndices.length, - text: App.UI.SlaveList.render(employeesIndices, [], App.UI.SlaveList.SlaveInteract.penthouseInteract) + text: App.UI.SlaveList.render.listMarkup(employeesIndices, [], App.UI.SlaveList.SlaveInteract.penthouseInteract) }; } @@ -656,7 +776,14 @@ App.UI.SlaveList.penthousePage = function() { function _updateList(job) { State.temporary.mainPageUpdate.job = job; - App.UI.replace('#' + listElementId, _slavesForJob(job).text); + const e = document.getElementById(listElementId); + e.innerHTML = ''; + const employeesIndices = job === 'all' ? ph.employeesIndices() : ph.job(job).employeesIndices(); + if (employeesIndices.length === 0) { + return; + } + SlaveSort.indices(employeesIndices); + e.appendChild(App.UI.SlaveList.render.listDOM(employeesIndices, [], App.UI.SlaveList.SlaveInteract.penthouseInteract)); } /** @@ -748,7 +875,7 @@ App.UI.SlaveList.penthousePage = function() { const penthouseSlavesIndices = ph.employeesIndices(); SlaveSort.indices(penthouseSlavesIndices); tabs.push(makeTabDesc('all', `All (${penthouseSlavesIndices.length})`, - this.render(penthouseSlavesIndices, [], App.UI.SlaveList.SlaveInteract.penthouseInteract))); + this.render.listMarkup(penthouseSlavesIndices, [], App.UI.SlaveList.SlaveInteract.penthouseInteract))); r += '<div class="tab">'; @@ -805,15 +932,15 @@ App.UI.SlaveList.slaveSelectionList = function() { * @typedef ListOptions * @property {slaveFilterCallbackReasoned|slaveFilterCallbackSimple} filter * @property {slaveTestCallback} [expCheck] - * @property {slaveTextGenerator} interactionLink - * @property {slaveTextGenerator} [postNote] + * @property {slaveToElement} interactionLink + * @property {slaveToElement} [postNote] */ /** * @param {slaveFilterCallbackReasoned|slaveFilterCallbackSimple} filter - * @param {slaveTextGenerator} interactionLink + * @param {slaveToElement} interactionLink * @param {slaveTestCallback} [experianceChecker] - * @param {slaveTextGenerator} [postNote] + * @param {slaveToElement} [postNote] * @returns {string} */ function selection(filter, interactionLink, experianceChecker, postNote) { @@ -831,7 +958,9 @@ App.UI.SlaveList.slaveSelectionList = function() { } function _updateList(assignment) { - App.UI.replace('#' + selectionElementId, _listSlaves(assignment, State.temporary.slaveSelection)); + const e = document.getElementById(selectionElementId); + e.innerHTML = ''; + e.appendChild(_listSlaves(assignment, State.temporary.slaveSelection)); } /** * Displays assignment filter links, whose action are generated by the callback @@ -874,7 +1003,7 @@ App.UI.SlaveList.slaveSelectionList = function() { * * @param {string} assignmentStr * @param {ListOptions} options - * @returns {string} + * @returns {DocumentFragment} */ function _listSlaves(assignmentStr, options) { /** @type {App.Entity.SlaveState[]} */ @@ -913,13 +1042,17 @@ App.UI.SlaveList.slaveSelectionList = function() { // done this way to test for tests presence only once const listPostNote = options.expCheck ? (options.postNote ? - (s, i) => options.expCheck(s) ? '<span class="lime">Has applicable career experience.</span><br>' : '' + options.postNote(s, i) : - (s) => options.expCheck(s) ? '<span class="lime">Has applicable career experience.</span>' : '') : + (s, i) => options.expCheck(s) ? App.UI.DOM.combineNodes( + App.UI.DOM.makeSpan("Has applicable career experience.", "lime"), + document.createElement("br"), + options.postNote(s, i) + ) : options.postNote(s, i) : + (s) => options.expCheck(s) ? App.UI.DOM.makeSpan("Has applicable career experience.", "lime") : null) : options.postNote ? (s, i) => options.postNote(s, i) : - () => ''; + () => null; - return App.UI.SlaveList.render(passingIndices, rejects, options.interactionLink, listPostNote); + return App.UI.SlaveList.render.listDOM(passingIndices, rejects, options.interactionLink, listPostNote); } }(); @@ -931,6 +1064,7 @@ App.UI.SlaveList.slaveSelectionList = function() { App.UI.SlaveList.facilityManagerSelection = function(facility, passage) { passage = passage || capFirstChar(facility.manager.desc.position) + " Workaround"; return this.slaveSelectionList(slave => facility.manager.canEmploy(slave), - (slave, index) => App.UI.passageLink(SlaveFullName(slave), passage, `$i = ${index}`), + (slave, index) => App.UI.DOM.passageLink(SlaveFullName(slave), passage, + () => { variables().i = index; }), slave => facility.manager.slaveHasExperience(slave)); }; diff --git a/src/js/slaveSummaryWidgets.js b/src/js/slaveSummaryWidgets.js index 1c333706ac884e9082dbf2bcb75d5010d437d548..5e2fb6551d7ac7add375b66214417553058f17d0 100644 --- a/src/js/slaveSummaryWidgets.js +++ b/src/js/slaveSummaryWidgets.js @@ -31,2429 +31,2152 @@ window.SlaveSummary = function SlaveSummary(slave) { window.SlaveSummaryUncached = (function() { "use strict"; let V; - let r; + /** @type {DocumentFragment} */ + let res; /** * @param {App.Entity.SlaveState} slave - * @returns {string} */ + * @returns {DocumentFragment} */ function SlaveSummaryUncached(slave) { V = State.variables; - r = ""; + res = document.createDocumentFragment(); + let para = makeParagraph(res); if (V.abbreviateDevotion === 1) { - short_devotion(slave); + short_devotion(slave, para); } else if (V.abbreviateDevotion === 2) { - long_devotion(slave); + long_devotion(slave, para); } if (slave.fuckdoll === 0) { if (V.abbreviateRules === 1) { - short_rules(slave); + short_rules(slave, para); } else if (V.abbreviateRules === 2) { - long_rules(slave); + long_rules(slave, para); } } if (slave.tired !== 0) { - r += `Tired.`; + addText(para, `Tired.`); } if (V.abbreviateDiet === 1) { - short_weight(slave); + short_weight(slave, para); } else if (V.abbreviateDiet === 2) { - long_weight(slave); + long_weight(slave, para); } if (V.abbreviateDiet === 1) { - short_diet(slave); + short_diet(slave, para); } else if (V.abbreviateDiet === 2) { - long_diet(slave); + long_diet(slave, para); } if (V.abbreviateHealth === 1) { - short_health(slave); + short_health(slave, para); } else if (V.abbreviateHealth === 2) { - long_health(slave); + long_health(slave, para); } if (V.abbreviateDrugs === 1) { - short_drugs(slave); + short_drugs(slave, para); } else if (V.abbreviateDrugs === 2) { - long_drugs(slave); + long_drugs(slave, para); } - if (V.abbreviateNationality + V.abbreviateGenitalia + V.abbreviatePhysicals + V.abbreviateSkills + V.abbreviateMental !== 0) { - r += `<br>`; - if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) { - r += " "; - } - } - V.desc = SlaveTitle(slave); - const first_letter = V.desc.substring(0, 1).toUpperCase(); - V.desc = first_letter + V.desc.substring(1); - r += `<strong><span class="coral">${V.desc}${V.abbreviatePhysicals === 2? '.' : ''}</span></strong> `; - if (V.seeRace === 1) { - r += `<span class="tan">`; - if (V.abbreviateRace === 1) { - short_race(slave); - } else if (V.abbreviateRace === 2) { - long_race(slave); - } - r += `</span> `; - } - if (V.abbreviateNationality === 1) { - short_nationality(slave); - } else if (V.abbreviateNationality === 2) { - long_nationality(slave); + + para = makeParagraph(res); + para.classList.add("pink"); + + makeSpan(para, `${capFirstChar(SlaveTitle(slave))}${V.abbreviatePhysicals === 2 ? '.' : ''}`, ["coral", "strong"]); + if (V.seeRace === 1 && V.abbreviateRace !== 0) { + makeSpan(para, V.abbreviateRace === 1 ? short_race(slave) : long_race(slave), "tan"); } - if (V.abbreviatePhysicals === 1) { - short_skin(slave); - } else { - r += `<span class="pink">${slave.skin.charAt(0).toUpperCase() + slave.skin.slice(1)} skin.</span> `; + if (V.abbreviateNationality !== 0) { + makeSpan(para, V.abbreviateNationality === 1 ? short_nationality(slave) : long_nationality(slave), "tan"); } + makeSpan(para, V.abbreviatePhysicals === 1 ? short_skin(slave) : `${capFirstChar(slave.skin)} skin.`); if (V.abbreviateGenitalia === 1) { - short_genitals(slave); + short_genitals(slave, para); } else if (V.abbreviateGenitalia === 2) { - long_genitals(slave); + long_genitals(slave, para); } if (V.abbreviatePhysicals === 1) { - short_age(slave); - short_face(slave); - short_eyes(slave); - short_ears(slave); + short_age(slave, para); + short_face(slave, para); + short_eyes(slave, para); + short_ears(slave, para); if (slave.markings !== "none") { - r += "Markings"; + makeSpan(para, "Markings"); } - short_lips(slave); - short_teeth(slave); - short_muscles(slave); - short_limbs(slave); - short_voice(slave); - short_tits_ass(slave); - short_hips(slave); - short_waist(slave); - short_implants(slave); - short_lactation(slave); - short_mods(slave); - r += `</span>`; + short_lips(slave, para); + short_teeth(slave, para); + short_muscles(slave, para); + short_limbs(slave, para); + short_voice(slave, para); + short_tits_ass(slave, para); + short_hips(slave, para); + short_waist(slave, para); + short_implants(slave, para); + short_lactation(slave, para); + short_mods(slave, para); } else if (V.abbreviatePhysicals === 2) { - long_age(slave); - long_face(slave); - long_eyes(slave); - long_ears(slave); - long_lips(slave); - long_teeth(slave); - long_muscles(slave); - long_limbs(slave); - long_voice(slave); - long_tits_ass(slave); - long_hips(slave); - long_waist(slave); - long_implants(slave); - long_lactation(slave); - long_mods(slave); + long_age(slave, para); + long_face(slave, para); + long_eyes(slave, para); + long_ears(slave, para); + long_lips(slave, para); + long_teeth(slave, para); + long_muscles(slave, para); + long_limbs(slave, para); + long_voice(slave, para); + long_tits_ass(slave, para); + long_hips(slave, para); + long_waist(slave, para); + long_implants(slave, para); + long_lactation(slave, para); + long_mods(slave, para); if (!jQuery.isEmptyObject(slave.brand)) { - r += `Branded.`; + makeSpan(para, `Branded.`); } - r += `</span>`; } if (V.abbreviateHormoneBalance === 1) { if (slave.hormoneBalance <= -21) { - r += `<span class="deepskyblue">`; - r += ` <strong>HB:M</strong>`; + makeSpan(para, "HB:M", ["deepskyblue", "strong"]); } else if (slave.hormoneBalance <= 20) { - r += `<span class="pink">`; - r += ` <strong>HB:N</strong>`; + makeSpan(para, "HB:N", ["pink", "strong"]); } else if (slave.hormoneBalance <= 500) { - r += `<span class="pink">`; - r += ` <strong>HB:F</strong>`; + makeSpan(para, "HB:F", ["pink", "strong"]); } - r += `</span>`; } else if (V.abbreviateHormoneBalance === 2) { - r += `<span class=`; - if (slave.hormoneBalance <= -21) { - r += `"deepskyblue"`; - } else { - r += `"pink"`; - } - r += `> `; + const colorClass = slave.hormoneBalance <= -21 ? "deepskyblue" : "pink"; + let desc = ""; if (slave.hormoneBalance < -400) { - r += `Overwhelmingly masculine`; + desc = `Overwhelmingly masculine`; } else if (slave.hormoneBalance <= -300) { - r += `Extremely masculine`; + desc = `Extremely masculine`; } else if (slave.hormoneBalance <= -200) { - r += `Heavily masculine`; + desc = `Heavily masculine`; } else if (slave.hormoneBalance <= -100) { - r += `Very masculine`; + desc = `Very masculine`; } else if (slave.hormoneBalance <= -21) { - r += `Masculine`; + desc = `Masculine`; } else if (slave.hormoneBalance <= 20) { - r += `Neutral`; + desc = `Neutral`; } else if (slave.hormoneBalance <= 99) { - r += `Feminine`; + desc = `Feminine`; } else if (slave.hormoneBalance <= 199) { - r += `Very feminine`; + desc = `Very feminine`; } else if (slave.hormoneBalance <= 299) { - r += `Heavily feminine`; + desc = `Heavily feminine`; } else if (slave.hormoneBalance <= 399) { - r += `Extremely feminine`; + desc = `Extremely feminine`; } else if (slave.hormoneBalance <= 500) { - r += `Overwhelmingly feminine`; + desc = `Overwhelmingly feminine`; } - r += ` hormone balance.</span>`; - } - r += "<br>"; - if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) { - r += " "; + makeSpan(para, desc + " hormone balance.", colorClass); } + + para = makeParagraph(res); + if (V.abbreviateSkills === 1) { - short_intelligence(slave); - short_sex_skills(slave); - if (slave.skill.combat > 0) { - r += "C"; - } - r += "</span> "; - short_prestige(slave); - short_porn_prestige(slave); + short_intelligence(slave, para); + short_skills(slave, para); + short_prestige(slave, para); + short_porn_prestige(slave, para); } else if (V.abbreviateSkills === 2) { - long_intelligence(slave); - long_sex_skills(slave); - if (slave.skill.combat > 0) { - r += "Trained fighter."; - } - r += "</span> "; - long_prestige(slave); - long_porn_prestige(slave); + long_intelligence(slave, para); + long_skills(slave, para); + long_prestige(slave, para); + long_porn_prestige(slave, para); } if (V.abbreviateMental === 1) { if (slave.fetish !== "mindbroken") { if (slave.fetishKnown === 1) { - short_fetish(slave); + short_fetish(slave, para); } if (slave.attrKnown === 1) { - short_attraction(slave); + short_attraction(slave, para); } } if (slave.clitPiercing === 3) { - short_smart_fetish(slave); - short_smart_attraction(slave); + short_smart_fetish(slave, para); + short_smart_attraction(slave, para); } - short_behavior_flaw(slave); - short_sex_flaw(slave); - short_behavior_quirk(slave); - short_sex_quirk(slave); + short_behavior_flaw(slave, para); + short_sex_flaw(slave, para); + short_behavior_quirk(slave, para); + short_sex_quirk(slave, para); } else if (V.abbreviateMental === 2) { if (slave.fetish !== "mindbroken") { if (slave.fetishKnown === 1) { - long_fetish(slave); + long_fetish(slave, para); } if (slave.attrKnown === 1) { - long_attraction(slave); + long_attraction(slave, para); } } if (slave.clitPiercing === 3) { - long_smart_fetish(slave); - long_smart_attraction(slave); + long_smart_fetish(slave, para); + long_smart_attraction(slave, para); } - long_behavior_flaw(slave); - long_sex_flaw(slave); - long_behavior_quirk(slave); - long_sex_quirk(slave); + long_behavior_flaw(slave, para); + long_sex_flaw(slave, para); + long_behavior_quirk(slave, para); + long_sex_quirk(slave, para); } if (slave.custom.label) { - r += `<strong><span class="yellow">${capFirstChar(slave.custom.label)}.</span></strong>`; + makeSpan(res, `${capFirstChar(slave.custom.label)}.`, ["yellow", "strong"]); } if ((slave.relationship !== 0) || (slave.relation !== 0) || (V.abbreviateClothes === 2) || (V.abbreviateRulesets === 2)) { - r += `<br>`; - if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) { - r += ` `; - } + para = makeParagraph(res); } if (V.abbreviateMental === 1) { - r += `<span class="lightgreen">`; - if (V.familyTesting === 1) { - short_extended_family(slave); - } else { - short_legacy_family(slave); - } - r += `</span>`; - short_clone(slave); - short_rival(slave); + makeSpan(para, V.familyTesting === 1 ? short_extended_family(slave) : short_legacy_family(slave), "lightgreen"); + short_clone(slave, para); + short_rival(slave, para); } else if (V.abbreviateMental === 2) { if (V.familyTesting === 1) { - long_extended_family(slave); + long_extended_family(slave, para); } else { - long_legacy_family(slave); + long_legacy_family(slave, para); } - long_clone(slave); - long_rival(slave); + long_clone(slave, para); + long_rival(slave, para); } if (slave.fuckdoll === 0) { if (V.abbreviateClothes === 2) { - r += ` `; + const dressingBlock = makeBlock(para); if (slave.choosesOwnClothes === 1) { - r += `Dressing ${getPronouns(slave).objectReflexive}. `; + makeSpan(dressingBlock, `Dressing ${getPronouns(slave).himself}.`); } - long_clothes(slave); - long_collar(slave); - long_belly(slave); + long_clothes(slave, dressingBlock); + long_collar(slave, dressingBlock); + long_belly(slave, dressingBlock); if (slave.missingArms !== 3) { - long_arms(slave); + long_arms(slave, dressingBlock); } if (slave.missingLegs !== 3) { - long_legs(slave); - long_shoes(slave); + long_legs(slave, dressingBlock); + long_shoes(slave, dressingBlock); } - long_chastity(slave); - long_vaginal_acc(slave); - long_dick_acc(slave); - long_buttplug(slave); + long_chastity(slave, dressingBlock); + long_vaginal_acc(slave, dressingBlock); + long_dick_acc(slave, dressingBlock); + long_buttplug(slave, dressingBlock); } } - r += ` `; - rules_assistant(slave); + const RABlock = makeBlock(para); + rules_assistant(slave, RABlock); if (V.abbreviateOrigins === 2 && slave.origin !== 0) { - origins(slave); + origins(slave, res); } - return r; + return res; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c */ - function short_devotion(slave) { + function short_devotion(slave, c) { if (slave.fetish === "mindbroken") { - r += `<span class="red">MB</span>`; + makeSpan(c, "MB", "red"); } else if (slave.devotion < -95) { - r += `<span class="darkviolet">Hate${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + makeSpan(c, "Hate", "darkviolet", true, slave.devotion); } else if (slave.devotion < -50) { - r += `<span class="darkviolet">Hate${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + makeSpan(c, "Hate", "darkviolet", true, slave.devotion); } else if (slave.devotion < -20) { - r += `<span class="mediumorchid">Res${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + makeSpan(c, "Res", "mediumorchid", true, slave.devotion); } else if (slave.devotion <= 20) { - r += `<span class="yellow">Ambiv${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + makeSpan(c, "Ambiv", "yellow", true, slave.devotion); } else if (slave.devotion <= 50) { - r += `<span class="hotpink">Accept${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + makeSpan(c, "Accept", "hotpink", true, slave.devotion); } else if (slave.devotion <= 95) { - r += `<span class="deeppink">Devo${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + makeSpan(c, "Devo", "deeppink", true, slave.devotion); } else { - r += `<span class="magenta">Wor${V.summaryStats ? `[${slave.devotion}]` : ''}</span>`; + makeSpan(c, "Wor", "magenta", true, slave.devotion); } - r += " "; if (slave.fetish === "mindbroken") { return; } else if (slave.trust < -95) { - r += `<span class="darkgoldenrod">ETerr${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + makeSpan(c, "ETerr", "darkgoldenrod", true, slave.trust); } else if (slave.trust < -50) { - r += `<span class="goldenrod">Terr${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + makeSpan(c, "Terr", "goldenrod", true, slave.trust); } else if (slave.trust < -20) { - r += `<span class="gold">Fright${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + makeSpan(c, "Fright", "gold", true, slave.trust); } else if (slave.trust <= 20) { - r += `<span class="yellow">Fear${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + makeSpan(c, "Fear", "yellow", true, slave.trust); } else if (slave.trust <= 50) { if (slave.devotion < -20) { - r += `<span class="orange">Caref${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + makeSpan(c, "Caref", "orange", true, slave.trust); } else { - r += `<span class="mediumaquamarine">Caref${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + makeSpan(c, "Caref", "mediumaquamarine", true, slave.trust); } } else if (slave.trust < 95) { if (slave.devotion < -20) { - r += `<span class="orangered">Bold${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + makeSpan(c, "Bold", "orangered", true, slave.trust); } else { - r += `<span class="mediumseagreen">Trust${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + makeSpan(c, "Trust", "mediumseagreen", true, slave.trust); } } else { if (slave.devotion < -20) { - r += `<span class="darkred">Defiant${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + makeSpan(c, "Defiant", "darkred", true, slave.trust); } else { - r += `<span class="seagreen">VTrust ${V.summaryStats ? `[${slave.trust}]` : ''}</span>`; + makeSpan(c, "VTrust", "seagreen", true, slave.trust); } } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_devotion(slave) { + function long_devotion(slave, c) { if (slave.fetish === "mindbroken") { - r += `<span class="red">Mindbroken.</span>`; + makeSpan(c, "Mindbroken.", "red"); } else if (slave.devotion < -95) { - r += `<span class="darkviolet">Very hateful${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + makeSpan(c, "Very hateful", "darkviolet", true, slave.devotion); } else if (slave.devotion < -50) { - r += `<span class="darkviolet">Hateful${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + makeSpan(c, "Hateful", "darkviolet", true, slave.devotion); } else if (slave.devotion < -20) { - r += `<span class="mediumorchid">Resistant${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + makeSpan(c, "Resistant", "mediumorchid", true, slave.devotion); } else if (slave.devotion <= 20) { - r += `<span class="yellow">Ambivalent${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + makeSpan(c, "Ambivalent", "yellow", true, slave.devotion); } else if (slave.devotion <= 50) { - r += `<span class="hotpink">Accepting${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + makeSpan(c, "Accepting", "hotpink", true, slave.devotion); } else if (slave.devotion <= 95) { - r += `<span class="deeppink">Devoted${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + makeSpan(c, "Devoted", "deeppink", true, slave.devotion); } else { - r += `<span class="magenta">Worshipful${V.summaryStats ? `[${slave.devotion}]` : ''}.</span>`; + makeSpan(c, "Worshipful", "magenta", true, slave.devotion); } - r += " "; if (slave.fetish === "mindbroken") { return; } else if (slave.trust < -95) { - r += `<span class="darkgoldenrod">Extremely terrified${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + makeSpan(c, "Extremely terrified", "darkgoldenrod", true, slave.trust); } else if (slave.trust < -50) { - r += `<span class="goldenrod">Terrified${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + makeSpan(c, "Terrified", "goldenrod", true, slave.trust); } else if (slave.trust < -20) { - r += `<span class="gold">Frightened${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + makeSpan(c, "Frightened", "gold", true, slave.trust); } else if (slave.trust <= 20) { - r += `<span class="yellow">Fearful${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + makeSpan(c, "Fearful", "yellow", true, slave.trust); } else if (slave.trust <= 50) { if (slave.devotion < -20) { - r += `<span class="orange">Careful${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + makeSpan(c, "Careful", "orange", true, slave.trust); } else { - r += `<span class="mediumaquamarine">Careful${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + makeSpan(c, "Careful", "mediumaquamarine", true, slave.trust); } } else if (slave.trust < 95) { if (slave.devotion < -20) { - r += `<span class="orangered">Bold${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + makeSpan(c, "Bold", "orangered", true, slave.trust); } else { - r += `<span class="mediumseagreen">Trusting${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + makeSpan(c, "Trusting", "mediumseagreen", true, slave.trust); } } else { if (slave.devotion < -20) { - r += `<span class="darkred">Defiant${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + makeSpan(c, "Defiant", "darkred", true, slave.trust); } else { - r += `<span class="seagreen">Profoundly trusting${V.summaryStats ? `[${slave.trust}]` : ''}.</span>`; + makeSpan(c, "Profoundly trusting", "seagreen", true, slave.trust); } } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_rules(slave) { + function short_rules(slave, c) { + const tagName = "strong;" switch (slave.livingRules) { case "luxurious": - r += `<strong>LS:Lux</strong>`; + tag(c, tagName, "LS:Lux"); break; case "normal": - r += `<strong>LS:Nor</strong>`; + tag(c, tagName, "LS:Nor"); break; default: - r += `<strong>LS:Spa</strong>`; + tag(c, tagName, "LS:Spa"); break; } - r += " "; - if (canTalk(slave, false)) { + if (canTalk(slave)) { switch (slave.speechRules) { case "permissive": - r += `<strong>SpR:P</strong>`; + tag(c, tagName, "SpR:P"); break; case "accent elimination": - r += `<strong>SpR:NoAcc</strong>`; + tag(c, tagName, "SpR:NoAcc"); break; case "language lessons": - r += `<strong>SpR:LL</strong>`; + tag(c, tagName, "SpR:LL"); break; default: - r += `<strong>SpR:R</strong>`; + tag(c, tagName, "SpR:R"); break; } - r += " "; } switch (slave.relationshipRules) { case "permissive": - r += `<strong>ReR:P</strong>`; + tag(c, tagName, "ReR:P"); break; case "just friends": - r += `<strong>ReR:Fr</strong>`; + tag(c, tagName, "ReR:Fr"); break; default: - r += `<strong>ReR:R</strong>`; + tag(c, tagName, "ReR:R"); break; } - r += " "; switch (slave.standardPunishment) { case "confinement": - r += `<strong>Pun:Conf</strong>`; + tag(c, tagName, "Pun:Conf"); break; case "whipping": - r += `<strong>Pun:Whip</strong>`; + tag(c, tagName, "Pun:Whip"); break; case "chastity": - r += `<strong>Pun:Chas</strong>`; + tag(c, tagName, "Pun:Chas"); break; default: - r += `<strong>Pun:Situ</strong>`; + tag(c, tagName, "Pun:Situ"); break; } - r += " "; switch (slave.standardReward) { case "relaxation": - r += `<strong>Rew:Relx</strong>`; + tag(c, tagName, "Rew:Relx"); break; case "drugs": - r += `<strong>Rew:Drug</strong>`; + tag(c, tagName, "Rew:Drug"); break; case "orgasm": - r += `<strong>Rew:Orga</strong>`; + tag(c, tagName, "Rew:Orga"); break; default: - r += `<strong>Rew:Situ</strong>`; + tag(c, tagName, "Rew:Situ"); break; } - r += " "; switch (slave.releaseRules) { case "permissive": - r += `<strong>MaR:P</strong>`; + tag(c, tagName, "MaR:P"); break; case "sapphic": - r += `<strong>MaR:S</strong>`; + tag(c, tagName, "MaR:S"); break; case "masturbation": - r += `<strong>MaR:M</strong>`; + tag(c, tagName, "MaR:M"); break; case "chastity": - r += `<strong>MaR:C</strong>`; + tag(c, tagName, "MaR:C"); break; default: - r += `<strong>MaR:R</strong>`; + tag(c, tagName, "MaR:R"); break; } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_rules(slave) { - r += `Living standard: ${slave.livingRules}. `; - if (canTalk(slave, false)) { - r += `Speech rules: ${slave.speechRules}. `; - } - r += `Relationship rules: ${slave.relationshipRules}. `; - r += `Typical punishment: ${slave.standardPunishment}. `; - r += `Typical reward: ${slave.standardReward}. `; - r += `Release rules: ${slave.releaseRules}. `; + function long_rules(slave, c) { + addText(c, `Living standard: ${slave.livingRules}. `); + if (canTalk(slave)) { + addText(c, `Speech rules: ${slave.speechRules}. `); + } + addText(c, `Relationship rules: ${slave.relationshipRules}. `); + addText(c, `Typical punishment: ${slave.standardPunishment}. `); + addText(c, `Typical reward: ${slave.standardReward}. `); + addText(c, `Release rules: ${slave.releaseRules}. `); } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_weight(slave) { + function short_weight(slave, c) { if (slave.weight < -95) { - r += `<strong><span class="red">W---${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + makeSpan(c, "W---", ["red", "strong"], true, slave.weight); } else if (slave.weight < -30) { if (slave.hips < -1) { - r += `<strong>W--${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + makeSpan(c, "W--", "strong", true, slave.weight); } else { - r += `<strong><span class="red">W--${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + makeSpan(c, "W--", ["red", "strong>"], true, slave.weight); } } else if (slave.weight < -10) { - r += `<strong>W-${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + makeSpan(c, "W-", "strong", true, slave.weight); } else if (slave.weight <= 10) { - r += `<strong>W${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + makeSpan(c, "W", "strong", true, slave.weight); } else if (slave.weight <= 30) { - r += `<strong>W+${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + makeSpan(c, "W+", "strong", true, slave.weight); } else if (slave.weight <= 95) { if (slave.hips > 1 || V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `<strong>W++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + makeSpan(c, "W++", "strong", true, slave.weight); } else { - r += `<strong><span class="red">W++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + makeSpan(c, "W++", ["red", "strong"], true, slave.weight); } } else if (slave.weight <= 130) { if (slave.hips > 2 || V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `<strong>W+++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + makeSpan(c, "W+++", "strong", true, slave.weight); } else { - r += `<strong><span class="red">W+++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + makeSpan(c, "W+++", ["red", "strong"], true, slave.weight); } } else if (slave.weight <= 160) { if (V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `<strong>W++++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + makeSpan(c, "W++++", "strong", true, slave.weight); } else { - r += `<strong><span class="red">W++++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + makeSpan(c, "W++++", ["red", "strong"], true, slave.weight); } } else if (slave.weight <= 190) { if (V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `<strong>W+++++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + makeSpan(c, "W+++++", "strong", true, slave.weight); } else { - r += `<strong><span class="red">W+++++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + makeSpan(c, "W+++++", ["red", "strong"], true, slave.weight); } } else { if (V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `<strong>W++++++${V.summaryStats? `[${slave.weight}]` : ''}</strong>`; + makeSpan(c, "W++++++", "strong", true, slave.weight); } else { - r += `<strong><span class="red">W++++++${V.summaryStats? `[${slave.weight}]` : ''}</span></strong>`; + makeSpan(c, "W++++++", ["red", "strong"], true, slave.weight); } } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_weight(slave) { + function long_weight(slave, c) { if (slave.weight < -95) { - r += `<span class="red">Emaciated${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + makeSpan(c, "Emaciated", "red", true, slave.weight); } else if (slave.weight < -30) { if (slave.hips < -1) { - r += `Model-thin${V.summaryStats? `[${slave.weight}]`: ''}.`; + makeSpan(c, "Model-thin", null, true, slave.weight); } else { - r += `<span class="red">Very thin${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + makeSpan(c, "Very thin", "red", true, slave.weight); } } else if (slave.weight < -10) { - r += `Thin${V.summaryStats? `[${slave.weight}]`: ''}.`; + makeSpan(c, "Thin", null, true, slave.weight); } else if (slave.weight <= 10) { - r += `Trim${V.summaryStats? `[${slave.weight}]`: ''}.`; + makeSpan(c, "Trim", null, true, slave.weight); } else if (slave.weight <= 30) { - r += `Plush${V.summaryStats? `[${slave.weight}]`: ''}.`; + makeSpan(c, "Plush", null, true, slave.weight); } else if (slave.weight <= 95) { if (slave.hips > 1 || V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `Nicely chubby${V.summaryStats? `[${slave.weight}]`: ''}.`; + makeSpan(c, "Nicely chubby", null, true, slave.weight); } else { - r += `<span class="red">Overweight${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + makeSpan(c, "Overweight", "red", true, slave.weight); } } else if (slave.weight <= 130) { if (slave.hips > 2 || V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `Pleasantly soft and shapely${V.summaryStats? `[${slave.weight}]`: ''}.`; + makeSpan(c, "Pleasantly soft and shapely", null, true, slave.weight); } else { - r += `<span class="red">Fat${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + makeSpan(c, "Fat", "red", true, slave.weight); } } else if (slave.weight <= 160) { if (V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `Amazingly voluptuous${V.summaryStats? `[${slave.weight}]`: ''}.`; + makeSpan(c, "Amazingly voluptuous", null, true, slave.weight); } else { - r += `<span class="red">Obese${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + makeSpan(c, "Obese", "red", true, slave.weight); } } else if (slave.weight <= 190) { if (V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `SSBBW${V.summaryStats? `[${slave.weight}]`: ''}.`; + makeSpan(c, "SSBBW", null, true, slave.weight); } else { - r += `<span class="red">Super Obese${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + makeSpan(c, "Super Obese", "red", true, slave.weight); } } else { if (V.arcologies[0].FSHedonisticDecadence !== "unset") { - r += `Perfectly massive${V.summaryStats? `[${slave.weight}]`: ''}.`; + makeSpan(c, "Perfectly massive", null, true, slave.weight); } else { - r += `<span class="red">Dangerously Obese${V.summaryStats ? `[${slave.weight}]`: ''}.</span>`; + makeSpan(c, "Dangerously Obese", "red", true, slave.weight); } } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_diet(slave) { - r += `<span class="teal">`; + function short_diet(slave, c) { + let diet = makeSpan(null, "", ["teal", "strong"]); switch (slave.diet) { case "restricted": - r += `<strong>Di:W-</strong>`; + diet.textContent = "Di:W-"; break; case "fattening": - r += `<strong>Di:W+</strong>`; + diet.textContent = "Di:W+"; break; case "XX": - r += `<strong>Di:XX+</strong>`; + diet.textContent = "Di:XX+"; break; case "XY": - r += `<strong>Di:XY+</strong>`; + diet.textContent = "Di:XY+"; break; case "XXY": - r += `<strong>Di:XXY+</strong>`; + diet.textContent = "Di:XXY+"; break; case "muscle building": - r += `<strong>Di:M+</strong>`; + diet.textContent = "Di:M+"; break; case "slimming": - r += `<strong>Di:M-</strong>`; + diet.textContent = "Di:M-"; break; case "cum production": - r += `<strong>Di:C+</strong>`; + diet.textContent = "Di:C+"; break; case "cleansing": - r += `<strong>Di:H+</strong>`; + diet.textContent = "Di:H+"; break; case "fertility": - r += `<strong>Di:F+</strong>`; + diet.textContent = "Di:F+"; break; } - r += `</span> `; - r += `<span class="cyan">`; + if (diet.textContent.length > 0) { + c.appendChild(diet); + } + let specialDiet = makeSpan(null, "", ["cyan", "strong"]); if (slave.dietCum === 2) { - r += `<strong>Cum++</strong>`; + specialDiet.textContent = "Cum++"; } else if (((slave.dietCum === 1) && (slave.dietMilk === 0))) { - r += `<strong>Cum+</strong>`; + specialDiet.textContent = "Cum+"; } else if (((slave.dietCum === 1) && (slave.dietMilk === 1))) { - r += `<strong>Cum+ Milk+</strong>`; + specialDiet.textContent = "Cum+ Milk+"; } else if (((slave.dietCum === 0) && (slave.dietMilk === 1))) { - r += `<strong>Milk+</strong>`; + specialDiet.textContent = "Milk+"; } else if ((slave.dietMilk === 2)) { - r += `<strong>Milk++</strong>`; + specialDiet.textContent = ">Milk++"; + } + if (specialDiet.textContent.length > 0) { + c.appendChild(specialDiet); } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_diet(slave) { - r += `<span class="teal">`; + function long_diet(slave, c) { + let dietDesc = ""; switch (slave.diet) { case "restricted": - r += `Dieting.`; + dietDesc = `Dieting.`; break; case "fattening": - r += `Gaining weight.`; + dietDesc = `Gaining weight.`; break; case "XX": - r += `Estrogen rich.`; + dietDesc = `Estrogen rich.`; break; case "XY": - r += `Testosterone rich.`; + dietDesc = `Testosterone rich.`; break; case "XXY": - r += `Futanari mix.`; + dietDesc = `Futanari mix.`; break; case "muscle building": - r += `Pumping iron.`; + dietDesc = `Pumping iron.`; break; case "slimming": - r += `Slimming down.`; + dietDesc = `Slimming down.`; break; case "cum production": - r += `Cum production.`; + dietDesc = `Cum production.`; break; case "cleansing": - r += `Cleansing.`; + dietDesc = `Cleansing.`; break; case "fertility": - r += `Fertility.`; + dietDesc = `Fertility.`; break; } - r += `</span> `; + + if (dietDesc) { + makeSpan(c, dietDesc, "teal"); + } + + function specialDiet(text) { + addText(c, "Diet base: "); + makeSpan(c, text, "cyan"); + } + if (slave.dietCum === 2) { - r += `Diet base: <span class="cyan">Cum Based.</span>`; + specialDiet("Cum Based."); } else if (((slave.dietCum === 1) && (slave.dietMilk === 0))) { - r += `Diet base: <span class="cyan">Cum Added.</span>`; + specialDiet("Cum Added."); } else if (((slave.dietCum === 1) && (slave.dietMilk === 1))) { - r += `Diet base: <span class="cyan">Milk & Cum Added.</span>`; + specialDiet("Milk & Cum Added."); } else if (((slave.dietCum === 0) && (slave.dietMilk === 1))) { - r += `Diet base: <span class="cyan">Milk Added.</span>`; + specialDiet("Milk Added."); } else if ((slave.dietMilk === 2)) { - r += `Diet base: <span class="cyan">Milk Based.</span>`; + specialDiet("Milk Based."); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_health(slave) { + function short_health(slave, c) { if (slave.health < -20) { - r += `<strong><span class="red">H${V.summaryStats? `[${slave.health}]` : ''}</span></strong>`; + makeSpan(c, "H", ["red", "strong"], true, slave.health); } else if (slave.health <= 20) { - r += `<strong><span class="yellow">H${V.summaryStats? `[${slave.health}]` : ''}</span></strong>`; + makeSpan(c, "H", ["yellow", "strong"], true, slave.health); } else if (slave.health > 20) { - r += `<strong><span class="green">H${V.summaryStats? `[${slave.health}]` : ''}</span></strong>`; + makeSpan(c, "H", ["green", "strong"], true, slave.health); } - r += " "; if (passage() === "Clinic" && V.clinicUpgradeScanner && slave.chem > 15) { - r += `<strong><span class="cyan">C${Math.ceil(slave.chem/10)}</span></strong> `; + makeSpan(c, `C${Math.ceil(slave.chem/10)}`, ["cyan", "strong"]); } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_health(slave) { + function long_health(slave, c) { if (slave.health < -90) { - r += `<span class="red">On the edge of death${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + makeSpan(c, "On the edge of death", ["red", "strong"], true, slave.health); } else if (slave.health < -50) { - r += `<span class="red">Extremely unhealthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + makeSpan(c, "Extremely unhealthy", ["red", "strong"], true, slave.health); } else if (slave.health < -20) { - r += `<span class="red">Unhealthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + makeSpan(c, "Unhealthy", ["red", "strong"], true, slave.health); } else if (slave.health <= 20) { - r += `<span class="yellow">Healthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + makeSpan(c, "Healthy", "yellow", true, slave.health); } else if (slave.health <= 50) { - r += `<span class="green">Very healthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + makeSpan(c, "Very healthy", "green", true, slave.health); } else if (slave.health <= 90) { - r += `<span class="green">Extremely healthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + makeSpan(c, "Extremely healthy", "green", true, slave.health); } else { - r += `<span class="green">Unnaturally healthy${V.summaryStats? `[${slave.health}]` : ''}.</span>`; + makeSpan(c, "Unnaturally healthy", "green", true, slave.health); } - r += " "; if (passage() === "Clinic" && V.clinicUpgradeScanner && slave.chem > 15) { - r += `<strong><span class="cyan">Carcinogen buildup: ${Math.ceil(slave.chem/10)}</span>.</strong> `; + makeSpan(c, `Carcinogen buildup: ${Math.ceil(slave.chem/10)}.`, "cyan"); } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_drugs(slave) { - r += `<span class="tan">`; + function short_drugs(slave, c) { + let drugDesc = ""; switch (slave.drugs) { case "breast injections": - r += `<strong>Dr:Boobs+</strong>`; + drugDesc = "Boobs+"; break; case "intensive breast injections": - r += `<strong>Dr:Boobs++</strong>`; + drugDesc = "Boobs++" break; case "hyper breast injections": - r += `<strong>Dr:Boobs+++</strong>`; + drugDesc = "Boobs+++" break; case "butt injections": - r += `<strong>Dr:Butt+</strong>`; + drugDesc = "Butt+"; break; case "intensive butt injections": - r += `<strong>Dr:Butt++</strong>`; + drugDesc = "Butt++"; break; case "hyper butt injections": - r += `<strong>Dr:Butt+++</strong>`; + drugDesc = "Butt+++"; break; case "lip injections": - r += `<strong>Dr:Lip+</strong>`; + drugDesc = "Lip+"; break; case "fertility drugs": - r += `<strong>Dr:Fert+</strong>`; + drugDesc = "Fert+"; break; case "super fertility drugs": - r += `<strong>Dr:Fert++</strong>`; + drugDesc = "Fert++"; break; case "penis enhancement": - r += `<strong>Dr:Dick+</strong>`; + drugDesc = "Dick+"; break; case "intensive penis enhancement": - r += `<strong>Dr:Dick++</strong>`; + drugDesc = "Dick++"; break; case "hyper penis enhancement": - r += `<strong>Dr:Dick+++</strong>`; + drugDesc = "Dick+++"; break; case "testicle enhancement": - r += `<strong>Dr:Balls+</strong>`; + drugDesc = "Balls+"; break; case "intensive testicle enhancement": - r += `<strong>Dr:Balls++</strong>`; + drugDesc = "Balls++"; break; case "hyper testicle enhancement": - r += `<strong>Dr:Balls+++</strong>`; + drugDesc = "Balls+++"; break; case "psychosuppressants": - r += `<strong>Dr:Psych</strong>`; + drugDesc = "Psych"; break; case "steroids": - r += `<strong>Dr:Ster</strong>`; + drugDesc = "Ster"; break; case "female hormone injections": - r += `<strong>Dr:HormXX++</strong>`; + drugDesc = "HormXX++"; break; case "male hormone injections": - r += `<strong>Dr:HormXY++</strong>`; + drugDesc = "HormXY++"; break; case "hormone enhancers": - r += `<strong>Dr:Horm+</strong>`; + drugDesc = "Horm+"; break; case "hormone blockers": - r += `<strong>Dr:Horm-</strong>`; + drugDesc = "Horm-"; break; case "anti-aging cream": - r += `<strong>Dr:Age-</strong>`; + drugDesc = "Age-"; break; case "appetite suppressors": - r += `<strong>Dr:ApSup</strong>`; + drugDesc = "ApSup"; break; case "penis atrophiers": - r += `<strong>Dr:Dick-</strong>`; + drugDesc = "Dick-"; break; case "testicle atrophiers": - r += `<strong>Dr:Balls-</strong>`; + drugDesc = "Balls-"; break; case "clitoris atrophiers": - r += `<strong>Dr:Clit-</strong>`; + drugDesc = "Clit-"; break; case "labia atrophiers": - r += `<strong>Dr:Labia-</strong>`; + drugDesc = "Labia-"; break; case "nipple atrophiers": - r += `<strong>Dr:Nipple-</strong>`; + drugDesc = "Nipple-"; break; case "lip atrophiers": - r += `<strong>Dr:Lip-</strong>`; + drugDesc = "Lip-"; break; case "breast redistributors": - r += `<strong>Dr:Breast-</strong>`; + drugDesc = "Breast-"; break; case "butt redistributors": - r += `<strong>Dr:Butt-</strong>`; + drugDesc = "Butt-"; break; case "sag-B-gone": - r += `<strong>Dr:AntiSag</strong>`; + drugDesc = "AntiSag"; break; case "growth stimulants": - r += `<strong>Dr:GroStim</strong>`; + drugDesc = "GroStim"; break; case "priapism agents": - r += `<strong>Dr:Erection</strong>`; + drugDesc = "Erection"; break; } - r += `</span> `; - r += `<span class="lightgreen">`; + if (drugDesc) { + makeSpan(c, "Dr:" + drugDesc, ["tan", "strong"]); + } if (slave.curatives === 2) { - r += `<strong>Cura</strong>`; + makeSpan(c, "Cura", ["lightgreen", "strong"]); } else if (slave.curatives === 1) { - r += `<strong>Prev</strong>`; + makeSpan(c, "Prev", ["lightgreen", "strong"]); } - r += `</span> `; if (slave.aphrodisiacs !== 0) { - r += `<span class="lightblue">`; if (slave.aphrodisiacs === 1) { - r += `<strong>Aph</strong>`; + makeSpan(c, "Aph", ["lightblue", "strong"]); } else if (slave.aphrodisiacs === 2) { - r += `<strong>Aph++</strong>`; + makeSpan(c, "Aph++", ["lightblue", "strong"]); } else { - r += `<strong>Anaph</strong>`; + makeSpan(c, "Anaph", ["lightblue", "strong"]); } - r += `</span> `; } if (slave.addict !== 0) { - r += `<span class="cyan">Add</span>`; + makeSpan(c, "Add", "cyan"); } - r += `<span class="lightsalmon">`; + let styles = ["lightsalmon", "strong"]; if (slave.hormones > 1) { - r += `<strong>Ho:F+</strong>`; + makeSpan(c, "Ho:F+", styles); } else if (slave.hormones > 0) { - r += `<strong>Ho:F</strong>`; + makeSpan(c, "Ho:F", styles); } else if (slave.hormones < -1) { - r += `<strong>Ho:M+</strong>`; + makeSpan(c, "Ho:M+", styles, ); } else if (slave.hormones < 0) { - r += `<strong>Ho:M</strong>`; + makeSpan(c, "Ho:M", styles); } - r += `</span> `; - r += `<span class="mediumseagreen">`; + + styles = ["mediumseagreen", "strong"]; if ((slave.bellyImplant > -1)) { - r += `<strong>Belly Imp</strong>`; + makeSpan(c, "Belly Imp", styles); } else if (((slave.preg <= -2) || (slave.ovaries === 0)) && (slave.vagina !== -1)) { - r += `<strong>Barr</strong>`; + makeSpan(c, "Barr", styles); } else if (slave.pubertyXX === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { - r += `<strong>Prepub</strong>`; + makeSpan(c, "Prepub", styles); } else if (slave.ovaryAge >= 47 && (slave.ovaries === 1 || slave.mpreg === 1)) { - r += `<strong>Meno</strong>`; + makeSpan(c, "Meno", styles); } else if (slave.pregWeek < 0) { - r += `<strong>Postpartum</strong>`; + makeSpan(c, "Postpartum", styles); } else if (slave.preg === -1) { - r += `<strong>CC</strong>`; + makeSpan(c, "CC", styles); } else if (slave.preg === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { - r += `<strong>Fert+</strong>`; + makeSpan(c, "Fert+", styles); } else if (((slave.preg < slave.pregData.normalBirth / 10) && (slave.preg > 0) && slave.pregKnown === 0) || slave.pregWeek === 1) { - r += `<strong>Preg?</strong>`; + makeSpan(c, "Preg?", styles); } else if ((slave.preg >= 36) && (slave.broodmother > 0)) { - r += `<strong>Perm preg</strong>`; + makeSpan(c, "Perm preg", styles); } else if (slave.pregKnown === 1) { - r += `<strong>${slave.pregWeek} wks preg</strong>`; + makeSpan(c, `${slave.pregWeek} wks preg`, styles); } - r += `</span> `; if (slave.induce === 1) { - r += `<span class="orange"><strong>Early Labor</strong></span>`; + makeSpan(c, "Early Labor", ["orange", "strong"]); } if (slave.pubertyXY === 0 && slave.balls > 0) { - r += `<strong>Prepub balls</strong>`; + makeSpan(c, "Prepub balls", "strong"); } if (slave.balls > 0 && slave.vasectomy === 1) { - r += `<strong>Vasect</strong>`; + makeSpan(c, "Vasect", "strong"); } - r += `<span class="springgreen">`; + styles = ["springgreen", "strong"]; if (slave.inflation === 3) { - r += `<strong>8 ltr ${slave.inflationType}</strong>`; + makeSpan(c, `8 ltr ${slave.inflationType}`, styles); } else if (slave.inflation === 2) { - r += `<strong>4 ltr ${slave.inflationType}</strong>`; + makeSpan(c, `4 ltr ${slave.inflationType}`, styles); } else if (slave.inflation === 1) { - r += `<strong>2 ltr ${slave.inflationType}</strong>`; + makeSpan(c, `2 ltr ${slave.inflationType}`, styles); } else if (slave.bellyFluid > 0) { - r += `<strong>${slave.bellyFluid}ccs ${slave.inflationType}</strong>`; + makeSpan(c, `${slave.bellyFluid}ccs ${slave.inflationType}`, styles); } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_drugs(slave) { + function long_drugs(slave, c) { let swd = WombGetLittersData(slave); if ((slave.drugs !== "no drugs") && (slave.drugs !== "none")) { - r += `<span class="tan">On ${slave.drugs}.</span> `; + makeSpan(c, `On ${slave.drugs}.`, "tan"); } - r += `<span class="lightgreen">`; if (slave.curatives === 2) { - r += `On curatives.`; + makeSpan(c, "On curatives.", "lightgreen"); } else if (slave.curatives === 1) { - r += `On preventatives.`; + makeSpan(c, "On preventatives.", "lightgreen"); } - r += `</span> `; - r += `<span class="lightblue">`; if (slave.aphrodisiacs > 0) { - r += `On ${slave.aphrodisiacs > 1 ? 'extreme': ''} aphrodisiacs.`; + makeSpan(c, `On ${slave.aphrodisiacs > 1 ? 'extreme' : ''} aphrodisiacs.`, "lightblue"); } else if (slave.aphrodisiacs === -1) { - r += `On anaphrodisiacs.`; + makeSpan(c, "On anaphrodisiacs.", "lightblue"); } - r += `</span> `; if (slave.addict !== 0) { - r += `<span class="cyan">Addict.</span>`; + makeSpan(c, "Addict.", "cyan"); } - r += `<span class="lightsalmon">`; if (slave.hormones > 1) { - r += `Heavy female hormones.`; + makeSpan(c, "Heavy female hormones.", "lightsalmon"); } else if (slave.hormones > 0) { - r += `Female hormones.`; + makeSpan(c, "Female hormones.", "lightsalmon"); } else if (slave.hormones < -1) { - r += `Heavy male hormones.`; + makeSpan(c, "Heavy male hormones.", "lightsalmon"); } else if (slave.hormones < 0) { - r += `Male hormones.`; + makeSpan(c, "Male hormones.", "lightsalmon"); } - r += `</span> `; - r += `<span class="mediumseagreen">`; + let styles = "mediumseagreen"; if ((slave.bellyImplant > -1)) { - r += `Belly Implant.`; + makeSpan(c, "Belly Implant.", styles); } else if (((slave.preg <= -2) || (slave.ovaries === 0)) && (slave.vagina !== -1)) { - r += `Barren.`; + makeSpan(c, "Barren.", styles); } else if (slave.pubertyXX === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { - r += `Not ovulating yet.`; + makeSpan(c, "Not ovulating yet.", styles); } else if (slave.ovaryAge >= 47 && (slave.ovaries === 1 || slave.mpreg === 1)) { - r += `Menopausal.`; + makeSpan(c, "Menopausal.", styles); } else if (slave.pregWeek < 0) { - r += `Postpartum.`; + makeSpan(c, "Postpartum.", styles); } else if (slave.preg === -1) { - r += `On contraceptives.`; + makeSpan(c, "On contraceptives.", styles); } else if (slave.preg === 0 && (slave.ovaries === 1 || slave.mpreg === 1)) { - r += `Fertile.`; + makeSpan(c, "Fertile.", styles); } else if ((slave.preg >= 36) && (slave.broodmother > 0)) { - r += `Permanently pregnant.`; + makeSpan(c, "Permanently pregnant.", styles); } else if (swd.litters.length > 1) { - r += `<span class="lime">`; - r += `Concurrent pregnancies: (${swd.litters.length} sets).`; - r+= ` Max:${swd.litters[0]} / Min:${swd.litters[swd.litters.length-1]} week(s).`; - r += `</span> `; + let pregTxt = `Concurrent pregnancies: (${swd.litters.length} sets).`; + pregTxt += ` Max:${swd.litters[0]} / Min:${swd.litters[swd.litters.length-1]} week(s).`; + makeSpan(c, pregTxt, "lime"); } else if (((slave.preg < slave.pregData.normalBirth / 10) && (slave.preg > 0) && slave.pregKnown === 0) || slave.pregWeek === 1) { - r += `May be pregnant.`; + makeSpan(c, "May be pregnant."); } else if (slave.pregKnown === 1) { if (slave.pregType < 2 || slave.broodmother > 0) { - r += `${slave.pregWeek} weeks pregnant.`; + makeSpan(c, `${slave.pregWeek} weeks pregnant.`); } else { - r += `${slave.pregWeek} weeks pregnant with `; + let desc = `${slave.pregWeek} weeks pregnant with `; if (slave.pregType >= 40) { - r += `a tremendous brood of offspring.`; + desc += `a tremendous brood of offspring.`; } else if (slave.pregType >= 20) { - r += `a brood of offspring.`; + desc += `a brood of offspring.`; } else if (slave.pregType >= 10) { - r += `${slave.pregType} babies.`; + desc += `${slave.pregType} babies.`; } else if (slave.pregType === 9) { - r += `nonuplets.`; + desc += `nonuplets.`; } else if (slave.pregType === 8) { - r += `octuplets.`; + desc += `octuplets.`; } else if (slave.pregType === 7) { - r += `septuplets.`; + desc += `septuplets.`; } else if (slave.pregType === 6) { - r += `sextuplets.`; + desc += `sextuplets.`; } else if (slave.pregType === 5) { - r += `quintuplets.`; + desc += `quintuplets.`; } else if (slave.pregType === 4) { - r += `quadruplets.`; + desc += `quadruplets.`; } else if (slave.pregType === 3) { - r += `triplets.`; + desc += `triplets.`; } else { - r += `twins.`; + desc += `twins.`; } + makeSpan(c, desc); } if (slave.preg > slave.pregData.normalBirth && slave.broodmother === 0) { - r += ` (Overdue.)`; + makeSpan(c, "(Overdue.)"); } } - r += `</span> `; if (slave.induce === 1) { - r += `<span class="orange">Showing signs of early labor.</span>`; + makeSpan(c, "Showing signs of early labor.", "orange"); } if (slave.pubertyXY === 0 && slave.balls > 0) { - r += `Has not had first ejaculation.`; + makeSpan(c, "Has not had first ejaculation."); } if (slave.balls > 0 && slave.vasectomy === 1) { - r += `Vasectomy.`; + makeSpan(c, "Vasectomy."); } - r += `<span class="springgreen">`; if (slave.inflation === 3) { - r += `Filled with 8 liters of ${slave.inflationType}.`; + makeSpan(c, `Filled with 8 liters of ${slave.inflationType}.`, "springgreen"); } else if (slave.inflation === 2) { - r += `Filled with 4 liters of ${slave.inflationType}.`; + makeSpan(c, `Filled with 4 liters of ${slave.inflationType}.`, "springgreen"); } else if (slave.inflation === 1) { - r += `Filled with 2 liters of ${slave.inflationType}.`; + makeSpan(c, `Filled with 2 liters of ${slave.inflationType}.`, "springgreen"); } else if (slave.bellyFluid > 0) { - r += `Stuffed with ${slave.bellyFluid}ccs of ${slave.inflationType}.`; + makeSpan(c, `Stuffed with ${slave.bellyFluid}ccs of ${slave.inflationType}.`, "springgreen"); } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @returns {string} */ function long_race(slave) { switch (slave.race) { case "white": - r += `Caucasian.`; - break; + return `Caucasian.`; case "asian": - r += `Asian.`; - break; + return `Asian.`; case "indo-aryan": - r += `Indo-aryan.`; - break; + return `Indo-aryan.`; case "latina": - r += `Latina.`; - break; + return `Latina.`; case "middle eastern": - r += `Middle Eastern.`; - break; + return `Middle Eastern.`; case "black": - r += `Black.`; - break; + return `Black.`; case "pacific islander": - r += `Pacific Islander.`; - break; + return `Pacific Islander.`; case "malay": - r += `Malay.`; - break; + return `Malay.`; case "amerindian": - r += `Amerindian.`; - break; + return `Amerindian.`; case "semitic": - r += `Semitic.`; - break; + return `Semitic.`; case "southern european": - r += `Southern European.`; - break; + return `Southern European.`; case "mixed race": - r += `Mixed race.`; - break; + return `Mixed race.`; default: - r += `${slave.race.charAt(0).toUpperCase() + slave.race.slice(1)}.`; - break; + return `${slave.race.charAt(0).toUpperCase() + slave.race.slice(1)}.`; } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @returns {string} */ function short_race(slave) { switch (slave.race) { case "white": - r += `C`; - break; + return `C`; case "asian": - r += `A`; - break; + return `A`; case "indo-aryan": - r += `I`; - break; + return `I`; case "latina": - r += `L`; - break; + return `L`; case "middle eastern": - r += `ME`; - break; + return `ME`; case "black": - r += `B`; - break; + return `B`; case "pacific islander": - r += `PI`; - break; + return `PI`; case "malay": - r += `M`; - break; + return `M`; case "amerindian": - r += `AI`; - break; + return `AI`; case "semitic": - r += `S`; - break; + return `S`; case "southern european": - r += `SE`; - break; + return `SE`; case "mixed race": - r += `MR`; - break; + return `MR`; default: - r += `${slave.race.charAt(0).toUpperCase() + slave.race.charAt(1) + slave.race.charAt(2)}`; - break; + return `${slave.race.charAt(0).toUpperCase() + slave.race.charAt(1) + slave.race.charAt(2)}`; } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @returns {string} */ function short_nationality(slave) { - r += `<span class="tan">`; switch (slave.nationality) { case "Afghan": - r += `Afg`; - break; + return "Afg"; case "Albanian": - r += `Alb`; - break; + return "Alb"; case "Algerian": - r += `Alg`; - break; + return "Alg"; case "American": - r += `USA`; - break; + return "USA"; case "Andorran": - r += `And`; - break; + return "And"; case "Angolan": - r += `Ang`; - break; + return "Ang"; case "Antiguan": - r += `AB`; - break; + return "AB"; case "Argentinian": - r += `Arg`; - break; + return "Arg"; case "Armenian": - r += `Arm`; - break; + return "Arm"; case "Aruban": - r += `Aru`; - break; + return "Aru"; case "Australian": - r += `Aus`; - break; + return "Aus"; case "Austrian": - r += `Aut`; - break; + return "Aut"; case "Azerbaijani": - r += `Aze`; - break; + return "Aze"; case "Bahamian": - r += `Bah`; - break; + return "Bah"; case "Bahraini": - r += `Bah`; - break; + return "Bah"; case "Bangladeshi": - r += `Bgd`; - break; + return "Bgd"; case "Barbadian": - r += `Bar`; - break; + return "Bar"; case "Belarusian": - r += `Ber`; - break; + return "Ber"; case "Belgian": - r += `Bel`; - break; + return "Bel"; case "Belizean": - r += `Blz`; - break; + return "Blz"; case "Beninese": - r += `Ben`; - break; + return "Ben"; case "Bermudian": - r += `Bmd`; - break; + return "Bmd"; case "Bhutanese": - r += `Bhu`; - break; + return "Bhu"; case "Bissau-Guinean": - r += `GB`; - break; + return "GB"; case "Bolivian": - r += `Bol`; - break; + return "Bol"; case "Bosnian": - r += `Bos`; - break; + return "Bos"; case "Brazilian": - r += `Bra`; - break; + return "Bra"; case "British": - r += `UK`; - break; + return "UK"; case "Bruneian": - r += `Bru`; - break; + return "Bru"; case "Bulgarian": - r += `Bul`; - break; + return "Bul"; case "Burkinabé": - r += `BF`; - break; + return "BF"; case "Burmese": - r += `Bur`; - break; + return "Bur"; case "Burundian": - r += `Bnd`; - break; + return "Bnd"; case "Cambodian": - r += `Kam`; - break; + return "Kam"; case "Cameroonian": - r += `Cam`; - break; + return "Cam"; case "Canadian": - r += `Can`; - break; + return "Can"; case "Cape Verdean": - r += `CV`; - break; + return "CV"; case "Catalan": - r += `Cat`; - break; + return "Cat"; case "Central African": - r += `CAR`; - break; + return "CAR"; case "Chadian": - r += `Cha`; - break; + return "Cha"; case "Chilean": - r += `Chl`; - break; + return "Chl"; case "Chinese": - r += `Chi`; - break; + return "Chi"; case "Colombian": - r += `Col`; - break; + return "Col"; case "Comorian": - r += `Com`; - break; + return "Com"; case "Congolese": - r += `RC`; - break; + return "RC"; case "a Cook Islander": - r += `CI`; - break; + return "CI"; case "Costa Rican": - r += `CR`; - break; + return "CR"; case "Croatian": - r += `Cro`; - break; + return "Cro"; case "Cuban": - r += `Cub`; - break; + return "Cub"; case "Curaçaoan": - r += `Cur`; - break; + return "Cur"; case "Cypriot": - r += `Cyp`; - break; + return "Cyp"; case "Czech": - r += `Cze`; - break; + return "Cze"; case "Danish": - r += `Den`; - break; + return "Den"; case "Djiboutian": - r += `Dji`; - break; + return "Dji"; case "Dominican": - r += `DR`; - break; + return "DR"; case "Dominiquais": - r += `Dom`; - break; + return "Dom"; case "Dutch": - r += `Nld`; - break; + return "Nld"; case "East Timorese": - r += `ET`; - break; + return "ET"; case "Ecuadorian": - r += `Ecu`; - break; + return "Ecu"; case "Egyptian": - r += `Egy`; - break; + return "Egy"; case "Emirati": - r += `UAE`; - break; + return "UAE"; case "Equatoguinean": - r += `EG`; - break; + return "EG"; case "Eritrean": - r += `Eri`; - break; + return "Eri"; case "Estonian": - r += `Est`; - break; + return "Est"; case "Ethiopian": - r += `Eth`; - break; + return "Eth"; case "Fijian": - r += `Fij`; - break; + return "Fij"; case "Filipina": - r += `Phl`; - break; + return "Phl"; case "Finnish": - r += `Fin`; - break; + return "Fin"; case "French": - r += `Fra`; - break; + return "Fra"; case "French Guianan": - r += `FG`; - break; + return "FG"; case "French Polynesian": - r += `FP`; - break; + return "FP"; case "Gabonese": - r += `Gab`; - break; + return "Gab"; case "Gambian": - r += `Gam`; - break; + return "Gam"; case "Georgian": - r += `Geo`; - break; + return "Geo"; case "German": - r += `Ger`; - break; + return "Ger"; case "Ghanan": - r += `Gha`; - break; + return "Gha"; case "Greek": - r += `Gre`; - break; + return "Gre"; case "Greenlandic": - r += `Grn`; - break; + return "Grn"; case "Grenadian": - r += `Gda`; - break; + return "Gda"; case "Guamanian": - r += `Gua`; - break; + return "Gua"; case "Guatemalan": - r += `Gtm`; - break; + return "Gtm"; case "Guinean": - r += `Gui`; - break; + return "Gui"; case "Guyanese": - r += `Guy`; - break; + return "Guy"; case "Haitian": - r += `Hai`; - break; + return "Hai"; case "Honduran": - r += `Hon`; - break; + return "Hon"; case "Hungarian": - r += `Hun`; - break; + return "Hun"; case "I-Kiribati": - r += `Kir`; - break; + return "Kir"; case "Icelandic": - r += `Ice`; - break; + return "Ice"; case "Indian": - r += `Ind`; - break; + return "Ind"; case "Indonesian": - r += `Idn`; - break; + return "Idn"; case "Iranian": - r += `Irn`; - break; + return "Irn"; case "Iraqi": - r += `Irq`; - break; + return "Irq"; case "Irish": - r += `Irl`; - break; + return "Irl"; case "Israeli": - r += `Isr`; - break; + return "Isr"; case "Italian": - r += `Ita`; - break; + return "Ita"; case "Ivorian": - r += `IC`; - break; + return "IC"; case "Jamaican": - r += `Jam`; - break; + return "Jam"; case "Japanese": - r += `Jpn`; - break; + return "Jpn"; case "Jordanian": - r += `Jor`; - break; + return "Jor"; case "Kazakh": - r += `Kaz`; - break; + return "Kaz"; case "Kenyan": - r += `Ken`; - break; + return "Ken"; case "Kittitian": - r += `SKN`; - break; + return "SKN"; case "Korean": - r += `Kor`; - break; + return "Kor"; case "Kosovan": - r += `Kos`; - break; + return "Kos"; case "Kurdish": - r += `Kur`; - break; + return "Kur"; case "Kuwaiti": - r += `Kuw`; - break; + return "Kuw"; case "Kyrgyz": - r += `Kyr`; - break; + return "Kyr"; case "Laotian": - r += `Lao`; - break; + return "Lao"; case "Latvian": - r += `Lat`; - break; + return "Lat"; case "Lebanese": - r += `Lbn`; - break; + return "Lbn"; case "Liberian": - r += `Lib`; - break; + return "Lib"; case "Libyan": - r += `Lby`; - break; + return "Lby"; case "a Liechtensteiner": - r += `Lie`; - break; + return "Lie"; case "Lithuanian": - r += `Lit`; - break; + return "Lit"; case "Luxembourgian": - r += `Lux`; - break; + return "Lux"; case "Macedonian": - r += `Mac`; - break; + return "Mac"; case "Malagasy": - r += `Mad`; - break; + return "Mad"; case "Malawian": - r += `Mwi`; - break; + return "Mwi"; case "Malaysian": - r += `Mys`; - break; + return "Mys"; case "Maldivian": - r += `Mdv`; - break; + return "Mdv"; case "Malian": - r += `Mal`; - break; + return "Mal"; case "Maltese": - r += `Mlt`; - break; + return "Mlt"; case "Marshallese": - r += `MI`; - break; + return "MI"; case "Mauritanian": - r += `Mta`; - break; + return "Mta"; case "Mauritian": - r += `Mts`; - break; + return "Mts"; case "Mexican": - r += `Mex`; - break; + return "Mex"; case "Micronesian": - r += `FSM`; - break; + return "FSM"; case "Moldovan": - r += `Mol`; - break; + return "Mol"; case "Monégasque": - r += `Mnc`; - break; + return "Mnc"; case "Mongolian": - r += `Mon`; - break; + return "Mon"; case "Montenegrin": - r += `Mng`; - break; + return "Mng"; case "Moroccan": - r += `Mor`; - break; + return "Mor"; case "Mosotho": - r += `Les`; - break; + return "Les"; case "Motswana": - r += `Bot`; - break; + return "Bot"; case "Mozambican": - r += `Moz`; - break; + return "Moz"; case "Namibian": - r += `Nam`; - break; + return "Nam"; case "Nauruan": - r += `Nau`; - break; + return "Nau"; case "Nepalese": - r += `Npl`; - break; + return "Npl"; case "New Caledonian": - r += `NC`; - break; + return "NC"; case "a New Zealander": - r += `NZ`; - break; + return "NZ"; case "Ni-Vanuatu": - r += `Van`; - break; + return "Van"; case "Nicaraguan": - r += `Nic`; - break; + return "Nic"; case "Nigerian": - r += `Nga`; - break; + return "Nga"; case "Nigerien": - r += `Ngr`; - break; + return "Ngr"; case "Niuean": - r += `Niu`; - break; + return "Niu"; case "Norwegian": - r += `Nor`; - break; + return "Nor"; case "Omani": - r += `Omn`; - break; + return "Omn"; case "Pakistani": - r += `Pak`; - break; + return "Pak"; case "Palauan": - r += `Plu`; - break; + return "Plu"; case "Palestinian": - r += `Pal`; - break; + return "Pal"; case "Panamanian": - r += `Pan`; - break; + return "Pan"; case "Papua New Guinean": - r += `PNG`; - break; + return "PNG"; case "Paraguayan": - r += `Par`; - break; + return "Par"; case "Peruvian": - r += `Per`; - break; + return "Per"; case "Polish": - r += `Pol`; - break; + return "Pol"; case "Portuguese": - r += `Por`; - break; + return "Por"; case "Puerto Rican": - r += `PR`; - break; + return "PR"; case "Qatari": - r += `Qat`; - break; + return "Qat"; case "Romanian": - r += `Rom`; - break; + return "Rom"; case "Russian": - r += `Rus`; - break; + return "Rus"; case "Rwandan": - r += `Rwa`; - break; + return "Rwa"; case "Sahrawi": - r += `Sah`; - break; + return "Sah"; case "Saint Lucian": - r += `SL`; - break; + return "SL"; case "Salvadoran": - r += `ES`; - break; + return "ES"; case "Sammarinese": - r += `SM`; - break; + return "SM"; case "Samoan": - r += `Sam`; - break; + return "Sam"; case "São Toméan": - r += `STP`; - break; + return "STP"; case "Saudi": - r += `Sau`; - break; + return "Sau"; case "Scottish": - r += `Sco`; - break; + return "Sco"; case "Senegalese": - r += `Sen`; - break; + return "Sen"; case "Serbian": - r += `Srb`; - break; + return "Srb"; case "Seychellois": - r += `Sey`; - break; + return "Sey"; case "Sierra Leonean": - r += `Sie`; - break; + return "Sie"; case "Singaporean": - r += `Sng`; - break; + return "Sng"; case "Slovak": - r += `Svk`; - break; + return "Svk"; case "Slovene": - r += `Svn`; - break; + return "Svn"; case "a Solomon Islander": - r += `SI`; - break; + return "SI"; case "Somali": - r += `Som`; - break; + return "Som"; case "South African": - r += `RSA`; - break; + return "RSA"; case "South Sudanese": - r += `SS`; - break; + return "SS"; case "Spanish": - r += `Spa`; - break; + return "Spa"; case "Sri Lankan": - r += `Sri`; - break; + return "Sri"; case "Sudanese": - r += `Sud`; - break; + return "Sud"; case "Surinamese": - r += `Sur`; - break; + return "Sur"; case "Swazi": - r += `Swa`; - break; + return "Swa"; case "Swedish": - r += `Swe`; - break; + return "Swe"; case "Swiss": - r += `Swi`; - break; + return "Swi"; case "Syrian": - r += `Syr`; - break; + return "Syr"; case "Taiwanese": - r += `Tai`; - break; + return "Tai"; case "Tajik": - r += `Taj`; - break; + return "Taj"; case "Tanzanian": - r += `Tza`; - break; + return "Tza"; case "Thai": - r += `Tha`; - break; + return "Tha"; case "Tibetan": - r += `Tib`; - break; + return "Tib"; case "Togolese": - r += `Tog`; - break; + return "Tog"; case "Tongan": - r += `Ton`; - break; + return "Ton"; case "Trinidadian": - r += `TT`; - break; + return "TT"; case "Tunisian": - r += `Tun`; - break; + return "Tun"; case "Turkish": - r += `Tur`; - break; + return "Tur"; case "Turkmen": - r += `Tkm`; - break; + return "Tkm"; case "Tuvaluan": - r += `Tuv`; - break; + return "Tuv"; case "Ugandan": - r += `Uga`; - break; + return "Uga"; case "Ukrainian": - r += `Ukr`; - break; + return "Ukr"; case "Uruguayan": - r += `Uru`; - break; + return "Uru"; case "Uzbek": - r += `Uzb`; - break; + return "Uzb"; case "Vatican": - r += `VC`; - break; + return "VC"; case "Venezuelan": - r += `Ven`; - break; + return "Ven"; case "Vietnamese": - r += `Vnm`; - break; + return "Vnm"; case "Vincentian": - r += `SVG`; - break; + return "SVG"; case "Yemeni": - r += `Yem`; - break; + return "Yem"; case "Zairian": - r += `DRC`; - break; + return "DRC"; case "Zambian": - r += `Zam`; - break; + return "Zam"; case "Zimbabwean": if (slave.race === "white") { - r += `Rho`; + return `Rho`; } else { - r += `Zwe`; + return `Zwe`; } - break; case "Ancient Chinese Revivalist": - r += `Chi Rev`; - break; + return `Chi Rev`; case "Ancient Egyptian Revivalist": - r += `Egy Rev`; - break; + return `Egy Rev`; case "Arabian Revivalist": - r += `Ara Rev`; - break; + return `Ara Rev`; case "Aztec Revivalist": - r += `Azt Rev`; - break; + return `Azt Rev`; case "Edo Revivalist": - r += `Edo Rev`; - break; + return `Edo Rev`; case "Roman Revivalist": - r += `Rom Rev`; - break; + return `Rom Rev`; case "": case "none": case "slave": case "Stateless": - r += `None`; - break; + return "None"; default: - r += `${slave.nationality.charAt(0) + slave.nationality.charAt(1) + slave.nationality.charAt(2)}`; - break; + return `${slave.nationality.charAt(0) + slave.nationality.charAt(1) + slave.nationality.charAt(2)}`; } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @returns {string} */ function long_nationality(slave) { - r += `<span class="tan">`; switch (slave.nationality) { case "a Cook Islander": - r += `Cook Islander.`; - break; + return `Cook Islander.`; case "a Liechtensteiner": - r += `Liechtensteiner.`; - break; + return `Liechtensteiner.`; case "a New Zealander": - r += `New Zealander.`; - break; + return `New Zealander.`; case "a Solomon Islander": - r += `Solomon Islander.`; - break; + return `Solomon Islander.`; case "Zimbabwean": if (slave.race === "white") { - r += `Rhodesian.`; + return `Rhodesian.`; } else { - r += `${slave.nationality}.`; + return `${slave.nationality}.`; } - break; case "slave": case "none": case "": case "Stateless": - r += `Stateless.`; - break; + return `Stateless.`; default: - r += `${slave.nationality}.`; - break; + return `${slave.nationality}.`; } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @returns {string} */ function short_skin(slave) { - r += `<span class="pink">`; switch (slave.skin) { case "pure white": - r += `P. Whi`; - break; + return `P. Whi`; case "extremely fair": - r += `E. Fai`; - break; + return `E. Fai`; case "very fair": - r += `V. Fai`; - break; + return `V. Fai`; case "extremely pale": - r += `E. Pal`; - break; + return `E. Pal`; case "very pale": - r += `V. Pal`; - break; + return `V. Pal`; case "light brown": - r += `L. Br`; - break; + return `L. Br`; case "dark brown": - r += `D. Br`; - break; + return `D. Br`; case "light olive": - r += `L. Oli`; - break; + return `L. Oli`; case "dark olive": - r += `D. Oli`; - break; + return `D. Oli`; case "light beige": - r += `L. Bei`; - break; + return `L. Bei`; case "dark beige": - r += `D. Bei`; - break; + return `D. Bei`; case "tan": - r += `Tan`; - break; + return `Tan`; case "bronze": - r += `Bron`; - break; + return `Bron`; case "ebony": - r += `Ebon`; - break; + return `Ebon`; case "pure black": - r += `P. Bla`; - break; + return `P. Bla`; case "dark": case "fair": case "pale": - r += `${slave.skin.charAt(0).toUpperCase() + slave.skin.slice(1)}`; - break; + return `${slave.skin.charAt(0).toUpperCase() + slave.skin.slice(1)}`; default: - r += `${slave.skin.charAt(0).toUpperCase() + slave.skin.charAt(1) + slave.skin.charAt(2)}`; - break; + return `${slave.skin.charAt(0).toUpperCase() + slave.skin.charAt(1) + slave.skin.charAt(2)}`; } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_genitals(slave) { + function short_genitals(slave, c) { if (slave.dick > 0) { - r += `<span class="pink">`; + let dickDesc = ""; if (slave.balls === 0) { - r += `Geld`; + dickDesc += `Geld`; } if ((slave.dick > 8) && (slave.balls > 8)) { - r += `Junk+++`; + dickDesc += `Junk+++`; } else if ((slave.dick > 5) && (slave.balls > 5)) { - r += `Junk++`; + dickDesc += `Junk++`; } else if ((slave.dick > 4) && (slave.balls > 4)) { - r += `Junk+`; + dickDesc += `Junk+`; } else if ((slave.dick > 3) && (slave.balls > 3)) { - r += `Junk`; + dickDesc += `Junk`; } else if (slave.dick > 8) { - r += `Dick+++`; + dickDesc += `Dick+++`; } else if (slave.dick > 5) { - r += `Dick++`; + dickDesc += `Dick++`; } else if (slave.dick > 4) { - r += `Dick+`; + dickDesc += `Dick+`; } else if (slave.dick > 3) { - r += `Dick`; + dickDesc += `Dick`; } else if (slave.balls > 10) { - r += `Balls+++`; + dickDesc += `Balls+++`; } else if (slave.balls > 5) { - r += `Balls++`; + dickDesc += `Balls++`; } else if (slave.balls > 4) { - r += `Balls+`; + dickDesc += `Balls+`; } else if (slave.balls > 3) { - r += `Balls`; + dickDesc += `Balls`; + } + if (dickDesc.length) { + makeSpan(c, dickDesc, "pink"); } - r += `</span> `; } if (slave.vagina === 0) { - r += `<span class="lime">VV</span>`; + makeSpan(c, "VV", "lime"); } else if ((slave.pregKnown === 1) && canWalk(slave) && (slave.clothes === "no clothing" || slave.clothes === "body oil") && (slave.shoes === "none")) { - r += `<span class="pink">NBP</span>`; + makeSpan(c, "NBP", "pink"); } if (slave.anus === 0) { - r += ` <span class="lime">AV</span>`; + makeSpan(c, "AV", "lime"); } - r += `<span class="pink">`; + let holesDesc = ""; if ((slave.vagina > 3) && (slave.anus > 3)) { - r += ` V++A++`; + holesDesc += `V++A++`; } else if ((slave.vagina > 2) && (slave.anus > 2)) { - r += ` V+A+`; + holesDesc += `V+A+`; } else if (slave.vagina > 3) { - r += ` V++`; + holesDesc += `V++`; } else if (slave.vagina > 2) { - r += ` V+`; + holesDesc += `V+`; } else if (slave.anus > 3) { - r += ` A++`; + holesDesc += `A++`; } else if (slave.anus > 2) { - r += ` A+`; + holesDesc += `A+`; + } + if (holesDesc.length) { + makeSpan(c, holesDesc, "pink"); } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_genitals(slave) { + function long_genitals(slave, c) { if (slave.dick > 0) { - r += `<span class="pink">`; + let dickDesc = ""; if (slave.balls === 0) { - r += `Gelded.`; + dickDesc += 'Gelded.'; } if ((slave.dick > 8) && (slave.balls > 8)) { - r += `Hyper dick & balls.`; + dickDesc += `Hyper dick & balls.`; } else if ((slave.dick > 5) && (slave.balls > 5)) { - r += `Monster dick & balls.`; + dickDesc += `Monster dick & balls.`; } else if ((slave.dick > 4) && (slave.balls > 4)) { - r += `Huge dick & balls.`; + dickDesc = `Huge dick & balls.`; } else if ((slave.dick > 3) && (slave.balls > 3)) { - r += `Big dick & balls.`; + dickDesc = `Big dick & balls.`; } else if (slave.dick > 8) { - r += `Hyper dong.`; + dickDesc = `Hyper dong.`; } else if (slave.dick > 5) { - r += `Monster dong.`; + dickDesc = `Monster dong.`; } else if (slave.dick > 4) { - r += `Huge dick.`; + dickDesc = `Huge dick.`; } else if (slave.dick > 3) { - r += `Big dick.`; + dickDesc = `Big dick.`; } else if (slave.balls > 8) { - r += `Hyper balls.`; + dickDesc = `Hyper balls.`; } else if (slave.balls > 5) { - r += `Monstrous balls.`; + dickDesc = `Monstrous balls.`; } else if (slave.balls > 4) { - r += `Huge balls.`; + dickDesc = `Huge balls.`; } else if (slave.balls > 3) { - r += `Big balls.`; + dickDesc = `Big balls.`; + } + if (dickDesc.length) { + makeSpan(c, dickDesc, "pink"); } - r += `</span> `; } if (slave.vagina === 0) { - r += `<span class="lime">Virgin.</span> `; + makeSpan(c, "Virgin.", "lime"); } else if ((slave.pregKnown === 1) && canWalk(slave) && (slave.clothes === "no clothing" || slave.clothes === "body oil") && (slave.shoes === "none")) { - r += `<span class="pink">Naked, barefoot, and pregnant.</span> `; + makeSpan(c, "Naked, barefoot, and pregnant.", "pink"); } if (slave.anus === 0) { - r += `<span class="lime">Anal virgin.</span> `; + makeSpan(c, "Anal virgin.", "lime"); } - r += `<span class="pink">`; + let holesDesc = ""; if ((slave.vagina > 3) && (slave.anus > 3)) { - r += `Blown out holes.`; + holesDesc += `Blown out holes.`; } else if ((slave.vagina > 2) && (slave.anus > 2)) { - r += `High mileage.`; + holesDesc += `High mileage.`; } else if (slave.vagina > 3) { - r += `Cavernous pussy.`; + holesDesc += `Cavernous pussy.`; } else if (slave.vagina > 2) { - r += `Loose pussy.`; + holesDesc += `Loose pussy.`; } else if (slave.anus > 3) { - r += `Permagaped anus.`; + holesDesc += `Permagaped anus.`; } else if (slave.anus > 2) { - r += `Gaping anus.`; + holesDesc += `Gaping anus.`; + } + if (holesDesc.length) { + makeSpan(c, holesDesc, "pink"); } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_age(slave) { - r += `<span class="pink">`; + function short_age(slave, c) { + let r = makeSpan(c, "", "pink"); if (V.showAgeDetail === 1) { - r += slave.actualAge; + r.textContent += slave.actualAge.toString(); } else if (slave.actualAge >= 40) { - r += `40s`; + r.textContent += "40s"; } else if (slave.actualAge >= 35) { - r += `Lt30s`; + r.textContent += "Lt30s"; } else if (slave.actualAge >= 30) { - r += `Ea30s`; + r.textContent += "Ea30s"; } else if (slave.actualAge >= 25) { - r += `Lt20s`; + r.textContent += "Lt20s"; } else if (slave.actualAge >= 20) { - r += `Ea20s`; + r.textContent += "Ea20s"; } else if (slave.actualAge >= 18) { - r += slave.actualAge; + r.textContent += slave.actualAge.toString(); } if (slave.actualAge !== slave.physicalAge) { - r += ` w ${slave.physicalAge}y-bdy`; + r.textContent += ` w ${slave.physicalAge}y-bdy`; } if (slave.visualAge !== slave.physicalAge) { - r += ` Lks${slave.visualAge}`; + r.textContent += ` Lks${slave.visualAge}`; } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_face(slave) { + function short_face(slave, c) { if (slave.face < -95) { - r += `<span class="red">Face---${V.summaryStats? `[${slave.face}]` : ''}</span>`; + makeSpan(c, "Face---", "red", true, slave.face); } else if (slave.face < -40) { - r += `<span class="red">Face--${V.summaryStats? `[${slave.face}]` : ''}</span>`; + makeSpan(c, "Face--", "red", true, slave.face); } else if (slave.face < -10) { - r += `<span class="red">Face-${V.summaryStats? `[${slave.face}]` : ''}</span>`; + makeSpan(c, "Face-", "red", true, slave.face); } else if (slave.face <= 10) { - r += `Face${V.summaryStats? `[${slave.face}]` : ''}`; + makeSpan(c, "Face", null, true, slave.face); } else if (slave.face <= 40) { - r += `<span class="pink">Face+${V.summaryStats? `[${slave.face}]` : ''}</span>`; + makeSpan(c, "Face+", "pink", true, slave.face); } else if (slave.face <= 95) { - r += `<span class="pink">Face++${V.summaryStats? `[${slave.face}]` : ''}</span>`; + makeSpan(c, "Face++", "pink", true, slave.face); } else { - r += `<span class="pink">Face+++${V.summaryStats? `[${slave.face}]` : ''}</span>`; + makeSpan(c, "Face+++", "pink", true, slave.face); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_eyes(slave) { - if (slave.eyes <= -2) { - r += `<span class="red">Blind</span>`; + function short_eyes(slave, c) { + if (slave.eyes === -2) { + makeSpan(c, "Blind", "red"); } else if (((slave.eyes === -1) && (slave.eyewear !== "corrective glasses") && (slave.eyewear !== "corrective contacts")) || (slave.eyewear === "blurring glasses") || (slave.eyewear === "blurring contacts")) { - r += `<span class="yellow">Sight-</span>`; + makeSpan(c, "Sight-", "yellow"); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_ears(slave) { + function short_ears(slave, c) { if (slave.hears === -2) { - r += `<span class="red">Deaf</span>`; + makeSpan(c, "Deaf", "red"); } else if ((slave.hears === -1) && (slave.earwear !== "hearing aids")) { - r += `<span class="yellow">Hearing-</span>`; + makeSpan(c, "Hearing-", "yellow"); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_lips(slave) { + function short_lips(slave, c) { if (slave.lips > 95) { - r += `Facepussy`; + makeSpan(c, "Facepussy"); } else if (slave.lips > 70) { - r += `Lips+++${V.summaryStats? `[${slave.lips}]` : ''}`; + makeSpan(c, "Lips+++", null, true, slave.lips); } else if (slave.lips > 40) { - r += `Lips++${V.summaryStats? `[${slave.lips}]` : ''}`; + makeSpan(c, "Lips++", null, true, slave.lips); } else if (slave.lips > 20) { - r += `Lips+${V.summaryStats? `[${slave.lips}]` : ''}`; + makeSpan(c, "Lips+", null, true, slave.lips); } else if (slave.lips > 10) { - r += `Lips${V.summaryStats? `[${slave.lips}]` : ''}`; + makeSpan(c, "Lips", null, true, slave.lips); } else { - r += `<span class="red">Lips-${V.summaryStats? `[${slave.lips}]` : ''}</span>`; + makeSpan(c, "Lips-", "red", true, slave.lips); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_teeth(slave) { + function short_teeth(slave, c) { if (slave.teeth === "crooked") { - r += `<span class="yellow">Cr Teeth</span>`; + makeSpan(c, "Cr Teeth", "yellow"); } else if (slave.teeth === "gapped") { - r += `<span class="yellow">Gap</span>`; + makeSpan(c, "Gap", "yellow"); } else if (slave.teeth === "cosmetic braces") { - r += `Cos Braces`; + makeSpan(c, `Cos Braces`); } else if (slave.teeth === "straightening braces") { - r += `Braces`; + makeSpan(c, `Braces`); } else if (slave.teeth === "removable") { - r += `Rem Teeth`; + makeSpan(c, `Rem Teeth`); } else if (slave.teeth === "pointy") { - r += `Fangs`; + makeSpan(c, `Fangs`); } else if (slave.teeth === "baby") { - r += `Baby`; + makeSpan(c, `Baby`); } else if (slave.teeth === "mixed") { - r += `Mixed`; + makeSpan(c, `Mixed`); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_muscles(slave) { + function short_muscles(slave, c) { if (slave.muscles > 95) { - r += `Musc++${V.summaryStats? `[${slave.muscles}]`: ''}`; + makeSpan(c, "Musc++", undefined, true, slave.muscles); } else if (slave.muscles > 50) { - r += `Musc+${V.summaryStats? `[${slave.muscles}]`: ''}`; + makeSpan(c, "Musc+", undefined, true, slave.muscles); } else if (slave.muscles > 5) { - r += `Fit${V.summaryStats? `[${slave.muscles}]`: ''}`; + makeSpan(c, "Fit", undefined, true, slave.muscles); } else if (slave.muscles > -6) { - r += `Soft${V.summaryStats? `[${slave.muscles}]`: ''}`; + makeSpan(c, "Soft", undefined, true, slave.muscles); } else if (slave.muscles > -31) { if (V.arcologies[0].FSPhysicalIdealist === "unset") { - r += `<span class="red">Weak</span>${V.summaryStats? `[${slave.muscles}]`: ''}`; + makeSpan(c, "Weak", "red", true, slave.muscles); } else { - r += `Soft${V.summaryStats? `[${slave.muscles}]`: ''}`; + makeSpan(c, "Soft", undefined, true, slave.muscles); } } else if (slave.muscles > -96) { if (V.arcologies[0].FSPhysicalIdealist === "unset") { - r += `<span class="red">Weak+</span>${V.summaryStats? `[${slave.muscles}]`: ''}`; + makeSpan(c, "Weak+", "red", true, slave.muscles); } else { - r += `Soft+${V.summaryStats? `[${slave.muscles}]`: ''}`; + makeSpan(c, "Soft+", undefined, true, slave.muscles); } } else { - r += `<span class="red">Weak++</span>${V.summaryStats? `[${slave.muscles}]`: ''}`; + makeSpan(c, "Weak++", "red", true, slave.muscles); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_limbs(slave) { + function short_limbs(slave, c) { if (slave.amp !== 0) { if (slave.amp === -1) { - r += `P-Limbs`; + addText(c, "P-Limbs"); } else if (slave.amp === -2) { - r += `Sex P-Limbs`; + addText(c, "Sex P-Limbs"); } else if (slave.amp === -3) { - r += `Beauty P-Limbs`; + addText(c, "Beauty P-Limbs"); } else if (slave.amp === -4) { - r += `Combat P-Limbs`; + addText(c, "Combat P-Limbs"); } else if (slave.amp === -5) { - r += `Cyber P-Limbs`; + addText(c, "Cyber P-Limbs"); } else { - r += `Amp`; + addText(c, "Amp"); } } - r += " "; + addText(c, " "); if (!canWalk(slave)) { - r += ` Immob `; + addText(c, " Immob "); } if (slave.heels === 1) { - r += ` Heel `; + addText(c, " Heel "); } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_voice(slave) { + function short_voice(slave, c) { if (slave.voice === 0) { - r += `<span class="red">Mute</span>`; + makeSpan(c, "Mute", "red"); } else { if (slave.accent === 3) { - r += `<span class="red">Acc--</span>`; + makeSpan(c, "Acc--", "red"); } else if (slave.accent === 2) { - r += `Acc-`; + makeSpan(c, "Acc-"); } else if (slave.accent === 4) { - r += `Acc--`; + makeSpan(c, "Acc--"); } else if (slave.accent === 1) { - r += `<span class="pink">Acc</span>`; + makeSpan(c, "Acc", "pink"); } } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_tits_ass(slave) { - r += `<span class="pink">`; + function short_tits_ass(slave, c) { + let styles = "pink"; if ((slave.boobs >= 12000) && (slave.butt > 9)) { - r += `T&A+++`; + makeSpan(c, "T&A+++", styles); } else if ((slave.boobs > 4000) && (slave.butt > 8)) { - r += `T&A++`; + makeSpan(c, "T&A++", styles); } else if ((slave.boobs > 2000) && (slave.butt > 6)) { - r += `T&A+`; + makeSpan(c, "T&A+", styles); } else if ((slave.boobs > 800) && (slave.butt > 4)) { - r += `T&A`; + makeSpan(c, "T&A", styles); } else if ((slave.boobs < 500) && (slave.butt < 3) && (slave.weight <= 10) && (slave.muscles <= 30)) { - r += `Girlish`; + makeSpan(c, "Girlish", styles); } else if (slave.boobs >= 12000) { - r += `Boobs+++`; + makeSpan(c, "Boobs+++", styles); } else if (slave.boobs > 4000) { - r += `Boobs++`; + makeSpan(c, "Boobs++", styles); } else if (slave.boobs > 2000) { - r += `Boobs+`; + makeSpan(c, "Boobs+", styles); } else if (slave.boobs > 800) { - r += `Boobs`; + makeSpan(c, "Boobs", styles); } else if (slave.butt > 9) { - r += `Ass+++`; + makeSpan(c, "Ass+++", styles); } else if (slave.butt > 8) { - r += `Ass++`; + makeSpan(c, "Ass++", styles); } else if (slave.butt > 6) { - r += `Ass+`; + makeSpan(c, "Ass+", styles); } else if (slave.butt > 4) { - r += `Ass`; + makeSpan(c, "Ass", styles); } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_hips(slave) { - r += `<span class="red">`; + function short_hips(slave, c) { + let desc = ""; if (slave.hips < -1) { if (slave.butt > 2 && (V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { - r += `Disp+`; + desc = `Disp+`; } } else if (slave.hips < 0) { if (slave.butt > 4 && (V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { - r += `Disp+`; + desc = `Disp+`; } } else if (slave.hips > 2) { if (slave.butt <= 8) { - r += `Disp-`; + desc = `Disp-`; } } else if (slave.hips > 1) { if (slave.butt <= 3 && (V.arcologies[0].FSSlimnessEnthusiast === "unset" || (slave.boobs >= 500))) { - r += `Disp-`; + desc = `Disp-`; } } else if (slave.hips > 0) { if (slave.butt > 8) { if ((V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { - r += `Disp+`; + desc = `Disp+`; } } else if (slave.butt <= 2 && (V.arcologies[0].FSSlimnessEnthusiast === "unset" || (slave.boobs >= 500))) { - r += `Disp-`; + desc = `Disp-`; } } else { if (slave.butt > 6) { if ((V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset")) { - r += `Disp+`; + desc = `Disp+`; } } else if (slave.butt <= 1 && (V.arcologies[0].FSSlimnessEnthusiast === "unset" || (slave.boobs >= 500))) { - r += `Disp-`; + desc = `Disp-`; } } - r += `</span> `; + if (desc) { + makeSpan(c, desc, "red"); + } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_waist(slave) { + function short_waist(slave, c) { if (slave.waist > 95) { - r += `<span class="red">Wst---${V.summaryStats? `[${slave.waist}]` : ''}</span>`; + makeSpan(c, "Wst---", "red", false, slave.waist); } else if (slave.waist > 40) { - r += `<span class="red">Wst--${V.summaryStats? `[${slave.waist}]`: ''}</span>`; + makeSpan(c, "Wst--", "red", false, slave.waist); } else if (slave.waist > 10) { - r += `<span class="red">Wst-${V.summaryStats? `[${slave.waist}]` : ''}</span>`; + makeSpan(c, "Wst-", "red", false, slave.waist); } else if (slave.waist >= -10) { - r += `Wst${V.summaryStats? `[${slave.waist}]`: ''}`; + makeSpan(c, "Wst", undefined, false, slave.waist); } else if (slave.waist >= -40) { - r += `<span class="pink">Wst+${V.summaryStats? `[${slave.waist}]` : ''}</span>`; + makeSpan(c, "Wst+", "pink", false, slave.waist); } else if (slave.waist >= -95) { - r += `<span class="pink">Wst++${V.summaryStats? `[${slave.waist}]` : ''}</span>`; + makeSpan(c, "Wst++", "pink", false, slave.waist); } else { - r += `<span class="pink">Wst+++${V.summaryStats? `[${slave.waist}]`: ''}</span>`; + makeSpan(c, "Wst+++", "pink", false, slave.waist); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_implants(slave) { - r += `<span class="pink">`; + function short_implants(slave, c) { if ((slave.boobsImplant === 0) && (slave.buttImplant === 0) && (slave.waist >= -95) && (slave.lipsImplant === 0) && (slave.faceImplant <= 5) && (slave.bellyImplant === -1)) { - r += `Natr`; + makeSpan(c, "Natr", "pink"); } else { - r += `Impl`; + makeSpan(c, "Impl", "pink"); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_lactation(slave) { + function short_lactation(slave, c) { if (slave.lactation === 1) { - r += `Lact`; + makeSpan(c, "Lact", "pink"); } else if (slave.lactation === 2) { - r += `Lact++`; + makeSpan(c, "Lact", "pink"); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_mods(slave) { + function short_mods(slave, c) { V.modScore = SlaveStatsChecker.modScore(slave); if (slave.corsetPiercing === 0 && V.piercingScore < 3 && V.tatScore < 2) { return; } else if (V.modScore > 15 || (V.piercingScore > 8 && V.tatScore > 5)) { - r += `Mods++`; + makeSpan(c, "Mods++"); } else if (V.modScore > 7) { - r += `Mods+`; + makeSpan(c, "Mods+"); } else { - r += `Mods`; + makeSpan(c, "Mods"); } if (!jQuery.isEmptyObject(slave.brand)) { - r += `Br`; + makeSpan(c, "Br"); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_age(slave) { - r += `<span class="pink">`; + function long_age(slave, c) { + let r = makeSpan(c, "", "pink"); if (V.showAgeDetail === 1) { - r += `Age ` + `${slave.actualAge}` + `.`; + r.textContent += `Age ` + `${slave.actualAge}` + `.`; } else if (slave.actualAge >= 40) { - r += `Forties.`; + r.textContent += `Forties.`; } else if (slave.actualAge >= 35) { - r += `Late thirties.`; + r.textContent += `Late thirties.`; } else if (slave.actualAge >= 30) { - r += `Early thirties.`; + r.textContent += `Early thirties.`; } else if (slave.actualAge >= 25) { - r += `Late twenties.`; + r.textContent += `Late twenties.`; } else if (slave.actualAge >= 20) { - r += `Early twenties.`; + r.textContent += `Early twenties.`; } else if (slave.actualAge >= 19) { - r += `Nineteen.`; + r.textContent += `Nineteen.`; } else if (slave.actualAge >= 18) { - r += `Eighteen.`; + r.textContent += `Eighteen.`; } else { - r += `Underage.`; + r.textContent += `Underage.`; } - r += " "; + r.textContent += " "; /* ** No NCS, then do the standard, However because of the wrinkes of Incubators, as long as visual age is greater ** than or equal to physical age, we do the old physical body/Looks for fresh out of the can NCS slaves. */ if (((slave.geneMods.NCS === 0) || (slave.visualAge >= slave.physicalAge))) { if (slave.actualAge !== slave.physicalAge) { - r += `${slave.physicalAge}` + ` year old body. `; + r.textContent += `${slave.physicalAge}` + ` year old body. `; } if (slave.visualAge !== slave.physicalAge) { - r += `Looks ` + `${slave.visualAge}` + `. `; + r.textContent += `Looks ` + `${slave.visualAge}` + `. `; } } else { /* @@ -2465,1640 +2188,1580 @@ window.SlaveSummaryUncached = (function() { ** say: 'Age 1. 11 year old body.' -- this conflicts with the way NCS works though, because she hasn't ** visually aged, so our change here makes it say 'Age 1. Appears to have a 10 year old body.' */ - r += `Appears to have a ` + `${slave.visualAge}` + ` year old body. `; + r.textContent += `Appears to have a ` + `${slave.visualAge}` + ` year old body. `; } if (slave.geneMods.NCS === 1) { - r += `(<span class="orange">NCS</span>) `; + makeSpan(r, "NCS", "orange"); } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_face(slave) { + function long_face(slave, c) { if (slave.face < -95) { - r += `<span class="red">Very ugly${V.summaryStats? `[${slave.face}]`: ''}</span>`; + return makeSpan(c, `Very ugly ${slave.faceShape} face`, "red", true, slave.face); } else if (slave.face < -40) { - r += `<span class="red">Ugly${V.summaryStats? `[${slave.face}]`: ''}</span>`; + return makeSpan(c, `Ugly ${slave.faceShape} face`, "red", true, slave.face); } else if (slave.face < -10) { - r += `<span class="red">Unattractive${V.summaryStats? `[${slave.face}]`: ''}</span>`; + return makeSpan(c, `Unattractive ${slave.faceShape} face`, "red", true, slave.face); } else if (slave.face <= 10) { - r += `Average${V.summaryStats? `[${slave.face}]`: ''}`; + return makeSpan(c, `Average ${slave.faceShape} face`, null, true, slave.face); } else if (slave.face <= 40) { - r += `<span class="pink">Attractive${V.summaryStats? `[${slave.face}]`: ''}</span>`; + return makeSpan(c, `Attractive ${slave.faceShape} face`, "pink", true, slave.face); } else if (slave.face <= 95) { - r += `<span class="pink">Beautiful${V.summaryStats? `[${slave.face}]`: ''}</span>`; + return makeSpan(c, `Beautiful ${slave.faceShape} face`, "pink", true, slave.face); } else { - r += `<span class="pink">Very beautiful${V.summaryStats? `[${slave.face}]`: ''}</span>`; + return makeSpan(c, `Very beautiful ${slave.faceShape} face`, "pink", true, slave.face); } - r += ` ${slave.faceShape} face. `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_eyes(slave) { + function long_eyes(slave, c) { if (slave.eyes <= -2) { - r += `<span class="red">Blind.</span>`; + makeSpan(c, "Blind.", "red"); } else if (((slave.eyes === -1) && (slave.eyewear !== "corrective glasses") && (slave.eyewear !== "corrective contacts")) || (slave.eyewear === "blurring glasses") || (slave.eyewear === "blurring contacts")) { - r += `<span class="yellow">Nearsighted.</span>`; + makeSpan(c, "Nearsighted.", "yellow"); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_ears(slave) { + function long_ears(slave, c) { if (slave.hears <= -2) { - r += `<span class="red">Deaf.</span>`; + makeSpan(c, "Deaf.", "red"); } else if ((slave.hears === -1) && (slave.earwear !== "hearing aids")) { - r += `<span class="yellow">Hard of hearing.</span>`; + makeSpan(c, "Hard of hearing.", "yellow"); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_lips(slave) { + function long_lips(slave, c) { if (slave.lips > 95) { - r += `Facepussy${V.summaryStats? `[${slave.lips}]`: ''}.`; + makeSpan(c, "Facepussy", undefined, true, slave.lips); } else if (slave.lips > 70) { - r += `Huge lips${V.summaryStats? `[${slave.lips}]`: ''}.`; + makeSpan(c, "Huge lips", undefined, true, slave.lips); } else if (slave.lips > 40) { - r += `Big lips${V.summaryStats? `[${slave.lips}]`: ''}.`; + makeSpan(c, "Big lips", undefined, true, slave.lips); } else if (slave.lips > 20) { - r += `Pretty lips${V.summaryStats? `[${slave.lips}]`: ''}.`; + makeSpan(c, "Pretty lips", undefined, true, slave.lips); } else if (slave.lips > 10) { - r += `Normal lips${V.summaryStats? `[${slave.lips}]`: ''}.`; + makeSpan(c, "Normal lips", undefined, true, slave.lips); } else { - r += `<span class="red">Thin lips${V.summaryStats? `[${slave.lips}]`: ''}.</span>`; + makeSpan(c, "Thin lips", "red", true, slave.lips); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_teeth(slave) { + function long_teeth(slave, c) { if (slave.teeth === "crooked") { - r += `<span class="yellow">Crooked teeth.</span>`; + makeSpan(c, "Crooked teeth.", "yellow"); } else if (slave.teeth === "gapped") { - r += `<span class="yellow">Tooth gap.</span>`; + makeSpan(c, "Tooth gap.", "yellow"); } else if (slave.teeth === "cosmetic braces") { - r += `Cosmetic braces.`; + makeSpan(c, "Cosmetic braces."); } else if (slave.teeth === "straightening braces") { - r += `Braces.`; + makeSpan(c, "Braces."); } else if (slave.teeth === "removable") { - r += `Removable teeth.`; + makeSpan(c, "Removable teeth."); } else if (slave.teeth === "pointy") { - r += `Sharp fangs.`; + makeSpan(c, "Sharp fangs."); } else if (slave.teeth === "baby") { - r += `Baby teeth.`; + makeSpan(c, "Baby teeth."); } else if (slave.teeth === "mixed") { - r += `Mixed teeth.`; + makeSpan(c, "Mixed teeth."); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_muscles(slave) { + function long_muscles(slave, c) { if (slave.muscles > 95) { - r += `Hugely muscular${V.summaryStats? `[${slave.muscles}]` : ''}.`; + makeSpan(c, "Hugely muscular", undefined, true, slave.muscles); } else if (slave.muscles > 50) { - r += `Muscular${V.summaryStats? `[${slave.muscles}]`: ''}.`; + makeSpan(c, "Muscular", undefined, true, slave.muscles); } else if (slave.muscles > 5) { - r += `Fit${V.summaryStats? `[${slave.muscles}]`: ''}.`; + makeSpan(c, "Fit", undefined, true, slave.muscles); } else if (slave.muscles > -6) { - r += `Soft${V.summaryStats? `[${slave.muscles}]`: ''}.`; + makeSpan(c, "Soft", undefined, true, slave.muscles); } else if (slave.muscles > -31) { if (V.arcologies[0].FSPhysicalIdealist === "unset") { - r += `<span class="red">Weak${V.summaryStats? `[${slave.muscles}]`: ''}.</span>`; + makeSpan(c, "Weak", "red", true, slave.muscles); } else { - r += `Weak${V.summaryStats? `[${slave.muscles}]`: ''}.`; + makeSpan(c, "Weak", undefined, true, slave.muscles); } } else if (slave.muscles > -96) { if (V.arcologies[0].FSPhysicalIdealist === "unset") { - r += `<span class="red">Very weak${V.summaryStats? `[${slave.muscles}]`: ''}.</span>`; + makeSpan(c, "Very weak", "red", true, slave.muscles); } else { - r += `Very weak${V.summaryStats? `[${slave.muscles}]`: ''}.`; + makeSpan(c, "Very weak", undefined, true, slave.muscles); } } else { - r += `<span class="red">Frail${V.summaryStats? `[${slave.muscles}]`: ''}.</span>`; + makeSpan(c, "Frail", "red", true, slave.muscles); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_limbs(slave) { + function long_limbs(slave, c) { if (slave.amp !== 0) { if (slave.amp === -1) { - r += `Prosthetic limbs.`; + makeSpan(c, `Prosthetic limbs.`); } else if (slave.amp === -2) { - r += `Sexy prosthetic limbs.`; + makeSpan(c, `Sexy prosthetic limbs.`); } else if (slave.amp === -3) { - r += `Beautiful prosthetic limbs.`; + makeSpan(c, `Beautiful prosthetic limbs.`); } else if (slave.amp === -4) { - r += `Deadly prosthetic limbs.`; + makeSpan(c, `Deadly prosthetic limbs.`); } else if (slave.amp === -5) { - r += `Cyber prosthetic limbs.`; + makeSpan(c, `Cyber prosthetic limbs.`); } else { - r += `Amputee.`; + makeSpan(c, `Amputee.`); } } - r += " "; if (!canWalk(slave)) { - r += `Immobile. `; + makeSpan(c, "Immobile."); } if (slave.heels === 1) { - r += `Heeled. `; + makeSpan(c, "Heeled."); } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_voice(slave) { + function long_voice(slave, c) { if (slave.voice === 0) { - r += `<span class="red">Mute.</span>`; + makeSpan(c, "Mute.", "red"); } else { if (slave.accent === 3) { - r += `<span class="red">Bad accent.</span>`; + makeSpan(c, "Bad accent.", "red"); } else if (slave.accent === 4) { - r += `<span class="red">No language skills.</span>`; + makeSpan(c, "No language skills.", "red"); } else if (slave.accent === 2) { - r += `Accent.`; + makeSpan(c, "Accent."); } else if (slave.accent === 1) { - r += `<span class="pink">Cute accent.</span>`; + makeSpan(c, "Cute accent.", "pink"); } } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_tits_ass(slave) { - r += `<span class="pink">`; + function long_tits_ass(slave, c) { + const styles = "pink"; if ((slave.boobs >= 12000) && (slave.butt > 9)) { - r += `Hyper T&A.`; + makeSpan(c, "Hyper T&A.", styles); } else if ((slave.boobs > 4000) && (slave.butt > 8)) { - r += `Enormous T&A.`; + makeSpan(c, "Enormous T&A.", styles); } else if ((slave.boobs > 2000) && (slave.butt > 6)) { - r += `Huge T&A.`; + makeSpan(c, "Huge T&A.", styles); } else if ((slave.boobs > 800) && (slave.butt > 4)) { - r += `Big T&A.`; + makeSpan(c, "Big T&A.", styles); } else if ((slave.boobs < 500) && (slave.butt < 3) && (slave.weight <= 10) && (slave.muscles <= 30)) { - r += `Girlish figure.`; + makeSpan(c, "Girlish figure.", styles); } else if (slave.boobs >= 12000) { - r += `Immobilizing tits.`; + makeSpan(c, "Immobilizing tits.", styles); } else if (slave.boobs > 4000) { - r += `Monstrous tits.`; + makeSpan(c, "Monstrous tits.", styles); } else if (slave.boobs > 2000) { - r += `Huge tits.`; + makeSpan(c, "Huge tits.", styles); } else if (slave.boobs > 800) { - r += `Big tits.`; + makeSpan(c, "Big tits.", styles); } else if (slave.butt > 9) { - r += `Hyper ass.`; + makeSpan(c, "Hyper ass.", styles); } else if (slave.butt > 8) { - r += `Titanic ass.`; + makeSpan(c, "Titanic ass.", styles); } else if (slave.butt > 6) { - r += `Huge ass.`; + makeSpan(c, "Huge ass.", styles); } else if (slave.butt > 4) { - r += `Big ass.`; + makeSpan(c, "Big ass.", styles); } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_hips(slave) { - r += `<span class="red">`; + function long_hips(slave, c) { + const styles = "red"; if (slave.hips < -1) { if (slave.butt > 2 && (V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset") && (V.arcologies[0].FSAssetExpansionist < 20 || V.arcologies[0].FSAssetExpansionist === "unset")) { - r += `Disproportionately big butt.`; + makeSpan(c, "Disproportionately big butt.", styles); } } else if (slave.hips < 0) { if (slave.butt > 4 && (V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset") && (V.arcologies[0].FSAssetExpansionist < 20 || V.arcologies[0].FSAssetExpansionist === "unset")) { - r += `Disproportionately big butt.`; + makeSpan(c, "Disproportionately big butt.", styles); } } else if (slave.hips > 2) { if (slave.butt <= 8) { - r += `Disproportionately small butt.`; + makeSpan(c, "Disproportionately small butt.", styles); } } else if (slave.hips > 1) { if (slave.butt <= 3 && ((V.arcologies[0].FSSlimnessEnthusiast === "unset") || (slave.boobs >= 500))) { - r += `Disproportionately small butt.`; + makeSpan(c, "Disproportionately small butt.", styles); } } else if (slave.hips > 0) { if (slave.butt > 8) { if ((V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset") && (V.arcologies[0].FSAssetExpansionist < 20 || V.arcologies[0].FSAssetExpansionist === "unset")) { - r += `Disproportionately big butt.`; + makeSpan(c, "Disproportionately big butt.", styles); } } else if (slave.butt <= 2 && ((V.arcologies[0].FSSlimnessEnthusiast === "unset") || (slave.boobs >= 500))) { - r += `Disproportionately small butt.`; + makeSpan(c, "Disproportionately small butt.", styles); } } else { if (slave.butt > 6) { if ((V.arcologies[0].FSTransformationFetishist < 20 || V.arcologies[0].FSTransformationFetishist === "unset") && (V.arcologies[0].FSHedonisticDecadence < 20 || V.arcologies[0].FSHedonisticDecadence === "unset") && (V.arcologies[0].FSAssetExpansionist < 20 || V.arcologies[0].FSAssetExpansionist === "unset")) { - r += `Disproportionately big butt.`; + makeSpan(c, "Disproportionately big butt.", styles); } } else if (slave.butt <= 1 && ((V.arcologies[0].FSSlimnessEnthusiast === "unset") || (slave.boobs >= 500))) { - r += `Disproportionately small butt.`; + makeSpan(c, "Disproportionately small butt.", styles); } } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_waist(slave) { + function long_waist(slave, c) { if (slave.waist > 95) { - r += `<span class="red">Masculine waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; + makeSpan(c, "Masculine waist", "red", true, slave.waist); } else if (slave.waist > 40) { - r += `<span class="red">Ugly waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; + makeSpan(c, "Ugly waist", "red", true, slave.waist); } else if (slave.waist > 10) { - r += `<span class="red">Unattractive waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; + makeSpan(c, "Unattractive waist", "red", true, slave.waist); } else if (slave.waist >= -10) { - r += `Average waist${V.summaryStats? `[${slave.waist}]`: ''}.`; + makeSpan(c, "Average waist", null, true, slave.waist); } else if (slave.waist >= -40) { - r += `<span class="pink">Feminine waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; + makeSpan(c, "Feminine waist", "pink", true, slave.waist); } else if (slave.waist >= -95) { - r += `<span class="pink">Hourglass waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; + makeSpan(c, "Hourglass waist", "pink", true, slave.waist); } else { - r += `<span class="pink">Absurdly narrow waist${V.summaryStats? `[${slave.waist}]`: ''}.</span>`; + makeSpan(c, "Absurdly narrow waist", "pink", true, slave.waist); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_implants(slave) { - r += `<span class="pink">`; + function long_implants(slave, c) { + const styles = "pink"; if ((slave.boobsImplant !== 0) || (slave.buttImplant !== 0) || (slave.lipsImplant !== 0) || (slave.bellyImplant !== -1)) { - r += `Implants.`; + makeSpan(c, "Implants.", styles); } else if ((slave.faceImplant >= 30) || (slave.waist < -95)) { - r += `Surgery enhanced.`; + makeSpan(c, "Surgery enhanced.", styles); } else { - r += `All natural.`; + makeSpan(c, "All natural.", styles); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_lactation(slave) { + function long_lactation(slave, c) { if (slave.lactation === 1) { - r += `Lactating naturally.`; + makeSpan(c, "Lactating naturally.", "pink"); } else if (slave.lactation === 2) { - r += `Heavy lactation.`; + makeSpan(c, "Heavy lactation.", "pink"); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_mods(slave) { + function long_mods(slave, c) { V.modScore = SlaveStatsChecker.modScore(slave); if (slave.corsetPiercing === 0 && V.piercingScore < 3 && V.tatScore < 2) { return; } else if (V.modScore > 15 || (V.piercingScore > 8 && V.tatScore > 5)) { - r += `Extensive body mods.`; + makeSpan(c, "Extensive body mods."); } else if (V.modScore > 7) { - r += `Noticeable body mods.`; + makeSpan(c, "Noticeable body mods."); } else { - r += `Light body mods.`; + makeSpan(c, "Light body mods."); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_intelligence(slave) { + function short_intelligence(slave, c) { const intelligence = slave.intelligence + slave.intelligenceImplant; if (slave.fetish === "mindbroken") { return; - } else if (slave.intelligenceImplant >= 30) { - if (intelligence >= 130) { - r += `<span class="deepskyblue">I++++(e+)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence > 95) { - r += `<span class="deepskyblue">I+++(e+)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence > 50) { - r += `<span class="deepskyblue">I++(e+)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence > 15) { - r += `<span class="deepskyblue">I+(e+)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence >= -15) { - r += `I(e+)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}`; - } else if (intelligence >= -50) { - r += `<span class="orangered">I-(e+)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence >= -95) { - r += `<span class="orangered">I--(e+)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else { - r += `<span class="orangered">I---(e+)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } + } + let education = ""; + let naturalIntelligence = ""; + let styles = undefined; + if (slave.intelligenceImplant >= 30) { + education = "(e+)"; } else if (slave.intelligenceImplant >= 15) { - if (intelligence > 95) { - r += `<span class="deepskyblue">I+++(e)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence > 50) { - r += `<span class="deepskyblue">I++(e)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence > 15) { - r += `<span class="deepskyblue">I+(e)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence >= -15) { - r += `I(e)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}`; - } else if (intelligence >= -50) { - r += `<span class="orangered">I-(e)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence >= -95) { - r += `<span class="orangered">I--(e)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else { - r += `<span class="orangered">I---(e)${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } + education = "(e)"; + } + if (intelligence >= 130) { + naturalIntelligence = "I++++"; + styles = "deepskyblue"; + } else if (intelligence > 95) { + naturalIntelligence = "I+++"; + styles = "deepskyblue"; + } else if (intelligence > 50) { + naturalIntelligence = "I++"; + styles = "deepskyblue"; + } else if (intelligence > 15) { + naturalIntelligence = "I+"; + styles = "deepskyblue"; + } else if (intelligence >= -15) { + naturalIntelligence = "I"; + } else if (intelligence >= -50) { + naturalIntelligence = "I-"; + styles = "orangered"; + } else if (intelligence >= -95) { + naturalIntelligence = "I--"; + styles = "orangered"; } else { - if (intelligence > 95) { - r += `<span class="deepskyblue">I+++${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence > 50) { - r += `<span class="deepskyblue">I++${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence > 15) { - r += `<span class="deepskyblue">I+${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence >= -15) { - r += `I${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}`; - } else if (intelligence >= -50) { - r += `<span class="orangered">I-${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else if (intelligence >= -95) { - r += `<span class="orangered">I--${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } else { - r += `<span class="orangered">I---${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}</span>`; - } + naturalIntelligence = "I---"; + styles = "orangered"; } - r += " "; + makeSpan(c, `${naturalIntelligence}${education}`, styles, true, intelligence); } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_sex_skills(slave) { + function short_skills(slave, c) { let _SSkills = slave.skill.anal + slave.skill.oral; - r += `<span class="aquamarine">`; + let r = makeSpan(c, "", "aquamarine"); if (((_SSkills + slave.skill.whoring + slave.skill.entertainment) >= 400) && ((slave.vagina < 0) || (slave.skill.vaginal >= 100))) { - r += `MSS`; + r.textContent += `MSS`; } else { _SSkills += slave.skill.vaginal; _SSkills = Math.trunc(_SSkills); if (_SSkills > 180) { - r += `S++`; + r.textContent += `S++`; } else if ((_SSkills > 120) && (slave.vagina < 0)) { - r += `Sh++`; + r.textContent += `Sh++`; } else if (_SSkills > 90) { - r += `S+`; + r.textContent += `S+`; } else if (_SSkills > 30) { - r += `S`; + r.textContent += `S`; } else { - r += `S-`; + r.textContent += `S-`; } if (V.summaryStats) { - r += `[${_SSkills}] `; + r.textContent += `[${_SSkills}]`; } - r += " "; + r.textContent += " "; if (slave.skill.whoring >= 100) { - r += `W+++`; + r.textContent += `W+++`; } else if (slave.skill.whoring > 60) { - r += `W++`; + r.textContent += `W++`; } else if (slave.skill.whoring > 30) { - r += `W+`; + r.textContent += `W+`; } else if (slave.skill.whoring > 10) { - r += `W`; + r.textContent += `W`; } if (slave.skill.whoring > 10) { if (V.summaryStats) { - r += `[${slave.skill.whoring}] `; + r.textContent += `[${slave.skill.whoring}]`; } } - r += " "; + r.textContent += " "; if (slave.skill.entertainment >= 100) { - r += `E+++`; + r.textContent += `E+++`; } else if (slave.skill.entertainment > 60) { - r += `E++`; + r.textContent += `E++`; } else if (slave.skill.entertainment > 30) { - r += `E+`; + r.textContent += `E+`; } else if (slave.skill.entertainment > 10) { - r += `E`; + r.textContent += `E`; } if (slave.skill.entertainment > 10) { if (V.summaryStats) { - r += `[${slave.skill.entertainment}] `; + r.textContent += `[${slave.skill.entertainment}]`; } } } - r += " "; + if (slave.skill.combat > 0) { + r.textContent += " C"; + } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_prestige(slave) { + function short_prestige(slave, c) { if (slave.prestige > 0) { - r += `<span class="green">`; + const styles = "green"; if (slave.prestige > 2) { - r += `Prest++`; + makeSpan(c, "Prest++", styles); } else if (slave.prestige === 2) { - r += `Prest+`; + makeSpan(c, "Prest+", styles); } else if (slave.prestige === 1) { - r += `Prest`; + makeSpan(c, "Prest", styles); } - r += `</span> `; } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_porn_prestige(slave) { + function short_porn_prestige(slave, c) { if (slave.pornPrestige > 0) { - r += `<span class="green">`; + const styles = "green"; if (slave.pornPrestige > 2) { - r += `PPrest++`; + makeSpan(c, "PPrest++", styles); } else if (slave.pornPrestige === 2) { - r += `PPrest+`; + makeSpan(c, "PPrest+", styles); } else if (slave.pornPrestige === 1) { - r += `PPrest`; + makeSpan(c, "PPrest", styles); } - r += `</span> `; } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_intelligence(slave) { + function long_intelligence(slave, c) { const intelligence = slave.intelligence + slave.intelligenceImplant; if (slave.fetish === "mindbroken") { return; - } else if (slave.intelligenceImplant >= 30) { - if (intelligence >= 130) { - r += `<span class="deepskyblue">Genius${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence > 95) { - r += `<span class="deepskyblue">Brilliant, well educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence > 50) { - r += `<span class="deepskyblue">Very smart, well educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence > 15) { - r += `<span class="deepskyblue">Smart, well educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence >= -15) { - r += `Average intelligence, well educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.`; - } else if (intelligence >= -50) { - r += `<span class="orangered">Slow, well educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence >= -95) { - r += `<span class="orangered">Very slow, well educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else { - r += `<span class="orangered">Moronic, well educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } + } + let education = ""; + let naturalIntelligence = ""; + let styles = undefined; + if (slave.intelligenceImplant >= 30) { + education = ", well educated"; } else if (slave.intelligenceImplant >= 15) { - if (intelligence > 95) { - r += `<span class="deepskyblue">Brilliant, educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence > 50) { - r += `<span class="deepskyblue">Very smart, educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence > 15) { - r += `<span class="deepskyblue">Smart, educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence >= -15) { - r += `Average intelligence, educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.`; - } else if (intelligence >= -50) { - r += `<span class="orangered">Slow, educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence >= -95) { - r += `<span class="orangered">Very slow, educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else { - r += `<span class="orangered">Moronic, educated${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } + education = ", educated"; + } + if (intelligence >= 130) { + naturalIntelligence = "Genius"; + styles = "deepskyblue"; + } else if (intelligence > 95) { + naturalIntelligence = "Brilliant"; + styles = "deepskyblue"; + } else if (intelligence > 50) { + naturalIntelligence = "Very smart"; + styles = "deepskyblue"; + } else if (intelligence > 15) { + naturalIntelligence = "Smart"; + styles = "deepskyblue"; + } else if (intelligence >= -15) { + naturalIntelligence = "Average intelligence"; + } else if (intelligence >= -50) { + naturalIntelligence = "Slow"; + styles = "orangered"; + } else if (intelligence >= -95) { + naturalIntelligence = "Very slow"; + styles = "orangered"; } else { - if (intelligence > 95) { - r += `<span class="deepskyblue">Brilliant${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence > 50) { - r += `<span class="deepskyblue">Very smart${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence > 15) { - r += `<span class="deepskyblue">Smart${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence >= -15) { - r += `Average intelligence${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.`; - } else if (intelligence >= -50) { - r += `<span class="orangered">Slow${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else if (intelligence >= -95) { - r += `<span class="orangered">Very slow${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } else { - r += `<span class="orangered">Moronic${V.summaryStats ? `[${slave.intelligence+slave.intelligenceImplant}]` : ''}.</span>`; - } + naturalIntelligence = "Moronic"; + styles = "orangered"; } - r += " "; + makeSpan(c, `${naturalIntelligence}${education}`, styles, true, intelligence); } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_sex_skills(slave) { + function long_skills(slave, c) { let _SSkills = (slave.skill.anal + slave.skill.oral); - r += `<span class="aquamarine">`; if (((_SSkills + slave.skill.whoring + slave.skill.entertainment) >= 400) && ((slave.vagina < 0) || (slave.skill.vaginal >= 100))) { - r += `Masterful Sex Slave. `; + makeSpan(c, "Masterful Sex Slave.", "aquamarine"); } else { + let desc; _SSkills += slave.skill.vaginal; if (_SSkills > 180) { - r += `Sex master${V.summaryStats? `[${Math.trunc(_SSkills)}]`: ''}.`; + desc = "Sex master"; } else if ((_SSkills > 120) && (slave.vagina < 0)) { - r += `Masterful shemale${V.summaryStats? `[${Math.trunc(_SSkills)}]`: ''}.`; + desc = "Masterful shemale"; } else if (_SSkills > 90) { - r += `Sexual expert${V.summaryStats? `[${Math.trunc(_SSkills)}]`: ''}.`; + desc = "Sexual expert"; } else if (_SSkills > 30) { - r += `Sexually skilled${V.summaryStats? `[${Math.trunc(_SSkills)}]` : ''}.`; + desc = "Sexually skilled"; } else { - r += `Sexually unskilled${V.summaryStats? `[${Math.trunc(_SSkills)}]` : ''}.`; + desc = "Sexually unskilled"; + } + if (desc) { + makeSpan(c, desc, "aquamarine", true, Math.trunc(_SSkills)); + desc = ""; } - r += " "; if (slave.skill.whoring >= 100) { - r += `Masterful whore${V.summaryStats? `[${slave.skill.whoring}]`: ''}.`; + desc = "Masterful whore"; } else if (slave.skill.whoring >= 60) { - r += `Expert whore${V.summaryStats? `[${slave.skill.whoring}]`: ''}.`; + desc = "Expert whore"; } else if (slave.skill.whoring >= 30) { - r += `Skilled whore${V.summaryStats? `[${slave.skill.whoring}]`: ''}.`; + desc = "Skilled whore"; } else if (slave.skill.whoring >= 10) { - r += `Basic whore${V.summaryStats? `[${slave.skill.whoring}]`: ''}.`; + desc = "Basic whore"; + } + if (desc) { + makeSpan(c, desc, "aquamarine", true, slave.skill.whoring); + desc = ""; } - r += " "; if (slave.skill.entertainment >= 100) { - r += `Masterful entertainer${V.summaryStats? `[${slave.skill.entertainment}]`: ''}.`; + desc = "Masterful entertainer"; } else if (slave.skill.entertainment >= 60) { - r += `Expert entertainer${V.summaryStats? `[${slave.skill.entertainment}]`: ''}.`; + desc = "Expert entertainer"; } else if (slave.skill.entertainment >= 30) { - r += `Skilled entertainer${V.summaryStats? `[${slave.skill.entertainment}]`: ''}.`; + desc = "Skilled entertainer"; } else if (slave.skill.entertainment >= 10) { - r += `Basic entertainer${V.summaryStats? `[${slave.skill.entertainment}]`: ''}.`; + desc = "Basic entertainer"; } - r += " "; + if (desc) { + makeSpan(c, desc, "aquamarine", true, slave.skill.entertainment); + desc = ""; + } + } + if (slave.skill.combat > 0) { + makeSpan(c, "Trained fighter.", "aquamarine"); } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_prestige(slave) { + function long_prestige(slave, c) { if (slave.prestige > 0) { - r += `<span class="green">`; + const styles = "green"; if (slave.prestige > 2) { - r += `Extremely prestigious.`; + makeSpan(c, "Extremely prestigious.", styles); } else if (slave.prestige === 2) { - r += `Very prestigious.`; + makeSpan(c, "Very prestigious.", styles); } else if (slave.prestige === 1) { - r += `Prestigious.`; + makeSpan(c, "Prestigious.", styles); } - r += `</span> `; } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_porn_prestige(slave) { + function long_porn_prestige(slave, c) { if (slave.pornPrestige > 0) { - r += `<span class="green">`; + const styles = "green"; if (slave.pornPrestige > 2) { - r += `Porn star.`; + makeSpan(c, "Porn star.", styles); } else if (slave.pornPrestige === 2) { - r += `Porn slut.`; + makeSpan(c, "Porn slut.", styles); } else if (slave.pornPrestige === 1) { - r += `Porn amateur.`; + makeSpan(c, "Porn amateur.", styles); } - r += `</span> `; } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_fetish(slave) { - r += `<span class="lightcoral">`; + function short_fetish(slave, c) { + let descStr = ""; switch (slave.fetish) { case "submissive": if (slave.fetishStrength > 95) { - r += `Sub++`; + descStr = `Sub++`; } else if (slave.fetishStrength > 60) { - r += `Sub+`; + descStr = `Sub+`; } else { - r += `Sub`; + descStr = `Sub`; } break; case "cumslut": if (slave.fetishStrength > 95) { - r += `Oral++`; + descStr = `Oral++`; } else if (slave.fetishStrength > 60) { - r += `Oral+`; + descStr = `Oral+`; } else { - r += `Oral`; + descStr = `Oral`; } break; case "humiliation": if (slave.fetishStrength > 95) { - r += `Humil++`; + descStr = `Humil++`; } else if (slave.fetishStrength > 60) { - r += `Humil+`; + descStr = `Humil+`; } else { - r += `Humil`; + descStr = `Humil`; } break; case "buttslut": if (slave.fetishStrength > 95) { - r += `Anal++`; + descStr = `Anal++`; } else if (slave.fetishStrength > 60) { - r += `Anal+`; + descStr = `Anal+`; } else { - r += `Anal`; + descStr = `Anal`; } break; case "boobs": if (slave.fetishStrength > 95) { - r += `Boobs++`; + descStr = `Boobs++`; } else if (slave.fetishStrength > 60) { - r += `Boobs+`; + descStr = `Boobs+`; } else { - r += `Boobs`; + descStr = `Boobs`; } break; case "sadist": if (slave.fetishStrength > 95) { - r += `Sadist++`; + descStr = `Sadist++`; } else if (slave.fetishStrength > 60) { - r += `Sadist+`; + descStr = `Sadist+`; } else { - r += `Sadist`; + descStr = `Sadist`; } break; case "masochist": if (slave.fetishStrength > 95) { - r += `Pain++`; + descStr = `Pain++`; } else if (slave.fetishStrength > 60) { - r += `Pain+`; + descStr = `Pain+`; } else { - r += `Pain`; + descStr = `Pain`; } break; case "dom": if (slave.fetishStrength > 95) { - r += `Dom++`; + descStr = `Dom++`; } else if (slave.fetishStrength > 60) { - r += `Dom+`; + descStr = `Dom+`; } else { - r += `Dom`; + descStr = `Dom`; } break; case "pregnancy": if (slave.fetishStrength > 95) { - r += `Preg++`; + descStr = `Preg++`; } else if (slave.fetishStrength > 60) { - r += `Preg+`; + descStr = `Preg+`; } else { - r += `Preg`; + descStr = `Preg`; } break; default: - r += `Vanilla`; + descStr = `Vanilla`; break; } if (V.summaryStats) { - r += `[${slave.fetishStrength}]`; + descStr += `[${slave.fetishStrength}]`; } - r += `</span> `; + makeSpan(c, descStr, "lightcoral"); } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_attraction(slave) { + function short_attraction(slave, c) { if (slave.attrXY <= 5) { - r += `<span class="red">XY---${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; + makeSpan(c, "XY---", "red", false, slave.attrXY); } else if (slave.attrXY <= 15) { - r += `<span class="red">XY--${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; + makeSpan(c, "XY--", "red", false, slave.attrXY); } else if (slave.attrXY <= 35) { - r += `<span class="red">XY-${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; + makeSpan(c, "XY---", "red", false, slave.attrXY); } else if (slave.attrXY <= 65) { - r += `XY${V.summaryStats? `[${slave.attrXY}]`: ''}`; + makeSpan(c, "XY", undefined, false, slave.attrXY); } else if (slave.attrXY <= 85) { - r += `<span class="green">XY+${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; + makeSpan(c, "XY+", "green", false, slave.attrXY); } else if (slave.attrXY <= 95) { - r += `<span class="green">XY++${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; + makeSpan(c, "XY++", "green", false, slave.attrXY); } else if (slave.attrXX > 95) { if (slave.energy <= 95) { - r += `<span class="green">Omni!</span>`; + makeSpan(c, "Omni!", "green"); } else { - r += `<span class="green">Omni+Nympho!!</span>`; + makeSpan(c, "Omni+Nympho!!", "green"); } } else { - r += `<span class="green">XY+++${V.summaryStats? `[${slave.attrXY}]`: ''}</span>`; + makeSpan(c, "XY+++", "green", false, slave.attrXY); } - r += " "; if (slave.attrXX <= 5) { - r += `<span class="red">XX---${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; + makeSpan(c, "XX---", "red", false, slave.attrXX); } else if (slave.attrXX <= 15) { - r += `<span class="red">XX--${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; + makeSpan(c, "XX--", "red", false, slave.attrXX); } else if (slave.attrXX <= 35) { - r += `<span class="red">XX-${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; + makeSpan(c, "XX-", "red", false, slave.attrXX); } else if (slave.attrXX <= 65) { - r += `XX${V.summaryStats? `[${slave.attrXX}]`: ''}`; + makeSpan(c, "XX", undefined, false, slave.attrXX); } else if (slave.attrXX <= 85) { - r += `<span class="green">XX+${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; + makeSpan(c, "XX+", "green", false, slave.attrXX); } else if (slave.attrXX <= 95) { - r += `<span class="green">XX++${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; + makeSpan(c, "XX++", "green", false, slave.attrXX); } else if (slave.attrXY <= 95) { - r += `<span class="green">XX+++${V.summaryStats? `[${slave.attrXX}]`: ''}</span>`; + makeSpan(c, "XX+++", "green", false, slave.attrXX); } - r += " "; if (slave.energy > 95) { if ((slave.attrXY <= 95) || (slave.attrXX <= 95)) { - r += `<span class="green">Nympho!</span>`; + makeSpan(c, "Nympho!", "green"); } } else if (slave.energy > 80) { - r += `<span class="green">SD++${V.summaryStats? `[${slave.energy}]`: ''}</span>`; + makeSpan(c, "SD++", "green", false, slave.energy); } else if (slave.energy > 60) { - r += `<span class="green">SD+${V.summaryStats? `[${slave.energy}]`: ''}</span>`; + makeSpan(c, "SD+", "green", false, slave.energy); } else if (slave.energy > 40) { - r += `<span class="yellow">SD${V.summaryStats? `[${slave.energy}]`: ''}</span>`; + makeSpan(c, "SD", "green", false, slave.energy); } else if (slave.energy > 20) { - r += `<span class="red">SD-${V.summaryStats? `[${slave.energy}]`: ''}</span>`; + makeSpan(c, "SD-", "red", false, slave.energy); } else { - r += `<span class="red">SD--${V.summaryStats? `[${slave.energy}]`: ''}</span>`; + makeSpan(c, "SD--", "red", false, slave.energy); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_smart_fetish(slave) { - if (slave.fetishKnown === 1) { - if (slave.clitSetting === "off") { - r += `SP-`; - } else if (((slave.fetish !== "submissive") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "submissive")) { - r += `SP:sub`; - } else if (((slave.fetish !== "cumslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "oral")) { - r += `SP:oral`; - } else if (((slave.fetish !== "humiliation") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "humiliation")) { - r += `SP:humil`; - } else if (((slave.fetish !== "buttslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "anal")) { - r += `SP:anal`; - } else if (((slave.fetish !== "boobs") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "boobs")) { - r += `SP:boobs`; - } else if (((slave.fetish !== "sadist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "sadist")) { - r += `SP:sade`; - } else if (((slave.fetish !== "masochist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "masochist")) { - r += `SP:pain`; - } else if (((slave.fetish !== "dom") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "dom")) { - r += `SP:dom`; - } else if (((slave.fetish !== "pregnancy") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "pregnancy")) { - r += `SP:preg`; - } else if (((slave.fetish !== "none") && (slave.clitSetting === "vanilla"))) { - r += `SP:vanilla`; - } else if ((slave.energy <= 95) && (slave.clitSetting === "all")) { - r += `SP:all`; - } else if ((slave.energy > 5) && (slave.clitSetting === "none")) { - r += `SP:none`; - } else if (!["anti-men", "anti-women", "men", "women"].includes(slave.clitSetting)) { - r += `SP:monitoring`; - } - } else { - switch (slave.clitSetting) { - case "off": - r += `SP-`; - break; - case "submissive": - r += `SP:sub`; - break; - case "lesbian": - r += `SP:les`; - break; - case "oral": - r += `SP:oral`; - break; - case "humiliation": - r += `SP:humil`; - break; - case "anal": - r += `SP:anal`; - break; - case "boobs": - r += `SP:boobs`; - break; - case "sadist": - r += `SP:sade`; - break; - case "masochist": - r += `SP:pain`; - break; - case "dom": - r += `SP:dom`; - break; - case "pregnancy": - r += `SP:pregnancy`; - break; - case "vanilla": - r += `SP:vanilla`; - break; - case "all": - r += `SP:all`; - break; - case "none": - r += `SP:none`; - break; + function short_smart_fetish(slave, c) { + function settingStr() { + if (slave.fetishKnown === 1) { + if (slave.clitSetting === "off") { + return `SP-`; + } else if (((slave.fetish !== "submissive") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "submissive")) { + return `SP:sub`; + } else if (((slave.fetish !== "cumslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "oral")) { + return `SP:oral`; + } else if (((slave.fetish !== "humiliation") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "humiliation")) { + return `SP:humil`; + } else if (((slave.fetish !== "buttslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "anal")) { + return `SP:anal`; + } else if (((slave.fetish !== "boobs") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "boobs")) { + return `SP:boobs`; + } else if (((slave.fetish !== "sadist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "sadist")) { + return `SP:sade`; + } else if (((slave.fetish !== "masochist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "masochist")) { + return `SP:pain`; + } else if (((slave.fetish !== "dom") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "dom")) { + return `SP:dom`; + } else if (((slave.fetish !== "pregnancy") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "pregnancy")) { + return `SP:preg`; + } else if (((slave.fetish !== "none") && (slave.clitSetting === "vanilla"))) { + return `SP:vanilla`; + } else if ((slave.energy <= 95) && (slave.clitSetting === "all")) { + return `SP:all`; + } else if ((slave.energy > 5) && (slave.clitSetting === "none")) { + return `SP:none`; + } else if (!["anti-men", "anti-women", "men", "women"].includes(slave.clitSetting)) { + return `SP:monitoring`; + } + } else { + switch (slave.clitSetting) { + case "off": + return `SP-`; + case "submissive": + return `SP:sub`; + case "lesbian": + return `SP:les`; + case "oral": + return `SP:oral`; + case "humiliation": + return `SP:humil`; + case "anal": + return `SP:anal`; + case "boobs": + return `SP:boobs`; + case "sadist": + return `SP:sade`; + case "masochist": + return `SP:pain`; + case "dom": + return `SP:dom`; + case "pregnancy": + return `SP:pregnancy`; + case "vanilla": + return `SP:vanilla`; + case "all": + return `SP:all`; + case "none": + return `SP:none`; + } } + return null; + } + const s = settingStr(); + if (s) { + makeSpan(c, settingStr()); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_smart_attraction(slave) { - if (slave.attrKnown === 1) { - if (slave.clitSetting === "women") { - if (slave.attrXX < 95) { - r += `SP:women`; - } else { - r += `SP:monitoring`; - } - } else if (slave.clitSetting === "men") { - if (slave.attrXY < 95) { - r += `SP:men`; - } else { - r += `SP:monitoring`; + function short_smart_attraction(slave, c) { + function settingStr() { + if (slave.attrKnown === 1) { + if (slave.clitSetting === "women") { + if (slave.attrXX < 95) { + return `SP:women`; + } else { + return `SP:monitoring`; + } + } else if (slave.clitSetting === "men") { + if (slave.attrXY < 95) { + return `SP:men`; + } else { + return `SP:monitoring`; + } + } else if (slave.clitSetting === "anti-women") { + if (slave.attrXX > 0) { + return `SP:anti-women`; + } else { + return `SP:monitoring`; + } + } else if (slave.clitSetting === "anti-men") { + if (slave.attrXY > 0) { + return `SP:anti-men`; + } else { + return `SP:monitoring`; + } } - } else if (slave.clitSetting === "anti-women") { - if (slave.attrXX > 0) { - r += `SP:anti-women`; - } else { - r += `SP:monitoring`; - } - } else if (slave.clitSetting === "anti-men") { - if (slave.attrXY > 0) { - r += `SP:anti-men`; - } else { - r += `SP:monitoring`; + } else { + if (slave.clitSetting === "women") { + return `SP:women`; + } else if (slave.clitSetting === "men") { + return `SP:men`; + } else if (slave.clitSetting === "anti-women") { + return `SP:anti-women`; + } else if (slave.clitSetting === "anti-men") { + return `SP:anti-men`; } } - } else { - if (slave.clitSetting === "women") { - r += `SP:women`; - } else if (slave.clitSetting === "men") { - r += `SP:men`; - } else if (slave.clitSetting === "anti-women") { - r += `SP:anti-women`; - } else if (slave.clitSetting === "anti-men") { - r += `SP:anti-men`; - } + return null; + } + const s = settingStr(); + if (s) { + makeSpan(c, settingStr()); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_behavior_flaw(slave) { - r += `<span class="red">`; - switch (slave.behavioralFlaw) { - case "arrogant": - r += `Arrog`; - break; - case "bitchy": - r += `Bitchy`; - break; - case "odd": - r += `Odd`; - break; - case "hates men": - r += `Men-`; - break; - case "hates women": - r += `Women-`; - break; - case "gluttonous": - r += `Glut`; - break; - case "anorexic": - r += `Ano`; - break; - case "devout": - r += `Dev`; - break; - case "liberated": - r += `Lib`; - break; - default: - slave.behavioralFlaw = "none"; - break; + function short_behavior_flaw(slave, c) { + function descStr() { + switch (slave.behavioralFlaw) { + case "arrogant": + return `Arrog`; + case "bitchy": + return `Bitchy`; + case "odd": + return `Odd`; + case "hates men": + return `Men-`; + case "hates women": + return `Women-`; + case "gluttonous": + return `Glut`; + case "anorexic": + return `Ano`; + case "devout": + return `Dev`; + case "liberated": + return `Lib`; + default: + slave.behavioralFlaw = "none"; + return null; + } + } + const s = descStr(); + if (s) { + makeSpan(c, descStr(), "red"); } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_sex_flaw(slave) { + function short_sex_flaw(slave, c) { switch (slave.sexualFlaw) { case "hates oral": - r += `<span class="red">Oral-</span>`; + makeSpan(c, "Oral-", "red"); break; case "hates anal": - r += `<span class="red">Anal-</span>`; + makeSpan(c, "Anal-", "red"); break; case "hates penetration": - r += `<span class="red">Fuck-</span>`; + makeSpan(c, "Fuck-", "red"); break; case "shamefast": - r += `<span class="red">Shame</span>`; + makeSpan(c, "Shame", "red"); break; case "idealistic": - r += `<span class="red">Ideal</span>`; + makeSpan(c, "Ideal", "red"); break; case "repressed": - r += `<span class="red">Repre</span>`; + makeSpan(c, "Repre", "red"); break; case "apathetic": - r += `<span class="red">Apath</span>`; + makeSpan(c, "Apath", "red"); break; case "crude": - r += `<span class="red">Crude</span>`; + makeSpan(c, "Crude", "red"); break; case "judgemental": - r += `<span class="red">Judge</span>`; + makeSpan(c, "Judge", "red"); break; case "cum addict": - r += `<span class="yellow">CumAdd</span>`; + makeSpan(c, "CumAdd", "yellow"); break; case "anal addict": - r += `<span class="yellow">AnalAdd</span>`; + makeSpan(c, "AnalAdd", "yellow"); break; case "attention whore": - r += `<span class="yellow">Attention</span>`; + makeSpan(c, "Attention", "yellow"); break; case "breast growth": - r += `<span class="yellow">BoobObsess</span>`; + makeSpan(c, "BoobObsess", "yellow"); break; case "abusive": - r += `<span class="yellow">Abusive</span>`; + makeSpan(c, "Abusive", "yellow"); break; case "malicious": - r += `<span class="yellow">Malice</span>`; + makeSpan(c, "Malice", "yellow"); break; case "self hating": - r += `<span class="yellow">SelfHatr</span>`; + makeSpan(c, "SelfHatr", "yellow"); break; case "neglectful": - r += `<span class="yellow">SelfNeglect</span>`; + makeSpan(c, "SelfNeglect", "yellow"); break; case "breeder": - r += `<span class="yellow">BreedObsess</span>`; + makeSpan(c, "BreedObsess", "yellow"); break; default: slave.sexualFlaw = "none"; break; } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_behavior_quirk(slave) { - r += `<span class="green">`; - switch (slave.behavioralQuirk) { - case "confident": - r += `Confid`; - break; - case "cutting": - r += `Cutting`; - break; - case "funny": - r += `Funny`; - break; - case "fitness": - r += `Fit`; - break; - case "adores women": - r += `Women+`; - break; - case "adores men": - r += `Men+`; - break; - case "insecure": - r += `Insec`; - break; - case "sinful": - r += `Sinf`; - break; - case "advocate": - r += `Advoc`; - break; - default: - slave.behavioralQuirk = "none"; - break; + function short_behavior_quirk(slave, c) { + function descStr() { + switch (slave.behavioralQuirk) { + case "confident": + return `Confid`; + case "cutting": + return `Cutting`; + case "funny": + return `Funny`; + case "fitness": + return `Fit`; + case "adores women": + return `Women+`; + case "adores men": + return `Men+`; + case "insecure": + return `Insec`; + case "sinful": + return `Sinf`; + case "advocate": + return `Advoc`; + default: + slave.behavioralQuirk = "none"; + return null; + } + } + const s = descStr(); + if (s) { + makeSpan(c, s, "green"); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_sex_quirk(slave) { - switch (slave.sexualQuirk) { - case "gagfuck queen": - r += `Gagfuck`; - break; - case "painal queen": - r += `Painal`; - break; - case "strugglefuck queen": - r += `Struggle`; - break; - case "tease": - r += `Tease`; - break; - case "romantic": - r += `Romantic`; - break; - case "perverted": - r += `Perverted`; - break; - case "caring": - r += `Caring`; - break; - case "unflinching": - r += `Unflinch`; - break; - case "size queen": - r += `SizeQ`; - break; - default: - slave.sexualQuirk = "none"; - break; + function short_sex_quirk(slave, c) { + function descStr() { + switch (slave.sexualQuirk) { + case "gagfuck queen": + return `Gagfuck`; + case "painal queen": + return `Painal`; + case "strugglefuck queen": + return `Struggle`; + case "tease": + return `Tease`; + case "romantic": + return `Romantic`; + case "perverted": + return `Perverted`; + case "caring": + return `Caring`; + case "unflinching": + return `Unflinch`; + case "size queen": + return `SizeQ`; + default: + slave.sexualQuirk = "none"; + return null; + } + } + const s = descStr(); + if (s) { + makeSpan(c, s, "green"); } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_fetish(slave) { - r += `<span class="lightcoral">`; - switch (slave.fetish) { - case "submissive": - if (slave.fetishStrength > 95) { - r += `Complete submissive${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Submissive${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Submissive tendencies${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } - break; - case "cumslut": - if (slave.fetishStrength > 95) { - r += `Cumslut${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Oral fixation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Prefers oral${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } - break; - case "humiliation": - if (slave.fetishStrength > 95) { - r += `Humiliation slut${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Exhibitionist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Interest in humiliation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } - break; - case "buttslut": - if (slave.fetishStrength > 95) { - r += `Buttslut${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Anal fixation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Prefers anal${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } - break; - case "boobs": - if (slave.fetishStrength > 95) { - r += `Boobslut${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Breast fixation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Loves boobs${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } - break; - case "sadist": - if (slave.fetishStrength > 95) { - r += `Complete sadist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Sadist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Sadistic tendencies${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } - break; - case "masochist": - if (slave.fetishStrength > 95) { - r += `Complete masochist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Masochist${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Masochistic tendencies${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } - break; - case "dom": - if (slave.fetishStrength > 95) { - r += `Complete dom${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Dominant${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Dominant tendencies${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } - break; - case "pregnancy": - if (slave.fetishStrength > 95) { - r += `Pregnancy fetish${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else if (slave.fetishStrength > 60) { - r += `Pregnancy kink${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } else { - r += `Interest in impregnation${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - } - break; - default: - r += `Sexually vanilla${V.summaryStats? `[${slave.fetishStrength}]` : ''}.`; - break; + function long_fetish(slave, c) { + function fetishStr() { + switch (slave.fetish) { + case "submissive": + if (slave.fetishStrength > 95) { + return "Complete submissive"; + } else if (slave.fetishStrength > 60) { + return "Submissive"; + } else { + return "Submissive tendencies"; + } + case "cumslut": + if (slave.fetishStrength > 95) { + return "Cumslut"; + } else if (slave.fetishStrength > 60) { + return "Oral fixation"; + } else { + return "Prefers oral"; + } + case "humiliation": + if (slave.fetishStrength > 95) { + return "Humiliation slut"; + } else if (slave.fetishStrength > 60) { + return "Exhibitionist"; + } else { + return "Interest in humiliation"; + } + case "buttslut": + if (slave.fetishStrength > 95) { + return "Buttslut"; + } else if (slave.fetishStrength > 60) { + return "Anal fixation"; + } else { + return "Prefers anal"; + } + case "boobs": + if (slave.fetishStrength > 95) { + return "Boobslut"; + } else if (slave.fetishStrength > 60) { + return "Breast fixation"; + } else { + return "Loves boobs"; + } + case "sadist": + if (slave.fetishStrength > 95) { + return "Complete sadist"; + } else if (slave.fetishStrength > 60) { + return "Sadist"; + } else { + return "Sadistic tendencies"; + } + case "masochist": + if (slave.fetishStrength > 95) { + return "Complete masochist"; + } else if (slave.fetishStrength > 60) { + return "Masochist"; + } else { + return "Masochistic tendencies"; + } + case "dom": + if (slave.fetishStrength > 95) { + return "Complete dom"; + } else if (slave.fetishStrength > 60) { + return "Dominant"; + } else { + return "Dominant tendencies"; + } + case "pregnancy": + if (slave.fetishStrength > 95) { + return "Pregnancy fetish"; + } else if (slave.fetishStrength > 60) { + return "Pregnancy kink"; + } else { + return "Interest in impregnation"; + } + default: + return "Sexually vanilla"; + } } - r += `</span> `; + makeSpan(c, fetishStr(), "lightcoral", true, slave.fetishStrength); } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_attraction(slave) { + function long_attraction(slave, c) { if (slave.attrXY <= 5) { - r += `<span class="red">Disgusted by men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; + makeSpan(c, "Disgusted by men", "red", true, slave.attrXY); } else if (slave.attrXY <= 15) { - r += `<span class="red">Turned off by men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; + makeSpan(c, "Turned off by men", "red", true, slave.attrXY); } else if (slave.attrXY <= 35) { - r += `<span class="red">Not attracted to men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; + makeSpan(c, "Not attracted to men", "red", true, slave.attrXY); } else if (slave.attrXY <= 65) { - r += `Indifferent to men${V.summaryStats? `[${slave.attrXY}]` : ''}, `; + makeSpan(c, "Indifferent to men", undefined, true, slave.attrXY); } else if (slave.attrXY <= 85) { - r += `<span class="green">Attracted to men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; + makeSpan(c, "Attracted to men", "green", true, slave.attrXY); } else if (slave.attrXY <= 95) { - r += `<span class="green">Aroused by men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; + makeSpan(c, "Aroused by men", "green", true, slave.attrXY); } else if (slave.attrXX > 95) { if (slave.energy <= 95) { - r += `<span class="green">Omnisexual!</span> `; + makeSpan(c, "Omnisexual!", "green"); } else { - r += `<span class="green">Omnisexual nymphomaniac!</span> `; + makeSpan(c, "Omnisexual nymphomaniac!", "green"); } } else { - r += `<span class="green">Passionate about men${V.summaryStats? `[${slave.attrXY}]` : ''},</span> `; + makeSpan(c, "Passionate about men", "green", true, slave.attrXY); } if (slave.attrXX <= 5) { - r += `<span class="red">disgusted by women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; + makeSpan(c, "disgusted by women", "red", true, slave.attrXX); } else if (slave.attrXX <= 15) { - r += `<span class="red">turned off by women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; + makeSpan(c, "turned off by women", "red", true, slave.attrXX); } else if (slave.attrXX <= 35) { - r += `<span class="red">not attracted to women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; + makeSpan(c, "not attracted to women", "red", true, slave.attrXX); } else if (slave.attrXX <= 65) { - r += `indifferent to women${V.summaryStats? `[${slave.attrXX}]` : ''}. `; + makeSpan(c, "Disgusted by women", undefined, true, slave.attrXX); } else if (slave.attrXX <= 85) { - r += `<span class="green">attracted to women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; + makeSpan(c, "attracted to women", "green", true, slave.attrXX); } else if (slave.attrXX <= 95) { - r += `<span class="green">aroused by women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; + makeSpan(c, "aroused by women", "green", true, slave.attrXX); } else if (slave.attrXY <= 95) { - r += `<span class="green">passionate about women${V.summaryStats? `[${slave.attrXX}]` : ''}.</span> `; + makeSpan(c, "passionate about women", "green", true, slave.attrXX); } if (slave.energy > 95) { if ((slave.attrXY <= 95) || (slave.attrXX <= 95)) { - r += `<span class="green">Nymphomaniac!</span>`; + makeSpan(c, "Nymphomaniac!", "green"); } } else if (slave.energy > 80) { - r += `<span class="green">Powerful sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; + makeSpan(c, "Powerful sex drive", "green", true, slave.energy); } else if (slave.energy > 60) { - r += `<span class="green">Good sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; + makeSpan(c, "Good sex drive", "green", true, slave.energy); } else if (slave.energy > 40) { - r += `<span class="yellow">Average sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; + makeSpan(c, "Average sex drive", "yellow", true, slave.energy); } else if (slave.energy > 20) { - r += `<span class="red">Poor sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; + makeSpan(c, "Poor sex drive", "red", true, slave.energy); } else { - r += `<span class="red">No sex drive${V.summaryStats? `[${slave.energy}]` : ''}.</span>`; + makeSpan(c, "No sex drive", "red", true, slave.energy); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_smart_fetish(slave) { - if (slave.fetishKnown === 1) { - if (slave.clitSetting === "off") { - r += `SP off.`; - } else if (((slave.fetish !== "submissive") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "submissive")) { - r += `SP: submissive.`; - } else if (((slave.fetish !== "cumslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "oral")) { - r += `SP: oral.`; - } else if (((slave.fetish !== "humiliation") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "humiliation")) { - r += `SP: humiliation.`; - } else if (((slave.fetish !== "buttslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "anal")) { - r += `SP: anal.`; - } else if (((slave.fetish !== "boobs") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "boobs")) { - r += `SP: breasts.`; - } else if (((slave.fetish !== "sadist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "sadist")) { - r += `SP: sadism.`; - } else if (((slave.fetish !== "masochist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "masochist")) { - r += `SP: masochism.`; - } else if (((slave.fetish !== "dom") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "dom")) { - r += `SP: dominance.`; - } else if (((slave.fetish !== "pregnancy") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "pregnancy")) { - r += `SP: pregnancy.`; - } else if ((slave.fetish !== "none") && (slave.clitSetting === "vanilla")) { - r += `SP: vanilla.`; - } else if ((slave.energy <= 95) && (slave.clitSetting === "all")) { - r += `SP: all.`; - } else if ((slave.energy > 5) && (slave.clitSetting === "none")) { - r += `SP: none.`; - } else if (!["anti-men", "anti-women", "men", "women"].includes(slave.clitSetting)) { - r += `SP: monitoring.`; - } - } else { - switch (slave.clitSetting) { - case "off": - r += `SP off.`; - break; - case "submissive": - r += `SP: submissive.`; - break; - case "oral": - r += `SP: oral.`; - break; - case "humiliation": - r += `SP: humiliation.`; - break; - case "anal": - r += `SP: anal.`; - break; - case "boobs": - r += `SP: breasts.`; - break; - case "sadist": - r += `SP: sadism.`; - break; - case "masochist": - r += `SP: masochism.`; - break; - case "dom": - r += `SP: dominance.`; - break; - case "pregnancy": - r += `SP: pregnancy.`; - break; - case "vanilla": - r += `SP: vanilla.`; - break; - case "all": - r += `SP: all.`; - break; - case "none": - r += `SP: none.`; - break; + function long_smart_fetish(slave, c) { + function descStr() { + if (slave.fetishKnown === 1) { + if (slave.clitSetting === "off") { + return `SP off.`; + } else if (((slave.fetish !== "submissive") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "submissive")) { + return `SP: submissive.`; + } else if (((slave.fetish !== "cumslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "oral")) { + return `SP: oral.`; + } else if (((slave.fetish !== "humiliation") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "humiliation")) { + return `SP: humiliation.`; + } else if (((slave.fetish !== "buttslut") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "anal")) { + return `SP: anal.`; + } else if (((slave.fetish !== "boobs") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "boobs")) { + return `SP: breasts.`; + } else if (((slave.fetish !== "sadist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "sadist")) { + return `SP: sadism.`; + } else if (((slave.fetish !== "masochist") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "masochist")) { + return `SP: masochism.`; + } else if (((slave.fetish !== "dom") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "dom")) { + return `SP: dominance.`; + } else if (((slave.fetish !== "pregnancy") || (slave.fetishStrength <= 95)) && (slave.clitSetting === "pregnancy")) { + return `SP: pregnancy.`; + } else if ((slave.fetish !== "none") && (slave.clitSetting === "vanilla")) { + return `SP: vanilla.`; + } else if ((slave.energy <= 95) && (slave.clitSetting === "all")) { + return `SP: all.`; + } else if ((slave.energy > 5) && (slave.clitSetting === "none")) { + return `SP: none.`; + } else if (!["anti-men", "anti-women", "men", "women"].includes(slave.clitSetting)) { + return `SP: monitoring.`; + } + } else { + switch (slave.clitSetting) { + case "off": + return `SP off.`; + case "submissive": + return `SP: submissive.`; + case "oral": + return `SP: oral.`; + case "humiliation": + return `SP: humiliation.`; + case "anal": + return `SP: anal.`; + case "boobs": + return `SP: breasts.`; + case "sadist": + return `SP: sadism.`; + case "masochist": + return `SP: masochism.`; + case "dom": + return `SP: dominance.`; + case "pregnancy": + return `SP: pregnancy.`; + case "vanilla": + return `SP: vanilla.`; + case "all": + return `SP: all.`; + case "none": + return `SP: none.`; + } } + return null; + } + const s = descStr(); + if (s) { + makeSpan(c, s); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_smart_attraction(slave) { + function long_smart_attraction(slave, c) { if (slave.attrKnown === 1) { if ((slave.attrXX < 100) && (slave.clitSetting === "women")) { - r += `SP: women.`; + makeSpan(c, `SP: women.`); } else if ((slave.attrXY < 100) && (slave.clitSetting === "men")) { - r += `SP: men.`; + makeSpan(c, `SP: men.`); } } else { if (slave.clitSetting === "women") { - r += `SP: women.`; + makeSpan(c, `SP: women.`); } else if (slave.clitSetting === "men") { - r += `SP: men.`; + makeSpan(c, `SP: men.`); } } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_behavior_flaw(slave) { - r += `<span class="red">`; - switch (slave.behavioralFlaw) { - case "arrogant": - r += `Arrogant.`; - break; - case "bitchy": - r += `Bitchy.`; - break; - case "odd": - r += `Odd.`; - break; - case "hates men": - r += `Hates men.`; - break; - case "hates women": - r += `Hates women.`; - break; - case "gluttonous": - r += `Stress eater.`; - break; - case "anorexic": - r += `Anorexic.`; - break; - case "devout": - r += `Devoutly religious.`; - break; - case "liberated": - r += `Mentally liberated.`; - break; - default: - slave.behavioralFlaw = "none"; - break; + function long_behavior_flaw(slave, c) { + function descStr() { + switch (slave.behavioralFlaw) { + case "arrogant": + return `Arrogant.`; + case "bitchy": + return `Bitchy.`; + case "odd": + return `Odd.`; + case "hates men": + return `Hates men.`; + case "hates women": + return `Hates women.`; + case "gluttonous": + return `Stress eater.`; + case "anorexic": + return `Anorexic.`; + case "devout": + return `Devoutly religious.`; + case "liberated": + return `Mentally liberated.`; + default: + slave.behavioralFlaw = "none"; + return null; + } + } + const s = descStr(); + if (s) { + makeSpan(c, s, "red"); } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_sex_flaw(slave) { + function long_sex_flaw(slave, c) { switch (slave.sexualFlaw) { case "hates oral": - r += `<span class="red">Hates oral.</span>`; - break; case "hates anal": - r += `<span class="red">Hates anal.</span>`; - break; case "hates penetration": - r += `<span class="red">Hates penetration.</span>`; - break; case "shamefast": - r += `<span class="red">Shamefast.</span>`; + makeSpan(c, slave.sexualFlaw, "red", true); break; case "idealistic": - r += `<span class="red">Sexually idealistic.</span>`; - break; case "repressed": - r += `<span class="red">Sexually repressed.</span>`; - break; case "apathetic": - r += `<span class="red">Sexually apathetic.</span>`; - break; case "crude": - r += `<span class="red">Sexually crude.</span>`; - break; case "judgemental": - r += `<span class="red">Sexually judgemental.</span>`; + makeSpan(c, `Sexually ${slave.sexualFlaw}.`, "red"); break; case "cum addict": - r += `<span class="yellow">Cum addict.</span>`; - break; case "anal addict": - r += `<span class="yellow">Anal addict.</span>`; - break; case "attention whore": - r += `<span class="yellow">Attention whore.</span>`; + makeSpan(c, slave.sexualFlaw, "yellow", true); break; case "breast growth": - r += `<span class="yellow">Breast obsession.</span>`; + makeSpan(c, `Breast obsession.`, "yellow"); break; case "abusive": - r += `<span class="yellow">Sexually abusive.</span>`; - break; case "malicious": - r += `<span class="yellow">Sexually malicious.</span>`; + makeSpan(c, `Sexually ${slave.sexualFlaw}.`, "yellow"); break; case "self hating": - r += `<span class="yellow">Self hatred.</span>`; + makeSpan(c, `Self hatred.`, "yellow"); break; case "neglectful": - r += `<span class="yellow">Self neglectful.</span>`; + makeSpan(c, `Self neglectful.`, "yellow"); break; case "breeder": - r += `<span class="yellow">Breeding obsession.</span>`; + makeSpan(c, `Breeding obsession.`, "yellow"); break; default: slave.sexualFlaw = "none"; break; } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_behavior_quirk(slave) { - r += `<span class="green">`; + function long_behavior_quirk(slave, c) { switch (slave.behavioralQuirk) { case "confident": - r += `Confident.`; - break; case "cutting": - r += `Cutting.`; - break; case "funny": - r += `Funny.`; - break; case "fitness": - r += `Fitness.`; - break; case "adores women": - r += `Adores women.`; - break; case "adores men": - r += `Adores men.`; - break; case "insecure": - r += `Insecure.`; - break; case "sinful": - r += `Sinful.`; - break; case "advocate": - r += `Advocate.`; + makeSpan(c, slave.behavioralQuirk, "green", true); break; default: slave.behavioralQuirk = "none"; break; } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_sex_quirk(slave) { + function long_sex_quirk(slave, c) { switch (slave.sexualQuirk) { case "gagfuck queen": - r += `Gagfuck queen.`; - break; case "painal queen": - r += `Painal queen.`; - break; case "strugglefuck queen": - r += `Strugglefuck queen.`; - break; case "tease": - r += `Tease.`; - break; case "romantic": - r += `Romantic.`; - break; case "perverted": - r += `Perverted.`; - break; case "caring": - r += `Caring.`; - break; case "unflinching": - r += `Unflinching.`; - break; case "size queen": - r += `Size queen.`; + makeSpan(c, slave.sexualQuirk, "green", true); break; default: slave.sexualQuirk = "none"; break; } - r += `</span> `; } /** * @param {App.Entity.SlaveState} slave + * @returns {string} */ function short_extended_family(slave) { + let res = ""; let handled = 0; if (slave.mother > 0) { const _ssj = V.slaves.findIndex(s => s.ID === slave.mother); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s ${getPronouns(slave).daughter}`; + res += `${SlaveFullName(V.slaves[_ssj])}'s ${getPronouns(slave).daughter}`; if (slave.relationshipTarget === V.slaves[_ssj].ID) { const friendShipShort = relationshipTermShort(slave); - r += ` & ${friendShipShort}`; + res += ` & ${friendShipShort}`; handled = 1; } } - r += " "; + res += " "; } else if (slave.mother === -1) { - r += `Your ${getPronouns(slave).daughter}`; + res += `Your ${getPronouns(slave).daughter}`; if (slave.relationship === -3) { - r += ` & wife`; + res += ` & wife`; handled = 1; } else if (slave.relationship === -2) { - r += ` & lover`; + res += ` & lover`; handled = 1; } - r += " "; + res += " "; } else if (slave.mother in V.missingTable && V.showMissingSlavesSD && V.showMissingSlaves) { - r += `${V.missingTable[slave.mother].fullName}'s ${getPronouns(slave).daughter} `; + res += `${V.missingTable[slave.mother].fullName}'s ${getPronouns(slave).daughter} `; } if (slave.father > 0 && slave.father !== slave.mother) { const _ssj = V.slaves.findIndex(s => s.ID === slave.father); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s ${getPronouns(slave).daughter}`; + res += `${SlaveFullName(V.slaves[_ssj])}'s ${getPronouns(slave).daughter}`; if (slave.relationshipTarget === V.slaves[_ssj].ID && handled !== 1) { const friendShipShort = relationshipTermShort(slave); - r += ` & ${friendShipShort}`; + res += ` & ${friendShipShort}`; handled = 1; } } - r += " "; + res += " "; } else if (slave.father === -1 && slave.mother !== -1) { - r += `Your ${getPronouns(slave).daughter}`; + res += `Your ${getPronouns(slave).daughter}`; if (slave.relationship === -3) { - r += ` & wife`; + res += ` & wife`; handled = 1; } else if (slave.relationship === -2) { - r += ` & lover`; + res += ` & lover`; handled = 1; } - r += " "; + res += " "; } else if (slave.father in V.missingTable && slave.father !== slave.mother && V.showMissingSlavesSD && V.showMissingSlaves) { - r += `${V.missingTable[slave.father].fullName}'s ${getPronouns(slave).daughter}`; + res += `${V.missingTable[slave.father].fullName}'s ${getPronouns(slave).daughter}`; } if (slave.daughters === 1) { let _ssj = V.slaves.findIndex(s => s.mother === slave.ID); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s mother`; + res += `${SlaveFullName(V.slaves[_ssj])}'s mother`; if (slave.relationshipTarget === V.slaves[_ssj].ID) { const friendShipShort = relationshipTermShort(slave); - r += ` & ${friendShipShort}`; + res += ` & ${friendShipShort}`; handled = 1; } } - r += " "; + res += " "; _ssj = V.slaves.findIndex(s => s.father === slave.ID); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s father`; + res += `${SlaveFullName(V.slaves[_ssj])}'s father`; if (slave.relationshipTarget === V.slaves[_ssj].ID && handled !== 1) { const friendShipShort = relationshipTermShort(slave); - r += ` & ${friendShipShort}`; + res += ` & ${friendShipShort}`; handled = 1; } } - r += " "; + res += " "; } else if (slave.daughters > 1) { - r += `multiple daughters `; + res += `multiple daughters `; } if (slave.sisters === 1) { const _ssj = V.slaves.findIndex(s => areSisters(s, slave) > 0); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s ${getPronouns(slave).sister}`; + res += `${SlaveFullName(V.slaves[_ssj])}'s ${getPronouns(slave).sister}`; if (slave.relationshipTarget === V.slaves[_ssj].ID) { const friendShipShort = relationshipTermShort(slave); - r += `& ${friendShipShort}`; + res += `& ${friendShipShort}`; handled = 1; } } - r += " "; + res += " "; } else if (slave.sisters > 1) { - r += `multiple sisters `; + res += `multiple sisters `; } if (slave.relationship > 0 && handled !== 1) { const _ssj = V.slaves.findIndex(s => s.ID === slave.relationshipTarget); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s`; + res += `${SlaveFullName(V.slaves[_ssj])}'s`; const friendShipShort = relationshipTermShort(slave); - r += ` ${friendShipShort}`; + res += ` ${friendShipShort}`; } } else if (slave.relationship === -3 && slave.mother !== -1 && slave.father !== -1) { - r += `Your wife`; + res += `Your wife`; } else if (slave.relationship === -2) { - r += `E Bonded`; + res += `E Bonded`; } else if (slave.relationship === -1) { - r += `E Slut`; + res += `E Slut`; } - r += " "; + return res; } /** * @param {App.Entity.SlaveState} slave + * @returns {string} */ function short_legacy_family(slave) { + let res = ""; if (slave.relation !== 0) { const _ssj = V.slaves.findIndex(s => s.ID === slave.relationTarget); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s ${slave.relation}`; + res += `${SlaveFullName(V.slaves[_ssj])}'s ${slave.relation}`; } } if (slave.relationship > 0) { @@ -4106,187 +3769,204 @@ window.SlaveSummaryUncached = (function() { if (_ssj !== -1) { const friendship = relationshipTerm(slave); if (slave.relationshipTarget !== slave.relationTarget) { - r += `${SlaveFullName(V.slaves[_ssj])}'s`; + res += `${SlaveFullName(V.slaves[_ssj])}'s`; } else { - r += ` &`; + res += ` &`; } - r += ` ${friendship}`; + res += ` ${friendship}`; } } else if (slave.relationship === -3) { - r += `Your wife`; + res += `Your wife`; } else if (slave.relationship === -2) { - r += `E Bonded`; + res += `E Bonded`; } else if (slave.relationship === -1) { - r += `E Slut`; + res += `E Slut`; } + return res; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_clone(slave) { + function short_clone(slave, c) { if (slave.clone !== 0) { - r += ` Clone`; + makeSpan(c, "Clone"); } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function short_rival(slave) { + function short_rival(slave, c) { if (slave.rivalry !== 0) { - r += ` `; + const block = makeBlock(c, "lightsalmon"); const _ssj = V.slaves.findIndex(s => s.ID === slave.rivalryTarget); if (_ssj !== -1) { - r += `<span class="lightsalmon">`; if (slave.rivalry <= 1) { - r += `Disl ${SlaveFullName(V.slaves[_ssj])}`; + block.textContent = `Disl ${SlaveFullName(V.slaves[_ssj])}`; } else if (slave.rivalry <= 2) { - r += `${SlaveFullName(V.slaves[_ssj])}'s rival`; + block.textContent = `${SlaveFullName(V.slaves[_ssj])}'s rival`; } else { - r += `Hates ${SlaveFullName(V.slaves[_ssj])}`; + block.textContent = `Hates ${SlaveFullName(V.slaves[_ssj])}`; } - r += `</span> `; } } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_extended_family(slave) { + function long_extended_family(slave, c) { let handled = 0; + const block = makeBlock(); if (slave.mother > 0) { const _ssj = V.slaves.findIndex(s => s.ID === slave.mother); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">${getPronouns(slave).daughter}`; + addText(block, `${SlaveFullName(V.slaves[_ssj])}'s `); + const tmpSpan = makeSpan(block, getPronouns(slave).daughter, "lightgreen"); if (slave.relationshipTarget === V.slaves[_ssj].ID) { const friendShipShort = relationshipTerm(slave); - r += ` and ${friendShipShort}`; + tmpSpan.textContent += ` and ${friendShipShort}`; handled = 1; } - r += `.</span> `; + tmpSpan.textContent += '.'; } } else if (slave.mother === -1) { - r += `Your `; + addText(block, `Your `); if (slave.relationship === -3) { - r += `<span class="lightgreen">${getPronouns(slave).daughter} and wife.</span> `; + makeSpan(block, `${getPronouns(slave).daughter} and wife.`, "lightgreen"); handled = 1; } else if (slave.relationship === -2) { - r += `<span class="lightgreen">${getPronouns(slave).daughter} and lover.</span> `; + makeSpan(block, `${getPronouns(slave).daughter} and lover.`, "lightgreen"); handled = 1; } else { - r += `<span class="lightgreen">${getPronouns(slave).daughter}.</span> `; + makeSpan(block, `${getPronouns(slave).daughter}.`, "lightgreen"); } } else if (slave.mother in V.missingTable && V.showMissingSlavesSD && V.showMissingSlaves) { - r += `${V.missingTable[slave.mother].fullName}'s <span class="lightgreen">${getPronouns(slave).daughter}.</span> `; + addText(block, `${V.missingTable[slave.mother].fullName}'s `); + makeSpan(block, `${getPronouns(slave).daughter}.`, "lightgreen"); } if (slave.father > 0 && slave.father !== slave.mother) { const _ssj = V.slaves.findIndex(s => s.ID === slave.father); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">${getPronouns(slave).daughter}`; + addText(block, `${SlaveFullName(V.slaves[_ssj])}'s `); + const tmpSpan = makeSpan(block, getPronouns(slave).daughter, "lightgreen"); if (slave.relationshipTarget === V.slaves[_ssj].ID) { const friendShipShort = relationshipTerm(slave); - r += ` and ${friendShipShort}`; + tmpSpan.textContent += ` and ${friendShipShort}`; handled = 1; } - r += `.</span> `; + tmpSpan.textContent += '.'; } } else if (slave.father === -1 && slave.father !== slave.mother) { - r += `Your `; + addText(block, `Your `); if (slave.relationship === -3) { - r += `<span class="lightgreen">${getPronouns(slave).daughter} and wife.</span> `; + makeSpan(block, `${getPronouns(slave).daughter} and wife.`, "lightgreen"); handled = 1; } else if (slave.relationship === -2) { - r += `<span class="lightgreen">${getPronouns(slave).daughter} and lover.</span> `; + makeSpan(block, `${getPronouns(slave).daughter} and lover.`, "lightgreen"); handled = 1; } else { - r += `<span class="lightgreen">${getPronouns(slave).daughter}.</span> `; + makeSpan(block, `${getPronouns(slave).daughter}.`, "lightgreen"); } } else if (slave.father in V.missingTable && slave.father !== slave.mother && V.showMissingSlavesSD && V.showMissingSlaves) { - r += `${V.missingTable[slave.father].fullName}'s <span class="lightgreen">${getPronouns(slave).daughter}.</span> `; + addText(block, `${V.missingTable[slave.mother].fullName}'s `); + makeSpan(block, `${getPronouns(slave).daughter}.`, "lightgreen"); } if (slave.daughters === 1) { let _ssj = V.slaves.findIndex(s => s.mother === slave.ID); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">mother`; + addText(block, `${SlaveFullName(V.slaves[_ssj])}'s `); + const tmpSpan = makeSpan(block, "mother", "lightgreen"); if (slave.relationshipTarget === V.slaves[_ssj].ID) { const friendShipShort = relationshipTerm(slave); - r += ` and ${friendShipShort}`; + tmpSpan.textContent += ` and ${friendShipShort}`; handled = 1; } - r += `.</span> `; + tmpSpan.textContent += '.'; } _ssj = V.slaves.findIndex(s => s.father === slave.ID); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">father`; + addText(block, `${SlaveFullName(V.slaves[_ssj])}'s `); + const tmpSpan = makeSpan(block, "father", "lightgreen"); if (slave.relationshipTarget === V.slaves[_ssj].ID) { const friendShipShort = relationshipTerm(slave); - r += ` and ${friendShipShort}`; + tmpSpan.textContent += ` and ${friendShipShort}`; handled = 1; } - r += `.</span> `; + tmpSpan.textContent += '.'; } } else if (slave.daughters > 1) { if (slave.daughters > 10) { - r += `<span class="lightgreen">Has tons of daughters.</span> `; + makeSpan(block, "Has tons of daughters.", "lightgreen"); } else if (slave.daughters > 5) { - r += `<span class="lightgreen">Has many daughters.</span> `; + makeSpan(block, "Has many daughters.", "lightgreen"); } else { - r += `<span class="lightgreen">Has several daughters.</span> `; + makeSpan(block, "Has several daughters.", "lightgreen"); } } if (slave.sisters === 1) { const _ssj = V.slaves.findIndex(s => areSisters(s, slave) > 0); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightgreen">${getPronouns(slave).sister}`; + addText(block, `${SlaveFullName(V.slaves[_ssj])}'s `); + const tmpSpan = makeSpan(block, getPronouns(slave).sister, "lightgreen"); if (slave.relationshipTarget === V.slaves[_ssj].ID) { const friendShipShort = relationshipTerm(slave); - r += ` and ${friendShipShort}`; + tmpSpan.textContent += ` and ${friendShipShort}`; handled = 1; } - r += `.</span> `; + tmpSpan.textContent += '.'; } } else if (slave.sisters > 1) { if (slave.sisters > 10) { - r += `<span class="lightgreen">One of many sisters.</span> `; + makeSpan(block, "One of many sisters.", "lightgreen"); } else if (slave.sisters > 5) { - r += `<span class="lightgreen">Has many sisters.</span> `; + makeSpan(block, "Has many sisters.", "lightgreen"); } else { - r += `<span class="lightgreen">Has several sisters.</span> `; + makeSpan(block, "Has several sisters.", "lightgreen"); } } if (slave.relationship > 0 && handled !== 1) { const _ssj = V.slaves.findIndex(s => s.ID === slave.relationshipTarget); if (_ssj !== -1) { const friendship = relationshipTerm(slave); - r += `${SlaveFullName(V.slaves[_ssj])}'s `; - r += `<span class="lightgreen">${friendship}.</span> `; + addText(block, `${SlaveFullName(V.slaves[_ssj])}'s `); + makeSpan(block, `${friendship}.`, "lightgreen"); } } else if (slave.relationship === -3 && slave.mother !== -1 && slave.father !== -1) { - r += `<span class="lightgreen">Your wife.</span> `; + makeSpan(block, "Your wife.", "lightgreen"); } else if (slave.relationship === -2) { - r += `<span class="lightgreen">Emotionally bonded to you.</span> `; + makeSpan(block, "Emotionally bonded to you.", "lightgreen"); } else if (slave.relationship === -1) { - r += `<span class="lightgreen">Emotional slut.</span> `; + makeSpan(block, "Emotional slut.", "lightgreen"); + } + + if (block.textContent.length > 0) { + c.appendChild(block); } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_legacy_family(slave) { + function long_legacy_family(slave, c) { + const block = makeBlock(); if (slave.relation !== 0) { const _ssj = V.slaves.findIndex(s => s.ID === slave.relationTarget); if (_ssj !== -1) { - r += `${SlaveFullName(V.slaves[_ssj])}'s `; + addText(block, `${SlaveFullName(V.slaves[_ssj])}'s `); if (slave.relationshipTarget !== slave.relationTarget) { - r += `<span class="lightgreen">${slave.relation}.</span> `; + makeSpan(block, `${slave.relation}.`, "lightgreen"); } else { - r += `<span class="lightgreen">${slave.relation}</span> `; - } - if (slave.relationship <= 0) { - r += ` `; + makeSpan(block, `${slave.relation}`, "lightgreen"); } } } @@ -4295,672 +3975,659 @@ window.SlaveSummaryUncached = (function() { if (_ssj !== -1) { const friendship = relationshipTerm(slave); if (slave.relationshipTarget !== slave.relationTarget) { - r += `${SlaveFullName(V.slaves[_ssj])}'s `; + addText(block, `${SlaveFullName(V.slaves[_ssj])}'s `); } else { - r += ` and `; + addText(block, `and `); } - r += `<span class="lightgreen">${friendship}.</span> `; + makeSpan(block, `${friendship}.`, "lightgreen"); } } else if (slave.relationship === -3) { - r += `<span class="lightgreen">Your wife.</span> `; + makeSpan(block, "Your wife.", "lightgreen"); } else if (slave.relationship === -2) { - r += `<span class="lightgreen">Emotionally bonded to you.</span> `; + makeSpan(block, "Emotionally bonded to you.", "lightgreen"); } else if (slave.relationship === -1) { - r += `<span class="lightgreen">Emotional slut.</span> `; + makeSpan(block, "Emotional slut.", "lightgreen"); + } + + if (block.textContent.length > 0) { + c.appendChild(block); } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_clone(slave) { + function long_clone(slave, c) { if (slave.clone !== 0) { - r += ` <span class="skyblue">Clone of ${slave.clone}.</span>`; + makeSpan(c, `Clone of ${slave.clone}.`, "skyblue"); } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_rival(slave) { + function long_rival(slave, c) { if (slave.rivalry !== 0) { - r += ` `; + const block = makeBlock(c); const _ssj = V.slaves.findIndex(s => s.ID === slave.rivalryTarget); if (_ssj !== -1) { if (slave.rivalry <= 1) { - r += `<span class="lightsalmon">Dislikes</span> ${SlaveFullName(V.slaves[_ssj])}.`; + makeSpan(block, "Dislikes", "lightsalmon"); + block.appendChild(document.createTextNode(` ${SlaveFullName(V.slaves[_ssj])}.`)); } else if (slave.rivalry <= 2) { - r += `${SlaveFullName(V.slaves[_ssj])}'s <span class="lightsalmon">rival.</span>`; + block.appendChild(document.createTextNode(`${SlaveFullName(V.slaves[_ssj])}'s `)); + makeSpan(block, "rival.", "lightsalmon"); } else { - r += `<span class="lightsalmon">Hates</span> ${SlaveFullName(V.slaves[_ssj])}.`; + makeSpan(block, "Hates", "lightsalmon"); + block.appendChild(document.createTextNode(` ${SlaveFullName(V.slaves[_ssj])}.`)); } } - r += " "; } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_clothes(slave) { - switch (slave.clothes) { - case "attractive lingerie": - r += `Nice lingerie.`; - break; - case "a succubus outfit": - r += `Succubus outfit.`; - break; - case "a string bikini": - r += `String bikini.`; - break; - case "a scalemail bikini": - r += `Scalemail bikini.`; - break; - case "striped panties": - r += `Striped panties.`; - break; - case "a monokini": - r += `Monokini.`; - break; - case "an apron": - r += `Apron.`; - break; - case "a cybersuit": - r += `Cybersuit.`; - break; - case "cutoffs and a t-shirt": - r += `Cutoffs, t-shirt.`; - break; - case "a slutty outfit": - r += `Slutty outfit.`; - break; - case "uncomfortable straps": - r += `Leather straps.`; - break; - case "a fallen nuns habit": - r += `Slutty habit.`; - break; - case "a chattel habit": - r += `Chattel habit.`; - break; - case "a penitent nuns habit": - r += `Cilice.`; - break; - case "slutty jewelry": - r += `Bangles.`; - break; - case "attractive lingerie for a pregnant woman": - r += `Preggo lingerie.`; - break; - case "a maternity dress": - r += `Maternity dress.`; - break; - case "stretch pants and a crop-top": - r += `Stretch pants, crop-top.`; - break; - case "harem gauze": - r += `Harem outfit.`; - break; - case "a slave gown": - r += `Slave gown.`; - break; - case "a halter top dress": - r += `Halter top dress.`; - break; - case "a mini dress": - r += `Mini dress.`; - break; - case "a ball gown": - r += `Ball gown.`; - break; - case "slutty business attire": - r += `Slutty suit.`; - break; - case "nice business attire": - r += `Nice suit.`; - break; - case "a comfortable bodysuit": - r += `Bodysuit.`; - break; - case "a military uniform": - r += `Military uniform.`; - break; - case "a schutzstaffel uniform": - r += `Schutzstaffel uniform.`; - break; - case "a slutty schutzstaffel uniform": - r += `Slutty Schutzstaffel uniform.`; - break; - case "a red army uniform": - r += `Red Army uniform.`; - break; - case "a long qipao": - r += `Long Qipao.`; - break; - case "battlearmor": - r += `Battlearmor.`; - break; - case "a mounty outfit": - r += `Mounty outfit.`; - break; - case "a dirndl": - r += `Dirndl.`; - break; - case "lederhosen": - r += `Lederhosen.`; - break; - case "a biyelgee costume": - r += `Biyelgee costume.`; - break; - case "a leotard": - r += `Leotard.`; - break; - case "a bunny outfit": - r += `Bunny outfit.`; - break; - case "a slutty maid outfit": - r += `Slutty maid.`; - break; - case "a nice maid outfit": - r += `Nice maid.`; - break; - case "a slutty nurse outfit": - r += `Slutty nurse.`; - break; - case "a nice nurse outfit": - r += `Nice nurse.`; - break; - case "a schoolgirl outfit": - r += `Schoolgirl outfit.`; - break; - case "a kimono": - r += `Kimono.`; - break; - case "a hijab and abaya": - r += `Hijab and abaya.`; - break; - case "battledress": - r += `Battledress.`; - break; - case "a latex catsuit": - r += `Nice latex.`; - break; - case "restrictive latex": - r += `Bondage latex.`; - break; - case "conservative clothing": - r += `Conservative clothing.`; - break; - case "chains": - r += `Chains.`; - break; - case "overalls": - r += `Overalls.`; - break; - case "a cheerleader outfit": - r += `Cheerleader.`; - break; - case "clubslut netting": - r += `Netting.`; - break; - case "shibari ropes": - r += `Shibari.`; - break; - case "Western clothing": - r += `Chaps.`; - break; - case "body oil": - r += `Body oil.`; - break; - case "a toga": - r += `Toga.`; - break; - case "a huipil": - r += `Huipil.`; - break; - case "a slutty qipao": - r += `Slutty qipao.`; - break; - case "spats and a tank top": - r += `Spats, tank top.`; - break; - case "a burkini": - r += `Burkini.`; - break; - case "a niqab and abaya": - r += `Niqab and abaya.`; - break; - case "a klan robe": - r += `Klan robe.`; - break; - case "a hijab and blouse": - r += `Hijab and blouse.`; - break; - case "a burqa": - r += `Burqa.`; - break; - case "kitty lingerie": - r += `Kitty lingerie.`; - break; - case "a tube top and thong": - r += `Tube top, thong.`; - break; - case "a button-up shirt and panties": - r += `Button-up shirt, panties.`; - break; - case "a gothic lolita dress": - r += `Gothic lolita dress.`; - break; - case "a hanbok": - r += `Hanbok.`; - break; - case "a bra": - r += `Nice bra.`; - break; - case "a button-up shirt": - r += `Nice button-up shirt.`; - break; - case "a nice pony outfit": - r += `Nice pony outfit.`; - break; - case "a sweater": - r += `Nice sweater.`; - break; - case "a tank-top": - r += `Nice tank-top.`; - break; - case "a thong": - r += `Nice thong.`; - break; - case "a tube top": - r += `Nice tube top.`; - break; - case "a one-piece swimsuit": - r += `Swimsuit.`; - break; - case "a police uniform": - r += `Police uniform.`; - break; - case "a striped bra": - r += `Striped bra.`; - break; - case "a skimpy loincloth": - r += `Skimpy loincloth.`; - break; - case "a slutty klan robe": - r += `Slutty klan robe.`; - break; - case "a slutty pony outfit": - r += `Slutty pony outfit.`; - break; - case "a Santa dress": - r += `Santa dress.`; - break; - case "a sports bra": - r += `Sports bra.`; - break; - case "a sweater and panties": - r += `Sweater, panties.`; - break; - case "a t-shirt": - r += `T-shirt.`; - break; - case "a tank-top and panties": - r += `Tank-top, panties.`; - break; - case "a t-shirt and thong": - r += `Thong, t-shirt.`; - break; - case "an oversized t-shirt and boyshorts": - r += `Over-sized t-shirt, boy shorts.`; - break; - case "an oversized t-shirt": - r += `Nice over-sized t-shirt.`; - break; - case "a t-shirt and jeans": - r += `Blue jeans, t-shirt.`; - break; - case "boyshorts": - r += `Boy shorts.`; - break; - case "cutoffs": - r += `Jean shorts.`; - break; - case "leather pants and pasties": - r += `Leather pants, pasties.`; - break; - case "leather pants": - r += `Nice leather pants.`; - break; - case "panties": - r += `Nice panties.`; - break; - case "sport shorts and a t-shirt": - r += `Nice sport shorts, shirt.`; - break; - case "a t-shirt and panties": - r += `Panties, t-shirt.`; - break; - case "panties and pasties": - r += `Pasties, panties.`; - break; - case "pasties": - r += `Pasties.`; - break; - case "striped underwear": - r += `Striped underwear`; - break; - case "sport shorts and a sports bra": - r += `Shorts, bra.`; - break; - case "jeans": - r += `Tight blue jeans.`; - break; - case "a sweater and cutoffs": - r += `Jean shorts, sweater.`; - break; - case "leather pants and a tube top": - r += `Leather pants, tube top.`; - break; - case "sport shorts": - r += `Shorts.`; - break; - default: - r += `Naked.`; - break; + function long_clothes(slave, c) { + function descStr() { + switch (slave.clothes) { + case "attractive lingerie": + return `Nice lingerie.`; + case "a succubus outfit": + return `Succubus outfit.`; + case "a string bikini": + return `String bikini.`; + case "a scalemail bikini": + return `Scalemail bikini.`; + case "striped panties": + return `Striped panties.`; + case "a monokini": + return `Monokini.`; + case "an apron": + return `Apron.`; + case "a cybersuit": + return `Cybersuit.`; + case "cutoffs and a t-shirt": + return `Cutoffs, t-shirt.`; + case "a slutty outfit": + return `Slutty outfit.`; + case "uncomfortable straps": + return `Leather straps.`; + case "a fallen nuns habit": + return `Slutty habit.`; + case "a chattel habit": + return `Chattel habit.`; + case "a penitent nuns habit": + return `Cilice.`; + case "slutty jewelry": + return `Bangles.`; + case "attractive lingerie for a pregnant woman": + return `Preggo lingerie.`; + case "a maternity dress": + return `Maternity dress.`; + case "stretch pants and a crop-top": + return `Stretch pants, crop-top.`; + case "harem gauze": + return `Harem outfit.`; + case "a slave gown": + return `Slave gown.`; + case "a halter top dress": + return `Halter top dress.`; + case "a mini dress": + return `Mini dress.`; + case "a ball gown": + return `Ball gown.`; + case "slutty business attire": + return `Slutty suit.`; + case "nice business attire": + return `Nice suit.`; + case "a comfortable bodysuit": + return `Bodysuit.`; + case "a military uniform": + return `Military uniform.`; + case "a schutzstaffel uniform": + return `Schutzstaffel uniform.`; + case "a slutty schutzstaffel uniform": + return `Slutty Schutzstaffel uniform.`; + case "a red army uniform": + return `Red Army uniform.`; + case "a long qipao": + return `Long Qipao.`; + case "battlearmor": + return `Battlearmor.`; + case "a mounty outfit": + return `Mounty outfit.`; + case "a dirndl": + return `Dirndl.`; + case "lederhosen": + return `Lederhosen.`; + case "a biyelgee costume": + return `Biyelgee costume.`; + case "a leotard": + return `Leotard.`; + case "a bunny outfit": + return `Bunny outfit.`; + case "a slutty maid outfit": + return `Slutty maid.`; + case "a nice maid outfit": + return `Nice maid.`; + case "a slutty nurse outfit": + return `Slutty nurse.`; + case "a nice nurse outfit": + return `Nice nurse.`; + case "a schoolgirl outfit": + return `Schoolgirl outfit.`; + case "a kimono": + return `Kimono.`; + case "a hijab and abaya": + return `Hijab and abaya.`; + case "battledress": + return `Battledress.`; + case "a latex catsuit": + return `Nice latex.`; + case "restrictive latex": + return `Bondage latex.`; + case "conservative clothing": + return `Conservative clothing.`; + case "chains": + return `Chains.`; + case "overalls": + return `Overalls.`; + case "a cheerleader outfit": + return `Cheerleader.`; + case "clubslut netting": + return `Netting.`; + case "shibari ropes": + return `Shibari.`; + case "Western clothing": + return `Chaps.`; + case "body oil": + return `Body oil.`; + case "a toga": + return `Toga.`; + case "a huipil": + return `Huipil.`; + case "a slutty qipao": + return `Slutty qipao.`; + case "spats and a tank top": + return `Spats, tank top.`; + case "a burkini": + return `Burkini.`; + case "a niqab and abaya": + return `Niqab and abaya.`; + case "a klan robe": + return `Klan robe.`; + case "a hijab and blouse": + return `Hijab and blouse.`; + case "a burqa": + return `Burqa.`; + case "kitty lingerie": + return `Kitty lingerie.`; + case "a tube top and thong": + return `Tube top, thong.`; + case "a button-up shirt and panties": + return `Button-up shirt, panties.`; + case "a gothic lolita dress": + return `Gothic lolita dress.`; + case "a hanbok": + return `Hanbok.`; + case "a bra": + return `Nice bra.`; + case "a button-up shirt": + return `Nice button-up shirt.`; + case "a nice pony outfit": + return `Nice pony outfit.`; + case "a sweater": + return `Nice sweater.`; + case "a tank-top": + return `Nice tank-top.`; + case "a thong": + return `Nice thong.`; + case "a tube top": + return `Nice tube top.`; + case "a one-piece swimsuit": + return `Swimsuit.`; + case "a police uniform": + return `Police uniform.`; + case "a striped bra": + return `Striped bra.`; + case "a skimpy loincloth": + return `Skimpy loincloth.`; + case "a slutty klan robe": + return `Slutty klan robe.`; + case "a slutty pony outfit": + return `Slutty pony outfit.`; + case "a Santa dress": + return `Santa dress.`; + case "a sports bra": + return `Sports bra.`; + case "a sweater and panties": + return `Sweater, panties.`; + case "a t-shirt": + return `T-shirt.`; + case "a tank-top and panties": + return `Tank-top, panties.`; + case "a t-shirt and thong": + return `Thong, t-shirt.`; + case "an oversized t-shirt and boyshorts": + return `Over-sized t-shirt, boy shorts.`; + case "an oversized t-shirt": + return `Nice over-sized t-shirt.`; + case "a t-shirt and jeans": + return `Blue jeans, t-shirt.`; + case "boyshorts": + return `Boy shorts.`; + case "cutoffs": + return `Jean shorts.`; + case "leather pants and pasties": + return `Leather pants, pasties.`; + case "leather pants": + return `Nice leather pants.`; + case "panties": + return `Nice panties.`; + case "sport shorts and a t-shirt": + return `Nice sport shorts, shirt.`; + case "a t-shirt and panties": + return `Panties, t-shirt.`; + case "panties and pasties": + return `Pasties, panties.`; + case "pasties": + return `Pasties.`; + case "striped underwear": + return `Striped underwear`; + case "sport shorts and a sports bra": + return `Shorts, bra.`; + case "jeans": + return `Tight blue jeans.`; + case "a sweater and cutoffs": + return `Jean shorts, sweater.`; + case "leather pants and a tube top": + return `Leather pants, tube top.`; + case "sport shorts": + return `Shorts.`; + default: + return `Naked.`; + } } - r += " "; + makeSpan(c, descStr()); } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_collar(slave) { - switch (slave.collar) { - case "uncomfortable leather": - r += `Leather collar.`; - break; - case "tight steel": - r += `Steel collar.`; - break; - case "preg biometrics": - r += `Pregnancy biometrics collar.`; - break; - case "cruel retirement counter": - r += `Cruel counter collar.`; - break; - case "shock punishment": - r += `Shock collar.`; - break; - case "dildo gag": - r += `Dildo gag.`; - break; - case "massive dildo gag": - r += `Throat-bulging dildo gag.`; - break; - case "neck corset": - r += `Neck corset.`; - break; - case "stylish leather": - r += `Stylish leather collar.`; - break; - case "satin choker": - r += `Satin choker.`; - break; - case "silk ribbon": - r += `Silken ribbon.`; - break; - case "heavy gold": - r += `Gold collar.`; - break; - case "bowtie": - r += `Bowtie collar.`; - break; - case "pretty jewelry": - r += `Pretty collar.`; - break; - case "nice retirement counter": - r += `Nice counter collar.`; - break; - case "bell collar": - r += `Bell collar.`; - break; - case "leather with cowbell": - r += `Cowbell collar.`; - break; - case "ancient Egyptian": - r += `Wesekh.`; - break; - case "ball gag": - r += `Ball gag.`; - break; - case "bit gag": - r += `Bit gag.`; - break; - case "porcelain mask": - r += `Porcelain mask.`; - break; + function long_collar(slave, c) { + function descStr() { + switch (slave.collar) { + case "uncomfortable leather": + return `Leather collar.`; + case "tight steel": + return `Steel collar.`; + case "preg biometrics": + return `Pregnancy biometrics collar.`; + case "cruel retirement counter": + return `Cruel counter collar.`; + case "shock punishment": + return `Shock collar.`; + case "dildo gag": + return `Dildo gag.`; + case "massive dildo gag": + return `Throat-bulging dildo gag.`; + case "neck corset": + return `Neck corset.`; + case "stylish leather": + return `Stylish leather collar.`; + case "satin choker": + return `Satin choker.`; + case "silk ribbon": + return `Silken ribbon.`; + case "heavy gold": + return `Gold collar.`; + case "bowtie": + return `Bowtie collar.`; + case "pretty jewelry": + return `Pretty collar.`; + case "nice retirement counter": + return `Nice counter collar.`; + case "bell collar": + return `Bell collar.`; + case "leather with cowbell": + return `Cowbell collar.`; + case "ancient Egyptian": + return `Wesekh.`; + case "ball gag": + return `Ball gag.`; + case "bit gag": + return `Bit gag.`; + case "porcelain mask": + return `Porcelain mask.`; + default: + return null; + } + } + const s = descStr(); + if (s) { + makeSpan(c, s); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_belly(slave) { - switch (slave.bellyAccessory) { - case "shapewear": - r += `Shapewear.`; - break; - case "a small empathy belly": - r += `Small fake belly.`; - break; - case "a medium empathy belly": - r += `Medium fake belly.`; - break; - case "a large empathy belly": - r += `Large fake belly.`; - break; - case "a huge empathy belly": - r += `Huge fake belly.`; - break; - case "a corset": - r += `Corset.`; - break; - case "an extreme corset": - r += `Extreme corsetage.`; - break; + function long_belly(slave, c) { + function descStr() { + switch (slave.bellyAccessory) { + case "shapewear": + return `Shapewear.`; + case "a small empathy belly": + return `Small fake belly.`; + case "a medium empathy belly": + return `Medium fake belly.`; + case "a large empathy belly": + return `Large fake belly.`; + case "a huge empathy belly": + return `Huge fake belly.`; + case "a corset": + return `Corset.`; + case "an extreme corset": + return `Extreme corsetage.`; + default: + return null; + } + } + const s = descStr(); + if (s) { + makeSpan(c, s); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_arms(slave) { - if (slave.armAccessory === "hand gloves") { - r += `Hand gloves.`; - } else if (slave.armAccessory === "elbow gloves") { - r += `Elbow gloves.`; + function long_arms(slave, c) { + if (["hand gloves", "elbow gloves"].includes(slave.armAccessory)) { + makeSpan(c, slave.armAccessory, undefined, true); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_legs(slave) { + function long_legs(slave, c) { if (slave.legAccessory === "short stockings") { - r += `Short stockings.`; + makeSpan(c, "Short stockings."); } else if (slave.legAccessory === "long stockings") { - r += `Long stockings.`; + makeSpan(c, "Long stockings."); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_shoes(slave) { - if (slave.shoes === "heels") { - r += `Heels.`; - } else if (slave.shoes === "pumps") { - r += `Pumps.`; - } else if (slave.shoes === "extreme heels") { - r += `Extreme heels.`; - } else if (slave.shoes === "boots") { - r += `Boots.`; + function long_shoes(slave, c) { + if (["heels", "pumps", "extreme heels", "boots", "flats"].includes(slave.shoes)) { + makeSpan(c, slave.shoes, undefined, true); } else if (slave.heels === 1) { - r += `<span class="yellow">Crawling.</span>`; - } else if (slave.shoes === "flats") { - r += `Flats.`; + makeSpan(c, "Crawling.", "yellow"); } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_chastity(slave) { + function long_chastity(slave, c) { if (slave.chastityAnus === 1 && slave.chastityPenis === 1 && slave.chastityVagina === 1) { - r += `Full chastity.`; + makeSpan(c, "Full chastity."); } else if (slave.chastityPenis === 1 && slave.chastityVagina === 1) { - r += `Genital chastity.`; + makeSpan(c, "Genital chastity."); } else if ((slave.chastityAnus === 1 && slave.chastityVagina === 1) || (slave.chastityAnus === 1 && slave.chastityPenis === 1)) { - r += `Combined chastity.`; + makeSpan(c, "Combined chastity."); } else if (slave.chastityVagina === 1) { - r += `Vaginal chastity.`; + makeSpan(c, "Vaginal chastity."); } else if (slave.chastityPenis === 1) { - r += `Chastity cage.`; + makeSpan(c, "Chastity cage."); } else if (slave.chastityAnus === 1) { - r += `Anal chastity.`; + makeSpan(c, "Anal chastity."); } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_vaginal_acc(slave) { + function long_vaginal_acc(slave, c) { if (slave.vaginalAttachment !== "vibrator") { switch (slave.vaginalAccessory) { case "bullet vibrator": - r += `Attached bullet vibrator.`; + makeSpan(c, "Attached bullet vibrator."); break; case "smart bullet vibrator": - r += `Attached smart bullet vibrator.`; + makeSpan(c, "Attached smart bullet vibrator."); break; case "dildo": - r += `Vaginal dildo.`; + makeSpan(c, "Vaginal dildo."); break; case "large dildo": - r += `Large vaginal dildo.`; + makeSpan(c, "Large vaginal dildo."); break; case "huge dildo": - r += `Huge vaginal dildo.`; + makeSpan(c, "Huge vaginal dildo."); break; case "long dildo": - r += `Long vaginal dildo.`; + makeSpan(c, "Long vaginal dildo."); break; case "long, large dildo": - r += `Long and large vaginal dildo.`; + makeSpan(c, "Long and large vaginal dildo."); break; case "long, huge dildo": - r += `Long and wide vaginal dildo.`; + makeSpan(c, "Long and wide vaginal dildo."); break; } } - r += " "; if (slave.vaginalAttachment !== "none") { switch (slave.vaginalAttachment) { case "vibrator": - r += `Vibrating dildo.`; + makeSpan(c, "Vibrating dildo."); break; } - r += " "; } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_dick_acc(slave) { + function long_dick_acc(slave, c) { switch (slave.dickAccessory) { case "sock": - r += `Cock sock.`; + makeSpan(c, "Cock sock."); break; case "bullet vibrator": - r += `Frenulum bullet vibrator.`; + makeSpan(c, "Frenulum bullet vibrator."); break; case "smart bullet vibrator": - r += `Smart frenulum bullet vibrator.`; + makeSpan(c, "Smart frenulum bullet vibrator."); break; } - r += " "; } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function long_buttplug(slave) { + function long_buttplug(slave, c) { switch (slave.buttplug) { case "plug": - r += `Buttplug.`; + makeSpan(c, "Buttplug."); break; case "large plug": - r += `Large buttplug.`; + makeSpan(c, "Large buttplug."); break; case "huge plug": - r += `Huge buttplug.`; + makeSpan(c, "Huge buttplug."); break; case "long plug": - r += `Long buttplug.`; + makeSpan(c, "Long buttplug."); break; case "long, large plug": - r += `Large, long buttplug.`; + makeSpan(c, "Large, long buttplug."); break; case "long, huge plug": - r += `Enormous buttplug.`; + makeSpan(c, "Enormous buttplug."); break; } - r += " "; switch (slave.buttplugAttachment) { case "tail": - r += `Attached tail. `; + makeSpan(c, "Attached tail."); break; case "cat tail": - r += `Attached cat tail. `; + makeSpan(c, "Attached cat tail."); break; case "fox tail": - r += `Attached fox tail. `; + makeSpan(c, "Attached fox tail."); break; case "cow tail": - r += `Attached cow tail. `; + makeSpan(c, "Attached cow tail."); break; } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function rules_assistant(slave) { + function rules_assistant(slave, c) { if (slave.useRulesAssistant === 0) { - r += `<span class="lightgreen">RA-Exempt</span> `; + makeSpan(c, "RA-Exempt", "lightgreen"); } else if (V.abbreviateRulesets === 2 && (slave.currentRules !== undefined) && (slave.currentRules.length > 0)) { - r += `Rules: ${V.defaultRules.filter(x => ruleApplied(slave, x)).map(x => x.name).join(", ")}`; + c.appendChild(document.createTextNode(`Rules: ${V.defaultRules.filter(x => ruleApplied(slave, x)).map(x => x.name).join(", ")}`)); } } /** * @param {App.Entity.SlaveState} slave + * @param {Node} c + * @returns {void} */ - function origins(slave) { - r += `<br>`; - if (V.seeImages !== 1 || V.seeSummaryImages !== 1 || V.imageChoice === 1) { - r += ` `; - } + function origins(slave, c) { + const para = makeParagraph(c); + para.classList.add("gray"); const pronouns = getPronouns(slave); - r += `<span class="gray">${slave.origin.replace(/\$([A-Z]?[a-z]+)/g, (match, cap1) => pronouns[cap1] || match)}</span>`; + para.textContent = `${slave.origin.replace(/\$([A-Z]?[a-z]+)/g, (match, cap1) => pronouns[cap1] || match)}`; + } + + /** + * @param {HTMLElement} element + * @param {string|string[]} [classNames] + */ + function _addClassNames(element, classNames) { + if (classNames != undefined) { /* eslint-disable-line eqeqeq */ + if (Array.isArray(classNames)) { + element.classList.add(...classNames); + } else { + element.classList.add(classNames); + } + } + } + + /** + * @param {Node} container + * @param {string} text + * @param {string|string[]} [classNames] + * @param {boolean} [stdDecor=false] + * @param {number} [value] + */ + function makeSpan(container, text, classNames, stdDecor = false, value) { + let r = document.createElement("span"); + r.classList.add("ssi"); + _addClassNames(r, classNames); + if (value != undefined && V.summaryStats) { /* eslint-disable-line eqeqeq */ + text += `[${value}]`; + } + r.textContent = stdDecor ? `${capFirstChar(text)}.` : text; + if (container) { + container.appendChild(r); + } + return r; + } + + /** + * @param {Node} container + * @param {string} text + * @returns {Text} + */ + function addText(container, text) { + const r = document.createTextNode(text); + if (container) { + container.appendChild(r); + } + return r; + } + + /** + * @param {Node} [container] + * @param {string|string[]} [classNames] + */ + function makeBlock(container, classNames) { + let r = document.createElement("span"); + r.classList.add("ssb"); + _addClassNames(r, classNames); + if (container) { + container.appendChild(r); + } + return r; + } + + /** + * @param {Node} container + * @param {string|string[]} [classNames] + * @returns {HTMLParagraphElement} + */ + function makeParagraph(container, classNames) { + let r = document.createElement("p"); + r.classList.add("si"); + _addClassNames(r, classNames); + if (container) { + container.appendChild(r); + } + return r; + } + + /** + * @param {Node} container + * @param {string} name + * @param {string} content + */ + function tag(container, name, content) { + let r = document.createElement(name); + r.textContent = content; + if (container) { + container.appendChild(r); + } + return r; } return SlaveSummaryUncached; + })(); diff --git a/src/js/utilsDOM.js b/src/js/utilsDOM.js new file mode 100644 index 0000000000000000000000000000000000000000..094cd5751c84e2db12a32d47243c62faddeb3d1e --- /dev/null +++ b/src/js/utilsDOM.js @@ -0,0 +1,170 @@ +/** + * @callback passageLinkHandler + * @returns {void} + */ +/** + * Creates a HTML element with custom SugarCube attributes which works as a passage link + * + * The result works in the same way as the wiki markup in the SugarCube + * @see https://www.motoslave.net/sugarcube/2/docs/#markup-html-attribute + * @param {string} linkText link text + * @param {string} passage the passage name to link to + * @param {passageLinkHandler} [handler] setter text (optional) + * @param {string} [tooltip=''] tooltip text (optional) + * @param {string} [elementType='a'] element type (optional) default is 'a'. + * Could be any of 'a', 'audio', img', 'source', 'video' + * @returns {HTMLElement} element text + * + * @example + * // equal to [[Go to town|Town]] + * App.UI.passageLink("Go to town", "Town") + */ +App.UI.DOM.passageLink = function(linkText, passage, handler, tooltip = '', elementType = 'a') { + let res = document.createElement(elementType); + res.setAttribute("data-passage", passage); + res.onclick = (ev) => { + ev.preventDefault(); + if (handler) { + handler(); + } + Engine.play(passage); + }; + + if (tooltip) { + res.title = tooltip; + } + res.textContent = linkText; + return res; +}; + +/** + * Returns link element for an assignment + * @param {App.Entity.SlaveState} slave + * @param {string} assignment + * @param {string} [passage] passage to go to + * @param {assignmentCallback} [callback] + * @param {string} [linkText] + * @returns {HTMLAnchorElement} + */ +App.UI.DOM.assignmentLink = function(slave, assignment, passage, callback, linkText) { + let res = document.createElement("a"); + res.textContent = linkText; + res.onclick = (e) => { + e.preventDefault(); + assignJob(slave, assignment); + if (callback) { + callback(this.desc.assignment); + } + if (passage !== '') { + SugarCube.Engine.play(passage); + } + }; + return res; +}; + +App.UI.DOM.link = function() { + return makeLink; + + /** + * Creates a markup for a SugarCube link which executes given function with given arguments + * + * @param {string} linkText link text + * @param {*} handler callable object + * @param {*} args arguments + * @param {string} [passage] the passage name to link to + * @returns {HTMLAnchorElement} link in SC markup + */ + function makeLink(linkText, handler, args = [], passage = '', tooltip = '') { + const hArgs = Array.isArray(args) ? args : [args]; + let link = document.createElement("a"); + link.textContent = linkText; + link.title = tooltip; + link.onclick = () => { + handler(...hArgs); + if (passage !== '') { + SugarCube.Engine.play(passage); + } + }; + return link; + } +}(); + +/** + * Creates a span for an link with tooltip containing the reasons why it is disabled + * @param {string} link + * @param {string[]} reasons + * @returns {HTMLSpanElement} + */ +App.UI.DOM.disabledLink = function(link, reasons) { + /** @type {HTMLElement} */ + let tooltip; + if (reasons.length === 1) { + tooltip = document.createElement("span"); + tooltip.textContent = reasons[0]; + } else { + tooltip = document.createElement("div"); + let ul = document.createElement("ul"); + for (const li of reasons.map(r => { + const li = document.createElement("li"); + li.textContent = r; + return li; + })) { + ul.appendChild(li); + } + } + tooltip.className = "tooltip"; + let res = document.createElement("span"); + res.textContent = link; + res.className = "textWithTooltip"; + res.appendChild(tooltip); + return res; +}; + +/** +* @param {string} text +* @param {string|string[]} [classNames] +*/ +App.UI.DOM.makeSpan = function makeSpan(text, classNames) { + let r = document.createElement("span"); + if (classNames !== undefined) { + if (Array.isArray(classNames)) { + r.classList.add(...classNames); + } else { + r.classList.add(classNames); + } + } + r.innerHTML = text; + return r; +}; + +/** + * @param {string} passage + * @return {Element} + */ +App.Utils.passageElement = function(passage) { + return document.querySelector(`tw-passagedata[name="${passage}"]`); +}; + +/** + * @param {Node[]} nodes + * @returns {DocumentFragment} + */ +App.UI.DOM.combineNodes = function(...nodes) { + let res = document.createDocumentFragment(); + for (const n of nodes) { + res.appendChild(n); + } + return res; +}; + +/** + * @param {string} text + * @returns {HTMLElement} + */ +App.Utils.htmlToElement = function(text) { + const template = document.createElement("template"); + text = text.trim(); // Never return a text node of whitespace as the result + template.innerHTML = text; + // @ts-ignore + return template.content.firstChild; +}; diff --git a/src/npc/agent/agentSelect.tw b/src/npc/agent/agentSelect.tw index 5c6ff3eaf43e6ac97bcd2aa2b1b6938144c2ba39..3fb70d8818209ddf2e0d1874e6bc212c64d7f8f2 100644 --- a/src/npc/agent/agentSelect.tw +++ b/src/npc/agent/agentSelect.tw @@ -5,6 +5,7 @@ <<= App.UI.SlaveList.slaveSelectionList( s => (s.fuckdoll === 0 && s.devotion > 20 && s.intelligence + s.intelligenceImplant > 15 && s.intelligenceImplant >= 15 && canWalk(s) && canSee(s) && canHear(s) && canTalk(s) && s.broodmother < 2 && (s.breedingMark !== 1 || State.variables.propOutcome === 0 || State.variables.eugenicsFullControl === 1 || State.variables.arcologies[0].FSRestart === "unset")), - (slave, index) => App.UI.passageLink(SlaveFullName(slave), 'Agent Workaround', `$i = ${index}`), + (slave, index) => App.UI.DOM.passageLink(SlaveFullName(slave), 'Agent Workaround', + () => { variables().i = index; }), s => App.Entity.facilities.arcologyAgent.manager.slaveHasExperience(s) )>> diff --git a/src/uncategorized/coursingAssociation.tw b/src/uncategorized/coursingAssociation.tw index 083551e337a2d136ebffc1641d936ebc37ad38f4..a0ca2d88441f1429ac3915bf2ab402598447cf2d 100644 --- a/src/uncategorized/coursingAssociation.tw +++ b/src/uncategorized/coursingAssociation.tw @@ -16,7 +16,7 @@ The chasing slaves are known as lurchers, the term once used for the sighthounds <<if $Lurcher != 0>> <br><br>''Fire your Lurcher:'' - <<= App.UI.SlaveList.render([App.Utils.slaveIndexForId($Lurcher.ID)], [], + <<= App.UI.SlaveList.render.listMarkup([App.Utils.slaveIndexForId($Lurcher.ID)], [], (slave, index) => App.UI.passageLink(SlaveFullName(slave), 'Retrieve', `$i = ${App.Utils.slaveIndexForId($Lurcher.ID)}`))>> <</if>> @@ -24,5 +24,5 @@ The chasing slaves are known as lurchers, the term once used for the sighthounds <br><br> <<= App.UI.SlaveList.slaveSelectionList( s => $Lurcher.ID !== s.ID && canWalk(s) && (s.assignmentVisible === 1 && s.fuckdoll === 0), - (slave, index) => App.UI.passageLink(SlaveFullName(slave), 'Assign', `$i = ${index}`) + (slave, index) => App.UI.DOM.passageLink(SlaveFullName(slave), 'Assign', () => { variables().i = index; }) )>> diff --git a/src/uncategorized/matchmaking.tw b/src/uncategorized/matchmaking.tw index b5429aaca992e70e2438c094e4c519b5eea503d5..3b15c83ef7ae22974a6289cc73e2c9506bc11414 100644 --- a/src/uncategorized/matchmaking.tw +++ b/src/uncategorized/matchmaking.tw @@ -385,7 +385,7 @@ Despite $his devotion and trust, $he is still a slave, and probably knows that $ s => s.devotion >= 100 && s.relationship === $activeSlave.relationship && s.ID !== $activeSlave.ID, App.UI.SlaveList.SlaveInteract.stdInteract, null, - (s, i) => App.UI.passageLink('Match them', 'Matchmaking', `$subSlave = $slaves[${i}]`) + (s, i) => App.UI.DOM.passageLink('Match them', 'Matchmaking', () => { variables().subSlave = App.Utils.slaveByIndex(i); }) )>> </span> diff --git a/src/uncategorized/options.tw b/src/uncategorized/options.tw index cf52a4c26aceb8d487fee25284ecc69a41a1b38b..c33e7848415a95b964fd2dc88a0f88e8fbcf15e7 100644 --- a/src/uncategorized/options.tw +++ b/src/uncategorized/options.tw @@ -296,7 +296,7 @@ This save was created using FC version $ver build $releaseID. <</options>> <<if $seeImages > 0>> - <div style="position:relative;width:200px;height:200px;margin:0 auto;"> + <div class="imageRef" style="width:200px;height:200px;margin:0 auto;"> <<= SlaveArt(BaseSlave(), 0, 0)>> </div> diff --git a/src/uncategorized/personalAttentionSelect.tw b/src/uncategorized/personalAttentionSelect.tw index 818ea3557201c450e3281425b83651fde484de1a..bea85578a9ceff32296d6cffc9fa67dba70948ee 100644 --- a/src/uncategorized/personalAttentionSelect.tw +++ b/src/uncategorized/personalAttentionSelect.tw @@ -350,5 +350,5 @@ <br><br>__Select a slave to train:__ <<if $PC.slaving >= 100>>//Your @@.springgreen;slaving experience@@ allows you to divide your attention between more than one slave each week, with slightly reduced efficiency//<</if>> <<= App.UI.SlaveList.slaveSelectionList( s => s.assignmentVisible === 1 && s.fuckdoll === 0, - s => `<<link "${SlaveFullName(s)}">><<run App.UI.selectSlaveForPersonalAttention(${s.ID})>><</link>>` + s => App.UI.DOM.link(SlaveFullName(s), (id) => {App.UI.selectSlaveForPersonalAttention(id); }, s.ID) )>> diff --git a/src/uncategorized/rulesSlaveSelect.tw b/src/uncategorized/rulesSlaveSelect.tw index abda187c938d3914eb83c4c2999e9c17fa213fdb..7b72d51ff14f3bdd25acf649858b16f62a669d88 100644 --- a/src/uncategorized/rulesSlaveSelect.tw +++ b/src/uncategorized/rulesSlaveSelect.tw @@ -12,18 +12,33 @@ Select slaves to exclude from Rule $r: <<print App.UI.SlaveList.slaveSelectionList( s => !ruleSlaveSelected(s, $currentRule), - (s, i) => `<u><strong>${App.UI.passageLink(SlaveFullName(s), 'Rules Slave Select Workaround', `$activeSlave = $slaves[${i}]`)}</strong></u>` + (s, i) => { + let l = App.UI.DOM.passageLink(SlaveFullName(s), 'Rules Slave Select Workaround', + () => { App.Utils.setActiveSlaveByIndex(i); }); + l.classList.add("emphasizedSlave"); + return l; + } )>> <<else>> Rule $r currently limited to specific slaves: [[Clear list|Rules Slave Select][$currentRule.selectedSlaves = []]] <<print App.UI.SlaveList.slaveSelectionList( s => ruleSlaveSelected(s, $currentRule), - (s, i) => `<u><strong>${App.UI.passageLink(SlaveFullName(s), 'Rules Slave Deselect Workaround', `$activeSlave = $slaves[${i}]`)}</strong></u>` + (s, i) => { + let l = App.UI.DOM.passageLink(SlaveFullName(s), 'Rules Slave Deselect Workaround', + () => { App.Utils.setActiveSlaveByIndex(i); }); + l.classList.add("emphasizedSlave"); + return l; + } )>> <br><br> Choose more specific slaves: <<print App.UI.SlaveList.slaveSelectionList( s => !ruleSlaveSelected(s, $currentRule), - (s, i) => `<u><strong>${App.UI.passageLink(SlaveFullName(s), 'Rules Slave Select Workaround', `$activeSlave = $slaves[${i}]`)}</strong></u>` + (s, i) => { + let l = App.UI.DOM.passageLink(SlaveFullName(s), 'Rules Slave Select Workaround', + () => { App.Utils.setActiveSlaveByIndex(i); }); + l.classList.add("emphasizedSlave"); + return l; + } )>> <</if>> diff --git a/src/uncategorized/subordinateTargeting.tw b/src/uncategorized/subordinateTargeting.tw index a742da8af47876f40994340b5ebf7799eda33e34..7d90320cc0b9a8854b8fcfcb78d485733080c893 100644 --- a/src/uncategorized/subordinateTargeting.tw +++ b/src/uncategorized/subordinateTargeting.tw @@ -21,7 +21,7 @@ <<= App.UI.SlaveList.slaveSelectionList( s => s.devotion >= -20 && s.fuckdoll === 0 && State.variables.activeSlave.ID !== s.ID && (State.variables.activeSlave.amp !== 1 || s.amp !== 1), - (s, i) => App.UI.passageLink(SlaveFullName(s), 'Subordinate Targeting', `$activeSlave.subTarget = ${s.ID}`), + (s, i) => App.UI.DOM.passageLink(SlaveFullName(s), 'Subordinate Targeting', () => { App.activeSlave.subTarget = s.ID; }), )>> <br><br>[[None|Subordinate Targeting][$activeSlave.subTarget = 0]]