<commit_before>
window.variant.phenos = _.sortBy(window.variant.phenos, function(d) { return Number.parseFloat(d.phewas_code); });

var first_of_each_category = (function() {
    var categories_seen = {};
    return window.variant.phenos.filter(function(pheno) {
        if (categories_seen.hasOwnProperty(pheno.category_name)) {
            return false;
        } else {
            categories_seen[pheno.category_name] = 1;
            return true;
        }
    });
})();

var category_order = (function() {
    var rv = {};
    first_of_each_category.forEach(function(pheno, i) {
        rv[pheno.category_name] = i;
    });
    return rv;
})();

// sortBy is a stable sort, so we just sort by category_order and we're good.
window.variant.phenos = _.sortBy(window.variant.phenos, function(d) {
    return category_order[d.category_name];
});

function create_phewas_plot() {
    var svg_width = $('#phewas_plot_container').width();
    var svg_height = 550;

    var plot_margin = {
        'left': 70,
        'right': 30,
        'top': 10,
        'bottom': 170,
    };

    var plot_width = svg_width - plot_margin.left - plot_margin.right;
    var plot_height = svg_height - plot_margin.top - plot_margin.bottom;

    var x_scale = d3.scale.linear()
        .domain([0, window.variant.phenos.length])
        .range([0, plot_width]);

    var neglog10_min_pval = -Math.log10(d3.min(window.variant.phenos, function(d) {
        return d.pval;
    }));
    var y_scale = d3.scale.linear()
        .domain([neglog10_min_pval, 0])
        .range([0, plot_height]);

    var unique_categories = d3.set(window.variant.phenos.map(function(cat) {
        return cat.category_name;
    })).values();
    var color_by_category = d3.scale.category20()
        .domain(unique_categories);

    var phewas_svg = d3.select('#phewas_plot_container').append("svg")
        .attr('id', 'phewas_svg')
        .attr("width", svg_width)
        .attr("height", svg_height)
        .style("display", "block")
        .style("margin", "auto");
    var phewas_plot = phewas_svg.append("g")
        .attr('id', 'phewas_plot')
        .attr("transform", fmt("translate({0},{1})", plot_margin.left, plot_margin.top));

    // Significance Threshold line
    var significance_threshold = 3e-5;
    var significance_threshold_tooltip = d3.tip()
        .attr('class', 'd3-tip')
        .html(function(d) {
            return 'Significance Threshold: 3E-5';
        })
        .offset([-8,0]);
    phewas_svg.call(significance_threshold_tooltip);

    phewas_plot.append('line')
        .attr('x1', 0)
        .attr('x2', plot_width)
        .attr('y1', y_scale(-Math.log10(significance_threshold)))
        .attr('y2', y_scale(-Math.log10(significance_threshold)))
        .attr('stroke-width', '5px')
        .attr('stroke', 'lightgray')
        .attr('stroke-dasharray', '10,10')
        .on('mouseover', significance_threshold_tooltip.show)
        .on('mouseout', significance_threshold_tooltip.hide);

    // Points & labels
    var tooltip_template = _.template($('#tooltip-template').html());
    var point_tooltip = d3.tip()
        .attr('class', 'd3-tip')
        .html(function(d) {
            return tooltip_template({d: d, color_by_category: color_by_category});
        })
        .offset([-8,0]);
    phewas_svg.call(point_tooltip);

    var links = phewas_plot.selectAll('a.pheno_point')
        .data(window.variant.phenos)
        .enter()
        .append('a')
        .attr('class', 'pheno_point')
        .attr('xlink:href', function(d) {
            return '/pheno/' + d.phewas_code;
        })
        .each(function(d, i) {
            d.myIndex = i;
        });
    links.append('circle')
        .attr('cx', function(d) {
            return x_scale(d.myIndex);
        })
        .attr('cy', function(d) {
            return y_scale(-Math.log10(d.pval));
        })
        .attr('r', 5)
        .style('fill', function(d) {
            return color_by_category(d.category_name);
        })
        .style('fill-opacity', 0.5)
        .style('stroke-width', 1)
        .style('stroke', function(d) {
            return color_by_category(d.category_name);
        })
        .on('mouseover', function(d) {
            //Note: once a tooltip has been explicitly placed once, it must be explicitly placed forever after.
            point_tooltip.show(d, this);
            // console.log(fmt('{0} {1}', x_scale(d.myIndex), y_scale(-Math.log10(d.pval))), this);
        })
        .on('mouseout', point_tooltip.hide);
    links
        .each(function(d) {
            d.myCircle = this.firstChild;
        })
        .filter(function(d) {
            return d.pval < significance_threshold;
        })
        .append('text')
        .style('text-anchor', 'start')
        .attr('x', function(d) {
            return x_scale(d.myIndex) + 10;
        })
        .attr('y', function(d) {
            return y_scale(-Math.log10(d.pval));
        })
        .attr('dy', '.3em') // vertically center
        .text(function(d) {
            if (d.phewas_string.length < 30) {
                return d.phewas_string;
            } else {
                // Try to cut the string at a space.
                var break_index = d.phewas_string.slice(20, 30).indexOf(' ');
                break_index = (break_index === -1) ? 25 : 20 + break_index;
                return d.phewas_string.slice(0, break_index).trim() + '...';
            }
        })
        .on('mouseover', function(d) {
            point_tooltip.show(d, d.myCircle);
        })
        .on('mouseout', point_tooltip.hide);

    // Axes
    var yAxis = d3.svg.axis()
        .scale(y_scale)
        .orient("left")
        .tickFormat(d3.format("d"));
    phewas_plot.append("g")
        .attr("class", "y axis")
        .attr('transform', 'translate(-3,0)') // avoid letting points spill through the y axis.
        .call(yAxis);

    phewas_svg.append('text')
        .style('text-anchor', 'middle')
        .attr('transform', fmt('translate({0},{1})rotate(-90)',
                               plot_margin.left*.4,
                               plot_height/2 + plot_margin.top))
        .text('-log10(pvalue)');

    var xAxis = d3.svg.axis()
        .scale(x_scale)
        .orient("bottom")
        .ticks(0);
    phewas_plot.append("g")
        .attr("class", "x axis")
        .attr("transform", fmt("translate(0,{0})", plot_height))
        .call(xAxis);

    phewas_svg.selectAll('text.category_name')
        .data(first_of_each_category)
        .enter() // Do we need this?
        .append('text')
        .style('text-anchor', 'start')
        .attr('transform', function(d) {
            return fmt('translate({0},{1})rotate(50)',
                       plot_margin.left + x_scale(d.myIndex) + 3,
                       plot_height + plot_margin.top + 15);
        })
        .text(function(d) {
            return d.category_name;
        })
        .style('fill', function(d) {
            return color_by_category(d.category_name);
        });

}

$(create_phewas_plot);

function fmt(format) {
    var args = Array.prototype.slice.call(arguments, 1);
    return format.replace(/{(\d+)}/g, function(match, number) {
        return (typeof args[number] != 'undefined') ? args[number] : match;
    });
}
<commit_msg>Indent variant.js<commit_after>(function() { // Create PheWAS plot.

    window.variant.phenos = _.sortBy(window.variant.phenos, function(d) { return Number.parseFloat(d.phewas_code); });

    var first_of_each_category = (function() {
        var categories_seen = {};
        return window.variant.phenos.filter(function(pheno) {
            if (categories_seen.hasOwnProperty(pheno.category_name)) {
                return false;
            } else {
                categories_seen[pheno.category_name] = 1;
                return true;
            }
        });
    })();

    var category_order = (function() {
        var rv = {};
        first_of_each_category.forEach(function(pheno, i) {
            rv[pheno.category_name] = i;
        });
        return rv;
    })();

    // sortBy is a stable sort, so we just sort by category_order and we're good.
    window.variant.phenos = _.sortBy(window.variant.phenos, function(d) {
        return category_order[d.category_name];
    });

    $(function() {
        var svg_width = $('#phewas_plot_container').width();
        var svg_height = 550;

        var plot_margin = {
            'left': 70,
            'right': 30,
            'top': 10,
            'bottom': 170,
        };

        var plot_width = svg_width - plot_margin.left - plot_margin.right;
        var plot_height = svg_height - plot_margin.top - plot_margin.bottom;

        var x_scale = d3.scale.linear()
            .domain([0, window.variant.phenos.length])
            .range([0, plot_width]);

        var neglog10_min_pval = -Math.log10(d3.min(window.variant.phenos, function(d) {
            return d.pval;
        }));
        var y_scale = d3.scale.linear()
            .domain([neglog10_min_pval, 0])
            .range([0, plot_height]);

        var unique_categories = d3.set(window.variant.phenos.map(function(cat) {
            return cat.category_name;
        })).values();
        var color_by_category = d3.scale.category20()
            .domain(unique_categories);

        var phewas_svg = d3.select('#phewas_plot_container').append("svg")
            .attr('id', 'phewas_svg')
            .attr("width", svg_width)
            .attr("height", svg_height)
            .style("display", "block")
            .style("margin", "auto");
        var phewas_plot = phewas_svg.append("g")
            .attr('id', 'phewas_plot')
            .attr("transform", fmt("translate({0},{1})", plot_margin.left, plot_margin.top));

        // Significance Threshold line
        var significance_threshold = 3e-5;
        var significance_threshold_tooltip = d3.tip()
            .attr('class', 'd3-tip')
            .html(function(d) {
                return 'Significance Threshold: 3E-5';
            })
            .offset([-8,0]);
        phewas_svg.call(significance_threshold_tooltip);

        phewas_plot.append('line')
            .attr('x1', 0)
            .attr('x2', plot_width)
            .attr('y1', y_scale(-Math.log10(significance_threshold)))
            .attr('y2', y_scale(-Math.log10(significance_threshold)))
            .attr('stroke-width', '5px')
            .attr('stroke', 'lightgray')
            .attr('stroke-dasharray', '10,10')
            .on('mouseover', significance_threshold_tooltip.show)
            .on('mouseout', significance_threshold_tooltip.hide);

        // Points & labels
        var tooltip_template = _.template($('#tooltip-template').html());
        var point_tooltip = d3.tip()
            .attr('class', 'd3-tip')
            .html(function(d) {
                return tooltip_template({d: d, color_by_category: color_by_category});
            })
            .offset([-8,0]);
        phewas_svg.call(point_tooltip);

        var links = phewas_plot.selectAll('a.pheno_point')
            .data(window.variant.phenos)
            .enter()
            .append('a')
            .attr('class', 'pheno_point')
            .attr('xlink:href', function(d) {
                return '/pheno/' + d.phewas_code;
            })
            .each(function(d, i) {
                d.myIndex = i;
            });
        links.append('circle')
            .attr('cx', function(d) {
                return x_scale(d.myIndex);
            })
            .attr('cy', function(d) {
                return y_scale(-Math.log10(d.pval));
            })
            .attr('r', 5)
            .style('fill', function(d) {
                return color_by_category(d.category_name);
            })
            .style('fill-opacity', 0.5)
            .style('stroke-width', 1)
            .style('stroke', function(d) {
                return color_by_category(d.category_name);
            })
            .on('mouseover', function(d) {
                //Note: once a tooltip has been explicitly placed once, it must be explicitly placed forever after.
                point_tooltip.show(d, this);
                // console.log(fmt('{0} {1}', x_scale(d.myIndex), y_scale(-Math.log10(d.pval))), this);
            })
            .on('mouseout', point_tooltip.hide);
        links
            .each(function(d) {
                d.myCircle = this.firstChild;
            })
            .filter(function(d) {
                return d.pval < significance_threshold;
            })
            .append('text')
            .style('text-anchor', 'start')
            .attr('x', function(d) {
                return x_scale(d.myIndex) + 10;
            })
            .attr('y', function(d) {
                return y_scale(-Math.log10(d.pval));
            })
            .attr('dy', '.3em') // vertically center
            .text(function(d) {
                if (d.phewas_string.length < 30) {
                    return d.phewas_string;
                } else {
                    // Try to cut the string at a space.
                    var break_index = d.phewas_string.slice(20, 30).indexOf(' ');
                    break_index = (break_index === -1) ? 25 : 20 + break_index;
                    return d.phewas_string.slice(0, break_index).trim() + '...';
                }
            })
            .on('mouseover', function(d) {
                point_tooltip.show(d, d.myCircle);
            })
            .on('mouseout', point_tooltip.hide);

        // Axes
        var yAxis = d3.svg.axis()
            .scale(y_scale)
            .orient("left")
            .tickFormat(d3.format("d"));
        phewas_plot.append("g")
            .attr("class", "y axis")
            .attr('transform', 'translate(-3,0)') // avoid letting points spill through the y axis.
            .call(yAxis);

        phewas_svg.append('text')
            .style('text-anchor', 'middle')
            .attr('transform', fmt('translate({0},{1})rotate(-90)',
                                   plot_margin.left*.4,
                                   plot_height/2 + plot_margin.top))
            .text('-log10(pvalue)');

        var xAxis = d3.svg.axis()
            .scale(x_scale)
            .orient("bottom")
            .ticks(0);
        phewas_plot.append("g")
            .attr("class", "x axis")
            .attr("transform", fmt("translate(0,{0})", plot_height))
            .call(xAxis);

        phewas_svg.selectAll('text.category_name')
            .data(first_of_each_category)
            .enter() // Do we need this?
            .append('text')
            .style('text-anchor', 'start')
            .attr('transform', function(d) {
                return fmt('translate({0},{1})rotate(50)',
                           plot_margin.left + x_scale(d.myIndex) + 3,
                           plot_height + plot_margin.top + 15);
            })
            .text(function(d) {
                return d.category_name;
            })
            .style('fill', function(d) {
                return color_by_category(d.category_name);
            });

    });
})();

