<commit_before>/*global config*/
import Resource from '../services/ResourceProvider';
import Q from 'q';
import { findWhere, map, extend, max } from 'underscore';
import humanizeDuration from 'humanize-duration';

function _parse(resp) {
  if (resp.startTimestamp && resp.endTimestamp) {
    resp.duration = humanizeDuration(resp.endTimestamp - resp.startTimestamp, {round: true});
  }

  return resp;
}

function _fetchModuleNames(params) {
  const moduleNamesPromise = new Resource({
    url: `${config.apiRoot}/branches/${params.branchId}/modules`,
    type: 'GET'
  }).send();

  return moduleNamesPromise;
}

function _fetchModuleNamesById(branchId) {
  const moduleNamesPromise = new Resource({
    url: `${config.apiRoot}/branches/${branchId}/modules`,
    type: 'GET'
  }).send();

  return moduleNamesPromise;
}

function _fetchBranchBuildHistory(params) {
  const branchBuildHistoryPromise = new Resource({
    url: `${config.apiRoot}/builds/history/branch/${params.branchId}`,
    type: 'GET'
  }).send();

  return branchBuildHistoryPromise;
}

function fetchRepoBuild(params, cb) {
  return _fetchBranchBuildHistory(params).then((resp) => {
    let repoBuild;

    if (params.buildNumber === 'latest') {
      repoBuild = max(resp, (build) => { return build.buildNumber; });
    }

    else {
      repoBuild = findWhere(resp, {buildNumber: parseInt(params.buildNumber, 10)});
    }

    const repoBuildPromise = new Resource({
      url: `${config.apiRoot}/branches/builds/${repoBuild.id}`,
      type: 'GET'
    }).send();

    return repoBuildPromise.then((resp) => {
      return cb(_parse(resp));
    });
  });
}

function fetchRepoBuildById(repoBuildId, cb) {
  const repoBuildPromise = new Resource({
    url: `${config.apiRoot}/branches/builds/${repoBuildId}`,
    type: 'GET'
  }).send();

  return repoBuildPromise.then((resp) => {
    return cb(_parse(resp));
  });
}

function fetchModuleBuilds(params, cb) {
  return _fetchBranchBuildHistory(params).then((resp) => {
    let repoBuild;

    if (params.buildNumber === 'latest') {
      repoBuild = max(resp, (build) => { return build.buildNumber; });
    }

    else {
      repoBuild = findWhere(resp, {buildNumber: parseInt(params.buildNumber, 10)});
    }

    const moduleBuildsPromise = new Resource({
      url: `${config.apiRoot}/branches/builds/${repoBuild.id}/modules`,
      type: 'GET'
    }).send();
    const moduleInfoPromise = _fetchModuleNames(params);

    Q.spread([moduleInfoPromise, moduleBuildsPromise],
      (moduleInfos, moduleBuilds) => {
        const moduleBuildsWithNames = map(moduleBuilds, (build) => {
          const moduleInfo = findWhere(moduleInfos, {id: build.moduleId});
          const moduleInfoExtended = {
            name: moduleInfo.name,
            blazarPath: `/builds/branch/${params.branchId}/build/${repoBuild.buildNumber}/module/${moduleInfo.name}`
          };

          return extend(build, moduleInfoExtended);
        });

        cb(moduleBuildsWithNames);
      });
  });
}

function fetchModuleBuildsById(branchId, repoBuildId, buildNumber, cb) {
  const moduleBuildsPromise = new Resource({
    url: `${config.apiRoot}/branches/builds/${repoBuildId}/modules`,
    type: 'GET'
  }).send();
  const moduleInfoPromise = _fetchModuleNamesById(branchId);

  Q.spread([moduleInfoPromise, moduleBuildsPromise],
    (moduleInfos, moduleBuilds) => {
      const moduleBuildsWithNames = map(moduleBuilds, (build) => {
        const moduleInfo = findWhere(moduleInfos, {id: build.moduleId});
        const moduleInfoExtended = {
          name: moduleInfo.name,
          blazarPath: `/builds/branch/${branchId}/build/${buildNumber}/module/${moduleInfo.name}`
        };

        return extend(build, moduleInfoExtended);
      });

      cb(moduleBuildsWithNames);
    });
}

function cancelBuild(params) {
  return _fetchBranchBuildHistory(params).then((resp) => {
    const repoBuild = findWhere(resp, {buildNumber: parseInt(params.buildNumber, 10)});
    const cancelPromise = new Resource({
      url: `${config.apiRoot}/branches/builds/${repoBuild.id}/cancel`,
      type: 'POST'
    }).send();

    cancelPromise.error((error) => {
      console.warn(error); // TODO: be better
    });
  });
}

export default {
  fetchRepoBuild: fetchRepoBuild,
  fetchRepoBuildById: fetchRepoBuildById,
  fetchModuleBuilds: fetchModuleBuilds,
  fetchModuleBuildsById: fetchModuleBuildsById,
  cancelBuild: cancelBuild
};
<commit_msg>styling and slight refactor<commit_after>/*global config*/
import Resource from '../services/ResourceProvider';
import Q from 'q';
import { findWhere, map, extend, max } from 'underscore';
import humanizeDuration from 'humanize-duration';

function _parse(resp) {
  if (resp.startTimestamp && resp.endTimestamp) {
    resp.duration = humanizeDuration(resp.endTimestamp - resp.startTimestamp, {round: true});
  }

  return resp;
}

function _fetchModuleNames(params) {
  const moduleNamesPromise = new Resource({
    url: `${config.apiRoot}/branches/${params.branchId}/modules`,
    type: 'GET'
  }).send();

  return moduleNamesPromise;
}

function _fetchModuleNamesById(branchId) {
  const moduleNamesPromise = new Resource({
    url: `${config.apiRoot}/branches/${branchId}/modules`,
    type: 'GET'
  }).send();

  return moduleNamesPromise;
}

function _fetchBranchBuildHistory(params) {
  const branchBuildHistoryPromise = new Resource({
    url: `${config.apiRoot}/builds/history/branch/${params.branchId}`,
    type: 'GET'
  }).send();

  return branchBuildHistoryPromise;
}

function _getRepoBuildByParam(params, resp) {
  if (params.buildNumber === 'latest') {
    return max(resp, (build) => {
      return build.buildNumber;
    });
  }

  return findWhere(resp, {buildNumber: parseInt(params.buildNumber, 10)});
}

function fetchRepoBuild(params, cb) {
  return _fetchBranchBuildHistory(params).then((resp) => {
    const repoBuild = _getRepoBuildByParam(params, resp);
    const repoBuildPromise = new Resource({
      url: `${config.apiRoot}/branches/builds/${repoBuild.id}`,
      type: 'GET'
    }).send();

    return repoBuildPromise.then((resp) => {
      return cb(_parse(resp));
    });
  });
}

function fetchRepoBuildById(repoBuildId, cb) {
  const repoBuildPromise = new Resource({
    url: `${config.apiRoot}/branches/builds/${repoBuildId}`,
    type: 'GET'
  }).send();

  return repoBuildPromise.then((resp) => {
    return cb(_parse(resp));
  });
}

function fetchModuleBuilds(params, cb) {
  return _fetchBranchBuildHistory(params).then((resp) => {
    const repoBuild = _getRepoBuildByParam(params, resp);
    const moduleBuildsPromise = new Resource({
      url: `${config.apiRoot}/branches/builds/${repoBuild.id}/modules`,
      type: 'GET'
    }).send();
    const moduleInfoPromise = _fetchModuleNames(params);

    Q.spread([moduleInfoPromise, moduleBuildsPromise],
      (moduleInfos, moduleBuilds) => {
        const moduleBuildsWithNames = map(moduleBuilds, (build) => {
          const moduleInfo = findWhere(moduleInfos, {id: build.moduleId});
          const moduleInfoExtended = {
            name: moduleInfo.name,
            blazarPath: `/builds/branch/${params.branchId}/build/${repoBuild.buildNumber}/module/${moduleInfo.name}`
          };

          return extend(build, moduleInfoExtended);
        });

        cb(moduleBuildsWithNames);
      });
  });
}

function fetchModuleBuildsById(branchId, repoBuildId, buildNumber, cb) {
  const moduleBuildsPromise = new Resource({
    url: `${config.apiRoot}/branches/builds/${repoBuildId}/modules`,
    type: 'GET'
  }).send();
  const moduleInfoPromise = _fetchModuleNamesById(branchId);

  Q.spread([moduleInfoPromise, moduleBuildsPromise],
    (moduleInfos, moduleBuilds) => {
      const moduleBuildsWithNames = map(moduleBuilds, (build) => {
        const moduleInfo = findWhere(moduleInfos, {id: build.moduleId});
        const moduleInfoExtended = {
          name: moduleInfo.name,
          blazarPath: `/builds/branch/${branchId}/build/${buildNumber}/module/${moduleInfo.name}`
        };

        return extend(build, moduleInfoExtended);
      });

      cb(moduleBuildsWithNames);
    });
}

function cancelBuild(params) {
  return _fetchBranchBuildHistory(params).then((resp) => {
    const repoBuild = findWhere(resp, {buildNumber: parseInt(params.buildNumber, 10)});
    const cancelPromise = new Resource({
      url: `${config.apiRoot}/branches/builds/${repoBuild.id}/cancel`,
      type: 'POST'
    }).send();

    cancelPromise.error((error) => {
      console.warn(error); // TODO: be better
    });
  });
}

export default {
  fetchRepoBuild: fetchRepoBuild,
  fetchRepoBuildById: fetchRepoBuildById,
  fetchModuleBuilds: fetchModuleBuilds,
  fetchModuleBuildsById: fetchModuleBuildsById,
  cancelBuild: cancelBuild
};
<|endoftext|>


<commit_before>module.exports = standard

var auto = require('run-auto')
var cp = require('child_process')
var debug = require('debug')('standard')
var findRoot = require('find-root')
var fs = require('fs')
var glob = require('glob')
var parallel = require('run-parallel')
var path = require('path')
var split = require('split')
var standardFormat = require('standard-format')
var stdin = require('get-stdin')
var str = require('string-to-stream')
var uniq = require('uniq')

var JSCS_RC = path.join(__dirname, 'rc', '.jscsrc')
var JSCS_REPORTER = path.join(__dirname, 'lib', 'jscs-reporter.js')
var JSCS_REPORTER_VERBOSE = path.join(__dirname, 'lib', 'jscs-reporter-verbose.js')

var ESLINT_RC = path.join(__dirname, 'rc', '.eslintrc')
var ESLINT_REPORTER = path.join(__dirname, 'lib', 'eslint-reporter.js')
var ESLINT_REPORTER_VERBOSE = path.join(__dirname, 'lib', 'eslint-reporter-verbose.js')

var DEFAULT_IGNORE = [
  '**/node_modules/**',
  '.git/**',
  '**/*.min.js',
  '**/bundle.js',
  'coverage/**'
]

var ERROR_RE = /.*?:\d+:\d+/
var FILE_RE = /(.*?):/
var LINE_RE = /.*?:(\d+)/
var COL_RE = /.*?:\d+:(\d+)/

/**
 * JavaScript Standard Style
 *
 * @param {Object} opts                        options object
 * @param {string|Array.<String>} opts.ignore  files to ignore
 * @param {string} opts.cwd                    current working directory
 * @param {Array.<string>} opts.files          files to check
 * @param {boolean} opts.stdin                 check text from stdin instead of filesystem
 * @param {boolean} opts.verbose               show error codes
 * @param {boolean} opts.format                format code using standard-format before linting
 */
