<commit_before>var PinPoint = PinPoint || {};

PinPoint.updatePopup = function() {
  chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
    // Pull the url from the current tab
    var url = tabs[0].url;
    // Create array of note objects belonging to current url; returns empty array if no notes present.
    var notes = getNotes(url);
    // Sorts the notes by time of video
    notes.sort(function(a,b) { return a.seconds - b.seconds } );

    var table = document.getElementById('notes-table');
    table.innerHTML = '';

    for (note of notes) {
      var node = new PinPoint.NotePresenter(note).present();
      table.appendChild(node);
    }

    var links = document.getElementsByClassName("link");
      for(var i=0;i< links.length; i++) {
        links[i].addEventListener("click", tabUpdate(i));
      };
      function tabUpdate(i) {
        return function(){
        chrome.tabs.update(null, {url: links[i].href});
        };
      };
  });
};

window.addEventListener('load', function() {
  var dashLink = document.getElementById("dash-link")
  dashLink.addEventListener("click", function(){
    chrome.tabs.create({url: "dashboard.html"})
  })
});

<commit_msg>Add event listener for clicking enable/disable link (skeleton, unfinished logic) and assign backgroundpage to variable for access.<commit_after>var PinPoint = PinPoint || {};

window.addEventListener('load', function() {
  var backgroundPage = chrome.extension.getBackgroundPage()

  var dashLink = document.getElementById("dash-link")
  dashLink.addEventListener("click", function(){
    chrome.tabs.create({url: "dashboard.html"})
  })

  var disableLink = document.getElementById("disable")
  dashLink.addEventListener("click", function(){

  })
});
// PinPoint.updatePopup = function() {
//   chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
//     // Pull the url from the current tab
//     var url = tabs[0].url;
//     // Create array of note objects belonging to current url; returns empty array if no notes present.
//     var notes = getNotes(url);
//     // Sorts the notes by time of video
//     notes.sort(function(a,b) { return a.seconds - b.seconds } );

//     var table = document.getElementById('notes-table');
//     table.innerHTML = '';

//     for (note of notes) {
//       var node = new PinPoint.NotePresenter(note).present();
//       table.appendChild(node);
//     }

//     var links = document.getElementsByClassName("link");
//       for(var i=0;i< links.length; i++) {
//         links[i].addEventListener("click", tabUpdate(i));
//       };
//       function tabUpdate(i) {
//         return function(){
//         chrome.tabs.update(null, {url: links[i].href});
//         };
//       };
//   });
// };

<|endoftext|>


<commit_before>// 3rd party modules
var chalk = require('chalk');
var glob = require('glob');

// public
module.exports = resolveTarball;

// implementation
function resolveTarball (deps) {
  return Promise.all(deps.map(resolvePackage));
}

function resolvePackage (dep) {
  return new Promise(function (resolve, reject) {
    var pkgPath = getPkgPath(dep);
    var pkgJson = getPkgJson(pkgPath);
    if (pkgJson && pkgJson.dist && pkgJson.dist.tarball) {
      dep.shrinkwrap.resolved = pkgJson.dist.tarball;
      console.info(chalk.green('✓ set missing "resolved" property for %s to %s'), dep.id, dep.shrinkwrap.resolved);
      resolve();
    } else {
      console.error(chalk.red('failed to resolve tarball for %s'), dep.id);
      reject(new Error('failed to resolve tarball for ' + dep.id));
    }
  });
}

function getPkgJson (pkgPath) {
  return pkgPath ? require(pkgPath) : {
    dist: {
      tarball: ''
    }
  };
}

function getPkgPath (dep) {
  return glob.sync('node_modules/**/' + dep.name + '/**/package.json', {
    realpath: true
  })[0] || '';
}
<commit_msg>feat(shrinkwrap): query registry if unable to patch missing resolved property locally<commit_after>// 3rd party modules
var chalk = require('chalk');
var glob = require('glob');

// modules
var shell = require('./lib/shell');

// public
module.exports = resolveTarball;

// implementation
function resolveTarball (deps) {
  return Promise.all(deps.map(resolveLocally));
}

function resolveLocally (dep) {
  return new Promise(function (resolve, reject) {
    var pkgPath = getPkgPath(dep);
    var pkgJson = getPkgJson(pkgPath);
    if (pkgJson && pkgJson.dist && pkgJson.dist.tarball) {
      dep.shrinkwrap.resolved = pkgJson.dist.tarball;
      console.info(chalk.green('✓ set missing "resolved" property for %s to %s'), dep.id, dep.shrinkwrap.resolved);
      resolve();
    } else {
      console.info(chalk.gray('? %s has no "dist.tarball" in package.json, trying npm registry...'), dep.id);
      resolveRemotely(dep)
        .then(resolve, reject);
    }
  });
}

function getPkgJson (pkgPath) {
  return pkgPath ? require(pkgPath) : {
    dist: {
      tarball: ''
    }
  };
}

function getPkgPath (dep) {
  return glob.sync('node_modules/**/' + dep.name + '/package.json', {
    realpath: true
  })[0] || '';
}

function resolveRemotely (dep) {
  return shell('npm view ' + dep.id + ' --json')
    .then(success, fail)
    .catch(fail);

  function success (stdout) {
    dep.shrinkwrap.resolved = JSON.parse(stdout).dist.tarball;
    console.info(chalk.green('✓ set missing "resolved" property for %s to %s'), dep.id, dep.shrinkwrap.resolved);
  }

  function fail (err) {
    console.error(chalk.red('! failed to resolve tarball for %s'), dep.id);
    throw err;
  }
}
<|endoftext|>


