<commit_before>/*
 * Released under BSD License
 * Copyright (c) 2014-2015 hizzgdev@163.com
 *
 * Project Home:
 *   https://github.com/hizzgdev/jsmind/
 */

(function($w){
    "use strict";
    var $d = $w.document;
    var __name__ = 'jsMind';
    var jsMind = $w[__name__];

    var jdom = jsMind.util.dom;
    var jcanvas = jsMind.util.canvas;

    var clear_selection = "getSelection" in $w ? function(){
         $w.getSelection().removeAllRanges();
    } : function(){
         $d.selection.empty();
    };

    var option = {
        line_width : 5
    };

    var jd = null;

    jsMind.draggable = function(jm_){
        this.jm = jm_;
        this.e_canvas = null;
        this.canvas_ctx = null;
        this.shadow = null;
        this.shadow_w = 0;
        this.shadow_h = 0;
        this.active_node = null;
        this.target_node = null;
        this.target_direct = null;
        this.client_w = 0;
        this.client_h = 0;
        this.offset_x = 0;
        this.offset_y = 0;
        this.hlookup = 0;
        this.capture = false;
        this.moved = false;
    };

    jsMind.draggable.prototype = {
        init:function(){
            this._create_canvas();
            this._create_shadow();
            this._event_bind();
        },

        reset:function(){
            this.jm.view.e_nodes.appendChild(this.shadow);
            this.e_canvas.width=this.jm.view.size.w;
            this.e_canvas.height=this.jm.view.size.h;
        },

        _create_canvas:function(){
            var c = $d.createElement('canvas');
            this.jm.view.e_panel.appendChild(c);
            var ctx = c.getContext('2d');
            this.e_canvas = c;
            this.canvas_ctx = ctx;
        },

        _create_shadow:function(){
            var s = $d.createElement('jmnode');
            s.style.visibility = 'hidden';
            s.style.zIndex = '3';
            s.style.cursor = 'move';
            s.style.opacity= '0.7';
            this.shadow = s;
        },

        reset_shadow:function(el){
            var s = this.shadow.style;
            this.shadow.innerHTML = el.innerHTML;
            s.left = el.style.left;
            s.top = el.style.top;
            this.shadow_w = this.shadow.clientWidth;
            this.shadow_h = this.shadow.clientHeight;
        },

        show_shadow:function(){
            if(!this.moved){
                this.shadow.style.visibility = 'visible';
            }
        },

        hide_shadow:function(){
            this.shadow.style.visibility = 'hidden';
        },

        clear_lines:function(){
            jcanvas.clear(this.canvas_ctx, 0, 0, this.jm.view.size.w, this.jm.view.size.h);
        },

        _magnet_shadow:function(node){
            if(!!node){
                this.canvas_ctx.lineWidth = option.line_width;
                this.canvas_ctx.strokeStyle = 'rgba(0,0,0,0.3)';
                this.canvas_ctx.lineCap = 'round';
                this.clear_lines();
                jcanvas.lineto(this.canvas_ctx,
                    node.sp.x,
                    node.sp.y,
                    node.np.x,
                    node.np.y);
            }
        },

        _lookup_close_node:function(){
            var root = this.jm.get_root();
            var root_view_data = root._data.view;
            var root_x = root_view_data.abs_x + root_view_data.width/2;

            var sw = this.shadow_w;
            var sh = this.shadow_h;
            var sx = this.shadow.offsetLeft;
            var sy = this.shadow.offsetTop;

            var nw,nh,nx,ny;

            var direct = (sx + sw/2)>=root_x ?
                            jsMind.direction.right : jsMind.direction.left;
            var nodes = this.jm.mind.nodes;
            var node = null;
            var view_data = null;
            var min_distance = Number.MAX_VALUE;
            var distance = 0;
            var closest_node = null;
            var closest_p = null;
            var shadow_p = null;
            for(var nodeid in nodes){
                var np,sp;
                node = nodes[nodeid];
                if(node.isroot || node.direction == direct){
                    if(node.id == this.active_node.id){
                        continue;
                    }
                    view_data = node._data.view;
                    nw = view_data.width;
                    nh = view_data.height;
                    nx = view_data.abs_x;
                    ny = view_data.abs_y;
                    if(direct == jsMind.direction.right){
                        if(sx-nx-nw<=0){continue;}
                        distance = Math.abs(sx-nx-nw) + Math.abs(sy+sh/2-ny-nh/2);
                        np = {x:nx+nw-option.line_width,y:ny+nh/2};
                        sp = {x:sx+option.line_width,y:sy+sh/2};
                    }else{
                        if(nx-sx-sw<=0){continue;}
                        distance = Math.abs(sx+sw-nx) + Math.abs(sy+sh/2-ny-nh/2);
                        np = {x:nx+option.line_width,y:ny+nh/2};
                        sp = {x:sx+sw-option.line_width,y:sy+sh/2};
                    }
                    if(distance < min_distance){
                        closest_node = node;
                        closest_p = np;
                        shadow_p = sp;
                        min_distance = distance;
                    }
                }
            }
            var result_node = null;
            if(!!closest_node){
                result_node = {
                    node:closest_node,
                    direction:direct,
                    sp:shadow_p,
                    np:closest_p
                };
            }
            return result_node;
        },

        lookup_close_node:function(){
            var node_data = this._lookup_close_node();
            if(!!node_data){
                this._magnet_shadow(node_data);
                this.target_node = node_data.node;
                this.target_direct = node_data.direction;
            }
        },

        _event_bind:function(){
            var container = this.jm.view.container;
            jdom.add_event(container,'mousedown',function(e){jd.dragstart.call(jd,e);});
            jdom.add_event(container,'mousemove',function(e){jd.drag.call(jd,e);});
            jdom.add_event(container,'mouseup',function(e){jd.dragend.call(jd,e);});
        },

        dragstart:function(e){
            if(!this.jm.get_editable()){return;}
            if(this.capture){return;}
            this.active_node = null;

            var jview = this.jm.view;
            var el = e.target || event.srcElement;
            var isnode = jview.is_node(el);
            if(isnode){
                var nodeid = jview.get_nodeid(el);
                var node = this.jm.get_node(nodeid);
                if(!node.isroot){
                    this.reset_shadow(el);
                    this.active_node = node;
                    this.offset_x = e.clientX - el.offsetLeft;
                    this.offset_y = e.clientY - el.offsetTop;
                    this.client_hw = Math.floor(el.clientWidth/2);
                    this.client_hh = Math.floor(el.clientHeight/2);
                    if(this.hlookup != 0){
                        $w.clearInterval(this.hlookup);
                    }
                    this.hlookup = $w.setInterval(function(){
                        jd.lookup_close_node.call(jd);
                    },400);
                    this.capture = true;
                }
            }
        },

        drag:function(e){
            if(!this.jm.get_editable()){return;}
            if(this.capture){
                this.show_shadow();
                this.moved = true;
                clear_selection();
                var px = e.clientX - this.offset_x;
                var py = e.clientY - this.offset_y;
                var cx = px + this.client_hw;
                var cy = py + this.client_hh;
                this.shadow.style.left = px + 'px';
                this.shadow.style.top = py + 'px';
                clear_selection();
            }
        },

        dragend:function(e){
            if(!this.jm.get_editable()){return;}
            if(this.capture){
                if(this.hlookup != 0){
                    $w.clearInterval(this.hlookup);
                    this.hlookup = 0;
                    this.clear_lines();
                }
                if(this.moved){
                    var src_node = this.active_node;
                    var target_node = this.target_node;
                    var target_direct = this.target_direct;
                    this.move_node(src_node,target_node,target_direct);
                }
                this.hide_shadow();
            }
            this.moved = false;
            this.capture = false;
        },

        move_node:function(src_node,target_node,target_direct){
            var shadow_h = this.shadow.offsetTop;
            if(!!target_node && !!src_node && !jsMind.node.inherited(src_node, target_node)){
                // lookup before_node
                var sibling_nodes = target_node.children;
                var sc = sibling_nodes.length;
                var node = null;
                var node_h = null;
                var delta_y = Number.MAX_VALUE;
                var node_before = null;
                var beforeid = '_last_';
                while(sc--){
                    node = sibling_nodes[sc];
                    if(node.direction == target_direct && node.id != src_node.id){
                        node_h = node._data.view.abs_y;
                        var dy = node_h - shadow_h;
                        if(dy > 0 && dy < delta_y){
                            delta_y = dy;
                            node_before = node;
                            beforeid = '_first_';
                        }
                    }
                }
                if(!!node_before){beforeid = node_before.id;}
                this.jm.move_node(src_node, beforeid, target_node.id, target_direct);
            }
            this.active_node = null;
            this.target_node = null;
            this.target_direct = null;
        }
    };

    var jm_event_handle = function(jm_, type, data){
        if(type === 'init'){
            jd = new jsMind.draggable(jm_);
            jd.init();
        }
        if(type === 'show'){//reset
            if(!!jd){
                jd.reset();
            }
        }
    };

    jsMind.add_event_handle(jm_event_handle);
})(window);
<commit_msg>refactor variable name<commit_after>/*
 * Released under BSD License
 * Copyright (c) 2014-2015 hizzgdev@163.com
 *
 * Project Home:
 *   https://github.com/hizzgdev/jsmind/
 */

