<commit_before>/**
 * Competence class
 */
function Competence(viewmodel, id, code, name, weight, locked, subcompetences) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: ko.observable(locked),
        subcompetences: ko.observableArray(subcompetences),

        addSubCompetence: function() {
            this.subcompetences.push(new SubCompetence(this));

            /*var total = 100;
            alert(total);
            console.log(this.subcompetences);
            for(var sub in this.subcompetences){
                alert(sub);
                sub.calculateWeight(100);
                total -= sub.weight;
                alert(total);
            }*/
        },

        removeThis: function() {
            viewmodel.removeCompetence(this);
        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        },

        removeSubCompetence: function(subCompetence) {
            this.subcompetences.remove(subCompetence);
        }
    };

}

/**
 * SubCompetence class
 */
function SubCompetence(parent, id, code, name, weight, locked, indicators) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: ko.observable(locked),
        indicators: ko.observableArray(indicators),

        addIndicator: function() {
            this.indicators.push(new Indicator(this));
        },

        /*calculateWeight: function(total){
            this.weight = total;
        },*/

        removeThis: function() {
            parent.removeSubCompetence(this);
        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        },

        removeIndicator: function(indicator) {
            this.indicators.remove(indicator);
        }

    };
}

/**
 * Indicator class
 */
function Indicator(parent, id, name, weight, locked, description) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: ko.observable(locked),
        description : ko.observable(description),

        removeThis: function() {
            parent.removeIndicator(this);
        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        }
    };
}

// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    //gvm.competences = 0;
    gvm.subcomp = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.addCompetenceBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddCompetence");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.competences = ko.observableArray([]);

    gvm.addCompetence = function() {
        gvm.competences.push(new Competence(this));

        // Update automated weight calculation
        var lockedPercent = 0;
        var nrOfUnlocked = 0;

        console.log("Array lenght: " + gvm.competences.length);

        for(var index = 0; index < gvm.competences.length; index++)
        {
            if(gvm.competences[index].locked == true)
            {
                lockedPercent += gvm.competences[index].weight;
            }
            else
            {
                nrOfUnlocked++;
            }
        }
        console.log("Unlocked: " + nrOfUnlocked);
        console.log("Locked Percent: " + lockedPercent);

        var remainingPercent = 100 - lockedPercent;

        var percentPerCompetence = remainingPercent / nrOfUnlocked;

        console.log(percentPerCompetence);

        ko.utils.arrayForEach(gvm.competences, function(competence){
            console.log(competence.weight);
            competence.weight(percent);
        });
    };

    gvm.removeCompetence = function(competence) {
        gvm.competences.remove(competence);
    }

    gvm.updateCompetence = function(id, code, description, max, weight) {
        var comp = new Competence(this, id, code, description, weight);
        gvm.competences.push(comp);
        return comp;
    }

    gvm.clearStructure = function() {
        gvm.competences.destroyAll();
    }
}

/**
 * Push the current project state to the database
 * @returns {undefined}
 */
function saveProjectStructure() {
    $.ajax({
       type: "POST",
       url: "/api/projectstructure/" + projectid,
       data: ko.toJSON(viewModel.competences),
       success: function(){
           // TODO make multilangual and with modals
           alert("Saved projectstructure to server");

           fetchProjectStructure();
       }
    });
}

function fetchProjectStructure() {
    viewModel.clearStructure();

    $.getJSON("/api/projectstructure/" + projectid, function(data){
        $.each(data, function(i, item){
            var competence = viewModel.updateCompetence(item.id, item.code, item.description, item.max, item.weight);

            $.each(item.subcompetences, function(i, subcomp){
               var subcompetence = new SubCompetence(competence, subcomp.id, subcomp.code, subcomp.description, subcomp.weight);
               competence.subcompetences.push(subcompetence);

               $.each(subcomp.indicators, function(i, indic){
                  subcompetence.indicators.push(new Indicator(subcompetence, indic.id, indic.name, indic.description));
               });
            });
        })
    });
}

function initPage() {
    fetchProjectStructure();

    $(".addCompetenceBtn").click(function() {
        viewModel.addCompetence();
    });

    $(".savePageBtn").click(function(){
        saveProjectStructure();
    });
}
<commit_msg>lock icons<commit_after>/**
 * Competence class
 */
function Competence(viewmodel, id, code, name, weight, locked, subcompetences) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: ko.observable(locked),
        subcompetences: ko.observableArray(subcompetences),

        addSubCompetence: function() {
            this.subcompetences.push(new SubCompetence(this));

            /*var total = 100;
            alert(total);
            console.log(this.subcompetences);
            for(var sub in this.subcompetences){
                alert(sub);
                sub.calculateWeight(100);
                total -= sub.weight;
                alert(total);
            }*/
        },

        removeThis: function() {
            viewmodel.removeCompetence(this);
        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        },

        removeSubCompetence: function(subCompetence) {
            this.subcompetences.remove(subCompetence);
        }
    };

}

/**
 * SubCompetence class
 */
function SubCompetence(parent, id, code, name, weight, locked, indicators) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: ko.observable(locked),
        indicators: ko.observableArray(indicators),

        addIndicator: function() {
            this.indicators.push(new Indicator(this));
        },

        /*calculateWeight: function(total){
            this.weight = total;
        },*/

        removeThis: function() {
            parent.removeSubCompetence(this);
        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        },

        removeIndicator: function(indicator) {
            this.indicators.remove(indicator);
        }

    };
}

/**
 * Indicator class
 */
function Indicator(parent, id, name, weight, locked, description) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: ko.observable(locked),
        description : ko.observable(description),

        removeThis: function() {
            parent.removeIndicator(this);
        },

        toggleLock: function(data, event){
            if(this.locked == true)
            {
                $(event.target).addClass("icon-unlock").removeClass("icon-lock");
                this.locked = false;
            }
            else
            {
                $(event.target).addClass("icon-lock").removeClass("icon-unlock");
                this.locked = true;
            }
        }
    };
}

// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    //gvm.competences = 0;
    gvm.subcomp = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.addCompetenceBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddCompetence");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.competences = ko.observableArray([]);

    gvm.addCompetence = function() {
        gvm.competences.push(new Competence(this));

        // Update automated weight calculation
        var lockedPercent = 0;
        var nrOfUnlocked = 0;

        console.log("Array lenght: " + gvm.competences.length);

        for(var index = 0; index < gvm.competences.length; index++)
        {
            if(gvm.competences[index].locked == true)
            {
                lockedPercent += gvm.competences[index].weight;
            }
            else
            {
                nrOfUnlocked++;
            }
        }
        console.log("Unlocked: " + nrOfUnlocked);
        console.log("Locked Percent: " + lockedPercent);

        var remainingPercent = 100 - lockedPercent;

        var percentPerCompetence = remainingPercent / nrOfUnlocked;

        console.log(percentPerCompetence);

        ko.utils.arrayForEach(gvm.competences, function(competence){
            console.log(competence.weight);
            competence.weight(percent);
        });
    };

    gvm.removeCompetence = function(competence) {
        gvm.competences.remove(competence);
    }

    gvm.updateCompetence = function(id, code, description, max, weight) {
        var comp = new Competence(this, id, code, description, weight);
        gvm.competences.push(comp);
        return comp;
    }

    gvm.clearStructure = function() {
        gvm.competences.destroyAll();
    }
}

/**
 * Push the current project state to the database
 * @returns {undefined}
 */
function saveProjectStructure() {
    $.ajax({
       type: "POST",
       url: "/api/projectstructure/" + projectid,
       data: ko.toJSON(viewModel.competences),
       success: function(){
           // TODO make multilangual and with modals
           alert("Saved projectstructure to server");

           fetchProjectStructure();
       }
    });
}

function fetchProjectStructure() {
    viewModel.clearStructure();

    $.getJSON("/api/projectstructure/" + projectid, function(data){
        $.each(data, function(i, item){
            var competence = viewModel.updateCompetence(item.id, item.code, item.description, item.max, item.weight);

            $.each(item.subcompetences, function(i, subcomp){
               var subcompetence = new SubCompetence(competence, subcomp.id, subcomp.code, subcomp.description, subcomp.weight);
               competence.subcompetences.push(subcompetence);

               $.each(subcomp.indicators, function(i, indic){
                  subcompetence.indicators.push(new Indicator(subcompetence, indic.id, indic.name, indic.description));
               });
            });
        })
    });
}

function initPage() {
    fetchProjectStructure();

    $(".addCompetenceBtn").click(function() {
        viewModel.addCompetence();
    });

    $(".savePageBtn").click(function(){
        saveProjectStructure();
    });

    console.log(viewModel.competences);
}
<|endoftext|>