<commit_before>export default class Router {
    constructor (data) {
        this.data = {};

        if (data) {
            this.data = data;
        }
    }

    route (hash) {
        //TODO: use regex to catch dynamic urls
        if (this.data[hash] !== undefined) {
            this.data[hash]();
        } else {
            this.data['default']();
        }
    }
}
<commit_msg>checking for function assigned for the selected hash instead of just undefined check<commit_after>export default class Router {
    constructor (data) {
        this.data = {};

        if (data) {
            this.data = data;
        }
    }

    route (hash) {
        //TODO: use regex to catch dynamic urls
        if (typeof this.data[hash] === 'function') {
            this.data[hash]();
        } else {
            this.data['default']();
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>selected row was not marked in labellist_callback<commit_after><|endoftext|>


<commit_before>// @flow
import React, {Component} from 'react'
import {Box, Icon, Input, Text} from '../../common-adapters'
import {globalColors, globalMargins, globalStyles} from '../../styles'

import type {Props} from './'

class Conversation extends Component<void, Props, void> {
  _input: any

  _setRef = r => {
    this._input = r
  }

  render () {
    return (
      <Box style={{...globalStyles.flexBoxColumn, minHeight: 48, borderTop: `solid 1px ${globalColors.black_05}`}}>
        <Box style={{...globalStyles.flexBoxRow}}>
          <Input
            small={true}
            style={styleInput}
            hintStyle={{textAlign: 'left'}}
            ref={this._setRef}
            hintText={`Write to ${this.props.participants.join(', ')}`}
            underlineShow={false}
            onEnterKeyDown={() => {
              this.props.onPostMessage(this._input.getValue())
              this._input.clearValue()
            }}
          />
          <Icon style={styleIcon} type='iconfont-emoji' />
          <Icon style={styleIcon} type='iconfont-attachment' />
        </Box>
        <Text type='BodySmall' style={styleFooter}>*bold*, _italics_, `code`, >quote</Text>
      </Box>
    )
  }
}

const styleInput = {
  flex: 1,
  marginLeft: globalMargins.tiny,
  marginRight: globalMargins.tiny,
  textAlign: 'left',
}

const styleIcon = {
  padding: 5,
}

const styleFooter = {
  flex: 1,
  color: globalColors.black_20,
  textAlign: 'right',
  marginTop: 0,
  marginBottom: globalMargins.tiny,
  marginRight: globalMargins.tiny,
}

export default Conversation
<commit_msg>Closer to Zeplin<commit_after>// @flow
import React, {Component} from 'react'
import {Box, Icon, Input, Text} from '../../common-adapters'
import {globalColors, globalMargins, globalStyles} from '../../styles'

import type {Props} from './'

class Conversation extends Component<void, Props, void> {
  _input: any

  _setRef = r => {
    this._input = r
  }

  render () {
    return (
      <Box style={{...globalStyles.flexBoxColumn, borderTop: `solid 1px ${globalColors.black_05}`}}>
        <Box style={{...globalStyles.flexBoxRow}}>
          <Input
            small={true}
            style={styleInput}
            hintStyle={{textAlign: 'left'}}
            ref={this._setRef}
            hintText={`Write to ${this.props.participants.join(', ')}`}
            underlineShow={false}
            onEnterKeyDown={() => {
              this.props.onPostMessage(this._input.getValue())
              this._input.clearValue()
            }}
          />
          <Icon onClick={() => console.log('emoji callback')} style={styleIcon} type='iconfont-emoji' />
          <Icon onClick={() => console.log('attachment callback')} style={styleIcon} type='iconfont-attachment' />
        </Box>
        <Text type='BodySmall' style={styleFooter}>*bold*, _italics_, `code`, >quote</Text>
      </Box>
    )
  }
}

const styleInput = {
  flex: 1,
  marginLeft: globalMargins.tiny,
  marginRight: globalMargins.tiny,
  textAlign: 'left',
}

const styleIcon = {
  paddingTop: globalMargins.xtiny,
  paddingLeft: globalMargins.xtiny,
  paddingRight: globalMargins.xtiny,

}

const styleFooter = {
  flex: 1,
  color: globalColors.black_20,
  textAlign: 'right',
  marginTop: 0,
  marginBottom: globalMargins.xtiny,
  marginRight: globalMargins.tiny,
}

export default Conversation
<|endoftext|>


<commit_before>'use strict';

var express = require('express'); // do not change this line

var server = express();

server.get('/lorem', function(req, res) {
	res.status(200);
	res.set({ 'Content-Type': 'text/html' });
	res.write('<!DOCTYPE html>lorem ipsum');
	res.end();
});

server.listen(process.env.PORT || 8080);

// create an express server that listens on port: process.env.PORT || 8080
// on a get request of '/lorem', respond with a webpage containing '<!DOCTYPE html>lorem ipsum'
<commit_msg>checkout sample node app<commit_after><|endoftext|>


<commit_before>/*
 * grunt-contrib-internal
 * http://gruntjs.com/
 *
 * Copyright (c) 2014 Tyler Kellen, contributors
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  // Add custom template delimiters.
  grunt.template.addDelimiters('build-contrib', '{%', '%}');

  grunt.registerTask('build-contrib', 'Generate contrib plugin files.', function() {
    var path = require('path');
    var readJson = require('read-package-json');

    var done = this.async();
    var asset = path.join.bind(null, __dirname, 'assets');
    var self = this;

    readJson('package.json', console.error, false, function (err, data) {
      if (err) {
        console.error("There was an error reading the file");
        done(false);
      }

      var meta = data;
      meta.changelog = grunt.file.readYAML('CHANGELOG');
      meta.travis = grunt.file.exists('.travis.yml');

      if (meta.travis) {
        // create a valid Travis URL, based on [user/repository_name]
        meta.travis = 'https://travis-ci.org' + meta.repository.url
          .replace('github.com', '')
          .replace('git://', '')
          .replace('https://', '')
          .replace('http://', '')
          .replace('.git', '');
      }

      meta.appveyor = grunt.file.exists('appveyor.yml') ? grunt.file.readYAML('appveyor.yml') : null;

      if (meta.appveyor && meta.appveyor.project_id) {
        var pid = meta.appveyor.project_id;
        meta.appveyor = 'https://ci.appveyor.com/api/projects/status/' + pid + '/branch/master';
      }

      var authors = grunt.file.read('AUTHORS');
      meta.authors = authors.split('\n').map(function(author) {
        var matches = author.match(/(.*?)\s*\((.*)\)/) || [];
        return {name: matches[1], url: matches[2]};
      });

      // Used to display the "in development" warning message @ the top.
      meta.in_development = (meta.keywords || []).indexOf('gruntplugin') === -1 || '';

      // Read plugin/task docs.
      meta.docs = {plugin: {}, task: {}};
      grunt.file.expand('docs/*.md').forEach(function(filepath) {
        // Parse out the task name and section name.
        var basename = path.basename(filepath, '.md');
        var parts = basename.split('-');
        var section = parts.pop();
        var taskname = parts.join('-');

        var namespace = taskname ? meta.docs.task : meta.docs.plugin;
        if (taskname) {
          if (!namespace[taskname]) { namespace[taskname] = {}; }
          namespace = namespace[taskname];
        }

        // Read doc file.
        var doc = grunt.file.read(filepath);
        // Adjust header level to be semantically correct for the readme.
        doc = doc.replace(/^#/gm, '###');
        // Process as template.
        doc = grunt.template.process(doc, {data: meta, delimiters: 'build-contrib'});
        namespace[section] = doc;
      });

      // Generate readme.
      var tmpl = grunt.file.read(asset('README.tmpl.md'));
      var newReadme = grunt.template.process(tmpl, {data: meta, delimiters: 'build-contrib'});

      // Only write readme if it actually changed.
      var oldReadme = grunt.file.exists('README.md') ? grunt.file.read('README.md') : '';
      var re = /(\*This file was generated on.*)/;
      if (oldReadme.replace(re, '') !== newReadme.replace(re, '')) {
        grunt.file.write('README.md', newReadme);
        grunt.log.ok('Created README.md');
      } else {
        grunt.log.ok('Keeping README.md.');
      }

      // Copy contributing guide
      grunt.file.copy(path.resolve(__dirname, '..', 'CONTRIBUTING.md'), 'CONTRIBUTING.md');
      grunt.log.ok('Created CONTRIBUTING.md');

      // Fail task if any errors were logged.
      if (self.errorCount > 0) { done(false); }
      done();
    });

  });

};
<commit_msg>Use SVG for the AppVeyor badge too.<commit_after>/*
 * grunt-contrib-internal
 * http://gruntjs.com/
 *
 * Copyright (c) 2014 Tyler Kellen, contributors
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {

  // Add custom template delimiters.
  grunt.template.addDelimiters('build-contrib', '{%', '%}');

  grunt.registerTask('build-contrib', 'Generate contrib plugin files.', function() {
    var path = require('path');
    var readJson = require('read-package-json');

    var done = this.async();
    var asset = path.join.bind(null, __dirname, 'assets');
    var self = this;

    readJson('package.json', console.error, false, function (err, data) {
      if (err) {
        console.error("There was an error reading the file");
        done(false);
      }

      var meta = data;
      meta.changelog = grunt.file.readYAML('CHANGELOG');
      meta.travis = grunt.file.exists('.travis.yml');

      if (meta.travis) {
        // create a valid Travis URL, based on [user/repository_name]
        meta.travis = 'https://travis-ci.org' + meta.repository.url
          .replace('github.com', '')
          .replace('git://', '')
          .replace('https://', '')
          .replace('http://', '')
          .replace('.git', '');
      }

      meta.appveyor = grunt.file.exists('appveyor.yml') ? grunt.file.readYAML('appveyor.yml') : null;

      if (meta.appveyor && meta.appveyor.project_id) {
        var pid = meta.appveyor.project_id;
        meta.appveyor = 'https://ci.appveyor.com/api/projects/status/' + pid + '/branch/master?svg=true';
      }

      var authors = grunt.file.read('AUTHORS');
      meta.authors = authors.split('\n').map(function(author) {
        var matches = author.match(/(.*?)\s*\((.*)\)/) || [];
        return {name: matches[1], url: matches[2]};
      });

      // Used to display the "in development" warning message @ the top.
      meta.in_development = (meta.keywords || []).indexOf('gruntplugin') === -1 || '';

      // Read plugin/task docs.
      meta.docs = {plugin: {}, task: {}};
      grunt.file.expand('docs/*.md').forEach(function(filepath) {
        // Parse out the task name and section name.
        var basename = path.basename(filepath, '.md');
        var parts = basename.split('-');
        var section = parts.pop();
        var taskname = parts.join('-');

        var namespace = taskname ? meta.docs.task : meta.docs.plugin;
        if (taskname) {
          if (!namespace[taskname]) { namespace[taskname] = {}; }
          namespace = namespace[taskname];
        }

        // Read doc file.
        var doc = grunt.file.read(filepath);
        // Adjust header level to be semantically correct for the readme.
        doc = doc.replace(/^#/gm, '###');
        // Process as template.
        doc = grunt.template.process(doc, {data: meta, delimiters: 'build-contrib'});
        namespace[section] = doc;
      });

      // Generate readme.
      var tmpl = grunt.file.read(asset('README.tmpl.md'));
      var newReadme = grunt.template.process(tmpl, {data: meta, delimiters: 'build-contrib'});

      // Only write readme if it actually changed.
      var oldReadme = grunt.file.exists('README.md') ? grunt.file.read('README.md') : '';
      var re = /(\*This file was generated on.*)/;
      if (oldReadme.replace(re, '') !== newReadme.replace(re, '')) {
        grunt.file.write('README.md', newReadme);
        grunt.log.ok('Created README.md');
      } else {
        grunt.log.ok('Keeping README.md.');
      }

      // Copy contributing guide
      grunt.file.copy(path.resolve(__dirname, '..', 'CONTRIBUTING.md'), 'CONTRIBUTING.md');
      grunt.log.ok('Created CONTRIBUTING.md');

      // Fail task if any errors were logged.
      if (self.errorCount > 0) { done(false); }
      done();
    });

  });

};
<|endoftext|>


<commit_before>import React from 'react';
import View from './View';
import CSS from './utils/css';

CSS.register({
  '.progress': {
    position: 'relative',
  },
  '.progress .progressBG': {
    position: 'absolute',
    opacity: '0.3',
    width: '100%',
    height: '100%',
    top: '0',
    left: '0',
  },
  '.progress .progressBar': {
    position: 'absolute',
    height: '100%',
    top: '0',
    left: '0',
  }
});

export default class Progress extends View {

  static propTypes = {
    ...View.propTypes,

    value: React.PropTypes.number,
    max: React.PropTypes.number,
  }

  static defaultProps = {
    ...View.defaultProps,
    value: 0,
    max: 100,
  }

  getClassNames(){
    let cs = super.getClassNames();
    cs.progress = true;
    return cs;
  }

  getStyle(){
    let style = super.getStyle();
    style.backgroundColor = 'transparent';
    return style;
  }

  render(){

    let w = Math.max( 0, Math.min( this.props.value / this.props.max * 100, 100 ) );

    let barStyle = {
      backgroundColor: this.getBackgroundColor(),
      width: w+'%',
    };
    let backgroundStyle = {
      backgroundColor: this.getBackgroundColor(), // this.getThemeMode() == 'light' ? -5 : 5 ),
    };
    let children = [];
    children.push(  );
    children.push(  );

    return super.render(children);

  }
}
<commit_msg>Adding keys<commit_after>import React from 'react';
import View from './View';
import CSS from './utils/css';

CSS.register({
  '.progress': {
    position: 'relative',
  },
  '.progress .progressBG': {
    position: 'absolute',
    opacity: '0.3',
    width: '100%',
    height: '100%',
    top: '0',
    left: '0',
  },
  '.progress .progressBar': {
    position: 'absolute',
    height: '100%',
    top: '0',
    left: '0',
  }
});

export default class Progress extends View {

  static propTypes = {
    ...View.propTypes,

    value: React.PropTypes.number,
    max: React.PropTypes.number,
  }

  static defaultProps = {
    ...View.defaultProps,
    value: 0,
    max: 100,
  }

  getClassNames(){
    let cs = super.getClassNames();
    cs.progress = true;
    return cs;
  }

  getStyle(){
    let style = super.getStyle();
    style.backgroundColor = 'transparent';
    return style;
  }

  render(){

    let w = Math.max( 0, Math.min( this.props.value / this.props.max * 100, 100 ) );

    let barStyle = {
      backgroundColor: this.getBackgroundColor(),
      width: w+'%',
    };
    let backgroundStyle = {
      backgroundColor: this.getBackgroundColor(), // this.getThemeMode() == 'light' ? -5 : 5 ),
    };
    let children = [];
    children.push(  );
    children.push(  );

    return super.render(children);

  }
}
<|endoftext|>


<commit_before>/*
 * grunt-build-control
 * https://github.com/robwierzbowski/grunt-build-control
 *
 * Copyright (c) 2013 Rob Wierzbowski
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {
  var fs = require('fs');
  var path = require('path');
  var crypto = require('crypto');
  var shelljs = require('shelljs');

  grunt.registerMultiTask('buildcontrol', 'Version control built code.', function() {

    var done = this.async();
    var gruntDir = shelljs.pwd();
    var remoteName = null;

    var options = this.options({
      commit: false,
      // tag: false,
      push: false,
      message: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%',
      connectCommits: true
    });

    var tokens = {
      branch: '(unavailable)',
      commit: '(unavailable)',
      name:   '(unavailable)'
    };

    // Wraps shellJs calls that act on the file structure to give better Grunt
    // output and error handling
    // Args:
    // - command: the shell command
    // - verbose: show output on the cli, defaults to true
    function execWrap(command, verbose) {
      var shellResult = shelljs.exec(command, {silent: true});
      verbose = typeof verbose === 'undefined' ? true : verbose;

      if (shellResult.code === 0) {
        if (verbose) {
          grunt.log.write(shellResult.output);
        }
      }
      else {
        throw shellResult.output;
      }
    }

    // Check requirements
    function checkRequirements () {
      // Check that required options are set.
      ['branch', 'dir', 'remote'].forEach( function (element) {
        if (!options.hasOwnProperty(element)) {
          throw('The "' + element + '" option is required.');
        }
      });

      // Check that the build directory exists
      if (!fs.existsSync(options.dir)) {
        throw('Build directory "' + options.dir + '" doesn\'t exist. Nothing to version.');
      }

      // If connectCommits is true check that the main project's working
      // directory is clean
      if (options.connectCommits && shelljs.exec('git diff', {silent: true}).output !== '') {
        throw ('There are uncommitted changes in your working directory. \n' +
          'Please commit changes to the main project before you commit to \n' +
          'the built code.\n');
      }
    }

    // Assign %token% values if available
    function assignTokens () {
      var sourceBranch = shelljs.exec('git symbolic-ref --quiet HEAD', {silent: true});
      var sourceCommit = shelljs.exec('git rev-parse --short HEAD', {silent: true});

      if (sourceBranch.code === 0) {
        tokens.branch = sourceBranch.output.split('/').pop().replace(/\n/g, '');
      }
      if (sourceCommit.code === 0) {
        tokens.commit = sourceCommit.output.replace(/\n/g, '');
      }
      if (shelljs.test('-f', 'package.json', {silent: true})) {
        tokens.name = JSON.parse(fs.readFileSync('package.json', 'utf8')).name;
      }
      else {
        tokens.name = process.cwd().split('/').pop();
      }
    }

    // Initialize git repo if one doesn't exist
    function initGit () {
      if (!fs.existsSync(path.join(gruntDir, options.dir, '.git'))) {
        grunt.log.subhead('Creating git repository in ' + options.dir + '.');

        execWrap('git init');
      }
    }

    // Create a named remote if one doesn't exist
    function initRemote () {
      remoteName = "remote-" + crypto.createHash('md5').update(options.remote).digest('hex').substring(0, 6);

      // Alternative: query by git config
      // if (shelljs.exec('git config remote.' + remoteName + '.url').output !== '') {
      if (shelljs.exec('git remote', {silent: true}).output.indexOf(remoteName) === -1) {
        grunt.log.subhead('Creating remote.');

        execWrap('git remote add ' + remoteName + ' ' + options.remote);
      }
    }

    // Create branch if it doesn't exist
    function initBranch () {
      // If branch exists
      if (shelljs.exec('git show-ref --verify --quiet refs/heads/' + options.branch, {silent: true}).code === 0) {

        // If it's not tracking the remote
        if (shelljs.exec('git config branch.' + options.branch + '.remote', {silent: true}).output.replace(/\n/g, '') !== remoteName) {

          // If remote doesn't exist
          if (shelljs.exec('git ls-remote --exit-code ' + remoteName + ' ' + options.branch, {silent: true}).code !== 0) {
            gitPush();
          }

          gitTrack();
        }
        return;
      }
      // If branch doesn't exist locally but exists on remote
      else if (shelljs.exec('git ls-remote --exit-code ' + remoteName + ' ' + options.branch, {silent: true}).code === 0) {

        // Create tracking local branch
        execWrap('git branch --track ' + options.branch  + ' ' + remoteName + '/' + options.branch);
        return;
      }
      // If branch doesn't exist anywhere
      else {
        grunt.log.subhead('Creating branch "' + options.branch + '".');

        // Create local branch
        execWrap('git checkout --orphan ' + options.branch);

        // Initialize branch so we can move the HEAD ref around
        execWrap('git commit --allow-empty -m "Initial commit."');

        // Push and track upstream branch
        gitPush();
        gitTrack();
      }
    }

    // Check if local branch should safeUpdate
    // Requires fetched local refs
    function shouldUpdate() {
      var status = shelljs.exec('git status -sb --porcelain', {silent: true});
      var ahead = false;
      var behind = false;

      if (status.code === 0) {
        ahead = status.output.indexOf('ahead') === -1 ? false : true;
        behind = status.output.indexOf('behind') === -1 ? false : true;

        if (ahead && behind) {
          throw('The remote and local branches have diverged. Please \n' +
            'resolve manually before attempting again.');
        }
        else if (ahead) {
          return false;
        }
        else if (behind) {
          return true;
        }
      }
    }

    // Fetch remote refs to a specific branch, equivalent to a pull without
    // checkout
    function safeUpdate () {
      grunt.log.subhead('Fetching ' + options.branch + ' history from ' + options.remote + '.');

      // `--update-head-ok` allows fetch on the current branch
      execWrap('git fetch --verbose --update-head-ok ' + remoteName + ' ' + options.branch + ':' + options.branch);
    }

    // Make the current working tree the branch HEAD without checking out files
    function safeCheckout () {
      execWrap('git symbolic-ref HEAD refs/heads/' + options.branch);
    }

    // Make sure the stage is clean
    function gitReset () {
      execWrap('git reset', false);
    }

    // Fetch remote refs
    function gitFetch () {
      execWrap('git fetch ' + remoteName, false);
    }

    // Set branch to track remote
    function gitTrack () {
      execWrap('git branch --set-upstream-to=' + remoteName + '/' + options.branch + ' ' + options.branch);
    }

    // Stage and commit to a branch
    function gitCommit () {
      var message = options.message
        .replace(/%sourceName%/g, tokens.name)
        .replace(/%sourceCommit%/g, tokens.commit)
        .replace(/%sourceBranch%/g, tokens.branch);

      // If there are no changes, skip commit
      if (shelljs.exec('git status --porcelain', {silent: true}).output === '') {
        grunt.log.subhead('No changes to your branch. Skipping commit.');
        return;
      }

      // Stage and commit
      grunt.log.subhead('Committing changes to ' + options.branch + '.');
      execWrap('git add -A . && git commit -m "' + message + '"');
    }

    // TODO: Implement tag option
    // Pronounced "gihttag"
    // function gitTag () {
    // }

    // Push branch to remote
    function gitPush () {
      grunt.log.subhead('Pushing ' + options.branch + ' to ' + options.remote);
      execWrap('git push ' + remoteName + ' ' + options.branch);
    }

    // Run task
    try {

      // Preperatory tasks
      checkRequirements();
      assignTokens();

      // Change working directory
      shelljs.cd(options.dir);

      // Git setup
      initGit();
      initRemote();

      // Tasks for pushing and committing
      gitFetch();

      initBranch();

      if (shouldUpdate()) {
        safeUpdate();
      }

      safeCheckout();

      if (options.commit) {
        gitCommit();
      }

      // if (options.tag) {
      //   gitCommit();
      // }

      if (options.push) {
        gitPush();
      }
    }
    catch (e) {
      grunt.fail.warn(e);
      done(false);
    }
    finally {
      // Revert working directory
      shelljs.cd(gruntDir);
      done(true);
    }
  });
};
<commit_msg>Fix error on fresh repo, existing remote branch<commit_after>/*
 * grunt-build-control
 * https://github.com/robwierzbowski/grunt-build-control
 *
 * Copyright (c) 2013 Rob Wierzbowski
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {
  var fs = require('fs');
  var path = require('path');
  var crypto = require('crypto');
  var shelljs = require('shelljs');

  grunt.registerMultiTask('buildcontrol', 'Version control built code.', function() {

    var done = this.async();
    var gruntDir = shelljs.pwd();
    var remoteName = null;

    var options = this.options({
      commit: false,
      // tag: false,
      push: false,
      message: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%',
      connectCommits: true
    });

    var tokens = {
      branch: '(unavailable)',
      commit: '(unavailable)',
      name:   '(unavailable)'
    };

    // Wraps shellJs calls that act on the file structure to give better Grunt
    // output and error handling
    // Args:
    // - command: the shell command
    // - verbose: show output on the cli, defaults to true
    function execWrap(command, verbose) {
      var shellResult = shelljs.exec(command, {silent: true});
      verbose = typeof verbose === 'undefined' ? true : verbose;

      if (shellResult.code === 0) {
        if (verbose) {
          grunt.log.write(shellResult.output);
        }
      }
      else {
        throw shellResult.output;
      }
    }

    // Check requirements
    function checkRequirements () {
      // Check that required options are set.
      ['branch', 'dir', 'remote'].forEach( function (element) {
        if (!options.hasOwnProperty(element)) {
          throw('The "' + element + '" option is required.');
        }
      });

      // Check that the build directory exists
      if (!fs.existsSync(options.dir)) {
        throw('Build directory "' + options.dir + '" doesn\'t exist. Nothing to version.');
      }

      // If connectCommits is true check that the main project's working
      // directory is clean
      if (options.connectCommits && shelljs.exec('git diff', {silent: true}).output !== '') {
        throw ('There are uncommitted changes in your working directory. \n' +
          'Please commit changes to the main project before you commit to \n' +
          'the built code.\n');
      }
    }

    // Assign %token% values if available
    function assignTokens () {
      var sourceBranch = shelljs.exec('git symbolic-ref --quiet HEAD', {silent: true});
      var sourceCommit = shelljs.exec('git rev-parse --short HEAD', {silent: true});

      if (sourceBranch.code === 0) {
        tokens.branch = sourceBranch.output.split('/').pop().replace(/\n/g, '');
      }
      if (sourceCommit.code === 0) {
        tokens.commit = sourceCommit.output.replace(/\n/g, '');
      }
      if (shelljs.test('-f', 'package.json', {silent: true})) {
        tokens.name = JSON.parse(fs.readFileSync('package.json', 'utf8')).name;
      }
      else {
        tokens.name = process.cwd().split('/').pop();
      }
    }

    // Initialize git repo if one doesn't exist
    function initGit () {
      if (!fs.existsSync(path.join(gruntDir, options.dir, '.git'))) {
        grunt.log.subhead('Creating git repository in ' + options.dir + '.');

        execWrap('git init');
      }
    }

    // Create a named remote if one doesn't exist
    function initRemote () {
      remoteName = "remote-" + crypto.createHash('md5').update(options.remote).digest('hex').substring(0, 6);

      // Alternative: query by git config
      // if (shelljs.exec('git config remote.' + remoteName + '.url').output !== '') {
      if (shelljs.exec('git remote', {silent: true}).output.indexOf(remoteName) === -1) {
        grunt.log.subhead('Creating remote.');

        execWrap('git remote add ' + remoteName + ' ' + options.remote);
      }
    }

    // Create branch if it doesn't exist
    function initBranch () {
      // If branch exists
      if (shelljs.exec('git show-ref --verify --quiet refs/heads/' + options.branch, {silent: true}).code === 0) {

        // If it's not tracking the remote
        if (shelljs.exec('git config branch.' + options.branch + '.remote', {silent: true}).output.replace(/\n/g, '') !== remoteName) {

          // If remote doesn't exist
          if (shelljs.exec('git ls-remote --exit-code ' + remoteName + ' ' + options.branch, {silent: true}).code !== 0) {
            gitPush();
          }

          gitTrack();
        }
        return;
      }
      // If branch doesn't exist locally but exists on remote
      else if (shelljs.exec('git ls-remote --exit-code ' + remoteName + ' ' + options.branch, {silent: true}).code === 0) {

        // Create tracking local branch
        execWrap('git branch --track ' + options.branch  + ' ' + remoteName + '/' + options.branch);
        return;
      }
      // If branch doesn't exist anywhere
      else {
        grunt.log.subhead('Creating branch "' + options.branch + '".');

        // Create local branch
        execWrap('git checkout --orphan ' + options.branch);

        // Initialize branch so we can move the HEAD ref around
        execWrap('git commit --allow-empty -m "Initial commit."');

        // Push and track upstream branch
        gitPush();
        gitTrack();
      }
    }

    // Check if local branch should safeUpdate
    // Requires fetched local refs
    function shouldUpdate() {
      var status = shelljs.exec('git status -sb --porcelain', {silent: true});
      var ahead = false;
      var behind = false;

      if (status.code === 0) {
        ahead = status.output.indexOf('ahead') === -1 ? false : true;
        behind = status.output.indexOf('behind') === -1 ? false : true;

        if (ahead && behind) {
          throw('The remote and local branches have diverged. Please \n' +
            'resolve manually before attempting again.');
        }
        else if (ahead) {
          return false;
        }
        else if (behind) {
          return true;
        }
      }
    }

    // Fetch remote refs to a specific branch, equivalent to a pull without
    // checkout
    function safeUpdate () {
      grunt.log.subhead('Fetching ' + options.branch + ' history from ' + options.remote + '.');

      // `--update-head-ok` allows fetch on the current branch
      execWrap('git fetch --verbose --update-head-ok ' + remoteName + ' ' + options.branch + ':' + options.branch);
    }

    // Make the current working tree the branch HEAD without checking out files
    function safeCheckout () {
      execWrap('git symbolic-ref HEAD refs/heads/' + options.branch);
    }

    // Make sure the stage is clean
    function gitReset () {
      execWrap('git reset', false);
    }

    // Fetch remote refs
    function gitFetch () {
      execWrap('git fetch ' + remoteName, false);
    }

    // Set branch to track remote
    function gitTrack () {
      execWrap('git branch --set-upstream-to=' + remoteName + '/' + options.branch + ' ' + options.branch);
    }

    // Stage and commit to a branch
    function gitCommit () {
      var message = options.message
        .replace(/%sourceName%/g, tokens.name)
        .replace(/%sourceCommit%/g, tokens.commit)
        .replace(/%sourceBranch%/g, tokens.branch);

      // If there are no changes, skip commit
      if (shelljs.exec('git status --porcelain', {silent: true}).output === '') {
        grunt.log.subhead('No changes to your branch. Skipping commit.');
        return;
      }

      // Stage and commit
      grunt.log.subhead('Committing changes to ' + options.branch + '.');
      execWrap('git add -A .');
      execWrap('git commit -m "' + message + '"');
    }

    // TODO: Implement tag option
    // Pronounced "gihttag"
    // function gitTag () {
    // }

    // Push branch to remote
    function gitPush () {
      grunt.log.subhead('Pushing ' + options.branch + ' to ' + options.remote);
      execWrap('git push ' + remoteName + ' ' + options.branch);
    }

    // Run task
    try {

      // Preperatory tasks
      checkRequirements();
      assignTokens();

      // Change working directory
      shelljs.cd(options.dir);

      // Git setup
      initGit();
      initRemote();

      // Tasks for pushing and committing
      gitFetch();
      initBranch();

      if (shouldUpdate()) {
        safeUpdate();
      }

      safeCheckout();
      gitReset();

      if (options.commit) {
        gitCommit();
      }

      // if (options.tag) {
      //   gitCommit();
      // }

      if (options.push) {
        gitPush();
      }
    }
    catch (e) {
      grunt.fail.warn(e);
      done(false);
    }
    finally {
      // Revert working directory
      shelljs.cd(gruntDir);
      done(true);
    }
  });
};
<|endoftext|>


<commit_before>var
	PluginBuilder = require('systemjs-pluginbuilder')
;

module.exports = function(grunt) {

	function onMessage(data) {
		var colors = {
			error: 'red',
			info: 'white',
			success: 'green'
		};

		grunt.log.writeln(data.message[colors[data.type]]);
	}

	grunt.registerMultiTask('pluginbuilder', 'SystemJS build task to create plugin based bundles', function() {
		var
			done = this.async(),
			options = this.options({onMessage: onMessage})
		;

		if (options.basePath) {
			options.basePath = grunt.file.expand(options.basePath)[0];
		}

		if (options.pluginPaths) {
			options.pluginPaths = grunt.file.expand(options.pluginPaths);
		}

		new PluginBuilder(options)
			.build()
			.then(function() {
				grunt.log.writeln();
				grunt.log.ok('Your build is done');
				done();
			})
			.catch(function(error) {
				grunt.log.writeln();
				grunt.log.writeln('Your build failed'.red);
				grunt.fail.warn(error);
			});
	});

};
<commit_msg>Add icons for logging<commit_after>var
	PluginBuilder = require('systemjs-pluginbuilder')
;

module.exports = function(grunt) {

	function onMessage(data) {
		var
			colors = {
				error: 'red',
				info: 'white',
				success: 'green'
			},
			icons = {
				error: String.fromCharCode(9747),
				info: String.fromCharCode(8594),
				success: String.fromCharCode(10004)
			}
		;

		grunt.log.writeln(
			icons[data.type][colors[data.type]] + ' ' +
			data.message[colors[data.type]]
		);
	}

	grunt.registerMultiTask('pluginbuilder', 'SystemJS build task to create plugin based bundles', function() {
		var
			done = this.async(),
			options = this.options({onMessage: onMessage})
		;

		if (options.basePath) {
			options.basePath = grunt.file.expand(options.basePath)[0];
		}

		if (options.pluginPaths) {
			options.pluginPaths = grunt.file.expand(options.pluginPaths);
		}

		new PluginBuilder(options)
			.build()
			.then(function() {
				grunt.log.writeln();
				grunt.log.ok('Your build is done');
				done();
			})
			.catch(function(error) {
				grunt.log.writeln();
				grunt.log.writeln('Your build failed'.red);
				grunt.fail.warn(error);
			});
	});

};
<|endoftext|>


<commit_before>function sendMessage() {
  var args = Array.prototype.slice.call( arguments );
  alert( JSON.stringify( args ) );
}

// create the benchmark suite
var suite = new Benchmark.Suite();

suite.on( 'cycle', function( event ) {
  sendMessage( 'benchmark.cycle', String( event.target ) );
});

suite.on( 'complete', function() {
  sendMessage('benchmark.done');
});

window.onerror = function( e ) {
  sendMessage( 'benchmark.error', e );
};
<commit_msg>BUGFIX: Move error messaging first in `setup.js` for better stability<commit_after>function sendMessage() {
  var args = Array.prototype.slice.call( arguments );
  alert( JSON.stringify( args ) );
}

window.onerror = function( e ) {
  sendMessage( 'benchmark.error', e );
};

// create the benchmark suite
var suite = new Benchmark.Suite();

suite.on( 'cycle', function( event ) {
  sendMessage( 'benchmark.cycle', String( event.target ) );
});

suite.on( 'complete', function() {
  sendMessage('benchmark.done');
});
<|endoftext|>


<commit_before>'use strict';

var minify = require('html-minifier').minify;
var finalTemplate =
  '<%= strict %>angular.module(<%= moduleName %><%= newModule %>).\n' +
  'run([<%= templateCache %>, function($templateCache) {' +
  '<%= put(cache) %>\n' +
  '}]);\n';

module.exports = function(grunt) {
  var chalk = require('chalk');

  grunt.registerMultiTask('angularTemplateCache', function() {
    var options = this.options({
      htmlmin: {},
      quote: '\'',
      strict: true,
      newModule: false,
      indent: '  '
    });

    if(options.module === undefined) {
      throw new Error('module must be defined.');
    }

    var indent = options.indent;
    var putTemplate = '$templateCache.put(<%= name %>,<%= template %>);';

    /**
     * Escape backslashes and the specified quotes and prepend and
     * append a quote.
     *
     * @param {string} The string to quote.
     * @returns The quoted string.
     */
    function q(string) {
      var quote = options.quote;
      string = string.replace(/\\/, '\\\\').replace(/\r?\n/, '\\n');
      string = string.replace(new RegExp(quote, 'g'), '\\' + quote);
      return quote + string + quote;
    }

    /**
     * Parse the templates to the putTemplate template.
     *
     * @param {templates} An object consisting of key->value pairs
     *                    of templateName->templateContent.
     */
    function parsePutTemplate(templates) {
      var out = '';
      for(var name in templates) {
        var tmpl = templates[name];
        if(tmpl.indexOf('\n') === -1) {
          // If it's a single line template, enquote it.
          tmpl = ' ' + q(tmpl);
        } else {
          // Otherwise enquote each line and indent it nicely.
          var ending = '\n' + indent + indent;
          tmpl = ending + tmpl.split(/^/gm).map(q).join(' +' + ending) +
                 '\n' + indent;
        }
        out += '\n' + indent + grunt.template.process(
          putTemplate, {
            data: {
              name: q(name),
              template: tmpl
            }
          }
        );
      }
      return out;
    }

    var templateCount = 0;
    this.files.forEach(function(files) {
      var cache = {};
      templateCount += files.src.length;
      files.src.filter(function(f) {
        grunt.log.verbose.writeln('Found template: ' + f);
        var content = grunt.file.read(files.cwd + '/' + f);
        if (options.preprocess instanceof Function) {
          content = options.preprocess(content, f);
        }
        if (options.htmlmin !== null) {
          content = minify(content, options.htmlmin);
        }
        if (options.postprocess instanceof Function) {
          content = options.postprocess(content, f);
        }
        if (options.processName instanceof Function) {
          f = options.processName(f, content);
        }
        cache[f] = content;
      });
      var parsedTemplate = grunt.template.process(finalTemplate, {
        data: {
          strict: options.strict ? q('use strict') + ';\n\n' : '',
          moduleName: q(options.module),
          newModule: options.newModule ? ', []' : '',
          templateCache: q('$templateCache'),
          cache: cache,
          put: parsePutTemplate
        }
      });
      grunt.file.write(files.dest, parsedTemplate);
      grunt.log.writeln(
        'Found ' + chalk.cyan(templateCount) + ' ' +
        grunt.util.pluralize(templateCount, 'template/templates')
      );
    });
  });
};
<commit_msg>feat: show which template causes htmlmin to fail<commit_after>'use strict';

