<commit_before>const Tree = require('functional-red-black-tree')
const Account = require('ethereumjs-account')
const async = require('async')

var Cache = module.exports = function (trie) {
  this._cache = Tree()
  this._checkpoints = []
  this._deletes = []
  this._trie = trie
}

Cache.prototype.put = function (key, val, fromTrie) {
  var modified = !fromTrie
  this._update(key, val, modified, true)
}

// returns the queried account or an empty account
Cache.prototype.get = function (key) {
  var account = this.lookup(key)
  if (!account) {
    account = new Account()
    account.exists = false
  }
  return account
}

// returns the queried account or undefined
Cache.prototype.lookup = function (key) {
  key = key.toString('hex')

  var it = this._cache.find(key)
  if (it.node) {
    var account = new Account(it.value.val)
    account.exists = it.value.exists
    return account
  }
}

Cache.prototype._lookupAccount = function (address, cb) {
  var self = this
  self._trie.get(address, function (err, raw) {
    if (err) return cb(err)
    var account = new Account(raw)
    var exists = !!raw
    account.exists = exists
    cb(null, account, exists)
  })
}

Cache.prototype.getOrLoad = function (key, cb) {
  var self = this
  var account = this.lookup(key)
  if (account) {
    cb(null, account)
  } else {
    self._lookupAccount(key, function (err, account, exists) {
      if (err) return cb(err)
      self._update(key, account, false, exists)
      cb(null, account)
    })
  }
}

Cache.prototype.warm = function (addresses, cb) {
  var self = this
  // shim till async supports iterators
  var accountArr = []
  addresses.forEach(function (val) {
    if (val) accountArr.push(val)
  })

  async.eachSeries(accountArr, function (addressHex, done) {
    var address = new Buffer(addressHex, 'hex')
    self._lookupAccount(address, function (err, account) {
      if (err) return done(err)
      self._update(address, account, false, account.exists)
      done()
    })
  }, cb)
}

Cache.prototype.flush = function (cb) {
  var it = this._cache.begin
  var self = this
  var next = true
  async.whilst(function () {
    return next
  }, function (done) {
    if (it.value.modified) {
      it.value.modified = false
      it.value.val = it.value.val.serialize()
      self._trie.put(new Buffer(it.key, 'hex'), it.value.val, function () {
        next = it.hasNext
        it.next()
        done()
      })
    } else {
      next = it.hasNext
      it.next()
      done()
    }
  }, function () {
    async.eachSeries(self._deletes, function (address, done) {
      self._trie.del(address, done)
    }, function () {
      self._deletes = []
      cb()
    })
  })
}

Cache.prototype.checkpoint = function () {
  this._checkpoints.push(this._cache)
}

Cache.prototype.revert = function () {
  this._cache = this._checkpoints.pop(this._cache)
}

Cache.prototype.commit = function () {
  this._checkpoints.pop()
}

Cache.prototype.clear = function () {
  this._deletes = []
  this._cache = Tree()
}

Cache.prototype.del = function (key) {
  if (key.toString('hex') === '') {
    return
  }
  this._deletes.push(key)
  key = key.toString('hex')
  this._cache = this._cache.remove(key)
}

Cache.prototype._update = function (key, val, modified, exists) {
  key = key.toString('hex')
  var it = this._cache.find(key)
  if (it.node) {
    this._cache = it.update({
      val: val,
      modified: modified,
      exists: true
    })
  } else {
    this._cache = this._cache.insert(key, {
      val: val,
      modified: modified,
      exists: exists
    })
  }
}
<commit_msg>Update cache.js<commit_after>const Tree = require('functional-red-black-tree')
const Account = require('ethereumjs-account')
const async = require('async')

var Cache = module.exports = function (trie) {
  this._cache = Tree()
  this._checkpoints = []
  this._deletes = []
  this._trie = trie
}

Cache.prototype.put = function (key, val, fromTrie) {
  var modified = !fromTrie
  this._update(key, val, modified, true)
}

// returns the queried account or an empty account
Cache.prototype.get = function (key) {
  var account = this.lookup(key)
  if (!account) {
    account = new Account()
    account.exists = false
  }
  return account
}

// returns the queried account or undefined
Cache.prototype.lookup = function (key) {
  key = key.toString('hex')

  var it = this._cache.find(key)
  if (it.node) {
    var account = new Account(it.value.val)
    account.exists = it.value.exists
    return account
  }
}

Cache.prototype._lookupAccount = function (address, cb) {
  var self = this
  self._trie.get(address, function (err, raw) {
    if (err) return cb(err)
    var account = new Account(raw)
    var exists = !!raw
    account.exists = exists
    cb(null, account, exists)
  })
}

Cache.prototype.getOrLoad = function (key, cb) {
  var self = this
  var account = this.lookup(key)
  if (account) {
    cb(null, account)
  } else {
    self._lookupAccount(key, function (err, account, exists) {
      if (err) return cb(err)
      self._update(key, account, false, exists)
      cb(null, account)
    })
  }
}

Cache.prototype.warm = function (addresses, cb) {
  var self = this
  // shim till async supports iterators
  var accountArr = []
  addresses.forEach(function (val) {
    if (val) accountArr.push(val)
  })

  async.eachSeries(accountArr, function (addressHex, done) {
    var address = new Buffer(addressHex, 'hex')
    self._lookupAccount(address, function (err, account) {
      if (err) return done(err)
      self._update(address, account, false, account.exists)
      done()
    })
  }, cb)
}

Cache.prototype.flush = function (cb) {
  var it = this._cache.begin
  var self = this
  var next = true
  async.whilst(function () {
    return next
  }, function (done) {
    if (it.value.modified) {
      it.value.modified = false
      it.value.val = it.value.val.serialize()
      self._trie.put(new Buffer(it.key, 'hex'), it.value.val, function () {
        next = it.hasNext
        it.next()
        done()
      })
    } else {
      next = it.hasNext
      it.next()
      done()
    }
  }, function () {
    async.eachSeries(self._deletes, function (address, done) {
      self._trie.del(address, done)
    }, function () {
      self._deletes = []
      cb()
    })
  })
}

Cache.prototype.checkpoint = function () {
  this._checkpoints.push(this._cache)
}

Cache.prototype.revert = function () {
  this._cache = this._checkpoints.pop(this._cache)
}

Cache.prototype.commit = function () {
  this._checkpoints.pop()
}

Cache.prototype.clear = function () {
  this._deletes = []
  this._cache = Tree()
}

Cache.prototype.del = function (key) {
  this._deletes.push(key)
  key = key.toString('hex')
  this._cache = this._cache.remove(key)
}

Cache.prototype._update = function (key, val, modified, exists) {
  key = key.toString('hex')
  var it = this._cache.find(key)
  if (it.node) {
    this._cache = it.update({
      val: val,
      modified: modified,
      exists: true
    })
  } else {
    this._cache = this._cache.insert(key, {
      val: val,
      modified: modified,
      exists: exists
    })
  }
}
<|endoftext|>


<commit_before>// Error checking and parameter validation
var isTypedArray = require('./is-typed-array')
var extend = require('./extend')

var GL_COMPILE_STATUS

function raise (message) {
  var error = new Error('(regl) ' + message)
  console.error(error)
  throw error
}

function check (pred, message) {
  if (!pred) {
    raise(message)
  }
}

function encolon (message) {
  if (message) {
    return ': ' + message
  }
  return ''
}

function checkParameter (param, possibilities, message) {
  if (!(param in possibilities)) {
    raise('unknown parameter (' + param + ')' + encolon(message) +
          '. possible values: ' + Object.keys(possibilities).join())
  }
}

function checkIsTypedArray (data, message) {
  if (!isTypedArray(data)) {
    raise(
      'invalid parameter type' + encolon(message) +
      '. must be a typed array')
  }
}

function checkTypeOf (value, type, message) {
  if (typeof value !== type) {
    raise(
      'invalid parameter type' + encolon(message) +
      '. expected ' + type + ', got ' + (typeof value))
  }
}

function checkNonNegativeInt (value, message) {
  if (!((value >= 0) &&
        ((value | 0) === value))) {
    raise('invalid parameter type, (' + value + ')' + encolon(message) +
          '. must be a nonnegative integer')
  }
}

function checkOneOf (value, list, message) {
  if (list.indexOf(value) < 0) {
    raise('invalid value' + encolon(message) + '. must be one of: ' + list)
  }
}

function leftPad (str, n) {
  str = str + ''
  while (str.length < n) {
    str = ' ' + str
  }
  return str
}

function ShaderFile () {
  this.name = 'unknown'
  this.lines = []
  this.index = {}
  this.hasErrors = false
}

function ShaderLine (number, line) {
  this.number = number
  this.line = line
  this.errors = []
}

function ShaderError (fileNumber, lineNumber, message) {
  this.file = fileNumber
  this.line = lineNumber
  this.message = message
}

function parseSource (source) {
  var lines = source.split('\n')
  var annotated = []
  var lineNumber = 1
  var fileNumber = 0
  var files = {
    unknown: new ShaderFile(),
    0: new ShaderFile()
  }
  files.unknown.lines.push(new ShaderLine(0, ''))
  for (var i = 0; i < lines.length; ++i) {
    var line = lines[i]
    var parts = /^\s*\#\s*(\w+)\s+(.+)\s*$/.exec(line)
    if (parts) {
      switch(parts[1]) {
        case 'line':
          var lineNumberInfo = /(\d+)(\s+\d+)?/.exec(parts[2])
          if (lineNumberInfo) {
            lineNumber = lineNumberInfo[1] | 0
            if (lineNumberInfo[2]) {
              fileNumber = lineNumberInfo[2] | 0
              if (!(fileNumber in files)) {
                files[fileNumber] = new ShaderFile()
              }
            }
          }
          break
        case 'define':
          var nameInfo = /SHADER_NAME(_B64)?\s+(.*)$/.exec(parts[2])
          if (nameInfo) {
            files[fileNumber].name = (nameInfo[1]
                ? btoa(nameInfo[2])
                : nameInfo[2])
          }
          break
      }
    }
    files[fileNumber].lines.push(new ShaderLine(lineNumber++, line))
  }
  Object.keys(files).forEach(function (fileNumber) {
    var file = files[fileNumber]
    file.lines.forEach(function (line) {
      file.index[line.number] = line
    })
  })
  return files
}