function fmt(format) {
    var args = Array.prototype.slice.call(arguments, 1);
    return format.replace(/{(\d+)}/g, function(match, number) {
        return (typeof args[number] != 'undefined') ? args[number] : match;
    });
}
<|endoftext|>


<commit_before>// Copyright 2018-2019, University of Colorado Boulder
/* eslint-disable bad-text */

/**
 * Lint detector for invalid text.
 * Lint is disabled for this file so the bad texts aren't themselves flagged.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */

'use strict';

module.exports = function( context ) {

  const getBadTextTester = require( './getBadTextTester' );

  // see getBadTextTester for schema
  const forbiddenTextObjects = [

    // Proper casing for *boxes

    // toolbox is one word
    'toolBox', // prefer toolbox
    'ToolBox', // prefer Toolbox
    'TOOL_BOX', // prefer TOOLBOX

    // checkbox is one word
    'checkBox', // prefer checkbox
    'CheckBox', // prefer Checkbox
    'CHECK_BOX', // prefer CHECKBOX

    // combo box is two words
    'combobox', // prefer combo box
    'Combobox', // prefer Combo Box
    'COMBOBOX', // prefer COMBO_BOX

    'Overriden', // should have 2 "d"s
    'overriden', // should have 2 "d"s

    'iFrame', // should be iframe

    // event.keyCode according to spec, rather than event.keycode
    'keycode',

    // prefer hotkey (one word)
    'hot key',
    'hotKey',
    'HotKey',

    // In ES6, extending object causes methods to be dropped
    { id: 'extends Object ', codeTokens: [ 'extends', 'Object' ] },

    // Forbid common duplicate words
    ' the the ',
    ' a a ',
    'dipose', // happens more than you'd think

    // For phet-io use PHET_IO in constants
    'PHETIO',
    'PHET-IO',
    'Phet-iO',
    ' Phet ',
    'phetio element', // use "phet-io element" or "PhET-iO element"
    'Phet-iO',
    { id: 'IO type', regex: /\bIO type/ }, // https://github.com/phetsims/chipper/issues/977

    '@return ',

    'Util = require( \'', // Utils should now be plural, see https://github.com/phetsims/tasks/issues/966

    // if on a one line arrow function returning something, prefer instead `() => theReturn`, see https://github.com/phetsims/chipper/issues/790
    ' => { return ',

    'define( function( require ) {', // use define( require => { to standardize before es6 module migration

    // optional 'options' should use brackets and required 'config' shouldn't use brackets, see https://github.com/phetsims/chipper/issues/859
    '@param {Object} options',
    '@param {Object} [config]',

    // PhET prefers to use the term "position" to refer to the physical (x,y) position of objects.
    // The lint rule can be disabled for occurrences where we do prefer locationProperty, for instance if we
    // had a sim about people that are from three different named locations.
    'locationProperty',

    {
      id: 'Import from statements require a *.js suffix',
      predicate: line => {
        if ( line.trim().indexOf( 'import ' ) === 0 && line.indexOf( ' from ' ) > 0 && line.indexOf( '.js' ) === -1 ) {
          return false;
        }
        return true;
      }
    },

    {
      id: 'Import statements require a *.js suffix',
      predicate: line => {
        if ( line.trim().indexOf( 'import \'' ) === 0 && line.indexOf( ';' ) >= 0 && line.indexOf( '.js' ) === -1 ) {
          return false;
        }
        return true;
      }
    },

    {
      id: 'Export statements should not have a register call',
      predicate: line => {
        if ( line.trim().indexOf( 'export default' ) === 0 && line.indexOf( '.register(' ) >= 0 ) {
          return false;
        }
        return true;
      }
    }
  ];

  return {
    Program: getBadTextTester( forbiddenTextObjects, context )
  };
};

module.exports.schema = [
  // JSON Schema for rule options goes here
];<commit_msg>hotkey (one word) instead of hot key, and add to bad-text.js, see https://github.com/phetsims/scenery/issues/1242<commit_after>// Copyright 2018-2019, University of Colorado Boulder
/* eslint-disable bad-text */

/**
 * Lint detector for invalid text.
 * Lint is disabled for this file so the bad texts aren't themselves flagged.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */

'use strict';

module.exports = function( context ) {

  const getBadTextTester = require( './getBadTextTester' );

  // see getBadTextTester for schema
  const forbiddenTextObjects = [

    // Proper casing for *boxes

    // toolbox is one word
    'toolBox', // prefer toolbox
    'ToolBox', // prefer Toolbox
    'TOOL_BOX', // prefer TOOLBOX

    // checkbox is one word
    'checkBox', // prefer checkbox
    'CheckBox', // prefer Checkbox
    'CHECK_BOX', // prefer CHECKBOX

    // combo box is two words
    'combobox', // prefer combo box
    'Combobox', // prefer Combo Box
    'COMBOBOX', // prefer COMBO_BOX

    'Overriden', // should have 2 "d"s
    'overriden', // should have 2 "d"s

    'iFrame', // should be iframe

    // event.keyCode according to spec, rather than event.keycode
    'keycode',

    // prefer hotkey (one word)
    'hot key',
    'hotKey',
    'HotKey',
    'HOT_KEY',

    // In ES6, extending object causes methods to be dropped
    { id: 'extends Object ', codeTokens: [ 'extends', 'Object' ] },

    // Forbid common duplicate words
    ' the the ',
    ' a a ',
    'dipose', // happens more than you'd think

    // For phet-io use PHET_IO in constants
    'PHETIO',
    'PHET-IO',
    'Phet-iO',
    ' Phet ',
    'phetio element', // use "phet-io element" or "PhET-iO element"
    'Phet-iO',
    { id: 'IO type', regex: /\bIO type/ }, // https://github.com/phetsims/chipper/issues/977

    '@return ',

    'Util = require( \'', // Utils should now be plural, see https://github.com/phetsims/tasks/issues/966

    // if on a one line arrow function returning something, prefer instead `() => theReturn`, see https://github.com/phetsims/chipper/issues/790
    ' => { return ',

    'define( function( require ) {', // use define( require => { to standardize before es6 module migration

    // optional 'options' should use brackets and required 'config' shouldn't use brackets, see https://github.com/phetsims/chipper/issues/859
    '@param {Object} options',
    '@param {Object} [config]',

    // PhET prefers to use the term "position" to refer to the physical (x,y) position of objects.
    // The lint rule can be disabled for occurrences where we do prefer locationProperty, for instance if we
    // had a sim about people that are from three different named locations.
    'locationProperty',

    {
      id: 'Import from statements require a *.js suffix',
      predicate: line => {
        if ( line.trim().indexOf( 'import ' ) === 0 && line.indexOf( ' from ' ) > 0 && line.indexOf( '.js' ) === -1 ) {
          return false;
        }
        return true;
      }
    },

    {
      id: 'Import statements require a *.js suffix',
      predicate: line => {
        if ( line.trim().indexOf( 'import \'' ) === 0 && line.indexOf( ';' ) >= 0 && line.indexOf( '.js' ) === -1 ) {
          return false;
        }
        return true;
      }
    },

    {
      id: 'Export statements should not have a register call',
      predicate: line => {
        if ( line.trim().indexOf( 'export default' ) === 0 && line.indexOf( '.register(' ) >= 0 ) {
          return false;
        }
        return true;
      }
    }
  ];

  return {
    Program: getBadTextTester( forbiddenTextObjects, context )
  };
};

module.exports.schema = [
  // JSON Schema for rule options goes here
];<|endoftext|>


<commit_before>/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global define */