var minify = require('html-minifier').minify;
var finalTemplate =
  '<%= strict %>angular.module(<%= moduleName %><%= newModule %>).\n' +
  'run([<%= templateCache %>, function($templateCache) {' +
  '<%= put(cache) %>\n' +
  '}]);\n';

module.exports = function(grunt) {
  var chalk = require('chalk');

  grunt.registerMultiTask('angularTemplateCache', function() {
    var options = this.options({
      htmlmin: {},
      quote: '\'',
      strict: true,
      newModule: false,
      indent: '  '
    });

    if(options.module === undefined) {
      throw new Error('module must be defined.');
    }

    var indent = options.indent;
    var putTemplate = '$templateCache.put(<%= name %>,<%= template %>);';

    /**
     * Escape backslashes and the specified quotes and prepend and
     * append a quote.
     *
     * @param {string} The string to quote.
     * @returns The quoted string.
     */
    function q(string) {
      var quote = options.quote;
      string = string.replace(/\\/, '\\\\').replace(/\r?\n/, '\\n');
      string = string.replace(new RegExp(quote, 'g'), '\\' + quote);
      return quote + string + quote;
    }

    /**
     * Parse the templates to the putTemplate template.
     *
     * @param {templates} An object consisting of key->value pairs
     *                    of templateName->templateContent.
     */
    function parsePutTemplate(templates) {
      var out = '';
      for(var name in templates) {
        var tmpl = templates[name];
        if(tmpl.indexOf('\n') === -1) {
          // If it's a single line template, enquote it.
          tmpl = ' ' + q(tmpl);
        } else {
          // Otherwise enquote each line and indent it nicely.
          var ending = '\n' + indent + indent;
          tmpl = ending + tmpl.split(/^/gm).map(q).join(' +' + ending) +
                 '\n' + indent;
        }
        out += '\n' + indent + grunt.template.process(
          putTemplate, {
            data: {
              name: q(name),
              template: tmpl
            }
          }
        );
      }
      return out;
    }

    var templateCount = 0;
    this.files.forEach(function(files) {
      var cache = {};
      templateCount += files.src.length;
      files.src.filter(function(f) {
        grunt.log.verbose.writeln('Found template: ' + f);
        var content = grunt.file.read(files.cwd + '/' + f);
        if (options.preprocess instanceof Function) {
          content = options.preprocess(content, f);
        }
        if (options.htmlmin !== null) {
          try {
            content = minify(content, options.htmlmin);
          } catch(e) {
            grunt.fail.warn('error minifying template: ' + f + '.');
          }
        }
        if (options.postprocess instanceof Function) {
          content = options.postprocess(content, f);
        }
        if (options.processName instanceof Function) {
          f = options.processName(f, content);
        }
        cache[f] = content;
      });
      var parsedTemplate = grunt.template.process(finalTemplate, {
        data: {
          strict: options.strict ? q('use strict') + ';\n\n' : '',
          moduleName: q(options.module),
          newModule: options.newModule ? ', []' : '',
          templateCache: q('$templateCache'),
          cache: cache,
          put: parsePutTemplate
        }
      });
      grunt.file.write(files.dest, parsedTemplate);
      grunt.log.writeln(
        'Found ' + chalk.cyan(templateCount) + ' ' +
        grunt.util.pluralize(templateCount, 'template/templates')
      );
    });
  });
};
<|endoftext|>