function standard (opts) {
  if (!opts) opts = {}
  var errors = []

  var root
  try {
    root = findRoot(process.cwd())
  } catch (e) {}

  var ignore = (opts.ignore || []).concat(DEFAULT_IGNORE) // globs to ignore

  if (root) {
    var packageOpts = require(path.join(root, 'package.json')).standard
    if (packageOpts) ignore = ignore.concat(packageOpts.ignore)
  }

  var jscsReporter = opts.verbose ? JSCS_REPORTER_VERBOSE : JSCS_REPORTER
  var jscsArgs = ['--config', JSCS_RC, '--reporter', jscsReporter]

  var eslintReporter = opts.verbose ? ESLINT_REPORTER_VERBOSE : ESLINT_REPORTER
  var eslintArgs = ['--config', ESLINT_RC, '--format', eslintReporter]

  if (opts.verbose) {
    jscsArgs.push('--verbose')
  }

  var stdinData

  if ((Array.isArray(opts.files) && opts.files.length > 0) || !opts.stdin) {
    var patterns = (Array.isArray(opts.files) && opts.files.length > 0)
      ? opts.files
      : [ '**/*.js' ]

    // traverse filesystem
    parallel(patterns.map(function (pattern) {
      return function (cb) {
        glob(pattern, {
          cwd: opts.cwd || process.cwd(),
          nodir: true,
          ignore: ignore
        }, cb)
      }
    }), function (err, results) {
      if (err) return error(err)

      // flatten nested arrays
      var files = results.reduce(function (files, result) {
        result.forEach(function (file) {
          files.push(file)
        })
        return files
      }, [])

      // de-dupe
      files = uniq(files)
      if (files.length > 0) {
        if (opts.format) {
          format(files)
        }
        jscsArgs = jscsArgs.concat(files)
        eslintArgs = eslintArgs.concat(files)
        lint()
      }
    })
  } else {
    // stdin
    eslintArgs.push('--stdin')

    stdin(function (data) {
      stdinData = data

      if (opts.format) {
        stdinData = standardFormat.transform(stdinData)
        process.stdout.write(stdinData)
        process.stderr.write('\n')
      }

      lint()
    })
  }

  function format (files) {
    files.forEach(function (file) {
      var data = fs.readFileSync(file).toString()
      fs.writeFileSync(file, standardFormat.transform(data))
    })
  }

  function lint () {
    auto({
      eslintPath: findBinPath.bind(undefined, 'eslint'),
      jscsPath: findBinPath.bind(undefined, 'jscs'),
      eslint: ['eslintPath', function (cb, r) {
        spawn(r.eslintPath, eslintArgs, cb)
      }],
      jscs: ['jscsPath', function (cb, r) {
        spawn(r.jscsPath, jscsArgs, cb)
      }]
    }, function (err, r) {
      if (err) return error(err)
      if (r.eslint !== 0 || r.jscs !== 0) printErrors()
    })
  }

  function findBinPath (bin, cb) {
    var opts = { cwd: __dirname }
    cp.exec('npm run --silent which-' + bin, opts, function (err, stdout) {
      if (err) return cb(err)
      cb(null, stdout.toString().replace(/\n/g, ''))
    })
  }

  function spawn (command, args, cb) {
    debug(command + ' ' + args.join(' '))
    var child = cp.spawn(command, args)
    child.on('error', cb)
    child.on('close', function (code) {
      cb(null, code)
    })
    if (opts.stdin) {
      str(stdinData).pipe(child.stdin)
    }
    stderrPipe(child.stdout)
    stderrPipe(child.stderr)
  }

  function stderrPipe (readable) {
    readable
      .pipe(split())
      .on('data', function (line) {
        if (line === '') return
        errors.push(line)
      })
  }

  function printErrors () {
    console.error('Error: Use JavaScript Standard Style (https://github.com/feross/standard)')
    var unexpectedOutput = []
    var errMap = {}
    errors
      .map(function (str) { // normalize stdin "filename"
        return str.replace(/^(<text>|input)/, 'stdin')
      })
      .filter(function (str) {
        // don't process unexpected/malformed output, just print it at the end
        if (!ERROR_RE.test(str)) {
          unexpectedOutput.push(str)
          return false
        }

        // de-duplicate errors
        if (errMap[str]) return false
        errMap[str] = true
        return true
      })
      .sort(function (a, b) {
        // sort by line number (merges output from all linters)
        var fileA = FILE_RE.exec(a)[1]
        var fileB = FILE_RE.exec(b)[1]

        var lineA = Number(LINE_RE.exec(a)[1])
        var lineB = Number(LINE_RE.exec(b)[1])

        var colA = Number(COL_RE.exec(a)[1])
        var colB = Number(COL_RE.exec(b)[1])

        if (fileA !== fileB) return fileA < fileB ? -1 : 1
        if (lineA !== lineB) return lineA - lineB
        return colA - colB
      })
      .forEach(function (str) {
        console.error('  ' + str) // indent
      })

    if (unexpectedOutput.length) console.error('\nUnexpected Linter Output:')
    unexpectedOutput.forEach(function (str) {
      console.error(str)
    })

    process.exit(1)
  }
}

function error (err) {
  console.error(err.stack || err.message || err)
  process.exit(1)
}
<commit_msg>Better unexpected output handling<commit_after>module.exports = standard

var auto = require('run-auto')
var cp = require('child_process')
var debug = require('debug')('standard')
var findRoot = require('find-root')
var fs = require('fs')
var glob = require('glob')
var parallel = require('run-parallel')
var path = require('path')
var split = require('split')
var standardFormat = require('standard-format')
var stdin = require('get-stdin')
var str = require('string-to-stream')
var uniq = require('uniq')

var JSCS_RC = path.join(__dirname, 'rc', '.jscsrc')
var JSCS_REPORTER = path.join(__dirname, 'lib', 'jscs-reporter.js')
var JSCS_REPORTER_VERBOSE = path.join(__dirname, 'lib', 'jscs-reporter-verbose.js')

var ESLINT_RC = path.join(__dirname, 'rc', '.eslintrc')
var ESLINT_REPORTER = path.join(__dirname, 'lib', 'eslint-reporter.js')
var ESLINT_REPORTER_VERBOSE = path.join(__dirname, 'lib', 'eslint-reporter-verbose.js')

var DEFAULT_IGNORE = [
  '**/node_modules/**',
  '.git/**',
  '**/*.min.js',
  '**/bundle.js',
  'coverage/**'
]

var ERROR_RE = /.*?:\d+:\d+:/
var FILE_RE = /(.*?):/
var LINE_RE = /.*?:(\d+)/
var COL_RE = /.*?:\d+:(\d+)/

/**
 * JavaScript Standard Style
 *
 * @param {Object} opts                        options object
 * @param {string|Array.<String>} opts.ignore  files to ignore
 * @param {string} opts.cwd                    current working directory
 * @param {Array.<string>} opts.files          files to check
 * @param {boolean} opts.stdin                 check text from stdin instead of filesystem
 * @param {boolean} opts.verbose               show error codes
 * @param {boolean} opts.format                format code using standard-format before linting
 */
function standard (opts) {
  if (!opts) opts = {}
  var errors = []

  var root
  try {
    root = findRoot(process.cwd())
  } catch (e) {}

  var ignore = (opts.ignore || []).concat(DEFAULT_IGNORE) // globs to ignore

  if (root) {
    var packageOpts = require(path.join(root, 'package.json')).standard
    if (packageOpts) ignore = ignore.concat(packageOpts.ignore)
  }

  var jscsReporter = opts.verbose ? JSCS_REPORTER_VERBOSE : JSCS_REPORTER
  var jscsArgs = ['--config', JSCS_RC, '--reporter', jscsReporter]

  var eslintReporter = opts.verbose ? ESLINT_REPORTER_VERBOSE : ESLINT_REPORTER
  var eslintArgs = ['--config', ESLINT_RC, '--format', eslintReporter]

  if (opts.verbose) {
    jscsArgs.push('--verbose')
  }

  var stdinData

  if ((Array.isArray(opts.files) && opts.files.length > 0) || !opts.stdin) {
    var patterns = (Array.isArray(opts.files) && opts.files.length > 0)
      ? opts.files
      : [ '**/*.js' ]

    // traverse filesystem
    parallel(patterns.map(function (pattern) {
      return function (cb) {
        glob(pattern, {
          cwd: opts.cwd || process.cwd(),
          nodir: true,
          ignore: ignore
        }, cb)
      }
    }), function (err, results) {
      if (err) return error(err)

      // flatten nested arrays
      var files = results.reduce(function (files, result) {
        result.forEach(function (file) {
          files.push(file)
        })
        return files
      }, [])

      // de-dupe
      files = uniq(files)
      if (files.length > 0) {
        if (opts.format) {
          format(files)
        }
        jscsArgs = jscsArgs.concat(files)
        eslintArgs = eslintArgs.concat(files)
        lint()
      }
    })
  } else {
    // stdin
    eslintArgs.push('--stdin')

    stdin(function (data) {
      stdinData = data

      if (opts.format) {
        stdinData = standardFormat.transform(stdinData)
        process.stdout.write(stdinData)
        process.stderr.write('\n')
      }

      lint()
    })
  }

  function format (files) {
    files.forEach(function (file) {
      var data = fs.readFileSync(file).toString()
      fs.writeFileSync(file, standardFormat.transform(data))
    })
  }

  function lint () {
    auto({
      eslintPath: findBinPath.bind(undefined, 'eslint'),
      jscsPath: findBinPath.bind(undefined, 'jscs'),
      eslint: ['eslintPath', function (cb, r) {
        spawn(r.eslintPath, eslintArgs, cb)
      }],
      jscs: ['jscsPath', function (cb, r) {
        spawn(r.jscsPath, jscsArgs, cb)
      }]
    }, function (err, r) {
      if (err) return error(err)
      if (r.eslint !== 0 || r.jscs !== 0) printErrors()
    })
  }

  function findBinPath (bin, cb) {
    var opts = { cwd: __dirname }
    cp.exec('npm run --silent which-' + bin, opts, function (err, stdout) {
      if (err) return cb(err)
      cb(null, stdout.toString().replace(/\n/g, ''))
    })
  }

  function spawn (command, args, cb) {
    debug(command + ' ' + args.join(' '))
    var child = cp.spawn(command, args)
    child.on('error', cb)
    child.on('close', function (code) {
      cb(null, code)
    })
    if (opts.stdin) {
      str(stdinData).pipe(child.stdin)
    }
    stderrPipe(child.stdout)
    stderrPipe(child.stderr)
  }

  function stderrPipe (readable) {
    readable
      .pipe(split())
      .on('data', function (line) {
        if (line === '') return
        errors.push(line)
      })
  }

  function printErrors () {
    console.error('Error: Use JavaScript Standard Style (https://github.com/feross/standard)')
    var unexpectedOutput = []
    var errMap = {}
    errors
      .map(function (str) { // normalize stdin "filename"
        return str.replace(/^(<text>|input)/, 'stdin')
      })
      .filter(function (str) {
        // don't process unexpected/malformed output, just print it at the end
        if (!ERROR_RE.test(str)) {
          unexpectedOutput.push(str)
          return false
        }

        // de-duplicate errors
        if (errMap[str]) return false
        errMap[str] = true
        return true
      })
      .sort(function (a, b) {
        // sort by line number (merges output from all linters)
        var fileA = FILE_RE.exec(a)[1]
        var fileB = FILE_RE.exec(b)[1]

        var lineA = Number(LINE_RE.exec(a)[1])
        var lineB = Number(LINE_RE.exec(b)[1])

        var colA = Number(COL_RE.exec(a)[1])
        var colB = Number(COL_RE.exec(b)[1])

        if (fileA !== fileB) return fileA < fileB ? -1 : 1
        if (lineA !== lineB) return lineA - lineB
        return colA - colB
      })
      .forEach(function (str) {
        console.error('  ' + str) // indent
      })

    if (unexpectedOutput.length) {
      console.error('\nUnexpected Linter Output:')
    }
    unexpectedOutput.forEach(function (str) {
      console.error(str)
    })
    if (unexpectedOutput.length) {
      console.error('\nIf you think this is a bug in `standard`, open an issue: https://github.com/feross/standard')
    }

    process.exit(1)
  }
}