function parseErrorLog (errLog) {
  var result = []
  errLog.split('\n').forEach(function (errMsg) {
    var parts = /^ERROR\:\s+(\d+)\:(\d+)\:\s*(.*)$/.exec(errMsg)
    if (parts) {
      result.push(new ShaderError(
        parts[1] | 0,
        parts[2] | 0,
        parts[3].trim()))
    } else if (errMsg.length > 0) {
      result.push(new ShaderError('unknown', 0, errMsg))
    }
  })
  return result
}

function annotateFiles (files, errors) {
  errors.forEach(function (error) {
    var file = files[error.file]
    if (file) {
      var line = file.index[error.line]
      if (line) {
        line.errors.push(error)
        file.hasErrors = true
        return
      }
    }
    files.unknown.hasErrors = true
    files.unknown.lines[0].errors.push(error)
  })
}

function checkShaderError (gl, shader, source, type) {
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    var errLog = gl.getShaderInfoLog(shader)
    var typeName = type === gl.FRAGMENT_SHADER ? 'fragment' : 'vertex'
    var files = parseSource(source)
    var errors = parseErrorLog(errLog)
    annotateFiles(files, errors)

    Object.keys(files).forEach(function (fileNumber) {
      var file = files[fileNumber]
      if (!file.hasErrors) {
        return
      }

      var strings = ['']
      var styles = ['']

      function push (str, style) {
        strings.push(str)
        styles.push(style || '')
      }

      push('file number ' + fileNumber + ': ' + file.name + '\n', 'color:red;text-decoration:underline;font-weight:bold')

      file.lines.forEach(function (line) {
        if (line.errors.length > 0) {
          push(leftPad(line.number, 4) + '|  ', 'background-color:yellow; font-weight:bold')
          push(line.line + '\n', 'color:red; background-color:yellow; font-weight:bold')

          // try to guess token
          var offset = 0
          line.errors.forEach(function (error) {

            var message = error.message
            var token = /^\s*\'(.*)\'\s*\:\s*(.*)$/.exec(message)
            if (token) {
              var tokenPat = token[1]
              message = token[2]
              switch (tokenPat) {
                case 'assign':
                  tokenPat = '='
                  break
              }
              offset = Math.max(line.line.indexOf(tokenPat, offset), 0)
            } else {
              offset = 0
            }

            push(leftPad('| ', 6))
            push(leftPad('^^^', offset + 3) + '\n', 'font-weight:bold')
            push(leftPad('| ', 6))
            push(message + '\n', 'font-weight:bold')
          })
          push(leftPad('| ', 6) + '\n')
        } else {
          push(leftPad(line.number, 4) + '|  ')
          push(line.line + '\n', 'color:red')
        }
      })

      styles[0] = strings.join('%c')

      console.log.apply(console, styles)
    })

    check.raise('Error compiling ' + typeName + ' shader, ' + files[0].name)
  }
}

function checkLinkError (gl, program, fragShader, vertShader) {
  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    var errLog = gl.getProgramInfoLog(program)
    var fragParse = parseSource(fragShader)
    var vertParse = parseSource(vertShader)

    var header = 'Error linking program, vertex shader: ' +
      vertParse[0].name + ', fragment shader: ' + fragParse[0].name

    console.log('%c' + header + '\n%c' + errLog,
      'color:red;text-decoration:underline;font-weight:bold',
      'color:red')
    check.raise(header)
  }
}

module.exports = extend(check, {
  raise: raise,
  parameter: checkParameter,
  type: checkTypeOf,
  isTypedArray: checkIsTypedArray,
  nni: checkNonNegativeInt,
  oneOf: checkOneOf,
  shaderError: checkShaderError,
  linkError: checkLinkError
})
<commit_msg>add funny hack to guess file name locations from stack traces<commit_after>// Error checking and parameter validation
var isTypedArray = require('./is-typed-array')
var extend = require('./extend')

var GL_COMPILE_STATUS

function raise (message) {
  var error = new Error('(regl) ' + message)
  console.error(error)
  throw error
}

function check (pred, message) {
  if (!pred) {
    raise(message)
  }
}

function encolon (message) {
  if (message) {
    return ': ' + message
  }
  return ''
}

function checkParameter (param, possibilities, message) {
  if (!(param in possibilities)) {
    raise('unknown parameter (' + param + ')' + encolon(message) +
          '. possible values: ' + Object.keys(possibilities).join())
  }
}

function checkIsTypedArray (data, message) {
  if (!isTypedArray(data)) {
    raise(
      'invalid parameter type' + encolon(message) +
      '. must be a typed array')
  }
}

function checkTypeOf (value, type, message) {
  if (typeof value !== type) {
    raise(
      'invalid parameter type' + encolon(message) +
      '. expected ' + type + ', got ' + (typeof value))
  }
}

function checkNonNegativeInt (value, message) {
  if (!((value >= 0) &&
        ((value | 0) === value))) {
    raise('invalid parameter type, (' + value + ')' + encolon(message) +
          '. must be a nonnegative integer')
  }
}

function checkOneOf (value, list, message) {
  if (list.indexOf(value) < 0) {
    raise('invalid value' + encolon(message) + '. must be one of: ' + list)
  }
}

function leftPad (str, n) {
  str = str + ''
  while (str.length < n) {
    str = ' ' + str
  }
  return str
}

function ShaderFile () {
  this.name = 'unknown'
  this.lines = []
  this.index = {}
  this.hasErrors = false
}

function ShaderLine (number, line) {
  this.number = number
  this.line = line
  this.errors = []
}

function ShaderError (fileNumber, lineNumber, message) {
  this.file = fileNumber
  this.line = lineNumber
  this.message = message
}

function guessFileName () {
  var error = new Error()
  var stack = error.stack
  var pat = /at compileProcedure.*\n\s+at.*\((.*)\)/.exec(stack)
  if (pat) {
    return pat[1]
  }
  return 'unknown'
}

function parseSource (source) {
  var lines = source.split('\n')
  var annotated = []
  var lineNumber = 1
  var fileNumber = 0
  var files = {
    unknown: new ShaderFile(),
    0: new ShaderFile()
  }
  files[0].name = guessFileName()
  files.unknown.lines.push(new ShaderLine(0, ''))
  for (var i = 0; i < lines.length; ++i) {
    var line = lines[i]
    var parts = /^\s*\#\s*(\w+)\s+(.+)\s*$/.exec(line)
    if (parts) {
      switch(parts[1]) {
        case 'line':
          var lineNumberInfo = /(\d+)(\s+\d+)?/.exec(parts[2])
          if (lineNumberInfo) {
            lineNumber = lineNumberInfo[1] | 0
            if (lineNumberInfo[2]) {
              fileNumber = lineNumberInfo[2] | 0
              if (!(fileNumber in files)) {
                files[fileNumber] = new ShaderFile()
              }
            }
          }
          break
        case 'define':
          var nameInfo = /SHADER_NAME(_B64)?\s+(.*)$/.exec(parts[2])
          if (nameInfo) {
            files[fileNumber].name = (nameInfo[1]
                ? btoa(nameInfo[2])
                : nameInfo[2])
          }
          break
      }
    }
    files[fileNumber].lines.push(new ShaderLine(lineNumber++, line))
  }
  Object.keys(files).forEach(function (fileNumber) {
    var file = files[fileNumber]
    file.lines.forEach(function (line) {
      file.index[line.number] = line
    })
  })
  return files
}

function parseErrorLog (errLog) {
  var result = []
  errLog.split('\n').forEach(function (errMsg) {
    var parts = /^ERROR\:\s+(\d+)\:(\d+)\:\s*(.*)$/.exec(errMsg)
    if (parts) {
      result.push(new ShaderError(
        parts[1] | 0,
        parts[2] | 0,
        parts[3].trim()))
    } else if (errMsg.length > 0) {
      result.push(new ShaderError('unknown', 0, errMsg))
    }
  })
  return result
}

function annotateFiles (files, errors) {
  errors.forEach(function (error) {
    var file = files[error.file]
    if (file) {
      var line = file.index[error.line]
      if (line) {
        line.errors.push(error)
        file.hasErrors = true
        return
      }
    }
    files.unknown.hasErrors = true
    files.unknown.lines[0].errors.push(error)
  })
}

function checkShaderError (gl, shader, source, type) {
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    var errLog = gl.getShaderInfoLog(shader)
    var typeName = type === gl.FRAGMENT_SHADER ? 'fragment' : 'vertex'
    var files = parseSource(source)
    var errors = parseErrorLog(errLog)
    annotateFiles(files, errors)

    Object.keys(files).forEach(function (fileNumber) {
      var file = files[fileNumber]
      if (!file.hasErrors) {
        return
      }

      var strings = ['']
      var styles = ['']

      function push (str, style) {
        strings.push(str)
        styles.push(style || '')
      }

      push('file number ' + fileNumber + ': ' + file.name + '\n', 'color:red;text-decoration:underline;font-weight:bold')

      file.lines.forEach(function (line) {
        if (line.errors.length > 0) {
          push(leftPad(line.number, 4) + '|  ', 'background-color:yellow; font-weight:bold')
          push(line.line + '\n', 'color:red; background-color:yellow; font-weight:bold')

          // try to guess token
          var offset = 0
          line.errors.forEach(function (error) {

            var message = error.message
            var token = /^\s*\'(.*)\'\s*\:\s*(.*)$/.exec(message)
            if (token) {
              var tokenPat = token[1]
              message = token[2]
              switch (tokenPat) {
                case 'assign':
                  tokenPat = '='
                  break
              }
              offset = Math.max(line.line.indexOf(tokenPat, offset), 0)
            } else {
              offset = 0
            }

            push(leftPad('| ', 6))
            push(leftPad('^^^', offset + 3) + '\n', 'font-weight:bold')
            push(leftPad('| ', 6))
            push(message + '\n', 'font-weight:bold')
          })
          push(leftPad('| ', 6) + '\n')
        } else {
          push(leftPad(line.number, 4) + '|  ')
          push(line.line + '\n', 'color:red')
        }
      })

      styles[0] = strings.join('%c')

      console.log.apply(console, styles)
    })

    check.raise('Error compiling ' + typeName + ' shader, ' + files[0].name)
  }
}

function checkLinkError (gl, program, fragShader, vertShader) {
  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    var errLog = gl.getProgramInfoLog(program)
    var fragParse = parseSource(fragShader)
    var vertParse = parseSource(vertShader)

    var header = 'Error linking program, vertex shader: ' +
      vertParse[0].name + ', fragment shader: ' + fragParse[0].name

    console.log('%c' + header + '\n%c' + errLog,
      'color:red;text-decoration:underline;font-weight:bold',
      'color:red')
    check.raise(header)
  }
}