<commit_before>import Object3DPlugin from './rendererPlugins/Object3DPlugin';

/**
 * Используется для инициализация WebGL контекста и отрисовки объектов.
 * Для некоторых объектов может использовать специфичные рендеры.
 *
 * @param {Object} options
 * @param {HTMLElement} [options.canvas] Элемент canvas
 * @param {WebGLRenderingContext} [options.gl] Если элемент canvas не указан, то можно напрямую передать WebGL контекст
 * @param {Number} [options.pixelRatio=1] Pixel ratio экрана
 * @param {Boolean} [options.antialias=true] Использовать ли антиалиасинг
 * @param {Boolean} [options.autoClear=true] Стирать ли прошлый кадр перед новый рендерингом
 * @param {Array} [options.clearColor=true] Цвет заливки в формате RGBA
 * @param {Object} [options.sortObjects=true] Нужно ли сортировать прозрачные объекты по удаленности
 * или по renderOrder
 * */
class Renderer {
    constructor(options) {
        options = options || {};

        if (options.canvas) {
            this._canvasElement = typeof options.canvas === 'string' ?
                document.getElementById(options.canvas) : options.canvas;

            const attributes = {
                antialias: options.antialias !== undefined ? options.antialias : true
            };

            this._gl = this._canvasElement.getContext('webgl', attributes) ||
                this._canvasElement.getContext('experimental-webgl', attributes);
        } else {
            this._gl = options.gl;
        }

        this._pixelRatio = options.pixelRatio || 1;

        /**
         * Определяет стирать ли прошлый кадр перед новым рендерингом
         * @type {Boolean}
         */
        this.autoClear = options.autoClear !== undefined ? options.autoClear : true;

        /**
         * Цвет заливки в формате RGBA
         * @type {Array}
         */
        this.clearColor = options.clearColor || [1, 1, 1, 1];
        this.sortObjects = true;

        this._plugins = [];
        this._pluginsByType = {};
        this._maxPluginOrder = 0;

        this.addPlugin(new Object3DPlugin(), 0);
    }

