<commit_before>;(function($, window, document, undefined) {
    'use strict';

    var CONST = {
        maxNumbComparisons: 5
    }
    /* Datatable functionality */
    var DataTable = {
        initVariables: function() {
            this.frameworkTable = null;
        },

        cacheElements: function() {
            this.$modalContainer = $("#addFrameworkModal");
            this.$frameworkTable = $("#addFrameworksTable");
            this.$filterFieldContainer = $('#addFrameworksTable_filter');
            this.$filterField = $('#addFrameworksTable_filter').find(':input');
        },

        init: function($frameworkTable) {
            this.initVariables();
            this.initTable($frameworkTable);
            this.cacheElements();
            this.cleanMarkup();
            this.bindEvents();
            this.hideCurrentFrameworks(CF.currentFrameworks);
        },

        initTable: function($frameworkTable) {
            this.frameworkTable = $frameworkTable.DataTable({
                ajax: {
                    url: '../php/testThumbFrameworks.php',
                    dataSrc: "frameworks"
                },
                "columnDefs": [
                    { "visible": false, "targets": 1 }  // hide second column
                ],
                columns: [
                    {
                        data: 'framework',
                        "type": "html",
                        render: function (data, type, row) {
                            if (type ==='display') {
                                var thumbs = "";
                                thumbs = ' \
							               \
							              ' + data + ' \
							              ' + row.status + '';
                                return thumbs;
                            } else return '';
                        }
                    },
                    {data:'framework'}  //Must provide second column in order for search to work...
                ],
                language: {
                    search: "",
                    searchPlaceholder: "Search by framework name...",
                    zeroRecords: "No Frameworks found. Please try another search term."
                },
                "sAutoWidth": false,
                "iDisplayStart ": 6,
                "iDisplayLength": 6,
                "lengthChange": false,
                "bInfo": false, // hide showing entries
            });
        },

        cleanMarkup: function() {
            this.$filterFieldContainer.removeClass('dataTables_filter');
            this.$filterFieldContainer.find("input").addClass("modal-search");
            this.$frameworkTable.addClass("table table-hover"); //add bootstrap class
            this.$frameworkTable.css("width","100%");
        },

        bindEvents: function() {
            var that = this;
            this.$modalContainer.on('shown.bs.modal', function (){
                // On modal overlay shown focus the search field
                that.$filterField.focus();
            });

            this.$frameworkTable.find('tbody').on('click', 'tr', function () {
                var data = that.frameworkTable.row( this ).data();
                CF.addRemoveShownFrameworks(data.framework, 0);
                CF.sendRequest(data.framework);
                that.$modalContainer.modal('hide');
            });

            this.$filterField.on('focus', function() {
                $(this).select();
            });
        },

        hideCurrentFrameworks: function(currentFrameworks) {
            var i=0;
            var regexNames = "";
            if(currentFrameworks.length !== 0) {
                for(i=0; i<currentFrameworks.length; i++) {
                    regexNames += currentFrameworks[i] + "|";
                }
                regexNames = regexNames.slice(0, -1);    //remove last "|"

                this.frameworkTable
                    .columns(1) //The index of column to search
                    .search('^(?:(?!(' + regexNames + ')).)*$\r?\n?', true, false) //The RegExp search all string that not cointains values
                    .draw();
            } else {
                this.frameworkTable
                    .search( '' )   // Clear all searches
                    .columns().search( '' )
                    .draw();
            }
        }
    }

    /* Compare framework page functions */
    var CF = {

        initVariables: function() {
            this.columnTransform = [4,4,4,3,15,2]; // first 3 are 3 column layout and then 4,5,6 column
            this.currentFrameworks = this.getUrlParams();
            this.frameworkOrder = this.currentFrameworks.concat("","","","","","");
        },

        cacheElements: function() {
            this.$frameworkTable = $('#addFrameworksTable');
            this.$frameworkHeaderContainer = $('#frameworkheader-container');
            this.$frameworkDevSpecContainer = $('#framework-dev-spec-container');
            this.$frameworkHardwareFeatContainer = $('#framework-hardware-feature-container');
            this.$frameworkSupportFeatContainer = $('#framework-support-feature-container');
            this.$frameworkResourcesContainer = $('#framework-resources-container');
            //Sub containers from tool specification
            this.$toolTecCon = $('#toolTecCon');
            this.$toolAnnCon = $('#toolAnnCon');
            this.$toolVerCon = $('#toolVerCon');
            this.$toolPlaCon = $('#toolPlaCon');
            this.$toolLanCon = $('#toolLanCon');
            this.$toolProCon = $('#toolProCon');
            this.$toolLicCon = $('#toolLicCon');
            this.$toolSrcCon = $('#toolSrcCon');
            this.$toolCostCon = $('#toolCostCon');

            this.$addFrameworkButton = $('.add-framework');
            this.$msg = $('#msg');
            this.$collapseButton = $('#btnCollapseAll');
        },

        init: function() {
            this.initVariables();
            this.cacheElements();
            this.bindEvents();

            this.loadComparisonData();
            this.nothingLeft();
            this.figOutAddButton();

            DataTable.init(this.$frameworkTable);

            console.log( "all init and Bindings complete!" );
        },

        bindEvents: function() {
            this.$collapseButton.on('click', function() {
                var panels = $(this).siblings('.panel-group');
                var btnLabel = $(this).children('.btn-label');
                var option = ""
                if($(btnLabel).text() === "Collapse All") {
                    $(btnLabel).text("Open All");
                    option = "hide";
                } else {
                    $(btnLabel).text("Collapse All");
                    option = "show";
                }
                $(panels).each(function() {
                    $(this).find('.collapse').collapse(option);
                });
            });
        },

        loadComparisonData: function() {
            var i = 0;
            for(i=0; i<this.currentFrameworks.length; i++) {
                this.sendRequest(this.currentFrameworks[i]);
            }
        },
        /*
         * 0 for add and 1 for removal
         * !NOTE: frameworkOrder is needed to ensure that the background
         * color is always unique. We store the position of the framework
         * in the comparison table.
         */
        addRemoveShownFrameworks: function(frameworkName, addRemove) {
            var compareIndex = 0;
            if(addRemove) {
                //remove element from stored frameworks and free spot
                compareIndex = this.currentFrameworks.indexOf(frameworkName);
                this.currentFrameworks.splice(compareIndex, 1);
                compareIndex = this.frameworkOrder.indexOf(frameworkName);
                this.frameworkOrder[compareIndex] = "";
            } else {
                //add element to stored frameworks and find/fill free spot
                this.currentFrameworks.push(frameworkName);
                compareIndex = this.frameworkOrder.indexOf("");
                this.frameworkOrder[compareIndex] = frameworkName
            }
            this.figOutAddButton();
            this.nothingLeft();
            DataTable.hideCurrentFrameworks(this.currentFrameworks);
            this.updateUrlParams();
        },

        sendRequest: function(data) {
            $.ajax({
                method: "GET",
                url: "../php/searchFramework.php?keyword=" + data,
                dataType: "json",

                error: this.errorCallback,
                success: this.succesCallback
            });
        },

        errorCallback: function(jqXHR, status, errorThrown) {
            console.log("Something went wrong with request");
        },

        succesCallback: function(data, status, jqXHR) {
            console.log("Successful request");
            CF.addMarkupToPage(data);
            CF.bindEventNewItem();
        },

        recalculateColumns: function() {
            var $columns = $('.col-md-9 > div');
            var columnWidth = columnWidth = 'col-md-' + this.columnTransform[this.currentFrameworks.length-1];
            $columns.each(function(index) {
                $(this).alterClass('col-md-*', columnWidth);
            });
            return columnWidth;
        },

        figOutAddButton: function() {
            if(this.currentFrameworks.length > (CONST.maxNumbComparisons-1)) {
                this.$addFrameworkButton.addClass('disabled');
                this.$addFrameworkButton.prop('disabled', true);
            } else {
                this.$addFrameworkButton.removeClass('disabled');
                this.$addFrameworkButton.removeProp('disabled');
            }
        },

        updateUrlParams: function() {
            // get current url
            var i = 0;
            var newUrl = window.location.href;
            if(newUrl.indexOf('?') === -1) {
                newUrl += '?frameworks='
            } else {
                newUrl = newUrl.substring(0, (newUrl.indexOf('=') + 1));
            }
            // add currentFrameworks to url
            for(i=0; i<this.currentFrameworks.length; i++) {
                newUrl += this.currentFrameworks[i] + ";"
            }
            // remove last ';' from newUrl
            newUrl = newUrl.slice(0, -1);
            if (history.pushState) {
                window.history.pushState({path:newUrl},'',newUrl);
            }
        },

        addMarkupToPage: function(data) {
            var frameworkPos = this.frameworkOrder.indexOf(data.framework);
            var columnWidth = this.recalculateColumns();
            var frameworkClass = data.framework.replace(/[^a-zA-Z0-9]/g, "")

            var contents = '
' + data.header +	'
';
            this.$frameworkHeaderContainer.append(contents);
            // Add tool specification markup
            contents = '
' + data.toolTecCon + '
';
            this.$toolTecCon.append(contents);
            contents = '
' + data.toolAnnCon + '
';
            this.$toolAnnCon.append(contents);
            contents = '
' + data.toolVerCon + '
';
            this.$toolVerCon.append(contents);
            contents = '
' + data.toolPlaCon + '
';
            this.$toolPlaCon.append(contents);
            contents = '
' + data.toolLanCon + '
';
            this.$toolLanCon.append(contents);
            contents = '
' + data.toolProCon + '
';
            this.$toolProCon.append(contents);
            contents = '
' + data.toolLicCon + '
';
            this.$toolLicCon.append(contents);
            contents = '
' + data.toolSrcCon + '
';
            this.$toolSrcCon.append(contents);
            contents = '
' + data.toolCostCon + '
';
            this.$toolCostCon.append(contents);
            // -----------------------------
            contents = '
' + data.dev_specification + '
';
            this.$frameworkDevSpecContainer.append(contents);
            contents = '
' + data.hardware_features + '
';
            this.$frameworkHardwareFeatContainer.append(contents);
            contents = '
' + data.support_features + '
';
            this.$frameworkSupportFeatContainer.append(contents);
            contents = '
' + data.resources + '
';
            this.$frameworkResourcesContainer.append(contents);
        },

        bindEventNewItem: function() {
            var that = this;
            // First remove all click handlers and then re-attach to include new ones
            $('.glyphicon-remove-circle').off('click')
            $('.glyphicon-remove-circle').on('click', function() {
                var parentHeaderContainer = $(this).parents('.header-container');
                var frameworkName = $(parentHeaderContainer).find('h4').text();
                var frameworkClass = frameworkName.replace(/[^a-zA-Z0-9]/g, "")
                var $parentBodyContainers = $('.' + frameworkClass);
                that.addRemoveShownFrameworks(frameworkName, 1);

                $(parentHeaderContainer).remove();
                $parentBodyContainers.remove();

                that.recalculateColumns();
            });
        },

        getUrlParams: function () {
            var i = 0
            var vars = [], hash = [];
            var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
            for(i = 0; i < hashes.length; i++) {
                hash = hashes[i].split('=');
                if(hash[0] === "frameworks") {
                    vars = hash[1].split(';');
                }
            }
            //replace %20 with " "
            for(i=0; i < vars.length; i++) {
                vars[i] = vars[i].replace(/%20/g, " ");
            }
            return vars;
        },

        hidePanels: function() {
            $('.compare-body').hide();
        },

        showPanels: function() {
            $('.compare-body').show();
        },
        // Check if there are frameworks being compared (if not show a message)
        nothingLeft: function() {
            if (this.currentFrameworks.length === 0) {
                this.hidePanels();
                this.$msg.show();
            } else {
                this.showPanels();
                this.$msg.hide();
            }
        }

    }

    $( document ).ready(function() {
        console.log( "Document ready!" );
        CF.init();
    });

    window.addEventListener("popstate", function(e) {
        window.location.reload();
    });

    /*
     * HELPER Function for wildcard class removal with jQuery
     *
     * https://gist.github.com/peteboere/1517285
     * LICENSE: MIT-license
     */
    $.fn.alterClass = function ( removals, additions ) {
        var self = this;
        if ( removals.indexOf( '*' ) === -1 ) {
            // Use native jQuery methods if there is no wildcard matching
            self.removeClass( removals );
            return !additions ? self : self.addClass( additions );
        }
        var patt = new RegExp( '\\s' +
                removals.
                    replace( /\*/g, '[A-Za-z0-9-_]+' ).
                    split( ' ' ).
                    join( '\\s|\\s' ) +
                '\\s', 'g' );
        self.each( function ( i, it ) {
            var cn = ' ' + it.className + ' ';
            while ( patt.test( cn ) ) {
                cn = cn.replace( patt, ' ' );
            }
            it.className = $.trim( cn );
        });
        return !additions ? self : self.addClass( additions );
    };

})(jQuery, window, document);

