<commit_before>const TableStorageAdapter = require("./azure/table-storage-adapter").TableStorageAdapter;
const Promise = require('bluebird');
const crypto = require('crypto');
const moment = require('moment');
const azure = require('azure-storage');

/**
 * ClientUser class
 *
 * @class ClientUser
 */
class ClientUser {

    /**
     * Creates an instance of User.
     *
     * @param {string} clientId client identification
     * @param {string} username username
     * @param {string} userkey userkey
     * @param {Boolean} isActive isActive
     * @param {Date} expiry expiry
     *
     * @memberOf ClientUser
     */
    constructor(clientId, username, userkey, isActive, expiry) {
        this._clientId = clientId;
        this._username = username;
        this._userkey = userkey;
        this._isActive = isActive;
        this._expiry = expiry;
    }

    get clientId() {
        return this._clientId;
    }
    set clientId(value) {
        return this._clientId;
    }

    get username() {
        return this._username;
    }
    set username(value) {
        return this._username;
    }

    get expiry() {
        return this._expiry;
    }
    set expiry(value) {
        this._expiry = value;
    }

    get userkey() {
        return this._userkey;
    }
    set userkey(value) {
        this._userkey = value;
    }

    get isActive() {
        return this._isActive;
    }
    set isActive(value) {
        this._isActive = value;
    }

    /**
     * Saves client user;
     *
     *
     * @memberOf ClientUser
     * @returns {Promise} a save promise
     */
    save() {
        const entGen = azure.TableUtilities.entityGenerator;
        const entity = {
            "PartitionKey": entGen.String(this.clientId),
            "RowKey": entGen.String(this.userkey),
            "username": entGen.String(this.username),
            "isActive": entGen.Boolean(this.isActive),
            "expiry": entGen.DateTime(this.expiry)
        };
        const tableService = new TableStorageAdapter().service;
        const promise = new Promise((resolve, reject) => {
            return tableService.insertOrReplaceEntityAsync('clientusers', entity)
            .then((result) => {
                resolve(result);
            })
            .catch(reject);
        });

        return promise;
    }
}

/**
 * Generates a userkey for specific clientid
 *
 * @param {string} clientId client identificatioin
 * @param {string} username users username
 * @param {string} password users password
 *
 * @returns {Promise} a userkey Promise
 */
ClientUser.generateUserkey = function (clientId, username, password) {
    const promise = new Promise((resolve, reject) => {
        try {
            const hmac = crypto.createHmac('sha256', process.env.APP_HMAC_SECRET);
            const hash = hmac.update(`${username}${clientId}++++${password}`).digest('hex');
            resolve(hash);
        }
        catch (error) {
            reject(error);
        }
    });

    return promise;
};

/**
 * Gets client user for clientid, username and password
 *
 * @param {string} clientId client identification
 * @param {string} userkey users key
 * @param {string} username users username
 * @param {string} password users password
 *
 * @returns {Promise} a fetch promise
 */
ClientUser.fetch = function (clientId, userkey, username, password) {
    const tableService = new TableStorageAdapter();
    const promise = new Promise((resolve, reject) => {
        const retrieveEntityResolve = (clientUserEntity) => {
            const clientUser = new ClientUser(clientUserEntity.PartitionKey._, clientUserEntity.username._, clientUserEntity.RowKey._, clientUserEntity.isActive._, moment(clientUserEntity.expiry._));

            return resolve(clientUser);
        };
        const userkeyResolve = (hash) => {
            const tableAdapterResolve = (tableAdapter) => {
                if (!tableAdapter.isSuccessful) {
                    return reject('Azure Table not found and not created');
                }

                return tableService.service.retrieveEntityAsync('clientusers', clientId, hash)
                    .then(retrieveEntityResolve)
                    .catch(reject);
            };

            return tableService.table("clientusers")
                .then(tableAdapterResolve)
                .catch(reject);
        };
        if (userkey) {
            return tableService.service.retrieveEntityAsync('clientusers', clientId, userkey)
                .then(retrieveEntityResolve)
                .catch(reject);
        }

        return ClientUser.generateUserkey(clientId, username, password)
            .then(userkeyResolve)
            .catch(reject);
    });

    return promise;
};
exports.ClientUser = ClientUser;<commit_msg>adding error on no HMAC Secret environment variable<commit_after>const TableStorageAdapter = require("./azure/table-storage-adapter").TableStorageAdapter;
const Promise = require('bluebird');
const crypto = require('crypto');
const moment = require('moment');
const azure = require('azure-storage');

/**
 * ClientUser class
 *
 * @class ClientUser
 */
class ClientUser {

    /**
     * Creates an instance of User.
     *
     * @param {string} clientId client identification
     * @param {string} username username
     * @param {string} userkey userkey
     * @param {Boolean} isActive isActive
     * @param {Date} expiry expiry
     *
     * @memberOf ClientUser
     */
    constructor(clientId, username, userkey, isActive, expiry) {
        this._clientId = clientId;
        this._username = username;
        this._userkey = userkey;
        this._isActive = isActive;
        this._expiry = expiry;
    }

    get clientId() {
        return this._clientId;
    }
    set clientId(value) {
        return this._clientId;
    }

    get username() {
        return this._username;
    }
    set username(value) {
        return this._username;
    }

    get expiry() {
        return this._expiry;
    }
    set expiry(value) {
        this._expiry = value;
    }

    get userkey() {
        return this._userkey;
    }
    set userkey(value) {
        this._userkey = value;
    }

    get isActive() {
        return this._isActive;
    }
    set isActive(value) {
        this._isActive = value;
    }

    /**
     * Saves client user;
     *
     *
     * @memberOf ClientUser
     * @returns {Promise} a save promise
     */
    save() {
        const entGen = azure.TableUtilities.entityGenerator;
        const entity = {
            "PartitionKey": entGen.String(this.clientId),
            "RowKey": entGen.String(this.userkey),
            "username": entGen.String(this.username),
            "isActive": entGen.Boolean(this.isActive),
            "expiry": entGen.DateTime(this.expiry)
        };
        const tableService = new TableStorageAdapter().service;
        const promise = new Promise((resolve, reject) => {
            return tableService.insertOrReplaceEntityAsync('clientusers', entity)
                .then((result) => {
                    resolve(result);
                })
                .catch(reject);
        });

        return promise;
    }
}

/**
 * Generates a userkey for specific clientid
 *
 * @param {string} clientId client identificatioin
 * @param {string} username users username
 * @param {string} password users password
 *
 * @returns {Promise} a userkey Promise
 */
ClientUser.generateUserkey = function (clientId, username, password) {
    if (!process.env.APP_HMAC_SECRET) {
        throw new Error('NO APP HMAC SECRET');
    }
    const promise = new Promise((resolve, reject) => {
        try {
            const hmac = crypto.createHmac('sha256', process.env.APP_HMAC_SECRET);
            const hash = hmac.update(`${username}${clientId}++++${password}`).digest('hex');
            resolve(hash);
        }
        catch (error) {
            reject(error);
        }
    });

    return promise;
};

/**
 * Gets client user for clientid, username and password
 *
 * @param {string} clientId client identification
 * @param {string} userkey users key
 * @param {string} username users username
 * @param {string} password users password
 *
 * @returns {Promise} a fetch promise
 */
ClientUser.fetch = function (clientId, userkey, username, password) {
    const tableService = new TableStorageAdapter();
    const promise = new Promise((resolve, reject) => {
        const retrieveEntityResolve = (clientUserEntity) => {
            const clientUser = new ClientUser(clientUserEntity.PartitionKey._, clientUserEntity.username._, clientUserEntity.RowKey._, clientUserEntity.isActive._, moment(clientUserEntity.expiry._));

            return resolve(clientUser);
        };
        const userkeyResolve = (hash) => {
            const tableAdapterResolve = (tableAdapter) => {
                if (!tableAdapter.isSuccessful) {
                    return reject('Azure Table not found and not created');
                }

                return tableService.service.retrieveEntityAsync('clientusers', clientId, hash)
                    .then(retrieveEntityResolve)
                    .catch(reject);
            };

            return tableService.table("clientusers")
                .then(tableAdapterResolve)
                .catch(reject);
        };
        if (userkey) {
            return tableService.service.retrieveEntityAsync('clientusers', clientId, userkey)
                .then(retrieveEntityResolve)
                .catch(reject);
        }

        return ClientUser.generateUserkey(clientId, username, password)
            .then(userkeyResolve)
            .catch(reject);
    });

    return promise;
};
exports.ClientUser = ClientUser;<|endoftext|>