<commit_before>var breadcrumbs = (function() {
    var Dom = YAHOO.util.Dom;

    /**
     * This component actually renders the menu.
     *
     * @type {YAHOO.widget.Menu}
     */
    var menu;

    /**
     * Used for fetching the content of the menu asynchronously from the server
     */
    var xhr;

    /**
     * When mouse hovers over the anchor that has context menu, we capture its region here.
     * This is used to to avoid showing menu when the mouse slides over to other elements after a delay.
     *
     * @type {YAHOO.util.Region}
     */
    var hitTest;

    /**
     * Current mouse cursor position in the page coordinate.
     *
     * @type {YAHOO.util.Point}
     */
    var mouse;

    /**
     * Timer ID for lazy menu display.
     */
    var menuDelay;

    function makeMenuHtml(icon,displayName) {
        return (icon!=null ? " " : "")+displayName;
    }

    Event.observe(window,"load",function(){
      menu = new YAHOO.widget.Menu("breadcrumb-menu", {position:"dynamic", hidedelay:1000});
    });

    Event.observe(window,"mousemove",function (ev){
        mouse = new YAHOO.util.Point(ev.pageX,ev.pageY);
    });

    function cancelMenu() {
        if (menuDelay) {
            window.clearTimeout(menuDelay);
            menuDelay = null;
        }
    }

    function combinePath(a,b) {
        if (a.endsWith('/'))    return a+b;
        return a+'/'+b;
    }

    /**
     * @param {HTMLElement} e
     *      anchor tag
     * @param {Number} delay
     *      Number of milliseconds to wait before the menu is displayed.
     *      The mouse needs to be on the same anchor tag after this delay.
     */
    function handleHover(e,delay) {
        function showMenu(items) {
            cancelMenu();
            hitTest = Dom.getRegion(e);
            menuDelay = window.setTimeout(function() {
                if (hitTest.contains(mouse)) {
                    menu.hide();
                    var pos = [e, "tl", "bl"];
                    if ($(e).hasClassName("tl-tr"))  pos = [e,"tl","tr"]
                    menu.cfg.setProperty("context", pos);
                    menu.clearContent();
                    menu.addItems(items);
                    menu.render("breadcrumb-menu-target");
                    menu.show();
                }
                menuDelay = null;
            },delay);
        }

        if (xhr)
            xhr.options.onComplete = function () {
            };   // ignore the currently pending call

        if (e.items) {// use what's already loaded
            showMenu(e.items());
        } else {// fetch menu on demand
            xhr = new Ajax.Request(combinePath(e.getAttribute("href"),"contextMenu"), {
                onComplete:function (x) {
                    var a = x.responseText.evalJSON().items;
                    a.each(function (e) {
                        e.text = makeMenuHtml(e.icon, e.displayName);
                    });
                    e.items = function() { return a };
                    showMenu(a);
                }
            });
        }

        return false;
    }

    jenkinsRules["#breadcrumbs LI"] = function (e) {
        // when the mouse hovers over LI, activate the menu
        $(e).observe("mouseover", function () { handleHover(e.firstChild,0) });
    };

    jenkinsRules["A.model-link"] = function (a) {
        // ditto for model-link, but give it a larger delay to avoid unintended menus to be displayed
        $(a).observe("mouseover", function () { handleHover(a,500); });
    };

    /**
     * @namespace breadcrumbs
     * @class ContextMenu
     * @constructor
     */
    var ContextMenu = function () {
        this.items = [];
    };
    ContextMenu.prototype = {
        /**
         * Creates a menu item.
         *
         * @return {breadcrumbs.MenuItem}
         */
        "add" : function (url,icon,displayName) {
            this.items.push({ url:url, text:makeMenuHtml(icon,displayName) });
            return this;
        }
    };

    return {
        /**
         * Activates the context menu for the specified breadcrumb element.
         *
         * @param {String|HTMLElement} li
         *      The LI tag to which you associate the menu (or its ID)
         * @param {Function|breadcrumbs.ContextMenu} menu
         *      Pass in the configured menu object. If a function is given, this function
         *      is called each time a menu needs to be displayed. This is convenient for dynamically
         *      populating the content.
         */
        "attachMenu" : function (li,menu) {
            $(li).firstChild.items =  (typeof menu=="function") ? menu : function() { return menu.items };
        },

        "ContextMenu" : ContextMenu
    };
})();
<commit_msg>Cheaper handling of query string / fragment identifier.<commit_after>var breadcrumbs = (function() {
    var Dom = YAHOO.util.Dom;

    /**
     * This component actually renders the menu.
     *
     * @type {YAHOO.widget.Menu}
     */
    var menu;

    /**
     * Used for fetching the content of the menu asynchronously from the server
     */
    var xhr;

    /**
     * When mouse hovers over the anchor that has context menu, we capture its region here.
     * This is used to to avoid showing menu when the mouse slides over to other elements after a delay.
     *
     * @type {YAHOO.util.Region}
     */
    var hitTest;

    /**
     * Current mouse cursor position in the page coordinate.
     *
     * @type {YAHOO.util.Point}
     */
    var mouse;

    /**
     * Timer ID for lazy menu display.
     */
    var menuDelay;

    function makeMenuHtml(icon,displayName) {
        return (icon!=null ? " " : "")+displayName;
    }

    Event.observe(window,"load",function(){
      menu = new YAHOO.widget.Menu("breadcrumb-menu", {position:"dynamic", hidedelay:1000});
    });

    Event.observe(window,"mousemove",function (ev){
        mouse = new YAHOO.util.Point(ev.pageX,ev.pageY);
    });

    function cancelMenu() {
        if (menuDelay) {
            window.clearTimeout(menuDelay);
            menuDelay = null;
        }
    }

    function combinePath(a,b) {
        var qs;
        var i = a.indexOf('?');
        if (i>=0)  { qs=a.substring(i); a=a.substring(0,i); }
        else        qs="";

        i=a.indexOf('#');
        if (i>=0)   a=a.substring(0,i);

        if (a.endsWith('/'))    return a+b+qs;
        return a+'/'+b+qs;
    }

    /**
     * @param {HTMLElement} e
     *      anchor tag
     * @param {Number} delay
     *      Number of milliseconds to wait before the menu is displayed.
     *      The mouse needs to be on the same anchor tag after this delay.
     */
    function handleHover(e,delay) {
        function showMenu(items) {
            cancelMenu();
            hitTest = Dom.getRegion(e);
            menuDelay = window.setTimeout(function() {
                if (hitTest.contains(mouse)) {
                    menu.hide();
                    var pos = [e, "tl", "bl"];
                    if ($(e).hasClassName("tl-tr"))  pos = [e,"tl","tr"]
                    menu.cfg.setProperty("context", pos);
                    menu.clearContent();
                    menu.addItems(items);
                    menu.render("breadcrumb-menu-target");
                    menu.show();
                }
                menuDelay = null;
            },delay);
        }

        if (xhr)
            xhr.options.onComplete = function () {
            };   // ignore the currently pending call

        if (e.items) {// use what's already loaded
            showMenu(e.items());
        } else {// fetch menu on demand
            xhr = new Ajax.Request(combinePath(e.getAttribute("href"),"contextMenu"), {
                onComplete:function (x) {
                    var a = x.responseText.evalJSON().items;
                    a.each(function (e) {
                        e.text = makeMenuHtml(e.icon, e.displayName);
                    });
                    e.items = function() { return a };
                    showMenu(a);
                }
            });
        }

        return false;
    }

    jenkinsRules["#breadcrumbs LI"] = function (e) {
        // when the mouse hovers over LI, activate the menu
        $(e).observe("mouseover", function () { handleHover(e.firstChild,0) });
    };

    jenkinsRules["A.model-link"] = function (a) {
        // ditto for model-link, but give it a larger delay to avoid unintended menus to be displayed
        $(a).observe("mouseover", function () { handleHover(a,500); });
    };

    /**
     * @namespace breadcrumbs
     * @class ContextMenu
     * @constructor
     */
    var ContextMenu = function () {
        this.items = [];
    };
    ContextMenu.prototype = {
        /**
         * Creates a menu item.
         *
         * @return {breadcrumbs.MenuItem}
         */
        "add" : function (url,icon,displayName) {
            this.items.push({ url:url, text:makeMenuHtml(icon,displayName) });
            return this;
        }
    };

    return {
        /**
         * Activates the context menu for the specified breadcrumb element.
         *
         * @param {String|HTMLElement} li
         *      The LI tag to which you associate the menu (or its ID)
         * @param {Function|breadcrumbs.ContextMenu} menu
         *      Pass in the configured menu object. If a function is given, this function
         *      is called each time a menu needs to be displayed. This is convenient for dynamically
         *      populating the content.
         */
        "attachMenu" : function (li,menu) {
            $(li).firstChild.items =  (typeof menu=="function") ? menu : function() { return menu.items };
        },

        "ContextMenu" : ContextMenu
    };
})();
<|endoftext|>


<commit_before>import Restle from '../../../dist/lib';
import Promise from 'bluebird';
import test from 'tape';
import schemas from '../fixtures/restle-schemas';

import adapter from './adapter';
import model from './model';
import router from './router';

const app = new Restle({ namespace: 'api', port: 1337 });

app.register({
  person: schemas.person,
  animal: schemas.animal,
  building: schemas.building,
  habitat: schemas.habitat,
  company: schemas.company,
  country: schemas.country,
});

app.on('ready', () => {
  console.log('App is ready!');

  // adapter -> model -> router
  test('adapter tests', t => {
    const models = {
      person: app.model('person'),
      animal: app.model('animal'),
      building: app.model('building'),
      habitat: app.model('habitat'),
      company: app.model('company'),
      country: app.model('country'),
    };

    adapter(t, app, models).then(success => {
      t.ok(success, 'adapter tests were successful');
      t.end();
    });
  });

  test('model tests', t => {
    model(t, app).then(success => {
      t.ok(success, 'model tests were successful');
      t.end();
    });
  });

  test('router tests', t => {
    router(t, app).then(success => {
      t.ok(success, 'router tests were successful');
      t.end();
    });
  });

  test('teardown', t => {
    app.disconnect().then(() => {
      t.pass('app disconnected');
      t.end();
    });
  });
});
<commit_msg>Simplify schema registration<commit_after>import Restle from '../../../dist/lib';
import Promise from 'bluebird';
import test from 'tape';
import schemas from '../fixtures/restle-schemas';

import adapter from './adapter';
import model from './model';
import router from './router';

const app = new Restle({ namespace: 'api', port: 1337 });

app.register(schemas);

app.on('ready', () => {
  console.log('App is ready!');

  // adapter -> model -> router
  test('adapter tests', t => {
    const models = {
      person: app.model('person'),
      animal: app.model('animal'),
      building: app.model('building'),
      habitat: app.model('habitat'),
      company: app.model('company'),
      country: app.model('country'),
    };

    adapter(t, app, models).then(success => {
      t.ok(success, 'adapter tests were successful');
      t.end();
    });
  });

  test('model tests', t => {
    model(t, app).then(success => {
      t.ok(success, 'model tests were successful');
      t.end();
    });
  });

  test('router tests', t => {
    router(t, app).then(success => {
      t.ok(success, 'router tests were successful');
      t.end();
    });
  });

  test('teardown', t => {
    app.disconnect().then(() => {
      t.pass('app disconnected');
      t.end();
    });
  });
});
<|endoftext|>


<commit_before>define(['angular', 'rarity/rarity-def'], function (angular, rarityModule) {

    'use strict';

    rarityModule.controller('RarityEditCtrl', [
        '$scope', '$state', '$log', 'Restangular', 'RarityService',
        function ($scope, $state, $log, Restangular, RarityService) {

            var self = this;

            RarityService.read($state.params.id).then(function (rarity) {
                self.originalUser = rarity;
                $scope.rarity = Restangular.copy(self.originalUser);
            });

            $scope.isNotDirty = function () {
                return angular.equals(self.originalUser, $scope.rarity);
            };

            $scope.save = function () {
                RarityService.update($scope.rarity)
                    .then(function () {
                        //RarityService.showList();
                    }, function (response) {
                        if (response.status === 422) {
                            $scope.errors = response.data;
                        }
                        else {
                            // TODO show error message
                            $log.error('error updating rarity');
                        }
                    });
            };

            $scope.cancel = function () {
                RarityService.showList();
            };

        }]);

});<commit_msg>re add navigation rule after editing a rarity<commit_after>define(['angular', 'rarity/rarity-def'], function (angular, rarityModule) {

    'use strict';

    rarityModule.controller('RarityEditCtrl', [
        '$scope', '$state', '$log', 'Restangular', 'RarityService',
        function ($scope, $state, $log, Restangular, RarityService) {

            var self = this;

            RarityService.read($state.params.id).then(function (rarity) {
                self.originalUser = rarity;
                $scope.rarity = Restangular.copy(self.originalUser);
            });

            $scope.isNotDirty = function () {
                return angular.equals(self.originalUser, $scope.rarity);
            };

            $scope.save = function () {
                RarityService.update($scope.rarity)
                    .then(function () {
                        RarityService.showList();
                    }, function (response) {
                        if (response.status === 422) {
                            $scope.errors = response.data;
                        }
                        else {
                            // TODO show error message
                            $log.error('error updating rarity');
                        }
                    });
            };

            $scope.cancel = function () {
                RarityService.showList();
            };

        }]);

});<|endoftext|>