function error (err) {
  console.error(err.stack || err.message || err)
  process.exit(1)
}
<|endoftext|>


<commit_before>'use strict';

var assert = require('assert');
var stream = require('stream');
var http = require('http');
var url = require('url');
var fh = require('./index');
var Request = fh.Request;

fh.agent = false; // opt out of connection pooling - makes the tests fail

describe('flowHttp.Request', function () {
  it('should be a duplex stream', function () {
    assert(Request.prototype instanceof stream.Duplex, 'The Request object should be an instance of stream.Duplex');
  });
});

describe('request', function () {
  var req;

  before(function () {
    req = new Request(url.parse('http://example.com'));
  });

  it('should have the original http.ClientRequest object', function () {
    assert(req.req instanceof http.ClientRequest);
  });

  it('should have the reqular http.ClientRequest methods', function () {
    assert.strictEqual(typeof req.setHeader, 'function');
    assert.strictEqual(typeof req.getHeader, 'function');
    assert.strictEqual(typeof req.removeHeader, 'function');
  });
});

describe('flowHttp module', function () {
  it('shoud be a function', function () {
    assert.strictEqual(typeof fh, 'function');
  });

  it('should have functions for each REST HTTP method', function () {
    assert.strictEqual(typeof fh.get, 'function');
    assert.strictEqual(typeof fh.post, 'function');
    assert.strictEqual(typeof fh.put, 'function');
    assert.strictEqual(typeof fh.del, 'function');
  });

  it('should alias fh as fh.get', function () {
    assert.strictEqual(fh, fh.get);
  });
});

describe('flowHttp', function () {
  var url = 'http://localhost:5000';
  var server;

  before(function (done) {
    server = http.createServer(function (req, res) {
      res.end('server response');
    });
    server.listen(5000, done);
  });

  after(function () {
    server.close();
  });

  it('should return instances of Request', function () {
    assert(fh.request(url) instanceof Request, '.request() should return an instance of Request');
    assert(fh(url) instanceof Request, 'Implicit GET should return an instance of Request');
    assert(fh.get(url) instanceof Request, 'Explicit GET should return an instance of Request');
    assert(fh.post(url) instanceof Request, 'POST should return an instance of Request');
    assert(fh.put(url) instanceof Request, 'PUT should return an instance of Request');
    assert(fh.del(url) instanceof Request, 'DELETE should return an instance of Request');
  });

  it('should include the original http.IncomingMessage object on the returned Request object', function (done) {
    var req = fh(url);
    req.on('response', function (res) {
      assert(res instanceof http.IncomingMessage);
      assert.strictEqual(req.res, res);
      done();
    });
  });

  ['get', 'del'].forEach(function (method) {
    describe('fh.' + method, function () {
      var response = false;
      before(function (done) {
        var req = fh[method](url).on('response', function (res) {
          response = true;
          done();
        });
        setTimeout(function () {
          if (!response) done(new Error('the response event was never emitted'));
        }, 100);
      });

      it('should autimatically send the request', function () {
        assert.ok(response);
      });
    });
  });

  ['request', 'post', 'put'].forEach(function (method) {
    describe('fh.' + method, function () {
      before(function (done) {
        var req = fh[method](url).on('response', function () {
          done(new Error('the response event should not have been emitted'));
        });
        setTimeout(done, 100);
      });

      it('should not autimatically send the request', function () {
        assert(true);
      });
    });
  });

  ['get', 'del'].forEach(function (method) {
    describe('fh.' + method, function () {
      var data = false, end = false, body = '';

      before(function (done) {
        fh[method](url)
          .on('data', function (chunk) {
            body += chunk;
            data = true;
          })
          .on('end', function () {
            end = true;
            done();
          });
        setTimeout(function () {
          if (!end) done(new Error('the end event was never fired'));
        }, 100);
      });

      it('should emit a data event', function () {
        assert.ok(data);
      });

      it('should emit an end event', function () {
        assert.ok(end);
      });

      it('should get expected body', function () {
        assert.equal(body, 'server response');
      });
    });
  });

  ['post', 'put'].forEach(function (method) {
    describe('Write to fh.' + method, function () {
      var data = false, end = false, body = '';

      before(function (done) {
        var req = fh[method](url)
          .on('data', function (chunk) {
            body += chunk;
            data = true;
          })
          .on('end', function () {
            end = true;
            done();
          });
        req.end('sending data...');
        setTimeout(function () {
          if (!end) done(new Error('the end event was never fired'));
        }, 100);
      });

      it('should emit a data event', function () {
        assert.ok(data);
      });

      it('should emit an end event', function () {
        assert.ok(end);
      });

      it('should get expected body', function () {
        assert.equal(body, 'server response');
      });
    });

    describe('Pipe to fh.' + method, function () {
      var data = false, end = false, body = '';

      before(function (done) {
        var readableStream = require('fs').createReadStream(__filename);
        readableStream.pipe(fh[method](url))
          .on('data', function (chunk) {
            body += chunk;
            data = true;
          })
          .on('end', function () {
            end = true;
            done();
          });
        setTimeout(function () {
          if (!end) done(new Error('the end event was never fired'));
        }, 100);
      });

      it('should emit a data event', function () {
        assert.ok(data);
      });

      it('should emit an end event', function () {
        assert.ok(end);
      });

      it('should get expected body', function () {
        assert.equal(body, 'server response');
      });
    });
  });
});
<commit_msg>Clean up tests<commit_after>'use strict';

var assert = require('assert');
var stream = require('stream');
var http = require('http');
var url = require('url');
var fh = require('./index');
var Request = fh.Request;

fh.agent = false; // opt out of connection pooling - makes the tests fail

describe('flowHttp.Request', function () {
  it('should be a duplex stream', function () {
    assert(Request.prototype instanceof stream.Duplex, 'The Request object should be an instance of stream.Duplex');
  });
});

describe('request', function () {
  var req;

  before(function () {
    req = new Request(url.parse('http://example.com'));
  });

  it('should have the original http.ClientRequest object', function () {
    assert(req.req instanceof http.ClientRequest);
  });

  it('should have the reqular http.ClientRequest methods', function () {
    assert.strictEqual(typeof req.setHeader, 'function');
    assert.strictEqual(typeof req.getHeader, 'function');
    assert.strictEqual(typeof req.removeHeader, 'function');
  });
});

describe('flowHttp module', function () {
  it('shoud be a function', function () {
    assert.strictEqual(typeof fh, 'function');
  });

  it('should have functions for each REST HTTP method', function () {
    assert.strictEqual(typeof fh.get, 'function');
    assert.strictEqual(typeof fh.post, 'function');
    assert.strictEqual(typeof fh.put, 'function');
    assert.strictEqual(typeof fh.del, 'function');
  });

  it('should alias fh as fh.get', function () {
    assert.strictEqual(fh, fh.get);
  });
});

describe('flowHttp', function () {
  var url = 'http://localhost:5000';
  var server;

  before(function (done) {
    server = http.createServer(function (req, res) {
      res.end('server response');
    });
    server.listen(5000, done);
  });

  after(function () {
    server.close();
  });

  it('should return instances of Request', function () {
    assert(fh.request(url) instanceof Request, '.request() should return an instance of Request');
    assert(fh(url) instanceof Request, 'Implicit GET should return an instance of Request');
    assert(fh.get(url) instanceof Request, 'Explicit GET should return an instance of Request');
    assert(fh.post(url) instanceof Request, 'POST should return an instance of Request');
    assert(fh.put(url) instanceof Request, 'PUT should return an instance of Request');
    assert(fh.del(url) instanceof Request, 'DELETE should return an instance of Request');
  });

  it('should include the original http.IncomingMessage object on the returned Request object', function (done) {
    var req = fh(url);
    req.on('response', function (res) {
      assert(res instanceof http.IncomingMessage);
      assert.strictEqual(req.res, res);
      done();
    });
  });

  ['get', 'del'].forEach(function (method) {
    describe('fh.' + method, function () {
      before(function (done) {
        fh[method](url).on('response', function () {
          done();
        });
      });

      it('should autimatically send the request', function () {
        assert(true);
      });
    });
  });

  ['request', 'post', 'put'].forEach(function (method) {
    describe('fh.' + method, function () {
      before(function (done) {
        fh[method](url).on('response', function () {
          done(new Error('the response event should not have been emitted'));
        });
        setTimeout(done, 100);
      });

      it('should not autimatically send the request', function () {
        assert(true);
      });
    });
  });

  ['get', 'del'].forEach(function (method) {
    describe('fh.' + method, function () {
      var data = false, end = false, body = '';

      before(function (done) {
        fh[method](url)
          .on('data', function (chunk) {
            body += chunk;
            data = true;
          })
          .on('end', function () {
            end = true;
            done();
          });
      });

      it('should emit a data event', function () {
        assert.ok(data);
      });

      it('should emit an end event', function () {
        assert.ok(end);
      });

      it('should get expected body', function () {
        assert.equal(body, 'server response');
      });
    });
  });

  ['post', 'put'].forEach(function (method) {
    describe('Write to fh.' + method, function () {
      var data = false, end = false, body = '';

      before(function (done) {
        var req = fh[method](url)
          .on('data', function (chunk) {
            body += chunk;
            data = true;
          })
          .on('end', function () {
            end = true;
            done();
          });
        req.end('sending data...');
      });

      it('should emit a data event', function () {
        assert.ok(data);
      });

      it('should emit an end event', function () {
        assert.ok(end);
      });

      it('should get expected body', function () {
        assert.equal(body, 'server response');
      });
    });

    describe('Pipe to fh.' + method, function () {
      var data = false, end = false, body = '';

      before(function (done) {
        var readableStream = require('fs').createReadStream(__filename);
        readableStream.pipe(fh[method](url))
          .on('data', function (chunk) {
            body += chunk;
            data = true;
          })
          .on('end', function () {
            end = true;
            done();
          });
      });

      it('should emit a data event', function () {
        assert.ok(data);
      });

      it('should emit an end event', function () {
        assert.ok(end);
      });

      it('should get expected body', function () {
        assert.equal(body, 'server response');
      });
    });
  });
});
<|endoftext|>


<commit_before>const express = require('express');
const app = express();
const backpat = require('backpat').backpat;

app.use(express.static('./'));
app.use(express.static('dist'));

app.get('/favicon.ico', (req, res) => {
  res.sendFile(`${__dirname}/favicon.ico`);
});

app.get('/deps', (req, res) => {
  backpat().then(res.send.bind(res));
});

app.get('*', (req, res) => {
  res.sendFile(`${__dirname}/dist/index.html`);
});

const port = process.env.PORT || 3000;

app.listen(port, () => {
  console.log('app listening on', port);
});
<commit_msg>refactor: Move deps api into subapp<commit_after>const express = require('express');
const backpat = require('backpat').backpat;