    /**
     * Добавляет {@link RendererPlugin} к рендеру. К рендеру может быть добавлен только один плагин каждого типа.
     * @param {Plugin} plugin Плагин
     * @param {?Number} order Каждый плагин выполняется при рендеринге по возрастанию order,
     * если его нет, то выбирается максимальный order + 1.
     */
    addPlugin(plugin, order) {
        if (order === undefined) {
            order = this._maxPluginOrder + 1;
        }

        this._plugins.push({
            plugin,
            order
        });
        this._plugins.sort((a, b) => a.order - b.order);
        this._pluginsByType[plugin.type] = plugin;

        this._maxPluginOrder = Math.max.apply(Math, this._plugins.map(p => p.order));

        return this;
    }

    /**
     * Удаляет {@link RendererPlugin} из рендера.
     * @param {Plugin} Plugin Класс плагина
     */
    removePlugin(Plugin) {
        this._plugins.some((el, i) => {
            if (el.plugin instanceof Plugin) {
                delete this._pluginsByType[this._plugins[i].plugin.type];
                this._plugins.splice(i, 1);
                return true;
            }
        });

        return this;
    }

    /**
     * Устанавливает параметр pixel ratio
     * @param {Number} value
     */
    setPixelRatio(value) {
        this._pixelRatio = value;

        return this;
    }

    /**
     * Возвращает текущий pixel ratio
     * @returns {Number}
     */
    getPixelRatio() {
        return this._pixelRatio;
    }

    /**
     * Устанавливает размеры элементу canvas и viewport для WebGL
     * @param {Number} width Ширина в пикселях
     * @param {Number} height Высота в пикселях
     */
    setSize(width, height) {
        this._size = [
            width * this._pixelRatio,
            height * this._pixelRatio
        ];

        if (this._canvasElement) {
            this._canvasElement.width = this._size[0];
            this._canvasElement.height = this._size[1];
            this._canvasElement.style.width = width + 'px';
            this._canvasElement.style.height = height + 'px';
        }

        this.setViewport();

        return this;
    }

    /**
     * Устанавливает viewport для WebGL
     * Если размеры не указаны, то выставляет размеры указанные в функции {@link Renderer#setSize}
     * @param {Number} [width] Ширина в пикселях
     * @param {Number} [height] Высота в пикселях
     */
    setViewport(width, height) {
        if (width !== undefined && height !== undefined) {
            this._gl.viewport(0, 0, width, height);
        } else {
            this._gl.viewport(0, 0, this._size[0], this._size[1]);
        }

        return this;
    }

    /**
     * Возвращает текущий viewport WebGL
     * @returns {Array}
     */
    getSize() {
        return this._size;
    }

    /**
     * Устанавливает RenderTarget
     * @param {?RenderTarget} renderTarget
     */
    setRenderTarget(renderTarget) {
        this._renderTarget = renderTarget;
        return this;
    }

    /**
     * Считывает указанную область пикселей в массив
     * @param {Number} x Координаты начала области
     * @param {Number} y Координаты начала области
     * @param {Number} width Ширина области
     * @param {Number} height Высота области
     * @param {TypedArray} array Массив для записи данных
     */
    readPixels(x, y, width, height, array) {
        const gl = this._gl;

        if (this._renderTarget) {
            this._renderTarget.bind(gl);
            gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, array);
            this._renderTarget.unbind(gl);
        } else {
            gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, array);
        }

        return this;
    }

    /**
     * Очищает текущий кадр и заливает цветом указанным в clearColor
     */
    clear() {
        const gl = this._gl;

        gl.clearColor.apply(gl, this.clearColor);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        return this;
    }

    /**
     * Рисует сцену
     * @param {Scene} scene Сцена
     * @param {Camera} camera Камера
     */
    render(scene, camera) {
        const gl = this._gl;

        scene.typifyForRender(this._pluginsByType);

        if (this._renderTarget) {
            this._renderTarget.bind(gl);
        }

        gl.clearDepth(1);
        gl.clearStencil(0);

        if (this.autoClear) {
            this.clear();
        }

        camera.updateLocalMatrix();
        camera.updateWorldMatrix();

        const state = {
            renderer: this,
            scene,
            camera,
            gl
        };
        // TODO: make state immutable?

        this._plugins.forEach(el => {
            if (el.plugin.hasObjects()) {
                el.plugin.render(state);
            }
        });

        if (this._renderTarget) {
            this._renderTarget.unbind(gl);
        }

        return this;
    }
}

export default Renderer;

/**
 * Состояние рендера. Передается объектам для отрисовки.
 *
 * @typedef {Object} State
 * @property {WebGLRenderingContext} gl
 * @property {Scene} scene
 * @property {Camera} camera
 * @property {Renderer} renderer
 */
