<commit_before>/*
 * grunt-release
 * https://github.com/geddski/grunt-release
 *
 * Copyright (c) 2013 Dave Geddes
 * Licensed under the MIT license.
 */

var shell = require('shelljs');
var semver = require('semver');

module.exports = function(grunt){
  grunt.registerTask('release', 'bump version, git tag, git push, npm publish', function(type){
    //defaults
    var options = this.options({
      bump: true,
      file: grunt.config('pkgFile') || 'package.json',
      add: true,
      commit: true,
      tag: true,
      push: true,
      pushTags: true,
      npm : true
    });

    var tagName = grunt.config.getRaw('release.options.tagName') || '<%= version %>';
    var commitMessage = grunt.config.getRaw('release.options.commitMessage') || 'release <%= version %>';
    var tagMessage = grunt.config.getRaw('release.options.tagMessage') || 'version <%= version %>';

    var config = setup(options.file, type);
    var templateOptions = {
      data: {
        version: config.newVersion
      }
    };

    if (options.bump) bump(config);
    if (options.add) add(config);
    if (options.commit) commit(config);
    if (options.tag) tag(config);
    if (options.push) push();
    if (options.pushTags) pushTags(config);
    if (options.npm) publish(config);

    function setup(file, type){
      var pkg = grunt.file.readJSON(file);
      var newVersion = pkg.version;
      if (options.bump) {
        newVersion = semver.inc(pkg.version, type || 'patch');
      }
      return {file: file, pkg: pkg, newVersion: newVersion};
    }

    function add(config){
      run('git add ' + config.file);
    }

    function commit(config){
      var message = grunt.template.process(commitMessage, templateOptions);
      run('git commit '+ config.file +' -m "'+ message +'"', config.file + ' committed');
    }

    function tag(config){
      var name = grunt.template.process(tagName, templateOptions);
      var message = grunt.template.process(tagMessage, templateOptions);
      run('git tag ' + name + ' -m "'+ message +'"', 'New git tag created: ' + name);
    }

    function push(){
      run('git push', 'pushed to remote');
    }

    function pushTags(config){
      run('git push --tags', 'pushed new tag '+ config.newVersion +' to remote');
    }

    function publish(config){
      var cmd = 'npm publish';
      var msg = 'published '+ config.newVersion +' to npm';
      var npmtag = getNpmTag();
      if (npmtag){
        cmd += ' --tag ' + npmtag;
        msg += ' with a tag of "' + npmtag + '"';
      }
      if (options.folder){ cmd += ' ' + options.folder }
      run(cmd, msg);
    }

    function getNpmTag(){
      var tag = grunt.option('npmtag') || options.npmtag;
      if(tag === true) { tag = config.newVersion }
      return tag;
    }

    function run(cmd, msg){
      var nowrite = grunt.option('no-write');
      if (nowrite) {
        grunt.verbose.writeln('Not actually running: ' + cmd);
      }
      else {
        grunt.verbose.writeln('Running: ' + cmd);
        shell.exec(cmd, {silent:true});
      }

      if (msg) grunt.log.ok(msg);
    }

    function bump(config){
      config.pkg.version = config.newVersion;
      grunt.file.write(config.file, JSON.stringify(config.pkg, null, '  ') + '\n');
      grunt.log.ok('Version bumped to ' + config.newVersion);
    }

  });
};
<commit_msg>refactor variables for use in multiple steps<commit_after>/*
 * grunt-release
 * https://github.com/geddski/grunt-release
 *
 * Copyright (c) 2013 Dave Geddes
 * Licensed under the MIT license.
 */

var shell = require('shelljs');
var semver = require('semver');

module.exports = function(grunt){
  grunt.registerTask('release', 'bump version, git tag, git push, npm publish', function(type){

    //defaults
    var options = this.options({
      bump: true,
      file: grunt.config('pkgFile') || 'package.json',
      add: true,
      commit: true,
      tag: true,
      push: true,
      pushTags: true,
      npm : true
    });

    var config = setup(options.file, type);
    var templateOptions = {
      data: {
        version: config.newVersion
      }
    };
    var tagName = grunt.template.process(grunt.config.getRaw('release.options.tagName') || '<%= version %>', templateOptions);
    var commitMessage = grunt.template.process(grunt.config.getRaw('release.options.commitMessage') || 'release <%= version %>', templateOptions);
    var tagMessage = grunt.template.process(grunt.config.getRaw('release.options.tagMessage') || 'version <%= version %>', templateOptions);
    var nowrite = grunt.option('no-write');
    var task = this;

    if (options.bump) bump(config);
    if (options.add) add(config);
    if (options.commit) commit(config);
    if (options.tag) tag(config);
    if (options.push) push();
    if (options.pushTags) pushTags(config);
    if (options.npm) publish(config);

    function setup(file, type){
      var pkg = grunt.file.readJSON(file);
      var newVersion = pkg.version;
      if (options.bump) {
        newVersion = semver.inc(pkg.version, type || 'patch');
      }
      return {file: file, pkg: pkg, newVersion: newVersion};
    }

    function add(config){
      run('git add ' + config.file);
    }

    function commit(config){
      run('git commit '+ config.file +' -m "'+ commitMessage +'"', config.file + ' committed');
    }

    function tag(config){
      run('git tag ' + tagName + ' -m "'+ tagMessage +'"', 'New git tag created: ' + tagName);
    }

    function push(){
      run('git push', 'pushed to remote');
    }

    function pushTags(config){
      run('git push --tags', 'pushed new tag '+ config.newVersion +' to remote');
    }

    function publish(config){
      var cmd = 'npm publish';
      var msg = 'published '+ config.newVersion +' to npm';
      var npmtag = getNpmTag();
      if (npmtag){
        cmd += ' --tag ' + npmtag;
        msg += ' with a tag of "' + npmtag + '"';
      }
      if (options.folder){ cmd += ' ' + options.folder }
      run(cmd, msg);
    }

    function getNpmTag(){
      var tag = grunt.option('npmtag') || options.npmtag;
      if(tag === true) { tag = config.newVersion }
      return tag;
    }

    function run(cmd, msg){
      if (nowrite) {
        grunt.verbose.writeln('Not actually running: ' + cmd);
      }
      else {
        grunt.verbose.writeln('Running: ' + cmd);
        shell.exec(cmd, {silent:true});
      }

      if (msg) grunt.log.ok(msg);
    }

    function bump(config){
      config.pkg.version = config.newVersion;
      grunt.file.write(config.file, JSON.stringify(config.pkg, null, '  ') + '\n');
      grunt.log.ok('Version bumped to ' + config.newVersion);
    }

  });
};
<|endoftext|>


<commit_before>// @flow
import React, { Component } from 'react';
import { View, StyleSheet, Linking } from 'react-native';
import { isEqual } from 'lodash';
import ActionSheet from '@yfuks/react-native-action-sheet';
import { Text, Card, Button } from '../../components';
import appStyle from '../../appStyle';
import MemberIcon from './MemberIcon';
import PointsBadge from './PointsBadge';
import { Analytics } from '../../services';
import type { CardType } from '../../types';
import { differenceInBusinessDays } from '../../services/Time';
import Icon from '../Icon';

export default class extends Component<Props> {
  shouldComponentUpdate(nextProps: Props) {
    return !isEqual(nextProps.card, this.props.card);
  }

  showActionSheet = () => {
    Analytics.logEvent('card_actionSheet_trigger'); // how curious are users?
    ActionSheet.showActionSheetWithOptions(
      {
        options: ['Open in Trello', 'Cancel'],
        cancelButtonIndex: 1,
      },
      index => {
        switch (index) {
          case 0:
            Linking.openURL(this.props.card.url).catch(e => console.error('Error opening URL', e));
            break;
          default:
            break;
        }
      }
    );
  };

  render() {
    const { card } = this.props;
    const validationLatenessInDays =
      card.dateEndDevelopment && differenceInBusinessDays(card.dateDone || Date.now(), card.dateEndDevelopment);

    return (
      <Button style={this.props.style} onLongPress={this.showActionSheet}>
        <View>
          <Card>
            <View style={styles.labelsRow}>
              <View style={styles.idShortContainer}>
                <Text>#{card.idShort}</Text>
              </View>
              {validationLatenessInDays > 1 && (
                <View style={styles.lateValidationContainer}>
                  <Text style={styles.lateValidationText}>{validationLatenessInDays}</Text>
                  <Icon
                    type="material-community"
                    name="clock-alert"
                    size={appStyle.font.size.default}
                    color={appStyle.colors.overRed}
                  />
                </View>
              )}
            </View>
            <Text style={styles.title}>{card.name}</Text>
            <View style={styles.membersRow}>
              <View style={styles.pointsContainer}>
                {card.points != null && <PointsBadge points={card.points.toLocaleString()} />}
                {card.points != null && card.postPoints != null && <View style={{ width: 4 }} />}
                {card.postPoints != null && <PointsBadge points={card.postPoints.toLocaleString()} isPostEstimation />}
              </View>
              <View style={styles.membersContainer}>
                <View style={styles.members}>
                  {card.members.map(member => (
                    <View key={member.id} style={styles.member}>
                      <MemberIcon member={member} />
                    </View>
                  ))}
                </View>
              </View>
            </View>
          </Card>
        </View>
      </Button>
    );
  }
}

const styles = StyleSheet.create({
  labelsRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  membersRow: {
    flexDirection: 'row',
  },
  title: {
    marginVertical: appStyle.margin,
  },
  membersContainer: {
    flex: 5,
    alignSelf: 'flex-end',
    justifyContent: 'flex-end',
  },
  members: {
    flexDirection: 'row',
    alignSelf: 'flex-end',
    justifyContent: 'flex-end',
  },
  member: {
    marginLeft: 5,
  },
  idShortContainer: {
    backgroundColor: appStyle.colors.secondary,
    justifyContent: 'center',
    alignItems: 'center',
    paddingHorizontal: 7,
    borderRadius: appStyle.borderRadius,
  },
  lateValidationContainer: {
    flexDirection: 'row',
    backgroundColor: appStyle.colors.red,
    justifyContent: 'center',
    alignItems: 'center',
    paddingHorizontal: 7,
    borderRadius: appStyle.borderRadius,
  },
  lateValidationText: {
    marginRight: 2,
    color: appStyle.colors.overRed,
  },
  pointsContainer: {
    flex: 1,
    flexDirection: 'row',
    flexShrink: 1,
    alignItems: 'flex-end',
  },
});

type Props = {
  card: CardType,
  style?: any,
};
<commit_msg>Fix width of the TrelloCards' row with points and members<commit_after>// @flow
import React, { Component } from 'react';
import { View, StyleSheet, Linking } from 'react-native';
import { isEqual } from 'lodash';
import ActionSheet from '@yfuks/react-native-action-sheet';
import { Text, Card, Button } from '../../components';
import appStyle from '../../appStyle';
import MemberIcon from './MemberIcon';
import PointsBadge from './PointsBadge';
import { Analytics } from '../../services';
import type { CardType } from '../../types';
import { differenceInBusinessDays } from '../../services/Time';
import Icon from '../Icon';

export default class extends Component<Props> {
  shouldComponentUpdate(nextProps: Props) {
    return !isEqual(nextProps.card, this.props.card);
  }