<commit_msg>Fixed parameter parser bug on navigation<commit_after>;(function($, window, document, undefined) {
    'use strict';

    var CONST = {
        maxNumbComparisons: 5
    }
    /* Datatable functionality */
    var DataTable = {
        initVariables: function() {
            this.frameworkTable = null;
        },

        cacheElements: function() {
            this.$modalContainer = $("#addFrameworkModal");
            this.$frameworkTable = $("#addFrameworksTable");
            this.$filterFieldContainer = $('#addFrameworksTable_filter');
            this.$filterField = $('#addFrameworksTable_filter').find(':input');
        },

        init: function($frameworkTable) {
            this.initVariables();
            this.initTable($frameworkTable);
            this.cacheElements();
            this.cleanMarkup();
            this.bindEvents();
            this.hideCurrentFrameworks(CF.currentFrameworks);
        },

        initTable: function($frameworkTable) {
            this.frameworkTable = $frameworkTable.DataTable({
                ajax: {
                    url: '../php/testThumbFrameworks.php',
                    dataSrc: "frameworks"
                },
                "columnDefs": [
                    { "visible": false, "targets": 1 }  // hide second column
                ],
                columns: [
                    {
                        data: 'framework',
                        "type": "html",
                        render: function (data, type, row) {
                            if (type ==='display') {
                                var thumbs = "";
                                thumbs = ' \
							               \
							              ' + data + ' \
							              ' + row.status + '';
                                return thumbs;
                            } else return '';
                        }
                    },
                    {data:'framework'}  //Must provide second column in order for search to work...
                ],
                language: {
                    search: "",
                    searchPlaceholder: "Search by framework name...",
                    zeroRecords: "No Frameworks found. Please try another search term."
                },
                "sAutoWidth": false,
                "iDisplayStart ": 6,
                "iDisplayLength": 6,
                "lengthChange": false,
                "bInfo": false, // hide showing entries
            });
        },

        cleanMarkup: function() {
            this.$filterFieldContainer.removeClass('dataTables_filter');
            this.$filterFieldContainer.find("input").addClass("modal-search");
            this.$frameworkTable.addClass("table table-hover"); //add bootstrap class
            this.$frameworkTable.css("width","100%");
        },

        bindEvents: function() {
            var that = this;
            this.$modalContainer.on('shown.bs.modal', function (){
                // On modal overlay shown focus the search field
                that.$filterField.focus();
            });

            this.$frameworkTable.find('tbody').on('click', 'tr', function () {
                var data = that.frameworkTable.row( this ).data();
                CF.addRemoveShownFrameworks(data.framework, 0);
                CF.sendRequest(data.framework);
                that.$modalContainer.modal('hide');
            });

            this.$filterField.on('focus', function() {
                $(this).select();
            });
        },

        hideCurrentFrameworks: function(currentFrameworks) {
            var i=0;
            var regexNames = "";
            if(currentFrameworks.length !== 0) {
                for(i=0; i<currentFrameworks.length; i++) {
                    regexNames += currentFrameworks[i] + "|";
                }
                regexNames = regexNames.slice(0, -1);    //remove last "|"

                this.frameworkTable
                    .columns(1) //The index of column to search
                    .search('^(?:(?!(' + regexNames + ')).)*$\r?\n?', true, false) //The RegExp search all string that not cointains values
                    .draw();
            } else {
                this.frameworkTable
                    .search( '' )   // Clear all searches
                    .columns().search( '' )
                    .draw();
            }
        }
    }

    /* Compare framework page functions */
    var CF = {

        initVariables: function() {
            this.columnTransform = [4,4,4,3,15,2]; // first 3 are 3 column layout and then 4,5,6 column
            this.currentFrameworks = this.getUrlParams();
            this.frameworkOrder = this.currentFrameworks.concat("","","","","","");
        },

        cacheElements: function() {
            this.$frameworkTable = $('#addFrameworksTable');
            this.$frameworkHeaderContainer = $('#frameworkheader-container');
            this.$frameworkDevSpecContainer = $('#framework-dev-spec-container');
            this.$frameworkHardwareFeatContainer = $('#framework-hardware-feature-container');
            this.$frameworkSupportFeatContainer = $('#framework-support-feature-container');
            this.$frameworkResourcesContainer = $('#framework-resources-container');
            //Sub containers from tool specification
            this.$toolTecCon = $('#toolTecCon');
            this.$toolAnnCon = $('#toolAnnCon');
            this.$toolVerCon = $('#toolVerCon');
            this.$toolPlaCon = $('#toolPlaCon');
            this.$toolLanCon = $('#toolLanCon');
            this.$toolProCon = $('#toolProCon');
            this.$toolLicCon = $('#toolLicCon');
            this.$toolSrcCon = $('#toolSrcCon');
            this.$toolCostCon = $('#toolCostCon');

            this.$addFrameworkButton = $('.add-framework');
            this.$msg = $('#msg');
            this.$collapseButton = $('#btnCollapseAll');
        },

        init: function() {
            this.initVariables();
            this.cacheElements();
            this.bindEvents();

            this.loadComparisonData();
            this.nothingLeft();
            this.figOutAddButton();

            DataTable.init(this.$frameworkTable);

            console.log( "all init and Bindings complete!" );
        },

        bindEvents: function() {
            this.$collapseButton.on('click', function() {
                var panels = $(this).siblings('.panel-group');
                var btnLabel = $(this).children('.btn-label');
                var option = ""
                if($(btnLabel).text() === "Collapse All") {
                    $(btnLabel).text("Open All");
                    option = "hide";
                } else {
                    $(btnLabel).text("Collapse All");
                    option = "show";
                }
                $(panels).each(function() {
                    $(this).find('.collapse').collapse(option);
                });
            });
        },

        loadComparisonData: function() {
            var i = 0;
            for(i=0; i<this.currentFrameworks.length; i++) {
                this.sendRequest(this.currentFrameworks[i]);
            }
        },
        /*
         * 0 for add and 1 for removal
         * !NOTE: frameworkOrder is needed to ensure that the background
         * color is always unique. We store the position of the framework
         * in the comparison table.
         */
        addRemoveShownFrameworks: function(frameworkName, addRemove) {
            var compareIndex = 0;
            if(addRemove) {
                //remove element from stored frameworks and free spot
                compareIndex = this.currentFrameworks.indexOf(frameworkName);
                this.currentFrameworks.splice(compareIndex, 1);
                compareIndex = this.frameworkOrder.indexOf(frameworkName);
                this.frameworkOrder[compareIndex] = "";
            } else {
                //add element to stored frameworks and find/fill free spot
                this.currentFrameworks.push(frameworkName);
                compareIndex = this.frameworkOrder.indexOf("");
                this.frameworkOrder[compareIndex] = frameworkName
            }
            this.figOutAddButton();
            this.nothingLeft();
            DataTable.hideCurrentFrameworks(this.currentFrameworks);
            this.updateUrlParams();
        },

        sendRequest: function(data) {
            $.ajax({
                method: "GET",
                url: "../php/searchFramework.php?keyword=" + data,
                dataType: "json",

                error: this.errorCallback,
                success: this.succesCallback
            });
        },

        errorCallback: function(jqXHR, status, errorThrown) {
            console.log("Something went wrong with request");
        },

        succesCallback: function(data, status, jqXHR) {
            console.log("Successful request");
            CF.addMarkupToPage(data);
            CF.bindEventNewItem();
        },

        recalculateColumns: function() {
            var $columns = $('.col-md-9 > div');
            var columnWidth = columnWidth = 'col-md-' + this.columnTransform[this.currentFrameworks.length-1];
            $columns.each(function(index) {
                $(this).alterClass('col-md-*', columnWidth);
            });
            return columnWidth;
        },

        figOutAddButton: function() {
            if(this.currentFrameworks.length > (CONST.maxNumbComparisons-1)) {
                this.$addFrameworkButton.addClass('disabled');
                this.$addFrameworkButton.prop('disabled', true);
            } else {
                this.$addFrameworkButton.removeClass('disabled');
                this.$addFrameworkButton.removeProp('disabled');
            }
        },

        updateUrlParams: function() {
            // get current url
            var i = 0;
            var newUrl = window.location.href;
            if(newUrl.indexOf('?') === -1) {
                newUrl += '?frameworks='
            } else {
                newUrl = newUrl.substring(0, (newUrl.indexOf('=') + 1));
            }
            // add currentFrameworks to url
            for(i=0; i<this.currentFrameworks.length; i++) {
                newUrl += this.currentFrameworks[i] + ";"
            }
            // remove last ';' from newUrl
            newUrl = newUrl.slice(0, -1);
            if (history.pushState) {
                window.history.pushState({path:newUrl},'',newUrl);
            }
        },

        addMarkupToPage: function(data) {
            var frameworkPos = this.frameworkOrder.indexOf(data.framework);
            var columnWidth = this.recalculateColumns();
            var frameworkClass = data.framework.replace(/[^a-zA-Z0-9]/g, "")

            var contents = '
' + data.header +	'
';
            this.$frameworkHeaderContainer.append(contents);
            // Add tool specification markup
            contents = '
' + data.toolTecCon + '
';
            this.$toolTecCon.append(contents);
            contents = '
' + data.toolAnnCon + '
';
            this.$toolAnnCon.append(contents);
            contents = '
' + data.toolVerCon + '
';
            this.$toolVerCon.append(contents);
            contents = '
' + data.toolPlaCon + '
';
            this.$toolPlaCon.append(contents);
            contents = '
' + data.toolLanCon + '
';
            this.$toolLanCon.append(contents);
            contents = '
' + data.toolProCon + '
';
            this.$toolProCon.append(contents);
            contents = '
' + data.toolLicCon + '
';
            this.$toolLicCon.append(contents);
            contents = '
' + data.toolSrcCon + '
';
            this.$toolSrcCon.append(contents);
            contents = '
' + data.toolCostCon + '
';
            this.$toolCostCon.append(contents);
            // -----------------------------
            contents = '
' + data.dev_specification + '
';
            this.$frameworkDevSpecContainer.append(contents);
            contents = '
' + data.hardware_features + '
';
            this.$frameworkHardwareFeatContainer.append(contents);
            contents = '
' + data.support_features + '
';
            this.$frameworkSupportFeatContainer.append(contents);
            contents = '
' + data.resources + '
';
            this.$frameworkResourcesContainer.append(contents);
        },

        bindEventNewItem: function() {
            var that = this;
            // First remove all click handlers and then re-attach to include new ones
            $('.glyphicon-remove-circle').off('click')
            $('.glyphicon-remove-circle').on('click', function() {
                var parentHeaderContainer = $(this).parents('.header-container');
                var frameworkName = $(parentHeaderContainer).find('h4').text();
                var frameworkClass = frameworkName.replace(/[^a-zA-Z0-9]/g, "")
                var $parentBodyContainers = $('.' + frameworkClass);
                that.addRemoveShownFrameworks(frameworkName, 1);

                $(parentHeaderContainer).remove();
                $parentBodyContainers.remove();

                that.recalculateColumns();
            });
        },

        getUrlParams: function () {
            var i = 0
            var vars = [], hash = [];
            var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
            for(i = 0; i < hashes.length; i++) {
                hash = hashes[i].split('=');
                if(hash[0] === "frameworks" && hash.length > 1) {
                    vars = hash[1].split(';');
                }
            }
            //replace %20 with " "
            for(i=0; i < vars.length; i++) {
                vars[i] = vars[i].replace(/%20/g, " ");
            }
            return vars;
        },

        hidePanels: function() {
            $('.compare-body').hide();
        },

        showPanels: function() {
            $('.compare-body').show();
        },
        // Check if there are frameworks being compared (if not show a message)
        nothingLeft: function() {
            if (this.currentFrameworks.length === 0) {
                this.hidePanels();
                this.$msg.show();
            } else {
                this.showPanels();
                this.$msg.hide();
            }
        }

    }

    $( document ).ready(function() {
        console.log( "Document ready!" );
        CF.init();
    });

    window.addEventListener("popstate", function(e) {
        window.location.reload();
    });

    /*
     * HELPER Function for wildcard class removal with jQuery
     *
     * https://gist.github.com/peteboere/1517285
     * LICENSE: MIT-license
     */
    $.fn.alterClass = function ( removals, additions ) {
        var self = this;
        if ( removals.indexOf( '*' ) === -1 ) {
            // Use native jQuery methods if there is no wildcard matching
            self.removeClass( removals );
            return !additions ? self : self.addClass( additions );
        }
        var patt = new RegExp( '\\s' +
                removals.
                    replace( /\*/g, '[A-Za-z0-9-_]+' ).
                    split( ' ' ).
                    join( '\\s|\\s' ) +
                '\\s', 'g' );
        self.each( function ( i, it ) {
            var cn = ' ' + it.className + ' ';
            while ( patt.test( cn ) ) {
                cn = cn.replace( patt, ' ' );
            }
            it.className = $.trim( cn );
        });
        return !additions ? self : self.addClass( additions );
    };

})(jQuery, window, document);

