<commit_before>// ==UserScript==
// @name         Agario Skins+
// @namespace    https://github.com/Lukkez/Agario-Skins/
// @version      1.0.0
// @description  My extension
// @author       Lukkez
// @license      MIT
// @match        http://agar.io/
// @run-at       document-start
// @grant        none
// ==/UserScript==

//waits for the page to load

window.onload = function() {
    var ctx = document.getElementById("canvas").getContext("2d")

    //replaces title
    //h2 selects all h2 elements
    $("h2").replaceWith('
Agar.io Skins+
');

    //zoom
    window.agar.minScale = -30;

    //sets dark theme to true on extension load
    setDarkTheme(true);
    //sets show mass to true on extension load
    setShowMass(true);

    //Cell skin
    image = new Image();
    image.crossOrigin = 'anonymous';
    image.src = 'http://i.imgur.com/dOFpphQ.png';
    window.agar.hooks.cellSkin = function(cell, old_skin) {
        if (cell.name == "Bot") return image;
        return old_skin;
}

    image = new Image()
    image.crossOrigin = 'anonymous'
    image.src = 'http://i.imgur.com/GBpr1JR.png' //link
    window.agar.hooks.cellSkin = function(cell, old_skin) {
        for (i = 0; i < window.agar.myCells.length; i++) {
            if(cell.id == window.agar.myCells[i]) return image;
        }
    }

    window.agar.hooks.drawCellMass = function(cell, old_draw) {
     if(cell.size > 20) return cell;
    }

    //Show other players mass text
    window.agar.hooks.cellMassTextScale = function(cell, old_scale) {
    }

}
<commit_msg>Oops, Ogar-feeder-bot code removed<commit_after>// ==UserScript==
// @name         Agario Skins+
// @namespace    https://github.com/Lukkez/Agario-Skins/
// @version      1.0.0
// @description  My extension
// @author       Lukkez
// @license      MIT
// @match        http://agar.io/
// @run-at       document-start
// @grant        none
// ==/UserScript==

//waits for the page to load

window.onload = function() {
    var ctx = document.getElementById("canvas").getContext("2d")

    //replaces title
    //h2 selects all h2 elements
    $("h2").replaceWith('
Agar.io Skins+
');

    //zoom
    window.agar.minScale = -30;

    //sets dark theme to true on extension load
    setDarkTheme(true);
    //sets show mass to true on extension load
    setShowMass(true);

    image = new Image()
    image.crossOrigin = 'anonymous'
    image.src = 'http://i.imgur.com/GBpr1JR.png' //link
    window.agar.hooks.cellSkin = function(cell, old_skin) {
        for (i = 0; i < window.agar.myCells.length; i++) {
            if(cell.id == window.agar.myCells[i]) return image;
        }
    }

    window.agar.hooks.drawCellMass = function(cell, old_draw) {
     if(cell.size > 20) return cell;
    }

    //Show other players mass text
    window.agar.hooks.cellMassTextScale = function(cell, old_scale) {
    }

}
<|endoftext|>


<commit_before>/* eslint camelcase: 0 */
const JOB_START = 'playbook_on_start';
const JOB_END = 'playbook_on_stats';
const PLAY_START = 'playbook_on_play_start';
const TASK_START = 'playbook_on_task_start';

const HOST_STATUS_KEYS = ['dark', 'failures', 'changed', 'ok', 'skipped'];
const COMPLETE = ['successful', 'failed'];
const INCOMPLETE = ['canceled', 'error'];
const UNSUCCESSFUL = ['failed'].concat(INCOMPLETE);
const FINISHED = COMPLETE.concat(INCOMPLETE);

function JobStatusService (moment, message) {
    this.dispatch = () => message.dispatch('status', this.state);
    this.subscribe = listener => message.subscribe('status', listener);

    this.init = ({ model }) => {
        this.created = model.get('created');
        this.job = model.get('id');
        this.jobType = model.get('type');
        this.project = model.get('project');

        this.active = false;
        this.latestTime = null;
        this.counter = -1;

        this.state = {
            running: false,
            counts: {
                plays: 0,
                tasks: 0,
                hosts: 0,
            },
            hosts: {},
            status: model.get('status'),
            elapsed: model.get('elapsed'),
            started: model.get('started'),
            finished: model.get('finished'),
            scm: {
                id: model.get('summary_fields.project_update.id'),
                status: model.get('summary_fields.project_update.status')
            },
        };

        if (model.get('type') === 'job' || model.get('type') === 'project_update') {
            if (model.has('playbook_counts')) {
                this.setPlaybookCounts(model.get('playbook_counts'));
            }

            if (model.has('host_status_counts')) {
                this.setHostStatusCounts(model.get('host_status_counts'));
            }
        } else {
            const hostStatusCounts = this.createHostStatusCounts(this.state.status);

            this.setHostStatusCounts(hostStatusCounts);
            this.setPlaybookCounts({ task_count: 1, play_count: 1 });
        }

        this.updateRunningState();
        this.dispatch();
    };

    this.createHostStatusCounts = status => {
        if (UNSUCCESSFUL.includes(status)) {
            return { failures: 1 };
        }

        if (COMPLETE.includes(status)) {
            return { ok: 1 };
        }

        return null;
    };

    this.pushStatusEvent = data => {
        const isJobStatusEvent = (this.job === data.unified_job_id);
        const isProjectStatusEvent = (this.project && (this.project === data.project_id));

        if (isJobStatusEvent) {
            this.setJobStatus(data.status);
            this.dispatch();
        } else if (isProjectStatusEvent) {
            this.setProjectStatus(data.status);
            this.setProjectUpdateId(data.unified_job_id);
            this.dispatch();
        }
    };

    this.pushJobEvent = data => {
        const isLatest = ((!this.counter) || (data.counter > this.counter));

        let changed = false;

        if (!this.active && !(data.event === JOB_END)) {
            this.active = true;
            this.setJobStatus('running');
            changed = true;
        }

        if (isLatest) {
            this.counter = data.counter;
            this.latestTime = data.created;
            this.setElapsed(moment(data.created).diff(this.created, 'seconds'));
            changed = true;
        }

        if (data.event === JOB_START) {
            this.setStarted(this.state.started || data.created);
            changed = true;
        }

        if (data.event === PLAY_START) {
            this.state.counts.plays++;
            changed = true;
        }

        if (data.event === TASK_START) {
            this.state.counts.tasks++;
            changed = true;
        }

        if (data.event === JOB_END) {
            this.setStatsEvent(data);
            changed = true;
        }

        if (changed) {
            this.dispatch();
        }
    };

    this.isExpectingStatsEvent = () => (this.jobType === 'job') ||
        (this.jobType === 'project_update');

    this.updateStats = () => {
        this.updateHostCounts();

        if (this.statsEvent) {
            this.setFinished(this.statsEvent.created);
            this.setJobStatus(this.statsEvent.failed ? 'failed' : 'successful');
        }
    };

    this.updateRunningState = () => {
        this.state.running = (Boolean(this.state.started) && !this.state.finished) ||
            (this.state.status === 'running') ||
            (this.state.status === 'pending') ||
            (this.state.status === 'waiting');
    };

    this.updateHostCounts = () => {
        const countedHostNames = [];

        const counts = Object.assign(...HOST_STATUS_KEYS.map(key => ({ [key]: 0 })));

        HOST_STATUS_KEYS.forEach(key => {
            const hostData = _.get(this.statsEvent, ['event_data', key], {});

            Object.keys(hostData).forEach(hostName => {
                const isAlreadyCounted = (countedHostNames.indexOf(hostName) > -1);
                const shouldBeCounted = ((!isAlreadyCounted) && hostData[hostName] > 0);

                if (shouldBeCounted) {
                    countedHostNames.push(hostName);
                    counts[key]++;
                }
            });
        });

        this.state.counts.hosts = countedHostNames.length;
        this.setHostStatusCounts(counts);
    };

    this.setJobStatus = status => {
        const isExpectingStats = this.isExpectingStatsEvent();
        const isIncomplete = _.includes(INCOMPLETE, status);
        const isFinished = _.includes(FINISHED, status);
        const isAlreadyFinished = _.includes(FINISHED, this.state.status);

        if (isAlreadyFinished) {
            return;
        }

        if ((isExpectingStats && isIncomplete) || (!isExpectingStats && isFinished)) {
            if (this.latestTime) {
                this.setFinished(this.latestTime);
                if (!this.state.started && this.state.elapsed) {
                    this.setStarted(moment(this.latestTime)
                        .subtract(this.state.elapsed, 'seconds'));
                }
            }
        }

        this.state.status = status;
        this.updateRunningState();
    };

    this.setElapsed = elapsed => {
        this.state.elapsed = elapsed;
    };

    this.setStarted = started => {
        this.state.started = started;
        this.updateRunningState();
    };

    this.setProjectStatus = status => {
        this.state.scm.status = status;
    };

    this.setProjectUpdateId = id => {
        this.state.scm.id = id;
    };

    this.setFinished = time => {
        this.state.finished = time;
        this.updateRunningState();
    };

    this.setStatsEvent = data => {
        this.statsEvent = data;
    };

    this.setHostStatusCounts = counts => {
        counts = counts || {};

        HOST_STATUS_KEYS.forEach(key => {
            counts[key] = counts[key] || 0;
        });

        if (!this.state.counts.hosts) {
            this.state.counts.hosts = Object.keys(counts)
                .reduce((sum, key) => sum + counts[key], 0);
        }

        this.state.hosts = counts;
    };

    this.setPlaybookCounts = ({ play_count, task_count }) => {
        this.state.counts.plays = play_count;
        this.state.counts.tasks = task_count;
    };

    this.resetCounts = () => {
        this.state.counts.plays = 0;
        this.state.counts.tasks = 0;
        this.state.counts.hosts = 0;
    };
}

JobStatusService.$inject = [
    'moment',
    'OutputMessageService',
];

export default JobStatusService;
<commit_msg>use host_status_counts field for adhoc command jobs ui<commit_after>/* eslint camelcase: 0 */
const JOB_START = 'playbook_on_start';
const JOB_END = 'playbook_on_stats';
const PLAY_START = 'playbook_on_play_start';
const TASK_START = 'playbook_on_task_start';

const HOST_STATUS_KEYS = ['dark', 'failures', 'changed', 'ok', 'skipped'];
const COMPLETE = ['successful', 'failed'];
const INCOMPLETE = ['canceled', 'error'];
const UNSUCCESSFUL = ['failed'].concat(INCOMPLETE);
const FINISHED = COMPLETE.concat(INCOMPLETE);

function JobStatusService (moment, message) {
    this.dispatch = () => message.dispatch('status', this.state);
    this.subscribe = listener => message.subscribe('status', listener);

    this.init = ({ model }) => {
        this.created = model.get('created');
        this.job = model.get('id');
        this.jobType = model.get('type');
        this.project = model.get('project');

        this.active = false;
        this.latestTime = null;
        this.counter = -1;

        this.state = {
            running: false,
            counts: {
                plays: 0,
                tasks: 0,
                hosts: 0,
            },
            hosts: {},
            status: model.get('status'),
            elapsed: model.get('elapsed'),
            started: model.get('started'),
            finished: model.get('finished'),
            scm: {
                id: model.get('summary_fields.project_update.id'),
                status: model.get('summary_fields.project_update.status')
            },
        };

        if (model.has('host_status_counts')) {
            this.setHostStatusCounts(model.get('host_status_counts'));
        } else {
            const hostStatusCounts = this.createHostStatusCounts(this.state.status);

            this.setHostStatusCounts(hostStatusCounts);
        }

        if (model.has('playbook_counts')) {
            this.setPlaybookCounts(model.get('playbook_counts'));
        } else {
            this.setPlaybookCounts({ task_count: 1, play_count: 1 });
        }

        this.updateRunningState();
        this.dispatch();
    };

    this.createHostStatusCounts = status => {
        if (UNSUCCESSFUL.includes(status)) {
            return { failures: 1 };
        }

        if (COMPLETE.includes(status)) {
            return { ok: 1 };
        }

        return null;
    };

    this.pushStatusEvent = data => {
        const isJobStatusEvent = (this.job === data.unified_job_id);
        const isProjectStatusEvent = (this.project && (this.project === data.project_id));

        if (isJobStatusEvent) {
            this.setJobStatus(data.status);
            this.dispatch();
        } else if (isProjectStatusEvent) {
            this.setProjectStatus(data.status);
            this.setProjectUpdateId(data.unified_job_id);
            this.dispatch();
        }
    };

    this.pushJobEvent = data => {
        const isLatest = ((!this.counter) || (data.counter > this.counter));

        let changed = false;

        if (!this.active && !(data.event === JOB_END)) {
            this.active = true;
            this.setJobStatus('running');
            changed = true;
        }

        if (isLatest) {
            this.counter = data.counter;
            this.latestTime = data.created;
            this.setElapsed(moment(data.created).diff(this.created, 'seconds'));
            changed = true;
        }

        if (data.event === JOB_START) {
            this.setStarted(this.state.started || data.created);
            changed = true;
        }

        if (data.event === PLAY_START) {
            this.state.counts.plays++;
            changed = true;
        }

        if (data.event === TASK_START) {
            this.state.counts.tasks++;
            changed = true;
        }

        if (data.event === JOB_END) {
            this.setStatsEvent(data);
            changed = true;
        }

        if (changed) {
            this.dispatch();
        }
    };

    this.isExpectingStatsEvent = () => (this.jobType === 'job') ||
        (this.jobType === 'project_update') ||
        (this.jobType === 'ad_hoc_command');

    this.updateStats = () => {
        this.updateHostCounts();

        if (this.statsEvent) {
            this.setFinished(this.statsEvent.created);

            const failures = _.get(this.statsEvent, ['event_data', 'failures'], {});
            const dark = _.get(this.statsEvent, ['event_data', 'dark'], {});

            if (this.statsEvent.failed ||
                Object.keys(failures).length > 0 ||
                Object.keys(dark).length > 0) {
                this.setJobStatus('failed');
            } else {
                this.setJobStatus('successful');
            }
        }
    };

    this.updateRunningState = () => {
        this.state.running = (Boolean(this.state.started) && !this.state.finished) ||
            (this.state.status === 'running') ||
            (this.state.status === 'pending') ||
            (this.state.status === 'waiting');
    };

    this.updateHostCounts = () => {
        const countedHostNames = [];

        const counts = Object.assign(...HOST_STATUS_KEYS.map(key => ({ [key]: 0 })));

        HOST_STATUS_KEYS.forEach(key => {
            const hostData = _.get(this.statsEvent, ['event_data', key], {});

            Object.keys(hostData).forEach(hostName => {
                const isAlreadyCounted = (countedHostNames.indexOf(hostName) > -1);
                const shouldBeCounted = ((!isAlreadyCounted) && hostData[hostName] > 0);

                if (shouldBeCounted) {
                    countedHostNames.push(hostName);
                    counts[key]++;
                }
            });
        });

        this.state.counts.hosts = countedHostNames.length;
        this.setHostStatusCounts(counts);
    };

    this.setJobStatus = status => {
        const isExpectingStats = this.isExpectingStatsEvent();
        const isIncomplete = INCOMPLETE.includes(status);
        const isFinished = FINISHED.includes(status);
        const isAlreadyFinished = FINISHED.includes(this.state.status);

        if (isAlreadyFinished) {
            return;
        }

        if ((isExpectingStats && isIncomplete) || (!isExpectingStats && isFinished)) {
            if (this.latestTime) {
                this.setFinished(this.latestTime);
                if (!this.state.started && this.state.elapsed) {
                    this.setStarted(moment(this.latestTime)
                        .subtract(this.state.elapsed, 'seconds'));
                }
            }
        }

        this.state.status = status;
        this.updateRunningState();
    };

    this.setElapsed = elapsed => {
        this.state.elapsed = elapsed;
    };

    this.setStarted = started => {
        this.state.started = started;
        this.updateRunningState();
    };

    this.setProjectStatus = status => {
        this.state.scm.status = status;
    };

    this.setProjectUpdateId = id => {
        this.state.scm.id = id;
    };

    this.setFinished = time => {
        this.state.finished = time;
        this.updateRunningState();
    };

    this.setStatsEvent = data => {
        this.statsEvent = data;
    };

    this.setHostStatusCounts = counts => {
        counts = counts || {};

        HOST_STATUS_KEYS.forEach(key => {
            counts[key] = counts[key] || 0;
        });

        if (!this.state.counts.hosts) {
            this.state.counts.hosts = Object.keys(counts)
                .reduce((sum, key) => sum + counts[key], 0);
        }

        this.state.hosts = counts;
    };

    this.setPlaybookCounts = ({ play_count, task_count }) => {
        this.state.counts.plays = play_count;
        this.state.counts.tasks = task_count;
    };

    this.resetCounts = () => {
        this.state.counts.plays = 0;
        this.state.counts.tasks = 0;
        this.state.counts.hosts = 0;
    };
}

JobStatusService.$inject = [
    'moment',
    'OutputMessageService',
];

export default JobStatusService;
<|endoftext|>


<commit_before>#!/usr/bin/env node

function getLastGlucose(data) {

    var one = data[0];
    var two = data[1];
    var o = {
        delta: one.glucose - two.glucose
        , glucose: one.glucose
    };

    return o;

}

function setTempBasal(rate, duration) {

    maxSafeBasal = Math.min(profile_data.max_basal, 2 * profile_data.max_daily_basal, 4 * profile_data.current_basal);

    if (rate < 0) { rate = 0; } // if >30m @ 0 required, zero temp will be extended to 30m instead
    else if (rate > maxSafeBasal) { rate = maxSafeBasal; }

    requestedTemp.duration = duration;
    requestedTemp.rate = rate;

};

if (!module.parent) {
    var iob_input = process.argv.slice(2, 3).pop()
    var temps_input = process.argv.slice(3, 4).pop()
    var glucose_input = process.argv.slice(4, 5).pop()
    var profile_input = process.argv.slice(5, 6).pop()

    if (!iob_input || !temps_input || !glucose_input || !profile_input) {
        console.error('usage: ', process.argv.slice(0, 2), '<iob.json> <current-temps.json> <glucose.json> <profile.json>');
        process.exit(1);
    }

    var cwd = process.cwd()
    var glucose_data = require(cwd + '/' + glucose_input);
    var temps_data = require(cwd + '/' + temps_input);
    var iob_data = require(cwd + '/' + iob_input);
    var profile_data = require(cwd + '/' + profile_input);

    if (typeof profile_data === 'undefined' || typeof profile_data.current_basal === 'undefined') {
        console.error('Error: could not get current basal rate');
        process.exit(1);
    }

    // if target_bg is set, great. otherwise, if min and max are set, then set target to their average
    var target_bg;
    if (typeof profile_data.target_bg !== 'undefined') {
        target_bg = profile_data.target_bg;
    } else {
        if (typeof profile_data.max_bg !== 'undefined' && typeof profile_data.max_bg !== 'undefined') {
            target_bg = (profile_data.max_bg + profile_data.max_bg) / 2;
        } else {
            console.error('Error: could not determine target_bg');
            process.exit(1);
        }
    }

    var glucose_status = getLastGlucose(glucose_data);
    var bg = glucose_status.glucose
    var eventualBG = bg - (iob_data.iob * profile_data.sens);
    var requestedTemp = {
        'temp': 'absolute'
    };

    //if old reading from Dexcom do nothing

    var systemTime = new Date();
    var displayTime = new Date(glucose_data[0].display_time.replace('T', ' '));
    var minAgo = (systemTime - displayTime) / 60 / 1000

    if (minAgo < 10 && minAgo > -5 ) { // Dexcom data is recent, but not far in the future

        if (bg < profile_data.min_bg - 30) { // low glucose suspend mode: BG is < ~80
            if (glucose_status.delta > 0) { // if BG is rising
                if (temps_data.rate > profile_data.current_basal) { // if a high-temp is running
                    setTempBasal(0, 0); // cancel it
                } else { // no high-temp
                    console.error("No action required (no high-temp to cancel)")
                }
            }
            else { // if (glucose_status.delta <= 0) { // BG is not yet rising
                setTempBasal(0, 30);
            }

        } else {

            // if BG is rising but eventual BG is below target, or BG is falling but eventual BG is above target,
            // then cancel any temp basals.
            if ((glucose_status.delta > 0 && eventualBG < profile_data.min_bg) || (glucose_status.delta < 0 && eventualBG >= profile_data.max_bg)) {
                if (temps_data.duration > 0) { // if there is currently any temp basal running
                    setTempBasal(0, 0); // cancel temp
                } else {
                    console.error("No action required (no temp to cancel)")
                }

            } else if (eventualBG < profile_data.min_bg) { // if eventual BG is below target:
                // calculate 30m low-temp required to get projected BG up to target
                // negative insulin required to get up to min:
                var insulinReq = Math.max(0, (target_bg - eventualBG) / profile_data.sens);
                // rate required to deliver insulinReq less insulin over 30m:
                var rate = profile_data.current_basal - (2 * insulinReq);

                if (typeof temps_data.rate === 'undefined' || ( temps_data.duration > 0 && rate < temps_data.rate )) { // if required temp < existing temp basal
                    setTempBasal(rate, 30);
                } else {
                    console.error("No action required (existing basal " + temps_data.rate + " <= required temp " + rate + " )")
                }

            } else if (eventualBG > profile_data.max_bg) { // if eventual BG is above target:
                // calculate 30m high-temp required to get projected BG down to target
                // additional insulin required to get down to max:
                var insulinReq = (target_bg - eventualBG) / profile_data.sens;
                // rate required to deliver insulinReq more insulin over 30m:
                var rate = profile_data.current_basal - (2 * insulinReq);
                if (typeof temps_data.rate === 'undefined' || rate > temps_data.rate){ // if required temp > existing temp basal
                    setTempBasal(rate, 30);
                } else {
                    console.error("No action required (existing basal " + temps_data.rate + " >= required temp " + rate + " )")
                }

            } else { // if (profile_data.min_bg < eventualBG < profile_data.max_bg) {
                console.error(eventualBG + " is in range. No action required.")
            }
        }
    } else {
        console.error("BG data is too old")
    }

    console.log(JSON.stringify(requestedTemp));
}

<commit_msg>check whether temps_data.duration > 0 to differentiate no-temp from zero-temp<commit_after>#!/usr/bin/env node

function getLastGlucose(data) {

    var one = data[0];
    var two = data[1];
    var o = {
        delta: one.glucose - two.glucose
        , glucose: one.glucose
    };

    return o;

}

function setTempBasal(rate, duration) {

    maxSafeBasal = Math.min(profile_data.max_basal, 2 * profile_data.max_daily_basal, 4 * profile_data.current_basal);

    if (rate < 0) { rate = 0; } // if >30m @ 0 required, zero temp will be extended to 30m instead
    else if (rate > maxSafeBasal) { rate = maxSafeBasal; }

    requestedTemp.duration = duration;
    requestedTemp.rate = rate;

};

if (!module.parent) {
    var iob_input = process.argv.slice(2, 3).pop()
    var temps_input = process.argv.slice(3, 4).pop()
    var glucose_input = process.argv.slice(4, 5).pop()
    var profile_input = process.argv.slice(5, 6).pop()

    if (!iob_input || !temps_input || !glucose_input || !profile_input) {
        console.error('usage: ', process.argv.slice(0, 2), '<iob.json> <current-temps.json> <glucose.json> <profile.json>');
        process.exit(1);
    }

    var cwd = process.cwd()
    var glucose_data = require(cwd + '/' + glucose_input);
    var temps_data = require(cwd + '/' + temps_input);
    var iob_data = require(cwd + '/' + iob_input);
    var profile_data = require(cwd + '/' + profile_input);

    if (typeof profile_data === 'undefined' || typeof profile_data.current_basal === 'undefined') {
        console.error('Error: could not get current basal rate');
        process.exit(1);
    }

    // if target_bg is set, great. otherwise, if min and max are set, then set target to their average
    var target_bg;
    if (typeof profile_data.target_bg !== 'undefined') {
        target_bg = profile_data.target_bg;
    } else {
        if (typeof profile_data.max_bg !== 'undefined' && typeof profile_data.max_bg !== 'undefined') {
            target_bg = (profile_data.max_bg + profile_data.max_bg) / 2;
        } else {
            console.error('Error: could not determine target_bg');
            process.exit(1);
        }
    }

    var glucose_status = getLastGlucose(glucose_data);
    var bg = glucose_status.glucose
    var eventualBG = bg - (iob_data.iob * profile_data.sens);
    var requestedTemp = {
        'temp': 'absolute'
    };

    //if old reading from Dexcom do nothing

    var systemTime = new Date();
    var displayTime = new Date(glucose_data[0].display_time.replace('T', ' '));
    var minAgo = (systemTime - displayTime) / 60 / 1000

    if (minAgo < 10 && minAgo > -5 ) { // Dexcom data is recent, but not far in the future

        if (bg < profile_data.min_bg - 30) { // low glucose suspend mode: BG is < ~80
            if (glucose_status.delta > 0) { // if BG is rising
                if (temps_data.rate > profile_data.current_basal) { // if a high-temp is running
                    setTempBasal(0, 0); // cancel it
                } else { // no high-temp
                    console.error("No action required (no high-temp to cancel)")
                }
            }
            else { // if (glucose_status.delta <= 0) { // BG is not yet rising
                setTempBasal(0, 30);
            }

        } else {

            // if BG is rising but eventual BG is below target, or BG is falling but eventual BG is above target,
            // then cancel any temp basals.
            if ((glucose_status.delta > 0 && eventualBG < profile_data.min_bg) || (glucose_status.delta < 0 && eventualBG >= profile_data.max_bg)) {
                if (temps_data.duration > 0) { // if there is currently any temp basal running
                    setTempBasal(0, 0); // cancel temp
                } else {
                    console.error("No action required (no temp to cancel)")
                }

            } else if (eventualBG < profile_data.min_bg) { // if eventual BG is below target:
                // calculate 30m low-temp required to get projected BG up to target
                // negative insulin required to get up to min:
                var insulinReq = Math.max(0, (target_bg - eventualBG) / profile_data.sens);
                // rate required to deliver insulinReq less insulin over 30m:
                var rate = profile_data.current_basal - (2 * insulinReq);

                if (typeof temps_data.rate !== 'undefined' && ( temps_data.duration > 0 && rate <= temps_data.rate )) { // if required temp < existing temp basal
                    console.error("No action required (existing basal " + temps_data.rate + " <= required temp " + rate + " )")
                } else {
                    setTempBasal(rate, 30);
                }

            } else if (eventualBG > profile_data.max_bg) { // if eventual BG is above target:
                // calculate 30m high-temp required to get projected BG down to target
                // additional insulin required to get down to max:
                var insulinReq = (target_bg - eventualBG) / profile_data.sens;
                // rate required to deliver insulinReq more insulin over 30m:
                var rate = profile_data.current_basal - (2 * insulinReq);
                if (typeof temps_data.rate === 'undefined' || rate > temps_data.rate){ // if required temp > existing temp basal
                    setTempBasal(rate, 30);
                } else {
                    console.error("No action required (existing basal " + temps_data.rate + " >= required temp " + rate + " )")
                }

            } else { // if (profile_data.min_bg < eventualBG < profile_data.max_bg) {
                console.error(eventualBG + " is in range. No action required.")
            }
        }
    } else {
        console.error("BG data is too old")
    }

    console.log(JSON.stringify(requestedTemp));
}

<|endoftext|>


<commit_before>require('../selection');
angular.module('n52.core.selection')
    .component('platformMapSelector', {
        bindings: {
            mapId: '@',
            serviceUrl: '<',
            filter: '<',
            mapLayers: '<',
            cluster: '<',
            platformSelected: "&onPlatformSelected",
        },
        templateUrl: 'n52.core.selection.platform-map-selector',
        controller: ['seriesApiInterface', '$scope', 'leafletData',
            function(seriesApiInterface, $scope, leafletData) {

                this.markers = {};
                var layer;

                this.$onInit = () => {
                    setTimeout(() => {
                        leafletData.getMap(this.mapId).then((map) => {
                            map.invalidateSize();
                        });
                    }, 10);
                };

                this.$onChanges = () => {
                    this.loading = true;
                    leafletData.getMap(this.mapId).then((map) => {
                        // clear layer
                        if (layer) map.removeLayer(layer);
                        // add marker to layer
                        seriesApiInterface.getPlatforms(null, this.serviceUrl, this.filter)
                            .then((res) => {
                                layer = L.markerClusterGroup();
                                res.forEach(entry => {
                                    var marker = L.marker([entry.geometry.coordinates[1], entry.geometry.coordinates[0]], {

                                    });
                                    marker.on('click', () => {
                                        seriesApiInterface.getPlatforms(entry.id, this.serviceUrl)
                                            .then(entry => {
                                                this.platformSelected({
                                                    platform: entry
                                                });
                                            });
                                    });
                                    marker.addTo(map);
                                    layer.addLayer(marker);
                                });

                                layer.addTo(map);
                                // zoom to layer
                                map.invalidateSize();
                                map.fitBounds(layer.getBounds());
                                this.loading = false;
                            });
                    });
                };
            }
        ]
    });
<commit_msg>update restructure provider-map-selector<commit_after>require('../selection');
angular.module('n52.core.selection')
    .component('platformMapSelector', {
        bindings: {
            mapId: '@',
            serviceUrl: '<',
            filter: '<',
            mapLayers: '<',
            cluster: '<',
            platformSelected: "&onPlatformSelected",
        },
        templateUrl: 'n52.core.selection.platform-map-selector',
        controller: ['seriesApiInterface', '$scope', 'leafletData',
            function(seriesApiInterface, $scope, leafletData) {

                var myIcon = L.icon({
                    iconUrl: require('leaflet/dist/images/marker-icon.png'),
                    iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
                    shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
                    iconSize: [25, 41],
                    iconAnchor: [12, 41],
                    popupAnchor: [1, -34],
                    shadowSize: [41, 41]
                });

                this.markers = {};
                var layer;

                this.$onInit = () => {
                    setTimeout(() => {
                        leafletData.getMap(this.mapId).then((map) => {
                            map.invalidateSize();
                        });
                    }, 10);
                };

                this.$onChanges = () => {
                    this.loading = true;
                    leafletData.getMap(this.mapId).then((map) => {
                        // clear layer
                        if (layer) map.removeLayer(layer);
                        // add marker to layer
                        seriesApiInterface.getPlatforms(null, this.serviceUrl, this.filter)
                            .then((res) => {
                                layer = L.markerClusterGroup({
                                    animate: false
                                });
                                res.forEach(entry => {
                                    var marker = L.marker([entry.geometry.coordinates[1], entry.geometry.coordinates[0]], {
                                        icon: myIcon
                                    });
                                    marker.on('click', () => {
                                        seriesApiInterface.getPlatforms(entry.id, this.serviceUrl)
                                            .then(entry => {
                                                this.platformSelected({
                                                    platform: entry
                                                });
                                            });
                                    });
                                    layer.addLayer(marker);
                                });

                                layer.addTo(map);
                                // zoom to layer
                                map.invalidateSize();
                                map.fitBounds(layer.getBounds());
                                this.loading = false;
                            });
                    });
                };
            }
        ]
    });
<|endoftext|>


<commit_before>'use strict';

app.controller('roomController', function($scope, $http, $stateParams, $cookieStore, $uibModal, webchatService, errorModalDefaultAlert) {

  $scope.roomChatEvents = [];
  $scope.messageInputDisabled = true;
  $scope.messageInputTextPlaceholder = "Joining room...";

  $scope.identityIdAuthorNameMap = {};

  var roomId = $stateParams.roomId;
  var userId = "Me";

  var unsentMessageMap = {};
  var confirmedSentMessageIdMap = {};

  var recentRoomMessagesFetched = false;
  var clientRoomSessionWatchId = undefined;

  var scrollLockEnabled = true;

  var roomChatEventComparator = function(a, b) {
    // Try to sort by timestamp first.
    var timestampComparison = (a.timestamp - b.timestamp);
    if (timestampComparison != 0) {
      return timestampComparison;
    }

    // If the timestamps match, sort by message text.
    // It's arbitrary, but will result in consistent ordering among different
    // clients.

    if (a.message < b.message) {
      return -1;
    }
    else if (a.message > b.message) {
      return 1;
    }
    return 0;
  }

  var newMessagesReceived = function(messageArray, unsent = false) {
    for (var i=0; i < messageArray.length; i++) {
      var eachMessage = messageArray[i];

      if (!unsent) {
        // Make sure we haven't already shown this message on the screen in
        // anticipation of its sending being confirmed.

        var eachClientMessageId = eachMessage["client-message-id"];

        if (!angular.isUndefined(eachClientMessageId)) {
          // This message has already been shown on the screen.

          if (unsentMessageMap.hasOwnProperty(eachClientMessageId)) {
            // Receiving it now confirms its sending was successful.
            unsentMessageConfirmed(eachClientMessageId, eachMessage["message-id"]);
            continue;
          }

          if (confirmedSentMessageIdMap.hasOwnProperty(eachClientMessageId)) {
            // We already know this message was confirmed.
            continue;
          }
        }
      }

      $scope.identityIdAuthorNameMap[eachMessage["identity-id"]] = eachMessage["author-name"];

      $scope.roomChatEvents.push(eachMessage);
      $scope.roomChatEvents.sort(roomChatEventComparator);

    }

    if (scrollLockEnabled) {
      setTimeout(function() {
        window.scrollTo(0,document.body.scrollHeight);
      }, 0)
    }

  }

  var focusSendMessageBox = function() {
    window.setTimeout(function() {
      document.getElementById("message-input").focus();
    }, 0);
  }

  var stopSessionWatchingSession = function(clientSessionId) {
    webchatService.stopWatchingForRoomSessionMessages(clientSessionId);
  }

  var fetchRecentRoomMessages = function() {
    webchatService.getRoomMessageHistory(roomId)
      .then(function(response) {
        var messageArray = response.messages;

        newMessagesReceived(messageArray);
        recentRoomMessagesFetched = true;

        evaluateIfReadyToPost();

        if (response.truncated) {
          console.log("Room has prior messages, too.");
        }
      })
      .catch(function(errorReason) {
        errorModalDefaultAlert("An error occurred fetching recent room messages.");
        console.log(errorReason);
      })
  }

  var createNewRoomSession = function() {
    webchatService.createNewRoomSession(roomId)
      .then(function(sessionId) {

        if (!angular.isUndefined(clientRoomSessionWatchId)) {
          stopSessionWatchingSession(clientRoomSessionWatchId);
          clientRoomSessionWatchId = undefined;
        }

        clientRoomSessionWatchId = webchatService.watchForRoomSessionMessages(roomId, sessionId, newMessagesReceived);

        evaluateIfReadyToPost();

      })
      .catch(function(errorReason) {
        if (errorReason == "LoginRequired") {

          $uibModal.open({
            templateUrl: 'modal-simple.html',
            controller: 'modalSimpleController',
            resolve: {
              config: function() {
                return {
                  mode: 'login-required',
                  message: 'You must log in to join a room.',
                  modalTitle: 'Login Required'
                }
              }
            }
          });

        }
        else {
          errorModalDefaultAlert("An error occurred in trying to enter the room.");
        }
      });
  }

  // User is ready to post if the session is created and recent messages have been fetched.
  var readyToPostConfirmed = false;
  var inviteFunctionalityUnderstood = false;

  var evaluateIfReadyToPost = function() {

    if (readyToPostConfirmed) {
      return;
    }

    if (recentRoomMessagesFetched && !angular.isUndefined(clientRoomSessionWatchId)) {

      $scope.messageInputTextPlaceholder = "Send a message";
      $scope.messageInputDisabled = false;

      focusSendMessageBox();
      readyToPostConfirmed = true;

      if (!inviteFunctionalityUnderstood) {
        if (angular.isUndefined($cookieStore.get("invite-tutorial-shown"))) {

          $uibModal.open({
            templateUrl: 'modal-simple.html',
            controller: 'modalSimpleController',
            resolve: {
              config: function() {
                return {
                  mode: 'invite-tutorial'
                }
              }
            }
          });

          return;
        }
        else {
          inviteFunctionalityUnderstood = true;
        }
      }

    }
  }

  fetchRecentRoomMessages();
  createNewRoomSession();

  var unsentMessageConfirmed = function(clientMessageId, serverMessageId) {
    var unsentMessage = unsentMessageMap[clientMessageId];
    if (angular.isUndefined(unsentMessage)) {
      return;
    }

    confirmedSentMessageIdMap[clientMessageId] = true;
    unsentMessage["message-id"] = serverMessageId;
    if (unsentMessage.hasOwnProperty("send-failure")) {
      delete unsentMessage["send-failure"];
    }
    delete unsentMessage["unsent"];

    delete unsentMessageMap[clientMessageId];
  }

  var postUnsentMessage = function(messageText) {

    var unsentMessageObject = {
      "message-id": Guid.raw(),
      "client-message-id": Guid.raw(),
      "timestamp": Math.floor(Date.now() / 1000),
      "identity-id": userId,
      "author-name": userId,
      "message": messageText,
      "unsent": true
    };

    unsentMessageMap[unsentMessageObject["client-message-id"]] = unsentMessageObject;

    newMessagesReceived([unsentMessageObject], true);

    return unsentMessageObject;
  }

  $scope.messageSendFormSubmitted = function() {

    var messageText = $scope.messageInputText;

    var clientMessageId = Guid.raw();

    var unsentMessage = postUnsentMessage(messageText);
    var clientMessageId = unsentMessage["client-message-id"];
    $scope.messageInputText = "";
    focusSendMessageBox();

    var postRoomId = roomId;

    webchatService.postNewRoomMessage(postRoomId, messageText, clientMessageId)
      .then(function(serverMessageId) {
        unsentMessageConfirmed(clientMessageId, serverMessageId);
      })
      .catch(function() {
        if (unsentMessage.hasOwnProperty("unsent") && unsentMessage["unsent"]) {
          unsentMessage["send-failure"] = true;
        }
        else {
          console.log("Ignoring error in sending message already confirmed received.");
        }
      })

  }

  // http://stackoverflow.com/a/10795797
  var getDocHeight = function() {
    var D = document;
    return Math.max(
      D.body.scrollHeight, D.documentElement.scrollHeight,
      D.body.offsetHeight, D.documentElement.offsetHeight,
      D.body.clientHeight, D.documentElement.clientHeight
    );
  }

  $(window).scroll(function() {
    if($(window).scrollTop() + $(window).height() == getDocHeight()) {
      scrollLockEnabled = true;
    }
    else {
      scrollLockEnabled = false;
    }
  });

});<commit_msg>Fixed double-modal in room join front end when not logged in.<commit_after>'use strict';

app.controller('roomController', function($scope, $http, $stateParams, $cookieStore, $uibModal, webchatService, errorModalDefaultAlert) {

  $scope.roomChatEvents = [];
  $scope.messageInputDisabled = true;
  $scope.messageInputTextPlaceholder = "Joining room...";

  $scope.identityIdAuthorNameMap = {};

  var roomId = $stateParams.roomId;
  var userId = "Me";

  var unsentMessageMap = {};
  var confirmedSentMessageIdMap = {};

  var recentRoomMessagesFetched = false;
  var clientRoomSessionWatchId = undefined;

  var scrollLockEnabled = true;

  var roomChatEventComparator = function(a, b) {
    // Try to sort by timestamp first.
    var timestampComparison = (a.timestamp - b.timestamp);
    if (timestampComparison != 0) {
      return timestampComparison;
    }

    // If the timestamps match, sort by message text.
    // It's arbitrary, but will result in consistent ordering among different
    // clients.

    if (a.message < b.message) {
      return -1;
    }
    else if (a.message > b.message) {
      return 1;
    }
    return 0;
  }

  var newMessagesReceived = function(messageArray, unsent = false) {
    for (var i=0; i < messageArray.length; i++) {
      var eachMessage = messageArray[i];

      if (!unsent) {
        // Make sure we haven't already shown this message on the screen in
        // anticipation of its sending being confirmed.

        var eachClientMessageId = eachMessage["client-message-id"];

        if (!angular.isUndefined(eachClientMessageId)) {
          // This message has already been shown on the screen.

          if (unsentMessageMap.hasOwnProperty(eachClientMessageId)) {
            // Receiving it now confirms its sending was successful.
            unsentMessageConfirmed(eachClientMessageId, eachMessage["message-id"]);
            continue;
          }

          if (confirmedSentMessageIdMap.hasOwnProperty(eachClientMessageId)) {
            // We already know this message was confirmed.
            continue;
          }
        }
      }

      $scope.identityIdAuthorNameMap[eachMessage["identity-id"]] = eachMessage["author-name"];

      $scope.roomChatEvents.push(eachMessage);
      $scope.roomChatEvents.sort(roomChatEventComparator);

    }

    if (scrollLockEnabled) {
      setTimeout(function() {
        window.scrollTo(0,document.body.scrollHeight);
      }, 0)
    }

  }

  var focusSendMessageBox = function() {
    window.setTimeout(function() {
      document.getElementById("message-input").focus();
    }, 0);
  }

  var stopSessionWatchingSession = function(clientSessionId) {
    webchatService.stopWatchingForRoomSessionMessages(clientSessionId);
  }

  var loginRequiredModalShown = false;

  var showLoginRequiredModal = function() {
    if (loginRequiredModalShown) {
      return;
    }

    $uibModal.open({
      templateUrl: 'modal-simple.html',
      controller: 'modalSimpleController',
      resolve: {
        config: function() {
          return {
            mode: 'login-required',
            message: 'You must log in to join a room.',
            modalTitle: 'Login Required'
          }
        }
      }
    });

    loginRequiredModalShown = true;
  }

  var fetchRecentRoomMessages = function() {
    webchatService.getRoomMessageHistory(roomId)
      .then(function(response) {
        var messageArray = response.messages;

        newMessagesReceived(messageArray);
        recentRoomMessagesFetched = true;

        evaluateIfReadyToPost();

        if (response.truncated) {
          console.log("Room has prior messages, too.");
        }
      })
      .catch(function(errorReason) {
        console.log(errorReason);

        if (errorReason == "LoginRequired") {
          showLoginRequiredModal();
        }
        else {
          errorModalDefaultAlert("An error occurred fetching recent room messages.");
        }

      })
  }

  var createNewRoomSession = function() {
    webchatService.createNewRoomSession(roomId)
      .then(function(sessionId) {

        if (!angular.isUndefined(clientRoomSessionWatchId)) {
          stopSessionWatchingSession(clientRoomSessionWatchId);
          clientRoomSessionWatchId = undefined;
        }

        clientRoomSessionWatchId = webchatService.watchForRoomSessionMessages(roomId, sessionId, newMessagesReceived);

        evaluateIfReadyToPost();

      })
      .catch(function(errorReason) {
        if (errorReason == "LoginRequired") {
          showLoginRequiredModal();
        }
        else {
          errorModalDefaultAlert("An error occurred in trying to enter the room.");
        }
      });
  }

  // User is ready to post if the session is created and recent messages have been fetched.
  var readyToPostConfirmed = false;
  var inviteFunctionalityUnderstood = false;

  var evaluateIfReadyToPost = function() {

    if (readyToPostConfirmed) {
      return;
    }

    if (recentRoomMessagesFetched && !angular.isUndefined(clientRoomSessionWatchId)) {

      $scope.messageInputTextPlaceholder = "Send a message";
      $scope.messageInputDisabled = false;

      focusSendMessageBox();
      readyToPostConfirmed = true;

      if (!inviteFunctionalityUnderstood) {
        if (angular.isUndefined($cookieStore.get("invite-tutorial-shown"))) {

          $uibModal.open({
            templateUrl: 'modal-simple.html',
            controller: 'modalSimpleController',
            resolve: {
              config: function() {
                return {
                  mode: 'invite-tutorial'
                }
              }
            }
          });

          return;
        }
        else {
          inviteFunctionalityUnderstood = true;
        }
      }

    }
  }

  fetchRecentRoomMessages();
  createNewRoomSession();

  var unsentMessageConfirmed = function(clientMessageId, serverMessageId) {
    var unsentMessage = unsentMessageMap[clientMessageId];
    if (angular.isUndefined(unsentMessage)) {
      return;
    }

    confirmedSentMessageIdMap[clientMessageId] = true;
    unsentMessage["message-id"] = serverMessageId;
    if (unsentMessage.hasOwnProperty("send-failure")) {
      delete unsentMessage["send-failure"];
    }
    delete unsentMessage["unsent"];

    delete unsentMessageMap[clientMessageId];
  }

  var postUnsentMessage = function(messageText) {

    var unsentMessageObject = {
      "message-id": Guid.raw(),
      "client-message-id": Guid.raw(),
      "timestamp": Math.floor(Date.now() / 1000),
      "identity-id": userId,
      "author-name": userId,
      "message": messageText,
      "unsent": true
    };

    unsentMessageMap[unsentMessageObject["client-message-id"]] = unsentMessageObject;

    newMessagesReceived([unsentMessageObject], true);

    return unsentMessageObject;
  }

  $scope.messageSendFormSubmitted = function() {

    var messageText = $scope.messageInputText;

    var clientMessageId = Guid.raw();

    var unsentMessage = postUnsentMessage(messageText);
    var clientMessageId = unsentMessage["client-message-id"];
    $scope.messageInputText = "";
    focusSendMessageBox();

    var postRoomId = roomId;

    webchatService.postNewRoomMessage(postRoomId, messageText, clientMessageId)
      .then(function(serverMessageId) {
        unsentMessageConfirmed(clientMessageId, serverMessageId);
      })
      .catch(function() {
        if (unsentMessage.hasOwnProperty("unsent") && unsentMessage["unsent"]) {
          unsentMessage["send-failure"] = true;
        }
        else {
          console.log("Ignoring error in sending message already confirmed received.");
        }
      })

  }

  // http://stackoverflow.com/a/10795797
  var getDocHeight = function() {
    var D = document;
    return Math.max(
      D.body.scrollHeight, D.documentElement.scrollHeight,
      D.body.offsetHeight, D.documentElement.offsetHeight,
      D.body.clientHeight, D.documentElement.clientHeight
    );
  }

  $(window).scroll(function() {
    if($(window).scrollTop() + $(window).height() == getDocHeight()) {
      scrollLockEnabled = true;
    }
    else {
      scrollLockEnabled = false;
    }
  });

});<|endoftext|>


<commit_before>'use strict';

treeherder.factory('thResultSets', [
    '$rootScope', '$http', '$location', '$q', 'thUrl', 'thEvents', 'thServiceDomain', 'ThLog', 'thNotify',
    function($rootScope, $http, $location, $q, thUrl, thEvents, thServiceDomain, ThLog, thNotify) {

    var getJobObj = function(job, jobPropertyNames){
        //Map the job property names to their corresponding
        //values in a job object
        var jobObj = {};
        var j = 0;
        for(; j < jobPropertyNames.length; j++){
            jobObj[ jobPropertyNames[j] ] = job[j];
        }
        return jobObj;
    };

    // Convert jobs value array into into an associative array
    // with property names
    var resultSetResponseTransformer = function(data, headersGetter){

        var responseData = angular.fromJson(data);
        var r = 0;
        for(; r<responseData.results.length; r++){

            if(responseData.results[r].platforms === undefined){
                continue;
            }

            var p = 0;
            for(; p < responseData.results[r].platforms.length; p++){
                var g = 0;
                for(; g < responseData.results[r].platforms[p].groups.length; g++){
                    var j = 0;
                    for(; j < responseData.results[r].platforms[p].groups[g].jobs.length; j++){

                        responseData.results[r].platforms[p].groups[g].jobs[j] = getJobObj(
                                responseData.results[r].platforms[p].groups[g].jobs[j],
                                responseData.job_property_names
                            );
                    }
                }
            }
        }

        return responseData;
    };

    var $log = new ThLog("thResultSets");

    // get the resultsets for this repo
    return {
        getResultSets: function(repoName, rsOffsetId, count, resultsetlist, with_jobs, full, keep_filters) {
            rsOffsetId = typeof rsOffsetId === 'undefined'?  0: rsOffsetId;
            count = typeof count === 'undefined'?  10: count;
            with_jobs = _.isUndefined(with_jobs) ? true: with_jobs;
            full = _.isUndefined(full) ? true: full;
            keep_filters = _.isUndefined(keep_filters) ? true : false;

            var params = {
                full: full,
                format: "json",
                with_jobs: with_jobs
            };

            if (count > 0) {
                params.count = count;
            }

            if(rsOffsetId > 0){
                params.id__lt = rsOffsetId;
            }

            if(keep_filters){
                // if there are any search params on the url line, they should
                // pass directly to the set of resultsets.
                // with the exception of ``repo``.  That has no effect on the
                // service at this time, but it could be confusing.
                var locationParams = _.clone($location.search());
                delete locationParams.repo;

                // support date ranges.  we must convert the strings to a timezone
                // appropriate timestamp
                $log.debug("locationParams", locationParams);
                if (_.has(locationParams, "startdate")) {
                    params.push_timestamp__gte = Date.parse(
                        locationParams.startdate)/1000;

                    delete locationParams.startdate;
                }
                if (_.has(locationParams, "enddate")) {
                    params.push_timestamp__lt = Date.parse(
                        locationParams.enddate)/1000 + 84600;

                    delete locationParams.enddate;
                }

                $log.debug("updated params", params);
                _.extend(params, locationParams);
            }

            if (resultsetlist) {
                _.extend(params, {
                    offset: 0,
                    count: resultsetlist.length,
                    id__in: resultsetlist.join()
                });
            }
            return $http.get(
                thUrl.getProjectUrl("/resultset/", repoName),
                {
                    params: params,
                    transformResponse:resultSetResponseTransformer
                }
            );
        },
        get: function(uri) {
            return $http.get(thServiceDomain + uri, {params: {format: "json"}});
        },
        getResultSetJobs: function(resultSets, repoName){

            var uri = '1/get_resultset_jobs';
            var fullUrl = thUrl.getProjectUrl("/resultset/", repoName) + uri;

            _.each(
                resultSets.results,
                function(rs, index){

                    return $http.get(
                        fullUrl, {
                            params: {
                                format: "json",
                                result_set_ids:rs.id
                            },
                            transformResponse:resultSetResponseTransformer
                        }
                    ).then( function(response){
                        if(response.status === 200){

                            if(response.data.results.length > 0){

                                $rootScope.$broadcast(
                                    thEvents.mapResultSetJobs,
                                    repoName,
                                    response.data.results[0]
                                    );
                            }

                        }else{
                            // Send notification with response.status to
                            // UI here
                            thNotify.send(
                                "Error retrieing job data! response status " + response.status,
                                "danger",
                                true);
                        }
                }); //Close then

            }); //Close each

        } //Close getResultSetJobs
    };
}]);
<commit_msg>Minor spelling correction in resultsets.js<commit_after>'use strict';

treeherder.factory('thResultSets', [
    '$rootScope', '$http', '$location', '$q', 'thUrl', 'thEvents', 'thServiceDomain', 'ThLog', 'thNotify',
    function($rootScope, $http, $location, $q, thUrl, thEvents, thServiceDomain, ThLog, thNotify) {

    var getJobObj = function(job, jobPropertyNames){
        //Map the job property names to their corresponding
        //values in a job object
        var jobObj = {};
        var j = 0;
        for(; j < jobPropertyNames.length; j++){
            jobObj[ jobPropertyNames[j] ] = job[j];
        }
        return jobObj;
    };

    // Convert jobs value array into into an associative array
    // with property names
    var resultSetResponseTransformer = function(data, headersGetter){

        var responseData = angular.fromJson(data);
        var r = 0;
        for(; r<responseData.results.length; r++){

            if(responseData.results[r].platforms === undefined){
                continue;
            }

            var p = 0;
            for(; p < responseData.results[r].platforms.length; p++){
                var g = 0;
                for(; g < responseData.results[r].platforms[p].groups.length; g++){
                    var j = 0;
                    for(; j < responseData.results[r].platforms[p].groups[g].jobs.length; j++){

                        responseData.results[r].platforms[p].groups[g].jobs[j] = getJobObj(
                                responseData.results[r].platforms[p].groups[g].jobs[j],
                                responseData.job_property_names
                            );
                    }
                }
            }
        }

        return responseData;
    };

    var $log = new ThLog("thResultSets");

    // get the resultsets for this repo
    return {
        getResultSets: function(repoName, rsOffsetId, count, resultsetlist, with_jobs, full, keep_filters) {
            rsOffsetId = typeof rsOffsetId === 'undefined'?  0: rsOffsetId;
            count = typeof count === 'undefined'?  10: count;
            with_jobs = _.isUndefined(with_jobs) ? true: with_jobs;
            full = _.isUndefined(full) ? true: full;
            keep_filters = _.isUndefined(keep_filters) ? true : false;

            var params = {
                full: full,
                format: "json",
                with_jobs: with_jobs
            };

            if (count > 0) {
                params.count = count;
            }

            if(rsOffsetId > 0){
                params.id__lt = rsOffsetId;
            }

            if(keep_filters){
                // if there are any search params on the url line, they should
                // pass directly to the set of resultsets.
                // with the exception of ``repo``.  That has no effect on the
                // service at this time, but it could be confusing.
                var locationParams = _.clone($location.search());
                delete locationParams.repo;

                // support date ranges.  we must convert the strings to a timezone
                // appropriate timestamp
                $log.debug("locationParams", locationParams);
                if (_.has(locationParams, "startdate")) {
                    params.push_timestamp__gte = Date.parse(
                        locationParams.startdate)/1000;

                    delete locationParams.startdate;
                }
                if (_.has(locationParams, "enddate")) {
                    params.push_timestamp__lt = Date.parse(
                        locationParams.enddate)/1000 + 84600;

                    delete locationParams.enddate;
                }

                $log.debug("updated params", params);
                _.extend(params, locationParams);
            }

            if (resultsetlist) {
                _.extend(params, {
                    offset: 0,
                    count: resultsetlist.length,
                    id__in: resultsetlist.join()
                });
            }
            return $http.get(
                thUrl.getProjectUrl("/resultset/", repoName),
                {
                    params: params,
                    transformResponse:resultSetResponseTransformer
                }
            );
        },
        get: function(uri) {
            return $http.get(thServiceDomain + uri, {params: {format: "json"}});
        },
        getResultSetJobs: function(resultSets, repoName){

            var uri = '1/get_resultset_jobs';
            var fullUrl = thUrl.getProjectUrl("/resultset/", repoName) + uri;

            _.each(
                resultSets.results,
                function(rs, index){

                    return $http.get(
                        fullUrl, {
                            params: {
                                format: "json",
                                result_set_ids:rs.id
                            },
                            transformResponse:resultSetResponseTransformer
                        }
                    ).then( function(response){
                        if(response.status === 200){

                            if(response.data.results.length > 0){

                                $rootScope.$broadcast(
                                    thEvents.mapResultSetJobs,
                                    repoName,
                                    response.data.results[0]
                                    );
                            }

                        }else{
                            // Send notification with response.status to
                            // UI here
                            thNotify.send(
                                "Error retrieving job data! response status " + response.status,
                                "danger",
                                true);
                        }
                }); //Close then

            }); //Close each

        } //Close getResultSetJobs
    };
}]);
<|endoftext|>


<commit_before>/*global angular */
/*
 jQuery UI Datepicker plugin wrapper

 @note If ≤ IE8 make sure you have a polyfill for Date.toISOString()
 @param [ui-date] {object} Options to pass to $.fn.datepicker() merged onto ui.config
 */

angular.module('ui.directives')

.directive('uiDate', ['ui.config', function (uiConfig) {
  'use strict';
  var options;
  options = {};
  if (angular.isObject(uiConfig.date)) {
    angular.extend(options, uiConfig.date);
  }
  return {
    require:'?ngModel',
    link:function (scope, element, attrs, controller) {
      var getOptions = function () {
        return angular.extend({}, uiConfig.date, scope.$eval(attrs.uiDate));
      };
      var initDateWidget = function () {
        var opts = getOptions();

        // If we have a controller (i.e. ngModelController) then wire it up
        if (controller) {
          var updateModel = function () {
            scope.$apply(function () {
              var date = element.datepicker("getDate");
              element.datepicker("setDate", element.val());
              controller.$setViewValue(date);
              element.blur();
            });
          };
          if (opts.onSelect) {
            // Caller has specified onSelect, so call this as well as updating the model
            var userHandler = opts.onSelect;
            opts.onSelect = function (value, picker) {
              updateModel();
              scope.$apply(function() {
                userHandler(value, picker);
              });
            };
          } else {
            // No onSelect already specified so just update the model
            opts.onSelect = updateModel;
          }
          // In case the user changes the text directly in the input box
          element.bind('change', updateModel);

          // Update the date picker when the model changes
          controller.$render = function () {
            var date = controller.$viewValue;
            if ( angular.isDefined(date) && date !== null && !angular.isDate(date) ) {
              throw new Error('ng-Model value must be a Date object - currently it is a ' + typeof date + ' - use ui-date-format to convert it from a string');
            }
            element.datepicker("setDate", date);
          };
        }
        // If we don't destroy the old one it doesn't update properly when the config changes
        element.datepicker('destroy');
        // Create the new datepicker widget
        element.datepicker(opts);
        if ( controller ) {
          // Force a render to override whatever is in the input text box
          controller.$render();
        }
      };
      // Watch for changes to the directives options
      scope.$watch(getOptions, initDateWidget, true);
    }
  };
}
])

.directive('uiDateFormat', [function() {
  var directive = {
    require:'ngModel',
    link: function(scope, element, attrs, modelCtrl) {
      if ( attrs.uiDateFormat === '' ) {
        // Default to ISO formatting
        modelCtrl.$formatters.push(function(value) {
          if (angular.isString(value) ) {
            return new Date(value);
          }
        });
        modelCtrl.$parsers.push(function(value){
          if (value) {
            return value.toISOString();
          }
        });
      } else {
        var format = attrs.uiDateFormat;
        // Use the datepicker with the attribute value as the format string to convert to and from a string
        modelCtrl.$formatters.push(function(value) {
          if (angular.isString(value) ) {
            return $.datepicker.parseDate(format, value);
          }
        });
        modelCtrl.$parsers.push(function(value){
          if (value) {
            return $.datepicker.formatDate(format, value);
          }
        });
      }
    }
  };
  return directive;
}]);
<commit_msg>feat(dateFormat): Added support for ui.config closes #349<commit_after>/*global angular */
/*
 jQuery UI Datepicker plugin wrapper

 @note If ≤ IE8 make sure you have a polyfill for Date.toISOString()
 @param [ui-date] {object} Options to pass to $.fn.datepicker() merged onto ui.config
 */

angular.module('ui.directives')

.directive('uiDate', ['ui.config', function (uiConfig) {
  'use strict';
  var options;
  options = {};
  if (angular.isObject(uiConfig.date)) {
    angular.extend(options, uiConfig.date);
  }
  return {
    require:'?ngModel',
    link:function (scope, element, attrs, controller) {
      var getOptions = function () {
        return angular.extend({}, uiConfig.date, scope.$eval(attrs.uiDate));
      };
      var initDateWidget = function () {
        var opts = getOptions();

        // If we have a controller (i.e. ngModelController) then wire it up
        if (controller) {
          var updateModel = function () {
            scope.$apply(function () {
              var date = element.datepicker("getDate");
              element.datepicker("setDate", element.val());
              controller.$setViewValue(date);
              element.blur();
            });
          };
          if (opts.onSelect) {
            // Caller has specified onSelect, so call this as well as updating the model
            var userHandler = opts.onSelect;
            opts.onSelect = function (value, picker) {
              updateModel();
              scope.$apply(function() {
                userHandler(value, picker);
              });
            };
          } else {
            // No onSelect already specified so just update the model
            opts.onSelect = updateModel;
          }
          // In case the user changes the text directly in the input box
          element.bind('change', updateModel);

          // Update the date picker when the model changes
          controller.$render = function () {
            var date = controller.$viewValue;
            if ( angular.isDefined(date) && date !== null && !angular.isDate(date) ) {
              throw new Error('ng-Model value must be a Date object - currently it is a ' + typeof date + ' - use ui-date-format to convert it from a string');
            }
            element.datepicker("setDate", date);
          };
        }
        // If we don't destroy the old one it doesn't update properly when the config changes
        element.datepicker('destroy');
        // Create the new datepicker widget
        element.datepicker(opts);
        if ( controller ) {
          // Force a render to override whatever is in the input text box
          controller.$render();
        }
      };
      // Watch for changes to the directives options
      scope.$watch(getOptions, initDateWidget, true);
    }
  };
}
])

.directive('uiDateFormat', ['ui.config', function(uiConfig) {
  var directive = {
    require:'ngModel',
    link: function(scope, element, attrs, modelCtrl) {
      var dateFormat = attrs.uiDateFormat || uiConfig.dateFormat;
      if ( dateFormat ) {
        var format = attrs.uiDateFormat;
        // Use the datepicker with the attribute value as the format string to convert to and from a string
        modelCtrl.$formatters.push(function(value) {
          if (angular.isString(value) ) {
            return $.datepicker.parseDate(format, value);
          }
        });
        modelCtrl.$parsers.push(function(value){
          if (value) {
            return $.datepicker.formatDate(format, value);
          }
        });
      } else {
        // Default to ISO formatting
        modelCtrl.$formatters.push(function(value) {
          if (angular.isString(value) ) {
            return new Date(value);
          }
        });
        modelCtrl.$parsers.push(function(value){
          if (value) {
            return value.toISOString();
          }
        });
      }
    }
  };
  return directive;
}]);
<|endoftext|>


<commit_before>var gridUtil = function(grid,config){
	config = Ext.decode(config);
	var proceed = function(){
		if(config.is_ajax){
			if(config.url == "#") return;
			Ext.Ajax.request({
				url: config.url,
				params:config.params,
				success: function(response){
					if(config.onsuccess == "RELOAD"){
						grid.getStore().reload();
						if(grid.getSelectionModel){
							var sm = grid.getSelectionModel();
							sm.clearSelections();
						}
					}
					if(config.onsuccess == "REDIRECT"){
						window.location.href = config.redirect;
					}
				}
			})
		}else{
			window.location.href = config.url
		}
	}

	if(!grid){alert("Component not found"); return;}
	if(config.confirmMsg){
		Ext.Msg.show({
			title:'Confirmation required.',
			msg: config.confirmMsg,
			buttons: Ext.Msg.YESNOCANCEL,
			fn: function(btn,text){
				if (btn == 'yes'){
			        proceed();
			    }
			},
			icon: Ext.MessageBox.QUESTION
		})
	}else{
		proceed();
	}

}<commit_msg>changes<commit_after>var gridUtil = function(grid,config){
	config = Ext.decode(config);
	var proceed = function(){
		if(config.is_ajax){
			if(config.url == "#") return;
			Ext.Ajax.request({
				url: config.url,
				params:config.params,
				success: function(response){
					if(config.onsuccess == "RELOAD"){
						grid.getStore().reload();
						if(grid.getSelectionModel){
							var sm = grid.getSelectionModel();
							sm.clearSelections();
						}
					}
					if(config.onsuccess == "REDIRECT"){
						window.location.href = config.redirect;
					}
				}
			})
		}else{
			window.location.href = config.url
		}
	}

	if(!grid){alert("Component not found"); return;}

	if(config.confirmMsg){
		Ext.Msg.show({
			title:'Confirmation required.',
			msg: config.confirmMsg,
			buttons: Ext.Msg.YESNOCANCEL,
			fn: function(btn,text){
				if (btn == 'yes'){
			        proceed();
			    }
			},
			icon: Ext.MessageBox.QUESTION
		})
	}else{
		proceed();
	}

}<|endoftext|>


<commit_before>var shuffle = require('shuffle-array');
var models = require('../models/index');
var ZiviService = require('./../services/zivi.service.js');
var SocketService = require('./../services/socket.service');

var ZiviTimer = {};
const TIMER_SOCKET_NAME = 'timer';
ZiviTimer.ZIVI_TIMER_INTERVAL = 600;
ZiviTimer.remainingSeconds = ZiviTimer.ZIVI_TIMER_INTERVAL;

ZiviTimer.pushTimerData = function () {
  SocketService.writeToSocket(TIMER_SOCKET_NAME, {
    remaining: ZiviTimer.remainingSeconds
  });
};

ZiviTimer.shuffleZivisAndSaveOrder = function () {
  ZiviService.findAll(function (zivis) {
    var ziviCount = zivis.length;
    var selectedZivis = [];
    for(var i = 0; i <= ziviCount; i++){
      var zivi = selectZiviFairly(createFairArray(getMaxFirstZiviCount(zivis), zivis));
      selectedZivis.push(zivi);
      zivis = zivis.filter(function(element){
        return element._id !== zivi._id;
      });
    }
    if (selectedZivis.length > 0) {
      selectedZivis[0].first += 1;
      for (var j = 0; j < selectedZivis.length; j++) {
        selectedZivis[j].order = j + 1;
        selectedZivis[j].save();
      }
    }
  });
};

function getMaxFirstZiviCount(zivis){
  var max = -1;
  zivis.forEach(function(zivi){
    if(zivi.first > max){
      max = zivi.first;
    }
  });
  return max;
}

function createFairArray(max, zivis){
  var fairArray = [];
  zivis.forEach(function(zivi){
    for(var i = 0; i < max - zivi.first + 1; i++){
      fairArray.push(zivi);
    }
  });
  return fairArray;
}

function selectZiviFairly(fairArray){
  shuffle(fairArray);
  return fairArray[0];
}

function tickTimer() {
  ZiviTimer.remainingSeconds--;
  ZiviTimer.pushTimerData();
  if (ZiviTimer.remainingSeconds === 0) {
    ZiviTimer.remainingSeconds = ZiviTimer.ZIVI_TIMER_INTERVAL;
    ZiviTimer.shuffleZivisAndSaveOrder();
  }
}

ZiviTimer.shuffleZivisAndSaveOrder();
setInterval(tickTimer, 1000);

module.exports = ZiviTimer;
<commit_msg>Fix error message because Mongoose loves to return undefined<commit_after>var shuffle = require('shuffle-array');
var models = require('../models/index');
var ZiviService = require('./../services/zivi.service.js');
var SocketService = require('./../services/socket.service');

var ZiviTimer = {};
const TIMER_SOCKET_NAME = 'timer';
ZiviTimer.ZIVI_TIMER_INTERVAL = 600;
ZiviTimer.remainingSeconds = ZiviTimer.ZIVI_TIMER_INTERVAL;

ZiviTimer.pushTimerData = function () {
  SocketService.writeToSocket(TIMER_SOCKET_NAME, {
    remaining: ZiviTimer.remainingSeconds
  });
};

ZiviTimer.shuffleZivisAndSaveOrder = function () {
  ZiviService.findAll(function (zivis) {
    var ziviCount = zivis.length;
    var selectedZivis = [];
    for (var i = 0; i <= ziviCount; i++) {
      var zivi = selectZiviFairly(createFairArray(getMaxFirstZiviCount(zivis), zivis));
      selectedZivis.push(zivi);
      zivis = zivis.filter(function (element) {
        return element._id !== zivi._id;
      });
    }
    if (selectedZivis.length > 0) {
      selectedZivis[0].first += 1;
      for (var j = 0; j < selectedZivis.length; j++) {
        if (selectedZivis[j] === undefined) { // idk
          continue;
        }
        selectedZivis[j].order = j + 1;
        selectedZivis[j].save();
      }
    }
  });
};

function getMaxFirstZiviCount(zivis) {
  var max = -1;
  zivis.forEach(function (zivi) {
    if (zivi.first > max) {
      max = zivi.first;
    }
  });
  return max;
}

function createFairArray(max, zivis) {
  var fairArray = [];
  zivis.forEach(function (zivi) {
    for (var i = 0; i < max - zivi.first + 1; i++) {
      fairArray.push(zivi);
    }
  });
  return fairArray;
}

function selectZiviFairly(fairArray) {
  shuffle(fairArray);
  return fairArray[0];
}

function tickTimer() {
  ZiviTimer.remainingSeconds--;
  ZiviTimer.pushTimerData();
  if (ZiviTimer.remainingSeconds === 0) {
    ZiviTimer.remainingSeconds = ZiviTimer.ZIVI_TIMER_INTERVAL;
    ZiviTimer.shuffleZivisAndSaveOrder();
  }
}

ZiviTimer.shuffleZivisAndSaveOrder();
setInterval(tickTimer, 1000);

module.exports = ZiviTimer;
<|endoftext|>


<commit_before>$(document).ready(
	function()
    {
		$("#nav_tournaments").toggleClass("active");
		correctRuleInfo();
		correctTimestamps();
    }
);

function correctRuleInfo()
{
	$(".rule_info").each(
		function (index, item)
		{
			var rule_info = JSON.parse($(item).html());
			var rules = [];
			for (rule in rule_info)
			{
				var weight = rule_info[rule];
				var rule_object = {name: rule, weight: weight};
				console.log(rule + ": " + weight.toString());
				var rule_length = rules.length;
				for (var i = 0; i < rule_length; ++i)
				{
					if (rules[i].weight > weight) continue;
					rules.splice(i, 0, rule_object);
					break;
				}
				if (i == rule_length)
					rules.push(rule_object);
			}

			var text = "";
			var rule_count = rules.length;
			for (var i = 0; i < rule_count; ++i)
			{
				text = text + "" + rules[i].name + ": " + rules[i].weight.toString() + " ";
			}
			$(item).html(text);
		}
	);
}

function correctTimestamps()
{
	$(".timestamp").each(
		function (index, item)
		{
			var twodigits = function(x) {if (x >= 10) return x; return "0" + x;}
			var date = new Date(parseInt($(item).html()) * 1000);
			$(item).html(twodigits(date.getDate()) + "." + twodigits(date.getMonth()) + ". " + twodigits(date.getHours()) + ":" + twodigits(date.getMinutes()));
		}
	);
}<commit_msg>frontend: corrected date in Tournaments view (month off-by-one)<commit_after>$(document).ready(
	function()
    {
		$("#nav_tournaments").toggleClass("active");
		correctRuleInfo();
		correctTimestamps();
    }
);

function correctRuleInfo()
{
	$(".rule_info").each(
		function (index, item)
		{
			var rule_info = JSON.parse($(item).html());
			var rules = [];
			for (rule in rule_info)
			{
				var weight = rule_info[rule];
				var rule_object = {name: rule, weight: weight};
				var rule_length = rules.length;
				for (var i = 0; i < rule_length; ++i)
				{
					if (rules[i].weight > weight) continue;
					rules.splice(i, 0, rule_object);
					break;
				}
				if (i == rule_length)
					rules.push(rule_object);
			}

			var text = "";
			var rule_count = rules.length;
			for (var i = 0; i < rule_count; ++i)
			{
				text = text + "" + rules[i].name + ": " + rules[i].weight.toString() + " ";
			}
			$(item).html(text);
		}
	);
}

function correctTimestamps()
{
	$(".timestamp").each(
		function (index, item)
		{
			var twodigits = function(x) {if (x >= 10) return x; return "0" + x;}
			var date = new Date(parseInt($(item).html()) * 1000);
			$(item).html(twodigits(date.getDate()) + "." + twodigits(date.getMonth()+1) + ". " + twodigits(date.getHours()) + ":" + twodigits(date.getMinutes()));
		}
	);
}<|endoftext|>


<commit_before>/*
	GEIESMONADS - JS monads
	Author: Marco Faustinelli (contacts@faustinelli.net)
	Web: http://faustinelli.net/
	     http://faustinelli.wordpress.com/

	The MIT License - Copyright (c) 2013/2015 Geiesmonads Project
*/

var expect = chai.expect;
mocha.setup('bdd');

describe('maybe monad', function() {
  var maybe = MONAD.maybe.UNIT;
  var isSome = MONAD.maybe.isSome;
  it('may be some or none', function() {
    expect(maybe(12)()).to.be.equal(12);
    expect(isSome(maybe(null))).to.be.not.ok;
  });
  it('binds into some or none', function() {
    var famb = a => maybe(a * 2);
    expect(maybe(12).bind(famb)()).to.be.equal(24);
    expect(isSome(maybe(null).bind(famb))).to.be.not.ok;
  });
});

describe('either a monad', function() {
  var left = MONAD.either.left;
  var right = MONAD.either.right;
  var isLeft = MONAD.either.isLeft;
  var isRight = MONAD.either.isRight;
  it('may be left or right', function() {
    expect(left(12)()).to.be.equal(12);
    expect(right(13)()).to.be.equal(13);
    expect(isLeft(right('www'))).to.be.not.ok;
    expect(isRight(left('www'))).to.be.not.ok;
    expect(isLeft(left('www'))).to.be.ok;
    expect(isRight(right('www'))).to.be.ok;
  });
  it('binds from right to left', function() {
    var farb = a => right(a * 2);
    var falb = a => left(a * 2);
    var right2Right = right(12).bind(farb);
    expect(right2Right()).to.be.equal(24);
    expect(isRight(right2Right)).to.be.ok;

    var right2Left = right(12).bind(falb);
    expect(right2Left()).to.be.equal(24);
    expect(isLeft(right2Left)).to.be.ok;
  });
  it('binds from left to left', function() {
    var farb = a => right(a * 2);
    var falb = a => left(a * 2);
    var left2Right = left(12).bind(farb);
    expect(left2Right()).to.be.equal(12);
    expect(isLeft(left2Right)).to.be.ok;

    var left2Left = left(12).bind(falb);
    expect(left2Left()).to.be.equal(12);
    expect(isLeft(left2Left)).to.be.ok;
  });
});

var state = MONAD.state.state;
var unit = MONAD.state.UNIT;
var getState = MONAD.state.sGet;

describe('state monad', function() {
  it('is a spring mouse', function() {
    expect(unit(12)(1)[0]).to.be.equal(1);
    expect(unit(12)(1)[1]).to.be.equal(12);
    expect(state(s => [s, 12])(1)[0]).to.be.equal(1);
    expect(state(s => [s, 12])(1)[1]).to.be.equal(12);
  });
  it('binds very well', function() {
    var twelve = unit(12);
    var fasmb = a => state(s => [a+s, a-s]);
    var bound = twelve.bind(fasmb);
    var [sss, aaa] = bound(1);
    expect(sss).to.be.equal(13);
    expect(aaa).to.be.equal(11);
  });
  it('features sGet', function() {
    var twelve = unit(12);
    var fasmb = a => state(s => [a+s, a-s]); // s -> 12+s
    var bound = twelve.bind(fasmb).bind(a => getState);
    var [sss, aaa] = bound(1);
    expect(sss).to.be.equal(13);
    expect(aaa).to.be.equal(13);
  });
  it('features sSet', function() {
    var setState = MONAD.state.sSet;
    var twelve = unit(12);
    var fasmb = a => state(s => [a+s, a-s]); // a -> 12-s
    var bound = twelve.bind(fasmb).bind(a => setState(a*2));
    var [sss, aaa] = bound(1);
    expect(sss).to.be.equal(22);
    expect(aaa).to.be.undefined;
  });
});

var node = MyTree.node;
var leaf = MyTree.leaf;
var empty = MyTree.empty;
var left = MyTree.left;
var right = MyTree.right;
var identity = x => x;

var simpleTree = node(leaf('a'),node(leaf('b'),leaf('c')));
var complexTree = node(
  leaf('a'),
  node(
    node(
      leaf('b'),
      leaf('c')),
    leaf('d')
  )
);
var complexTreeWithEmpties = node(
  leaf('a'),
  node(
    node(
      leaf('b'),
      empty()),
    leaf('d')
  )
);

describe('manual labeler', function() {
  it('labels a single leaf', function() {
    var result = MyTree.manualLabeler(0, leaf('aaa'));
    expect(result[0]).to.be.equal(1);
    expect(result[1](identity)).to.be.eql([0,'aaa']);
  });
  it('labels a half-empty node', function() {
    // [1, node(empty(), leaf([1,'aaa']))]
    var result = MyTree.manualLabeler(0, node(empty(), leaf('aaa')));
    expect(result[0]).to.be.equal(1);
    expect(left(result[1])(identity)).to.be.undefined;
    expect(right(result[1])(identity)).to.be.eql([0, 'aaa']);
  });
  it('labels a simple tree', function() {
    var simpleResult = MyTree.manualLabeler(0, simpleTree);
    expect(simpleResult[0]).to.be.equal(3);
    var leftLabeledLeaf = left(simpleResult[1]); // leaf([0,'a'])
    expect(leftLabeledLeaf(identity)).to.be.eql([0,'a']);
    expect(right(right(simpleResult[1]))(identity)).to.be.eql([2,'c']);
  });
  it('labels a complex tree', function() {
    var complexResult = MyTree.manualLabeler(0, complexTree);
    var finalState = complexResult[0];
    var labeledTree = complexResult[1];
    expect(finalState).to.be.equal(4);
    expect(left(labeledTree)(identity)).to.be.eql([0,'a']);
    expect(right(left(right(labeledTree)))(identity)).to.be.eql([2,'c']);
    expect(right(right(labeledTree))(identity)).to.be.eql([3,'d']);
  });
});

describe('monadic labeler', function() {
  it('labels a single leaf', function() {
    var result = MyTree.monadicLabeler(leaf('aaa'));
    // s => [s+1, leaf([s,'aaa'])]
    expect(result.bind(a => getState)(0)[1]).to.be.equal(1);
    expect(result(0)[0]).to.be.equal(1);
    expect(result(0)[1](identity)).to.be.eql([0, 'aaa']);
  });
  it('labels a half-empty node', function() {
    // result(0) = [1, node(empty(), leaf([1,'aaa']))]
    var result = MyTree.monadicLabeler(node(empty(), leaf('aaa')));
    expect(result(0)[0]).to.be.equal(1);
    expect(left(result(0)[1])(identity)).to.be.undefined;
    expect(right(result(0)[1])(identity)).to.be.eql([0, 'aaa']);
  });
  it('labels a simple tree', function() {
    var simpleResult = MyTree.monadicLabeler(simpleTree);
    // s => [s+3, node(leaf([s,'a']),node(leaf([s+1,'b']),leaf([s+2,'c'])))]
    expect(simpleResult(0)[0]).to.be.equal(3);
    var leftLabeledLeaf = left(simpleResult(0)[1]); // leaf([0,'a'])
    expect(leftLabeledLeaf(identity)).to.be.eql([0,'a']);
    expect(right(right(simpleResult(0)[1]))(identity)).to.be.eql([2,'c']);
  });
  it('labels a complex tree', function() {
    var complexResult = MyTree.monadicLabeler(complexTree);
    var finalState = complexResult(0)[0];
    var labeledTree = complexResult(0)[1];
    expect(finalState).to.be.equal(4);
    expect(left(labeledTree)(identity)).to.be.eql([0,'a']);
    expect(right(left(right(labeledTree)))(identity)).to.be.eql([2,'c']);
  });
  it('labels a complex tree with empties', function() {
    var complexResult = MyTree.monadicLabeler(complexTreeWithEmpties);
    var finalState = complexResult(0)[0];
    var labeledTree = complexResult(0)[1];
    expect(finalState).to.be.equal(3);
    expect(left(labeledTree)(identity)).to.be.eql([0,'a']);
    expect(right(left(right(labeledTree)))(identity)).to.be.undefined;
  });
});
<commit_msg>other lil things<commit_after>/*
	GEIESMONADS - JS monads
	Author: Marco Faustinelli (contacts@faustinelli.net)
	Web: http://faustinelli.net/
	     http://faustinelli.wordpress.com/

	The MIT License - Copyright (c) 2013/2015 Geiesmonads Project
*/

var expect = chai.expect;
mocha.setup('bdd');

describe('maybe monad', function() {
  var maybe = MONAD.maybe.UNIT;
  var isSome = MONAD.maybe.isSome;
  it('may be some or none', function() {
    expect(maybe(12)()).to.be.equal(12);
    expect(isSome(maybe(null))).to.be.not.ok;
  });
  it('binds into some or none', function() {
    var famb = a => maybe(a * 2);
    expect(maybe(12).bind(famb)()).to.be.equal(24);
    expect(isSome(maybe(null).bind(famb))).to.be.not.ok;
  });
});

describe('either a monad', function() {
  var left = MONAD.either.left;
  var right = MONAD.either.right;
  var isLeft = MONAD.either.isLeft;
  var isRight = MONAD.either.isRight;
  it('may be left or right', function() {
    expect(left(12)()).to.be.equal(12);
    expect(right(13)()).to.be.equal(13);
    expect(isLeft(right('www'))).to.be.not.ok;
    expect(isRight(left('www'))).to.be.not.ok;
    expect(isLeft(left('www'))).to.be.ok;
    expect(isRight(right('www'))).to.be.ok;
  });
  it('binds from right to left', function() {
    var farb = a => right(a * 2);
    var falb = a => left(a * 2);
    var right2Right = right(12).bind(farb);
    expect(right2Right()).to.be.equal(24);
    expect(isRight(right2Right)).to.be.ok;

    var right2Left = right(12).bind(falb);
    expect(right2Left()).to.be.equal(24);
    expect(isLeft(right2Left)).to.be.ok;
  });
  it('binds from left to left', function() {
    var farb = a => right(a * 2);
    var falb = a => left(a * 2);
    var left2Right = left(12).bind(farb);
    expect(left2Right()).to.be.equal(12);
    expect(isLeft(left2Right)).to.be.ok;

    var left2Left = left(12).bind(falb);
    expect(left2Left()).to.be.equal(12);
    expect(isLeft(left2Left)).to.be.ok;
  });
});

var state = MONAD.state.state;
var unit = MONAD.state.UNIT;
var getState = MONAD.state.sGet;

describe('state monad', function() {
  it('is a spring mouse', function() {
    expect(unit(12)(1)[0]).to.be.equal(1);
    expect(unit(12)(1)[1]).to.be.equal(12);
    expect(state(s => [s, 12])(1)[0]).to.be.equal(1);
    expect(state(s => [s, 12])(1)[1]).to.be.equal(12);
  });
  it('binds very well', function() {
    var twelve = unit(12);
    var fasmb = a => state(s => [a+s, a-s]);
    var bound = twelve.bind(fasmb);
    var [sss, aaa] = bound(1);
    expect(sss).to.be.equal(13);
    expect(aaa).to.be.equal(11);
  });
  it('features sGet', function() {
    var twelve = unit(12);
    var fasmb = a => state(s => [a+s, a-s]); // s -> 12+s
    var bound = twelve.bind(fasmb).bind(a => getState);
    var [sss, aaa] = bound(1);
    expect(sss).to.be.equal(13);
    expect(aaa).to.be.equal(13);
  });
  it('features sSet', function() {
    var setState = MONAD.state.sSet;
    var twelve = unit(12);
    var fasmb = a => state(s => [a+s, a-s]); // a -> 12-s
    var bound = twelve.bind(fasmb).bind(a => setState(a*2));
    var [sss, aaa] = bound(1);
    expect(sss).to.be.equal(22);
    expect(aaa).to.be.undefined;
  });
});

var node = MyTree.node;
var leaf = MyTree.leaf;
var empty = MyTree.empty;
var left = MyTree.left;
var right = MyTree.right;
var identity = x => x;

var simpleTree = node(leaf('a'),node(leaf('b'),leaf('c')));
var complexTree = node(
  leaf('a'),
  node(
    node(
      leaf('b'),
      leaf('c')),
    leaf('d')
  )
);
var complexTreeWithEmpties = node(
  leaf('a'),
  node(
    node(
      leaf('b'),
      empty()),
    leaf('d')
  )
);

describe('manual labeler', function() {
  it('labels a single leaf', function() {
    var result = MyTree.manualLabeler(0, leaf('aaa'));
    expect(result[0]).to.be.equal(1);
    expect(result[1](identity)).to.be.eql([0,'aaa']);
  });
  it('labels a half-empty node', function() {
    // [1, node(empty(), leaf([1,'aaa']))]
    var result = MyTree.manualLabeler(0, node(empty(), leaf('aaa')));
    expect(result[0]).to.be.equal(1);
    expect(left(result[1])(identity)).to.be.undefined;
    expect(right(result[1])(identity)).to.be.eql([0, 'aaa']);
  });
  it('labels a simple tree', function() {
    var simpleResult = MyTree.manualLabeler(0, simpleTree);
    expect(simpleResult[0]).to.be.equal(3);
    var leftLabeledLeaf = left(simpleResult[1]); // leaf([0,'a'])
    expect(leftLabeledLeaf(identity)).to.be.eql([0,'a']);
    expect(right(right(simpleResult[1]))(identity)).to.be.eql([2,'c']);
  });
  it('labels a complex tree', function() {
    var complexResult = MyTree.manualLabeler(0, complexTree);
    var finalState = complexResult[0];
    var labeledTree = complexResult[1];
    expect(finalState).to.be.equal(4);
    expect(left(labeledTree)(identity)).to.be.eql([0,'a']);
    expect(right(left(right(labeledTree)))(identity)).to.be.eql([2,'c']);
    expect(right(right(labeledTree))(identity)).to.be.eql([3,'d']);
  });
});

describe('monadic labeler', function() {
  it('labels a single leaf', function() {
    var result = MyTree.monadicLabeler(leaf('aaa'));
    // s => [s+1, leaf([s,'aaa'])]
    expect(result.bind(a => getState)(0)[1]).to.be.equal(1);
    expect(result(0)[0]).to.be.equal(1);
    expect(result(0)[1](identity)).to.be.eql([0, 'aaa']);
  });
  it('labels a half-empty node', function() {
    // result(0) = [1, node(empty(), leaf([1,'aaa']))]
    var result = MyTree.monadicLabeler(node(empty(), leaf('aaa')));
    expect(result(0)[0]).to.be.equal(1);
    expect(left(result(0)[1])(identity)).to.be.undefined;
    expect(right(result(0)[1])(identity)).to.be.eql([0, 'aaa']);
  });
  it('labels a simple tree', function() {
    var simpleResult = MyTree.monadicLabeler(simpleTree);
    // s => [s+3, node(leaf([s,'a']),node(leaf([s+1,'b']),leaf([s+2,'c'])))]
    expect(simpleResult(0)[0]).to.be.equal(3);
    var leftLabeledLeaf = left(simpleResult(0)[1]); // leaf([0,'a'])
    expect(leftLabeledLeaf(identity)).to.be.eql([0,'a']);
    expect(right(right(simpleResult(0)[1]))(identity)).to.be.eql([2,'c']);
  });
  it('labels a complex tree', function() {
    var complexResult = MyTree.monadicLabeler(complexTree);
    var finalState = complexResult(0)[0];
    var labeledTree = complexResult(0)[1];
    expect(finalState).to.be.equal(4);
    expect(left(labeledTree)(identity)).to.be.eql([0,'a']);
    expect(right(left(right(labeledTree)))(identity)).to.be.eql([2,'c']);
  });
  it('labels a complex tree with empties', function() {
    var complexResult = MyTree.monadicLabeler(complexTreeWithEmpties);
    var finalState = complexResult(0)[0];
    var labeledTree = complexResult(0)[1];
    expect(finalState).to.be.equal(3);
    expect(left(labeledTree)(identity)).to.be.eql([0,'a']);
    expect(right(left(right(labeledTree)))(identity)).to.be.undefined;
  });
});<|endoftext|>