<commit_msg>Add rendering userdata (#62)<commit_after>import Object3DPlugin from './rendererPlugins/Object3DPlugin';

/**
 * Используется для инициализация WebGL контекста и отрисовки объектов.
 * Для некоторых объектов может использовать специфичные рендеры.
 *
 * @param {Object} options
 * @param {HTMLElement} [options.canvas] Элемент canvas
 * @param {WebGLRenderingContext} [options.gl] Если элемент canvas не указан, то можно напрямую передать WebGL контекст
 * @param {Number} [options.pixelRatio=1] Pixel ratio экрана
 * @param {Boolean} [options.antialias=true] Использовать ли антиалиасинг
 * @param {Boolean} [options.autoClear=true] Стирать ли прошлый кадр перед новый рендерингом
 * @param {Array} [options.clearColor=true] Цвет заливки в формате RGBA
 * @param {Object} [options.sortObjects=true] Нужно ли сортировать прозрачные объекты по удаленности
 * или по renderOrder
 * */
class Renderer {
    constructor(options) {
        options = options || {};

        if (options.canvas) {
            this._canvasElement = typeof options.canvas === 'string' ?
                document.getElementById(options.canvas) : options.canvas;

            const attributes = {
                antialias: options.antialias !== undefined ? options.antialias : true
            };

            this._gl = this._canvasElement.getContext('webgl', attributes) ||
                this._canvasElement.getContext('experimental-webgl', attributes);
        } else {
            this._gl = options.gl;
        }

        this._pixelRatio = options.pixelRatio || 1;

        /**
         * Определяет стирать ли прошлый кадр перед новым рендерингом
         * @type {Boolean}
         */
        this.autoClear = options.autoClear !== undefined ? options.autoClear : true;

        /**
         * Цвет заливки в формате RGBA
         * @type {Array}
         */
        this.clearColor = options.clearColor || [1, 1, 1, 1];
        this.sortObjects = true;

        this._plugins = [];
        this._pluginsByType = {};
        this._maxPluginOrder = 0;

        this.addPlugin(new Object3DPlugin(), 0);
    }

    /**
     * Добавляет {@link RendererPlugin} к рендеру. К рендеру может быть добавлен только один плагин каждого типа.
     * @param {Plugin} plugin Плагин
     * @param {?Number} order Каждый плагин выполняется при рендеринге по возрастанию order,
     * если его нет, то выбирается максимальный order + 1.
     */
    addPlugin(plugin, order) {
        if (order === undefined) {
            order = this._maxPluginOrder + 1;
        }

        this._plugins.push({
            plugin,
            order
        });
        this._plugins.sort((a, b) => a.order - b.order);
        this._pluginsByType[plugin.type] = plugin;

        this._maxPluginOrder = Math.max.apply(Math, this._plugins.map(p => p.order));

        return this;
    }

    /**
     * Удаляет {@link RendererPlugin} из рендера.
     * @param {Plugin} Plugin Класс плагина
     */
    removePlugin(Plugin) {
        this._plugins.some((el, i) => {
            if (el.plugin instanceof Plugin) {
                delete this._pluginsByType[this._plugins[i].plugin.type];
                this._plugins.splice(i, 1);
                return true;
            }
        });

        return this;
    }

    /**
     * Устанавливает параметр pixel ratio
     * @param {Number} value
     */
    setPixelRatio(value) {
        this._pixelRatio = value;

        return this;
    }

    /**
     * Возвращает текущий pixel ratio
     * @returns {Number}
     */
    getPixelRatio() {
        return this._pixelRatio;
    }

    /**
     * Устанавливает размеры элементу canvas и viewport для WebGL
     * @param {Number} width Ширина в пикселях
     * @param {Number} height Высота в пикселях
     */
    setSize(width, height) {
        this._size = [
            width * this._pixelRatio,
            height * this._pixelRatio
        ];

        if (this._canvasElement) {
            this._canvasElement.width = this._size[0];
            this._canvasElement.height = this._size[1];
            this._canvasElement.style.width = width + 'px';
            this._canvasElement.style.height = height + 'px';
        }

        this.setViewport();

        return this;
    }

    /**
     * Устанавливает viewport для WebGL
     * Если размеры не указаны, то выставляет размеры указанные в функции {@link Renderer#setSize}
     * @param {Number} [width] Ширина в пикселях
     * @param {Number} [height] Высота в пикселях
     */
    setViewport(width, height) {
        if (width !== undefined && height !== undefined) {
            this._gl.viewport(0, 0, width, height);
        } else {
            this._gl.viewport(0, 0, this._size[0], this._size[1]);
        }

        return this;
    }

    /**
     * Возвращает текущий viewport WebGL
     * @returns {Array}
     */
    getSize() {
        return this._size;
    }

    /**
     * Устанавливает RenderTarget
     * @param {?RenderTarget} renderTarget
     */
    setRenderTarget(renderTarget) {
        this._renderTarget = renderTarget;
        return this;
    }

    /**
     * Считывает указанную область пикселей в массив
     * @param {Number} x Координаты начала области
     * @param {Number} y Координаты начала области
     * @param {Number} width Ширина области
     * @param {Number} height Высота области
     * @param {TypedArray} array Массив для записи данных
     */
    readPixels(x, y, width, height, array) {
        const gl = this._gl;

        if (this._renderTarget) {
            this._renderTarget.bind(gl);
            gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, array);
            this._renderTarget.unbind(gl);
        } else {
            gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, array);
        }

        return this;
    }

    /**
     * Очищает текущий кадр и заливает цветом указанным в clearColor
     */
    clear() {
        const gl = this._gl;

        gl.clearColor.apply(gl, this.clearColor);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        return this;
    }

    /**
     * Рисует сцену
     * @param {Scene} scene Сцена
     * @param {Camera} camera Камера
     * @param {*} userData Дополнительная информация, которая будет передана всем плагинам и объектам
     */
    render(scene, camera, userData) {
        const gl = this._gl;

        scene.typifyForRender(this._pluginsByType);

        if (this._renderTarget) {
            this._renderTarget.bind(gl);
        }

        gl.clearDepth(1);
        gl.clearStencil(0);

        if (this.autoClear) {
            this.clear();
        }

        camera.updateLocalMatrix();
        camera.updateWorldMatrix();

        const state = {
            renderer: this,
            scene,
            camera,
            gl,
            userData
        };
        // TODO: make state immutable?

        this._plugins.forEach(el => {
            if (el.plugin.hasObjects()) {
                el.plugin.render(state);
            }
        });

        if (this._renderTarget) {
            this._renderTarget.unbind(gl);
        }

        return this;
    }
}

export default Renderer;

/**
 * Состояние рендера. Передается объектам для отрисовки.
 *
 * @typedef {Object} State
 * @property {WebGLRenderingContext} gl
 * @property {Scene} scene
 * @property {Camera} camera
 * @property {Renderer} renderer
 */
<|endoftext|>


<commit_before>/* eslint-disable no-underscore-dangle */

import assign from "object-assign";
import React from "react";

const ID = Symbol("ReactResolver.ID");
const CHILDREN = Symbol("ReactResolver.CHILDREN");
const HAS_RESOLVED = Symbol("ReactResolver.HAS_RESOLVED");
const IS_CLIENT = Symbol("ReactResolver.IS_CLIENT");

export default class Resolver extends React.Component {
  static childContextTypes = {
    resolver: React.PropTypes.instanceOf(Resolver),
  }

  static contextTypes = {
    resolver: React.PropTypes.instanceOf(Resolver),
  }

  static defaultProps = {
    data: {},
    props: {},
    resolve: {},
  }

  static propTypes = {
    component: React.PropTypes.func.isRequired,
    data: React.PropTypes.object.isRequired,
    props: React.PropTypes.object,
    resolve: React.PropTypes.object,
  }

  static render = function(render, node) {
    const initialData = window.__REACT_RESOLVER_PAYLOAD__;

    // Server-rendered output, but missing payload
    if (!initialData && node.innerHTML) {
      return Resolver.resolve(render).then(({ Resolved }) => {
        React.render(<Resolved />, node);
      });
    }

    React.render(<Resolver data={initialData} render={render} />, node);

    delete window.__REACT_RESOLVER_PAYLOAD__;
  }

  static resolve = function(render, initialData = {}) {
    const queue = [];

    React.renderToStaticMarkup(
      <Resolver
        data={initialData}
        onResolve={(promise) => queue.push(promise)}
        render={render}
      />
    );

    return Promise.all(queue).then((results) => {
      const data = assign({}, initialData);

      results.forEach(({ id, resolved }) => data[id] = resolved);

      if (Object.keys(initialData).length < Object.keys(data).length) {
        return Resolver.resolve(render, data);
      }

      class Resolved extends React.Component {
        displayName = "Resolved"

        render() {
          return (
            <Resolver data={data} render={render} />
          );
        }
      }

      return { data, Resolved };
    });
  }

  displayName = "Resolver"

  constructor(props, context) {
    super(props, context);

    // Internal tracking variables
    this[ID] = this.generateId();
    this[CHILDREN] = [];
    this[HAS_RESOLVED] = false;
    this[IS_CLIENT] = false;

    this.state = {
      pending: {},
      resolved: this.cached() || {},
    };
  }

  cached(resolver = this) {
    const id = resolver[ID];

    if (this.props.data.hasOwnProperty(id)) {
      return assign({}, this.props.data[id]);
    } else if (this.context.resolver) {
      return this.context.resolver.cached(resolver);
    }
  }

  clearData(resolver = this) {
    const id = resolver[ID];

    if (this.props.data.hasOwnProperty(id)) {
      delete this.props.data[id];
    } else if (this.context.resolver) {
      return this.context.resolver.clearData(resolver);
    }
  }

  componentDidMount() {
    this[IS_CLIENT] = true;
  }

  componentWillMount() {
    const nextState = this.computeState(this.props, this.state);

    if (this.isPending(nextState)) {
      this.resolve(nextState);
      this[HAS_RESOLVED] = false;
    } else {
      this[HAS_RESOLVED] = true;
    }

    this.setState(nextState);
  }

  componentWillReceiveProps(nextProps) {
    const cleanState = {
      pending: {},
      resolved: {},
    };

    const { pending, resolved } = this.computeState(nextProps, cleanState);

    // Next state will resolve async props again, but update existing sync props
    const nextState = {
      pending,
      resolved: { ...this.state.resolved, ...resolved },
    };

    this.setState(nextState);
  }

  computeState(thisProps, nextState) {
    const { context, props, resolve } = thisProps;

    Object.keys(resolve).forEach(name => {
      // Ignore existing supplied props or existing resolved values
      if (!props.hasOwnProperty(name) && !nextState.resolved.hasOwnProperty(name)) {
        const factory = resolve[name];
        const value = factory(props, context);

        if (value instanceof Promise) {
          nextState.pending[name] = value;
        } else {
          // Synchronous values are immediately assigned
          nextState.resolved[name] = value;
        }
      }
    });

    return nextState;
  }

  generateId() {
    const { resolver } = this.context;

    if (!resolver) {
      return ".0";
    }

    const id = `${resolver[ID]}.${resolver[CHILDREN].length}`;

    if (resolver && resolver[CHILDREN].indexOf(this) === -1) {
      resolver[CHILDREN].push(this);
    }

    return id;
  }

  getChildContext() {
    return { resolver: this };
  }

  isPending(state = this.state) {
    return Object.keys(state.pending).length > 0;
  }

  isParentPending() {
    const { resolver } = this.context;

    if (resolver) {
      return resolver.isPending() || resolver.isParentPending();
    }

    return false;
  }

  onResolve(state) {
    if (this.props.onResolve) {
      this.props.onResolve(state);
    } else if (this.context.resolver) {
      this.context.resolver.onResolve(state);
    }
  }

  render() {
    // Avoid rendering until ready
    if (!this[HAS_RESOLVED]) {
      return false;
    }

    return (
      <this.props.component
        {...this.props.props}
        {...this.state.resolved}
      />
    );
  }

  resolve(state) {
    const pending = Object.keys(state.pending).map(name => {
      const promise = state.pending[name];

      return { name, promise };
    });

    const promises = pending.map(({ promise }) => promise);

    const resolving = Promise.all(promises).then(values => {
      const id = this[ID];
      const resolved = values.reduce((resolved, value, i) => {
        const { name } = pending[i];

        resolved[name] = value;

        return resolved;
      }, {});

      return { id, resolved };
    });

    // Resolve listeners get the current ID + resolved
    this.onResolve(resolving);

    // Update current component with new data (on client)
    resolving.then(({ resolved }) => {
      this[HAS_RESOLVED] = true;

      if (!this[IS_CLIENT]) {
        return false;
      }

      const nextState = {
        pending: {},
        resolved: { ...state.resolved, ...resolved },
      };

      this.setState(nextState);
    });
  }