const deps = express();

deps.get('/', (req, res) => {
  backpat().then(res.send.bind(res));
});

const app = express();

app.use(express.static('./'));
app.use(express.static('dist'));
app.use('/deps', deps);

app.get('/favicon.ico', (req, res) => {
  res.sendFile(`${__dirname}/favicon.ico`);
});

app.get('/deps', (req, res) => {
  backpat().then(res.send.bind(res));
});

app.get('*', (req, res) => {
  res.sendFile(`${__dirname}/dist/index.html`);
});

const port = process.env.PORT || 3000;

app.listen(port, () => {
  console.log('app listening on', port);
});
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2015 Stephen Howell, stephenhowell@outlook.com

//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.

(function (ext) {

    var jointData = { rightHandState: "Unknown", leftHandState: "Unknown", "SpineBase": null, "SpineMid": null, "Neck": null, "Head": null, "ShoulderLeft": null, "ElbowLeft": null, "WristLeft": null, "HandLeft": null, "ShoulderRight": null, "ElbowRight": null, "WristRight": null, "HandRight": null, "HipLeft": null, "KneeLeft": null, "AnkleLeft": null, "FootLeft": null, "HipRight": null, "KneeRight": null, "AnkleRight": null, "FootRight": null, "SpineShoulder": null, "HandTipLeft": null, "ThumbLeft": null, "HandTipRight": null, "ThumbRight": null };

    var bodies = [jointData, jointData, jointData, jointData, jointData, jointData, jointData]; // Closest and 6 maximum bodies

    var numTracked = 0;

    var entry = false;
    var exit = false;

    var connection = new WebSocket('ws://localhost:8181/');

    ext.connect = function (address, port)
    {
        connection = new WebSocket('ws://' + address + ':' + port + '/');
    };

    connection.onopen = function () {
        console.log('Connection to localhost:8181 open!');
    }

    connection.onclose = function () {
        console.log('Connection to localhost:8181 closed!');
    }

    connection.onerror = function (error) {
        console.log('Error detected: ' + error.toString());
    }

    connection.onmessage = function (e) {
        var kdata = JSON.parse(e.data); // console.log(JSON.stringify(kdata));

        // Check if it's a body (could be a face etc.)
        if (kdata.type == "body") {
            bodies[kdata.index] = kdata.joints;
            bodies[kdata.index]["rightHandState"] = kdata.rightHandState;
            bodies[kdata.index]["leftHandState"] = kdata.leftHandState;
            numTracked = kdata.numTracked;
        }
        else if (kdata.type == "event")
        {
            if(kdata.eventType == "entry")
            {
                entry = true;
            }
            else if(kdata.eventType == "exit")
            {
                exit = true;
            }

        }
    }

    // Cleanup function when the extension is unloaded
    ext._shutdown = function () { if (connection.socket.connected) { connection.socket.disconnect(); } };

    // Status reporting code
    // Use this to report missing hardware, plugin or unsupported browser
    ext._getStatus = function () {
        if (connection.readyState == 1) {
            return { status: 2, msg: 'Connected' };
        }
        else {
            connection = new WebSocket('ws://localhost:8181/'); // Does nae work at all
            return {
                status: 1, msg: 'Not connected, attempting reconnection, make sure Kinect2ScratchX is running!'
            };
        }
    };

    ext.Disconnect = function (callback) {
        if (!(connection === null)) {
            if (connection.readyState == 1) {
                //console.log("disconnecting from server");
                connection.close();
            } else { console.log("Disconnect: socket already disconnected"); }
        }
    };

    // There must be a nicer way to do this
    ext.convertDescToIndex = function (bodyDesc) {
        switch (bodyDesc)
        {
            case 'Closest Person': return 0; break;
            case 'Person 1': return 1; break;
            case 'Person 2': return 2; break;
            case 'Person 3': return 3; break;
            case 'Person 4': return 4; break;
            case 'Person 5': return 5; break;
            case 'Person 6': return 6; break;
        }
        return 0;
    };

    ext.getLimbValue = function (coordinate, side, bodyPart, desc)
    {
        var index = convertDescToIndex(desc);
        var joint = bodies[index].jointData[bodyPart + side]; // bodies...index...
        console.log("Joint is " + JSON.stringify(joint));
        if (coordinate == "x")
            return joint[0];
        else if (coordinate == "y")
            return joint[1];
        else if (coordinate == "z")
            return joint[2];
        else
            return 0;
    };

    ext.getTorsoValue = function (coordinate, torsoJoint, desc) {
        var index = convertDescToIndex(desc);
        var joint = bodies[index].jointData[torsoJoint];
        if (coordinate == "x")
            return joint[0];
        else if (coordinate == "y")
            return joint[1];
        else if (coordinate == "z")
            return joint[2];
        else
            return 0;
    };

    ext.getHandState = function (side, state, index) {
        if (side == "Right" && rightHandState == state)
            return true;

        if (side == "Left" && leftHandState == state)
            return true;

        return false;
    };

    ext.userEntered = function () {
        var result = entry;
        entry = false;
        return result;
    };

    ext.userLost = function () {
        var result = exit;
        exit = false;
        return result;
    };

    // Block and block menu descriptions
    var descriptor = {
        blocks: [
            ['h', 'When a person enters view', 'userEntered'],
            ['r', 'number of tracked people', 'getTrackedUsers'],
            ['r', '%m.coordinate of %m.side %m.limbs of %m.index', 'getLimbValue', 'x', 'Right', 'Hand', 'Closest Person'],
            ['r', '%m.coordinate of %m.side %m.limbs of %m.index', 'getLimbValue', 'y', 'Right', 'Hand', 'Closest Person'],
            ['r', '%m.coordinate of %m.side %m.limbs of %m.index', 'getLimbValue', 'z', 'Right', 'Hand', 'Closest Person'],
			['r', '%m.coordinate of %m.torso of %m.index', 'getTorsoValue', 'x', 'Head', 'Closest Person'],
			['b', '%m.index %m.side Hand is %m.state', 'getHandState', 'Closest Person', 'Right', 'Closed'],
            ['b', '%m.index %m.side Hand is %m.state', 'getHandState', 'Closest Person', 'Left', 'Lasso'],
            ['h', 'When a person exits view', 'userLost']
        ],
        menus: {
            index: ["Closest Person", "Person 1", "Person 2", "Person 3", "Person 4", "Person 5", "Person 6"],
            coordinate: ["x", "y", "z"],
            side: ["Right", "Left"],
            swipeDirections: ["Right", "Left", "Up", "Down"],
            state: ["Open", "Closed", "Lasso", "Unknown"],
            torso: ["Head", "Neck", "SpineShoulder", "SpineMid", "SpineBase"],
            limbs: ["Shoulder", "Elbow", "Wrist", "Hand", "HandTip", "Thumb", "Hip", "Knee", "Ankle", "Foot"]
        },
        url: 'http://stephenhowell.github.io'
    };

    // Register the extension
    ScratchExtensions.register('Kinect To ScratchX 3', descriptor, ext);

})({});

<commit_msg>morning<commit_after>// The MIT License (MIT)

// Copyright (c) 2015 Stephen Howell, stephenhowell@outlook.com

//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.

(function (ext) {

    var jointData = { rightHandState: "Unknown", leftHandState: "Unknown", "SpineBase": null, "SpineMid": null, "Neck": null, "Head": null, "ShoulderLeft": null, "ElbowLeft": null, "WristLeft": null, "HandLeft": null, "ShoulderRight": null, "ElbowRight": null, "WristRight": null, "HandRight": null, "HipLeft": null, "KneeLeft": null, "AnkleLeft": null, "FootLeft": null, "HipRight": null, "KneeRight": null, "AnkleRight": null, "FootRight": null, "SpineShoulder": null, "HandTipLeft": null, "ThumbLeft": null, "HandTipRight": null, "ThumbRight": null };

    var bodies = [jointData, jointData, jointData, jointData, jointData, jointData, jointData]; // Closest and 6 maximum bodies

    var numTracked = 0;

    var entry = false;
    var exit = false;

    var connection = new WebSocket('ws://localhost:8181/');

    ext.connect = function (address, port)
    {
        connection = new WebSocket('ws://' + address + ':' + port + '/');
    };

    connection.onopen = function () {
        console.log('Connection to localhost:8181 open!');
    }

    connection.onclose = function () {
        console.log('Connection to localhost:8181 closed!');
    }

    connection.onerror = function (error) {
        console.log('Error detected: ' + error.toString());
    }

    connection.onmessage = function (e) {
        var kdata = JSON.parse(e.data); // console.log(JSON.stringify(kdata));

        // Check if it's a body (could be a face etc.)
        if (kdata.type == "body") {
            bodies[kdata.index] = kdata.joints;
            bodies[kdata.index]["rightHandState"] = kdata.rightHandState;
            bodies[kdata.index]["leftHandState"] = kdata.leftHandState;
            numTracked = kdata.numTracked;
        }
        else if (kdata.type == "event")
        {
            if(kdata.eventType == "entry")
            {
                entry = true;
            }
            else if(kdata.eventType == "exit")
            {
                exit = true;
            }

        }
    }

    // Cleanup function when the extension is unloaded
    ext._shutdown = function () { if (connection.socket.connected) { connection.socket.disconnect(); } };

    // Status reporting code
    // Use this to report missing hardware, plugin or unsupported browser
    ext._getStatus = function () {
        if (connection.readyState == 1) {
            return { status: 2, msg: 'Connected' };
        }
        else {
            connection = new WebSocket('ws://localhost:8181/'); // Does nae work at all
            return {
                status: 1, msg: 'Not connected, attempting reconnection, make sure Kinect2ScratchX is running!'
            };
        }
    };

    ext.Disconnect = function (callback) {
        if (!(connection === null)) {
            if (connection.readyState == 1) {
                //console.log("disconnecting from server");
                connection.close();
            } else { console.log("Disconnect: socket already disconnected"); }
        }
    };

    // There must be a nicer way to do this
    ext.convertDescToIndex = function (bodyDesc) {
        switch (bodyDesc)
        {
            case 'Closest Person': return 0; break;
            case 'Person 1': return 1; break;
            case 'Person 2': return 2; break;
            case 'Person 3': return 3; break;
            case 'Person 4': return 4; break;
            case 'Person 5': return 5; break;
            case 'Person 6': return 6; break;
        }
        return 0;
    };

    ext.getLimbValue = function (coordinate, side, bodyPart, desc)
    {
        var index = convertDescToIndex(desc);
        var joint = bodies[index].jointData[bodyPart + side]; // bodies...index...
        console.log("Joint is " + JSON.stringify(joint));
        if (coordinate == "x")
            return joint[0];
        else if (coordinate == "y")
            return joint[1];
        else if (coordinate == "z")
            return joint[2];
        else
            return 0;
    };

    ext.getTorsoValue = function (coordinate, torsoJoint, desc) {
        var index = convertDescToIndex(desc);
        var joint = bodies[index].jointData[torsoJoint];
        if (coordinate == "x")
            return joint[0];
        else if (coordinate == "y")
            return joint[1];
        else if (coordinate == "z")
            return joint[2];
        else
            return 0;
    };

    ext.getHandState = function (side, state, index) {
        if (side == "Right" && rightHandState == state)
            return true;

        if (side == "Left" && leftHandState == state)
            return true;

        return false;
    };

    ext.userEntered = function () {
        var result = entry;
        entry = false;
        return result;
    };

    ext.userLost = function () {
        var result = exit;
        exit = false;
        return result;
    };

    // Block and block menu descriptions
    var descriptor = {
        blocks: [
            ['h', 'When a person enters view', 'userEntered'],
            ['r', 'number of tracked people', 'getTrackedUsers'],
            ['r', '%m.coordinate of %m.side %m.limbs of %m.index', 'getLimbValue', 'x', 'Right', 'Hand', 'Closest Person'],
            ['r', '%m.coordinate of %m.side %m.limbs of %m.index', 'getLimbValue', 'y', 'Right', 'Hand', 'Closest Person'],
            ['r', '%m.coordinate of %m.side %m.limbs of %m.index', 'getLimbValue', 'z', 'Right', 'Hand', 'Closest Person'],
			['r', '%m.coordinate of %m.torso of %m.index', 'getTorsoValue', 'x', 'Head', 'Closest Person'],
			['b', '%m.side Hand is %m.state of %m.index', 'getHandState', 'Right', 'Closed', 'Closest Person'],
            ['b', '%m.side Hand is %m.state of %m.index', 'getHandState', 'Left', 'Lasso', 'Closest Person'],
            ['h', 'When a person exits view', 'userLost']
        ],
        menus: {
            index: ["Closest Person", "Person 1", "Person 2", "Person 3", "Person 4", "Person 5", "Person 6"],
            coordinate: ["x", "y", "z"],
            side: ["Right", "Left"],
            swipeDirections: ["Right", "Left", "Up", "Down"],
            state: ["Open", "Closed", "Lasso", "Unknown"],
            torso: ["Head", "Neck", "SpineShoulder", "SpineMid", "SpineBase"],
            limbs: ["Shoulder", "Elbow", "Wrist", "Hand", "HandTip", "Thumb", "Hip", "Knee", "Ankle", "Foot"]
        },
        url: 'http://stephenhowell.github.io'
    };

    // Register the extension
    ScratchExtensions.register('Kinect To ScratchX 3', descriptor, ext);

})({});