<|endoftext|>


<commit_before>var xhr = new XMLHttpRequest(),
	stylesheet = 'stable.css';

if (/Chrome\/(\d\d)/.exec(navigator.userAgent)[1] > 55) {
	stylesheet = 'canary.css';
}

xhr.open("GET", "/" + stylesheet, false);
xhr.send();
chrome.devtools.panels.applyStyleSheet(xhr.responseText);
<commit_msg>Version down to temporarily patch stable styles<commit_after>var xhr = new XMLHttpRequest(),
	stylesheet = 'stable.css';

if (/Chrome\/(\d\d)/.exec(navigator.userAgent)[1] > 53) {
	stylesheet = 'canary.css';
}

xhr.open("GET", "/" + stylesheet, false);
xhr.send();
chrome.devtools.panels.applyStyleSheet(xhr.responseText);
<|endoftext|>


<commit_before>/**
 * Copyright 2015-2019 OpenCB
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {LitElement, html} from "lit";
import UtilsNew from "../../core/utilsNew.js";
import LitUtils from "../commons/utils/lit-utils.js";
import NotificationUtils from "../commons/utils/notification-utils.js";

export default class OpencgaJobDetailLog extends LitElement {

    constructor() {
        super();

        this._init();
    }

    createRenderRoot() {
        return this;
    }

    static get properties() {
        return {
            opencgaSession: {
                type: Object
            },
            job: {
                type: Object
            },
            active: {
                type: Boolean
            },
            config: {
                type: Object
            }
        };
    }

    _init() {
        this._prefix = "sf-" + UtilsNew.randomString(6);

        this.content = null;
        this._config = {...this.getDefaultConfig(), ...this.config};
    }

    connectedCallback() {
        super.connectedCallback();
    }

    async updated(changedProperties) {
        if (changedProperties.has("job")) {
            this.jobId = this.job.id;
            if (this.active) {
                this.fetchContent(this.job, {command: this._config.command, type: this._config.type});
            }
        }

        if (changedProperties.has("active")) {
            this.content = null;
            this.requestUpdate();
            await this.updateComplete;
            // todo this should call fetchContent iff the job has changed
            // console.log("new job = old job ", this.active && this.jobId === this.job.id)
            if (this.active) {
                this.fetchContent(this.job, {command: this._config.command, type: this._config.type});
            } else {
                this.clearReload();
            }
        }
    }

    setCommand(command) {
        this._config.command = command;
        this.clearReload();
        this.fetchContent(this.job, {command: this._config.command, type: this._config.type});
        this.setReloadInterval();
    }

    setType(type) {
        this._config.type = type;
        this.clearReload();
        this.fetchContent(this.job, {command: this._config.command, type: this._config.type});
        this.setReloadInterval();
    }

    // setInterval makes sense only in case of Tail log
    setReloadInterval() {
        if (this.active && this._config.command === "tail" && this.job.internal.status.name === "RUNNING") {
            // console.log("setting interval");
            this.requestUpdate();
            this.interval = setInterval(() => {
                // this.content += "\n" + UtilsNew.randomString(6);
                if ($(".jobs-details-log", this).is(":visible")) {
                    // tail call is actually head (after the first tail call)
                    this.fetchContent(this.job, {command: "head", offset: this.contentOffset}, true);
                } else {
                    this.clearReload();
                }
                this.requestUpdate();
            }, 10000);
        }
    }

    clearReload() {
        this.contentOffset = 0;
        clearInterval(this.interval);
        this.requestUpdate();
    }

    async fetchContent(job, params = {}, append = false) {
        if (!append) {
            this.content = "";
        }
        this.loading = true;
        this.requestUpdate();
        await this.updateComplete;

        const command = params.command || this._config.command;
        // const offset = params.offset || 0;
        // console.log("request ", "command", command, "params", params, "offset", offset, "append", append);

        this.opencgaSession.opencgaClient.jobs()[command + "Log"](job.id, {
            study: this.opencgaSession.study.fqn,
            lines: this._config.lines,
            type: this._config.type,
            offset: params.offset || 0,
            ...params
        }).then(restResponse => {
            const result = restResponse.getResult(0);
            if (result.content) {
                // if command=tail this is the first tail call (the subsequents will be head)
                if (command === "tail") {
                    this.contentOffset = result.offset;
                }
                // append is true only in case of tail command (it has been kept as separate param to quickly have one-shot Tail call button (not live), just in case)
                if (append) {
                    if (this.contentOffset !== result.offset) {
                        this.content = this.content + result.content;
                        this.contentOffset = result.offset;
                    }
                } else {
                    this.content = result.content + "\n";
                }
            } else {
                // this.content = "No content";
            }
        }).catch(response => {
            this.content = "An error occurred while fetching log.\n";
            NotificationUtils.dispatch(this, NotificationUtils.NOTIFY_RESPONSE, response);
        }).finally(() => {
            this.loading = false;
            this.requestUpdate();
        });
    }

    onScroll(e) {
        // TODO custom infinite scroll
        // console.log(e)
    }

    getDefaultConfig() {
        return {
            command: "head",
            type: "stderr",
            lines: 50
        };
    }

    render() {
        return html`

                    <button type="button" class="btn btn-default btn-small ripple ${this._config.command === "head" ? "active" : ""}" @click="${() => this.setCommand("head")}">
                         Head
                    </button>
                    <button type="button" class="btn btn-default btn-small ripple ${this._config.command === "tail" ? "active" : ""}" @click="${() => this.setCommand("tail")}">
                         Tail
                    </button>

                    <button type="button" class="btn btn-default btn-small ripple ${this._config.type === "stderr" ? "active" : ""}" @click="${() => this.setType("stderr")}">
                         Stderr
                    </button>
                    <button type="button" class="btn btn-default btn-small ripple ${this._config.type === "stdout" ? "active" : ""}" @click="${() => this.setType("stdout")}">
                         Stout
                    </button>

${this.content}\n${this.loading || (this.content && this._config.command === "tail") ? html`<div class="cursor"></div>` : ""}

        `;
    }

}

customElements.define("opencga-job-detail-log", OpencgaJobDetailLog);
<commit_msg>wc: fixed Job browser warning pending jobs #TASK-611<commit_after>/**
 * Copyright 2015-2019 OpenCB
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import {LitElement, html} from "lit";
import UtilsNew from "../../core/utilsNew.js";
import LitUtils from "../commons/utils/lit-utils.js";
import NotificationUtils from "../commons/utils/notification-utils.js";

export default class OpencgaJobDetailLog extends LitElement {

    constructor() {
        super();

        this._init();
    }

    createRenderRoot() {
        return this;
    }

    static get properties() {
        return {
            opencgaSession: {
                type: Object
            },
            job: {
                type: Object
            },
            active: {
                type: Boolean
            },
            config: {
                type: Object
            }
        };
    }

    _init() {
        this._prefix = "sf-" + UtilsNew.randomString(6);

        this.content = null;
        this._config = {...this.getDefaultConfig(), ...this.config};
    }

    connectedCallback() {
        super.connectedCallback();
    }

    async updated(changedProperties) {
        if (changedProperties.has("job")) {
            this.jobId = this.job.id;
            if (this.active) {
                this.fetchContent(this.job, {command: this._config.command, type: this._config.type});
            }
        }

        if (changedProperties.has("active")) {
            this.content = null;
            this.requestUpdate();
            await this.updateComplete;
            // todo this should call fetchContent iff the job has changed
            // console.log("new job = old job ", this.active && this.jobId === this.job.id)
            if (this.active) {
                this.fetchContent(this.job, {command: this._config.command, type: this._config.type});
            } else {
                this.clearReload();
            }
        }
    }

    setCommand(command) {
        this._config.command = command;
        this.clearReload();
        this.fetchContent(this.job, {command: this._config.command, type: this._config.type});
        this.setReloadInterval();
    }

    setType(type) {
        this._config.type = type;
        this.clearReload();
        this.fetchContent(this.job, {command: this._config.command, type: this._config.type});
        this.setReloadInterval();
    }

    // setInterval makes sense only in case of Tail log
    setReloadInterval() {
        if (this.active && this._config.command === "tail" && this.job.internal.status.name === "RUNNING") {
            // console.log("setting interval");
            this.requestUpdate();
            this.interval = setInterval(() => {
                // this.content += "\n" + UtilsNew.randomString(6);
                if ($(".jobs-details-log", this).is(":visible")) {
                    // tail call is actually head (after the first tail call)
                    this.fetchContent(this.job, {command: "head", offset: this.contentOffset}, true);
                } else {
                    this.clearReload();
                }
                this.requestUpdate();
            }, 10000);
        }
    }

    clearReload() {
        this.contentOffset = 0;
        clearInterval(this.interval);
        this.requestUpdate();
    }

    async fetchContent(job, params = {}, append = false) {
        if (!append) {
            this.content = "";
        }
        this.loading = true;
        this.requestUpdate();
        await this.updateComplete;

        const command = params.command || this._config.command;
        // const offset = params.offset || 0;
        // console.log("request ", "command", command, "params", params, "offset", offset, "append", append);
        if (["PENDING", "ABORTED", "RUNNING"].every(status => status !== job?.internal?.status.id)) {
            this.opencgaSession.opencgaClient.jobs()[command + "Log"](job.id, {
                study: this.opencgaSession.study.fqn,
                lines: this._config.lines,
                type: this._config.type,
                offset: params.offset || 0,
                ...params
            }).then(restResponse => {
                const result = restResponse.getResult(0);
                if (result.content) {
                // if command=tail this is the first tail call (the subsequents will be head)
                    if (command === "tail") {
                        this.contentOffset = result.offset;
                    }
                    // append is true only in case of tail command (it has been kept as separate param to quickly have one-shot Tail call button (not live), just in case)
                    if (append) {
                        if (this.contentOffset !== result.offset) {
                            this.content = this.content + result.content;
                            this.contentOffset = result.offset;
                        }
                    } else {
                        this.content = result.content + "\n";
                    }
                } else {
                // this.content = "No content";
                }
            }).catch(response => {
                this.content = "An error occurred while fetching log.\n";
                NotificationUtils.dispatch(this, NotificationUtils.NOTIFY_RESPONSE, response);
            }).finally(() => {
                this.loading = false;
                this.requestUpdate();
            });
        } else {
            this.content = `Job is ${job?.internal?.status?.id}\n`;
            this.loading = false;
            this.requestUpdate();
        }
    }

    onScroll(e) {
        // TODO custom infinite scroll
        // console.log(e)
    }

    getDefaultConfig() {
        return {
            command: "head",
            type: "stderr",
            lines: 50
        };
    }

    render() {
        return html`

                    <button type="button" class="btn btn-default btn-small ripple ${this._config.command === "head" ? "active" : ""}" @click="${() => this.setCommand("head")}">
                         Head
                    </button>
                    <button type="button" class="btn btn-default btn-small ripple ${this._config.command === "tail" ? "active" : ""}" @click="${() => this.setCommand("tail")}">
                         Tail
                    </button>

                    <button type="button" class="btn btn-default btn-small ripple ${this._config.type === "stderr" ? "active" : ""}" @click="${() => this.setType("stderr")}">
                         Stderr
                    </button>
                    <button type="button" class="btn btn-default btn-small ripple ${this._config.type === "stdout" ? "active" : ""}" @click="${() => this.setType("stdout")}">
                         Stout
                    </button>

${this.content}\n${this.loading || (this.content && this._config.command === "tail") ? html`<div class="cursor"></div>` : ""}

        `;
    }

}

customElements.define("opencga-job-detail-log", OpencgaJobDetailLog);
<|endoftext|>


<commit_before>lstsatelites();

function lstsatelites(){

	$.ajax({
		url:baseurl+'Csatelite/listasatelites',
		type:'POST',
		success:function(data){
			var obj=JSON.parse(data);

			// console.log(obj[0].nombres);

			//html='<select id="tpprod" name="tpprod" class=" pr form-control">';
			html='';
			html+='<option value="">Seleccione una opcion</option>';

			$.each(obj,function(i,items){
				html+='<option value="'+items.idtrabajador+'"">' + items.nombres+ '</option>';
			});

			//html+='</select>';
			$("#trabajador").html(html);

		}

	});
}

<<<<<<< HEAD
$('#trabajador').on('change',function(){

 var param=$('#trabajador').val();
resumenproductos(param);

});

 function resumenproductos(param){

 }
=======

$('#trabajador').on('change',function(){

	var dato=$('#trabajador').val();

	listageneral(dato);
});
// Creamos  la lista general que tendra por defecto todos los listados
listageneral(0);

function listageneral(dato){

	 $('#tblsatelite').DataTable({
			'paging':true,
			'info':true,
			'filter':true,
			'destroy':true,
			'stateSave':true,

			'ajax':{

				"url":baseurl+"Clistasatel/lstgeneral",
				'data':{trabajador:dato},
				'type':'POST',
				dataSrc:''
			},

			'columns':[
			//{data: 'idpedido','sClass':'dt-body-center'},
			{data: 'factura','sClass':'dt-body-center'},
			//{data:'nomtipoprod'},
			{data:'nomprod'},
			{data:'facultad'},
			{data:'cantidad'},
			{data:'talla'},
			{data:'descripcion'},
			//{data:'nombres'},
			{data:'fecha_ingreso'},
			{data:'estado'},
			{data:'nombres'},

			{"orderable":true,
			render:function(data,type,row){

return ' $ ' +
									//'<input type="radio" class="idpedido" onchange="validarc();"name="idpedido" value='+row.idpedido+' required="true">'
									row.precio

                       +
                      '';

					//return '</a
					//return ' Enviar';
					}
			}

			],
			"columnDefs": [
        {
          "targets": [7],
          "data": "estado",
          "render": function(data, type, row) {

            if (data == 2) {
              return "Pendiente Pago";
            }else if (data == 3) {
              return "Producto Entregado";
            }else if (data == 2) {
              return "En cortes";
            }

          }
        }
         ],

 "order":[[0,"asc"]],

		});
}

function cambioestado(){

	var s=$('#trabajador').val();

	window.open(baseurl+'Cpdfreport/reportesatelite/?satel='+s);
}

>>>>>>> b48b9842c33f306258fa4f6b2263e2c5fdd9716d
<commit_msg>is<commit_after>lstsatelites();

function lstsatelites(){

	$.ajax({
		url:baseurl+'Csatelite/listasatelites',
		type:'POST',
		success:function(data){
			var obj=JSON.parse(data);

			// console.log(obj[0].nombres);

			//html='<select id="tpprod" name="tpprod" class=" pr form-control">';
			html='';
			html+='<option value="">Seleccione una opcion</option>';

			$.each(obj,function(i,items){
				html+='<option value="'+items.idtrabajador+'"">' + items.nombres+ '</option>';
			});

			//html+='</select>';
			$("#trabajador").html(html);

		}

	});
}

$('#trabajador').on('change',function(){

	var dato=$('#trabajador').val();

	listageneral(dato);
});
// Creamos  la lista general que tendra por defecto todos los listados
listageneral(0);

function listageneral(dato){

	 $('#tblsatelite').DataTable({
			'paging':true,
			'info':true,
			'filter':true,
			'destroy':true,
			'stateSave':true,

			'ajax':{

				"url":baseurl+"Clistasatel/lstgeneral",
				'data':{trabajador:dato},
				'type':'POST',
				dataSrc:''
			},

			'columns':[
			//{data: 'idpedido','sClass':'dt-body-center'},
			{data: 'factura','sClass':'dt-body-center'},
			//{data:'nomtipoprod'},
			{data:'nomprod'},
			{data:'facultad'},
			{data:'cantidad'},
			{data:'talla'},
			{data:'descripcion'},
			//{data:'nombres'},
			{data:'fecha_ingreso'},
			{data:'estado'},
			{data:'nombres'},

			{"orderable":true,
			render:function(data,type,row){

return ' $ ' +
									//'<input type="radio" class="idpedido" onchange="validarc();"name="idpedido" value='+row.idpedido+' required="true">'
									row.precio

                       +
                      '';

					//return '</a
					//return ' Enviar';
					}
			}

			],
			"columnDefs": [
        {
          "targets": [7],
          "data": "estado",
          "render": function(data, type, row) {

            if (data == 2) {
              return "Pendiente Pago";
            }else if (data == 3) {
              return "Producto Entregado";
            }else if (data == 2) {
              return "En cortes";
            }

          }
        }
         ],

 "order":[[0,"asc"]],

		});
}

function cambioestado(){

	var s=$('#trabajador').val();

	window.open(baseurl+'Cpdfreport/reportesatelite/?satel='+s);
}

<|endoftext|>


<commit_before>import Model, { transaction } from "./base"

import { BLACK, WHITE } from "~/share/constants/chess"
import { START } from "~/share/constants/revision_types"
import { DRAW, WHITE_WIN, BLACK_WIN } from "~/share/constants/results"

import User from "./user"
import Position from "./position"
import Revision from "./revision"

export default class Game extends Model {
  constructor(...args) {
    super(...args)
  }

  get tableName() {
    return "games"
  }

  get hasTimestamps() {
    return true
  }

  whiteUser() {
    return this.belongsTo(User, "white_user_id")
  }

  blackUser() {
    return this.belongsTo(User, "black_user_id")
  }

  revisions() {
    return this.hasMany(Revision)
  }

  positions() {
    return this.belongsToMany(Position).through(Revision)
  }

  ascendingPositions() {
    return this.positions().orderBy("move_number", "ASC")
  }

  currentPosition() {
    return this.hasOne(Position)
      .through(Revision, "id", "game_id")
      .orderBy("move_number", "DESC")
      .query(qb => qb.limit(1))
  }

  static async forUser(uuid) {
    return await Game
      .query(builder => {
        builder.innerJoin("users", function() {
          this.on("users.id", "=", "games.white_user_id").orOn("users.id", "=", "games.black_user_id")
        })

        builder.where("users.uuid", "=", uuid)
      })
      .orderBy("-created_at")
      .fetchAll()
  }

  static async create(whiteUser, blackUser) {
    const game = new Game({
      white_user_id: whiteUser.get("id"),
      black_user_id: blackUser.get("id")
    })

    const position = new Position()

    await transaction(async transacting => {
      await game.save(null, { transacting })
      await position.save(null, { transacting })

      await new Revision({
        type: START,
        game_id: game.get("id"),
        source_game_id: game.get("id"),
        position_id: position.get("id")
      }).save(null, { transacting })
    })

    return game
  }

  setResult(chess) {
    this.set("result", getResult(chess))
  }

  async serializePrepare() {
    await this.refresh({
      withRelated: [
        "whiteUser",
        "blackUser",
        "whiteUser.profile",
        "blackUser.profile",
        "currentPosition"
      ]
    })
  }

  serialize() {
    return {
      uuid: this.get("uuid"),
      result: this.get("result"),
      currentPosition: this.related("currentPosition").serialize(),
      players: [
        { color: WHITE, ...this.related("whiteUser").serialize() },
        { color: BLACK, ...this.related("blackUser").serialize() }
      ]
    }
  }
}

function getResult(chess) {
  if (chess.in_draw()) {
    return DRAW
  }

  if (chess.in_checkmate()) {
    switch (chess.turn()) {
      case WHITE: return BLACK_WIN
      case BLACK: return WHITE_WIN
    }
  }
}
<commit_msg>load relations on game when listing<commit_after>import Model, { transaction } from "./base"

import { BLACK, WHITE } from "~/share/constants/chess"
import { START } from "~/share/constants/revision_types"
import { DRAW, WHITE_WIN, BLACK_WIN } from "~/share/constants/results"

import User from "./user"
import Position from "./position"
import Revision from "./revision"

export default class Game extends Model {
  constructor(...args) {
    super(...args)
  }

  get tableName() {
    return "games"
  }

  get hasTimestamps() {
    return true
  }

  whiteUser() {
    return this.belongsTo(User, "white_user_id")
  }

  blackUser() {
    return this.belongsTo(User, "black_user_id")
  }

  revisions() {
    return this.hasMany(Revision)
  }

  positions() {
    return this.belongsToMany(Position).through(Revision)
  }

  ascendingPositions() {
    return this.positions().orderBy("move_number", "ASC")
  }

  currentPosition() {
    return this.hasOne(Position)
      .through(Revision, "id", "game_id")
      .orderBy("move_number", "DESC")
      .query(qb => qb.limit(1))
  }

  static async forUser(uuid) {
    return await Game
      .query(builder => {
        builder.innerJoin("users", function() {
          this.on("users.id", "=", "games.white_user_id").orOn("users.id", "=", "games.black_user_id")
        })

        builder.where("users.uuid", "=", uuid)
      })
      .orderBy("-created_at")
      .fetchAll({
        withRelated: [
          "whiteUser",
          "blackUser",
          "whiteUser.profile",
          "blackUser.profile",
          "currentPosition"
        ]
      })
  }

  static async create(whiteUser, blackUser) {
    const game = new Game({
      white_user_id: whiteUser.get("id"),
      black_user_id: blackUser.get("id")
    })

    const position = new Position()

    await transaction(async transacting => {
      await game.save(null, { transacting })
      await position.save(null, { transacting })

      await new Revision({
        type: START,
        game_id: game.get("id"),
        source_game_id: game.get("id"),
        position_id: position.get("id")
      }).save(null, { transacting })
    })

    return game
  }

  setResult(chess) {
    this.set("result", getResult(chess))
  }

  async serializePrepare() {
    await this.refresh({
      withRelated: [
        "whiteUser",
        "blackUser",
        "whiteUser.profile",
        "blackUser.profile",
        "currentPosition"
      ]
    })
  }

  serialize() {
    return {
      uuid: this.get("uuid"),
      result: this.get("result"),
      currentPosition: this.related("currentPosition").serialize(),
      players: [
        { color: WHITE, ...this.related("whiteUser").serialize() },
        { color: BLACK, ...this.related("blackUser").serialize() }
      ]
    }
  }
}

function getResult(chess) {
  if (chess.in_draw()) {
    return DRAW
  }

  if (chess.in_checkmate()) {
    switch (chess.turn()) {
      case WHITE: return BLACK_WIN
      case BLACK: return WHITE_WIN
    }
  }
}
<|endoftext|>


<commit_before>/* jshint indent: false */ // TODO: ENYO-3311