  showActionSheet = () => {
    Analytics.logEvent('card_actionSheet_trigger'); // how curious are users?
    ActionSheet.showActionSheetWithOptions(
      {
        options: ['Open in Trello', 'Cancel'],
        cancelButtonIndex: 1,
      },
      index => {
        switch (index) {
          case 0:
            Linking.openURL(this.props.card.url).catch(e => console.error('Error opening URL', e));
            break;
          default:
            break;
        }
      }
    );
  };

  render() {
    const { card } = this.props;
    const validationLatenessInDays =
      card.dateEndDevelopment && differenceInBusinessDays(card.dateDone || Date.now(), card.dateEndDevelopment);

    return (
      <Button style={this.props.style} onLongPress={this.showActionSheet}>
        <View>
          <Card>
            <View style={styles.labelsRow}>
              <View style={styles.idShortContainer}>
                <Text>#{card.idShort}</Text>
              </View>
              {validationLatenessInDays > 1 && (
                <View style={styles.lateValidationContainer}>
                  <Text style={styles.lateValidationText}>{validationLatenessInDays}</Text>
                  <Icon
                    type="material-community"
                    name="clock-alert"
                    size={appStyle.font.size.default}
                    color={appStyle.colors.overRed}
                  />
                </View>
              )}
            </View>
            <Text style={styles.title}>{card.name}</Text>
            <View style={styles.membersRow}>
              <View style={styles.pointsContainer}>
                {card.points != null && <PointsBadge points={card.points.toLocaleString()} />}
                {card.points != null && card.postPoints != null && <View style={{ width: 4 }} />}
                {card.postPoints != null && <PointsBadge points={card.postPoints.toLocaleString()} isPostEstimation />}
              </View>
              <View style={styles.membersContainer}>
                <View style={styles.members}>
                  {card.members.map(member => (
                    <View key={member.id} style={styles.member}>
                      <MemberIcon member={member} />
                    </View>
                  ))}
                </View>
              </View>
            </View>
          </Card>
        </View>
      </Button>
    );
  }
}

const styles = StyleSheet.create({
  labelsRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  membersRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  title: {
    marginVertical: appStyle.margin,
  },
  membersContainer: {
    alignSelf: 'flex-end',
  },
  members: {
    flexDirection: 'row',
    alignSelf: 'flex-end',
    justifyContent: 'flex-end',
  },
  member: {
    marginLeft: 5,
  },
  idShortContainer: {
    backgroundColor: appStyle.colors.secondary,
    justifyContent: 'center',
    alignItems: 'center',
    paddingHorizontal: 7,
    borderRadius: appStyle.borderRadius,
  },
  lateValidationContainer: {
    flexDirection: 'row',
    backgroundColor: appStyle.colors.red,
    justifyContent: 'center',
    alignItems: 'center',
    paddingHorizontal: 7,
    borderRadius: appStyle.borderRadius,
  },
  lateValidationText: {
    marginRight: 2,
    color: appStyle.colors.overRed,
  },
  pointsContainer: {
    flexDirection: 'row',
    alignItems: 'flex-end',
  },
});

type Props = {
  card: CardType,
  style?: any,
};
<|endoftext|>


<commit_before>var http = require('http'),
    sys = require('sys'),
    posix = require('posix');

function extname(path) {
    var index = path.lastIndexOf('.');
    return index < 0 ? '' : path.substring(index);
}

exports.serveFile = function(req, res, filename) {
    // TODO: Ensure security against directory traversal attacks
    var body, headers;
    var content_type = mime.lookup(extname(filename));
    var encoding = (content_type.slice(0,4) === 'text' ? 'utf8' : 'binary');
    var status = 200;

    function loadResponseData(callback) {
        if (body && headers) {
            callback();
            return;
        }
        sys.puts("loading " + filename + "...");
        var promise = posix.cat(filename, encoding);
        promise.addCallback(function(data) {
            body = data;
            headers = [
                ['Content-Type', content_type],
                ['Content-Length', encoding === 'utf8' ? encodeURIComponent(body).replace(/%../g, 'x').length : body.length]
            ];
            sys.puts("static file " + filename + " loaded");
            callback();
        });
        promise.addErrback(function() {
            status = 404;
            body = '404'
            sys.puts("Error loading " + filename);
            callback();
        });
    }
    loadResponseData(function() {
        res.sendHeader(status, headers);
        res.sendBody(body, encoding);
        res.finish();
    });
}

exports.serve = function(app, port) {
    sys.puts('Server on http://127.0.0.1:' + port + '/');
    return http.createServer(app).listen(port);
}

function respond(res, body, content_type, status) {
    content_type = content_type || 'text/html';
    res.sendHeader(status || 200, {
        'Content-Type': content_type  + '; charset=utf-8'
    });
    res.sendBody(body);
    res.finish();
}
exports.respond = respond;

exports.redirect = redirect = function(res, location, status) {
    status = status || 301;
    res.sendHeader(status || 200, {
        'Content-Type': 'text/html; charset=utf-8',
        'Location': location
    });
    res.sendBody('Redirecting...');
    res.finish();
}

exports.extractPost = function(req, callback) {
    req.setBodyEncoding('utf-8');
    var body = '';
    req.addListener('body', function(chunk) {
        body += chunk;
    });
    req.addListener('complete', function() {
        callback(http.parseUri('http://fake/?' + body).params);
    });
}

var debuginfo = {}
exports.debuginfo = debuginfo;

exports.makeApp = function(urls, options) {
    // Compile the regular expressions
    var compiled = urls.map(function(pair) {
        return [new RegExp(pair[0]), pair[1]];
    });
    options = options || {};
    var show_404 = (options.show_404 || default_show_404);
    var show_500 = (options.show_500 || default_show_500);
    return function(req, res) {
        debuginfo.last_request = req;
        debuginfo.last_response = res;
        var path = req.uri.path;
        var view = show_404;
        var args = [req, res];
        for (var pair, i = 0; pair = compiled[i]; i++) {
            //sys.puts("Matching " + pair[0] + " against path " + path);
            var match = pair[0](path);
            if (match) {
                //sys.puts("  matched! " + match);
                // Add matched bits to args
                match.slice(1).forEach(function(arg) {
                    args.push(arg);
                });
                view = pair[1];
                break;
            }
        }
        try {
            view.apply(null, args);
        } catch (e) {
            debuginfo.last_e = e;
            show_500(req, res, e);
        }
    }
}

function default_show_404(req, res) {
    respond(res,
        '
404
', 'text/html', 404
    );
}
exports.default_show_404 = default_show_404