define(function (require, exports, module) {
    "use strict";

    var FileSystemError = require("filesystem/FileSystemError"),
        FileSystemStats = require("filesystem/FileSystemStats"),
        Filer           = require("filesystem/impls/filer/BracketsFiler"),
        Dialog          = require("thirdparty/filer-dialogs/filer-dialogs"),
        BlobUtils       = require("filesystem/impls/filer/BlobUtils"),
        Handlers        = require("filesystem/impls/filer/lib/handlers");

    var fs              = Filer.fs(),
        Path            = Filer.Path,
        watchers        = {};

    var _changeCallback;            // Callback to notify FileSystem of watcher changes

    function showOpenDialog(allowMultipleSelection, chooseDirectories, title, initialPath, fileTypes, callback) {
        Dialog.showOpenDialog.apply(null, arguments);
    }

    function showSaveDialog(title, initialPath, defaultName, callback) {
        Dialog.showSaveAsDialog.apply(null, arguments);
    }

    /**
     * Convert Filer error codes to FileSystemError values.
     *
     * @param {?Object} err A Filer error code or Brackets error string
     * @return {?string} A FileSystemError string, or null if there was no error code.
     * @private
     **/
    function _mapError(err) {
        if (!err) {
            return null;
        }

        // If we get a raw Brackets error string passed through,
        // we don't need to map anything, and can just use it directly.
        if (typeof err === "string") {
            return err;
        }

        // Otherwise it's a Filer error, try and use err.code
        switch (err.code) {
        case 'EINVAL':
            return FileSystemError.INVALID_PARAMS;
        case 'ENOENT':
            return FileSystemError.NOT_FOUND;
        case 'EROFS':
            return FileSystemError.NOT_WRITABLE;
        case 'ENOSPC':
            return FileSystemError.OUT_OF_SPACE;
        case 'ENOTEMPTY':
        case 'EEXIST':
            return FileSystemError.ALREADY_EXISTS;
        case 'ENOTDIR':
            return FileSystemError.INVALID_PARAMS;
        case 'EBADF':
            return FileSystemError.NOT_READABLE;
        }

        // We don't know what this is, log it. We likely need a new case above.
        console.log('[Brackets Filesystem] Unknown I/O error', err);
        return FileSystemError.UNKNOWN;
    }

    /**
     * Convert a callback to one that transforms its first parameter from a
     * Filer error code to a FileSystemError string.
     *
     * @param {function(?number)} cb A callback that expects an Filer error code
     * @return {function(?string)} A callback that expects a FileSystemError string
     * @private
     **/
    function _wrap(cb) {
        return function (err) {
            var args = Array.prototype.slice.call(arguments);
            args[0] = _mapError(args[0]);
            cb.apply(null, args);
        };
    }

    function stat(path, callback) {
        fs.stat(path, function(err, stats) {
            if (err){
                callback(_mapError(err));
                return;
            }

            var mtime = new Date(stats.mtime);

            var options = {
                isFile: stats.isFile(),
                mtime: mtime,
                size: stats.size,
                // TODO: figure out how to deal with realPath
                realPath: path,
                hash: mtime.getTime()
            };

            var fsStats = new FileSystemStats(options);

            callback(null, fsStats);
        });
    }

    function exists(path, callback) {
        fs.exists(path, function(exists) {
            callback(null, exists);
        });
    }

    function readdir(path, callback) {
        path = Path.normalize(path);

        fs.readdir(path, function (err, contents) {
            if (err) {
                callback(_mapError(err));
                return;
            }

            var count = contents.length;
            if (!count) {
                callback(null, [], []);
                return;
            }

            var stats = [];
            contents.forEach(function (val, idx) {
                stat(Path.join(path, val), function (err, stat) {
                    stats[idx] = err || stat;
                    count--;
                    if (count <= 0) {
                        callback(null, contents, stats);
                    }
                });
            });
        });
    }

    function mkdir(path, mode, callback) {
        if(typeof mode === 'function') {
            callback = mode;
        }

        fs.mkdir(path, mode, function (err) {
            if (err) {
                callback(_mapError(err));
                return;
            }
            stat(path, callback);
        });
    }

    function rename(oldPath, newPath, callback) {
        function updateBlobURL(err) {
            if(err) {
                return callback(_mapError(err));
            }

            // If this was a rename on a file path, update the Blob cache too
            stat(newPath, function(err, stat) {
                if(err) {
                    return callback(_mapError(err));
                }

                if(stat.isFile) {
                    BlobUtils.rename(oldPath, newPath);
                }

                callback();
            });
        }

        fs.rename(oldPath, newPath, _wrap(updateBlobURL));
    }

    function readFile(path, options, callback) {
        if(typeof options === 'function') {
            callback = options;
        }
        options = options || {};

        var encoding = options.encoding || "utf8";

        // Execute the read and stat calls in parallel. Callback early if the
        // read call completes first with an error; otherwise wait for both
        // to finish.
        var done = false, data, stat, err;

        if (options.stat) {
            done = true;
            stat = options.stat;
        } else {
            exports.stat(path, function (_err, _stat) {
                if (done) {
                    callback(_err, _err ? null : data, _stat);
                } else {
                    done = true;
                    stat = _stat;
                    err = _err;
                }
            });
        }

        fs.readFile(path, encoding, function (_err, _data) {
            if (_err) {
                callback(_mapError(_err));
                return;
            }

            if (done) {
                callback(err, err ? null : _data, stat);
            } else {
                done = true;
                data = _data;
            }
        });
    }

    function writeFile(path, data, options, callback) {
        if(typeof options === 'function') {
            callback = options;
        }
        options = options || {};

        var encoding = options.encoding || "utf8";

        function _finishWrite(created) {
            fs.writeFile(path, data, encoding, function (err) {
                if (err) {
                    callback(_mapError(err));
                    return;
                }

                // Cache a Blob URL for the file
                Handlers.handleFile(path, data);

                stat(path, function (err, stat) {
                    callback(_mapError(err), stat, created);
                });
            });
        }

        stat(path, function (err, stats) {
            if (err) {
                switch (err) {
                case FileSystemError.NOT_FOUND:
                    _finishWrite(true);
                    break;
                default:
                    callback(err);
                }
                return;
            }

            if (options.hasOwnProperty("expectedHash") && options.expectedHash !== stats._hash) {
                console.error("Blind write attempted: ", path, stats._hash, options.expectedHash);

                if (options.hasOwnProperty("expectedContents")) {
                    fs.readFile(path, encoding, function (_err, _data) {
                        if (_err || _data !== options.expectedContents) {
                            callback(FileSystemError.CONTENTS_MODIFIED);
                            return;
                        }

                        _finishWrite(false);
                    });
                    return;
                } else {
                    callback(FileSystemError.CONTENTS_MODIFIED);
                    return;
                }
            }

            _finishWrite(false);
        });
    }

    function unlink(path, callback) {
        fs.unlink(path, function(err){
            // TODO: deal with the symlink case (i.e., only remove cache
            // item if file is really going away).
            BlobUtils.remove(path);
            callback(_mapError(err));
        });
    }

    function moveToTrash(path, callback) {
        // TODO: do we want to support a .trash/ dir or the like?
        unlink(path, callback);
    }

    function initWatchers(changeCallback, offlineCallback) {
        _changeCallback = changeCallback;
    }

    function watchPath(path, callback) {
        path = Path.normalize(path);

        if(watchers[path]) {
            return;
        }
        watchers[path] = fs.watch(path, {recursive: true}, function(event, filename) {
            stat(filename, function(err, stats) {
                if(err) {
                    return;
                }
                _changeCallback(filename, stats);
            });
        });
        callback();
    }

    function unwatchPath(path, callback) {
        path = Path.normalize(path);

        if(watchers[path]) {
            watchers[path].close();
            delete watchers[path];
        }
        callback();
    }

    function unwatchAll(callback) {
        Object.keys(watchers).forEach(function(path) {
            unwatchPath(path, function(){});
        });
        callback();
    }

    // Export public API
    exports.showOpenDialog  = showOpenDialog;
    exports.showSaveDialog  = showSaveDialog;
    exports.exists          = exists;
    exports.readdir         = readdir;
    exports.mkdir           = mkdir;
    exports.rename          = rename;
    exports.stat            = stat;
    exports.readFile        = readFile;
    exports.writeFile       = writeFile;
    exports.unlink          = unlink;
    exports.moveToTrash     = moveToTrash;
    exports.initWatchers    = initWatchers;
    exports.watchPath       = watchPath;
    exports.unwatchPath     = unwatchPath;
    exports.unwatchAll      = unwatchAll;

    exports.recursiveWatch    = true;
    exports.normalizeUNCPaths = false;
});
<commit_msg>Fix #297: Filer Filesystem can't remove directories<commit_after>/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global define */

