<commit_before>/*
 * Copyright 2008-2013 Microarray Informatics Team, EMBL-European Bioinformatics Institute
 *
 * 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.
 *
 *
 * For further details of the Gene Expression Atlas project, including source code,
 * downloads and documentation, please see:
 *
 * http://gxa.github.com/gxa
 */

/*global $,jQuery,console,loadSliderAndPlot: false */
/*jslint browser:true */
/*jslint nomen: true*/

var heatmapModule = (function ($) {

    "use strict";

    function showTranscriptBreakdownFancyBox(){
        $.fancybox({
                href: '#transcript-breakdown',
                padding: 0,
                openEffect: 'elastic',
                closeEffect: 'elastic',
                helpers: {
                    overlay: {
                        locked: false
                    }
                }
            }
        );
    }

    function showCellText(div) {
        $(div).removeClass("hide_cell").addClass("show_cell");
    }

    function hideCellText(div) {
        $(div).removeClass("show_cell").addClass("hide_cell");
    }

    function showExpressionLevels() {
        $("div[data-color]").each(function () {
            showCellText(this);
        });
        $(".gradient-level-min").attr("style", 'white-space: nowrap;');
        $(".gradient-level-max").attr("style", 'white-space: nowrap;');
    }

    function hideExpressionLevels() {
        $("div[data-color]").each(function () {
            hideCellText(this);
        });
        $(".gradient-level-min").css("display", "none");
        $(".gradient-level-max").css("display", "none");
    }

    function initDisplayLevelsButton() { //binds toggle handler

        $("#display-levels").button()
            .toggle(
            function () {
                $(this).button('option', 'label', 'Hide levels');
                showExpressionLevels(this);
                $("#prefForm #displayLevels").val("true");
            },
            function () {
                $(this).button('option', 'label', 'Display levels');
                hideExpressionLevels(this);
                $("#prefForm #displayLevels").val("false");
            }
        );

        if ($("#prefForm #displayLevels").val() === "true") {
            $("#display-levels").click();
        }

    }

    function initHeatmapCellsClickHandling(experimentAccession, species, selectedFilterFactorsJson) { //binds heatmap cells click handler

        function buildPlotData(transcriptRates) {
            var data = [],
                index = 0;
            $.each(transcriptRates, function (key, value) {
                data[index++] = {label: key, data: Math.abs(value.toFixed(1)), color: (value < 0 ? 'white' : undefined)};
            });
            return data;
        }

        function paintPieChart(plotData, geneId){
            $.plot('#transcripts-pie', plotData, {
                series: {
                    pie:{stroke: {
                        color: "#d3d3d3"
                    },
                        show: true
                    }
                },
                legend: {
                    show: true,
                    labelFormatter: function (label) {
                        return label === "Others" ? "Others" :
                                "" +
                                label + "";
                    }
                }
            });
        }

        //on click...
        $("#heatmap-table td:has(div[data-color])").click(function () {

            //gene and factor properties are extracted from gene and factor headers in the html table
            var factorValue = $(this).find("div").attr("data-organism-part"),
                factorType = $("#queryFactorType").attr("value"),
                geneId = $(this).parent().find("td a:eq(0)").attr("id"),
                geneName = $(this).parent().find("td a:eq(0)").text();

            $.ajax({
                url: "json/transcripts/" + experimentAccession,
                type: "GET",
                data: {
                    'geneId': geneId,
                    'factorType': factorType,
                    'factorValue': factorValue,
                    'selectedFilterFactorsJson': JSON.stringify(selectedFilterFactorsJson)
                },
                datatype: 'json',
                success: function (data) {
                    var totalCount = data.totalTranscriptsCount,
                        plotData = buildPlotData(data.transcriptExpressions);

                    species = species.replace(" ", "_");

                    $('#transcript-breakdown').css('position','absolute')
                        .css('left','-5000px')
                    $('#transcript-breakdown').show();

                    paintPieChart(plotData, geneId);

                    //next line is required because the div is configured to stay in an invisible position (position:absolute; left:-5000px)
                    //in order to make it invisible during the show-up of fancybox
                    //all of this is required because of IE8 :( . It doesn' t allow painting canvas in a hidden div, so we need to first show the div, then paint in it, then reposition it, then fancybox it...
                    $('#transcript-breakdown').hide();
                    $('#transcript-breakdown').css('position','relative')
                        .css('left','0px');

                    showTranscriptBreakdownFancyBox();

                    var s = '';
                    if (totalCount > 1) {
                        s = 's';
                    }

                    $('#transcript-breakdown-title').html("Expression Level Breakdown for " +
                        "" +
                        geneName + "" + " (" + totalCount + " transcript" + s + ") in " + factorValue);

                }
            }).fail(function (data) {
                    console.log("ERROR:  " + data);
            });

        });
    }

    //there must be a cleaner way to do this, but I don't know it yet!
    function buildHeatmapCellTooltip(expressionLevel, tstatistic, foldChange) {
        return "

Adjusted P-value	" +
            (tstatistic !== undefined ? "T-statistic	" : "") +
            "Log2-fold Change
" +
            "

" + expressionLevel + "	" +
            (tstatistic !== undefined ? "" + tstatistic + "	" : "") +

            "" + foldChange + "

" +
            "
";
    }

    function initHeatmapCellsTooltip() { //initializes heatmap cells tooltip
        $("#heatmap-table td:has(div[data-fold-change])").attr('title', '').tooltip(
            {
                open: function (event, ui) {
                    var colour = $(this).find("div").attr("data-color");
                    ui.tooltip.css('background', colour);
                },
                tooltipClass: "help-tooltip pvalue-tooltip-styling",

                content: function (callback) {
                    var expressionLevel = $(this).find("div").html(),
                        foldChange = $(this).find("div").attr("data-fold-change"),
                        tstatistic = $(this).find("div").attr("data-tstatistic");

                    return buildHeatmapCellTooltip(expressionLevel, tstatistic, foldChange);
                }

            });
    }

    function initDownloadButton() {
        $('#download-profiles-link').button().tooltip();
    }

    function restrictLabelSize(label, maxSize) {
        var result = label;
        if (label.length > maxSize) {
            label = label.substring(0, maxSize);
            if (label.lastIndexOf(" ") > maxSize - 5) {
                label = label.substring(0, label.lastIndexOf(" "));
            }
            label = label + "...";
        }
        return label;
    }

    function initHeatmapFactorHeaders() {//shorten header labels if necessary and inits tooltips

        $(".factor-header")
            .each(function () {
                if ($.browser.msie) {
                    $(this).append($(this).attr("data-organism-part"));
                } else {
                    var organismPartName = $(this).attr("data-organism-part");
                    organismPartName = restrictLabelSize(organismPartName, 17);
                    $(this).append(organismPartName);
                }
            }).tooltip();

    }

    function createAccessionHeaders(accessionHeaders) {

        var headers;

        $(accessionHeaders).each(function () {
            headers += "" + this + "	";
        });
        //add custom header cells for gene name and design element
        $($("#heatmap-table thead")).append("
" + headers + "
");

        //add display levels cell colspan
        if (accessionHeaders.length === 2) {

            $("#heatmap-table thead tr th:eq(1)").remove();
            $("#heatmap-table thead tr th:eq(0)").attr("colspan", 2);

        }
        //add rowspan to factor headers
        $($("#heatmap-table thead tr th:gt(0)")).attr("rowspan", 2);
    }

    function initMaPlotButtons(experimentAccession, arrayDesignAccession) {
        var thElements = $(".factor-header").parent(),
            maPlotURL;

        thElements.css("width", "60px");
        $(".factor-header").css("transform-origin");
        $(".factor-header").css("top", "57px");

        $(thElements).each(function () {
            var contrastName = $(this).children().attr("data-contrast-name");

            maPlotURL = 'external-resources/' + experimentAccession + '/' + (arrayDesignAccession ? arrayDesignAccession + '/' : '' ) + contrastName + '/ma-plot.png';
            //append a button div now
            $(this).append("

");

        });

        $(".ma-button").tooltip().button();

        $(".ma-button").fancybox({
            padding: 0,
            openEffect: 'elastic',
            closeEffect: 'elastic'
        });

    }

    function initTranscriptBreakdownFancyBox(experimentAccession, parameters){
        initHeatmapCellsClickHandling(experimentAccession, parameters.species, parameters.selectedFilterFactorsJson);

        $('#geneid').tooltip();
        $('#transcript-breakdown-title-help').tooltip();

    }

    function initHeatmap(experimentAccession, parameters) {

        $('#heatmap-table th:first').addClass('horizontal-header-cell'); //because displaytag doesn't let us configure TH cells...

        if (parameters && parameters.species) {
            initTranscriptBreakdownFancyBox(experimentAccession, parameters);
        }

        initHeatmapCellsTooltip();
        initDownloadButton();
        initDisplayLevelsButton();
        initHeatmapFactorHeaders();

        if (parameters && parameters.arrayDesignAccession) { //then it is a microarray experiment
            createAccessionHeaders(['Gene', 'Design Element']);
        } else {
            createAccessionHeaders(['Gene']);
        }

        if (parameters && parameters.cutoff === 0.05 && !parameters.geneQuery) {
            initMaPlotButtons(experimentAccession, parameters.arrayDesignAccession);
        }

        $("#heatmap-div").show();

    }

    function initBaselineHeatmap(experimentAccession, species, selectedFilterFactorsJson) {
        initHeatmap(experimentAccession, {species: species, selectedFilterFactorsJson: selectedFilterFactorsJson});
    }

    function initRnaSeqHeatmap(experimentAccession, cutoff, geneQuery) {
        initHeatmap(experimentAccession, {cutoff: cutoff, geneQuery: geneQuery});
    }

    function initMicroarrayHeatmap(experimentAccession, arrayDesignAccession, cutoff, geneQuery) {
        initHeatmap(experimentAccession, {  arrayDesignAccession: arrayDesignAccession,
            cutoff: cutoff,
            geneQuery: geneQuery });
    }

    return {

        initBaselineHeatmap: initBaselineHeatmap,
        initRnaSeqHeatmap: initRnaSeqHeatmap,
        initMicroarrayHeatmap: initMicroarrayHeatmap

    };

}(jQuery));
<commit_msg>refactoring yesterday workaround for pie chart in IE8<commit_after>/*
 * Copyright 2008-2013 Microarray Informatics Team, EMBL-European Bioinformatics Institute
 *
 * 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.
 *
 *
 * For further details of the Gene Expression Atlas project, including source code,
 * downloads and documentation, please see:
 *
 * http://gxa.github.com/gxa
 */

/*global $,jQuery,console,loadSliderAndPlot: false */
/*jslint browser:true */
/*jslint nomen: true*/

var heatmapModule = (function ($) {

    "use strict";

    function showTranscriptBreakdownFancyBox(){
        $.fancybox({
                href: '#transcript-breakdown',
                padding: 0,
                openEffect: 'elastic',
                closeEffect: 'elastic',
                helpers: {
                    overlay: {
                        locked: false
                    }
                }
            }
        );
    }

    function showCellText(div) {
        $(div).removeClass("hide_cell").addClass("show_cell");
    }

    function hideCellText(div) {
        $(div).removeClass("show_cell").addClass("hide_cell");
    }

    function showExpressionLevels() {
        $("div[data-color]").each(function () {
            showCellText(this);
        });
        $(".gradient-level-min").attr("style", 'white-space: nowrap;');
        $(".gradient-level-max").attr("style", 'white-space: nowrap;');
    }

    function hideExpressionLevels() {
        $("div[data-color]").each(function () {
            hideCellText(this);
        });
        $(".gradient-level-min").css("display", "none");
        $(".gradient-level-max").css("display", "none");
    }

    function initDisplayLevelsButton() { //binds toggle handler

        $("#display-levels").button()
            .toggle(
            function () {
                $(this).button('option', 'label', 'Hide levels');
                showExpressionLevels(this);
                $("#prefForm #displayLevels").val("true");
            },
            function () {
                $(this).button('option', 'label', 'Display levels');
                hideExpressionLevels(this);
                $("#prefForm #displayLevels").val("false");
            }
        );

        if ($("#prefForm #displayLevels").val() === "true") {
            $("#display-levels").click();
        }

    }

    function initHeatmapCellsClickHandling(experimentAccession, species, selectedFilterFactorsJson) { //binds heatmap cells click handler

        function buildPlotData(transcriptRates) {
            var data = [],
                index = 0;
            $.each(transcriptRates, function (key, value) {
                data[index++] = {label: key, data: Math.abs(value.toFixed(1)), color: (value < 0 ? 'white' : undefined)};
            });
            return data;
        }

        function paintPieChart(plotData, geneId){

            $('#transcript-breakdown').css('position','absolute')
                .css('left','-5000px')
            $('#transcript-breakdown').show();

            $.plot('#transcripts-pie', plotData, {
                series: {
                    pie:{stroke: {
                        color: "#d3d3d3"
                    },
                        show: true
                    }
                },
                legend: {
                    show: true,
                    labelFormatter: function (label) {
                        return label === "Others" ? "Others" :
                                "" +
                                label + "";
                    }
                }
            });

            //next lines are required because the div is configured to stay in an invisible position (position:absolute; left:-5000px)
            //in order to make it invisible during the show-up of fancybox
            //all of this is required because of IE8 :( . It doesn' t allow painting canvas in a hidden div, so we need to first show the div, then paint in it, then reposition it, then fancybox it...
            $('#transcript-breakdown').hide();
            $('#transcript-breakdown').css('position','relative')
                .css('left','0px');

        }

        //on click...
        $("#heatmap-table td:has(div[data-color])").click(function () {

            //gene and factor properties are extracted from gene and factor headers in the html table
            var factorValue = $(this).find("div").attr("data-organism-part"),
                factorType = $("#queryFactorType").attr("value"),
                geneId = $(this).parent().find("td a:eq(0)").attr("id"),
                geneName = $(this).parent().find("td a:eq(0)").text();

            $.ajax({
                url: "json/transcripts/" + experimentAccession,
                type: "GET",
                data: {
                    'geneId': geneId,
                    'factorType': factorType,
                    'factorValue': factorValue,
                    'selectedFilterFactorsJson': JSON.stringify(selectedFilterFactorsJson)
                },
                datatype: 'json',
                success: function (data) {
                    var totalCount = data.totalTranscriptsCount,
                        plotData = buildPlotData(data.transcriptExpressions);

                    species = species.replace(" ", "_");

                    paintPieChart(plotData, geneId);

                    showTranscriptBreakdownFancyBox();

                    var s = '';
                    if (totalCount > 1) {
                        s = 's';
                    }

                    $('#transcript-breakdown-title').html("Expression Level Breakdown for " +
                        "" +
                        geneName + "" + " (" + totalCount + " transcript" + s + ") in " + factorValue);

                }
            }).fail(function (data) {
                    console.log("ERROR:  " + data);
            });

        });
    }

    //there must be a cleaner way to do this, but I don't know it yet!
    function buildHeatmapCellTooltip(expressionLevel, tstatistic, foldChange) {
        return "

Adjusted P-value	" +
            (tstatistic !== undefined ? "T-statistic	" : "") +
            "Log2-fold Change
" +
            "

" + expressionLevel + "	" +
            (tstatistic !== undefined ? "" + tstatistic + "	" : "") +

            "" + foldChange + "

" +
            "
";
    }

    function initHeatmapCellsTooltip() { //initializes heatmap cells tooltip
        $("#heatmap-table td:has(div[data-fold-change])").attr('title', '').tooltip(
            {
                open: function (event, ui) {
                    var colour = $(this).find("div").attr("data-color");
                    ui.tooltip.css('background', colour);
                },
                tooltipClass: "help-tooltip pvalue-tooltip-styling",

                content: function (callback) {
                    var expressionLevel = $(this).find("div").html(),
                        foldChange = $(this).find("div").attr("data-fold-change"),
                        tstatistic = $(this).find("div").attr("data-tstatistic");

                    return buildHeatmapCellTooltip(expressionLevel, tstatistic, foldChange);
                }

            });
    }

    function initDownloadButton() {
        $('#download-profiles-link').button().tooltip();
    }

    function restrictLabelSize(label, maxSize) {
        var result = label;
        if (label.length > maxSize) {
            label = label.substring(0, maxSize);
            if (label.lastIndexOf(" ") > maxSize - 5) {
                label = label.substring(0, label.lastIndexOf(" "));
            }
            label = label + "...";
        }
        return label;
    }

    function initHeatmapFactorHeaders() {//shorten header labels if necessary and inits tooltips

        $(".factor-header")
            .each(function () {
                if ($.browser.msie) {
                    $(this).append($(this).attr("data-organism-part"));
                } else {
                    var organismPartName = $(this).attr("data-organism-part");
                    organismPartName = restrictLabelSize(organismPartName, 17);
                    $(this).append(organismPartName);
                }
            }).tooltip();

    }

    function createAccessionHeaders(accessionHeaders) {

        var headers;

        $(accessionHeaders).each(function () {
            headers += "" + this + "	";
        });
        //add custom header cells for gene name and design element
        $($("#heatmap-table thead")).append("
" + headers + "
");

        //add display levels cell colspan
        if (accessionHeaders.length === 2) {

            $("#heatmap-table thead tr th:eq(1)").remove();
            $("#heatmap-table thead tr th:eq(0)").attr("colspan", 2);

        }
        //add rowspan to factor headers
        $($("#heatmap-table thead tr th:gt(0)")).attr("rowspan", 2);
    }

    function initMaPlotButtons(experimentAccession, arrayDesignAccession) {
        var thElements = $(".factor-header").parent(),
            maPlotURL;

        thElements.css("width", "60px");
        $(".factor-header").css("transform-origin");
        $(".factor-header").css("top", "57px");

        $(thElements).each(function () {
            var contrastName = $(this).children().attr("data-contrast-name");

            maPlotURL = 'external-resources/' + experimentAccession + '/' + (arrayDesignAccession ? arrayDesignAccession + '/' : '' ) + contrastName + '/ma-plot.png';
            //append a button div now
            $(this).append("

");

        });

        $(".ma-button").tooltip().button();

        $(".ma-button").fancybox({
            padding: 0,
            openEffect: 'elastic',
            closeEffect: 'elastic'
        });

    }

    function initTranscriptBreakdownFancyBox(experimentAccession, parameters){
        initHeatmapCellsClickHandling(experimentAccession, parameters.species, parameters.selectedFilterFactorsJson);

        $('#geneid').tooltip();
        $('#transcript-breakdown-title-help').tooltip();

    }

    function initHeatmap(experimentAccession, parameters) {

        $('#heatmap-table th:first').addClass('horizontal-header-cell'); //because displaytag doesn't let us configure TH cells...

        if (parameters && parameters.species) {
            initTranscriptBreakdownFancyBox(experimentAccession, parameters);
        }

        initHeatmapCellsTooltip();
        initDownloadButton();
        initDisplayLevelsButton();
        initHeatmapFactorHeaders();

        if (parameters && parameters.arrayDesignAccession) { //then it is a microarray experiment
            createAccessionHeaders(['Gene', 'Design Element']);
        } else {
            createAccessionHeaders(['Gene']);
        }

        if (parameters && parameters.cutoff === 0.05 && !parameters.geneQuery) {
            initMaPlotButtons(experimentAccession, parameters.arrayDesignAccession);
        }

        $("#heatmap-div").show();

    }

    function initBaselineHeatmap(experimentAccession, species, selectedFilterFactorsJson) {
        initHeatmap(experimentAccession, {species: species, selectedFilterFactorsJson: selectedFilterFactorsJson});
    }

    function initRnaSeqHeatmap(experimentAccession, cutoff, geneQuery) {
        initHeatmap(experimentAccession, {cutoff: cutoff, geneQuery: geneQuery});
    }

    function initMicroarrayHeatmap(experimentAccession, arrayDesignAccession, cutoff, geneQuery) {
        initHeatmap(experimentAccession, {  arrayDesignAccession: arrayDesignAccession,
            cutoff: cutoff,
            geneQuery: geneQuery });
    }

    return {

        initBaselineHeatmap: initBaselineHeatmap,
        initRnaSeqHeatmap: initRnaSeqHeatmap,
        initMicroarrayHeatmap: initMicroarrayHeatmap

    };

}(jQuery));
<|endoftext|>


<commit_before>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * All rights reserved.
 */

// TODO: It might be better to make a ContextProvider class, since you
// can always find the canvas through context.canvas. This saves code and
// speed by not having to do canvas.getContext('2d')
// TODO: Run through the canvas array to find a canvas with the requested
// width / height, so we don't need to resize it?
var CanvasProvider = {
	canvases: [],
	getCanvas: function(size) {
		if (this.canvases.length) {
			var canvas = this.canvases.pop();
			// If they are not the same size, we don't need to clear them
			// using clearRect and visa versa.
			if ((canvas.width != size.width)
					|| (canvas.height != size.height)) {
				canvas.width = size.width;
				canvas.height = size.height;
			} else {
				// +1 is needed on some browsers to really clear the borders
				canvas.getContext('2d').clearRect(0, 0,
						size.width + 1, size.height + 1);
			}
			return canvas;
		} else {
//#ifdef BROWSER
			var canvas = document.createElement('canvas');
			canvas.width = size.width;
			canvas.height = size.height;
			return canvas;
//#else // !BROWSER
			// TODO: Implement for server environments
			return null;
//#endif // !BROWSER
		}
	},

	returnCanvas: function(canvas) {
		this.canvases.push(canvas);
	}
};
<commit_msg>Start adding support for rhino-canvas on server.<commit_after>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * All rights reserved.
 */

// TODO: It might be better to make a ContextProvider class, since you
// can always find the canvas through context.canvas. This saves code and
// speed by not having to do canvas.getContext('2d')
// TODO: Run through the canvas array to find a canvas with the requested
// width / height, so we don't need to resize it?
var CanvasProvider = {
	canvases: [],
	getCanvas: function(size) {
		if (this.canvases.length) {
			var canvas = this.canvases.pop();
			// If they are not the same size, we don't need to clear them
			// using clearRect and visa versa.
			if ((canvas.width != size.width)
					|| (canvas.height != size.height)) {
				canvas.width = size.width;
				canvas.height = size.height;
			} else {
				// +1 is needed on some browsers to really clear the borders
				canvas.getContext('2d').clearRect(0, 0,
						size.width + 1, size.height + 1);
			}
			return canvas;
		} else {
//#ifdef BROWSER
			var canvas = document.createElement('canvas');
			canvas.width = size.width;
			canvas.height = size.height;
			return canvas;
//#else // !BROWSER
			// Only rhino-canvas for now:
			return new Image(size.width, size.height);
//#endif // !BROWSER
		}
	},

	returnCanvas: function(canvas) {
		this.canvases.push(canvas);
	}
};
<|endoftext|>


<commit_before>/**
 * Github FileBrowser configuration module.
 */
(function(Rubeus) {

    // Private members

    function refreshGitHubTree(grid, item, branch) {
        var data = item.data || {};
        data.branch = branch;
        var url = item.urls.branch + '?' + $.param({branch: branch});
        $.ajax({
            type: 'get',
            url: url,
            success: function(data) {
                // Update the item with the new branch data
                $.extend(item, data);
                grid.reloadFolder(item);
            }
        });
    }

    // Register configuration
    Rubeus.cfg.github = {
        // Handle changing the branch select
        listeners: [{
            on: 'change',
            selector: '.github-branch-select',
            callback: function(evt, row, grid) {
                var $this = $(evt.target);
                var branch = $this.val();
                refreshGitHubTree(grid, row, branch);
            }
        }]
    };

})(Rubeus);
<commit_msg>hgrid views now return lists<commit_after>/**
 * Github FileBrowser configuration module.
 */
(function(Rubeus) {

    // Private members

    function refreshGitHubTree(grid, item, branch) {
        var data = item.data || {};
        data.branch = branch;
        var url = item.urls.branch + '?' + $.param({branch: branch});
        $.ajax({
            type: 'get',
            url: url,
            success: function(data) {
                // Update the item with the new branch data
                $.extend(item, data[0]);
                grid.reloadFolder(item);
            }
        });
    }

    // Register configuration
    Rubeus.cfg.github = {
        // Handle changing the branch select
        listeners: [{
            on: 'change',
            selector: '.github-branch-select',
            callback: function(evt, row, grid) {
                var $this = $(evt.target);
                var branch = $this.val();
                refreshGitHubTree(grid, row, branch);
            }
        }]
    };

})(Rubeus);
<|endoftext|>


<commit_before>exports.run = (bot, msg, args) => {
    let count = parseInt(args[0]) || 1;

    msg.delete();
    msg.channel.fetchMessages({ limit: Math.min(count, 100), before: msg.id })
        .then(messages => {
            Promise.all(messages.filter(m => m.author.id === bot.user.id)
                .map(m => m.delete()))
                .then(() => {
                    msg.channel.sendMessage(`:white_check_mark: Pruned \`${count}\` messages.`).then(m => m.delete(2000));
                });
        }).catch(msg.error);

};

exports.info = {
    name: 'prune',
    usage: 'prune [amount]',
    description: 'Deletes a certain number of messages sent by you'
};
<commit_msg>Fixed up //prune<commit_after>exports.run = (bot, msg, args) => {
    let count = parseInt(args[0]) || 1;

    msg.delete();
    msg.channel.fetchMessages({ limit: Math.min(count, 100), before: msg.id }).then(messages => {
        const prunable = messages.filter(m => m.author.id === bot.user.id);

        return Promise.all(
            prunable.map(m => m.delete())
        ).then(() => {
            msg.channel.sendMessage(`:white_check_mark: Pruned \`${prunable.size}\` messages.`).then(m => m.delete(2000));
        });
    }).catch(msg.error);
};

exports.info = {
    name: 'prune',
    usage: 'prune [amount]',
    description: 'Deletes a certain number of messages sent by you'
};
<|endoftext|>


<commit_before>//
// Copyright (c) 2017 DrSmugleaf
//

"use strict"
const DB = require("../../../util/db.js")
const winston = require("winston")

module.exports = class Quote {
  constructor(client) {
    this.client = client

    this.db = new DB()

    this.quotes = new Map()
  }

  async init() {
    await this.db.query("CREATE TABLE IF NOT EXISTS quotes (id BIGSERIAL PRIMARY KEY, text TEXT, submitter TEXT, guild BIGINT)")

    const rows = await this.db.query("SELECT id, text, submitter, CAST(guild as TEXT) as guild FROM quotes")
    for(const row of rows) {
      const guild = row.guild
      const quotes = this.quotes.get(guild) || new Array()
      quotes.push(row)
      this.quotes.set(guild, quotes)
    }
  }

  add(data) {
    const that = this
    return new Promise(function(resolve, reject) {
      that.db.query(
        "INSERT INTO quotes (text, submitter, guild) VALUES ($1::text, $2::text, $3::bigint)",
        [data.text, data.submitter, data.guild]
      ).then((data) => {
        const quotes = that.quotes.get(data.guild) || new Array()
        quotes.push(data)
        that.quotes.set(data.guild, quotes)
        resolve()
      }).catch((e) => {
        winston.error(e)
        reject(e)
      })
    })
  }

  delete(data) {
    const quote = this.quotes.get(data.guild).find((quote) => {
      return quote.id === data.id
    })

    return new Promise(function(resolve, reject) {
      if(!quote) reject()
      this.db.query("DELETE FROM quotes WHERE id=$1::bigint", [quote.id], "one").then(() => {
        resolve()
      }).catch((e) => {
        winston.error(e)
        reject(e)
      })
    })
  }

  get(data) {
    const quotes = this.quotes.get(data.guild)

    if(data.id) return quotes.find((quote) => { return quote.id === data.id })
    return quotes[Math.floor(Math.random() * quotes.length)]
  }

  has(data) {
    return Boolean(this.quotes.get(data.guild).find((quote) => {
      return quote.id === data.id
    }))
  }
}
<commit_msg>Quote ID ordering now depends on the server's quotes<commit_after>//
// Copyright (c) 2017 DrSmugleaf
//

"use strict"
const DB = require("../../../util/db.js")
const winston = require("winston")

module.exports = class Quote {
  constructor(client) {
    this.client = client

    this.db = new DB()

    this.quotes = new Map()
  }

  async init() {
    await this.db.query("CREATE TABLE IF NOT EXISTS quotes (id BIGSERIAL PRIMARY KEY, text TEXT, submitter TEXT, guild BIGINT)")

    const rows = await this.db.query("SELECT id as realid, text, submitter, CAST(guild as TEXT) as guild FROM quotes")
    for(var row of rows) {
      const guild = row.guild
      const quotes = this.quotes.get(guild) || new Array()
      const id = quotes[quotes.length - 1] ? quotes[quotes.length - 1].id + 1 : 1
      row.id = id
      quotes.push(row)
      this.quotes.set(guild, quotes)
    }
  }

  add(data) {
    const that = this
    return new Promise(function(resolve, reject) {
      that.db.query(
        "INSERT INTO quotes (text, submitter, guild) VALUES ($1::text, $2::text, $3::bigint)",
        [data.text, data.submitter, data.guild]
      ).then((data) => {
        const quotes = that.quotes.get(data.guild) || new Array()
        const id = quotes[quotes.length - 1] ? quotes[quotes.length - 1].id : 1
        data.id = id
        quotes.push(data)
        that.quotes.set(data.guild, quotes)
        resolve()
      }).catch((e) => {
        winston.error(e)
        reject(e)
      })
    })
  }

  delete(data) {
    const quote = this.quotes.get(data.guild).find((quote) => {
      return quote.id === data.id
    })

    return new Promise(function(resolve, reject) {
      if(!quote) reject()
      this.db.query("DELETE FROM quotes WHERE id=$1::bigint", [quote.id], "one").then(() => {
        resolve()
      }).catch((e) => {
        winston.error(e)
        reject(e)
      })
    })
  }

  get(data) {
    const quotes = this.quotes.get(data.guild)

    if(data.id) return quotes.find((quote) => { return quote.id === data.id })
    return quotes[Math.floor(Math.random() * quotes.length)]
  }

  has(data) {
    return Boolean(this.quotes.get(data.guild).find((quote) => {
      return quote.id === data.id
    }))
  }
}
<|endoftext|>


<commit_before>/* global FormData */

import React from 'react';
import Relay from 'react-relay';
import axios from 'axios';

import ArrowDown from 'material-ui/svg-icons/navigation/arrow-drop-down';
import Dialog from 'material-ui/Dialog';
import IconButton from 'material-ui/IconButton';
import IconMenu from 'material-ui/IconMenu';
import MenuItem from 'material-ui/MenuItem';
import Paper from 'material-ui/Paper';
import RaisedButton from 'material-ui/RaisedButton';
import getMuiTheme from 'material-ui/styles/getMuiTheme';

import Date from './Date';
import Text from './Text';
import EventItem from './EventItem';
import EditEvent from './EditEvent';
import ProjectForm from './ProjectForm';
import FileList from './FileList';
import FileUpload from './FileUpload';
import MusicList from './MusicList';
import PermissionChips from './PermissionChips';
import AddEventMutation from '../mutations/addEvent';
import AddFileMutation from '../mutations/addFile';
import SaveFilePermissionsMutation from '../mutations/saveFilePermissions';
import SaveProjectMutation from '../mutations/saveProject';
import SetProjectPosterMutation from '../mutations/setProjectPoster';
import { flattenPermissions } from '../utils';
import theme from '../theme';

class Project extends React.Component {
    static contextTypes = {
        relay: Relay.PropTypes.Environment,
    };

    static propTypes = {
        organization: React.PropTypes.object,
        viewer: React.PropTypes.object,
    }

    static childContextTypes = {
        muiTheme: React.PropTypes.object.isRequired,
    }

    constructor(props) {
        super(props);
        this.muiTheme = getMuiTheme(theme);
    }

    state = {
        public: false,
        addEvent: false,
        addFile: false,
        editProject: false,
        showEnded: false,
        event: {
            title: '',
            location: '',
            start: null,
            end: null,
            tags: [],
            year: '',
            permissions: [],
            mdtext: '',
        },
    }

    getChildContext() {
        return { muiTheme: this.muiTheme };
    }

    onDrop = (files, permissions) => {
        files.forEach(file => {
            const data = new FormData();
            data.append('file', file);

            axios.post('/upload', data)
            .then((response) => {
                this.context.relay.commitUpdate(new AddFileMutation({
                    viewer: null,
                    organization: this.props.organization,
                    hex: response.data.hex,
                    permissions,
                    tags: [this.props.organization.project.tag],
                    filename: file.name,
                    projectTag: this.props.organization.project.tag,
                }), {
                    onSuccess: () => {
                        // console.log("successfile");
                    },
                    onFailure: transaction => {
                        console.error(transaction.getError().source.errors);
                    },
                });
            })
            .catch(error => {
                console.error("err", error);
            });
        });
    }

    togglePublic = () => {
        this.setState({ public: !this.state.public });
    }

    toggleAddEvent = () => {
        this.setState({ addEvent: !this.state.addEvent });
    }

    toggleEditProject = () => {
        this.setState({ editProject: !this.state.editProject });
    }

    closeAddEvent = () => {
        this.setState({ addEvent: false });
    }

    toggleAddFile = () => {
        this.setState({ addFile: !this.state.addFile });
    }

    closeAddFile = () => {
        this.setState({ addFile: false });
    }

    saveEvent = (event) => {
        this.context.relay.commitUpdate(new AddEventMutation({
            organization: this.props.organization,
            title: event.title,
            location: event.location,
            start: event.start,
            end: event.end,
            tags: [this.props.organization.project.tag],
            mdtext: event.mdtext,
            permissions: event.permissions.map(permission => permission.value),
        }), {
            onSuccess: () => {
                this.closeAddEvent();
            },
            onFailure: (error, ost, kake) => {
                console.error('AD', error, ost, kake);
            },
        });
    }

    onSaveFilePermissions = (file, permissions, onSuccess) => {
        this.context.relay.commitUpdate(new SaveFilePermissionsMutation({
            organization: this.props.organization,
            fileId: file,
            permissions: permissions.map(permission => permission.id),
        }), {
            onSuccess,
        });
    }

    onSetProjectPoster = (file) => {
        this.context.relay.commitUpdate(new SetProjectPosterMutation({
            organization: this.props.organization,
            fileId: file,
            projectId: this.props.organization.project.id,
        }));
    }

    saveProject = (project, callbacks) => {
        this.context.relay.commitUpdate(new SaveProjectMutation({
            organization: this.props.organization,
            ...project,
        }), {
            onSuccess: () => {
                if (callbacks && callbacks.onSuccess) {
                    callbacks.onSuccess();
                }
            },
        });
    }

    showEnded = () => {
        this.setState({ showEnded: true });
    }

    render() {
        const viewer = this.props.viewer;
        const org = this.props.organization;
        const project = this.props.organization.project;
        const isMember = this.props.organization.isMember;
        const hasEndedActivities = project.events.edges.filter(edge => edge.node.isEnded).length > 0;
        return (
            <Paper className="row">

{project.title}

                            {project.start ? <Date date={project.start} /> –  : null}
                            <Date date={project.end} />
                            {project.conductors.map(conductor => conductor.name)}

                    {isMember
                        ? <IconMenu
                            iconButtonElement={<IconButton><ArrowDown /></IconButton>}
                            anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
                            targetOrigin={{ vertical: 'top', horizontal: 'right' }}
                        >
                            {hasEndedActivities
                                    ? <MenuItem
                                        primaryText="Vis tidligere aktiviteter"
                                        onTouchTap={this.showEnded}
                                    />
                                    : null
                            }
                            <MenuItem
                                primaryText="Rediger prosjektinfo"
                                onTouchTap={this.toggleEditProject}
                            />
                            <MenuItem
                                primaryText="Legg til aktivitet"
                                onTouchTap={this.toggleAddEvent}
                            />
                            <MenuItem
                                primaryText="Last opp filer"
                                onTouchTap={this.toggleAddFile}
                            />
                        </IconMenu>
                        : null
                    }

                        <PermissionChips
                            permissions={flattenPermissions(project.permissions)}
                            memberGroupId={org.memberGroup.id}
                        />
                        {project.publicMdtext
                            ?

Informasjon

                                <Text text={project.publicMdtext} />

                            : null
                        }
                        {isMember && project.privateMdtext
                            ?

Intern informasjon

                                <Text text={project.privateMdtext} />

                            : null
                        }
                        {project.music.length
                                ?

Repertoar

                                    <MusicList music={project.music} isMember={isMember} />

                                : null
                        }
                        {isMember && project.files.edges.length
                            ? <FileList
                                files={project.files}
                                memberGroupId={org.memberGroup.id}
                                onSavePermissions={this.onSaveFilePermissions}
                                onSetProjectPoster={this.onSetProjectPoster}
                                style={{ margin: '0 -15px' }}
                                title="Prosjektfiler"
                                viewer={this.props.viewer}
                            />
                            : null
                        }

                        {project.poster ?

                            :
                            null
                        }
                        {project.events.edges.length
                                ?

                                    {project.events.edges
                                            .filter(edge => this.state.showEnded || !edge.node.isEnded)
                                            .map(edge => (
                                                <EventItem
                                                    key={edge.node.id}
                                                    event={edge.node}
                                                />
                                            ))
                                    }

                                : null
                        }

                {isMember
                    ?

                        <ProjectForm
                            open={this.state.editProject}
                            save={this.saveProject}
                            toggle={this.toggleEditProject}
                            viewer={this.props.viewer}
                            {...project}
                        />
                        <Dialog
                            title="Legg til aktivitet"
                            open={this.state.addEvent}
                            onRequestClose={this.closeAddEvent}
                            autoScrollBodyContent
                        >
                            <EditEvent
                                viewer={this.props.viewer}
                                saveEvent={this.saveEvent}
                                {...this.state.event}
                            />
                        </Dialog>
                        <Dialog
                            title="Last opp filer"
                            open={this.state.addFile}
                            onRequestClose={this.closeAddFile}
                            autoScrollBodyContent
                        >
                            <FileUpload viewer={viewer} organization={org} onDrop={this.onDrop} />
                            <RaisedButton label="Ferdig" primary onTouchTap={this.closeAddFile} />
                        </Dialog>

                    : null
                }
            </Paper>
        );
    }
}

export default Relay.createContainer(Project, {
    initialVariables: {
        year: '',
        tag: '',
    },
    fragments: {
        viewer: () => Relay.QL`
        fragment on User {
            groups {
                id
                name
            }
            ${ProjectForm.getFragment('viewer')}
        }
        `,
        organization: () => Relay.QL`
        fragment on Organization {
            name
            isMember
            memberGroup {
                id
            }
            project(year:$year, tag:$tag) {
                id
                title
                tag
                start
                end
                year
                publicMdtext
                privateMdtext
                conductors {
                    name
                }
                poster {
                    filename
                    largePath
                }
                events(first:100) {
                    edges {
                        node {
                            id
                            isEnded
                            ${EventItem.getFragment('event')}
                        }
                    }
                }
                files(first:100) {
                    edges {
                        node {
                            id
                            filename
                            created
                            mimetype
                            size
                            permissions {
                                public
                                groups {
                                    id
                                    name
                                }
                                users {
                                    id
                                    name
                                }
                            }
                            tags
                            isImage
                            thumbnailPath
                            path
                        }
                    }
                }
                music {
                    piece {
                        id
                        title
                        composers
                    }
                }
                permissions {
                    public
                    groups {
                        id
                        name
                    }
                    users {
                        id
                        name
                    }
                }
            }
            ${AddEventMutation.getFragment('organization')}
            ${AddFileMutation.getFragment('organization')}
            ${SaveFilePermissionsMutation.getFragment('organization')}
            ${SaveProjectMutation.getFragment('organization')}
            ${SetProjectPosterMutation.getFragment('organization')}
        }`,
    },
});
<commit_msg>Add Helmet for Project<commit_after>/* global FormData */

import React from 'react';
import Helmet from 'react-helmet';
import Relay from 'react-relay';
import axios from 'axios';

import ArrowDown from 'material-ui/svg-icons/navigation/arrow-drop-down';
import Dialog from 'material-ui/Dialog';
import IconButton from 'material-ui/IconButton';
import IconMenu from 'material-ui/IconMenu';
import MenuItem from 'material-ui/MenuItem';
import Paper from 'material-ui/Paper';
import RaisedButton from 'material-ui/RaisedButton';
import getMuiTheme from 'material-ui/styles/getMuiTheme';

import Date from './Date';
import Text from './Text';
import EventItem from './EventItem';
import EditEvent from './EditEvent';
import ProjectForm from './ProjectForm';
import FileList from './FileList';
import FileUpload from './FileUpload';
import MusicList from './MusicList';
import PermissionChips from './PermissionChips';
import AddEventMutation from '../mutations/addEvent';
import AddFileMutation from '../mutations/addFile';
import SaveFilePermissionsMutation from '../mutations/saveFilePermissions';
import SaveProjectMutation from '../mutations/saveProject';
import SetProjectPosterMutation from '../mutations/setProjectPoster';
import { flattenPermissions } from '../utils';
import theme from '../theme';

class Project extends React.Component {
    static contextTypes = {
        relay: Relay.PropTypes.Environment,
    };

    static propTypes = {
        organization: React.PropTypes.object,
        viewer: React.PropTypes.object,
    }

    static childContextTypes = {
        muiTheme: React.PropTypes.object.isRequired,
    }

    constructor(props) {
        super(props);
        this.muiTheme = getMuiTheme(theme);
    }

    state = {
        public: false,
        addEvent: false,
        addFile: false,
        editProject: false,
        showEnded: false,
        event: {
            title: '',
            location: '',
            start: null,
            end: null,
            tags: [],
            year: '',
            permissions: [],
            mdtext: '',
        },
    }

    getChildContext() {
        return { muiTheme: this.muiTheme };
    }

    onDrop = (files, permissions) => {
        files.forEach(file => {
            const data = new FormData();
            data.append('file', file);

            axios.post('/upload', data)
            .then((response) => {
                this.context.relay.commitUpdate(new AddFileMutation({
                    viewer: null,
                    organization: this.props.organization,
                    hex: response.data.hex,
                    permissions,
                    tags: [this.props.organization.project.tag],
                    filename: file.name,
                    projectTag: this.props.organization.project.tag,
                }), {
                    onSuccess: () => {
                        // console.log("successfile");
                    },
                    onFailure: transaction => {
                        console.error(transaction.getError().source.errors);
                    },
                });
            })
            .catch(error => {
                console.error("err", error);
            });
        });
    }

    togglePublic = () => {
        this.setState({ public: !this.state.public });
    }

    toggleAddEvent = () => {
        this.setState({ addEvent: !this.state.addEvent });
    }

    toggleEditProject = () => {
        this.setState({ editProject: !this.state.editProject });
    }

    closeAddEvent = () => {
        this.setState({ addEvent: false });
    }

    toggleAddFile = () => {
        this.setState({ addFile: !this.state.addFile });
    }

    closeAddFile = () => {
        this.setState({ addFile: false });
    }

    saveEvent = (event) => {
        this.context.relay.commitUpdate(new AddEventMutation({
            organization: this.props.organization,
            title: event.title,
            location: event.location,
            start: event.start,
            end: event.end,
            tags: [this.props.organization.project.tag],
            mdtext: event.mdtext,
            permissions: event.permissions.map(permission => permission.value),
        }), {
            onSuccess: () => {
                this.closeAddEvent();
            },
            onFailure: (error, ost, kake) => {
                console.error('AD', error, ost, kake);
            },
        });
    }

    onSaveFilePermissions = (file, permissions, onSuccess) => {
        this.context.relay.commitUpdate(new SaveFilePermissionsMutation({
            organization: this.props.organization,
            fileId: file,
            permissions: permissions.map(permission => permission.id),
        }), {
            onSuccess,
        });
    }

    onSetProjectPoster = (file) => {
        this.context.relay.commitUpdate(new SetProjectPosterMutation({
            organization: this.props.organization,
            fileId: file,
            projectId: this.props.organization.project.id,
        }));
    }

    saveProject = (project, callbacks) => {
        this.context.relay.commitUpdate(new SaveProjectMutation({
            organization: this.props.organization,
            ...project,
        }), {
            onSuccess: () => {
                if (callbacks && callbacks.onSuccess) {
                    callbacks.onSuccess();
                }
            },
        });
    }

    showEnded = () => {
        this.setState({ showEnded: true });
    }

    render() {
        const viewer = this.props.viewer;
        const org = this.props.organization;
        const project = this.props.organization.project;
        const isMember = this.props.organization.isMember;
        const hasEndedActivities = project.events.edges.filter(edge => edge.node.isEnded).length;
        return (
            <Paper className="row">
                <Helmet
                    title={project.title}
                    meta={[
                        { property: 'og:title', content: project.title },
                        { property: 'og:description', content: project.publicMdtext },
                        { property: 'og:image', content: project.poster ? `${org.baseurl}/${project.poster.largePath}` : '' },
                        { property: 'og:url', content: `${org.baseurl}/${project.year}/${project.tag}` },
                    ]}
                />

{project.title}

                            {project.start ? <Date date={project.start} /> –  : null}
                            <Date date={project.end} />
                            {project.conductors.map(conductor => conductor.name)}

                    {isMember
                        ? <IconMenu
                            iconButtonElement={<IconButton><ArrowDown /></IconButton>}
                            anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
                            targetOrigin={{ vertical: 'top', horizontal: 'right' }}
                        >
                            {hasEndedActivities
                                    ? <MenuItem
                                        primaryText="Vis tidligere aktiviteter"
                                        onTouchTap={this.showEnded}
                                    />
                                    : null
                            }
                            <MenuItem
                                primaryText="Rediger prosjektinfo"
                                onTouchTap={this.toggleEditProject}
                            />
                            <MenuItem
                                primaryText="Legg til aktivitet"
                                onTouchTap={this.toggleAddEvent}
                            />
                            <MenuItem
                                primaryText="Last opp filer"
                                onTouchTap={this.toggleAddFile}
                            />
                        </IconMenu>
                        : null
                    }

                        <PermissionChips
                            permissions={flattenPermissions(project.permissions)}
                            memberGroupId={org.memberGroup.id}
                        />
                        {project.publicMdtext
                            ?

Informasjon

                                <Text text={project.publicMdtext} />

                            : null
                        }
                        {isMember && project.privateMdtext
                            ?

Intern informasjon

                                <Text text={project.privateMdtext} />

                            : null
                        }
                        {project.music.length
                                ?

Repertoar

                                    <MusicList music={project.music} isMember={isMember} />

                                : null
                        }
                        {isMember && project.files.edges.length
                            ? <FileList
                                files={project.files}
                                memberGroupId={org.memberGroup.id}
                                onSavePermissions={this.onSaveFilePermissions}
                                onSetProjectPoster={this.onSetProjectPoster}
                                style={{ margin: '0 -15px' }}
                                title="Prosjektfiler"
                                viewer={this.props.viewer}
                            />
                            : null
                        }

                        {project.poster ?

                            :
                            null
                        }
                        {project.events.edges.length
                                ?

                                    {project.events.edges
                                            .filter(edge => this.state.showEnded || !edge.node.isEnded)
                                            .map(edge => (
                                                <EventItem
                                                    key={edge.node.id}
                                                    event={edge.node}
                                                />
                                            ))
                                    }

                                : null
                        }

                {isMember
                    ?

                        <ProjectForm
                            open={this.state.editProject}
                            save={this.saveProject}
                            toggle={this.toggleEditProject}
                            viewer={this.props.viewer}
                            {...project}
                        />
                        <Dialog
                            title="Legg til aktivitet"
                            open={this.state.addEvent}
                            onRequestClose={this.closeAddEvent}
                            autoScrollBodyContent
                        >
                            <EditEvent
                                viewer={this.props.viewer}
                                saveEvent={this.saveEvent}
                                {...this.state.event}
                            />
                        </Dialog>
                        <Dialog
                            title="Last opp filer"
                            open={this.state.addFile}
                            onRequestClose={this.closeAddFile}
                            autoScrollBodyContent
                        >
                            <FileUpload viewer={viewer} organization={org} onDrop={this.onDrop} />
                            <RaisedButton label="Ferdig" primary onTouchTap={this.closeAddFile} />
                        </Dialog>

                    : null
                }
            </Paper>
        );
    }
}

export default Relay.createContainer(Project, {
    initialVariables: {
        year: '',
        tag: '',
    },
    fragments: {
        viewer: () => Relay.QL`
        fragment on User {
            groups {
                id
                name
            }
            ${ProjectForm.getFragment('viewer')}
        }
        `,
        organization: () => Relay.QL`
        fragment on Organization {
            name
            isMember
            memberGroup {
                id
            }
            baseurl
            project(year:$year, tag:$tag) {
                id
                title
                tag
                start
                end
                year
                publicMdtext
                privateMdtext
                conductors {
                    name
                }
                poster {
                    filename
                    largePath
                }
                events(first:100) {
                    edges {
                        node {
                            id
                            isEnded
                            ${EventItem.getFragment('event')}
                        }
                    }
                }
                files(first:100) {
                    edges {
                        node {
                            id
                            filename
                            created
                            mimetype
                            size
                            permissions {
                                public
                                groups {
                                    id
                                    name
                                }
                                users {
                                    id
                                    name
                                }
                            }
                            tags
                            isImage
                            thumbnailPath
                            path
                        }
                    }
                }
                music {
                    piece {
                        id
                        title
                        composers
                    }
                }
                permissions {
                    public
                    groups {
                        id
                        name
                    }
                    users {
                        id
                        name
                    }
                }
            }
            ${AddEventMutation.getFragment('organization')}
            ${AddFileMutation.getFragment('organization')}
            ${SaveFilePermissionsMutation.getFragment('organization')}
            ${SaveProjectMutation.getFragment('organization')}
            ${SetProjectPosterMutation.getFragment('organization')}
        }`,
    },
});
<|endoftext|>


<commit_before>const exec = require('child_process').exec

const gochan = require('gochan')

const logger = require('./logger.js').get()

const tokens = gochan()

let getFileLogs = function(repo, threads, files) {
    logger.verbose(`getting file logs...`)

    let execGit = (file, index, resolve, reject) => {
        tokens.get((err, token) => {
            logger.verbose(`thread #${token}: started reading file: ${file}`)

            exec(`git --git-dir ${repo}/.git log --follow --oneline -- ${file}`,
            (err, stdout, stderr) => {
                if (err == null && stderr == '') {
                    let count = stdout.trim().split(/\r?\n/).length

                    logger.verbose(`finished reading file: ${count} changes ${file}`)
                    logger.verbose(`file #${index}, thread #${token}\n`)

                    tokens.put(token)

                    resolve({
                        file,
                        count
                    })
                }
                else {
                    tokens.put(token)

                    reject(err)
                }
            })
        })
    }

    for (let i = 0; i < threads; i++) {
        tokens.put(i)
    }

    files = files.map(function(file, index) {
        return new Promise((resolve, reject) => execGit(file, index, resolve, reject))
    })

    logger.verbose(`total files count: ${files.length}`)

    return files
}

module.exports = getFileLogs<commit_msg>added file path parenthesis escaping for getting file log<commit_after>const exec = require('child_process').exec

const gochan = require('gochan')

const logger = require('./logger.js').get()

const tokens = gochan()

let getFileLogs = function(repo, threads, files) {
    logger.verbose(`getting file logs...`)

    let execGit = (file, index, resolve, reject) => {
        tokens.get((err, token) => {
            logger.verbose(`thread #${token}: started reading file: ${file}`)

            exec(`git --git-dir ${repo}/.git log --follow --oneline -- ${file.replace(/(?=[() ])/g, '\\')}`,
            (err, stdout, stderr) => {
                if (err == null && stderr == '') {
                    let count = stdout.trim().split(/\r?\n/).length

                    logger.verbose(`finished reading file: ${count} changes ${file}`)
                    logger.verbose(`file #${index}, thread #${token}\n`)

                    tokens.put(token)

                    resolve({
                        file,
                        count
                    })
                }
                else {
                    tokens.put(token)

                    reject(err)
                }
            })
        })
    }

    for (let i = 0; i < threads; i++) {
        tokens.put(i)
    }

    files = files.map(function(file, index) {
        return new Promise((resolve, reject) => execGit(file, index, resolve, reject))
    })

    logger.verbose(`total files count: ${files.length}`)

    return files
}

module.exports = getFileLogs<|endoftext|>


<commit_before><commit_msg>updated hashtag<commit_after><|endoftext|>


<commit_before>// Dependencies
const React = require('react');
const ReactDOM = require('react-dom');

import builder from 'focus-core/component/builder';

// Mixins

const mdlBehaviour = require('../mixin/mdl-behaviour');

const Progress = {
    mixins: [mdlBehaviour],
    /**
     * Get default props
     * @return {Object} the default props
     */
    getDefaultProps() {
        return {
            completed: 0
        };
    },
    componentDidMount() {
        const bar = ReactDOM.findDOMNode(this.refs.bar);
        if (bar) {
            bar.MaterialProgress.setProgress(0);
            bar.MaterialProgress.setBuffer(100);
        }
    },
    /**
     * Component will receive props
     * @param  {Object} completed new completed prop
     */
    componentWillReceiveProps({completed}) {
        if (0 > completed) {
            completed = 0;
        }
        if (100 < completed) {
            completed = 100;
        }
        const bar = ReactDOM.findDOMNode(this.refs.bar);
        if (bar) {
            bar.MaterialProgress.setProgress(completed);
            bar.MaterialProgress.setBuffer(100);
        }
    },
    /**
     * Render the component
     * @return {Function} the rendered component
     */
    render() {
        let completed = +this.props.completed;
        if (0 > completed) {
            completed = 0;
        }
        if (100 < completed) {
            completed = 100;
        }
        return (

        );
    }
};

module.exports = builder(Progress);
<commit_msg>clean common/progress-bar<commit_after>// Dependencies
import React from 'react';
import ReactDOM from 'react-dom';
import builder from 'focus-core/component/builder';
// Mixins
import mdlBehaviour from '../mixin/mdl-behaviour';

const Progress = {
    mixins: [mdlBehaviour],
    /**
     * Get default props
     * @return {Object} the default props
     */
    getDefaultProps() {
        return {
            completed: 0
        };
    },
    componentDidMount() {
        const bar = ReactDOM.findDOMNode(this.refs.bar);
        if (bar) {
            bar.MaterialProgress.setProgress(0);
            bar.MaterialProgress.setBuffer(100);
        }
    },
    /**
     * Component will receive props
     * @param  {Object} completed new completed prop
     */
    componentWillReceiveProps({ completed }) {
        if (0 > completed) {
            completed = 0;
        }
        if (100 < completed) {
            completed = 100;
        }
        const bar = ReactDOM.findDOMNode(this.refs.bar);
        if (bar) {
            bar.MaterialProgress.setProgress(completed);
            bar.MaterialProgress.setBuffer(100);
        }
    },
    /**
     * Render the component
     * @return {Function} the rendered component
     */
    render() {
        let completed = +this.props.completed;
        if (0 > completed) {
            completed = 0;
        }
        if (100 < completed) {
            completed = 100;
        }
        return (

        );
    }
};

const { mixin, component } = builder(Progress);
export { mixin, component };
export default { mixin, component };
<|endoftext|>


<commit_before>/* global Inputmask formatJS */
/* eslint-disable no-unused-vars */

var DateTimeHelper = (function() {
  function isValidTimeStr(timeStr) {
    return /^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/.test(timeStr);
  }

  function isValidDate(date) {
    return (date instanceof Date) && !isNaN(date.getTime());
  }

  function addLeadingZero(value) {
    return ('0' + value).slice(-2);
  }

  function recalcTimestamp(date, timeStr) {
    if (!isValidTimeStr(timeStr)) {
      date.setHours(0);
      date.setMinutes(0);
      return date;
    }

    date.setHours(timeStr.split(':')[0]);
    date.setMinutes(timeStr.split(':')[1]);
    return date;
  }

  function stringDateTimeFormat(date, format) {
    let y = date.getFullYear();
    let m = addLeadingZero(date.getMonth() + 1);
    let d = addLeadingZero(date.getDate());
    let hours = addLeadingZero(date.getHours());
    let mins = addLeadingZero(date.getMinutes());

    if (format === 'dateonly') {
      return `${y}/${m}/${d}`;
    }
    return `${y}/${m}/${d} ${hours}:${mins}`;
  }

  function insertHiddenField($container) {
    let formId = $container.data('form-id');
    let columnId = $container.data('column-id');
    let dateStr = $container.find('input.date-part').data('selected-date');
    let timeStr = $container.find('input.time-part').val();
    let columnType = $container.data('type');
    let date = new Date(dateStr);
    let value = '';
    let hiddenField;

    if (isValidDate(date) && isValidTimeStr(timeStr)) {
      value = stringDateTimeFormat(recalcTimestamp(date, timeStr), 'full');
    }

    hiddenField = `
      <input class="repository-cell-value"
             type="hidden"
             form="${formId}"
             name="repository_cells[${columnId}]"
             value="${value}"
             data-type="${columnType}"/>`;

    $container.find('input.repository-cell-value').remove();
    $container.prepend(hiddenField);
  }

  function insertRangeHiddenField($container) {
    let formId = $container.data('form-id');
    let columnId = $container.data('column-id');
    let columnType = $container.data('type');
    let $startContainer = $container.find('.start-time');
    let $endContainer = $container.find('.end-time');
    let startDate = new Date($startContainer.find('input.date-part').data('selected-date'));
    let startTimeStr = $startContainer.find('input.time-part').val();
    let endDate = new Date($endContainer.find('input.date-part').data('selected-date'));
    let endTimeStr = $endContainer.find('input.time-part').val();
    let hiddenField;
    let value = '';

    if (isValidDate(startDate)
      && isValidTimeStr(startTimeStr)
      && isValidDate(endDate)
      && isValidTimeStr(endTimeStr)) {
      let start = stringDateTimeFormat(recalcTimestamp(startDate, startTimeStr), 'full');
      let end = stringDateTimeFormat(recalcTimestamp(endDate, endTimeStr), 'full');
      value = JSON.stringify({ start_time: start, end_time: end });
    }

    hiddenField = `
      <input class="repository-cell-value"
             type="hidden"
             form="${formId}"
             name="repository_cells[${columnId}]"
             value='${value}'
             data-type="${columnType}"/>`;

    $container.find('input.repository-cell-value').remove();
    $container.prepend(hiddenField);
  }

  function initChangeEvents($cell) {
    $cell.find('input.time-part').on('change', function() {
      let $input = $(this);
      let $container = $input.closest('.datetime-container');

      if ($container.hasClass('range-type')) {
        insertRangeHiddenField($container);
      } else {
        insertHiddenField($container);
      }
    });

    $cell.find('input.date-part').on('dp.change', function(e) {
      let $input = $(this);
      let date = e.date._d;
      let $container = $input.closest('.datetime-container');

      if (date !== undefined) {
        $input.data('selected-date', stringDateTimeFormat(date, 'dateonly'));
      } else {
        $input.data('selected-date', '');
      }

      if ($container.hasClass('range-type')) {
        insertRangeHiddenField($container);
      } else {
        insertHiddenField($container);
      }
    });
  }

  function dateInputField(value, dateDataValue) {
    return `

        <input class="calendar-input date-part sci-input-field"
                type="datetime"
                placeholder="${formatJS}"
                data-datetime-part="date"
                data-selected-date="${dateDataValue}"
                value='${value}'/>

    `;
  }

  function timeInputField(value) {
    return `

        <input class="time-part sci-input-field"
               type="text"
               data-mask-type="time"
               value='${value}'
               placeholder="HH:mm"/>

    `;
  }

  function getDateOrDefault($span, mode) {
    let dateStr = $span.data('date');
    let date;
    if (mode === 'timeonly') {
      // Set default date if no data in span
      date = new Date(dateStr);
      if (isValidDate(date)) {
        dateStr = stringDateTimeFormat(new Date(date), 'dateonly');
      } else {
        dateStr = stringDateTimeFormat(new Date(), 'dateonly');
      }
    }
    return dateStr;
  }

  function getTimeOrDefault($span, mode) {
    let timeStr = $span.data('time');

    if ((mode === 'dateonly') && (!isValidTimeStr(timeStr))) {
      timeStr = '00:00';
    }
    return timeStr;
  }

  function initCurrentTimeSelector($cell) {
    $cell.find('.time-container .fa-clock').click(function() {
      var inputField = $(this).prev();
      var d = new Date();
      var h = addLeadingZero(d.getHours());
      var m = addLeadingZero(d.getMinutes());
      inputField.val(h + ':' + m);
    });
  }

  function initDateTimeEditMode(formId, columnId, $cell, mode, columnType) {
    let $span = $cell.find('span').first();
    let date = $span.data('date');
    let dateDataValue = getDateOrDefault($span, mode);
    let time = getTimeOrDefault($span, mode);
    let datetime = $span.data('datetime');
    let inputFields = `

      ${dateInputField(date, dateDataValue)}
      ${timeInputField(time)}

  `;

    $cell.html(inputFields);
    initCurrentTimeSelector($cell);

    Inputmask('datetime', {
      inputFormat: 'HH:MM',
      placeholder: 'HH:mm',
      clearIncomplete: true,
      showMaskOnHover: true,
      hourFormat: 24
    }).mask($cell.find('input[data-mask-type="time"]'));

    $cell.find('.calendar-input').datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });
    initChangeEvents($cell);
  }

  function initDateTimeRangeEditMode(formId, columnId, $cell, mode, columnType) {
    let $startSpan = $cell.find('span').first();
    let startDate = $startSpan.data('date');
    let startTime = getTimeOrDefault($startSpan, mode);
    let startDatetime = $startSpan.data('datetime');
    let startDateDataValue = getDateOrDefault($startSpan, mode);
    let $endSpan = $cell.find('span').last();
    let endDate = $endSpan.data('date');
    let endTime = getTimeOrDefault($endSpan, mode);
    let endDatetime = $endSpan.data('datetime');
    let endDateDataValue = getDateOrDefault($endSpan, mode);

    let inputFields = `

        ${dateInputField(startDate, startDateDataValue)}
        ${timeInputField(startTime)}

—

        ${dateInputField(endDate, endDateDataValue)}
        ${timeInputField(endTime)}

  `;

    $cell.html(inputFields);
    initCurrentTimeSelector($cell);

    Inputmask('datetime', {
      inputFormat: 'HH:MM',
      placeholder: 'HH:mm',
      clearIncomplete: true,
      showMaskOnHover: true,
      hourFormat: 24
    }).mask($cell.find('input[data-mask-type="time"]'));

    let $cal1 = $cell.find('.calendar-input').first().datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });
    let $cal2 = $cell.find('.calendar-input').last().datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });

    $cal1.on('dp.change', function(e) {
      $cal2.data('DateTimePicker').minDate(e.date);
    });
    $cal2.on('dp.change', function(e) {
      $cal1.data('DateTimePicker').maxDate(e.date);
    });

    initChangeEvents($cell);
  }

  return {
    initDateTimeEditMode: initDateTimeEditMode,
    initDateTimeRangeEditMode: initDateTimeRangeEditMode
  };
}());
<commit_msg>Update hidden field for time cell<commit_after>/* global Inputmask formatJS */
/* eslint-disable no-unused-vars */