(function($w){
    "use strict";
    var $d = $w.document;
    var __name__ = 'jsMind';
    var jsMind = $w[__name__];
    if(!!jsMind){return;}

    var jdom = jsMind.util.dom;
    var jcanvas = jsMind.util.canvas;

    var clear_selection = "getSelection" in $w ? function(){
         $w.getSelection().removeAllRanges();
    } : function(){
         $d.selection.empty();
    };

    var option = {
        line_width : 5
    };

    jsMind.draggable = function(jm){
        this.jm = jm;
        this.e_canvas = null;
        this.canvas_ctx = null;
        this.shadow = null;
        this.shadow_w = 0;
        this.shadow_h = 0;
        this.active_node = null;
        this.target_node = null;
        this.target_direct = null;
        this.client_w = 0;
        this.client_h = 0;
        this.offset_x = 0;
        this.offset_y = 0;
        this.hlookup = 0;
        this.capture = false;
        this.moved = false;
    };

    jsMind.draggable.prototype = {
        init:function(){
            this._create_canvas();
            this._create_shadow();
            this._event_bind();
        },

        reset:function(){
            this.jm.view.e_nodes.appendChild(this.shadow);
            this.e_canvas.width=this.jm.view.size.w;
            this.e_canvas.height=this.jm.view.size.h;
        },

        _create_canvas:function(){
            var c = $d.createElement('canvas');
            this.jm.view.e_panel.appendChild(c);
            var ctx = c.getContext('2d');
            this.e_canvas = c;
            this.canvas_ctx = ctx;
        },

        _create_shadow:function(){
            var s = $d.createElement('jmnode');
            s.style.visibility = 'hidden';
            s.style.zIndex = '3';
            s.style.cursor = 'move';
            s.style.opacity= '0.7';
            this.shadow = s;
        },

        reset_shadow:function(el){
            var s = this.shadow.style;
            this.shadow.innerHTML = el.innerHTML;
            s.left = el.style.left;
            s.top = el.style.top;
            this.shadow_w = this.shadow.clientWidth;
            this.shadow_h = this.shadow.clientHeight;
        },

        show_shadow:function(){
            if(!this.moved){
                this.shadow.style.visibility = 'visible';
            }
        },

        hide_shadow:function(){
            this.shadow.style.visibility = 'hidden';
        },

        clear_lines:function(){
            jcanvas.clear(this.canvas_ctx, 0, 0, this.jm.view.size.w, this.jm.view.size.h);
        },

        _magnet_shadow:function(node){
            if(!!node){
                this.canvas_ctx.lineWidth = option.line_width;
                this.canvas_ctx.strokeStyle = 'rgba(0,0,0,0.3)';
                this.canvas_ctx.lineCap = 'round';
                this.clear_lines();
                jcanvas.lineto(this.canvas_ctx,
                    node.sp.x,
                    node.sp.y,
                    node.np.x,
                    node.np.y);
            }
        },

        _lookup_close_node:function(){
            var root = this.jm.get_root();
            var root_view_data = root._data.view;
            var root_x = root_view_data.abs_x + root_view_data.width/2;

            var sw = this.shadow_w;
            var sh = this.shadow_h;
            var sx = this.shadow.offsetLeft;
            var sy = this.shadow.offsetTop;

            var nw,nh,nx,ny;

            var direct = (sx + sw/2)>=root_x ?
                            jsMind.direction.right : jsMind.direction.left;
            var nodes = this.jm.mind.nodes;
            var node = null;
            var view_data = null;
            var min_distance = Number.MAX_VALUE;
            var distance = 0;
            var closest_node = null;
            var closest_p = null;
            var shadow_p = null;
            for(var nodeid in nodes){
                var np,sp;
                node = nodes[nodeid];
                if(node.isroot || node.direction == direct){
                    if(node.id == this.active_node.id){
                        continue;
                    }
                    view_data = node._data.view;
                    nw = view_data.width;
                    nh = view_data.height;
                    nx = view_data.abs_x;
                    ny = view_data.abs_y;
                    if(direct == jsMind.direction.right){
                        if(sx-nx-nw<=0){continue;}
                        distance = Math.abs(sx-nx-nw) + Math.abs(sy+sh/2-ny-nh/2);
                        np = {x:nx+nw-option.line_width,y:ny+nh/2};
                        sp = {x:sx+option.line_width,y:sy+sh/2};
                    }else{
                        if(nx-sx-sw<=0){continue;}
                        distance = Math.abs(sx+sw-nx) + Math.abs(sy+sh/2-ny-nh/2);
                        np = {x:nx+option.line_width,y:ny+nh/2};
                        sp = {x:sx+sw-option.line_width,y:sy+sh/2};
                    }
                    if(distance < min_distance){
                        closest_node = node;
                        closest_p = np;
                        shadow_p = sp;
                        min_distance = distance;
                    }
                }
            }
            var result_node = null;
            if(!!closest_node){
                result_node = {
                    node:closest_node,
                    direction:direct,
                    sp:shadow_p,
                    np:closest_p
                };
            }
            return result_node;
        },

        lookup_close_node:function(){
            var node_data = this._lookup_close_node();
            if(!!node_data){
                this._magnet_shadow(node_data);
                this.target_node = node_data.node;
                this.target_direct = node_data.direction;
            }
        },

        _event_bind:function(){
            var jd = this;
            var container = this.jm.view.container;
            jdom.add_event(container,'mousedown',function(e){jd.dragstart.call(jd,e);});
            jdom.add_event(container,'mousemove',function(e){jd.drag.call(jd,e);});
            jdom.add_event(container,'mouseup',function(e){jd.dragend.call(jd,e);});
        },

        dragstart:function(e){
            if(!this.jm.get_editable()){return;}
            if(this.capture){return;}
            this.active_node = null;

            var jview = this.jm.view;
            var el = e.target || event.srcElement;
            var isnode = jview.is_node(el);
            if(isnode){
                var nodeid = jview.get_nodeid(el);
                var node = this.jm.get_node(nodeid);
                if(!node.isroot){
                    this.reset_shadow(el);
                    this.active_node = node;
                    this.offset_x = e.clientX - el.offsetLeft;
                    this.offset_y = e.clientY - el.offsetTop;
                    this.client_hw = Math.floor(el.clientWidth/2);
                    this.client_hh = Math.floor(el.clientHeight/2);
                    if(this.hlookup != 0){
                        $w.clearInterval(this.hlookup);
                    }
                    var jd = this;
                    this.hlookup = $w.setInterval(function(){
                        jd.lookup_close_node.call(jd);
                    },400);
                    this.capture = true;
                }
            }
        },

        drag:function(e){
            if(!this.jm.get_editable()){return;}
            if(this.capture){
                this.show_shadow();
                this.moved = true;
                clear_selection();
                var px = e.clientX - this.offset_x;
                var py = e.clientY - this.offset_y;
                var cx = px + this.client_hw;
                var cy = py + this.client_hh;
                this.shadow.style.left = px + 'px';
                this.shadow.style.top = py + 'px';
                clear_selection();
            }
        },

        dragend:function(e){
            if(!this.jm.get_editable()){return;}
            if(this.capture){
                if(this.hlookup != 0){
                    $w.clearInterval(this.hlookup);
                    this.hlookup = 0;
                    this.clear_lines();
                }
                if(this.moved){
                    var src_node = this.active_node;
                    var target_node = this.target_node;
                    var target_direct = this.target_direct;
                    this.move_node(src_node,target_node,target_direct);
                }
                this.hide_shadow();
            }
            this.moved = false;
            this.capture = false;
        },

        move_node:function(src_node,target_node,target_direct){
            var shadow_h = this.shadow.offsetTop;
            if(!!target_node && !!src_node && !jsMind.node.inherited(src_node, target_node)){
                // lookup before_node
                var sibling_nodes = target_node.children;
                var sc = sibling_nodes.length;
                var node = null;
                var node_h = null;
                var delta_y = Number.MAX_VALUE;
                var node_before = null;
                var beforeid = '_last_';
                while(sc--){
                    node = sibling_nodes[sc];
                    if(node.direction == target_direct && node.id != src_node.id){
                        node_h = node._data.view.abs_y;
                        var dy = node_h - shadow_h;
                        if(dy > 0 && dy < delta_y){
                            delta_y = dy;
                            node_before = node;
                            beforeid = '_first_';
                        }
                    }
                }
                if(!!node_before){beforeid = node_before.id;}
                this.jm.move_node(src_node, beforeid, target_node.id, target_direct);
            }
            this.active_node = null;
            this.target_node = null;
            this.target_direct = null;
        }
    };

    var jm_event_handle = function(jm, type, data){
        if(type === 'init'){
            var jd = new jsMind.draggable(jm);
            jd.init();
            jm.draggable = jd;
        }
        if(type === 'show'){//reset
            var jd = jm.draggable;
            if(!!jd){
                jd.reset();
            }
        }
    };

    jsMind.add_event_handle(jm_event_handle);
})(window);
<|endoftext|>