define(function (require, exports, module) {
    "use strict";

    var FileSystemError = require("filesystem/FileSystemError"),
        FileSystemStats = require("filesystem/FileSystemStats"),
        Filer           = require("filesystem/impls/filer/BracketsFiler"),
        Dialog          = require("thirdparty/filer-dialogs/filer-dialogs"),
        BlobUtils       = require("filesystem/impls/filer/BlobUtils"),
        Handlers        = require("filesystem/impls/filer/lib/handlers");

    var fs              = Filer.fs(),
        Path            = Filer.Path,
        watchers        = {};

    var _changeCallback;            // Callback to notify FileSystem of watcher changes

    function showOpenDialog(allowMultipleSelection, chooseDirectories, title, initialPath, fileTypes, callback) {
        Dialog.showOpenDialog.apply(null, arguments);
    }

    function showSaveDialog(title, initialPath, defaultName, callback) {
        Dialog.showSaveAsDialog.apply(null, arguments);
    }

    /**
     * Convert Filer error codes to FileSystemError values.
     *
     * @param {?Object} err A Filer error code or Brackets error string
     * @return {?string} A FileSystemError string, or null if there was no error code.
     * @private
     **/
    function _mapError(err) {
        if (!err) {
            return null;
        }

        // If we get a raw Brackets error string passed through,
        // we don't need to map anything, and can just use it directly.
        if (typeof err === "string") {
            return err;
        }

        // Otherwise it's a Filer error, try and use err.code
        switch (err.code) {
        case 'EINVAL':
            return FileSystemError.INVALID_PARAMS;
        case 'ENOENT':
            return FileSystemError.NOT_FOUND;
        case 'EROFS':
            return FileSystemError.NOT_WRITABLE;
        case 'ENOSPC':
            return FileSystemError.OUT_OF_SPACE;
        case 'ENOTEMPTY':
            // There's no good case for this in Brackets (trying to rmdir non-empty dir)
            return "Directory Not Empty";
        case 'EEXIST':
            return FileSystemError.ALREADY_EXISTS;
        case 'ENOTDIR':
            return FileSystemError.INVALID_PARAMS;
        case 'EBADF':
            return FileSystemError.NOT_READABLE;
        }

        // We don't know what this is, log it. We likely need a new case above.
        console.log('[Brackets Filesystem] Unknown I/O error', err);
        return FileSystemError.UNKNOWN;
    }

    /**
     * Convert a callback to one that transforms its first parameter from a
     * Filer error code to a FileSystemError string.
     *
     * @param {function(?number)} cb A callback that expects an Filer error code
     * @return {function(?string)} A callback that expects a FileSystemError string
     * @private
     **/
    function _wrap(cb) {
        return function (err) {
            var args = Array.prototype.slice.call(arguments);
            args[0] = _mapError(args[0]);
            cb.apply(null, args);
        };
    }

    function stat(path, callback) {
        fs.stat(path, function(err, stats) {
            if (err){
                callback(_mapError(err));
                return;
            }

            var mtime = new Date(stats.mtime);

            var options = {
                isFile: stats.isFile(),
                mtime: mtime,
                size: stats.size,
                // TODO: figure out how to deal with realPath
                realPath: path,
                hash: mtime.getTime()
            };

            var fsStats = new FileSystemStats(options);

            callback(null, fsStats);
        });
    }

    function exists(path, callback) {
        fs.exists(path, function(exists) {
            callback(null, exists);
        });
    }

    function readdir(path, callback) {
        path = Path.normalize(path);

        fs.readdir(path, function (err, contents) {
            if (err) {
                callback(_mapError(err));
                return;
            }

            var count = contents.length;
            if (!count) {
                callback(null, [], []);
                return;
            }

            var stats = [];
            contents.forEach(function (val, idx) {
                stat(Path.join(path, val), function (err, stat) {
                    stats[idx] = err || stat;
                    count--;
                    if (count <= 0) {
                        callback(null, contents, stats);
                    }
                });
            });
        });
    }

    function mkdir(path, mode, callback) {
        if(typeof mode === 'function') {
            callback = mode;
        }

        fs.mkdir(path, mode, function (err) {
            if (err) {
                callback(_mapError(err));
                return;
            }
            stat(path, callback);
        });
    }

    function rename(oldPath, newPath, callback) {
        function updateBlobURL(err) {
            if(err) {
                return callback(_mapError(err));
            }

            // If this was a rename on a file path, update the Blob cache too
            stat(newPath, function(err, stat) {
                if(err) {
                    return callback(_mapError(err));
                }

                if(stat.isFile) {
                    BlobUtils.rename(oldPath, newPath);
                }

                callback();
            });
        }

        fs.rename(oldPath, newPath, _wrap(updateBlobURL));
    }

    function readFile(path, options, callback) {
        if(typeof options === 'function') {
            callback = options;
        }
        options = options || {};

        var encoding = options.encoding || "utf8";

        // Execute the read and stat calls in parallel. Callback early if the
        // read call completes first with an error; otherwise wait for both
        // to finish.
        var done = false, data, stat, err;

        if (options.stat) {
            done = true;
            stat = options.stat;
        } else {
            exports.stat(path, function (_err, _stat) {
                if (done) {
                    callback(_err, _err ? null : data, _stat);
                } else {
                    done = true;
                    stat = _stat;
                    err = _err;
                }
            });
        }

        fs.readFile(path, encoding, function (_err, _data) {
            if (_err) {
                callback(_mapError(_err));
                return;
            }

            if (done) {
                callback(err, err ? null : _data, stat);
            } else {
                done = true;
                data = _data;
            }
        });
    }

    function writeFile(path, data, options, callback) {
        if(typeof options === 'function') {
            callback = options;
        }
        options = options || {};

        var encoding = options.encoding || "utf8";

        function _finishWrite(created) {
            fs.writeFile(path, data, encoding, function (err) {
                if (err) {
                    callback(_mapError(err));
                    return;
                }

                // Cache a Blob URL for the file
                Handlers.handleFile(path, data);

                stat(path, function (err, stat) {
                    callback(_mapError(err), stat, created);
                });
            });
        }

        stat(path, function (err, stats) {
            if (err) {
                switch (err) {
                case FileSystemError.NOT_FOUND:
                    _finishWrite(true);
                    break;
                default:
                    callback(err);
                }
                return;
            }

            if (options.hasOwnProperty("expectedHash") && options.expectedHash !== stats._hash) {
                console.error("Blind write attempted: ", path, stats._hash, options.expectedHash);

                if (options.hasOwnProperty("expectedContents")) {
                    fs.readFile(path, encoding, function (_err, _data) {
                        if (_err || _data !== options.expectedContents) {
                            callback(FileSystemError.CONTENTS_MODIFIED);
                            return;
                        }

                        _finishWrite(false);
                    });
                    return;
                } else {
                    callback(FileSystemError.CONTENTS_MODIFIED);
                    return;
                }
            }

            _finishWrite(false);
        });
    }

    function unlink(path, callback) {
        fs.stat(path, function(err, stats) {
            if (err) {
                callback(_mapError(err));
                return;
            }

            // Deal with dir vs. file
            var fnName = stats.isDirectory() ? 'rmdir' : 'unlink';
            fs[fnName](path, function(err) {
                // TODO: deal with the symlink case (i.e., only remove cache
                // item if file is really going away).
                BlobUtils.remove(path);
                callback(_mapError(err));
            });
        });
    }

    function moveToTrash(path, callback) {
        // TODO: do we want to support a .trash/ dir or the like?
        unlink(path, callback);
    }

    function initWatchers(changeCallback, offlineCallback) {
        _changeCallback = changeCallback;
    }

    function watchPath(path, callback) {
        path = Path.normalize(path);

        if(watchers[path]) {
            return;
        }
        watchers[path] = fs.watch(path, {recursive: true}, function(event, filename) {
            stat(filename, function(err, stats) {
                if(err) {
                    return;
                }
                _changeCallback(filename, stats);
            });
        });
        callback();
    }

    function unwatchPath(path, callback) {
        path = Path.normalize(path);

        if(watchers[path]) {
            watchers[path].close();
            delete watchers[path];
        }
        callback();
    }

    function unwatchAll(callback) {
        Object.keys(watchers).forEach(function(path) {
            unwatchPath(path, function(){});
        });
        callback();
    }

    // Export public API
    exports.showOpenDialog  = showOpenDialog;
    exports.showSaveDialog  = showSaveDialog;
    exports.exists          = exists;
    exports.readdir         = readdir;
    exports.mkdir           = mkdir;
    exports.rename          = rename;
    exports.stat            = stat;
    exports.readFile        = readFile;
    exports.writeFile       = writeFile;
    exports.unlink          = unlink;
    exports.moveToTrash     = moveToTrash;
    exports.initWatchers    = initWatchers;
    exports.watchPath       = watchPath;
    exports.unwatchPath     = unwatchPath;
    exports.unwatchAll      = unwatchAll;

    exports.recursiveWatch    = true;
    exports.normalizeUNCPaths = false;
});
<|endoftext|>


<commit_before>"use strict";

var pg = require("pg");
var port = parseInt(process.env.PORT, 10) || 8080;
var socketIo = require("socket.io").listen(port);

socketIo.configure(function () {
	socketIo.set("log level", 2);
});

var connectionString = process.env.DATABASE_URL || "postgres://localhost/hikeio";
var client = new pg.Client(connectionString);
client.connect();

socketIo.sockets.on("connection", function (socket) {
	socket.on("get-hikes-in-bounds", function (data) {

		console.log("Getting hikes in bounds:", data);

		// Longitude is tricky because it can jump from 179 to -179 across the international date line
		var longitudeWhereClause;
		if (data.sw.longitude < data.ne.longitude) {
			longitudeWhereClause = "(locations.longitude >= $3 AND locations.longitude <= $4)";
		} else {
			longitudeWhereClause = "(locations.longitude >= $3 OR locations.longitude <= $4)";
		}

		var queryString =  "SELECT hikes.string_id, hikes.name, hike.distance, locations.latitude, locations.longitude \
							FROM hikes, locations \
							WHERE locations.latitude >= $1 AND \
								locations.latitude <= $2 AND " + longitudeWhereClause + " AND \
								hikes.location_id = locations.id \
							ORDER BY locations.latitude, locations.longitude;";
		client.query(queryString, [data.sw.latitude, data.ne.latitude, data.sw.longitude, data.ne.longitude], function(err, result) {
			if (!result) {
				console.log(err);
				return;
			}
			console.log("Found " + result.rows.length + " hikes");
			socket.emit("get-hikes-in-bounds", result.rows);
		});
	});
});<commit_msg>Fix typo in db query.<commit_after>"use strict";

var pg = require("pg");
var port = parseInt(process.env.PORT, 10) || 8080;
var socketIo = require("socket.io").listen(port);

socketIo.configure(function () {
	socketIo.set("log level", 2);
});

var connectionString = process.env.DATABASE_URL || "postgres://localhost/hikeio";
var client = new pg.Client(connectionString);
client.connect();

socketIo.sockets.on("connection", function (socket) {
	socket.on("get-hikes-in-bounds", function (data) {

		console.log("Getting hikes in bounds:", data);

		// Longitude is tricky because it can jump from 179 to -179 across the international date line
		var longitudeWhereClause;
		if (data.sw.longitude < data.ne.longitude) {
			longitudeWhereClause = "(locations.longitude >= $3 AND locations.longitude <= $4)";
		} else {
			longitudeWhereClause = "(locations.longitude >= $3 OR locations.longitude <= $4)";
		}

		var queryString =  "SELECT hikes.string_id, hikes.name, hikes.distance, locations.latitude, locations.longitude \
							FROM hikes, locations \
							WHERE locations.latitude >= $1 AND \
								locations.latitude <= $2 AND " + longitudeWhereClause + " AND \
								hikes.location_id = locations.id \
							ORDER BY locations.latitude, locations.longitude;";
		client.query(queryString, [data.sw.latitude, data.ne.latitude, data.sw.longitude, data.ne.longitude], function(err, result) {
			if (!result) {
				console.log(err);
				return;
			}
			console.log("Found " + result.rows.length + " hikes");
			socket.emit("get-hikes-in-bounds", result.rows);
		});
	});
});<|endoftext|>


<commit_before>var TelegramBot = require('node-telegram-bot-api');
var bot = new TelegramBot(process.env.CHAINTACT_BOT_TOKEN, {polling: true});
var mongoose = require('mongoose');
var dbUrl = "mongodb://chaintact_db/chaintactdb";

mongoose.connect(dbUrl);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
  console.log("I'm in!");
});

//Database
var userSchema = mongoose.Schema({
    telegramID: String,
    telegramUsername: String,
    firstName: String,
    lastName: String,
    ETHAddress: String
});

var User = mongoose.model('User', userSchema);

bot.getMe().then(function (me) {
  console.log('Hi my name is %s!', me.username);
});

//BOT commands

var helpText = "Commands for /chaintact :\n"
  + "    help - List of commands\n"
  + "    set [ETH address] - Set your ETH address to your profil\n"
  + "    get [telegram user] - Sends this user ETH address\n"
  + "    group - Sends the list of all group users ETH addresses"

//matches /start
bot.onText(/\/start/, function (msg, match) {
  var fromId = msg.from.id; // get the id, of who is sending the message
  var message = "Welcome to your ChaintactBot\n"
  message += helpText
  bot.sendMessage(fromId, message);
});

//match /chaintact [whatever]
bot.onText(/\/chaintact (.+)/, function (msg, match) {
  var fromId = msg.from.id; // get the id, of who is sending the message
  var command = match[1];
  var message;
  switch(command) {
    case "help":
      message = helpText;
      break;
    case "set":
      message = "Coming soon!";
      message += " fromId:" + fromId
      break;
    case "get":
      message = "Coming soon!";
      break;
    case "group":
      message = "Coming soon!";
      break;
    default:
      message = helpText;
  }
  bot.sendMessage(fromId, message);
});
<commit_msg>Set function<commit_after>var TelegramBot = require('node-telegram-bot-api');
var bot = new TelegramBot(process.env.CHAINTACT_BOT_TOKEN, {polling: true});
var mongoose = require('mongoose');
var dbUrl = "mongodb://chaintact_db/chaintactdb";

mongoose.connect(dbUrl);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
  console.log("I'm in!");
});

//Database
var userSchema = mongoose.Schema({
    telegramID: String,
    telegramUsername: String,
    firstName: String,
    lastName: String,
    ETHAddress: String
});

var User = mongoose.model('User', userSchema);

bot.getMe().then(function (me) {
  console.log('Hi my name is %s!', me.username);
});

//BOT commands

var helpText = "Commands for /chaintact :\n"
  + "    help - List of commands\n"
  + "    set [ETH address] - Set your ETH address to your profil\n"
  + "    get [telegram user] - Sends this user ETH address\n"
  + "    group - Sends the list of all group users ETH addresses"

