<commit_before>/* eslint-env node */
const chalk = require('chalk');
let write;

function TimeReporter (opts) {
  this.out = opts.out || process.stdout;
  this.runDuration = 0;
  this.previousDot = true;
  this.opts = opts;

  write = this.out.write.bind(this.out);
  this.failures = [];
  this.longestTest = { runDuration: 0 };
  this.longTests = [];
}

TimeReporter.prototype = {
  writeFailure: function (data) {
    write(chalk.red(`\nTest Failure - ${data.name.trim()}\n`));
    if (data.error && data.error.message) {
      write(chalk.red(data.error.message) + '\n');
      write(chalk.red(data.error.stack) + '\n');
    } else {
      write(chalk.red(`${JSON.stringify(data)}`));
    }
    this.failures.push(data);
  },

  report: function (prefix, data) {
    this.runDuration += data.runDuration;
    let dot = false;
    if (data.skipped) {
      write(chalk.blue(`\nTest Skipped - ${data.name.trim()}`));
    }
    if (data.failed) {
      this.writeFailure(data);
    }
    if (data.passed) {
      if (data.runDuration > this.longestTest.runDuration) {
        this.longestTest = data;
      }
      if (this.opts.sort && !this.done && data.runDuration > 500) {
        this.longTests.push(data);
        dot = true;
        if (!this.previousDot) {
          write('\n');
        }
        write('⌛');
        return;
      }
      const result = `\n${data.runDuration}ms - ${data.name.trim()}`;
      if (data.runDuration > 2000) {
        write(chalk.magenta(result));
      } else if (data.runDuration > 1000) {
        write(chalk.red(result));
      } else if (data.runDuration > 500) {
        write(chalk.yellow(result));
      } else {
        dot = true;
        if (!this.previousDot) {
          write('\n');
        }
        write('.');
      }
    }
    this.previousDot = dot;
  },
  finish: function () {
    this.done = true;
    if (this.opts.sort && this.longTests.length) {
      const sorted = this.longTests.sort((a, b) => a.runDuration < b.runDuration ? -1 : 1);
      sorted.forEach(data => this.report(null, data));
    } else if (this.longestTest.name) {
      write(`\n Longest test - ${this.longestTest.runDuration}ms - ${this.longestTest.name.trim()}\n`);
    }
    write(`\n Tests completed in ${this.runDuration / 1000} seconds \n`);

    if (this.failures.length) {
      this.write('\n Failing tests: \n');
      this.failures.forEach(this.writeFailure);
    }
    write(`\nLEGEND: ${chalk.blue('Skipped')} ${chalk.magenta('Tests > 2 seconds')} ${chalk.red('Tests > 1 second')} ${chalk.yellow('Tests > 0.5 seconds')}\n`);
  }
};

module.exports = TimeReporter;
<commit_msg>I'm bad at code<commit_after>/* eslint-env node */
const chalk = require('chalk');
let write;

function TimeReporter (opts) {
  this.out = opts.out || process.stdout;
  this.runDuration = 0;
  this.previousDot = true;
  this.opts = opts;

  write = this.out.write.bind(this.out);
  this.failures = [];
  this.longestTest = { runDuration: 0 };
  this.longTests = [];
}

TimeReporter.prototype = {
  writeFailure: function (data) {
    write(chalk.red(`\nTest Failure - ${data.name.trim()}\n`));
    if (data.error && data.error.message) {
      write(chalk.red(data.error.message) + '\n');
      write(chalk.red(data.error.stack) + '\n');
    } else {
      write(chalk.red(`${JSON.stringify(data)}`));
    }
    this.failures.push(data);
  },

  report: function (prefix, data) {
    this.runDuration += data.runDuration;
    let dot = false;
    if (data.skipped) {
      write(chalk.blue(`\nTest Skipped - ${data.name.trim()}`));
    }
    if (data.failed) {
      this.writeFailure(data);
    }
    if (data.passed) {
      if (data.runDuration > this.longestTest.runDuration) {
        this.longestTest = data;
      }
      if (this.opts.sort && !this.done && data.runDuration > 500) {
        this.longTests.push(data);
        dot = true;
        if (!this.previousDot) {
          write('\n');
        }
        write('⌛');
        return;
      }
      const result = `\n${data.runDuration}ms - ${data.name.trim()}`;
      if (data.runDuration > 2000) {
        write(chalk.magenta(result));
      } else if (data.runDuration > 1000) {
        write(chalk.red(result));
      } else if (data.runDuration > 500) {
        write(chalk.yellow(result));
      } else {
        dot = true;
        if (!this.previousDot) {
          write('\n');
        }
        write('.');
      }
    }
    this.previousDot = dot;
  },
  finish: function () {
    this.done = true;
    if (this.opts.sort && this.longTests.length) {
      const sorted = this.longTests.sort((a, b) => a.runDuration < b.runDuration ? -1 : 1);
      sorted.forEach(data => this.report(null, data));
    } else if (this.longestTest.name) {
      write(`\n Longest test - ${this.longestTest.runDuration}ms - ${this.longestTest.name.trim()}\n`);
    }
    write(`\n Tests completed in ${this.runDuration / 1000} seconds \n`);

    if (this.failures.length) {
      write('\n Failing tests: \n');
      this.failures.forEach(this.writeFailure);
    }
    write(`\nLEGEND: ${chalk.blue('Skipped')} ${chalk.magenta('Tests > 2 seconds')} ${chalk.red('Tests > 1 second')} ${chalk.yellow('Tests > 0.5 seconds')}\n`);
  }
};

module.exports = TimeReporter;
<|endoftext|>


<commit_before>let express = require('express');
let fs = require('fs');

let app = express();
let images = __dirname;

app.use('/images/:im_name', (req, res, next) => {
  let extensions = ['.png', '.jpg'];
  extensions.forEach((extension) => {
    fs.exists( images + '/images/' + req.params.im_name + extension, (exists) => {
      if(exists) {
        req.url += extension;
        next();
      }
    });
  });
  next();
});

app.use(express.static(images));

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});
<commit_msg>resolved check for files if not answer with not found<commit_after>let express = require('express');
let fs = require('fs');

let app = express();
let images = __dirname;

app.use('/images/:im_name', (req, res, next) => {
  let extensions = ['.png', '.jpg'];
  var exists = false;
  let runs = 1;
  extensions.forEach((extension) => {
    fs.exists( images + '/images/' + req.params.im_name + extension, (exists) => {
      if(exists) {
        req.url += extension;
        next();
      } else if (runs == extensions.length){
        next();
      }
      runs++;
    });
  });
});

app.use(express.static(images));

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});
<|endoftext|>


<commit_before>var exec = require('child_process').exec;
var S = require('string');

var streamTimeout= 10000;

var textos = ["q?","Q?"];
var nasus_quotes = [
"Who let the dogs out? Woof. Woof. Woof.",
"No, I will not fetch the ball.",
"My bite is worse than my bark.",
"The cycle of life and death continues. We will live, they will die.",
"Do not try my patience.",
"Life is part of a cycle. Yours is over.",
"Your soul will be measured.",
"Return to the dust.",
"The cycle of stack and farm continues. We will Q, they will die... Oh, wait..."
];

setTimeout(function(){
	var nasus = exec('tweet stream "nasus" --json');
	showScreen("Reading 'nasus' tweets");
	nasus.stdout.on('data', function(data) {
	    var dados = JSON.parse(data);
	    showScreen("@"+dados.user.screen_name+": "+dados.text);
	    var textoAleatorio = textos[Math.floor(Math.random()*textos.length)];
	    var comando = 'tweet new "@'+dados.user.screen_name+' '+textoAleatorio+'"';
	    var newTweet = exec(comando);
	    showScreen(comando);
	    newTweet.stdout.on('data', function(nasusData) {
	      showScreen(nasusData);
	    });
	    newTweet.stderr.on('data', function(data) {
	      showScreen(data);
	    });
	});
	nasus.on('close', function(code) {
	  showScreen("stream 'nasus': "+code);
	  if(S(code).contains("many requests")){
	    setTimeout(function() {showScreen('Waiting twitter for a calm down...');}, streamTimeout);
	  }
	  process.exit();
	});
	nasus.stderr.on('data', function(data) {
	  showScreen("stream 'nasus': "+data);
          if(S(data).contains("many requests")){
            setTimeout(function() {showScreen('Waiting twitter for a calm down...');}, streamTimeout);
          }
	  process.exit();
	});
}, streamTimeout);

setTimeout(function(){
var reply = exec('tweet stream "@such_nasus" --json');
showScreen("Reading '@such_nasus' tweets");
reply.stdout.on('data', function(data) {
    var dados = JSON.parse(data);
    showScreen("@"+dados.user.screen_name+": "+dados.text);
    var quoteAleatorio = nasus_quotes[Math.floor(Math.random()*nasus_quotes.length)];
    var comando = 'tweet new "@'+dados.user.screen_name+' '+quoteAleatorio+'"';
    var newTweet = exec(comando);
    showScreen(comando);
    newTweet.stdout.on('data', function(nasusData) {
      showScreen(nasusData);
    });
    newTweet.stderr.on('data', function(nasusData) {
      showScreen(nasusData);
    });
});
reply.on('close', function(code) {
  showScreen("stream '@such_nasus': "+code);
  if(S(code).contains("many requests")){
    setTimeout(function() {showScreen('Waiting twitter for a calm down...');}, streamTimeout*3);
  }
  process.exit();
});
reply.stderr.on('data', function(data) {
  showScreen("stream '@such_nasus': "+data);
  if(S(data).contains("many requests")){
     setTimeout(function() {showScreen('Waiting twitter for a calm down...');process.exit();}, streamTimeout*3);
  }

});
}, streamTimeout*2);

function showScreen(text){
  var date = new Date();
  var current_time = date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
  console.log(current_time+"- "+text);
}
<commit_msg>refactor(index): recriando o index<commit_after>var quotes = require('./quotes');
var twitterClient = require('./twitterClient');

twitterClient.stream('nasus,@such_nasus', function(error, tweet){
  if(error)
    return console.error(error);
  console.log(tweet.user.screen_name+':',tweet.text);
  var randomText = random(quotes);
  twitterClient.tweet(`@${tweet.user.screen_name} ${randomText}`, function(error, tweet){
    if(error)
      return console.error(error);
    return console.log('tweeted:',tweet.text);
  });
});

function random(array){
  return array[Math.floor(Math.random()*array.length)];
}
<|endoftext|>


<commit_before>/*!
 * pkg-tree (https://github.com/jonschlinkert/pkg-tree)
 *
 * Copyright (c) 2016, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var fs = require('fs');
var path = require('path');
var yellow = require('ansi-yellow');
var archy = require('archy');
var hasGlob = require('has-glob');
var get = require('get-value');
var define = require('define-property');
var stringify = require('stringify-keys');
var glob = require('glob-object');

function find(dir, cwd) {
  cwd = cwd || dir;
  var pkgPath = path.resolve(dir, 'package.json');
  var pkg = require(pkgPath);
  var deps = pkg.dependencies || {};
  var tree = {};
  define(tree, 'pkg', pkg);

  for (var key in deps) {
    tree[key] = find(path.resolve(cwd, 'node_modules', key), cwd);
  }
  return tree;
}

function buildTree(patterns, options) {
  if (typeof patterns !== 'string' && !Array.isArray(patterns)) {
    options = patterns;
    patterns = null;
  }

  options = options || {};
  var cwd = options.cwd || process.cwd();

  var pkg = require(path.resolve(cwd, 'package.json'));
  var obj = {};
  obj[pkg.name] = find(cwd);

  if (patterns) {
    var filtered = glob(patterns, obj);
    if (!Object.keys(filtered).length) {
      throw new Error('Cannot find a match for: ' + patterns);
    }
    return filtered;
  }
  return obj;
}

function buildNodes(tree, options) {
  options = options || {};
  var nodes = [];
  for (var key in tree) {
    var obj = {};
    var val = tree[key];

    if (options.has && !isMatch(val.pkg, options.has)) {
      continue;
    }

    obj.label = highlight(key, options);
    obj.nodes = buildNodes(val, options);
    nodes.push(obj);
  }
  return nodes;
}

function isMatch(pkg, obj) {
  if (typeof obj.key === 'undefined') {
    return true;
  }

  return true;

  // var val = get(pkg, obj.key);

  // if (get(pkg, obj.key) !== obj.val) {
  //   continue;
  // }
}

function highlight(key, options) {
  options = options || {};
  if (typeof options.highlight === 'function') {
    return options.highlight(key);
  }
  if (typeof options.highlight === 'string') {
    var re = new RegExp(options.highlight);
    return re.test(key) ? yellow(key) : key;
  }
  return key;
}

module.exports = function(patterns, options) {
  var tree = buildTree(patterns, options);
  var nodes = buildNodes(tree, options)[0];
  return archy(nodes);
};

module.exports.json = buildTree;
<commit_msg>reorganize code, add comments<commit_after>/*!
 * module-tree (https://github.com/jonschlinkert/module-tree)
 *
 * Copyright (c) 2016, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

var util = require('util');
var path = require('path');
var utils = require('./utils');

/**
 * Build an object, where dependencies represented properties and
 * keys are module names.
 *
 * ```js
 * {
 *   'union-value': {
 *     'get-value': {}
 *   }
 * }
 * ```
 * @name .buildTree
 * @param {Object} `patterns` Glob pattern to pass to [glob-object][] for filtering packages.
 * @param {Object} `options`
 * @return {Object}
 * @api public
 */

