code:
"use strict";

    var Combat = function(name, health) {
        this.name = name;
        this.health = health;
        this.max_health = health;
        this.power = 1;
        this.nextround = 0;

        this.held = 0;
        this.iscapturable = false;
        this.proc_countdown = 0;

        this.companionaction = 0;
        this.playeraction = 0;

        this.procs = [];
        this.proc_frequency = 0;
        this.proc_selected = 0;
        this.active_procs = [];
        this.active_proc_time = [];
        this.enemytype = -1;
    }

    /* Some quick docs to the arrays:
     * combat: [ min power, base power, companion reduction multiplier, max health ],
     * race: [ 'any', 'random', 'race' ]
     * willpower: [ base, +random ]
     */

    Data_.prototype.getEncounter = function(name) {
        if (typeof(name) == 'object')
            throw new Error("getEncounter expected a name, got an object: " + name);
        if (name.toLowerCase() in this.encounter)
            return this.encounter[name.toLowerCase()];
        else
            throw new Error("Encounter not found: " + name);
    }

    Data.encounter = {}

    var EnemyEncounter = function(args) {
        this.description = 'FIXME';
        this.aggressive = false;
        this.aggro_avoid = 0;
        this.aggro_description = 'FIXME'
        this.sneaky = 0;
        this.race = 'human';
        this.face = undefined;
        this.loyalty = undefined;
        this.obedience = undefined;
        this.willpower = 1;
        this.backstory = undefined;
        this.name = 'FIXME';
        this.health = 1;
        this.iscapturable = false;
        this.engage_button = 'Attack';
        this.avoid_button = 'Avoid';
        this.slavers = false;

        this.enemytype = -1;

        this.procs = [];
        this.proc_frequency = 0;

        this.power_min = 1;
        this.power_base = 1;
        this.companion_mult = 1;
        this.gold = 0;
        this.food = 0;

        if (!( (typeof args === "object") && (args !== null) ))
            throw("EnemyEncounter() requires proper construction");

        // build an enemy
        var mandatory = [ 'name', 'combat' ];

        if ('proc' in args)
            mandatory.push('proc_frequency');

        if ('willpower' in args || 'race' in args) {
            mandatory.push('race');
            this.iscapturable = true;
            this.engage_button = 'Attack her';
        } else if ('food' in args)
            mandatory.push('food');
        else
            mandatory.push('gold');

        if (args.slavers == true) {
            this.engage_button = 'Fight for her';
            this.description = "The group of slavers are leading a captured {{race}} girl.  You can't say anything else aobut her without getting closer.";
        } else
            mandatory.push('description');

        if ('aggro_avoid' in args || 'aggro_description' in args) {
            this.aggressive = true;
            this.engage_button = 'Fight';
            mandatory = mandatory.concat(['aggro_description', 'aggro_avoid']);
        }

        var failed = '';
        for (var i = 0; i < mandatory.length; i++) {
            if (!(mandatory[i] in args))
                failed += 'EnemyEncounter() expected ' + mandatory[i] + ' in args\n';
        }
        if (failed !== '')
            throw new Error(failed);

        args.power_min = args.combat[0];
        args.power_base = args.combat[1];
        args.companion_mult = args.combat[2];
        args.health = args.combat[3];
        delete args.combat;

        var keys = Object.keys(this);
        for(var i = 0; i < keys.length; i++)
            if (this.hasOwnProperty(keys[i]) && keys[i] in args)
                this[keys[i]] = args[keys[i]];

        var keys = Object.keys(args);
        for (var i = 0; i < keys.legnth; i++)
            if (!this.hasOwnProperty(keys[i]))
                console.Log("EnemyEncounter(): unknown property " + keys[i]);
    };

    EnemyEncounter.prototype.display = function() {
        if (this.aggressive && Game.Girls[Game.companion].skill.survival < this.aggro_avoid)
            var desc = this.aggro_description;
        else
            var desc = this.description;

        if (typeof(desc) === 'function')
            desc = desc();

        Game.combat = new Combat(this.name, this.health);
        Game.combat.procs = this.procs;
        Game.combat.proc_frequency = this.proc_frequency;
        Game.combat.power = Math.max(this.power_min, this.power_base - Game.Girls[Game.companion].skill.combat * this.companion_mult);
        Game.combat.iscapturable = this.iscapturable;
        if (typeof(this.gold) === 'function')
            Game.combat.gold = this.gold();
        else if (isArray(this.gold))
            Game.combat.gold = Math.tossDice.apply(this, this.gold);
        else
            Game.combat.gold = this.gold;

        if (typeof(this.food) === 'function')
            Game.combat.food = this.food();
        else if (isArray(this.food))
            Game.combat.food = Math.tossDice.apply(this, this.food);
        else
            Game.combat.food = this.food;

        if (this.iscapturable) {
            console.log("Making a new girl");

            if (typeof(this.willpower) == 'function')
                var will = this.willpower();
            else if (isArray(this.willpower))
                var will = Math.tossDice.apply(this, this.willpower);
            else
                var will = this.willpower;

            if (typeof(this.race) == 'function')
                var race = this.race();
            else if (isArray(this.race))
                var race = this.race.random();
            else
                var race = this.race;

            Game.newgirl = new Girl();
            Game.newgirl.generate(race, undefined, will);
            if (isArray(this.face))
                Game.newgirl.body.face.beauty = Math.tossDice.apply(this, this.face);
            if (isArray(this.obedience))
                Game.newgirl.obedience = Math.tossDice.apply(this, this.obedience);
            if (isArray(this.loyalty))
                Game.newgirl.loyalty = Math.tossDice.apply(this, this.loyalty);

            if (this.backstory !== undefined)
                Game.newgirl.backstory = this.backstory;
        }

        if (this.slavers)
            Game.combat.enemytype = 7;
        else
            Game.combat.enemytype = this.enemytype;

        var repl = {
            race: race,
            companion: Game.Girls[Game.companion].name,
            name: this.name,
        };

        /* do some substitution */
        desc = simple_template(desc, repl);

        /* No output until here. */
        ToText(desc + "

");

        if (this.slavers) {
            ToText("Greet them
");
            // do NOT show the girl description if she's held by slavers.
        } else if (this.iscapturable) {
            ToText(Game.newgirl.describe({ profile: 'enemy' }));
            ToText("
");
        }

        ToText("" + this.engage_button + "
");
        if (this.aggressive && Game.Girls[Game.companion].skill.survival < this.aggro_avoid)
            return; // can't avoid this encounter

        Object.forEach(Game.spells_known, function(k, v) {
            if (v < 1 || !Data.Spell[k].Target('encounter'))
                return;
            if (Game.mana > Data.Spell[k].cost)
                ToText("Cast "+Data.Spell[k].name+"
");
            else
                ToText("Cast " + Data.Spell[k].name + " - not enough mana (" +Data.Spell[k].cost+")
");
        });

        ToText(""+this.avoid_button + "
");
    }

    var Encounter = function(args) {
        this.etype = 'enemy';
        this.dest = undefined;
        this.description = '';
        this.button = 'Check';

        if (!( (typeof args === "object") && (args !== null) ))
            throw("Encounter() requires proper construction");

        if (args.etype == undefined || args.etype == 'enemy') {
            this.dest = new EnemyEncounter(args);

            /* Describe myself with some defaults if not specified */

            if ('map_description' in args)
                this.description = args.map_description;
            else if (this.dest.isaggressive) {
                /* aggro persons and creatures */
                if (this.dest.iscapturable)
                    this.description = '{{companion}} detects someone.';
                else
                    this.description = '{{companion}} detects something.';
            } else {
                if (this.dest.iscapturable)
                    this.description = 'You meet a lone person.';
                else
                    this.description = 'You meet a lone creature';
            }
            if ('button' in args)
                this.button = args.button;

        } else {
           if (!('display' in args)) { // if display() overridden, let them have whatever they want
                var mandatory = [ 'dest', 'description' ];

                var failed = '';
                for (var i = 0; i < mandatory.length; i++) {
                    if (!(mandatory[i] in args))
                        failed += 'Encounter() expected ' + mandatory[i] + ' in args\n';
                }
                if (failed !== '')
                    throw new Error(failed);
            }

            var keys = Object.keys(this);
            for(var i = 0; i < keys.length; i++)
                if (this.hasOwnProperty(keys[i]) && keys[i] in args)
                    this[keys[i]] = args[keys[i]];

            // pull function overrides in, even without hasOwnProperty
            keys = [ 'check', 'display' ];
            for(var i = 0; i < keys.length; i++)
                if (keys[i] in args)
                    this[keys[i]] = args[keys[i]];
        }
    }

    Encounter.prototype.display = function() {
        var desc = this.description;
        if (typeof(desc) === 'function')
            desc = desc();

        var subst = {
            companion: Game.Girls[Game.companion].name,
        };

        ToText(simple_template(desc, subst) + "

");

        if (this.etype == 'enemy') {
            if (this.dest.aggressive && this.dest.aggro_avoid > Game.Girls[Game.companion].skill.survival) {
                PrintLocation('encounterenemy');
                return false;
            } else if (false && this.dest.sneaky > Game.Girls[Game.companion].skill.survival) {
                ToText("Sneaky not implemented
");
            } else {
                ToText("" + this.button + "

");
            }
        } else if (this.etype == 'location') {
            ToText("" + this.button + "

");
        }
        return true;
    }

    Encounter.prototype.check = function() { return true; }

    Data.encounter.arachna = new Encounter({
        engage_button: 'Approach it',
        name: 'Arachna',
        race: 'arachna',
        aggro_avoid: 4,
        aggro_description: 'You are attacked by Arachna!',
        description: '{{companion}} spots an Arachna before she detects you.',
        combat: [ 5, 25, 6, 13 ],
        iscapturable: 1,
        willpower: [ 3, 2 ],
    });

    Data.encounter.bandit = new Encounter({
        name: 'Bandit',
        race: 'human',
        aggro_avoid: 2,
        aggro_description: 'You are being attacked by a lone bandit.',
        description: "{{companion}} spots a hiding criminal in the bushes.",
        gold: [7, 7],
        willpower: 1,
        face: [ 10, 20 ],
        combat: [ 3, 14, 5, 7 ]
    });

    Data.encounter.banditgirl = new Encounter({
        iscapturable: true,
        name: 'Bandit girl',
        description: 'You come across small camp of a single person. A lone bandit girl prepares to attack you.',
        sneaky: 1,
        race: 'human',
        willpower: 1,
        gold: [ 20, 20 ],
        face: [ 20, 20 ],
        backstory: '- You picked me up in the ancient forest where I was hiding.',
        combat: [ 2, 10, 3, 7 ]
    });

    Data.encounter.banditswithgirl = new Encounter({
        map_description: 'You spot a group of bandits carrying a girl with them.',
        description: "The group of slavers are leading a captured {{race}} girl.  You can't say anything else aobut her without getting closer.",
        name: 'Slavers',
        combat: [ 5, 25, 5, 12 ],
        slavers: true,
        willpower: [ 1, 4 ],
        gold: [ 20, 30 ],
        race: function() {// any race
            return Data.listRaces().random().name;
        },

        /* some specific overrides for saleable girls */
        face: [ 40, 60 ],
        obedience: [ 50, 0 ],
        loyalty: [ 25 , 0 ],
    });

    Data.encounter.banditswithharpy = new Encounter({
        map_description: 'You spot a group of bandits with a captured harpy.',
        name: 'Slavers',
        combat: [ 5, 25, 5, 12 ],
        slavers: true,
        willpower: [ 1, 5 ],
        gold: [ 20, 30 ],
        race: 'harpy',

        face: [ 40, 60 ],
        obedience: [ 20, 20 ],
        loyalty: [ 15 , 0 ],
    });

    Data.encounter.banditswithnereid = new Encounter({
        description: 'You meet a group of bandits carrying someone',
        name: 'Slavers',
        combat: [ 5, 25, 5, 12 ],
        slavers: true,
        willpower: [ 1, 5 ],
        gold: [ 20, 30 ],
        race: 'nereid',

        face: [ 40, 60 ],
        obedience: [ 20, 20 ],
        loyalty: [ 15 , 0 ],
    });

    Data.encounter.bunny = new Encounter({
        name: 'Bunny Girl',
        race: [ 'bunny', 'halfkin bunny' ],
        willpower: [ 1, 2 ], // dat heroic bunnies
        combat: [ 2, 9, 5, 6 ],
        description: 'You spot a meek looking {{race}} girl.',
        iscapturable: true,
    });

    Data.encounter.centaur = new Encounter({
        name: 'Centaur',
        race: 'centaur',
        description: 'A nomadic centair girl appears in sight',
        combat: [ 3, 14, 3, 10 ],
        iscapturable: true,
        willpower: [ 2, 3 ],
    });

    Data.encounter.demon = new Encounter({
        name: 'Demon girl',
        race: 'demon',
        description: 'You spot a demon girl lurking in the plants' shadows.',
        combat: [ 2, 16, 4, 9 ],
        willpower: [ 2, 3 ],
    });

    Data.encounter.dryad = new Encounter({
        name: 'Dryad',
        race: 'dryad',
        iscapturable: true,
        description: 'You spot a dryad girl walking through the woods.',
        combat: [ 5, 15, 3, 9 ],
        willpower: [ 1, 2 ],
        procs: [7],
        proc_frequency: 7,
        backstory: '- I do not remember much about my life before I ended up in the grove.'
    });

    Data.encounter.elfmaiden = new Encounter({
         name: 'Elf Maiden',
         race: 'elf',
         description: 'Brightly clothed girl with elven features hasn't detected your presence yet.',
         iscapturable: true,
         willpower: [ 2, 3 ], // better than your average peasant-elf
         combat: [ 2, 15, 5, 8 ],
    });

    Data.encounter.elfwarrior = new Encounter({
        name: 'Armed Elf',
        race: 'elf',
        aggro_avoid: 2,
        aggro_description: "
— How dare you intrude into our sacred lands.

Female Elven Warrior charges at you.",
        description: '{{companion}} spots lone elven warrior girl on the watch near one of the trees.',
        iscapturable: 1,
        combat: [ 4, 18, 4, 10 ],
        willpower: [ 2, 3 ],
    });

    Data.encounter.drow = new Encounter({
        name: 'Armed Drow',
        race: 'drow',
        aggro_avoid: 3,
        aggro_description: "
Female Drow Warrior silently charges at you.",
        description: '{{companion}} spots lone drow warrior girl on the watch between the pillars.',
        iscapturable: 1,
        combat: [ 5, 25, 5, 12 ],
        willpower: [ 3, 2 ],
    });

    Data.encounter.fairy = new Encounter({
        name: 'Fairy',
        race: 'fairy',
        iscapturable: true,
        description: 'You spot a fairy girl walking through the woods.',
        combat: [ 4, 12, 3, 7 ],
        willpower: [ 2, 2 ],
        procs: [1],
        face: [ 40, 60 ], // no ugly fairies
        proc_frequency: 4,
        backstory: '- I was living in the grove where you found me.',
    });

    Data.encounter.harpy = new Encounter({
        race: 'harpy',
        name: 'Harpy',
        description: 'You come across a lone harpy girl.',
        combat: [ 5, 20, 3, 10 ],
        iscapturable: 1,
        willpower: [1, 4],
    });

    Data.encounter.lamia = new Encounter({
        race: 'lamia',
        name: 'Lamia',
        combat: [ 4, 22, 6, 12 ],
        willpower: [ 3, 3 ],
        description: '{{companion}} spots a lone Lamia girl who seems to be unaware of your approach yet.',
        iscapturable: true,
        procs: [5],
        proc_frequency: 5
    });

    Data.encounter.nereid = new Encounter({
        name: 'Nereid',
        race: 'nereid',
        description: 'A silhouette of fish girl can be detected in the shadows of surroundings.',
        combat: [ 4, 18, 5, 10 ],
        willpower: [ 3, 3 ],
    });

    Data.encounter.peasantgirl = new Encounter({
        combat: [ 2, 12, 5, 6 ],
        name: 'Commoner Girl',
        race: function() {
            var _map = {
                elvenforest: [ 'human', 'elf', 'elf', 'halfkin wolf' ],
                meadows: [ 'human', 'taurus', 'taurus', 'halfkin bunny', 'bunny' ],
                highlands: [ 'orc', 'orc', 'goblin', 'gnome' ],
                crossroads: [ 'human', 'human', 'gnome', 'halfkin tanuki', 'halfkin cat', 'halfkin fox' ],
            }
            if (Game.mappos.toLowerCase() in _map)
                return _map[Game.mappos.toLowerCase()].random();
            return 'human';
        },
        description: 'You find a lone {{race}} girl, native to these lands.',
        obedience: [ 0, 20 ],
        face: [ 20, 50 ],
        willpower: [1, 3],
    });

    Data.encounter.scylla = new Encounter({
            name: 'Scylla',
            race: 'scylla',
            description: 'You find a Scylla girl hiding from human eyes.',
            combat: [ 5, 24, 5, 12 ],
            willpower: [ 1, 5 ]});

    Data.encounter.slime = new Encounter({
        race: 'slime',
        name: 'Slime Girl',
        combat: [ 2, 14, 3, 10 ], // slimes be squishier than demons [ 2, 16, 4, 9 ]
        face: [ 20, 60 ],
        willpower: [ 2, 3 ],
        description: 'A silhouette of a slime girl can be detected in the shadows of surroundings.',
        procs: [7],
        proc_frequency: 7
    });

    Data.encounter.tanuki = new Encounter({
        race: [ 'tanuki', 'halfkin tanuki' ],
        willpower: [ 2, 4 ],
        combat: [ 3, 14, 4, 9 ],
        name: 'Tanuki girl',
        sneaky: 2,
        description: 'A travelling {{race}} girl appears in sight',
    });

    Data.encounter.templeabbess = new Encounter({
        engage_button: "Approach her",
        map_description: "{{companion}} spots robed female figure in one of the cracks",
        name: "Red Moon Abbess",
        description: "Robed woman spots your approach and prepares to attack you.",
        combat: [ 4, 20, 6, 14 ],
        gold: [ 22, 6 ],
        procs: [ 6, 4 ],
        proc_frequency: 4,
        aggro_avoid: 3,
        aggro_description: "You are attacked by Red Moon Abbess!",
    });

    Data.encounter.templepeasant = new Encounter({
        name: '{{race}} Refugee',
        description: 'You spot a {{race}} woman hiding in the temple's ruins.  Likely a refugee or criminal',
        race: [ 'human', 'elf', 'drow' ],
        willpower: [ 2, 2 ],
        combat: [ 4, 16, 7, 10 ],
        face: [ 20, 60 ],
        backstory: '- I used to hide in undercity, where you captured me',
    });

    // new Encounters below this are beasts */
    /* beasts */

    Data.encounter.bear = new Encounter({
        name: 'bear',
        description: '{{companion}} spots a bear a couple feet away from you before it's too late.',
        combat: [ 2, 13, 4, 8 ],
        food: [ 40, 20 ],
        aggro_avoid: 2,
        aggro_description: 'As you walk through the wilderness, you hear a fierce roar.  It seems you provoked a bear by getting into it's territory and it goes for the attack.',
    });

    Data.encounter.cougar = new Encounter({
        name: 'Cougar',
        map_description: 'You see a hungry cougar ahead.',
        aggro_avoid: 3,
        aggro_description: 'It attacks you!',
        description: '{{companion}} stays upwind of the cougar, who hasn"t smelled you yet.',
        engage_button: 'Attack',
        combat: [ 4, 22, 7, 9 ],
        food: [ 20, 10 ],
    });

    Data.encounter.crab = new Encounter({
        combat: [4, 30, 7, 14 ],
        food: [ 30, 30 ],
        name: 'Giant enemy crab',
        enemytype: 4,
        aggro_avoid: 4,
        aggro_description: 'You are attacked by a giant crab!',
        description: function() { return Game.Girls[Game.companion].name + " spots a giant crab before you run into it."; },
    });

    Data.encounter.cultist = new Encounter({
        name: 'Red Moon Cultist',
        description: 'A robed figure leers at {{companion}} with a grin on his face.',
        combat: [ 3, 18, 6, 13 ],
        gold: [ 16, 5 ],
        procs: [4],
        proc_frequency: 6,
    });

    Data.encounter.ooze = new Encounter({
        name: 'Ooze',
        description: 'You spot pile of green living ooze with various parts of decomoposing material in it.',
        combat: [ 4, 22, 5, 12 ],
        gold: [ 18, 6 ],
        procs: [5],
        proc_frequency: 6,
    });

    Data.encounter.plant = new Encounter({
        name: 'Man-eating Plant',
        description: 'Moving hostile plant is in front of you.',
        combat: [ 3, 14, 5, 6 ],
        food: [ 20, 10 ],
        procs: [ 1, 7 ],
        proc_frequency: 3,
    });

    Data.encounter.werebeast = new Encounter({
        name: 'Werebeast',
        description: 'Giant werebeast jumps out of shadows, blocked by {{companion}} at last moment!',
        combat: [ 3, 19, 5, 10 ],
        gold: [ 20, 5 ],
        procs: [3],
        proc_frequency: 6,
        aggro_avoid: 4,
        aggro_description: 'Huge rabid half-animal stands before you, preparing to attack.',
    });

    Data.encounter.wisp = new Encounter({
        name: 'Wisp',
        description: 'You find a moving shapeless spirit fire occasionally taking the form of a personp',
        combat: [ 3, 14, 3, 5 ],
        gold: [ 2, 5 ],
    });

    Data.encounter.wolf = new Encounter({
        name: 'Wolf',
        description: "Medium sized lone wolf is before you.",
        combat: [ 2, 12, 5, 4 ],
        enemytype: 4, // beast
        food: [ 10, 10 ],
    });

    Data.encounter.hyena = new Encounter({
        name: 'Hyenas',
        aggro_description: "Pack of large, hungry looking hyenas encircle you.",
        description: "Sizable pack of large hyenas wander aimlessly.",
        aggro_avoid: 3,
        combat: [ 4, 16, 5, 14 ],
        food: [ 20, 20 ],
    });

    Data.encounter.undercityspider = new Encounter({
        map_description: '{{companion}} spots a dangerous giant spider ahead.',
        engage_button: 'Approach it',
        aggro_avoid: 3,
        aggro_description: '{{companion}} got caught in a sticky spider web',
        description: 'Giant Spider of size of a horse didn't notice your approach until you are ready to attack.',
        // ToText("

Giant Spider of size of a horse leaping on the " + Game.Girls[Game.companion].name + '' + "!

");
        combat: [ 4, 23, 6, 12 ],
        combat_start: function() { if (Game.Girls[Game.companion].skill.survival < 3) Combat.held = true; },
        name: 'Giant spider',
        procs: [2],
        proc_frequency: 5,
        gold: [ 25, 7 ],
    });

    Data.encounter.undercitytentacles = new Encounter({
        map_description: '{{companion}} spots a massive pile of squirming appendages.',
        engage_button: 'Approach it',
        avoid_button: 'Ignore it',
        name: 'Tentacle Mass',
        description: 'Giant mass of ooze and tentacles prepares to attack.',
        combat: [ 2, 15, 3, 15 ],
        gold: [ 22, 6 ],
        procs: [5],
        proc_frequency: 7,
        combat_start: function() { if (Game.Girls[Game.companion].skill.survival < 3) Combat.held = true; },
        aggro_avoid: 3,
        aggro_description: '{{companion}} is struggling to break free from tentacles grabbing her.'
    });


code:
"use strict";

    function $(id) {
        return document.getElementById(id);
    }
    var popupHold = false;
    var printTitle = $('printTitle');
    var printDiv = $('print');
    var printDivDefault = printDiv;
    var printContDiv = $('printCont');
    var printAdd = $('printAdd');
    var printAddCont = $('printAddCont');
    var printAddText = $('printAddText');
    var pageDiv = $('page');
    var menuDiv = $('menuInner');
    var toolbarDiv = $('toolbar');
    var prefsDiv = $('prefs');
    var printImage = $('clickImage');
    var spritesDiv = $('spritesDiv');

    var GamePrev = undefined;
    var g_totext;

    if (!('objectFit' in document.body.style)) {
        printImage.style.width = 'auto';
        printImage.style.height = 'auto';
        printImage.style.maxWidth = '100%';
    }
    var printImageBlock = $('printImage');
    var showImageButton = $('showImageButton');
    var consoleDiv = $('console');
    var dialogWind = $('dialog');
    var audioButton = $('audioButton');
    window.addEventListener('load', function() {
        FastClick.attach(document.body);
    }, false);

    window.addEventListener('message', function(e) {
        eval(e.data);
    });

    function isMobile() {
        if (getComputedStyle(showImageButton, null).display == 'none') {
            return false;
        }
        return true;
    }

    function Resize() {
        if (isMobile()) {
            printImageBlock.style.display = 'none';
        } else {
            printImageBlock.style.display = 'block';
        }
    }
    window.addEventListener('resize', Resize, false);
    window.addEventListener('orientationchange', Resize, false);
    document.addEventListener('dragstart', function(e) {
        e.preventDefault();
    });
    var tmpdiv = document.createElement('div');
    tmpdiv.innerHTML = '';
    var isIeLessThan10 = (tmpdiv.getElementsByTagName('i').length == 1);
    if (isIeLessThan10) {
        document.onselectstart = function() {
            return false;
        }
    }
    window.onkeyup = function(e) {
        keysUp(e);
    }
    window.onkeydown = function(e) {
        keysDown(e);
    }
    printImage.onerror = function() {
        badImageShow(this);
    }

    function isInputActive() {
        var tag = document.activeElement.tagName.toLowerCase();
        if (tag == 'input' || tag == 'textarea') {
            return true;
        } else {
            return false;
        }
    }

    function keysDown(event) {
        if (isInputActive()) {
            return;
        }
        var key = keyCode(event);
        if (key == 32) {
            event.preventDefault();
        }
    }

    function keysUp(event) {
        if (isInputActive()) {
            return;
        }
        if (showCover) {
            showPrintAdd(false);
            return;
        }
        var key = keyCode(event);
        if (key == 27) {
            closeWinds();
            return;
        }
        if (key == 32) {
            showImageToggle();
            return;
        }
        var keyN = -1;
        if (key >= 49 && key <= 57) {
            keyN = key - 49;
        }
        if (key >= 97 && key <= 105) {
            keyN = key - 97;
        }
        if (keyN >= 0) {
            var elems = menuDiv.querySelectorAll('*');
            var clickElems = [];
            for (var i = 0; i < elems.length; i++) {
                if (elems[i].onclick) {
                    clickElems.push(elems[i]);
                }
            }
            if (clickElems[keyN]) {
                clickElems[keyN].click();
            }
        }
    }

    function showImageToggle() {
        if (isMobile()) {
            if (getComputedStyle(printImageBlock, null).display == 'none') {
                printImageBlock.style.display = 'block';
            } else {
                printImageBlock.style.display = 'none';
            }
        } else {
            if (getComputedStyle(printAddCont, null).display == 'none') {
                showImage();
            } else {
                showPrintAdd(false);
            }
        }
    }

    function showImageForce() {
        if (isMobile()) {
            printImageBlock.style.display = 'block';
        }
    }

    function goodImageShow(img) {
        if (isTouchDevice) {
            mybody = document.body;
            mybody.style.display = 'none';
            scrollDiv(mybody);
            mybody.style.display = 'block';
        }
    }

    function badImageShow(img) {
        img.src = badImage;
    }

    function showImage() {
        if (!isMobile()) {
            printAddText.innerHTML = "";
            printAddText.innerHTML += spritesDiv.innerHTML;
            showPrintAdd(true, false, true);
        } else {
            printImageBlock.style.display = 'none';
        }
    }
    var printAddTextAlign = printAddText.style.textAlign;

    function showPrintAdd(show, bounce, center) {
        if (show) {
            closeWinds();
            showShadow(true);
            if (center) {
                printAddText.style.textAlign = 'center';
            } else {
                printAddText.style.textAlign = printAddTextAlign;
            }
            var inner = printAddText.innerHTML;
            inner = inner.replace(/(
<\/p>)*?<span class="buttonback"[^<]+?<\/span>(
<\/p>)*?/gi, '').trim();
            if (inner == '') {
                return;
            }
            printAddText.innerHTML = inner;
            printAddCont.style.display = 'block';
            scrollDiv(printAdd);
            if (isAnimation && animation_enable) {
                var effect = 'effect_scale';
                if (bounce) {
                    effect = 'effect_bounce';
                }
                Animate(printAdd, effect);
            } else {
                fade(printAddText);
            }
        } else {
            if (showCover) {
                musicAudio.play();
            }
            showShadow(false);
            printAddCont.style.display = 'none';
        }
    }

    function MenuInit() {
        var StoryMenu = GetLocation('StoryMenu');
        if (StoryMenu != false) {
            if (StoryMenu.Text.search(/<span class='(button|plink)/) != -1) {
                menuDiv.innerHTML = '';
                eval(StoryMenu.Text);
            }
        }
    }
    var fontSize = 1;

    function ChangeFontSize() {
        if (fontSize < 1.2) {
            fontSize = fontSize + 0.1;
        } else {
            fontSize = 0.8
        }
        fade(printDiv);
        printDiv.style.fontSize = fontSize + 'em';
        printAdd.style.fontSize = fontSize + 'em';
    }

    function scrollDiv(obj, bottom) {
        if (!obj) {
            obj = printContDiv;
        }
        if (bottom) {
            obj.scrollTop = obj.scrollHeight;
        } else {
            obj.scrollTop = 0;
        }
    }
    function closeWinds() {
        showPrintAdd(false);
        showPrefs(true);
        showShadow(false);
        dialogWind.style.display = 'none';
    }

    function showShadow(show) {
        if (show) {
            if (!$('shadowlayer')) {
                var shadow = document.createElement('div');
                shadow.id = 'shadowlayer';
                document.body.appendChild(shadow);
            }
        } else {
            var shadow = $('shadowlayer');
            if (shadow) {
                document.body.removeChild(shadow);
            }
            showCover = false;
            printAddCont.style.display = 'none';
        }
    }

    function keyCode(event) {
        return event.keyCode ? event.keyCode : event.charCode ? event.charCode : event.which;
    }
    var isTouchDevice = false;
    if ('ontouchmove' in window) {
        isTouchDevice = true;
    }
    if (isTouchDevice) {
        try {
            var ignore = /:hover/;
            for (var i = 0; i < document.styleSheets.length; i++) {
                var sheet = document.styleSheets[i];
                if (!sheet.cssRules) {
                    continue;
                }
                for (var j = sheet.cssRules.length - 1; j >= 0; j--) {
                    var rule = sheet.cssRules[j];
                    if (rule.type === CSSRule.STYLE_RULE && ignore.test(rule.selectorText)) {
                        sheet.deleteRule(j);
                    }
                }
            }
        } catch (e) {}
    }
    var musicAudio = $('musicAudio');
    musicAudio.addEventListener('play', function() {
        audioPlayEvent();
    }, false);
    musicAudio.addEventListener('pause', function() {
        audioPauseEvent();
    }, false);
    musicAudio.addEventListener('durationchange', function() {
        audioPlayEvent();
    }, false);
    musicAudio.addEventListener('error', function() {
        if (this.src.substr(-4) == '.mp3') {
            AlertMessage('Error loading file
' + this.src);
        }
    }, false);
    var audio_enable = true;
    var animation_enable = true;
    var showCover = false;
    var TimeToFade = 500;
    var isAnimation = false;
    if (document.body.style.WebkitAnimation !== undefined || document.body.style.MozAnimation !== undefined || document.body.style.OAnimation !== undefined || document.body.style.msAnimation !== undefined || document.body.style.KhtmlAnimation !== undefined || document.body.style.animation !== undefined) {
        isAnimation = true;
    }

    function tbAnimate(obj) {
        Animate(obj, 'effect_scale');
    }

    function prefixedEventListener(element, type, callback) {
        var pfx = ['webkit', 'moz', 'MS', 'o', ''];
        for (var p = 0; p < pfx.length; p++) {
            if (!pfx[p]) type = type.toLowerCase();
            element.addEventListener(pfx[p] + type, callback, false);
        }
    }

    function Animate(obj, animID) {
        if (isAnimation) {
            var objclass = obj.className.split(' ')[0];
            obj.className = objclass + ' ' + animID;
            prefixedEventListener(obj, 'AnimationEnd', function() {
                obj.className = objclass;
            }, false);
        }
    }

    function AreYouSure(func, text) {
        showPrefs(true);
        window.confirm_func = func;
        if (!text) {
            text = 'Are you sure?';
        }
        text += "
";
        text += "No";
        text += "Yes
";
        dialogWind.innerHTML = text;
        showShadow(true);
        dialogWind.style.display = 'block';
        Animate(dialogWind, 'effect_fade_fast');
    }

    function AlertMessage(text) {
        text += "
OK
";
        dialogWind.innerHTML = text;
        showShadow(true);
        dialogWind.style.display = 'block';
        Animate(dialogWind, 'effect_fade_fast');
    }

    function isArray(inputArray) {
        return inputArray && !(inputArray.propertyIsEnumerable('length')) && typeof inputArray === 'object' && typeof inputArray.length === 'number';
    }

    function LocNotFound(loc) {
        AlertMessage('Passage not found');
    }

    function GetFileData(id) {
        if (/^http(s)?:\/\/.+?$/.test(id)) {
            var ret = {}
            ret.src = id;
            return ret;
        }
        id = id.trim().toLowerCase();
        for (var key in storydata) {
            if (storydata[key][0] == id) {
                return storydata[key][1];
            }
        }
        return '';
    }

    function prefsFill() {
        var out = '';
        if (!showCover) {
            out += '
Restart
';
        }
        out += '
Save

Restore
';
        if (audio_enable) {
            out += '
Disable Sound
';
        } else {
            out += '
Enable Sound
';
        }
        if (isAnimation) {
            if (animation_enable) {
                out += '
Disable Animation
';
            } else {
                out += '
Enable Animation
';
            }
        }
        out += '
Change Text Size
';
        out += "
Export game
";
        out += "
Debug JSON
";
        prefsDiv.innerHTML = out;
    }

    function showPrefs(close) {
        if (close || prefsDiv.style.display != 'none' || dialogWind.style.display != 'none') {
            showShadow(false);
            dialogWind.style.display = 'none';
            prefsDiv.style.display = 'none';
        } else {
            showShadow(true);
            prefsFill();
            prefsDiv.style.display = 'block';
            Animate(prefsDiv, 'effect_fade_fast');
        }
    }

    function fade(element) {
        if (TimeToFade == 0 || !element) {
            return;
        }
        var eid = element.id;
        element.style.opacity = '0';
        if (element.FadeState == null) {
            if (element.style.opacity == null || element.style.opacity == '' || element.style.opacity == '1') {
                element.FadeState = 2;
            } else {
                element.FadeState = -2;
            }
        }
        if (element.FadeState == 1 || element.FadeState == -1) {
            element.FadeState = element.FadeState == 1 ? -1 : 1;
            element.FadeTimeLeft = TimeToFade - element.FadeTimeLeft;
        } else {
            element.FadeState = element.FadeState == 2 ? -1 : 1;
            element.FadeTimeLeft = TimeToFade;
            setTimeout("animateFade(" + new Date().getTime() + ",'" + eid + "')", 33);
        }
    }

    function animateFade(lastTick, eid) {
        var curTick = new Date().getTime();
        var elapsedTicks = curTick - lastTick;
        var element = $(eid);
        if (element.FadeTimeLeft <= elapsedTicks) {
            element.style.opacity = '1';
            element.style.filter = 'alpha(opacity = 100)';
            element.FadeState = element.FadeState == 1 ? 2 : -2;
            return;
        }
        element.FadeTimeLeft -= elapsedTicks;
        var newOpVal = element.FadeTimeLeft / TimeToFade;
        newOpVal = 1 - newOpVal;
        element.style.opacity = newOpVal;
        element.style.filter = 'alpha(opacity = ' + (newOpVal * 100) + ')';
        setTimeout("animateFade(" + curTick + ",'" + eid + "')", 33);
    }

    var g_locations = 0;

    function Locations(Title, Text, Parsed) {
        this.Index = g_locations++;
        this.Title = Title;
        this.Text = Text;
        this.Parsed = Parsed;
    }

    Locations.prototype.SetImage = function(src) {
        if (Game.settings.flavor_image == 1) {
            printImage.src = pictureDefault;
            printImage.onload = function() {
                printImage.src = src;
                this.onload = null;
            }
            showImageForce();
        }
    }

    function Trim(str) {
        return str.replace(/^\s+|\s+$/g, '');
    }

    var Location = [];
    var PrevLocation;
    var CurLocation;
    var PrevImage = pictureDefault;
    var PrevTitle;
    var PrevMenu;
    var PrevAudio;
    var PrevSprites = '';

    function getAsmSys_time() {
        var d = new Date();
        return Math.round(d.getTime() / 1000);
    }

    function getAsmSys_titleCur() {
        return CurLocation.Title;
    }

    function getAsmSys_titlePrev() {
        return PrevLocation.Title;
    }
    var asmSys_gender = 0;
    var asmSys_choice = 0;

    function GetLocation(Title) {
        for (var key in Location) {
            var Loc = Location[key];
            if (!('Title' in Loc))
                console.log("Broken: looking for " + Title);
            else if (Trim(Loc.Title.toLowerCase()) == Trim(Title.toLowerCase())) {
                return Loc;
            }
        }
        return false;
    }

    function GetIndexLocation(Title) {
        if (!Title) {
            return -1;
        }
        Title = Title.toString();
        var LocIndex = 0;
        for (var key in Location) {
            var Loc = Location[key];
            if (Trim(Loc.Title.toLowerCase()) == Trim(Title.toLowerCase())) {
                return LocIndex;
            }
            LocIndex++;
        }
        return -1;
    }

    function FlipPage() {
        ToText2(g_totext, true);
        if (isAnimation && animation_enable && TimeToFade > 0) {
            Animate(printDiv, 'effect_flip');
        } else {
            fade(printDiv);
        }
    }

    function ToText(s, fromstart) {
        if (printDiv != $('print')) {
            return ToText2(s, fromstart);
        }
        if (fromstart) g_totext = s;
        else g_totext += s;
    }

    function ToText2(s, fromstart, div) {
        if (!div) {
            div = printDiv;
        }
        if (fromstart) {
            div.innerHTML = s;
        } else {
            div.innerHTML += s;
        }
        var innr = div.innerHTML;
        if (innr.substr(0, 3) == '
') {
            div.innerHTML = innr.replace(/^(
<\/p>)+/i, '');
        }
    }

    function PrintLocation(Title, replay) {
        if (Game !== undefined && Game.SpellKnown === undefined) {
            throw("fuck me");
        }
        if (!Title) {
            return false;
        }
        Title = Title.toString();
        if (Title.search(/:\/\//) != -1) {
            window.open(Title);
        } else {
            var Loc = GetLocation(Title);
            if (Loc != false) {
                closeWinds();
                if (!replay) {
                    PrevLocation = CurLocation;
                    CurLocation = Loc;
                    PrevImage = printImage.src;
                    PrevTitle = printTitle.innerHTML;
                    PrevMenu = menuDiv.innerHTML;
                    PrevAudio = musicAudio.src;
                    PrevSprites = spritesDiv.innerHTML;
                }
                showPrintAdd(false);
                scrollDiv();
                if (Game) printTitle.innerHTML = Game.energy; // TODO toolbar should get proper attention sometime, hack
                if (Loc.Parsed == 1) {
                    ToText('', true);
                    Loc.Text();
                } else {
                    ToText(Loc.Text, true);
                }
                FlipPage();
            } else {
                LocNotFound(Title);
            }
        }
    }

    function DisplayLocation(Title, div) {
        var pdiv = printDiv;
        if (!Title) {
            return false;
        }
        if (div !== undefined) {
            printDiv = div;
            ToText('', true);
        }
        Title = Title.toString();
        if (CurLocation.Title.toLowerCase() == Title.toLowerCase() && printDiv != printAddText) {
            return;
        }
        if (Title.search(/:\/\//) != -1) {} else {
            var Loc = GetLocation(Title);
            if (Loc != false) {
                if (Loc.Parsed == 1) {
                    Loc.Text();
                } else {
                    ToText(Loc.Text);
                }
            } else {
                LocNotFound(Title);
            }
        }
        printDiv = pdiv;
    }

    function NoBack() {
        PrevLocation = '';
        PrevImage = pictureDefault;
        PrevSprites = '';
        PrevTitle = '';
        PrevMenu = '';
        PrevAudio = '';
    }

    function Back() {
        throw Fail("No longer supported");
    }

    function audioPlayEvent() {
        if (audio_enable && (musicAudio.src.substr(-4) == '.mp3' || musicAudio.src.substr(0, 15) == 'data:audio/mp3;')) {
            audioButton.style.display = 'inline-block';
            audioButton.style.opacity = 1;
        } else {
            audioButton.style.display = 'none';
        }
    }

    function audioPauseEvent() {
        audioButton.style.opacity = 0.5;
    }

    function PlayPauseButton() {
        if (musicAudio.paused) {
            musicAudio.play();
        } else {
            musicAudio.pause();
        }
    }

    function playMusic() {
        if (audio_enable) {
            musicAudio.play();
        }
    }

    function stopMusic() {
        audioButton.style.display = 'none';
        if (musicAudio.readyState) {
            musicAudio.pause();
            musicAudio.currentTime = 0;
        }
    }
    var Events = [];

    function startEvent(locTitle, timerSec) {
        var locIndex = GetIndexLocation(locTitle);
        if (locIndex != -1) {
            stopEvent(locTitle);
            if (window['eventNum' + locIndex] === undefined) {
                Events.push(GetIndexLocation(locTitle) + ':' + timerSec);
                window['eventNum' + locIndex] = setInterval(function() {
                    DisplayLocation(locTitle);
                }, timerSec * 1000);
            }
        }
    }

    function stopEvent(locTitle) {
        var locIndex = GetIndexLocation(locTitle);
        if (locIndex != -1) {
            clearInterval(window['eventNum' + locIndex]);
            window['eventNum' + locIndex] = undefined;
            for (var i = 0; i <= (Events.length - 1); i++) {
                var curEvent = Events[i];
                var curEventArr = curEvent.split(':');
                curEvent = curEventArr[0];
                if (curEvent == GetIndexLocation(locTitle)) {
                    Events.splice(i, 1);
                    break;
                }
            }
        }
    }

    function stopAllEvents() {
        Events.length = 0;
        for (var i = 0; i <= (Location.length - 1); i++) {
            if (window['eventNum' + i] !== undefined) {
                clearInterval(window['eventNum' + i]);
                window['eventNum' + i] = undefined;
            }
        }
    }

    function choice(elem, variable, n) {
        if (elem.className == 'plink selected') {
            elem.className = 'plink';
            window[variable] = 0;
        } else {
            var elems = elem.parentNode.getElementsByClassName('plink selected');
            for (var i = 0; i < elems.length; i++) {
                elems[i].className = 'plink';
            }
            elem.className = 'plink selected';
            window[variable] = n;
        }
    }

    function clearSprites() {
        spritesDiv.innerHTML = '';
    }

    function popup(text, hold) {
        var orig = printDiv;
        printDiv = printAddText;
        ToText(text, true);
        if (hold !== undefined) {
            popupHold = true;
            if (typeof(hold) !== 'string')
                hold = 'Ok';
            ToText("" + hold + "");

        }
        showPrintAdd(true);
        scrollDiv(printAdd);
        printDiv = orig;
    }

    function popupLocation(loc, hold) {
        var orig = printDiv;
        printDiv = printAddText;
        ToText('', true);
        DisplayLocation(loc);

        if (hold !== undefined) {
            popupHold = true;
            if (typeof(hold) === 'string')
                ToText(hold);
            else
                ToText("Ok");

        }
        showPrintAdd(true);
        scrollDiv(printAdd);
        printDiv = orig;
    }

    function closePopup() {
        popupHold = false;
        showPrintAdd(false);
    }

repo_name: spdevel/sfp

license: unknown


code:
"use strict";
    Location.push(new Locations("map", function() {
        ToText("Map: " + Game.mappos + "

");

        /* set the side menu appropriately */
        printDiv = menuDiv;
        ToText("Return to the mansionQuest logCheck stats", true);
        printDiv = $('print');

        if (Game.mappos.toLowerCase() in Data.portal) {
            var addportal = true;
            // see if we know this one
            for (var i = 0; i < Game.portals.length; i++)
                if (Game.portals[i] == Game.mappos.toLowerCase()) {
                    addportal = false; // we already know this one
                    break;
                }
            if (addportal) {
                Game.portals.push(Game.mappos.toLowerCase());
                ToText("You discovered a portal to the " + Data.portal[Game.mappos.toLowerCase()] + "

");
            }
        }

        var z = Data.Zone(Game.mappos);
        if (z.image.match(/\//))
            this.SetImage(z.image);
        else
            this.SetImage("files/backgrounds/" + z.image);
        ToText(z.description + "

");

        if (Game.companion == -1)
            ToText("Advance through area - you can't go in there alone!

");
        else if (Game.energy > 0)
            ToText("Advance through area

");
        else
            ToText("Advance through area - you are too tired to go on

");

        for (var i = 0; i<z.exit.length; i++)
            z.exit[i].display();
    }, 1));

    Location.push(new Locations("mapreturn", function() {
       ToText("

Move on

");
    }, 1));

    Location.push(new Locations("mapencs", function() {
        var z = Data.Zone(Game.mappos);

        if (z === undefined) {
            ToText("No map data for " + Game.mappos + "
");
            ToText("Return to mansion
");
            return;
        }

        ToText(z.description + "

");

        if (Game.zone_travelled < z.size) {
            /* see if we qualify for better encounters. */
            Game.encounter = z.getEncounter();
            var enc = Data.getEncounter(Game.encounter);
            if (enc.display() == false)
                return; // don't show any more.

            ToText("

Continue your way through

");
            Object.forEach(Game.spells_known, function(k) {
                if (k in Data.Spell && Data.Spell[k].Target('map')) {
                    var s = Data.Spell[k];
                    if (Game.mana >= s.cost)
                        ToText("Cast " + s.name + "
");
                    else
                        ToText("Cast " + s.name + " - not enough mana
");
                }
            });
        } else { // completed the zone
            ToText("

");
            DisplayLocation('endzonerewards');
            ToText("

");
            if (Game.energy >= 1) {
                ToText("

Stay around and scout for more

");
            } else {
                ToText("

You are too tired to stay around for more.

");
            }
            console.log("checkme: " + Game.mappos + ", " + z.border.length);
            for (var i = 0; i < z.border.length; i++)
                if (z.border[i].check()) z.border[i].display();
        }
        ToText("

");
    }, 1));

    Location.push(new Locations("encounterenemy", function() {
        var enemy = Data.getEncounter(Game.encounter).dest;
        enemy.display();
        // ToText("Return
");
    }, 1));

    Location.push(new Locations("encounterspell", function() {
        var enemy = Data.getEncounter(Game.encounter).dest;
        var spell = Data.Spell[Game.tmp2];

        Game.mana -= spell.cost;
        spell.castEncounter();
    }, 1));

    Location.push(new Locations("portals", function() {
        ToText("Portals allow easy transportation to other regions, however it can't send more than two people at once, so choose who you want to bring with you carefully. More portals will unlock with progress.

");
        Game.zone_travelled = 0;
        ToText("

");
        if (Game.energy == 0 && !Game.Girls[Game.companion].isRace("centaur")) {
            ToText("

You are too tired to travel anywhere.

Back

");
            ToText("Shaliq Village
");
            for (var i = 0; i < Game.portals.length; i++) {
                if (Game.portals[i] in Data.portal)
                    ToText("" + Data.portal[Game.portals[i]] + "

");
                else
                    Game.portals.splice(i--,1);
            }
        } else {
            ToText("

Choose your destination.

Shaliq Village

");
            for (var i = 0; i < Game.portals.length; i++)
                if (Game.portals[i] in Data.portal)
                    ToText("" + Data.portal[Game.portals[i]] + "

");
                else
                    Game.portals.splice(i--,1);

            ToText("

Back

");
        }
    }, 1));

    Location.push(new Locations("workchoose", function() {
        /* replacing jobs as they're added */
        var girl = Game.Girls[Game.tmp0];
        for (var i in Data.job_byname) {
            if (!Data.job_byname.hasOwnProperty(i))
                continue;
            var job = Data.getJob(i);
            if (job == undefined)
                continue;

            ToText(job.display(girl));
        }
    }, 1));

    Data.addTrigger("endoftheday", function() {
        /* reset things */
        console.log("reset daily portions");
        Game.days_elapsed++;
        Game.dates_available = 2;
        Game.energy = 5;
        Game.restock.slaveguild = 0;
        return true;
    });

    Data.addTrigger("endoftheday", function() {
        console.log("check jobs for sanity");
        Game.sanitize_roles();
        return true;
    });

    Data.addTrigger('endoftheday', function() {
        console.log('Magical toxicity');
        for (var i = 0; i < Game.Girls.length; i++) {
            var res = Game.Girls[i];

            if (res.body.toxicity >= 1 && res.busy == 0) {
                if (res.isRace("slime")) {
                    res.body.toxicity = 0;
                } else
                    res.body.toxicity = Math.max(0, res.body.toxicity - 5);

                if (res.body.toxicity >= 35 && Math.tossCoin(0.4)) {
                    res.stress = res.stress + 20;
                    res.health = res.health - 15;
                    ToText(" " + res.name + '' + " suffers from magical toxicity." + '' + " ");
                } else if (res.body.toxicity >= 60 && Math.tossCoin(0.4) && !res.isRace("scylla")) {
                    ToText(" " + res.name + '' + " suffers from magical toxicity." + '' + " ");
                    res.mutate();
                }
            }
        }
    });

    Data.addTrigger("endoftheday", function() {
        console.log("New girl jobs");
        ToText("

Servants are working:

");;
        for(var i = 0; i < Game.Girls.length; i++) {
            var res = Game.Girls[i];
            var job = res.getJob();
            if (job !== undefined) {
                if (job.canTake(res, ToText))
                    job.nightly(res);
                else
                    res.setJob("Rest");
                ToText("

");
            }
            if ((res.stress >= 100) || (res.stress >= 75 && res.hasMentalTrait("Frail"))) {
                res.mindbroken();
            }
        }
        return true;
    });

    Location.push(new Locations("endoftheday1", function() {
        menuDiv.innerHTML = '';
        printDiv = menuDiv;
        ToText("Proceed", false);
        printDiv = $('print');
        ToText("

");

        if (Game.gold.toString() != 'NaN') {
            Game.revert.gold = Math.round(Game.gold);
        }
        if (Game.food.toString() != 'NaN') {
            Game.revert.food = Math.round(Game.food);
        }
        if (Game.mana.toString() != 'NaN') {
            Game.revert.mana = Math.round(Game.mana);
        }
        Game.trigger("endoftheday");
    }, 1));

    Location.push(new Locations("endoftheday2", function() {
        menuDiv.innerHTML = '';
        printDiv = menuDiv;
        ToText("Proceed", false);
        printDiv = $('print');
        ToText("

");
        var current_cook = -1;
        Game.tmp6 = 0;
        ToText("

By the end of a day your residents gather together for dinner.

");
        Game.tmp0 = 0;
        var tmp_service = -1;
        for (var loop_asm34 = 1; loop_asm34 <= Game.Girls.length; loop_asm34++) {
            if (Game.Girls[Game.tmp0].hasJob('Chef')) {
                current_cook = Game.tmp0;
                tmp_service = Game.Girls[Game.tmp0].skill.service;
                ToText(" " + Game.Girls[Game.tmp0].name + '' + " is cooking today. ");
            }
            Game.tmp0++;
        }
        ToText("

");
        if (Game.food > 1) {
            if (current_cook != -1)
            Game.food = Math.max(Game.food - (10 - (0 + 10 * (0.1 + (0.1 * tmp_service)))), 0);
            Game.tmp6 = 10 - (0 + 10 * (0.1 + (0.1 * tmp_service)));
            ToText("

You had a dinner. ");
            Game.health = Math.min(Game.health + 5, 100);
            ToText("

");
        } else {
            ToText(" There's no food in the mansion and you are starving. " + '');
            Game.health = Game.health - 15;
            if (Game.health < 1) {
                ToText(" You died of stravation. ");
                menuDiv.innerHTML = '';
                printDiv = menuDiv;
                ToText("Start again", false);
                printDiv = $('print');
            }
        }
        ToText("

");;
        if (Game.Girls.length > 0 && Game.Girls[0].id > 0) {
            ToText("        ");
            Game.tmp0 = 0;
            for (var loop_asm35 = 1; loop_asm35 <= Game.Girls.length; loop_asm35++) {
                ToText("        ");
                if (Game.Girls[Game.tmp0].health < 1) {
                    ToText(" " + Game.Girls[Game.tmp0].name + '' + " died of poor health. ");
                    DisplayLocation('death1');
                    continue;
                }
                if ((Game.Girls[Game.tmp0].busy < 1 || Game.Girls[Game.tmp0].mission == 5) && Game.Girls[Game.tmp0].where_sleep != 5) {
                    ToText("                ");
                    if (Game.food < 1) {
                        Game.Girls[Game.tmp0].health = Game.Girls[Game.tmp0].health - 15;
                        Game.Girls[Game.tmp0].stress += 15;
                        ToText("                No food left for " + Game.Girls[Game.tmp0].name + '' + ". ");
                        if (Game.Girls[Game.tmp0].health < 1) {
                            ToText(" " + Game.Girls[Game.tmp0].name + '' + " died of starvation. ");
                            DisplayLocation('death1');
                            continue;
                        }
                        ToText("                ");
                    } else if (Game.food > 0) {
                        Game.tmp2 = (10 - (0 + 10 * (0.1 + (0.1 * tmp_service))));
                        if (Game.Girls[Game.tmp0].isRace("dryad")) {
                            Game.tmp2 = Game.tmp2 - Math.round(Game.tmp2 / 2);
                        }
                        Game.food = Math.max(Game.food - Game.tmp2, 0);
                        Game.tmp6 += Game.tmp2;
                        Game.Girls[Game.tmp0].health = Math.min(Game.Girls[Game.tmp0].health + 10, 100);
                        Game.Girls[Game.tmp0].loyalty = Math.min(Game.Girls[Game.tmp0].loyalty + 1, 100);
                        Game.Girls[Game.tmp0].stress = Math.max(Game.Girls[Game.tmp0].stress - 12, 0);
                        if (Game.Girls[Game.tmp0].isRace("fairy")) {
                            Game.Girls[Game.tmp0].stress = Math.max(Game.Girls[Game.tmp0].stress - 12, 0);
                        }
                        ToText("                ");
                        Game.Girls[Game.tmp0].obedience = Math.max(Math.min(Game.Girls[Game.tmp0].obedience - (Game.Girls[Game.tmp0].attr.willpower * 3 + Math.round(Game.Girls[Game.tmp0].attr.confidence / 4)) + Game.Girls[Game.tmp0].loyalty, 100), 0);
                        ToText("                ");
                    }
                    if (Game.Girls[Game.tmp0].where_sleep <= 3 && Game.Girls[Game.tmp0].busy < 1) {
                        ToText("        ");
                        if (Game.Girls[Game.tmp0].hasMentalTrait("Passive")) {
                            Game.Girls[Game.tmp0].obedience = Math.min(Game.Girls[Game.tmp0].obedience + 10, 100);
                        } else if (Game.Girls[Game.tmp0].hasMentalTrait("Clingy")) {
                            Game.Girls[Game.tmp0].loyalty = Math.min(Game.Girls[Game.tmp0].loyalty + 3, 100);
                        } else if (Game.Girls[Game.tmp0].hasMentalTrait("Prude") && Game.Girls[Game.tmp0].corruption >= 50) {
                            Game.Girls[Game.tmp0].trait2 = 0;
                            ToText(" " + Game.Girls[Game.tmp0].name + '' + " is no more prude, revoking her views on indecency. ");
                        } else if (Game.Girls[Game.tmp0].hasMentalTrait("Pliable") && Game.Girls[Game.tmp0].loyalty >= 80) {
                            ToText(" " + Game.Girls[Game.tmp0].name + '' + " became Devoted. Her willpower strengthened." + '' + " ");
                            Game.Girls[Game.tmp0].addMentalTrait("Devoted");
                            Game.Girls[Game.tmp0].attr.courage = Math.min(Game.Girls[Game.tmp0].attr.courage + Math.tossDice(20, 25), 100);
                            Game.Girls[Game.tmp0].attr.wit = Math.min(Game.Girls[Game.tmp0].attr.wit + Math.tossDice(20, 25), 100);
                        } else if (Game.Girls[Game.tmp0].hasMentalTrait("Pliable") && Game.Girls[Game.tmp0].corruption >= 80) {
                            ToText(" " + Game.Girls[Game.tmp0].name + '' + " became Slutty. Her willpower strengthened." + '' + " ");
                            Game.Girls[Game.tmp0].addMentalTrait("Slutty");
                            Game.Girls[Game.tmp0].attr.confidence = Math.min(Game.Girls[Game.tmp0].attr.confidence + Math.tossDice(20, 25), 100);
                            Game.Girls[Game.tmp0].attr.charm = Math.min(Game.Girls[Game.tmp0].attr.charm + Math.tossDice(20, 25), 100);
                        } else if (Game.Girls[Game.tmp0].hasMentalTrait("Devoted") && Game.Girls[Game.tmp0].loyalty < 80) {
                            Game.Girls[Game.tmp0].loyalty = 80;
                        }
                        ToText("        ");
                        if (Game.Girls[Game.tmp0].rules.toString().charAt(0) == 2) {
                            if (Game.Girls[Game.tmp0].attr.courage >= 25) {
                                Game.Girls[Game.tmp0].attr.courage = Math.max(Game.Girls[Game.tmp0].attr.courage - Math.tossDice(2, 4), 1);
                            }
                            Game.Girls[Game.tmp0].obedience = Math.min(Game.Girls[Game.tmp0].obedience + Math.tossDice(4, 8), 100);
                        }
                        ToText("        ");
                        if (Game.Girls[Game.tmp0].rules.toString().charAt(1) == 2) {
                            if (Game.Girls[Game.tmp0].attr.confidence >= 20) {
                                Game.Girls[Game.tmp0].attr.confidence = Math.max(Game.Girls[Game.tmp0].attr.confidence - Math.tossDice(6, 10), 1);
                            }
                            if (Game.Girls[Game.tmp0].attr.charm >= 20) {
                                Game.Girls[Game.tmp0].attr.charm = Math.max(Game.Girls[Game.tmp0].attr.charm - Math.tossDice(4, 7), 1);
                            }
                            Game.Girls[Game.tmp0].obedience = Math.min(Game.Girls[Game.tmp0].obedience + Math.tossDice(10, 15), 100);
                        }
                        ToText("        ");
                        if (Game.Girls[Game.tmp0].rules.toString().charAt(3) == 2) {
                            if (Game.Girls[Game.tmp0].corruption < 30) {
                                Game.Girls[Game.tmp0].attr.confidence = Math.max(Game.Girls[Game.tmp0].attr.confidence - Math.tossDice(3, 6), 1);
                                Game.Girls[Game.tmp0].corruption += Math.tossDice(3, 5);
                            } else {
                                Game.Girls[Game.tmp0].lust += Math.tossDice(5, 10);
                            }
                        }
                        ToText("        ");
                        if (Game.Girls[Game.tmp0].obedience <= 40 && Game.Girls[Game.tmp0].attr.willpower >= 2 && Game.Girls[Game.tmp0].rules.toString().charAt(0) != 2) {
                            ToText(" " + Game.Girls[Game.tmp0].name + '' + " dares to openly show her disrespect of you and instigate other servants. " + '' + " ");
                            Game.tmp2 = 0;
                            for (var loop_asm36 = 1; loop_asm36 <= Game.Girls.length; loop_asm36++) {
                                if ((Game.Girls[Game.tmp2].id != Game.Girls[Game.tmp0].id) && Game.Girls[Game.tmp2].loyalty <= 30 && !Game.Girls[Game.tmp0].hasMentalTrait("Loner")) {
                                    Game.Girls[Game.tmp2].obedience = Math.max(Game.Girls[Game.tmp2].obedience - Math.round(Game.Girls[Game.tmp0].attr.charm / 3), 0);
                                }
                                Game.tmp2++;
                            }
                        }
                        ToText("        ");
                        if (Game.Girls[Game.tmp0].obedience <= 60 && Game.Girls[Game.tmp0].loyalty <= 25) {
                            switch(Math.tossCase(4)) {
                            case 0:
                                Game.gold = Math.max(Game.gold - Math.tossDice(20, 60), 0);
                                ToText(" You notice that some of your gold is missing." + '' + " ");
                                break;
                            case 1:
                                Game.food = Math.max(Game.food - Math.tossDice(20, 50), 0);
                                ToText(" You notice that some of your food is gone." + '' + " ");
                                break;
                            }
                        }
                        ToText("        ");
                        if (Game.Girls[Game.tmp0].body.clothing == 2) {
                            ToText(" " + Game.Girls[Game.tmp0].name + '' + "'s sundress help her slightly relax.
");
                            Game.Girls[Game.tmp0].stress = Math.max(Game.Girls[Game.tmp0].stress - 4, 0);
                        } else if (Game.Girls[Game.tmp0].body.clothing == 3) {
                            Game.Girls[Game.tmp0].obedience = Math.min(Game.Girls[Game.tmp0].obedience + 3, 100);
                            ToText(" " + Game.Girls[Game.tmp0].name + '' + "'s maid uniform inspires her to be more obedient.
");
                        } else if (Game.Girls[Game.tmp0].body.clothing == 5) {
                            ToText(" " + Game.Girls[Game.tmp0].name + '' + " wears pet suit and ");
                            if ((Game.Girls[Game.tmp0].attr.confidence >= 40 && !Game.Girls[Game.tmp0].hasSexTrait("submissive"))) {
                                Game.Girls[Game.tmp0].attr.confidence = Math.max(Game.Girls[Game.tmp0].attr.confidence - Math.tossDice(2, 4), 1);
                                ToText(" is very unpleasant about it, although");
                            }
                            Game.Girls[Game.tmp0].obedience = Math.min(Game.Girls[Game.tmp0].obedience + 5, 100);
                            ToText(" her obedience grows.
");
                        } else if ((Game.Girls[Game.tmp0].body.clothing == 8 || Game.Girls[Game.tmp0].body.clothing == 9) && Game.Girls[Game.tmp0].corruption <= 20) {
                            ToText(" " + Game.Girls[Game.tmp0].name + '' + "'s revealing clothes causing her to become more open to dirty things.");
                            Game.Girls[Game.tmp0].corruption = Game.Girls[Game.tmp0].corruption + Math.tossDice(2, 4);
                            if (Game.Girls[Game.tmp0].body.clothing == 9 && Game.Girls[Game.tmp0].attr.charm < 30) {
                                Game.Girls[Game.tmp0].attr.charm += Math.tossDice(2, 4);
                                ToText(" " + Game.Girls[Game.tmp0].name + '' + " slightly improved her natural behavior to be more likable. ");
                            }
                            ToText("
");
                        }
                    }
                    ToText("        ");
                }
                if (Game.Girls[Game.tmp0].where_sleep <= 3 && Game.Girls[Game.tmp0].busy < 1) {
                    if (Game.Girls[Game.tmp0].obedience < 25 && (Game.Girls[Game.tmp0].unique != 2 && Game.mission.cali >= 10)) {
                        if (Game.Girls[Game.tmp0].body.brand.type == 'simple') {
                            if (Game.Girls[Game.tmp0].attr.courage / 4 + Game.Girls[Game.tmp0].stress / 5 + Game.Girls[Game.tmp0].attr.willpower * 5 > Game.Girls[Game.tmp0].loyalty * 2 + Game.Girls[Game.tmp0].obedience + Game.Girls[Game.tmp0].attr.wit / 5) {
                                ToText(" " + Game.Girls[Game.tmp0].name + '' + " escaped during the night." + '' + " ");
                                DisplayLocation('death1');
                                continue;
                            }
                        } else if (Game.Girls[Game.tmp0].body.brand.type == 'no') {
                            if (Game.Girls[Game.tmp0].attr.courage / 3 + Game.Girls[Game.tmp0].stress / 4 + Game.Girls[Game.tmp0].attr.willpower * 10 + Game.Girls[Game.tmp0].attr.wit / 3 > Game.Girls[Game.tmp0].loyalty * 2 + Game.Girls[Game.tmp0].obedience) {
                                ToText(" " + Game.Girls[Game.tmp0].name + '' + " escaped during the night." + '' + " ");
                                DisplayLocation('death1');
                                continue;
                            }
                        }
                    }
                }
                if (Game.Girls[Game.tmp0].where_sleep == 5) {
                    ToText("                                ");
                    if (Game.Girls[Game.tmp0].prisoner_feeding == 0 || Game.food < 1) {
                        Game.Girls[Game.tmp0].health = Game.Girls[Game.tmp0].health - 15;
                        Game.Girls[Game.tmp0].obedience = Math.min(Game.Girls[Game.tmp0].obedience + 10, 100);
                        ToText("                Prisoner " + Game.Girls[Game.tmp0].name + '' + " had no dinner. ");
                        if (Game.Girls[Game.tmp0].health < 1) {
                            ToText(" " + Game.Girls[Game.tmp0].name + '' + " died of starvation.");
                            DisplayLocation('death1');
                            continue;
                        } else {
                            Game.Girls[Game.tmp0].stress += 10;
                        }
                        ToText("                ");
                    } else if (Game.Girls[Game.tmp0].prisoner_feeding == 1 && Game.food > 0) {
                        Game.tmp2 = (8 - (0 + 8 * (0.1 + (0.1 * tmp_service))));
                        if (Game.Girls[Game.tmp0].isRace("dryad")) {
                            Game.tmp2 = Game.tmp2 - Math.round(Game.tmp2 / 2);
                        }
                        Game.food = Math.max(Game.food - Game.tmp2, 0);
                        Game.tmp6 += Game.tmp2;
                        Game.Girls[Game.tmp0].health = Math.min(Game.Girls[Game.tmp0].health + 10, 100);
                        if (Game.Girls[Game.tmp0].stress >= 25) {
                            Game.Girls[Game.tmp0].stress = Math.max(Game.Girls[Game.tmp0].stress - 10, 0);
                            if (Game.Girls[Game.tmp0].isRace("fairy")) {
                                Game.Girls[Game.tmp0].stress = Math.max(Game.Girls[Game.tmp0].stress - 10, 0);
                            }
                            ToText("  ");
                        }
                    }
                    Game.Girls[Game.tmp0].obedience = Math.max(Math.min(Game.Girls[Game.tmp0].obedience - (Game.Girls[Game.tmp0].attr.willpower * 3 + Math.round(Game.Girls[Game.tmp0].attr.confidence / 4)) + Game.Girls[Game.tmp0].loyalty + 5, 100), 0);
                }
                Game.Girls[Game.tmp0].WillRecounter();
                if (Game.Girls[Game.tmp0].potion_effect > 0) {
                    Game.Girls[Game.tmp0].potion_effect = 0;
                }
                if (Game.Girls[Game.tmp0].spell_effect > 0) {
                    Game.Girls[Game.tmp0].spell_effect = 0;
                }
                if (Game.Girls[Game.tmp0].stress < 0) {
                    Game.Girls[Game.tmp0].stress = 0;
                }
                Game.tmp0++;
            };;
            ToText("

");
        }
        ToText("

Your residents consume " + Math.round(Game.tmp6) + '' + " units of food per day.

");
        Game.tmp0 = 0;
        ToText("

");
        for (var loop_asm38 = 1; loop_asm38 <= Game.Girls.length; loop_asm38++) {
            ToText("

");
            if (Game.Girls[Game.tmp0].where_sleep != 5 && Game.Girls[Game.tmp0].busy < 1) {
                ToText("

");
                if (Game.Girls[Game.tmp0].rules.toString().charAt(4) == 2) {
                    Game.Girls[Game.tmp0].lust = Game.Girls[Game.tmp0].lust + Math.tossDice(20, 30);
                }
                ToText("

");
                if (Game.Girls[Game.tmp0].lust >= 90 && (Game.Girls[Game.tmp0].where_sleep == 1 || Game.Girls[Game.tmp0].where_sleep == 2) && Game.Girls[Game.tmp0].rules.toString().charAt(2) != 2) {
                    Game.Girls[Game.tmp0].lust = 0;
                    Game.Girls[Game.tmp0].stress = Math.max(Game.Girls[Game.tmp0].stress - 10, 0);
                    ToText(" " + Game.Girls[Game.tmp0].name + '' + " masturbated profoundly in her bed. ");
                } else if (Game.Girls[Game.tmp0].lust >= 90 && Game.Girls[Game.tmp0].where_sleep == 3 && !Game.Girls[Game.tmp0].body.pussy.virgin.value) {
                    Game.Girls[Game.tmp0].lust = 0;
                    Game.Girls[Game.tmp0].stress = Math.max(Game.Girls[Game.tmp0].stress - 15, 0);
                    Game.Girls[Game.tmp0].loyalty = Math.min(Game.Girls[Game.tmp0].loyalty + 4, 100);
                    ToText(" " + Game.Girls[Game.tmp0].name + " couldn't handle her lust, and rode you for hours.");
                    Game.Girls[Game.tmp0].possiblePregnancy(Game.player);
                }
                ToText("

        ");
                if (Game.Girls[Game.tmp0].busy < 1) {
                    ToText("

                ");
                    if (Game.Girls[Game.tmp0].where_sleep == 2) {
                        Game.Girls[Game.tmp0].health = Math.min(Game.Girls[Game.tmp0].health + 5, 100);
                        Game.Girls[Game.tmp0].stress = Math.max(Game.Girls[Game.tmp0].stress - 5, 0);
                        ToText("

                " + Game.Girls[Game.tmp0].name + '' + " sleeps in private room, which helps her heal faster and give some stress relief.

                ");
                    } else if (Game.Girls[Game.tmp0].where_sleep == 3) {
                        Game.Girls[Game.tmp0].loyalty = Math.min(Game.Girls[Game.tmp0].loyalty + 2, 100);
                        if (Game.Girls[Game.tmp0].loyalty >= 30) {
                            Game.Girls[Game.tmp0].stress = Math.max(Game.Girls[Game.tmp0].stress - Math.round(Game.Girls[Game.tmp0].loyalty / 7), 0);
                        }
                        ToText(" " + Game.Girls[Game.tmp0].name + '' + " keeps you company at night and you grew closer.

                ");
                    }
                    ToText("

        ");
                }
                ToText("

");
            }
            ToText("

");
            Game.tmp0++;
            ToText("

");
        }
    }, 1));

    Location.push(new Locations("endoftheday3", function() {
        menuDiv.innerHTML = '';
        printDiv = menuDiv;
        ToText("Proceed", false);
        printDiv = $('print');
        ToText("

");
        Game.tmp0 = 0;
        Game.tmp5 = -1;
        ToText("

");
        for (var loop_asm39 = 1; loop_asm39 <= Game.Girls.length; loop_asm39++) {
            ToText("

");
            Game.tmp0++;
        }
        ToText("

");
        Game.tmp0 = 0;
        ToText("

");
        for (var loop_asm40 = 1; loop_asm40 <= Game.Girls.length; loop_asm40++) {
            ToText("

");
            if (Game.roles.labassistant == -1 && Game.Girls[Game.tmp0].mission == 5) {
                Game.Girls[Game.tmp0].busy++;
                ToText(" You need lab assistant to progress on modifications. ");
            } else if (Game.Girls[Game.tmp0].mission == 5) {
                Game.Girls[Game.roles.labassistant].experience += 5;
            }
            ToText("

");
            if (Game.Girls[Game.tmp0].body.pregnancy >= 1) {
                Game.Girls[Game.tmp0].body.pregnancy++;
                if (Game.Girls[Game.tmp0].busy == 0) {
                    Game.Girls[Game.tmp0].stress += 4;
                }
            }
            ToText("

");
            if (Game.Girls[Game.tmp0].body.pregnancy >= 12 && Game.Girls[Game.tmp0].body.lactation != 1) {
                Game.Girls[Game.tmp0].body.lactation = 1;
            }
            ToText("

");
            if (Game.Girls[Game.tmp0].busy > 0) {
                ToText("

        ");
                Game.Girls[Game.tmp0].busy = Game.Girls[Game.tmp0].busy - 1;
                ToText("

        ");
                if (Game.Girls[Game.tmp0].busy == 0 && Game.Girls[Game.tmp0].mission == 4) {
                    Game.Girls[Game.tmp0].backstory += 'Then I was transformed by staying in the plant in grove. ';
                    ToText("

");
                    Game.Girls[Game.tmp0].setRace("dryad");
                    Game.Girls[Game.tmp0].body.race.generateBody(Game.Girls[Game.tmp0].body);
                    Game.mission.plant = 4;
                    Game.Girls[Game.tmp0].busy = -1;
                    ToText("

You feel like it's time to check on " + Game.Girls[Game.tmp0].name + '' + " in the mystic grove.

");
                }
                if (Game.Girls[Game.tmp0].mission == 5)
                    Game.Girls[Game.tmp0].busy++; // handled by lab assistant.
                ToText("

");
                if (Game.Girls[Game.tmp0].busy == 0 && Game.Girls[Game.tmp0].mission == 6) {
                    ToText("

" + Game.Girls[Game.tmp0].name + '' + " has returns from growth dimension. ");
                    Game.Girls[Game.tmp0].mission = 0;
                }
                ToText("

 ");
            }
            ToText("

");
            Game.tmp0++;
            ToText("

");
        }
        ToText("

");
        if (Game.mission.slaveguild != 2 && Game.days_elapsed % 3 == 0) {
            Game.mission.slaveguild = 0;
        }
        ToText("

");
        if (Game.restock.sebastian == 1 && Game.days_elapsed % 4 == 0) {
            Game.restock.sebastian = 0;
        }
        ToText("

");
        Game.tmp0 = 0;
        Game.tmp2 = -1;
        Game.tmp5 = 0;
        Game.gold_change = 0;
        var food = 0;
        var apiary_mana = 0;
        ToText("

");
        for (var i = 0; i < Game.Girls.length; i++) {
            if (Game.Girls[i].hasJob("Farm Cow") && Game.roles.manager != -1) {
                Game.tmp5 = Math.tossDice(0, 10) + 20 * Game.Girls[i].body.chest.size *
                            (1 + Game.Girls[i].body.chest.pairs * (Game.Girls[i].body.chest.ripe ? 0.33 : 0));
                if (Game.Girls[i].isRace("taurus")) {
                    Game.tmp5 = Math.round(Game.tmp5 * 1.33);
                }
                if (Game.Girls[i].attr.willpower != 0) {
                    Game.Girls[i].stress += 13;
                }
                Game.tmp5 = Math.round(Game.tmp5 * (0.4 + (Game.Girls[Game.roles.manager].skill.management * 0.08) + (Game.Girls[Game.roles.manager].skill.service * 0.04)));
                food += Game.tmp5;
                if (Game.Girls[i].stress >= 100) {
                    Game.Girls[i].mindbroken();
                }
            } else if (Game.Girls[i].hasJob("Farm Hen") && Game.roles.manager != -1) {
                Game.tmp5 = Math.tossDice(160, 185);
                if (Game.Girls[i].attr.willpower != 0 && !Game.Girls[i].hasSexTrait("deviant")) {
                    Game.Girls[i].stress += 16;
                }
                if (Game.Girls[i].body.chest.nipples.elastic == true) { //FIXME better function
                    Game.tmp5 = Game.tmp5 * 1.25;
                }
                if (Game.Girls[i].isRace("harpy")) {
                    Game.tmp5 = Game.tmp5 * 1.2;
                }
                Game.tmp5 = Math.round(Game.tmp5 * (0.4 + (Game.Girls[Game.roles.manager].skill.management * 0.08) + (Game.Girls[Game.roles.manager].skill.service * 0.04)));
                food += Game.tmp5;
                if (Game.Girls[i].stress >= 100) {
                    Game.Girls[i].mindbroken();
                }
            } else if (Game.Girls[i].hasJob("Apiary") && Game.roles.labassistant != -1) {
                Game.tmp5 = Math.tossDice(1, 2);
                if (Game.Girls[i].isRace("drow")) {
                    Game.tmp5++;
                }
                if (Game.Girls[i].attr.willpower != 0 && !Game.Girls[i].hasSexTrait("deviant")) {
                    Game.Girls[i].stress += 15;
                }
                if (Game.Girls[i].stress >= 100) {
                    Game.Girls[i].mindbroken();
                }
                Game.tmp5 = Game.tmp5 + Math.round(Game.Girls[Game.roles.labassistant].skill.magicarts / 2) + Math.floor(Game.Girls[Game.roles.labassistant].skill.service / 2.5);
                apiary_mana += Game.tmp5;
            }
        }
        if (Game.roles.manager != -1) {
            Game.Girls[Game.roles.manager].experience += Math.round(food / 50);
            ToText("

Your farm made " + food + '' + " food on this day.

");
            Game.food += food;
            ToText("

");
        }
        ToText("

");
        if (Game.roles.labassistant != -1) {
            Game.Girls[Game.roles.labassistant].experience += Math.round(apiary_mana);
            ToText("

Your apiary made " + apiary_mana + '' + " mana on this day.

");
            Game.mana += apiary_mana;
            ToText("

");
        }
        ToText("

");
        Game.tmp0 = 0;
        ToText("

");
        for (var loop_asm43 = 1; loop_asm43 <= Game.Girls.length; loop_asm43++) {
            Game.Girls[Game.tmp0].body.race.nightly(Game.Girls[Game.tmp0]);

            if (Game.Girls[Game.tmp0].experience >= 100) {
                Game.Girls[Game.tmp0].experience = Game.Girls[Game.tmp0].experience - 100;
                Game.Girls[Game.tmp0].level++;
                ToText(" " + Game.Girls[Game.tmp0].name + '' + " achieved enough experience for level up!" + '' + " ");
                if (Game.Girls[Game.tmp0].level <= 15) {
                    ToText(" She gets an extra skill point." + '' + " ");
                    Game.Girls[Game.tmp0].skillpoints++;
                }
            }
            ToText("

");
            if (Game.Girls[Game.tmp0].busy == 0 && Game.Girls[Game.tmp0].where_sleep <= 3 && Game.Girls[Game.tmp0].stress >= 85) {
                ToText("

");
                if (Game.Girls[Game.tmp0].rules.toString().charAt(0) == 2) {
                    ToText(" After she was allowed to talk," + '' + " ");
                }
                ToText(" " + Game.Girls[Game.tmp0].name + " complained ");
                if (Game.roles.headgirl != -1) {
                    ToText(" to the " + Game.Girls[Game.roles.headgirl].name + '' + ", " + '');
                } else {
                    ToText(" to you, " + '');
                }
                ToText(" that she's having it too hard and hoped to get some rest." + '' + "

");
            }
            ToText("

");
            Game.tmp0++;
        }
        ToText("

Nothing else happened today.

");
        if (Game.patron_beg == 1) {
            Game.patron_beg = 0;
        }
        ToText("

");
        Game.food = Math.round(Game.food);
        ToText("

");
        if (Game.gold.toString() == 'NaN') {
            Game.gold = Game.revert.gold;
            ToText(" Something went wrong and your money were rolledback." + '' + " ");
        }
        ToText("

");
        if (Game.food.toString() == 'NaN') {
            Game.food = Game.revert.food;
            ToText(" Something went wrong and your food was rolledback." + '' + " ");
        }
        ToText("

");
        if (Game.mana.toString() == 'NaN') {
            Game.mana = Game.revert.mana;
            ToText(" Something went wrong and your mana was rolledback." + '' + " ");
        }
    }, 1));

    Location.push(new Locations("headgirl", function() {
        ToText("Head Girl is an influental figure you assign to inspire or intimidate your less reliable servants. The obvious upside is that she won't take your energy to deal with rebellious servants in order to build obedience and her attendance won't have huge impact on personality of others as if you delivered punishments on your own. Confidence and Management will make her efficient when building obedience, and Charm with Allure are key to make others more accepting of your regime.

");

        if (Game.roles.headgirl == -1) {
            ToText("You have no headgirl set.");
            return;
        }

        var job = Data.job_byname.head_girl;

        var headgirl = Game.Girls[Game.roles.headgirl];

        var cando = [];
        cando[0] = job._canTake(headgirl, 0);
        cando[1] = job._canTake(headgirl, 1);

        var reqs = [];
        reqs[0] = job.showReqs(headgirl, 0);
        reqs[1] = job.showReqs(headgirl, 1);

        var out = '';

        out += "

";
        if (Game.headgirl_orders == 0)
            out += " ☑"
        else if (cando[0][0])
            out +="☐"
        else
            out += "☐";

        out += " Strict Behavior — Headgirl will focus on putting other servants in line at the cost of thier stress.";
        out += " Requires: " + reqs[0][0];

        out += "

";

        if (Game.headgirl_orders == 1)
            out += " ☑"
        else if (cando[1][0])
            out +="☐"
        else
            out += "☐";

        out += " Patronage Behavior — Headgirl will focus on kind approach and improve stress and loyalty of others.";
        out += " Requires: " + reqs[1][0];
        out += "

";

        ToText(out + "Return");
    }, 1));

    Location.push(new Locations("companion", function() {
        ToText("Choose a person to accompany you on your adventures. Current follower — ");
        if (Game.companion == -1) {
            ToText(" nobody. ");
        } else {
            ToText(Game.Girls[Game.companion].name + '' + ".");
        }
        ToText("

Nobody

");

        for (var i = 0; i < Game.Girls.length; i++) {
            if (Game.Girls[i].id > 0 && Game.Girls[i].busy == 0 && Game.Girls[i].mission == 0 && !Game.Girls[i].hasJob("Companion")) {
                ToText(Game.Girls[i].displaySelect("Game.tmp2 = " + i + ";PrintLocation("companion1");event.stopPropagation()") + "

");
            }
        }
    }, 1));

    Location.push(new Locations("racedescription", function() {
        var race = Data.getRace(Game.tmp1);
        ToText(race.description);
        if (race.trait != undefined)
            ToText("

Racial trait — " + race.trait + ".");
        ToText("

");
    }, 1));

    function ChangeNamesAndDesc(e) {
        if(Trim(e[0].value)!='')
            Game.Girls[Game.tmp0].name=Trim(e[0].value);
        Game.Girls[Game.tmp0].lastname=Trim(e[1].value);
        Game.Girls[Game.tmp0].extra_description=Trim(e[2].value);
    }

    Location.push(new Locations("rename", function() {
        var out = '';
        var girl = Game.Girls[Game.tmp0];
        if (girl.lastname == 0)
            girl.lastname = '';
        if (girl.extra_description == 0)
            girl.extra_description = '';

        out += "
<form action='' onsubmit= 'ChangeNamesAndDesc(this);PrintLocation("resident0");event.stopPropagation();'>";

        out += "Firstname: <input class='input_text2' type='text' onclick='event.stopPropagation();' autocapitalize='off' size='10' value='" + girl.name + "'" + focus + ">";

        out += "
Lastname: <input class='input_text2' type='text' onclick='event.stopPropagation();' autocapitalize='off' size='10' value='" + Game.Girls[Game.tmp0].lastname + "'>";

        out += "
Description:
<textarea class='input_text2' rows='15' style='width: 100%;' onclick='event.stopPropagation();' autocapitalize='off' size='10'>" + Game.Girls[Game.tmp0].extra_description + "</textarea>";
        out += "
<input class='button' type='submit' value='Change'> ";
        out += "Cancel";
        out += "</form>
";
        ToText(out);
    }, 1));