module.exports = extend(check, {
  raise: raise,
  parameter: checkParameter,
  type: checkTypeOf,
  isTypedArray: checkIsTypedArray,
  nni: checkNonNegativeInt,
  oneOf: checkOneOf,
  shaderError: checkShaderError,
  linkError: checkLinkError
})
<|endoftext|>


<commit_before>/**
 * Clean-css - https://github.com/jakubpawlowicz/clean-css
 * Released under the terms of MIT license
 *
 * Copyright (C) 2014 JakubPawlowicz.com
 */

var ImportInliner = require('./imports/inliner');
var UrlRebase = require('./images/url-rebase');
var SelectorsOptimizer = require('./selectors/optimizer');

var CommentsProcessor = require('./text/comments-processor');
var ExpressionsProcessor = require('./text/expressions-processor');
var FreeTextProcessor = require('./text/free-text-processor');
var UrlsProcessor = require('./text/urls-processor');

var CleanCSS = module.exports = function CleanCSS(options) {
  options = options || {};

  this.options = {
    advanced: options.advanced === undefined ? true : false,
    aggressiveMerging: undefined === options.aggressiveMerging ? true : false,
    benchmark: options.benchmark,
    compatibility: options.compatibility,
    debug: options.debug,
    inliner: options.inliner,
    keepBreaks: options.keepBreaks || false,
    keepSpecialComments: 'keepSpecialComments' in options ? options.keepSpecialComments : '*',
    processImport: undefined === options.processImport ? true : false,
    rebase: undefined === options.rebase ? true : false,
    relativeTo: options.relativeTo,
    root: options.root,
    roundingPrecision: options.roundingPrecision,
    target: options.target
  };

  this.stats = {};
  this.context = {
    errors: [],
    warnings: [],
    debug: options.debug
  };
  this.errors = this.context.errors;
  this.warnings = this.context.warnings;
};

CleanCSS.prototype.minify = function(data, callback) {
  var options = this.options;
  var self = this;

  if (Buffer.isBuffer(data))
    data = data.toString();

  if (options.processImport || data.indexOf('@shallow') > 0) {
    // inline all imports
    var runner = callback ?
      process.nextTick :
      function (callback) { return callback(); };

    return runner(function () {
      return new ImportInliner(self.context, options.inliner).process(data, {
        localOnly: !callback,
        root: options.root || process.cwd(),
        relativeTo: options.relativeTo,
        whenDone: runMinifier(callback, self)
      });
    });
  } else {
    return runMinifier(callback, self)(data);
  }
};

function runMinifier(callback, self) {
  return function (data) {
    data = self.options.debug ?
      minifyWithDebug(self, data) :
      minify.call(self, data);

    return callback ?
      callback.call(self, self.context.errors.length > 0 ? self.context.errors : null, data) :
      data;
  };
}

function minifyWithDebug(self, data) {
  var startedAt = process.hrtime();
  self.stats.originalSize = data.length;

  data = minify.call(self, data);

  var elapsed = process.hrtime(startedAt);
  self.stats.timeSpent = ~~(elapsed[0] * 1e3 + elapsed[1] / 1e6);
  self.stats.efficiency = 1 - data.length / self.stats.originalSize;
  self.stats.minifiedSize = data.length;

  return data;
}

function benchmark(runner) {
  return function (processor, action) {
    var name =  processor.constructor.name + '#' + action;
    var start = process.hrtime();
    runner(processor, action);
    var itTook = process.hrtime(start);
    console.log('%d ms: ' + name, 1000 * itTook[0] + itTook[1] / 1000000);
  };
}

function minify(data) {
  var options = this.options;
  var context = this.context;

  var commentsProcessor = new CommentsProcessor(options.keepSpecialComments, options.keepBreaks);
  var expressionsProcessor = new ExpressionsProcessor();
  var freeTextProcessor = new FreeTextProcessor();
  var urlsProcessor = new UrlsProcessor();

  var urlRebase = new UrlRebase(options, context);
  var selectorsOptimizer = new SelectorsOptimizer({
    keepBreaks: options.keepBreaks,
    advanced: options.advanced,
    compatibility: options.compatibility,
    aggressiveMerging: options.aggressiveMerging,
    roundingPrecision: options.roundingPrecision
  }, context);

  var run = function (processor, action, enabled) {
    if (enabled === false)
      return;

    data = processor[action](data);
  };

  if (options.benchmark)
    run = benchmark(run);

  run(commentsProcessor, 'escape');
  run(expressionsProcessor, 'escape');
  run(urlsProcessor, 'escape');
  run(freeTextProcessor, 'escape');
  run(selectorsOptimizer, 'process');
  run(freeTextProcessor, 'restore');
  run(urlsProcessor, 'restore');
  run(urlRebase, 'process', options.rebase);
  run(expressionsProcessor, 'restore');
  run(commentsProcessor, 'restore');

  return data;
}
<commit_msg>Simplifies `SelectorsOptimizer` instantiation.<commit_after>/**
 * Clean-css - https://github.com/jakubpawlowicz/clean-css
 * Released under the terms of MIT license
 *
 * Copyright (C) 2014 JakubPawlowicz.com
 */

var ImportInliner = require('./imports/inliner');
var UrlRebase = require('./images/url-rebase');
var SelectorsOptimizer = require('./selectors/optimizer');

var CommentsProcessor = require('./text/comments-processor');
var ExpressionsProcessor = require('./text/expressions-processor');
var FreeTextProcessor = require('./text/free-text-processor');
var UrlsProcessor = require('./text/urls-processor');

var CleanCSS = module.exports = function CleanCSS(options) {
  options = options || {};

  this.options = {
    advanced: options.advanced === undefined ? true : false,
    aggressiveMerging: undefined === options.aggressiveMerging ? true : false,
    benchmark: options.benchmark,
    compatibility: options.compatibility,
    debug: options.debug,
    inliner: options.inliner,
    keepBreaks: options.keepBreaks || false,
    keepSpecialComments: 'keepSpecialComments' in options ? options.keepSpecialComments : '*',
    processImport: undefined === options.processImport ? true : false,
    rebase: undefined === options.rebase ? true : false,
    relativeTo: options.relativeTo,
    root: options.root,
    roundingPrecision: options.roundingPrecision,
    target: options.target
  };

  this.stats = {};
  this.context = {
    errors: [],
    warnings: [],
    debug: options.debug
  };
  this.errors = this.context.errors;
  this.warnings = this.context.warnings;
};

CleanCSS.prototype.minify = function(data, callback) {
  var options = this.options;
  var self = this;

  if (Buffer.isBuffer(data))
    data = data.toString();

  if (options.processImport || data.indexOf('@shallow') > 0) {
    // inline all imports
    var runner = callback ?
      process.nextTick :
      function (callback) { return callback(); };

    return runner(function () {
      return new ImportInliner(self.context, options.inliner).process(data, {
        localOnly: !callback,
        root: options.root || process.cwd(),
        relativeTo: options.relativeTo,
        whenDone: runMinifier(callback, self)
      });
    });
  } else {
    return runMinifier(callback, self)(data);
  }
};

function runMinifier(callback, self) {
  return function (data) {
    data = self.options.debug ?
      minifyWithDebug(self, data) :
      minify.call(self, data);

    return callback ?
      callback.call(self, self.context.errors.length > 0 ? self.context.errors : null, data) :
      data;
  };
}

function minifyWithDebug(self, data) {
  var startedAt = process.hrtime();
  self.stats.originalSize = data.length;

  data = minify.call(self, data);

  var elapsed = process.hrtime(startedAt);
  self.stats.timeSpent = ~~(elapsed[0] * 1e3 + elapsed[1] / 1e6);
  self.stats.efficiency = 1 - data.length / self.stats.originalSize;
  self.stats.minifiedSize = data.length;

  return data;
}

function benchmark(runner) {
  return function (processor, action) {
    var name =  processor.constructor.name + '#' + action;
    var start = process.hrtime();
    runner(processor, action);
    var itTook = process.hrtime(start);
    console.log('%d ms: ' + name, 1000 * itTook[0] + itTook[1] / 1000000);
  };
}

function minify(data) {
  var options = this.options;
  var context = this.context;

  var commentsProcessor = new CommentsProcessor(options.keepSpecialComments, options.keepBreaks);
  var expressionsProcessor = new ExpressionsProcessor();
  var freeTextProcessor = new FreeTextProcessor();
  var urlsProcessor = new UrlsProcessor();

  var urlRebase = new UrlRebase(options, context);
  var selectorsOptimizer = new SelectorsOptimizer(options, context);

  var run = function (processor, action, enabled) {
    if (enabled === false)
      return;

    data = processor[action](data);
  };

  if (options.benchmark)
    run = benchmark(run);

  run(commentsProcessor, 'escape');
  run(expressionsProcessor, 'escape');
  run(urlsProcessor, 'escape');
  run(freeTextProcessor, 'escape');
  run(selectorsOptimizer, 'process');
  run(freeTextProcessor, 'restore');
  run(urlsProcessor, 'restore');
  run(urlRebase, 'process', options.rebase);
  run(expressionsProcessor, 'restore');
  run(commentsProcessor, 'restore');

  return data;
}
<|endoftext|>


<commit_before>/*
 Copyright (c) 2013, Intel Corporation

 Redistribution and use in source and binary forms, with or without modification,
 are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
 this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 this list of conditions and the following disclaimer in the documentation
 and/or other materials provided with the distribution.
 * Neither the name of Intel Corporation nor the names of its contributors
 may be used to endorse or promote products derived from this software
 without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
"use strict";
var mqtt = require('mqtt'),
    msg = require('./cloud-message').init();

/**
 * @description Build a path replacing patter {} by the data arguments
 * if more the one {} pattern is present it shall be use Array
 * @param path string the represent a URL path
 * @param data Array or string,
 * @returns {*}
 */