/* global Phonegap */

/**
 * UI: Phonegap pane in the ProjectProperties popup
 * @name Phonegap.BuildStatusUI
 */
enyo.kind({
	name: "Phonegap.ProjectProperties.PlatformBuildStatus",
	kind: "onyx.IconButton",
	ontap: "showStatusMessage",
	published: {
		platform: undefined,
		buildStatusData: undefined,
	},
	/**
	 * Update the image for the platform IconButton depending on the status of the related platform
	 * described in buildStatusData.
	 *
	 * @private
	 */
	buildStatusDataChanged: function() {
		if (this.buildStatusData && this.buildStatusData.status[this.platform] === "complete") {
			//Build status: complete
			this.setSrc("$services/assets/images/platforms/" + this.platform + "-logo-complete-32x32.png");

		} else {
			if (this.buildStatusData && this.buildStatusData.status[this.platform] === "error" ||
			    this.buildStatusData && this.buildStatusData.status[this.platform] === null){

				//Build status: error
				this.setSrc("$services/assets/images/platforms/" + this.platform + "-logo-error-32x32.png");

			} else {
				if(this.buildStatusData === null) {

					//Build status: application not built
					this.setSrc("$services/assets/images/platforms/" + this.platform + "-logo-not-available-32x32.png");

				} else {
					//Build status: pending
					this.setSrc("$services/assets/images/platforms/" + this.platform + "-logo-not-available-32x32.png");
					this.bubble("appIdChanged");
				}
			}
		}
	}
});