<commit_before>window.fakeStorage = {
  _data: {},

  setItem: function (id, val) {
    return this._data[id] = String(val);
  },

  getItem: function (id) {
    return this._data.hasOwnProperty(id) ? this._data[id] : undefined;
  },

  removeItem: function (id) {
    return delete this._data[id];
  },

  clear: function () {
    return this._data = {};
  }
};

function LocalScoreManager() {
  var localSupported = !!window.localStorage;

  this.key     = "bestScore";
  this.storage = localSupported ? window.localStorage : window.fakeStorage;
}

LocalScoreManager.prototype.get = function () {
  return this.storage.getItem(this.key) || 0;
};

LocalScoreManager.prototype.set = function (score) {
  this.storage.setItem(this.key, score);
};

<commit_msg>adding a test to verify the localStorage is supported fixing a bug on private browsing on safari<commit_after>window.fakeStorage = {
  _data: {},

  setItem: function (id, val) {
    return this._data[id] = String(val);
  },

  getItem: function (id) {
    return this._data.hasOwnProperty(id) ? this._data[id] : undefined;
  },

  removeItem: function (id) {
    return delete this._data[id];
  },

  clear: function () {
    return this._data = {};
  }
};

function isLocalStorageNameSupported()
{
  var testKey = 'test', storage = window.localStorage;
  try {
    storage.setItem(testKey, '1');
    storage.removeItem(testKey);
    return true;
  }
  catch (error) {
    return false;
  }
}

function LocalScoreManager() {
  var localSupported = isLocalStorageNameSupported();
  this.key     = "bestScore";
  this.storage = localSupported ? window.localStorage : window.fakeStorage;
}

LocalScoreManager.prototype.get = function () {
  return this.storage.getItem(this.key) || 0;
};

LocalScoreManager.prototype.set = function (score) {
  this.storage.setItem(this.key, score);
};

<|endoftext|>


<commit_before>const
  fs = require('fs'),
  test = require('ava'),
  TeleBot = require('../lib/telebot.js');

// Globals
var bot;

// Enviroment data

let {
  TEST_TELEBOT_TOKEN: TOKEN,
  TEST_TELEBOT_USER: USER
} = process.env;

test('bot environment', t => {

  t.true(!!TOKEN, 'TEST_TELEBOT_TOKEN required');
  t.true(!!USER, 'TEST_TELEBOT_USER required');

});

test('bot object', t => {

  const newSet = {
    token: TOKEN,
    polling: {
      interval: 100,
      limit: 50,
      timeout: 0,
      retryTimeout: 5000
    }
  };

  const oldSet = {
    token: TOKEN,
    limit: 30,
    sleep: 500,
    timeout: 100,
    retryTimeout: 10000
  };

  function check(bot) {
    t.is(bot.token, TOKEN);
    t.is(bot.id, TOKEN.split(':')[0]);
  }

  // Check new objects
  check(new TeleBot(TOKEN));

  // Old set
  check(bot = new TeleBot(oldSet));

  for (let name in oldSet) {
    if (name == 'sleep') {
      t.is(bot.interval, oldSet.sleep);
      continue;
    };
    t.is(bot[name], oldSet[name]);
  }

  // New set
  check(bot = new TeleBot(newSet));

  for (let name in newSet.polling) {
    t.is(bot[name], newSet.polling[name]);
  }

  // Connect
  bot.connect();
  t.not(bot.loopFn, null);
  t.deepEqual(bot.flags, { looping: true, poll: false, retry: false });

  // Disconnect
  bot.disconnect();
  t.false(bot.flags.looping);

});

test('events', t => {

  t.plan(9);

  function len(event) {
    return bot.eventList[event].list.length;
  }

  var delMe = x => {};

  t.is(all(bot.eventList), 2);

  // Set
  bot.on('connect', x => {});
  bot.on('connect', delMe);
  bot.on('custom', x => {});
  bot.on('custom', x => {});

  // Count
  t.is(len('custom'), 2);
  t.is(len('connect'), 2);
  t.is(all(bot.eventList), 3);

  // Remove
  t.true(bot.removeEvent('connect', delMe));
  t.is(len('connect'), 1);

  // Clean
  t.true(bot.cleanEvent('custom'));

  // Destroy
  t.true(bot.destroyEvent('custom'));
  t.is(all(bot.eventList), 2);

});

test('mods', t => {

  function len(event) {
    return bot.modList[event].length;
  }

  var delMe = x => x;

  t.is(all(bot.modList), 0);

  // Set
  bot.mod('custom', x => ++x);
  bot.mod('custom', x => ++x);
  bot.mod('custom', delMe);
  bot.mod('custom', x => ++x);

  // Count
  t.is(len('custom'), 4);
  t.is(all(bot.modList), 1);

  // Run
  t.is(bot.modRun('custom', 5), 8);

  // Remove
  t.true(bot.removeMod('custom', delMe));
  t.false(bot.removeMod('custom'));
  t.false(bot.removeMod('not_found'));

  t.is(len('custom'), 3);
  t.is(all(bot.modList), 1);

});

test('bot.answerList', t => {

  const id = 8;

  const opt = {
    cacheTime: 200,
    nextOffset: 3457,
    personal: true
  };

  const answers = bot.answerList(id, opt);

  t.is(answers.id, id);

  for (let key in opt) {
    t.is(answers[key], opt[key]);
  }

});

test('bot.getMe', t => {
  return bot.getMe().then(re => {
    t.true(re.ok && re.result.id == bot.id);
  });
});

test('bot.sendMessage', t => {
  let str = '#hello_test';
  return bot.sendMessage(USER, str).then(re => {
    t.true(re.ok && re.result.text == str);
  });
});

const sendMethods = {
  sendPhoto: {
    'url': 'https://telegram.org/img/t_logo.png',
    'buffer': fs.readFileSync(`${__dirname}/data/image.jpg`),
    'file system': `${__dirname}/data/image.jpg`
  },
  sendAudio: {
    'buffer': fs.readFileSync(`${__dirname}/data/audio.mp3`),
    'file system': `${__dirname}/data/audio.mp3`
  },
  sendDocument: {
    'url': 'http://www.google.com/humans.txt',
    'buffer': fs.readFileSync(`${__dirname}/data/file.txt`),
    'file system': `${__dirname}/data/file.txt`
  },
  sendSticker: {
    'url': 'http://www.gstatic.com/webp/gallery/1.webp',
    'buffer': fs.readFileSync(`${__dirname}/data/sticker.webp`),
    'file system': `${__dirname}/data/sticker.webp`
  },
  sendVideo: {
    'buffer': fs.readFileSync(`${__dirname}/data/video.mp4`),
    'file system': `${__dirname}/data/video.mp4`
  },
  sendVoice: {
    'buffer': fs.readFileSync(`${__dirname}/data/voice.m4a`),
    'file system': `${__dirname}/data/voice.m4a`
  }
}

for (let method in sendMethods) {
  let data = sendMethods[method];
  test(`bot.${ method }`, t => {
    for (let name in data) {
      bot[method](USER, data[name]).then(re => t.true(re.ok));
    }
  });
}

test('bot.sendLocation', t => {
  let loc = [37.641401, -115.783262];
  return bot.sendLocation(USER, loc).then(re => {
    t.true(re.ok);
    t.deepEqual(re.result.location, { latitude: loc[0], longitude: loc[1] });
  });
});

test('bot.sendVenue', t => {
  return bot.sendVenue(USER,  [56.9713962, 23.9890801], 'A', 'B').then(re => {
    t.truthy(re.ok && re.result.venue);
  });
});

test('bot.sendContact', t => {
  return bot.sendContact(USER, '112', 'First', 'Last').then(re => {
    t.truthy(re.ok && re.result.contact);
  });
});

test('bot.sendAction', t => {
  return bot.sendAction(USER, 'typing').then(re => {
    t.true(re.ok && re.result == true);
  });
});

test('bot.editText', t => {
  return bot.sendMessage(USER, 'text').then(re => {
    const chatId = USER;
    const messageId = re.result.message_id;
    return bot.editText({ chatId, messageId }, 'text OK');
  });
});

test('bot.editCaption', t => {
  const photo = 'https://telegram.org/img/tl_card_destruct.gif';
  return bot.sendPhoto(USER, photo, { caption: 'caption' }).then(re => {
    const chatId = USER;
    const messageId = re.result.message_id;
    return bot.editCaption({ chatId, messageId }, 'caption OK');
  });
});

test('bot.editMarkup', t => {
  let markup = bot.inlineKeyboard([
    [ bot.inlineButton('test', { callback: 1 }) ]
  ]);
  return bot.sendMessage(USER, 'markup', { markup }).then(re => {
    const chatId = USER;
    const messageId = re.result.message_id;
    markup = bot.inlineKeyboard([[bot.inlineButton('OK', { callback: 2 })]]);
    return bot.editMarkup({ chatId, messageId }, markup);
  });
});

// Functions

function all(obj) {
  return Object.keys(obj).length;
}
<commit_msg>Fix getMe test case<commit_after>const
  fs = require('fs'),
  test = require('ava'),
  TeleBot = require('../lib/telebot.js');

// Globals
var bot;

// Enviroment data

let {
  TEST_TELEBOT_TOKEN: TOKEN,
  TEST_TELEBOT_USER: USER
} = process.env;

test('bot environment', t => {

  t.true(!!TOKEN, 'TEST_TELEBOT_TOKEN required');
  t.true(!!USER, 'TEST_TELEBOT_USER required');

});

test('bot object', t => {

  const newSet = {
    token: TOKEN,
    polling: {
      interval: 100,
      limit: 50,
      timeout: 0,
      retryTimeout: 5000
    }
  };

  const oldSet = {
    token: TOKEN,
    limit: 30,
    sleep: 500,
    timeout: 100,
    retryTimeout: 10000
  };

  function check(bot) {
    t.is(bot.token, TOKEN);
    t.is(bot.id, TOKEN.split(':')[0]);
  }

  // Check new objects
  check(new TeleBot(TOKEN));

  // Old set
  check(bot = new TeleBot(oldSet));

  for (let name in oldSet) {
    if (name == 'sleep') {
      t.is(bot.interval, oldSet.sleep);
      continue;
    };
    t.is(bot[name], oldSet[name]);
  }

  // New set
  check(bot = new TeleBot(newSet));

  for (let name in newSet.polling) {
    t.is(bot[name], newSet.polling[name]);
  }

  // Connect
  bot.connect();
  t.not(bot.loopFn, null);
  t.deepEqual(bot.flags, { looping: true, poll: false, retry: false });

  // Disconnect
  bot.disconnect();
  t.false(bot.flags.looping);

});