function buildTree(patterns, options) {
  if (typeof patterns !== 'string' && !Array.isArray(patterns)) {
    options = patterns;
    patterns = null;
  }

  options = options || {};
  var cwd = options.cwd || process.cwd();

  var pkg = require(path.resolve(cwd, 'package.json'));
  var obj = {};
  obj[pkg.name] = resolvePkg(cwd);

  if (patterns) {
    var filtered = utils.glob(patterns, obj);
    if (!Object.keys(filtered).length) {
      throw new Error('Cannot find a match for: ' + patterns);
    }
    return filtered;
  }
  return obj;
}

/**
 * Build an object that can be passed to [archy][], where dependencies
 * are represented as `nodes`, and the name of each package is used
 * as the `label`.
 *
 * ```js
 * // results in an object like this
 * { label: 'union-value',
 *   nodes: [ { label: 'get-value', nodes: [] } ] }
 * ```
 * @name .buildNodes
 * @param {Object} `tree`
 * @param {Object} `options`
 * @return {Object}
 * @api public
 */

function buildNodes(tree, options) {
  options = options || {};

  function createNodes(t, opts) {
    var nodes = [];
    for (var key in t) {
      var obj = {};
      var val = t[key];
      var pkg = val.pkg;
      if (opts.version) {
        key += '@' + pkg.version;
      }
      obj.label = color(key, opts);
      obj.nodes = createNodes(val, opts);
      nodes.push(obj);
    }
    return nodes;
  }
  var res = createNodes(tree, options);
  return res[0];
}

function resolvePkg(dir, cwd) {
  cwd = cwd || dir;
  var pkgPath = path.resolve(dir, 'package.json');
  var pkg = require(pkgPath);
  var deps = pkg.dependencies || {};
  var tree = {};
  utils.define(tree, 'pkg', pkg);
  for (var key in deps) {
    tree[key] = resolvePkg(path.resolve(cwd, 'node_modules', key), cwd);
  }
  return tree;
}

function color(key, options) {
  options = options || {};
  if (typeof options.color === false) {
    return key;
  }
  if (typeof options.color === 'function') {
    return options.color(key);
  }
  if (typeof options.color === 'string') {
    var re = new RegExp(options.color);
    return re.test(key) ? utils.yellow(key) : key;
  }
  return utils.yellow(key);
}

/**
 * Build a tree from module dependencies using [archy][].
 *
 * @param {String|Array} `patterns` Glob patterns to pass to [glob-object][]
 * @param {Object} `options`
 * @return {Object}
 * @api public
 */

module.exports = function(patterns, options) {
  var tree = buildTree(patterns, options);
  var nodes = buildNodes(tree, options);
  return utils.archy(nodes);
};

/**
 * Expose `.buildTree`
 */

module.exports.buildTree = buildTree;

/**
 * Expose `.buildNodes`
 */

module.exports.buildNodes = buildNodes;
<|endoftext|>


<commit_before>/*!
 * gulp-csscomb | https://github.com/koistya/gulp-csscomb
 * Copyright (c) Konstantin Tarkus (@koistya). See LICENSE.txt
 */

'use strict';

var Comb = require('csscomb');
var fs = require('fs');
var gutil = require('gulp-util');
var path = require('path');
var through = require('through2');
var PluginError = gutil.PluginError;

// Constants
var PLUGIN_NAME = 'gulp-csscomb';
var SUPPORTED_EXTENSIONS = ['.css', '.sass', '.scss', '.less'];

// Plugin level function (dealing with files)
function Plugin(configPath, options) {

  if (arguments.length == 1 && typeof configPath === 'object') {
    options = configPath;
    configPath = options.configPath;
  } else if (arguments.length == 2 && typeof options === 'boolean') {
    options = { verbose: options }; // for backward compatibility
  }

  options = options || {};
  configPath = configPath || null;

  var verbose = options.verbose || false;
  //var lint = options.lint || false; // TODO: Report about found issues in style sheets

  // Create a stream through which each file will pass
  var stream = through.obj(function(file, enc, cb) {

    if (file.isNull()) {
      // Do nothing
    } else if (file.isStream()) {
      this.emit('error', new PluginError(PLUGIN_NAME, 'Streams are not supported!'));
      return cb();
    } else if (file.isBuffer() && SUPPORTED_EXTENSIONS.indexOf(path.extname(file.path)) !== -1) {

      if (verbose) {
        gutil.log(PLUGIN_NAME, 'Processing ' + gutil.colors.magenta(file.path));
      }

      if (configPath && !fs.existsSync(configPath)) {
        this.emit('error', new PluginError(PLUGIN_NAME, 'Configuration file not found: ' + gutil.colors.magenta(configPath)));
        return cb();
      }

      configPath = Comb.getCustomConfigPath(configPath || path.join(path.dirname(file.path), '.csscomb.json'));
      var config = Comb.getCustomConfig(configPath);

      if (verbose) {
        gutil.log(PLUGIN_NAME, 'Using configuration file ' + gutil.colors.magenta(configPath));
      }

      var comb = new Comb(config || 'csscomb');
      var syntax = file.path.split('.').pop();

      try {
        var output = comb.processString(
          file.contents.toString('utf8'), {
            syntax: options.syntax || syntax,
            filename: file.path
          });
        file.contents = new Buffer(output);
      } catch (err) {
        this.emit('error', new PluginError(PLUGIN_NAME, file.path + '\n' + err));
      }
    }

    // make sure the file goes through the next gulp plugin
    this.push(file);
    // tell the stream engine that we are done with this file
    return cb();
  });

  // Return the file stream
  return stream;
}

// Export the plugin main function
module.exports = Plugin;
<commit_msg>Use options.syntax w/o file path manipulation<commit_after>/*!
 * gulp-csscomb | https://github.com/koistya/gulp-csscomb
 * Copyright (c) Konstantin Tarkus (@koistya). See LICENSE.txt
 */

'use strict';

var Comb = require('csscomb');
var fs = require('fs');
var gutil = require('gulp-util');
var path = require('path');
var through = require('through2');
var PluginError = gutil.PluginError;

// Constants
var PLUGIN_NAME = 'gulp-csscomb';
var SUPPORTED_EXTENSIONS = ['.css', '.sass', '.scss', '.less'];

// Plugin level function (dealing with files)
function Plugin(configPath, options) {

  if (arguments.length == 1 && typeof configPath === 'object') {
    options = configPath;
    configPath = options.configPath;
  } else if (arguments.length == 2 && typeof options === 'boolean') {
    options = { verbose: options }; // for backward compatibility
  }

  options = options || {};
  configPath = configPath || null;

  var verbose = options.verbose || false;
  //var lint = options.lint || false; // TODO: Report about found issues in style sheets

  // Create a stream through which each file will pass
  var stream = through.obj(function(file, enc, cb) {

    if (file.isNull()) {
      // Do nothing
    } else if (file.isStream()) {
      this.emit('error', new PluginError(PLUGIN_NAME, 'Streams are not supported!'));
      return cb();
    } else if (file.isBuffer() && SUPPORTED_EXTENSIONS.indexOf(path.extname(file.path)) !== -1) {

      if (verbose) {
        gutil.log(PLUGIN_NAME, 'Processing ' + gutil.colors.magenta(file.path));
      }

      if (configPath && !fs.existsSync(configPath)) {
        this.emit('error', new PluginError(PLUGIN_NAME, 'Configuration file not found: ' + gutil.colors.magenta(configPath)));
        return cb();
      }

      configPath = Comb.getCustomConfigPath(configPath || path.join(path.dirname(file.path), '.csscomb.json'));
      var config = Comb.getCustomConfig(configPath);

      if (verbose) {
        gutil.log(PLUGIN_NAME, 'Using configuration file ' + gutil.colors.magenta(configPath));
      }

      var comb = new Comb(config || 'csscomb');
      var syntax = options.syntax || file.path.split('.').pop();

      try {
        var output = comb.processString(
          file.contents.toString('utf8'), {
            syntax: syntax,
            filename: file.path
          });
        file.contents = new Buffer(output);
      } catch (err) {
        this.emit('error', new PluginError(PLUGIN_NAME, file.path + '\n' + err));
      }
    }

    // make sure the file goes through the next gulp plugin
    this.push(file);
    // tell the stream engine that we are done with this file
    return cb();
  });

  // Return the file stream
  return stream;
}

// Export the plugin main function
module.exports = Plugin;
<|endoftext|>


<commit_before>var cwise = require("cwise");

var assign_ops = {
  add:  "+",
  sub:  "-",
  mul:  "*",
  div:  "/",
  mod:  "%",
  band: "&",
  bor:  "|",
  bxor: "^",
  lshift: "<<",
  rshift: ">>",
  rrshift: ">>>"
};

(function(){
  for(var id in assign_ops) {
    var op = assign_ops[id]
    exports[id] = cwise(Function("a","b","c","a=b"+op+"c"))
    exports[id+"eq"] = cwise(Function("a","b","a"+op+"=b"))
    exports[id+"s"] = cwise(Function("a","b","s","a=b"+op+"s"), {scalars:[2]})
    exports[id+"seq"] = cwise(Function("a","s","a"+op+"=s"), {scalars:[1]})
  }
})()

var unary_ops = {
  not: "!",
  bnot: "~",
  neg: "-",
  recip: "1.0/"
};

(function(){
  for(var id in unary_ops) {
    var op = unary_ops[id]
    exports[id] = cwise(Function("a","b","a="+op+"b"))
    exports[id+"eq"] = cwise(Function("a","a="+op+"a"))
  }
})()

var binary_ops = {
  and: "&&",
  or: "||",
  eq: "===",
  neq: "!==",
  lt: "<",
  gt: ">",
  leq: "<=",
  geq: ">="
};

(function() {
  for(var id in binary_ops) {
    var op = binary_ops[id]
    exports[id] = cwise(Function("a", "b", "c", "a=b"+op+"c"))
    exports[id+"s"] = cwise(Function("a", "b", "s", "a=b"+op+"s"), {scalars:[2]})
    exports[id+"eq"] = cwise(Function("a", "b", "a=a"+op+"b"))
    exports[id+"seq"] = cwise(Function("a", "s", "a=a"+op+"s"), {scalars:[1]})
  }
})()

var math_unary = [
  "abs",
  "acos",
  "asin",
  "atan",
  "ceil",
  "cos",
  "exp",
  "floor",
  "log",
  "round",
  "sin",
  "sqrt",
  "tan"
];

(function() {
  for(var i=0; i<math_unary.length; ++i) {
    var f = math_unary[i]
    exports[f] = cwise(Function("a", "b", "a=func(b)"), {
      pre: Function("var func=Math."+f)
    })
    exports[f+"eq"] = cwise(Function("a", "a=func(a)"), {
      pre: Function("var func=Math."+f)
    })
  }
})()

var math_comm = [
  "max",
  "min"
];
(function(){
  for(var i=0; i<math_comm.length; ++i) {
    var f= math_comm[i]
    exports[f] = cwise(Function("a", "b", "c", "a=func(b,c)"), {
      pre: Function("var func=Math."+f)
    })
    exports[f+"s"] = cwise(Function("a", "b", "c", "a=func(b,c)"), {
      pre: Function("var func=Math."+f),
      scalars:[2]
    })
    exports[f+"eq"] = cwise(Function("a", "b", "a=func(a,b)"), {
      pre: Function("var func=Math."+f)
    })
    exports[f+"seq"] = cwise(Function("a", "b", "a=func(a,b)"), {
      pre: Function("var func=Math."+f),
      scalars: [1]
    })
  }
})()