<commit_before>require('./urls');
//require('./channel');
require('./calcul');
require('./pages');
<commit_msg>Channel tests added again<commit_after>require('./urls');
require('./channel');
require('./calcul');
require('./pages');
<|endoftext|>


<commit_before>// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    gvm.numberOfCompetencesToAdd = 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.getProjectInfo = function() {
        $.getJSON('/api/project/' + $("#projectHeader").data('value'), function(data) {
            gvm.pageHeader(data[0].code + ' - ' + data[0].name);
        });
    };
}

function addCompetence() {
    var competencePanelWrapper = document.createElement('div');
    var competencePanel = document.createElement('div');
    var competencePanelHeading = document.createElement('div');
    var competencePanelBody = document.createElement('div');
    var competencePanelFooter = document.createElement('div');
    var competenceCode = document.createElement('input');
    var competenceName = document.createElement('input');
    var subcompetenceButton = document.createElement('button');
    var removeCompetenceButton = document.createElement('button');

    competenceCode.type = 'text';
    competenceCode.placeholder = "Competence-Code";
    $(competenceCode).addClass("form-control");

    competenceName.type = 'text';
    competenceName.placeholder = "Name of the competence";
    $(competenceName).addClass("form-control");

    $(subcompetenceButton).addClass("btn");
    $(subcompetenceButton).text("Add a subcompetence");
    $(subcompetenceButton).val(viewModel.numberOfCompetencesToAdd);
    $(subcompetenceButton).on('click', function() {
        addSubCompetence("comp-" + $(subcompetenceButton).val())
    });

    $(removeCompetenceButton).addClass("btn pull-right");
    $(removeCompetenceButton).text("Remove this competence");
    $(removeCompetenceButton).val(viewModel.numberOfCompetencesToAdd);
    $(removeCompetenceButton).on('click', function() {
        $(".panel-" + $(removeCompetenceButton).val()).remove();
    });

    $(competencePanelWrapper).addClass("col-md-9 compPanel panel-" + $(subcompetenceButton).val());
    $(competencePanel).addClass("panel panel-default");
    $(competencePanelHeading).addClass("panel-heading comp-" + $(subcompetenceButton).val());
    $(competencePanelBody).addClass("panel-body comp-"  + $(subcompetenceButton).val());
    $(competencePanelFooter).addClass("panel-footer");

    if(!$(".compPanel")[0]) {
        $("#top-col").after(competencePanelWrapper);
    } else {
        $(".compPanel:last").after(competencePanelWrapper);
    }
    ++viewModel.numberOfCompetencesToAdd;
    $(competencePanelWrapper).append(competencePanel);
    $(competencePanel).append(competencePanelHeading);
    $(competencePanelHeading).append(competenceName);
    $(competenceName).after(competenceCode);
    $(competencePanelHeading).after(competencePanelBody);
    $(competencePanelBody).after(competencePanelFooter);
    $(competencePanelFooter).append(subcompetenceButton);
    $(subcompetenceButton).after(removeCompetenceButton);
}

function addSubCompetence(competence) {
    var subcompPanelWrapper = document.createElement('div');
    var subcompPanel = document.createElement('div');
    var subcompPanelHeading = document.createElement('div');
    var subcompPanelBody = document.createElement('div');
    var subcompPanelFooter = document.createElement('div');

    $(subcompPanelWrapper).addClass("subcompPanel");
    $(subcompPanel).addClass("panel panel-default");
    $(subcompPanelHeading).addClass("panel-heading");
    $(subcompPanelBody).addClass("panel-body");
    $(subcompPanelFooter).addClass("panel-footer");

    $(".panel-body." + competence).append(subcompPanelWrapper);
    $(subcompPanelWrapper).append(subcompPanel);
    $(subcompPanel).append(subcompPanelHeading);
    $(subcompPanelHeading).after(subcompPanelBody);
    $(subcompPanelBody).after(subcompPanelFooter);
}

function addIndicator() {

}

function initPage() {
    viewModel.getProjectInfo();
    $("#addCompetenceBtn").click(function() {
        addCompetence();
    })
}<commit_msg>projectpage<commit_after>// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    gvm.numberOfCompetencesToAdd = 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.getProjectInfo = function() {
        $.getJSON('/api/project/' + $("#projectHeader").data('value'), function(data) {
            gvm.pageHeader(data[0].code + ' - ' + data[0].name);
        });
    };
}