test('events', t => {

  t.plan(9);

  function len(event) {
    return bot.eventList[event].list.length;
  }

  var delMe = x => {};

  t.is(all(bot.eventList), 2);

  // Set
  bot.on('connect', x => {});
  bot.on('connect', delMe);
  bot.on('custom', x => {});
  bot.on('custom', x => {});

  // Count
  t.is(len('custom'), 2);
  t.is(len('connect'), 2);
  t.is(all(bot.eventList), 3);

  // Remove
  t.true(bot.removeEvent('connect', delMe));
  t.is(len('connect'), 1);

  // Clean
  t.true(bot.cleanEvent('custom'));

  // Destroy
  t.true(bot.destroyEvent('custom'));
  t.is(all(bot.eventList), 2);

});

test('mods', t => {

  function len(event) {
    return bot.modList[event].length;
  }

  var delMe = x => x;

  t.is(all(bot.modList), 0);

  // Set
  bot.mod('custom', x => ++x);
  bot.mod('custom', x => ++x);
  bot.mod('custom', delMe);
  bot.mod('custom', x => ++x);

  // Count
  t.is(len('custom'), 4);
  t.is(all(bot.modList), 1);

  // Run
  t.is(bot.modRun('custom', 5), 8);

  // Remove
  t.true(bot.removeMod('custom', delMe));
  t.false(bot.removeMod('custom'));
  t.false(bot.removeMod('not_found'));

  t.is(len('custom'), 3);
  t.is(all(bot.modList), 1);

});

test('bot.answerList', t => {

  const id = 8;

  const opt = {
    cacheTime: 200,
    nextOffset: 3457,
    personal: true
  };

  const answers = bot.answerList(id, opt);

  t.is(answers.id, id);

  for (let key in opt) {
    t.is(answers[key], opt[key]);
  }

});

test('bot.getMe', t => {
  return bot.getMe().then(data => {
    t.true(data && data.id == bot.id);
  });
});

test('bot.sendMessage', t => {
  let str = '#hello_test';
  return bot.sendMessage(USER, str).then(re => {
    t.true(re.ok && re.result.text == str);
  });
});

const sendMethods = {
  sendPhoto: {
    'url': 'https://telegram.org/img/t_logo.png',
    'buffer': fs.readFileSync(`${__dirname}/data/image.jpg`),
    'file system': `${__dirname}/data/image.jpg`
  },
  sendAudio: {
    'buffer': fs.readFileSync(`${__dirname}/data/audio.mp3`),
    'file system': `${__dirname}/data/audio.mp3`
  },
  sendDocument: {
    'url': 'http://www.google.com/humans.txt',
    'buffer': fs.readFileSync(`${__dirname}/data/file.txt`),
    'file system': `${__dirname}/data/file.txt`
  },
  sendSticker: {
    'url': 'http://www.gstatic.com/webp/gallery/1.webp',
    'buffer': fs.readFileSync(`${__dirname}/data/sticker.webp`),
    'file system': `${__dirname}/data/sticker.webp`
  },
  sendVideo: {
    'buffer': fs.readFileSync(`${__dirname}/data/video.mp4`),
    'file system': `${__dirname}/data/video.mp4`
  },
  sendVoice: {
    'buffer': fs.readFileSync(`${__dirname}/data/voice.m4a`),
    'file system': `${__dirname}/data/voice.m4a`
  }
}

for (let method in sendMethods) {
  let data = sendMethods[method];
  test(`bot.${ method }`, t => {
    for (let name in data) {
      bot[method](USER, data[name]).then(re => t.true(re.ok));
    }
  });
}

test('bot.sendLocation', t => {
  let loc = [37.641401, -115.783262];
  return bot.sendLocation(USER, loc).then(re => {
    t.true(re.ok);
    t.deepEqual(re.result.location, { latitude: loc[0], longitude: loc[1] });
  });
});

test('bot.sendVenue', t => {
  return bot.sendVenue(USER,  [56.9713962, 23.9890801], 'A', 'B').then(re => {
    t.truthy(re.ok && re.result.venue);
  });
});

test('bot.sendContact', t => {
  return bot.sendContact(USER, '112', 'First', 'Last').then(re => {
    t.truthy(re.ok && re.result.contact);
  });
});

test('bot.sendAction', t => {
  return bot.sendAction(USER, 'typing').then(re => {
    t.true(re.ok && re.result == true);
  });
});

test('bot.editText', t => {
  return bot.sendMessage(USER, 'text').then(re => {
    const chatId = USER;
    const messageId = re.result.message_id;
    return bot.editText({ chatId, messageId }, 'text OK');
  });
});

test('bot.editCaption', t => {
  const photo = 'https://telegram.org/img/tl_card_destruct.gif';
  return bot.sendPhoto(USER, photo, { caption: 'caption' }).then(re => {
    const chatId = USER;
    const messageId = re.result.message_id;
    return bot.editCaption({ chatId, messageId }, 'caption OK');
  });
});

test('bot.editMarkup', t => {
  let markup = bot.inlineKeyboard([
    [ bot.inlineButton('test', { callback: 1 }) ]
  ]);
  return bot.sendMessage(USER, 'markup', { markup }).then(re => {
    const chatId = USER;
    const messageId = re.result.message_id;
    markup = bot.inlineKeyboard([[bot.inlineButton('OK', { callback: 2 })]]);
    return bot.editMarkup({ chatId, messageId }, markup);
  });
});

// Functions

function all(obj) {
  return Object.keys(obj).length;
}
<|endoftext|>


<commit_before>if (typeof exports == 'object' && exports) //This is a module, XHR support.
{
    var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; //Using xmlhttprequest 1.4.0 https://github.com/driverdan/node-XMLHttpRequest
}

var HTTPRequest = {
    //Public
    version: '0.0.1',
    defaultUA: 'HTTPRequest JS',
    post: function (url, data, callback, options)
    {
        var parameters = {
            METHOD: 'POST'
        };

        var request_parms = this._mergeobjs(options, parameters);

        callback('later');
    },
    get: function (url, callback, options)
    {
        var parameters = {
            METHOD: 'GET'
        };

        var request_parms = this._mergeobjs(options, parameters);

       	this.request(url, request_parms, callback);
    },
    request: function (url, parameters, callback)
    {
    	parameters = this._key2lower(parameters);

    	if (typeof parameters.useragent == 'undefined')
    	{
    		parameters.useragent = this._GetUA();
    	}

    	if (typeof parameters.method == 'undefined')
    	{
    		parameters.method = 'GET';
    	}

    	//Start request here...

        callback('callback from req');
    },
    encode: function (url)
    {
        return 'later!';
    },
    decode: function (url)
    {
        return 'later!';
    },
    //Private
    _GetUA: function()
    {
    	var temp_defaultUA = this.defaultUA + '/' + this.version;
    	if (typeof navigator == 'undefined')
    	{
    		return temp_defaultUA;
    	}
    	else
    	{
    		if (typeof navigator.userAgent == 'undefined')
   			{
	    		return temp_defaultUA;
	    	}
	    	else
	    	{
	    		return navigator.userAgent;
	    	}
    	}
    },
    _key2lower: function (obj)
    {
        if (typeof obj === 'object')
        {
            var newobj = {};
            for (var attrname in obj)
            {
                newobj[attrname.toLowerCase()] = obj[attrname];
            }
            return newobj;
        }
        else
        {
            return {};
        }
    },
    _mergeobjs: function (obj1, obj2)
    {
        //Make sure they are objects!
        if (typeof obj1 != 'object')
        {
            obj1 = {};
        }

        if (typeof obj2 != 'object')
        {
            obj2 = {};
        }
        //Merge
        var obj3 = {};
        for (var attrname in obj1)
        {
            obj3[attrname] = obj1[attrname];
        }
        for (var attrname in obj2)
        {
            obj3[attrname] = obj2[attrname];
        }
        return obj3;
    }
};

// Make a Node module, if possible.
if (typeof exports == 'object' && exports)
{
    module.exports = HTTPRequest;
}<commit_msg>_getXHR function!<commit_after>var HTTPRequest = {
    //Public
    version: '0.0.1',
    defaultUA: 'HTTPRequest JS',
    post: function (url, data, callback, options)
    {
        var parameters = {
            METHOD: 'POST'
        };

        var request_parms = this._mergeobjs(options, parameters);

        callback('later');
    },
    get: function (url, callback, options)
    {
        var parameters = {
            METHOD: 'GET'
        };

        var request_parms = this._mergeobjs(options, parameters);

        this.request(url, request_parms, callback);
    },
    request: function (url, parameters, callback)
    {
        parameters = this._key2lower(parameters);

        if (typeof parameters.useragent == 'undefined')
        {
            parameters.useragent = this._GetUA();
        }

        if (typeof parameters.method == 'undefined')
        {
            parameters.method = 'GET';
        }

        var xhr = this._getXHR();
        if (xhr == null) //NO XHR :(
        {
            callback(0); //return an error code zero
        }
        else
        {
            console.log(xhr);
            callback('callback from req');
        }

    },
    encode: function (url)
    {
        return 'later!';
    },
    decode: function (url)
    {
        return 'later!';
    },
    //Private
    _getXHR: function ()
    {
        if (typeof exports == 'object' && exports) //This is a module, require XHR support.
        {
            XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; //Using xmlhttprequest 1.4.0 https://github.com/driverdan/node-XMLHttpRequest
            return XMLHttpRequest;
        }
        else //Thanks http://www.webmasterworld.com/javascript/4027629.htm
        {
            if (window.XMLHttpRequest)
            {
                // Chrome, Firefox, IE7+, Opera, Safari
                return new XMLHttpRequest();
            }
            // IE6
            try
            {
                // The latest stable version. It has the best security, performance,
                // reliability, and W3C conformance. Ships with Vista, and available
                // with other OS's via downloads and updates.
                return new ActiveXObject('MSXML2.XMLHTTP.6.0');
            }
            catch (e)
            {
                try
                {
                    // The fallback.
                    return new ActiveXObject('MSXML2.XMLHTTP.3.0');
                }
                catch (e) //This browser is not AJAX enabled.
                {
                    return null;
                }
            }
        }
    },
    _GetUA: function ()
    {
        var temp_defaultUA = this.defaultUA + '/' + this.version;
        if (typeof navigator == 'undefined')
        {
            return temp_defaultUA;
        }
        else
        {
            if (typeof navigator.userAgent == 'undefined')
            {
                return temp_defaultUA;
            }
            else
            {
                return navigator.userAgent;
            }
        }
    },
    _key2lower: function (obj)
    {
        if (typeof obj === 'object')
        {
            var newobj = {};
            for (var attrname in obj)
            {
                newobj[attrname.toLowerCase()] = obj[attrname];
            }
            return newobj;
        }
        else
        {
            return {};
        }
    },
    _mergeobjs: function (obj1, obj2)
    {
        //Make sure they are objects!
        if (typeof obj1 != 'object')
        {
            obj1 = {};
        }

        if (typeof obj2 != 'object')
        {
            obj2 = {};
        }
        //Merge
        var obj3 = {};
        for (var attrname in obj1)
        {
            obj3[attrname] = obj1[attrname];
        }
        for (var attrname in obj2)
        {
            obj3[attrname] = obj2[attrname];
        }
        return obj3;
    }
};