var buildPath = function (path, data) {
    var re = /{\w+}/;
    var pathReplace = path;
    if (Array.isArray(data)) {
        data.forEach(function (value) {
            pathReplace = pathReplace.replace(re, value);
        });
    } else {
        pathReplace = pathReplace.replace(re, data);
    }
    return pathReplace;
};
function IoTKitCloud(conf, broker, logger, deviceId, sensorsStore){
    //TODO refactor as Gateway - Broker codes.
    var me = this;
    me.logger = logger;
    me.sensorsStore = sensorsStore;
    me.sensorsList = {};
    me.client = broker;
    me.deviceId = deviceId;
    me.activationCode = conf.activation_code;
    me.deviceToken = conf.device_token;
    me.apiKey = conf.apikey;
    me.accountId = "anon";
    me.logger.info("device id: ", me.deviceId);
    me.logger.info('Cloud client created');
    me.topics = {
        reg: conf.reg_topic || '/server/registration',
        status: conf.status_topic || '/server/registration_status',
        metric: conf.metric_topic || '/server/metric/',
        device: conf.device || "devices/{deviceid}",
        device_activation: conf.device_activation || "devices/{deviceid}/activation",
        device_metadata: conf.device_metadata ||"devices/{deviceid}/metadata",
        device_status: conf.device_status || "devices/{deviceid}/activation_status",
        metric_topic: conf.metric_topic || "server/metric/{accountid}/{deviceid}"
    };
    me.activationCompleted = false;
    me.pubArgs = {
        qos: 1,
        retain: false
    };
/*    me.client.subscribe(buildPath(me.topics.device_status, me.deviceId))
        .on('message', function(topic, message) {
            me.logger.info('STATUS: %s', topic, message);
            var regStatus = null;
            try {
                regStatus = JSON.parse(message);
            } catch (e){
                me.logger.info('STATUS: %s. Cannot parse message: ', topic, message);
                regStatus = null;
            }
            //status = 1 --> mean activated
            if (regStatus && regStatus.status === 1) {
                me.deviceToken = regStatus.deviceToken;
                me.accountId = regStatus.accountId;
                me.activationCompleted = true;
                me.logger.info('Devices activated successfully');
            }
        });*/
/*    me.activate = function (callback) {
        var actMsg = {
            "activationCode": me.activationCode,
            "apiKey": me.apiKey
        };
        me.logger.info('Called activate');
        me.client.publish(buildPath(me.topics.device_activation, me.deviceId),
                            JSON.stringify(actMsg),
                            me.pubArgs);
        me.logger.info('Activate - pub done');
        function waitForActivation() {
            var retries = 0;
            if (!me.activationCompleted) {
                retries ++;
                if (retries < 10) {
                    setTimeout(waitForActivation, 500);
                } else {
                    callback(new Error("The Activation token has not received"));
                }
            } else {
                callback(null);
            }
        }
        waitForActivation();
    };*/
}
/**
 * Handler to wait the token from MQTT server, the token is use to auth metrics send by the device
 * @param topic
 * @param message
 */
IoTKitCloud.prototype.waitForToken = function (topic, message) {
    var me = this;
        me.logger.info('STATUS: %s', topic, message);
        var regStatus = null;
        try {
            regStatus = JSON.parse(message);
        } catch (e){
            me.logger.info('STATUS: %s. Cannot parse message: ', topic, message);
            regStatus = null;
        }
        //status = 1 --> mean activated
        if (regStatus && regStatus.status === 1) {
            me.deviceToken = regStatus.deviceToken;
            me.accountId = regStatus.accountId;
            me.activationCompleted = true;
            me.logger.info('Devices activated successfully');
        }

};
/**
 * Will send the activation code to MQTT Server.
 * @param code (optional)
 */
IoTKitCloud.prototype.sendActivationCode = function(code) {
    var me = this;
    var actMsg = {
        "activationCode": code || me.activationCode,
        "apiKey": me.apiKey
    };
    var args = {
        qos : 1,
        retain: false
    }
    me.logger.info('Called activate');
    me.client.publish(buildPath(me.topics.device_activation, me.deviceId),
        JSON.stringify(actMsg),
        me.args);
};

/**
 * It will activate the device, by sending the activation code and receiving the token
 * from server if the toke is at device the activation will not called.
 * @param callback
 */
IoTKitCloud.prototype.activate = function (callback) {
    var me = this;
    me.logger.info('Called activate');
    var tokenTopic = buildPath(me.topics.device_status, me.deviceId);
    me.client.bind(tokenTopic, me.waitForToken);
    me.sendActivationCode();
    me.logger.info('Activate - pub done');
    var retries = 0;
    function waitForActivation() {
        if (!me.activationCompleted) {
            retries ++;
            if (retries < 10) {
                setTimeout(waitForActivation, 500);
            } else {
                callback(new Error("The Activation token has not received"));
            }
        } else {
            me.client.unbind(tokenTopic);
            callback(null);
        }
    }
    waitForActivation();
};

IoTKitCloud.prototype.reg = function(sensorsListArg) {
    var me = this;
    me.sensorsList = sensorsListArg || me.sensorsList;
    var doc = msg.getRegMsg(me.deviceId, undefined, undefined, me.sensorsList);
    if (!sensorsListArg) {
        // TODO: move this logic to the cloud message module
        me.logger.info("Changing message type...");
        doc.msg_type = "device_capability_registration_msg";
        doc.device_token = me.deviceToken;
    }
    me.logger.debug("Reg doc: %j", doc, {});
    me.client.publish(buildPath(me.topics.device_metadata,me.deviceId), doc, me.pubArgs);
};
IoTKitCloud.prototype.metric = function(message){
    var me = this;
    var doc = msg.getMetricMsg(me.deviceId, me.accountId, message);
    doc.device_token = me.deviceToken;
    me.logger.debug("Metric doc: %j", doc, {});
    me.client.publish(buildPath(me.topics.metric_topic,
                                [me.accountId, me.deviceId]),
                     doc, me.pubArgs);
};

exports.init = function(conf, broker, logger, deviceId, sensorsStore) {
    return new IoTKitCloud(conf, broker, logger, deviceId, sensorsStore);
};<commit_msg>sync variables names<commit_after>/*
 Copyright (c) 2013, Intel Corporation

 Redistribution and use in source and binary forms, with or without modification,
 are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
 this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 this list of conditions and the following disclaimer in the documentation
 and/or other materials provided with the distribution.
 * Neither the name of Intel Corporation nor the names of its contributors
 may be used to endorse or promote products derived from this software
 without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
"use strict";
var mqtt = require('mqtt'),
    msg = require('./cloud-message').init();

/**
 * @description Build a path replacing patter {} by the data arguments
 * if more the one {} pattern is present it shall be use Array
 * @param path string the represent a URL path
 * @param data Array or string,
 * @returns {*}
 */
var buildPath = function (path, data) {
    var re = /{\w+}/;
    var pathReplace = path;
    if (Array.isArray(data)) {
        data.forEach(function (value) {
            pathReplace = pathReplace.replace(re, value);
        });
    } else {
        pathReplace = pathReplace.replace(re, data);
    }
    return pathReplace;
};
function IoTKitCloud(conf, broker, logger, deviceId, sensorsStore){
    //TODO refactor as Gateway - Broker codes.
    var me = this;
    me.logger = logger;
    me.sensorsStore = sensorsStore;
    me.sensorsList = {};
    me.client = broker;
    me.deviceId = deviceId;
    me.activationCode = conf.activation_code;
    me.deviceToken = conf.device_token;
    me.apiKey = conf.apikey;
    me.accountId = "anon";
    me.logger.info("device id: ", me.deviceId);
    me.logger.info('Cloud client created');
    me.topics = {
        reg: conf.reg_topic || '/server/registration',
        status: conf.status_topic || '/server/registration_status',
        metric: conf.metric_topic || '/server/metric/',
        device: conf.device || "devices/{deviceid}",
        device_activation: conf.device_activation || "devices/{deviceid}/activation",
        device_metadata: conf.device_metadata ||"devices/{deviceid}/metadata",
        device_status: conf.device_status || "devices/{deviceid}/activation_status",
        metric_topic: conf.metric_topic || "server/metric/{accountid}/{deviceid}"
    };
    me.activationCompleted = false;
    me.pubArgs = {
        qos: 1,
        retain: false
    };
/*    me.client.subscribe(buildPath(me.topics.device_status, me.deviceId))
        .on('message', function(topic, message) {
            me.logger.info('STATUS: %s', topic, message);
            var regStatus = null;
            try {
                regStatus = JSON.parse(message);
            } catch (e){
                me.logger.info('STATUS: %s. Cannot parse message: ', topic, message);
                regStatus = null;
            }
            //status = 1 --> mean activated
            if (regStatus && regStatus.status === 1) {
                me.deviceToken = regStatus.deviceToken;
                me.accountId = regStatus.accountId;
                me.activationCompleted = true;
                me.logger.info('Devices activated successfully');
            }
        });*/
/*    me.activate = function (callback) {
        var actMsg = {
            "activationCode": me.activationCode,
            "apiKey": me.apiKey
        };
        me.logger.info('Called activate');
        me.client.publish(buildPath(me.topics.device_activation, me.deviceId),
                            JSON.stringify(actMsg),
                            me.pubArgs);
        me.logger.info('Activate - pub done');
        function waitForActivation() {
            var retries = 0;
            if (!me.activationCompleted) {
                retries ++;
                if (retries < 10) {
                    setTimeout(waitForActivation, 500);
                } else {
                    callback(new Error("The Activation token has not received"));
                }
            } else {
                callback(null);
            }
        }
        waitForActivation();
    };*/
}
/**
 * Handler to wait the token from MQTT server, the token is use to auth metrics send by the device
 * @param topic
 * @param message
 */
IoTKitCloud.prototype.waitForToken = function (topic, message) {
    var me = this;
        me.logger.info('STATUS: %s', topic, message);
        var regStatus = null;
        try {
            regStatus = JSON.parse(message);
        } catch (e){
            me.logger.info('STATUS: %s. Cannot parse message: ', topic, message);
            regStatus = null;
        }
        //status = 1 --> mean activated
        if (regStatus && regStatus.status === 1) {
            me.deviceToken = regStatus.deviceToken;
            me.accountId = regStatus.accountId;
            me.activationCompleted = true;
            me.logger.info('Devices activated successfully');
        }

};
/**
 * Will send the activation code to MQTT Server.
 * @param code (optional)
 */
IoTKitCloud.prototype.sendActivationCode = function(code) {
    var me = this;
    var actMsg = {
        "activationCode": code || me.activationCode,
        "apiKey": me.apiKey
    };
    var args = {
        qos : 1,
        retain: false
    }
    me.logger.info('Called activate');
    me.client.publish(buildPath(me.topics.device_activation, me.deviceId),
        JSON.stringify(actMsg),
        me.args);
};

/**
 * It will activate the device, by sending the activation code and receiving the token
 * from server if the toke is at device the activation will not called.
 * @param callback
 */