function addCompetence() {
    var competencePanelWrapper = document.createElement('div');
    var competencePanel = document.createElement('div');
    var competencePanelHeading = document.createElement('div');
    var competencePanelBody = document.createElement('div');
    var competencePanelFooter = document.createElement('div');
    var competenceCode = document.createElement('input');
    var competenceName = document.createElement('input');
    var subcompetenceButton = document.createElement('button');
    var removeCompetenceButton = document.createElement('button');

    competenceCode.type = 'text';
    competenceCode.placeholder = "Competence-Code";
    $(competenceCode).addClass("form-control");

    competenceName.type = 'text';
    competenceName.placeholder = "Name of the competence";
    $(competenceName).addClass("form-control");

    $(subcompetenceButton).addClass("btn");
    $(subcompetenceButton).text("Add a subcompetence");
    $(subcompetenceButton).val(viewModel.numberOfCompetencesToAdd);
    $(subcompetenceButton).on('click', function() {
        addSubCompetence("comp-" + $(subcompetenceButton).val())
    });

    $(removeCompetenceButton).addClass("btn pull-right");
    $(removeCompetenceButton).text("Remove this competence");
    $(removeCompetenceButton).val(viewModel.numberOfCompetencesToAdd);
    $(removeCompetenceButton).on('click', function() {
        $(".panel-" + $(removeCompetenceButton).val()).remove();
    });

    $(competencePanelWrapper).addClass("col-md-9 compPanel panel-" + $(subcompetenceButton).val());
    $(competencePanel).addClass("panel panel-default");
    $(competencePanelHeading).addClass("panel-heading comp-" + $(subcompetenceButton).val());
    $(competencePanelBody).addClass("panel-body comp-"  + $(subcompetenceButton).val());
    $(competencePanelFooter).addClass("panel-footer");

    if(!$(".compPanel")[0]) {
        $("#top-col").after(competencePanelWrapper);
    } else {
        $(".compPanel:last").after(competencePanelWrapper);
    }
    ++viewModel.numberOfCompetencesToAdd;
    $(competencePanelWrapper).append(competencePanel);
    $(competencePanel).append(competencePanelHeading);
    $(competencePanelHeading).append(competenceName);
    $(competenceName).after(competenceCode);
    $(competencePanelHeading).after(competencePanelBody);
    $(competencePanelBody).after(competencePanelFooter);
    $(competencePanelFooter).append(subcompetenceButton);
    $(subcompetenceButton).after(removeCompetenceButton);
}

function addSubCompetence(competence) {
    var subcompPanelWrapper = document.createElement('div');
    var subcompPanel = document.createElement('div');
    var subcompPanelHeading = document.createElement('div');
    var subcompPanelBody = document.createElement('div');
    var subcompPanelFooter = document.createElement('div');
    var subcompCode = document.createElement('input');
    var subcompName = document.createElement('input');
    var indicatorButton = document.createElement('button');
    var removeSubcompButton = document.createElement('button');

    subcompCode.type = 'text';
    subcompCode.placeholder = "Competence-Code";
    $(subcompCode).addClass("form-control");

    subcompName.type = 'text';
    subcompName.placeholder = "Name of the competence";
    $(subcompName).addClass("form-control");

    $(indicatorButton).addClass("btn");
    $(indicatorButton).text("Add a subcompetence");
    $(indicatorButton).val(viewModel.numberOfCompetencesToAdd);
    $(indicatorButton).on('click', function() {
        addSubCompetence("comp-" + $(subcompetenceButton).val())
    });

    $(removeSubcompButton).addClass("btn pull-right");
    $(removeSubcompButton).text("Remove this competence");
    $(removeSubcompButton).val(viewModel.numberOfCompetencesToAdd);
    $(removeSubcompButton).on('click', function() {
        $(".panel-" + $(removeCompetenceButton).val()).remove();
    });

    $(subcompPanelWrapper).addClass("subcompPanel");
    $(subcompPanel).addClass("panel panel-default");
    $(subcompPanelHeading).addClass("panel-heading");
    $(subcompPanelBody).addClass("panel-body");
    $(subcompPanelFooter).addClass("panel-footer");

    $(".panel-body." + competence).append(subcompPanelWrapper);
    $(subcompPanelWrapper).append(subcompPanel);
    $(subcompPanel).append(subcompPanelHeading);
    $(subcompPanelHeading).append(subcompName);
    $(subcompName).after(subcompCode);
    $(subcompPanelHeading).after(subcompPanelBody);
    $(subcompPanelBody).after(subcompPanelFooter);
    $(subcompPanelFooter).after(indicatorButton);
    $(indicatorButton).after(removeSubcompButton);

    $(competencePanelWrapper).append(competencePanel);
    $(competencePanel).append(competencePanelHeading);
    $(competencePanelHeading).append(competenceName);
    $(competenceName).after(competenceCode);
    $(competencePanelHeading).after(competencePanelBody);
    $(competencePanelBody).after(competencePanelFooter);
    $(competencePanelFooter).append(subcompetenceButton);
    $(subcompetenceButton).after(removeCompetenceButton);
}

function addIndicator() {

}

function initPage() {
    viewModel.getProjectInfo();
    $("#addCompetenceBtn").click(function() {
        addCompetence();
    })
}<|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);
        },

        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);
        },

        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;
        this.weight = 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>weight check<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);
        },

        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);
        },

        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|>


<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: false,
        subcompetences: ko.observableArray(subcompetences),

        addSubCompetence: function() {
            this.subcompetences.push(new SubCompetence(this));
            automatedWeightCalculation(this.subcompetences());
            /*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);
            automatedWeightCalculation(this.subcompetences());
        }
    };

}

/**
 * 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: false,
        indicators: ko.observableArray(indicators),

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

        /*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);
            automatedWeightCalculation(this.indicators());
        }

    };
}

/**
 * Indicator class
 */
function Indicator(parent, id, name, weight, locked, description) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: false,
        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));
        automatedWeightCalculation(this.competences());

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

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

    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(){
        if(totalPercentCheck()) {
            saveProjectStructure();
            console.log("Saved");
        }
        else
        {
            console.log("Not saved");
        }
    });
}

function totalPercentCheck()
{
    var totalPercentCompetences = 0;
    var totalPercentSubcompetences = new Array();
    var totalPercentIndicators = new Array();
    var nrOfSubcompetences = 0;
    var nrOfIndicators = 0;

    var checkSubcompetences = true;
    var checkIndicators = true;

    for(var indexCompetences =0; indexCompetences < viewModel.competences().length; indexCompetences++)
    {
        totalPercentCompetences = totalPercentCompetences + parseInt(viewModel.competences()[indexCompetences].weight());
        totalPercentSubcompetences.push(0);
        for(var indexSubcompetence = 0; indexSubcompetence < viewModel.competences()[indexCompetences].subcompetences().length; indexSubcompetence++)
        {
            console.log(viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].weight());
            totalPercentSubcompetences[nrOfSubcompetences] = totalPercentSubcompetences[nrOfSubcompetences] + parseInt(viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].weight());
            totalPercentIndicators.push(0);
            for(var indexIndicators = 0; indexIndicators < viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].indicators().length; indexIndicators++)
            {
                console.log(viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].indicators()[indexIndicators].weight());
                totalPercentIndicators[nrOfIndicators] = totalPercentIndicators[nrOfIndicators] + parseInt(viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].indicators()[indexIndicators].weight());
            }
            nrOfIndicators++;
        }
        nrOfSubcompetences++;
    }

    console.log(nrOfSubcompetences + " and " + nrOfIndicators);

    for(var i = 0; i < nrOfSubcompetences - 1; i++)
    {
        if(totalPercentSubcompetences[i] != 100)
        {
            checkSubcompetences = false;
        }
    }

    for(var index = 0; index < nrOfIndicators - 1; index++)
    {
        if(totalPercentIndicators[index] != 100)
        {
            checkIndicators = false;
        }
    }

    console.log(checkSubcompetences + " and " + checkIndicators)

    if(totalPercentCompetences == 100 && checkSubcompetences && checkIndicators )
    {
        return true;
    }
    else
    {
        return false;
    }
}