<|endoftext|>


<commit_before>var Router = require("routes")
var url = require("url")
var location = require("global/document").location

module.exports = HashRouter

function HashRouter(opts) {
    function applyChange(event) {
        var hash = getRoute()

        var route = router.match(hash)
        if (route) {
            var newHash = hash
            var oldHash = "/"

            if (event) {
                var newUrl = url.parse(event.newURL)
                if (newUrl && "hash" in newUrl) {
                    newHash = newUrl.hash.substring(1)
                }

                var oldUrl = url.parse(event.oldURL)
                if (oldUrl && "hash" in oldUrl) {
                    oldHash = oldUrl.hash.substring(1)
                }
            }

            route.fn(hash, {
                params: route.params,
                splats: route.splats,
                newUrl: newHash,
                oldUrl: oldHash
            })
        }
    }

    opts = opts || {}
    var setRoute = opts.setRoute || defaultSetRoute
    var getRoute = opts.getRoute || defaultGetRoute

    var router = Router()

    applyChange.go = setRoute
    applyChange.addRoute = router.addRoute.bind(router)

    return applyChange
}

function defaultSetRoute(uri) {
    location.hash = "#" + uri
}

function defaultGetRoute() {
    return location.hash.substring(1)
}
<commit_msg>updated default & expose get<commit_after>var Router = require("routes")
var url = require("url")
var location = require("global/document").location

module.exports = HashRouter

function HashRouter(opts) {
    function applyChange(event) {
        var hash = getRoute() || "/"

        var route = router.match(hash)
        if (route) {
            var newHash = hash
            var oldHash = "/"

            if (event) {
                var newUrl = url.parse(event.newURL)
                if (newUrl && "hash" in newUrl) {
                    newHash = newUrl.hash.substring(1)
                }

                var oldUrl = url.parse(event.oldURL)
                if (oldUrl && "hash" in oldUrl) {
                    oldHash = oldUrl.hash.substring(1)
                }
            }

            route.fn(hash, {
                params: route.params,
                splats: route.splats,
                newUrl: newHash,
                oldUrl: oldHash
            })
        }
    }

    opts = opts || {}
    var setRoute = opts.setRoute || defaultSetRoute
    var getRoute = opts.getRoute || defaultGetRoute

    var router = Router()

    applyChange.go = setRoute
    applyChange.get = getRoute
    applyChange.addRoute = router.addRoute.bind(router)

    return applyChange
}

function defaultSetRoute(uri) {
    location.hash = "#" + uri
}

function defaultGetRoute() {
    return location.hash.substring(1)
}
<|endoftext|>


<commit_before>
var _            = require("lodash"),
    async        = require("async"),
    url          = require("url"),
    uuid         = require("uuid"),
    SockJS       = require("sockjs-client"),
    RestJS       = require("restjs"),
    EventEmitter = require("events").EventEmitter;

var MAX_DELAY = 5 * 1000,
    MIN_DELAY = 10,
    dt = 5;

var nextDelay = function(last){
  return Math.min(last * dt, MAX_DELAY);
};

if(typeof RestJS === "object" && RestJS.Rest)
  RestJS = RestJS.Rest;

var Monitor = function(socket, emitter){
  this._socket = socket;
  this._inTransit = {};
  this._emitter = emitter;
};

Monitor.prototype.sendMessage = function(data, callback){
  if(typeof data === "string")
    data = JSON.parse(data);
  data.uuid = uuid.v4();
  if(!this._inTransit[data.rpc])
    this._inTransit[data.rpc] = {};
  this._inTransit[data.rpc][data.uuid] = callback || _.noop;
  this._socket.send(JSON.stringify(data));
};

Monitor.prototype.handleResponse = function(data){
  var fn = null;
  if(data.rpc && data.uuid)
    fn = this._inTransit[data.rpc][data.uuid];
  if(fn && typeof fn === "function"){
    if(data.error)
      fn(data.error);
    else
      fn(null, data.resp);
    delete this._inTransit[data.rpc][data.uuid];
    if(Object.keys(this._inTransit[data.rpc]).length === 0)
      delete this._inTransit[data.rpc];
  }
  if(data.channel){
    this._emitter.emit("message", data.channel, data.message);
  }
};

var rpcResponse = function(error, resp, instance, data){
  var res = {};
  if(error)
    res.error = error.message || error;
  else
    res.data = resp;
  var out = {
    rpc: "_rpc",
    fid: data.fid,
    resp: res
  };
  instance._socket.send(JSON.stringify(out));
};

var handleInternal = function(instance, command, data){
  if(command === "subscribe"){
    instance._channels[data.channel] = true;
  }else if(command === "unsubscribe"){
    delete instance._channels[data.channel];
  }else if(command === "rpc"){
    var fn = instance._actions;
    data.command.split(".").forEach(function(s){
      fn = fn && fn[s] ? fn[s] : null;
    });
    if(fn && typeof fn === "function"){
      fn(data.args, function(error, resp){
        rpcResponse(error, resp, instance, data);
      });
    }
  }
};

var attemptReconnect = function(tokenSocket){
  tokenSocket._connectTimer = setTimeout(function(instance){
    resetConnection(instance, function(error){
      if(error){
          instance._emitter.emit("reconnect", error);
          attemptReconnect(instance);
        }else{
          instance._emitter.emit("reconnect");
        }
    });
  }, tokenSocket._connectDelay, tokenSocket);
  tokenSocket._connectDelay = nextDelay(tokenSocket._connectDelay);
};

var formEncode = function(obj, prefix){
  var prop, out = [];
  for(prop in obj){
    if(!obj.hasOwnProperty(prop))
      continue;
    var key = prefix ? prefix + "[" + prop + "]" : prop,
        val = obj[prop];
    out.push(typeof val == "object" ? formEncode(val, key) : encodeURIComponent(key) + "=" + encodeURIComponent(val));
  }
  return out.join("&");
};

var request = function(client, options, data, callback){
  options = _.extend({}, options);
  options.path += (options.path.indexOf("?") < 0 ? "?" : "&") + formEncode(data);
  client.request(options, null, function(error, resp){
    if(error)
      return callback(error);
    try{
      resp = JSON.parse(resp.body);
    }catch(e){
      return callback(new Error(resp.body || "Invalid message"));
    }
    callback(resp.error ? new Error(resp.error) : null, resp);
  });
};

var resetConnection = function(tokenSocket, callback){
  request(tokenSocket._rest, tokenSocket._opts, tokenSocket._authentication, function(error, resp){
    if(error || !resp || !resp.token){
      error = error || new Error("No token found!");
      return typeof callback === "string"
          ? tokenSocket._emitter.emit(callback, error)
          : callback(error);
    }

    tokenSocket._token = resp.token;
    tokenSocket._socket = new SockJS(tokenSocket._protocol + "//" + tokenSocket._host + ":" + tokenSocket._port
      + tokenSocket._socketPrefix, [], tokenSocket._sockjs);

    tokenSocket._socket.onopen = function(){
      tokenSocket._monitor.sendMessage({
        rpc: "auth",
        token: tokenSocket._token
      }, function(error, resp){
          callback = typeof callback === "string" ? tokenSocket._emitter.emit.bind(tokenSocket._emitter, callback) : callback;
        if(error){
          callback(error);
        }else{
          delete tokenSocket._closed;
          clearInterval(tokenSocket._connectTimer);
          delete tokenSocket._connectTimer;
          tokenSocket._connectDelay = MIN_DELAY;
          replay(tokenSocket);
          callback();
        }
      });
    };

    tokenSocket._monitor = new Monitor(tokenSocket._socket, tokenSocket._emitter);

    tokenSocket._socket.onmessage = function(e){
      try{
        e.data = JSON.parse(e.data);
      }catch(ev){ return; }
      if(e.data.internal)
        handleInternal(tokenSocket, e.data.command, e.data.data);
      else
        tokenSocket._monitor.handleResponse(e.data);
    };

    tokenSocket._socket.onclose = function(){
      tokenSocket._closed = true;
      if(tokenSocket._reconnect)
        attemptReconnect(tokenSocket);
    };

  });
};

var checkAndUseConnection = function(tokenSocket, callback){
  if(tokenSocket._closed){
    tokenSocket._queue.push({
      fn: callback
    });
  }else{
    callback();
  }
};

var replay = function(tokenSocket){
  _.each(tokenSocket._channels, function(bool, channel){
    tokenSocket.subscribe(channel);
  });
  _.each(tokenSocket._queue, function(req){
    if(req.fn && typeof req.fn === "function")
      req.fn();
  });
  tokenSocket._queue = [];
};

var TokenSocket = function(options, actions){
  if(!options || !options.host)
    throw new Error("TokenSocket requires host option!");

  var self = this;
  self._emitter = new EventEmitter();

  _.each(EventEmitter.prototype, function(fn){
    self[fn] = self._emitter[fn];
  });

  self._closed = true;

  var parsed = url.parse(options.host);
  options.protocol = parsed.protocol === "https:" ? "https:" : "http:";
  if (parsed.protocol) {
    options.host = parsed.host;
  }

  if(!options.port){
    var parts = options.host.split(":");
    if(parts[1] && !isNaN(parseInt(parts[1]))){
      options.port = parseInt(parts[1]);
      options.host = parts[0];
    }
  }

  options = _.merge({
    tokenPath: "/socket/token",
    socketPrefix: "/sockets",
    authentication: {},
    reconnect: true,
    port: options.port ? options.port : (options.protocol === "https:" ? 443 : 80)
  }, options);

  _.extend(self, {
    _sockjs: options.sockjs,
    _connectDelay: MIN_DELAY,
    _connectTimer: null,
    _actions: actions || {},
    _ping: options.ping || false,
    _rest: new RestJS({ protocol: options.protocol.slice(0, options.protocol.length - 1) }),
    _reconnect: options.reconnect,
    _authentication: options.authentication,
    _socketPrefix: options.socketPrefix,
    _tokenPath: options.tokenPath,
    _channels: {},
    _queue: [],
    _host: options.host,
    _protocol: options.protocol,
    _port: options.port
  });

  if(typeof options.ready === "function")
    self.ready(options.ready);
  if(typeof options.onreconnect === "function")
    self.onreconnect(options.onreconnect);

  self._opts = {
    method: "GET",
    protocol: options.protocol,
    host: options.host,
    path: self._tokenPath,
    port: options.port
  };

  if(self._ping && self._ping > 0){
    self._pingTimer = setInterval(function(){
      if(!self._closed)
        self.rpc("_ping", {});
    }, self._ping);
  }

  resetConnection(self, "ready");
};

