<commit_before>let _                   = require('lodash'),
    moment              = require('moment'),
    redisCache          = require('../utils/redisCache'),
    mongoose            = require('../utils').mongoose,
    User                = mongoose.model('User'),
    Contest             = mongoose.model('Contest'),
    UserContests        = mongoose.model('UserContests'),
    CacheableRepository = require('./cacheableRepository');

class ContestRepository extends CacheableRepository {
    constructor() {
        super(Contest, 'contest');
    }

    create(set, withCache = false) {
        return new Promise((resolve, reject) => {
            super.create(set, withCache)
                .then(data => {
                    redisCache.updateCache(`${this.cacheKeyPrefix}:latestActive`, next => {
                        next(null, data);
                    });
                    resolve(data);
                })
                .catch(err => {
                    reject(err);
                })
        });
    }

    createUserContest(user, contest) {
        return new Promise((resolve, reject) => {
            let obj = new UserContests({
                user   : user._id,
                contest: contest._id,
                score  : 0,
                begin  : moment(contest.begin, 'LLL').toDate(),
                end    : moment(contest.end, 'LLL').toDate()
            });
            obj.save(err => {
                if (err) {
                    return reject(err);
                }
                let real     = obj.toObject();
                real.user    = user;
                real.contest = contest;
                resolve(real);
            });
        });
    }

    findByIdCore(id, columns, next) {
        this.model.findById(id, columns)
            .populate('problems', '-cases')
            .exec(next);
    }

    findActiveContests(openOnly = true, sort = '') {
        return redisCache.getCache(`${this.cacheKeyPrefix}:ActiveContests`, next => {
            Contest.find(openOnly ? {open: true} : null)
                .gte('end', new Date())
                .lte('begin', new Date())
                .sort(sort)
                .exec((err, contests) => {
                    if (err) {
                        return next(err);
                    }
                    return next(null, contests || []);
                });
        });
    }

    getLatestActiveInfo() {
        return redisCache.getCache(`${this.cacheKeyPrefix}:latestActive`, this._findLatestActiveInfo);
    }

    updateLatestActiveInfo() {
        return redisCache.updateCache(`${this.cacheKeyPrefix}:latestActive`, this._findLatestActiveInfo);
    }

    _findLatestActiveInfo(next) {
        Contest.findOne()
            .gte('end', new Date())
            .lte('begin', new Date())
            .sort('-begin')
            .exec((err, contest) => {
                if (err) {
                    return next(err);
                }
                UserContests.find({contest: contest._id})
                    .count()
                    .exec((err, userCount) => {
                        if (err) {
                            return next(err);
                        }
                        let obj       = contest.toObject();
                        obj.userCount = userCount;
                        if (userCount > 0) {
                            UserContests.findOne({contest: contest._id})
                                .sort('score')
                                .select('score')
                                .limit(1)
                                .exec((err, uc) => {
                                    if (err) {
                                        return next(err);
                                    }
                                    obj.maxScore = uc.score;
                                    return next(null, obj);
                                });
                        } else {
                            obj.maxScore = 0;
                            return next(null, obj);
                        }
                    });
            });
    }

    findAllContests(openOnly = true) {
        return redisCache.getCache(`${this.cacheKeyPrefix}:all`, next => {
            Contest.find(openOnly ? {open: true} : null)
            // .populate('problems')
                .exec((err, contests) => {
                    if (err) {
                        return next(err);
                    }
                    return next(null, contests || []);
                });
        });
    }

    findByUser(userId) {
        return new Promise(
            (resolve, reject) => UserContests.find({user: userId})
                .exec((err, data) => {
                    if (err) {
                        return reject(err);
                    }
                    resolve(data);
                }));
    }

    findByName(contestName) {
        return redisCache.getCache(`${this.cacheKeyPrefix}:${contestName}`, next => {
            Contest.findOne({name: contestName})
                .populate('problems', '-cases')
                .exec((err, contest) => {
                    if (err) {
                        return next(err);
                    }
                    if (!contest) {
                        err        = new Error('Not found');
                        err.status = 404;
                        return next(err);
                    }
                    let obj   = contest.toObject();
                    obj.begin = moment(obj.begin).format('LLL');
                    obj.end   = moment(obj.end).format('LLL');
                    next(null, obj);
                });
        })
    }

    findOneByIdAndUser(contestId, userId) {
        return redisCache.getCache(`${this.cacheKeyPrefix}:${contestId}:${userId}`, next => {
            UserContests.findOne({contest: contestId, user: userId})
                .exec((err, uc) => {
                    if (err) {
                        return next(err);
                    }
                    if (!uc) {
                        err        = new Error('Not found');
                        err.status = 404;
                        return next(err);
                    }
                    let obj   = uc.toObject();
                    obj.begin = moment(obj.begin).format('LLL');
                    obj.end   = moment(obj.end).format('LLL');
                    next(null, obj);
                });
        })
    }

    getTop10(contestId) {
        return redisCache.getCache(`${this.cacheKeyPrefix}:${contestId}:top10`,
            next => this._findTop10ById(contestId, next));
    }

    updateTop10(contestId) {
        return redisCache.updateCache(`${this.cacheKeyPrefix}:${contestId}:top10`,
            next => this._findTop10ById(contestId, next));
    }

    _findTop10ById(contestId, next) {
        UserContests.find({contest: contestId, score: {$gt: 0}})
            .sort('-score')
            .populate('user')
            .exec((err, uc) => {
                if (err) {
                    return next(err);
                }
                if (!uc) {
                    err        = new Error('Not found');
                    err.status = 404;
                    return next();
                }
                next(null, uc);
            });
    }
}

module.exports = ContestRepository;<commit_msg>fix crash if there is no contest<commit_after>let _                   = require('lodash'),
    moment              = require('moment'),
    redisCache          = require('../utils/redisCache'),
    mongoose            = require('../utils').mongoose,
    User                = mongoose.model('User'),
    Contest             = mongoose.model('Contest'),
    UserContests        = mongoose.model('UserContests'),
    CacheableRepository = require('./cacheableRepository');

class ContestRepository extends CacheableRepository {
    constructor() {
        super(Contest, 'contest');
    }

    create(set, withCache = false) {
        return new Promise((resolve, reject) => {
            super.create(set, withCache)
                .then(data => {
                    redisCache.updateCache(`${this.cacheKeyPrefix}:latestActive`, next => {
                        next(null, data);
                    });
                    resolve(data);
                })
                .catch(err => {
                    reject(err);
                })
        });
    }

    createUserContest(user, contest) {
        return new Promise((resolve, reject) => {
            let obj = new UserContests({
                user   : user._id,
                contest: contest._id,
                score  : 0,
                begin  : moment(contest.begin, 'LLL').toDate(),
                end    : moment(contest.end, 'LLL').toDate()
            });
            obj.save(err => {
                if (err) {
                    return reject(err);
                }
                let real     = obj.toObject();
                real.user    = user;
                real.contest = contest;
                resolve(real);
            });
        });
    }

    findByIdCore(id, columns, next) {
        this.model.findById(id, columns)
            .populate('problems', '-cases')
            .exec(next);
    }

    findActiveContests(openOnly = true, sort = '') {
        return redisCache.getCache(`${this.cacheKeyPrefix}:ActiveContests`, next => {
            Contest.find(openOnly ? {open: true} : null)
                .gte('end', new Date())
                .lte('begin', new Date())
                .sort(sort)
                .exec((err, contests) => {
                    if (err) {
                        return next(err);
                    }
                    return next(null, contests || []);
                });
        });
    }

    getLatestActiveInfo() {
        return redisCache.getCache(`${this.cacheKeyPrefix}:latestActive`, this._findLatestActiveInfo);
    }

    updateLatestActiveInfo() {
        return redisCache.updateCache(`${this.cacheKeyPrefix}:latestActive`, this._findLatestActiveInfo);
    }

    _findLatestActiveInfo(next) {
        Contest.findOne()
            .gte('end', new Date())
            .lte('begin', new Date())
            .sort('-begin')
            .exec((err, contest) => {
                if (err) {
                    return next(err);
                }
                if(!contest){
                    err = new Error('Not found');
                    err.status = 404;
                    return next(err);
                }

                UserContests.find({contest: contest._id})
                    .count()
                    .exec((err, userCount) => {
                        if (err) {
                            return next(err);
                        }
                        let obj       = contest.toObject();
                        obj.userCount = userCount;
                        if (userCount > 0) {
                            UserContests.findOne({contest: contest._id})
                                .sort('score')
                                .select('score')
                                .limit(1)
                                .exec((err, uc) => {
                                    if (err) {
                                        return next(err);
                                    }
                                    obj.maxScore = uc.score;
                                    return next(null, obj);
                                });
                        } else {
                            obj.maxScore = 0;
                            return next(null, obj);
                        }
                    });
            });
    }

    findAllContests(openOnly = true) {
        return redisCache.getCache(`${this.cacheKeyPrefix}:all`, next => {
            Contest.find(openOnly ? {open: true} : null)
            // .populate('problems')
                .exec((err, contests) => {
                    if (err) {
                        return next(err);
                    }
                    return next(null, contests || []);
                });
        });
    }

    findByUser(userId) {
        return new Promise(
            (resolve, reject) => UserContests.find({user: userId})
                .exec((err, data) => {
                    if (err) {
                        return reject(err);
                    }
                    resolve(data);
                }));
    }

    findByName(contestName) {
        return redisCache.getCache(`${this.cacheKeyPrefix}:${contestName}`, next => {
            Contest.findOne({name: contestName})
                .populate('problems', '-cases')
                .exec((err, contest) => {
                    if (err) {
                        return next(err);
                    }
                    if (!contest) {
                        err        = new Error('Not found');
                        err.status = 404;
                        return next(err);
                    }
                    let obj   = contest.toObject();
                    obj.begin = moment(obj.begin).format('LLL');
                    obj.end   = moment(obj.end).format('LLL');
                    next(null, obj);
                });
        })
    }

    findOneByIdAndUser(contestId, userId) {
        return redisCache.getCache(`${this.cacheKeyPrefix}:${contestId}:${userId}`, next => {
            UserContests.findOne({contest: contestId, user: userId})
                .exec((err, uc) => {
                    if (err) {
                        return next(err);
                    }
                    if (!uc) {
                        err        = new Error('Not found');
                        err.status = 404;
                        return next(err);
                    }
                    let obj   = uc.toObject();
                    obj.begin = moment(obj.begin).format('LLL');
                    obj.end   = moment(obj.end).format('LLL');
                    next(null, obj);
                });
        })
    }

    getTop10(contestId) {
        return redisCache.getCache(`${this.cacheKeyPrefix}:${contestId}:top10`,
            next => this._findTop10ById(contestId, next));
    }

    updateTop10(contestId) {
        return redisCache.updateCache(`${this.cacheKeyPrefix}:${contestId}:top10`,
            next => this._findTop10ById(contestId, next));
    }

    _findTop10ById(contestId, next) {
        UserContests.find({contest: contestId, score: {$gt: 0}})
            .sort('-score')
            .populate('user')
            .exec((err, uc) => {
                if (err) {
                    return next(err);
                }
                if (!uc) {
                    err        = new Error('Not found');
                    err.status = 404;
                    return next();
                }
                next(null, uc);
            });
    }
}