// Make a Node module, if possible.
if (typeof exports == 'object' && exports)
{
    module.exports = HTTPRequest;
}<|endoftext|>


<commit_before>import _ from 'lodash'
import { TwitterClient } from '../../modules/twitter'

const defaultGetParams = {
  include_entities: true,
  tweet_mode: 'extended',
  count: 200
}

const state = {
  me: {},
  lists: [],
  listId: '',
  tweetedIdStr: [],
  timeline: [],
  mentions: [],
  favorites: [],
  listsStatuses: []
}

const mutations = {
  ADD_ME (state, me) {
    state.me = me
  },
  ADD_LISTS (state, lists) {
    state.lists = lists
  },
  ADD_TIMELINE (state, tweets) {
    state.timeline = tweets.concat(state.timeline)
  },
  DELETE_TWEET (state, idx) {
    state.timeline.splice(idx, 1)
  },
  ADD_TWEETED_ID_STR (state, idStr) {
    state.tweetedIdStr.push(idStr)
  },
  REMOVE_TWEETS (state) {
    state.tweetedIdStr.forEach((idStr) => {
      state.timeline.splice(state.timeline.findIndex(TwitterClient.findItem, idStr), 1)
    })
    state.tweetedIdStr = []
  },
  ADD_MENTIONS (state, tweets) {
    state.mentions = tweets.concat(state.mentions)
  },
  ADD_FAVORITES (state, tweets) {
    state.favorites = tweets.concat(state.favorites)
  },
  ADD_LISTS_STATUSES (state, tweets) {
    state.listsStatuses = tweets.concat(state.listsStatuses)
  },
  UPDATE_FAVORITED (state, {idx, favorited}) {
    state.timeline[idx].favorited = favorited
  },
  UPDATE_RETWEETED (state, {idx, retweeted}) {
    state.timeline[idx].retweeted = retweeted
  }
}

const actions = {
  fetchAccount ({ commit }) {
    TwitterClient.fetchAccount()
      .then((user) => {
        commit('ADD_ME', user)
      })
  },
  fetchLists ({ commit }) {
    TwitterClient.fetchLists()
      .then((lists) => {
        commit('ADD_LISTS', lists)
      })
  },
  fetchTimeline ({ commit }) {
    commit('REMOVE_TWEETS')
    const params = _.cloneDeep(defaultGetParams)
    if (state.timeline.length > 0) {
      params.since_id = state.timeline[0].id_str
    }
    TwitterClient.fetchTweets('statuses/home_timeline', params)
      .then((tweets) => {
        if (tweets.length > 0) {
          commit('ADD_TIMELINE', tweets)
        }
      })
  },
  addTimeline ({ commit }, tweet) {
    commit('ADD_TIMELINE', [TwitterClient.parseTweet(tweet)])
    commit('ADD_TWEETED_ID_STR', tweet.id_str)
  },
  remoteTweets ({ commit }) {
    commit('REMOVE_TWEETS')
  },
  deleteTweet ({ commit }, idStr) {
    commit('DELETE_TWEET', state.timeline.findIndex(TwitterClient.findItem, idStr))
  },
  fetchMentions ({ commit }) {
    const params = _.cloneDeep(defaultGetParams)
    if (state.mentions.length > 0) {
      params.since_id = state.mentions[0].id_str
    }
    TwitterClient.fetchTweets('statuses/mentions_timeline', params)
      .then((tweets) => {
        if (tweets.length > 0) {
          commit('ADD_MENTIONS', tweets)
        }
      })
  },
  fetchFavorites ({ commit }) {
    const params = _.cloneDeep(defaultGetParams)
    if (state.favorites.length > 0) {
      params.since_id = state.favorites[0].id_str
    }
    TwitterClient.fetchTweets('favorites/list', params)
      .then((tweets) => {
        if (tweets.length > 0) {
          commit('ADD_FAVORITES', tweets)
        }
      })
  },
  fetchListsStatuses ({ commit }) {
    const params = _.cloneDeep(defaultGetParams)
    if (state.listsStatuses.length > 0) {
      params.list_id = state.listId
    }
    TwitterClient.fetchTweets('lists/statuses', params)
      .then((tweets) => {
        if (tweets.length > 0) {
          commit('ADD_LISTS_STATUSES', tweets)
        }
      })
  },
  updateFavorited ({ commit }, {idStr, favorited}) {
    commit('UPDATE_FAVORITED', {
      idx: state.timeline.findIndex(TwitterClient.findItem, idStr),
      favorited: favorited
    })
  },
  updateRetweeted ({ commit }, {idStr, retweeted}) {
    commit('UPDATE_RETWEETED', {
      idx: state.timeline.findIndex(TwitterClient.findItem, idStr),
      retweeted: retweeted
    })
  }
}

export default {
  state,
  mutations,
  actions
}
<commit_msg>Fixed params<commit_after>import _ from 'lodash'
import { TwitterClient } from '../../modules/twitter'

const defaultGetParams = {
  include_entities: true,
  tweet_mode: 'extended',
  count: 200
}

const state = {
  me: {},
  lists: [],
  listId: '',
  tweetedIdStr: [],
  timeline: [],
  mentions: [],
  favorites: [],
  listsStatuses: []
}

const mutations = {
  ADD_ME (state, me) {
    state.me = me
  },
  ADD_LISTS (state, lists) {
    state.lists = lists
  },
  ADD_TIMELINE (state, tweets) {
    state.timeline = tweets.concat(state.timeline)
  },
  DELETE_TWEET (state, idx) {
    state.timeline.splice(idx, 1)
  },
  ADD_TWEETED_ID_STR (state, idStr) {
    state.tweetedIdStr.push(idStr)
  },
  REMOVE_TWEETS (state) {
    state.tweetedIdStr.forEach((idStr) => {
      state.timeline.splice(state.timeline.findIndex(TwitterClient.findItem, idStr), 1)
    })
    state.tweetedIdStr = []
  },
  ADD_MENTIONS (state, tweets) {
    state.mentions = tweets.concat(state.mentions)
  },
  ADD_FAVORITES (state, tweets) {
    state.favorites = tweets.concat(state.favorites)
  },
  ADD_LISTS_STATUSES (state, tweets) {
    state.listsStatuses = tweets.concat(state.listsStatuses)
  },
  UPDATE_FAVORITED (state, {idx, favorited}) {
    state.timeline[idx].favorited = favorited
  },
  UPDATE_RETWEETED (state, {idx, retweeted}) {
    state.timeline[idx].retweeted = retweeted
  }
}

const actions = {
  fetchAccount ({ commit }) {
    TwitterClient.fetchAccount()
      .then((user) => {
        commit('ADD_ME', user)
      })
  },
  fetchLists ({ commit }) {
    TwitterClient.fetchLists()
      .then((lists) => {
        commit('ADD_LISTS', lists)
      })
  },
  fetchTimeline ({ commit }) {
    commit('REMOVE_TWEETS')
    const params = _.cloneDeep(defaultGetParams)
    if (state.timeline.length > 0) {
      params.since_id = state.timeline[0].id_str
    }
    TwitterClient.fetchTweets('statuses/home_timeline', params)
      .then((tweets) => {
        if (tweets.length > 0) {
          commit('ADD_TIMELINE', tweets)
        }
      })
  },
  addTimeline ({ commit }, tweet) {
    commit('ADD_TIMELINE', [TwitterClient.parseTweet(tweet)])
    commit('ADD_TWEETED_ID_STR', tweet.id_str)
  },
  remoteTweets ({ commit }) {
    commit('REMOVE_TWEETS')
  },
  deleteTweet ({ commit }, idStr) {
    commit('DELETE_TWEET', state.timeline.findIndex(TwitterClient.findItem, idStr))
  },
  fetchMentions ({ commit }) {
    const params = _.cloneDeep(defaultGetParams)
    if (state.mentions.length > 0) {
      params.since_id = state.mentions[0].id_str
    }
    TwitterClient.fetchTweets('statuses/mentions_timeline', params)
      .then((tweets) => {
        if (tweets.length > 0) {
          commit('ADD_MENTIONS', tweets)
        }
      })
  },
  fetchFavorites ({ commit }) {
    const params = _.cloneDeep(defaultGetParams)
    if (state.favorites.length > 0) {
      params.since_id = state.favorites[0].id_str
    }
    TwitterClient.fetchTweets('favorites/list', params)
      .then((tweets) => {
        if (tweets.length > 0) {
          commit('ADD_FAVORITES', tweets)
        }
      })
  },
  fetchListsStatuses ({ commit }) {
    const params = _.cloneDeep(defaultGetParams)
    if (state.listsStatuses.length > 0) {
      params.since_id = state.listsStatuses[0].id_str
    }
    params.list_id = state.listId
    TwitterClient.fetchTweets('lists/statuses', params)
      .then((tweets) => {
        if (tweets.length > 0) {
          commit('ADD_LISTS_STATUSES', tweets)
        }
      })
  },
  updateFavorited ({ commit }, {idStr, favorited}) {
    commit('UPDATE_FAVORITED', {
      idx: state.timeline.findIndex(TwitterClient.findItem, idStr),
      favorited: favorited
    })
  },
  updateRetweeted ({ commit }, {idStr, retweeted}) {
    commit('UPDATE_RETWEETED', {
      idx: state.timeline.findIndex(TwitterClient.findItem, idStr),
      retweeted: retweeted
    })
  }
}

export default {
  state,
  mutations,
  actions
}
<|endoftext|>


<commit_before>"use strict"; // run code in ES5 strict mode

//https://github.com/flatiron/winston
var winston = require("winston"),
    config = require("./config/config.js");

//output all levels and messages to console
var developmentTransport = {
        console: {
            colorize: "true",
            timestamp : "true"
        }
    },
    testingTransport = {
        console: {
            silent : "true"
        }
    },
    loggers = winston.loggers;