var math_noncomm = [
  "atan2",
  "pow"
];

(function(){
  for(var i=0; i<math_noncomm.length; ++i) {
    var f= math_noncomm[i]
    exports[f] = cwise(Function("a", "b", "c", "a=func(b,c)"), {
      pre: Function("var func=Math."+f)
    })
    exports[f+"s"] = cwise(Function("a", "b", "c", "a=func(b,c)"), {
      pre: Function("var func=Math."+f),
      scalars:[2]
    })
    exports[f+"eq"] = cwise(Function("a", "b", "a=func(a,b)"), {
      pre: Function("var func=Math."+f)
    })
    exports[f+"seq"] = cwise(Function("a", "b", "a=func(a,b)"), {
      pre: Function("var func=Math."+f),
      scalars: [1]
    })
    exports[f+"op"] = cwise(Function("a", "b", "c", "a=func(c,b)"), {
      pre: Function("var func=Math."+f)
    })
    exports[f+"sop"] = cwise(Function("a", "b", "c", "a=func(c,b)"), {
      pre: Function("var func=Math."+f),
      scalars:[2]
    })
    exports[f+"opeq"] = cwise(Function("a", "b", "a=func(b,a)"), {
      pre: Function("var func=Math."+f)
    })
    exports[f+"sopeq"] = cwise(Function("a", "b", "a=func(b,a)"), {
      pre: Function("var func=Math."+f),
      scalars: [1]
    })
  }
})()

exports.any = cwise(function(a) { if(a) return true }, {
  post: function() { return false }
})

exports.all = cwise(function(a) { if(!a) return false }, {
  post: function() { return true }
})

exports.sum = cwise(Function("a", "s+=a"), {
  pre: Function("var s=0"),
  post: Function("return s")
})

exports.prod = cwise(Function("a", "s*=a"), {
  pre: Function("var s=1"),
  post: Function("return s")
})

exports.norm2squared = cwise(Function("a", "s+=a*a"), {
  pre: Function("var s=0"),
  post: Function("return s")
})

exports.norm2 = function(a) {
  return Math.sqrt(exports.norm2squared(a))
}

exports.norminf = cwise(Function("a", "if(a<0){if(-a<s){s=-a}}else{if(a>s){s=a}}"), {
  pre: Function("var s=0"),
  post: Function("return s")
})

exports.norm1 = cwise(Function("a", "if(a<0){s-=a}else{s+=a}"), {
  pre: Function("var s=0"),
  post: Function("return s")
})

exports.sup = cwise(Function("a", "if(a>s)s=a"), {
  pre: Function("var s=Number.NEGATIVE_INFINITY"),
  post: Function("return s")
})

exports.inf = cwise(Function("a", "if(a<s)s=a"), {
  pre: Function("var s=Number.POSITIVE_INFINITY"),
  post: Function("return s")
})

exports.argmin = cwise(Function("a", "i", "if(a<s){s=a;for(var k=0;k<i.length;++k){j[k]=i[k];}}"), {
  index: 1,
  pre: Function("a", "i", "var s=Number.NEGATIVE_INFINITY,j=i.slice(0)"),
  post: Function("return j")
})

exports.argmax = cwise(Function("a", "i", "if(a>s){s=a;for(var k=0;k<i.length;++k){j[k]=i[k];}}"), {
  index: 1,
  pre: Function("a", "i", "var s=Number.NEGATIVE_INFINITY,j=i.slice(0)"),
  post: Function("return j")
})

exports.random = cwise(Function("a", "a=func()"), {
  pre: Function("var func=Math.random")
})

exports.assign = cwise(function(a,b) {a=b})
exports.assigns = cwise(function(a,b) {a=b}, {scalars:[1]})
<commit_msg>switched to use new cwise api<commit_after>var cwise = require("cwise");

var assign_ops = {
  add:  "+",
  sub:  "-",
  mul:  "*",
  div:  "/",
  mod:  "%",
  band: "&",
  bor:  "|",
  bxor: "^",
  lshift: "<<",
  rshift: ">>",
  rrshift: ">>>"
};

(function(){
  for(var id in assign_ops) {
    var op = assign_ops[id]
    exports[id] = cwise("array","array","array").body(Function("a","b","c","a=b"+op+"c")).compile()
    exports[id+"eq"] = cwise("array","array").body(Function("a","b","a"+op+"=b")).compile()
    exports[id+"s"] = cwise("array", "scalar").body(Function("a","b","s","a=b"+op+"s")).compile()
    exports[id+"seq"] = cwise("array","scalar").body(Function("a","s","a"+op+"=s")).compile()
  }
})()

var unary_ops = {
  not: "!",
  bnot: "~",
  neg: "-",
  recip: "1.0/"
};

(function(){
  for(var id in unary_ops) {
    var op = unary_ops[id]
    exports[id] = cwise("array", "array").body(Function("a","b","a="+op+"b")).compile()
    exports[id+"eq"] = cwise("array").body(Function("a","a="+op+"a")).compile()
  }
})()

var binary_ops = {
  and: "&&",
  or: "||",
  eq: "===",
  neq: "!==",
  lt: "<",
  gt: ">",
  leq: "<=",
  geq: ">="
};

(function() {
  for(var id in binary_ops) {
    var op = binary_ops[id]
    exports[id] = cwise("array","array","array").body(Function("a", "b", "c", "a=b"+op+"c")).compile()
    exports[id+"s"] = cwise("array","array","scalar").body(Function("a", "b", "s", "a=b"+op+"s")).compile()
    exports[id+"eq"] = cwise("array", "array").body(Function("a", "b", "a=a"+op+"b")).compile()
    exports[id+"seq"] = cwise("array", "scalar").body(Function("a", "s", "a=a"+op+"s")).compile()
  }
})()

var math_unary = [
  "abs",
  "acos",
  "asin",
  "atan",
  "ceil",
  "cos",
  "exp",
  "floor",
  "log",
  "round",
  "sin",
  "sqrt",
  "tan"
];

(function() {
  for(var i=0; i<math_unary.length; ++i) {
    var f = math_unary[i]
    exports[f] = cwise("array", "array")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b) {
                    a = this.func(b)
                  })
                  .compile()
    exports[f+"eq"] = cwise("array")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a) {
                    a = this.func(a)
                  })
                  .compile()
  }
})()

var math_comm = [
  "max",
  "min"
];
(function(){
  for(var i=0; i<math_comm.length; ++i) {
    var f= math_comm[i]

    exports[f] = cwise("array", "array", "array")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b,c) {
                    a = this.func(b,c)
                  })
                  .compile()
    exports[f+"s"] = cwise("array", "array", "scalar")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b,c) {
                    a = this.func(b,c)
                  })
                  .compile()
    exports[f+"eq"] = cwise("array", "array")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b) {
                    a = this.func(a,b)
                  })
                  .compile()
    exports[f+"seq"] = cwise("array", "scalar")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b) {
                    a = this.func(a,b)
                  })
                  .compile()
  }
})()

var math_noncomm = [
  "atan2",
  "pow"
];

(function(){
  for(var i=0; i<math_noncomm.length; ++i) {
    var f= math_noncomm[i]
    exports[f] = cwise("array", "array", "array")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b,c) {
                    a = this.func(b,c)
                  })
                  .compile()
    exports[f+"s"] = cwise("array", "array", "scalar")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b,c) {
                    a = this.func(b,c)
                  })
                  .compile()
    exports[f+"eq"] = cwise("array", "array")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b) {
                    a = this.func(a,b)
                  })
                  .compile()
    exports[f+"seq"] = cwise("array", "scalar")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b) {
                    a = this.func(a,b)
                  })
                  .compile()
    exports[f+"op"] = cwise("array", "array", "array")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b,c) {
                    a = this.func(c,b)
                  })
                  .compile()
    exports[f+"ops"] = cwise("array", "array", "scalar")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b,c) {
                    a = this.func(c,b)
                  })
                  .compile()
    exports[f+"opeq"] = cwise("array", "array")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b) {
                    a = this.func(b,a)
                  })
                  .compile()
    exports[f+"opseq"] = cwise("array", "scalar")
                  .begin(Function("this.func=Math."+f))
                  .body(function(a,b) {
                    a = this.func(b,a)
                  })
                  .compile()
  }
})()

exports.any = cwise("array")
  .body(function(a) {
    if(a) {
      return true
    }
  })
  .end(function() {
    return false
  })
  .compile()

exports.all = cwise("array")
  .body(function(a) {
    if(!a) {
      return false
    }
  })
  .end(function() {
    return true
  })
  .compile()

exports.sum = cwise("array")
  .begin(function() {
    this.sum = 0
  })
  .body(function(a) {
    this.sum += a
  })
  .end(function() {
    return this.sum
  })
  .compile()

exports.prod = cwise("array")
  .begin(function() {
    this.prod = 1
  })
  .body(function(a) {
    this.prod *= a
  })
  .end(function() {
    return this.prod
  })
  .compile()

exports.norm2squared = cwise("array")
  .begin(function() {
    this.sum = 0
  })
  .body(function(a) {
    this.sum += a*a
  })
  .end(function() {
    return this.sum
  })
  .compile()

exports.norm2 = cwise("array")
  .begin(function() {
    this.sum = 0
  })
  .body(function(a) {
    this.sum += a*a
  })
  .end(function() {
    return Math.sqrt(this.sum)
  })
  .compile()

exports.norminf = cwise("array")
  .begin(function() {
    this.n = 0
  })
  .body(function(a) {
    if(a<0){
      if(-a<this.n){
        this.n=-a
      }
    } else if(a>this.n){
      s=a
    }
  })
  .end(function() {
    return this.n
  })
  .compile()

exports.norm1 = cwise("array")
  .begin(function() {
    this.sum = 0
  })
  .body(function(a) {
    this.sum += a < 0 ? -a : a
  })
  .end(function() {
    return this.sum
  })
  .compile()

exports.sup = cwise("array")
  .begin(function() {
    this.hi = Number.NEGATIVE_INFINITY
  })
  .body(function(a) {
    if(a > this.hi) {
      this.hi = a
    }
  })
  .end(function() {
    return this.hi
  })
  .compile()

exports.inf = cwise("array")
  .begin(function() {
    this.lo = Number.POSITIVE_INFINITY
  })
  .body(function(a) {
    if(a < this.lo) {
      this.lo = a
    }
  })
  .end(function() {
    return this.lo
  })
  .compile()

exports.argmin = cwise("index", "array")
  .begin(function(i) {
    this.min_v = Number.POSITIVE_INFINITY
    this.min_i = i.slice(0)
  })
  .body(function(i, a) {
    if(a < this.min_v) {
      this.min_v = a
      for(var k=0; k<i.length; ++k) {
        this.min_i[k] = i[k]
      }
    }
  })
  .end(function() {
    return this.min_i
  })
  .compile()

exports.argmax = cwise("index", "array")
  .begin(function(i) {
    this.max_v = Number.NEGATIVE_INFINITY
    this.max_i = i.slice(0)
  })
  .body(function(i, a) {
    if(a > this.max_v) {
      this.max_v = a
      for(var k=0; k<i.length; ++k) {
        this.max_i[k] = i[k]
      }
    }
  })
  .end(function() {
    return this.max_i
  })
  .compile()

exports.random = cwise("array")
  .begin(function() {
    this.rnd = Math.random
  })
  .body(function(a) {
    a = this.rnd()
  })
  .compile()

exports.assign = cwise("array", "array")
  .body(function(a,b) {
    a = b
  })
  .compile()

exports.assigns = cwise("array", "scalar")
  .body(function(a,b) {
    a = b
  })
  .compile()
<|endoftext|>


<commit_before>'use strict';