  shouldComponentUpdate(nextProps, nextState) {
    // Prevent rendering until pending values are resolved
    if (this.isPending(nextState)) {
      this.resolve(nextState);

      return false;
    }

    // Prevent updating when parent is changing values
    if (this.isParentPending()) {
      return false;
    }

    // Update if we have resolved successfully
    return this[HAS_RESOLVED];
  }
}
<commit_msg>Move componentWillMount logic to constructor<commit_after>/* eslint-disable no-underscore-dangle */

import assign from "object-assign";
import React from "react";

const ID = Symbol("ReactResolver.ID");
const CHILDREN = Symbol("ReactResolver.CHILDREN");
const HAS_RESOLVED = Symbol("ReactResolver.HAS_RESOLVED");
const IS_CLIENT = Symbol("ReactResolver.IS_CLIENT");

export default class Resolver extends React.Component {
  static childContextTypes = {
    resolver: React.PropTypes.instanceOf(Resolver),
  }

  static contextTypes = {
    resolver: React.PropTypes.instanceOf(Resolver),
  }

  static defaultProps = {
    data: {},
    props: {},
    resolve: {},
  }

  static propTypes = {
    component: React.PropTypes.func.isRequired,
    data: React.PropTypes.object.isRequired,
    props: React.PropTypes.object,
    resolve: React.PropTypes.object,
  }

  static render = function(render, node) {
    const initialData = window.__REACT_RESOLVER_PAYLOAD__;

    // Server-rendered output, but missing payload
    if (!initialData && node.innerHTML) {
      return Resolver.resolve(render).then(({ Resolved }) => {
        React.render(<Resolved />, node);
      });
    }

    React.render(<Resolver data={initialData} render={render} />, node);

    delete window.__REACT_RESOLVER_PAYLOAD__;
  }

  static resolve = function(render, initialData = {}) {
    const queue = [];

    React.renderToStaticMarkup(
      <Resolver
        data={initialData}
        onResolve={(promise) => queue.push(promise)}
        render={render}
      />
    );

    return Promise.all(queue).then((results) => {
      const data = assign({}, initialData);

      results.forEach(({ id, resolved }) => data[id] = resolved);

      if (Object.keys(initialData).length < Object.keys(data).length) {
        return Resolver.resolve(render, data);
      }

      class Resolved extends React.Component {
        displayName = "Resolved"

        render() {
          return (
            <Resolver data={data} render={render} />
          );
        }
      }

      return { data, Resolved };
    });
  }

  displayName = "Resolver"

  constructor(props, context) {
    super(props, context);

    // Internal tracking variables
    this[ID] = this.generateId();
    this[CHILDREN] = [];
    this[HAS_RESOLVED] = false;
    this[IS_CLIENT] = false;

    this.state = this.computeState(this.props, {
      pending: {},
      resolved: this.cached() || {},
    });

    if (this.isPending(this.state)) {
      this.resolve(this.state);
      this[HAS_RESOLVED] = false;
    } else {
      this[HAS_RESOLVED] = true;
    }
  }

  cached(resolver = this) {
    const id = resolver[ID];

    if (this.props.data.hasOwnProperty(id)) {
      return assign({}, this.props.data[id]);
    } else if (this.context.resolver) {
      return this.context.resolver.cached(resolver);
    }
  }

  clearData(resolver = this) {
    const id = resolver[ID];

    if (this.props.data.hasOwnProperty(id)) {
      delete this.props.data[id];
    } else if (this.context.resolver) {
      return this.context.resolver.clearData(resolver);
    }
  }

  componentDidMount() {
    this[IS_CLIENT] = true;

  }

  componentWillReceiveProps(nextProps) {
    const cleanState = {
      pending: {},
      resolved: {},
    };

    const { pending, resolved } = this.computeState(nextProps, cleanState);

    // Next state will resolve async props again, but update existing sync props
    const nextState = {
      pending,
      resolved: { ...this.state.resolved, ...resolved },
    };

    this.setState(nextState);
  }

  computeState(thisProps, nextState) {
    const { context, props, resolve } = thisProps;

    Object.keys(resolve).forEach(name => {
      // Ignore existing supplied props or existing resolved values
      if (!props.hasOwnProperty(name) && !nextState.resolved.hasOwnProperty(name)) {
        const factory = resolve[name];
        const value = factory(props, context);

        if (value instanceof Promise) {
          nextState.pending[name] = value;
        } else {
          // Synchronous values are immediately assigned
          nextState.resolved[name] = value;
        }
      }
    });

    return nextState;
  }

  generateId() {
    const { resolver } = this.context;

    if (!resolver) {
      return ".0";
    }

    const id = `${resolver[ID]}.${resolver[CHILDREN].length}`;

    if (resolver && resolver[CHILDREN].indexOf(this) === -1) {
      resolver[CHILDREN].push(this);
    }

    return id;
  }

  getChildContext() {
    return { resolver: this };
  }

  isPending(state = this.state) {
    return Object.keys(state.pending).length > 0;
  }

  isParentPending() {
    const { resolver } = this.context;

    if (resolver) {
      return resolver.isPending() || resolver.isParentPending();
    }

    return false;
  }

  onResolve(state) {
    if (this.props.onResolve) {
      this.props.onResolve(state);
    } else if (this.context.resolver) {
      this.context.resolver.onResolve(state);
    }
  }

  render() {
    // Avoid rendering until ready
    if (!this[HAS_RESOLVED]) {
      return false;
    }

    return (
      <this.props.component
        {...this.props.props}
        {...this.state.resolved}
      />
    );
  }

  resolve(state) {
    const pending = Object.keys(state.pending).map(name => {
      const promise = state.pending[name];

      return { name, promise };
    });

    const promises = pending.map(({ promise }) => promise);

    const resolving = Promise.all(promises).then(values => {
      const id = this[ID];
      const resolved = values.reduce((resolved, value, i) => {
        const { name } = pending[i];

        resolved[name] = value;

        return resolved;
      }, {});

      return { id, resolved };
    });

    // Resolve listeners get the current ID + resolved
    this.onResolve(resolving);

    // Update current component with new data (on client)
    resolving.then(({ resolved }) => {
      this[HAS_RESOLVED] = true;

      if (!this[IS_CLIENT]) {
        return false;
      }

      const nextState = {
        pending: {},
        resolved: { ...state.resolved, ...resolved },
      };

      this.setState(nextState);
    });
  }

  shouldComponentUpdate(nextProps, nextState) {
    // Prevent rendering until pending values are resolved
    if (this.isPending(nextState)) {
      this.resolve(nextState);

      return false;
    }

    // Prevent updating when parent is changing values
    if (this.isParentPending()) {
      return false;
    }

    // Update if we have resolved successfully
    return this[HAS_RESOLVED];
  }
}
<|endoftext|>


<commit_before>import * as React from 'react';
import classNames from 'classnames';
import prefix, { globalKey } from './utils/prefix';
import Icon from './Icon';

type Props = {
  className?: string,
  classPrefix?: string,
  style?: Object,
  itemWidth?: number | string,
  status?: 'finish' | 'wait' | 'process' | 'error',
  icon?: React.Element<typeof Icon>,
  stepNumber?: number,
  description?: React.Node,
  title?: React.Node
};

class StepItem extends React.Component<Props> {
  static defaultProps = {
    classPrefix: `${globalKey}steps-item`,
  };
  render() {
    const {
      className,
      classPrefix,
      style,
      itemWidth,
      status,
      icon,
      stepNumber,
      description,
      title,
      ...rest
    } = this.props;

    const addPrefix: Function = prefix(classPrefix);
    const classes = classNames(classPrefix, {
      [addPrefix('custom')]: icon
    }, addPrefix(`status-${status}`), className);

    const styles = {
      width: itemWidth,
      ...style
    };

    const contentNode = (title || description) ? (

        {title &&
{title}
}
        {description &&
{description}
}

    ) : null;

    let iconNode = (
      <span className={addPrefix(['icon', `icon-${status}`])}>
        {stepNumber}

    );

    if (icon) {
      iconNode = (

          {icon}

      );
    }

    return (

          {iconNode}

        {contentNode}

    );
  }
}

export default StepItem;
<commit_msg>Update StepItem.js<commit_after>import * as React from 'react';
import classNames from 'classnames';
import prefix, { globalKey } from './utils/prefix';
import Icon from './Icon';

type Props = {
  className?: string,
  classPrefix?: string,
  style?: Object,
  itemWidth?: number | string,
  status?: 'finish' | 'wait' | 'process' | 'error',
  icon?: React.Element<typeof Icon>,
  stepNumber?: number,
  description?: React.Node,
  title?: React.Node
};

class StepItem extends React.Component<Props> {
  static defaultProps = {
    classPrefix: `${globalKey}steps-item`,
  };
  render() {
    const {
      className,
      classPrefix,
      style,
      itemWidth,
      status,
      icon,
      stepNumber,
      description,
      title,
      ...rest
    } = this.props;

    const addPrefix: Function = prefix(classPrefix);
    const classes = classNames(classPrefix, {
      [addPrefix('custom')]: icon
    }, addPrefix(`status-${status}`), className);

    const styles = {
      width: itemWidth,
      ...style
    };

    const contentNode = (title || description) ? (

        {title &&
{title}
}
        {description &&
{description}
}

    ) : null;

    let iconNode = (
      <span className={addPrefix(['icon', `icon-${status}`])}>
        {stepNumber}

    );

    if (icon) {
      iconNode = (

          {icon}

      );
    }

    return (

          {iconNode}

        {contentNode}

    );
  }
}

export default StepItem;
<|endoftext|>