if (config.mode === "development") {
    loggers.add("core", developmentTransport);
    loggers.add("build", developmentTransport);
    loggers.add("server", developmentTransport);
}
else if(config.mode === "testing") {
    loggers.add("core", testingTransport);
    loggers.add("build", testingTransport);
    loggers.add("server", testingTransport);
}
//staging & production
else {
    loggers.add("core", {
        file: {
            colorize: "true",
            filename : config.logDir + "/core.log",
            level : "info"
        },
        console : {
            colorize: "true",
            timestamp : "true",
            level : "warn"
        }
    });

    loggers.add("build", {
        file: {
            colorize: "true",
            filename : config.logDir + "/build.log",
            level : "info"
        },
        console : {
            colorize: "true",
            timestamp : "true",
            level : "warn"
        }
    });

    loggers.add("server", {
        file: {
            colorize: "true",
            filename : config.logDir + "/server.log",
            level : "info"
        },
        console : {
            colorize: "true",
            timestamp : "true",
            level : "warn"
        }
    });
}

loggers.get("core").info("Logger initialized");

module.exports = winston.loggers;<commit_msg>- Introduced bundle logger<commit_after>"use strict"; // run code in ES5 strict mode

//https://github.com/flatiron/winston
var winston = require("winston"),
    config = require("./config/config.js");

//output all levels and messages to console
var developmentTransport = {
        console: {
            colorize: "true",
            timestamp : "true"
        }
    },
    testingTransport = {
        console: {
            silent : "true"
        }
    },
    loggers = winston.loggers;

if (config.mode === "development") {
    loggers.add("core", developmentTransport);
    loggers.add("bundle", developmentTransport);
    loggers.add("server", developmentTransport);
}
else if(config.mode === "testing") {
    loggers.add("core", testingTransport);
    loggers.add("bundle", testingTransport);
    loggers.add("server", testingTransport);
}
//staging & production
else {
    loggers.add("core", {
        file: {
            colorize: "true",
            filename : config.logDir + "/core.log",
            level : "info"
        },
        console : {
            colorize: "true",
            timestamp : "true",
            level : "warn"
        }
    });

    loggers.add("bundle", {
        file: {
            colorize: "true",
            filename : config.logDir + "/bundle.log",
            level : "info"
        },
        console : {
            colorize: "true",
            timestamp : "true",
            level : "warn"
        }
    });

    loggers.add("server", {
        file: {
            colorize: "true",
            filename : config.logDir + "/server.log",
            level : "info"
        },
        console : {
            colorize: "true",
            timestamp : "true",
            level : "warn"
        }
    });
}

loggers.get("core").info("Logger initialized");

module.exports = winston.loggers;<|endoftext|>


<commit_before>// Copyright 2002-2015, University of Colorado Boulder

/**
 * Grunt configuration file for PhET projects.
 * Tasks share information via global.phet, see individual tasks for details.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 * @author Jon Olson
 * @author Sam Reid
 * @author John Blanco
 */

// use process.env
/* jslint node: true */

// built-in node APIs
var assert = require( 'assert' );
var fs = require( 'fs' );

// 3rd-party packages
var _ = require( '../../../sherpa/lib/lodash-2.4.1.min' ); // eslint-disable-line require-statement-match

// PhET custom grunt tasks
var afterRequirejsBuild = require( '../../../chipper/js/grunt/afterRequirejsBuild' );
var checkoutShas = require( '../../../chipper/js/grunt/checkoutShas' );
var commitsSince = require( '../../../chipper/js/grunt/commitsSince' );
var createSim = require( '../../../chipper/js/grunt/createSim' );
var deployProduction = require( '../../../chipper/js/grunt/deployProduction' );
var deployDev = require( '../../../chipper/js/grunt/deployDev' );
var deployUtil = require( '../../../chipper/js/grunt/deployUtil' );
var generateREADME = require( '../../../chipper/js/grunt/generateREADME' );
var generateThumbnails = require( '../../../chipper/js/grunt/generateThumbnails' );
var reportMedia = require( '../../../chipper/js/grunt/reportMedia' );
var reportThirdParty = require( '../../../chipper/js/grunt/reportThirdParty' );
var getBuildConfig = require( '../../../chipper/js/grunt/getBuildConfig' );
var getGruntConfig = require( '../../../chipper/js/grunt/getGruntConfig' );

module.exports = function( grunt ) {
  'use strict';

  // For eslint
  require( 'load-grunt-tasks' )( grunt );

  //---------------------------------------------------------------------------------------------------------------
  // Configuration

  var buildConfig = getBuildConfig( grunt );

  // Initialize and document all globals
  assert( !global.phet, 'global.phet already exists' );
  global.phet = {

    chipper: {

      // the grunt instance, for situations where we can't pass it as a function argument
      grunt: grunt,

      // for code that runs in both requirejs and build modes, and therefore doesn't have access to grunt.file
      fs: fs,

      // polyfill to work around the cache buster arg in the *-config.js file that all sims have.
      getCacheBusterArgs: function() { return ''; },

      // media plugins populate this with license.json entries, see getLicenseEntry.js for format of entries
      licenseEntries: {},

      // use by media plugins, which don't have access to buildConfig
      brand: buildConfig.brand,

      // populated by mipmap.js
      mipmapsToBuild: [],

      // populated by string.js
      strings: {}
    }
  };

  // Initialize grunt
  grunt.initConfig( getGruntConfig( grunt, buildConfig.name, buildConfig.phetLibs ) );

  //---------------------------------------------------------------------------------------------------------------
  // Primary tasks
  //---------------------------------------------------------------------------------------------------------------

  // Default task ('grunt')

  grunt.registerTask( 'default', 'Builds the English HTML', [ 'build' ] );

  // Add the linting step as an pre-build step.  Can be skipped with --lint=false
  var optionalTasks = [];
  if ( grunt.option( 'lint' ) === false ) {

    // do nothing
  }
  else {
    optionalTasks.push( 'lint-all' );
  }

  grunt.registerTask( 'build',
    'Builds the simulation:\n' +
    'with no options, builds HTML for English only\n' +
    '--locales=* : all locales in strings/ directory\n' +
    '--locales=fr : French\n' +
    '--locales=ar,fr,es : Arabic, French and Spanish (comma separated locales)\n' +
    '--localesRepo=$repo : all locales in another repository\'s strings/ directory, ignored if --locales is present\n' +
    '--lint=false : skip the lint sub-task',
    optionalTasks.concat( [
      'clean',
      'requirejs:build',
      'after-requirejs-build' ] )
  );

  grunt.registerTask( 'build-for-server', 'meant for use by build-server only',
    [ 'build', 'generate-thumbnails' ]
  );

  grunt.registerTask( 'deploy-production',
    'Invoke deployDev and then deploy a simulation to the production server.\n' +
    'Should be run AFTER grunt build since it uses the shas from dependencies.json in the build directory.\n' +
    'Deploys to figaro by default, but simian can be used for testing by setting:\n' +
    '"productionServerName": "simian.colorado.edu" and "productionServerURL": "https://phet-dev.colorado.edu" in build-local.json\n' +
    '--locales : optionally tell build server to build from a comma separated list of locales, defaults to en\n' +
    '--noDev : if true, deploy to production only, not spot as well. Useful for testing',
    function() {
      // before invoking the build-server, do a dev deploy, including committing and pushing to github
      var done = grunt.task.current.async();
      if ( grunt.option( 'noDev' ) ) {
        deployProduction( grunt, done );
      }
      else {
        deployDev( grunt, function() {
          deployProduction( grunt, done );
        } );
      }
    }
  );

  grunt.registerTask( 'deploy-dev',
    'Deploy a dev version to spot, or optionally to the server in your preferences file\n' +
    '--mkdir : set to true to create the sim dir and .htaccess file before copying the version directory\n' +
    '--test : set to true to disable commit and push, and SCP to a test directory on spot',
    function() {
      deployDev( grunt );
    }
  );

  grunt.registerTask( 'deploy-rc',
    'Deploy a rc version to spot using the build server.\n' +
    'Behaves identically to grunt deploy-dev, except the sim is rebuilt and deployed from the build-server instead of locally.\n' +
    'This is useful to ensure that the rc version is built in the same environment as our production deploys',
    function() {
      grunt.option( 'noDev', true );
      grunt.option( 'option', 'rc' );

      var done = grunt.task.current.async();

      deployUtil.commitAndPush( grunt, function() {
        deployProduction( grunt, done );
      } );
    }
  );

  grunt.registerTask( 'lint', 'lint js files that are specific to this repository', [ 'eslint:repoFiles' ] );

  grunt.registerTask( 'lint-all', 'lint all js files that are required to build this repository', [ 'eslint:allFiles' ] );

  grunt.registerTask( 'clean',
    'Erases the build/ directory and all its contents, and recreates the build/ directory',
    function() {
      if ( grunt.file.exists( 'build' ) ) {
        grunt.file.delete( 'build' );
      }
      grunt.file.mkdir( 'build' );
    } );

  grunt.registerTask( 'after-requirejs-build',
    '(internal use only) Do things after the requirejs:build task',
    function() {
      afterRequirejsBuild( grunt, buildConfig );
    } );

  //---------------------------------------------------------------------------------------------------------------
  // Utility tasks
  //---------------------------------------------------------------------------------------------------------------

  grunt.registerTask( 'checkout-shas',
    'Check out shas for a project, as specified in dependencies.json',
    function() {
      checkoutShas( grunt, buildConfig.name, false /* toMaster */ );
    } );

  grunt.registerTask( 'checkout-master',
    'Check out master branch for all dependencies, as specified in dependencies.json',
    function() {
      checkoutShas( grunt, buildConfig.name, true /* toMaster */ );
    } );

  grunt.registerTask( 'create-sim',
    'Creates a sim based on the simula-rasa template.\n' +
    '--name="string" : the repository name\n' +
    '--author="string" : the author name\n' +
    '--title="string" : (optional) the simulation title\n' +
    '--clean=true : (optional) deletes the repository directory if it exists',
    function() {
      createSim( grunt );
    } );

  // See reportMedia.js
  grunt.registerTask( 'report-media',
    '(project-wide) Report on license.json files throughout all working copies. ' +
    'Reports any media (such as images or audio) files that have any of the following problems:\n' +
    '(1) incompatible-license (resource license not approved)\n' +
    '(2) not-annotated (license.json missing or entry missing from license.json)\n' +
    '(3) missing-file (entry in the license.json but not on the file system)',
    function() {
      reportMedia( grunt );
    } );

  // see reportThirdParty.js
  grunt.registerTask( 'report-third-party',
    'This task is used to create a report of third-party resources (code, ' +
    'images, audio, etc) used in a set of PhET simulations by reading the ' +
    'license information in built HTML files.\n' +
    '--input (required argument) the path to the directory containing HTML ' +
    'files which will be reported on.\n' +
    '--output (required argument) the path to a file where the report should be ' +
    'written. The file is in markdown syntax and the *.md suffix is ' +
    'recommended. This will silently overwrite an existing file, if there is ' +
    'one.\n' +
    '--active-runnables (optional, default to false) If true, ' +
    'the task iterates over the active-runnables and copies each ' +
    'built HTML file into the directory specified with --input before ' +
    'running the report. If any HTML files are missing, the report will fail. ' +
    'Before using this flag, the developer should run `grunt-all.sh` to make ' +
    'sure all of the HTML files are up-to-date. The directory is neither ' +
    'automatically created nor automatically cleaned, this is the ' +
    'responsibility of the developer. (Note that if you fail to manually ' +
    'clean the directory, you may end up with stale HTML files).',
    function() {
      reportThirdParty( grunt );
    } );

  grunt.registerTask( 'published-README',
    'Generates README.md file for a published simulation.',
    function() {
      assert( buildConfig.simTitleStringKey, 'missing buildConfig.simTitleStringKey' );
      generateREADME( grunt, buildConfig.name, buildConfig.phetLibs, buildConfig.simTitleStringKey, true /* published */ );
    } );

  grunt.registerTask( 'unpublished-README',
    'Generates README.md file for an unpublished simulation.',
    function() {
      assert( buildConfig.simTitleStringKey, 'missing buildConfig.simTitleStringKey' );
      generateREADME( grunt, buildConfig.name, buildConfig.phetLibs, buildConfig.simTitleStringKey, false /* published */ );
    } );

  grunt.registerTask( 'generate-thumbnails', 'Generate 128x84 and 600x394 thumbnails to be used on the website.',
    function() {
      var finished = _.after( 2, grunt.task.current.async() );
      generateThumbnails( grunt, buildConfig.name, 128, 84, finished );
      generateThumbnails( grunt, buildConfig.name, 600, 394, finished );
    } );

  grunt.registerTask( 'commits-since',
    'Shows commits since a specified date. Use --date=\<date\> to specify the date.',
    function() {
      commitsSince( grunt, buildConfig );
    } );

  /*
   * Load tasks from grunt plugins that have been installed locally using npm.
   * Put these in package.json and run 'npm install' before running grunt.
   */
  grunt.loadNpmTasks( 'grunt-requirejs' );
};
<commit_msg>add * to documention about deploy-production locales<commit_after>// Copyright 2002-2015, University of Colorado Boulder