function default_show_500(req, res, e) {
    var msg = ''
    if ('stack' in e && 'type' in e) {
        msg = (
            '
' + e.type + '

' +
            e.stack + '
'
        );
    } else {
        msg = JSON.stringify(e, 0, 2);
    }
    respond(res, '
500
' + msg, 'text/html', 500);
}
exports.default_show_500 = default_show_500

exports.mime = mime = {
    lookup : function(ext, fallback) {
        return mime.types[ext.toLowerCase()] || fallback || mime.default_type;
    },
    default_type: 'application/octet-stream',
    types: {
        ".3gp"   : "video/3gpp",
        ".a"     : "application/octet-stream",
        ".ai"    : "application/postscript",
        ".aif"   : "audio/x-aiff",
        ".aiff"  : "audio/x-aiff",
        ".asc"   : "application/pgp-signature",
        ".asf"   : "video/x-ms-asf",
        ".asm"   : "text/x-asm",
        ".asx"   : "video/x-ms-asf",
        ".atom"  : "application/atom+xml",
        ".au"    : "audio/basic",
        ".avi"   : "video/x-msvideo",
        ".bat"   : "application/x-msdownload",
        ".bin"   : "application/octet-stream",
        ".bmp"   : "image/bmp",
        ".bz2"   : "application/x-bzip2",
        ".c"     : "text/x-c",
        ".cab"   : "application/vnd.ms-cab-compressed",
        ".cc"    : "text/x-c",
        ".chm"   : "application/vnd.ms-htmlhelp",
        ".class" : "application/octet-stream",
        ".com"   : "application/x-msdownload",
        ".conf"  : "text/plain",
        ".cpp"   : "text/x-c",
        ".crt"   : "application/x-x509-ca-cert",
        ".css"   : "text/css",
        ".csv"   : "text/csv",
        ".cxx"   : "text/x-c",
        ".deb"   : "application/x-debian-package",
        ".der"   : "application/x-x509-ca-cert",
        ".diff"  : "text/x-diff",
        ".djv"   : "image/vnd.djvu",
        ".djvu"  : "image/vnd.djvu",
        ".dll"   : "application/x-msdownload",
        ".dmg"   : "application/octet-stream",
        ".doc"   : "application/msword",
        ".dot"   : "application/msword",
        ".dtd"   : "application/xml-dtd",
        ".dvi"   : "application/x-dvi",
        ".ear"   : "application/java-archive",
        ".eml"   : "message/rfc822",
        ".eps"   : "application/postscript",
        ".exe"   : "application/x-msdownload",
        ".f"     : "text/x-fortran",
        ".f77"   : "text/x-fortran",
        ".f90"   : "text/x-fortran",
        ".flv"   : "video/x-flv",
        ".for"   : "text/x-fortran",
        ".gem"   : "application/octet-stream",
        ".gemspec": "text/x-script.ruby",
        ".gif"   : "image/gif",
        ".gz"    : "application/x-gzip",
        ".h"     : "text/x-c",
        ".hh"    : "text/x-c",
        ".htm"   : "text/html",
        ".html"  : "text/html",
        ".ico"   : "image/vnd.microsoft.icon",
        ".ics"   : "text/calendar",
        ".ifb"   : "text/calendar",
        ".iso"   : "application/octet-stream",
        ".jar"   : "application/java-archive",
        ".java"  : "text/x-java-source",
        ".jnlp"  : "application/x-java-jnlp-file",
        ".jpeg"  : "image/jpeg",
        ".jpg"   : "image/jpeg",
        ".js"    : "application/javascript",
        ".json"  : "application/json",
        ".log"   : "text/plain",
        ".m3u"   : "audio/x-mpegurl",
        ".m4v"   : "video/mp4",
        ".man"   : "text/troff",
        ".mathml"  : "application/mathml+xml",
        ".mbox"  : "application/mbox",
        ".mdoc"  : "text/troff",
        ".me"    : "text/troff",
        ".mid"   : "audio/midi",
        ".midi"  : "audio/midi",
        ".mime"  : "message/rfc822",
        ".mml"   : "application/mathml+xml",
        ".mng"   : "video/x-mng",
        ".mov"   : "video/quicktime",
        ".mp3"   : "audio/mpeg",
        ".mp4"   : "video/mp4",
        ".mp4v"  : "video/mp4",
        ".mpeg"  : "video/mpeg",
        ".mpg"   : "video/mpeg",
        ".ms"    : "text/troff",
        ".msi"   : "application/x-msdownload",
        ".odp"   : "application/vnd.oasis.opendocument.presentation",
        ".ods"   : "application/vnd.oasis.opendocument.spreadsheet",
        ".odt"   : "application/vnd.oasis.opendocument.text",
        ".ogg"   : "application/ogg",
        ".p"     : "text/x-pascal",
        ".pas"   : "text/x-pascal",
        ".pbm"   : "image/x-portable-bitmap",
        ".pdf"   : "application/pdf",
        ".pem"   : "application/x-x509-ca-cert",
        ".pgm"   : "image/x-portable-graymap",
        ".pgp"   : "application/pgp-encrypted",
        ".pkg"   : "application/octet-stream",
        ".pl"    : "text/x-script.perl",
        ".pm"    : "text/x-script.perl-module",
        ".png"   : "image/png",
        ".pnm"   : "image/x-portable-anymap",
        ".ppm"   : "image/x-portable-pixmap",
        ".pps"   : "application/vnd.ms-powerpoint",
        ".ppt"   : "application/vnd.ms-powerpoint",
        ".ps"    : "application/postscript",
        ".psd"   : "image/vnd.adobe.photoshop",
        ".py"    : "text/x-script.python",
        ".qt"    : "video/quicktime",
        ".ra"    : "audio/x-pn-realaudio",
        ".rake"  : "text/x-script.ruby",
        ".ram"   : "audio/x-pn-realaudio",
        ".rar"   : "application/x-rar-compressed",
        ".rb"    : "text/x-script.ruby",
        ".rdf"   : "application/rdf+xml",
        ".roff"  : "text/troff",
        ".rpm"   : "application/x-redhat-package-manager",
        ".rss"   : "application/rss+xml",
        ".rtf"   : "application/rtf",
        ".ru"    : "text/x-script.ruby",
        ".s"     : "text/x-asm",
        ".sgm"   : "text/sgml",
        ".sgml"  : "text/sgml",
        ".sh"    : "application/x-sh",
        ".sig"   : "application/pgp-signature",
        ".snd"   : "audio/basic",
        ".so"    : "application/octet-stream",
        ".svg"   : "image/svg+xml",
        ".svgz"  : "image/svg+xml",
        ".swf"   : "application/x-shockwave-flash",
        ".t"     : "text/troff",
        ".tar"   : "application/x-tar",
        ".tbz"   : "application/x-bzip-compressed-tar",
        ".tcl"   : "application/x-tcl",
        ".tex"   : "application/x-tex",
        ".texi"  : "application/x-texinfo",
        ".texinfo" : "application/x-texinfo",
        ".text"  : "text/plain",
        ".tif"   : "image/tiff",
        ".tiff"  : "image/tiff",
        ".torrent" : "application/x-bittorrent",
        ".tr"    : "text/troff",
        ".txt"   : "text/plain",
        ".vcf"   : "text/x-vcard",
        ".vcs"   : "text/x-vcalendar",
        ".vrml"  : "model/vrml",
        ".war"   : "application/java-archive",
        ".wav"   : "audio/x-wav",
        ".wma"   : "audio/x-ms-wma",
        ".wmv"   : "video/x-ms-wmv",
        ".wmx"   : "video/x-ms-wmx",
        ".wrl"   : "model/vrml",
        ".wsdl"  : "application/wsdl+xml",
        ".xbm"   : "image/x-xbitmap",
        ".xhtml"   : "application/xhtml+xml",
        ".xls"   : "application/vnd.ms-excel",
        ".xml"   : "application/xml",
        ".xpm"   : "image/x-xpixmap",
        ".xsl"   : "application/xml",
        ".xslt"  : "application/xslt+xml",
        ".yaml"  : "text/yaml",
        ".yml"   : "text/yaml",
        ".zip"   : "application/zip"
    }
};
<commit_msg>Updated for Node version 0.1.25<commit_after>var http = require('http'),
    sys = require('sys'),
    posix = require('posix')
	url = require('url');

function extname(path) {
    var index = path.lastIndexOf('.');
    return index < 0 ? '' : path.substring(index);
}

exports.serveFile = function(req, res, filename) {
    // TODO: Ensure security against directory traversal attacks
    var body, headers;
    var content_type = mime.lookup(extname(filename));
    var encoding = (content_type.slice(0,4) === 'text' ? 'utf8' : 'binary');
    var status = 200;

    function loadResponseData(callback) {
        if (body && headers) {
            callback();
            return;
        }
        sys.puts("loading " + filename + "...");
        var promise = posix.cat(filename, encoding);
        promise.addCallback(function(data) {
            body = data;
            headers = [
                ['Content-Type', content_type],
                ['Content-Length', encoding === 'utf8' ? encodeURIComponent(body).replace(/%../g, 'x').length : body.length]
            ];
            sys.puts("static file " + filename + " loaded");
            callback();
        });
        promise.addErrback(function() {
            status = 404;
            body = '404'
            sys.puts("Error loading " + filename);
            callback();
        });
    }
    loadResponseData(function() {
        res.sendHeader(status, headers);
        res.sendBody(body, encoding);
        res.finish();
    });
}

exports.serve = function(app, port) {
    sys.puts('Server on http://127.0.0.1:' + port + '/');
    return http.createServer(app).listen(port);
}

function respond(res, body, content_type, status) {
    content_type = content_type || 'text/html';
    res.sendHeader(status || 200, {
        'Content-Type': content_type  + '; charset=utf-8'
    });
    res.sendBody(body);
    res.finish();
}
exports.respond = respond;

exports.redirect = redirect = function(res, location, status) {
    status = status || 301;
    res.sendHeader(status || 200, {
        'Content-Type': 'text/html; charset=utf-8',
        'Location': location
    });
    res.sendBody('Redirecting...');
    res.finish();
}

exports.extractPost = function(req, callback) {
    req.setBodyEncoding('utf-8');
    var body = '';
    req.addListener('body', function(chunk) {
        body += chunk;
    });
    req.addListener('complete', function() {
        callback(http.parseUri('http://fake/?' + body).params);
    });
}

var debuginfo = {}
exports.debuginfo = debuginfo;

exports.makeApp = function(urls, options) {
    // Compile the regular expressions
    var compiled = urls.map(function(pair) {
        return [new RegExp(pair[0]), pair[1]];
    });
    options = options || {};
    var show_404 = (options.show_404 || default_show_404);
    var show_500 = (options.show_500 || default_show_500);
    return function(req, res) {
        debuginfo.last_request = req;
        debuginfo.last_response = res;
        var path = url.parse(req.url)["pathname"];
        var view = show_404;
        var args = [req, res];
        for (var pair, i = 0; pair = compiled[i]; i++) {
            //sys.puts("Matching " + pair[0] + " against path " + path);
            var match = pair[0](path);
            if (match) {
                //sys.puts("  matched! " + match);
                // Add matched bits to args
                match.slice(1).forEach(function(arg) {
                    args.push(arg);
                });
                view = pair[1];
                break;
            }
        }
        try {
            view.apply(null, args);
        } catch (e) {
            debuginfo.last_e = e;
            show_500(req, res, e);
        }
    }
}

function default_show_404(req, res) {
    respond(res,
        '
404
', 'text/html', 404
    );
}
exports.default_show_404 = default_show_404

function default_show_500(req, res, e) {
    var msg = ''
    if ('stack' in e && 'type' in e) {
        msg = (
            '
' + e.type + '

' +
            e.stack + '
'
        );
    } else {
        msg = JSON.stringify(e, 0, 2);
    }
    respond(res, '
500
' + msg, 'text/html', 500);
}
exports.default_show_500 = default_show_500

exports.mime = mime = {
    lookup : function(ext, fallback) {
        return mime.types[ext.toLowerCase()] || fallback || mime.default_type;
    },
    default_type: 'application/octet-stream',
    types: {
        ".3gp"   : "video/3gpp",
        ".a"     : "application/octet-stream",
        ".ai"    : "application/postscript",
        ".aif"   : "audio/x-aiff",
        ".aiff"  : "audio/x-aiff",
        ".asc"   : "application/pgp-signature",
        ".asf"   : "video/x-ms-asf",
        ".asm"   : "text/x-asm",
        ".asx"   : "video/x-ms-asf",
        ".atom"  : "application/atom+xml",
        ".au"    : "audio/basic",
        ".avi"   : "video/x-msvideo",
        ".bat"   : "application/x-msdownload",
        ".bin"   : "application/octet-stream",
        ".bmp"   : "image/bmp",
        ".bz2"   : "application/x-bzip2",
        ".c"     : "text/x-c",
        ".cab"   : "application/vnd.ms-cab-compressed",
        ".cc"    : "text/x-c",
        ".chm"   : "application/vnd.ms-htmlhelp",
        ".class" : "application/octet-stream",
        ".com"   : "application/x-msdownload",
        ".conf"  : "text/plain",
        ".cpp"   : "text/x-c",
        ".crt"   : "application/x-x509-ca-cert",
        ".css"   : "text/css",
        ".csv"   : "text/csv",
        ".cxx"   : "text/x-c",
        ".deb"   : "application/x-debian-package",
        ".der"   : "application/x-x509-ca-cert",
        ".diff"  : "text/x-diff",
        ".djv"   : "image/vnd.djvu",
        ".djvu"  : "image/vnd.djvu",
        ".dll"   : "application/x-msdownload",
        ".dmg"   : "application/octet-stream",
        ".doc"   : "application/msword",
        ".dot"   : "application/msword",
        ".dtd"   : "application/xml-dtd",
        ".dvi"   : "application/x-dvi",
        ".ear"   : "application/java-archive",
        ".eml"   : "message/rfc822",
        ".eps"   : "application/postscript",
        ".exe"   : "application/x-msdownload",
        ".f"     : "text/x-fortran",
        ".f77"   : "text/x-fortran",
        ".f90"   : "text/x-fortran",
        ".flv"   : "video/x-flv",
        ".for"   : "text/x-fortran",
        ".gem"   : "application/octet-stream",
        ".gemspec": "text/x-script.ruby",
        ".gif"   : "image/gif",
        ".gz"    : "application/x-gzip",
        ".h"     : "text/x-c",
        ".hh"    : "text/x-c",
        ".htm"   : "text/html",
        ".html"  : "text/html",
        ".ico"   : "image/vnd.microsoft.icon",
        ".ics"   : "text/calendar",
        ".ifb"   : "text/calendar",
        ".iso"   : "application/octet-stream",
        ".jar"   : "application/java-archive",
        ".java"  : "text/x-java-source",
        ".jnlp"  : "application/x-java-jnlp-file",
        ".jpeg"  : "image/jpeg",
        ".jpg"   : "image/jpeg",
        ".js"    : "application/javascript",
        ".json"  : "application/json",
        ".log"   : "text/plain",
        ".m3u"   : "audio/x-mpegurl",
        ".m4v"   : "video/mp4",
        ".man"   : "text/troff",
        ".mathml"  : "application/mathml+xml",
        ".mbox"  : "application/mbox",
        ".mdoc"  : "text/troff",
        ".me"    : "text/troff",
        ".mid"   : "audio/midi",
        ".midi"  : "audio/midi",
        ".mime"  : "message/rfc822",
        ".mml"   : "application/mathml+xml",
        ".mng"   : "video/x-mng",
        ".mov"   : "video/quicktime",
        ".mp3"   : "audio/mpeg",
        ".mp4"   : "video/mp4",
        ".mp4v"  : "video/mp4",
        ".mpeg"  : "video/mpeg",
        ".mpg"   : "video/mpeg",
        ".ms"    : "text/troff",
        ".msi"   : "application/x-msdownload",
        ".odp"   : "application/vnd.oasis.opendocument.presentation",
        ".ods"   : "application/vnd.oasis.opendocument.spreadsheet",
        ".odt"   : "application/vnd.oasis.opendocument.text",
        ".ogg"   : "application/ogg",
        ".p"     : "text/x-pascal",
        ".pas"   : "text/x-pascal",
        ".pbm"   : "image/x-portable-bitmap",
        ".pdf"   : "application/pdf",
        ".pem"   : "application/x-x509-ca-cert",
        ".pgm"   : "image/x-portable-graymap",
        ".pgp"   : "application/pgp-encrypted",
        ".pkg"   : "application/octet-stream",
        ".pl"    : "text/x-script.perl",
        ".pm"    : "text/x-script.perl-module",
        ".png"   : "image/png",
        ".pnm"   : "image/x-portable-anymap",
        ".ppm"   : "image/x-portable-pixmap",
        ".pps"   : "application/vnd.ms-powerpoint",
        ".ppt"   : "application/vnd.ms-powerpoint",
        ".ps"    : "application/postscript",
        ".psd"   : "image/vnd.adobe.photoshop",
        ".py"    : "text/x-script.python",
        ".qt"    : "video/quicktime",
        ".ra"    : "audio/x-pn-realaudio",
        ".rake"  : "text/x-script.ruby",
        ".ram"   : "audio/x-pn-realaudio",
        ".rar"   : "application/x-rar-compressed",
        ".rb"    : "text/x-script.ruby",
        ".rdf"   : "application/rdf+xml",
        ".roff"  : "text/troff",
        ".rpm"   : "application/x-redhat-package-manager",
        ".rss"   : "application/rss+xml",
        ".rtf"   : "application/rtf",
        ".ru"    : "text/x-script.ruby",
        ".s"     : "text/x-asm",
        ".sgm"   : "text/sgml",
        ".sgml"  : "text/sgml",
        ".sh"    : "application/x-sh",
        ".sig"   : "application/pgp-signature",
        ".snd"   : "audio/basic",
        ".so"    : "application/octet-stream",
        ".svg"   : "image/svg+xml",
        ".svgz"  : "image/svg+xml",
        ".swf"   : "application/x-shockwave-flash",
        ".t"     : "text/troff",
        ".tar"   : "application/x-tar",
        ".tbz"   : "application/x-bzip-compressed-tar",
        ".tcl"   : "application/x-tcl",
        ".tex"   : "application/x-tex",
        ".texi"  : "application/x-texinfo",
        ".texinfo" : "application/x-texinfo",
        ".text"  : "text/plain",
        ".tif"   : "image/tiff",
        ".tiff"  : "image/tiff",
        ".torrent" : "application/x-bittorrent",
        ".tr"    : "text/troff",
        ".txt"   : "text/plain",
        ".vcf"   : "text/x-vcard",
        ".vcs"   : "text/x-vcalendar",
        ".vrml"  : "model/vrml",
        ".war"   : "application/java-archive",
        ".wav"   : "audio/x-wav",
        ".wma"   : "audio/x-ms-wma",
        ".wmv"   : "video/x-ms-wmv",
        ".wmx"   : "video/x-ms-wmx",
        ".wrl"   : "model/vrml",
        ".wsdl"  : "application/wsdl+xml",
        ".xbm"   : "image/x-xbitmap",
        ".xhtml"   : "application/xhtml+xml",
        ".xls"   : "application/vnd.ms-excel",
        ".xml"   : "application/xml",
        ".xpm"   : "image/x-xpixmap",
        ".xsl"   : "application/xml",
        ".xslt"  : "application/xslt+xml",
        ".yaml"  : "text/yaml",
        ".yml"   : "text/yaml",
        ".zip"   : "application/zip"
    }
};
<|endoftext|>


<commit_before>"use strict";
// Include gulp
var fs = require("fs");
var gulp = require("gulp");
var sourcemaps = require("gulp-sourcemaps")
var path = require("path");
var browserSync = require("browser-sync").create();
var sass = require('gulp-sass');
var babelify = require('babelify');
var gutil = require('gulp-util');
var replace = require('gulp-replace');

var browserify = require("browserify");
var source = require('vinyl-source-stream');
var reload = browserSync.reload;

var runSequence = require('run-sequence');

var extensions = ['.js','.json','.es6'];

gulp.task('watch',['browserify', 'sass'], function(){
  browserSync.init({
     server:'./src'
  });
  gulp.watch("./src/sass/**/*.scss", ['sass']);
  gulp.watch("./src/scripts/**/*.js", ['browserify']);
  gulp.watch("./src/**/*.html").on('change', reload);
  gulp.watch("./src/bundle*.js").on('change', reload);
});

gulp.task('sass',function(){
  return gulp.src('./src/sass/**/*.scss')
  .pipe(sourcemaps.init())
  .pipe(sass()).on('error', function logError(error) {
      console.error(error);
  })
  .pipe(sourcemaps.write())
  .pipe(gulp.dest('./src/css'))
  .pipe(reload({stream:true}));
});

gulp.task('browserify', ['browserify_phone', 'browserify_moderator', 'browserify_screen', 'browserify_summary']);

gulp.task('browserify_phone',function(){
  return browserify({entries: './src/scripts/app_phone.js', debug:true, extensions: extensions})
    .transform(babelify)
    .on('error', gutil.log)
    .bundle()
    .on('error', gutil.log)
    .pipe(source('bundle_phone.js'))
    .pipe(gulp.dest('./src'));
});

gulp.task('browserify_moderator',function(){
  return browserify({entries: './src/scripts/app_moderator.js', debug:true, extensions: extensions})
    .transform(babelify)
    .on('error', gutil.log)
    .bundle()
    .on('error', gutil.log)
    .pipe(source('bundle_moderator.js'))
    .pipe(gulp.dest('./src'));
});

gulp.task('browserify_screen',function(){
  return browserify(['./src/scripts/app_screen.js'], {debug:true})
    .transform(babelify)
    .on('error', gutil.log)
    .bundle()
    .on('error', gutil.log)
    .pipe(source('bundle_screen.js'))
    .pipe(gulp.dest('./src'));
});

gulp.task('browserify_summary',function(){
  return browserify(['./src/scripts/app_summary.js'], {debug:true})
    .transform(babelify)
    .on('error', gutil.log)
    .bundle()
    .on('error', gutil.log)
    .pipe(source('bundle_summary.js'))
    .pipe(gulp.dest('./src'));
});

gulp.task("copy", function () {
   return gulp.src([
        "src/*.html",
        "src/*.js",
        "src/*.json",
        "src/css/**",
        "src/assets/**",
        ],{"base":"./src"})
    .pipe(gulp.dest('./public/'));
});

gulp.task("replace", function(){
  gulp.src(['./public/bundle_phone.js', './public/bundle_moderator.js'])
  .pipe(replace('/* SERVICE_WORKER_REPLACE', ''))
  .pipe(replace('SERVICE_WORKER_REPLACE */', ''))
  .pipe(gulp.dest('./public/'));
});

gulp.task("replace_timestamp", function(){
  gulp.src['./public/service-worker-phone.js', './public/service-worker-moderator.js']
  .pipe(replace('{timestamp}', Date.now()))
  .pipe(gulp.dest('./public/'));
})

gulp.task('build',function(){
  runSequence(
    ['browserify', 'sass'],
    'copy',
    'replace_phone',
    'replace_timestamp'
  );
});

/* Default task */
gulp.task("default", ["watch"]);
<commit_msg>fix build<commit_after>"use strict";
// Include gulp
var fs = require("fs");
var gulp = require("gulp");
var sourcemaps = require("gulp-sourcemaps")
var path = require("path");
var browserSync = require("browser-sync").create();
var sass = require('gulp-sass');
var babelify = require('babelify');
var gutil = require('gulp-util');
var replace = require('gulp-replace');

var browserify = require("browserify");
var source = require('vinyl-source-stream');
var reload = browserSync.reload;

var runSequence = require('run-sequence');

var extensions = ['.js','.json','.es6'];

gulp.task('watch',['browserify', 'sass'], function(){
  browserSync.init({
     server:'./src'
  });
  gulp.watch("./src/sass/**/*.scss", ['sass']);
  gulp.watch("./src/scripts/**/*.js", ['browserify']);
  gulp.watch("./src/**/*.html").on('change', reload);
  gulp.watch("./src/bundle*.js").on('change', reload);
});

gulp.task('sass',function(){
  return gulp.src('./src/sass/**/*.scss')
  .pipe(sourcemaps.init())
  .pipe(sass()).on('error', function logError(error) {
      console.error(error);
  })
  .pipe(sourcemaps.write())
  .pipe(gulp.dest('./src/css'))
  .pipe(reload({stream:true}));
});

gulp.task('browserify', ['browserify_phone', 'browserify_moderator', 'browserify_screen', 'browserify_summary']);

gulp.task('browserify_phone',function(){
  return browserify({entries: './src/scripts/app_phone.js', debug:true, extensions: extensions})
    .transform(babelify)
    .on('error', gutil.log)
    .bundle()
    .on('error', gutil.log)
    .pipe(source('bundle_phone.js'))
    .pipe(gulp.dest('./src'));
});

gulp.task('browserify_moderator',function(){
  return browserify({entries: './src/scripts/app_moderator.js', debug:true, extensions: extensions})
    .transform(babelify)
    .on('error', gutil.log)
    .bundle()
    .on('error', gutil.log)
    .pipe(source('bundle_moderator.js'))
    .pipe(gulp.dest('./src'));
});

gulp.task('browserify_screen',function(){
  return browserify(['./src/scripts/app_screen.js'], {debug:true})
    .transform(babelify)
    .on('error', gutil.log)
    .bundle()
    .on('error', gutil.log)
    .pipe(source('bundle_screen.js'))
    .pipe(gulp.dest('./src'));
});

gulp.task('browserify_summary',function(){
  return browserify(['./src/scripts/app_summary.js'], {debug:true})
    .transform(babelify)
    .on('error', gutil.log)
    .bundle()
    .on('error', gutil.log)
    .pipe(source('bundle_summary.js'))
    .pipe(gulp.dest('./src'));
});

gulp.task("copy", function () {
   return gulp.src([
        "src/*.html",
        "src/*.js",
        "src/*.json",
        "src/css/**",
        "src/assets/**",
        ],{"base":"./src"})
    .pipe(gulp.dest('./public/'));
});

gulp.task("replace", function(){
  gulp.src(['./public/bundle_phone.js', './public/bundle_moderator.js'])
  .pipe(replace('/* SERVICE_WORKER_REPLACE', ''))
  .pipe(replace('SERVICE_WORKER_REPLACE */', ''))
  .pipe(gulp.dest('./public/'));
});

gulp.task("replace_timestamp", function(){
  gulp.src['./public/service-worker-phone.js', './public/service-worker-moderator.js']
  .pipe(replace('{timestamp}', Date.now()))
  .pipe(gulp.dest('./public/'));
})

gulp.task('build',function(){
  runSequence(
    ['browserify', 'sass'],
    'copy',
    'replace',
    'replace_timestamp'
  );
});

/* Default task */
gulp.task("default", ["watch"]);
<|endoftext|>


<commit_before>/**
 * grunt-inline-images
 * https://github.com/EE/grunt-inline-images
 *
 * Author Michał Gołębiowski <michal.golebiowski@laboratorium.ee>
 * Licensed under the MIT license.
 */

'use strict';

// Gruntfile.js & tasks/*.js are the only non-transpiled files.
/* eslint-disable no-var, no-eval */

var assert = require('assert');

module.exports = function (grunt) {
    try {
        assert.strictEqual(eval('(() => 2)()'), 2);
        return require('../src/inline-images')(grunt);
    } catch (e) {
        return require('../dist/src/inline-images')(grunt);
    }
};
<commit_msg>Add back a missing comment<commit_after>/**
 * grunt-inline-images
 * https://github.com/EE/grunt-inline-images
 *
 * Author Michał Gołębiowski <michal.golebiowski@laboratorium.ee>
 * Licensed under the MIT license.
 */

'use strict';

// Disable options that don't work in Node.js 0.10.
// Gruntfile.js & tasks/*.js are the only non-transpiled files.
/* eslint-disable no-var, no-eval */

var assert = require('assert');

module.exports = function (grunt) {
    try {
        assert.strictEqual(eval('(() => 2)()'), 2);
        return require('../src/inline-images')(grunt);
    } catch (e) {
        return require('../dist/src/inline-images')(grunt);
    }
};
<|endoftext|>


<commit_before>function Cell(gameServer, owner, position, size) {
    this.gameServer = gameServer;
    this.owner = owner;     // playerTracker that owns this cell

    this.tickOfBirth = 0;
    this.color = { r: 0, g: 0, b: 0 };
    this.position = { x: 0, y: 0 };
    this._sizeSquared = 0;
    this._size = 0;
    this._mass = 0;
    this._speed = null;
    this.cellType = -1;     // 0 = Player Cell, 1 = Food, 2 = Virus, 3 = Ejected Mass
    this.isSpiked = false;  // If true, then this cell has spikes around it
    this.isAgitated = false;// If true, then this cell has waves on it's outline
    this.killedBy = null;   // Cell that ate this cell
    this.isMoving = false;  // Indicate that cell is in boosted mode

    this.boostDistance = 0;
    this.boostDirection = { x: 1, y: 0, angle: Math.PI / 2 };
    this.boostMaxSpeed = 78;// boost speed limit, sqrt(780*780/100)
    this.ejector = null;

    if (this.gameServer != null) {
        this.nodeId = this.gameServer.getNextNodeId();
        this.tickOfBirth = this.gameServer.tickCounter;
        if (size != null) {
            this.setSize(size);
        }
        if (position != null) {
            this.setPosition(position);
        }
    }
}

module.exports = Cell;

// Fields not defined by the constructor are considered private and need a getter/setter to access from a different class

Cell.prototype.setColor = function (color) {
    this.color.r = color.r;
    this.color.g = color.g;
    this.color.b = color.b;
};

Cell.prototype.setSize = function (size) {
    this._size = size;
    this._sizeSquared = size * size;
    this._mass = this._sizeSquared / 100;
    if (this.owner)
        this.owner.isMassChanged = true;
};

Cell.prototype.getSpeed = function () {
    var speed = 2.1106 / Math.pow(this._size, 0.449);
    // tickStep = 40ms
    this._speed = (this.owner.customspeed > 0) ?
    speed * 40 * this.owner.customspeed : // Set by command
    speed * 40 * this.gameServer.config.playerSpeed;
    return this._speed;
};

Cell.prototype.setAngle = function (angle) {
    this.boostDirection = {
        x: Math.sin(angle),
        y: Math.cos(angle),
        angle: angle
    };
};

// Returns cell age in ticks for specified game tick
Cell.prototype.getAge = function (tick) {
    if (this.tickOfBirth == null) return 0;
    return Math.max(0, tick - this.tickOfBirth);
};

Cell.prototype.setKiller = function (cell) {
    this.killedBy = cell;
};

Cell.prototype.setPosition = function (pos) {
    this.position.x = pos.x;
    this.position.y = pos.y;
};

// by default cell cannot eat anyone
Cell.prototype.canEat = function (cell) {
    return false;
};

// Called to eat prey cell
Cell.prototype.onEat = function (prey) {
    // Cant grow from cells under 17 mass (vanilla)
    if (this.gameServer.config.playerBotGrow == 0) {
        if (this._mass >= 625 && prey._mass <= 17 && prey.cellType != 3)
            prey._sizeSquared = 0;
    }
    this.setSize(Math.sqrt(this._sizeSquared + prey._sizeSquared));
};

Cell.prototype.onEaten = function (hunter) {
};

Cell.prototype.onAdd = function (gameServer) {
};

Cell.prototype.onRemove = function (gameServer) {
};

Cell.prototype.setBoost = function (distance, angle) {
    this.boostDistance = distance;
    this.setAngle(angle);
    this.isMoving = true;
    if (!this.owner) {
        var index = this.gameServer.movingNodes.indexOf(this);
        if (index < 0)
            this.gameServer.movingNodes.push(this);
    }
};

Cell.prototype.move = function (border) {
    if (this.isMoving && this.boostDistance <= 0) {
        this.boostDistance = 0;
        this.isMoving = false;
        return;
    }
    // add speed and set direction
    var speed = Math.sqrt(this.boostDistance * this.boostDistance / 100);
    this.boostDistance -= speed;
    this.position.x += this.boostDirection.x * speed;
    this.position.y += this.boostDirection.y * speed;

    // reflect off border
    var r = this._size / 2;
    if (this.position.x < border.minx + r || this.position.x > border.maxx - r)
        this.boostDirection.x =- this.boostDirection.x;
	if (this.position.y < border.miny + r || this.position.y > border.maxy - r)
	    this.boostDirection.y =- this.boostDirection.y;
	this.checkBorder(border);
};

Cell.prototype.checkBorder = function (border) {
    this.position.x = Math.max(this.position.x, border.minx + this._size / 2);
    this.position.y = Math.max(this.position.y, border.miny + this._size / 2);
    this.position.x = Math.min(this.position.x, border.maxx - this._size / 2);
    this.position.y = Math.min(this.position.y, border.maxy - this._size / 2);
};
<commit_msg>Performance<commit_after>function Cell(gameServer, owner, position, size) {
    this.gameServer = gameServer;
    this.owner = owner;     // playerTracker that owns this cell

    this.tickOfBirth = 0;
    this.color = { r: 0, g: 0, b: 0 };
    this.position = { x: 0, y: 0 };
    this._sizeSquared = 0;
    this._size = 0;
    this._mass = 0;
    this.cellType = -1;     // 0 = Player Cell, 1 = Food, 2 = Virus, 3 = Ejected Mass
    this.isSpiked = false;  // If true, then this cell has spikes around it
    this.isAgitated = false;// If true, then this cell has waves on it's outline
    this.killedBy = null;   // Cell that ate this cell
    this.isMoving = false;  // Indicate that cell is in boosted mode

    this.boostDistance = 0;
    this.boostDirection = { x: 1, y: 0, angle: Math.PI / 2 };
    this.boostMaxSpeed = 78;// boost speed limit, sqrt(780*780/100)
    this.ejector = null;

    if (this.gameServer != null) {
        this.nodeId = this.gameServer.getNextNodeId();
        this.tickOfBirth = this.gameServer.tickCounter;
        if (size != null) this.setSize(size);
        if (position != null) {
            this.position.x = position.x;
            this.position.y = position.y;
        }
    }
}

module.exports = Cell;

// Fields not defined by the constructor are considered private and need a getter/setter to access from a different class

Cell.prototype.setColor = function (color) {
    this.color.r = color.r;
    this.color.g = color.g;
    this.color.b = color.b;
};

Cell.prototype.setSize = function (size) {
    this._size = size;
    this._sizeSquared = size * size;
    this._mass = this._sizeSquared / 100;
    if (this.owner)
        this.owner.isMassChanged = true;
};

// Returns cell age in ticks for specified game tick
Cell.prototype.getAge = function (tick) {
    if (this.tickOfBirth == null) return 0;
    return Math.max(0, tick - this.tickOfBirth);
};

// by default cell cannot eat anyone
Cell.prototype.canEat = function (cell) {
    return false;
};

// Called to eat prey cell
Cell.prototype.onEat = function (prey) {
    // Cant grow from cells under 17 mass (vanilla)
    if (this.gameServer.config.playerBotGrow == 0) {
        if (this._mass >= 625 && prey._mass <= 17 && prey.cellType != 3)
            prey._sizeSquared = 0;
    }
    this.setSize(Math.sqrt(this._sizeSquared + prey._sizeSquared));
};

Cell.prototype.setBoost = function (distance, angle) {
    this.boostDistance = distance;
    this.boostDirection = {
        x: Math.sin(angle),
        y: Math.cos(angle),
        angle: angle
    };
    this.isMoving = true;
    if (!this.owner) {
        var index = this.gameServer.movingNodes.indexOf(this);
        if (index < 0)
            this.gameServer.movingNodes.push(this);
    }
};

Cell.prototype.move = function (border) {
    if (this.isMoving && this.boostDistance <= 0) {
        this.boostDistance = 0;
        this.isMoving = false;
        return;
    }
    // add speed and set direction
    var speed = Math.sqrt(this.boostDistance * this.boostDistance / 100);
    this.boostDistance -= speed;
    this.position.x += this.boostDirection.x * speed;
    this.position.y += this.boostDirection.y * speed;

    // reflect off border
    var r = this._size / 2;
    if (this.position.x < border.minx + r || this.position.x > border.maxx - r)
        this.boostDirection.x =- this.boostDirection.x;
	if (this.position.y < border.miny + r || this.position.y > border.maxy - r)
	    this.boostDirection.y =- this.boostDirection.y;
	this.checkBorder(border);
};

Cell.prototype.checkBorder = function (border) {
    this.position.x = Math.max(this.position.x, border.minx + this._size / 2);
    this.position.y = Math.max(this.position.y, border.miny + this._size / 2);
    this.position.x = Math.min(this.position.x, border.maxx - this._size / 2);
    this.position.y = Math.min(this.position.y, border.maxy - this._size / 2);
};

Cell.prototype.onEaten = function (hunter) { };
Cell.prototype.onAdd = function (gameServer) { };
Cell.prototype.onRemove = function (gameServer) { };
<|endoftext|>


<commit_before>import throttle from 'lodash/throttle';
export const EWatermark = {
    name: 'e-watermark',
    props: {
        text: { type: String, default: 'text' },
        markSize: { type: Number, default: 120 },
        opacity: { type: Number, default: 0.1 },
        image: { type: [
            HTMLImageElement,
            HTMLVideoElement,
            HTMLCanvasElement,
            window.SVGImageElement,
            window.ImageBitmap,
            window.OffscreenCanvas,
        ] },
    },
    watch: {
        text() {
            setTimeout(() => {
                this.redrawMark();
                this.redraw();
            }, 100);
        },
    },
    computed: {
        markWidth() {
            return this.markSize * Math.sqrt(3) * 2;
        },
        markHeight() {
            return this.markSize * 2;
        },
    },
    created() {
        this.redraw = throttle(this.redraw, 250);
    },
    mounted() {
        this.drawMark();
        this.redraw();
        window.addEventListener('resize', this.redraw);
    },
    destroyed() {
        window.removeEventListener('resize', this.redraw);
    },
    methods: {
        drawMark() {
            const markEl = this.$refs.mark;
            const width = markEl.width;
            const height = markEl.height;
            const ctx = markEl.getContext('2d');

            ctx.translate(width / 2, height / 2);
            ctx.scale(2, 2);
            ctx.rotate(-Math.PI / 6);
            ctx.fillStyle = 'black';
            ctx.font = '14px Arial';
            ctx.textAlign = 'center';
            ctx.fillText(this.text, 0, 0);

            return markEl;
        },
        redrawMark() {
            const markEl = this.$refs.mark;
            const ctx = markEl.getContext('2d');
            const width = markEl.width;
            const height = markEl.height;
            ctx.clearRect(-width, -height, width * 2, height * 2);
            ctx.fillText(this.text, 0, 0);
        },
        draw(image) {
            const canvasEl = this.$refs.canvas;
            const wh = window.innerHeight;
            const ww = window.innerWidth;
            const isFirstPaint = !this.lastRectangle;
            this.lastRectangle = isFirstPaint ? {
                ww: 0,
                wh: 0,
            } : this.lastRectangle;
            if (wh > this.lastRectangle.wh || ww > this.lastRectangle.ww) {
                this.lastRectangle = {
                    ww: Math.max(ww, this.lastRectangle.ww),
                    wh: Math.max(wh, this.lastRectangle.wh),
                };
            } else if (!isFirstPaint) {
                return;
            }
            canvasEl.style.width = ww + 'px';
            canvasEl.style.height = wh + 'px';
            const width = canvasEl.width = ww * 2;
            const height = canvasEl.height = wh * 2;

            const ctx = canvasEl.getContext('2d');

            const markHeight = this.markHeight;
            const markWidth = this.markWidth;
            for (let i = 0; i < width; i += markWidth) {
                for (let j = 0; j < height; j += markHeight)
                    ctx.drawImage(image, i, j, markWidth, markHeight);
            }
        },
        redraw() {
            const image = this.image || this.$refs.mark;
            this.draw(image);
        },
    },
};

export default EWatermark;
<commit_msg>:ok_hand: Review e-watermark<commit_after>import throttle from 'lodash/throttle';

export const EWatermark = {
    name: 'e-watermark',
    props: {
        text: { type: String, default: 'text' },
        markSize: { type: Number, default: 120 },
        opacity: { type: Number, default: 0.1 },
        image: { type: [
            HTMLImageElement,
            HTMLVideoElement,
            HTMLCanvasElement,
            window.SVGImageElement,
            window.ImageBitmap,
            window.OffscreenCanvas,
        ] },
    },
    watch: {
        text() {
            setTimeout(() => {
                this.redrawMark();
                this.redraw();
            }, 100);
        },
    },
    computed: {
        markWidth() {
            return this.markSize * Math.sqrt(3) * 2;
        },
        markHeight() {
            return this.markSize * 2;
        },
    },
    created() {
        this.redraw = throttle(this.redraw, 250);
    },
    mounted() {
        this.drawMark();
        this.redraw();
        window.addEventListener('resize', this.redraw);
    },
    destroyed() {
        window.removeEventListener('resize', this.redraw);
    },
    methods: {
        drawMark() {
            const markEl = this.$refs.mark;
            const width = markEl.width;
            const height = markEl.height;
            const ctx = markEl.getContext('2d');

            ctx.translate(width / 2, height / 2);
            ctx.scale(2, 2);
            ctx.rotate(-Math.PI / 6);
            ctx.fillStyle = 'black';
            ctx.font = '14px Arial';
            ctx.textAlign = 'center';
            ctx.fillText(this.text, 0, 0);

            return markEl;
        },
        redrawMark() {
            const markEl = this.$refs.mark;
            const ctx = markEl.getContext('2d');
            const width = markEl.width;
            const height = markEl.height;
            ctx.clearRect(-width, -height, width * 2, height * 2);
            ctx.fillText(this.text, 0, 0);
        },
        draw(image) {
            const canvasEl = this.$refs.canvas;

            const windowHeight = window.innerHeight;
            const windowWidth = window.innerWidth;
            const isFirstPaint = !this.lastRectangle;
            this.lastRectangle = isFirstPaint ? {
                windowWidth: 0,
                windowHeight: 0,
            } : this.lastRectangle;
            if (windowHeight > this.lastRectangle.windowHeight || windowWidth > this.lastRectangle.windowWidth) {
                this.lastRectangle = {
                    windowWidth: Math.max(windowWidth, this.lastRectangle.windowWidth),
                    windowHeight: Math.max(windowHeight, this.lastRectangle.windowHeight),
                };
            } else if (!isFirstPaint) {
                return;
            }

            canvasEl.style.width = windowWidth + 'px';
            canvasEl.style.height = windowHeight + 'px';
            const width = canvasEl.width = windowWidth * 2;
            const height = canvasEl.height = windowHeight * 2;

            const ctx = canvasEl.getContext('2d');

            const markHeight = this.markHeight;
            const markWidth = this.markWidth;
            for (let i = 0; i < width; i += markWidth) {
                for (let j = 0; j < height; j += markHeight)
                    ctx.drawImage(image, i, j, markWidth, markHeight);
            }
        },
        redraw() {
            const image = this.image || this.$refs.mark;
            this.draw(image);
        },
    },
};

export default EWatermark;
<|endoftext|>


<commit_before>var cheerio = require('cheerio'),
    fs = require('fs'),
    path = require('path'),
    marked = require('marked');

marked.setOptions({

});

var idRegex = /[^\w]/g;

var setExtHeader1Regex = /^(.+)[ \t]*\r?\n=+[ \t]*(?:\r?\n)+/gm;
var setExtHeader2Regex = /^(.+)[ \t]*\r?\n-+[ \t]*(?:\r?\n)+/gm;

/*    /
    ^(\#{1,6})      // $1 = string of #'s
        [ \t]*
    (.+?)           // $2 = Header text
    [ \t]*
    \#*             // optional closing #'s (not counted)
    \n+
    /gm */
var atxHeaderRegex = /^(\#{1,6})[ \t]*(.+?)[ \t]*\#*(?:\r?\n)+/gm;
var markdownHeaders = [
    '',
    "#",
    "##",
    "###",
    "####",
    "#####",
    "######"
];

var allHtmlHeaders = 'h1, h2, h3, h4, h5, h6';

var buildHeader = function(name, depth) {
    if (depth < 1) {
        return '
' + name + '
';
    } else {
        return '<h' + (depth) + '>' + name + '</h' + depth + '>';
    }
};

var appendTocElement = function(toc, link) {
    var element = cheerio.load('

');
    element('li')
        .addClass('docmd-toc-item')
        .append(link);
    toc.root().append(element.html());
};

var buildSimpleTocLink = function(name, anchorId) {
    return cheerio.load('')('a')
        .attr('href', '#' + anchorId)
        .addClass("docmd-toc-link")
        .text(name);
};

var adjustMarkdownHeaders = function(markdown, depth) {
    markdown = markdown.replace(atxHeaderRegex, function (wholeMatch, m1, m2) {
        var currentLevel = m1.length;
        var newLevel = depth + currentLevel - 1;
        if (newLevel > 6) {
            newLevel = 6;
        }
        return '\n' + markdownHeaders[newLevel] + ' ' + m2 + '\n\n';
        }
    );

    markdown = markdown.replace(setExtHeader1Regex, function(wholeMatch, m1) {
        return '\n' + markdownHeaders[depth] + ' ' + m1 + '\n\n';
    });

    markdown = markdown.replace(setExtHeader2Regex, function(wholeMatch, m1) {
        var newLevel = depth + 1;
        if (newLevel > 6) {
            newLevel = 6;
        }
        return '\n' + markdownHeaders[newLevel] + ' ' + m1 + '\n\n';
    });
    return markdown;
};

var buildAndLinkHtml = function(options, properties, depth) {
    if (depth > 4) {
        //TODO determine if this is the correct threshold
        depth = 4;
    }
    var tocSections = cheerio.load('');
    var name,
        header,
        $,
        markdown;
    if (properties["name"]) {
        name = properties["name"];
        $ = cheerio.load(buildHeader(name, depth));
        markdown = depth > 0 ? markdownHeaders[depth] + name + '\n\n' : "" ;
        header = $(allHtmlHeaders).first();
    } else if (properties["file"]) {
        var sectionFile = path.join(options['docDir'], properties["file"]);
        markdown = fs.readFileSync(sectionFile, {"encoding": "utf-8"});
        if (options['normalizeHeaders']) {
            markdown = adjustMarkdownHeaders(markdown, depth);
        }
        var markdownHtml = marked(markdown);
        $ = cheerio.load('');
        $.root().append(markdownHtml);
        header = $(allHtmlHeaders).first();
        name = header.text();
    } else  {
        grunt.fail.warn("A toc list contains an element that is neither a name nor a file");
    }
    var anchorId = properties["referenceId"];
    if (!anchorId) {
        anchorId = buildId(name);
    }
    header.attr('id', anchorId);
    appendTocElement(tocSections, buildSimpleTocLink(name, anchorId));

    if (properties["toc"]) {
        properties["toc"].forEach(function(section) {
            var sectionContent = buildAndLinkHtml(options, section, depth + 1);

            appendTocElement(tocSections, sectionContent["toc"]);
            $.root().append(sectionContent['main']);
            markdown = markdown + '\n\n' + sectionContent['markdown'];
        });
    }

    var toc = cheerio.load('');
    var tocContents = cheerio.load('
');
    tocContents('ul').addClass('docmd-toc-list')
        .append(tocSections.html());
    toc.root().append(tocContents.html());

    return {
        "main": $.root().html(),
        "toc": toc.html(),
        "markdown": markdown
    };
};

var buildGuideLinks = function(guides) {
    var $ = cheerio.load('
');
    guides.forEach(function(guide) {
        var element = cheerio.load('');
        var icon;
        element('a')
            .addClass("all-guides-list-item list-group-item")
            .attr('href', guide.link + '.html');
        element('span')
            .addClass('docmd-guide-name')
            .text(guide.text);

        if (guide.propertiesFile.guideIcon) {
            icon = cheerio.load('');
            icon('img')
                .addClass('docmd-guide-icon')
                .attr('src', guide.propertiesFile.guideIcon);

        } else {
            icon = cheerio.load('');
            icon('span')
                .addClass('glyphicon glyphicon-book')
        }
        element('a')
            .prepend(icon.root().html());
        $('div').append(element.root().html())
    });
    return $.root().html();
};

var highlightCurrentGuide = function(guideLinksHtml, guideLink) {
    var $ = cheerio.load(guideLinksHtml);
    $('a').each(function() {
        var link = $(this);
        if (link.attr('href') === guideLink) {
            link.addClass('docmd-selected-guide');
        }
    });
    return $.root().html();
};

var buildId = function(name) {
    return name.replace(idRegex, '');
};

module.exports = {
    buildAndLinkHtml: buildAndLinkHtml,
    buildGuideLinks: buildGuideLinks,
    highlightCurrentGuide: highlightCurrentGuide,
    buildId: buildId
};
<commit_msg>Fixes header ids For all headers within the markdown but not included in the table of contents, the marked package was giving them an id created by replacing all non-alphanumeric characters with a '-'. This change overrides that behavior so as to provide consistency with the id pattern in use for headers within the table of contents (remove all non-alphanumeric characters).<commit_after>var cheerio = require('cheerio'),
    fs = require('fs'),
    path = require('path'),
    marked = require('marked');

marked.setOptions({

});

var idRegex = /[^\w]/g;

var setExtHeader1Regex = /^(.+)[ \t]*\r?\n=+[ \t]*(?:\r?\n)+/gm;
var setExtHeader2Regex = /^(.+)[ \t]*\r?\n-+[ \t]*(?:\r?\n)+/gm;

/*    /
    ^(\#{1,6})      // $1 = string of #'s
        [ \t]*
    (.+?)           // $2 = Header text
    [ \t]*
    \#*             // optional closing #'s (not counted)
    \n+
    /gm */
var atxHeaderRegex = /^(\#{1,6})[ \t]*(.+?)[ \t]*\#*(?:\r?\n)+/gm;
var markdownHeaders = [
    '',
    "#",
    "##",
    "###",
    "####",
    "#####",
    "######"
];

var allHtmlHeaders = 'h1, h2, h3, h4, h5, h6';

var buildHeader = function(name, depth) {
    if (depth < 1) {
        return '
' + name + '
';
    } else {
        return '<h' + (depth) + '>' + name + '</h' + depth + '>';
    }
};

var appendTocElement = function(toc, link) {
    var element = cheerio.load('

');
    element('li')
        .addClass('docmd-toc-item')
        .append(link);
    toc.root().append(element.html());
};

var buildSimpleTocLink = function(name, anchorId) {
    return cheerio.load('')('a')
        .attr('href', '#' + anchorId)
        .addClass("docmd-toc-link")
        .text(name);
};

var adjustMarkdownHeaders = function(markdown, depth) {
    markdown = markdown.replace(atxHeaderRegex, function (wholeMatch, m1, m2) {
        var currentLevel = m1.length;
        var newLevel = depth + currentLevel - 1;
        if (newLevel > 6) {
            newLevel = 6;
        }
        return '\n' + markdownHeaders[newLevel] + ' ' + m2 + '\n\n';
        }
    );

    markdown = markdown.replace(setExtHeader1Regex, function(wholeMatch, m1) {
        return '\n' + markdownHeaders[depth] + ' ' + m1 + '\n\n';
    });

    markdown = markdown.replace(setExtHeader2Regex, function(wholeMatch, m1) {
        var newLevel = depth + 1;
        if (newLevel > 6) {
            newLevel = 6;
        }
        return '\n' + markdownHeaders[newLevel] + ' ' + m1 + '\n\n';
    });
    return markdown;
};

var buildAndLinkHtml = function(options, properties, depth) {
    if (depth > 4) {
        //TODO determine if this is the correct threshold
        depth = 4;
    }
    var tocSections = cheerio.load('');
    var name,
        header,
        $,
        markdown;
    if (properties["name"]) {
        name = properties["name"];
        $ = cheerio.load(buildHeader(name, depth));
        markdown = depth > 0 ? markdownHeaders[depth] + name + '\n\n' : "" ;
        header = $(allHtmlHeaders).first();
    } else if (properties["file"]) {
        var sectionFile = path.join(options['docDir'], properties["file"]);
        markdown = fs.readFileSync(sectionFile, {"encoding": "utf-8"});
        if (options['normalizeHeaders']) {
            markdown = adjustMarkdownHeaders(markdown, depth);
        }
        var markdownHtml = marked(markdown);
        $ = cheerio.load('');
        $.root().append(markdownHtml);
        $(allHtmlHeaders).each(function() {
            var header = $(this);
            header.attr('id', header.text().replace(idRegex, ''));
        });
        header = $(allHtmlHeaders).first();
        name = header.text();
    } else  {
        grunt.fail.warn("A toc list contains an element that is neither a name nor a file");
    }
    var anchorId = properties["referenceId"];
    if (!anchorId) {
        anchorId = buildId(name);
    }
    header.attr('id', anchorId);
    appendTocElement(tocSections, buildSimpleTocLink(name, anchorId));

    if (properties["toc"]) {
        properties["toc"].forEach(function(section) {
            var sectionContent = buildAndLinkHtml(options, section, depth + 1);

            appendTocElement(tocSections, sectionContent["toc"]);
            $.root().append(sectionContent['main']);
            markdown = markdown + '\n\n' + sectionContent['markdown'];
        });
    }

    var toc = cheerio.load('');
    var tocContents = cheerio.load('
');
    tocContents('ul').addClass('docmd-toc-list')
        .append(tocSections.html());
    toc.root().append(tocContents.html());

    return {
        "main": $.root().html(),
        "toc": toc.html(),
        "markdown": markdown
    };
};

var buildGuideLinks = function(guides) {
    var $ = cheerio.load('
');
    guides.forEach(function(guide) {
        var element = cheerio.load('');
        var icon;
        element('a')
            .addClass("all-guides-list-item list-group-item")
            .attr('href', guide.link + '.html');
        element('span')
            .addClass('docmd-guide-name')
            .text(guide.text);

        if (guide.propertiesFile.guideIcon) {
            icon = cheerio.load('');
            icon('img')
                .addClass('docmd-guide-icon')
                .attr('src', guide.propertiesFile.guideIcon);

        } else {
            icon = cheerio.load('');
            icon('span')
                .addClass('glyphicon glyphicon-book')
        }
        element('a')
            .prepend(icon.root().html());
        $('div').append(element.root().html())
    });
    return $.root().html();
};

var highlightCurrentGuide = function(guideLinksHtml, guideLink) {
    var $ = cheerio.load(guideLinksHtml);
    $('a').each(function() {
        var link = $(this);
        if (link.attr('href') === guideLink) {
            link.addClass('docmd-selected-guide');
        }
    });
    return $.root().html();
};

var buildId = function(name) {
    return name.replace(idRegex, '');
};

module.exports = {
    buildAndLinkHtml: buildAndLinkHtml,
    buildGuideLinks: buildGuideLinks,
    highlightCurrentGuide: highlightCurrentGuide,
    buildId: buildId
};
<|endoftext|>


<commit_before>'use strict'

var React = require('react')

var WellSlide = React.createClass({
  _clicked: function () {
    this.props.onSlideClicked(this.props.index)
  },

  render: function () {
    return (
      <div
        className={
					"sp-well-slide " + (this.props.model.selected? "selected":'')
				}
        onClick={this._clicked}>
      </div>
    )
  }
})

module.exports = WellSlide
<commit_msg>display components in well slides<commit_after>'use strict'

var React = require('react')
var ComponentViewFactory = require('components/widgets/componentViewFactory')
var WellSlide = React.createClass({
  _clicked: function () {
    this.props.onSlideClicked(this.props.index)
  },
  render: function () {
    let componentsView = this.props.model.components.map((component, index) => {
      let ComponentView = ComponentViewFactory(component)
      return (
        <ComponentView {...component}
          key = {index}
        />
      )
    })
    return (
      <div
        className={
					"sp-well-slide " + (this.props.model.selected? "selected":'')
				}
        onClick={this._clicked}>
        {componentsView}
      </div>
    )
  }
})

module.exports = WellSlide
<|endoftext|>


<commit_before>var gulp = require('gulp');
var browserSync = require('browser-sync');
var reload = browserSync.reload;

gulp.task('serve-dev', function() {
  browserSync({
    server: {
      baseDir: '.'
    }
  });

  gulp.watch(['*.html', 'scripts/**/*.js'], reload);
});
<commit_msg>Fix javascript path<commit_after>var gulp = require('gulp');
var browserSync = require('browser-sync');
var reload = browserSync.reload;

gulp.task('serve-dev', function() {
  browserSync({
    server: {
      baseDir: '.'
    }
  });

  gulp.watch(['*.html', 'javascripts/**/*.js'], reload);
});
<|endoftext|>


<commit_before>/**
* Copyright (c) 2012, 2degrees Limited <2degrees-floss@googlegroups.com>.
* All Rights Reserved.
*
* This file is part of event-nexus
* <https://github.com/2degrees/event-nexus>, which is subject to
* the provisions of the BSD at
* <http://dev.2degreesnetwork.com/p/2degrees-license.html>. A copy of the
* license should accompany this distribution. THIS SOFTWARE IS PROVIDED "AS IS"
* AND ANY AND ALL EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST
* INFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Dependencies:
* - jQuery 1.7.2+
*
*/

var event_trackers = (function () {

    'use strict';

    var UserInteractionTracker = function (
        element_selector,
        event_name,
        tracking_data
    ) {
        this.element_selector = element_selector;
        this.event_name = event_name;
        this.tracking_data = $.extend({is_interactive: true}, tracking_data);
    };

    UserInteractionTracker.prototype.bind = function (tracking_data_handler) {
        var self = this;
        $(document).on(self.event_name, self.element_selector, function () {
            var tracking_data = resolve_tracking_data(
                self.tracking_data,
                $(this)
            );
            tracking_data_handler(tracking_data);
        });
    };

    var build_specific_user_interaction_tracker = function (event_name) {
        return function (element_selector, tracking_data) {
            return new UserInteractionTracker(
                element_selector,
                event_name,
                tracking_data
            );
        };
    };

    /**
     * Tracker for links which leave the current page.
     *
     * @param {String} element_selector
     * @param {Object} tracking_data
     */
    var OutboundLinkTracker = function (element_selector, tracking_data) {
        this.element_selector = element_selector;
        this.tracking_data = $.extend({is_interactive: true}, tracking_data);
    };
    OutboundLinkTracker.prototype.bind = function (tracking_data_handler) {
        var self = this;

        var handler = function (event) {
            event.preventDefault();

            var $element = $(this);

            var tracking_data = resolve_tracking_data(
                self.tracking_data,
                $element
            );
            tracking_data_handler(tracking_data);

            // Delay outbound click
            setTimeout(
                function () { $element[0].click(); },
                100
            );
            $(document).off('click.event_nexus', self.element_selector);
        };

        $(document).on('click.event_nexus', self.element_selector, handler);
    };

    var ElementImpressionTracker = function (element_selector, tracking_data) {
        this.element_selector = element_selector;
        this.tracking_data = $.extend({is_interactive: false}, tracking_data);
    };

    ElementImpressionTracker.prototype.bind = function (tracking_data_handler) {
        var self = this;

        $(function () {
            var $matching_elements = $(self.element_selector);
            $matching_elements.each(function () {
                var tracking_data = resolve_tracking_data(
                    self.tracking_data,
                    $(this)
                );
                tracking_data_handler(tracking_data);
            });
        });
    };

    var resolve_tracking_data = function (tracking_data, $element) {
        var resolved_tracking_data = {};

        $.each(tracking_data, function (key, value) {
            var resolved_value;
            if ($.isFunction(value)) {
                resolved_value = value($element);
            } else {
                resolved_value = value;
            }
            resolved_tracking_data[key] = resolved_value;
        });

        return resolved_tracking_data;
    };

    // Public API

    var module = {
        build_specific_user_interaction_tracker:
            build_specific_user_interaction_tracker,
        ClickTracker: build_specific_user_interaction_tracker('click'),
        ElementImpressionTracker: ElementImpressionTracker,
        OutboundLinkTracker: OutboundLinkTracker,
        UserInteractionTracker: UserInteractionTracker,
        resolve_tracking_data: resolve_tracking_data
    };
    return module;
})();

var event_recorders = (function () {

    'use strict';

    var ConsoleEventRecorder = function () {};
    ConsoleEventRecorder.prototype.record = (function () {
        var recording_function;

        if (window.console) {
            recording_function = function (tracking_data) {
                var message = '';
                $.each(tracking_data, function(key, value) {
                    message += key + ': ' + value + ', ';
                });
                console.info(message);
            };
        } else {
            recording_function = $.noop;
        }
        return recording_function;
    })();

    // Public API

    var module = {
        ConsoleEventRecorder: ConsoleEventRecorder
    };
    return module;
})();

var event_tracker_binding = (function () {

    'use strict';

    var check_element_to_track_exists = function (tracker_configuration) {
        if (!window.console) {
            return;
        }

        var element_selector =
            tracker_configuration.event_tracker.element_selector;
        if ($(element_selector).length) {
            console.log('Tracked element "' + element_selector + '" found');
        } else {
            console.warn(
                'Tracked element "' + element_selector + '" not found'
            );
        }
    };

    var bind_trackers_to_dom = function (
        event_tracking_configuration,
        event_recorder,
        page_id,
        debug
    ) {
        $.each(event_tracking_configuration, function () {
            var tracker_configuration = this;

            var are_page_ids_specified =
                !$.isEmptyObject(tracker_configuration.page_ids);
            var is_current_page_id_matched =
                $.inArray(page_id, tracker_configuration.page_ids) !== -1;
            if (are_page_ids_specified && !is_current_page_id_matched) {
                return true;
            }

            if (debug) {
                check_element_to_track_exists(tracker_configuration);
            }

            tracker_configuration.event_tracker.bind(
                function (tracking_data) {
                    event_recorder.record(tracking_data);
                }
            );
        });
    };

    // Public API

    var module = {
        bind_trackers_to_dom: bind_trackers_to_dom
    };
    return module;
})();
<commit_msg>Improved the way OutboundLinkTracker is implemented<commit_after>/**
* Copyright (c) 2012, 2degrees Limited <2degrees-floss@googlegroups.com>.
* All Rights Reserved.
*
* This file is part of event-nexus
* <https://github.com/2degrees/event-nexus>, which is subject to
* the provisions of the BSD at
* <http://dev.2degreesnetwork.com/p/2degrees-license.html>. A copy of the
* license should accompany this distribution. THIS SOFTWARE IS PROVIDED "AS IS"
* AND ANY AND ALL EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST
* INFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Dependencies:
* - jQuery 1.7.2+
*
*/

var event_trackers = (function () {

    'use strict';

    var UserInteractionTracker = function (
        element_selector,
        event_name,
        tracking_data
    ) {
        this.element_selector = element_selector;
        this.event_name = event_name;
        this.tracking_data = $.extend({is_interactive: true}, tracking_data);
    };

    UserInteractionTracker.prototype.bind = function (tracking_data_handler) {
        var self = this;
        $(document).on(self.event_name, self.element_selector, function () {
            var tracking_data = resolve_tracking_data(
                self.tracking_data,
                $(this)
            );
            tracking_data_handler(tracking_data);
        });
    };

    var build_specific_user_interaction_tracker = function (event_name) {
        return function (element_selector, tracking_data) {
            return new UserInteractionTracker(
                element_selector,
                event_name,
                tracking_data
            );
        };
    };

    /**
     * Tracker for links which leave the current page.
     *
     * @param {String} element_selector
     * @param {Object} tracking_data
     */
    var OutboundLinkTracker = function (element_selector, tracking_data) {
        this.element_selector = element_selector;
        this.tracking_data = $.extend({is_interactive: true}, tracking_data);
    };
    OutboundLinkTracker.prototype.bind = function (tracking_data_handler) {
        var self = this;

        var handler = function (event) {
            var $element = $(this);
            if (!$element.attr('href')) {
                $.error(
                    'Cannot use OutboundLinkTracker on elements without "href"'
                );
            }

            var tracking_data = resolve_tracking_data(
                self.tracking_data,
                $element
            );
            tracking_data_handler(tracking_data);

            // Delay outbound click
            if (event.metaKey || event.ctrlKey) {
                event.preventDefault();
                setTimeout(
                    function () { location.href = $element.attr('href'); },
                    100
                );
                $(document).off('click.event_nexus', self.element_selector);
            }
        };

        $(document).on('click.event_nexus', self.element_selector, handler);
    };

    var ElementImpressionTracker = function (element_selector, tracking_data) {
        this.element_selector = element_selector;
        this.tracking_data = $.extend({is_interactive: false}, tracking_data);
    };

    ElementImpressionTracker.prototype.bind = function (tracking_data_handler) {
        var self = this;

        $(function () {
            var $matching_elements = $(self.element_selector);
            $matching_elements.each(function () {
                var tracking_data = resolve_tracking_data(
                    self.tracking_data,
                    $(this)
                );
                tracking_data_handler(tracking_data);
            });
        });
    };

    var resolve_tracking_data = function (tracking_data, $element) {
        var resolved_tracking_data = {};

        $.each(tracking_data, function (key, value) {
            var resolved_value;
            if ($.isFunction(value)) {
                resolved_value = value($element);
            } else {
                resolved_value = value;
            }
            resolved_tracking_data[key] = resolved_value;
        });

        return resolved_tracking_data;
    };

    // Public API

    var module = {
        build_specific_user_interaction_tracker:
            build_specific_user_interaction_tracker,
        ClickTracker: build_specific_user_interaction_tracker('click'),
        ElementImpressionTracker: ElementImpressionTracker,
        OutboundLinkTracker: OutboundLinkTracker,
        UserInteractionTracker: UserInteractionTracker,
        resolve_tracking_data: resolve_tracking_data
    };
    return module;
})();

var event_recorders = (function () {

    'use strict';

    var ConsoleEventRecorder = function () {};
    ConsoleEventRecorder.prototype.record = (function () {
        var recording_function;

        if (window.console) {
            recording_function = function (tracking_data) {
                var message = '';
                $.each(tracking_data, function(key, value) {
                    message += key + ': ' + value + ', ';
                });
                console.info(message);
            };
        } else {
            recording_function = $.noop;
        }
        return recording_function;
    })();

    // Public API

    var module = {
        ConsoleEventRecorder: ConsoleEventRecorder
    };
    return module;
})();

var event_tracker_binding = (function () {

    'use strict';

    var check_element_to_track_exists = function (tracker_configuration) {
        if (!window.console) {
            return;
        }

        var element_selector =
            tracker_configuration.event_tracker.element_selector;
        if ($(element_selector).length) {
            console.log('Tracked element "' + element_selector + '" found');
        } else {
            console.warn(
                'Tracked element "' + element_selector + '" not found'
            );
        }
    };

    var bind_trackers_to_dom = function (
        event_tracking_configuration,
        event_recorder,
        page_id,
        debug
    ) {
        $.each(event_tracking_configuration, function () {
            var tracker_configuration = this;

            var are_page_ids_specified =
                !$.isEmptyObject(tracker_configuration.page_ids);
            var is_current_page_id_matched =
                $.inArray(page_id, tracker_configuration.page_ids) !== -1;
            if (are_page_ids_specified && !is_current_page_id_matched) {
                return true;
            }

            if (debug) {
                check_element_to_track_exists(tracker_configuration);
            }

            tracker_configuration.event_tracker.bind(
                function (tracking_data) {
                    event_recorder.record(tracking_data);
                }
            );
        });
    };

    // Public API

    var module = {
        bind_trackers_to_dom: bind_trackers_to_dom
    };
    return module;
})();
<|endoftext|>


<commit_before>// dependencies
//
import React from 'react';
import uniqueId from 'lodash/uniqueId';

class RadioButtonGroup extends React.Component {
    constructor(props) {
        super(props);

        this.id = uniqueId('form-radiobuttongroup-');
    }

    render() {
        const { label, options } = this.props;

        return (

                {label ? ({label}) : null}
                {options.map((opt) => (

                            <input type="radio" name={this.id} value={opt.value} />
                            {opt.name}

                ))}

        );
    }
}

export default RadioButtonGroup;
<commit_msg>code cleanup<commit_after>// dependencies
//
import React from 'react';
import uniqueId from 'lodash/uniqueId';

class RadioButtonGroup extends React.Component {
    constructor(props) {
        super(props);

        this.id = uniqueId('form-radiobuttongroup-');
    }

    render() {
        const { label, options } = this.props;

        return (

                {label ? ({label}) : null}
                {options.map((opt) => (

                            <input type="radio" name={this.id} value={opt.value} />
                            {opt.name}

                ))}

        );
    }
}

export default RadioButtonGroup;
<|endoftext|>


<commit_before>module.exports = [{
  label: 'Link',
  selectors: [
    '[data-backstop="cdr-link"]',
    '[data-backstop="cdr-link--standalone"]',
    '[data-backstop="cdr-link--button"]',
  ],
  hoverSelectors: [
    '[data-backstop="cdr-link--standalone"]',
  ],
}];
<commit_msg>refactor(link): restore backstop tests for link<commit_after>module.exports = [{
  url: 'http://localhost:3000/#/links',
  label: 'Link',
  selectors: [
    '[data-backstop="cdr-link"]',
    '[data-backstop="cdr-link--standalone"]',
    '[data-backstop="cdr-link--button"]',
  ],
  hoverSelectors: [
    '[data-backstop="cdr-link--standalone"]',
  ],
}];
<|endoftext|>


<commit_before>var gulp        = require('gulp');
var browserify  = require('gulp-browserify');
var jade        = require('gulp-jade');
var uglify      = require('gulp-uglify');
var concat      = require('gulp-concat');
var rename      = require('gulp-rename');
var browserSync = require('browser-sync').create();

var dist = './dist';
var src  = './src';

// default task
gulp.task('default', ['browser-sync'], function () {
  gulp.watch('dist/*.html', ['reload']);
  gulp.watch('dist/*.css', ['reload']);
  gulp.watch('dist/*.js', ['reload']);
});

// sync browser
gulp.task('browser-sync', function() {
  browserSync.init({
    port: 8080,
    server: {
      baseDir: 'dist',
      index: 'popup.html'
    }
  });
});

// reload browser
gulp.task('reload', function () {
  browserSync.reload();
});

// copy bootflat files into src

// convert jade to html
gulp.task('jade', function() {
  gulp.src('./src/jade/*.jade')
    .pipe(jade())
    .pipe(gulp.dest('./dist/'));
});

// convert sass to css

// concat css

// minify css

// minify and concat js
gulp.task('js', function() {
  gulp.src([
    './node_modules/bootflat/js/bootstrap.min.js'
  ])
  .pipe(uglify({
    preserveComments: 'license'
  }))
  .pipe(concat('app.js'))
  .pipe(gulp.dest('dist/js'));
});

// convert and minify and distribution into dist

// watch src
<commit_msg>Implement gulpfile<commit_after>var gulp        = require('gulp');
var browserify  = require('gulp-browserify');
var jade        = require('gulp-jade');
var minifyCss   = require('gulp-minify-css');
var uglify      = require('gulp-uglify');
var concat      = require('gulp-concat');
var rename      = require('gulp-rename');
var browserSync = require('browser-sync').create();

var dist = './dist';
var src  = './src';

// default task
gulp.task('default', ['browser-sync'], function () {
  gulp.watch('dist/*.html', ['reload']);
  gulp.watch('dist/*.css', ['reload']);
  gulp.watch('dist/*.js', ['reload']);
});

// sync browser
gulp.task('browser-sync', function() {
  browserSync.init({
    port: 8080,
    server: {
      baseDir: 'dist',
      index: 'popup.html'
    }
  });
});

// reload browser
gulp.task('reload', function () {
  browserSync.reload();
});

// copy bootflat files into src

// convert jade to html
gulp.task('jade', function() {
  gulp.src('./src/jade/*.jade')
    .pipe(jade())
    .pipe(gulp.dest('./dist/'));
});

// convert sass to css

// minify and concat css
gulp.task('css', function() {
  gulp.src([
    './node_modules/bootflat/bootflat/css/bootflat.min.css'
  ])
  .pipe(minifyCss())
  .pipe(concat('app.css'))
  .pipe(gulp.dest('dist/css'));
});

// minify and concat js
gulp.task('js', function() {
  gulp.src([
    './node_modules/bootflat/js/bootstrap.min.js'
  ])
  .pipe(uglify({
    preserveComments: 'license'
  }))
  .pipe(concat('app.js'))
  .pipe(gulp.dest('dist/js'));
});

// convert and minify and distribution into dist

// watch src
<|endoftext|>