IoTKitCloud.prototype.activate = function (callback) {
    var me = this;
    me.logger.info('Called activate');
    var tokenTopic = buildPath(me.topics.device_status, me.deviceId);
    me.client.bind(tokenTopic, me.waitForToken);
    me.sendActivationCode();
    me.logger.info('Activate - pub done');
    var retries = 0;
    function waitForActivation() {
        if (!me.activationCompleted) {
            retries ++;
            if (retries < 10) {
                setTimeout(waitForActivation, 500);
            } else {
                callback(new Error("The Activation token has not received"));
            }
        } else {
            me.client.unbind(tokenTopic);
            callback(null);
        }
    }
    waitForActivation();
};

IoTKitCloud.prototype.reg = function(sensorsListArg) {
    var me = this;
    me.sensorsList = sensorsListArg || me.sensorsList;
    var doc = msg.getRegMsg(me.deviceId, undefined, undefined, me.sensorsList);
    if (!sensorsListArg) {
        // TODO: move this logic to the cloud message module
        me.logger.info("Changing message type...");
        doc.msg_type = "device_capability_registration_msg";
    }
    doc.deviceToken = me.deviceToken;
    me.logger.debug("Reg doc: %j", doc, {});
    me.client.publish(buildPath(me.topics.device_metadata,me.deviceId), doc, me.pubArgs);
};
IoTKitCloud.prototype.metric = function(message){
    var me = this;
    var doc = msg.getMetricMsg(me.deviceId, me.accountId, message);
    doc.deviceToken = me.deviceToken;
    me.logger.debug("Metric doc: %j", doc, {});
    me.client.publish(buildPath(me.topics.metric_topic,
                                [me.accountId, me.deviceId]),
                     doc, me.pubArgs);
};

exports.init = function(conf, broker, logger, deviceId, sensorsStore) {
    return new IoTKitCloud(conf, broker, logger, deviceId, sensorsStore);
};<|endoftext|>


<commit_before>module.exports = function(users, experiments, schema) {
    const parse = require('co-body');
    const status = require('http-status');
    const _ = require('lodash');
    const nodemailer = require('nodemailer');
    const smtpTransport = require('nodemailer-smtp-transport');
    let mailTransport = mailTransportConfig();

    return {
        updateProjectFavorites,
        updateUserSettings,
        createAccount,
        resetPasswordGenerateLink,
        getUserRegistrationFromUuid,
        getUserForPasswordResetFromUuid,
        setUserResetPasswordFlag,
        clearUserResetPasswordFlag
    };

    function* updateProjectFavorites(next) {
        let attrs = yield parse(this);
        this.body = yield users.updateProjectFavorites(this.reqctx.user.id, this.params.project_id, attrs);
        this.status = status.OK;
        yield next;
    }

    function* updateUserSettings(next) {
        let args = yield parse(this);
        let errors = yield validateUserSettingsArgs(args, this.reqctx.user.id);
        if (errors != null) {
            this.status = status.BAD_REQUEST;
            this.body = errors;
        } else {
            let settingArgs = {
                default_project: args.default_project,
                default_experiment: args.default_experiment
            };
            let rv = yield users.updateUserSettings(this.reqctx.user.id, settingArgs);
            if (rv.error) {
                this.status = status.BAD_REQUEST;
                this.body = rv;
            } else {
                this.body = rv.val;
            }
        }
        yield next;
    }

    function* createAccount(next) {
        let accountArgs = yield parse(this);
        schema.prepare(schema.userAccountSchema, accountArgs);
        let errors = yield validateCreateAccount(accountArgs);
        if (errors !== null) {
            this.status = status.BAD_REQUEST;
            this.body = errors;
        } else {
            let rv = yield users.createUnverifiedAccount(accountArgs);
            if (rv.error) {
                this.status = status.BAD_REQUEST;
                this.body = rv;
            } else {
                let evl = emailValidationLinkToUser(rv.val, accountArgs.site);
                if (evl.error) {
                    this.status = status.BAD_REQUEST;
                    this.body = evl;
                } else {
                    this.body = evl.val;
                }
            }
        }
        yield next;
    }

    function* resetPasswordGenerateLink(next) {
        let resetArgs = yield parse(this);
        let user = yield users.get(resetArgs.email);
        let userId = user.id;
        if (!user) {
            this.status = status.BAD_REQUEST;
            let errorMessage = "No registered user for given email address: "+ resetArgs.email + ". Please register anew.";
            this.body = {error: errorMessage};
        } else {
            let rv = yield users.createPasswordResetRequest(user);
            if (rv.error) {
                this.status = status.BAD_REQUEST;
                this.body = rv;
            } else {
                schema.prepare(schema.userAccountSchema, user);
                let finalUser = yield users.get(userId);
                let evl = emailResetLinkToUser(finalUser, finalUser.site);
                if (evl.error) {
                    this.status = status.BAD_REQUEST;
                    this.body = evl;
                } else {
                    this.body = finalUser;
                }
            }
        }
        yield next;
    }

    function* getUserRegistrationFromUuid(next) {
        let result = yield users.getUserRegistrationFromUuid(this.params.validation_id);
        if (result.error) {
            this.status = status.BAD_REQUEST;
            this.body = result;
        } else {
            this.status = status.OK;
            this.body = result.val;
        }
        yield next;
    }

    function* getUserForPasswordResetFromUuid(next) {
        let result = yield users.getUserForPasswordResetFromUuid(this.params.validation_id);
        if (result.error) {
            this.status = status.BAD_REQUEST;
            this.body = result;
        } else {
            this.status = status.OK;
            this.body = result.val;
        }
        yield next;
    }

    function* setUserResetPasswordFlag(next) {
        let result = yield user.clearResetPassword(this.params.user_id);
        if (result.error) {
            this.status = status.BAD_REQUEST;
            this.body = result;
        } else {
            this.status = status.OK;
            this.body = result.val;
        }
        yield next;
    }

    function* clearUserResetPasswordFlag(next) {
        let result = yield user.clearResetPassword(this.params.user_id);
        if (result.error) {
            this.status = status.BAD_REQUEST;
            this.body = result;
        } else {
            this.status = status.OK;
            this.body = result.val;
        }
        yield next;
    }

    function* validateUserSettingsArgs(args, userId) {
        if (!args.default_project || !_.isString(args.default_project)) {
            return {error: `Bad argument for default_project`};
        }

        let isValidProject = yield users.userHasProjectAccess(userId, args.default_project);
        if (!isValidProject) {
            return {error: `No such project: ${args.default_project}`};
        }

        if (args.default_experiment && !_.isString(args.default_experiment)) {
            return {error: `Bad argument for default_experiment`};
        }

        if (args.default_experiment) {
            let experimentInProject = yield experiments.experimentExistsInProject(args.default_project, args.default_experiment);
            if (!experimentInProject) {
                return {error: `No such experiment ${args.default_experiment} in project ${args.default_project}`};
            }
        } else {
            args.default_experiment = '';
        }

        return null;
    }

    function* validateCreateAccount(accountArgs) {
        return yield schema.validate(schema.userAccountSchema, accountArgs);
    }

    function emailResetLinkToUser(userData,site) {
        var transporter = nodemailer.createTransport(mailTransport);
        var sendTo = userData.id;
        var validationLink = `${process.env.MC_BASE_API_LINK}/reset-validate/${userData.validate_uuid}`;
        if (site === 'mcpub') {
            validationLink = `${process.env.MCPUB_BASE_API_LINK}/reset-validate/${userData.validate_uuid}`
        }
        let emailMsg =
            `Thank you for registering for an account with Materials Commons. To complete the registration
            process please click on the given link or copy and paste in the url given below.`;
        var plainTextBody = `${emailMsg} Please validate using the following URL: ${validationLink}`;
        var htmlBody = `${emailMsg} Please validate by clicking <a href='${validationLink}'>here</a>  or using the following link link: ${validationLink}`;

        var mailOptions = {
            from: process.env.MC_VERIFY_EMAIL,
            to: sendTo,
            subject: 'MaterialCommons - account verification',
            text: plainTextBody,
            html: htmlBody
        };

        // send mail with defined transport object
        transporter.sendMail(mailOptions, function(error, info){
            if(error){
                return {error: error};
            }
        });

        return {val: userData}
    }

    function emailValidationLinkToUser(userData, site) {
        var transporter = nodemailer.createTransport(mailTransport);
        var sendTo = userData.id;
        var validationLink = `${process.env.MC_BASE_API_LINK}/validate/${userData.validate_uuid}`;
        if (site === 'mcpub') {
            validationLink = `${process.env.MCPUB_BASE_API_LINK}/validate/${userData.validate_uuid}`
        }
        let emailMsg =
            `Thank you for registering for an account with Materials Commons. To complete the registration
            process please click on the given link or copy and paste in the url given below.`;
        var plainTextBody = `${emailMsg} Please validate using the following URL: ${validationLink}`;
        var htmlBody = `${emailMsg} Please validate by clicking <a href='${validationLink}'>here</a>  or using the following link link: ${validationLink}`;

        var mailOptions = {
            from: process.env.MC_VERIFY_EMAIL,
            to: sendTo,
            subject: 'MaterialCommons - account verification',
            text: plainTextBody,
            html: htmlBody
        };

        // send mail with defined transport object
        transporter.sendMail(mailOptions, function(error, info){
            if(error){
                return {error: error};
            }
        });

        return {val: userData}
    }

    function mailTransportConfig() {
        if (process.env.MC_SMTP_HOST === 'localhost') {
            return smtpTransport();
        } else {
            let mailURL = `smtps://${process.env.MC_VERIFY_EMAIL}:${process.env.MC_VERIFY_PASS}@${process.env.MC_SMTP_HOST}`;
            return mailURL;
        }
    }

};
<commit_msg>fixed url in e-mail body link/url for the lost-password reset request; feature now working<commit_after>module.exports = function(users, experiments, schema) {
    const parse = require('co-body');
    const status = require('http-status');
    const _ = require('lodash');
    const nodemailer = require('nodemailer');
    const smtpTransport = require('nodemailer-smtp-transport');
    let mailTransport = mailTransportConfig();

    return {
        updateProjectFavorites,
        updateUserSettings,
        createAccount,
        resetPasswordGenerateLink,
        getUserRegistrationFromUuid,
        getUserForPasswordResetFromUuid,
        setUserResetPasswordFlag,
        clearUserResetPasswordFlag
    };

    function* updateProjectFavorites(next) {
        let attrs = yield parse(this);
        this.body = yield users.updateProjectFavorites(this.reqctx.user.id, this.params.project_id, attrs);
        this.status = status.OK;
        yield next;
    }

    function* updateUserSettings(next) {
        let args = yield parse(this);
        let errors = yield validateUserSettingsArgs(args, this.reqctx.user.id);
        if (errors != null) {
            this.status = status.BAD_REQUEST;
            this.body = errors;
        } else {
            let settingArgs = {
                default_project: args.default_project,
                default_experiment: args.default_experiment
            };
            let rv = yield users.updateUserSettings(this.reqctx.user.id, settingArgs);
            if (rv.error) {
                this.status = status.BAD_REQUEST;
                this.body = rv;
            } else {
                this.body = rv.val;
            }
        }
        yield next;
    }

    function* createAccount(next) {
        let accountArgs = yield parse(this);
        schema.prepare(schema.userAccountSchema, accountArgs);
        let errors = yield validateCreateAccount(accountArgs);
        if (errors !== null) {
            this.status = status.BAD_REQUEST;
            this.body = errors;
        } else {
            let rv = yield users.createUnverifiedAccount(accountArgs);
            if (rv.error) {
                this.status = status.BAD_REQUEST;
                this.body = rv;
            } else {
                let evl = emailValidationLinkToUser(rv.val, accountArgs.site);
                if (evl.error) {
                    this.status = status.BAD_REQUEST;
                    this.body = evl;
                } else {
                    this.body = evl.val;
                }
            }
        }
        yield next;
    }

    function* resetPasswordGenerateLink(next) {
        let resetArgs = yield parse(this);
        let user = yield users.get(resetArgs.email);
        let userId = user.id;
        if (!user) {
            this.status = status.BAD_REQUEST;
            let errorMessage = "No registered user for given email address: "+ resetArgs.email + ". Please register anew.";
            this.body = {error: errorMessage};
        } else {
            let rv = yield users.createPasswordResetRequest(user);
            if (rv.error) {
                this.status = status.BAD_REQUEST;
                this.body = rv;
            } else {
                schema.prepare(schema.userAccountSchema, user);
                let finalUser = yield users.get(userId);
                let evl = emailResetLinkToUser(finalUser, finalUser.site);
                if (evl.error) {
                    this.status = status.BAD_REQUEST;
                    this.body = evl;
                } else {
                    this.body = finalUser;
                }
            }
        }
        yield next;
    }

    function* getUserRegistrationFromUuid(next) {
        let result = yield users.getUserRegistrationFromUuid(this.params.validation_id);
        if (result.error) {
            this.status = status.BAD_REQUEST;
            this.body = result;
        } else {
            this.status = status.OK;
            this.body = result.val;
        }
        yield next;
    }

    function* getUserForPasswordResetFromUuid(next) {
        let result = yield users.getUserForPasswordResetFromUuid(this.params.validation_id);
        if (result.error) {
            this.status = status.BAD_REQUEST;
            this.body = result;
        } else {
            this.status = status.OK;
            this.body = result.val;
        }
        yield next;
    }

    function* setUserResetPasswordFlag(next) {
        let result = yield user.clearResetPassword(this.params.user_id);
        if (result.error) {
            this.status = status.BAD_REQUEST;
            this.body = result;
        } else {
            this.status = status.OK;
            this.body = result.val;
        }
        yield next;
    }

    function* clearUserResetPasswordFlag(next) {
        let result = yield user.clearResetPassword(this.params.user_id);
        if (result.error) {
            this.status = status.BAD_REQUEST;
            this.body = result;
        } else {
            this.status = status.OK;
            this.body = result.val;
        }
        yield next;
    }

    function* validateUserSettingsArgs(args, userId) {
        if (!args.default_project || !_.isString(args.default_project)) {
            return {error: `Bad argument for default_project`};
        }

        let isValidProject = yield users.userHasProjectAccess(userId, args.default_project);
        if (!isValidProject) {
            return {error: `No such project: ${args.default_project}`};
        }

        if (args.default_experiment && !_.isString(args.default_experiment)) {
            return {error: `Bad argument for default_experiment`};
        }

        if (args.default_experiment) {
            let experimentInProject = yield experiments.experimentExistsInProject(args.default_project, args.default_experiment);
            if (!experimentInProject) {
                return {error: `No such experiment ${args.default_experiment} in project ${args.default_project}`};
            }
        } else {
            args.default_experiment = '';
        }

        return null;
    }

    function* validateCreateAccount(accountArgs) {
        return yield schema.validate(schema.userAccountSchema, accountArgs);
    }

    function emailResetLinkToUser(userData,site) {
        var transporter = nodemailer.createTransport(mailTransport);
        var sendTo = userData.id;
        var validationLink = `${process.env.MC_BASE_API_LINK}/rvalidate/${userData.validate_uuid}`;
        if (site === 'mcpub') {
            validationLink = `${process.env.MCPUB_BASE_API_LINK}/rvalidate/${userData.validate_uuid}`
        }
        let emailMsg =
            `You have requested a password reset at Materials Commons reset in the account for this email.
            To complete this process please click on the given link or copy and paste in the url given below.`;
        var plainTextBody = `${emailMsg} Please validate using the following URL: ${validationLink}`;
        var htmlBody = `${emailMsg} Please validate by clicking <a href='${validationLink}'>here</a>  or using the following url: ${validationLink}`;

        var mailOptions = {
            from: process.env.MC_VERIFY_EMAIL,
            to: sendTo,
            subject: 'MaterialCommons - account verification',
            text: plainTextBody,
            html: htmlBody
        };

        // send mail with defined transport object
        transporter.sendMail(mailOptions, function(error, info){
            if(error){
                return {error: error};
            }
        });

        return {val: userData}
    }

    function emailValidationLinkToUser(userData, site) {
        var transporter = nodemailer.createTransport(mailTransport);
        var sendTo = userData.id;
        var validationLink = `${process.env.MC_BASE_API_LINK}/validate/${userData.validate_uuid}`;
        if (site === 'mcpub') {
            validationLink = `${process.env.MCPUB_BASE_API_LINK}/validate/${userData.validate_uuid}`
        }
        let emailMsg =
            `Thank you for registering for an account with Materials Commons. To complete the registration
            process please click on the given link or copy and paste in the url given below.`;
        var plainTextBody = `${emailMsg} Please validate using the following URL: ${validationLink}`;
        var htmlBody = `${emailMsg} Please validate by clicking <a href='${validationLink}'>here</a>  or using the following url: ${validationLink}`;

        var mailOptions = {
            from: process.env.MC_VERIFY_EMAIL,
            to: sendTo,
            subject: 'MaterialCommons - account verification',
            text: plainTextBody,
            html: htmlBody
        };

        // send mail with defined transport object
        transporter.sendMail(mailOptions, function(error, info){
            if(error){
                return {error: error};
            }
        });

        return {val: userData}
    }

    function mailTransportConfig() {
        if (process.env.MC_SMTP_HOST === 'localhost') {
            return smtpTransport();
        } else {
            let mailURL = `smtps://${process.env.MC_VERIFY_EMAIL}:${process.env.MC_VERIFY_PASS}@${process.env.MC_SMTP_HOST}`;
            return mailURL;
        }
    }

};
<|endoftext|>