/**
 * The widget "Build status", show the building state of the application
 * for each platform.
 */
enyo.kind({
	name: "Phonegap.ProjectProperties.BuildStatus",
	kind: "FittableRows",
	published: {
		appId: "",
		buildStatusData: undefined,
		phongapUrl: "https://build.phonegap.com",
		provider: undefined,
		selectedPlatform: undefined
	},
	handlers: {
		onUpdateStatusMessage: "updateDownloadMessageContent"
	},
	components: [
		{
			name: "buildStatusContainer", kind: "FittableRows", classes: "ares-project-properties-build-status-container",
			components: [
				{
					name: "platformIconContainer",
					classes:"ares-project-properties-platform-icon-container",
					kind: "FittableColumns",
				},

				{ name: "downloadStatus", kind: "Phonegap.ProjectProperties.DownloadStatus" },
				{
					name: "messageContainer",
					classes: "ares-project-properties-status-message-container",
					showing: false,
					components: [
						{
							name: "hideStatusContainer",
							kind: "onyx.IconButton",
							src: "$project-view/assets/images/close-button-16x16.png",
							classes: "ares-project-properties-hide-status-button",
							ontap:"hideMessageContainer"
						},
						{
							name: "statusMessage",
							classes: "ares-project-properties-status-message"
						}
					]
				},
				{
					kind: "FittableColumns",
					style: "height: 32px; position: relative; top:-6em;",
					components: [
						{
							name:"separatorForDownloadButton"
						},
						{
							name: "downloadButton",
							kind: "onyx.IconButton",
							src: "$services/assets/images/download-icon.png",
							showing: false,
							ontap: "downloadPackage"
						}
					]
				}

			]
		}
	],
	/**@private*/
	create: function() {
		this.inherited(arguments);
		this.createIconButtons();
		this.appIdChanged();
		this.setProvider(Phonegap.ProjectProperties.getProvider());
	},

	/**
	 * Create the IconButtons displaying the build state of the application
	 * for all platforms defined in the object {Phonegap.ProjectProperties.downloadStatus}
	 *
	 * @private
	 */
	createIconButtons: function() {
		for (var key in Phonegap.ProjectProperties.downloadStatus) {
			this.$.platformIconContainer.createComponent(
				{
					name: key + "Decorator",
					classes: "ares-project-properties-build-status-icon",
					components: [
						{
							name: key + "Button",
							kind: "Phonegap.ProjectProperties.PlatformBuildStatus",
							platform: key
						}
					]
				},
				{owner: this}
			);

		}
	},

	/**
	 * Charge the icon showing the build status of the application of a a given platform depending on
	 * its status. the status is checked from the "buildStatusData" object.
	 * By clicking on the icon, the status message is displayed.
	 *
	 * @private
	 */
	buildStatusDataChanged: function(){
		var pendingApplication = false;

		//Check if there is a pending build.
		for(var key1 in this.buildStatusData && this.buildStatusData.status) {
			if (this.buildStatusData.status[key1] === "pending") {
				pendingApplication = true;
			}
		}

		//If there is a pending build, another buildStatus Request is sent after 600 ms timeout.
		if (pendingApplication) {
			setTimeout(this.sendBuildStatusRequest(), 2000);
		}

		// Get only the Enyo control that have the "platform" attribute
		// => {Phonegap.ProjectProperties.PlatformBuildStatus} instance
		for(var key2 in this.$){
			if(this.$[key2].platform !== undefined) {
				this.$[key2].setBuildStatusData(this.buildStatusData);
			}
		}

		//Update to Status container if a platform is selected.
		if(this.selectedPlatform !== undefined) {
			this.showStatusMessage({platform: this.selectedPlatform});
		}

	},

	/**
	 * Use the phonegap service to request a {buildStatus} object from Phonegap build
	 * @private
	 */
	sendBuildStatusRequest: function() {
		this.provider.getAppData(this.appId, enyo.bind(this, this.getBuildStatusData));
	},

	/**
	 * Update the content of the statusMessage row.
	 * @protected
	 */
	updateDownloadMessageContent: function() {

		this.$.statusMessage.setContent(this.$.downloadStatus.getDownloadStatus(this.selectedPlatform));
		this.$.statusMessage.show();
		this.updateDownloadMessageDisplay(this.selectedPlatform);

		//stop the propagation of the bubble event
		return true;
	},

	/**
	 * Highlight the selected platform button by appling a css style on its decorator.
	 * @param {enyo.component} inIconButtonDecorator decorator of the button
	 * @private
	 */
	addHightlightIconButton: function(inIconButtonDecorator) {
		this.removeHightlightIconButton();
		inIconButtonDecorator.addClass("ares-project-properties-buildStatus-icon-highlight");

	},

	/**
	 * Remove the highlignt effect from all platform buttons.
	 * @private
	 */
	removeHightlightIconButton: function() {
		for(var key in Phonegap.ProjectProperties.downloadStatus) {
			this.$[key + "Decorator"].removeClass("ares-project-properties-buildStatus-icon-highlight");
		}
	},

	/**
	 *
	 * @param  {String} inPlatform Mobile platform supported by Phonegap.
	 * @private
	 */
	updateDownloadMessageDisplay: function(inPlatform) {
		var classAttribute = "ares-project-properties-buildStatus-download-button-" + inPlatform;
		this.$.separatorForDownloadButton.setClassAttribute(classAttribute);

		this.$.downloadButton.show();
	},

	/**@private*/
	showStatusMessage: function(inSender){

		this.setSelectedPlatform(inSender.platform);
		this.$.messageContainer.show();
		this.addHightlightIconButton(this.$[inSender.platform+ "Decorator"]);

		//Build status: complete
		if (this.buildStatusData && this.buildStatusData.status[inSender.platform] === "complete") {

				this.updateDownloadMessageContent();
				this.updateDownloadMessageDisplay(inSender.platform);

		} else {
			this.$.downloadButton.hide();

			if (this.buildStatusData && this.buildStatusData.status[inSender.platform] === "error" ||
				this.buildStatusData && this.buildStatusData.status[inSender.platform] === null){

				//Build status: error
				this.$.statusMessage.setContent("Error: " + this.buildStatusData.error[inSender.platform]);

			} else {

				if(this.buildStatusData === null) {

					//Build status: application not built
					this.$.statusMessage.setContent("Build the application first");

				} else {

					//Build status: pending
					this.$.statusMessage.setContent("Build in progress");
				}
			}
		}

		//stop the propagation of the bubble event
		return true;
	},

	/**
	 * Listener to launch the download request form the Phonegap Build service manager.
	 * @param  {Object} inSender
	 * @param  {Object} inEvent
	 * @private
	 */
	downloadPackage: function(inSender, inEvent) {

		var projectConfig = this.owner.getProject();
		this.provider.downloadPackage(projectConfig, this.selectedPlatform, this.buildStatusData, enyo.bind(this, this.getPackage));

		//set the download status to "Download on progress"
		this.$.downloadStatus.setDownloadStatus(this.selectedPlatform, 2);
	},

	/**
	 * Callback used in the function "downloadPackage()"" in "Build.js"
	 * Update the status message to show the current status of the download request.
	 *
	 * @param  {Object} err       error object
	 * @private
	 */
	getPackage: function(err) {
		if(err) {
			//set the download status to "Download failed"
			this.$.downloadStatus.setDownloadStatus(this.selectedPlatform, 0);
		} else {
			//set the download status to "Download complete"
			this.$.downloadStatus.setDownloadStatus(this.selectedPlatform, 1);
		}
	},

	/**@private*/
	hideMessageContainer: function() {
		//Unselect the focused platform
		this.setSelectedPlatform(undefined);
		this.removeHightlightIconButton();

		this.$.messageContainer.hide();
		this.$.downloadButton.hide();
	},

	/**@private*/
	hideMessageContent: function() {
		this.$.downloadButton.hide();
	},

	/**@private*/
	appIdChanged: function(){

		if(this.appId === "" || this.appId === undefined){
			this.setBuildStatusData(null);
		} else {
			this.sendBuildStatusRequest();
		}
		this.$.buildStatusContainer.render();
	},

	/**
	 * Callback function to initialize the "buildStatusData" object.
	 *
	 * @param  {Object} err               error object
	 * @param  {Object} inBuildStatusData Object returned by Phonegap build, it contains several informations
	 *                                    about the built application.
	 * @private
	 */
	getBuildStatusData: function (err, inBuildStatusData) {
		if (err) {
			this.error("err:", err);
		} else {
			this.setBuildStatusData(inBuildStatusData.user);
		}
	}
});