const bundleTypes = {
  UMD_DEV: 'UMD_DEV',
  UMD_PROD: 'UMD_PROD',
  UMD_PROFILING: 'UMD_PROFILING',
  NODE_DEV: 'NODE_DEV',
  NODE_PROD: 'NODE_PROD',
  NODE_PROFILING: 'NODE_PROFILING',
  FB_WWW_DEV: 'FB_WWW_DEV',
  FB_WWW_PROD: 'FB_WWW_PROD',
  FB_WWW_PROFILING: 'FB_WWW_PROFILING',
  RN_OSS_DEV: 'RN_OSS_DEV',
  RN_OSS_PROD: 'RN_OSS_PROD',
  RN_OSS_PROFILING: 'RN_OSS_PROFILING',
  RN_FB_DEV: 'RN_FB_DEV',
  RN_FB_PROD: 'RN_FB_PROD',
  RN_FB_PROFILING: 'RN_FB_PROFILING',
};

const UMD_DEV = bundleTypes.UMD_DEV;
const UMD_PROD = bundleTypes.UMD_PROD;
const UMD_PROFILING = bundleTypes.UMD_PROFILING;
const NODE_DEV = bundleTypes.NODE_DEV;
const NODE_PROD = bundleTypes.NODE_PROD;
const NODE_PROFILING = bundleTypes.NODE_PROFILING;
const FB_WWW_DEV = bundleTypes.FB_WWW_DEV;
const FB_WWW_PROD = bundleTypes.FB_WWW_PROD;
const FB_WWW_PROFILING = bundleTypes.FB_WWW_PROFILING;
const RN_OSS_DEV = bundleTypes.RN_OSS_DEV;
const RN_OSS_PROD = bundleTypes.RN_OSS_PROD;
const RN_OSS_PROFILING = bundleTypes.RN_OSS_PROFILING;
const RN_FB_DEV = bundleTypes.RN_FB_DEV;
const RN_FB_PROD = bundleTypes.RN_FB_PROD;
const RN_FB_PROFILING = bundleTypes.RN_FB_PROFILING;

const moduleTypes = {
  ISOMORPHIC: 'ISOMORPHIC',
  RENDERER: 'RENDERER',
  RENDERER_UTILS: 'RENDERER_UTILS',
  RECONCILER: 'RECONCILER',
  NON_FIBER_RENDERER: 'NON_FIBER_RENDERER',
};

// React
const ISOMORPHIC = moduleTypes.ISOMORPHIC;
// Individual renderers. They bundle the reconciler. (e.g. ReactDOM)
const RENDERER = moduleTypes.RENDERER;
// Helper packages that access specific renderer's internals. (e.g. TestUtils)
const RENDERER_UTILS = moduleTypes.RENDERER_UTILS;
// Standalone reconciler for third-party renderers.
const RECONCILER = moduleTypes.RECONCILER;
// Non-Fiber implementations like SSR and Shallow renderers.
const NON_FIBER_RENDERER = moduleTypes.NON_FIBER_RENDERER;

const bundles = [
  /******* Isomorphic *******/
  {
    bundleTypes: [
      UMD_DEV,
      UMD_PROD,
      UMD_PROFILING,
      NODE_DEV,
      NODE_PROD,
      FB_WWW_DEV,
      FB_WWW_PROD,
      FB_WWW_PROFILING,
    ],
    moduleType: ISOMORPHIC,
    entry: 'react',
    global: 'React',
    externals: [],
  },

  /******* React DOM *******/
  {
    bundleTypes: [
      UMD_DEV,
      UMD_PROD,
      UMD_PROFILING,
      NODE_DEV,
      NODE_PROD,
      NODE_PROFILING,
      FB_WWW_DEV,
      FB_WWW_PROD,
      FB_WWW_PROFILING,
    ],
    moduleType: RENDERER,
    entry: 'react-dom',
    global: 'ReactDOM',
    externals: ['react'],
  },

  //******* Test Utils *******/
  {
    moduleType: RENDERER_UTILS,
    bundleTypes: [FB_WWW_DEV, NODE_DEV, NODE_PROD, UMD_DEV, UMD_PROD],
    entry: 'react-dom/test-utils',
    global: 'ReactTestUtils',
    externals: ['react', 'react-dom'],
  },

  /* React DOM internals required for react-native-web (e.g., to shim native events from react-dom) */
  {
    bundleTypes: [
      UMD_DEV,
      UMD_PROD,
      NODE_DEV,
      NODE_PROD,
      FB_WWW_DEV,
      FB_WWW_PROD,
    ],
    moduleType: RENDERER_UTILS,
    entry: 'react-dom/unstable-native-dependencies',
    global: 'ReactDOMUnstableNativeDependencies',
    externals: ['react', 'react-dom'],
  },

  /******* React DOM Server *******/
  {
    bundleTypes: [
      UMD_DEV,
      UMD_PROD,
      NODE_DEV,
      NODE_PROD,
      FB_WWW_DEV,
      FB_WWW_PROD,
    ],
    moduleType: NON_FIBER_RENDERER,
    entry: 'react-dom/server.browser',
    global: 'ReactDOMServer',
    externals: ['react'],
  },

  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: NON_FIBER_RENDERER,
    entry: 'react-dom/server.node',
    externals: ['react', 'stream'],
  },

  /******* React ART *******/
  {
    bundleTypes: [
      UMD_DEV,
      UMD_PROD,
      NODE_DEV,
      NODE_PROD,
      FB_WWW_DEV,
      FB_WWW_PROD,
    ],
    moduleType: RENDERER,
    entry: 'react-art',
    global: 'ReactART',
    externals: ['react'],
    babel: opts =>
      Object.assign({}, opts, {
        // Include JSX
        presets: opts.presets.concat([require.resolve('babel-preset-react')]),
      }),
  },

  /******* React Native *******/
  {
    bundleTypes: [RN_FB_DEV, RN_FB_PROD, RN_FB_PROFILING],
    moduleType: RENDERER,
    entry: 'react-native-renderer',
    global: 'ReactNativeRenderer',
    externals: [
      'ExceptionsManager',
      'InitializeCore',
      'Platform',
      'RCTEventEmitter',
      'TextInputState',
      'UIManager',
      'deepDiffer',
      'deepFreezeAndThrowOnMutationInDev',
      'flattenStyle',
      'ReactNativeViewConfigRegistry',
    ],
  },

  {
    bundleTypes: [RN_OSS_DEV, RN_OSS_PROD, RN_OSS_PROFILING],
    moduleType: RENDERER,
    entry: 'react-native-renderer',
    global: 'ReactNativeRenderer',
    externals: [
      'ExceptionsManager',
      'InitializeCore',
      'Platform',
      'RCTEventEmitter',
      'TextInputState',
      'UIManager',
      'deepDiffer',
      'deepFreezeAndThrowOnMutationInDev',
      'flattenStyle',
      'ReactNativeViewConfigRegistry',
    ],
  },

  /******* React Native Fabric *******/
  {
    bundleTypes: [RN_FB_DEV, RN_FB_PROD, RN_FB_PROFILING],
    moduleType: RENDERER,
    entry: 'react-native-renderer/fabric',
    global: 'ReactFabric',
    externals: [
      'ExceptionsManager',
      'InitializeCore',
      'Platform',
      'RCTEventEmitter',
      'TextInputState',
      'UIManager',
      'FabricUIManager',
      'deepDiffer',
      'deepFreezeAndThrowOnMutationInDev',
      'flattenStyle',
      'ReactNativeViewConfigRegistry',
    ],
  },

  {
    bundleTypes: [RN_OSS_DEV, RN_OSS_PROD, RN_OSS_PROFILING],
    moduleType: RENDERER,
    entry: 'react-native-renderer/fabric',
    global: 'ReactFabric',
    externals: [
      'ExceptionsManager',
      'InitializeCore',
      'Platform',
      'RCTEventEmitter',
      'TextInputState',
      'UIManager',
      'FabricUIManager',
      'deepDiffer',
      'deepFreezeAndThrowOnMutationInDev',
      'flattenStyle',
      'ReactNativeViewConfigRegistry',
    ],
  },

  /******* React Test Renderer *******/
  {
    bundleTypes: [FB_WWW_DEV, NODE_DEV, NODE_PROD, UMD_DEV, UMD_PROD],
    moduleType: RENDERER,
    entry: 'react-test-renderer',
    global: 'ReactTestRenderer',
    externals: ['react'],
  },

  {
    bundleTypes: [FB_WWW_DEV, NODE_DEV, NODE_PROD, UMD_DEV, UMD_PROD],
    moduleType: NON_FIBER_RENDERER,
    entry: 'react-test-renderer/shallow',
    global: 'ReactShallowRenderer',
    externals: ['react'],
  },

  /******* React Noop Renderer (used for tests) *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: RENDERER,
    entry: 'react-noop-renderer',
    global: 'ReactNoopRenderer',
    externals: ['react', 'expect'],
    // React Noop uses generators. However GCC currently
    // breaks when we attempt to use them in the output.
    // So we precompile them with regenerator, and include
    // it as a runtime dependency of React Noop. In practice
    // this isn't an issue because React Noop is only used
    // in our tests. We wouldn't want to do this for any
    // public package though.
    babel: opts =>
      Object.assign({}, opts, {
        plugins: opts.plugins.concat([
          require.resolve('babel-plugin-transform-regenerator'),
        ]),
      }),
  },

  /******* React Noop Persistent Renderer (used for tests) *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: RENDERER,
    entry: 'react-noop-renderer/persistent',
    global: 'ReactNoopRendererPersistent',
    externals: ['react', 'expect'],
    // React Noop uses generators. However GCC currently
    // breaks when we attempt to use them in the output.
    // So we precompile them with regenerator, and include
    // it as a runtime dependency of React Noop. In practice
    // this isn't an issue because React Noop is only used
    // in our tests. We wouldn't want to do this for any
    // public package though.
    babel: opts =>
      Object.assign({}, opts, {
        plugins: opts.plugins.concat([
          require.resolve('babel-plugin-transform-regenerator'),
        ]),
      }),
  },

  /******* React Reconciler *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: RECONCILER,
    entry: 'react-reconciler',
    global: 'ReactReconciler',
    externals: ['react'],
  },

  /******* React Persistent Reconciler *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: RECONCILER,
    entry: 'react-reconciler/persistent',
    global: 'ReactPersistentReconciler',
    externals: ['react'],
  },

  /******* Reflection *******/
  {
    moduleType: RENDERER_UTILS,
    bundleTypes: [NODE_DEV, NODE_PROD],
    entry: 'react-reconciler/reflection',
    global: 'ReactFiberTreeReflection',
    externals: [],
  },

  /******* React Is *******/
  {
    bundleTypes: [
      NODE_DEV,
      NODE_PROD,
      FB_WWW_DEV,
      FB_WWW_PROD,
      UMD_DEV,
      UMD_PROD,
    ],
    moduleType: ISOMORPHIC,
    entry: 'react-is',
    global: 'ReactIs',
    externals: [],
  },

  /******* React Debug Tools *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: ISOMORPHIC,
    entry: 'react-debug-tools',
    global: 'ReactDebugTools',
    externals: [],
  },

  /******* React Cache (experimental) *******/
  {
    bundleTypes: [
      FB_WWW_DEV,
      FB_WWW_PROD,
      NODE_DEV,
      NODE_PROD,
      UMD_DEV,
      UMD_PROD,
    ],
    moduleType: ISOMORPHIC,
    entry: 'react-cache',
    global: 'ReactCache',
    externals: ['react', 'scheduler'],
  },

  /******* createComponentWithSubscriptions (experimental) *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: ISOMORPHIC,
    entry: 'create-subscription',
    global: 'createSubscription',
    externals: ['react'],
  },

  /******* React Scheduler (experimental) *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD, FB_WWW_DEV, FB_WWW_PROD],
    moduleType: ISOMORPHIC,
    entry: 'scheduler',
    global: 'Scheduler',
    externals: [],
  },

  /******* Jest React (experimental) *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD, FB_WWW_DEV, FB_WWW_PROD],
    moduleType: ISOMORPHIC,
    entry: 'jest-react',
    global: 'JestReact',
    externals: ['jest-diff'],
  },

  /******* ESLint Plugin for Hooks (proposal) *******/
  {
    // TODO: it's awkward to create a bundle for this
    // but if we don't, the package won't get copied.
    // We also can't create just DEV bundle because
    // it contains a NODE_ENV check inside.
    // We should probably tweak our build process
    // to allow "raw" packages that don't get bundled.
    bundleTypes: [NODE_DEV, NODE_PROD, FB_WWW_DEV],
    moduleType: ISOMORPHIC,
    entry: 'eslint-plugin-react-hooks',
    externals: [],
  },

  {
    bundleTypes: [
      FB_WWW_DEV,
      FB_WWW_PROD,
      FB_WWW_PROFILING,
      NODE_DEV,
      NODE_PROD,
      NODE_PROFILING,
    ],
    moduleType: ISOMORPHIC,
    entry: 'scheduler/tracing',
    global: 'SchedulerTracing',
    externals: [],
  },
];