//matches /start
bot.onText(/\/start/, function (msg, match) {
  var fromId = msg.from.id; // get the id, of who is sending the message
  var message = "Welcome to your ChaintactBot\n"
  message += helpText
  bot.sendMessage(fromId, message);
});

//match /chaintact [whatever]
bot.onText(/\/chaintact (.+)/, function (msg, match) {
  var fromId = msg.from.id; // get the id, of who is sending the message
  var fromUsername = "";
  var fromLastName = "";
  var fromFirstName = "";
  if(msg.from.username != null) fromUsername = msg.from.username
  if(msg.from.first_name != null) fromFirstName = msg.from.username
  if(msg.from.last_name != null) fromLastName = msg.from.username
  var command = match[1];
  var message;
  switch(command) {
    case "help":
      message = helpText;
      break;
    case "set":

      if(match[2] == null) {
        message = "please enter an ETH address!";
        break;
      }

      User.findOne({telegramID: fromId}, function(err, user) {
        if(user == null) {
          var newUser = new User({telegramID:fromId, telegramUsername:fromUsername, firstName:fromFirstName, lastName:fromLastName, ETHAddress:match[2]});
          newUser.save(function (err) {
            if (err) return handleError(err);
            console.log("User created : " + telegramID);
          })
        } else {
          user.telegramUsername = fromUsername
          user.firstName = fromFirstName
          user.lastName = fromLastName
          user.ETHAddress = match[2]
          .save(function (err) {
            if (err) return handleError(err);
            console.log("User updated : " + telegramID);
          })
        }
      })
      break;
    case "get":
      message = "Coming soon!";
      break;
    case "group":
      message = "Coming soon!";
      break;
    default:
      message = helpText;
  }
  bot.sendMessage(fromId, message);
});
<|endoftext|>


<commit_before>'use strict';
import {Menu, MenuItem, MenuDivider} from 'react-toolbox/lib/menu';
import {Button} from 'react-toolbox/lib/button';
import Link from 'react-toolbox/lib/link';
import Tooltip from 'react-toolbox/lib/tooltip';
import {getColumns} from '../columnsParam';
import {getHeatmap} from '../heatmapParam';
var konami = require('../konami');
var React = require('react');
var _ = require('../underscore_ext');
var Rx = require('../rx');
var {createBookmark, getRecent, setRecent} = require('../bookmark');

var compStyles = require('./BookmarkMenu.module.css');
var gaEvents = require('../gaEvents');

// XXX This is a horrible work-around for react-toolbox menu limitations.
// We want the Bookmark MenuItem to not close the menu. Menu closes when
// a MenuItem is clicked by intercepting the onClick handler. However, it
// only intercepts onClick handlers of MenuItem children. By simply wrapping
// MenuItem, we avoid this.
class NoCloseMenuItem extends React.Component {
	render() {
		var {tooltip, ...otherProps} = this.props;
		return <MenuItem {...otherProps}/>;
	}
}

var TooltipNoCloseMenuItem = Tooltip(NoCloseMenuItem);

var privateWarning = 'Unable to create bookmark link due to private data in view. Use export instead';

var linking = false;

class BookmarkMenu extends React.Component {
	state = {loading: false, open: false, recent: false};

	componentWillMount() {
		var asciiC = 67;
		this.ksub = konami(asciiC).subscribe(() => {linking = true;});
	}

	componentWillUnmount() {
		this.ksub.unsubscribe();
	}

	// RTB positions and clips the menu content according
	// to the initial menu render size, which causes problems
	// for dynamic content. This is a work-around which causes
	// the Menu component to re-calculate its size every time
	// we update.
	componentDidUpdate() {
		if (this.state.open && this.menuRef) {
			this.menuRef.show();
		}
	}

	onRef = ref => {
		this.menuRef = ref;
	}

	onBookmark = () => {
		gaEvents('bookmark', 'create');
		var {getState} = this.props;
		this.setState({loading: true});
		Rx.Observable.ajax({
			method: 'POST',
			url: '/api/bookmarks/bookmark',
			responseType: 'text',
			headers: {
				'X-CSRFToken': document.cookie.replace(/.*csrftoken=([0-9a-z]+)/, '$1'),
				'Content-Type': 'application/x-www-form-urlencoded'
			},
			body: `content=${encodeURIComponent(createBookmark(getState()))}`
		}).subscribe(this.onSetBookmark, () => this.setState({loading: false}));
	};

	onSetBookmark = (resp) => {
		var {id} = JSON.parse(resp.response);
		setRecent(id);
		this.setState({bookmark: `${location.href}?bookmark=${id}`, loading: false});
	};

	onResetBookmark = () => {
		this.setState({bookmark: null});
	};

	onCopyBookmarkToClipboard = () => {
		this.bookmarkEl.select();
		document.execCommand('copy');
	};

	onExport = () => {
		gaEvents('bookmark', 'export');
		var {getState} = this.props;
		var url = URL.createObjectURL(new Blob([JSON.stringify(getState())], { type: 'application/json' }));
		var a = document.createElement('a');
		var filename = 'xenaState.json';
		_.extend(a, { id: filename, download: filename, href: url });
		document.body.appendChild(a);
		a.click();
		document.body.removeChild(a);
	};

	onImport = () => {
		this.refs.import.click();
	};

	onImportSelected = (ev) => {
		gaEvents('bookmark', 'import');
		var file = ev.target.files[0],
			reader = new FileReader(),
			{onImport} = this.props;

		reader.onload = () => onImport(reader.result);
		reader.readAsText(file);
		ev.target.value = null;
	};

	resetBookmark = () => {
		this.setState({bookmark: null});
	};

	onClick = () => {
		this.setState({open: !(this.state.open || this.state.recent), recent: false});
	};

	onRecent = () => {
		this.setState({recent: !this.state.recent, open: false});
	}

	onRecentHide = () => {
		this.setState({recent: false});
	}

	handleMenuHide = () => {
		this.setState({open: false});
		if (this.props.onHide) {
			this.props.onHide();
		}
	};

	onViewBookmark(id) {
		window.location = window.location.href + `?bookmark=${id}`;
	}

	render() {
		var {bookmark, loading, open, recent} = this.state,
			{isPublic, getState} = this.props,
			recentBookmarks = getRecent(),
			BookmarkElement = isPublic ? NoCloseMenuItem : TooltipNoCloseMenuItem;

		return (

				<Button onClick={this.onClick}>Bookmark</Button>
				<Menu innerRef={this.onRef} position='topLeft' active={open} onHide={this.handleMenuHide} className={compStyles.iconBookmark} iconRipple={false} onShow={this.resetBookmark}>
					<BookmarkElement
						tooltip={privateWarning}
						style={{pointerEvents: 'all' /* override MenuItem 'disabled' class */}}
						disabled={!isPublic}
						onClick={this.onBookmark}
						caption='Bookmark'/>
					{recentBookmarks.length > (bookmark ? 1 : 0) ?
						<MenuItem onClick={this.onRecent} title={null} caption='Recent bookmarks'/> : null}
					<MenuItem onClick={this.onExport} title={null} caption='Export'/>
					<MenuItem onClick={this.onImport} title={null} caption='Import'/>
					{linking ? <Link target='_blank' href={`${location.href.replace(/heatmap*/, 'heatmap')}heatmap/?columns=${getColumns(getState())}&heatmap=${getHeatmap(getState())}`} label='Link'/> : null}
					<Link className={compStyles.help} target='_blank' href='https://ucsc-xena.gitbook.io/project/overview-of-features/bookmarks' label='Help'/>
					{bookmark || loading ? <MenuDivider/> : null}
					{bookmark || loading ? (
						<MenuItem
							onClick={bookmark ? this.onCopyBookmarkToClipboard : undefined}
							caption={bookmark ? 'Copy Bookmark' : 'Your Bookmark is Loading'}
							disabled={!bookmark}/>) : null}
					{bookmark ? (

							Note: bookmarks are only guaranteed for 3 months after creation

) : null}
					<input className={compStyles.bookmarkInput} ref={(input) => this.bookmarkEl = input} value={bookmark || ''}/>
					<input className={compStyles.importInput} ref='import' id='import' onChange={this.onImportSelected} type='file'/>
				</Menu>
				<Menu onSelect={this.onViewBookmark}
						position='auto'
						active={recent && recentBookmarks.length > 0}
						className={compStyles.iconBookmark}
						iconRipple={false}
						onHide={this.onRecentHide}>
					{recentBookmarks.map(({id, time}) => (
						<MenuItem key={id} value={id} title={null} caption={`${time.replace(/ GMT.*/, '')} (${id.slice(0, 4)})`}/>
						))}
				</Menu>

);
	}
}

module.exports = BookmarkMenu;
<commit_msg>Fix generation of deep links<commit_after>'use strict';
import {Menu, MenuItem, MenuDivider} from 'react-toolbox/lib/menu';
import {Button} from 'react-toolbox/lib/button';
import Link from 'react-toolbox/lib/link';
import Tooltip from 'react-toolbox/lib/tooltip';
import {getColumns} from '../columnsParam';
import {getHeatmap} from '../heatmapParam';
var konami = require('../konami');
var React = require('react');
var _ = require('../underscore_ext');
var Rx = require('../rx');
var {createBookmark, getRecent, setRecent} = require('../bookmark');

var compStyles = require('./BookmarkMenu.module.css');
var gaEvents = require('../gaEvents');

// XXX This is a horrible work-around for react-toolbox menu limitations.
// We want the Bookmark MenuItem to not close the menu. Menu closes when
// a MenuItem is clicked by intercepting the onClick handler. However, it
// only intercepts onClick handlers of MenuItem children. By simply wrapping
// MenuItem, we avoid this.
class NoCloseMenuItem extends React.Component {
	render() {
		var {tooltip, ...otherProps} = this.props;
		return <MenuItem {...otherProps}/>;
	}
}

var TooltipNoCloseMenuItem = Tooltip(NoCloseMenuItem);

var privateWarning = 'Unable to create bookmark link due to private data in view. Use export instead';

var linking = false;

class BookmarkMenu extends React.Component {
	state = {loading: false, open: false, recent: false};

	componentWillMount() {
		var asciiC = 67;
		this.ksub = konami(asciiC).subscribe(() => {linking = true;});
	}

	componentWillUnmount() {
		this.ksub.unsubscribe();
	}

	// RTB positions and clips the menu content according
	// to the initial menu render size, which causes problems
	// for dynamic content. This is a work-around which causes
	// the Menu component to re-calculate its size every time
	// we update.
	componentDidUpdate() {
		if (this.state.open && this.menuRef) {
			this.menuRef.show();
		}
	}

	onRef = ref => {
		this.menuRef = ref;
	}

	onBookmark = () => {
		gaEvents('bookmark', 'create');
		var {getState} = this.props;
		this.setState({loading: true});
		Rx.Observable.ajax({
			method: 'POST',
			url: '/api/bookmarks/bookmark',
			responseType: 'text',
			headers: {
				'X-CSRFToken': document.cookie.replace(/.*csrftoken=([0-9a-z]+)/, '$1'),
				'Content-Type': 'application/x-www-form-urlencoded'
			},
			body: `content=${encodeURIComponent(createBookmark(getState()))}`
		}).subscribe(this.onSetBookmark, () => this.setState({loading: false}));
	};

	onSetBookmark = (resp) => {
		var {id} = JSON.parse(resp.response);
		setRecent(id);
		this.setState({bookmark: `${location.href}?bookmark=${id}`, loading: false});
	};