TokenSocket.prototype.ready = function(callback){
  this._emitter.on("ready", callback);
};

TokenSocket.prototype.onreconnect = function(callback){
  this._emitter.on("reconnect", callback);
};

TokenSocket.prototype.channels = function(){
  return Object.keys(this._channels);
};

// @rpc is the controller action
TokenSocket.prototype.rpc = function(rpc, data, callback){
  var self = this;
  checkAndUseConnection(self, function(){
    self._monitor.sendMessage({
      rpc: rpc,
      req: data
    }, callback);
  });
};

TokenSocket.prototype.register = function(actions){
  this._actions = actions;
};

TokenSocket.prototype.subscribe = function(channel, callback){
  var self = this;
  checkAndUseConnection(self, function(){
    self._channels[channel] = true;
    self._monitor.sendMessage({
      rpc: "_subscribe",
      req: { channel: channel }
     }, callback);
  });
};

TokenSocket.prototype.unsubscribe = function(channel, callback){
  var self = this;
  checkAndUseConnection(self, function(){
    delete self._channels[channel];
    self._monitor.sendMessage({
      rpc: "_unsubscribe",
      req: { channel: channel }
    }, callback);
  });
};

TokenSocket.prototype.publish = function(channel, data, callback){
  var self = this;
  checkAndUseConnection(self, function(){
    self._monitor.sendMessage({
      rpc: "_publish",
      req: {
        channel: channel,
        data: data
      }
    }, callback);
  });
};

TokenSocket.prototype.broadcast = function(data, callback){
  var self = this;
  checkAndUseConnection(self, function(){
    self._monitor.sendMessage({
      rpc: "_broadcast",
      req: { data: data }
    }, callback);
  });
};

TokenSocket.prototype.onmessage = function(callback){
  this._emitter.on("message", callback);
};

TokenSocket.prototype.end = function(callback){
  this._emitter.removeAllListeners("ready");
  this._emitter.removeAllListeners("reconnect");
  this._emitter.removeAllListeners("message");
  this._closed = true;
  this._socket.onclose = callback;
  this._socket.close();
};

module.exports = TokenSocket;
<commit_msg>node: allow passing headers to the token request<commit_after>
var _            = require("lodash"),
    async        = require("async"),
    url          = require("url"),
    uuid         = require("uuid"),
    SockJS       = require("sockjs-client"),
    RestJS       = require("restjs"),
    EventEmitter = require("events").EventEmitter;

var MAX_DELAY = 5 * 1000,
    MIN_DELAY = 10,
    dt = 5;

var nextDelay = function(last){
  return Math.min(last * dt, MAX_DELAY);
};

if(typeof RestJS === "object" && RestJS.Rest)
  RestJS = RestJS.Rest;

var Monitor = function(socket, emitter){
  this._socket = socket;
  this._inTransit = {};
  this._emitter = emitter;
};

Monitor.prototype.sendMessage = function(data, callback){
  if(typeof data === "string")
    data = JSON.parse(data);
  data.uuid = uuid.v4();
  if(!this._inTransit[data.rpc])
    this._inTransit[data.rpc] = {};
  this._inTransit[data.rpc][data.uuid] = callback || _.noop;
  this._socket.send(JSON.stringify(data));
};

Monitor.prototype.handleResponse = function(data){
  var fn = null;
  if(data.rpc && data.uuid)
    fn = this._inTransit[data.rpc][data.uuid];
  if(fn && typeof fn === "function"){
    if(data.error)
      fn(data.error);
    else
      fn(null, data.resp);
    delete this._inTransit[data.rpc][data.uuid];
    if(Object.keys(this._inTransit[data.rpc]).length === 0)
      delete this._inTransit[data.rpc];
  }
  if(data.channel){
    this._emitter.emit("message", data.channel, data.message);
  }
};

var rpcResponse = function(error, resp, instance, data){
  var res = {};
  if(error)
    res.error = error.message || error;
  else
    res.data = resp;
  var out = {
    rpc: "_rpc",
    fid: data.fid,
    resp: res
  };
  instance._socket.send(JSON.stringify(out));
};

var handleInternal = function(instance, command, data){
  if(command === "subscribe"){
    instance._channels[data.channel] = true;
  }else if(command === "unsubscribe"){
    delete instance._channels[data.channel];
  }else if(command === "rpc"){
    var fn = instance._actions;
    data.command.split(".").forEach(function(s){
      fn = fn && fn[s] ? fn[s] : null;
    });
    if(fn && typeof fn === "function"){
      fn(data.args, function(error, resp){
        rpcResponse(error, resp, instance, data);
      });
    }
  }
};

var attemptReconnect = function(tokenSocket){
  tokenSocket._connectTimer = setTimeout(function(instance){
    resetConnection(instance, function(error){
      if(error){
          instance._emitter.emit("reconnect", error);
          attemptReconnect(instance);
        }else{
          instance._emitter.emit("reconnect");
        }
    });
  }, tokenSocket._connectDelay, tokenSocket);
  tokenSocket._connectDelay = nextDelay(tokenSocket._connectDelay);
};

var formEncode = function(obj, prefix){
  var prop, out = [];
  for(prop in obj){
    if(!obj.hasOwnProperty(prop))
      continue;
    var key = prefix ? prefix + "[" + prop + "]" : prop,
        val = obj[prop];
    out.push(typeof val == "object" ? formEncode(val, key) : encodeURIComponent(key) + "=" + encodeURIComponent(val));
  }
  return out.join("&");
};

var request = function(client, options, data, callback){
  options = _.extend({}, options);
  options.path += (options.path.indexOf("?") < 0 ? "?" : "&") + formEncode(data);
  client.request(options, null, function(error, resp){
    if(error)
      return callback(error);
    try{
      resp = JSON.parse(resp.body);
    }catch(e){
      return callback(new Error(resp.body || "Invalid message"));
    }
    callback(resp.error ? new Error(resp.error) : null, resp);
  });
};

var resetConnection = function(tokenSocket, callback){
  request(tokenSocket._rest, tokenSocket._opts, tokenSocket._authentication, function(error, resp){
    if(error || !resp || !resp.token){
      error = error || new Error("No token found!");
      return typeof callback === "string"
          ? tokenSocket._emitter.emit(callback, error)
          : callback(error);
    }

    tokenSocket._token = resp.token;
    tokenSocket._socket = new SockJS(tokenSocket._protocol + "//" + tokenSocket._host + ":" + tokenSocket._port
      + tokenSocket._socketPrefix, [], tokenSocket._sockjs);

    tokenSocket._socket.onopen = function(){
      tokenSocket._monitor.sendMessage({
        rpc: "auth",
        token: tokenSocket._token
      }, function(error, resp){
          callback = typeof callback === "string" ? tokenSocket._emitter.emit.bind(tokenSocket._emitter, callback) : callback;
        if(error){
          callback(error);
        }else{
          delete tokenSocket._closed;
          clearInterval(tokenSocket._connectTimer);
          delete tokenSocket._connectTimer;
          tokenSocket._connectDelay = MIN_DELAY;
          replay(tokenSocket);
          callback();
        }
      });
    };

    tokenSocket._monitor = new Monitor(tokenSocket._socket, tokenSocket._emitter);

    tokenSocket._socket.onmessage = function(e){
      try{
        e.data = JSON.parse(e.data);
      }catch(ev){ return; }
      if(e.data.internal)
        handleInternal(tokenSocket, e.data.command, e.data.data);
      else
        tokenSocket._monitor.handleResponse(e.data);
    };

    tokenSocket._socket.onclose = function(){
      tokenSocket._closed = true;
      if(tokenSocket._reconnect)
        attemptReconnect(tokenSocket);
    };

  });
};

var checkAndUseConnection = function(tokenSocket, callback){
  if(tokenSocket._closed){
    tokenSocket._queue.push({
      fn: callback
    });
  }else{
    callback();
  }
};

var replay = function(tokenSocket){
  _.each(tokenSocket._channels, function(bool, channel){
    tokenSocket.subscribe(channel);
  });
  _.each(tokenSocket._queue, function(req){
    if(req.fn && typeof req.fn === "function")
      req.fn();
  });
  tokenSocket._queue = [];
};

var TokenSocket = function(options, actions){
  if(!options || !options.host)
    throw new Error("TokenSocket requires host option!");

  var self = this;
  self._emitter = new EventEmitter();

  _.each(EventEmitter.prototype, function(fn){
    self[fn] = self._emitter[fn];
  });

  self._closed = true;

  var parsed = url.parse(options.host);
  options.protocol = parsed.protocol === "https:" ? "https:" : "http:";
  if (parsed.protocol) {
    options.host = parsed.host;
  }

  if(!options.port){
    var parts = options.host.split(":");
    if(parts[1] && !isNaN(parseInt(parts[1]))){
      options.port = parseInt(parts[1]);
      options.host = parts[0];
    }
  }

  options = _.merge({
    tokenPath: "/socket/token",
    socketPrefix: "/sockets",
    authentication: {},
    reconnect: true,
    port: options.port ? options.port : (options.protocol === "https:" ? 443 : 80)
  }, options);

  _.extend(self, {
    _sockjs: options.sockjs,
    _connectDelay: MIN_DELAY,
    _connectTimer: null,
    _actions: actions || {},
    _ping: options.ping || false,
    _rest: new RestJS({ protocol: options.protocol.slice(0, options.protocol.length - 1) }),
    _reconnect: options.reconnect,
    _authentication: options.authentication,
    _socketPrefix: options.socketPrefix,
    _tokenPath: options.tokenPath,
    _channels: {},
    _queue: [],
    _host: options.host,
    _protocol: options.protocol,
    _port: options.port
  });

  if(typeof options.ready === "function")
    self.ready(options.ready);
  if(typeof options.onreconnect === "function")
    self.onreconnect(options.onreconnect);

  self._opts = {
    method: "GET",
    protocol: options.protocol,
    host: options.host,
    headers: options.headers || {},
    path: self._tokenPath,
    port: options.port
  };

  if(self._ping && self._ping > 0){
    self._pingTimer = setInterval(function(){
      if(!self._closed)
        self.rpc("_ping", {});
    }, self._ping);
  }

  resetConnection(self, "ready");
};

TokenSocket.prototype.ready = function(callback){
  this._emitter.on("ready", callback);
};

TokenSocket.prototype.onreconnect = function(callback){
  this._emitter.on("reconnect", callback);
};

TokenSocket.prototype.channels = function(){
  return Object.keys(this._channels);
};

// @rpc is the controller action
TokenSocket.prototype.rpc = function(rpc, data, callback){
  var self = this;
  checkAndUseConnection(self, function(){
    self._monitor.sendMessage({
      rpc: rpc,
      req: data
    }, callback);
  });
};