<commit_before>/*
 * grunt-version-build
 * https://github.com/robwierzbowski/grunt-version-build
 *
 * Copyright (c) 2013 Rob Wierzbowski
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {
  var fs = require('fs');
  var path = require('path');
  var shelljs = require('shelljs');

  grunt.registerMultiTask('version_build', 'Version built code next to your project\'s source.', function() {

    var done = this.async();
    var gruntDir = shelljs.pwd();

    var options = this.options({
      commit: false,
      // tag: false,
      push: false,
      commitMsg: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%'
    });

    var tokens = {
      branch: '(unavailable)',
      commit: '(unavailable)',
      name:   '(unavailable)'
    };

    // Check requirements
    function checkRequirements () {
      // Check that required options are set.
      ['branch', 'dir', 'remote'].forEach( function (element) {
        if (!options.hasOwnProperty(element)) {
          throw('The "' + element + '" option is required.');
        }
      });

      // Check that the dist directory exists
      if (!fs.existsSync(options.dir)) {
        grunt.log.subhead('Creating target directory "' + options.dir + '".');
        shelljs.mkdir(options.dir);
      }
    }

    // Assign %token% values if available
    function assignTokens () {
      var sourceBranch = shelljs.exec('git symbolic-ref --quiet HEAD', {silent: true});
      var sourceCommit = shelljs.exec('git rev-parse --short HEAD', {silent: true});

      if (sourceBranch.code === 0) {
        tokens.branch = sourceBranch.output.split('/').pop().replace(/\n/g, '');
      }
      if (sourceCommit.code === 0) {
        tokens.commit = sourceCommit.output.replace(/\n/g, '');
      }
      if (shelljs.test('-f', 'package.json', {silent: true})) {
        tokens.name = JSON.parse(fs.readFileSync('package.json', 'utf8')).name;
      }
      // TODO: Use containing directory name if package.json isn't available
      // else {
      //
      // }
    }

    // Initialize git repo if one doesn't exist
    function initGit () {
      if (!fs.existsSync(path.join(gruntDir, options.dir, '.git'))) {
        grunt.log.subhead('Creating git repository in ' + options.dir + '.');
        shelljs.exec('git init');
      }
    }

    // Fetch remote refs
    function gitFetch () {
      grunt.log.subhead('Fetching ' + options.branch + ' history from ' + options.remote + '.');

      // `--update-head-ok` allows fetch on the current branch
      shelljs.exec('git fetch --tags --verbose --update-head-ok ' + options.remote + ' ' + options.branch + ':' + options.branch);
    }

    // Create branch if it doesn't exist
    function initBranch () {

      // If branch exists, all is good
      if (shelljs.exec('git show-ref --verify --quiet refs/heads/' + options.branch, {silent: true}).code === 0) {
        return;
      }
      // If branch exists on remote, fetch it
      else if (shelljs.exec('git ls-remote --exit-code ' + options.remote + ' ' + options.branch, {silent: true}).code === 0) {

        gitFetch();
        return;
      }
      // If branch doesn't exist anywhere, create it
      else {

        grunt.log.subhead('Creating branch "' + options.branch + '".');

        shelljs.exec('git checkout --orphan ' + options.branch);
        shelljs.exec('git reset', {silent: true});

        // Initialize branch so we can move the HEAD ref around
        shelljs.exec('git commit --allow-empty -m "Initial commit"');
      }
    }

    // Make the current working tree the branch HEAD without checking out files
    function safeCheckout () {
      shelljs.exec('git symbolic-ref HEAD refs/heads/' + options.branch);
    }

    // Stage and commit to a branch
    function gitCommit () {
      var commitMsg = options.commitMsg
        .replace(/%sourceName%/g, tokens.name)
        .replace(/%sourceCommit%/g, tokens.commit)
        .replace(/%sourceBranch%/g, tokens.branch);

      // Unstage any changes, just in case
      shelljs.exec('git reset', {silent: true});

      // If there are no changes, skip commit
      if (shelljs.exec('git status --porcelain', {silent: true}).output === '') {
        grunt.log.subhead('No changes to your branch. Skipping commit.');
        return;
      }

      // Stage and commit
      grunt.log.subhead('Committing changes to ' + options.branch + '.');
      shelljs.exec('git add -A . && git commit -m "' + commitMsg + '"');
    }

    // TODO: Implement tag option
    // Pronounced "gihttag"
    // function gitTag () {
    // }

    // Push branch to remote
    function gitPush () {
      grunt.log.subhead('Pushing ' + options.branch + ' to ' + options.remote);
      shelljs.exec('git push --tags ' + options.remote + ' HEAD:' + options.branch);
    }

    // Run task
    try {
      checkRequirements();
      assignTokens();

      // Change working directory
      shelljs.cd(options.dir);

      initGit();
      initBranch();
      safeCheckout();

      // Fetch changes from remote branch if it exists
      // TODO: Instead of checking if the remote exists, it would be better to
      // - check if remote is ahead of local
      // - check if remote is a ff merge
      // and if so, gitFetch(). Otherwise throw helpful, descriptive errors
      // Possible references:
      // - http://stackoverflow.com/questions/3258243/git-check-if-pull-needed
      if (shelljs.exec('git ls-remote --exit-code ' + options.remote + ' ' + options.branch, {silent: true}).code === 0) {
        gitFetch();
      }

      if (options.commit) {
        gitCommit();
      }

      // if (options.tag) {
      //   gitCommit();
      // }

      if (options.push) {
        gitPush();
      }
    }
    catch (e) {
      grunt.fail.warn(e);
      done(false);
    }
    finally {
      shelljs.cd(gruntDir);
      done(true);
    }
  });
};
<commit_msg>Add error catching,variable assignment style<commit_after>/*
 * grunt-version-build
 * https://github.com/robwierzbowski/grunt-version-build
 *
 * Copyright (c) 2013 Rob Wierzbowski
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function (grunt) {
  var fs = require('fs');
  var path = require('path');
  var shelljs = require('shelljs');

  grunt.registerMultiTask('version_build', 'Version built code next to your project\'s source.', function() {

    var done = this.async();
    var gruntDir = shelljs.pwd();

    var options = this.options({
      commit: false,
      // tag: false,
      push: false,
      commitMsg: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%'
    });

    var tokens = {
      branch: '(unavailable)',
      commit: '(unavailable)',
      name:   '(unavailable)'
    };

    // Use shellResult to store the return object for shelljs/node functions
    // that operate on the file system (for error handling)
    var shellResult = {};

    // Check requirements
    function checkRequirements () {
      // Check that required options are set.
      ['branch', 'dir', 'remote'].forEach( function (element) {
        if (!options.hasOwnProperty(element)) {
          throw('The "' + element + '" option is required.');
        }
      });

      // Check that the dist directory exists
      if (!fs.existsSync(options.dir)) {
        grunt.log.subhead('Creating target directory "' + options.dir + '".');
        shelljs.mkdir(options.dir);
      }
    }

    // Assign %token% values if available
    function assignTokens () {
      var sourceBranch = shelljs.exec('git symbolic-ref --quiet HEAD', {silent: true});
      var sourceCommit = shelljs.exec('git rev-parse --short HEAD', {silent: true});

      if (sourceBranch.code === 0) {
        tokens.branch = sourceBranch.output.split('/').pop().replace(/\n/g, '');
      }
      if (sourceCommit.code === 0) {
        tokens.commit = sourceCommit.output.replace(/\n/g, '');
      }
      if (shelljs.test('-f', 'package.json', {silent: true})) {
        tokens.name = JSON.parse(fs.readFileSync('package.json', 'utf8')).name;
      }
      // TODO: Use containing directory name if package.json isn't available
      // else {
      //
      // }
    }

    // Initialize git repo if one doesn't exist
    function initGit () {
      if (!fs.existsSync(path.join(gruntDir, options.dir, '.git'))) {
        grunt.log.subhead('Creating git repository in ' + options.dir + '.');

        shellResult = shelljs.exec('git init');
        if (shellResult !== 0) {
          throw shellResult.output;
        }
      }
    }

    // Fetch remote refs to a specific branch, equivalent to a pull without checkout
    function gitFetch () {
      grunt.log.subhead('Fetching ' + options.branch + ' history from ' + options.remote + '.');

      // `--update-head-ok` allows fetch on the current branch
      shellResult = shelljs.exec('git fetch --tags --verbose --update-head-ok ' + options.remote + ' ' + options.branch + ':' + options.branch);
      if (shellResult !== 0) {
        throw shellResult.output;
      }
    }

    // Make sure the stage is clean
    function gitReset () {
      shellResult = shelljs.exec('git reset', {silent: true});
      if (shellResult !== 0) {
        throw shellResult.output;
      }
    }

    // Create branch if it doesn't exist
    function initBranch () {
      // If branch exists, all is good
      if (shelljs.exec('git show-ref --verify --quiet refs/heads/' + options.branch, {silent: true}).code === 0) {
        return;
      }
      // If branch exists on remote, fetch it
      else if (shelljs.exec('git ls-remote --exit-code ' + options.remote + ' ' + options.branch, {silent: true}).code === 0) {

        gitFetch();
        return;
      }
      // If branch doesn't exist anywhere, create it
      else {
        grunt.log.subhead('Creating branch "' + options.branch + '".');

        shellResult = shelljs.exec('git checkout --orphan ' + options.branch);
        if (shellResult !== 0) {
          throw shellResult.output;
        }

        gitReset();

        // Initialize branch so we can move the HEAD ref around
        shellResult = shelljs.exec('git commit --allow-empty -m "Initial commit"');
        if (shellResult !== 0) {
          throw shellResult.output;
        }
      }
    }

    // Make the current working tree the branch HEAD without checking out files
    function safeCheckout () {
      shellResult = shelljs.exec('git symbolic-ref HEAD refs/heads/' + options.branch);
      if (shellResult !== 0) {
        throw shellResult.output;
      }
    }

    // Stage and commit to a branch
    function gitCommit () {
      var commitMsg = options.commitMsg
        .replace(/%sourceName%/g, tokens.name)
        .replace(/%sourceCommit%/g, tokens.commit)
        .replace(/%sourceBranch%/g, tokens.branch);

      // Unstage any changes, just in case
      gitReset();

      // If there are no changes, skip commit
      if (shelljs.exec('git status --porcelain', {silent: true}).output === '') {
        grunt.log.subhead('No changes to your branch. Skipping commit.');
        return;
      }

      // Stage and commit
      grunt.log.subhead('Committing changes to ' + options.branch + '.');
      shellResult = shelljs.exec('git add -A . && git commit -m "' + commitMsg + '"');
      if (shellResult !== 0) {
        throw shellResult.output;
      }
    }

    // TODO: Implement tag option
    // Pronounced "gihttag"
    // function gitTag () {
    // }

    // Push branch to remote
    function gitPush () {
      grunt.log.subhead('Pushing ' + options.branch + ' to ' + options.remote);
      shellResult = shelljs.exec('git push --tags ' + options.remote + ' HEAD:' + options.branch);
      if (shellResult !== 0) {
        throw shellResult.output;
      }
    }

    // Run task
    try {
      checkRequirements();
      assignTokens();

      // Change working directory
      shelljs.cd(options.dir);

      initGit();
      initBranch();
      safeCheckout();

      // Fetch changes from remote branch if it exists
      // TODO: Instead of checking if the remote exists, it would be better to
      // - check if remote is ahead of local
      // - check if remote is a ff merge
      // and if so, gitFetch(). Otherwise throw helpful, descriptive errors
      // Possible references:
      // - http://stackoverflow.com/questions/3258243/git-check-if-pull-needed
      if (shelljs.exec('git ls-remote --exit-code ' + options.remote + ' ' + options.branch, {silent: true}).code === 0) {
        gitFetch();
      }

      if (options.commit) {
        gitCommit();
      }

      // if (options.tag) {
      //   gitCommit();
      // }

      if (options.push) {
        gitPush();
      }
    }
    catch (e) {
      grunt.fail.warn(e);
      done(false);
    }
    finally {
      shelljs.cd(gruntDir);
      done(true);
    }
  });
};
<|endoftext|>