function automatedWeightCalculation(data)
{
    var lockedPercent = 0;
    var nrOfUnlocked = 0;

    for(var index = 0; index < data.length; index++)
    {
        if(data[index].locked == true)
        {
            lockedPercent = lockedPercent + parseInt(data[index].weight());
        }
        else
        {
            nrOfUnlocked++;
        }
    }

    var remainingPercent = 100 - lockedPercent;

    var percentPerCompetence = remainingPercent / nrOfUnlocked;

    percentPerCompetence = percentPerCompetence.toFixed(2);

    for(var index = 0; index < data.length; index++)
    {
        if(data[index].locked == false)
        {
            data[index].weight(percentPerCompetence);
        }
    }
}
<commit_msg>total procent check<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: false,
        subcompetences: ko.observableArray(subcompetences),

        addSubCompetence: function() {
            this.subcompetences.push(new SubCompetence(this));
            automatedWeightCalculation(this.subcompetences());
            /*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);
            automatedWeightCalculation(this.subcompetences());
        }
    };

}

/**
 * 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: false,
        indicators: ko.observableArray(indicators),

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

        /*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);
            automatedWeightCalculation(this.indicators());
        }

    };
}

/**
 * Indicator class
 */
function Indicator(parent, id, name, weight, locked, description) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        weight: ko.observable(weight),
        locked: false,
        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));
        automatedWeightCalculation(this.competences());

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

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

    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(){
        if(totalPercentCheck()) {
            saveProjectStructure();
            console.log("Saved");
        }
        else
        {
            console.log("Not saved");
        }
    });
}

function totalPercentCheck()
{
    var totalPercentCompetences = 0;
    var totalPercentSubcompetences = new Array();
    var totalPercentIndicators = new Array();
    var nrOfSubcompetences = 0;
    var nrOfIndicators = 0;

    var checkSubcompetences = true;
    var checkIndicators = true;

    for(var indexCompetences =0; indexCompetences < viewModel.competences().length; indexCompetences++)
    {
        totalPercentCompetences = totalPercentCompetences + parseInt(viewModel.competences()[indexCompetences].weight());
        totalPercentSubcompetences.push(0);
        for(var indexSubcompetence = 0; indexSubcompetence < viewModel.competences()[indexCompetences].subcompetences().length; indexSubcompetence++)
        {
            console.log(viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].weight());
            totalPercentSubcompetences[nrOfSubcompetences] = totalPercentSubcompetences[nrOfSubcompetences] + parseInt(viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].weight());
            totalPercentIndicators.push(0);
            for(var indexIndicators = 0; indexIndicators < viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].indicators().length; indexIndicators++)
            {
                console.log(viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].indicators()[indexIndicators].weight());
                totalPercentIndicators[nrOfIndicators] = totalPercentIndicators[nrOfIndicators] + parseInt(viewModel.competences()[indexCompetences].subcompetences()[indexSubcompetence].indicators()[indexIndicators].weight());
            }
            nrOfIndicators++;
        }
        nrOfSubcompetences++;
    }

    for(var i = 0; i < nrOfSubcompetences - 1; i++)
    {
        if(totalPercentSubcompetences[i] != 100)
        {
            checkSubcompetences = false;
        }
    }

    for(var index = 0; index < nrOfIndicators - 1; index++)
    {
        if(totalPercentIndicators[index] != 100)
        {
            checkIndicators = false;
        }
    }

    if(totalPercentCompetences == 100 && checkSubcompetences && checkIndicators )
    {
        return true;
    }
    else
    {
        return false;
    }
}

function automatedWeightCalculation(data)
{
    var lockedPercent = 0;
    var nrOfUnlocked = 0;

    for(var index = 0; index < data.length; index++)
    {
        if(data[index].locked == true)
        {
            lockedPercent = lockedPercent + parseInt(data[index].weight());
        }
        else
        {
            nrOfUnlocked++;
        }
    }

    var remainingPercent = 100 - lockedPercent;

    var percentPerCompetence = remainingPercent / nrOfUnlocked;

    percentPerCompetence = percentPerCompetence.toFixed(2);

    for(var index = 0; index < data.length; index++)
    {
        if(data[index].locked == false)
        {
            data[index].weight(percentPerCompetence);
        }
    }
}
<|endoftext|>


<commit_before>export const WEEKDAYS = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday']
export const WEEKEND_DAYS = ['saturday', 'sunday']
export const ALL_DAYS = [...WEEKDAYS, ...WEEKEND_DAYS]

/**
 * Extracts the day of week fields of an object (e.g. a monitoredTrip) to an array.
 * Example: { monday: truthy, tuesday: falsy, wednesday: truthy ... } => ['monday', 'wednesday' ...]
 */
export function dayFieldsToArray (monitoredTrip) {
  return ALL_DAYS.filter(day => monitoredTrip[day])
}

/**
 * Converts an array of day of week values into an object with those fields.
 * Example: ['monday', 'wednesday' ...] => { monday: true, tuesday: false, wednesday: true ... }
 */
export function arrayToDayFields (arrayOfDayTypes) {
  const result = {}
  ALL_DAYS.forEach(day => {
    result[day] = arrayOfDayTypes.includes(day)
  })
  return result
}

/**
 * Returns a FormattedMessage string for the pluralised day of week via the react-intl imperative API
 * such that i18n IDs are hardcoded and can be kept track of by format.js tools
 */
export function getFormattedDayOfWeekPlural (day, intl) {
  switch (day) {
    case 'monday':
      return intl.formatMessage({id: 'common.daysOfWeekPlural.monday'})
    case 'tuesday':
      return intl.formatMessage({id: 'common.daysOfWeekPlural.tuesday'})
    case 'wednesday':
      return intl.formatMessage({id: 'common.daysOfWeekPlural.wednesday'})
    case 'thursday':
      return intl.formatMessage({id: 'common.daysOfWeekPlural.thursday'})
    case 'friday':
      return intl.formatMessage({id: 'common.daysOfWeekPlural.friday'})
    case 'saturday':
      return intl.formatMessage({id: 'common.daysOfWeekPlural.saturday'})
    case 'sunday':
      return intl.formatMessage({id: 'common.daysOfWeekPlural.sunday'})
    default:
      return null
  }
}
<commit_msg>chore: correct typo<commit_after>export const WEEKDAYS = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday']
export const WEEKEND_DAYS = ['saturday', 'sunday']
export const ALL_DAYS = [...WEEKDAYS, ...WEEKEND_DAYS]

/**
 * Extracts the day of week fields of an object (e.g. a monitoredTrip) to an array.
 * Example: { monday: truthy, tuesday: falsey, wednesday: truthy ... } => ['monday', 'wednesday' ...]
 */
export function dayFieldsToArray(monitoredTrip) {
  return ALL_DAYS.filter((day) => monitoredTrip[day])
}

/**
 * Converts an array of day of week values into an object with those fields.
 * Example: ['monday', 'wednesday' ...] => { monday: true, tuesday: false, wednesday: true ... }
 */
export function arrayToDayFields(arrayOfDayTypes) {
  const result = {}
  ALL_DAYS.forEach((day) => {
    result[day] = arrayOfDayTypes.includes(day)
  })
  return result
}

/**
 * Returns a FormattedMessage string for the pluralised day of week via the react-intl imperative API
 * such that i18n IDs are hardcoded and can be kept track of by format.js tools
 */