/**
 * Grunt configuration file for PhET projects.
 * Tasks share information via global.phet, see individual tasks for details.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 * @author Jon Olson
 * @author Sam Reid
 * @author John Blanco
 */

// use process.env
/* jslint node: true */

// built-in node APIs
var assert = require( 'assert' );
var fs = require( 'fs' );

// 3rd-party packages
var _ = require( '../../../sherpa/lib/lodash-2.4.1.min' ); // eslint-disable-line require-statement-match

// PhET custom grunt tasks
var afterRequirejsBuild = require( '../../../chipper/js/grunt/afterRequirejsBuild' );
var checkoutShas = require( '../../../chipper/js/grunt/checkoutShas' );
var commitsSince = require( '../../../chipper/js/grunt/commitsSince' );
var createSim = require( '../../../chipper/js/grunt/createSim' );
var deployProduction = require( '../../../chipper/js/grunt/deployProduction' );
var deployDev = require( '../../../chipper/js/grunt/deployDev' );
var deployUtil = require( '../../../chipper/js/grunt/deployUtil' );
var generateREADME = require( '../../../chipper/js/grunt/generateREADME' );
var generateThumbnails = require( '../../../chipper/js/grunt/generateThumbnails' );
var reportMedia = require( '../../../chipper/js/grunt/reportMedia' );
var reportThirdParty = require( '../../../chipper/js/grunt/reportThirdParty' );
var getBuildConfig = require( '../../../chipper/js/grunt/getBuildConfig' );
var getGruntConfig = require( '../../../chipper/js/grunt/getGruntConfig' );

module.exports = function( grunt ) {
  'use strict';

  // For eslint
  require( 'load-grunt-tasks' )( grunt );

  //---------------------------------------------------------------------------------------------------------------
  // Configuration

  var buildConfig = getBuildConfig( grunt );

  // Initialize and document all globals
  assert( !global.phet, 'global.phet already exists' );
  global.phet = {

    chipper: {

      // the grunt instance, for situations where we can't pass it as a function argument
      grunt: grunt,

      // for code that runs in both requirejs and build modes, and therefore doesn't have access to grunt.file
      fs: fs,

      // polyfill to work around the cache buster arg in the *-config.js file that all sims have.
      getCacheBusterArgs: function() { return ''; },

      // media plugins populate this with license.json entries, see getLicenseEntry.js for format of entries
      licenseEntries: {},

      // use by media plugins, which don't have access to buildConfig
      brand: buildConfig.brand,

      // populated by mipmap.js
      mipmapsToBuild: [],

      // populated by string.js
      strings: {}
    }
  };

  // Initialize grunt
  grunt.initConfig( getGruntConfig( grunt, buildConfig.name, buildConfig.phetLibs ) );

  //---------------------------------------------------------------------------------------------------------------
  // Primary tasks
  //---------------------------------------------------------------------------------------------------------------

  // Default task ('grunt')

  grunt.registerTask( 'default', 'Builds the English HTML', [ 'build' ] );

  // Add the linting step as an pre-build step.  Can be skipped with --lint=false
  var optionalTasks = [];
  if ( grunt.option( 'lint' ) === false ) {

    // do nothing
  }
  else {
    optionalTasks.push( 'lint-all' );
  }

  grunt.registerTask( 'build',
    'Builds the simulation:\n' +
    'with no options, builds HTML for English only\n' +
    '--locales=* : all locales in strings/ directory\n' +
    '--locales=fr : French\n' +
    '--locales=ar,fr,es : Arabic, French and Spanish (comma separated locales)\n' +
    '--localesRepo=$repo : all locales in another repository\'s strings/ directory, ignored if --locales is present\n' +
    '--lint=false : skip the lint sub-task',
    optionalTasks.concat( [
      'clean',
      'requirejs:build',
      'after-requirejs-build' ] )
  );

  grunt.registerTask( 'build-for-server', 'meant for use by build-server only',
    [ 'build', 'generate-thumbnails' ]
  );

  grunt.registerTask( 'deploy-production',
    'Invoke deployDev and then deploy a simulation to the production server.\n' +
    'Should be run AFTER grunt build since it uses the shas from dependencies.json in the build directory.\n' +
    'Deploys to figaro by default, but simian can be used for testing by setting:\n' +
    '"productionServerName": "simian.colorado.edu" and "productionServerURL": "https://phet-dev.colorado.edu" in build-local.json\n' +
    '--locales : optionally tell build server to build from a comma separated list of locales (or * for all existing locales),' +
    'defaults to en\n' +
    '--noDev : if true, deploy to production only, not spot as well. Useful for testing',
    function() {
      // before invoking the build-server, do a dev deploy, including committing and pushing to github
      var done = grunt.task.current.async();
      if ( grunt.option( 'noDev' ) ) {
        deployProduction( grunt, done );
      }
      else {
        deployDev( grunt, function() {
          deployProduction( grunt, done );
        } );
      }
    }
  );

  grunt.registerTask( 'deploy-dev',
    'Deploy a dev version to spot, or optionally to the server in your preferences file\n' +
    '--mkdir : set to true to create the sim dir and .htaccess file before copying the version directory\n' +
    '--test : set to true to disable commit and push, and SCP to a test directory on spot',
    function() {
      deployDev( grunt );
    }
  );

  grunt.registerTask( 'deploy-rc',
    'Deploy a rc version to spot using the build server.\n' +
    'Behaves identically to grunt deploy-dev, except the sim is rebuilt and deployed from the build-server instead of locally.\n' +
    'This is useful to ensure that the rc version is built in the same environment as our production deploys',
    function() {
      grunt.option( 'noDev', true );
      grunt.option( 'option', 'rc' );

      var done = grunt.task.current.async();

      deployUtil.commitAndPush( grunt, function() {
        deployProduction( grunt, done );
      } );
    }
  );

  grunt.registerTask( 'lint', 'lint js files that are specific to this repository', [ 'eslint:repoFiles' ] );

  grunt.registerTask( 'lint-all', 'lint all js files that are required to build this repository', [ 'eslint:allFiles' ] );

  grunt.registerTask( 'clean',
    'Erases the build/ directory and all its contents, and recreates the build/ directory',
    function() {
      if ( grunt.file.exists( 'build' ) ) {
        grunt.file.delete( 'build' );
      }
      grunt.file.mkdir( 'build' );
    } );

  grunt.registerTask( 'after-requirejs-build',
    '(internal use only) Do things after the requirejs:build task',
    function() {
      afterRequirejsBuild( grunt, buildConfig );
    } );

  //---------------------------------------------------------------------------------------------------------------
  // Utility tasks
  //---------------------------------------------------------------------------------------------------------------

  grunt.registerTask( 'checkout-shas',
    'Check out shas for a project, as specified in dependencies.json',
    function() {
      checkoutShas( grunt, buildConfig.name, false /* toMaster */ );
    } );

  grunt.registerTask( 'checkout-master',
    'Check out master branch for all dependencies, as specified in dependencies.json',
    function() {
      checkoutShas( grunt, buildConfig.name, true /* toMaster */ );
    } );

  grunt.registerTask( 'create-sim',
    'Creates a sim based on the simula-rasa template.\n' +
    '--name="string" : the repository name\n' +
    '--author="string" : the author name\n' +
    '--title="string" : (optional) the simulation title\n' +
    '--clean=true : (optional) deletes the repository directory if it exists',
    function() {
      createSim( grunt );
    } );

  // See reportMedia.js
  grunt.registerTask( 'report-media',
    '(project-wide) Report on license.json files throughout all working copies. ' +
    'Reports any media (such as images or audio) files that have any of the following problems:\n' +
    '(1) incompatible-license (resource license not approved)\n' +
    '(2) not-annotated (license.json missing or entry missing from license.json)\n' +
    '(3) missing-file (entry in the license.json but not on the file system)',
    function() {
      reportMedia( grunt );
    } );

  // see reportThirdParty.js
  grunt.registerTask( 'report-third-party',
    'This task is used to create a report of third-party resources (code, ' +
    'images, audio, etc) used in a set of PhET simulations by reading the ' +
    'license information in built HTML files.\n' +
    '--input (required argument) the path to the directory containing HTML ' +
    'files which will be reported on.\n' +
    '--output (required argument) the path to a file where the report should be ' +
    'written. The file is in markdown syntax and the *.md suffix is ' +
    'recommended. This will silently overwrite an existing file, if there is ' +
    'one.\n' +
    '--active-runnables (optional, default to false) If true, ' +
    'the task iterates over the active-runnables and copies each ' +
    'built HTML file into the directory specified with --input before ' +
    'running the report. If any HTML files are missing, the report will fail. ' +
    'Before using this flag, the developer should run `grunt-all.sh` to make ' +
    'sure all of the HTML files are up-to-date. The directory is neither ' +
    'automatically created nor automatically cleaned, this is the ' +
    'responsibility of the developer. (Note that if you fail to manually ' +
    'clean the directory, you may end up with stale HTML files).',
    function() {
      reportThirdParty( grunt );
    } );

  grunt.registerTask( 'published-README',
    'Generates README.md file for a published simulation.',
    function() {
      assert( buildConfig.simTitleStringKey, 'missing buildConfig.simTitleStringKey' );
      generateREADME( grunt, buildConfig.name, buildConfig.phetLibs, buildConfig.simTitleStringKey, true /* published */ );
    } );

  grunt.registerTask( 'unpublished-README',
    'Generates README.md file for an unpublished simulation.',
    function() {
      assert( buildConfig.simTitleStringKey, 'missing buildConfig.simTitleStringKey' );
      generateREADME( grunt, buildConfig.name, buildConfig.phetLibs, buildConfig.simTitleStringKey, false /* published */ );
    } );

  grunt.registerTask( 'generate-thumbnails', 'Generate 128x84 and 600x394 thumbnails to be used on the website.',
    function() {
      var finished = _.after( 2, grunt.task.current.async() );
      generateThumbnails( grunt, buildConfig.name, 128, 84, finished );
      generateThumbnails( grunt, buildConfig.name, 600, 394, finished );
    } );

  grunt.registerTask( 'commits-since',
    'Shows commits since a specified date. Use --date=\<date\> to specify the date.',
    function() {
      commitsSince( grunt, buildConfig );
    } );

  /*
   * Load tasks from grunt plugins that have been installed locally using npm.
   * Put these in package.json and run 'npm install' before running grunt.
   */
  grunt.loadNpmTasks( 'grunt-requirejs' );
};
<|endoftext|>