var DateTimeHelper = (function() {
  function isValidTimeStr(timeStr) {
    return /^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/.test(timeStr);
  }

  function isValidDate(date) {
    return (date instanceof Date) && !isNaN(date.getTime());
  }

  function addLeadingZero(value) {
    return ('0' + value).slice(-2);
  }

  function recalcTimestamp(date, timeStr) {
    if (!isValidTimeStr(timeStr)) {
      date.setHours(0);
      date.setMinutes(0);
      return date;
    }

    date.setHours(timeStr.split(':')[0]);
    date.setMinutes(timeStr.split(':')[1]);
    return date;
  }

  function stringDateTimeFormat(date, format) {
    let y = date.getFullYear();
    let m = addLeadingZero(date.getMonth() + 1);
    let d = addLeadingZero(date.getDate());
    let hours = addLeadingZero(date.getHours());
    let mins = addLeadingZero(date.getMinutes());

    if (format === 'dateonly') {
      return `${y}/${m}/${d}`;
    }
    return `${y}/${m}/${d} ${hours}:${mins}`;
  }

  function insertHiddenField($container) {
    let formId = $container.data('form-id');
    let columnId = $container.data('column-id');
    let dateStr = $container.find('input.date-part').data('selected-date');
    let timeStr = $container.find('input.time-part').val();
    let columnType = $container.data('type');
    let date = new Date(dateStr);
    let value = '';
    let hiddenField;

    if (isValidDate(date) && isValidTimeStr(timeStr)) {
      value = stringDateTimeFormat(recalcTimestamp(date, timeStr), 'full');
    }

    hiddenField = `
      <input class="repository-cell-value"
             type="hidden"
             form="${formId}"
             name="repository_cells[${columnId}]"
             value="${value}"
             data-type="${columnType}"/>`;

    $container.find('input.repository-cell-value').remove();
    $container.prepend(hiddenField);
  }

  function insertRangeHiddenField($container) {
    let formId = $container.data('form-id');
    let columnId = $container.data('column-id');
    let columnType = $container.data('type');
    let $startContainer = $container.find('.start-time');
    let $endContainer = $container.find('.end-time');
    let startDate = new Date($startContainer.find('input.date-part').data('selected-date'));
    let startTimeStr = $startContainer.find('input.time-part').val();
    let endDate = new Date($endContainer.find('input.date-part').data('selected-date'));
    let endTimeStr = $endContainer.find('input.time-part').val();
    let hiddenField;
    let value = '';

    if (isValidDate(startDate)
      && isValidTimeStr(startTimeStr)
      && isValidDate(endDate)
      && isValidTimeStr(endTimeStr)) {
      let start = stringDateTimeFormat(recalcTimestamp(startDate, startTimeStr), 'full');
      let end = stringDateTimeFormat(recalcTimestamp(endDate, endTimeStr), 'full');
      value = JSON.stringify({ start_time: start, end_time: end });
    }

    hiddenField = `
      <input class="repository-cell-value"
             type="hidden"
             form="${formId}"
             name="repository_cells[${columnId}]"
             value='${value}'
             data-type="${columnType}"/>`;

    $container.find('input.repository-cell-value').remove();
    $container.prepend(hiddenField);
  }

  function initChangeEvents($cell) {
    $cell.find('input.time-part').on('change', function() {
      let $input = $(this);
      let $container = $input.closest('.datetime-container');

      if ($container.hasClass('range-type')) {
        insertRangeHiddenField($container);
      } else {
        insertHiddenField($container);
      }
    });

    $cell.find('input.date-part').on('dp.change', function(e) {
      let $input = $(this);
      let date = e.date._d;
      let $container = $input.closest('.datetime-container');

      if (date !== undefined) {
        $input.data('selected-date', stringDateTimeFormat(date, 'dateonly'));
      } else {
        $input.data('selected-date', '');
      }

      if ($container.hasClass('range-type')) {
        insertRangeHiddenField($container);
      } else {
        insertHiddenField($container);
      }
    });
  }

  function dateInputField(value, dateDataValue) {
    return `

        <input class="calendar-input date-part sci-input-field"
                type="datetime"
                placeholder="${formatJS}"
                data-datetime-part="date"
                data-selected-date="${dateDataValue}"
                value='${value}'/>

    `;
  }

  function timeInputField(value) {
    return `

        <input class="time-part sci-input-field"
               type="text"
               data-mask-type="time"
               value='${value}'
               placeholder="HH:mm"/>

    `;
  }

  function getDateOrDefault($span, mode) {
    let dateStr = $span.data('date');
    let date;
    if (mode === 'timeonly') {
      // Set default date if no data in span
      date = new Date(dateStr);
      if (isValidDate(date)) {
        dateStr = stringDateTimeFormat(new Date(date), 'dateonly');
      } else {
        dateStr = stringDateTimeFormat(new Date(), 'dateonly');
      }
    }
    return dateStr;
  }

  function getTimeOrDefault($span, mode) {
    let timeStr = $span.data('time');

    if ((mode === 'dateonly') && (!isValidTimeStr(timeStr))) {
      timeStr = '00:00';
    }
    return timeStr;
  }

  function initCurrentTimeSelector($cell) {
    $cell.find('.time-container .fa-clock').click(function() {
      var inputField = $(this).prev();
      var d = new Date();
      var h = addLeadingZero(d.getHours());
      var m = addLeadingZero(d.getMinutes());
      inputField.val(h + ':' + m).change();
    });
  }

  function initDateTimeEditMode(formId, columnId, $cell, mode, columnType) {
    let $span = $cell.find('span').first();
    let date = $span.data('date');
    let dateDataValue = getDateOrDefault($span, mode);
    let time = getTimeOrDefault($span, mode);
    let datetime = $span.data('datetime');
    let inputFields = `

      ${dateInputField(date, dateDataValue)}
      ${timeInputField(time)}

  `;

    $cell.html(inputFields);
    initCurrentTimeSelector($cell);

    Inputmask('datetime', {
      inputFormat: 'HH:MM',
      placeholder: 'HH:mm',
      clearIncomplete: true,
      showMaskOnHover: true,
      hourFormat: 24
    }).mask($cell.find('input[data-mask-type="time"]'));

    $cell.find('.calendar-input').datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });
    initChangeEvents($cell);
  }

  function initDateTimeRangeEditMode(formId, columnId, $cell, mode, columnType) {
    let $startSpan = $cell.find('span').first();
    let startDate = $startSpan.data('date');
    let startTime = getTimeOrDefault($startSpan, mode);
    let startDatetime = $startSpan.data('datetime');
    let startDateDataValue = getDateOrDefault($startSpan, mode);
    let $endSpan = $cell.find('span').last();
    let endDate = $endSpan.data('date');
    let endTime = getTimeOrDefault($endSpan, mode);
    let endDatetime = $endSpan.data('datetime');
    let endDateDataValue = getDateOrDefault($endSpan, mode);

    let inputFields = `

        ${dateInputField(startDate, startDateDataValue)}
        ${timeInputField(startTime)}

—

        ${dateInputField(endDate, endDateDataValue)}
        ${timeInputField(endTime)}

  `;

    $cell.html(inputFields);
    initCurrentTimeSelector($cell);

    Inputmask('datetime', {
      inputFormat: 'HH:MM',
      placeholder: 'HH:mm',
      clearIncomplete: true,
      showMaskOnHover: true,
      hourFormat: 24
    }).mask($cell.find('input[data-mask-type="time"]'));

    let $cal1 = $cell.find('.calendar-input').first().datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });
    let $cal2 = $cell.find('.calendar-input').last().datetimepicker({ ignoreReadonly: true, locale: 'en', format: formatJS });

    $cal1.on('dp.change', function(e) {
      $cal2.data('DateTimePicker').minDate(e.date);
    });
    $cal2.on('dp.change', function(e) {
      $cal1.data('DateTimePicker').maxDate(e.date);
    });

    initChangeEvents($cell);
  }

  return {
    initDateTimeEditMode: initDateTimeEditMode,
    initDateTimeRangeEditMode: initDateTimeRangeEditMode
  };
}());
<|endoftext|>