// Based on deep-freeze by substack (public domain)
function deepFreeze(o) {
  Object.freeze(o);
  Object.getOwnPropertyNames(o).forEach(function(prop) {
    if (
      o[prop] !== null &&
      (typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
      !Object.isFrozen(o[prop])
    ) {
      deepFreeze(o[prop]);
    }
  });
  return o;
}

// Don't accidentally mutate config as part of the build
deepFreeze(bundles);

module.exports = {
  bundleTypes,
  moduleTypes,
  bundles,
};
<commit_msg>Add global to ESLint plugin bundle config<commit_after>'use strict';

const bundleTypes = {
  UMD_DEV: 'UMD_DEV',
  UMD_PROD: 'UMD_PROD',
  UMD_PROFILING: 'UMD_PROFILING',
  NODE_DEV: 'NODE_DEV',
  NODE_PROD: 'NODE_PROD',
  NODE_PROFILING: 'NODE_PROFILING',
  FB_WWW_DEV: 'FB_WWW_DEV',
  FB_WWW_PROD: 'FB_WWW_PROD',
  FB_WWW_PROFILING: 'FB_WWW_PROFILING',
  RN_OSS_DEV: 'RN_OSS_DEV',
  RN_OSS_PROD: 'RN_OSS_PROD',
  RN_OSS_PROFILING: 'RN_OSS_PROFILING',
  RN_FB_DEV: 'RN_FB_DEV',
  RN_FB_PROD: 'RN_FB_PROD',
  RN_FB_PROFILING: 'RN_FB_PROFILING',
};

const UMD_DEV = bundleTypes.UMD_DEV;
const UMD_PROD = bundleTypes.UMD_PROD;
const UMD_PROFILING = bundleTypes.UMD_PROFILING;
const NODE_DEV = bundleTypes.NODE_DEV;
const NODE_PROD = bundleTypes.NODE_PROD;
const NODE_PROFILING = bundleTypes.NODE_PROFILING;
const FB_WWW_DEV = bundleTypes.FB_WWW_DEV;
const FB_WWW_PROD = bundleTypes.FB_WWW_PROD;
const FB_WWW_PROFILING = bundleTypes.FB_WWW_PROFILING;
const RN_OSS_DEV = bundleTypes.RN_OSS_DEV;
const RN_OSS_PROD = bundleTypes.RN_OSS_PROD;
const RN_OSS_PROFILING = bundleTypes.RN_OSS_PROFILING;
const RN_FB_DEV = bundleTypes.RN_FB_DEV;
const RN_FB_PROD = bundleTypes.RN_FB_PROD;
const RN_FB_PROFILING = bundleTypes.RN_FB_PROFILING;

const moduleTypes = {
  ISOMORPHIC: 'ISOMORPHIC',
  RENDERER: 'RENDERER',
  RENDERER_UTILS: 'RENDERER_UTILS',
  RECONCILER: 'RECONCILER',
  NON_FIBER_RENDERER: 'NON_FIBER_RENDERER',
};

// React
const ISOMORPHIC = moduleTypes.ISOMORPHIC;
// Individual renderers. They bundle the reconciler. (e.g. ReactDOM)
const RENDERER = moduleTypes.RENDERER;
// Helper packages that access specific renderer's internals. (e.g. TestUtils)
const RENDERER_UTILS = moduleTypes.RENDERER_UTILS;
// Standalone reconciler for third-party renderers.
const RECONCILER = moduleTypes.RECONCILER;
// Non-Fiber implementations like SSR and Shallow renderers.
const NON_FIBER_RENDERER = moduleTypes.NON_FIBER_RENDERER;

const bundles = [
  /******* Isomorphic *******/
  {
    bundleTypes: [
      UMD_DEV,
      UMD_PROD,
      UMD_PROFILING,
      NODE_DEV,
      NODE_PROD,
      FB_WWW_DEV,
      FB_WWW_PROD,
      FB_WWW_PROFILING,
    ],
    moduleType: ISOMORPHIC,
    entry: 'react',
    global: 'React',
    externals: [],
  },

  /******* React DOM *******/
  {
    bundleTypes: [
      UMD_DEV,
      UMD_PROD,
      UMD_PROFILING,
      NODE_DEV,
      NODE_PROD,
      NODE_PROFILING,
      FB_WWW_DEV,
      FB_WWW_PROD,
      FB_WWW_PROFILING,
    ],
    moduleType: RENDERER,
    entry: 'react-dom',
    global: 'ReactDOM',
    externals: ['react'],
  },

  //******* Test Utils *******/
  {
    moduleType: RENDERER_UTILS,
    bundleTypes: [FB_WWW_DEV, NODE_DEV, NODE_PROD, UMD_DEV, UMD_PROD],
    entry: 'react-dom/test-utils',
    global: 'ReactTestUtils',
    externals: ['react', 'react-dom'],
  },

  /* React DOM internals required for react-native-web (e.g., to shim native events from react-dom) */
  {
    bundleTypes: [
      UMD_DEV,
      UMD_PROD,
      NODE_DEV,
      NODE_PROD,
      FB_WWW_DEV,
      FB_WWW_PROD,
    ],
    moduleType: RENDERER_UTILS,
    entry: 'react-dom/unstable-native-dependencies',
    global: 'ReactDOMUnstableNativeDependencies',
    externals: ['react', 'react-dom'],
  },

  /******* React DOM Server *******/
  {
    bundleTypes: [
      UMD_DEV,
      UMD_PROD,
      NODE_DEV,
      NODE_PROD,
      FB_WWW_DEV,
      FB_WWW_PROD,
    ],
    moduleType: NON_FIBER_RENDERER,
    entry: 'react-dom/server.browser',
    global: 'ReactDOMServer',
    externals: ['react'],
  },

  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: NON_FIBER_RENDERER,
    entry: 'react-dom/server.node',
    externals: ['react', 'stream'],
  },

  /******* React ART *******/
  {
    bundleTypes: [
      UMD_DEV,
      UMD_PROD,
      NODE_DEV,
      NODE_PROD,
      FB_WWW_DEV,
      FB_WWW_PROD,
    ],
    moduleType: RENDERER,
    entry: 'react-art',
    global: 'ReactART',
    externals: ['react'],
    babel: opts =>
      Object.assign({}, opts, {
        // Include JSX
        presets: opts.presets.concat([require.resolve('babel-preset-react')]),
      }),
  },

  /******* React Native *******/
  {
    bundleTypes: [RN_FB_DEV, RN_FB_PROD, RN_FB_PROFILING],
    moduleType: RENDERER,
    entry: 'react-native-renderer',
    global: 'ReactNativeRenderer',
    externals: [
      'ExceptionsManager',
      'InitializeCore',
      'Platform',
      'RCTEventEmitter',
      'TextInputState',
      'UIManager',
      'deepDiffer',
      'deepFreezeAndThrowOnMutationInDev',
      'flattenStyle',
      'ReactNativeViewConfigRegistry',
    ],
  },

  {
    bundleTypes: [RN_OSS_DEV, RN_OSS_PROD, RN_OSS_PROFILING],
    moduleType: RENDERER,
    entry: 'react-native-renderer',
    global: 'ReactNativeRenderer',
    externals: [
      'ExceptionsManager',
      'InitializeCore',
      'Platform',
      'RCTEventEmitter',
      'TextInputState',
      'UIManager',
      'deepDiffer',
      'deepFreezeAndThrowOnMutationInDev',
      'flattenStyle',
      'ReactNativeViewConfigRegistry',
    ],
  },

  /******* React Native Fabric *******/
  {
    bundleTypes: [RN_FB_DEV, RN_FB_PROD, RN_FB_PROFILING],
    moduleType: RENDERER,
    entry: 'react-native-renderer/fabric',
    global: 'ReactFabric',
    externals: [
      'ExceptionsManager',
      'InitializeCore',
      'Platform',
      'RCTEventEmitter',
      'TextInputState',
      'UIManager',
      'FabricUIManager',
      'deepDiffer',
      'deepFreezeAndThrowOnMutationInDev',
      'flattenStyle',
      'ReactNativeViewConfigRegistry',
    ],
  },

  {
    bundleTypes: [RN_OSS_DEV, RN_OSS_PROD, RN_OSS_PROFILING],
    moduleType: RENDERER,
    entry: 'react-native-renderer/fabric',
    global: 'ReactFabric',
    externals: [
      'ExceptionsManager',
      'InitializeCore',
      'Platform',
      'RCTEventEmitter',
      'TextInputState',
      'UIManager',
      'FabricUIManager',
      'deepDiffer',
      'deepFreezeAndThrowOnMutationInDev',
      'flattenStyle',
      'ReactNativeViewConfigRegistry',
    ],
  },

  /******* React Test Renderer *******/
  {
    bundleTypes: [FB_WWW_DEV, NODE_DEV, NODE_PROD, UMD_DEV, UMD_PROD],
    moduleType: RENDERER,
    entry: 'react-test-renderer',
    global: 'ReactTestRenderer',
    externals: ['react'],
  },

  {
    bundleTypes: [FB_WWW_DEV, NODE_DEV, NODE_PROD, UMD_DEV, UMD_PROD],
    moduleType: NON_FIBER_RENDERER,
    entry: 'react-test-renderer/shallow',
    global: 'ReactShallowRenderer',
    externals: ['react'],
  },

  /******* React Noop Renderer (used for tests) *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: RENDERER,
    entry: 'react-noop-renderer',
    global: 'ReactNoopRenderer',
    externals: ['react', 'expect'],
    // React Noop uses generators. However GCC currently
    // breaks when we attempt to use them in the output.
    // So we precompile them with regenerator, and include
    // it as a runtime dependency of React Noop. In practice
    // this isn't an issue because React Noop is only used
    // in our tests. We wouldn't want to do this for any
    // public package though.
    babel: opts =>
      Object.assign({}, opts, {
        plugins: opts.plugins.concat([
          require.resolve('babel-plugin-transform-regenerator'),
        ]),
      }),
  },

  /******* React Noop Persistent Renderer (used for tests) *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: RENDERER,
    entry: 'react-noop-renderer/persistent',
    global: 'ReactNoopRendererPersistent',
    externals: ['react', 'expect'],
    // React Noop uses generators. However GCC currently
    // breaks when we attempt to use them in the output.
    // So we precompile them with regenerator, and include
    // it as a runtime dependency of React Noop. In practice
    // this isn't an issue because React Noop is only used
    // in our tests. We wouldn't want to do this for any
    // public package though.
    babel: opts =>
      Object.assign({}, opts, {
        plugins: opts.plugins.concat([
          require.resolve('babel-plugin-transform-regenerator'),
        ]),
      }),
  },

  /******* React Reconciler *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: RECONCILER,
    entry: 'react-reconciler',
    global: 'ReactReconciler',
    externals: ['react'],
  },

  /******* React Persistent Reconciler *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: RECONCILER,
    entry: 'react-reconciler/persistent',
    global: 'ReactPersistentReconciler',
    externals: ['react'],
  },

  /******* Reflection *******/
  {
    moduleType: RENDERER_UTILS,
    bundleTypes: [NODE_DEV, NODE_PROD],
    entry: 'react-reconciler/reflection',
    global: 'ReactFiberTreeReflection',
    externals: [],
  },

  /******* React Is *******/
  {
    bundleTypes: [
      NODE_DEV,
      NODE_PROD,
      FB_WWW_DEV,
      FB_WWW_PROD,
      UMD_DEV,
      UMD_PROD,
    ],
    moduleType: ISOMORPHIC,
    entry: 'react-is',
    global: 'ReactIs',
    externals: [],
  },

  /******* React Debug Tools *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: ISOMORPHIC,
    entry: 'react-debug-tools',
    global: 'ReactDebugTools',
    externals: [],
  },

  /******* React Cache (experimental) *******/
  {
    bundleTypes: [
      FB_WWW_DEV,
      FB_WWW_PROD,
      NODE_DEV,
      NODE_PROD,
      UMD_DEV,
      UMD_PROD,
    ],
    moduleType: ISOMORPHIC,
    entry: 'react-cache',
    global: 'ReactCache',
    externals: ['react', 'scheduler'],
  },

  /******* createComponentWithSubscriptions (experimental) *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD],
    moduleType: ISOMORPHIC,
    entry: 'create-subscription',
    global: 'createSubscription',
    externals: ['react'],
  },

  /******* React Scheduler (experimental) *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD, FB_WWW_DEV, FB_WWW_PROD],
    moduleType: ISOMORPHIC,
    entry: 'scheduler',
    global: 'Scheduler',
    externals: [],
  },

  /******* Jest React (experimental) *******/
  {
    bundleTypes: [NODE_DEV, NODE_PROD, FB_WWW_DEV, FB_WWW_PROD],
    moduleType: ISOMORPHIC,
    entry: 'jest-react',
    global: 'JestReact',
    externals: ['jest-diff'],
  },

  /******* ESLint Plugin for Hooks (proposal) *******/
  {
    // TODO: it's awkward to create a bundle for this
    // but if we don't, the package won't get copied.
    // We also can't create just DEV bundle because
    // it contains a NODE_ENV check inside.
    // We should probably tweak our build process
    // to allow "raw" packages that don't get bundled.
    bundleTypes: [NODE_DEV, NODE_PROD, FB_WWW_DEV],
    moduleType: ISOMORPHIC,
    entry: 'eslint-plugin-react-hooks',
    global: 'ESlintPluginReactHooks',
    externals: [],
  },

  {
    bundleTypes: [
      FB_WWW_DEV,
      FB_WWW_PROD,
      FB_WWW_PROFILING,
      NODE_DEV,
      NODE_PROD,
      NODE_PROFILING,
    ],
    moduleType: ISOMORPHIC,
    entry: 'scheduler/tracing',
    global: 'SchedulerTracing',
    externals: [],
  },
];

