<commit_before>var defnode = require('defnode'), tern = require('tern');

tern.registerPlugin('def-origin', function(server, options) {
  function traverse(av) {
    // detect cycles
    if (av._defNodeSeen) return;
    av._defNodeSeen = true;

    var type = av.getType();
    if (type && av.originNode && av.originNode.sourceFile) {
      if (!type.metaData) type.metaData = {};
      type.metaData.aval = avalMetaData(av);
      type.metaData.type = typeMetaData(type);
    }

    av.forAllProps(function(prop, val, local) {
        traverse(val);
    });
  }

  return {
    passes: {
      preCondenseReach: function(state) {
        Object.keys(state.roots).forEach(function(rootName) {
          traverse(state.roots[rootName]);
        });
        Object.keys(state.cx.topScope.props).forEach(function(prop) {
          traverse(state.cx.topScope.props[prop]);
        });
      },
    },
  };
});

function avalMetaData(av) {
  var md = {
    originFile: av.originNode.sourceFile.name,
    identSpan: formatSpan(av.originNode),
  };
  try {
    var defNode = defnode.findDefinitionNode(av.originNode.sourceFile.ast, av.originNode.start, av.originNode.end)
    if (defNode) {
      md['defSpan'] = formatSpan(defNode);
    }
  } catch (e) {}
  return md;
}

function typeMetaData(t) {
  var md = {};
  if (t.origin) md.origin = t.origin;
  if (t.name) md.name = t.name;
  return md;
}

function formatSpan(node) {
  return node.start + '-' + node.end;
}
<commit_msg>Run after other plugins<commit_after>var defnode = require('defnode'), tern = require('tern');

tern.registerPlugin('def-origin', function(server, options) {
  function traverse(av) {
    // detect cycles
    if (av._defNodeSeen) return;
    av._defNodeSeen = true;

    var type = av.getType();
    if (type && av.originNode && av.originNode.sourceFile) {
      if (!type.metaData) type.metaData = {};
      type.metaData.aval = avalMetaData(av);
      type.metaData.type = typeMetaData(type);
    }

    av.forAllProps(function(prop, val, local) {
        traverse(val);
    });
  }

  return {
    passes: {
      preCondenseReach: function f(state) {
        // Must run after plugins that modify state.roots.
        state.passes.preCondenseReach.push(function(state) {
          Object.keys(state.roots).forEach(function(rootName) {
            traverse(state.roots[rootName]);
          });
          Object.keys(state.cx.topScope.props).forEach(function(prop) {
            traverse(state.cx.topScope.props[prop]);
          });
        });
      },
    },
  };
});

function avalMetaData(av) {
  var md = {
    originFile: av.originNode.sourceFile.name,
    identSpan: formatSpan(av.originNode),
  };
  try {
    var defNode = defnode.findDefinitionNode(av.originNode.sourceFile.ast, av.originNode.start, av.originNode.end)
    if (defNode) {
      md['defSpan'] = formatSpan(defNode);
    }
  } catch (e) {}
  return md;
}

function typeMetaData(t) {
  var md = {};
  if (t.origin) md.origin = t.origin;
  if (t.name) md.name = t.name;
  return md;
}

function formatSpan(node) {
  return node.start + '-' + node.end;
}
<|endoftext|>


<commit_before>var _eval = Npm.require('eval');
var cheerio = Npm.require('cheerio');