TokenSocket.prototype.register = function(actions){
  this._actions = actions;
};

TokenSocket.prototype.subscribe = function(channel, callback){
  var self = this;
  checkAndUseConnection(self, function(){
    self._channels[channel] = true;
    self._monitor.sendMessage({
      rpc: "_subscribe",
      req: { channel: channel }
     }, callback);
  });
};

TokenSocket.prototype.unsubscribe = function(channel, callback){
  var self = this;
  checkAndUseConnection(self, function(){
    delete self._channels[channel];
    self._monitor.sendMessage({
      rpc: "_unsubscribe",
      req: { channel: channel }
    }, callback);
  });
};

TokenSocket.prototype.publish = function(channel, data, callback){
  var self = this;
  checkAndUseConnection(self, function(){
    self._monitor.sendMessage({
      rpc: "_publish",
      req: {
        channel: channel,
        data: data
      }
    }, callback);
  });
};

TokenSocket.prototype.broadcast = function(data, callback){
  var self = this;
  checkAndUseConnection(self, function(){
    self._monitor.sendMessage({
      rpc: "_broadcast",
      req: { data: data }
    }, callback);
  });
};

TokenSocket.prototype.onmessage = function(callback){
  this._emitter.on("message", callback);
};

TokenSocket.prototype.end = function(callback){
  this._emitter.removeAllListeners("ready");
  this._emitter.removeAllListeners("reconnect");
  this._emitter.removeAllListeners("message");
  this._closed = true;
  this._socket.onclose = callback;
  this._socket.close();
};

module.exports = TokenSocket;
<|endoftext|>


<commit_before>/*
 * Analyze Controller.
 * This manages all actions executed from metrics explorer.
 */

define(['../../helpers/chart-helper'], function (chartHelper) {

  // Used for local storage, which is used to store our metrics selection.
  var STORED_APP_NAME = 'continuuity-analyze';

  // Used to query for available element types from REST.
  var AVAILABLE_TYPES = ['apps', 'streams', 'flows', 'mapreduce', 'datasets', 'procedures'];

  var Controller = Em.Controller.extend(Em.Evented, {

    elementModels: [],

    // Holds available element models.
    elementsCache: [],

    // Holds a per-type cache of available metrics.
    metricsCache: Em.Object.create(),

    // Holds the currently selected metrics.
    selected: Em.ArrayProxy.create({ content: [] }),

    // Holds temporary information from the 'Add Metric' form.
    configuring: Em.Object.extend({
      noSelection: function () {
        return this.get('element.name') === 'Elements' ||
          this.get('metric.name') === 'Metric Names';
      }.property('element', 'metric'),
      element: {
        name: 'Elements'
      },
      metric: {
        name: 'Metric Names'
      }
    }),

    init: function () {

      /*
       * Only 'extend' allows computed properties, as above.
       * Therefore we create / construct here.
       */
      this.set('configuring', this.get('configuring').create());

    },

    load: function (id) {

      var self = this;

      this.set('selected', Em.ArrayProxy.create({ content: [] }));

      /*
       * Prepopulate metrics selection from Local Storage if available.
       */
      if (window.localStorage) {

        var saved = localStorage.getItem(STORED_APP_NAME);
        if (saved) {
          this.set('selected.content', JSON.parse(saved).content);
        }

      }

      function findElement(type, id) {

        var models = self.elementModels, i = models.length;
        while (i--) {
          if (models[i].type === type && models[i].id === id) {
            return models[i];
          }
        }
        return null;

      }

      // Needs time to find elements. Move to run loop.
      setTimeout(function () {

        $("#elementSelector").select2({
            containerCssClass: "analyze-configurator-element-select",
            placeholder: "Select Element",
            query: function(query) {

              var data = [];

              $.each(self.elementsCache, function(){

                var children = [];
                $.each(this.children, function () {
                  if(query.term.length === 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ){
                      children.push({id: this.id, text: this.text });
                  }
                });
                this.children = children;
                if (children.length) {
                  data.push(this);
                }
              });
              query.callback({results: data});

            }
        });
        $("#elementSelector").on('change', function (e) {

          if (e.added) {
            var id = e.added.id.split('|');
            var element = findElement(id[0], id[1]);
            self.selectElement(element);
          }

        });

        function filterMetrics(term, metrics) {

          var results = [];
          $.each(metrics, function () {
            if(term.length === 0 || this.text.toUpperCase().indexOf(term.toUpperCase()) >= 0 ){
                results.push({id: this.id, text: this.text });
            }
          });
          return results;

        }

        function getUserMetrics(model, term, done) {

          var context = model.get('context');
          var metrics = self.get('metricsList');

          self.HTTP.rest('metrics/user' + model.get('context'), function (response, status) {

            if (response.error) {

              Em.debug(response.error);

            } else {

              if (response.result.length) {

                var userMetrics = [], result = response.result, i = result.length;
                while (i--) {

                  var path = '/user' + context + '/' + window.encodeURIComponent(result[i].metric);
                  var j = metrics.length, found = false;

                  while (j--) {
                    if (metrics[j].id === path) {
                      found = true;
                    }
                  }

                  if (!found) {
                    userMetrics.push({
                      id: path,
                      text: result[i].metric
                    });
                  }
                }

                metrics = metrics.concat(userMetrics);
                self.set('metricsList', metrics);
                done({results: filterMetrics(term, metrics)});

              } else {

                done({results: filterMetrics(term, metrics)});

              }
            }
          });
        }

        $("#metricSelector").select2({
            placeholder: "Select Metric",
            query: function(query) {

              var model = self.configuring.element;
              var metrics = self.metricsCache.get(model.type);

              if (metrics) {

                // The element supports user-defined metrics. (Runnable)
                if (model.get('context')) {
                  getUserMetrics(model, query.term, query.callback);

                } else {
                  query.callback({results: filterMetrics(query.term, metrics)});

                }

              } else {

                self.HTTP.rest('metrics', 'system', model.type, function (metrics, status) {

                  var i = metrics.length;
                  while (i--) {
                    metrics[i] = {
                      id: metrics[i].path,
                      text: metrics[i].name
                    };
                  }

                  self.get('metricsCache').set(model.type, metrics);
                  self.set('metricsList', metrics);

                  // The element supports user-defined metrics. (Runnable)
                  if (model.get('context')) {
                    getUserMetrics(model, query.term, query.callback);

                  } else {
                    query.callback({results: filterMetrics(query.term, metrics)});

                  }

                });

              }

            }

        });
        $("#metricSelector").on('change', function (e) {

          if (e.added) {
            self.selectMetric({
              name: e.added.text,
              path: e.added.id
            });
          }

        });

      }, 500);

      function sortByKey (obj) {

        var keys = [];
        var sorted_obj = {};

        for(var key in obj){
            if(obj.hasOwnProperty(key)){
                keys.push(key);
            }
        }
        keys.sort();
        $.each(keys, function(i, key){
            sorted_obj[key] = obj[key];
        });

        return sorted_obj;

      }

      /*
       * Get all available Elements for selection.
       */
      var i = AVAILABLE_TYPES.length;
      var singular = {
        'apps': 'App',
        'streams': 'Stream',
        'flows': 'Flow',
        'mapreduce': 'Mapreduce',
        'datasets': 'Dataset',
        'procedures': 'Procedure'
      };

      // This format is used by the select2 box to render in groups.
      var byType = {};
      var remaining = i;

      while (i--) {
        (function (nextType) {

          self.HTTP.rest(nextType, function (models, status) {

            var i = models.length;
            while (i--) {
              if (C[singular[nextType]]) {
                models[i] = C[singular[nextType]].create(models[i]);
                self.elementModels.push(models[i]);
              }
            }

            $.each(models, function (i, element) {

              var id = element.type + '|' + element.id;

              if (byType[element.type]) {
                byType[element.type].push({
                  id: id,
                  text: element.name
                });
              } else {
                byType[element.type] = [{
                  id: id,
                  text: element.name
                }];
              }

            });

            if (!--remaining) {

              byType = sortByKey(byType);

              for (var type in byType) {
                self.elementsCache.push({
                  text: type + 's',
                  children: byType[type]
                });
              }

            }

          });

        })(AVAILABLE_TYPES[i]);
      }

      this.set('paused', false);

      this.set('interval', setInterval(function () {

        if (!self.get('paused')) {
          self.update();
        }

      }, 1000));

    },

    unload: function () {

      this.set('elementModels', []);
      this.set('elementsCache', []);
      this.set('metricsCache', Em.Object.create());

      clearInterval(this.get('interval'));

      // This is set in the Analyze embeddable.
      C.removeResizeHandler('metrics-explorer');

    },

    colors: ['#fce94f', '#edd400', '#c4a000', '#fcaf3e', '#f57900', '#ce5c00',
    '#e9b96e', '#c17d11', '#8f5902', '#8ae234', '#73d216', '#4e9a06', '#729fcf',
    '#3465a4', '#204a87', '#ad7fa8', '#75507b', '#5c3566', '#ef2929', '#cc0000'],

    update: function () {

      var self = this;
      var urls = [];

      var selected = this.get('selected');
      var start, now = new Date().getTime();

      // Add a two second buffer to make sure we have a full response.
      start = now - ((C.__timeRange + 2) * 1000);
      start = Math.floor(start / 1000);

      this.get('selected').forEach(function (item) {
        urls.push(item.path + '?start=' + start + '&count=' + C.__timeRange);
      });

      function findMetric (path) {
        var i = selected.content.length;
        while (i --) {
          if (path.indexOf(selected.content[i].path) === 0) {
            return selected.content[i];
          }
        }
      }
      if (!Em.isEmpty(urls)) {
        this.HTTP.post('metrics', urls, function (response, status) {

          if (response.result) {

            var s = null, series = [], selected = self.get('selected.content'),
              result = response.result, metric, d;

            for (var i = 0; i < result.length; i ++) {

              if ((metric = findMetric(result[i].path))) {

                s = {
                  name: metric.metric + ' (' + metric.element + ', ' + metric.type + ')',
                  color: metric.color,
                  data: []
                }, d = response.result[i].result.data;

                for (var j = 0; j < d.length; j ++) {
                  s.data.push({
                    x: d[j].time,
                    y: d[j].value
                  });
                }

                series.push(s);

              }

            }
            self.set('series', series);

          }

        });
      }

    }.observes('selected.[]'),

    paused: false,
    pausedLabel: function () {

      return this.get('paused') ? 'Continue' : 'Pause';

    }.property('paused').cacheable(false),
    togglePause: function () {

      this.set('paused', !this.get('paused'));

    },

    showConfigure: function (metric) {

      var index = Math.floor(Math.random() * this.colors.length);

      this.configuring.set('color', this.colors[index]);
      this.configuring.set('element', { name: 'Elements' });
      this.configuring.set('metric', { name: 'Metric Names' });

      $("#elementSelector").select2('val', null);
      $("#metricSelector").select2('val', null);
      $('#analyze-configurator').fadeIn(100);

    },

    hideConfigure: function () {

      $('#analyze-configurator').fadeOut(100);

    },

    selectColor: function (color) {

      this.configuring.set('color', color);

    },

    selectElement: function (model) {

      this.configuring.set('element', model);
      $("#metricSelector").select2("enable", true);

    },

    selectMetric: function (metric) {

      this.configuring.set('metric', metric);

    },

    addToChart: function () {

      var element = this.get('configuring.element');
      var metric = this.get('configuring.metric');
      var color = this.get('configuring.color');

      var path = element.interpolate(metric.path);
      var selected = {
        element: element.name,
        type: element.type,
        metric: metric.name,
        path: path,
        color: color,
        href: element.get('href')
      };

      this.get('selected').pushObject(selected);

      this.saveLocal();
      this.hideConfigure();

    },

    removeFromChart: function (selected) {

      this.get('selected').removeObject(selected);
      this.saveLocal();
      this.hideConfigure();

    },

    /**
     * Saves selection state to localstorage.
     */
    saveLocal: function() {
      localStorage.setItem(STORED_APP_NAME, JSON.stringify(this.get('selected')));
    }

  });

  Controller.reopenClass({
    type: 'Analyze',
    kind: 'Controller'
  });

  return Controller;

});
<commit_msg>Using palette for colors<commit_after>/*
 * Analyze Controller.
 * This manages all actions executed from metrics explorer.
 */