/**
 * Model kind to keep track on the download status for each
 * mobile platform supported by Phonegap Build.
 *
 * Used only by the widget {Phonegap.ProjectProperties.BuildStatus}
 */
enyo.kind({
	name: "Phonegap.ProjectProperties.DownloadStatus",

	/**
	 * Set the download status for a platform defined in {this.downloadStatus}.
	 *
	 * @param {String} inPlatform       platform defined in {this.downloadStatus}
	 * @param {integer} inDownloadStatus code status: 0 => failed, 1 => complete, other => on progress
	 * @public
	 */
	setDownloadStatus: function(inPlatform, inDownloadStatus) {
		if(inDownloadStatus === 1){
			Phonegap.ProjectProperties.downloadStatus[inPlatform] = "Download complete";
		} else {
			if (inDownloadStatus === 0) {
				Phonegap.ProjectProperties.downloadStatus[inPlatform] = "Download failed";
			} else {
				Phonegap.ProjectProperties.downloadStatus[inPlatform] = "Download on progress";
			}
		}

		this.bubble("onUpdateStatusMessage");
	},

	/**
	 * Get the download status value by platform.
	 *
	 * @param  {String} inPlatform [description]
	 * @return {String} status message
	 * @public
	 */
	getDownloadStatus: function(inPlatform) {
		return Phonegap.ProjectProperties.downloadStatus[inPlatform];
	}

});<commit_msg>ENYO-2788: refactor the code to send the buildStatusData request.<commit_after>/* jshint indent: false */ // TODO: ENYO-3311