<commit_before>var mysqlAdapter = require('simple-orm-mysql-adapter')(require('../mysql-connection'));
var orm = require('../../orm');

var basePermissionModel = Object.create(orm.baseModel(mysqlAdapter));

//add functionality to all user model instances to baseUserModel object

var permissionModel = Object.create(basePermissionModel);

permissionModel.define('Users', {
  id: {
    column: 'id',
    type: 'integer',
    primaryKey: true,
    autoIncrement: true
  },
  firstName: {
    column: 'firstName',
    type: 'string'
  },
  lastName: {
    column: 'lastName',
    type: 'string',
    exclude: 'update'
  },
  email: {
    column: 'email',
    type: 'string'
  },
  username: {
    column: 'username',
    type: 'string'
  },
  password: {
    column: 'password',
    type: 'string'
  },
  createdTimestamp: {
    column: 'createdTimestamp',
    type: 'datetime',
    exclude: 'always'
  },
  updatedTimestamp: {
    column: 'updatedTimestamp',
    type: 'datetime',
    allowNull: true,
    defaultValue: null,
    exclude: 'insert'
  },
  lastPasswordChangeDate: {
    column: 'lastPasswordChangeDate',
    type: 'date',
    allowNull: true,
    defaultValue: null
  },
  requirePasswordChangeFlag: {
    column: 'requirePasswordChangeFlag',
    type: 'boolean',
    defaultValue: false
  },
  status: {
    column: 'status',
    type: 'enum',
    values: [
      'active',
      'inactive',
      'banned',
      'registered'
    ],
    defaultValue: 'registered'
  }
});

var permissionRepository = Object.create(orm.baseRepository(permissionModel));

//add functionality specific to the user repository here

module.exports = permissionRepository;<commit_msg>fixed permission test model<commit_after>var mysqlAdapter = require('simple-orm-mysql-adapter')(require('../mysql-connection'));
var orm = require('../../orm');

var basePermissionModel = Object.create(orm.baseModel(mysqlAdapter));

//add functionality to all user model instances to baseUserModel object

var permissionModel = Object.create(basePermissionModel);

permissionModel.define('Permissions', {
  id: {
    column: 'id',
    type: 'integer',
    primaryKey: true,
    autoIncrement: true
  },
  title: {
    column: 'title',
    type: 'string'
  }
});

var permissionRepository = Object.create(orm.baseRepository(permissionModel));

//add functionality specific to the user repository here

module.exports = permissionRepository;<|endoftext|>


<commit_before>/**
 * Competence class
 */
function Competence(viewmodel, id, code, name, weight, subcompetences) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        subcompetences: ko.observableArray(subcompetences),

        addSubCompetence: function() {
            this.subcompetences.push(new SubCompetence(this));
        },

        removeThis: function() {
            viewmodel.removeCompetence(this);
        },

        toggleLock: function(){
            alert(weight);
        },

        removeSubCompetence: function(subCompetence) {
            this.subcompetences.remove(subCompetence);
        }
    };

}

/**
 * SubCompetence class
 */
function SubCompetence(parent, id, code, name, weight, indicators) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        indicators: ko.observableArray(indicators),

        addIndicator: function() {
            this.indicators.push(new Indicator(this));
        },

        removeThis: function() {
            parent.removeSubCompetence(this);
        },

        toggleLock: function(){
            alert((parseInt(parent.weight() - this.weight())));
        },

        removeIndicator: function(indicator) {
            this.indicators.remove(indicator);
        },

    };
}

/**
 * Indicator class
 */
function Indicator(parent, id, name, description) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        description : ko.observable(description),

        removeThis: function() {
            parent.removeIndicator(this);
        }
    };
}

// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    gvm.competences = 0;
    gvm.subcomp = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.addCompetenceBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddCompetence");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.competences = ko.observableArray([]);

    gvm.addCompetence = function() {
        gvm.competences.push(new Competence(this));

        // Update automated weight calculation
        var size = gvm.competences.length;
        var percent = 100/size;
        gvm.competences[0] = 50;
        console.log(this.weight);

        ko.utils.arrayForEach(gvm.competences, function(competence){
            competence.weight(percent);
            alert(percent);
        });
    };

    gvm.removeCompetence = function(competence) {
        gvm.competences.remove(competence);
    }

    gvm.updateCompetence = function(id, code, description, max, weight) {
        var comp = new Competence(this, id, code, description, weight);
        gvm.competences.push(comp);
        return comp;
    }

    gvm.clearStructure = function() {
        gvm.competences.destroyAll();
    }
}

/**
 * Push the current project state to the database
 * @returns {undefined}
 */
function saveProjectStructure() {
    $.ajax({
       type: "POST",
       url: "/api/projectstructure/" + projectid,
       data: ko.toJSON(viewModel.competences),
       success: function(){
           // TODO make multilangual and with modals
           alert("Saved projectstructure to server");

           fetchProjectStructure();
       }
    });
}

function fetchProjectStructure() {
    viewModel.clearStructure();

    $.getJSON("/api/projectstructure/" + projectid, function(data){
        $.each(data, function(i, item){
            var competence = viewModel.updateCompetence(item.id, item.code, item.description, item.max, item.weight);

            $.each(item.subcompetences, function(i, subcomp){
               var subcompetence = new SubCompetence(competence, subcomp.id, subcomp.code, subcomp.description, subcomp.weight);
               competence.subcompetences.push(subcompetence);

               $.each(subcomp.indicators, function(i, indic){
                  subcompetence.indicators.push(new Indicator(subcompetence, indic.id, indic.name, indic.description));
               });
            });
        })
    });
}

function initPage() {
    fetchProjectStructure();

    $(".addCompetenceBtn").click(function() {
        viewModel.addCompetence();
    });

    $(".savePageBtn").click(function(){
        saveProjectStructure();
    });

    $(".locked").click(function() {
        setLocked();
    });
}
<commit_msg>lock weight<commit_after>/**
 * Competence class
 */
function Competence(viewmodel, id, code, name, weight, subcompetences) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        subcompetences: ko.observableArray(subcompetences),

        addSubCompetence: function() {
            this.subcompetences.push(new SubCompetence(this));
        },

        removeThis: function() {
            viewmodel.removeCompetence(this);
        },

        toggleLock: function(){
            alert(weight);
        },

        removeSubCompetence: function(subCompetence) {
            this.subcompetences.remove(subCompetence);
        }
    };

}

/**
 * SubCompetence class
 */
function SubCompetence(parent, id, code, name, weight, indicators) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        weight: ko.observable(weight),
        indicators: ko.observableArray(indicators),

        addIndicator: function() {
            this.indicators.push(new Indicator(this));
        },

        removeThis: function() {
            parent.removeSubCompetence(this);
        },

        toggleLock: function(){
            ko.weightLeft = parseInt(100 - this.weight() - ko.weightLeft())
            alert((ko.weightLeft()));
        },

        removeIndicator: function(indicator) {
            this.indicators.remove(indicator);
        },

    };
}

/**
 * Indicator class
 */
function Indicator(parent, id, name, description) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        description : ko.observable(description),

        removeThis: function() {
            parent.removeIndicator(this);
        }
    };
}

// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    gvm.competences = 0;
    gvm.subcomp = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.addCompetenceBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddCompetence");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.competences = ko.observableArray([]);

    gvm.addCompetence = function() {
        gvm.competences.push(new Competence(this));

        // Update automated weight calculation
        var size = gvm.competences.length;
        var percent = 100/size;
        gvm.competences[0] = 50;
        console.log(this.weight);

        ko.utils.arrayForEach(gvm.competences, function(competence){
            competence.weight(percent);
            alert(percent);
        });
    };

    gvm.removeCompetence = function(competence) {
        gvm.competences.remove(competence);
    }

    gvm.updateCompetence = function(id, code, description, max, weight) {
        var comp = new Competence(this, id, code, description, weight);
        gvm.competences.push(comp);
        return comp;
    }

    gvm.clearStructure = function() {
        gvm.competences.destroyAll();
    }
}

/**
 * Push the current project state to the database
 * @returns {undefined}
 */
function saveProjectStructure() {
    $.ajax({
       type: "POST",
       url: "/api/projectstructure/" + projectid,
       data: ko.toJSON(viewModel.competences),
       success: function(){
           // TODO make multilangual and with modals
           alert("Saved projectstructure to server");

           fetchProjectStructure();
       }
    });
}

function fetchProjectStructure() {
    viewModel.clearStructure();

    $.getJSON("/api/projectstructure/" + projectid, function(data){
        $.each(data, function(i, item){
            var competence = viewModel.updateCompetence(item.id, item.code, item.description, item.max, item.weight);

            $.each(item.subcompetences, function(i, subcomp){
               var subcompetence = new SubCompetence(competence, subcomp.id, subcomp.code, subcomp.description, subcomp.weight);
               competence.subcompetences.push(subcompetence);

               $.each(subcomp.indicators, function(i, indic){
                  subcompetence.indicators.push(new Indicator(subcompetence, indic.id, indic.name, indic.description));
               });
            });
        })
    });
}

function initPage() {
    fetchProjectStructure();

    $(".addCompetenceBtn").click(function() {
        viewModel.addCompetence();
    });

    $(".savePageBtn").click(function(){
        saveProjectStructure();
    });

    $(".locked").click(function() {
        setLocked();
    });
}
<|endoftext|>