	onResetBookmark = () => {
		this.setState({bookmark: null});
	};

	onCopyBookmarkToClipboard = () => {
		this.bookmarkEl.select();
		document.execCommand('copy');
	};

	onExport = () => {
		gaEvents('bookmark', 'export');
		var {getState} = this.props;
		var url = URL.createObjectURL(new Blob([JSON.stringify(getState())], { type: 'application/json' }));
		var a = document.createElement('a');
		var filename = 'xenaState.json';
		_.extend(a, { id: filename, download: filename, href: url });
		document.body.appendChild(a);
		a.click();
		document.body.removeChild(a);
	};

	onImport = () => {
		this.refs.import.click();
	};

	onImportSelected = (ev) => {
		gaEvents('bookmark', 'import');
		var file = ev.target.files[0],
			reader = new FileReader(),
			{onImport} = this.props;

		reader.onload = () => onImport(reader.result);
		reader.readAsText(file);
		ev.target.value = null;
	};

	resetBookmark = () => {
		this.setState({bookmark: null});
	};

	onClick = () => {
		this.setState({open: !(this.state.open || this.state.recent), recent: false});
	};

	onRecent = () => {
		this.setState({recent: !this.state.recent, open: false});
	}

	onRecentHide = () => {
		this.setState({recent: false});
	}

	handleMenuHide = () => {
		this.setState({open: false});
		if (this.props.onHide) {
			this.props.onHide();
		}
	};

	onViewBookmark(id) {
		window.location = window.location.href + `?bookmark=${id}`;
	}

	render() {
		var {bookmark, loading, open, recent} = this.state,
			{isPublic, getState} = this.props,
			recentBookmarks = getRecent(),
			BookmarkElement = isPublic ? NoCloseMenuItem : TooltipNoCloseMenuItem;

		return (

				<Button onClick={this.onClick}>Bookmark</Button>
				<Menu innerRef={this.onRef} position='topLeft' active={open} onHide={this.handleMenuHide} className={compStyles.iconBookmark} iconRipple={false} onShow={this.resetBookmark}>
					<BookmarkElement
						tooltip={privateWarning}
						style={{pointerEvents: 'all' /* override MenuItem 'disabled' class */}}
						disabled={!isPublic}
						onClick={this.onBookmark}
						caption='Bookmark'/>
					{recentBookmarks.length > (bookmark ? 1 : 0) ?
						<MenuItem onClick={this.onRecent} title={null} caption='Recent bookmarks'/> : null}
					<MenuItem onClick={this.onExport} title={null} caption='Export'/>
					<MenuItem onClick={this.onImport} title={null} caption='Import'/>
					{linking ? <Link target='_blank' href={`${location.href.replace(/heatmap.*/, 'heatmap')}heatmap/?columns=${getColumns(getState())}&heatmap=${getHeatmap(getState())}`} label='Link'/> : null}
					<Link className={compStyles.help} target='_blank' href='https://ucsc-xena.gitbook.io/project/overview-of-features/bookmarks' label='Help'/>
					{bookmark || loading ? <MenuDivider/> : null}
					{bookmark || loading ? (
						<MenuItem
							onClick={bookmark ? this.onCopyBookmarkToClipboard : undefined}
							caption={bookmark ? 'Copy Bookmark' : 'Your Bookmark is Loading'}
							disabled={!bookmark}/>) : null}
					{bookmark ? (

							Note: bookmarks are only guaranteed for 3 months after creation

) : null}
					<input className={compStyles.bookmarkInput} ref={(input) => this.bookmarkEl = input} value={bookmark || ''}/>
					<input className={compStyles.importInput} ref='import' id='import' onChange={this.onImportSelected} type='file'/>
				</Menu>
				<Menu onSelect={this.onViewBookmark}
						position='auto'
						active={recent && recentBookmarks.length > 0}
						className={compStyles.iconBookmark}
						iconRipple={false}
						onHide={this.onRecentHide}>
					{recentBookmarks.map(({id, time}) => (
						<MenuItem key={id} value={id} title={null} caption={`${time.replace(/ GMT.*/, '')} (${id.slice(0, 4)})`}/>
						))}
				</Menu>

);
	}
}

module.exports = BookmarkMenu;
<|endoftext|>


<commit_before>const electron = require('electron');
const ipc = require('electron').ipcMain;
const development = false;

global.urls = {
    app_url: development ? 'http://localhost:8000' : 'http://four.featherq.com',
    websocket_url: "ws://188.166.234.33:443/socket/server.php"
};

global.windowProperties = {
    width: development ? 800 : 400,
    height: development ? 800 : 300,
    transparent: true,
    alwaysOnTop: false,
    icon: 'images/favicon-32x32.png'
};

global.ids = {
    user_id: null,
    business_id: null,
    service_id: null,
    terminal_id: null
};

// Module to control application life.
const app = electron.app;
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow;

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
//var mainWindow;

var mainWindow = null;
var pqWindow = null;
var terminalWindow = null;

function createLoginWindow () {
    // Create the browser window.
    mainWindow = new BrowserWindow(global.windowProperties);

    // and load the index.html of the app.
    mainWindow.loadURL('file://' + __dirname + '/views/login.html');

    // Open the DevTools.
    if(development) mainWindow.webContents.openDevTools();

    // Emitted when the window is closed.
    mainWindow.on('closed', function () {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null
    });

    //close windows
    if(terminalWindow !== null){
        terminalWindow.close();
    }
    if(pqWindow !== null){
        pqWindow.close();
    }
}

function createTerminalsWindow () {
    terminalWindow = new BrowserWindow(global.windowProperties);
    terminalWindow.loadURL('file://' + __dirname + '/views/terminals.html');
    if(development) terminalWindow.webContents.openDevTools();
    terminalWindow.on('closed', function () {
        terminalWindow = null;
    });

    //close windows
    if(mainWindow !== null){
        mainWindow.close();
    }
    if(pqWindow !== null){
        pqWindow.close();
    }
}

function createProcessQueueWindow () {
    // Create the browser window.
    pqWindow = new BrowserWindow({
        width: development ? 800 : 400,
        height: development ? 800 : 200,
        transparent: true,
        alwaysOnTop: false,
        icon: 'images/favicon-32x32.png'
    });
    pqWindow.loadURL('file://' + __dirname + '/views/index.html');
    if(development) pqWindow.webContents.openDevTools();
    pqWindow.on('closed', function () {
        pqWindow = null;
    });

    //close windows
    if(mainWindow !== null){
        mainWindow.close();
    }
    if(terminalWindow !== null){
        terminalWindow.close();
    }
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.dock.setIcon('images/favicon-32x32.png');

app.on('ready', createLoginWindow);
ipc.on('terminal-chosen', createProcessQueueWindow);
ipc.on('login-success', createTerminalsWindow);

// Quit when all windows are closed.
app.on('window-all-closed', function () {
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
        app.quit()
    }
});