<commit_before>'use babel';

import EventEmitter from 'events';
import fs from 'fs';
import path from 'path';
import os from 'os';
import {execSync} from 'child_process';
import voucher from 'voucher';
import glob from 'glob';

export const config = require('./config');

export function providingFunction()
{
    const generateErrorMatch = [
        "CMake Error at (?<file>[\\/0-9a-zA-Z\\._-]+):(?<line>\\d+)"
    ];
    const generateWarningMatch = [
        "CMake Error at (?<file>[\\/0-9a-zA-Z\\._-]+):(?<line>\\d+)"
    ];
    const compileErrorMatch = [
        "(?<file>.+):(?<line>\\d+):(?<column>\\d+):\\s+(.*\\s+)?error:\\s+(?<message>.+)", // GCC/Clang Error
        "(.*>)?(?<file>.+)\\((?<line>\\d+)\\):\\s+(.*\\s+)?error\\s+(C\\d+):(?<message>.*)" // Visual Studio Error
    ];
    const compileWarningMatch = [
        "(?<file>.+):(?<line>\\d+):(?<column>\\d+):\\s+(.*\\s+)?warning:\\s+(?<message>.+)", // GCC/Clang warning
        "(.*>)?(?<file>.+)\\((?<line>\\d+)\\):\\s+(.*\\s+)?warning\\s+(C\\d+):(?<message>.*)" // Visual Studio warning
    ];
    return class CMakeBuildProvider extends EventEmitter {
        constructor(source_dir)
        {
            super();
            // TODO allow the source directory to be selected.
            this.source_dir = source_dir;

            atom.config.observe('build-cmake.build_suffix', (suffix) => {
                this.build_dir = this.source_dir + suffix;
                this.cache_path = path.join(this.build_dir, 'CMakeCache.txt');
            });
            atom.config.observe('build-cmake.generator', (generator) => {
                // TODO: Validate generator exists and show feedback to user.
                this.generator = (!!generator) ? generator.trim() : '';
            });
            atom.config.observe('build-cmake.executable', (executable) => {
                // TODO: Validate executable is on path/exists and show feedback to user.
                this.executable = executable;
            });
            atom.config.observe('build-cmake.custom_args', (c_args) => {
                this.custom_args = c_args;
            });
            atom.config.observe('build-cmake.vs_args', (args) => {
                this.vs_args = args.split(' ');
            });
            atom.config.onDidChange('build-cmake.build_suffix', () => { this.emit('refresh'); });
            atom.config.onDidChange('build-cmake.executable', () => { this.emit('refresh'); });
            atom.config.onDidChange('build-cmake.generator', () => { this.emit('refresh'); });
            atom.config.onDidChange('build-cmake.custom_args', () => { this.emit('refresh'); });
            atom.config.onDidChange('build-cmake.vs_args', () => { this.emit('refresh'); });
        }

        destructor()
        {
        }

        getNiceName()
        {
            return 'cmake';
        }

        isEligible()
        {
            return fs.existsSync(path.join(this.source_dir, 'CMakeLists.txt')) || fs.existsSync(this.cache_path);
        }

        createVisualStudioTarget(target_name)
        {
            return {
                atomCommandName : 'cmake:' + target_name,
                name : target_name,
                exec : this.executable,
                cwd : this.source_dir,
                args : [ '--build', this.build_dir, '--target', target_name, '--' ].concat(this.vs_args),
                errorMatch : compileErrorMatch.concat(generateErrorMatch),
                warningMatch : compileWarningMatch.concat(generateWarningMatch),
                sh : false
            };
        }

        visualStudioTargets()
        {
            return Array.from(new Set(glob.sync("**/*.vcxproj", { cwd : this.build_dir, nodir : true, ignore : "CMakeFiles/**" })
                                          .map(target => path.basename(target, '.vcxproj'))))
                .map(target => this.createVisualStudioTarget(target))
                .concat([ this.createVisualStudioTarget('clean') ]);
        }

        createMakeFileTarget(target_name)
        {
            return {
                atomCommandName : 'cmake:' + target_name,
                name : target_name,
                exec : this.executable,
                cwd : this.source_dir,
                args : [ '--build', this.build_dir, '--target', target_name, '--', '-j' + os.cpus().length ],
                errorMatch : compileErrorMatch.concat(generateErrorMatch),
                warningMatch : compileWarningMatch.concat(generateWarningMatch),
                sh : false
            };
        }

        makeFileTargets()
        {
            output = execSync(
                this.executable + ' --build "' + this.build_dir + '" --target help', { cwd : this.build_dir });
            return output.toString('utf8')
                .split(/[\r\n]{1,2}/)
                .filter(line => line.startsWith('...'))
                .map((line) => this.createMakeFileTarget(line.replace('... ', '').split(' ')[0]));
        }

        createNinjaTarget(target_name)
        {
            return {
                atomCommandName : 'cmake:' + target_name,
                name : target_name,
                exec : this.executable,
                cwd : this.source_dir,
                args : [ '--build', this.build_dir, '--target', target_name ],
                errorMatch : compileErrorMatch.concat(generateErrorMatch),
                warningMatch : compileWarningMatch.concat(generateWarningMatch),
                sh : false
            };
        }

        ninjaTargets()
        {
            output = execSync(
                this.executable + ' --build "' + this.build_dir + '" -- -t targets', { cwd : this.build_dir });
            return output.toString('utf8')
                .split(/[\r\n]{1,2}/)
                .map((line) => this.createMakeFileTarget(line.split(':')[0].trim()));
        }

        settings()
        {
            fs.unwatchFile(this.cache_path);

            fs.watchFile(this.cache_path, (curr, prev) => {
                if (fs.existsSync(this.cache_path) && curr.mtime != prev.mtime)
                    this.emit('refresh');
            });

            var args = this.custom_args.split(' ').concat([ '-B' + this.build_dir, '-H' + this.source_dir, '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON' ]);
            // Add custom generator if specified.
            if (!!this.generator) {
                args.unshift('-G' + this.generator);
            }
            const generateTarget = {
                atomCommandName : 'cmake:generate',
                name : 'generate',
                exec : this.executable,
                cwd : this.source_dir,
                args : args,
                errorMatch : generateErrorMatch,
                warningMatch : generateWarningMatch,
                sh : false
            };

            return voucher(fs.readFile, this.cache_path, { encoding : 'utf8' })
                .then(cache => {
                    var generator = cache.match(/CMAKE_GENERATOR:INTERNAL=(.*)/)[1];
                    if (generator.match('Visual Studio'))
                        return [ generateTarget ].concat(this.visualStudioTargets());
                    else if (generator.match('Ninja'))
                        return [ generateTarget ].concat(this.ninjaTargets());
                    else
                        return [ generateTarget ].concat(this.makeFileTargets());
                })
                .catch(e => {
                    return [ generateTarget ];
                });
        }
    };
}
<commit_msg>Missed a hunk.<commit_after>'use babel';