// Based on deep-freeze by substack (public domain)
function deepFreeze(o) {
  Object.freeze(o);
  Object.getOwnPropertyNames(o).forEach(function(prop) {
    if (
      o[prop] !== null &&
      (typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
      !Object.isFrozen(o[prop])
    ) {
      deepFreeze(o[prop]);
    }
  });
  return o;
}

// Don't accidentally mutate config as part of the build
deepFreeze(bundles);

module.exports = {
  bundleTypes,
  moduleTypes,
  bundles,
};
<|endoftext|>


<commit_before>
var empty = new Buffer(0)

  // a global index for parsing the options and the payload
  // we can do this as the parsing is a sync operation
  , index

  // last five bits are 1
  // 31.toString(2) => '111111'
  , lowerCodeMask = 31

  , nextMsgId = 0

  , codes

codes = {
    'GET': 1
  , 'POST': 2
  , 'PUT': 3
  , 'DELETE': 4
  , 'get': 1
  , 'post': 2
  , 'put': 3
  , 'delete': 4
}

module.exports.generate = function generate(packet) {

  var buffer
    , byte
    , pos = 0
    , options
    , i
    , length

  packet = fillGenDefaults(packet)
  options = prepareOptions(packet)
  length = calculateLength(packet, options)

  if (length > 1280)
    throw new Error('Max packet size is 1280: current is ' + length)

  buffer = new Buffer(length)

  // first byte
  byte = 0
  byte |= 1 << 6 // first two bits are version
  byte |= confirmableAckResetMask(packet)
  byte |= packet.token.length
  buffer.writeUInt8(byte, pos++)

  // code can be humized or not
  if (codes[packet.code])
    buffer.writeUInt8(codes[packet.code], pos++)
  else
    buffer.writeUInt8(toCode(packet.code), pos++)

  // two bytes for the message id
  buffer.writeUInt16BE(packet.messageId, pos)
  pos += 2

  // the token might be an empty buffer
  packet.token.copy(buffer, pos)
  pos += packet.token.length

  // write the options
  for (i = 0; i < options.length; i++) {
    options[i].copy(buffer, pos)
    pos += options[i].length
  }

  if (packet.code !== '0.00') {

    // payload separator
    buffer.writeUInt8(255, pos++)
    packet.payload.copy(buffer, pos)
  }

  return buffer
}

module.exports.parse = function parse(buffer) {
  index = 4
  parseVersion(buffer)

  var result = {
      code: parseCode(buffer)
    , confirmable: parseConfirmable(buffer)
    , reset: parseReset(buffer)
    , ack: parseAck(buffer)
    , messageId: buffer.readUInt16BE(2)
    , token: parseToken(buffer)
    , options: null
    , payload: null
  }

  if (result.code !== '0.00') {
    result.options = parseOptions(buffer)
    result.payload = buffer.slice(index + 1)
  } else {
    if (buffer.length != 4)
      throw new Error('Empty messages must be empty')

    result.options = []
    result.payload = empty
  }

  return result
}

function parseVersion(buffer) {
  var version = buffer.readUInt8(0) >> 6

  if (version !== 1)
    throw new Error('Unsupported version')

  return version
}

function parseConfirmable(buffer) {
  return (buffer.readUInt8(0) & 48) === 0
}

function parseReset(buffer) {
  // 110000 is 48
  return (buffer.readUInt8(0) & 48) === 48
}

function parseAck(buffer) {
  // 100000 is 32
  return (buffer.readUInt8(0) & 48) === 32
}

function parseCode(buffer) {
  var byte = buffer.readUInt8(1)
    , code = '' + (byte >> 5) + '.'

  byte = byte & lowerCodeMask

  if (byte < 10)
    code += '0' + byte
  else
    code += byte

  return code
}

function parseToken(buffer) {
  var length = buffer.readUInt8(0) & 15
    , result

  if (length > 8) {
    throw new Error('Token length not allowed')
  }

  result = buffer.slice(index, index + length)

  index += length

  return result
}

var numMap  = {
    '1': 'If-Match'
  , '3': 'Uri-Host'
  , '4': 'ETag'
  , '5': 'If-None-Match'
  , '6': 'Observe'
  , '7': 'Uri-Port'
  , '8': 'Location-Path'
  , '11': 'Uri-Path'
  , '12': 'Content-Format'
  , '14': 'Max-Age'
  , '15': 'Uri-Query'
  , '17': 'Accept'
  , '20': 'Location-Query'
  , '35': 'Proxy-Uri'
  , '39': 'Proxy-Scheme'
  , '60': 'Size1'
}

var optionNumberToString = (function genOptionParser() {

  var code = Object.keys(numMap).reduce(function(acc, key) {

    acc += 'case ' + key + ':\n'
    acc += '  return \'' + numMap[key] +'\'\n'

    return acc
  }, 'switch(number) {\n')

  code += 'default:\n'
  code += 'return \'\' + number'
  code += '}\n'

  return new Function('number', code)
})()

function parseOptions(buffer) {

  var byte
    , number = 0
    , delta
    , length
    , nextOption = true
    , options = []
    , option

  while (index < buffer.length) {
    byte = buffer.readUInt8(index)

    if (byte === 255 || index > buffer.length) {
      break
    }

    delta = byte >> 4
    length = byte & 15

    index += 1

    if (delta === 13) {
      delta = buffer.readUInt8(index) + 13
      index += 1
    } else if (delta === 14) {
      delta = buffer.readUInt16BE(index) + 269
      index += 2
    } else if (delta === 15) {
      throw new Error('Wrong option delta')
    }

    if (length === 13) {
      length = buffer.readUInt8(index) + 13
      index += 1
    } else if (length === 14) {
      length = buffer.readUInt16BE(index) + 269
      index += 2
    } else if (length === 15) {
      throw new Error('Wrong option length')
    }

    number += delta

    options.push({
        name: optionNumberToString(number)
      , value: buffer.slice(index, index + length)
    })

    index += length
  }

  return options
}

function toCode(code) {
  var split = code.split && code.split('.')
    , by = 0

  if (split && split.length === 2) {
    by |= parseInt(split[0]) << 5
    by |= parseInt(split[1])
  } else {

    if (!split)
      code = parseInt(code)

    by |= (code / 100) << 5
    by |= (code % 100)
  }

  return by
}

function fillGenDefaults(packet) {

  if (!packet)
    packet = {}

  if (!packet.payload)
    packet.payload = empty

  if (!packet.token)
    packet.token = empty

  if (packet.token.length > 8)
    throw new Error('Token too long')

  if (!packet.code)
    packet.code = '0.01'

  if (!packet.messageId)
    packet.messageId = nextMsgId++

  if (!packet.options)
    packet.options = []

  if (nextMsgId === 65535)
    nextMsgId = 0

  if (!packet.confirmable)
    packet.confirmable = false

  if (!packet.reset)
    packet.reset = false

  if (!packet.ack)
    packet.ack = false

  return packet
}

function confirmableAckResetMask(packet) {
  var result

  if (packet.confirmable)
    result = 0 << 4
  else if (packet.ack)
    result = 2 << 4
  else if (packet.reset)
    result = 3 << 4
  else
    result = 1 << 4 // the message is non-confirmable

  return result
}

function calculateLength(packet, options) {
  var length = 4 + packet.payload.length + packet.token.length
    , i

  if (packet.code !== '0.00')
    length += 1

  for (i = 0; i < options.length; i++) {
    length += options[i].length
  }

  return length
}

var optionStringToNumber = (function genOptionParser() {

  var code = Object.keys(numMap).reduce(function(acc, key) {

    acc += 'case \'' + numMap[key] + '\':\n'
    acc += '  return \'' + key +'\'\n'

    return acc
  }, 'switch(string) {\n')

  code += 'default:\n'
  code += 'return parseInt(string)'
  code += '}\n'

  return new Function('string', code)
})()

var nameMap = Object.keys(numMap).reduce(function(acc, key) {
  acc[numMap[key]] = key
  return acc
}, {})

function optionSorter(a, b) {
  a = a.name
  b = b.name

  a = nameMap[a] || parseInt(a)
  b = nameMap[b] || parseInt(b)

  if (a > b)
    return 1
  else if (b < a)
    return -1
  else
    return 0
}

function prepareOptions(packet) {
  var options = []
    , total = 0
    , delta
    , buffer
    , byte
    , option
    , i
    , bufferSize
    , pos
    , value

  packet.options.sort(optionSorter)

  for (i = 0; i < packet.options.length; i++) {
    pos = 0
    option = packet.options[i].name
    delta = optionStringToNumber(option) - total
    value = packet.options[i].value

    // max option length is 1 header, 2 ext numb, 2 ext length
    buffer = new Buffer(value.length + 5)

    byte = 0

    if (delta <= 12) {
      byte |= delta << 4
    } else if (delta > 12 && delta < 269) {
      byte |= 13 << 4
    } else {
      byte |= 14 << 4
    }

    if (value.length <= 12) {
      byte |= value.length
    } else if (value.length > 12 && value.length < 269) {
      byte |= 13
    } else {
      byte |= 14
    }

    buffer.writeUInt8(byte, pos++)

    if (delta > 12 && delta < 269) {
      buffer.writeUInt8(delta - 13, pos++)
    } else if (delta >= 269) {
      buffer.writeUInt16BE(delta - 269, pos)
      pos += 2
    }

    if (value.length > 12 && value.length < 269) {
      buffer.writeUInt8(value.length - 13, pos++)
    } else if (value.length >= 269) {
      buffer.writeUInt16BE(value.length - 269, pos)
      pos += 2
    }

    value.copy(buffer, pos)
    pos += value.length
    total += delta
    options.push(buffer.slice(0, pos))
  }

  return options
}
<commit_msg>Randomized start of messageIds.<commit_after>
var empty = new Buffer(0)

  // a global index for parsing the options and the payload
  // we can do this as the parsing is a sync operation
  , index

  // last five bits are 1
  // 31.toString(2) => '111111'
  , lowerCodeMask = 31

  , nextMsgId = Math.floor(Math.random() * 65535)

  , codes

codes = {
    'GET': 1
  , 'POST': 2
  , 'PUT': 3
  , 'DELETE': 4
  , 'get': 1
  , 'post': 2
  , 'put': 3
  , 'delete': 4
}

module.exports.generate = function generate(packet) {

  var buffer
    , byte
    , pos = 0
    , options
    , i
    , length

  packet = fillGenDefaults(packet)
  options = prepareOptions(packet)
  length = calculateLength(packet, options)

  if (length > 1280)
    throw new Error('Max packet size is 1280: current is ' + length)

  buffer = new Buffer(length)

  // first byte
  byte = 0
  byte |= 1 << 6 // first two bits are version
  byte |= confirmableAckResetMask(packet)
  byte |= packet.token.length
  buffer.writeUInt8(byte, pos++)

  // code can be humized or not
  if (codes[packet.code])
    buffer.writeUInt8(codes[packet.code], pos++)
  else
    buffer.writeUInt8(toCode(packet.code), pos++)

  // two bytes for the message id
  buffer.writeUInt16BE(packet.messageId, pos)
  pos += 2

  // the token might be an empty buffer
  packet.token.copy(buffer, pos)
  pos += packet.token.length

  // write the options
  for (i = 0; i < options.length; i++) {
    options[i].copy(buffer, pos)
    pos += options[i].length
  }

  if (packet.code !== '0.00') {

    // payload separator
    buffer.writeUInt8(255, pos++)
    packet.payload.copy(buffer, pos)
  }

  return buffer
}

module.exports.parse = function parse(buffer) {
  index = 4
  parseVersion(buffer)

  var result = {
      code: parseCode(buffer)
    , confirmable: parseConfirmable(buffer)
    , reset: parseReset(buffer)
    , ack: parseAck(buffer)
    , messageId: buffer.readUInt16BE(2)
    , token: parseToken(buffer)
    , options: null
    , payload: null
  }

  if (result.code !== '0.00') {
    result.options = parseOptions(buffer)
    result.payload = buffer.slice(index + 1)
  } else {
    if (buffer.length != 4)
      throw new Error('Empty messages must be empty')

    result.options = []
    result.payload = empty
  }

  return result
}

function parseVersion(buffer) {
  var version = buffer.readUInt8(0) >> 6

  if (version !== 1)
    throw new Error('Unsupported version')

  return version
}

function parseConfirmable(buffer) {
  return (buffer.readUInt8(0) & 48) === 0
}

function parseReset(buffer) {
  // 110000 is 48
  return (buffer.readUInt8(0) & 48) === 48
}

function parseAck(buffer) {
  // 100000 is 32
  return (buffer.readUInt8(0) & 48) === 32
}

function parseCode(buffer) {
  var byte = buffer.readUInt8(1)
    , code = '' + (byte >> 5) + '.'

  byte = byte & lowerCodeMask

  if (byte < 10)
    code += '0' + byte
  else
    code += byte

  return code
}

function parseToken(buffer) {
  var length = buffer.readUInt8(0) & 15
    , result

  if (length > 8) {
    throw new Error('Token length not allowed')
  }

  result = buffer.slice(index, index + length)

  index += length

  return result
}

var numMap  = {
    '1': 'If-Match'
  , '3': 'Uri-Host'
  , '4': 'ETag'
  , '5': 'If-None-Match'
  , '6': 'Observe'
  , '7': 'Uri-Port'
  , '8': 'Location-Path'
  , '11': 'Uri-Path'
  , '12': 'Content-Format'
  , '14': 'Max-Age'
  , '15': 'Uri-Query'
  , '17': 'Accept'
  , '20': 'Location-Query'
  , '35': 'Proxy-Uri'
  , '39': 'Proxy-Scheme'
  , '60': 'Size1'
}

var optionNumberToString = (function genOptionParser() {

  var code = Object.keys(numMap).reduce(function(acc, key) {

    acc += 'case ' + key + ':\n'
    acc += '  return \'' + numMap[key] +'\'\n'

    return acc
  }, 'switch(number) {\n')

  code += 'default:\n'
  code += 'return \'\' + number'
  code += '}\n'

  return new Function('number', code)
})()

function parseOptions(buffer) {

  var byte
    , number = 0
    , delta
    , length
    , nextOption = true
    , options = []
    , option

  while (index < buffer.length) {
    byte = buffer.readUInt8(index)

    if (byte === 255 || index > buffer.length) {
      break
    }

    delta = byte >> 4
    length = byte & 15

    index += 1

    if (delta === 13) {
      delta = buffer.readUInt8(index) + 13
      index += 1
    } else if (delta === 14) {
      delta = buffer.readUInt16BE(index) + 269
      index += 2
    } else if (delta === 15) {
      throw new Error('Wrong option delta')
    }

    if (length === 13) {
      length = buffer.readUInt8(index) + 13
      index += 1
    } else if (length === 14) {
      length = buffer.readUInt16BE(index) + 269
      index += 2
    } else if (length === 15) {
      throw new Error('Wrong option length')
    }

    number += delta

    options.push({
        name: optionNumberToString(number)
      , value: buffer.slice(index, index + length)
    })

    index += length
  }

  return options
}

function toCode(code) {
  var split = code.split && code.split('.')
    , by = 0

  if (split && split.length === 2) {
    by |= parseInt(split[0]) << 5
    by |= parseInt(split[1])
  } else {

    if (!split)
      code = parseInt(code)

    by |= (code / 100) << 5
    by |= (code % 100)
  }

  return by
}

function fillGenDefaults(packet) {

  if (!packet)
    packet = {}

  if (!packet.payload)
    packet.payload = empty

  if (!packet.token)
    packet.token = empty

  if (packet.token.length > 8)
    throw new Error('Token too long')

  if (!packet.code)
    packet.code = '0.01'

  if (!packet.messageId)
    packet.messageId = nextMsgId++

  if (!packet.options)
    packet.options = []

  if (nextMsgId === 65535)
    nextMsgId = 0

  if (!packet.confirmable)
    packet.confirmable = false

  if (!packet.reset)
    packet.reset = false

  if (!packet.ack)
    packet.ack = false

  return packet
}

function confirmableAckResetMask(packet) {
  var result

  if (packet.confirmable)
    result = 0 << 4
  else if (packet.ack)
    result = 2 << 4
  else if (packet.reset)
    result = 3 << 4
  else
    result = 1 << 4 // the message is non-confirmable

  return result
}

function calculateLength(packet, options) {
  var length = 4 + packet.payload.length + packet.token.length
    , i

  if (packet.code !== '0.00')
    length += 1

  for (i = 0; i < options.length; i++) {
    length += options[i].length
  }

  return length
}

var optionStringToNumber = (function genOptionParser() {

  var code = Object.keys(numMap).reduce(function(acc, key) {

    acc += 'case \'' + numMap[key] + '\':\n'
    acc += '  return \'' + key +'\'\n'

    return acc
  }, 'switch(string) {\n')

  code += 'default:\n'
  code += 'return parseInt(string)'
  code += '}\n'

  return new Function('string', code)
})()

var nameMap = Object.keys(numMap).reduce(function(acc, key) {
  acc[numMap[key]] = key
  return acc
}, {})

function optionSorter(a, b) {
  a = a.name
  b = b.name

  a = nameMap[a] || parseInt(a)
  b = nameMap[b] || parseInt(b)

  if (a > b)
    return 1
  else if (b < a)
    return -1
  else
    return 0
}

function prepareOptions(packet) {
  var options = []
    , total = 0
    , delta
    , buffer
    , byte
    , option
    , i
    , bufferSize
    , pos
    , value

  packet.options.sort(optionSorter)

  for (i = 0; i < packet.options.length; i++) {
    pos = 0
    option = packet.options[i].name
    delta = optionStringToNumber(option) - total
    value = packet.options[i].value

    // max option length is 1 header, 2 ext numb, 2 ext length
    buffer = new Buffer(value.length + 5)

    byte = 0

    if (delta <= 12) {
      byte |= delta << 4
    } else if (delta > 12 && delta < 269) {
      byte |= 13 << 4
    } else {
      byte |= 14 << 4
    }

    if (value.length <= 12) {
      byte |= value.length
    } else if (value.length > 12 && value.length < 269) {
      byte |= 13
    } else {
      byte |= 14
    }

    buffer.writeUInt8(byte, pos++)

    if (delta > 12 && delta < 269) {
      buffer.writeUInt8(delta - 13, pos++)
    } else if (delta >= 269) {
      buffer.writeUInt16BE(delta - 269, pos)
      pos += 2
    }

    if (value.length > 12 && value.length < 269) {
      buffer.writeUInt8(value.length - 13, pos++)
    } else if (value.length >= 269) {
      buffer.writeUInt16BE(value.length - 269, pos)
      pos += 2
    }

    value.copy(buffer, pos)
    pos += value.length
    total += delta
    options.push(buffer.slice(0, pos))
  }

  return options
}
<|endoftext|>


<commit_before>/**
 * @fileoverview WAVE audio library element: a web audio granular engine.
 * @author Karim.Barkati@ircam.fr, Norbert.Schnell@ircam.fr, Victor.Saiz@ircam.fr
 * @version 1.2.6
 */

/**
 * Function invocation pattern for object creation.
 * @public
 */

var createGranularEngine = function createGranularEngine(audioBuffer, audioContext, optName) {
  'use strict';

  /**
   * ECMAScript5 property descriptors object.
   */

  var granularEngineObject = {

    // Properties with default values
    period: { // in sec
      writable: true,
      value: 0.01
    },
    position: { // buffer position (in sec), assumed not normalized
      writable: true,
      value: 0
    },
    positionVariation: {
      writable: true,
      value: 0.003
    },
    duration: {
      writable: true,
      value: 0.2
    },
    resampling: {
      writable: true,
      value: 0
    },
    resamplingVariation: {
      writable: true,
      value: 0
    },
    centered: {
      writable: true,
      value: false
    },
    maxGrainAmplitude: {
      writable: true,
      value: 0.2
    },

    // Other properties
    context: {
      writable: true
    },
    buffer: {
      writable: true
    },
    bufferDuration: {
      writable: true
    },
    nextEventTime: {
      writable: true
    },
    gainNode: {
      writable: true
    },
    outputNode: {
      writable: true
    },
    gain: {
      writable: true
    },
    name: {
      writable: true,
    },

    /**
     * Mandatory initialization method.
     * @public
     * @chainable
     */
    init: {
      enumerable: true,
      value: function(audioBuffer, audioContext, optName) {

        this.context = audioContext;
        this.setBuffer(audioBuffer);
        this.name = optName;

        // Create web audio nodes, relying on the given audio context.
        this.gainNode = this.context.createGain();
        this.outputNode = this.context.createGain(); // dummy node to provide a web audio-like output node
        this.connect(this.context.destination); // default destination

        makeSchedulable(this); // an audio engine has to inherit schedulable properties

        return this; // for chainability
      }
    },

    /**
     * Recommended self-checking public method.
     * @public
     */
    isValid: {
      enumerable: true,
      value: function() {
        if (this.buffer) {
          return true;
        } else {
          console.error("No buffer is set");
          return false;
        }
      }
    },

    /**
     * Optional phase resetting public method.
     * @public
     */
    resetPhase: {
      enumerable: true,
      value: function() {
        // This engine does not manage phase.
      }
    },

    /**
     * Connect public method.
     * @public
     * @chainable
     */
    connect: {
      enumerable: true,
      value: function(target) {
        this.outputNode = target;
        this.gainNode.connect(this.outputNode || this.context.destination);
        return this; // for chainability
      }
    },

    /**
     * Set buffer and bufferDuration.
     * @public
     * @chainable
     */
    setBuffer: {
      enumerable: true,
      value: function(buffer) {
        if (buffer) {
          this.buffer = buffer;
          this.bufferDuration = buffer.duration;
          return this; // for chainability
        } else {
          throw "Buffer setting error";
        }
      }
    },

    /**
     * Set gain value and squared volume.
     * @public
     * @chainable
     */
    setGain: {
      enumerable: true,
      value: function(gain) {
        if (gain) {
          this.gain = gain;
          // Let's use an x-squared curve since simple linear (x) does not sound as good.
          this.gainNode.gain.value = gain * gain;
          return this; // for chainability
        } else {
          throw "Gain setting error";
        }
      }
    },

    /**
     * Set buffer position.
     * @public
     * @chainable
     */
    seek: {
      enumerable: true,
      value: function(position) {
        if (!isNaN(parseFloat(position))) { // number check
          if (position >= 0 && position <= this.bufferDuration) {
            this.position = position;
            return this;
          } else {
            console.log("Position is out of bounds");
          }
        } else {
          throw "Seeking error";
        }
      }
    },

    /**
     * Grain factory.
     * @private
     */
    makeNextGrain: {
      enumerable: false,
      value: function() {
        var source = this.context.createBufferSource();
        var resamplingRate = this.computeResamplingRate();
        var grainDuration = this.duration / resamplingRate;
        var grainPosition = this.computeGrainPosition(grainDuration);
        var grainEnvelopeNode = this.makeGrainEnvelope(grainDuration);

        source.buffer = this.buffer;
        source.playbackRate.value = resamplingRate;

        source.connect(grainEnvelopeNode);
        grainEnvelopeNode.connect(this.gainNode);

        // args: schedule time, buffer offset, duration (all in seconds)
        source.start(this.nextEventTime, grainPosition, this.duration);
      }
    },

    /**
     * Compute grain position from direct interaction or external transporter delegation.
     * @private
     */
    computeGrainPosition: {
      enumerable: false,
      value: function(grainDuration) {
        var grainPosition;

        // Update grain position when slaved, from last synchronization
        if (this.isTransportable) {
          var position = this.transporter.getPositionAtTime(this.nextEventTime);

          if (position >= 0 && position <= this.bufferDuration) {
            this.position = position;
          } else {
            console.log("Grain position is out of bounds");
            if (this.hasOwnProperty("notifyEnd")) {
              this.notifyEnd();
            }
          }
        }

        grainPosition = this.randomizeGrainPosition(this.position % this.bufferDuration);
        if (this.centered) grainPosition -= 0.5 * grainDuration;

        return grainPosition;
      }
    },

    /**
     * Randomize position to break phasing artifacts, except when playing at normal speed.
     * @private
     */
    randomizeGrainPosition: {
      enumerable: false,
      value: function(grainPosition) {
        var randomGrainShift = (Math.random() - 0.5) * 2.0 * this.positionVariation;

        return (grainPosition + randomGrainShift) % this.bufferDuration;
      }
    },

    /**
     * Simple triangle envelope generator for grains.
     * @todo hanning envelope (or gaussian)
     * @private
     */
    makeGrainEnvelope: {
      enumerable: false,
      value: function(grainDuration) {
        var envelopeNode = this.context.createGain();
        var attackDuration = 0.5 * grainDuration;
        var releaseDuration = 0.5 * grainDuration;

        var attackEndTime = this.nextEventTime + attackDuration;
        var grainEndTime = this.nextEventTime + grainDuration;
        var releaseStartTime = grainEndTime - releaseDuration;

        // make attack and release
        envelopeNode.gain.setValueAtTime(0.0, this.nextEventTime);
        envelopeNode.gain.linearRampToValueAtTime(this.maxGrainAmplitude, attackEndTime);

        if (releaseStartTime > attackEndTime) {
          envelopeNode.gain.setValueAtTime(this.maxGrainAmplitude, releaseStartTime);
        }

        envelopeNode.gain.linearRampToValueAtTime(0.0, grainEndTime);
        return envelopeNode;
      }
    },

    /**
     * Compute resampling rate for pitch shifting.
     * @private
     */
    computeResamplingRate: {
      enumerable: false,
      value: function() {
        var randomResampling = (Math.random() - 0.5) * 2.0 * this.resamplingVariation;
        var totalResampling = this.resampling + randomResampling;
        var resamplingRate = Math.pow(2.0, totalResampling / 1200.0);
        return resamplingRate;
      }
    },

    //////////////////////////////////////
    // Required schedulable properties. //
    //////////////////////////////////////

    /**
     * Make next event.
     * @private
     */
    makeAtNextTime: {
      enumerable: false,
      value: function() {
        this.makeNextGrain();
      }
    },

    /**
     * Compute next event time.
     * @private
     */
    computeNextEventTime: {
      enumerable: false,
      value: function() {
        this.nextEventTime = this.nextEventTime + this.period;
        return this.nextEventTime;
      }
    },

    /**
     * Get next event time.
     * @private
     */
    getNextTime: {
      enumerable: false,
      value: function() {
        return this.nextEventTime;
      }
    },

    /**
     * Set next event time.
     * @private
     */
    setNextEventTime: {
      enumerable: false,
      value: function(time) {
        this.nextEventTime = time;
      }
    },

  }; // End of object definition.

  // Instantiate an object and initialize it.
  var granularEngine = Object.create({}, granularEngineObject);
  return granularEngine.init(audioBuffer, audioContext, optName);
};

// CommonJS function export
module.exports = createGranularEngine;<commit_msg>Changed scheduling and transporting APIs: 'makeAtNextTime()' and 'computeNextEventTime()' are now merged into the single 'makeEventAndComputeNextTime()' method (resp. 'makeEventAndComputeNextPosition()').<commit_after>/**
 * @fileoverview WAVE audio library element: a web audio granular engine.
 * @author Karim.Barkati@ircam.fr, Norbert.Schnell@ircam.fr, Victor.Saiz@ircam.fr
 * @version 1.2.7
 */

/**
 * Function invocation pattern for object creation.
 * @public
 */

var createGranularEngine = function createGranularEngine(audioBuffer, audioContext, optName) {
  'use strict';

  /**
   * ECMAScript5 property descriptors object.
   */

  var granularEngineObject = {

    // Properties with default values
    period: { // in sec
      writable: true,
      value: 0.01
    },
    position: { // buffer position (in sec), assumed not normalized
      writable: true,
      value: 0
    },
    positionVariation: {
      writable: true,
      value: 0.003
    },
    duration: {
      writable: true,
      value: 0.2
    },
    resampling: {
      writable: true,
      value: 0
    },
    resamplingVariation: {
      writable: true,
      value: 0
    },
    centered: {
      writable: true,
      value: false
    },
    maxGrainAmplitude: {
      writable: true,
      value: 0.2
    },

    // Other properties
    context: {
      writable: true
    },
    buffer: {
      writable: true
    },
    bufferDuration: {
      writable: true
    },
    nextEventTime: {
      writable: true
    },
    gainNode: {
      writable: true
    },
    outputNode: {
      writable: true
    },
    gain: {
      writable: true
    },
    name: {
      writable: true,
    },

    /**
     * Mandatory initialization method.
     * @public
     * @chainable
     */
    init: {
      enumerable: true,
      value: function(audioBuffer, audioContext, optName) {

        this.context = audioContext;
        this.setBuffer(audioBuffer);
        this.name = optName;

        // Create web audio nodes, relying on the given audio context.
        this.gainNode = this.context.createGain();
        this.outputNode = this.context.createGain(); // dummy node to provide a web audio-like output node
        this.connect(this.context.destination); // default destination

        makeSchedulable(this); // an audio engine has to inherit schedulable properties

        return this; // for chainability
      }
    },

    /**
     * Recommended self-checking public method.
     * @public
     */
    isValid: {
      enumerable: true,
      value: function() {
        if (this.buffer) {
          return true;
        } else {
          console.error("No buffer is set");
          return false;
        }
      }
    },

    /**
     * Optional phase resetting public method.
     * @public
     */
    resetPhase: {
      enumerable: true,
      value: function() {
        // This engine does not manage phase.
      }
    },

    /**
     * Connect public method.
     * @public
     * @chainable
     */
    connect: {
      enumerable: true,
      value: function(target) {
        this.outputNode = target;
        this.gainNode.connect(this.outputNode || this.context.destination);
        return this; // for chainability
      }
    },

    /**
     * Set buffer and bufferDuration.
     * @public
     * @chainable
     */
    setBuffer: {
      enumerable: true,
      value: function(buffer) {
        if (buffer) {
          this.buffer = buffer;
          this.bufferDuration = buffer.duration;
          return this; // for chainability
        } else {
          throw "Buffer setting error";
        }
      }
    },

    /**
     * Set gain value and squared volume.
     * @public
     * @chainable
     */
    setGain: {
      enumerable: true,
      value: function(gain) {
        if (gain) {
          this.gain = gain;
          // Let's use an x-squared curve since simple linear (x) does not sound as good.
          this.gainNode.gain.value = gain * gain;
          return this; // for chainability
        } else {
          throw "Gain setting error";
        }
      }
    },

    /**
     * Set buffer position.
     * @public
     * @chainable
     */
    seek: {
      enumerable: true,
      value: function(position) {
        if (!isNaN(parseFloat(position))) { // number check
          if (position >= 0 && position <= this.bufferDuration) {
            this.position = position;
            return this;
          } else {
            console.log("Position is out of bounds");
          }
        } else {
          throw "Seeking error";
        }
      }
    },

    /**
     * Grain factory.
     * @private
     */
    makeNextGrain: {
      enumerable: false,
      value: function() {
        var source = this.context.createBufferSource();
        var resamplingRate = this.computeResamplingRate();
        var grainDuration = this.duration / resamplingRate;
        var grainPosition = this.computeGrainPosition(grainDuration);
        var grainEnvelopeNode = this.makeGrainEnvelope(grainDuration);

        source.buffer = this.buffer;
        source.playbackRate.value = resamplingRate;

        source.connect(grainEnvelopeNode);
        grainEnvelopeNode.connect(this.gainNode);

        // args: schedule time, buffer offset, duration (all in seconds)
        source.start(this.nextEventTime, grainPosition, this.duration);
      }
    },

    /**
     * Compute grain position from direct interaction or external transporter delegation.
     * @private
     */
    computeGrainPosition: {
      enumerable: false,
      value: function(grainDuration) {
        var grainPosition;

        // Update grain position when slaved, from last synchronization
        if (this.isTransportable) {
          var position = this.transporter.getPositionAtTime(this.nextEventTime);

          if (position >= 0 && position <= this.bufferDuration) {
            this.position = position;
          } else {
            console.log("Grain position is out of bounds");
            if (this.hasOwnProperty("notifyEnd")) {
              this.notifyEnd();
            }
          }
        }

        grainPosition = this.randomizeGrainPosition(this.position % this.bufferDuration);
        if (this.centered) grainPosition -= 0.5 * grainDuration;

        return grainPosition;
      }
    },

    /**
     * Randomize position to break phasing artifacts, except when playing at normal speed.
     * @private
     */
    randomizeGrainPosition: {
      enumerable: false,
      value: function(grainPosition) {
        var randomGrainShift = (Math.random() - 0.5) * 2.0 * this.positionVariation;

        return (grainPosition + randomGrainShift) % this.bufferDuration;
      }
    },

    /**
     * Simple triangle envelope generator for grains.
     * @todo hanning envelope (or gaussian)
     * @private
     */
    makeGrainEnvelope: {
      enumerable: false,
      value: function(grainDuration) {
        var envelopeNode = this.context.createGain();
        var attackDuration = 0.5 * grainDuration;
        var releaseDuration = 0.5 * grainDuration;

        var attackEndTime = this.nextEventTime + attackDuration;
        var grainEndTime = this.nextEventTime + grainDuration;
        var releaseStartTime = grainEndTime - releaseDuration;

        // make attack and release
        envelopeNode.gain.setValueAtTime(0.0, this.nextEventTime);
        envelopeNode.gain.linearRampToValueAtTime(this.maxGrainAmplitude, attackEndTime);

        if (releaseStartTime > attackEndTime) {
          envelopeNode.gain.setValueAtTime(this.maxGrainAmplitude, releaseStartTime);
        }

        envelopeNode.gain.linearRampToValueAtTime(0.0, grainEndTime);
        return envelopeNode;
      }
    },

    /**
     * Compute resampling rate for pitch shifting.
     * @private
     */
    computeResamplingRate: {
      enumerable: false,
      value: function() {
        var randomResampling = (Math.random() - 0.5) * 2.0 * this.resamplingVariation;
        var totalResampling = this.resampling + randomResampling;
        var resamplingRate = Math.pow(2.0, totalResampling / 1200.0);
        return resamplingRate;
      }
    },

    //////////////////////////////////////
    // Required schedulable properties. //
    //////////////////////////////////////

    /**
     * Make event and compute next event time.
     * @private
     */
    makeEventAndComputeNextTime: {
      enumerable: false,
      value: function() {
        this.makeNextGrain();
        this.nextEventTime = this.nextEventTime + this.period;
        return this.nextEventTime;
      }
    },

    /**
     * Get next event time.
     * @private
     */
    getNextTime: {
      enumerable: false,
      value: function() {
        return this.nextEventTime;
      }
    },

    /**
     * Set next event time.
     * @private
     * @todo Unused?
     */
    setNextEventTime: {
      enumerable: false,
      value: function(time) {
        this.nextEventTime = time;
      }
    },

  }; // End of object definition.

  // Instantiate an object and initialize it.
  var granularEngine = Object.create({}, granularEngineObject);
  return granularEngine.init(audioBuffer, audioContext, optName);
};

// CommonJS function export
module.exports = createGranularEngine;<|endoftext|>