var handler = function (compileStep) {
  var source = compileStep.read().toString('utf8');
  var jsx = "var Template = Template || {};";
  var eventMaps = {};

  // Split out event maps.
  var _eventMaps = source.split(/Template\.([^\.]+)\.events\(\{/i);
  for(var i = 1; i <= _eventMaps.length-1; i+=2) {
    var className = _eventMaps[i];
    // Split out the trailing end after the Template.Name.events.
    var _eventMap = (_eventMaps[i+1] + '').split(/\n\}\)/i);
    _eventMap = (_eventMap[0] || '').trim();
    if (_eventMap) {
      try {
        var jsxEventMap = Babel.transformMeteor('module.exports = {' + _eventMap + '};', {
          sourceMap: false,
          extraWhitelist: ["react"]
        });
      } catch(e) {
        if (e.loc) {
          // Babel error
          compileStep.error({
            message: e.message,
            sourcePath: compileStep.inputPath,
            line: e.loc.line,
            column: e.loc.column
          });
          return;
        } else {
          throw e;
        }
      }
      var mapContent = jsxEventMap.code;
      if (mapContent) {
        var res = _eval(mapContent);
        if (typeof res == 'object') {
          eventMaps[className] = eventMaps[className] || {};
          _.extend(eventMaps[className], res);
          eventMaps[className].string = _eventMap;
        }
      }
    }
  }

  // Find and start parsing and compiling each templates.
  var parts = source.split(/<template name="(\w+)">/i);
  var extras = parts[0];
  for(var i=1; i <= parts.length-1; i+=2) {
    var className = parts[i];
    jsx += "Template." + className + " = {\n";
    jsx += "  _extend: {},\n";
    jsx += "  _instance: {},\n";
    jsx += "  onCreated: function(f) {return this._onCreated = f || (this._onCreated || function(){})},\n";
    jsx += "  helpers: function(o) {return this._helpers = o || (this._helpers || {})},\n";
    jsx += "  extend: function(o) {return _.extend(this._extend, o || {})},\n";
    jsx += "  events: function() {}\n"; // Ignore, injected below.
    jsx += "};\n";
  }
  for(var i=1; i <= parts.length-1; i+=2) {
    var className = parts[i];

    // Split out the trailing end after the template.
    var code = parts[i+1].split(/<\/template>/i);
    var markup = (code[0] || '');

    /* INJECT EVENTS */
    if (eventMaps[className]) {
      markup = markup.replace(/<((?!br)[^\>]+)\/>/ig, '<$1></$1>');
      for(var key in _.omit(eventMaps[className], 'string')) {
        var selectors = key.split(',');
        for(var j=0; j < selectors.length; j++) {
          var selector = selectors[j].trim().split(/\s(.+)?/);
          var event = selector[0];
          var select = selector[1];
          var $ = cheerio.load(markup);
          // Get the react event name or use custom name.
          var eventName = ReactEvents[event] ? ReactEvents[event] : event;
          // Remove duplicate listeners.
          $(select).removeAttr(eventName);
          // Append new listener.
          $(select).attr(eventName, "{__component.events['" + key + "'].bind(__component, typeof context != 'undefined' ? context : (this.data ? this.data : this))}");
          markup = $.html();
        }
      }
      // Cheerio adds qoutes on all attributes, React don't want that so we have to remove those quotes.
      markup = markup.replace(/"({[^"}]+})"/g, '$1');
    }

    /* START SPACEBARS */

    // Add return and key={index} inside {{#each}}.
    markup = markup.replace(/({{#each\s+[^}]+}}[^<]*)(<\w+)/g, '$1let context=arguments[0];return ($2 key={index}');
    // {{#each}} in
    markup = markup.replace(/{{#each\s+([^\s]+)\s+in\s+([^}]+)\s*}}/g, "{(Sideburns.check(this, '$2')? this.data.$2 : []).map(function($1, index){");
    // {{/each}}
    markup = markup.replace(/{{\/each}}/g, ");})}");

    // ^{{#if}}
    markup = markup.replace(/^\W*{{#if\s+(\w+)\s*}}/g, "{Sideburns.check(this, '$1')?(");
    // {{/if}}$
    markup = markup.replace(/{{\/if}}\W*$/g, "):''}");
    // {{#if}}
    markup = markup.replace(/{{#if\s+(\w+)\s*}}/g, "{Sideburns.check(this, '$1')?(");
    // {{else}} {{/if}}
    markup = markup.replace(/(?:{{else}}(?![\w\W]*{{else}}))([\w\W]*){{\/if}}/g, "):($1)}");
    // {{/if}}
    markup = markup.replace(/{{\/if}}/g, "):''}");

    // ^{{#unless}}
    markup = markup.replace(/^\W*{{#unless\s+(\w+)\s*}}/g, "{!Sideburns.check(this, '$1')?(");
    // {{/unless}}$
    markup = markup.replace(/{{\/unless}}\W*$/g, "):''}");
    // {{#unless}}
    markup = markup.replace(/{{#unless\s+(\w+)\s*}}/g, "{!Sideburns.check(this, '$1')?(");
    // {{else}} {{/unless}}
    markup = markup.replace(/(?:{{else}}(?![\w\W]*{{else}}))([\w\W]*){{\/unless}}/g, "):($1)}");
    // {{/unless}}
    markup = markup.replace(/{{\/unless}}/g, "):''}");

    // {{helper}} raw HTML
    markup = markup.replace(/{{{([^}]*)}}}/g, "{Sideburns.check(this, '$1')? this.data.$1 : ''}");

    // {{helper}} SafeString – Dynamic Attribute (class)
    markup = markup.replace(/\sclass={{([^}]*)}}/g, " className={Sideburns.check(this, '$1')? new Sideburns.classNames(this.data.$1) : ''}");

    // {{helper}} SafeString – Dynamic Attribute (other)
    markup = markup.replace(/={{([^}]*)}}/g, "={Sideburns.check(this, '$1')? new Sideburns.SafeString(this.data.$1) : ''}");

    // {{helper}} SafeString – In Attribute Values (class)
    markup = markup.replace(/\sclass="([^\"{]*){{([^}]*)}}([^\"{]*)\"/g, " className={Sideburns.check(this, '$2')? '$1' + new Sideburns.classNames(this.data.$2) + '$3' : ''}");

    // {{helper}} SafeString – In Attribute Values (other)
    markup = markup.replace(/="([^\"{]*){{([^}]*)}}([^\"{]*)\"/g, "={Sideburns.check(this, '$2')? '$1' + new Sideburns.classNames(this.data.$2) + '$3' : ''}");

    // {{helper}} SafeString
    markup = markup.replace(/{{([^}]*)}}/g, "{Sideburns.check(this, '$1')? new Sideburns.SafeString(this.data.$1) : ''}");

    /* END SPACEBARS */

    // Fix that annoying issue with React, and allow usage of class.
    markup = markup.replace(/\sclass=/g, ' className=');

    // Fix that annoying issue with React, and allow usage of for.
    markup = markup.replace(/\sfor=/g, ' htmlFor=');

    // ES2015 Template for React components.
    jsx += "Template." + className + "._instance = {displayName: \"" + className + "\",\n";
    jsx += "  _created: false,\n";
    jsx += "  mixins: [ReactMeteorData],\n";
    if (eventMaps[className]) {
      jsx += "  events: {" + eventMaps[className].string + "},\n";
    }
    jsx += "  getInitialState: function() {_.extend(this, _.omit(Template." + className + "._extend, 'getInitialState')); return Template." + className + "._extend.getInitialState ? Template." + className + "._extend.getInitialState.call(this) : null;},\n";
    jsx += "  getMeteorData() {\n";
    jsx += "    let self = this;\n";
    jsx += "    if (!self._created) {\n";
    jsx += "      Tracker.nonreactive(function(){Template." + className + ".onCreated().call(self)});\n";
    jsx += "      self._created = true;\n";
    jsx += "    }\n";
    jsx += "    let _helpers = {};\n";
    jsx += "    let helpers = Template." + className + ".helpers();\n";
    jsx += "    for (let key in helpers) {\n";
    jsx += "      _helpers[key] = helpers[key].call(self);\n";
    jsx += "    };\n";
    jsx += "    return _helpers;\n";
    jsx += "  },\n";
    jsx += "  render: function() {\n";
    jsx += "    let __component = this;";
    jsx += "    return (" + markup + ");";
    jsx += "  }\n";
    jsx += "};\n";
    jsx += className + " = React.createClass(Template." + className + "._instance);";
    extras += (code[1] || '');
  }

  var reactJsx = jsx + extras;
  var outputFile = compileStep.inputPath + ".jsx";

  // Capture jsx failures in compiling.
  try {
    var result = Babel.transformMeteor(reactJsx, {
      sourceMap: true,
      filename: compileStep.pathForSourceMap,
      sourceMapName: compileStep.pathForSourceMap,
      extraWhitelist: ["react"]
    });
  } catch (e) {
    if (e.loc) {
      // Babel error
      compileStep.error({
        message: e.message,
        sourcePath: compileStep.inputPath,
        line: e.loc.line,
        column: e.loc.column
      });

      console.log('\n\n\n');
      console.log(compileStep.pathForSourceMap);
      console.log('=====================');
      var lines = (jsx + extras).split(/\n/g);
      _.each(lines, function(line, i) {
        console.log((i+1) + '  ', line);
      });

      return;
    } else {
      throw e;
    }
  }

  compileStep.addJavaScript({
    path: outputFile,
    sourcePath: reactJsx,
    data: result.code,
    sourceMap: JSON.stringify(result.map)
  });
};

Plugin.registerSourceHandler('html.jsx', handler);
<commit_msg>change event argument order<commit_after>var _eval = Npm.require('eval');
var cheerio = Npm.require('cheerio');

var handler = function (compileStep) {
  var source = compileStep.read().toString('utf8');
  var jsx = "var Template = Template || {};";
  var eventMaps = {};

  // Split out event maps.
  var _eventMaps = source.split(/Template\.([^\.]+)\.events\(\{/i);
  for(var i = 1; i <= _eventMaps.length-1; i+=2) {
    var className = _eventMaps[i];
    // Split out the trailing end after the Template.Name.events.
    var _eventMap = (_eventMaps[i+1] + '').split(/\n\}\)/i);
    _eventMap = (_eventMap[0] || '').trim();
    if (_eventMap) {
      try {
        var jsxEventMap = Babel.transformMeteor('module.exports = {' + _eventMap + '};', {
          sourceMap: false,
          extraWhitelist: ["react"]
        });
      } catch(e) {
        if (e.loc) {
          // Babel error
          compileStep.error({
            message: e.message,
            sourcePath: compileStep.inputPath,
            line: e.loc.line,
            column: e.loc.column
          });
          return;
        } else {
          throw e;
        }
      }
      var mapContent = jsxEventMap.code;
      if (mapContent) {
        var res = _eval(mapContent);
        if (typeof res == 'object') {
          eventMaps[className] = eventMaps[className] || {};
          _.extend(eventMaps[className], res);
          eventMaps[className].string = _eventMap;
        }
      }
    }
  }

  // Find and start parsing and compiling each templates.
  var parts = source.split(/<template name="(\w+)">/i);
  var extras = parts[0];
  for(var i=1; i <= parts.length-1; i+=2) {
    var className = parts[i];
    jsx += "Template." + className + " = {\n";
    jsx += "  _extend: {},\n";
    jsx += "  _instance: {},\n";
    jsx += "  onCreated: function(f) {return this._onCreated = f || (this._onCreated || function(){})},\n";
    jsx += "  helpers: function(o) {return this._helpers = o || (this._helpers || {})},\n";
    jsx += "  extend: function(o) {return _.extend(this._extend, o || {})},\n";
    jsx += "  events: function() {}\n"; // Ignore, injected below.
    jsx += "};\n";
  }
  for(var i=1; i <= parts.length-1; i+=2) {
    var className = parts[i];

    // Split out the trailing end after the template.
    var code = parts[i+1].split(/<\/template>/i);
    var markup = (code[0] || '');

    /* INJECT EVENTS */
    if (eventMaps[className]) {
      markup = markup.replace(/<((?!br)[^\>]+)\/>/ig, '<$1></$1>');
      for(var key in _.omit(eventMaps[className], 'string')) {
        var selectors = key.split(',');
        for(var j=0; j < selectors.length; j++) {
          var selector = selectors[j].trim().split(/\s(.+)?/);
          var event = selector[0];
          var select = selector[1];
          var $ = cheerio.load(markup);
          // Get the react event name or use custom name.
          var eventName = ReactEvents[event] ? ReactEvents[event] : event;
          // Remove duplicate listeners.
          $(select).removeAttr(eventName);
          // Append new listener.
          $(select).attr(eventName, "{eventHandler.bind(__component, '" + key + "', typeof context != 'undefined' ? context : (this.data ? this.data : this))}");
          markup = $.html();
        }
      }
      // Cheerio adds qoutes on all attributes, React don't want that so we have to remove those quotes.
      markup = markup.replace(/"({[^"}]+})"/g, '$1');
    }

    /* START SPACEBARS */

    // Add return and key={index} inside {{#each}}.
    markup = markup.replace(/({{#each\s+[^}]+}}[^<]*)(<\w+)/g, '$1let context=arguments[0];return ($2 key={index}');
    // {{#each}} in
    markup = markup.replace(/{{#each\s+([^\s]+)\s+in\s+([^}]+)\s*}}/g, "{(Sideburns.check(this, '$2')? this.data.$2 : []).map(function($1, index){");
    // {{/each}}
    markup = markup.replace(/{{\/each}}/g, ");})}");

    // ^{{#if}}
    markup = markup.replace(/^\W*{{#if\s+(\w+)\s*}}/g, "{Sideburns.check(this, '$1')?(");
    // {{/if}}$
    markup = markup.replace(/{{\/if}}\W*$/g, "):''}");
    // {{#if}}
    markup = markup.replace(/{{#if\s+(\w+)\s*}}/g, "{Sideburns.check(this, '$1')?(");
    // {{else}} {{/if}}
    markup = markup.replace(/(?:{{else}}(?![\w\W]*{{else}}))([\w\W]*){{\/if}}/g, "):($1)}");
    // {{/if}}
    markup = markup.replace(/{{\/if}}/g, "):''}");

    // ^{{#unless}}
    markup = markup.replace(/^\W*{{#unless\s+(\w+)\s*}}/g, "{!Sideburns.check(this, '$1')?(");
    // {{/unless}}$
    markup = markup.replace(/{{\/unless}}\W*$/g, "):''}");
    // {{#unless}}
    markup = markup.replace(/{{#unless\s+(\w+)\s*}}/g, "{!Sideburns.check(this, '$1')?(");
    // {{else}} {{/unless}}
    markup = markup.replace(/(?:{{else}}(?![\w\W]*{{else}}))([\w\W]*){{\/unless}}/g, "):($1)}");
    // {{/unless}}
    markup = markup.replace(/{{\/unless}}/g, "):''}");

    // {{helper}} raw HTML
    markup = markup.replace(/{{{([^}]*)}}}/g, "{Sideburns.check(this, '$1')? this.data.$1 : ''}");

    // {{helper}} SafeString – Dynamic Attribute (class)
    markup = markup.replace(/\sclass={{([^}]*)}}/g, " className={Sideburns.check(this, '$1')? new Sideburns.classNames(this.data.$1) : ''}");

    // {{helper}} SafeString – Dynamic Attribute (other)
    markup = markup.replace(/={{([^}]*)}}/g, "={Sideburns.check(this, '$1')? new Sideburns.SafeString(this.data.$1) : ''}");

    // {{helper}} SafeString – In Attribute Values (class)
    markup = markup.replace(/\sclass="([^\"{]*){{([^}]*)}}([^\"{]*)\"/g, " className={Sideburns.check(this, '$2')? '$1' + new Sideburns.classNames(this.data.$2) + '$3' : ''}");

    // {{helper}} SafeString – In Attribute Values (other)
    markup = markup.replace(/="([^\"{]*){{([^}]*)}}([^\"{]*)\"/g, "={Sideburns.check(this, '$2')? '$1' + new Sideburns.classNames(this.data.$2) + '$3' : ''}");

    // {{helper}} SafeString
    markup = markup.replace(/{{([^}]*)}}/g, "{Sideburns.check(this, '$1')? new Sideburns.SafeString(this.data.$1) : ''}");

    /* END SPACEBARS */

    // Fix that annoying issue with React, and allow usage of class.
    markup = markup.replace(/\sclass=/g, ' className=');

    // Fix that annoying issue with React, and allow usage of for.
    markup = markup.replace(/\sfor=/g, ' htmlFor=');

    // ES2015 Template for React components.
    jsx += "Template." + className + "._instance = {displayName: \"" + className + "\",\n";
    jsx += "  _created: false,\n";
    jsx += "  mixins: [ReactMeteorData],\n";
    if (eventMaps[className]) {
      jsx += "  events: {" + eventMaps[className].string + "},\n";
    }
    jsx += "  getInitialState: function() {_.extend(this, _.omit(Template." + className + "._extend, 'getInitialState')); return Template." + className + "._extend.getInitialState ? Template." + className + "._extend.getInitialState.call(this) : null;},\n";
    jsx += "  getMeteorData() {\n";
    jsx += "    let self = this;\n";
    jsx += "    if (!self._created) {\n";
    jsx += "      Tracker.nonreactive(function(){Template." + className + ".onCreated().call(self)});\n";
    jsx += "      self._created = true;\n";
    jsx += "    }\n";
    jsx += "    let _helpers = {};\n";
    jsx += "    let helpers = Template." + className + ".helpers();\n";
    jsx += "    for (let key in helpers) {\n";
    jsx += "      _helpers[key] = helpers[key].call(self);\n";
    jsx += "    };\n";
    jsx += "    return _helpers;\n";
    jsx += "  },\n";
    jsx += "  render: function() {\n";
    jsx += "    let __component = this;";
    jsx += "    function eventHandler(key,context,event){";
    jsx += "        __component.events[key].call(this,event,context);";
    jsx += "    }";
    jsx += "    return (" + markup + ");";
    jsx += "  }\n";
    jsx += "};\n";
    jsx += className + " = React.createClass(Template." + className + "._instance);";
    extras += (code[1] || '');
  }

  var reactJsx = jsx + extras;
  var outputFile = compileStep.inputPath + ".jsx";

  // Capture jsx failures in compiling.
  try {
    var result = Babel.transformMeteor(reactJsx, {
      sourceMap: true,
      filename: compileStep.pathForSourceMap,
      sourceMapName: compileStep.pathForSourceMap,
      extraWhitelist: ["react"]
    });
  } catch (e) {
    if (e.loc) {
      // Babel error
      compileStep.error({
        message: e.message,
        sourcePath: compileStep.inputPath,
        line: e.loc.line,
        column: e.loc.column
      });

      console.log('\n\n\n');
      console.log(compileStep.pathForSourceMap);
      console.log('=====================');
      var lines = (jsx + extras).split(/\n/g);
      _.each(lines, function(line, i) {
        console.log((i+1) + '  ', line);
      });

      return;
    } else {
      throw e;
    }
  }

  compileStep.addJavaScript({
    path: outputFile,
    sourcePath: reactJsx,
    data: result.code,
    sourceMap: JSON.stringify(result.map)
  });
};

Plugin.registerSourceHandler('html.jsx', handler);
<|endoftext|>


<commit_before>var _eval = Npm.require('eval');
var cheerio = Npm.require('cheerio');

var handler = function (compileStep) {
  var source = compileStep.read().toString('utf8');
  var jsx = "var Template = Template || {};";
  var eventMaps = {};

  // Split out event maps.
  var _eventMaps = source.split(/Template\.([^\.]+)\.events\(\{/i);
  for(var i = 1; i <= _eventMaps.length-1; i+=2) {
    var className = _eventMaps[i];
    // Split out the trailing end after the Template.Name.events.
    var _eventMap = (_eventMaps[i+1] + '').split(/\n\}\)/i);
    _eventMap = (_eventMap[0] || '').trim();
    if (_eventMap) {
      try {
        var jsxEventMap = Babel.transformMeteor('module.exports = {' + _eventMap + '};', {
          sourceMap: false,
          extraWhitelist: ["react"]
        });
      } catch(e) {
        if (e.loc) {
          // Babel error
          compileStep.error({
            message: e.message,
            sourcePath: compileStep.inputPath,
            line: e.loc.line,
            column: e.loc.column
          });
          return;
        } else {
          throw e;
        }
      }
      var mapContent = jsxEventMap.code;
      if (mapContent) {
        var res = _eval(mapContent);
        if (typeof res == 'object') {
          eventMaps[className] = eventMaps[className] || {};
          _.extend(eventMaps[className], res);
          eventMaps[className].string = _eventMap;
        }
      }
    }
  }

  // Find and start parsing and compiling each templates.
  var parts = source.split(/<template name="(\w+)">/i);
  var extras = parts[0];
  for(var i=1; i <= parts.length-1; i+=2) {
    var className = parts[i];
    jsx += "Template." + className + " = {\n";
    jsx += "  _extend: {},\n";
    jsx += "  _instance: {},\n";
    jsx += "  onCreated: function(f) {return this._onCreated = f || (this._onCreated || function(){})},\n";
    jsx += "  helpers: function(o) {return this._helpers = o || (this._helpers || {})},\n";
    jsx += "  extend: function(o) {return _.extend(this._extend, o || {})},\n";
    jsx += "  events: function() {}\n"; // Ignore, injected below.
    jsx += "};\n";
  }
  for(var i=1; i <= parts.length-1; i+=2) {
    var className = parts[i];

    // Split out the trailing end after the template.
    var code = parts[i+1].split(/<\/template>/i);
    var markup = (code[0] || '');

    /* INJECT EVENTS */
    if (eventMaps[className]) {
      markup = markup.replace(/<((?!br)[^\>]+)\/>/ig, '<$1></$1>');
      for(var key in _.omit(eventMaps[className], 'string')) {
        var selectors = key.split(',');
        for(var j=0; j < selectors.length; j++) {
          var selector = selectors[j].trim().split(/\s(.+)?/);
          var event = selector[0];
          var select = selector[1];
          var $ = cheerio.load(markup);
          // Get the react event name or use custom name.
          var eventName = ReactEvents[event] ? ReactEvents[event] : event;
          // Remove duplicate listeners.
          $(select).removeAttr(eventName);
          // Append new listener.
          $(select).attr(eventName, "{eventHandler.bind(__component, '" + key + "', typeof context != 'undefined' ? context : (this.data ? this.data : this))}");
          markup = $.html();
        }
      }
      // Cheerio adds qoutes on all attributes, React don't want that so we have to remove those quotes.
      markup = markup.replace(/"({[^"}]+})"/g, '$1');
    }

    /* START SPACEBARS */

    // Add return and key={index} inside {{#each}}.
    markup = markup.replace(/({{#each\s+[^}]+}}[^<]*)(<\w+)/g, '$1return ($2 key={index}');
    // {{#each}} in
    markup = markup.replace(/{{#each\s+([^\s]+)\s+in\s+([^}]+)\s*}}/g, "{(Sideburns.check(context, '$2')? context.$2 : []).map(function($1, index){let context=__component.data;context.$1=$1");
    // {{/each}}
    markup = markup.replace(/{{\/each}}/g, ");})}");

    // ^{{#if}}
    markup = markup.replace(/^\W*{{#if\s+(\w+)\s*}}/g, "{Sideburns.check(context, '$1')?(");
    // {{/if}}$
    markup = markup.replace(/{{\/if}}\W*$/g, "):''}");
    // {{#if}}
    markup = markup.replace(/{{#if\s+(\w+)\s*}}/g, "{Sideburns.check(context, '$1')?(");
    // {{else}} {{/if}}
    markup = markup.replace(/(?:{{else}}(?![\w\W]*{{else}}))([\w\W]*){{\/if}}/g, "):($1)}");
    // {{/if}}
    markup = markup.replace(/{{\/if}}/g, "):''}");

    // ^{{#unless}}
    markup = markup.replace(/^\W*{{#unless\s+(\w+)\s*}}/g, "{!Sideburns.check(context, '$1')?(");
    // {{/unless}}$
    markup = markup.replace(/{{\/unless}}\W*$/g, "):''}");
    // {{#unless}}
    markup = markup.replace(/{{#unless\s+(\w+)\s*}}/g, "{!Sideburns.check(context, '$1')?(");
    // {{else}} {{/unless}}
    markup = markup.replace(/(?:{{else}}(?![\w\W]*{{else}}))([\w\W]*){{\/unless}}/g, "):($1)}");
    // {{/unless}}
    markup = markup.replace(/{{\/unless}}/g, "):''}");

    // {{helper}} raw HTML
    markup = markup.replace(/{{{([^}]*)}}}/g, "{Sideburns.check(context, '$1')? context.data.$1 : ''}");

    // {{helper}} SafeString – Dynamic Attribute (class)
    markup = markup.replace(/\sclass={{([^}]*)}}/g, " className={Sideburns.check(context, '$1')? new Sideburns.classNames(context.$1) : ''}");

    // {{helper}} SafeString – Dynamic Attribute (other)
    markup = markup.replace(/={{([^}]*)}}/g, "={Sideburns.check(context, '$1')? new Sideburns.SafeString(context.$1) : ''}");

    // {{helper}} SafeString – In Attribute Values (class)
    markup = markup.replace(/\sclass="([^\"{]*){{([^}]*)}}([^\"{]*)\"/g, " className={Sideburns.check(context, '$2')? '$1' + new Sideburns.classNames(context.$2) + '$3' : ''}");

    // {{helper}} SafeString – In Attribute Values (other)
    markup = markup.replace(/="([^\"{]*){{([^}]*)}}([^\"{]*)\"/g, "={Sideburns.check(context, '$2')? '$1' + new Sideburns.classNames(context.$2) + '$3' : ''}");

    // {{helper}} SafeString
    markup = markup.replace(/{{([^}]*)}}/g, "{Sideburns.check(context, '$1')? new Sideburns.SafeString(context.$1) : ''}");

    /* END SPACEBARS */

    // Fix that annoying issue with React, and allow usage of class.
    markup = markup.replace(/\sclass=/g, ' className=');

    // Fix that annoying issue with React, and allow usage of for.
    markup = markup.replace(/\sfor=/g, ' htmlFor=');

    // ES2015 Template for React components.
    jsx += "Template." + className + "._instance = {displayName: \"" + className + "\",\n";
    jsx += "  _created: false,\n";
    jsx += "  mixins: [ReactMeteorData],\n";
    if (eventMaps[className]) {
      jsx += "  events: {" + eventMaps[className].string + "},\n";
    }
    jsx += "  getInitialState: function() {_.extend(this, _.omit(Template." + className + "._extend, 'getInitialState')); return Template." + className + "._extend.getInitialState ? Template." + className + "._extend.getInitialState.call(this) : null;},\n";
    jsx += "  getMeteorData() {\n";
    jsx += "    let self = this;\n";
    jsx += "    if (!self._created) {\n";
    jsx += "      Tracker.nonreactive(function(){Template." + className + ".onCreated().call(self)});\n";
    jsx += "      self._created = true;\n";
    jsx += "    }\n";
    jsx += "    let _helpers = {};\n";
    jsx += "    let helpers = Template." + className + ".helpers();\n";
    jsx += "    for (let key in helpers) {\n";
    jsx += "      _helpers[key] = helpers[key].call(self);\n";
    jsx += "    };\n";
    jsx += "    return _helpers;\n";
    jsx += "  },\n";
    jsx += "  render: function() {\n";
    jsx += "    let __component = this;";
    jsx += "    let context = this.data;";
    jsx += "    function eventHandler(key,context,event){";
    jsx += "        __component.events[key].call(this,event,context);";
    jsx += "    }";
    jsx += "    return (" + markup + ");";
    jsx += "  }\n";
    jsx += "};\n";
    jsx += className + " = React.createClass(Template." + className + "._instance);";
    extras += (code[1] || '');
  }

  var reactJsx = jsx + extras;
  var outputFile = compileStep.inputPath + ".jsx";

  // Capture jsx failures in compiling.
  try {
    var result = Babel.transformMeteor(reactJsx, {
      sourceMap: true,
      filename: compileStep.pathForSourceMap,
      sourceMapName: compileStep.pathForSourceMap,
      extraWhitelist: ["react"]
    });
  } catch (e) {
    if (e.loc) {
      // Babel error
      compileStep.error({
        message: e.message,
        sourcePath: compileStep.inputPath,
        line: e.loc.line,
        column: e.loc.column
      });

      console.log('\n\n\n');
      console.log(compileStep.pathForSourceMap);
      console.log('=====================');
      var lines = (jsx + extras).split(/\n/g);
      _.each(lines, function(line, i) {
        console.log((i+1) + '  ', line);
      });

      return;
    } else {
      throw e;
    }
  }

  compileStep.addJavaScript({
    path: outputFile,
    sourcePath: reactJsx,
    data: result.code,
    sourceMap: JSON.stringify(result.map)
  });
};

Plugin.registerSourceHandler('html.jsx', handler);
<commit_msg>Completed issue/#4 onRendered()<commit_after>var _eval = Npm.require('eval');
var cheerio = Npm.require('cheerio');

var handler = function (compileStep) {
  var source = compileStep.read().toString('utf8');
  var jsx = "var Template = Template || {};";
  var eventMaps = {};

  // Split out event maps.
  var _eventMaps = source.split(/Template\.([^\.]+)\.events\(\{/i);
  for(var i = 1; i <= _eventMaps.length-1; i+=2) {
    var className = _eventMaps[i];
    // Split out the trailing end after the Template.Name.events.
    var _eventMap = (_eventMaps[i+1] + '').split(/\n\}\)/i);
    _eventMap = (_eventMap[0] || '').trim();
    if (_eventMap) {
      try {
        var jsxEventMap = Babel.transformMeteor('module.exports = {' + _eventMap + '};', {
          sourceMap: false,
          extraWhitelist: ["react"]
        });
      } catch(e) {
        if (e.loc) {
          // Babel error
          compileStep.error({
            message: e.message,
            sourcePath: compileStep.inputPath,
            line: e.loc.line,
            column: e.loc.column
          });
          return;
        } else {
          throw e;
        }
      }
      var mapContent = jsxEventMap.code;
      if (mapContent) {
        var res = _eval(mapContent);
        if (typeof res == 'object') {
          eventMaps[className] = eventMaps[className] || {};
          _.extend(eventMaps[className], res);
          eventMaps[className].string = _eventMap;
        }
      }
    }
  }

  // Find and start parsing and compiling each templates.
  var parts = source.split(/<template name="(\w+)">/i);
  var extras = parts[0];
  for(var i=1; i <= parts.length-1; i+=2) {
    var className = parts[i];
    jsx += "Template." + className + " = {\n";
    jsx += "  _extend: {},\n";
    jsx += "  _instance: {},\n";
    jsx += "  onCreated: function(f) {return this._onCreated = f || (this._onCreated || function(){})},\n";
    jsx += "  onRendered: function(f) {return this._onRendered = f || (this._onRendered || function(){})},\n";
    jsx += "  helpers: function(o) {return this._helpers = o || (this._helpers || {})},\n";
    jsx += "  extend: function(o) {return _.extend(this._extend, o || {})},\n";
    jsx += "  events: function() {}\n"; // Ignore, injected below.
    jsx += "};\n";
  }
  for(var i=1; i <= parts.length-1; i+=2) {
    var className = parts[i];

    // Split out the trailing end after the template.
    var code = parts[i+1].split(/<\/template>/i);
    var markup = (code[0] || '');

    /* INJECT EVENTS */
    if (eventMaps[className]) {
      markup = markup.replace(/<((?!br)[^\>]+)\/>/ig, '<$1></$1>');
      for(var key in _.omit(eventMaps[className], 'string')) {
        var selectors = key.split(',');
        for(var j=0; j < selectors.length; j++) {
          var selector = selectors[j].trim().split(/\s(.+)?/);
          var event = selector[0];
          var select = selector[1];
          var $ = cheerio.load(markup);
          // Get the react event name or use custom name.
          var eventName = ReactEvents[event] ? ReactEvents[event] : event;
          // Remove duplicate listeners.
          $(select).removeAttr(eventName);
          // Append new listener.
          $(select).attr(eventName, "{eventHandler.bind(__component, '" + key + "', typeof context != 'undefined' ? context : (this.data ? this.data : this))}");
          markup = $.html();
        }
      }
      // Cheerio adds qoutes on all attributes, React don't want that so we have to remove those quotes.
      markup = markup.replace(/"({[^"}]+})"/g, '$1');
    }

    /* START SPACEBARS */

    // Add return and key={index} inside {{#each}}.
    markup = markup.replace(/({{#each\s+[^}]+}}[^<]*)(<\w+)/g, '$1return ($2 key={index}');
    // {{#each}} in
    markup = markup.replace(/{{#each\s+([^\s]+)\s+in\s+([^}]+)\s*}}/g, "{(Sideburns.check(context, '$2')? context.$2 : []).map(function($1, index){let context=__component.data;context.$1=$1");
    // {{/each}}
    markup = markup.replace(/{{\/each}}/g, ");})}");

    // ^{{#if}}
    markup = markup.replace(/^\W*{{#if\s+(\w+)\s*}}/g, "{Sideburns.check(context, '$1')?(");
    // {{/if}}$
    markup = markup.replace(/{{\/if}}\W*$/g, "):''}");
    // {{#if}}
    markup = markup.replace(/{{#if\s+(\w+)\s*}}/g, "{Sideburns.check(context, '$1')?(");
    // {{else}} {{/if}}
    markup = markup.replace(/(?:{{else}}(?![\w\W]*{{else}}))([\w\W]*){{\/if}}/g, "):($1)}");
    // {{/if}}
    markup = markup.replace(/{{\/if}}/g, "):''}");

    // ^{{#unless}}
    markup = markup.replace(/^\W*{{#unless\s+(\w+)\s*}}/g, "{!Sideburns.check(context, '$1')?(");
    // {{/unless}}$
    markup = markup.replace(/{{\/unless}}\W*$/g, "):''}");
    // {{#unless}}
    markup = markup.replace(/{{#unless\s+(\w+)\s*}}/g, "{!Sideburns.check(context, '$1')?(");
    // {{else}} {{/unless}}
    markup = markup.replace(/(?:{{else}}(?![\w\W]*{{else}}))([\w\W]*){{\/unless}}/g, "):($1)}");
    // {{/unless}}
    markup = markup.replace(/{{\/unless}}/g, "):''}");

    // {{helper}} raw HTML
    markup = markup.replace(/{{{([^}]*)}}}/g, "{Sideburns.check(context, '$1')? context.data.$1 : ''}");

    // {{helper}} SafeString – Dynamic Attribute (class)
    markup = markup.replace(/\sclass={{([^}]*)}}/g, " className={Sideburns.check(context, '$1')? new Sideburns.classNames(context.$1) : ''}");

    // {{helper}} SafeString – Dynamic Attribute (other)
    markup = markup.replace(/={{([^}]*)}}/g, "={Sideburns.check(context, '$1')? new Sideburns.SafeString(context.$1) : ''}");

    // {{helper}} SafeString – In Attribute Values (class)
    markup = markup.replace(/\sclass="([^\"{]*){{([^}]*)}}([^\"{]*)\"/g, " className={Sideburns.check(context, '$2')? '$1' + new Sideburns.classNames(context.$2) + '$3' : ''}");

    // {{helper}} SafeString – In Attribute Values (other)
    markup = markup.replace(/="([^\"{]*){{([^}]*)}}([^\"{]*)\"/g, "={Sideburns.check(context, '$2')? '$1' + new Sideburns.classNames(context.$2) + '$3' : ''}");

    // {{helper}} SafeString
    markup = markup.replace(/{{([^}]*)}}/g, "{Sideburns.check(context, '$1')? new Sideburns.SafeString(context.$1) : ''}");

    /* END SPACEBARS */

    // Fix that annoying issue with React, and allow usage of class.
    markup = markup.replace(/\sclass=/g, ' className=');

    // Fix that annoying issue with React, and allow usage of for.
    markup = markup.replace(/\sfor=/g, ' htmlFor=');

    // ES2015 Template for React components.
    jsx += "Template." + className + "._instance = {displayName: \"" + className + "\",\n";
    jsx += "  _created: false,\n";
    jsx += "  mixins: [ReactMeteorData],\n";
    if (eventMaps[className]) {
      jsx += "  events: {" + eventMaps[className].string + "},\n";
    }
    jsx += "  getInitialState: function() {_.extend(this, _.omit(Template." + className + "._extend, 'getInitialState')); return Template." + className + "._extend.getInitialState ? Template." + className + "._extend.getInitialState.call(this) : null;},\n";
    jsx += "  getMeteorData() {\n";
    jsx += "    let self = this;\n";
    jsx += "    if (!self._created) {\n";
    jsx += "      Tracker.nonreactive(function(){Template." + className + ".onCreated().call(self)});\n";
    jsx += "      self._created = true;\n";
    jsx += "    }\n";
    jsx += "    let _helpers = {};\n";
    jsx += "    let helpers = Template." + className + ".helpers();\n";
    jsx += "    for (let key in helpers) {\n";
    jsx += "      _helpers[key] = helpers[key].call(self);\n";
    jsx += "    };\n";
    jsx += "    return _helpers;\n";
    jsx += "  },\n";
    jsx += "  componentDidMount: function() {\n";
    jsx += "    let self = this;\n";
    jsx += "    if (!self._rendered) {\n";
    jsx += "      Tracker.nonreactive(function(){Template." + className + ".onRendered().call(self)});\n";
    jsx += "      self._rendered = true;\n";
    jsx += "    }\n";
    jsx += "  },\n";
    jsx += "  render: function() {\n";
    jsx += "    let __component = this;";
    jsx += "    let context = this.data;";
    jsx += "    function eventHandler(key,context,event){";
    jsx += "        __component.events[key].call(this,event,context);";
    jsx += "    }";
    jsx += "    return (" + markup + ");";
    jsx += "  }\n";
    jsx += "};\n";
    jsx += className + " = React.createClass(Template." + className + "._instance);";
    extras += (code[1] || '');
  }

  var reactJsx = jsx + extras;
  var outputFile = compileStep.inputPath + ".jsx";

  // Capture jsx failures in compiling.
  try {
    var result = Babel.transformMeteor(reactJsx, {
      sourceMap: true,
      filename: compileStep.pathForSourceMap,
      sourceMapName: compileStep.pathForSourceMap,
      extraWhitelist: ["react"]
    });
  } catch (e) {
    if (e.loc) {
      // Babel error
      compileStep.error({
        message: e.message,
        sourcePath: compileStep.inputPath,
        line: e.loc.line,
        column: e.loc.column
      });

      console.log('\n\n\n');
      console.log(compileStep.pathForSourceMap);
      console.log('=====================');
      var lines = (jsx + extras).split(/\n/g);
      _.each(lines, function(line, i) {
        console.log((i+1) + '  ', line);
      });

      return;
    } else {
      throw e;
    }
  }

  compileStep.addJavaScript({
    path: outputFile,
    sourcePath: reactJsx,
    data: result.code,
    sourceMap: JSON.stringify(result.map)
  });
};

Plugin.registerSourceHandler('html.jsx', handler);
<|endoftext|>


<commit_before>var socketio = require("socket.io"),
    crypto = require("crypto"),
    uuid = require("uuid");

/**
 * Utility
 */
function safeCb(cb) {
    if (typeof cb === 'function') {
        return cb;
    } else {
        return function () {};
    }
}

module.exports = function Signaling(server, config) {
    var io = socketio.listen(server);

    io.sockets.on("connection", function (client) {

        client.resources = {
            video: true,
            audio: false,
            screen: false
        }

        // send private message to another id
        client.on("message", function (msg) {
            if (!msg) return;

            var toClient = io.to(msg.to);
            if (!toClient) {
                // TODO: send msg to a room ?
                return;
            }

            msg.from = client.id;
            toClient.emit("message", msg);

        });

        client.on("shareScreen", function () {
            client.resources.screen = true;
        });

        client.on("unshareScreen", function (type) {
            client.resources.screen = false;
            removeFeed("screen");
        });

        function removeFeed(type) {
            if (client.room) {
                // remove resources type in the room
                io.sockets.in(client.room).emit("remove", {
                    id: client.id,
                    type: type
                });
                // leave the room
                if (!type) {
                    client.leave(client.room);
                    delete client.room;
                }
            }
        }

        function joinRoom(name, cb) {
            // sanity check
            if (typeof name !== "string") return; // do nothing

            // check  max clients in the room
            var current = clientsInRoom(name);
            if (config.rooms && config.rooms.maxClients > 0 && current >= config.rooms.maxClients) {
                safeCb(cb)("full");
                return;
            }
            // leave all rooms
            removeFeed();
            safeCb(cb)(null, describeRoom(name));
            client.join(name);
            client.room = name;
        }

        /**
         * Event: join, leave, disconnect
         */
        client.on("join", joinRoom);
        client.on("leave", function () {
            removeFeed();
        });

        // we don't want to pass "leave" directly because the
        // event type string of "socket end" gets passed too.
        client.on('disconnect', function () {
            removeFeed();
        });

        client.on("create", function (name, cb) {
            name = name || uuid.v4();

            // check room is exists
            var room = io.nsps["/"].adapter.rooms[name];
            if (room && room.length) {
                safeCb(cb)("taken");
            } else {
                joinRoom(name);
                safeCb(cb)(null, name);
            }
        });

        // create shared secret nonces for TURN authentication
        // the process is described in draft-uberti-behave-turn-rest
        var credentials = [];
        // allow selectively vending turn credentials based on origin.
        var origin = client.handshake.headers.origin;
        if (!config.turnorigins || config.turnorigins.indexOf(origin) !== -1) {
            config.turnservers.forEach(function (server) {
                var hmac = crypto.createHmac('sha1', server.secret);
                // default to 86400 seconds timeout unless specified
                var username = Math.floor(new Date().getTime() / 1000) + (server.expiry || 86400) + "";
                hmac.update(username);
                credentials.push({
                    username: username,
                    credential: hmac.digest('base64'),
                    urls: server.urls || server.url
                });
            });
        }

        var iceInfo = {
            stunservers: config.stunservers || [],
            turnservers: credentials
        }

        // notify client about stun and turn servers
        client.emit("iceservers", iceInfo);

    });

    function clientsInRoom(name) {
        return io.sockets.clients(name).length;
    }

    function describeRoom(name) {
        var adapter = io.nsps["/"].adapter;
        var clients = adapter.rooms[name] || {};
        var result = {
            clients: {}
        }

        Object.keys(clients).forEach(function (id) {
            var client = adapter.nsp.connected[id];
            result.clients[id] = client.resources;
        });

    }
}<commit_msg>fix error count number of clients in a room<commit_after>var socketio = require("socket.io"),
    crypto = require("crypto"),
    uuid = require("uuid");

/**
 * Utility
 */
function safeCb(cb) {
    if (typeof cb === 'function') {
        return cb;
    } else {
        return function () {};
    }
}

module.exports = function Signaling(server, config) {
    var io = socketio.listen(server);

    io.sockets.on("connection", function (client) {

        client.resources = {
            video: true,
            audio: false,
            screen: false
        }

        // send private message to another id
        client.on("message", function (msg) {
            if (!msg) return;

            var toClient = io.to(msg.to);
            if (!toClient) {
                // TODO: send msg to a room ?
                return;
            }

            msg.from = client.id;
            toClient.emit("message", msg);

        });

        client.on("shareScreen", function () {
            client.resources.screen = true;
        });

        client.on("unshareScreen", function (type) {
            client.resources.screen = false;
            removeFeed("screen");
        });

        function removeFeed(type) {
            if (client.room) {
                // remove resources type in the room
                io.sockets.in(client.room).emit("remove", {
                    id: client.id,
                    type: type
                });
                // leave the room
                if (!type) {
                    client.leave(client.room);
                    delete client.room;
                }
            }
        }

        function joinRoom(name, cb) {
            // sanity check
            if (typeof name !== "string") return; // do nothing

            // check  max clients in the room
            var current = clientsInRoom(name);
            if (config.rooms && config.rooms.maxClients > 0 && current >= config.rooms.maxClients) {
                safeCb(cb)("full");
                return;
            }
            // leave all rooms
            removeFeed();
            safeCb(cb)(null, describeRoom(name));
            client.join(name);
            client.room = name;
        }

        /**
         * Event: join, leave, disconnect
         */
        client.on("join", joinRoom);
        client.on("leave", function () {
            removeFeed();
        });

        // we don't want to pass "leave" directly because the
        // event type string of "socket end" gets passed too.
        client.on('disconnect', function () {
            removeFeed();
        });

        client.on("create", function (name, cb) {
            name = name || uuid.v4();

            // check room is exists
            var room = io.nsps["/"].adapter.rooms[name];
            if (room && room.length) {
                safeCb(cb)("taken");
            } else {
                joinRoom(name);
                safeCb(cb)(null, name);
            }
        });

        // create shared secret nonces for TURN authentication
        // the process is described in draft-uberti-behave-turn-rest
        var credentials = [];
        // allow selectively vending turn credentials based on origin.
        var origin = client.handshake.headers.origin;
        if (!config.turnorigins || config.turnorigins.indexOf(origin) !== -1) {
            config.turnservers.forEach(function (server) {
                var hmac = crypto.createHmac('sha1', server.secret);
                // default to 86400 seconds timeout unless specified
                var username = Math.floor(new Date().getTime() / 1000) + (server.expiry || 86400) + "";
                hmac.update(username);
                credentials.push({
                    username: username,
                    credential: hmac.digest('base64'),
                    urls: server.urls || server.url
                });
            });
        }

        var iceInfo = {
            stunservers: config.stunservers || [],
            turnservers: credentials
        }

        // notify client about stun and turn servers
        client.emit("iceservers", iceInfo);

    });

    function clientsInRoom(name) {
        // return io.sockets.clients(name).length;
        var adapter = io.nsps["/"].adapter;
        var clients = adapter.rooms[name] || {};
        return Object.keys(clients).length;
    }

    function describeRoom(name) {
        var adapter = io.nsps["/"].adapter;
        var clients = adapter.rooms[name] || {};
        var result = {
            clients: {}
        }

        Object.keys(clients).forEach(function (id) {
            var client = adapter.nsp.connected[id];
            result.clients[id] = client.resources;
        });

    }
}<|endoftext|>


<commit_before>/*jslint browser: true*/
/*global Tangram, gui */

(function () {

    // default source, can be overriden by URL
    var default_tile_source = 'demo';

    var tile_sources = {
        'demo': {
            source: {
                type: 'GeoJSONTileSource',
                // url:  'http://localhost:8000/24640.json'
                url:  'http://vector.mapzen.com/osm/all/{z}/{x}/{y}.json'
            },
            layers: 'layers.js',
            styles: 'styles.yaml'
        },
    };
    var locations = {
        'London': [51.508, -0.105, 15],
        'New York': [40.70531887544228, -74.00976419448853, 16],
        'Seattle': [47.609722, -122.333056, 15]
    };
    var osm_debug = false;

    // set tile source
    default_tile_source = "demo";

    // set start location
    var map_start_location = [40.71186988568351,-74.01727437973024,17]

    /*** Map ***/

    var map = L.map('map', {
        maxZoom: 20,
        inertia: false,
        keyboard: true
    });
    var layer = Tangram.leafletLayer({
        vectorTileSource: tile_sources[default_tile_source].source,
        vectorLayers: tile_sources[default_tile_source].layers,
        vectorStyles: tile_sources[default_tile_source].styles,
        numWorkers: 2,
        // debug: true,
        attribution: 'Map data © OpenStreetMap contributors | Source Code',
        unloadInvisibleTiles: false,
        updateWhenIdle: false
    });

    var scene = layer.scene;
    window.scene = scene;

    // Update URL hash on move
    // map.attributionControl.setPrefix('');
    map.setView(map_start_location.slice(0, 2), map_start_location[2]);
    // map.on('moveend', updateURL);

    // Resize map to window
    function resizeMap() {
        document.getElementById('map').style.width = window.innerWidth + 'px';
        document.getElementById('map').style.height = window.innerHeight + 'px';
        map.invalidateSize(false);
    }

    window.addEventListener('resize', resizeMap);
    resizeMap();

    // Create dat GUI
    var gui = new dat.GUI();
    function addGUI () {
        gui.domElement.parentNode.style.zIndex = 5;
        window.gui = gui;

        // add color controls for each layer
        // var layer_controls = {};
        // layer.scene.layers.forEach(function(l) {
        //     if (layer.scene.styles.layers[l.name] == null) {
        //         return;
        //     }

        //     var mycolor = scene.modes[l.name+"-mode"].shaders.uniforms.u_color;
        //     layer_controls[l.name] = [mycolor[0] * 255, mycolor[1] * 255, mycolor[2] * 255];
        //     gui.
        //         addColor(layer_controls, l.name).
        //         onChange(function(value) {
        //             scene.modes[l.name+"-mode"].shaders.uniforms.u_color = [value[0]/255., value[1]/255., value[2]/255.];
        //             scene.dirty = true;
        //         });
        // });

        // add visibility togggles for each layer, in a folder
        var layer_gui = gui.addFolder('Layers');
        var layer_controls = {};
        layer.scene.layers.forEach(function(l) {
            if (layer.scene.styles.layers[l.name] == null) {
                return;
            }

            layer_controls[l.name] = !(layer.scene.styles.layers[l.name].visible == false);
            layer_gui.
                add(layer_controls, l.name).
                onChange(function(value) {
                    layer.scene.styles.layers[l.name].visible = value;
                    layer.scene.rebuildTiles();
                });
        });

        gui.height = 5;
        var height = gui.add(gui, "height", 0, 100);
        height.onFinishChange(function(value) {
            scene.styles.layers.buildings.filter = "function (f) { return f.properties.height > "+value+"; }";
            scene.rebuildTiles();
        });

        gui.roadwidth = 5;
        var roadwidth = gui.add(gui, "roadwidth", 0, 100);
        roadwidth.onFinishChange(function(value) {
            scene.styles.layers.roads.width.default = "function (f, t, h) { return "+value+"; }";
            scene.rebuildTiles();
        });

    }

    function animationFrame(cb) {
        if (typeof window.requestAnimationFrame === 'function') {
            return window.requestAnimationFrame;
        } else {
            return window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame    ||
                window.oRequestAnimationFrame      ||
                window.msRequestAnimationFrame     ||
                function (cb) {
                    setTimeout(cb, 1000 /60);
                };
        }
    }

    function frame () {

        layer.render();

        animationFrame()(frame);
    }

    /***** Render loop *****/
    window.addEventListener('load', function () {
        // Scene initialized
        layer.on('init', function() {
            addGUI();

            // setGLProgramDefines();
            scene.refreshModes();
            // updateURL();
        });
        layer.addTo(map);

        if (osm_debug == true) {
            window.osm_layer =
                L.tileLayer(
                    'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                    { opacity: 0.5 })
                .bringToFront()
                .addTo(map);
        }

        frame();
    });

}());
<commit_msg>update demo<commit_after>/*jslint browser: true*/
/*global Tangram, gui */

(function () {

    // default source, can be overriden by URL
    var default_tile_source = 'demo';

    var tile_sources = {
        'demo': {
            source: {
                type: 'GeoJSONTileSource',
                // url:  'http://localhost:8000/demo3/potosi_bolivia.osm-line2.geojson'
                // url:  'http://localhost:8000/demo3/potosi_bolivia.osm-polygon.geojson'
                // url:  'http://localhost:8000/demo3/2.json'
                url:  'http://vector.mapzen.com/osm/all/{z}/{x}/{y}.json'
            },
            layers: 'layers.js',
            styles: 'styles.yaml'
        },
    };
    var locations = {
        'London': [51.508, -0.105, 15],
        'New York': [40.70531887544228, -74.00976419448853, 16],
        'Seattle': [47.609722, -122.333056, 15]
    };
    var osm_debug = false;

    /*** URL parsing ***/

    // URL hash pattern is one of:
    // #[source]
    // #[lat],[lng],[zoom]
    // #[source],[lat],[lng],[zoom]
    // #[source],[location name]
    var url_hash = window.location.hash.slice(1, window.location.hash.length).split(',');

    // Get tile source from URL
    if (url_hash.length >= 1 && tile_sources[url_hash[0]] != null) {
        default_tile_source = url_hash[0];
    }

    // Get location from URL
    // var map_start_location = locations['New York'];
    var map_start_location = locations['London'];

    if (url_hash.length == 3) {
        map_start_location = url_hash.slice(0, 3);
    }
    if (url_hash.length > 3) {
        map_start_location = url_hash.slice(1, 4);
    }
    else if (url_hash.length == 2) {
        map_start_location = locations[url_hash[1]];
    }

    if (url_hash.length > 4) {
        var url_ui = url_hash.slice(4);

        // Mode on URL?
        var url_mode;
        if (url_ui) {
            var re = new RegExp(/mode=(\w+)/);
            url_ui.forEach(function(u) {
                var match = u.match(re);
                url_mode = (match && match.length > 1 && match[1]);
            });
        }
    }

    // set tile source
    default_tile_source = "demo";

    // Put current state on URL
    function updateURL() {
        var map_latlng = map.getCenter(),
            url_options = [default_tile_source, map_latlng.lat, map_latlng.lng, map.getZoom()];

        // if (rS) {
        //     url_options.push('rstats');
        // }

        // if (gl_mode_options && gl_mode_options.effect != '') {
        //     url_options.push('mode=' + gl_mode_options.effect);
        // }

        window.location.hash = url_options.join(',');
    }

    /*** Map ***/

    var map = L.map('map', {
        maxZoom: 20,
        inertia: false,
        keyboard: false
    });
    var layer = Tangram.leafletLayer({
        vectorTileSource: tile_sources[default_tile_source].source,
        vectorLayers: tile_sources[default_tile_source].layers,
        vectorStyles: tile_sources[default_tile_source].styles,
        numWorkers: 2,
        // debug: true,
        attribution: 'Map data © OpenStreetMap contributors | Source Code',
        unloadInvisibleTiles: false,
        updateWhenIdle: false
    });

    var scene = layer.scene;
    window.scene = scene;

    // Update URL hash on move
    // map.attributionControl.setPrefix('');
    map.setView(map_start_location.slice(0, 2), map_start_location[2]);
    map.on('moveend', updateURL);

    // Resize map to window
    function resizeMap() {
        document.getElementById('map').style.width = window.innerWidth + 'px';
        document.getElementById('map').style.height = window.innerHeight + 'px';
        map.invalidateSize(false);
    }

    window.addEventListener('resize', resizeMap);
    resizeMap();

    // Create dat GUI
    var gui = new dat.GUI();
    function addGUI () {
        gui.domElement.parentNode.style.zIndex = 5;
        window.gui = gui;

        // add color controls for each layer
        // var layer_controls = {};
        // layer.scene.layers.forEach(function(l) {
        //     if (layer.scene.styles.layers[l.name] == null) {
        //         return;
        //     }

        //     var mycolor = scene.modes[l.name+"-mode"].shaders.uniforms.u_color;
        //     layer_controls[l.name] = [mycolor[0] * 255, mycolor[1] * 255, mycolor[2] * 255];
        //     gui.
        //         addColor(layer_controls, l.name).
        //         onChange(function(value) {
        //             scene.modes[l.name+"-mode"].shaders.uniforms.u_color = [value[0]/255., value[1]/255., value[2]/255.];
        //             scene.dirty = true;
        //         });
        // });

        // add visibility togggles for each layer, in a folder
        var layer_gui = gui.addFolder('Layers');
        var layer_controls = {};
        layer.scene.layers.forEach(function(l) {
            if (layer.scene.styles.layers[l.name] == null) {
                return;
            }

            layer_controls[l.name] = !(layer.scene.styles.layers[l.name].visible == false);
            layer_gui.
                add(layer_controls, l.name).
                onChange(function(value) {
                    layer.scene.styles.layers[l.name].visible = value;
                    layer.scene.rebuildTiles();
                });
        });

        gui.height = 5;
        var height = gui.add(gui, "height", 0, 100);
        height.onFinishChange(function(value) {
            scene.styles.layers.buildings.filter = "function (f) { return f.properties.height > "+value+"; }";
            scene.rebuildTiles();
        });

        gui.roadwidth = 5;
        var roadwidth = gui.add(gui, "roadwidth", 0, 100);
        roadwidth.onFinishChange(function(value) {
            scene.styles.layers.roads.width.default = "function (f, t, h) { return "+value+"; }";
            scene.rebuildTiles();
        });

    }

    function animationFrame(cb) {
        if (typeof window.requestAnimationFrame === 'function') {
            return window.requestAnimationFrame;
        } else {
            return window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame    ||
                window.oRequestAnimationFrame      ||
                window.msRequestAnimationFrame     ||
                function (cb) {
                    setTimeout(cb, 1000 /60);
                };
        }
    }

    function frame () {

        layer.render();

        animationFrame()(frame);
    }

    /***** Render loop *****/
    window.addEventListener('load', function () {
        // Scene initialized
        layer.on('init', function() {
            addGUI();

            // setGLProgramDefines();
            scene.refreshModes();
            // updateURL();
        });
        layer.addTo(map);

        if (osm_debug == true) {
            window.osm_layer =
                L.tileLayer(
                    'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                    { opacity: 0.5 })
                .bringToFront()
                .addTo(map);
        }

        frame();
    });

}());
<|endoftext|>


<commit_before>'use strict';

(function (root, factory) {
  // optional AMD https://github.com/umdjs/umd/blob/master/amdWeb.js
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(factory);
  } else {
    // Browser globals
    root.simpleRAF = factory();
  }
}(this, function () {
  var rafID, callbacks, callbacksMeta,
      runCallback, removeCallback, loop, startLoop;

  callbacks = [];
  callbacksMeta = [];

  removeCallback = function (key) {
    var i = typeof key === 'function' ? callbacks.indexOf(key) : key;
    if (i > -1) {
      callbacks.splice(i, 1);
      callbacksMeta.splice(i, 1);
    }
    if (!callbacks.length) {
      window.cancelAnimationFrame(rafID);
    }
  };

  runCallback = function (callback, index, id) {
    var returnValue, meta;

    meta = callbacksMeta[index];
    meta.val += meta.increment;

    returnValue = callback.call(meta, id, meta.val);
    if (returnValue === false) {
      removeCallback(index);
    }
  };

  loop = function (id) {
    if ( !callbacks.length ) return;
    callbacks.forEach(function(obj, i){
      runCallback(obj, i, id);
    });
    rafID = window.requestAnimationFrame(loop);
  };

  startLoop = function () {
    if (callbacks.length === 1) {
        window.requestAnimationFrame(loop);
    }
  };

  return {
    on: function (callback, increment) {
      // todo: add the possibility to pass a increment array
      callbacks.push(callback);
      callbacksMeta.push({val: 0, increment: increment || 1 });
      startLoop();
    },
    off: function (callback) {
      removeCallback(callback);
    }
  };
}));
<commit_msg>adds documentation<commit_after>'use strict';

(function (root, factory) {
  // optional AMD https://github.com/umdjs/umd/blob/master/amdWeb.js
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(factory);
  } else {
    // Browser globals
    root.simpleRAF = factory();
  }
}(this, function () {
  var rafID, callbacks, callbacksMeta,
      runCallback, removeCallback, loop, startLoop;

  callbacks = [];
  /**
   * contains all the meta-information for each callback, like current
   * iteration and iteration
   */
  callbacksMeta = [];

  /**
   * removeCallback: removes a callback and its meta data from the corresponding
   * arrays
   * @param   {[type]} key function or index in callback array
   * @returns {[void]}
   */
  removeCallback = function (key) {
    var i = typeof key === 'function' ? callbacks.indexOf(key) : key;
    if (i > -1) {
      callbacks.splice(i, 1);
      callbacksMeta.splice(i, 1);
    }
    if (!callbacks.length) {
      window.cancelAnimationFrame(rafID);
    }
  };

  runCallback = function (callback, index, id) {
  /**
   * runCallback: calls the individual callbacks and passes the corresponding
   * meta data as arguments
   * @param   {Function} callback
   * @param   {integer}  index      position in callbacks array
   * @param   {double}   timeStamp  RAF DOMHighResTimeStamp
   * @returns {void}
   */
    var returnValue, meta;

    meta = callbacksMeta[index];
    meta.val += meta.increment;

    returnValue = callback.call(meta, id, meta.val);
    if (returnValue === false) {
      removeCallback(index);
    }
  };

  loop = function (id) {
  /**
   * loop: request animation frame loop
   * @param   {double} timeStamp RAF DOMHighResTimeStamp
   * @returns {void}
   */
    if ( !callbacks.length ) return;
    callbacks.forEach(function(obj, i){
      runCallback(obj, i, id);
    });
    rafID = window.requestAnimationFrame(loop);
  };

  /**
   * startLoop kicks of the RAF loop if there is at least one callback
   * @returns {void}
   */
  startLoop = function () {
    if (callbacks.length === 1) {
        window.requestAnimationFrame(loop);
    }
  };

  return {
    /**
     * on: public method to register a callback
     * @param   {Function} callback
     * @param   {float}   increment increment value on every callback
     * @returns {void}
     */
    on: function (callback, increment) {
      // todo: add the possibility to pass a increment array
      callbacks.push(callback);
      callbacksMeta.push({val: 0, increment: increment || 1 });
      startLoop();
    },
    /**
     * off description]
     * @param   {Function} callback callback function to remove
     * @returns {void}
     */
    off: function (callback) {
      removeCallback(callback);
    }
  };
}));
<|endoftext|>


<commit_before>const path = require('path');
const fs = require('fs-extra');
const exec = require('child_process').exec;
const config = require('./deploy-web.config');

function execute(command, silent) {
    if(!silent) {
        console.log('>', command);
    }
    return new Promise((resolve, reject) => {
        exec(command, (error, stdout, stderr) => {
            if(!silent) {
                console.log(stdout);
                console.log(stderr);
            }
            if(error) {
                reject(error);
            } else {
                resolve(stdout);
            }
        });
    });
}

function validateEnvironment() {
    if(!process.env.GITHUB_ACTOR) {
        throw new Error('Missing environment variable "GITHUB_ACTOR" providing the contributor name!');
    }
    if(!process.env.GITHUB_TOKEN) {
        throw new Error('Missing environment variable "GITHUB_TOKEN" to provide access to the git repository!');
    }
    if(!process.env.HAKUNEKO_PASSPHRASE) {
        throw new Error('Missing environment variable "HAKUNEKO_PASSPHRASE" to decrypt private key for signature!');
    }
}

async function gitStashPush(identifier) {
    identifier = identifier || 'HTDOCS#' + Date.now().toString(16).toUpperCase();
    await execute(`git stash push -u -m '${identifier}'`);
    return identifier;
}

async function gitStashPop(identifier) {
    let out = await execute(`git stash list`);
    if(out.includes(identifier)) {
        await execute(`git stash pop`);
    }
}

async function sslPack(archive, meta) {
    let key = path.resolve(config.key);
    let cwd = process.cwd();
    if(config.build) {
        process.chdir(config.build);
    }
    await execute(`zip -r ${archive} . > /dev/null`);
    let signature = await execute(`openssl dgst -sha256 -hex -sign ${key} -passin ${config.passphrase} ${archive} | cut -d' ' -f2`);
    await fs.writeFile(meta, `${archive}?signature=${signature}`);
    process.chdir(cwd);
}

async function gitCommit() {
    let user = process.env.GITHUB_ACTOR;
    let mail = user + '@users.noreply.github.com';
    let auth = Buffer.from('x-access-token:' + process.env.GITHUB_TOKEN).toString('base64');
    await execute(`git add ${config.directory}/*`);
    await execute(`git -c user.name="${user}" -c user.email="${mail}" commit -m 'Deployed Release: ${config.directory}'`);
    await execute(`git -c http.extraheader="AUTHORIZATION: Basic ${auth}" push origin HEAD:${config.branch}`);
}

async function main() {
    validateEnvironment();
    let meta = 'latest';
    let archive = Date.now().toString(36).toUpperCase() + '.zip';
    await sslPack(archive, meta);
    await fs.remove(config.directory);
    await fs.mkdir(config.directory);
    await fs.move(path.resolve(config.build, meta), path.resolve(config.directory, meta));
    await fs.move(path.resolve(config.build, archive), path.resolve(config.directory, archive));
    let stashID = await gitStashPush();
    await execute(`git branch`);
    await execute(`git checkout --track origin/${config.branch}`);
    await execute(`git rm -r ${config.directory} || true`);
    await gitStashPop(stashID);
    await gitCommit();
}

// exit application as soon as any uncaught exception is thrown
process.on('unhandledRejection', error => { throw error; });
main();<commit_msg>[github-actions] debug remote list<commit_after>const path = require('path');
const fs = require('fs-extra');
const exec = require('child_process').exec;
const config = require('./deploy-web.config');

function execute(command, silent) {
    if(!silent) {
        console.log('>', command);
    }
    return new Promise((resolve, reject) => {
        exec(command, (error, stdout, stderr) => {
            if(!silent) {
                console.log(stdout);
                console.log(stderr);
            }
            if(error) {
                reject(error);
            } else {
                resolve(stdout);
            }
        });
    });
}

function validateEnvironment() {
    if(!process.env.GITHUB_ACTOR) {
        throw new Error('Missing environment variable "GITHUB_ACTOR" providing the contributor name!');
    }
    if(!process.env.GITHUB_TOKEN) {
        throw new Error('Missing environment variable "GITHUB_TOKEN" to provide access to the git repository!');
    }
    if(!process.env.HAKUNEKO_PASSPHRASE) {
        throw new Error('Missing environment variable "HAKUNEKO_PASSPHRASE" to decrypt private key for signature!');
    }
}

async function gitStashPush(identifier) {
    identifier = identifier || 'HTDOCS#' + Date.now().toString(16).toUpperCase();
    await execute(`git stash push -u -m '${identifier}'`);
    return identifier;
}

async function gitStashPop(identifier) {
    let out = await execute(`git stash list`);
    if(out.includes(identifier)) {
        await execute(`git stash pop`);
    }
}

async function sslPack(archive, meta) {
    let key = path.resolve(config.key);
    let cwd = process.cwd();
    if(config.build) {
        process.chdir(config.build);
    }
    await execute(`zip -r ${archive} . > /dev/null`);
    let signature = await execute(`openssl dgst -sha256 -hex -sign ${key} -passin ${config.passphrase} ${archive} | cut -d' ' -f2`);
    await fs.writeFile(meta, `${archive}?signature=${signature}`);
    process.chdir(cwd);
}

async function gitCommit() {
    let user = process.env.GITHUB_ACTOR;
    let mail = user + '@users.noreply.github.com';
    let auth = Buffer.from('x-access-token:' + process.env.GITHUB_TOKEN).toString('base64');
    await execute(`git add ${config.directory}/*`);
    await execute(`git -c user.name="${user}" -c user.email="${mail}" commit -m 'Deployed Release: ${config.directory}'`);
    await execute(`git -c http.extraheader="AUTHORIZATION: Basic ${auth}" push origin HEAD:${config.branch}`);
}

async function main() {
    validateEnvironment();
    let meta = 'latest';
    let archive = Date.now().toString(36).toUpperCase() + '.zip';
    await sslPack(archive, meta);
    await fs.remove(config.directory);
    await fs.mkdir(config.directory);
    await fs.move(path.resolve(config.build, meta), path.resolve(config.directory, meta));
    await fs.move(path.resolve(config.build, archive), path.resolve(config.directory, archive));
    let stashID = await gitStashPush();
    await execute(`git remote -v`);
    await execute(`git branch`);
    await execute(`git checkout --track origin/${config.branch}`);
    await execute(`git rm -r ${config.directory} || true`);
    await gitStashPop(stashID);
    await gitCommit();
}

// exit application as soon as any uncaught exception is thrown
process.on('unhandledRejection', error => { throw error; });
main();<|endoftext|>


<commit_before>(function() {

////////////////////
// SiriWave9Curve //
////////////////////

function SiriWave9Curve(opt) {
	opt = opt || {};
	this.controller = opt.controller;
	this.color = opt.color;
	this.tick = 0;

	this.respawn();
}

SiriWave9Curve.prototype.respawn = function() {
	this.amplitude = 0.3 + Math.random() * 0.7;
	this.seed = Math.random();
	this.open_class = 2+(Math.random()*3)|0;
};

SiriWave9Curve.prototype.equation = function(i) {
	var p = this.tick;
	var y = -1 * Math.abs(Math.sin(p)) * this.controller.amplitude * this.amplitude * this.controller.MAX * Math.pow(1/(1+Math.pow(this.open_class*i,2)),2);
	if (Math.abs(y) < 0.001) {
		this.respawn();
	}
	return y;
};

SiriWave9Curve.prototype._draw = function(m) {
	this.tick += this.controller.speed * (1-0.5*Math.sin(this.seed*Math.PI));

	var ctx = this.controller.ctx;
	ctx.beginPath();

	var x_base = this.controller.width/2 + (-this.controller.width/4 + this.seed*(this.controller.width/2) );
	var y_base = this.controller.height/2;

	var x, y, x_init;

	var i = -3;
	while (i <= 3) {
		x = x_base + i * this.controller.width/4;
		y = y_base + (m * this.equation(i));
		x_init = x_init || x;
		ctx.lineTo(x, y);
		i += 0.01;
	}

	var h = Math.abs(this.equation(0));
	var gradient = ctx.createRadialGradient(x_base, y_base, h*1.15, x_base, y_base, h * 0.3 );
	gradient.addColorStop(0, 'rgba(' + this.color.join(',') + ',0.4)');
	gradient.addColorStop(1, 'rgba(' + this.color.join(',') + ',0.2)');

	ctx.fillStyle = gradient;

	ctx.lineTo(x_init, y_base);
	ctx.closePath();

	ctx.fill();
};

SiriWave9Curve.prototype.draw = function() {
	this._draw(-1);
	this._draw(1);
};

//////////////
// SiriWave //
//////////////

function SiriWave9(opt) {
	opt = opt || {};

	this.tick = 0;
	this.run = false;

	// UI vars

	this.ratio = opt.ratio || window.devicePixelRatio || 1;

	this.width = this.ratio * (opt.width || 320);
	this.height = this.ratio * (opt.height || 100);
	this.MAX = this.height/2;

	this.speed = 0.1;
	this.amplitude = opt.amplitude || 1;

	// Interpolation

	this.speedInterpolationSpeed = opt.speedInterpolationSpeed || 0.005;
	this.amplitudeInterpolationSpeed = opt.amplitudeInterpolationSpeed || 0.05;

	this._interpolation = {
		speed: this.speed,
		amplitude: this.amplitude
	};

	// Canvas

	this.canvas = document.createElement('canvas');
	this.canvas.width = this.width;
	this.canvas.height = this.height;

	if (opt.cover) {
		this.canvas.style.width = this.canvas.style.height = '100%';
	} else {
		this.canvas.style.width = (this.width / this.ratio) + 'px';
		this.canvas.style.height = (this.height / this.ratio) + 'px';
	};

	this.container = opt.container || document.body;
	this.container.appendChild(this.canvas);

	this.ctx = this.canvas.getContext('2d');

	// Create curves

	this.curves = [];
	for (var i = 0; i < SiriWave9.prototype.COLORS.length; i++) {
		var color = SiriWave9.prototype.COLORS[i];
		for (var j = 0; j < (3 * Math.random())|0; j++) {
			this.curves.push(new SiriWave9Curve({
				controller: this,
				color: color
			}));
		}
	}

	if (opt.autostart) {
		this.start();
	}
}

SiriWave9.prototype._interpolate = function(propertyStr) {
	increment = this[ propertyStr + 'InterpolationSpeed' ];

	if (Math.abs(this._interpolation[propertyStr] - this[propertyStr]) <= increment) {
		this[propertyStr] = this._interpolation[propertyStr];
	} else {
		if (this._interpolation[propertyStr] > this[propertyStr]) {
			this[propertyStr] += increment;
		} else {
			this[propertyStr] -= increment;
		}
	}
};

SiriWave9.prototype._clear = function() {
	this.ctx.globalCompositeOperation = 'destination-out';
	this.ctx.fillRect(0, 0, this.width, this.height);
	this.ctx.globalCompositeOperation = 'lighter';
};

SiriWave9.prototype._draw = function() {
	for (var i = 0, len = this.curves.length; i < len; i++) {
		this.curves[i].draw();
	}
};

SiriWave9.prototype._startDrawCycle = function() {
	if (this.run === false) return;
	this._clear();

	// Interpolate values
	this._interpolate('amplitude');
	this._interpolate('speed');

	this._draw();
	this.phase = (this.phase + Math.PI*this.speed) % (2*Math.PI);

	if (window.requestAnimationFrame) {
		window.requestAnimationFrame(this._startDrawCycle.bind(this));
	} else {
		setTimeout(this._startDrawCycle.bind(this), 20);
	}
};

SiriWave9.prototype.start = function() {
	this.tick = 0;
	this.run = true;
	this._startDrawCycle();
};

SiriWave9.prototype.stop = function() {
	this.tick = 0;
	this.run = false;
};

SiriWave9.prototype.setSpeed = function(v, increment) {
	this._interpolation.speed = v;
};

SiriWave9.prototype.setNoise = SiriWave9.prototype.setAmplitude = function(v) {
	this._interpolation.amplitude = Math.max(Math.min(v, 1), 0);
};

SiriWave9.prototype.COLORS = [
[32,133,252],
[94,252,169],
[253,71,103]
];

if (typeof define === 'function' && define.amd) {
	define(function(){ return SiriWave9; });
	return;
} else {
	window.SiriWave9 = SiriWave9;
}

})();
<commit_msg>little typo<commit_after>(function() {

////////////////////
// SiriWave9Curve //
////////////////////

function SiriWave9Curve(opt) {
	opt = opt || {};
	this.controller = opt.controller;
	this.color = opt.color;
	this.tick = 0;

	this.respawn();
}

SiriWave9Curve.prototype.respawn = function() {
	this.amplitude = 0.3 + Math.random() * 0.7;
	this.seed = Math.random();
	this.open_class = 2+(Math.random()*3)|0;
};

SiriWave9Curve.prototype.equation = function(i) {
	var p = this.tick;
	var y = -1 * Math.abs(Math.sin(p)) * this.controller.amplitude * this.amplitude * this.controller.MAX * Math.pow(1/(1+Math.pow(this.open_class*i,2)),2);
	if (Math.abs(y) < 0.001) {
		this.respawn();
	}
	return y;
};

SiriWave9Curve.prototype._draw = function(m) {
	this.tick += this.controller.speed * (1-0.5*Math.sin(this.seed*Math.PI));

	var ctx = this.controller.ctx;
	ctx.beginPath();

	var x_base = this.controller.width/2 + (-this.controller.width/4 + this.seed*(this.controller.width/2) );
	var y_base = this.controller.height/2;

	var x, y, x_init;

	var i = -3;
	while (i <= 3) {
		x = x_base + i * this.controller.width/4;
		y = y_base + (m * this.equation(i));
		x_init = x_init || x;
		ctx.lineTo(x, y);
		i += 0.01;
	}

	var h = Math.abs(this.equation(0));
	var gradient = ctx.createRadialGradient(x_base, y_base, h*1.15, x_base, y_base, h * 0.3 );
	gradient.addColorStop(0, 'rgba(' + this.color.join(',') + ',0.4)');
	gradient.addColorStop(1, 'rgba(' + this.color.join(',') + ',0.2)');

	ctx.fillStyle = gradient;

	ctx.lineTo(x_init, y_base);
	ctx.closePath();

	ctx.fill();
};

SiriWave9Curve.prototype.draw = function() {
	this._draw(-1);
	this._draw(1);
};

//////////////
// SiriWave //
//////////////

function SiriWave9(opt) {
	opt = opt || {};

	this.tick = 0;
	this.run = false;

	// UI vars

	this.ratio = opt.ratio || window.devicePixelRatio || 1;

	this.width = this.ratio * (opt.width || 320);
	this.height = this.ratio * (opt.height || 100);
	this.MAX = this.height/2;

	this.speed = 0.1;
	this.amplitude = opt.amplitude || 1;

	// Interpolation

	this.speedInterpolationSpeed = opt.speedInterpolationSpeed || 0.005;
	this.amplitudeInterpolationSpeed = opt.amplitudeInterpolationSpeed || 0.05;

	this._interpolation = {
		speed: this.speed,
		amplitude: this.amplitude
	};

	// Canvas

	this.canvas = document.createElement('canvas');
	this.canvas.width = this.width;
	this.canvas.height = this.height;

	if (opt.cover) {
		this.canvas.style.width = this.canvas.style.height = '100%';
	} else {
		this.canvas.style.width = (this.width / this.ratio) + 'px';
		this.canvas.style.height = (this.height / this.ratio) + 'px';
	};

	this.container = opt.container || document.body;
	this.container.appendChild(this.canvas);

	this.ctx = this.canvas.getContext('2d');

	// Create curves

	this.curves = [];
	for (var i = 0; i < SiriWave9.prototype.COLORS.length; i++) {
		var color = SiriWave9.prototype.COLORS[i];
		for (var j = 0; j < (3 * Math.random())|0; j++) {
			this.curves.push(new SiriWave9Curve({
				controller: this,
				color: color
			}));
		}
	}

	if (opt.autostart) {
		this.start();
	}
}

SiriWave9.prototype._interpolate = function(propertyStr) {
	increment = this[ propertyStr + 'InterpolationSpeed' ];

	if (Math.abs(this._interpolation[propertyStr] - this[propertyStr]) <= increment) {
		this[propertyStr] = this._interpolation[propertyStr];
	} else {
		if (this._interpolation[propertyStr] > this[propertyStr]) {
			this[propertyStr] += increment;
		} else {
			this[propertyStr] -= increment;
		}
	}
};

SiriWave9.prototype._clear = function() {
	this.ctx.globalCompositeOperation = 'destination-out';
	this.ctx.fillRect(0, 0, this.width, this.height);
	this.ctx.globalCompositeOperation = 'lighter';
};

SiriWave9.prototype._draw = function() {
	for (var i = 0, len = this.curves.length; i < len; i++) {
		this.curves[i].draw();
	}
};

SiriWave9.prototype._startDrawCycle = function() {
	if (this.run === false) return;
	this._clear();

	// Interpolate values
	this._interpolate('amplitude');
	this._interpolate('speed');

	this._draw();
	this.phase = (this.phase + Math.PI*this.speed) % (2*Math.PI);

	if (window.requestAnimationFrame) {
		window.requestAnimationFrame(this._startDrawCycle.bind(this));
	} else {
		setTimeout(this._startDrawCycle.bind(this), 20);
	}
};

SiriWave9.prototype.start = function() {
	this.tick = 0;
	this.run = true;
	this._startDrawCycle();
};

SiriWave9.prototype.stop = function() {
	this.tick = 0;
	this.run = false;
};

SiriWave9.prototype.setSpeed = function(v, increment) {
	this._interpolation.speed = v;
};

SiriWave9.prototype.setNoise = SiriWave9.prototype.setAmplitude = function(v) {
	this._interpolation.amplitude = Math.max(Math.min(v, 1), 0);
};

SiriWave9.prototype.COLORS = [
[32,133,252],
[94,252,169],
[253,71,103]
];

if (typeof define === 'function' && define.amd) {
	define(function(){ return SiriWave9; });
} else {
	window.SiriWave9 = SiriWave9;
}

})();
<|endoftext|>


<commit_before>"use strict";function _typeof(e){return e&&"undefined"!=typeof Symbol&&e.constructor===Symbol?"symbol":typeof e}!function(e){if("object"===("undefined"==typeof exports?"undefined":_typeof(exports))&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.gitUrlParse=e()}}(function(){return function e(r,t,n){function o(i,u){if(!t[i]){if(!r[i]){var l="function"==typeof require&&require;if(!u&&l)return l(i,!0);if(s)return s(i,!0);var f=new Error("Cannot find module '"+i+"'");throw f.code="MODULE_NOT_FOUND",f}var a=t[i]={exports:{}};r[i][0].call(a.exports,function(e){var t=r[i][1][e];return o(t?t:e)},a,a.exports,e,r,t,n)}return t[i].exports}for(var s="function"==typeof require&&require,i=0;i<n.length;i++)o(n[i]);return o}({1:[function(e,r,t){function n(e){if("string"!=typeof e)throw new Error("The url must be a string.");var r=o(e),t=r.resource.split("."),s=null;switch(r.toString=function(e){return n.stringify(this,e)},r.source=t.length>2?t.slice(-2).join("."):r.source=r.resource,r.name=r.pathname.substring(1).replace(/\.git$/,""),r.owner=r.user,r.organization=r.owner,r.source){case"cloudforge.com":r.owner=r.user,r.organization=t[0];break;default:s=r.name.split("/"),2===s.length&&(r.owner=s[0],r.name=s[1])}return r.full_name=r.owner,r.name&&(r.full_name&&(r.full_name+="/"),r.full_name+=r.name),r}var o=e("git-up");n.stringify=function(e,r){switch(r=r||e.protocol){case"ssh":return"git@"+e.resource+":"+e.full_name+".git";case"git+ssh":return"git+ssh://git@"+e.resource+"/"+e.full_name+".git";case"http":case"https":return r+"://"+e.resource+"/"+e.full_name;default:return e.href}},r.exports=n},{"git-up":2}],2:[function(e,r,t){function n(e){var r=o(e);r.token="";var t=r.user.split(":");return 2===t.length&&("x-oauth-basic"===t[1]?r.token=t[0]:"x-token-auth"===t[0]&&(r.token=t[1])),s(r.protocols)||s(e)?r.protocol="ssh":r.protocols.length?r.protocol=r.protocols[0]:r.protocol="file",r}var o=e("parse-url"),s=e("is-ssh");r.exports=n},{"is-ssh":3,"parse-url":4}],3:[function(e,r,t){function n(e){if(Array.isArray(e))return-1!==e.indexOf("ssh")||-1!==e.indexOf("rsync");if("string"!=typeof e)return!1;var r=o(e);return e=e.substring(e.indexOf("://")+3),n(r)?!0:e.indexOf("@")<e.indexOf(":")}var o=e("protocols");r.exports=n},{protocols:5}],4:[function(e,r,t){function n(e){var r={protocols:o(e),protocol:null,port:null,resource:"",user:"",pathname:"",hash:"",search:"",href:e},t=e.indexOf("://"),n=null,i=null;return r.protocol=r.protocols[0]||(s(e)?"ssh":"file"),-1!==t&&(e=e.substring(t+3)),i=e.split("/"),r.resource=i.shift(),n=r.resource.split("@"),2===n.length&&(r.user=n[0],r.resource=n[1]),n=r.resource.split(":"),2===n.length&&(r.resource=n[0],r.port=parseInt(n[1]),isNaN(r.port)&&(r.port=null,i.unshift(n[1]))),i=i.filter(Boolean),r.pathname="/"+i.join("/"),n=r.pathname.split("#"),2===n.length&&(r.pathname=n[0],r.hash=n[1]),n=r.pathname.split("?"),2===n.length&&(r.pathname=n[0],r.search=n[1]),r}var o=e("protocols"),s=e("is-ssh");r.exports=n},{"is-ssh":3,protocols:5}],5:[function(e,r,t){r.exports=function(e,r){r===!0&&(r=0);var t=e.indexOf("://"),n=e.substring(0,t).split("+").filter(Boolean);return"number"==typeof r?n[r]:n}},{}]},{},[1])(1)});<commit_msg>Rebuild<commit_after>"use strict";

function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; }

(function (f) {
    if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") {
        module.exports = f();
    } else if (typeof define === "function" && define.amd) {
        define([], f);
    } else {
        var g;if (typeof window !== "undefined") {
            g = window;
        } else if (typeof global !== "undefined") {
            g = global;
        } else if (typeof self !== "undefined") {
            g = self;
        } else {
            g = this;
        }g.gitUrlParse = f();
    }
})(function () {
    var define, module, exports;return (function e(t, n, r) {
        function s(o, u) {
            if (!n[o]) {
                if (!t[o]) {
                    var a = typeof require == "function" && require;if (!u && a) return a(o, !0);if (i) return i(o, !0);var f = new Error("Cannot find module '" + o + "'");throw f.code = "MODULE_NOT_FOUND", f;
                }var l = n[o] = { exports: {} };t[o][0].call(l.exports, function (e) {
                    var n = t[o][1][e];return s(n ? n : e);
                }, l, l.exports, e, t, n, r);
            }return n[o].exports;
        }var i = typeof require == "function" && require;for (var o = 0; o < r.length; o++) {
            s(r[o]);
        }return s;
    })({ 1: [function (require, module, exports) {
            "use strict";

            // Dependencies

            var gitUp = require("git-up");

            /**
             * gitUrlParse
             * Parses a Git url.
             *
             * @name gitUrlParse
             * @function
             * @param {String} url The Git url to parse.
             * @return {GitUrl} The `GitUrl` object containing:
             *
             *  - `protocols` (Array): An array with the url protocols (usually it has one element).
             *  - `port` (null|Number): The domain port.
             *  - `resource` (String): The url domain (including subdomains).
             *  - `user` (String): The authentication user (usually for ssh urls).
             *  - `pathname` (String): The url pathname.
             *  - `hash` (String): The url hash.
             *  - `search` (String): The url querystring value.
             *  - `href` (String): The input url.
             *  - `protocol` (String): The git url protocol.
             *  - `token` (String): The oauth token (could appear in the https urls).
             *  - `source` (String): The Git provider (e.g. `"github.com"`).
             *  - `owner` (String): The repository owner.
             *  - `name` (String): The repository name.
             *  - `full_name` (String): The owner and name values in the `owner/name` format.
             *  - `toString` (Function): A function to stringify the parsed url into another url type.
             *  - `organization` (String): The organization the owner belongs to. This is CloudForge specific.
             *
             */
            function gitUrlParse(url) {

                if (typeof url !== "string") {
                    throw new Error("The url must be a string.");
                }

                var urlInfo = gitUp(url),
                    sourceParts = urlInfo.resource.split("."),
                    splits = null;

                urlInfo.toString = function (type) {
                    return gitUrlParse.stringify(this, type);
                };

                urlInfo.source = sourceParts.length > 2 ? sourceParts.slice(-2).join(".") : urlInfo.source = urlInfo.resource;

                urlInfo.name = urlInfo.pathname.substring(1).replace(/\.git$/, "");
                urlInfo.owner = urlInfo.user;
                urlInfo.organization = urlInfo.owner;

                switch (urlInfo.source) {
                    case "cloudforge.com":
                        urlInfo.owner = urlInfo.user;
                        urlInfo.organization = sourceParts[0];
                        break;
                    default:
                        splits = urlInfo.name.split("/");
                        if (splits.length === 2) {
                            urlInfo.owner = splits[0];
                            urlInfo.name = splits[1];
                        }
                        break;
                }

                urlInfo.full_name = urlInfo.owner;
                if (urlInfo.name) {
                    urlInfo.full_name && (urlInfo.full_name += "/");
                    urlInfo.full_name += urlInfo.name;
                }

                return urlInfo;
            }

            /**
             * stringify
             * Stringifies a `GitUrl` object.
             *
             * @name stringify
             * @function
             * @param {GitUrl} obj The parsed Git url object.
             * @param {String} type The type of the stringified url (default `obj.protocol`).
             * @return {String} The stringified url.
             */
            gitUrlParse.stringify = function (obj, type) {
                type = type || obj.protocol;
                switch (type) {
                    case "ssh":
                        return "git@" + obj.resource + ":" + obj.full_name + ".git";
                    case "git+ssh":
                        return "git+ssh://git@" + obj.resource + "/" + obj.full_name + ".git";
                    case "http":
                    case "https":
                        return type + "://" + obj.resource + "/" + obj.full_name;
                    default:
                        return obj.href;
                }
            };

            module.exports = gitUrlParse;
        }, { "git-up": 2 }], 2: [function (require, module, exports) {
            "use strict";

            // Dependencies

            var parseUrl = require("parse-url"),
                isSsh = require("is-ssh");

            /**
             * gitUp
             * Parses the input url.
             *
             * @name gitUp
             * @function
             * @param {String} input The input url.
             * @return {Object} An object containing the following fields:
             *
             *  - `protocols` (Array): An array with the url protocols (usually it has one element).
             *  - `port` (null|Number): The domain port.
             *  - `resource` (String): The url domain (including subdomains).
             *  - `user` (String): The authentication user (usually for ssh urls).
             *  - `pathname` (String): The url pathname.
             *  - `hash` (String): The url hash.
             *  - `search` (String): The url querystring value.
             *  - `href` (String): The input url.
             *  - `protocol` (String): The git url protocol.
             *  - `token` (String): The oauth token (could appear in the https urls).
             */
            function gitUp(input) {
                var output = parseUrl(input);
                output.token = "";

                var splits = output.user.split(":");
                if (splits.length === 2) {
                    if (splits[1] === "x-oauth-basic") {
                        output.token = splits[0];
                    } else if (splits[0] === "x-token-auth") {
                        output.token = splits[1];
                    }
                }

                if (isSsh(output.protocols) || isSsh(input)) {
                    output.protocol = "ssh";
                } else if (output.protocols.length) {
                    output.protocol = output.protocols[0];
                } else {
                    output.protocol = "file";
                }

                return output;
            }

            module.exports = gitUp;
        }, { "is-ssh": 3, "parse-url": 4 }], 3: [function (require, module, exports) {
            // Dependencies
            var protocols = require("protocols");

            /**
             * isSsh
             * Checks if an input value is a ssh url or not.
             *
             * @name isSsh
             * @function
             * @param {String|Array} input The input url or an array of protocols.
             * @return {Boolean} `true` if the input is a ssh url, `false` otherwise.
             */
            function isSsh(input) {

                if (Array.isArray(input)) {
                    return input.indexOf("ssh") !== -1 || input.indexOf("rsync") !== -1;
                }

                if (typeof input !== "string") {
                    return false;
                }

                var prots = protocols(input);
                input = input.substring(input.indexOf("://") + 3);
                if (isSsh(prots)) {
                    return true;
                }

                // TODO This probably could be improved :)
                return input.indexOf("@") < input.indexOf(":");
            }

            module.exports = isSsh;
        }, { "protocols": 5 }], 4: [function (require, module, exports) {
            // Dependencies
            var protocols = require("protocols"),
                isSsh = require("is-ssh");

            /**
             * parseUrl
             * Parses the input url.
             *
             * @name parseUrl
             * @function
             * @param {String} url The input url.
             * @return {Object} An object containing the following fields:
             *
             *  - `protocols` (Array): An array with the url protocols (usually it has one element).
             *  - `protocol` (String): The first protocol, `"ssh"` (if the url is a ssh url) or `"file"`.
             *  - `port` (null|Number): The domain port.
             *  - `resource` (String): The url domain (including subdomains).
             *  - `user` (String): The authentication user (usually for ssh urls).
             *  - `pathname` (String): The url pathname.
             *  - `hash` (String): The url hash.
             *  - `search` (String): The url querystring value.
             *  - `href` (String): The input url.
             */
            function parseUrl(url) {
                var output = {
                    protocols: protocols(url),
                    protocol: null,
                    port: null,
                    resource: "",
                    user: "",
                    pathname: "",
                    hash: "",
                    search: "",
                    href: url
                },
                    protocolIndex = url.indexOf("://"),
                    resourceIndex = -1,
                    splits = null,
                    parts = null;

                output.protocol = output.protocols[0] || (isSsh(url) ? "ssh" : "file");

                if (protocolIndex !== -1) {
                    url = url.substring(protocolIndex + 3);
                }

                parts = url.split("/");
                output.resource = parts.shift();

                // user@domain
                splits = output.resource.split("@");
                if (splits.length === 2) {
                    output.user = splits[0];
                    output.resource = splits[1];
                }

                // domain.com:port
                splits = output.resource.split(":");
                if (splits.length === 2) {
                    output.resource = splits[0];
                    output.port = parseInt(splits[1]);
                    if (isNaN(output.port)) {
                        output.port = null;
                        parts.unshift(splits[1]);
                    }
                }

                // Remove empty elements
                parts = parts.filter(Boolean);

                // Stringify the pathname
                output.pathname = "/" + parts.join("/");

                // #some-hash
                splits = output.pathname.split("#");
                if (splits.length === 2) {
                    output.pathname = splits[0];
                    output.hash = splits[1];
                }

                // ?foo=bar
                splits = output.pathname.split("?");
                if (splits.length === 2) {
                    output.pathname = splits[0];
                    output.search = splits[1];
                }

                return output;
            }

            module.exports = parseUrl;
        }, { "is-ssh": 3, "protocols": 5 }], 5: [function (require, module, exports) {
            /**
             * protocols
             * Returns the protocols of an input url.
             *
             * @name protocols
             * @function
             * @param {String} input The input url.
             * @param {Boolean|Number} first If `true`, the first protocol will be returned. If number, it will represent the zero-based index of the protocols array.
             * @return {Array|String} The array of protocols or the specified protocol.
             */
            module.exports = function protocols(input, first) {

                if (first === true) {
                    first = 0;
                }

                var index = input.indexOf("://"),
                    splits = input.substring(0, index).split("+").filter(Boolean);

                if (typeof first === "number") {
                    return splits[first];
                }

                return splits;
            };
        }, {}] }, {}, [1])(1);
});
<|endoftext|>