import EventEmitter from 'events';
import fs from 'fs';
import path from 'path';
import os from 'os';
import {execSync} from 'child_process';
import voucher from 'voucher';
import glob from 'glob';

export const config = require('./config');

export function providingFunction()
{
    const generateErrorMatch = [
        "CMake Error at (?<file>[\\/0-9a-zA-Z\\._-]+):(?<line>\\d+)"
    ];
    const generateWarningMatch = [
        "CMake Error at (?<file>[\\/0-9a-zA-Z\\._-]+):(?<line>\\d+)"
    ];
    const compileErrorMatch = [
        "(?<file>.+):(?<line>\\d+):(?<column>\\d+):\\s+(.*\\s+)?error:\\s+(?<message>.+)", // GCC/Clang Error
        "(.*>)?(?<file>.+)\\((?<line>\\d+)\\):\\s+(.*\\s+)?error\\s+(C\\d+):(?<message>.*)" // Visual Studio Error
    ];
    const compileWarningMatch = [
        "(?<file>.+):(?<line>\\d+):(?<column>\\d+):\\s+(.*\\s+)?warning:\\s+(?<message>.+)", // GCC/Clang warning
        "(.*>)?(?<file>.+)\\((?<line>\\d+)\\):\\s+(.*\\s+)?warning\\s+(C\\d+):(?<message>.*)" // Visual Studio warning
    ];
    return class CMakeBuildProvider extends EventEmitter {
        constructor(source_dir)
        {
            super();
            // TODO allow the source directory to be selected.
            this.source_dir = source_dir;

            atom.config.observe('build-cmake.build_suffix', (suffix) => {
                this.build_dir = this.source_dir + suffix;
                this.cache_path = path.join(this.build_dir, 'CMakeCache.txt');
            });
            atom.config.observe('build-cmake.generator', (generator) => {
                // TODO: Validate generator exists and show feedback to user.
                this.generator = (!!generator) ? generator.trim() : '';
            });
            atom.config.observe('build-cmake.executable', (executable) => {
                // TODO: Validate executable is on path/exists and show feedback to user.
                this.executable = executable;
            });
            atom.config.observe('build-cmake.custom_args', (c_args) => {
                this.custom_args = c_args;
            });
            atom.config.observe('build-cmake.vs_args', (args) => {
                this.vs_args = args.split(' ');
            });
            atom.config.onDidChange('build-cmake.build_suffix', () => { this.emit('refresh'); });
            atom.config.onDidChange('build-cmake.executable', () => { this.emit('refresh'); });
            atom.config.onDidChange('build-cmake.generator', () => { this.emit('refresh'); });
            atom.config.onDidChange('build-cmake.custom_args', () => { this.emit('refresh'); });
            atom.config.onDidChange('build-cmake.vs_args', () => { this.emit('refresh'); });
        }

        destructor()
        {
        }

        getNiceName()
        {
            return 'cmake';
        }

        isEligible()
        {
            return fs.existsSync(path.join(this.source_dir, 'CMakeLists.txt')) || fs.existsSync(this.cache_path);
        }

        createVisualStudioTarget(target_name)
        {
            return {
                atomCommandName : 'cmake:' + target_name,
                name : target_name,
                exec : this.executable,
                cwd : this.source_dir,
                args : [ '--build', this.build_dir, '--target', target_name, '--' ].concat(this.vs_args),
                errorMatch : compileErrorMatch.concat(generateErrorMatch),
                warningMatch : compileWarningMatch.concat(generateWarningMatch),
                sh : false
            };
        }

        visualStudioTargets()
        {
            return Array.from(new Set(glob.sync("**/*.vcxproj", { cwd : this.build_dir, nodir : true, ignore : "CMakeFiles/**" })
                                          .map(target => path.basename(target, '.vcxproj'))))
                .map(target => this.createVisualStudioTarget(target))
                .concat([ this.createVisualStudioTarget('clean') ]);
        }

        createMakeFileTarget(target_name)
        {
            return {
                atomCommandName : 'cmake:' + target_name,
                name : target_name,
                exec : this.executable,
                cwd : this.source_dir,
                args : [ '--build', this.build_dir, '--target', target_name, '--', '-j' + os.cpus().length ],
                errorMatch : compileErrorMatch.concat(generateErrorMatch),
                warningMatch : compileWarningMatch.concat(generateWarningMatch),
                sh : false
            };
        }

        makeFileTargets()
        {
            output = execSync(
                this.executable + ' --build "' + this.build_dir + '" --target help', { cwd : this.build_dir });
            return output.toString('utf8')
                .split(/[\r\n]{1,2}/)
                .filter(line => line.startsWith('...'))
                .map((line) => this.createMakeFileTarget(line.replace('... ', '').split(' ')[0]));
        }

        createNinjaTarget(target_name)
        {
            return {
                atomCommandName : 'cmake:' + target_name,
                name : target_name,
                exec : this.executable,
                cwd : this.source_dir,
                args : [ '--build', this.build_dir, '--target', target_name ],
                errorMatch : compileErrorMatch.concat(generateErrorMatch),
                warningMatch : compileWarningMatch.concat(generateWarningMatch),
                sh : false
            };
        }

        ninjaTargets()
        {
            output = execSync(
                this.executable + ' --build "' + this.build_dir + '" -- -t targets', { cwd : this.build_dir });
            return output.toString('utf8')
                .split(/[\r\n]{1,2}/)
                .map((line) => this.createNinjaTarget(line.split(':')[0].trim()));
        }

        settings()
        {
            fs.unwatchFile(this.cache_path);

            fs.watchFile(this.cache_path, (curr, prev) => {
                if (fs.existsSync(this.cache_path) && curr.mtime != prev.mtime)
                    this.emit('refresh');
            });

            var args = this.custom_args.split(' ').concat([ '-B' + this.build_dir, '-H' + this.source_dir, '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON' ]);
            // Add custom generator if specified.
            if (!!this.generator) {
                args.unshift('-G' + this.generator);
            }
            const generateTarget = {
                atomCommandName : 'cmake:generate',
                name : 'generate',
                exec : this.executable,
                cwd : this.source_dir,
                args : args,
                errorMatch : generateErrorMatch,
                warningMatch : generateWarningMatch,
                sh : false
            };

            return voucher(fs.readFile, this.cache_path, { encoding : 'utf8' })
                .then(cache => {
                    var generator = cache.match(/CMAKE_GENERATOR:INTERNAL=(.*)/)[1];
                    if (generator.match('Visual Studio'))
                        return [ generateTarget ].concat(this.visualStudioTargets());
                    else if (generator.match('Ninja'))
                        return [ generateTarget ].concat(this.ninjaTargets());
                    else
                        return [ generateTarget ].concat(this.makeFileTargets());
                })
                .catch(e => {
                    return [ generateTarget ];
                });
        }
    };
}
<|endoftext|>


<commit_before>'use strict';
// 1.0.0