/* global Phonegap */

/**
 * UI: Phonegap pane in the ProjectProperties popup
 * @name Phonegap.BuildStatusUI
 */
enyo.kind({
	name: "Phonegap.ProjectProperties.PlatformBuildStatus",
	kind: "onyx.IconButton",
	ontap: "showStatusMessage",
	published: {
		platform: undefined,
		buildStatusData: undefined,
	},
	/**
	 * Update the image for the platform IconButton depending on the status of the related platform
	 * described in buildStatusData.
	 *
	 * @private
	 */
	buildStatusDataChanged: function() {
		if (this.buildStatusData && this.buildStatusData.status[this.platform] === "complete") {
			//Build status: complete
			this.setSrc("$services/assets/images/platforms/" + this.platform + "-logo-complete-32x32.png");

		} else {
			if (this.buildStatusData && this.buildStatusData.status[this.platform] === "error" ||
			    this.buildStatusData && this.buildStatusData.status[this.platform] === null){

				//Build status: error
				this.setSrc("$services/assets/images/platforms/" + this.platform + "-logo-error-32x32.png");

			} else {
				if(this.buildStatusData === null) {

					//Build status: application not built
					this.setSrc("$services/assets/images/platforms/" + this.platform + "-logo-not-available-32x32.png");

				} else {
					//Build status: pending
					this.setSrc("$services/assets/images/platforms/" + this.platform + "-logo-not-available-32x32.png");
					this.bubble("appIdChanged");
				}
			}
		}
	}
});

/**
 * The widget "Build status", show the building state of the application
 * for each platform.
 */