export function getFormattedDayOfWeekPlural(day, intl) {
  switch (day) {
    case 'monday':
      return intl.formatMessage({ id: 'common.daysOfWeekPlural.monday' })
    case 'tuesday':
      return intl.formatMessage({ id: 'common.daysOfWeekPlural.tuesday' })
    case 'wednesday':
      return intl.formatMessage({ id: 'common.daysOfWeekPlural.wednesday' })
    case 'thursday':
      return intl.formatMessage({ id: 'common.daysOfWeekPlural.thursday' })
    case 'friday':
      return intl.formatMessage({ id: 'common.daysOfWeekPlural.friday' })
    case 'saturday':
      return intl.formatMessage({ id: 'common.daysOfWeekPlural.saturday' })
    case 'sunday':
      return intl.formatMessage({ id: 'common.daysOfWeekPlural.sunday' })
    default:
      return null
  }
}
<|endoftext|>


<commit_before>'use strict';

var Promise = require('bluebird');
var moment = require('moment');
var fs = require('fs');
var dataSchema = require('./data_utils');
var _ = require('lodash');

function dateOptions(value) {
    var timeInterval = value.toLowerCase();
    var options = {
        year: 'y', years: 'y', 'y': 'y',
        months: 'M', month: 'M', mo: 'M', mos: 'M', M: 'M',
        weeks: 'w', week: 'w', wks: 'w', wk: 'w', w: 'w',
        days: 'd', day: 'd', d: 'd',
        hours: 'h', hour: 'h', hr: 'h', hrs: 'h', h: 'h',
        minutes: 'm', minute: 'm', min: 'm', mins: 'm', m: 'm',
        seconds: 's', second: 's', s: 's',
        milliseconds: 'ms', millisecond: 'ms', ms: 'ms'
    };

    if (options[timeInterval]) {
        return options[timeInterval];
    }
    else {
        throw new Error('date interval is not formatted correctly')
    }
}

function processInterval(str) {
    if (!moment(new Date(str)).isValid()) {
        //one or more digits, followed by one or more letters, case-insensitive
        var regex = /(\d+)([a-z]+)/i;
        var interval = regex.exec(str);

        if (interval === null) {
            throw  new Error('elasticsearch_reader interval and/or delay are incorrectly formatted. Needs to follow ' +
                '[number][letter\'s] format, e.g. "12s"')
        }

        //dont need first parameter, its the full string
        interval.shift();

        interval[1] = dateOptions(interval[1]);
        return interval;
    }
    else {
        throw  new Error('elasticsearch_reader interval and/or delay are incorrectly formatted. Needs to follow ' +
            '[number][letter\'s] format, e.g. "12s"')
    }
}

function buildRangeQuery(source, obj) {
    var date_field_name = source.date_field_name;
    var dateObj = {};

    dateObj[date_field_name] = {
        gte: obj.start,
        lt: obj.end
    };

    var body;

    if (obj.key) {
        body = {
            query: {
                must: [
                    {range: dateObj},
                    {wildcard: {_uid: obj.key}}
                ]
            }
        }
    }
    else {
        body = {
            query: {
                filtered: {
                    filter: {
                        range: dateObj
                    }
                }
            }
        };
    }

    return body;
}

function buildQuery(source, msg) {

    var query = {
        index: source.index,
        size: msg.count,
        body: buildRangeQuery(source, msg)
    };

    if (source.query) {
        query.q = source.query;
    }

    return query;
}

function getSchema(config) {

    if (config.json_schema) {
        var firstPath = config.json_schema;
        var nextPath = process.cwd() + '/' + config.json_schema;

        try {
            if (fs.existsSync(firstPath)) {
                return {schema: require(firstPath), isDefault: false};
            }
            else {
                return {schema: require(nextPath), isDefault: false};
            }
        }
        catch (e) {
            throw new Error('Could not retrieve code for: ' + opConfig + '\n' + e);
        }
    }
    else {
        return {schema: dataSchema, isDefault: true};
    }
}

function parsedSchema(opConfig) {
    var results = getSchema(opConfig);
    var schema = results.schema;
    var created = schema.properties.created;

    if (results.isDefault) {
        if (opConfig.format) {
            created.format = opConfig.format;
        }

        if (opConfig.start) {
            created.start = opConfig.start;
        }

        if (opConfig.end) {
            created.end = opConfig.end;
        }
    }

    return schema;
}

function logState(state_store) {
    return function(jobConfig, slice, status, error) {
        if (jobConfig.lifecycle !== "persistent") {
            return state_store.log(jobConfig.job_id, slice, status, error)
                .catch(function(err) {
                    jobConfig.logger.error("Error when saving state record: " + err)
                });
        }
        else {
            return Promise.resolve(true)
        }
    }
}

function warn(logger, msg) {
    var loggerFn = _.throttle(function() {
        logger.warn(msg)
    }, 5000);

    return loggerFn;
}

function filterResponse(logger, data, results) {
    var nonRetriableError = false;
    var reason = '';
    var retry = [];
    var items = results.items;

    for (var i = 0; i < items.length; i++) {
        //key could either be create or delete etc, just want the actual data at the value spot
        var item = _.values(items[i])[0];
        if (item.error) {
            //is this the right thing to check?
            if (item.error.type === 'es_rejected_execution_exception') {
                if (i === 0) {
                    retry.push(data[0], data[1])
                }
                else {
                    retry.push(data[i * 2], data[i * 2 + 1])
                }
            }
            else {
                nonRetriableError = true;
                reason = item.error.reason;
                break;
            }
        }
    }

    if (nonRetriableError) {
        return {data: [], error: nonRetriableError};
    }

    return {data: retry, error: false};
}

//"2016-01-19T13:33:09.356-07:00"
var dateFormat = "YYYY-MM-DDTHH:mm:ss.SSSZ";