module.exports = ContestRepository;<|endoftext|>


<commit_before>$(document).ready(function() {

    if (!("Notification" in window)) {
        console.log("This browser does not support system notifications");
    } else if (Notification.permission === "default") {
        Notification.requestPermission();
    }

    function notify() {
        if (!("Notification" in window)) {
            console.log("This browser does not support system notifications");
        } else if (Notification.permission === "granted") {
            var notification = new Notification("Получены новые данные.");
        } else if (Notification.permission === 'denied') {
            console.log("Notification permission denied.");
        }
    }

    $("#dnevnik-login").on("submit", function(a) {
        a.preventDefault();

        $("#error").show();
        $("#login-btn").hide();
        $("#error").html("
Loading...
");

        var csrf_token = "{{ csrf_token() }}";

        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrf_token);
                }
            }
        });

        $.ajax({
                url: "/login",
                type: "POST",
                dataType: "json",
                data: $("#dnevnik-login").serialize(),
                timeout: 30000,
            })
            .done(function(data) {
                if (data !== null) {
                    $("#error").html(data);
                    $("#login-btn").show();

                } else {
                    location.reload();
                }

            })
            .fail(function() {
                location.reload();
            });
    });

    $("#dnevnik-date").on("submit", function(a) {
        a.preventDefault();

        $("#dnevnik-out").html("
Дневник

Loading...

");

        $('.mdl-layout__content').animate({
            scrollTop: $("#dnevnik-out").offset().top + 'px'
        }, 'fast');

        if (!navigator.onLine) {
            if (localStorage.getItem('dnevnik') !== null) {
                $("#dnevnik-out").html(localStorage.getItem('dnevnik').replace('
Дневник
', '
Последние данные
'));

                return $('.mdl-layout__content').animate({
                    scrollTop: $("#dnevnik-out").offset().top + 'px'
                }, 'fast');

            } else {
                return location.reload();
            }

        } else {
            document.cookie = "Offset=" + (-new Date().getTimezoneOffset() / 60);

            var date = $("#dnevnik-date").serialize();
            var ajaxCalled = false;
            var callout = function() {

                var csrf_token = "{{ csrf_token() }}";

                $.ajaxSetup({
                    beforeSend: function(xhr, settings) {
                        if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                            xhr.setRequestHeader("X-CSRFToken", csrf_token);
                        }
                    }
                });

                $.ajax({
                        url: "/dnevnik",
                        type: "POST",
                        dataType: "json",
                        data: date,
                        timeout: 30000,
                    })
                    .done(function(data) {
                        if (data.indexOf('

') !== -1) {
                            $("#children_out").html(data.replace('

', ''));
                            $("#dnevnik-out").html("
Дневник

");
                            return;
                        } else {
                            $("#dnevnik-out").html(data);
                        }

                        if (localStorage.getItem('dnevnik') !== null) {
                            if ((data.indexOf("
Данные не получены ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Залогиньтесь ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Ох, похоже, что-то не так ( ͡° ͜ʖ ͡°)
") === -1) && (data.indexOf('

') === -1)) {
                                if (ajaxCalled === true) {
                                    if (data !== localStorage.getItem('dnevnik')) {
                                        notify();
                                    }
                                }

                                localStorage.removeItem("dnevnik");
                                localStorage.setItem('dnevnik', data);
                            }

                        } else {
                            if ((data.indexOf("
Данные не получены ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Залогиньтесь ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Ох, похоже, что-то не так ( ͡° ͜ʖ ͡°)
") === -1)  && (data.indexOf('

') === -1)) {
                                localStorage.setItem('dnevnik', data);
                            }
                        }

                        $('.mdl-layout__content').animate({
                            scrollTop: $("#dnevnik-out").offset().top + 'px'
                        }, 'fast');
                    })
                    .fail(function() {
                        if (localStorage.getItem('dnevnik') !== null) {
                            $("#dnevnik-out").html(localStorage.getItem('dnevnik').replace('
Дневник
', '
Последние данные
'));

                            $('.mdl-layout__content').animate({
                                scrollTop: $("#dnevnik-out").offset().top + 'px'
                            }, 'fast');

                        } else {
                            location.reload();
                        }

                    })
                    .always(function() {
                        setTimeout(callout, 1000 * 60 * 5);
                    });
            };

            callout();
        }

    });

    $("#dnevnik-stats").on("submit", function(a) {
        a.preventDefault();

        $("#stats-out").html("
Статистика

Loading...

");

        $('.mdl-layout__content').animate({
            scrollTop: $("#stats-out").offset().top + 'px'
        }, 'fast');

        if (!navigator.onLine) {
            if (localStorage.getItem('stats') !== null) {
                $("#stats-out").html(localStorage.getItem('stats').replace('
Статистика
', '
Последние данные
'));

                return $('.mdl-layout__content').animate({
                    scrollTop: $("#stats-out").offset().top + 'px'
                }, 'fast');

            } else {
                return location.reload();
            }

        } else {
            var csrf_token = "{{ csrf_token() }}";

            $.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader("X-CSRFToken", csrf_token);
                    }
                }
            });

            $.ajax({
                    url: "/stats",
                    type: "POST",
                    dataType: "json",
                    data: $("#dnevnik-stats").serialize(),
                    timeout: 30000,
                })
                .done(function(data) {
                    if (data.indexOf('

') !== -1) {
                        $("#children_out_stats").html(data.replace('

', ''));
                        $("#stats-out").html("
Cтатистика

");
                        return;
                    } else {
                        $("#stats-out").html(data);
                    }

                    if (localStorage.getItem('stats') !== null) {
                        if ((data.indexOf("
Данные не получены ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Залогиньтесь ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Ох, похоже, что-то не так ( ͡° ͜ʖ ͡°)
") === -1)  && (data.indexOf('

') === -1)) {
                            localStorage.removeItem("stats");
                            localStorage.setItem('stats', data);
                        }

                    } else {
                        if ((data.indexOf("
Данные не получены ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Залогиньтесь ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Ох, похоже, что-то не так ( ͡° ͜ʖ ͡°)
") === -1) && (data.indexOf('

') === -1)) {
                            localStorage.setItem('stats', data);
                        }
                    }

                    $('.mdl-layout__content').animate({
                        scrollTop: $("#stats-out").offset().top + 'px'
                    }, 'fast');
                })
                .fail(function() {
                    if (localStorage.getItem('stats') !== null) {
                        $("#stats-out").html(localStorage.getItem('stats').replace('
Статистика
', '
Последние данные
'));

                        $('.mdl-layout__content').animate({
                            scrollTop: $("#stats-out").offset().top + 'px'
                        }, 'fast');

                    } else {
                        location.reload();
                    }

                });
        }
    });

    $("#dnevnik-summary").on("submit", function(a) {
        a.preventDefault();

        $("#summary-out").html("
Итоговые

Loading...

");

        $('.mdl-layout__content').animate({
            scrollTop: $("#summary-out").offset().top + 'px'
        }, 'fast');

        if (!navigator.onLine) {
            if (localStorage.getItem('summary') !== null) {
                $("#summary-out").html(localStorage.getItem('summary').replace('
Итоговые
', '
Последние данные
'));

                return $('.mdl-layout__content').animate({
                    scrollTop: $("#summary-out").offset().top + 'px'
                }, 'fast');

            } else {
                return location.reload();
            }

        } else {
            var csrf_token = "{{ csrf_token() }}";

            $.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader("X-CSRFToken", csrf_token);
                    }
                }
            });

            $.ajax({
                    url: "/summary",
                    type: "POST",
                    dataType: "json",
                    data: $("#dnevnik-summary").serialize(),
                    timeout: 30000,
                })
                .done(function(data) {
                    if (data.indexOf('

') !== -1) {
                        $("#children_out_summary").html(data.replace('

', ''));
                        $("#summary-out").html("
Итоговые

");
                        return;
                    } else {
                        $("#summary-out").html(data);
                    }

                    if (localStorage.getItem('summary') !== null) {
                        if ((data.indexOf("
Данные не получены ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Залогиньтесь ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Ох, похоже, что-то не так ( ͡° ͜ʖ ͡°)
") === -1) && (data.indexOf('

') === -1)) {
                            localStorage.removeItem("summary");
                            localStorage.setItem('summary', data);
                        }

                    } else {
                        if ((data.indexOf("
Данные не получены ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Залогиньтесь ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Ох, похоже, что-то не так ( ͡° ͜ʖ ͡°)
") === -1) && (data.indexOf('

') === -1)) {
                            localStorage.setItem('summary', data);
                        }
                    }

                    $('.mdl-layout__content').animate({
                        scrollTop: $("#summary-out").offset().top + 'px'
                    }, 'fast');
                })
                .fail(function() {
                    if (localStorage.getItem('summary') !== null) {
                        $("#summary-out").html(localStorage.getItem('summary').replace('
Итоговые
', '
Последние данные
'));

                        $('.mdl-layout__content').animate({
                            scrollTop: $("#summary-out").offset().top + 'px'
                        }, 'fast');

                    } else {
                        location.reload();
                    }

                });
        }
    });

    $('form').each(function() {
        $(this).find('input').keypress(function(e) {
            if (e.which == 10 || e.which == 13) {
                this.form.submit();
            }
        });
    });

    HTMLDocument.prototype.__defineGetter__("write", function() {
        return null;
    });

});
<commit_msg>Update dnevnik.operator.js<commit_after>$(document).ready(function() {

    if (!("Notification" in window)) {
        console.log("This browser does not support system notifications");
    } else if (Notification.permission === "default") {
        Notification.requestPermission();
    }

    function notify() {
        if (!("Notification" in window)) {
            console.log("This browser does not support system notifications");
        } else if (Notification.permission === "granted") {
            var notification = new Notification("Получены новые данные.");
        } else if (Notification.permission === 'denied') {
            console.log("Notification permission denied.");
        }
    }

    $("#dnevnik-login").on("submit", function(a) {
        a.preventDefault();

        $("#error").show();
        $("#login-btn").hide();
        $("#error").html("
Loading...
");

        var csrf_token = "{{ csrf_token() }}";

        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrf_token);
                }
            }
        });

        $.ajax({
                url: "/login",
                type: "POST",
                dataType: "json",
                data: $("#dnevnik-login").serialize(),
                timeout: 30000,
            })
            .done(function(data) {
                if (data !== null) {
                    $("#error").html(data);
                    $("#login-btn").show();

                } else {
                    location.reload();
                }

            })
            .fail(function() {
                location.reload();
            });
    });

    $("#dnevnik-date").on("submit", function(a) {
        a.preventDefault();

        $("#dnevnik-out").html("
Дневник

Loading...

");

        $('.mdl-layout__content').animate({
            scrollTop: $("#dnevnik-out").offset().top + 'px'
        }, 'fast');

        if (!navigator.onLine) {
            if (localStorage.getItem('dnevnik') !== null) {
                $("#dnevnik-out").html(localStorage.getItem('dnevnik').replace('
Дневник
', '
Последние данные
'));

                return $('.mdl-layout__content').animate({
                    scrollTop: $("#dnevnik-out").offset().top + 'px'
                }, 'fast');

            } else {
                return location.reload();
            }

        } else {
            document.cookie = "Offset=" + (-new Date().getTimezoneOffset() / 60);

            var date = $("#dnevnik-date").serialize();
            var ajaxCalled = false;
            var callout = function() {

                var csrf_token = "{{ csrf_token() }}";

                $.ajaxSetup({
                    beforeSend: function(xhr, settings) {
                        if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                            xhr.setRequestHeader("X-CSRFToken", csrf_token);
                        }
                    }
                });

                $.ajax({
                        url: "/dnevnik",
                        type: "POST",
                        dataType: "json",
                        data: date,
                        timeout: 30000,
                    })
                    .done(function(data) {
                        if (data.indexOf('

') !== -1) {
                            $("#children_out_dnevnik").html(data.replace('

', ''));
                            $("#dnevnik-out").html("
Дневник

");
                            return;
                        } else {
                            $("#dnevnik-out").html(data);
                        }

                        if (localStorage.getItem('dnevnik') !== null) {
                            if ((data.indexOf("
Данные не получены ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Залогиньтесь ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Ох, похоже, что-то не так ( ͡° ͜ʖ ͡°)
") === -1) && (data.indexOf('

') === -1)) {
                                if (ajaxCalled === true) {
                                    if (data !== localStorage.getItem('dnevnik')) {
                                        notify();
                                    }
                                }

                                localStorage.removeItem("dnevnik");
                                localStorage.setItem('dnevnik', data);
                            }

                        } else {
                            if ((data.indexOf("
Данные не получены ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Залогиньтесь ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Ох, похоже, что-то не так ( ͡° ͜ʖ ͡°)
") === -1)  && (data.indexOf('

') === -1)) {
                                localStorage.setItem('dnevnik', data);
                            }
                        }

                        $('.mdl-layout__content').animate({
                            scrollTop: $("#dnevnik-out").offset().top + 'px'
                        }, 'fast');
                    })
                    .fail(function() {
                        if (localStorage.getItem('dnevnik') !== null) {
                            $("#dnevnik-out").html(localStorage.getItem('dnevnik').replace('
Дневник
', '
Последние данные
'));

                            $('.mdl-layout__content').animate({
                                scrollTop: $("#dnevnik-out").offset().top + 'px'
                            }, 'fast');

                        } else {
                            location.reload();
                        }

                    })
                    .always(function() {
                        setTimeout(callout, 1000 * 60 * 5);
                    });
            };

            callout();
        }

    });

    $("#dnevnik-stats").on("submit", function(a) {
        a.preventDefault();

        $("#stats-out").html("
Статистика

Loading...

");

        $('.mdl-layout__content').animate({
            scrollTop: $("#stats-out").offset().top + 'px'
        }, 'fast');

        if (!navigator.onLine) {
            if (localStorage.getItem('stats') !== null) {
                $("#stats-out").html(localStorage.getItem('stats').replace('
Статистика
', '
Последние данные
'));

                return $('.mdl-layout__content').animate({
                    scrollTop: $("#stats-out").offset().top + 'px'
                }, 'fast');

            } else {
                return location.reload();
            }

        } else {
            var csrf_token = "{{ csrf_token() }}";

            $.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader("X-CSRFToken", csrf_token);
                    }
                }
            });

            $.ajax({
                    url: "/stats",
                    type: "POST",
                    dataType: "json",
                    data: $("#dnevnik-stats").serialize(),
                    timeout: 30000,
                })
                .done(function(data) {
                    if (data.indexOf('

') !== -1) {
                        $("#children_out_stats").html(data.replace('

', ''));
                        $("#stats-out").html("
Cтатистика

");
                        return;
                    } else {
                        $("#stats-out").html(data);
                    }

                    if (localStorage.getItem('stats') !== null) {
                        if ((data.indexOf("
Данные не получены ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Залогиньтесь ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Ох, похоже, что-то не так ( ͡° ͜ʖ ͡°)
") === -1)  && (data.indexOf('

') === -1)) {
                            localStorage.removeItem("stats");
                            localStorage.setItem('stats', data);
                        }

                    } else {
                        if ((data.indexOf("
Данные не получены ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Залогиньтесь ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Ох, похоже, что-то не так ( ͡° ͜ʖ ͡°)
") === -1) && (data.indexOf('

') === -1)) {
                            localStorage.setItem('stats', data);
                        }
                    }

                    $('.mdl-layout__content').animate({
                        scrollTop: $("#stats-out").offset().top + 'px'
                    }, 'fast');
                })
                .fail(function() {
                    if (localStorage.getItem('stats') !== null) {
                        $("#stats-out").html(localStorage.getItem('stats').replace('
Статистика
', '
Последние данные
'));

                        $('.mdl-layout__content').animate({
                            scrollTop: $("#stats-out").offset().top + 'px'
                        }, 'fast');

                    } else {
                        location.reload();
                    }

                });
        }
    });

    $("#dnevnik-summary").on("submit", function(a) {
        a.preventDefault();

        $("#summary-out").html("
Итоговые

Loading...

");

        $('.mdl-layout__content').animate({
            scrollTop: $("#summary-out").offset().top + 'px'
        }, 'fast');

        if (!navigator.onLine) {
            if (localStorage.getItem('summary') !== null) {
                $("#summary-out").html(localStorage.getItem('summary').replace('
Итоговые
', '
Последние данные
'));

                return $('.mdl-layout__content').animate({
                    scrollTop: $("#summary-out").offset().top + 'px'
                }, 'fast');

            } else {
                return location.reload();
            }

        } else {
            var csrf_token = "{{ csrf_token() }}";

            $.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader("X-CSRFToken", csrf_token);
                    }
                }
            });

            $.ajax({
                    url: "/summary",
                    type: "POST",
                    dataType: "json",
                    data: $("#dnevnik-summary").serialize(),
                    timeout: 30000,
                })
                .done(function(data) {
                    if (data.indexOf('

') !== -1) {
                        $("#children_out_summary").html(data.replace('

', ''));
                        $("#summary-out").html("
Итоговые

");
                        return;
                    } else {
                        $("#summary-out").html(data);
                    }

                    if (localStorage.getItem('summary') !== null) {
                        if ((data.indexOf("
Данные не получены ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Залогиньтесь ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Ох, похоже, что-то не так ( ͡° ͜ʖ ͡°)
") === -1) && (data.indexOf('

') === -1)) {
                            localStorage.removeItem("summary");
                            localStorage.setItem('summary', data);
                        }

                    } else {
                        if ((data.indexOf("
Данные не получены ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Залогиньтесь ¯\_(ツ)_/¯
") === -1) && (data.indexOf("
Ох, похоже, что-то не так ( ͡° ͜ʖ ͡°)
") === -1) && (data.indexOf('

') === -1)) {
                            localStorage.setItem('summary', data);
                        }
                    }

                    $('.mdl-layout__content').animate({
                        scrollTop: $("#summary-out").offset().top + 'px'
                    }, 'fast');
                })
                .fail(function() {
                    if (localStorage.getItem('summary') !== null) {
                        $("#summary-out").html(localStorage.getItem('summary').replace('
Итоговые
', '
Последние данные
'));

                        $('.mdl-layout__content').animate({
                            scrollTop: $("#summary-out").offset().top + 'px'
                        }, 'fast');

                    } else {
                        location.reload();
                    }

                });
        }
    });

    $('form').each(function() {
        $(this).find('input').keypress(function(e) {
            if (e.which == 10 || e.which == 13) {
                this.form.submit();
            }
        });
    });

    HTMLDocument.prototype.__defineGetter__("write", function() {
        return null;
    });

});
<|endoftext|>


<commit_before>if (!String.prototype.format) {
    String.prototype.format = function () {
        var args = arguments;
        return this.replace(/{(\d+)}/g, function (match, number) {
            return typeof args[number] != 'undefined'
                ? args[number]
                : match
                ;
        });
    };
}

$(document).ready(function () {
    connect_to_ws();
});

function add_random_box({color}) {
    var divsize = 50;
    var posx = (Math.random() * ($(document).width() - divsize)).toFixed();
    var posy = (Math.random() * ($(document).height() - divsize)).toFixed();
    var $newdiv = $("

").css({
        'left': posx + 'px',
        'top': posy + 'px',
        'background-color': color,
        'opacity': 0
    });
    $newdiv.appendTo('body');
    $newdiv.animate({
        opacity: 1
    }, 500);
    setTimeout(function () {
        $newdiv.animate({
            opacity: 0,
        }, 1000);
        setTimeout(function () {
            $newdiv.remove();
        }, 1000);
    }, 5000);
}

// opacity = number between 0 and 100
function add_emotes({emotes, opacity, 'persistence_time': persistenceTime, 'scale': emoteScale}) {
    for (let {emote, 'shown_count': shownCount} of emotes) {
        let url;
        if (emote['bttv_hash'] != null) {
            url = `https://cdn.betterttv.net/emote/${emote['bttv_hash']}/3x`;
        } else if (emote['ffz_id'] != null) {
            url = `http://cdn.frankerfacez.com/emoticon/${emote['ffz_id']}/4`;
        } else if (emote['twitch_id'] != null) {
            url = `https://static-cdn.jtvnw.net/emoticons/v1/${emote['twitch_id']}/3.0`;
        }

        if (url == null) {
            console.warn('Failed to find a URL for emote:', emote);
            continue;
        }

        let divsize = 120;
        for (let i = 0; i < shownCount; i++) {
            let posx = (Math.random() * ($(document).width() - divsize)).toFixed();
            let posy = (Math.random() * ($(document).height() - divsize)).toFixed();
            let newdiv = $('').css({
                'left': posx + 'px',
                'top': posy + 'px',
                'opacity': 0,
                'transform': 'scale(' + String(emoteScale / 100) + ')'
            });
            newdiv.appendTo('body');
            newdiv.animate({
                opacity: opacity / 100
            }, 500);
            setTimeout(() => {
                newdiv.animate({
                    opacity: 0,
                }, 1000);
                setTimeout(() => {
                    newdiv.remove();
                }, 1000);
            }, persistenceTime);
        }
    }
}

function show_custom_image(data) {
    var url = data.url;
    var divsize = 120;
    var posx = (Math.random() * ($(document).width() - divsize)).toFixed();
    var posy = (Math.random() * ($(document).height() - divsize)).toFixed();
    var css_data = {
        'left': posx + 'px',
        'top': posy + 'px',
        'opacity': 0
    }
    if (data.width !== undefined) {
        css_data.width = data.width;
    }
    if (data.height !== undefined) {
        css_data.height = data.height;
    }
    if (data.x !== undefined) {
        css_data.left = data.x + 'px';
    }
    if (data.y !== undefined) {
        css_data.top = data.y + 'px';
    }
    var $newdiv = $('').css(css_data);
    $newdiv.appendTo('body');
    $newdiv.animate({
        opacity: 1
    }, 500);
    setTimeout(function () {
        $newdiv.animate({
            opacity: 0,
        }, 1000);
        setTimeout(function () {
            $newdiv.remove();
        }, 1000);
    }, 5000);
}

var message_id = 0;

function add_notification({message}) {
    var new_notification = $('
' + message + '
').prependTo('div.notifications');
    new_notification.textillate({
        autostart: false,
        in: {
            effect: 'bounceInLeft',
            delay: 5,
            delayScale: 1.5,
            sync: false,
            shuffle: false,
            reverse: false,
        },
        out: {
            effect: 'bounceOutLeft',
            sync: true,
            shuffle: false,
            reverse: false,
        },
        type: 'word',
    });
    new_notification.on('inAnimationEnd.tlt', function () {
        setTimeout(function () {
            new_notification.textillate('out');
            new_notification.animate({
                height: 0,
                opacity: 0,
            }, 1000);
        }, 2000);
    });
    new_notification.on('outAnimationEnd.tlt', function () {
        setTimeout(function () {
            new_notification.remove();
        }, 250);
    });
}

var current_emote_code = null;
var close_down_combo = null;

function refresh_combo_count(count) {
    $('#emote_combo span.count').html(count);
    $('#emote_combo span.count').addClass('animated pulsebig');
    $('#emote_combo span.count').on('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
        $(this).removeClass('animated pulsebig');
    });
    $('#emote_combo img').addClass('animated pulsebig');
    $('#emote_combo img').on('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
        $(this).removeClass('animated pulsebig');
    });
}

function refresh_combo_emote(emote) {
    var url = '';
    if ('bttv_hash' in emote && emote['bttv_hash'] !== null) {
        url = 'https://cdn.betterttv.net/emote/' + emote['bttv_hash'] + '/3x';
    } else if ('ffz_id' in emote && emote['ffz_id'] !== null) {
        url = 'http://cdn.frankerfacez.com/emoticon/' + emote['ffz_id'] + '/4';
    } else if ('twitch_id' in emote) {
        url = 'https://static-cdn.jtvnw.net/emoticons/v1/' + emote['twitch_id'] + '/3.0';
    } else {
        if (emote['code'] == 'xD') {
            url = 'https://cdn.pajlada.se/emoticons/XD.gif';
        }
    }
    $('#emote_combo img').attr('src', url);
}

function debug_text(text) {
    //add_notification(text);
}

function refresh_emote_combo({emote, count}) {
    var emote_combo = $('#emote_combo');
    if (emote_combo.length == 0) {
        if ('bttv_hash' in emote && emote['bttv_hash'] !== null) {
            var url = 'https://cdn.betterttv.net/emote/' + emote['bttv_hash'] + '/2x';
        } else {
            var url = 'https://static-cdn.jtvnw.net/emoticons/v1/' + emote['twitch_id'] + '/2.0';
        }
        current_emote_code = emote['code'];
        var message = 'x{0}  combo!'.format(count, url)
        var new_notification = $('
' + message + '
').prependTo('div.notifications');
        new_notification.addClass('animated bounceInLeft');

        new_notification.on('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
            if (new_notification.hasClass('ended')) {
                new_notification.animate({
                    height: 0,
                    opacity: 0,
                }, 500);
                setTimeout(function () {
                    new_notification.remove();
                }, 500);
            }
        });

        clearTimeout(close_down_combo);
        close_down_combo = setTimeout(function () {
            new_notification.addClass('animated bounceOutLeft ended');
        }, 4000);
    } else {
        clearTimeout(close_down_combo);
        close_down_combo = setTimeout(function () {
            emote_combo.addClass('animated bounceOutLeft ended');
        }, 3000);
        refresh_combo_emote(emote);
        refresh_combo_count(count);
    }
}

function create_object_for_win(points) {
    return {
        value: points,
        color: '#64DD17',
    }
}

function create_object_for_loss(points) {
    return {
        value: points,
        color: '#D50000',
    }
}

var hsbet_chart = false;

function hsbet_set_data(win_points, loss_points) {
    if (hsbet_chart !== false) {
        hsbet_chart.segments[0].value = win_points;
        hsbet_chart.segments[1].value = loss_points;
        hsbet_chart.update();
    }
}

function hsbet_update_data({win: win_points, loss: loss_points}) {
    if (hsbet_chart !== false) {
        hsbet_chart.segments[0].value += win_points;
        hsbet_chart.segments[1].value += loss_points;
        hsbet_chart.update();
    }
}

function create_graph(win, loss) {
    var ctx = $('#hsbet .chart').get(0).getContext('2d');
    if (win == 0) {
        win = 1;
    }
    if (loss == 0) {
        loss = 1;
    }
    var data = [
        create_object_for_win(win),
        create_object_for_loss(loss),
    ];
    var options = {
        animationSteps: 100,
        animationEasing: 'easeInOutQuart',
        segmentShowStroke: false,
    };
    if (hsbet_chart === false || true) {
        hsbet_chart = new Chart(ctx).Pie(data, options);
    } else {
        hsbet_set_data(win, loss);
    }
}

/* interval for ticking down the hsbet timer */
var tick_down = false;
var stop_hsbet = false;
var stop_hsbet_2 = false;

function hsbet_new_game({time_left, win, loss}) {
    console.log(time_left);
    var hsbet_el = $('#hsbet');

    if (tick_down !== false) {
        clearInterval(tick_down);
        clearTimeout(stop_hsbet);
        clearTimeout(stop_hsbet_2);
    }

    time_left -= 10;

    if (time_left <= 0) {
        return;
    }

    var time_left_el = hsbet_el.find('.time_left');
    console.log(time_left_el);
    console.log(time_left_el.text());
    time_left_el.text(time_left);
    console.log(time_left);
    hsbet_el.find('.left').css({'visibility': 'visible', 'opacity': 1});

    hsbet_el.hide();
    tick_down = setInterval(function () {
        console.log('HI');
        var old_val = parseInt(time_left_el.text());
        time_left_el.text(old_val - 1);
    }, 1000);
    stop_hsbet = setTimeout(function () {
        clearInterval(tick_down);
        hsbet_el.find('.left').fadeTo(1000, 0, function () {
            hsbet_el.find('.left').css('visibility', 'hidden');
            //hsbet_chart.update();
        });
        stop_hsbet_2 = setTimeout(function () {
            hsbet_el.fadeOut(1000);
        }, 10000);
    }, time_left * 1000);
    if (hsbet_chart !== false) {
        hsbet_chart.clear();
    }
    hsbet_el.find('.left').show();
    hsbet_el.fadeIn(1000, function () {
        create_graph(win, loss);
        console.log('XD');
    });
}

function play_sound({link, volume}) {
    let player = new Howl({
        src: [link],
        volume: volume * 0.01,  // the given volume is between 0 and 100
        onend: () => console.log('Playsound audio finished playing'),
        onloaderror: e => console.warn('audio load error', e),
        onplayerror: e => console.warn('audio play error', e)
    });

    player.play();
}

function handleWebsocketData(json_data) {
    if (json_data['event'] === undefined) {
        return;
    }

    let data = json_data.data;
    switch (json_data['event']) {
        case 'new_box':
            add_random_box(data);
            break;
        case 'new_emotes':
            add_emotes(data);
            break;
        case 'notification':
            add_notification(data);
            break;
        case 'timeout':
            add_notification('' + data.user + ' timed out ' + data.victim + ' EleGiggle');
            setTimeout(function () {
                // TODO idk kev maybe this will just stay removed with new playsounds system
                //play_sound('slap');
            }, 100);
            break;
        case 'play_sound':
            play_sound(data);
            break;
        case 'emote_combo':
            refresh_emote_combo(data);
            break;
        case 'hsbet_new_game':
            hsbet_new_game(data);
            break;
        case 'hsbet_update_data':
            hsbet_update_data(data);
            break;
        case 'show_custom_image':
            show_custom_image(data);
            break;
        case 'refresh':
        case 'reload':
            location.reload(true);
            break;
    }

}

let socket = null;

function connect_to_ws() {
    if (socket != null) {
        return;
    }

    console.log('Connecting to websocket....');
    socket = new WebSocket(ws_host);
    socket.binaryType = "arraybuffer";
    socket.onopen = function () {
        console.log('WebSocket Connected!');
    };
    socket.onerror = function (event) {
        console.error("WebSocket error observed:", event);
    };
    socket.onmessage = function (e) {
        if (typeof e.data != "string") {
            return;
        }

        let json_data = JSON.parse(e.data);
        console.log("Received data:", json_data);
        handleWebsocketData(json_data);
    };
    socket.onclose = function (e) {
        console.log(`WebSocket closed ${e.wasClean ? '' : 'un'}cleanly with reason ${e.code}: ${e.reason}`);
        socket = null;
        setTimeout(connect_to_ws, 2500);
    }

}
<commit_msg>Remove code duplicate + FFZ emotes now use HTTPS to load<commit_after>if (!String.prototype.format) {
    String.prototype.format = function () {
        var args = arguments;
        return this.replace(/{(\d+)}/g, function (match, number) {
            return typeof args[number] != 'undefined'
                ? args[number]
                : match
                ;
        });
    };
}

$(document).ready(function () {
    connect_to_ws();
});

function add_random_box({color}) {
    var divsize = 50;
    var posx = (Math.random() * ($(document).width() - divsize)).toFixed();
    var posy = (Math.random() * ($(document).height() - divsize)).toFixed();
    var $newdiv = $("

").css({
        'left': posx + 'px',
        'top': posy + 'px',
        'background-color': color,
        'opacity': 0
    });
    $newdiv.appendTo('body');
    $newdiv.animate({
        opacity: 1
    }, 500);
    setTimeout(function () {
        $newdiv.animate({
            opacity: 0,
        }, 1000);
        setTimeout(function () {
            $newdiv.remove();
        }, 1000);
    }, 5000);
}

function getEmoteUrl(emote) {
    if (emote['bttv_hash'] != null) {
        return `https://cdn.betterttv.net/emote/${emote['bttv_hash']}/3x`;
    } else if (emote['ffz_id'] != null) {
        return `https://cdn.frankerfacez.com/emoticon/${emote['ffz_id']}/4`;
    } else if (emote['twitch_id'] != null) {
        return `https://static-cdn.jtvnw.net/emoticons/v1/${emote['twitch_id']}/3.0`;
    }
}

// opacity = number between 0 and 100
function add_emotes({emotes, opacity, 'persistence_time': persistenceTime, 'scale': emoteScale}) {
    for (let {emote, 'shown_count': shownCount} of emotes) {
        let url = getEmoteUrl(emote);

        if (url == null) {
            console.warn('Failed to find a URL for emote:', emote);
            continue;
        }

        let divsize = 120;
        for (let i = 0; i < shownCount; i++) {
            let posx = (Math.random() * ($(document).width() - divsize)).toFixed();
            let posy = (Math.random() * ($(document).height() - divsize)).toFixed();
            let newdiv = $('').css({
                'left': posx + 'px',
                'top': posy + 'px',
                'opacity': 0,
                'transform': 'scale(' + String(emoteScale / 100) + ')'
            });
            newdiv.appendTo('body');
            newdiv.animate({
                opacity: opacity / 100
            }, 500);
            setTimeout(() => {
                newdiv.animate({
                    opacity: 0,
                }, 1000);
                setTimeout(() => {
                    newdiv.remove();
                }, 1000);
            }, persistenceTime);
        }
    }
}

function show_custom_image(data) {
    var url = data.url;
    var divsize = 120;
    var posx = (Math.random() * ($(document).width() - divsize)).toFixed();
    var posy = (Math.random() * ($(document).height() - divsize)).toFixed();
    var css_data = {
        'left': posx + 'px',
        'top': posy + 'px',
        'opacity': 0
    }
    if (data.width !== undefined) {
        css_data.width = data.width;
    }
    if (data.height !== undefined) {
        css_data.height = data.height;
    }
    if (data.x !== undefined) {
        css_data.left = data.x + 'px';
    }
    if (data.y !== undefined) {
        css_data.top = data.y + 'px';
    }
    var $newdiv = $('').css(css_data);
    $newdiv.appendTo('body');
    $newdiv.animate({
        opacity: 1
    }, 500);
    setTimeout(function () {
        $newdiv.animate({
            opacity: 0,
        }, 1000);
        setTimeout(function () {
            $newdiv.remove();
        }, 1000);
    }, 5000);
}

var message_id = 0;

function add_notification({message}) {
    var new_notification = $('
' + message + '
').prependTo('div.notifications');
    new_notification.textillate({
        autostart: false,
        in: {
            effect: 'bounceInLeft',
            delay: 5,
            delayScale: 1.5,
            sync: false,
            shuffle: false,
            reverse: false,
        },
        out: {
            effect: 'bounceOutLeft',
            sync: true,
            shuffle: false,
            reverse: false,
        },
        type: 'word',
    });
    new_notification.on('inAnimationEnd.tlt', function () {
        setTimeout(function () {
            new_notification.textillate('out');
            new_notification.animate({
                height: 0,
                opacity: 0,
            }, 1000);
        }, 2000);
    });
    new_notification.on('outAnimationEnd.tlt', function () {
        setTimeout(function () {
            new_notification.remove();
        }, 250);
    });
}

var current_emote_code = null;
var close_down_combo = null;

function refresh_combo_count(count) {
    $('#emote_combo span.count').html(count);
    $('#emote_combo span.count').addClass('animated pulsebig');
    $('#emote_combo span.count').on('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
        $(this).removeClass('animated pulsebig');
    });
    $('#emote_combo img').addClass('animated pulsebig');
    $('#emote_combo img').on('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
        $(this).removeClass('animated pulsebig');
    });
}

function refresh_combo_emote(emote) {
    $('#emote_combo img').attr('src', getEmoteUrl(emote));
}

function debug_text(text) {
    //add_notification(text);
}

function refresh_emote_combo({emote, count}) {
    var emote_combo = $('#emote_combo');
    if (emote_combo.length == 0) {
        if ('bttv_hash' in emote && emote['bttv_hash'] !== null) {
            var url = 'https://cdn.betterttv.net/emote/' + emote['bttv_hash'] + '/2x';
        } else {
            var url = 'https://static-cdn.jtvnw.net/emoticons/v1/' + emote['twitch_id'] + '/2.0';
        }
        current_emote_code = emote['code'];
        var message = 'x{0}  combo!'.format(count, url)
        var new_notification = $('
' + message + '
').prependTo('div.notifications');
        new_notification.addClass('animated bounceInLeft');

        new_notification.on('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
            if (new_notification.hasClass('ended')) {
                new_notification.animate({
                    height: 0,
                    opacity: 0,
                }, 500);
                setTimeout(function () {
                    new_notification.remove();
                }, 500);
            }
        });

        clearTimeout(close_down_combo);
        close_down_combo = setTimeout(function () {
            new_notification.addClass('animated bounceOutLeft ended');
        }, 4000);
    } else {
        clearTimeout(close_down_combo);
        close_down_combo = setTimeout(function () {
            emote_combo.addClass('animated bounceOutLeft ended');
        }, 3000);
        refresh_combo_emote(emote);
        refresh_combo_count(count);
    }
}

function create_object_for_win(points) {
    return {
        value: points,
        color: '#64DD17',
    }
}

function create_object_for_loss(points) {
    return {
        value: points,
        color: '#D50000',
    }
}

var hsbet_chart = false;

function hsbet_set_data(win_points, loss_points) {
    if (hsbet_chart !== false) {
        hsbet_chart.segments[0].value = win_points;
        hsbet_chart.segments[1].value = loss_points;
        hsbet_chart.update();
    }
}

function hsbet_update_data({win: win_points, loss: loss_points}) {
    if (hsbet_chart !== false) {
        hsbet_chart.segments[0].value += win_points;
        hsbet_chart.segments[1].value += loss_points;
        hsbet_chart.update();
    }
}

function create_graph(win, loss) {
    var ctx = $('#hsbet .chart').get(0).getContext('2d');
    if (win == 0) {
        win = 1;
    }
    if (loss == 0) {
        loss = 1;
    }
    var data = [
        create_object_for_win(win),
        create_object_for_loss(loss),
    ];
    var options = {
        animationSteps: 100,
        animationEasing: 'easeInOutQuart',
        segmentShowStroke: false,
    };
    if (hsbet_chart === false || true) {
        hsbet_chart = new Chart(ctx).Pie(data, options);
    } else {
        hsbet_set_data(win, loss);
    }
}

/* interval for ticking down the hsbet timer */
var tick_down = false;
var stop_hsbet = false;
var stop_hsbet_2 = false;

function hsbet_new_game({time_left, win, loss}) {
    console.log(time_left);
    var hsbet_el = $('#hsbet');

    if (tick_down !== false) {
        clearInterval(tick_down);
        clearTimeout(stop_hsbet);
        clearTimeout(stop_hsbet_2);
    }

    time_left -= 10;

    if (time_left <= 0) {
        return;
    }

    var time_left_el = hsbet_el.find('.time_left');
    console.log(time_left_el);
    console.log(time_left_el.text());
    time_left_el.text(time_left);
    console.log(time_left);
    hsbet_el.find('.left').css({'visibility': 'visible', 'opacity': 1});

    hsbet_el.hide();
    tick_down = setInterval(function () {
        console.log('HI');
        var old_val = parseInt(time_left_el.text());
        time_left_el.text(old_val - 1);
    }, 1000);
    stop_hsbet = setTimeout(function () {
        clearInterval(tick_down);
        hsbet_el.find('.left').fadeTo(1000, 0, function () {
            hsbet_el.find('.left').css('visibility', 'hidden');
            //hsbet_chart.update();
        });
        stop_hsbet_2 = setTimeout(function () {
            hsbet_el.fadeOut(1000);
        }, 10000);
    }, time_left * 1000);
    if (hsbet_chart !== false) {
        hsbet_chart.clear();
    }
    hsbet_el.find('.left').show();
    hsbet_el.fadeIn(1000, function () {
        create_graph(win, loss);
        console.log('XD');
    });
}

function play_sound({link, volume}) {
    let player = new Howl({
        src: [link],
        volume: volume * 0.01,  // the given volume is between 0 and 100
        onend: () => console.log('Playsound audio finished playing'),
        onloaderror: e => console.warn('audio load error', e),
        onplayerror: e => console.warn('audio play error', e)
    });

    player.play();
}

function handleWebsocketData(json_data) {
    if (json_data['event'] === undefined) {
        return;
    }

    let data = json_data.data;
    switch (json_data['event']) {
        case 'new_box':
            add_random_box(data);
            break;
        case 'new_emotes':
            add_emotes(data);
            break;
        case 'notification':
            add_notification(data);
            break;
        case 'timeout':
            add_notification('' + data.user + ' timed out ' + data.victim + ' EleGiggle');
            setTimeout(function () {
                // TODO idk kev maybe this will just stay removed with new playsounds system
                //play_sound('slap');
            }, 100);
            break;
        case 'play_sound':
            play_sound(data);
            break;
        case 'emote_combo':
            refresh_emote_combo(data);
            break;
        case 'hsbet_new_game':
            hsbet_new_game(data);
            break;
        case 'hsbet_update_data':
            hsbet_update_data(data);
            break;
        case 'show_custom_image':
            show_custom_image(data);
            break;
        case 'refresh':
        case 'reload':
            location.reload(true);
            break;
    }

}

let socket = null;

function connect_to_ws() {
    if (socket != null) {
        return;
    }

    console.log('Connecting to websocket....');
    socket = new WebSocket(ws_host);
    socket.binaryType = "arraybuffer";
    socket.onopen = function () {
        console.log('WebSocket Connected!');
    };
    socket.onerror = function (event) {
        console.error("WebSocket error observed:", event);
    };
    socket.onmessage = function (e) {
        if (typeof e.data != "string") {
            return;
        }

        let json_data = JSON.parse(e.data);
        console.log("Received data:", json_data);
        handleWebsocketData(json_data);
    };
    socket.onclose = function (e) {
        console.log(`WebSocket closed ${e.wasClean ? '' : 'un'}cleanly with reason ${e.code}: ${e.reason}`);
        socket = null;
        setTimeout(connect_to_ws, 2500);
    }

}
<|endoftext|>


<commit_before>'use strict';

(function() {
    var app = angular.module('testjob', ['ui.bootstrap', 'ngResource'])
        .config(function($interpolateProvider, $httpProvider, $resourceProvider){
            $interpolateProvider.startSymbol('[[').endSymbol(']]');
            $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
        });
})();<commit_msg>Config angular to upload files<commit_after>'use strict';

(function() {
    var app = angular.module('testjob', ['ui.bootstrap', 'ngResource'])
        .config(function($interpolateProvider, $httpProvider, $resourceProvider){
            $interpolateProvider.startSymbol('[[').endSymbol(']]');
            $httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
            $httpProvider.defaults.headers.post['Content-Type'] = undefined;
            $httpProvider.defaults.transformRequest = function(data) {
                if (data === undefined)
                    return data;

                var fd = new FormData();
                angular.forEach(data, function(value, key) {
                    if (value instanceof FileList) {
                        if (value.length == 1) {
                            fd.append(key, value[0]);
                        } else {
                            angular.forEach(value, function(file, index) {
                                fd.append(key + '_' + index, file);
                            });
                        }
                    } else {
                        fd.append(key, value);
                    }
                });

                return fd;
            };

    });

    //https://github.com/angular/angular.js/issues/1375#issuecomment-21933012
    app.directive('filesModel', function filesModelDirective(){
        return {
            controller: function($parse, $element, $attrs, $scope){
                var exp = $parse($attrs.filesModel);

                $element.on('change', function(){
                    exp.assign($scope, this.files);
                    $scope.$apply();
                });
            }
        };
    })
})();<|endoftext|>


<commit_before>export default `
06-09-2017 - Added Havoc Demon Hunter support by @Mamtooth.
`;
<commit_msg>Updated Havoc ChangeLogs<commit_after>export default `
06-09-2017 - Added spell suggestions and statistic boxes. (by Mamtooth)
06-09-2017 - Added Havoc Demon Hunter support by @Mamtooth.
`;
<|endoftext|>


<commit_before>var timepicker;
var datepicker;
var init_booking_form = function(){
  datepicker = $(".datepicker").pickadate({
    onSet: function(){
      update_disabled_timeslots();
      update_booking_form();
    },
    min: true
  });

  timepicker = $(".timepicker").pickatime({
    onSet: update_booking_form,
    interval: 60,
    format: "HH:i"
  });

  $("#new-booking-form").on('submit', function(event){
    event.preventDefault();

    var date = $("#new-booking-date").val();
    var time = $("#new-booking-time").val();

    var datetime = date + " " + time;

    data = { datetime_str:  datetime};
    $.post("/students/booking/", data, function(response){
      Materialize.toast(response, 4000);

      update_booking_list();
      update_disabled_timeslots();

      timepicker.pickatime("picker").clear();
      datepicker.pickadate("picker").clear();
    }).fail(function(response){
      Materialize.toast("Sorry, failed! " + response.responseText, 4000);
    });
  });

  update_booking_form();
};

var update_disabled_timeslots = function(){
  var date = $("#new-booking-date").val();
  date = moment(new Date(date)).format("DD.MMMM.YYYY");

  if(date === "Invalid date"){
    return;
  }

  $.getJSON("/students/booking/listall/" + date + "/", function(bookings){
    if(bookings.length > 0){
      var booked_slots = [];
      $.each(bookings, function(index, booking){
        start_time = moment(booking.fields.start_time).format("H");
        booked_slots.push(start_time);
      });

      booked_slots = booked_slots.map(function(str){
        return parseInt(str);
      });

      timepicker.pickatime("picker").set("disable", false);
      timepicker.pickatime("picker").set("enable", true);
      timepicker.pickatime("picker").set("disable", booked_slots);
    }
  }).fail(function(){
    console.log("Failed to retrieve json for all bookings for date:" + date);
  });
};

var init_booking_list = function(){
  update_booking_list();
  $("#user-bookings-list").on("click", ".secondary-content", delete_booking);
};

var update_booking_form = function(){
  var date = $("#new-booking-date").val();
  var time = $("#new-booking-time").val();

  $("#submit-new-booking").toggleClass("disabled", !(date && time));
  if(!(date && time)){
    $("#submit-new-booking").attr("disabled");
  }else{
    $("#submit-new-booking").removeAttr("disabled");
  }
};

var update_booking_list = function(){
  $("#user-bookings-list").empty();

  $.getJSON("/students/booking/list/", function(user_bookings){
    if(user_bookings.length === 0){
      help_text = "

You have no upcoming bookings.

";
      $("#user-bookings-list").append(help_text);
    }else{
      $.each(user_bookings, function(index, booking){
        booking_id = booking.pk;
        date = moment(booking.fields.start_time).format("Do MMM YYYY");

        current_time = moment();
        start_time = moment(booking.fields.start_time);
        is_current = start_time.isBefore(current_time)? "current-booking": "";
        start_time = start_time.format("HH:mm");
        end_time = moment(booking.fields.end_time).format("HH:mm");
        booking_info = start_time + " - " + end_time;

        list_item_html = "

" + date + "
" + booking_info + "
delete

";
        $("#user-bookings-list").append(list_item_html);
      });
    }
  }).fail(function(){
    Materialize.toast("Sorry, could not load your bookings", 4000);
  });
};

var delete_booking = function(event){
  event.preventDefault();

  source_btn = $(this);
  booking_id = source_btn.attr("id").match(/\d+/g);
    if(booking_id.length === 0){
    Materialize.toast("Sorry, booking not found", 4000);
    return false;
  }else{
    booking_id = booking_id[0];
  }

  // POST to delete the specified booking
  $.post("/students/booking/" + booking_id + "/delete/", function(response){
    Materialize.toast("Successfully deleted booking", 4000);

    update_booking_list();
  }).fail(function(response){
    Materialize.toast("Could not delete booking", 4000);
  });
};

$(function(){
  init_booking_form();
  init_booking_list();
});
<commit_msg>Don't show the delete icon for the current booking. (you can't delete the current booking)<commit_after>var timepicker;
var datepicker;
var init_booking_form = function(){
  datepicker = $(".datepicker").pickadate({
    onSet: function(){
      update_disabled_timeslots();
      update_booking_form();
    },
    min: true
  });

  timepicker = $(".timepicker").pickatime({
    onSet: update_booking_form,
    interval: 60,
    format: "HH:i"
  });

  $("#new-booking-form").on('submit', function(event){
    event.preventDefault();

    var date = $("#new-booking-date").val();
    var time = $("#new-booking-time").val();

    var datetime = date + " " + time;

    data = { datetime_str:  datetime};
    $.post("/students/booking/", data, function(response){
      Materialize.toast(response, 4000);

      update_booking_list();
      update_disabled_timeslots();

      timepicker.pickatime("picker").clear();
      datepicker.pickadate("picker").clear();
    }).fail(function(response){
      Materialize.toast("Sorry, failed! " + response.responseText, 4000);
    });
  });

  update_booking_form();
};

var update_disabled_timeslots = function(){
  var date = $("#new-booking-date").val();
  date = moment(new Date(date)).format("DD.MMMM.YYYY");

  if(date === "Invalid date"){
    return;
  }

  $.getJSON("/students/booking/listall/" + date + "/", function(bookings){
    if(bookings.length > 0){
      var booked_slots = [];
      $.each(bookings, function(index, booking){
        start_time = moment(booking.fields.start_time).format("H");
        booked_slots.push(start_time);
      });

      booked_slots = booked_slots.map(function(str){
        return parseInt(str);
      });

      timepicker.pickatime("picker").set("disable", false);
      timepicker.pickatime("picker").set("enable", true);
      timepicker.pickatime("picker").set("disable", booked_slots);
    }
  }).fail(function(){
    console.log("Failed to retrieve json for all bookings for date:" + date);
  });
};

var init_booking_list = function(){
  update_booking_list();
  $("#user-bookings-list").on("click", ".secondary-content", delete_booking);
};

var update_booking_form = function(){
  var date = $("#new-booking-date").val();
  var time = $("#new-booking-time").val();

  $("#submit-new-booking").toggleClass("disabled", !(date && time));
  if(!(date && time)){
    $("#submit-new-booking").attr("disabled");
  }else{
    $("#submit-new-booking").removeAttr("disabled");
  }
};

var update_booking_list = function(){
  $("#user-bookings-list").empty();

  $.getJSON("/students/booking/list/", function(user_bookings){
    if(user_bookings.length === 0){
      help_text = "

You have no upcoming bookings.

";
      $("#user-bookings-list").append(help_text);
    }else{
      $.each(user_bookings, function(index, booking){
        booking_id = booking.pk;
        date = moment(booking.fields.start_time).format("Do MMM YYYY");

        current_time = moment();
        start_time = moment(booking.fields.start_time);
        is_current = start_time.isBefore(current_time)? "current-booking": "";
        delete_icon = start_time.isBefore(current_time)? "": "delete";

        start_time = start_time.format("HH:mm");
        end_time = moment(booking.fields.end_time).format("HH:mm");
        booking_info = start_time + " - " + end_time;

        list_item_html = "

" + date + "
" + booking_info + "
" + delete_icon + "

";
        $("#user-bookings-list").append(list_item_html);
      });
    }
  }).fail(function(){
    Materialize.toast("Sorry, could not load your bookings", 4000);
  });
};

var delete_booking = function(event){
  event.preventDefault();

  source_btn = $(this);
  booking_id = source_btn.attr("id").match(/\d+/g);
    if(booking_id.length === 0){
    Materialize.toast("Sorry, booking not found", 4000);
    return false;
  }else{
    booking_id = booking_id[0];
  }

  // POST to delete the specified booking
  $.post("/students/booking/" + booking_id + "/delete/", function(response){
    Materialize.toast("Successfully deleted booking", 4000);

    update_booking_list();
  }).fail(function(response){
    Materialize.toast("Could not delete booking", 4000);
  });
};

$(function(){
  init_booking_form();
  init_booking_list();
});
<|endoftext|>


<commit_before>"use strict";

var Command = require('./command');

var BusinessService = function(dataProxy) {
  //if (!dataProxy instanceof DataProxy) throw 'dataproxy must ..';
  if (this instanceof BusinessService) {
    this.dataProxy = dataProxy;
  } else {
    return new BusinessService(dataProxy);
  }
};

BusinessService.prototype = {

  constructor: BusinessService,

  getAllCommand: function() {
    var service = this;
    var context = {};
    return new Command({
      onInitialization: function(done) {
        service.__onGetAllCommandInitialization(context, done);
      },
      getRules: function() {
        return service.__getRulesForGetAll(context);
      },
      onValidationSuccess: function(done) {
        return service.__getAll(context, done);
      }
    });
  },

  getByIdCommand: function(id) {
    var service = this;
    var context = {};
    return new Command({
      onInitialization: function(done) {
        service.__onGetByIdCommandInitialization(id, context, done);
      },
      getRules: function() {
        return service.__getRulesForGetById(id, context);
      },
      onValidationSuccess: function(done) {
        return service.__getById(id, context, done);
      }
    });
  },

  insertCommand: function(data) {
    var service = this;
    var context = {};
    return new Command({
      onInitialization: function(done) {
        service.__onInsertCommandInitialization(data, context, done);
      },
      getRules: function() {
        return service.__getRulesForInsert(data, context);
      },
      onValidationSuccess: function(done) {
        return service.__insert(data, context, done);
      }
    });
  },

  updateCommand: function(data) {
    var service = this;
    var context = {};
    return new Command({
      onInitialization: function(done) {
        service.__onUpdateCommandInitialization(data, context, done);
      },
      getRules: function() {
        return service.__getRulesForUpdate(data, context);
      },
      onValidationSuccess: function(done) {
        return service.__update(data, context, done);
      }
    });
  },

  deleteCommand: function(id) {
    var service = this;
    var context = {};
    return new Command({
      onInitialization: function(done) {
        service.__onDeleteCommandInitialization(id, context, done);
      },
      getRules: function() {
        return service.__getRulesForDelete(id, context);
      },
      onValidationSuccess: function(done) {
        return service.__delete(id, context, done);
      }
    });
  },

  __getAll: function(context, done) {
    return this.dataProxy.getAll(data, done);
  },

  __getRulesForGetAll: function(context) {
    return [];
  },

  __onGetAllCommandInitialization: function(context, done) {
    done();
  },

  __getById: function(id, context, done) {
    return this.dataProxy.getById(id, done);
  },

  __getRulesForGetById: function(id, context) {
    return [];
  },

  __onGetByIdCommandInitialization: function(id, context, done) {
    done();
  },

  __insert: function(data, context, done) {
    return this.dataProxy.insert(data, done);
  },

  __getRulesForInsert: function(data, context) {
    return [];
  },

  __onInsertCommandInitialization: function(data, context, done) {
    done();
  },

  __update(data, context, done) {
    return this.dataProxy.update(data, done);
  },

  __getRulesForUpdate: function(data, context) {
    return [];
  },

  __onUpdateCommandInitialization: function(data, context, done) {
    done();
  },

  __delete(id, context, done) {
    return this.dataProxy.delete(id, done);
  },

  __getRulesForDelete: function(id, context) {
    return [];
  },

  __onDeleteCommandInitialization: function(id, context, done) {
    done();
  }
};

module.exports = BusinessService;
<commit_msg>remove returning of data proxy invocations<commit_after>"use strict";

var Command = require('./command');

var BusinessService = function(dataProxy) {
  //if (!dataProxy instanceof DataProxy) throw 'dataproxy must ..';
  if (this instanceof BusinessService) {
    this.dataProxy = dataProxy;
  } else {
    return new BusinessService(dataProxy);
  }
};

BusinessService.prototype = {

  constructor: BusinessService,

  getAllCommand: function() {
    var service = this;
    var context = {};
    return new Command({
      onInitialization: function(done) {
        service.__onGetAllCommandInitialization(context, done);
      },
      getRules: function() {
        return service.__getRulesForGetAll(context);
      },
      onValidationSuccess: function(done) {
        return service.__getAll(context, done);
      }
    });
  },

  getByIdCommand: function(id) {
    var service = this;
    var context = {};
    return new Command({
      onInitialization: function(done) {
        service.__onGetByIdCommandInitialization(id, context, done);
      },
      getRules: function() {
        return service.__getRulesForGetById(id, context);
      },
      onValidationSuccess: function(done) {
        return service.__getById(id, context, done);
      }
    });
  },

  insertCommand: function(data) {
    var service = this;
    var context = {};
    return new Command({
      onInitialization: function(done) {
        service.__onInsertCommandInitialization(data, context, done);
      },
      getRules: function() {
        return service.__getRulesForInsert(data, context);
      },
      onValidationSuccess: function(done) {
        return service.__insert(data, context, done);
      }
    });
  },

  updateCommand: function(data) {
    var service = this;
    var context = {};
    return new Command({
      onInitialization: function(done) {
        service.__onUpdateCommandInitialization(data, context, done);
      },
      getRules: function() {
        return service.__getRulesForUpdate(data, context);
      },
      onValidationSuccess: function(done) {
        return service.__update(data, context, done);
      }
    });
  },

  deleteCommand: function(id) {
    var service = this;
    var context = {};
    return new Command({
      onInitialization: function(done) {
        service.__onDeleteCommandInitialization(id, context, done);
      },
      getRules: function() {
        return service.__getRulesForDelete(id, context);
      },
      onValidationSuccess: function(done) {
        return service.__delete(id, context, done);
      }
    });
  },

  __getAll: function(context, done) {
    this.dataProxy.getAll(done);
  },

  __getRulesForGetAll: function(context) {
    return [];
  },

  __onGetAllCommandInitialization: function(context, done) {
    done();
  },

  __getById: function(id, context, done) {
    this.dataProxy.getById(id, done);
  },

  __getRulesForGetById: function(id, context) {
    return [];
  },

  __onGetByIdCommandInitialization: function(id, context, done) {
    done();
  },

  __insert: function(data, context, done) {
    this.dataProxy.insert(data, done);
  },

  __getRulesForInsert: function(data, context) {
    return [];
  },

  __onInsertCommandInitialization: function(data, context, done) {
    done();
  },

  __update(data, context, done) {
    this.dataProxy.update(data, done);
  },

  __getRulesForUpdate: function(data, context) {
    return [];
  },

  __onUpdateCommandInitialization: function(data, context, done) {
    done();
  },

  __delete(id, context, done) {
    this.dataProxy.delete(id, done);
  },

  __getRulesForDelete: function(id, context) {
    return [];
  },

  __onDeleteCommandInitialization: function(id, context, done) {
    done();
  }
};

module.exports = BusinessService;
<|endoftext|>


<commit_before>export const GREY_EDGES_DASHED_MENU = "#grey-edges-dashed-menu";
export const GREY_EDGES_DASHED_SIDEBAR = "#dashedGrayLineButton";

export const UNWEIGHTED_DEMO_ID   = "#unweighted";
export const UNWEIGHTED_DEMO_PATH = "demo/unweighted";
export const UNWEIGHTED_DEMO_NAME = "Demo #1: Unweighted GRN (21 genes, 50 edges)";
export const WEIGHTED_DEMO_ID     = "#weighted";
export const WEIGHTED_DEMO_PATH   = "demo/weighted";
export const WEIGHTED_DEMO_NAME   = "Demo #2: Weighted GRN (21 genes, 50 edges, Dahlquist Lab unpublished data)";
export const SCHADE_INPUT_ID      = "#schadeInput";
export const SCHADE_INPUT_PATH    = "demo/schadeInput";
export const SCHADE_INPUT_NAME    = "Demo #3: Unweighted GRN (21 genes, 31 edges)";
export const SCHADE_OUTPUT_ID     = "#schadeOutput";
export const SCHADE_OUTPUT_PATH   = "demo/schadeOutput";
export const SCHADE_OUTPUT_NAME   = "Demo #4: Weighted GRN (21 genes, 31 edges, Schade et al. 2004 data)";

export const EXPORT_TO_PNG           = "#exportAsPng";
export const EXPORT_TO_SVG           = "#exportAsSvg";

export const DEMO_INFORMATION = [
    [ WEIGHTED_DEMO_ID,   WEIGHTED_DEMO_PATH,   WEIGHTED_DEMO_NAME   ],
    [ UNWEIGHTED_DEMO_ID, UNWEIGHTED_DEMO_PATH, UNWEIGHTED_DEMO_NAME ],
    [ SCHADE_INPUT_ID,    SCHADE_INPUT_PATH,    SCHADE_INPUT_NAME    ],
    [ SCHADE_OUTPUT_ID,   SCHADE_OUTPUT_PATH,   SCHADE_OUTPUT_NAME   ]
];

export const MIN_EDGE_WEIGHT_NORMALIZATION      = 0.0001;
export const MAX_EDGE_WEIGHT_NORMALIZATION      = 1000;

export const DEFAULT_ZOOM_VALUE                 = 100;

export const GREY_EDGE_THRESHOLD_MENU           = "#gray-edge-threshold-menu";
export const GREY_EDGE_THRESHOLD_SLIDER_SIDEBAR = "#grayThresholdInput";
export const GREY_EDGE_THRESHOLD_TEXT_SIDEBAR   = "#grayThresholdValue";

export const SET_NORMALIZATION_MENU             = "#edge-weight-normalization-factor-menu";
export const SET_NORMALIZATION_SIDEBAR          = "#normalization-button";
export const SET_NORMALIZATION_SIDEBAR_VALUE    = "#normalization-max";
export const RESET_NORMALIZATION_MENU           = "#reset-normalization-factor-menu";
export const RESET_NORMALIZATION_SIDEBAR        = "#resetNormalizationButton";

export const WEIGHTS_SHOW_MOUSE_OVER_MENU       = "#weightsMouseOverMenu";
export const WEIGHTS_SHOW_ALWAYS_MENU           = "#weightsAlwaysMenu";
export const WEIGHTS_HIDE_MENU                  = "#weightsNeverMenu";
export const WEIGHTS_SHOW_MOUSE_OVER_SIDE       = "#weightsMouseOverSide";
export const WEIGHTS_SHOW_ALWAYS_SIDE           = "#weightsAlwaysSide";
export const WEIGHTS_HIDE_SIDE                  = "#weightsNeverSide";
export const WEIGHTS_SHOW_MOUSE_OVER_CLASS      = ".weightsMouseOver";
export const WEIGHTS_SHOW_ALWAYS_CLASS          = ".weightsAlways";
export const WEIGHTS_HIDE_CLASS                 = ".weightsNever";

export const SHOW_WEIGHTS_MOUSEOVER             = "showWeightsMouseover";
export const SHOW_ALL_WEIGHTS                   = "showAllWeights";
export const HIDE_ALL_WEIGHTS                   = "hideAllWeights";

export const COLOR_EDGES                        = "#colorEdges";
export const BLACK_EDGES                        = "#blackEdges";
export const ACTIVE_COLOR_OPTION                = "active";

export const GRAVITY_LENGTH_WITHOUT_ZERO = 3;
export const LOCK_SLIDERS_CLASS          = ".lockSliders";
export const LOCK_SLIDERS_BUTTON         = "#lockSlidersButton";
export const LOCK_SLIDERS_MENU           = "#lockSlidersMenu";
export const RESET_SLIDERS_CLASS         = ".resetSliders";
export const RESET_SLIDERS_SIDEBAR       = "#resetSlidersButton";
export const RESET_SLIDERS_MENU          = "#resetSlidersMenu";
export const UNDO_SLIDERS_RESET_CLASS    = ".undoSliderReset";
export const UNDO_SLIDERS_RESET_ID       = "#undoReset";
export const UNDO_SLIDERS_RESET_MENU     = "#undoResetMenu";
export const UNDO_SLIDERS_RESET_SIDEBAR  = "#undoResetButton";

export const LINK_DIST_CLASS            = "#link-distance";
export const LINK_DIST_SLIDER_SIDEBAR   = "#linkDistInput";
export const LINK_DIST_VALUE            = "#linkDistVal";
export const LINK_DIST_MENU             = "#link-distance-menu";
export const LINK_DIST_DEFAULT_VALUE    = 500;
export const CHARGE_CLASS               = "#charge";
export const CHARGE_SLIDER_SIDEBAR      = "#chargeInput";
export const CHARGE_VALUE               = "#chargeVal";
export const CHARGE_MENU                = "#charge-menu";
export const CHARGE_DEFAULT_VALUE       = -50;

export const GRID_LAYOUT                = "GRID_LAYOUT";
export const FORCE_GRAPH                = "FORCE_GRAPH";
export const GRID_LAYOUT_BUTTON         = "#gridLayoutButton";
export const FORCE_GRAPH_CLASS          = "#forceGraph";
export const GRID_LAYOUT_CLASS          = "#gridLayout";

export const MINIMUM_MAX_LOG_FOLD_CHANGE                = 0;
export const MAXIMUM_MAX_LOG_FOLD_CHANGE                = 100;
export const DEFAULT_MAX_LOG_FOLD_CHANGE                = 3;
export const MAX_NUM_CHARACTERS_DROPDOWN                = 24;
export const NODE_COLORING_MENU                         = ".node-coloring";
export const NODE_COLORING_MENU_CLASS                   = ".node-coloring-menu";
export const NODE_COLORING_TOGGLE_SIDEBAR               = "#nodeColoringToggle";
export const AVG_REPLICATE_VALS_BOTTOM_SIDEBAR          = "#averageDataBottom";
export const AVG_REPLICATE_VALS_TOP_SIDEBAR             = "#averageDataTop";
export const AVG_REPLICATE_VALS_TOP_MENU                = "#averageDataTopMenu";
export const AVG_REPLICATE_VALS_BOTTOM_MENU             = "#averageDataBottomMenu";
export const NODE_COLORING_TOGGLE_MENU                  = "#node-coloring-toggle-menu";
export const NODE_COLORING_TOGGLE_CLASS                 = ".nodeColoringToggle";
export const LOG_FOLD_CHANGE_MAX_VALUE_CLASS            = ".logFoldChangeMaxValue";
export const LOG_FOLD_CHANGE_MAX_VALUE_SIDEBAR_INPUT    = "#log-fold-change-max-value-sidebar";
export const LOG_FOLD_CHANGE_MAX_VALUE_SIDEBAR_BUTTON   = "#log-fold-change-button";
export const LOG_FOLD_CHANGE_MAX_VALUE_MENU             = "#log-fold-change-max-value-menu";
export const ENDS_IN_EXPRESSION_REGEXP                  = /expression$/;
export const TOP_DATASET_SELECTION_MENU                 = "#topDatasetDropdownMenu";
export const TOP_DATASET_SELECTION_SIDEBAR              = "#dataset-top";
export const BOTTOM_DATASET_SELECTION_MENU              = "#bottomDatasetDropdownMenu";
export const BOTTOM_DATASET_SELECTION_SIDEBAR           = "#dataset-bottom";

export const ZOOM_CONTROL = ".zoom";
export const ZOOM_DISPLAY_MAXIMUM_SELECTOR = ".maximum-zoom-display";
export const ZOOM_DISPLAY_MAXIMUM_VALUE = 200;
export const ZOOM_DISPLAY_MINIMUM_SELECTOR = ".minimum-zoom-display";
export const ZOOM_DISPLAY_MINIMUM_VALUE = 25;
export const ZOOM_SLIDER = "#zoomSlider";
export const ZOOM_INPUT = "#zoomInput";
export const ZOOM_PERCENT = "#zoomPercent";

export const VIEWPORT_FIT = "containerFit";
<commit_msg>update spacing<commit_after>export const GREY_EDGES_DASHED_MENU = "#grey-edges-dashed-menu";
export const GREY_EDGES_DASHED_SIDEBAR = "#dashedGrayLineButton";

export const UNWEIGHTED_DEMO_ID   = "#unweighted";
export const UNWEIGHTED_DEMO_PATH = "demo/unweighted";
export const UNWEIGHTED_DEMO_NAME = "Demo #1: Unweighted GRN (21 genes, 50 edges)";
export const WEIGHTED_DEMO_ID     = "#weighted";
export const WEIGHTED_DEMO_PATH   = "demo/weighted";
export const WEIGHTED_DEMO_NAME   = "Demo #2: Weighted GRN (21 genes, 50 edges, Dahlquist Lab unpublished data)";
export const SCHADE_INPUT_ID      = "#schadeInput";
export const SCHADE_INPUT_PATH    = "demo/schadeInput";
export const SCHADE_INPUT_NAME    = "Demo #3: Unweighted GRN (21 genes, 31 edges)";
export const SCHADE_OUTPUT_ID     = "#schadeOutput";
export const SCHADE_OUTPUT_PATH   = "demo/schadeOutput";
export const SCHADE_OUTPUT_NAME   = "Demo #4: Weighted GRN (21 genes, 31 edges, Schade et al. 2004 data)";

export const EXPORT_TO_PNG           = "#exportAsPng";
export const EXPORT_TO_SVG           = "#exportAsSvg";

export const DEMO_INFORMATION = [
    [ WEIGHTED_DEMO_ID,   WEIGHTED_DEMO_PATH,   WEIGHTED_DEMO_NAME   ],
    [ UNWEIGHTED_DEMO_ID, UNWEIGHTED_DEMO_PATH, UNWEIGHTED_DEMO_NAME ],
    [ SCHADE_INPUT_ID,    SCHADE_INPUT_PATH,    SCHADE_INPUT_NAME    ],
    [ SCHADE_OUTPUT_ID,   SCHADE_OUTPUT_PATH,   SCHADE_OUTPUT_NAME   ]
];

export const MIN_EDGE_WEIGHT_NORMALIZATION      = 0.0001;
export const MAX_EDGE_WEIGHT_NORMALIZATION      = 1000;

export const DEFAULT_ZOOM_VALUE                 = 100;

export const GREY_EDGE_THRESHOLD_MENU           = "#gray-edge-threshold-menu";
export const GREY_EDGE_THRESHOLD_SLIDER_SIDEBAR = "#grayThresholdInput";
export const GREY_EDGE_THRESHOLD_TEXT_SIDEBAR   = "#grayThresholdValue";

export const SET_NORMALIZATION_MENU             = "#edge-weight-normalization-factor-menu";
export const SET_NORMALIZATION_SIDEBAR          = "#normalization-button";
export const SET_NORMALIZATION_SIDEBAR_VALUE    = "#normalization-max";
export const RESET_NORMALIZATION_MENU           = "#reset-normalization-factor-menu";
export const RESET_NORMALIZATION_SIDEBAR        = "#resetNormalizationButton";

export const WEIGHTS_SHOW_MOUSE_OVER_MENU       = "#weightsMouseOverMenu";
export const WEIGHTS_SHOW_ALWAYS_MENU           = "#weightsAlwaysMenu";
export const WEIGHTS_HIDE_MENU                  = "#weightsNeverMenu";
export const WEIGHTS_SHOW_MOUSE_OVER_SIDE       = "#weightsMouseOverSide";
export const WEIGHTS_SHOW_ALWAYS_SIDE           = "#weightsAlwaysSide";
export const WEIGHTS_HIDE_SIDE                  = "#weightsNeverSide";
export const WEIGHTS_SHOW_MOUSE_OVER_CLASS      = ".weightsMouseOver";
export const WEIGHTS_SHOW_ALWAYS_CLASS          = ".weightsAlways";
export const WEIGHTS_HIDE_CLASS                 = ".weightsNever";

export const SHOW_WEIGHTS_MOUSEOVER             = "showWeightsMouseover";
export const SHOW_ALL_WEIGHTS                   = "showAllWeights";
export const HIDE_ALL_WEIGHTS                   = "hideAllWeights";

export const COLOR_EDGES                        = "#colorEdges";
export const BLACK_EDGES                        = "#blackEdges";
export const ACTIVE_COLOR_OPTION                = "active";

export const GRAVITY_LENGTH_WITHOUT_ZERO = 3;
export const LOCK_SLIDERS_CLASS          = ".lockSliders";
export const LOCK_SLIDERS_BUTTON         = "#lockSlidersButton";
export const LOCK_SLIDERS_MENU           = "#lockSlidersMenu";
export const RESET_SLIDERS_CLASS         = ".resetSliders";
export const RESET_SLIDERS_SIDEBAR       = "#resetSlidersButton";
export const RESET_SLIDERS_MENU          = "#resetSlidersMenu";
export const UNDO_SLIDERS_RESET_CLASS    = ".undoSliderReset";
export const UNDO_SLIDERS_RESET_ID       = "#undoReset";
export const UNDO_SLIDERS_RESET_MENU     = "#undoResetMenu";
export const UNDO_SLIDERS_RESET_SIDEBAR  = "#undoResetButton";

export const LINK_DIST_CLASS            = "#link-distance";
export const LINK_DIST_SLIDER_SIDEBAR   = "#linkDistInput";
export const LINK_DIST_VALUE            = "#linkDistVal";
export const LINK_DIST_MENU             = "#link-distance-menu";
export const LINK_DIST_DEFAULT_VALUE    = 500;
export const CHARGE_CLASS               = "#charge";
export const CHARGE_SLIDER_SIDEBAR      = "#chargeInput";
export const CHARGE_VALUE               = "#chargeVal";
export const CHARGE_MENU                = "#charge-menu";
export const CHARGE_DEFAULT_VALUE       = -50;

export const GRID_LAYOUT                = "GRID_LAYOUT";
export const FORCE_GRAPH                = "FORCE_GRAPH";
export const GRID_LAYOUT_BUTTON         = "#gridLayoutButton";
export const FORCE_GRAPH_CLASS          = "#forceGraph";
export const GRID_LAYOUT_CLASS          = "#gridLayout";

export const MINIMUM_MAX_LOG_FOLD_CHANGE                = 0;
export const MAXIMUM_MAX_LOG_FOLD_CHANGE                = 100;
export const DEFAULT_MAX_LOG_FOLD_CHANGE                = 3;
export const MAX_NUM_CHARACTERS_DROPDOWN                = 24;
export const NODE_COLORING_MENU                         = ".node-coloring";
export const NODE_COLORING_MENU_CLASS                   = ".node-coloring-menu";
export const NODE_COLORING_TOGGLE_SIDEBAR               = "#nodeColoringToggle";
export const AVG_REPLICATE_VALS_BOTTOM_SIDEBAR          = "#averageDataBottom";
export const AVG_REPLICATE_VALS_TOP_SIDEBAR             = "#averageDataTop";
export const AVG_REPLICATE_VALS_TOP_MENU                = "#averageDataTopMenu";
export const AVG_REPLICATE_VALS_BOTTOM_MENU             = "#averageDataBottomMenu";
export const NODE_COLORING_TOGGLE_MENU                  = "#node-coloring-toggle-menu";
export const NODE_COLORING_TOGGLE_CLASS                 = ".nodeColoringToggle";
export const LOG_FOLD_CHANGE_MAX_VALUE_CLASS            = ".logFoldChangeMaxValue";
export const LOG_FOLD_CHANGE_MAX_VALUE_SIDEBAR_INPUT    = "#log-fold-change-max-value-sidebar";
export const LOG_FOLD_CHANGE_MAX_VALUE_SIDEBAR_BUTTON   = "#log-fold-change-button";
export const LOG_FOLD_CHANGE_MAX_VALUE_MENU             = "#log-fold-change-max-value-menu";
export const ENDS_IN_EXPRESSION_REGEXP                  = /expression$/;
export const TOP_DATASET_SELECTION_MENU                 = "#topDatasetDropdownMenu";
export const TOP_DATASET_SELECTION_SIDEBAR              = "#dataset-top";
export const BOTTOM_DATASET_SELECTION_MENU              = "#bottomDatasetDropdownMenu";
export const BOTTOM_DATASET_SELECTION_SIDEBAR           = "#dataset-bottom";

export const ZOOM_CONTROL                               = ".zoom";
export const ZOOM_DISPLAY_MAXIMUM_SELECTOR              = ".maximum-zoom-display";
export const ZOOM_DISPLAY_MAXIMUM_VALUE                 = 200;
export const ZOOM_DISPLAY_MINIMUM_SELECTOR              = ".minimum-zoom-display";
export const ZOOM_DISPLAY_MINIMUM_VALUE                 = 25;
export const ZOOM_SLIDER                                = "#zoomSlider";
export const ZOOM_INPUT                                 = "#zoomInput";
export const ZOOM_PERCENT                               = "#zoomPercent";
export const VIEWPORT_FIT                               = "containerFit";
<|endoftext|>


<commit_before>angular
  .module('crowdsource', [
    // third party modules
    'angular-loading-bar',
    'ui.bootstrap',
    'ngAnimate',
    'ngSanitize',
    'mgcrea.ngStrap',
    // local modules
    'crowdsource.config',
    'crowdsource.routes',
    'crowdsource.authentication',
    'crowdsource.layout',
    'crowdsource.home',
    'crowdsource.ranking',
  ]);

angular
  .module('crowdsource')
  .run(run);

run.$inject = ['$http'];

/**
* @name run
* @desc Update xsrf $http headers to align with Django's defaults
*/
function run($http) {
  $http.defaults.xsrfHeaderName = 'X-CSRFToken';
  $http.defaults.xsrfCookieName = 'csrftoken';
}<commit_msg>Registered task, tasksearch local modules<commit_after>angular
  .module('crowdsource', [
    // third party modules
    'angular-loading-bar',
    'ui.bootstrap',
    'ngAnimate',
    'ngSanitize',
    'mgcrea.ngStrap',
    // local modules
    'crowdsource.config',
    'crowdsource.routes',
    'crowdsource.authentication',
    'crowdsource.layout',
    'crowdsource.home',
    'crowdsource.ranking',
    'crowdsource.tasksearch',
    'crowdsource.tasks',
  ]);

angular
  .module('crowdsource')
  .run(run);

run.$inject = ['$http'];

/**
* @name run
* @desc Update xsrf $http headers to align with Django's defaults
*/
function run($http) {
  $http.defaults.xsrfHeaderName = 'X-CSRFToken';
  $http.defaults.xsrfCookieName = 'csrftoken';
}<|endoftext|>