<commit_before>setTimeout(function() {
        var ogarioVersion = $("#menu-footer").text().split("| ")[1];
        $("#menu-footer").text("");
		$("#menu-footer").prepend('Legend mod ' + 'Temporary Script (BUGGY)' + '' +
            'More FPS');
        document.getElementsByClassName('quick-yt icon-youtube2')[0].setAttribute('id', 'legendid');
        document.getElementsByClassName('quick-yt icon-youtube2')[0].href = "https://www.youtube.com/watch?v=CnIfNSpCf70";
        document.getElementsByClassName('quick-yt icon-youtube2')[0].setAttribute('data-original-title', 'Legend Promo Video');
        $('#legendid').addClass('fa fa-thumbs-o-up').removeClass('quick-yt icon-youtube2');
		$("#more-skins").attr('href', 'https://jimboy3100.github.io/skins/skins.html');

        $(".menu-tabs").children().attr("style", "width: 14.27%;");
        $(".menu-tabs>:nth-child(2)").after('

');
        //  $(".menu-tabs>:nth-child(2)").after('

');
        //	$(".menu-tabs").children().last().before('

');
        $("#main-menu>#profile").after('

' + //
Main Tools

            //											'<button id="IPBtn" type="button" class="btn btn-sm btn-info" data-toggle="button" aria-pressed="false" autocomplete="off" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-right: 0.5%;">Show Connector</button>' +
            '<button id="SHOSHOBtn" type="button" class="btn btn-sm btn-info" data-toggle="button" aria-pressed="false" autocomplete="off" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-right: 0.5%;">' + Premadeletter42 + '</button>' +
            '<button id="XPBtn" type="button" class="btn btn-sm btn-info" data-toggle="button" aria-pressed="false" autocomplete="off" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-left: 0.5%;">' + Premadeletter44 + '</button>' +
            //                                          '<button id="TIMEBtn" type="button" class="btn btn-sm btn-info" data-toggle="button" aria-pressed="false" autocomplete="off" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-right: 0.5%;">' + Premadeletter46 + '</button>' +
            //											'<button id="MAINBBtn" type="button" class="btn btn-sm btn-info" data-toggle="button" aria-pressed="false" autocomplete="off" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-right: 0.5%;">Show Main Banner</button>' +
            //                                          '<button id="MAINBTBtn" type="button" class="btn btn-sm btn-info" data-toggle="button" aria-pressed="false" autocomplete="off" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-left: 0.5%;">Show Main Tools</button>' +
            //											'<button id="MANUIBtn" type="button" class="btn btn-sm btn-info" data-toggle="button" aria-pressed="false" autocomplete="off" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-right: 0.5%;">Show Manual Skins</button>' +
            //											'<button id="RotationBtn" type="button" class="btn btn-sm btn-info" data-toggle="button" aria-pressed="false" autocomplete="off" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-left: 0.5%;">Show Rotation Btns</button>' +
            '<button id="HideAllBthn" type="button" class="btn btn-sm btn-danger" data-toggle="button" aria-pressed="false" autocomplete="off" data-toggle="tooltip" data-placement="right" data-original-title="Temporarily Hide/Show Everything. Function for Youtubers" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-right: 0.5%;">' + Premadeletter49 + '</button>' +
            '<button id="TIMEcalBtn" type="button" class="btn btn-sm btn-warning" data-toggle="button" aria-pressed="false" autocomplete="off" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-left: 0.5%;">' + Premadeletter50 + '</button>' +
            //											'<button id="copyGameNames" type="button" class="btn btn-sm btn-warning" data-toggle="button" aria-pressed="false" autocomplete="off" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-left: 0.5%; display: none;">' + Premadeletter52 + '</button>' +
            '<button id="autoCoinBtn" type="button" class="btn btn-sm btn-warning" data-toggle="button" aria-pressed="false" autocomplete="off" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-right: 0.5%;">' + Premadeletter53 + '</button>' +
            //											'<button id="autoRespawnBtn" type="button" class="btn btn-sm btn-warning" data-toggle="button" aria-pressed="false" autocomplete="off" data-original-title="" title="" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-left: 0.5%;"> Auto respawn</button>' +
            '<button id="troll1Btn" type="button" class="btn btn-sm btn-warning" data-toggle="button" aria-pressed="false" autocomplete="off" data-original-title="" title="" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-left: 0.5%;">' + Premadeletter55 + '</button>' +
            //											'<button id="OpenInfo" type="button" class="btn btn-sm btn-danger" data-toggle="button" aria-pressed="false" autocomplete="off" data-toggle="tooltip" data-placement="right" data-original-title="Mod Information and choose Template" style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-right: 0.5%;">Information</button>' +
            '<button id="OpenuserScripts" type="submit" class="btn btn-primary btn" data-itr="page_play" style="margin-top: 2px; display: block; width: 100%; padding: 4px 0 6px 0;">User Scripts</button>' +

            '
Manual background:  ' +
            '<select id="backgroundPic" class="form-control" onchange="changePicFun();" required="" data-original-title="" title="" style="display:inline; width: 40%" >' +
            '<option value="1" data-itr="">Minimap</option>' +
            '<option value="2" data-itr="">Leaderboard</option>' +
            '<option value="3" data-itr="">Teamboard</option>' +
            '<option value="4" data-itr="">Main Canvas</option>' +
            '<option value="5" data-itr="">Main Banner</option>' +
            '</select>' +

            '<input id="minimapPicture" class="form-control" placeholder="Minimap Image URL" value="" style="margin-top: 2px; display: block;" onblur="setminbgname();" data-toggle="tooltip" data-placement="right" data-original-title="Url of image starting with http://... or https://..." >' +
            '<input id="minbtext" class="form-control" placeholder="Minimap Text" value="" style="margin-top: 2px; display: block;" onblur="setminbtext();">' +
            '<input id="leadbPicture" class="form-control" placeholder="Leaderboard Image URL" value="" style="margin-top: 2px; display: none;" onblur="setleadbgname();" data-toggle="tooltip" data-placement="right" data-original-title="Url of image starting with http://... or https://..." >' +
            '<input id="leadbtext" class="form-control" placeholder="Leaderboard Logo Text" value="" style="margin-top: 2px; display: none; " onblur="setleadbtext();">' +
            '<input id="teambPicture" class="form-control" placeholder="Teamboard Image URL" value="" style="margin-top: 2px; display: none;" onblur="setteambgname();" data-toggle="tooltip" data-placement="right"  data-original-title="Url of image starting with http://... or https://..." >' +
            '<input id="teambtext" class="form-control" placeholder="Teamboard Logo Text" value="" style="margin-top: 2px; display: none; " onblur="setteambtext();">' +
            '<input id="canvasPicture" class="form-control" placeholder="Main Canvas Image URL" value="" style="margin-top: 2px; display: none;" onblur="setcanvasbgname();" data-toggle="tooltip" data-placement="right" data-original-title="Url of image starting with http://... or https://..." >' +
            '<input id="imgUrl" class="form-control" placeholder="Main Banner Icon URL" value="" style="margin-top: 2px; display: none; " onblur="setimgUrl();" data-toggle="tooltip" data-placement="right" data-original-title="Url of image starting with http://... or https://..." >' +
            '<input id="imgHref" class="form-control" placeholder="Main Banner Link URL" value="" style="margin-top: 2px; display: none; " onblur="setimgHref();" data-toggle="tooltip" data-placement="right" data-original-title="Url of link to redirect" >' +
            '
' +

            '
Manual Message Icons&Youtube:  ' +
            '<select id="changephotos" class="form-control" onchange="changePhotoFun();" required="" data-original-title="" title="" style="display:inline; width: 35%" >' +
            '<option value="1" data-itr="">Icon 1</option>' +
            '<option value="2" data-itr="">Icon 2</option>' +
            '<option value="3" data-itr="">Icon 3</option>' +
            '<option value="4" data-itr="">Icon 4</option>' +
            '<option value="5" data-itr="">Icon 5</option>' +
            '<option value="6" data-itr="">Icon 6</option>' +
            '<option value="7" data-itr="">Youtube 1</option>' +
            '<option value="8" data-itr="">Youtube 2</option>' +
            '<option value="9" data-itr="">Youtube 3</option>' +
            '<option value="10" data-itr="">Youtube 4</option>' +
            '<option value="11" data-itr="">Youtube 5</option>' +
            '<option value="12" data-itr="">Youtube 6</option>' +
            '</select>' +

            '<input id="pic1data" class="form-control" placeholder="Message Icon Text 1" value="" style="margin-top: 2px; display: block; " onblur="setpic1data();">' +
            '<input id="pic2data" class="form-control" placeholder="Message Icon Text 2" value="" style="margin-top: 2px; display: none; " onblur="setpic2data();">' +
            '<input id="pic3data" class="form-control" placeholder="Message Icon Text 3" value="" style="margin-top: 2px; display: none; " onblur="setpic3data();">' +
            '<input id="pic4data" class="form-control" placeholder="Message Icon Text 4" value="" style="margin-top: 2px; display: none; " onblur="setpic4data();">' +
            '<input id="pic5data" class="form-control" placeholder="Message Icon Text 5" value="" style="margin-top: 2px; display: none; " onblur="setpic5data();">' +
            '<input id="pic6data" class="form-control" placeholder="Message Icon Text 6" value="" style="margin-top: 2px; display: none; " onblur="setpic6data();">' +
            '<input id="yt1data" class="form-control" placeholder="Youtube Message Text 1" value="" style="margin-top: 2px; display: none; " onblur="setyt1data();">' +
            '<input id="yt2data" class="form-control" placeholder="Youtube Message Text 2" value="" style="margin-top: 2px; display: none; " onblur="setyt2data();">' +
            '<input id="yt3data" class="form-control" placeholder="Youtube Message Text 3" value="" style="margin-top: 2px; display: none; " onblur="setyt3data();">' +
            '<input id="yt4data" class="form-control" placeholder="Youtube Message Text 4" value="" style="margin-top: 2px; display: none; " onblur="setyt4data();">' +
            '<input id="yt5data" class="form-control" placeholder="Youtube Message Text 5" value="" style="margin-top: 2px; display: none; " onblur="setyt5data();">' +
            '<input id="yt6data" class="form-control" placeholder="Youtube Message Text 6" value="" style="margin-top: 2px; display: none; " onblur="setyt6data();">' +

            '<input id="pic1url" class="form-control" placeholder="Message Icon Imgur Url 1" value="" style="margin-top: 2px; display: block;" onblur="setpic1url();" data-toggle="tooltip" data-placement="right" data-original-title="e.g. http://i.imgur.com/RVBi3T1.gif" >' +
            '<input id="pic2url" class="form-control" placeholder="Message Icon Imgur Url 2" value="" style="margin-top: 2px; display: none;" onblur="setpic2url();" data-toggle="tooltip" data-placement="right" data-original-title="e.g. http://i.imgur.com/RVBi3T1.gif" >' +
            '<input id="pic3url" class="form-control" placeholder="Message Icon Imgur Url 3" value="" style="margin-top: 2px; display: none;" onblur="setpic3url();" data-toggle="tooltip" data-placement="right" data-original-title="e.g. http://i.imgur.com/RVBi3T1.gif" >' +
            '<input id="pic4url" class="form-control" placeholder="Message Icon Imgur Url 4" value="" style="margin-top: 2px; display: none;" onblur="setpic4url();" data-toggle="tooltip" data-placement="right" data-original-title="e.g. http://i.imgur.com/RVBi3T1.gif" >' +
            '<input id="pic5url" class="form-control" placeholder="Message Icon Imgur Url 5" value="" style="margin-top: 2px; display: none;" onblur="setpic5url();" data-toggle="tooltip" data-placement="right" data-original-title="e.g. http://i.imgur.com/RVBi3T1.gif" >' +
            '<input id="pic6url" class="form-control" placeholder="Message Icon Imgur Url 6" value="" style="margin-top: 2px; display: none;" onblur="setpic6url();" data-toggle="tooltip" data-placement="right" data-original-title="e.g. http://i.imgur.com/RVBi3T1.gif" >' +
            '<input id="yt1url" class="form-control" placeholder="Youtube Message Url 1" value="" style="margin-top: 2px; display: none;" onblur="setyt1url();" data-toggle="tooltip" data-placement="right" data-original-title="Url of youtube to be shown" >' +
            '<input id="yt2url" class="form-control" placeholder="Youtube Message Url 2" value="" style="margin-top: 2px; display: none;" onblur="setyt2url();" data-toggle="tooltip" data-placement="right" data-original-title="Url of youtube to be shown" >' +
            '<input id="yt3url" class="form-control" placeholder="Youtube Message Url 3" value="" style="margin-top: 2px; display: none;" onblur="setyt3url();" data-toggle="tooltip" data-placement="right" data-original-title="Url of youtube to be shown" >' +
            '<input id="yt4url" class="form-control" placeholder="Youtube Message Url 4" value="" style="margin-top: 2px; display: none;" onblur="setyt4url();" data-toggle="tooltip" data-placement="right" data-original-title="Url of youtube to be shown" >' +
            '<input id="yt5url" class="form-control" placeholder="Youtube Message Url 5" value="" style="margin-top: 2px; display: none;" onblur="setyt5url();" data-toggle="tooltip" data-placement="right" data-original-title="Url of youtube to be shown" >' +
            '<input id="yt6url" class="form-control" placeholder="Youtube Message Url 6" value="" style="margin-top: 2px; display: none;" onblur="setyt6url();" data-toggle="tooltip" data-placement="right" data-original-title="Url of youtube to be shown" >' +
            '

' +

            '
Choose Language:  ' +
            '<select id="legendlanguages" class="form-control" onchange="changeModLanguage();" required="" data-original-title="" title="" style="display:inline; width: 50%" >' +
            '<option value="1" data-itr="">English</option>' +
            '<option value="6" data-itr="">Arabic - عربى</option>' +
            '<option value="4" data-itr="">Bulgarian - български</option>' +
            '<option value="5" data-itr="">French - Français</option>' +
            '<option value="2" data-itr="">Greek - Ελληνικά</option>' +
            '<option value="3" data-itr="">Spanish - Español</option>' +

            //
            //		'<option value="5" data-itr="">Icon 5</option>' +
            //		'<option value="6" data-itr="">Icon 6</option>' +
            //		'<option value="7" data-itr="">Youtube 1</option>' +
            //		'<option value="8" data-itr="">Youtube 2</option>' +
            //		'<option value="9" data-itr="">Youtube 3</option>' +
            //		'<option value="10" data-itr="">Youtube 4</option>' +
            //		'<option value="11" data-itr="">Youtube 5</option>' +
            //		'<option value="12" data-itr="">Youtube 6</option>' +
            '</select>
' +

            '
Chat Position:
' +
            '<button id="bottomleft" type="button" class="btn btn-primary">Default</button>' +
            '<button id="bottomright" type="button" class="btn btn-primary"></button>' +
            '<button id="topleft" type="button" class="btn btn-primary"></button>' +
            '<button id="topright" type="button" class="btn btn-primary"></button>' +
            '

' +
            '
Discord Webhook Url (for sending TOKEN)  ' +
            '<input id="discwebhook1" class="form-control" placeholder="Discord Webhook 1 Url" value="" data-toggle="tooltip" data-placement="right" data-original-title="Must be filled for function to work. https://discordapp.com/api/webhooks/.../..." style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-left: 0.5%; display: inline-block; " onblur="setdiscwebhook1();">' +
            '<input id="discwebhook2" class="form-control" placeholder="Discord Webhook 2 Url" value="" data-toggle="tooltip" data-placement="right" data-original-title="Secondary Webhook(optional). https://discordapp.com/api/webhooks/.../..." style="margin-top: 2px; width: 49.5%; border-color: darkslategrey; margin-right: 0.5%; display: inline-block;" onblur="setdiscwebhook2();">' +
            '
Expansions: ' +
            '

' +

            '' + //
Other features

            '

');
		$("#___ytsubscribe_0").remove();
setTimeout(function() {
	toastr["warning"]("This Version is temporary and buggy. Install the old one when its ready");
	}, 5000);
}, 2000);
<commit_msg>Update thebuggybug.js<commit_after>setTimeout(function() {
        var ogarioVersion = $("#menu-footer").text().split("| ")[1];
        $("#menu-footer").text("");
		$("#menu-footer").prepend('Legend mod ' + 'Temporary Script (BUGGY)' + '' +
            'More FPS');
        document.getElementsByClassName('quick-yt icon-youtube2')[0].setAttribute('id', 'legendid');
        document.getElementsByClassName('quick-yt icon-youtube2')[0].href = "https://www.youtube.com/watch?v=CnIfNSpCf70";
        document.getElementsByClassName('quick-yt icon-youtube2')[0].setAttribute('data-original-title', 'Legend Promo Video');
        $('#legendid').addClass('fa fa-thumbs-o-up').removeClass('quick-yt icon-youtube2');
		$("#more-skins").attr('href', 'https://jimboy3100.github.io/skins/skins.html');

		$("#___ytsubscribe_0").remove();
setTimeout(function() {
	toastr["warning"]("This Version is temporary and buggy. Install the old one when its ready");
	}, 5000);
}, 2000);
<|endoftext|>


<commit_before><commit_msg>Add onbeforeunload to prevent data loss<commit_after><|endoftext|>


<commit_before>//
// This is injected in the content.
// Author: Hubert Figuiere
//

function analyzeObject(element) {
  var param = element ? element.firstChild : null;
  if (param === null) {
    console.error("No child or element to analyze in",
                  element ? element.localName : '(null)');
    return {
      type: "notflash"
    };
  }
  var width, height;
  width = element.getAttribute("width");
  height = element.getAttribute("height");

  while (param) {
    if (param.localName == 'embed') {

      var embed_type = param.getAttribute("type")
      if (embed_type != "application/x-shockwave-flash") {
        console.log("Not flash, but", embed_type);
        return {
          type: "notflash"
        };
      }

      width = param.hasAttribute("width") ? param.getAttribute("width") : width;
      height = param.hasAttribute("height") ? param.getAttribute("height") : height;
//      allowfullscreen = param.getAttribute("allowfullscreen");

      if (param.hasAttribute('src')) {
        var url = param.getAttribute('src');

//DEBUG        console.log("matching url", url);

        // YOUTUBE
        var matches = url.match('^(?:https?:)?\/\/(?:www\.)?youtube\.(?:googleapis\.)?com/v/([A-Za-z0-9_\-]{11})');
        if (matches) {
          return {
            type: "youtube",
            src: url,
            width: width,
            height: height,
            videoid: matches[1],
            processor: replaceYT
          };
        }

        // VIMEO
        matches = url.match('^(?:https?:)?\/\/(www\.)?vimeo.com/moogaloop\.swf\?.*clip_id=([0-9]*)');
        if (matches) {
          return {
            type: "vimeo",
            src: url,
            width: width,
            height: height,
            videoid: matches[2],
            processor: replaceVimeo
          };
        }

      }
    }
    param = param.nextSibling;
  }
}

// replace the vimeo embed by its iframe
function replaceVimeo(container, a) {
  if (a.type != "vimeo") {
    console.error("Wrong type, got", a.type);
    return;
  }

  if (a.videoid === undefined) {
    console.error("Couldn't match VIMEO video ID in URL", a.src);
    return ;
  }

  var replacement = document.createElement("iframe");
  replacement.setAttribute('src', 'https://player.vimeo.com/video/' + a.videoid);
  replacement.setAttribute('width', a.width);
  replacement.setAttribute('height', a.height);
  replacement.setAttribute('frameborder', '0');
//  replacement.setAttribute('webkitallowfullscreen'); // not needed
//  replacement.setAttribute('mozallowfullscreen'); // deprecated
  replacement.setAttribute('allowfullscreen', '');

  replaceObjectTag(container, replacement);
}

// replace the youtube embed by its iframe
function replaceYT(container, a) {
  if (a.type != "youtube") {
    console.error("Wrong type, got", a.type);
    return;
  }

  if (a.videoid === undefined) {
    console.error("Couldn't match YT video ID in URL", a.src);
    return ;
  }

  var replacement = document.createElement("iframe");
  replacement.setAttribute('class', 'youtube-player');
  replacement.setAttribute('type', 'text/html');
  replacement.setAttribute('width', a.width);
  replacement.setAttribute('height', a.height);
  replacement.setAttribute('src', 'https://www.youtube.com/embed/' + a.videoid);
  replacement.setAttribute('allowfullscreen', '');
  replacement.setAttribute('frameborder', '0');

  replaceObjectTag(container, replacement);

//  console.log("Replacing with ", replacement.outerHTML);
}

function replaceObjectTag(obj, replacement) {
  obj.parentNode.insertBefore(replacement, obj);
  obj.parentNode.removeChild(obj);
}

self.port.on("noFlash", function() {
  var elements = document.getElementsByTagName("object")

  var embeds = [];
  for (var i = 0; i < elements.length; i++) {
    embeds.push(elements.item(i));
  }

  for (var i in embeds) {
    try {
      console.log('processing', i);
      var analyzed = analyzeObject(embeds[i]);

      if (typeof analyzed.processor === 'function') {
        analyzed.processor(embeds[i], analyzed);
      } else {
        console.log("Found unprocessable object", embeds[i].localName, "of type", analyzed.type);
      }
    }
    catch (e) {
      console.error("Exception:", e.message, e.stack);
    }
  }
});
<commit_msg>Look for the <embed> instead of <object><commit_after>//
// This is injected in the content.
// Author: Hubert Figuiere
//

function analyzeObject(element) {
  if (element.localName != 'embed') {
    console.error("No child or element to analyze in",
                  element ? element.localName : '(null)');
    return {
      type: "notflash"
    };
  }
  var width, height;
  width = element.getAttribute("width");
  height = element.getAttribute("height");

  var embed_type = element.getAttribute("type")
  if (embed_type != "application/x-shockwave-flash") {
    console.log("Not flash, but", embed_type);
    return {
      type: "notflash"
    };
  }

//      allowfullscreen = element.getAttribute("allowfullscreen");

  if (element.hasAttribute('src')) {
    var url = element.getAttribute('src');

//DEBUG        console.log("matching url", url);

    // YOUTUBE
    var matches = url.match('^(?:https?:)?\/\/(?:www\.)?youtube\.(?:googleapis\.)?com/v/([A-Za-z0-9_\-]{11})');
    if (matches) {
      return {
        type: "youtube",
        src: url,
        width: width,
        height: height,
        videoid: matches[1],
        processor: replaceYT
      };
    }

    // VIMEO
    matches = url.match('^(?:https?:)?\/\/(www\.)?vimeo.com/moogaloop\.swf\?.*clip_id=([0-9]*)');
    if (matches) {
      return {
        type: "vimeo",
        src: url,
        width: width,
        height: height,
        videoid: matches[2],
        processor: replaceVimeo
      };
    }
  }
}

// replace the vimeo embed by its iframe
function replaceVimeo(container, a) {
  if (a.type != "vimeo") {
    console.error("Wrong type, got", a.type);
    return;
  }

  if (a.videoid === undefined) {
    console.error("Couldn't match VIMEO video ID in URL", a.src);
    return ;
  }

  var replacement = document.createElement("iframe");
  replacement.setAttribute('src', 'https://player.vimeo.com/video/' + a.videoid);
  replacement.setAttribute('width', a.width);
  replacement.setAttribute('height', a.height);
  replacement.setAttribute('frameborder', '0');
//  replacement.setAttribute('webkitallowfullscreen'); // not needed
//  replacement.setAttribute('mozallowfullscreen'); // deprecated
  replacement.setAttribute('allowfullscreen', '');

  replaceObjectTag(container, replacement);
}

// replace the youtube embed by its iframe
function replaceYT(container, a) {
  if (a.type != "youtube") {
    console.error("Wrong type, got", a.type);
    return;
  }

  if (a.videoid === undefined) {
    console.error("Couldn't match YT video ID in URL", a.src);
    return ;
  }

  var replacement = document.createElement("iframe");
  replacement.setAttribute('class', 'youtube-player');
  replacement.setAttribute('type', 'text/html');
  replacement.setAttribute('width', a.width);
  replacement.setAttribute('height', a.height);
  replacement.setAttribute('src', 'https://www.youtube.com/embed/' + a.videoid);
  replacement.setAttribute('allowfullscreen', '');
  replacement.setAttribute('frameborder', '0');

  replaceObjectTag(container, replacement);

//  console.log("Replacing with ", replacement.outerHTML);
}

function replaceObjectTag(obj, replacement) {
  obj.parentNode.insertBefore(replacement, obj);
  obj.parentNode.removeChild(obj);
}

self.port.on("noFlash", function() {
  var elements = document.getElementsByTagName("embed")

  var embeds = [];
  for (var i = 0; i < elements.length; i++) {
    embeds.push(elements.item(i));
  }

  for (var i in embeds) {
    try {
      console.log('processing', i);
      var analyzed = analyzeObject(embeds[i]);

      if (typeof analyzed.processor === 'function') {
        analyzed.processor(embeds[i], analyzed);
      } else {
        console.log("Found unprocessable object", embeds[i].localName, "of type", analyzed.type);
      }
    }
    catch (e) {
      console.error("Exception:", e.message, e.stack);
    }
  }
});
<|endoftext|>


<commit_before>/* @flow */

export const generateID = () => "" + MSModelObjectCommon.generateObjectID();
<commit_msg>Fix flow type for generateID<commit_after>/* @flow */

declare class MSModelObjectCommon {
  generateObjectID():string;
}

export const generateID = (): string => "" + MSModelObjectCommon.generateObjectID();
<|endoftext|>


<commit_before>var Player = function(ui) {
	var player = ui._context.createElement('video')

	if (ui.autoPlay)
		player.setAttribute('autoplay', "")

	shaka.polyfill.installAll();
	if (shaka.Player.isBrowserSupported()) {
		var shakaPlayer = new shaka.Player(player.dom);
		this.shakaPlayer = shakaPlayer;
		shakaPlayer.addEventListener('error', ui._context.wrapNativeCallback(function(err) { log("SHAKA PALER ERR", err) }));
	} else {
		console.error('Browser not supported!');
		return
	}

	var dom = player.dom
	player.on('play', function() { ui.waiting = false; ui.paused = dom.paused }.bind(ui))
	player.on('pause', function() { ui.paused = dom.paused }.bind(ui))
	player.on('ended', function() { ui.finished() }.bind(ui))
	player.on('seeked', function() { log("seeked"); ui.seeking = false; ui.waiting = false }.bind(ui))
	player.on('canplay', function() { log("canplay", dom.readyState); ui.ready = dom.readyState }.bind(ui))
	player.on('seeking', function() { log("seeking"); ui.seeking = true; ui.waiting = true }.bind(ui))
	player.on('waiting', function() { log("waiting"); ui.waiting = true }.bind(ui))
	player.on('stalled', function() { log("Was stalled", dom.networkState); }.bind(ui))
	player.on('emptied', function() { log("Was emptied", dom.networkState); }.bind(ui))
	player.on('volumechange', function() { ui.muted = dom.muted }.bind(ui))
	player.on('canplaythrough', function() { log("ready to play"); ui.paused = dom.paused }.bind(ui))

	player.on('error', function() {
		log("Player error occured", dom.error, "src", ui.source)

		if (!dom.error || !ui.source)
			return

		ui.error(dom.error)

		log("player.error", dom.error)
		switch (dom.error.code) {
		case 1:
			log("MEDIA_ERR_ABORTED error occured")
			break;
		case 2:
			log("MEDIA_ERR_NETWORK error occured")
			break;
		case 3:
			log("MEDIA_ERR_DECODE error occured")
			break;
		case 4:
			log("MEDIA_ERR_SRC_NOT_SUPPORTED error occured")
			break;
		default:
			log("UNDEFINED error occured")
			break;
		}
	}.bind(ui))

	player.on('timeupdate', function() {
		ui.waiting = false
		if (!ui.seeking)
			ui.progress = dom.currentTime
	}.bind(ui))

	player.on('durationchange', function() {
		var d = dom.duration
		log("Duration", d)
		ui.duration = isFinite(d) ? d : 0
	}.bind(ui))

	player.on('progress', function() {
		var last = dom.buffered.length - 1
		ui.waiting = false
		if (last >= 0)
			ui.buffered = dom.buffered.end(last) - dom.buffered.start(last)
	}.bind(ui))

	this.element = player
	this.ui = ui

	ui.element.remove()
	ui.element = player
	ui.parent.element.append(ui.element)
}

Player.prototype = Object.create(_globals.video.html5.backend.Player.prototype)

Player.prototype.configureDrm = function(config) {
	var laServers = {}
	if (config.widevine)
		servers['com.widevine.alpha'] = config.widevine
	if (config.playready)
		servers['com.microsoft.playready'] = config.playready

	this.shakaPlayer.configure({
		drm: { servers: laServers }
	});
}

Player.prototype.setSource = function(url) {
	var ui = this.ui
	this.shakaPlayer.load(url).then(function() {
		console.log('The video has now been loaded!');
	}).catch(function(err) { log("Failed to load manifest") });
}

exports.createPlayer = function(ui) {
	return new Player(ui)
}

exports.probeUrl = function(url) {
	return 150
}

exports.Player = Player
<commit_msg>Fix DRM configuring for shaka player<commit_after>var Player = function(ui) {
	var player = ui._context.createElement('video')

	if (ui.autoPlay)
		player.setAttribute('autoplay', "")
	ui.configureDrm = this.configureDrm.bind(this)

	shaka.polyfill.installAll();
	if (shaka.Player.isBrowserSupported()) {
		var shakaPlayer = new shaka.Player(player.dom);
		this.shakaPlayer = shakaPlayer;
		shakaPlayer.addEventListener('error', ui._context.wrapNativeCallback(function(err) { log("SHAKA PALER ERR", err) }));
	} else {
		console.error('Browser not supported!');
		return
	}

	var dom = player.dom
	player.on('play', function() { ui.waiting = false; ui.paused = dom.paused }.bind(ui))
	player.on('pause', function() { ui.paused = dom.paused }.bind(ui))
	player.on('ended', function() { ui.finished() }.bind(ui))
	player.on('seeked', function() { log("seeked"); ui.seeking = false; ui.waiting = false }.bind(ui))
	player.on('canplay', function() { log("canplay", dom.readyState); ui.ready = dom.readyState }.bind(ui))
	player.on('seeking', function() { log("seeking"); ui.seeking = true; ui.waiting = true }.bind(ui))
	player.on('waiting', function() { log("waiting"); ui.waiting = true }.bind(ui))
	player.on('stalled', function() { log("Was stalled", dom.networkState); }.bind(ui))
	player.on('emptied', function() { log("Was emptied", dom.networkState); }.bind(ui))
	player.on('volumechange', function() { ui.muted = dom.muted }.bind(ui))
	player.on('canplaythrough', function() { log("ready to play"); ui.paused = dom.paused }.bind(ui))

	player.on('error', function() {
		log("Player error occured", dom.error, "src", ui.source)

		if (!dom.error || !ui.source)
			return

		ui.error(dom.error)

		log("player.error", dom.error)
		switch (dom.error.code) {
		case 1:
			log("MEDIA_ERR_ABORTED error occured")
			break;
		case 2:
			log("MEDIA_ERR_NETWORK error occured")
			break;
		case 3:
			log("MEDIA_ERR_DECODE error occured")
			break;
		case 4:
			log("MEDIA_ERR_SRC_NOT_SUPPORTED error occured")
			break;
		default:
			log("UNDEFINED error occured")
			break;
		}
	}.bind(ui))

	player.on('timeupdate', function() {
		ui.waiting = false
		if (!ui.seeking)
			ui.progress = dom.currentTime
	}.bind(ui))

	player.on('durationchange', function() {
		var d = dom.duration
		log("Duration", d)
		ui.duration = isFinite(d) ? d : 0
	}.bind(ui))

	player.on('progress', function() {
		var last = dom.buffered.length - 1
		ui.waiting = false
		if (last >= 0)
			ui.buffered = dom.buffered.end(last) - dom.buffered.start(last)
	}.bind(ui))

	this.element = player
	this.ui = ui

	ui.element.remove()
	ui.element = player
	ui.parent.element.append(ui.element)
}

Player.prototype = Object.create(_globals.video.html5.backend.Player.prototype)

Player.prototype.configureDrm = function(config) {
	var laServers = {}
	if (config.widevine)
		laServers['com.widevine.alpha'] = config.widevine
	if (config.playready)
		laServers['com.microsoft.playready'] = config.playready

	this.shakaPlayer.configure({
		drm: { servers: laServers }
	});
}

Player.prototype.setSource = function(url) {
	var ui = this.ui
	this.shakaPlayer.load(url).then(function() {
		console.log('The video has now been loaded!');
	}).catch(function(err) { log("Failed to load manifest") });
}

exports.createPlayer = function(ui) {
	return new Player(ui)
}

exports.probeUrl = function(url) {
	return 150
}

exports.Player = Player
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import url from 'url';
import { BrowserSelector } from './objectutils';
import { Panel, PanelBody } from '../libs/bootstrap/panel';
import { FacetList, Listing } from './search';
import { FetchedData, Param } from './fetched';
import * as globals from './globals';

const regionGenomes = [
    { value: 'GRCh37', display: 'hg19' },
    { value: 'GRCh38', display: 'GRCh38' },
    { value: 'GRCm37', display: 'mm9' },
    { value: 'GRCm38', display: 'mm10' },
];

const AutocompleteBox = (props) => {
    const terms = props.auto['@graph']; // List of matching terms from server
    const handleClick = props.handleClick;
    const userTerm = props.userTerm && props.userTerm.toLowerCase(); // Term user entered

    if (!props.hide && userTerm && userTerm.length && terms && terms.length) {
        return (

                {terms.map((term) => {
                    let matchEnd;
                    let preText;
                    let matchText;
                    let postText;

                    // Boldface matching part of term
                    const matchStart = term.text.toLowerCase().indexOf(userTerm);
                    if (matchStart >= 0) {
                        matchEnd = matchStart + userTerm.length;
                        preText = term.text.substring(0, matchStart);
                        matchText = term.text.substring(matchStart, matchEnd);
                        postText = term.text.substring(matchEnd);
                    } else {
                        preText = term.text;
                    }
                    return (
                        <AutocompleteBoxMenu
                            key={term.text}
                            handleClick={handleClick}
                            term={term}
                            name={props.name}
                            preText={preText}
                            matchText={matchText}
                            postText={postText}
                        />
                    );
                }, this)}

        );
    }

    return null;
};

AutocompleteBox.propTypes = {
    auto: PropTypes.object,
    userTerm: PropTypes.string,
    handleClick: PropTypes.func,
    hide: PropTypes.bool,
    name: PropTypes.string,
};

AutocompleteBox.defaultProps = {
    auto: {}, // Looks required, but because it's built from <Param>, it can fail type checks.
    userTerm: '',
    handleClick: null,
    hide: false,
    name: '',
};

// Draw the autocomplete box drop-down menu.
class AutocompleteBoxMenu extends React.Component {
    constructor() {
        super();

        // Bind this to non-React methods.
        this.handleClick = this.handleClick.bind(this);
    }

    // Handle clicks in the drop-down menu. It just calls the parent's handleClick function, giving
    // it the parameters of the clicked item.
    handleClick() {
        const { term, name } = this.props;
        this.props.handleClick(term.text, term._source.payload.id, name);
    }

    render() {
        const { preText, matchText, postText } = this.props;

        /* eslint-disable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/no-noninteractive-tabindex, jsx-a11y/click-events-have-key-events */
        return (

                {preText}{matchText}{postText}

        );
        /* eslint-enable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/no-noninteractive-tabindex, jsx-a11y/click-events-have-key-events */
    }
}

AutocompleteBoxMenu.propTypes = {
    handleClick: PropTypes.func.isRequired, // Parent function to handle a click in a drop-down menu item
    term: PropTypes.object.isRequired, // Object for the term being searched
    name: PropTypes.string,
    preText: PropTypes.string, // Text before the matched term in the entered string
    matchText: PropTypes.string, // Matching text in the entered string
    postText: PropTypes.string, // Text after the matched term in the entered string
};

AutocompleteBoxMenu.defaultProps = {
    name: '',
    preText: '',
    matchText: '',
    postText: '',
};

class AdvSearch extends React.Component {
    constructor() {
        super();

        // Set intial React state.
        /* eslint-disable react/no-unused-state */
        // Need to disable this rule because of a bug in eslint-plugin-react.
        // https://github.com/yannickcr/eslint-plugin-react/issues/1484#issuecomment-366590614
        this.state = {
            disclosed: false,
            showAutoSuggest: false,
            searchTerm: '',
            coordinates: '',
            genome: '',
            terms: {},
        };
        /* eslint-enable react/no-unused-state */

        // Bind this to non-React methods.
        this.handleDiscloseClick = this.handleDiscloseClick.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.handleAutocompleteClick = this.handleAutocompleteClick.bind(this);
        this.handleAssemblySelect = this.handleAssemblySelect.bind(this);
        this.closeAutocompleteBox = this.closeAutocompleteBox.bind(this);
        this.tick = this.tick.bind(this);
    }

    componentDidMount() {
        // Use timer to limit to one request per second
        this.timer = setInterval(this.tick, 1000);
    }

    componentWillUnmount() {
        clearInterval(this.timer);
    }

    handleDiscloseClick() {
        this.setState(prevState => ({
            disclosed: !prevState.disclosed,
        }));
    }

    handleChange(e) {
        this.setState({ showAutoSuggest: true, terms: {} });
        this.newSearchTerm = e.target.value;
    }

    handleAutocompleteClick(term, id, name) {
        const newTerms = {};
        const inputNode = this.annotation;
        inputNode.value = term;
        newTerms[name] = id;
        this.setState({ terms: newTerms, showAutoSuggest: false });
        inputNode.focus();
        // Now let the timer update the terms state when it gets around to it.
    }

    handleAssemblySelect(event) {
        // Handle click in assembly-selection <select>
        this.setState({ genome: event.target.value });
    }

    closeAutocompleteBox() {
        this.setState({ showAutoSuggest: false });
    }

    tick() {
        if (this.newSearchTerm !== this.state.searchTerm) {
            this.setState({ searchTerm: this.newSearchTerm });
        }
    }

    render() {
        const context = this.props.context;
        const id = url.parse(this.context.location_href, true);
        const region = id.query.region || '';

        if (this.state.genome === '') {
            let assembly = regionGenomes[0].value;
            if (context.assembly) {
                assembly = regionGenomes.find(el =>
                    context.assembly === el.value || context.assembly === el.display
                ).value;
            }
            this.setState({ genome: assembly });
        }

        return (
            <Panel>
                <PanelBody>
                    <form id="panel1" className="adv-search-form" autoComplete="off" aria-labelledby="tab1" onSubmit={this.closeAutocompleteBox} >
                        <input type="hidden" name="annotation" value={this.state.terms.annotation} />

                            Enter any one of human Gene name, Symbol, Synonyms, Gene ID, HGNC ID, coordinates, rsid, Ensemble ID

                                <input id="annotation" ref={(input) => { this.annotation = input; }} defaultValue={region} name="region" type="text" className="form-control" onChange={this.handleChange} />
                                {(this.state.showAutoSuggest && this.state.searchTerm) ?
                                    <FetchedData loadingComplete>
                                        <Param name="auto" url={`/suggest/?genome=${this.state.genome}&q=${this.state.searchTerm}`} type="json" />
                                        <AutocompleteBox name="annotation" userTerm={this.state.searchTerm} handleClick={this.handleAutocompleteClick} />
                                    </FetchedData>
                                : null}

                                    <select value={this.state.genome} name="genome" onFocus={this.closeAutocompleteBox} onChange={this.handleAssemblySelect}>
                                        {regionGenomes.map(genomeId =>
                                            <option key={genomeId.value} value={genomeId.value}>{genomeId.display}</option>
                                        )}
                                    </select>

                                {context.notification ?

{context.notification}

                                : null}

                        <input type="submit" value="Search" className="btn btn-sm btn-info pull-right" />
                    </form>
                    {context.coordinates ?

Searched coordinates: {context.coordinates}

                    : null}
                </PanelBody>
            </Panel>
        );
    }
}

AdvSearch.propTypes = {
    context: PropTypes.object.isRequired,
};

AdvSearch.contextTypes = {
    autocompleteTermChosen: PropTypes.bool,
    autocompleteHidden: PropTypes.bool,
    onAutocompleteHiddenChange: PropTypes.func,
    location_href: PropTypes.string,
};

class RegionSearch extends React.Component {
    constructor() {
        super();

        // Bind this to non-React methods.
        this.onFilter = this.onFilter.bind(this);
    }

    onFilter(e) {
        if (this.props.onChange) {
            const search = e.currentTarget.getAttribute('href');
            this.props.onChange(search);
            e.stopPropagation();
            e.preventDefault();
        }
    }

    render() {
        const visualizeLimit = 100;
        const context = this.props.context;
        const results = context['@graph'];
        const columns = context.columns;
        const notification = context.notification;
        const searchBase = url.parse(this.context.location_href).search || '';
        const trimmedSearchBase = searchBase.replace(/[?|&]limit=all/, '');
        const filters = context.filters;
        const facets = context.facets;
        const total = context.total;
        const visualizeDisabled = total > visualizeLimit;

        // Get a sorted list of batch hubs keys with case-insensitive sort
        let visualizeKeys = [];
        if (context.visualize_batch && Object.keys(context.visualize_batch).length) {
            visualizeKeys = Object.keys(context.visualize_batch).sort((a, b) => {
                const aLower = a.toLowerCase();
                const bLower = b.toLowerCase();
                return (aLower > bLower) ? 1 : ((aLower < bLower) ? -1 : 0);
            });
        }

        return (

Region search

                <AdvSearch {...this.props} />
                {notification === 'Success' ?

                                <FacetList
                                    {...this.props}
                                    facets={facets}
                                    filters={filters}
                                    searchBase={searchBase ? `${searchBase}&` : `${searchBase}?`}
                                    onFilter={this.onFilter}
                                />

                                        Showing {results.length} of {total}

                                        {total > results.length && searchBase.indexOf('limit=all') === -1 ?
                                                <a
                                                    rel="nofollow"
                                                    className="btn btn-info btn-sm"
                                                    href={searchBase ? `${searchBase}&limit=all` : '?limit=all'}
                                                    onClick={this.onFilter}
                                                >
                                                    View All

                                        :

                                                {results.length > 25 ?

                                                            View 25

                                                : null}

                                        }

                                        {visualizeKeys && context.visualize_batch ?
                                            <BrowserSelector
                                                visualizeCfg={context.visualize_batch}
                                                disabled={visualizeDisabled}
                                                title={visualizeDisabled ? `Filter to ${visualizeLimit} to visualize` : 'Visualize'}
                                            />
                                        : null}

                                    {results.map(result => Listing({ context: result, columns, key: result['@id'] }))}

                : null}

        );
    }
}

RegionSearch.propTypes = {
    context: PropTypes.object.isRequired,
    onChange: PropTypes.func,
};

RegionSearch.defaultProps = {
    onChange: null,
};

RegionSearch.contextTypes = {
    location_href: PropTypes.string,
    navigate: PropTypes.func,
};

globals.contentViews.register(RegionSearch, 'region-search');
<commit_msg>ENCD-4256 Fix region search back button functionality (#2463)<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import url from 'url';
import { BrowserSelector } from './objectutils';
import { Panel, PanelBody } from '../libs/bootstrap/panel';
import { FacetList, Listing } from './search';
import { FetchedData, Param } from './fetched';
import * as globals from './globals';

const regionGenomes = [
    { value: 'GRCh37', display: 'hg19' },
    { value: 'GRCh38', display: 'GRCh38' },
    { value: 'GRCm37', display: 'mm9' },
    { value: 'GRCm38', display: 'mm10' },
];

const AutocompleteBox = (props) => {
    const terms = props.auto['@graph']; // List of matching terms from server
    const handleClick = props.handleClick;
    const userTerm = props.userTerm && props.userTerm.toLowerCase(); // Term user entered

    if (!props.hide && userTerm && userTerm.length && terms && terms.length) {
        return (

                {terms.map((term) => {
                    let matchEnd;
                    let preText;
                    let matchText;
                    let postText;

                    // Boldface matching part of term
                    const matchStart = term.text.toLowerCase().indexOf(userTerm);
                    if (matchStart >= 0) {
                        matchEnd = matchStart + userTerm.length;
                        preText = term.text.substring(0, matchStart);
                        matchText = term.text.substring(matchStart, matchEnd);
                        postText = term.text.substring(matchEnd);
                    } else {
                        preText = term.text;
                    }
                    return (
                        <AutocompleteBoxMenu
                            key={term.text}
                            handleClick={handleClick}
                            term={term}
                            name={props.name}
                            preText={preText}
                            matchText={matchText}
                            postText={postText}
                        />
                    );
                }, this)}

        );
    }

    return null;
};

AutocompleteBox.propTypes = {
    auto: PropTypes.object,
    userTerm: PropTypes.string,
    handleClick: PropTypes.func,
    hide: PropTypes.bool,
    name: PropTypes.string,
};

AutocompleteBox.defaultProps = {
    auto: {}, // Looks required, but because it's built from <Param>, it can fail type checks.
    userTerm: '',
    handleClick: null,
    hide: false,
    name: '',
};

// Draw the autocomplete box drop-down menu.
class AutocompleteBoxMenu extends React.Component {
    constructor() {
        super();

        // Bind this to non-React methods.
        this.handleClick = this.handleClick.bind(this);
    }

    // Handle clicks in the drop-down menu. It just calls the parent's handleClick function, giving
    // it the parameters of the clicked item.
    handleClick() {
        const { term, name } = this.props;
        this.props.handleClick(term.text, term._source.payload.id, name);
    }

    render() {
        const { preText, matchText, postText } = this.props;

        /* eslint-disable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/no-noninteractive-tabindex, jsx-a11y/click-events-have-key-events */
        return (

                {preText}{matchText}{postText}

        );
        /* eslint-enable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/no-noninteractive-tabindex, jsx-a11y/click-events-have-key-events */
    }
}

AutocompleteBoxMenu.propTypes = {
    handleClick: PropTypes.func.isRequired, // Parent function to handle a click in a drop-down menu item
    term: PropTypes.object.isRequired, // Object for the term being searched
    name: PropTypes.string,
    preText: PropTypes.string, // Text before the matched term in the entered string
    matchText: PropTypes.string, // Matching text in the entered string
    postText: PropTypes.string, // Text after the matched term in the entered string
};

AutocompleteBoxMenu.defaultProps = {
    name: '',
    preText: '',
    matchText: '',
    postText: '',
};

class AdvSearch extends React.Component {
    constructor() {
        super();

        // Set intial React state.
        /* eslint-disable react/no-unused-state */
        // Need to disable this rule because of a bug in eslint-plugin-react.
        // https://github.com/yannickcr/eslint-plugin-react/issues/1484#issuecomment-366590614
        this.state = {
            disclosed: false,
            showAutoSuggest: false,
            searchTerm: '',
            coordinates: '',
            genome: '',
            terms: {},
        };
        /* eslint-enable react/no-unused-state */

        // Bind this to non-React methods.
        this.handleDiscloseClick = this.handleDiscloseClick.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.handleAutocompleteClick = this.handleAutocompleteClick.bind(this);
        this.handleAssemblySelect = this.handleAssemblySelect.bind(this);
        this.handleOnFocus = this.handleOnFocus.bind(this);
        this.tick = this.tick.bind(this);
    }

    componentDidMount() {
        // Use timer to limit to one request per second
        this.timer = setInterval(this.tick, 1000);
    }

    componentWillUnmount() {
        clearInterval(this.timer);
    }

    handleDiscloseClick() {
        this.setState(prevState => ({
            disclosed: !prevState.disclosed,
        }));
    }

    handleChange(e) {
        this.setState({ showAutoSuggest: true, terms: {} });
        this.newSearchTerm = e.target.value;
    }

    handleAutocompleteClick(term, id, name) {
        const newTerms = {};
        const inputNode = this.annotation;
        inputNode.value = term;
        newTerms[name] = id;
        this.setState({ terms: newTerms, showAutoSuggest: false });
        inputNode.focus();
        // Now let the timer update the terms state when it gets around to it.
    }

    handleAssemblySelect(event) {
        // Handle click in assembly-selection <select>
        this.setState({ genome: event.target.value });
    }

    handleOnFocus() {
        this.setState({ showAutoSuggest: false });
        this.context.navigate(this.context.location_href);
    }

    tick() {
        if (this.newSearchTerm !== this.state.searchTerm) {
            this.setState({ searchTerm: this.newSearchTerm });
        }
    }

    render() {
        const context = this.props.context;
        const id = url.parse(this.context.location_href, true);
        const region = id.query.region || '';

        if (this.state.genome === '') {
            let assembly = regionGenomes[0].value;
            if (context.assembly) {
                assembly = regionGenomes.find(el =>
                    context.assembly === el.value || context.assembly === el.display
                ).value;
            }
            this.setState({ genome: assembly });
        }

        return (
            <Panel>
                <PanelBody>
                    <form id="panel1" className="adv-search-form" autoComplete="off" aria-labelledby="tab1" onSubmit={this.handleOnFocus} >
                        <input type="hidden" name="annotation" value={this.state.terms.annotation} />

                            Enter any one of human Gene name, Symbol, Synonyms, Gene ID, HGNC ID, coordinates, rsid, Ensemble ID

                                <input id="annotation" ref={(input) => { this.annotation = input; }} defaultValue={region} name="region" type="text" className="form-control" onChange={this.handleChange} />
                                {(this.state.showAutoSuggest && this.state.searchTerm) ?
                                    <FetchedData loadingComplete>
                                        <Param name="auto" url={`/suggest/?genome=${this.state.genome}&q=${this.state.searchTerm}`} type="json" />
                                        <AutocompleteBox name="annotation" userTerm={this.state.searchTerm} handleClick={this.handleAutocompleteClick} />
                                    </FetchedData>
                                : null}

                                    <select value={this.state.genome} name="genome" onFocus={this.closeAutocompleteBox} onChange={this.handleAssemblySelect}>
                                        {regionGenomes.map(genomeId =>
                                            <option key={genomeId.value} value={genomeId.value}>{genomeId.display}</option>
                                        )}
                                    </select>

                                {context.notification ?

{context.notification}

                                : null}

                        <input type="submit" value="Search" className="btn btn-sm btn-info pull-right" />
                    </form>
                    {context.coordinates ?

Searched coordinates: {context.coordinates}

                    : null}
                </PanelBody>
            </Panel>
        );
    }
}

AdvSearch.propTypes = {
    context: PropTypes.object.isRequired,
};

AdvSearch.contextTypes = {
    autocompleteTermChosen: PropTypes.bool,
    autocompleteHidden: PropTypes.bool,
    onAutocompleteHiddenChange: PropTypes.func,
    location_href: PropTypes.string,
    navigate: PropTypes.func,
};

class RegionSearch extends React.Component {
    constructor() {
        super();

        // Bind this to non-React methods.
        this.onFilter = this.onFilter.bind(this);
    }

    onFilter(e) {
        if (this.props.onChange) {
            const search = e.currentTarget.getAttribute('href');
            this.props.onChange(search);
            e.stopPropagation();
            e.preventDefault();
        }
    }

    render() {
        const visualizeLimit = 100;
        const context = this.props.context;
        const results = context['@graph'];
        const columns = context.columns;
        const notification = context.notification;
        const searchBase = url.parse(this.context.location_href).search || '';
        const trimmedSearchBase = searchBase.replace(/[?|&]limit=all/, '');
        const filters = context.filters;
        const facets = context.facets;
        const total = context.total;
        const visualizeDisabled = total > visualizeLimit;

        // Get a sorted list of batch hubs keys with case-insensitive sort
        let visualizeKeys = [];
        if (context.visualize_batch && Object.keys(context.visualize_batch).length) {
            visualizeKeys = Object.keys(context.visualize_batch).sort((a, b) => {
                const aLower = a.toLowerCase();
                const bLower = b.toLowerCase();
                return (aLower > bLower) ? 1 : ((aLower < bLower) ? -1 : 0);
            });
        }

        return (

Region search

                <AdvSearch {...this.props} />
                {notification === 'Success' ?

                                <FacetList
                                    {...this.props}
                                    facets={facets}
                                    filters={filters}
                                    searchBase={searchBase ? `${searchBase}&` : `${searchBase}?`}
                                    onFilter={this.onFilter}
                                />

                                        Showing {results.length} of {total}

                                        {total > results.length && searchBase.indexOf('limit=all') === -1 ?
                                                <a
                                                    rel="nofollow"
                                                    className="btn btn-info btn-sm"
                                                    href={searchBase ? `${searchBase}&limit=all` : '?limit=all'}
                                                    onClick={this.onFilter}
                                                >
                                                    View All

                                        :

                                                {results.length > 25 ?

                                                            View 25

                                                : null}

                                        }

                                        {visualizeKeys && context.visualize_batch ?
                                            <BrowserSelector
                                                visualizeCfg={context.visualize_batch}
                                                disabled={visualizeDisabled}
                                                title={visualizeDisabled ? `Filter to ${visualizeLimit} to visualize` : 'Visualize'}
                                            />
                                        : null}

                                    {results.map(result => Listing({ context: result, columns, key: result['@id'] }))}

                : null}

        );
    }
}

RegionSearch.propTypes = {
    context: PropTypes.object.isRequired,
    onChange: PropTypes.func,
};

RegionSearch.defaultProps = {
    onChange: null,
};

RegionSearch.contextTypes = {
    location_href: PropTypes.string,
    navigate: PropTypes.func,
};

globals.contentViews.register(RegionSearch, 'region-search');
<|endoftext|>


<commit_before>const assert = require('assert');
const color = require('../app/components/tasks/color');

describe('tasks', () => {
  describe('color.js', () => {
    describe('returnColor', () => {
      const now = Date.now();
      const currentRounded = (now + (86400000 - (now % 86400000))) +
        (new Date().getTimezoneOffset() * 60000);
      const testTimes = [currentRounded - 86400000, currentRounded + 86400000, now];
      it('should return yellow color hsla', () => {
        assert(color.returnColor(...testTimes) === 'hsla(60, 100%, 75%, .3)');
      });
    });
  });
});
<commit_msg>Update colors unit test<commit_after>const assert = require('assert');
const color = require('../app/components/tasks/color');

describe('tasks', () => {
  describe('color.js', () => {
    describe('returnColor', () => {
      const now = Date.now();
      const currentRounded = (now + (86400000 - (now % 86400000))) +
        (new Date().getTimezoneOffset() * 60000);
      const testTimes = [currentRounded - 86400000, currentRounded + 86400000, now];
      it('should return yellow color hsla', () => {
        assert(color.returnColor(...testTimes) === 'hsl(60, 100%, 60%)');
      });
    });
  });
});
<|endoftext|>


<commit_before>var e = module.exports = {};
var blargutil = require('./../util.js');

var bot;
e.init = (Tbot) => {
    bot = Tbot;
};
e.requireCtx = require;

e.isCommand = true;
e.hidden = false;
e.usage = '';
e.info = '';
e.category = blargutil.CommandType.CAT;

e.execute = (msg, words) => {
    if (msg.author.id === blargutil.CAT_ID) {
        var gArray;
        if (words[1]) {
            if (words[1].toLowerCase() == 'bots') {
                gArray = bot.guilds.filter(m => m.members.filter(m2 => m2.user.bot).length / m.memberCount > 0.8 || /bot/gi.test(m.name));
            }
        }
        if (!gArray) {
        var gArray = bot.guilds.map(m => m);
        }
        var messages = [];
        var i = 0;
        messages.push(`Guilds (page ${i}):\n`);
        gArray.forEach(function (guild) {
            var addTo = ` - ${guild.name} (${guild.id})\n`;
            if (messages[i].length + addTo.length > 2000) {
                i++;
                messages.push(`Guilds (page ${i}):\n`);
            }
            messages[i] += addTo;
        });
        for (i = 0; i < messages.length; i++) {
            blargutil.sendMessageToDiscord(msg.channel.id, messages[i]);
        }

    }
};<commit_msg>bot percentage<commit_after>var e = module.exports = {};
var blargutil = require('./../util.js');

var bot;
e.init = (Tbot) => {
    bot = Tbot;
};
e.requireCtx = require;

e.isCommand = true;
e.hidden = false;
e.usage = '';
e.info = '';
e.category = blargutil.CommandType.CAT;

e.execute = (msg, words) => {
    if (msg.author.id === blargutil.CAT_ID) {
        var gArray;
        var botRatio = false;
        if (words[1]) {
            if (words[1].toLowerCase() == 'bots') {
                gArray = bot.guilds.filter(m => m.members.filter(m2 => m2.user.bot).length / m.memberCount > 0.8 || /bot/gi.test(m.name));
                botRatio = true;
            }
        }
        if (!gArray) {
            gArray = bot.guilds.map(m => m);
        }
        var messages = [];
        var i = 0;
        messages.push(`Guilds (page ${i}):\n`);
        gArray.forEach(function (guild) {
            var addTo = ` - ${guild.name} (${guild.id})${botRatio
                ? ` ${Math.round(guild.members.filter(m2 => m2.user.bot).length / guild.memberCount * 100)}% Bots`
                : ''}\n`;
            if (messages[i].length + addTo.length > 2000) {
                i++;
                messages.push(`Guilds (page ${i}):\n`);
            }
            messages[i] += addTo;
        });
        for (i = 0; i < messages.length; i++) {
            blargutil.sendMessageToDiscord(msg.channel.id, messages[i]);
        }

    }
};<|endoftext|>


<commit_before>
var UPDATE_INTERVAL = 1;
const NAMESPACE_SVG = "http://www.w3.org/2000/svg";
const SENSOR_DESCRIPTION_URL = "sensor_description.json";
// to be defined in config/config.js
// const SENSOR_VALUES_URL = "..."

var getJSON = function (url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open("get", url, true);
    xhr.responseType = "json";
    xhr.onload = function () {
        var status = xhr.status;
        if (status == 200) {
            callback(null, xhr.response);
        } else {
            callback(status);
        }
    };
    xhr.send();
};

var myNamespaceResolver = {
    lookupNamespaceURI: function (prefix) {
        switch (prefix) {
            // resolve "x" prefix
            case 'x':
                return NAMESPACE_SVG;
            default:
                return null;
        }
    }
};

function initializeSensorValueNodes(sensorValues) {
    var sensorValueNodes = {};

    Object.keys(sensorValues).forEach(function (sensorId) {
        var sensorUnit = sensorValues[sensorId].unit;

        // due to unique id, only first iteration should exist
        var sensorIdNode = document.getElementById("plant-visualization").contentDocument.evaluate(
            '//x:text[text() = "' + sensorId + '"]',
            document.getElementById("plant-visualization").contentDocument,
            myNamespaceResolver,
            XPathResult.FIRST_ORDERED_NODE_TYPE,
            null
        ).singleNodeValue;

        if (sensorIdNode != null) {

            bbox = sensorIdNode.getBBox();

            var sensorValueNode = document.createElementNS(NAMESPACE_SVG, "text");
            var x = sensorIdNode.getAttribute("x");
            var y = parseFloat(sensorIdNode.getAttribute("y")) + bbox.height + 2;
            sensorValueNode.setAttribute("x", x);
            sensorValueNode.setAttribute("y", y.toString());
            sensorValueNode.setAttribute("text-anchor", "left");
            sensorValueNode.setAttribute("fill", "red");
            sensorValueNode.setAttribute("font-family", "Arial");
            sensorValueNode.textContent = "";

            var sensorValue = document.createElementNS(NAMESPACE_SVG, "tspan");
            sensorValue.setAttribute("id", sensorId);
            sensorValue.appendChild(document.createTextNode(NaN));

            var sensorUnitNode = document.createElementNS(NAMESPACE_SVG, "tspan");
            sensorUnitNode.appendChild(document.createTextNode(" " + sensorUnit));

            sensorValueNode.appendChild(sensorValue);
            sensorValueNode.appendChild(sensorUnitNode);

            sensorIdNode.parentNode.appendChild(sensorValueNode);

            sensorValueTextNodes[sensorId] = sensorValue;
        }
    });

    return sensorValueTextNodes;
}

function updateSensorValues() {
    getJSON(SENSOR_VALUES_URL, function (err, data) {
        if (err != null) {
            console.log("Something went wrong: " + err);
        } else {
            var sensorValues = data["data"];
            var timestamp = data["timestamp"];

            Object.keys(sensorValues).forEach(function (sensorId) {
				if (sensorValueTextNodes[sensorId] != undefined) {
					var sensorValue = sensorValues[sensorId];
          var newSensorValue;
					switch (typeof(sensorValue)) {
						case "number":
							// integer
							if(sensorValue % 1 === 0)
								newSensorValue = sensorValue.toString();
							// float
							else
								newSensorValue = sensorValue.toFixed(1).toString();
							break;
						case "boolean":
							if(sensorValue)
								newSensorValue = "True";
							else
								newSensorValue = "False";
                            break;
						default:
							newSensorValue = sensorValue.toString();
							break;
					}
                    var oldSensorValue = sensorValueTextNodes[sensorId].textContent;
                    sensorValueTextNodes[sensorId].textContent = newSensorValue;
				}
            });
            var datetime = new Date(timestamp * 1000);
            document.getElementById("last-update-time").textContent = datetime.toString("dd.MM.yyyy HH:mm:ss.") + Math.floor(datetime.getMilliseconds()/100);
        }
        setTimeout(updateSensorValues, UPDATE_INTERVAL * 1000)
    });
}

// required by function updateSensorValues()
var sensorValueTextNodes = {};

window.onload = function () {

    getJSON(SENSOR_DESCRIPTION_URL,
        function (err, data) {
            if (err != null) {
                console.log("Something went wrong: " + err);
            } else {
                sensorValueTextNodes = initializeSensorValueNodes(data);
                updateSensorValues();
            }
        });
};
<commit_msg>change to second precision<commit_after>
var UPDATE_INTERVAL = 1;
const NAMESPACE_SVG = "http://www.w3.org/2000/svg";
const SENSOR_DESCRIPTION_URL = "sensor_description.json";
// to be defined in config/config.js
// const SENSOR_VALUES_URL = "..."

var getJSON = function (url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open("get", url, true);
    xhr.responseType = "json";
    xhr.onload = function () {
        var status = xhr.status;
        if (status == 200) {
            callback(null, xhr.response);
        } else {
            callback(status);
        }
    };
    xhr.send();
};

var myNamespaceResolver = {
    lookupNamespaceURI: function (prefix) {
        switch (prefix) {
            // resolve "x" prefix
            case 'x':
                return NAMESPACE_SVG;
            default:
                return null;
        }
    }
};

function initializeSensorValueNodes(sensorValues) {
    var sensorValueNodes = {};

    Object.keys(sensorValues).forEach(function (sensorId) {
        var sensorUnit = sensorValues[sensorId].unit;

        // due to unique id, only first iteration should exist
        var sensorIdNode = document.getElementById("plant-visualization").contentDocument.evaluate(
            '//x:text[text() = "' + sensorId + '"]',
            document.getElementById("plant-visualization").contentDocument,
            myNamespaceResolver,
            XPathResult.FIRST_ORDERED_NODE_TYPE,
            null
        ).singleNodeValue;

        if (sensorIdNode != null) {

            bbox = sensorIdNode.getBBox();

            var sensorValueNode = document.createElementNS(NAMESPACE_SVG, "text");
            var x = sensorIdNode.getAttribute("x");
            var y = parseFloat(sensorIdNode.getAttribute("y")) + bbox.height + 2;
            sensorValueNode.setAttribute("x", x);
            sensorValueNode.setAttribute("y", y.toString());
            sensorValueNode.setAttribute("text-anchor", "left");
            sensorValueNode.setAttribute("fill", "red");
            sensorValueNode.setAttribute("font-family", "Arial");
            sensorValueNode.textContent = "";

            var sensorValue = document.createElementNS(NAMESPACE_SVG, "tspan");
            sensorValue.setAttribute("id", sensorId);
            sensorValue.appendChild(document.createTextNode(NaN));

            var sensorUnitNode = document.createElementNS(NAMESPACE_SVG, "tspan");
            sensorUnitNode.appendChild(document.createTextNode(" " + sensorUnit));

            sensorValueNode.appendChild(sensorValue);
            sensorValueNode.appendChild(sensorUnitNode);

            sensorIdNode.parentNode.appendChild(sensorValueNode);

            sensorValueTextNodes[sensorId] = sensorValue;
        }
    });

    return sensorValueTextNodes;
}

function updateSensorValues() {
    getJSON(SENSOR_VALUES_URL, function (err, data) {
        if (err != null) {
            console.log("Something went wrong: " + err);
        } else {
            var sensorValues = data["data"];
            var timestamp = data["timestamp"];

            Object.keys(sensorValues).forEach(function (sensorId) {
				if (sensorValueTextNodes[sensorId] != undefined) {
					var sensorValue = sensorValues[sensorId];
          var newSensorValue;
					switch (typeof(sensorValue)) {
						case "number":
							// integer
							if(sensorValue % 1 === 0)
								newSensorValue = sensorValue.toString();
							// float
							else
								newSensorValue = sensorValue.toFixed(1).toString();
							break;
						case "boolean":
							if(sensorValue)
								newSensorValue = "True";
							else
								newSensorValue = "False";
                            break;
						default:
							newSensorValue = sensorValue.toString();
							break;
					}
                    var oldSensorValue = sensorValueTextNodes[sensorId].textContent;
                    sensorValueTextNodes[sensorId].textContent = newSensorValue;
				}
            });
            var datetime = new Date(timestamp * 1000);
            document.getElementById("last-update-time").textContent = datetime.toString("dd.MM.yyyy HH:mm:ss");
        }
        setTimeout(updateSensorValues, UPDATE_INTERVAL * 1000)
    });
}

// required by function updateSensorValues()
var sensorValueTextNodes = {};

window.onload = function () {

    getJSON(SENSOR_DESCRIPTION_URL,
        function (err, data) {
            if (err != null) {
                console.log("Something went wrong: " + err);
            } else {
                sensorValueTextNodes = initializeSensorValueNodes(data);
                updateSensorValues();
            }
        });
};
<|endoftext|>


<commit_before>Ext.define('devilry_subjectadmin.view.managestudents.DeadlinesContainer', {
    extend: 'Ext.panel.Panel',
    alias: 'widget.admingroupinfo_deadlinescontainer',
    cls: 'devilry_subjectadmin_admingroupinfo_deadlinescontainer devilry_discussionview_container',

    requires: [
        'devilry_subjectadmin.view.managestudents.DeadlinePanel',
        'devilry_extjsextras.AlertMessage'
    ],

    frame: false,
    border: false,
    bodyPadding: 0,
    layout: 'anchor',
    defaults: {
        anchor: '100%'
    },

    populate: function(aggregatedGroupInfoRecord, active_feedback) {
        console.log(aggregatedGroupInfoRecord);
        var deadlines = aggregatedGroupInfoRecord.get('deadlines');
        if(deadlines.length == 0) {
            this.add({
                xtype: 'alertmessage',
                type: 'error',
                title: interpolate(gettext('No %(deadlines_term)s'), {
                    deadlines_term: gettext('deadlines')
                }, true),
                message: interpolate(gettext('This group has no %(deadlines_term)s, so they can not add %(deliveries_term)s.'), {
                    deadlines_term: gettext('deadlines'),
                    deliveries_term: gettext('deliveries')
                }, true)
            });
        } else {
            Ext.Array.each(deadlines, function(deadline) {
                this.add({
                    xtype: 'admingroupinfo_deadline',
                    deadline: deadline,
                    active_feedback: active_feedback
                });
            }, this);
        }

    }
});
<commit_msg>devilry_subjectadmin...DeadlinesContainer: Remove log.<commit_after>Ext.define('devilry_subjectadmin.view.managestudents.DeadlinesContainer', {
    extend: 'Ext.panel.Panel',
    alias: 'widget.admingroupinfo_deadlinescontainer',
    cls: 'devilry_subjectadmin_admingroupinfo_deadlinescontainer devilry_discussionview_container',

    requires: [
        'devilry_subjectadmin.view.managestudents.DeadlinePanel',
        'devilry_extjsextras.AlertMessage'
    ],

    frame: false,
    border: false,
    bodyPadding: 0,
    layout: 'anchor',
    defaults: {
        anchor: '100%'
    },

    populate: function(aggregatedGroupInfoRecord, active_feedback) {
        var deadlines = aggregatedGroupInfoRecord.get('deadlines');
        if(deadlines.length == 0) {
            this.add({
                xtype: 'alertmessage',
                type: 'error',
                title: interpolate(gettext('No %(deadlines_term)s'), {
                    deadlines_term: gettext('deadlines')
                }, true),
                message: interpolate(gettext('This group has no %(deadlines_term)s, so they can not add %(deliveries_term)s.'), {
                    deadlines_term: gettext('deadlines'),
                    deliveries_term: gettext('deliveries')
                }, true)
            });
        } else {
            Ext.Array.each(deadlines, function(deadline) {
                this.add({
                    xtype: 'admingroupinfo_deadline',
                    deadline: deadline,
                    active_feedback: active_feedback
                });
            }, this);
        }

    }
});
<|endoftext|>


<commit_before>import { Query } from 'ember-flexberry-data';
import ListFormRoute from 'ember-flexberry/routes/list-form';

export default ListFormRoute.extend({
  /**
    Name of model projection to be used as record's properties limitation.

    @property modelProjection
    @type String
    @default 'SuggestionL'
   */
  modelProjection: 'SuggestionL',

  /**
  developerUserSettings.
  {
  <componentName>: {
    <settingName>: {
        colsOrder: [ { propName :<colName>, hide: true|false }, ... ],
        sorting: [{ propName: <colName>, direction: "asc"|"desc" }, ... ],
        colsWidths: [ <colName>:<colWidth>, ... ],
      },
      ...
    },
    ...
  }
  For default userSetting use empty name ('').
  <componentName> may contain any of properties: colsOrder, sorting, colsWidth or being empty.

  @property developerUserSettings
  @type Object
  @default {}
  */
  developerUserSettings: { FOLVSettingExampleObjectListView: { } },

  /**
    Name of model to be used as list's records types.

    @property modelName
    @type String
    @default 'ember-flexberry-dummy-suggestion'
   */
  modelName: 'ember-flexberry-dummy-suggestion',

  /**
    Returns model related to current route.

    @method model
   */
  model(params) {
    let store = this.get('store');

    let query = new Query.Builder(store)
        .from('ember-flexberry-dummy-suggestion')
        .selectByProjection('SuggestionL');

    let list;
    return this._super(...arguments).then((data) => {
      list = data;

      return store.query('ember-flexberry-dummy-suggestion', query.build()).then((suggestion) => {
        let suggestionArr = suggestion.toArray();
        this.set('configurateRowByAddress', suggestionArr.objectAt(0).get('address'));
        return list;
      });
    });
  },

  /**
    Load limit accessible values.

    @method setupController
   */
  setupController() {
    this._super(...arguments);

    this.set('controller.configurateRowByAddress', this.get('configurateRowByAddress'));
  }
});
<commit_msg>Fix example.<commit_after>import { Query } from 'ember-flexberry-data';
import ListFormRoute from 'ember-flexberry/routes/list-form';

export default ListFormRoute.extend({
  /**
    Name of model projection to be used as record's properties limitation.

    @property modelProjection
    @type String
    @default 'SuggestionL'
   */
  modelProjection: 'SuggestionL',

  /**
  developerUserSettings.
  {
  <componentName>: {
    <settingName>: {
        colsOrder: [ { propName :<colName>, hide: true|false }, ... ],
        sorting: [{ propName: <colName>, direction: "asc"|"desc" }, ... ],
        colsWidths: [ <colName>:<colWidth>, ... ],
      },
      ...
    },
    ...
  }
  For default userSetting use empty name ('').
  <componentName> may contain any of properties: colsOrder, sorting, colsWidth or being empty.

  @property developerUserSettings
  @type Object
  @default {}
  */
  developerUserSettings: { FOLVSettingExampleObjectListView: { } },

  /**
    Name of model to be used as list's records types.

    @property modelName
    @type String
    @default 'ember-flexberry-dummy-suggestion'
   */
  modelName: 'ember-flexberry-dummy-suggestion',

  /**
    Returns model related to current route.

    @method model
   */
  model(params) {

    let store = this.get('store');

    let query = new Query.Builder(store)
      .from('ember-flexberry-dummy-suggestion')
      .selectByProjection('SuggestionE');

    let list;
    return this._super(...arguments).then((data) => {
      list = data;
      return store.query('ember-flexberry-dummy-suggestion', query.build());
    }).then((limitdata) => {
      let limitTypesArr = limitdata.toArray();
      this.set('configurateRowByAddress', limitTypesArr.objectAt(0).get('address'));

      if (this.get('reloadColl') === 1)
      {
        this.refresh();
      }

      return list;
    });
  },

  /**
    Load strings coloring condition in settigs.

    @method setupController
   */
  setupController() {
    this._super(...arguments);

    this.set('controller.configurateRowByAddress', this.get('configurateRowByAddress'));
  }
});
<|endoftext|>


<commit_before>import 'babel-polyfill';

import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'react-redux';
import {Router, Route, IndexRoute, browserHistory} from 'react-router';

import DashboardSubheader from './dashboard/components/subheader';
import Dashboard from './dashboard/components/dashboard';
import CategoriesSubheader from './categories/components/subheader';
import Categories from './categories/components/content';
import ProfileSubheader from './profile/components/subheader';
import Profile from './profile/components/profile';
import AnalyticsSubheader from './analytics/components/subheader';
import Analytics from './analytics/components/analytics';
import TransactionsSubheader from './transactions/components/subheader';
import Transactions from './transactions/components/transactions';
import Layout from './common/components/layout';
import About from './meta/components/about';
import Contact from './meta/components/contact';
import Privacy from './meta/components/privacy';
import Terms from './meta/components/terms';
import store from './redux/store';

const App = React.createClass({
  render() {
    return
Not Found Sorry
;
  }
});

render((
  <Provider store={store}>
    <Router history={browserHistory}>
      <Route path="/" component={Layout}>
        <IndexRoute components={{main: Dashboard, subheader: DashboardSubheader}}/>
        <Route path="/transactions" components={{main: Transactions, subheader: TransactionsSubheader}}/>
        <Route path="/categories" components={{main: Categories, subheader: CategoriesSubheader}}/>
        <Route path="/analytics" components={{main: Analytics, subheader: AnalyticsSubheader}}/>
        <Route path="/profile" components={{main: Profile, subheader: ProfileSubheader}}/>
        <Route path="/contact" components={{main: Contact}}/>
        <Route path="/privacy" components={{main: Privacy}}/>
        <Route path="/about" components={{main: About}}/>
        <Route path="/terms" components={{main: Terms}}/>
        <Route path="*" components={{main: App}}/>
      </Route>
    </Router>
  </Provider>
), document.querySelector('.app-container'));
<commit_msg>Redirect from /dashboard to /<commit_after>import 'babel-polyfill';

import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'react-redux';
import {Router, Route, IndexRoute, browserHistory, Redirect} from 'react-router';

import DashboardSubheader from './dashboard/components/subheader';
import Dashboard from './dashboard/components/dashboard';
import CategoriesSubheader from './categories/components/subheader';
import Categories from './categories/components/content';
import ProfileSubheader from './profile/components/subheader';
import Profile from './profile/components/profile';
import AnalyticsSubheader from './analytics/components/subheader';
import Analytics from './analytics/components/analytics';
import TransactionsSubheader from './transactions/components/subheader';
import Transactions from './transactions/components/transactions';
import Layout from './common/components/layout';
import About from './meta/components/about';
import Contact from './meta/components/contact';
import Privacy from './meta/components/privacy';
import Terms from './meta/components/terms';
import store from './redux/store';

const App = React.createClass({
  render() {
    return
Not Found Sorry
;
  }
});

render((
  <Provider store={store}>
    <Router history={browserHistory}>
      <Route path="/" component={Layout}>
        <IndexRoute components={{main: Dashboard, subheader: DashboardSubheader}}/>
        <Route path="/transactions" components={{main: Transactions, subheader: TransactionsSubheader}}/>
        <Route path="/categories" components={{main: Categories, subheader: CategoriesSubheader}}/>
        <Route path="/analytics" components={{main: Analytics, subheader: AnalyticsSubheader}}/>
        <Route path="/profile" components={{main: Profile, subheader: ProfileSubheader}}/>
        <Route path="/contact" components={{main: Contact}}/>
        <Route path="/privacy" components={{main: Privacy}}/>
        <Route path="/about" components={{main: About}}/>
        <Route path="/terms" components={{main: Terms}}/>
        <Redirect from="/dashboard" to="/" />
        <Route path="*" components={{main: App}}/>
      </Route>
    </Router>
  </Provider>
), document.querySelector('.app-container'));
<|endoftext|>