app.on('activate', function () {
    // On OS X it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (mainWindow === null && pqWindow === null && terminalWindow === null) {
        global.ids.user_id = null;
        createLoginWindow();
    }
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

<commit_msg>ARA Updated windows behaviour ARA 05312016 Changed transparency to false Updated Behaviour to show process queue window always on top<commit_after>const electron = require('electron');
const ipc = require('electron').ipcMain;
const development = false;

global.urls = {
    app_url: development ? 'http://localhost:8000' : 'http://four.featherq.com',
    websocket_url: "ws://188.166.234.33:443/socket/server.php"
};

global.windowProperties = {
    width: development ? 800 : 400,
    height: development ? 800 : 300,
    transparent: false,
    alwaysOnTop: false,
    icon: 'images/favicon-32x32.png'
};

global.ids = {
    user_id: null,
    business_id: null,
    service_id: null,
    terminal_id: null
};

// Module to control application life.
const app = electron.app;
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow;

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
//var mainWindow;

var mainWindow = null;
var pqWindow = null;
var terminalWindow = null;

function createLoginWindow () {
    // Create the browser window.
    mainWindow = new BrowserWindow(global.windowProperties);

    // and load the index.html of the app.
    mainWindow.loadURL('file://' + __dirname + '/views/login.html');

    // Open the DevTools.
    if(development) mainWindow.webContents.openDevTools();

    // Emitted when the window is closed.
    mainWindow.on('closed', function () {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null
    });

    //close windows
    if(terminalWindow !== null){
        terminalWindow.close();
    }
    if(pqWindow !== null){
        pqWindow.close();
    }
}

function createTerminalsWindow () {
    terminalWindow = new BrowserWindow(global.windowProperties);
    terminalWindow.loadURL('file://' + __dirname + '/views/terminals.html');
    if(development) terminalWindow.webContents.openDevTools();
    terminalWindow.on('closed', function () {
        terminalWindow = null;
    });

    //close windows
    if(mainWindow !== null){
        mainWindow.close();
    }
    if(pqWindow !== null){
        pqWindow.close();
    }
}

function createProcessQueueWindow () {
    // Create the browser window.
    var pqHeight = process.platform !== 'darwin' ? 200 : 163;
    pqWindow = new BrowserWindow({
        width: development ? 800 : 400,
        height: development ? 800 : pqHeight,
        transparent: false,
        alwaysOnTop: true,
        icon: 'images/favicon-32x32.png'
    });
    pqWindow.loadURL('file://' + __dirname + '/views/index.html');
    if(development) pqWindow.webContents.openDevTools();
    pqWindow.on('closed', function () {
        pqWindow = null;
    });

    //close windows
    if(mainWindow !== null){
        mainWindow.close();
    }
    if(terminalWindow !== null){
        terminalWindow.close();
    }
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.dock.setIcon('images/favicon-32x32.png');

app.on('ready', createLoginWindow);
ipc.on('terminal-chosen', createProcessQueueWindow);
ipc.on('login-success', createTerminalsWindow);

// Quit when all windows are closed.
app.on('window-all-closed', function () {
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
        app.quit()
    }
});

app.on('activate', function () {
    // On OS X it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (mainWindow === null && pqWindow === null && terminalWindow === null) {
        global.ids.user_id = null;
        createLoginWindow();
    }
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

<|endoftext|>


<commit_before>(function() {

  mit.Backgrounds = {

    // Speeds and Velocities of Backgrounds
    common_bg_speed: 1,

    cloud_bg_move_speed: 2,
    cloud_bg_vx: 0,

    backtree_bg_move_speed: 3,
    backtree_bg_vx: 0,

    fronttree_bg_move_speed: 5,
    fronttree_bg_vx: 0,

    ground_bg_move_speed: 7,
    ground_bg_vx: 0,

    grass_bg_move_speed: 7,
    grass_bg_vx: 0,

    combined_bg_move_speed: 3,
    combined_bg_vx: 0,

    log_x: 40,
    log_y: 0,

    sky_gradient: {},

    first_speed_inc: 0,
    second_speed_inc: 0,
    third_speed_inc: 0,

    init: function(ctx) {
      // Sky Gradient
      this.sky_gradient = ctx.createLinearGradient(0, 0, 0, mit.H);
      this.sky_gradient.addColorStop(0, '#06c4f4');
      this.sky_gradient.addColorStop(1, '#7bd4f6');

      // Clouds
      // this.cloud_img = new Image();
      // this.cloud_img.src = 'img/clouds.png';
      this.cloud_img = mit.image.clouds;

      this.cloud_img.width = mit.W;
      this.cloud_img.height = mit.H;

      // Back Trees
      // this.backtree_img = new Image();
      // this.backtree_img.src = 'img/back_trees.png';
      this.backtree_img = mit.image.backtrees;

      this.backtree_img.width = mit.W;
      this.backtree_img.height = mit.H;

      // Front Trees
      // this.fronttree_img = new Image();
      // this.fronttree_img.src = 'img/front_trees.png';
      this.fronttree_img = mit.image.fronttrees;

      this.fronttree_img.width = mit.W;
      this.fronttree_img.height = mit.H;

      // Ground
      // this.ground_img = new Image();
      // this.ground_img.src = 'img/ground.png';
      this.ground_img = mit.image.ground;

      this.ground_img.width = mit.W;
      this.ground_img.height = mit.H;

      // Grass
      // this.grass_img = new Image();
      // this.grass_img.src = 'img/grass.png';
      this.grass_img = mit.image.grass;

      this.grass_img.width = mit.W;
      this.grass_img.height = mit.H;

      // Log on which pappu sits
      // this.log_img = new Image();
      // this.log_img.src = 'img/log.png';
      this.log_img = mit.image.log;

      // Combined BG Image
      // this.combined_bg_img = new Image();
      // this.combined_bg_img.src = 'img/bg_combined.png';
      this.combined_bg_img = mit.image.bg_combined;
    },

    drawClouds: function(ctx) {
      var cloud_bg_vx_abs = Math.abs(this.cloud_bg_vx);

      ctx.drawImage(
        this.cloud_img,

        cloud_bg_vx_abs,
        0,
        mit.W + this.cloud_bg_vx,
        mit.H,

        0, 0,
        mit.W + this.cloud_bg_vx,
        mit.H
      );

      ctx.drawImage(
        this.cloud_img,

        0, 0,
        cloud_bg_vx_abs,
        mit.H,

        mit.W + this.cloud_bg_vx,
        0,
        cloud_bg_vx_abs,
        mit.H
      );

      this.cloud_bg_vx -= this.cloud_bg_move_speed;

      if (-this.cloud_bg_vx >= mit.W) {
        this.cloud_bg_vx = 0;
      }

      return;
    },

    drawBackTrees: function(ctx) {
      var backtree_bg_vx_abs = Math.abs(this.backtree_bg_vx);

      ctx.drawImage(
        this.backtree_img,

        backtree_bg_vx_abs,
        0,
        mit.W + this.backtree_bg_vx,
        mit.H,

        0, 0,
        mit.W + this.backtree_bg_vx,
        mit.H
      );

      ctx.drawImage(
        this.backtree_img,

        0, 0,
        backtree_bg_vx_abs,
        mit.H,

        mit.W + this.backtree_bg_vx,
        0,
        backtree_bg_vx_abs,
        mit.H
      );

      if (mit.game_started)
        this.backtree_bg_vx -= this.backtree_bg_move_speed * this.common_bg_speed;

      if (-this.backtree_bg_vx >= mit.W) {
        this.backtree_bg_vx = 0;
      }

      return;
    },

    drawFrontTrees: function(ctx) {
      var fronttree_bg_vx_abs = Math.abs(this.fronttree_bg_vx);

      ctx.drawImage(
        this.fronttree_img,

        fronttree_bg_vx_abs,
        0,
        mit.W + this.fronttree_bg_vx,
        mit.H,

        0, 0,
        mit.W + this.fronttree_bg_vx,
        mit.H
      );

      ctx.drawImage(
        this.fronttree_img,

        0, 0,
        fronttree_bg_vx_abs,
        mit.H,

        mit.W + this.fronttree_bg_vx,
        0,
        fronttree_bg_vx_abs,
        mit.H
      );

      if (mit.game_started)
        this.fronttree_bg_vx -= this.fronttree_bg_move_speed * this.common_bg_speed;

      if (-this.fronttree_bg_vx >= mit.W) {
        this.fronttree_bg_vx = 0;
      }

      return;
    },

    drawGround: function(ctx) {
      var ground_bg_vx_abs = Math.abs(this.ground_bg_vx);

      ctx.drawImage(
        this.ground_img,

        ground_bg_vx_abs,
        0,
        mit.W + this.ground_bg_vx,
        mit.H,

        0, 0,
        mit.W + this.ground_bg_vx,
        mit.H
      );

      ctx.drawImage(
        this.ground_img,

        0, 0,
        ground_bg_vx_abs,
        mit.H,

        mit.W + this.ground_bg_vx,
        0,
        ground_bg_vx_abs,
        mit.H
      );

      if (mit.game_started)
        this.ground_bg_vx -= this.ground_bg_move_speed * this.common_bg_speed;

      if (-this.ground_bg_vx >= mit.W) {
        this.ground_bg_vx = 0;
      }

      // console.log(-this.ground_bg_vx);

      return;
    },

    drawGrass: function(ctx) {
      var grass_bg_vx_abs = Math.abs(this.grass_bg_vx);

      ctx.drawImage(
        this.grass_img,

        grass_bg_vx_abs,
        0,
        mit.W + this.grass_bg_vx,
        mit.H,

        0, 0,
        mit.W + this.grass_bg_vx,
        mit.H
      );

      ctx.drawImage(
        this.grass_img,

        0, 0,
        grass_bg_vx_abs,
        mit.H,

        mit.W + this.grass_bg_vx,
        0,
        grass_bg_vx_abs,
        mit.H
      );

      if (mit.game_started)
        this.grass_bg_vx -= this.grass_bg_move_speed * this.common_bg_speed;

      if (-this.grass_bg_vx >= mit.W) {
        this.grass_bg_vx = 0;
      }

      return;
    },

    drawInitLog: function(ctx) {

      this.log_y = mit.H-(this.log_img.height+45);

      ctx.drawImage(this.log_img, this.log_x, this.log_y);

      if (mit.game_started) {
        this.log_x -= this.grass_bg_move_speed * this.common_bg_speed;
      }
    },

    drawCombinedBG: function(ctx) {
      var combined_bg_vx_abs = Math.abs(this.combined_bg_vx);

      ctx.drawImage(
        this.combined_bg_img,

        combined_bg_vx_abs,
        0,
        mit.W + this.combined_bg_vx,
        mit.H,

        0, 0,
        mit.W + this.combined_bg_vx,
        mit.H
      );

      ctx.drawImage(
        this.combined_bg_img,

        0, 0,
        combined_bg_vx_abs,
        mit.H,

        mit.W + this.combined_bg_vx,
        0,
        combined_bg_vx_abs,
        mit.H
      );

      if (mit.game_started)
        this.combined_bg_vx -= this.combined_bg_move_speed * this.common_bg_speed;

      if (-this.combined_bg_vx >= mit.W) {
        this.combined_bg_vx = 0;
      }
    },

    // Draw Awesome Backgrounds
    // Backgrounds have been made for 1000x500 dimensions
    draw: function(ctx) {

      if (mit.start_btn_clicked) {
        if (!this.fps || this.fps === 5000)
          this.fps = mit.fps;
      }
      else {
        this.fps = 5000;
      }

      if (this.fps > 56) {

        // Draw Linear Gradient for real/pure BG (sky/water)
        ctx.save();
        ctx.fillStyle = this.sky_gradient;
        ctx.fillRect(0, 0, mit.W, mit.H);
        ctx.restore();

        // Clouds
        this.drawClouds(ctx);

        // Back Small Trees
        this.drawBackTrees(ctx);

        // Front Big Trees
        this.drawFrontTrees(ctx);
      }
      else {
        this.drawCombinedBG(ctx);
      }

      // Drawing the initial wood log on which
      // Pappu gonna sit and bask in the cool and cozy
      // environment.
      if (this.log_x+100 > 0) {
        this.drawInitLog(ctx);
      }
      else if (!mit.game_started) {
        this.log_x = 40;
      }

      // Draw Ground now!
      this.drawGround(ctx);

      // Increasing speed based on points
      if (mit.score > 200 && !this.first_speed_inc) {
        this.cloud_bg_move_speed++;
        this.backtree_bg_move_speed++;
        this.fronttree_bg_move_speed++;
        this.ground_bg_move_speed++;
        this.combined_bg_move_speed++;

        this.first_speed_inc = 1;
      }

      if (mit.score > 1000 && !this.second_speed_inc) {
        this.cloud_bg_move_speed++;
        this.backtree_bg_move_speed++;
        this.fronttree_bg_move_speed++;
        this.ground_bg_move_speed++;
        this.combined_bg_move_speed++;

        this.second_speed_inc = 1;
      }

      if (mit.score > 3000 && !this.third_speed_inc) {
        this.cloud_bg_move_speed++;
        this.backtree_bg_move_speed++;
        this.fronttree_bg_move_speed++;
        this.ground_bg_move_speed++;
        this.combined_bg_move_speed++;

        this.third_speed_inc = 1;
      }

    }

  };

}());<commit_msg>fixing weir bugs in IE and Opera<commit_after>(function() {

  mit.Backgrounds = {

    // Speeds and Velocities of Backgrounds
    common_bg_speed: 1,

    cloud_bg_move_speed: 2,
    cloud_bg_vx: 0,

    backtree_bg_move_speed: 3,
    backtree_bg_vx: 0,

    fronttree_bg_move_speed: 5,
    fronttree_bg_vx: 0,

    ground_bg_move_speed: 7,
    ground_bg_vx: 0,

    grass_bg_move_speed: 7,
    grass_bg_vx: 0,

    combined_bg_move_speed: 3,
    combined_bg_vx: 0,

    log_x: 40,
    log_y: 0,

    sky_gradient: {},

    first_speed_inc: 0,
    second_speed_inc: 0,
    third_speed_inc: 0,

    init: function(ctx) {
      // Sky Gradient
      this.sky_gradient = ctx.createLinearGradient(0, 0, 0, mit.H);
      this.sky_gradient.addColorStop(0, '#06c4f4');
      this.sky_gradient.addColorStop(1, '#7bd4f6');

      // Clouds
      // this.cloud_img = new Image();
      // this.cloud_img.src = 'img/clouds.png';
      this.cloud_img = mit.image.clouds;

      this.cloud_img.width = mit.W;
      this.cloud_img.height = mit.H;

      // Back Trees
      // this.backtree_img = new Image();
      // this.backtree_img.src = 'img/back_trees.png';
      this.backtree_img = mit.image.backtrees;

      this.backtree_img.width = mit.W;
      this.backtree_img.height = mit.H;

      // Front Trees
      // this.fronttree_img = new Image();
      // this.fronttree_img.src = 'img/front_trees.png';
      this.fronttree_img = mit.image.fronttrees;

      this.fronttree_img.width = mit.W;
      this.fronttree_img.height = mit.H;

      // Ground
      // this.ground_img = new Image();
      // this.ground_img.src = 'img/ground.png';
      this.ground_img = mit.image.ground;

      this.ground_img.width = mit.W;
      this.ground_img.height = mit.H;

      // Grass
      // this.grass_img = new Image();
      // this.grass_img.src = 'img/grass.png';
      this.grass_img = mit.image.grass;

      this.grass_img.width = mit.W;
      this.grass_img.height = mit.H;

      // Log on which pappu sits
      // this.log_img = new Image();
      // this.log_img.src = 'img/log.png';
      this.log_img = mit.image.log;

      // Combined BG Image
      // this.combined_bg_img = new Image();
      // this.combined_bg_img.src = 'img/bg_combined.png';
      this.combined_bg_img = mit.image.bg_combined;
    },

    drawClouds: function(ctx) {
      var cloud_bg_vx_abs = Math.abs(this.cloud_bg_vx);

      // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE
      try {
        ctx.drawImage(
          this.cloud_img,

          cloud_bg_vx_abs,
          0,
          mit.W + this.cloud_bg_vx,
          mit.H,

          0, 0,
          mit.W + this.cloud_bg_vx,
          mit.H
        );

        ctx.drawImage(
          this.cloud_img,

          0, 0,
          cloud_bg_vx_abs,
          mit.H,

          mit.W + this.cloud_bg_vx,
          0,
          cloud_bg_vx_abs,
          mit.H
        );
      }
      catch(e) {}
      this.cloud_bg_vx -= this.cloud_bg_move_speed;

      if (-this.cloud_bg_vx >= mit.W) {
        this.cloud_bg_vx = 0;
      }

      return;
    },

    drawBackTrees: function(ctx) {
      var backtree_bg_vx_abs = Math.abs(this.backtree_bg_vx);

      // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE
      try {
        ctx.drawImage(
          this.backtree_img,

          backtree_bg_vx_abs,
          0,
          mit.W + this.backtree_bg_vx,
          mit.H,

          0, 0,
          mit.W + this.backtree_bg_vx,
          mit.H
        );

        ctx.drawImage(
          this.backtree_img,

          0, 0,
          backtree_bg_vx_abs,
          mit.H,

          mit.W + this.backtree_bg_vx,
          0,
          backtree_bg_vx_abs,
          mit.H
        );
      }
      catch(e) {}

      if (mit.game_started)
        this.backtree_bg_vx -= this.backtree_bg_move_speed * this.common_bg_speed;

      if (-this.backtree_bg_vx >= mit.W) {
        this.backtree_bg_vx = 0;
      }

      return;
    },

    drawFrontTrees: function(ctx) {
      var fronttree_bg_vx_abs = Math.abs(this.fronttree_bg_vx);

      // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE
      try {
        ctx.drawImage(
          this.fronttree_img,

          fronttree_bg_vx_abs,
          0,
          mit.W + this.fronttree_bg_vx,
          mit.H,

          0, 0,
          mit.W + this.fronttree_bg_vx,
          mit.H
        );

        ctx.drawImage(
          this.fronttree_img,

          0, 0,
          fronttree_bg_vx_abs,
          mit.H,

          mit.W + this.fronttree_bg_vx,
          0,
          fronttree_bg_vx_abs,
          mit.H
        );
      }
      catch(e) {}
      if (mit.game_started)
        this.fronttree_bg_vx -= this.fronttree_bg_move_speed * this.common_bg_speed;

      if (-this.fronttree_bg_vx >= mit.W) {
        this.fronttree_bg_vx = 0;
      }

      return;
    },

    drawGround: function(ctx) {
      var ground_bg_vx_abs = Math.abs(this.ground_bg_vx);
      // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE
      try {
        ctx.drawImage(
          this.ground_img,

          ground_bg_vx_abs,
          0,
          mit.W + this.ground_bg_vx,
          mit.H,

          0, 0,
          mit.W + this.ground_bg_vx,
          mit.H
        );

        ctx.drawImage(
          this.ground_img,

          0, 0,
          ground_bg_vx_abs,
          mit.H,

          mit.W + this.ground_bg_vx,
          0,
          ground_bg_vx_abs,
          mit.H
        );
      }
      catch(e) {}

      if (mit.game_started)
        this.ground_bg_vx -= this.ground_bg_move_speed * this.common_bg_speed;

      if (-this.ground_bg_vx >= mit.W) {
        this.ground_bg_vx = 0;
      }

      // console.log(-this.ground_bg_vx);

      return;
    },

    drawGrass: function(ctx) {
      var grass_bg_vx_abs = Math.abs(this.grass_bg_vx);
      // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE
      try {
        ctx.drawImage(
          this.grass_img,

          grass_bg_vx_abs,
          0,
          mit.W + this.grass_bg_vx,
          mit.H,

          0, 0,
          mit.W + this.grass_bg_vx,
          mit.H
        );

        ctx.drawImage(
          this.grass_img,

          0, 0,
          grass_bg_vx_abs,
          mit.H,

          mit.W + this.grass_bg_vx,
          0,
          grass_bg_vx_abs,
          mit.H
        );
      }
      catch(e) {}

      if (mit.game_started)
        this.grass_bg_vx -= this.grass_bg_move_speed * this.common_bg_speed;

      if (-this.grass_bg_vx >= mit.W) {
        this.grass_bg_vx = 0;
      }

      return;
    },

    drawInitLog: function(ctx) {

      this.log_y = mit.H-(this.log_img.height+45);

      ctx.drawImage(this.log_img, this.log_x, this.log_y);

      if (mit.game_started) {
        this.log_x -= this.grass_bg_move_speed * this.common_bg_speed;
      }
    },

    drawCombinedBG: function(ctx) {
      var combined_bg_vx_abs = Math.abs(this.combined_bg_vx);
      // fixing weird indexSizeError bugs for the most nonsensical browsers - opera and IE
      try {
        ctx.drawImage(
          this.combined_bg_img,

          combined_bg_vx_abs,
          0,
          mit.W + this.combined_bg_vx,
          mit.H,

          0, 0,
          mit.W + this.combined_bg_vx,
          mit.H
        );

        ctx.drawImage(
          this.combined_bg_img,

          0, 0,
          combined_bg_vx_abs,
          mit.H,

          mit.W + this.combined_bg_vx,
          0,
          combined_bg_vx_abs,
          mit.H
        );
      }
      catch(e) {}

      if (mit.game_started)
        this.combined_bg_vx -= this.combined_bg_move_speed * this.common_bg_speed;

      if (-this.combined_bg_vx >= mit.W) {
        this.combined_bg_vx = 0;
      }
    },

    // Draw Awesome Backgrounds
    // Backgrounds have been made for 1000x500 dimensions
    draw: function(ctx) {

      if (mit.start_btn_clicked) {
        if (!this.fps || this.fps === 5000)
          this.fps = mit.fps;
      }
      else {
        this.fps = 5000;
      }

      if (this.fps > 56) {

        // Draw Linear Gradient for real/pure BG (sky/water)
        ctx.save();
        ctx.fillStyle = this.sky_gradient;
        ctx.fillRect(0, 0, mit.W, mit.H);
        ctx.restore();

        // Clouds
        this.drawClouds(ctx);

        // Back Small Trees
        this.drawBackTrees(ctx);

        // Front Big Trees
        this.drawFrontTrees(ctx);
      }
      else {
        this.drawCombinedBG(ctx);
      }

      // Drawing the initial wood log on which
      // Pappu gonna sit and bask in the cool and cozy
      // environment.
      if (this.log_x+100 > 0) {
        this.drawInitLog(ctx);
      }
      else if (!mit.game_started) {
        this.log_x = 40;
      }

      // Draw Ground now!
      this.drawGround(ctx);

      // Increasing speed based on points
      if (mit.score > 200 && !this.first_speed_inc) {
        this.cloud_bg_move_speed++;
        this.backtree_bg_move_speed++;
        this.fronttree_bg_move_speed++;
        this.ground_bg_move_speed++;
        this.combined_bg_move_speed++;

        this.first_speed_inc = 1;
      }

      if (mit.score > 1000 && !this.second_speed_inc) {
        this.cloud_bg_move_speed++;
        this.backtree_bg_move_speed++;
        this.fronttree_bg_move_speed++;
        this.ground_bg_move_speed++;
        this.combined_bg_move_speed++;

        this.second_speed_inc = 1;
      }

      if (mit.score > 3000 && !this.third_speed_inc) {
        this.cloud_bg_move_speed++;
        this.backtree_bg_move_speed++;
        this.fronttree_bg_move_speed++;
        this.ground_bg_move_speed++;
        this.combined_bg_move_speed++;

        this.third_speed_inc = 1;
      }

    }

  };

}());<|endoftext|>


<commit_before>var karmaBaseConf = require('./karma.base.conf')

var browsers = {
  sl_chrome: {
    base: 'SauceLabs',
    browserName: 'chrome',
    platform: 'Windows 10',
    version: '50.0'
  },
  sl_firefox: {
    base: 'SauceLabs',
    browserName: 'firefox',
    platform: 'Windows 10',
    version: '46.0'
  },
  sl_ie_11: {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 10',
    version: '11.103'
  }/*,
  sl_edge: {
    base: 'SauceLabs',
    browserName: 'MicrosoftEdge',
    platform: 'Windows 10',
    version: '13.10586'
  }
  */
}

module.exports = function (config) {
  karmaBaseConf.plugins.push(require('karma-sauce-launcher'))
  karmaBaseConf.reporters.push('saucelabs')
  karmaBaseConf.logLevel = config.LOG_DEBUG
  karmaBaseConf.customLaunchers = browsers
  karmaBaseConf.captureTimeout = 200000
  karmaBaseConf.browserDisconnectTolerance = 3
  karmaBaseConf.concurrency = 5
  karmaBaseConf.browsers = Object.keys(browsers)
  karmaBaseConf.sauceLabs = {
    // Should be false for running on travis, as travis already starts its own
    // sauce connect
    startConnect: false,
    // https://github.com/karma-runner/karma-sauce-launcher/issues/73
    tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER
  }

  config.set(karmaBaseConf)
}
<commit_msg>chore: Reactivate Edge tests<commit_after>var karmaBaseConf = require('./karma.base.conf')

var browsers = {
  sl_chrome: {
    base: 'SauceLabs',
    browserName: 'chrome',
    platform: 'Windows 10',
    version: '50.0'
  },
  sl_firefox: {
    base: 'SauceLabs',
    browserName: 'firefox',
    platform: 'Windows 10',
    version: '46.0'
  },
  sl_ie_11: {
    base: 'SauceLabs',
    browserName: 'internet explorer',
    platform: 'Windows 10',
    version: '11.103'
  },
  sl_edge: {
    base: 'SauceLabs',
    browserName: 'MicrosoftEdge',
    platform: 'Windows 10',
    version: '13.10586'
  }
}

module.exports = function (config) {
  karmaBaseConf.plugins.push(require('karma-sauce-launcher'))
  karmaBaseConf.reporters.push('saucelabs')
  karmaBaseConf.logLevel = config.LOG_DEBUG
  karmaBaseConf.customLaunchers = browsers
  karmaBaseConf.captureTimeout = 200000
  karmaBaseConf.browserDisconnectTolerance = 3
  karmaBaseConf.concurrency = 5
  karmaBaseConf.browsers = Object.keys(browsers)
  karmaBaseConf.sauceLabs = {
    // Should be false for running on travis, as travis already starts its own
    // sauce connect
    startConnect: false,
    // https://github.com/karma-runner/karma-sauce-launcher/issues/73
    tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER
  }

  config.set(karmaBaseConf)
}
<|endoftext|>