angular.module('amChartsDirective', []).directive('amChart', function() {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      options: '=',
      height: '=',
      width: '='
    },
    template: '

',
    link: function($scope, $el) {

      // use existing outer id to create new id
      var id = $el[0].id;
      $el.attr('id', id);
      var chart;

      // we can't render a chart without any data
      if ($scope.options.data) {
        var renderChart = function(amChartOptions) {
          var o = amChartOptions || $scope.options;

          // set height and width
          var height = $scope.height || '400px';
          var width = $scope.width || '600px';

          $el.css({
            'height': height,
            'width': width
          });

          // instantiate new chart object
          if (o.type === 'xy') {
            chart = new AmCharts.AmXYChart();
          } else {
            chart = new AmCharts.AmSerialChart();
          }

          /** set some default values that amCharts doesnt provide **/
          chart.dataProvider = o.data;
          // if a category field is not specified, attempt to use the first field from an object in the array
          chart.categoryField = o.categoryField || Object.keys(o.data[0])[0];
          chart.startDuration = 0.5; // default animation length, because everyone loves a little pizazz

          // AutoMargin is on by default, but the default 20px all around seems to create unnecessary white space around the control
          chart.autoMargins = true;
          chart.marginTop = 0;
          chart.marginLeft = 0;
          chart.marginBottom = 0;
          chart.marginRight = 0;

          // modify default creditsPosition
          chart.creditsPosition = o.creditsPosition || 'top-right';

          var chartKeys = Object.keys(o);
          for (var i = 0; i < chartKeys.length; i++) {
            if (typeof o[chartKeys[i]] !== 'object' && typeof o[chartKeys[i]] !== 'function') {
              chart[chartKeys[i]] = o[chartKeys[i]];
            }
          }

          // Assign Category Axis Properties
          if (o.categoryAxis) {
            var categoryAxis = chart.categoryAxis;

            if (categoryAxis) {
              /* if we need to create any default values, we should assign them here */
              categoryAxis.parseDates = true;

              var keys = Object.keys(o.categoryAxis);
              for (var i = 0; i < keys.length; i++) {
                if (typeof o.categoryAxis[keys[i]] !== 'object') {
                  categoryAxis[keys[i]] = o.categoryAxis[keys[i]];
                }
              }
              chart.categoryAxis = categoryAxis;
            }
          }

          // Create value axis

          /* if we need to create any default values, we should assign them here */

          var addValueAxis = function (a) {
            var valueAxis = new AmCharts.ValueAxis();

            var keys = Object.keys(a);
            for (var i = 0; i < keys.length; i++) {
              if (typeof a[keys[i]] !== 'object') {
                valueAxis[keys[i]] = a[keys[i]];
              }
            }
            chart.addValueAxis(valueAxis);
          };

          if (o.valueAxes && o.valueAxes.length > 0) {
            for (var i = 0; i < o.valueAxes.length; i++) {
              addValueAxis(o.valueAxes[i])
            }
          }

          //reusable function to create graph
          var addGraph = function (g) {
            var graph = new AmCharts.AmGraph();
            /** set some default values that amCharts doesnt provide **/
              // if a category field is not specified, attempt to use the second field from an object in the array as a default value
            graph.valueField = g.valueField || Object.keys(o.data[0])[1];
            graph.balloonText = '[[category]]: [[value]]';
            if (g) {
              var keys = Object.keys(g);
              // iterate over all of the properties in the graph object and apply them to the new AmGraph
              for (var i = 0; i < keys.length; i++) {
                graph[keys[i]] = g[keys[i]];
              }
            }
            chart.addGraph(graph);
          };

          // create the graphs
          if (o.graphs && o.graphs.length > 0) {
            for (var i = 0; i < o.graphs.length; i++) {
              addGraph(o.graphs[i]);
            }
          } else {
            addGraph();
          }

          var chartCursor = new AmCharts.ChartCursor();
          if (o.chartCursor) {
            var keys = Object.keys(o.chartCursor);
            for (var i = 0; i < keys.length; i++) {
              if (typeof o.chartCursor[keys[i]] !== 'object') {
                chartCursor[keys[i]] = o.chartCursor[keys[i]];
              }
            }
          }
          chart.addChartCursor(chartCursor);

          // WRITE
          chart.write(id);
        };

        // Render the chart
        renderChart();

        // EVENTS =========================================================================

        $scope.$on('amCharts.triggerChartAnimate', function(event, id){
          if (id === $el[0].id || !id) {
            chart.animateAgain();
          }
        });

        $scope.$on('amCharts.updateData', function(event, data, id){
          if (id === $el[0].id || !id){
            chart.dataProvider = data;
            chart.validateData();
          }

        });

        $scope.$on('amCharts.validateNow', function(event, validateData, skipEvents, id){
          if (id === $el[0].id || !id){
            chart.validateNow(validateData === undefined ? true : validateData,
              skipEvents === undefined ? false : skipEvents)
          }
        });

        $scope.$on('amCharts.renderChart', function(event, amChartOptions,  id){
          if (id === $el[0].id || !id) {
            renderChart(amChartOptions);
          }
        });

      }

    }
  };
});

<commit_msg>Allow arrays into categoryAxis options<commit_after>'use strict';
// 1.0.0

angular.module('amChartsDirective', []).directive('amChart', function() {
  return {
    restrict: 'E',
    replace: true,
    scope: {
      options: '=',
      height: '=',
      width: '='
    },
    template: '

',
    link: function($scope, $el) {

      // use existing outer id to create new id
      var id = $el[0].id;
      $el.attr('id', id);
      var chart;

      // we can't render a chart without any data
      if ($scope.options.data) {
        var renderChart = function(amChartOptions) {
          var o = amChartOptions || $scope.options;

          // set height and width
          var height = $scope.height || '400px';
          var width = $scope.width || '600px';

          $el.css({
            'height': height,
            'width': width
          });

          // instantiate new chart object
          if (o.type === 'xy') {
            chart = new AmCharts.AmXYChart();
          } else {
            chart = new AmCharts.AmSerialChart();
          }

          /** set some default values that amCharts doesnt provide **/
          chart.dataProvider = o.data;
          // if a category field is not specified, attempt to use the first field from an object in the array
          chart.categoryField = o.categoryField || Object.keys(o.data[0])[0];
          chart.startDuration = 0.5; // default animation length, because everyone loves a little pizazz

          // AutoMargin is on by default, but the default 20px all around seems to create unnecessary white space around the control
          chart.autoMargins = true;
          chart.marginTop = 0;
          chart.marginLeft = 0;
          chart.marginBottom = 0;
          chart.marginRight = 0;

          // modify default creditsPosition
          chart.creditsPosition = o.creditsPosition || 'top-right';

          var chartKeys = Object.keys(o);
          for (var i = 0; i < chartKeys.length; i++) {
            if (typeof o[chartKeys[i]] !== 'object' && typeof o[chartKeys[i]] !== 'function') {
              chart[chartKeys[i]] = o[chartKeys[i]];
            }
          }

          // Assign Category Axis Properties
          if (o.categoryAxis) {
            var categoryAxis = chart.categoryAxis;

            if (categoryAxis) {
              /* if we need to create any default values, we should assign them here */
              categoryAxis.parseDates = true;

              var keys = Object.keys(o.categoryAxis);
              for (var i = 0; i < keys.length; i++) {
                if (!angular.isObject(o.categoryAxis[keys[i]]) || angular.isArray(o.categoryAxis[keys[i]])) {
                  categoryAxis[keys[i]] = o.categoryAxis[keys[i]];
                } else {
                  console.log('Stripped categoryAxis obj ' + keys[i]);
                }
              }
              chart.categoryAxis = categoryAxis;
            }
          }

          // Create value axis

          /* if we need to create any default values, we should assign them here */

          var addValueAxis = function (a) {
            var valueAxis = new AmCharts.ValueAxis();

            var keys = Object.keys(a);
            for (var i = 0; i < keys.length; i++) {
              if (typeof a[keys[i]] !== 'object') {
                valueAxis[keys[i]] = a[keys[i]];
              }
            }
            chart.addValueAxis(valueAxis);
          };

          if (o.valueAxes && o.valueAxes.length > 0) {
            for (var i = 0; i < o.valueAxes.length; i++) {
              addValueAxis(o.valueAxes[i])
            }
          }

          //reusable function to create graph
          var addGraph = function (g) {
            var graph = new AmCharts.AmGraph();
            /** set some default values that amCharts doesnt provide **/
              // if a category field is not specified, attempt to use the second field from an object in the array as a default value
            graph.valueField = g.valueField || Object.keys(o.data[0])[1];
            graph.balloonText = '[[category]]: [[value]]';
            if (g) {
              var keys = Object.keys(g);
              // iterate over all of the properties in the graph object and apply them to the new AmGraph
              for (var i = 0; i < keys.length; i++) {
                graph[keys[i]] = g[keys[i]];
              }
            }
            chart.addGraph(graph);
          };

          // create the graphs
          if (o.graphs && o.graphs.length > 0) {
            for (var i = 0; i < o.graphs.length; i++) {
              addGraph(o.graphs[i]);
            }
          } else {
            addGraph();
          }

          var chartCursor = new AmCharts.ChartCursor();
          if (o.chartCursor) {
            var keys = Object.keys(o.chartCursor);
            for (var i = 0; i < keys.length; i++) {
              if (typeof o.chartCursor[keys[i]] !== 'object') {
                chartCursor[keys[i]] = o.chartCursor[keys[i]];
              }
            }
          }
          chart.addChartCursor(chartCursor);

          // WRITE
          chart.write(id);
        };

        // Render the chart
        renderChart();

        // EVENTS =========================================================================

        $scope.$on('amCharts.triggerChartAnimate', function(event, id){
          if (id === $el[0].id || !id) {
            chart.animateAgain();
          }
        });

        $scope.$on('amCharts.updateData', function(event, data, id){
          if (id === $el[0].id || !id){
            chart.dataProvider = data;
            chart.validateData();
          }

        });

        $scope.$on('amCharts.validateNow', function(event, validateData, skipEvents, id){
          if (id === $el[0].id || !id){
            chart.validateNow(validateData === undefined ? true : validateData,
              skipEvents === undefined ? false : skipEvents)
          }
        });

        $scope.$on('amCharts.renderChart', function(event, amChartOptions,  id){
          if (id === $el[0].id || !id) {
            renderChart(amChartOptions);
          }
        });

      }

    }
  };
});

<|endoftext|>