<commit_before>/**
 * @file atob polyfill
 */
/*#ifndef(UMD)*/
"use strict";
/*global _gpfBase64*/
/*exported _gpfAtob*/ // atob polyfill
/*#endif*/

var _gpfRegExpBase64 = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/;

function _gpfAtobCheckInput (encodedData) {
    var string = encodedData.replace(/[\t\n\f\r ]+/g, "");
    if (!_gpfRegExpBase64.test(string)) {
        throw new TypeError("The string to be decoded is not correctly encoded.");
    }
    return string;
}

function _gpfAtob (encodedData) {
    var string = _gpfAtobCheckInput(encodedData);
    string += "==".slice(2 - (string.length & 3));
    var bitmap, result = "", r1, r2, i = 0;
    for (; i < string.length;) {
        bitmap = _gpfBase64.indexOf(string.charAt(i++)) << 18 | _gpfBase64.indexOf(string.charAt(i++)) << 12
                 | (r1 = _gpfBase64.indexOf(string.charAt(i++))) << 6 | (r2 = _gpfBase64.indexOf(string.charAt(i++)));

        result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255)
            : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255)
                : String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255);
    }
    return result;
}

/*#ifndef(UMD)*/

gpf.internals._gpfAtob = _gpfAtob;

/*#endif*/
<commit_msg>Improves code quality (#240)<commit_after>/**
 * @file atob polyfill
 */
/*#ifndef(UMD)*/
"use strict";
/*global _gpfBase64*/
/*global _gpfMaxUnsignedByte*/
/*exported _gpfAtob*/ // atob polyfill
/*#endif*/

var _gpfRegExpBase64 = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/,
    _GPF_6_BITS = 6,
    _GPF_12_BITS = 12,
    _GPF_18_BITS = 18,
    _GPF_1_BYTE = 8,
    _GPF_2_BYTES = 16,
    _GPF_PADDING = 64;

function _gpfAtobCheckInput (encodedData) {
    var string = encodedData.replace(/[\t\n\f\r ]+/g, "");
    if (!_gpfRegExpBase64.test(string)) {
        throw new TypeError("The string to be decoded is not correctly encoded.");
    }
    return string;
}

function _gpfAtobDecodeWithR2 (bitmap, r2) {
    if (r2 === _GPF_PADDING) {
        return String.fromCharCode(bitmap >> _GPF_1_BYTE & _gpfMaxUnsignedByte);
    }
    return String.fromCharCode(bitmap >> _GPF_1_BYTE & _gpfMaxUnsignedByte, bitmap & _gpfMaxUnsignedByte);
}

function _gpfAtobDecode (bitmap, r1, r2) {
    var result = String.fromCharCode(bitmap >> _GPF_2_BYTES & _gpfMaxUnsignedByte);
    if (r1 !== _GPF_PADDING) {
        return result + _gpfAtobDecodeWithR2(bitmap, r2);
    }
    return result;
}

function _gpfAtob (encodedData) {
    var input = _gpfAtobCheckInput(encodedData),
        length = input.length,
        index = 0,
        result = "",
        bitmap,
        r1,
        r2;
    input += "=="; // Pad leading bytes
    for (; index < length;) {
        bitmap = _gpfBase64.indexOf(input.charAt(index++)) << _GPF_18_BITS
                 | _gpfBase64.indexOf(input.charAt(index++)) << _GPF_12_BITS;
        r1 = _gpfBase64.indexOf(input.charAt(index++));
        r2 = _gpfBase64.indexOf(input.charAt(index++));
        bitmap |= r1 << _GPF_6_BITS | r2;
        result += _gpfAtobDecode(bitmap, r1, r2);
    }
    return result;
}

/*#ifndef(UMD)*/

gpf.internals._gpfAtob = _gpfAtob;

/*#endif*/
<|endoftext|>