enyo.kind({
	name: "Phonegap.ProjectProperties.BuildStatus",
	kind: "FittableRows",
	published: {
		appId: "",
		buildStatusData: undefined,
		phongapUrl: "https://build.phonegap.com",
		provider: undefined,
		selectedPlatform: undefined
	},
	handlers: {
		onUpdateStatusMessage: "updateDownloadMessageContent"
	},
	components: [
		{
			name: "buildStatusContainer", kind: "FittableRows", classes: "ares-project-properties-build-status-container",
			components: [
				{
					name: "platformIconContainer",
					classes:"ares-project-properties-platform-icon-container",
					kind: "FittableColumns",
				},

				{ name: "downloadStatus", kind: "Phonegap.ProjectProperties.DownloadStatus" },
				{
					name: "messageContainer",
					classes: "ares-project-properties-status-message-container",
					showing: false,
					components: [
						{
							name: "hideStatusContainer",
							kind: "onyx.IconButton",
							src: "$project-view/assets/images/close-button-16x16.png",
							classes: "ares-project-properties-hide-status-button",
							ontap:"hideMessageContainer"
						},
						{
							name: "statusMessage",
							classes: "ares-project-properties-status-message"
						}
					]
				},
				{
					kind: "FittableColumns",
					style: "height: 32px; position: relative; top:-6em;",
					components: [
						{
							name:"separatorForDownloadButton"
						},
						{
							name: "downloadButton",
							kind: "onyx.IconButton",
							src: "$services/assets/images/download-icon.png",
							showing: false,
							ontap: "downloadPackage"
						}
					]
				}

			]
		}
	],
	/**@private*/
	create: function() {
		this.inherited(arguments);
		this.createIconButtons();
		this.appIdChanged();
		this.setProvider(Phonegap.ProjectProperties.getProvider());
	},

	/**
	 * Create the IconButtons displaying the build state of the application
	 * for all platforms defined in the object {Phonegap.ProjectProperties.downloadStatus}
	 *
	 * @private
	 */
	createIconButtons: function() {
		for (var key in Phonegap.ProjectProperties.downloadStatus) {
			this.$.platformIconContainer.createComponent(
				{
					name: key + "Decorator",
					classes: "ares-project-properties-build-status-icon",
					components: [
						{
							name: key + "Button",
							kind: "Phonegap.ProjectProperties.PlatformBuildStatus",
							platform: key
						}
					]
				},
				{owner: this}
			);

		}
	},

	/**
	 * Charge the icon showing the build status of the application of a a given platform depending on
	 * its status. the status is checked from the "buildStatusData" object.
	 * By clicking on the icon, the status message is displayed.
	 *
	 * @private
	 */
	buildStatusDataChanged: function(){
		var pendingApplication = false;

		//Check if there is a pending build.
		for(var key1 in this.buildStatusData && this.buildStatusData.status) {
			if (this.buildStatusData.status[key1] === "pending") {
				pendingApplication = true;
			}
		}

		//If there is a pending build, another buildStatus Request is sent after 600 ms timeout.
		if (pendingApplication) {
			setTimeout(this.sendBuildStatusRequest(), 2000);
		}

		// Get only the Enyo control that have the "platform" attribute
		// => {Phonegap.ProjectProperties.PlatformBuildStatus} instance
		for(var key2 in this.$){
			if(this.$[key2].platform !== undefined) {
				this.$[key2].setBuildStatusData(this.buildStatusData);
			}
		}

		//Update to Status container if a platform is selected.
		if(this.selectedPlatform !== undefined) {
			this.showStatusMessage({platform: this.selectedPlatform});
		}

		this.$.buildStatusContainer.render();

	},

	/**
	 * Use the phonegap service to request a {buildStatus} object from Phonegap build
	 * @private
	 */
	sendBuildStatusRequest: function() {

		if(this.appId === "" || this.appId === undefined){
			this.setBuildStatusData(null);
		} else {
			this.provider.getAppData(this.appId, enyo.bind(this, this.getBuildStatusData));
		}
	},

	/**
	 * Update the content of the statusMessage row.
	 * @protected
	 */
	updateDownloadMessageContent: function() {

		this.$.statusMessage.setContent(this.$.downloadStatus.getDownloadStatus(this.selectedPlatform));
		this.$.statusMessage.show();
		this.updateDownloadMessageDisplay(this.selectedPlatform);

		//stop the propagation of the bubble event
		return true;
	},

	/**
	 * Highlight the selected platform button by appling a css style on its decorator.
	 * @param {enyo.component} inIconButtonDecorator decorator of the button
	 * @private
	 */
	addHightlightIconButton: function(inIconButtonDecorator) {
		this.removeHightlightIconButton();
		inIconButtonDecorator.addClass("ares-project-properties-buildStatus-icon-highlight");

	},

	/**
	 * Remove the highlignt effect from all platform buttons.
	 * @private
	 */
	removeHightlightIconButton: function() {
		for(var key in Phonegap.ProjectProperties.downloadStatus) {
			this.$[key + "Decorator"].removeClass("ares-project-properties-buildStatus-icon-highlight");
		}
	},

	/**
	 *
	 * @param  {String} inPlatform Mobile platform supported by Phonegap.
	 * @private
	 */
	updateDownloadMessageDisplay: function(inPlatform) {
		var classAttribute = "ares-project-properties-buildStatus-download-button-" + inPlatform;
		this.$.separatorForDownloadButton.setClassAttribute(classAttribute);

		this.$.downloadButton.show();
	},

	/**@private*/
	showStatusMessage: function(inSender){

		this.setSelectedPlatform(inSender.platform);
		this.$.messageContainer.show();
		this.addHightlightIconButton(this.$[inSender.platform+ "Decorator"]);

		//Build status: complete
		if (this.buildStatusData && this.buildStatusData.status[inSender.platform] === "complete") {

				this.updateDownloadMessageContent();
				this.updateDownloadMessageDisplay(inSender.platform);

		} else {
			this.$.downloadButton.hide();

			if (this.buildStatusData && this.buildStatusData.status[inSender.platform] === "error" ||
				this.buildStatusData && this.buildStatusData.status[inSender.platform] === null){

				//Build status: error
				this.$.statusMessage.setContent("Error: " + this.buildStatusData.error[inSender.platform]);

			} else {

				if(this.buildStatusData === null) {

					//Build status: application not built
					this.$.statusMessage.setContent("Build the application first");

				} else {

					//Build status: pending
					this.$.statusMessage.setContent("Build in progress");
				}
			}
		}

		//stop the propagation of the bubble event
		return true;
	},

	/**
	 * Listener to launch the download request form the Phonegap Build service manager.
	 * @param  {Object} inSender
	 * @param  {Object} inEvent
	 * @private
	 */
	downloadPackage: function(inSender, inEvent) {

		var projectConfig = this.owner.getProject();
		this.provider.downloadPackage(projectConfig, this.selectedPlatform, this.buildStatusData, enyo.bind(this, this.getPackage));

		//set the download status to "Download on progress"
		this.$.downloadStatus.setDownloadStatus(this.selectedPlatform, 2);
	},

	/**
	 * Callback used in the function "downloadPackage()"" in "Build.js"
	 * Update the status message to show the current status of the download request.
	 *
	 * @param  {Object} err       error object
	 * @private
	 */
	getPackage: function(err) {
		if(err) {
			//set the download status to "Download failed"
			this.$.downloadStatus.setDownloadStatus(this.selectedPlatform, 0);
		} else {
			//set the download status to "Download complete"
			this.$.downloadStatus.setDownloadStatus(this.selectedPlatform, 1);
		}
	},

	/**@private*/
	hideMessageContainer: function() {
		//Unselect the focused platform
		this.setSelectedPlatform(undefined);
		this.removeHightlightIconButton();

		this.$.messageContainer.hide();
		this.$.downloadButton.hide();
	},

	/**@private*/
	hideMessageContent: function() {
		this.$.downloadButton.hide();
	},

	/**@private*/
	appIdChanged: function(){
		this.sendBuildStatusRequest();
	},

	/**
	 * Callback function to initialize the "buildStatusData" object.
	 *
	 * @param  {Object} err               error object
	 * @param  {Object} inBuildStatusData Object returned by Phonegap build, it contains several informations
	 *                                    about the built application.
	 * @private
	 */
	getBuildStatusData: function (err, inBuildStatusData) {
		if (err) {
			this.error("err:", err);
		} else {
			this.setBuildStatusData(inBuildStatusData.user);
		}
	}
});

/**
 * Model kind to keep track on the download status for each
 * mobile platform supported by Phonegap Build.
 *
 * Used only by the widget {Phonegap.ProjectProperties.BuildStatus}
 */
enyo.kind({
	name: "Phonegap.ProjectProperties.DownloadStatus",

	/**
	 * Set the download status for a platform defined in {this.downloadStatus}.
	 *
	 * @param {String} inPlatform       platform defined in {this.downloadStatus}
	 * @param {integer} inDownloadStatus code status: 0 => failed, 1 => complete, other => on progress
	 * @public
	 */
	setDownloadStatus: function(inPlatform, inDownloadStatus) {
		if(inDownloadStatus === 1){
			Phonegap.ProjectProperties.downloadStatus[inPlatform] = "Download complete";
		} else {
			if (inDownloadStatus === 0) {
				Phonegap.ProjectProperties.downloadStatus[inPlatform] = "Download failed";
			} else {
				Phonegap.ProjectProperties.downloadStatus[inPlatform] = "Download on progress";
			}
		}

		this.bubble("onUpdateStatusMessage");
	},

	/**
	 * Get the download status value by platform.
	 *
	 * @param  {String} inPlatform [description]
	 * @return {String} status message
	 * @public
	 */
	getDownloadStatus: function(inPlatform) {
		return Phonegap.ProjectProperties.downloadStatus[inPlatform];
	}

});<|endoftext|>


<commit_before>import React from 'react';
import {propEq, filter} from 'ramda'

import CodeCoverage from './code-coverage'

export default class BuildComponent extends React.Component {

  getPropertyResult(propertyName) {
    const propertyNameCheck = propEq('name', propertyName);
    const results = filter(propertyNameCheck, this.props.property);

    return results.length !== 0 ? results[0].value : ''
  }

  displayTestResults(failedTests, passedTests) {
    let styling = {
      display: 'flex',
      margin: '5px',
      padding: '10px',
      fontSize: '24px',
      color: 'white'
    };
    let content = `${passedTests} Passed`;
    if (failedTests !== '') {
      content = `${failedTests} Failed`;
    }
    return (
{content}
)
  }

  displayFormat(percentageString) {
    return `${parseFloat(percentageString).toFixed(2)}%`;
  }

  render() {
    const failedTests = this.getPropertyResult('FailedTestCount');
    const buildPassed = failedTests === '';
    const passedTests = this.getPropertyResult('PassedTestCount');
    const ccLines = this.displayFormat(this.getPropertyResult('CodeCoverageL'));
    const ccFunctions = this.displayFormat(this.getPropertyResult('CodeCoverageM'));
    const ccStatements = this.displayFormat(this.getPropertyResult('CodeCoverageB'));
    let styling = {
      backgroundColor: buildPassed ? 'green' : '#FE2E2E',
      display: 'flex',
      flexDirection: 'column',
      alignSelf: 'center',
      margin: '5px',
      borderRadius: '5px',
      padding: '10px'
    };
    return (

          {this.props.buildNumber}

{this.props.branchName}

        {this.displayTestResults(failedTests, passedTests)}
        <CodeCoverage lines={ccLines} functions={ccFunctions} statements={ccStatements}/>

    )
  }
}

<commit_msg>Darker colour for the build id<commit_after>import React from 'react';
import {propEq, filter} from 'ramda'

import CodeCoverage from './code-coverage'

export default class BuildComponent extends React.Component {

  getPropertyResult(propertyName) {
    const propertyNameCheck = propEq('name', propertyName);
    const results = filter(propertyNameCheck, this.props.property);

    return results.length !== 0 ? results[0].value : ''
  }

  displayTestResults(failedTests, passedTests) {
    let styling = {
      display: 'flex',
      margin: '5px',
      padding: '10px',
      fontSize: '24px',
      color: 'white'
    };
    let content = `${passedTests} Passed`;
    if (failedTests !== '') {
      content = `${failedTests} Failed`;
    }
    return (
{content}
)
  }

  displayFormat(percentageString) {
    return `${parseFloat(percentageString).toFixed(2)}%`;
  }

  render() {
    const failedTests = this.getPropertyResult('FailedTestCount');
    const buildPassed = failedTests === '';
    const passedTests = this.getPropertyResult('PassedTestCount');
    const ccLines = this.displayFormat(this.getPropertyResult('CodeCoverageL'));
    const ccFunctions = this.displayFormat(this.getPropertyResult('CodeCoverageM'));
    const ccStatements = this.displayFormat(this.getPropertyResult('CodeCoverageB'));
    let styling = {
      backgroundColor: buildPassed ? 'green' : '#FE2E2E',
      display: 'flex',
      flexDirection: 'column',
      alignSelf: 'center',
      margin: '5px',
      borderRadius: '5px',
      padding: '10px'
    };
    return (

          {this.props.buildNumber}

{this.props.branchName}

        {this.displayTestResults(failedTests, passedTests)}
        <CodeCoverage lines={ccLines} functions={ccFunctions} statements={ccStatements}/>

    )
  }
}

<|endoftext|>