define(['../../helpers/chart-helper'], function (chartHelper) {

  // Used for local storage, which is used to store our metrics selection.
  var STORED_APP_NAME = 'continuuity-analyze';

  // Used to query for available element types from REST.
  var AVAILABLE_TYPES = ['apps', 'streams', 'flows', 'mapreduce', 'datasets', 'procedures'];

  var Controller = Em.Controller.extend(Em.Evented, {

    elementModels: [],

    // Holds available element models.
    elementsCache: [],

    // Holds a per-type cache of available metrics.
    metricsCache: Em.Object.create(),

    // Holds the currently selected metrics.
    selected: Em.ArrayProxy.create({ content: [] }),

    // Holds temporary information from the 'Add Metric' form.
    configuring: Em.Object.extend({
      noSelection: function () {
        return this.get('element.name') === 'Elements' ||
          this.get('metric.name') === 'Metric Names';
      }.property('element', 'metric'),
      element: {
        name: 'Elements'
      },
      metric: {
        name: 'Metric Names'
      }
    }),

    init: function () {

      /*
       * Only 'extend' allows computed properties, as above.
       * Therefore we create / construct here.
       */
      this.set('configuring', this.get('configuring').create());

    },

    load: function (id) {

      var self = this;

      this.set('palette', new Rickshaw.Color.Palette({ scheme: 'colorwheel', interpolatedStopCount: 2  }));

      this.set('selected', Em.ArrayProxy.create({ content: [] }));

      /*
       * Prepopulate metrics selection from Local Storage if available.
       */
      if (window.localStorage) {

        var saved = localStorage.getItem(STORED_APP_NAME);
        if (saved) {
          this.set('selected.content', JSON.parse(saved).content);
        }

      }

      var self = this;

      this.get('selected').forEach(function (item, index) {

        item.color = self.get('palette').color();

      });

      function findElement(type, id) {

        var models = self.elementModels, i = models.length;
        while (i--) {
          if (models[i].type === type && models[i].id === id) {
            return models[i];
          }
        }
        return null;

      }

      // Needs time to find elements. Move to run loop.
      setTimeout(function () {

        $("#elementSelector").select2({
            containerCssClass: "analyze-configurator-element-select",
            placeholder: "Select Element",
            query: function(query) {

              var data = [];

              $.each(self.elementsCache, function(){

                var children = [];
                $.each(this.children, function () {
                  if(query.term.length === 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0 ){
                      children.push({id: this.id, text: this.text });
                  }
                });
                this.children = children;
                if (children.length) {
                  data.push(this);
                }
              });
              query.callback({results: data});

            }
        });
        $("#elementSelector").on('change', function (e) {

          if (e.added) {
            var id = e.added.id.split('|');
            var element = findElement(id[0], id[1]);
            self.selectElement(element);
          }

        });

        function filterMetrics(term, metrics) {

          var results = [];
          $.each(metrics, function () {
            if(term.length === 0 || this.text.toUpperCase().indexOf(term.toUpperCase()) >= 0 ){
                results.push({id: this.id, text: this.text });
            }
          });
          return results;

        }

        function getUserMetrics(model, term, done) {

          var context = model.get('context');
          var metrics = self.get('metricsList');

          self.HTTP.rest('metrics/user' + model.get('context'), function (response, status) {

            if (response.error) {

              Em.debug(response.error);

            } else {

              if (response.result.length) {

                var userMetrics = [], result = response.result, i = result.length;
                while (i--) {

                  var path = '/user' + context + '/' + window.encodeURIComponent(result[i].metric);
                  var j = metrics.length, found = false;

                  while (j--) {
                    if (metrics[j].id === path) {
                      found = true;
                    }
                  }

                  if (!found) {
                    userMetrics.push({
                      id: path,
                      text: result[i].metric
                    });
                  }
                }

                metrics = metrics.concat(userMetrics);
                self.set('metricsList', metrics);
                done({results: filterMetrics(term, metrics)});

              } else {

                done({results: filterMetrics(term, metrics)});

              }
            }
          });
        }

        $("#metricSelector").select2({
            placeholder: "Select Metric",
            query: function(query) {

              var model = self.configuring.element;
              var metrics = self.metricsCache.get(model.type);

              if (metrics) {

                // The element supports user-defined metrics. (Runnable)
                if (model.get('context')) {
                  getUserMetrics(model, query.term, query.callback);

                } else {
                  query.callback({results: filterMetrics(query.term, metrics)});

                }

              } else {

                self.HTTP.rest('metrics', 'system', model.type, function (metrics, status) {

                  var i = metrics.length;
                  while (i--) {
                    metrics[i] = {
                      id: metrics[i].path,
                      text: metrics[i].name
                    };
                  }

                  self.get('metricsCache').set(model.type, metrics);
                  self.set('metricsList', metrics);

                  // The element supports user-defined metrics. (Runnable)
                  if (model.get('context')) {
                    getUserMetrics(model, query.term, query.callback);

                  } else {
                    query.callback({results: filterMetrics(query.term, metrics)});

                  }

                });

              }

            }

        });
        $("#metricSelector").on('change', function (e) {

          if (e.added) {
            self.selectMetric({
              name: e.added.text,
              path: e.added.id
            });
          }

        });

      }, 500);

      function sortByKey (obj) {

        var keys = [];
        var sorted_obj = {};

        for(var key in obj){
            if(obj.hasOwnProperty(key)){
                keys.push(key);
            }
        }
        keys.sort();
        $.each(keys, function(i, key){
            sorted_obj[key] = obj[key];
        });

        return sorted_obj;

      }

      /*
       * Get all available Elements for selection.
       */
      var i = AVAILABLE_TYPES.length;
      var singular = {
        'apps': 'App',
        'streams': 'Stream',
        'flows': 'Flow',
        'mapreduce': 'Mapreduce',
        'datasets': 'Dataset',
        'procedures': 'Procedure'
      };

      // This format is used by the select2 box to render in groups.
      var byType = {};
      var remaining = i;

      while (i--) {
        (function (nextType) {

          self.HTTP.rest(nextType, function (models, status) {

            var i = models.length;
            while (i--) {
              if (C[singular[nextType]]) {
                models[i] = C[singular[nextType]].create(models[i]);
                self.elementModels.push(models[i]);
              }
            }

            $.each(models, function (i, element) {

              var id = element.type + '|' + element.id;

              if (byType[element.type]) {
                byType[element.type].push({
                  id: id,
                  text: element.name
                });
              } else {
                byType[element.type] = [{
                  id: id,
                  text: element.name
                }];
              }

            });

            if (!--remaining) {

              byType = sortByKey(byType);

              for (var type in byType) {
                self.elementsCache.push({
                  text: type + 's',
                  children: byType[type]
                });
              }

            }

          });

        })(AVAILABLE_TYPES[i]);
      }

      this.set('paused', false);

      this.set('interval', setInterval(function () {

        if (!self.get('paused')) {
          self.update();
        }

      }, 1000));

    },

    unload: function () {

      this.set('elementModels', []);
      this.set('elementsCache', []);
      this.set('metricsCache', Em.Object.create());

      clearInterval(this.get('interval'));

      // This is set in the Analyze embeddable.
      C.removeResizeHandler('metrics-explorer');

    },

    update: function () {

      var self = this;
      var urls = [];

      var selected = this.get('selected');
      var start, now = new Date().getTime();

      // Add a two second buffer to make sure we have a full response.
      start = now - ((C.__timeRange + 2) * 1000);
      start = Math.floor(start / 1000);

      this.get('selected').forEach(function (item) {
        urls.push(item.path + '?start=' + start + '&count=' + C.__timeRange);
      });

      function findMetric (path) {
        var i = selected.content.length;
        while (i --) {
          if (path.indexOf(selected.content[i].path) === 0) {
            return selected.content[i];
          }
        }
      }
      if (!Em.isEmpty(urls)) {
        this.HTTP.post('metrics', urls, function (response, status) {

          if (response.result) {

            var s = null, series = [], selected = self.get('selected.content'),
              result = response.result, metric, d;

            for (var i = 0; i < result.length; i ++) {

              if ((metric = findMetric(result[i].path))) {

                s = {
                  name: metric.metric + ' (' + metric.element + ', ' + metric.type + ')',
                  color: metric.color,
                  data: []
                }, d = response.result[i].result.data;

                for (var j = 0; j < d.length; j ++) {
                  s.data.push({
                    x: d[j].time,
                    y: d[j].value
                  });
                }

                series.push(s);

              }

            }
            self.set('series', series);

          }

        });
      }

    }.observes('selected.[]'),

    paused: false,
    pausedLabel: function () {

      return this.get('paused') ? 'Continue' : 'Pause';

    }.property('paused').cacheable(false),
    togglePause: function () {

      this.set('paused', !this.get('paused'));

    },

    showConfigure: function (metric) {

      this.configuring.set('element', { name: 'Elements' });
      this.configuring.set('metric', { name: 'Metric Names' });

      $("#elementSelector").select2('val', null);
      $("#metricSelector").select2('val', null);
      $('#analyze-configurator').fadeIn(100);

    },

    hideConfigure: function () {

      $('#analyze-configurator').fadeOut(100);

    },

    selectElement: function (model) {

      this.configuring.set('element', model);
      $("#metricSelector").select2("enable", true);

    },

    selectMetric: function (metric) {

      this.configuring.set('metric', metric);

    },

    addToChart: function () {

      var element = this.get('configuring.element');
      var metric = this.get('configuring.metric');

      var path = element.interpolate(metric.path);
      var selected = {
        element: element.name,
        type: element.type,
        metric: metric.name,
        path: path,
        color: this.get('palette').color(),
        href: element.get('href')
      };

      this.get('selected').pushObject(selected);

      this.saveLocal();
      this.hideConfigure();

    },

    removeFromChart: function (selected) {

      this.get('selected').removeObject(selected);
      this.saveLocal();
      this.hideConfigure();

    },

    /**
     * Saves selection state to localstorage.
     */
    saveLocal: function() {
      localStorage.setItem(STORED_APP_NAME, JSON.stringify(this.get('selected')));
    }

  });

  Controller.reopenClass({
    type: 'Analyze',
    kind: 'Controller'
  });

  return Controller;

});
<|endoftext|>


<commit_before>var smcomp = require('./index.js');

var inputfile = '/Applications/MAMP/htdocs/gulpSM/source/main.sp';
var outputfile = '/Applications/MAMP/htdocs/gulpSM/release/test.smx';
var options = {
  '-v' : 2,
  '-E' : null
};

smcomp.compile(inputfile, outputfile, options, function(err, stdout){
    if(err) { return console.error(stdout); }
    //Success
    console.log(stdout);
});
<commit_msg>ignore file<commit_after><|endoftext|>