module.exports = {
    dateOptions: dateOptions,
    processInterval: processInterval,
    buildRangeQuery: buildRangeQuery,
    buildQuery: buildQuery,
    getSchema: getSchema,
    parsedSchema: parsedSchema,
    dateFormat: dateFormat,
    logState: logState,
    filterResponse: filterResponse,
    warn: warn
};<commit_msg>dsl fix (#262)<commit_after>'use strict';

var Promise = require('bluebird');
var moment = require('moment');
var fs = require('fs');
var dataSchema = require('./data_utils');
var _ = require('lodash');

function dateOptions(value) {
    var timeInterval = value.toLowerCase();
    var options = {
        year: 'y', years: 'y', 'y': 'y',
        months: 'M', month: 'M', mo: 'M', mos: 'M', M: 'M',
        weeks: 'w', week: 'w', wks: 'w', wk: 'w', w: 'w',
        days: 'd', day: 'd', d: 'd',
        hours: 'h', hour: 'h', hr: 'h', hrs: 'h', h: 'h',
        minutes: 'm', minute: 'm', min: 'm', mins: 'm', m: 'm',
        seconds: 's', second: 's', s: 's',
        milliseconds: 'ms', millisecond: 'ms', ms: 'ms'
    };

    if (options[timeInterval]) {
        return options[timeInterval];
    }
    else {
        throw new Error('date interval is not formatted correctly')
    }
}

function processInterval(str) {
    if (!moment(new Date(str)).isValid()) {
        //one or more digits, followed by one or more letters, case-insensitive
        var regex = /(\d+)([a-z]+)/i;
        var interval = regex.exec(str);

        if (interval === null) {
            throw  new Error('elasticsearch_reader interval and/or delay are incorrectly formatted. Needs to follow ' +
                '[number][letter\'s] format, e.g. "12s"')
        }

        //dont need first parameter, its the full string
        interval.shift();

        interval[1] = dateOptions(interval[1]);
        return interval;
    }
    else {
        throw  new Error('elasticsearch_reader interval and/or delay are incorrectly formatted. Needs to follow ' +
            '[number][letter\'s] format, e.g. "12s"')
    }
}

function buildRangeQuery(source, obj) {
    var date_field_name = source.date_field_name;
    var dateObj = {};

    dateObj[date_field_name] = {
        gte: obj.start,
        lt: obj.end
    };

    var body;

    if (obj.key) {
        body = {
            query: {
                bool: {
                    must: [
                        {range: dateObj},
                        {wildcard: {_uid: obj.key}}
                    ]
                }
            }
        }
    }
    else {
        body = {
            query: {
                filtered: {
                    filter: {
                        range: dateObj
                    }
                }
            }
        };
    }

    return body;
}

function buildQuery(source, msg) {

    var query = {
        index: source.index,
        size: msg.count,
        body: buildRangeQuery(source, msg)
    };

    if (source.query) {
        query.q = source.query;
    }

    return query;
}

function getSchema(config) {

    if (config.json_schema) {
        var firstPath = config.json_schema;
        var nextPath = process.cwd() + '/' + config.json_schema;

        try {
            if (fs.existsSync(firstPath)) {
                return {schema: require(firstPath), isDefault: false};
            }
            else {
                return {schema: require(nextPath), isDefault: false};
            }
        }
        catch (e) {
            throw new Error('Could not retrieve code for: ' + opConfig + '\n' + e);
        }
    }
    else {
        return {schema: dataSchema, isDefault: true};
    }
}

function parsedSchema(opConfig) {
    var results = getSchema(opConfig);
    var schema = results.schema;
    var created = schema.properties.created;

    if (results.isDefault) {
        if (opConfig.format) {
            created.format = opConfig.format;
        }

        if (opConfig.start) {
            created.start = opConfig.start;
        }

        if (opConfig.end) {
            created.end = opConfig.end;
        }
    }

    return schema;
}

function logState(state_store) {
    return function(jobConfig, slice, status, error) {
        if (jobConfig.lifecycle !== "persistent") {
            return state_store.log(jobConfig.job_id, slice, status, error)
                .catch(function(err) {
                    jobConfig.logger.error("Error when saving state record: " + err)
                });
        }
        else {
            return Promise.resolve(true)
        }
    }
}

function warn(logger, msg) {
    var loggerFn = _.throttle(function() {
        logger.warn(msg)
    }, 5000);

    return loggerFn;
}

function filterResponse(logger, data, results) {
    var nonRetriableError = false;
    var reason = '';
    var retry = [];
    var items = results.items;

    for (var i = 0; i < items.length; i++) {
        //key could either be create or delete etc, just want the actual data at the value spot
        var item = _.values(items[i])[0];
        if (item.error) {
            //is this the right thing to check?
            if (item.error.type === 'es_rejected_execution_exception') {
                if (i === 0) {
                    retry.push(data[0], data[1])
                }
                else {
                    retry.push(data[i * 2], data[i * 2 + 1])
                }
            }
            else {
                nonRetriableError = true;
                reason = item.error.reason;
                break;
            }
        }
    }

    if (nonRetriableError) {
        return {data: [], error: nonRetriableError};
    }

    return {data: retry, error: false};
}

//"2016-01-19T13:33:09.356-07:00"
var dateFormat = "YYYY-MM-DDTHH:mm:ss.SSSZ";

module.exports = {
    dateOptions: dateOptions,
    processInterval: processInterval,
    buildRangeQuery: buildRangeQuery,
    buildQuery: buildQuery,
    getSchema: getSchema,
    parsedSchema: parsedSchema,
    dateFormat: dateFormat,
    logState: logState,
    filterResponse: filterResponse,
    warn: warn
};<|endoftext|>


<commit_before>
module.exports = errorHandler

var cbCalled = false
  , log = require("./log")
  , npm = require("../../npm")
  , rm = require("./rm-rf")
  , constants = require("constants")
  , itWorked = false
  , path = require("path")

process.on("exit", function (code) {
  if (code) itWorked = false
  if (itWorked) log("ok")
  else {
    log.error([""
              ,"Additional logging details can be found in:"
              ,"    " + path.resolve("npm-debug.log")
              ].join("\n"))
    log.win("not ok")
  }
  itWorked = false // ready for next exit
})

function errorHandler (er) {
  if (cbCalled) throw new Error("Callback called more than once.")
  cbCalled = true
  if (!er) return exit(0)
  if (!(er instanceof Error)) {
    log.error(er)
    return exit(1)
  }
  if (!er.errno) {
    var m = er.message.match(/^(?:Error: )?(E[A-Z]+)/)
    if (m) {
      m = m[1]
      if (!constants[m] && !npm[m]) constants[m] = {}
      er.errno = npm[m] || constants[m]
    }
  }

  switch (er.errno) {
  case constants.ECONNREFUSED:
    log.error(er)
    log.error(["If you are using Cygwin, please set up your /etc/resolv.conf"
              ,"See step 4 in this wiki page:"
              ,"    http://github.com/ry/node/wiki/Building-node.js-on-Cygwin-%28Windows%29"
              ,"If you are not using Cygwin, please report this"
              ,"at <http://github.com/isaacs/npm/issues>"
              ,"or email it to <npm-@googlegroups.com>"
              ].join("\n"))
    break

  case constants.EACCES:
  case constants.EPERM:
    log.error(er)
    log.error(["",
              "Please use 'sudo' or log in as root to run this command."
              ,""
              ,"    sudo npm "
                +npm.config.get("argv").original.map(JSON.stringify).join(" ")
              ,""
              ,"or set the 'unsafe-perm' config var to true."
              ,""
              ,"    npm config set unsafe-perm true"
              ].join("\n"))
    break

  case npm.ELIFECYCLE:
    log.error(er.message)
    log.error(["","Failed at the "+er.pkgid+" "+er.stage+" script."
              ,"This is most likely a problem with the "+er.pkgname+" package,"
              ,"not with npm itself."
              ,"Tell the author that this fails on your system:"
              ,"    "+er.script
              ,"You can get their info via:"
              ,"    npm owner ls "+er.pkgname
              ,"There is likely additional logging output above."
              ].join("\n"))
    break

  case npm.EJSONPARSE:
    log.error(er.message)
    log.error("File: "+er.file)
    log.error(["Failed to parse package.json data."
              ,"package.json must be actual JSON, not just JavaScript."
              ,"","This is not a bug in npm."
              ,"Tell the package author to fix their package.json file."
              ].join("\n"), "JSON.parse")
    break

  case npm.E404:
    log.error(["'"+er.pkgid+"' is not in the npm registry."
              ,"You should bug the author to publish it."
              ,"Note that you can also install from a tarball or folder."
              ].join("\n"), "404")
    break

  case npm.EPUBLISHCONFLICT:
    log.error(["Cannot publish over existing version."
              ,"Bump the 'version' field, set the --force flag, or"
              ,"    npm unpublish '"+er.pkgid+"'"
              ,"and try again"
              ].join("\n"), "publish fail" )
    break

  case npm.EISGIT:
    log.error([er.message
              ,"    "+er.path
              ,"Refusing to remove it. Update manually,"
              ,"or move it out of the way first."
              ].join("\n"), "git" )
    break

  case npm.ECYCLE:
    log.error([er.message
              ,"While installing: "+er.pkgid
              ,"Found a pathological dependency case that npm cannot solve."
              ,"Please report this to the package author."
              ].join("\n"))
    break

  case npm.EENGINE:
    log.error([er.message
              ,"Not compatible with your version of node/npm: "+er.pkgid
              ,"Required: "+JSON.stringify(er.required)
              ,"Actual:   "+JSON.stringify({npm:npm.version
                                           ,node:process.version})
              ].join("\n"))
    break

  case constants.EEXIST:
    log.error([er.message
              ,"File exists: "+er.path
              ,"Move it away, and try again."].join("\n"))
    break

  default:
    log.error(er)
    log.error(["Report this *entire* log at:"
              ,"    <http://github.com/isaacs/npm/issues>"
              ,"or email it to:"
              ,"    <npm-@googlegroups.com>"
              ].join("\n"))
    break
  }

  var os = require("os")
  log.error("")
  log.error(os.type() + " " + os.release(), "System")
  log.error(process.argv
            .map(JSON.stringify).join(" "), "command")
  exit(typeof er.errno === "number" ? er.errno : 1)
}

function exit (code) {
  var doExit = npm.config.get("_exit")
  log.verbose([code, doExit], "exit")
  if (code) writeLogFile(reallyExit)
  else rm(npm.tmp, reallyExit)
  function reallyExit() {
    itWorked = !code
    if (doExit) process.exit(code || 0)
    else process.emit("exit", code || 0)
  }
}

function writeLogFile (cb) {
  var fs = require("./graceful-fs")
    , fstr = fs.createWriteStream("npm-debug.log")
    , sys = require("util")

  log.history.forEach(function (m) {
    var lvl = log.LEVEL[m.level]
      , pref = m.pref ? " " + m.pref : ""
      , b = lvl + pref + " "
      , msg = typeof m.msg === "string" ? m.msg
            : msg instanceof Error ? msg.stack || msg.message
            : sys.inspect(m.msg, 0, 4)
    fstr.write(new Buffer(b
                         +(msg.split(/\n+/).join("\n"+b))
                         + "\n"))
  })
  fstr.on("close", cb)
}
<commit_msg>delete debug log on success<commit_after>
module.exports = errorHandler

var cbCalled = false
  , log = require("./log")
  , npm = require("../../npm")
  , rm = require("./rm-rf")
  , constants = require("constants")
  , itWorked = false
  , path = require("path")

process.on("exit", function (code) {
  if (code) itWorked = false
  if (itWorked) log("ok")
  else {
    log.error([""
              ,"Additional logging details can be found in:"
              ,"    " + path.resolve("npm-debug.log")
              ].join("\n"))
    log.win("not ok")
  }
  itWorked = false // ready for next exit
})

function errorHandler (er) {
  if (cbCalled) throw new Error("Callback called more than once.")
  cbCalled = true
  if (!er) return exit(0)
  if (!(er instanceof Error)) {
    log.error(er)
    return exit(1)
  }
  if (!er.errno) {
    var m = er.message.match(/^(?:Error: )?(E[A-Z]+)/)
    if (m) {
      m = m[1]
      if (!constants[m] && !npm[m]) constants[m] = {}
      er.errno = npm[m] || constants[m]
    }
  }

  switch (er.errno) {
  case constants.ECONNREFUSED:
    log.error(er)
    log.error(["If you are using Cygwin, please set up your /etc/resolv.conf"
              ,"See step 4 in this wiki page:"
              ,"    http://github.com/ry/node/wiki/Building-node.js-on-Cygwin-%28Windows%29"
              ,"If you are not using Cygwin, please report this"
              ,"at <http://github.com/isaacs/npm/issues>"
              ,"or email it to <npm-@googlegroups.com>"
              ].join("\n"))
    break

  case constants.EACCES:
  case constants.EPERM:
    log.error(er)
    log.error(["",
              "Please use 'sudo' or log in as root to run this command."
              ,""
              ,"    sudo npm "
                +npm.config.get("argv").original.map(JSON.stringify).join(" ")
              ,""
              ,"or set the 'unsafe-perm' config var to true."
              ,""
              ,"    npm config set unsafe-perm true"
              ].join("\n"))
    break

  case npm.ELIFECYCLE:
    log.error(er.message)
    log.error(["","Failed at the "+er.pkgid+" "+er.stage+" script."
              ,"This is most likely a problem with the "+er.pkgname+" package,"
              ,"not with npm itself."
              ,"Tell the author that this fails on your system:"
              ,"    "+er.script
              ,"You can get their info via:"
              ,"    npm owner ls "+er.pkgname
              ,"There is likely additional logging output above."
              ].join("\n"))
    break

  case npm.EJSONPARSE:
    log.error(er.message)
    log.error("File: "+er.file)
    log.error(["Failed to parse package.json data."
              ,"package.json must be actual JSON, not just JavaScript."
              ,"","This is not a bug in npm."
              ,"Tell the package author to fix their package.json file."
              ].join("\n"), "JSON.parse")
    break

  case npm.E404:
    log.error(["'"+er.pkgid+"' is not in the npm registry."
              ,"You should bug the author to publish it."
              ,"Note that you can also install from a tarball or folder."
              ].join("\n"), "404")
    break

  case npm.EPUBLISHCONFLICT:
    log.error(["Cannot publish over existing version."
              ,"Bump the 'version' field, set the --force flag, or"
              ,"    npm unpublish '"+er.pkgid+"'"
              ,"and try again"
              ].join("\n"), "publish fail" )
    break

  case npm.EISGIT:
    log.error([er.message
              ,"    "+er.path
              ,"Refusing to remove it. Update manually,"
              ,"or move it out of the way first."
              ].join("\n"), "git" )
    break

  case npm.ECYCLE:
    log.error([er.message
              ,"While installing: "+er.pkgid
              ,"Found a pathological dependency case that npm cannot solve."
              ,"Please report this to the package author."
              ].join("\n"))
    break

  case npm.EENGINE:
    log.error([er.message
              ,"Not compatible with your version of node/npm: "+er.pkgid
              ,"Required: "+JSON.stringify(er.required)
              ,"Actual:   "+JSON.stringify({npm:npm.version
                                           ,node:process.version})
              ].join("\n"))
    break

  case constants.EEXIST:
    log.error([er.message
              ,"File exists: "+er.path
              ,"Move it away, and try again."].join("\n"))
    break

  default:
    log.error(er)
    log.error(["Report this *entire* log at:"
              ,"    <http://github.com/isaacs/npm/issues>"
              ,"or email it to:"
              ,"    <npm-@googlegroups.com>"
              ].join("\n"))
    break
  }

  var os = require("os")
  log.error("")
  log.error(os.type() + " " + os.release(), "System")
  log.error(process.argv
            .map(JSON.stringify).join(" "), "command")
  exit(typeof er.errno === "number" ? er.errno : 1)
}

function exit (code) {
  var doExit = npm.config.get("_exit")
  log.verbose([code, doExit], "exit")
  if (code) writeLogFile(reallyExit)
  else {
    rm("npm-debug.log", function () { rm(npm.tmp, reallyExit) })
  }
  function reallyExit() {
    itWorked = !code
    if (doExit) process.exit(code || 0)
    else process.emit("exit", code || 0)
  }
}

function writeLogFile (cb) {
  var fs = require("./graceful-fs")
    , fstr = fs.createWriteStream("npm-debug.log")
    , sys = require("util")

  log.history.forEach(function (m) {
    var lvl = log.LEVEL[m.level]
      , pref = m.pref ? " " + m.pref : ""
      , b = lvl + pref + " "
      , msg = typeof m.msg === "string" ? m.msg
            : msg instanceof Error ? msg.stack || msg.message
            : sys.inspect(m.msg, 0, 4)
    fstr.write(new Buffer(b
                         +(msg.split(/\n+/).join("\n"+b))
                         + "\n"))
  })
  fstr.on("close", cb)
}
<|endoftext|>