<commit_before>// TODO: learn how node streams work...

var dissolve = require('dissolve')
var concentrate = require('concentrate')

var COMMANDS = {
  0: function keepAlive(o) {
    // TODO: raise an event, so caller might reply?
    return o
  },
  1: function connectionAccepted(o) {
    o.data = JSON.parse(o.payload)
    return o
  },
  2: function connectionRefused(o) {
    // TODO: raise an event, we might want to disconnect
    return o
  },
  3: function dataUpdate(o) {
    // TODO: this needs to be parsed inside the dissolve.loop
    return o
  },
  4: function mapUpdate(o) {
    // TODO: this needs to be parsed inside the dissolve.loop
    return o
  },
  5: function command(o) {
    o.data = JSON.parse(o.payload)
    return o
  },
  6: function comandReply(o) {
    // TODO: this needs to be parsed inside the dissolve.loop
    return o
  },
}

function opcodeMissing(o) {
  o.error = 'has no handler or previous command not handled correctly'
  console.trace('opcodeMissing')
  o.name = opcodeMissing.name
  return o
}

var parser = module.exports = dissolve().loop(function(end) {
  this.uint32('length').tap(function() {
    this.int8('typeId').tap(function() {
      if (this.vars.length) {
        this.buffer('payload', this.vars.length)
        // TODO parse data_update, map_update here
      }
    })
  }).tap(function() {
    var command = COMMANDS[this.vars.typeId]
    if (typeof command === 'function') {
      var message = command(this.vars)
      message.name = command.name

      this.push(message)
    } else {
      this.push(opcodeMissing(this.vars))
    }

    this.vars = {} // reset
  })
})
<commit_msg>parse command type information<commit_after>// TODO: learn how node streams work...

var dissolve = require('dissolve')
var concentrate = require('concentrate')

var COMMAND_TYPES = {
  0: 'UseItem',
  1: 'DropItem',
  2: 'SetFavorite',
  3: 'ToggleComponentFavorite',
  4: 'SortInventory',
  5: 'ToggleQuestActive',
  6: 'SetCustomMapMarker',
  7: 'RemoveCustomMapMarker',
  8: 'CheckFastTravel',
  9: 'FastTravel',
  10: 'MoveLocalMap',
  11: 'ZoomLocalMap',
  12: 'ToggleRadioStation',
  13: 'RequestLocalMapSnapshot',
  14: 'ClearIdle',
};

var COMMANDS = {
  0: function keepAlive(o) {
    // TODO: raise an event, so caller might reply?
    return o
  },
  1: function connectionAccepted(o) {
    o.data = JSON.parse(o.payload)
    return o
  },
  2: function connectionRefused(o) {
    // TODO: raise an event, we might want to disconnect
    return o
  },
  3: function dataUpdate(o) {
    // TODO: this needs to be parsed inside the dissolve.loop
    return o
  },
  4: function mapUpdate(o) {
    // TODO: this needs to be parsed inside the dissolve.loop
    return o
  },
  5: function command(o) {
    o.data = JSON.parse(o.payload)
    if (COMMAND_TYPES[o.data.type]) {
      o.data.name = COMMAND_TYPES[o.data.type];
    }
    return o
  },
  6: function comandReply(o) {
    // TODO: this needs to be parsed inside the dissolve.loop
    return o
  },
}

function opcodeMissing(o) {
  o.error = 'has no handler or previous command not handled correctly'
  console.trace('opcodeMissing')
  o.name = opcodeMissing.name
  return o
}

var parser = module.exports = dissolve().loop(function(end) {
  this.uint32('length').tap(function() {
    this.int8('typeId').tap(function() {
      if (this.vars.length) {
        this.buffer('payload', this.vars.length)
        // TODO parse data_update, map_update here
      }
    })
  }).tap(function() {
    var command = COMMANDS[this.vars.typeId]
    if (typeof command === 'function') {
      var message = command(this.vars)
      message.name = command.name

      this.push(message)
    } else {
      this.push(opcodeMissing(this.vars))
    }

    this.vars = {} // reset
  })
})
<|endoftext|>


<commit_before>Factlink.triggerClick = function () {
  console.info("someone triggered a click");
};
<commit_msg>Created triggerClick method which handles extension clicks and decides what to do, depending on the user selection<commit_after>(function(Factlink, $, _, easyXDM, window, undefined) {

  Factlink.triggerClick = function () {
    var top = (window.innerHeight/2)-12 + window.pageYOffset,
        left = (window.innerWidth/2)-39.5 + window.pageXOffset;

    if ( Factlink.textSelected() ) {
      Factlink.createFactFromSelection();

      Factlink.prepare.show(top, left);
      Factlink.prepare.startLoading();
    } else {
      $('#fl').append("
Please select text to create a Factlink
");

      $('#fl .fl-message').fadeIn('slow');

      setTimeout(function() {
        $('#fl .fl-message').fadeOut('slow');
      }, 2545);
    }
  };

})(window.Factlink, Factlink.$, Factlink._, Factlink.easyXDM, Factlink.global);
<|endoftext|>


<commit_before>'use strict'

var StringDecoder = require('string_decoder').StringDecoder
var decoder = new StringDecoder()
var ReplyError = require('./replyError')
var bufferPool = new Buffer(32 * 1024)
var bufferOffset = 0
var interval = null
var counter = 0
var notDecreased = 0

/**
 * Used for lengths and numbers only, faster perf on arrays / bulks
 * @param parser
 * @returns {*}
 */
function parseSimpleNumbers (parser) {
  var offset = parser.offset
  var length = parser.buffer.length
  var number = 0
  var sign = false

  if (parser.buffer[offset] === 45) {
    sign = true
    offset++
  }

  while (offset < length) {
    var c1 = parser.buffer[offset++]
    if (c1 === 13 && parser.buffer[offset] === 10) { // \r\n
      parser.offset = offset + 1
      return sign ? -number : number
    }
    number = (number * 10) + (c1 - 48)
  }
}

/**
 * Used for integer numbers in case of the returnNumbers option
 * @param parser
 * @returns {*}
 */
function parseStringNumbers (parser) {
  var offset = parser.offset
  var length = parser.buffer.length
  var number = ''

  if (parser.buffer[offset] === 45) {
    number += '-'
    offset++
  }

  while (offset < length) {
    var c1 = parser.buffer[offset++]
    if (c1 === 13 && parser.buffer[offset] === 10) { // \r\n
      parser.offset = offset + 1
      return number
    }
    number += c1 - 48
  }
}

/**
 * Returns a string or buffer of the provided offset start and
 * end ranges. Checks `optionReturnBuffers`.
 * @param parser
 * @param start
 * @param end
 * @returns {*}
 */
function convertBufferRange (parser, start, end) {
  // If returnBuffers is active, all return values are returned as buffers besides numbers and errors
  parser.offset = end + 2
  if (parser.optionReturnBuffers === true) {
    return parser.buffer.slice(start, end)
  }

  return parser.buffer.toString('utf-8', start, end)
}

/**
 * Parse a '+' redis simple string response but forward the offsets
 * onto convertBufferRange to generate a string.
 * @param parser
 * @returns {*}
 */
function parseSimpleStringViaOffset (parser) {
  var start = parser.offset
  var offset = parser.offset
  var length = parser.buffer.length
  var buffer = parser.buffer

  while (offset < length) {
    if (buffer[offset++] === 10) { // \r\n
      return convertBufferRange(parser, start, offset - 2)
    }
  }
}

/**
 * Returns the string length via parseSimpleNumbers
 * @param parser
 * @returns {*}
 */
function parseLength (parser) {
  var string = parseSimpleNumbers(parser)
  if (string !== undefined) {
    return +string
  }
}

/**
 * Parse a ':' redis integer response
 * @param parser
 * @returns {*}
 */
function parseInteger (parser) {
  // If stringNumbers is activated the parser always returns numbers as string
  // This is important for big numbers (number > Math.pow(2, 53)) as js numbers
  // are 64bit floating point numbers with reduced precision
  if (parser.optionStringNumbers) {
    return parseStringNumbers(parser)
  }
  return parseSimpleNumbers(parser)
}

/**
 * Parse a '$' redis bulk string response
 * @param parser
 * @returns {*}
 */
function parseBulkString (parser) {
  var length = parseLength(parser)
  if (length === undefined) {
    return
  }
  if (length === -1) {
    return null
  }
  var offsetEnd = parser.offset + length
  if (offsetEnd + 2 > parser.buffer.length) {
    parser.bigStrSize = offsetEnd + 2
    parser.bigOffset = parser.offset
    parser.totalChunkSize = parser.buffer.length
    parser.bufferCache.push(parser.buffer)
    return
  }

  return convertBufferRange(parser, parser.offset, offsetEnd)
}

/**
 * Parse a '-' redis error response
 * @param parser
 * @returns {Error}
 */
function parseError (parser) {
  var string = parseSimpleStringViaOffset(parser)
  if (string !== undefined) {
    if (parser.optionReturnBuffers === true) {
      string = string.toString()
    }
    return new ReplyError(string)
  }
}

/**
 * Parsing error handler, resets parser buffer
 * @param parser
 * @param error
 */
function handleError (parser, error) {
  parser.buffer = null
  parser.returnFatalError(error)
}

/**
 * Parse a '*' redis array response
 * @param parser
 * @returns {*}
 */
function parseArray (parser) {
  var length = parseLength(parser)
  if (length === undefined) {
    return
  }
  if (length === -1) {
    return null
  }

  var responses = new Array(length)
  var bufferLength = parser.buffer.length
  for (var i = 0; i < length; i++) {
    if (parser.offset >= bufferLength) {
      return
    }
    var response = parseType(parser, parser.buffer[parser.offset++])
    if (response === undefined) {
      return
    }
    responses[i] = response
  }

  return responses
}

/**
 * Called the appropriate parser for the specified type.
 * @param parser
 * @param type
 * @returns {*}
 */
function parseType (parser, type) {
  switch (type) {
    case 36: // $
      return parseBulkString(parser)
    case 58: // :
      return parseInteger(parser)
    case 43: // +
      return parseSimpleStringViaOffset(parser)
    case 42: // *
      return parseArray(parser)
    case 45: // -
      return parseError(parser)
    default:
      const err = new ReplyError('Protocol error, got ' + JSON.stringify(String.fromCharCode(type)) + ' as reply type byte', 20)
      err.offset = parser.offset
      err.buffer = JSON.stringify(parser.buffer)
      return handleError(parser, err)
  }
}

// All allowed options including their typeof value
var optionTypes = {
  returnError: 'function',
  returnFatalError: 'function',
  returnReply: 'function',
  returnBuffers: 'boolean',
  stringNumbers: 'boolean',
  name: 'string'
}

/**
 * Javascript Redis Parser
 * @param options
 * @constructor
 */
function JavascriptRedisParser (options) {
  if (!(this instanceof JavascriptRedisParser)) {
    return new JavascriptRedisParser(options)
  }
  if (!options || !options.returnError || !options.returnReply) {
    throw new TypeError('Please provide all return functions while initiating the parser')
  }
  for (var key in options) {
    if (typeof options[key] !== optionTypes[key]) {
      throw new TypeError('The options argument contains the property "' + key + '" that is either unkown or of a wrong type')
    }
  }
  if (options.name === 'hiredis') {
    /* istanbul ignore next: hiredis is only supported for legacy usage */
    try {
      var Hiredis = require('./hiredis')
      console.error(new TypeError('Using hiredis is discouraged. Please use the faster JS parser by removing the name option.').stack.replace('Error', 'Warning'))
      return new Hiredis(options)
    } catch (e) {
      console.error(new TypeError('Hiredis is not installed. Please remove the `name` option. The (faster) JS parser is used instead.').stack.replace('Error', 'Warning'))
    }
  }
  this.optionReturnBuffers = !!options.returnBuffers
  this.optionStringNumbers = !!options.stringNumbers
  this.returnError = options.returnError
  this.returnFatalError = options.returnFatalError || options.returnError
  this.returnReply = options.returnReply
  this.name = 'javascript'
  this.offset = 0
  this.buffer = null
  this.bigStrSize = 0
  this.bigOffset = 0
  this.totalChunkSize = 0
  this.bufferCache = []
}

/**
 * Concat a bulk string containing multiple chunks
 * @param parser
 * @param buffer
 * @returns {String}
 */
function concatBulkString (parser) {
  var list = parser.bufferCache
  // The first chunk might contain the whole bulk string including the \r
  var chunks = list.length
  var offset = parser.bigStrSize - parser.totalChunkSize
  parser.offset = offset
  if (offset === 1) {
    if (chunks === 2) {
      return list[0].toString('utf8', parser.bigOffset, list[0].length - 1)
    }
  } else {
    chunks++
  }
  var res = decoder.write(list[0].slice(parser.bigOffset))
  for (var i = 1; i < chunks - 2; i++) {
    // We are only safe to fully add up elements that are neither the first nor any of the last two elements
    res += decoder.write(list[i])
  }
  res += decoder.end(list[i].slice(0, offset === 1 ? list[i].length - 1 : offset - 2))
  return res
}

/**
 * Decrease the bufferPool size over time
 * @returns {undefined}
 */
function decreaseBufferPool () {
  if (bufferPool.length > 50 * 1024) {
    // Balance between increasing and decreasing the bufferPool
    if (counter === 1 || notDecreased > counter * 2) {
      // Decrease the bufferPool by 16kb by removing the first 16kb of the current pool
      bufferPool = bufferPool.slice(Math.floor(bufferPool.length / 10), bufferPool.length)
    } else {
      notDecreased++
      counter--
    }
  } else {
    clearInterval(interval)
    counter = 0
    notDecreased = 0
    interval = null
  }
}

/**
 * Concat the collected chunks from parser.bufferCache
 * @param parser
 * @param length
 * @returns {Buffer}
 */
function concatBuffer (parser, length) {
  var list = parser.bufferCache
  var pos = bufferOffset
  length -= parser.offset
  if (bufferPool.length < length + bufferOffset) {
    // Increase the bufferPool size by three times the current needed length
    var multiplier = 3
    if (bufferOffset > 1024 * 1024 * 200) {
      bufferOffset = 1024 * 1024 * 50
      multiplier = 2
    }
    bufferPool = new Buffer(length * multiplier + bufferOffset)
    bufferOffset = 0
    counter++
    pos = 0
    if (interval === null) {
      interval = setInterval(decreaseBufferPool, 50)
    }
  }
  list[0].copy(bufferPool, pos, parser.offset, list[0].length)
  pos += list[0].length - parser.offset
  for (var i = 1; i < list.length; i++) {
    list[i].copy(bufferPool, pos)
    pos += list[i].length
  }
  var buffer = bufferPool.slice(bufferOffset, length + bufferOffset)
  bufferOffset += length
  return buffer
}

/**
 * Parse the redis buffer
 * @param buffer
 * @returns {undefined}
 */
JavascriptRedisParser.prototype.execute = function (buffer) {
  if (this.buffer === null) {
    this.buffer = buffer
    this.offset = 0
  } else if (this.bigStrSize === 0) {
    var oldLength = this.buffer.length
    var remainingLength = oldLength - this.offset
    var newBuffer = new Buffer(remainingLength + buffer.length)
    this.buffer.copy(newBuffer, 0, this.offset, oldLength)
    buffer.copy(newBuffer, remainingLength, 0, buffer.length)
    this.buffer = newBuffer
    this.offset = 0
  } else if (this.totalChunkSize + buffer.length >= this.bigStrSize) {
    this.bufferCache.push(buffer)
    // The returned type might be Array * (42) and in that case we can't improve the parsing currently
    if (this.optionReturnBuffers === false && this.buffer[this.offset] === 36) {
      this.returnReply(concatBulkString(this))
      this.buffer = buffer
    } else { // This applies for arrays too
      this.buffer = concatBuffer(this, this.totalChunkSize + buffer.length)
      this.offset = 0
    }
    this.bigStrSize = 0
    this.totalChunkSize = 0
    this.bufferCache = []
  } else {
    this.bufferCache.push(buffer)
    this.totalChunkSize += buffer.length
    return
  }

  while (this.offset < this.buffer.length) {
    var offset = this.offset
    var type = this.buffer[this.offset++]
    var response = parseType(this, type)
    if (response === undefined) {
      this.offset = offset
      return
    }

    if (type === 45) {
      this.returnError(response) // Errors -
    } else {
      this.returnReply(response) // Strings + // Integers : // Bulk strings $ // Arrays *
    }
  }

  this.buffer = null
}

module.exports = JavascriptRedisParser
<commit_msg>Accept inherited attributes etc.<commit_after>'use strict'

var StringDecoder = require('string_decoder').StringDecoder
var decoder = new StringDecoder()
var ReplyError = require('./replyError')
var bufferPool = new Buffer(32 * 1024)
var bufferOffset = 0
var interval = null
var counter = 0
var notDecreased = 0

/**
 * Used for lengths and numbers only, faster perf on arrays / bulks
 * @param parser
 * @returns {*}
 */
function parseSimpleNumbers (parser) {
  var offset = parser.offset
  var length = parser.buffer.length
  var number = 0
  var sign = false

  if (parser.buffer[offset] === 45) {
    sign = true
    offset++
  }

  while (offset < length) {
    var c1 = parser.buffer[offset++]
    if (c1 === 13 && parser.buffer[offset] === 10) { // \r\n
      parser.offset = offset + 1
      return sign ? -number : number
    }
    number = (number * 10) + (c1 - 48)
  }
}

/**
 * Used for integer numbers in case of the returnNumbers option
 * @param parser
 * @returns {*}
 */
function parseStringNumbers (parser) {
  var offset = parser.offset
  var length = parser.buffer.length
  var number = ''

  if (parser.buffer[offset] === 45) {
    number += '-'
    offset++
  }

  while (offset < length) {
    var c1 = parser.buffer[offset++]
    if (c1 === 13 && parser.buffer[offset] === 10) { // \r\n
      parser.offset = offset + 1
      return number
    }
    number += c1 - 48
  }
}

/**
 * Returns a string or buffer of the provided offset start and
 * end ranges. Checks `optionReturnBuffers`.
 * @param parser
 * @param start
 * @param end
 * @returns {*}
 */
function convertBufferRange (parser, start, end) {
  // If returnBuffers is active, all return values are returned as buffers besides numbers and errors
  parser.offset = end + 2
  if (parser.optionReturnBuffers === true) {
    return parser.buffer.slice(start, end)
  }

  return parser.buffer.toString('utf-8', start, end)
}

/**
 * Parse a '+' redis simple string response but forward the offsets
 * onto convertBufferRange to generate a string.
 * @param parser
 * @returns {*}
 */
function parseSimpleStringViaOffset (parser) {
  var start = parser.offset
  var offset = parser.offset
  var length = parser.buffer.length
  var buffer = parser.buffer

  while (offset < length) {
    if (buffer[offset++] === 10) { // \r\n
      return convertBufferRange(parser, start, offset - 2)
    }
  }
}

/**
 * Returns the string length via parseSimpleNumbers
 * @param parser
 * @returns {*}
 */
function parseLength (parser) {
  var string = parseSimpleNumbers(parser)
  if (string !== undefined) {
    return +string
  }
}

/**
 * Parse a ':' redis integer response
 * @param parser
 * @returns {*}
 */
function parseInteger (parser) {
  // If stringNumbers is activated the parser always returns numbers as string
  // This is important for big numbers (number > Math.pow(2, 53)) as js numbers
  // are 64bit floating point numbers with reduced precision
  if (parser.optionStringNumbers) {
    return parseStringNumbers(parser)
  }
  return parseSimpleNumbers(parser)
}

/**
 * Parse a '$' redis bulk string response
 * @param parser
 * @returns {*}
 */
function parseBulkString (parser) {
  var length = parseLength(parser)
  if (length === undefined) {
    return
  }
  if (length === -1) {
    return null
  }
  var offsetEnd = parser.offset + length
  if (offsetEnd + 2 > parser.buffer.length) {
    parser.bigStrSize = offsetEnd + 2
    parser.bigOffset = parser.offset
    parser.totalChunkSize = parser.buffer.length
    parser.bufferCache.push(parser.buffer)
    return
  }

  return convertBufferRange(parser, parser.offset, offsetEnd)
}

/**
 * Parse a '-' redis error response
 * @param parser
 * @returns {Error}
 */
function parseError (parser) {
  var string = parseSimpleStringViaOffset(parser)
  if (string !== undefined) {
    if (parser.optionReturnBuffers === true) {
      string = string.toString()
    }
    return new ReplyError(string)
  }
}

/**
 * Parsing error handler, resets parser buffer
 * @param parser
 * @param error
 */
function handleError (parser, error) {
  parser.buffer = null
  parser.returnFatalError(error)
}

/**
 * Parse a '*' redis array response
 * @param parser
 * @returns {*}
 */
function parseArray (parser) {
  var length = parseLength(parser)
  if (length === undefined) {
    return
  }
  if (length === -1) {
    return null
  }

  var responses = new Array(length)
  var bufferLength = parser.buffer.length
  for (var i = 0; i < length; i++) {
    if (parser.offset >= bufferLength) {
      return
    }
    var response = parseType(parser, parser.buffer[parser.offset++])
    if (response === undefined) {
      return
    }
    responses[i] = response
  }

  return responses
}

/**
 * Called the appropriate parser for the specified type.
 * @param parser
 * @param type
 * @returns {*}
 */
function parseType (parser, type) {
  switch (type) {
    case 36: // $
      return parseBulkString(parser)
    case 58: // :
      return parseInteger(parser)
    case 43: // +
      return parseSimpleStringViaOffset(parser)
    case 42: // *
      return parseArray(parser)
    case 45: // -
      return parseError(parser)
    default:
      const err = new ReplyError('Protocol error, got ' + JSON.stringify(String.fromCharCode(type)) + ' as reply type byte', 20)
      err.offset = parser.offset
      err.buffer = JSON.stringify(parser.buffer)
      return handleError(parser, err)
  }
}

// All allowed options including their typeof value
var optionTypes = {
  returnError: 'function',
  returnFatalError: 'function',
  returnReply: 'function',
  returnBuffers: 'boolean',
  stringNumbers: 'boolean',
  name: 'string'
}

/**
 * Javascript Redis Parser
 * @param options
 * @constructor
 */
function JavascriptRedisParser (options) {
  if (!(this instanceof JavascriptRedisParser)) {
    return new JavascriptRedisParser(options)
  }
  if (!options || !options.returnError || !options.returnReply) {
    throw new TypeError('Please provide all return functions while initiating the parser')
  }
  for (var key in options) {
    if (optionTypes.hasOwnProperty(key) && typeof options[key] !== optionTypes[key]) {
      throw new TypeError('The options argument contains the property "' + key + '" that is either unkown or of a wrong type')
    }
  }
  if (options.name === 'hiredis') {
    /* istanbul ignore next: hiredis is only supported for legacy usage */
    try {
      var Hiredis = require('./hiredis')
      console.error(new TypeError('Using hiredis is discouraged. Please use the faster JS parser by removing the name option.').stack.replace('Error', 'Warning'))
      return new Hiredis(options)
    } catch (e) {
      console.error(new TypeError('Hiredis is not installed. Please remove the `name` option. The (faster) JS parser is used instead.').stack.replace('Error', 'Warning'))
    }
  }
  this.optionReturnBuffers = !!options.returnBuffers
  this.optionStringNumbers = !!options.stringNumbers
  this.returnError = options.returnError
  this.returnFatalError = options.returnFatalError || options.returnError
  this.returnReply = options.returnReply
  this.name = 'javascript'
  this.offset = 0
  this.buffer = null
  this.bigStrSize = 0
  this.bigOffset = 0
  this.totalChunkSize = 0
  this.bufferCache = []
}

/**
 * Concat a bulk string containing multiple chunks
 * @param parser
 * @param buffer
 * @returns {String}
 */
function concatBulkString (parser) {
  var list = parser.bufferCache
  // The first chunk might contain the whole bulk string including the \r
  var chunks = list.length
  var offset = parser.bigStrSize - parser.totalChunkSize
  parser.offset = offset
  if (offset === 1) {
    if (chunks === 2) {
      return list[0].toString('utf8', parser.bigOffset, list[0].length - 1)
    }
  } else {
    chunks++
  }
  var res = decoder.write(list[0].slice(parser.bigOffset))
  for (var i = 1; i < chunks - 2; i++) {
    // We are only safe to fully add up elements that are neither the first nor any of the last two elements
    res += decoder.write(list[i])
  }
  res += decoder.end(list[i].slice(0, offset === 1 ? list[i].length - 1 : offset - 2))
  return res
}

/**
 * Decrease the bufferPool size over time
 * @returns {undefined}
 */
function decreaseBufferPool () {
  if (bufferPool.length > 50 * 1024) {
    // Balance between increasing and decreasing the bufferPool
    if (counter === 1 || notDecreased > counter * 2) {
      // Decrease the bufferPool by 16kb by removing the first 16kb of the current pool
      bufferPool = bufferPool.slice(Math.floor(bufferPool.length / 10), bufferPool.length)
    } else {
      notDecreased++
      counter--
    }
  } else {
    clearInterval(interval)
    counter = 0
    notDecreased = 0
    interval = null
  }
}

/**
 * Concat the collected chunks from parser.bufferCache
 * @param parser
 * @param length
 * @returns {Buffer}
 */
function concatBuffer (parser, length) {
  var list = parser.bufferCache
  var pos = bufferOffset
  length -= parser.offset
  if (bufferPool.length < length + bufferOffset) {
    // Increase the bufferPool size by three times the current needed length
    var multiplier = 3
    if (bufferOffset > 1024 * 1024 * 200) {
      bufferOffset = 1024 * 1024 * 50
      multiplier = 2
    }
    bufferPool = new Buffer(length * multiplier + bufferOffset)
    bufferOffset = 0
    counter++
    pos = 0
    if (interval === null) {
      interval = setInterval(decreaseBufferPool, 50)
    }
  }
  list[0].copy(bufferPool, pos, parser.offset, list[0].length)
  pos += list[0].length - parser.offset
  for (var i = 1; i < list.length; i++) {
    list[i].copy(bufferPool, pos)
    pos += list[i].length
  }
  var buffer = bufferPool.slice(bufferOffset, length + bufferOffset)
  bufferOffset += length
  return buffer
}

/**
 * Parse the redis buffer
 * @param buffer
 * @returns {undefined}
 */
JavascriptRedisParser.prototype.execute = function (buffer) {
  if (this.buffer === null) {
    this.buffer = buffer
    this.offset = 0
  } else if (this.bigStrSize === 0) {
    var oldLength = this.buffer.length
    var remainingLength = oldLength - this.offset
    var newBuffer = new Buffer(remainingLength + buffer.length)
    this.buffer.copy(newBuffer, 0, this.offset, oldLength)
    buffer.copy(newBuffer, remainingLength, 0, buffer.length)
    this.buffer = newBuffer
    this.offset = 0
  } else if (this.totalChunkSize + buffer.length >= this.bigStrSize) {
    this.bufferCache.push(buffer)
    // The returned type might be Array * (42) and in that case we can't improve the parsing currently
    if (this.optionReturnBuffers === false && this.buffer[this.offset] === 36) {
      this.returnReply(concatBulkString(this))
      this.buffer = buffer
    } else { // This applies for arrays too
      this.buffer = concatBuffer(this, this.totalChunkSize + buffer.length)
      this.offset = 0
    }
    this.bigStrSize = 0
    this.totalChunkSize = 0
    this.bufferCache = []
  } else {
    this.bufferCache.push(buffer)
    this.totalChunkSize += buffer.length
    return
  }

  while (this.offset < this.buffer.length) {
    var offset = this.offset
    var type = this.buffer[this.offset++]
    var response = parseType(this, type)
    if (response === undefined) {
      this.offset = offset
      return
    }

    if (type === 45) {
      this.returnError(response) // Errors -
    } else {
      this.returnReply(response) // Strings + // Integers : // Bulk strings $ // Arrays *
    }
  }

  this.buffer = null
}

module.exports = JavascriptRedisParser
<|endoftext|>


<commit_before> document.getElementById("searchButton").addEventListener("click", buttonHandler);

 // button handler
 function buttonHandler() {
    	var acronym = document.getElementById("acronymInput").value;
	lookupAcronym(acronym);
}

 // function to look up for acronym's def
function lookupAcronym(acronym) {
	if (acronym)  {
	    	var xmlhttp = new XMLHttpRequest();
	    	var url = "src/fakedAcronyms.JSON";
        	xmlhttp.onreadystatechange=function() {
			if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
				var arr = JSON.parse(xmlhttp.responseText);
        	    		document.getElementById("result").innerHTML = arr[acronym];
        	    		console.log(acronym + " is " + def);
			}
   		};
	    	xmlhttp.open("GET", url, true);
	    	xmlhttp.send();
	}
}
<commit_msg>changing JSON object's uri<commit_after> document.getElementById("searchButton").addEventListener("click", buttonHandler);

 // button handler
 function buttonHandler() {
    	var acronym = document.getElementById("acronymInput").value;
	lookupAcronym(acronym);
}

 // function to look up for acronym's def
function lookupAcronym(acronym) {
	if (acronym)  {
	    	var xmlhttp = new XMLHttpRequest();
	    	var url = "http://suproj.github.io/Terry/fakedAcronyms.JSON";
        	xmlhttp.onreadystatechange=function() {
			if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
				var arr = JSON.parse(xmlhttp.responseText);
        	    		document.getElementById("result").innerHTML = arr[acronym];
        	    		console.log(acronym + " is " + def);
			}
   		};
	    	xmlhttp.open("GET", url, true);
	    	xmlhttp.send();
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 Mansi Shah, Santosh Rajan
*/

var ast = {
        type: "Program",
        body: []
    }

module.exports = function (src) {

    var spaceRegEx = /^[ \t\r\n\b\f]+/,
        newLineRegEx = /\r?\n/g,
        nullRegEx = /^null\b/i,
        booleanRegEx = /^(true|false)\b/i,
        numberRegEx = /^[\-+]?(\d+(\.\d*)?|\.\d+)([e][+\-]?\d+)?/i,
        stringRegEx = /^('|").*?[^\\]\1/,
        identifierRegEx = /^[a-z\~]+[a-z0-9_\[\]\.\*]*/i,
        restParamRegEx = /^\.\.\.[a-z]+[a-z0-9_\[\]\.\*]*/i,
        rightParanthesesRegEx = /^\(/,
        leftParanthesesRegEx = /^\)/,
        rightSquareBracketRegEx = /^\[/,
        leftSquareBracketRegEx = /^\]/,
        rightCurlyBraceRegEx = /^\{/,
        leftCurlyBraceRegEx = /^\}/,
        operatorRegEx = /^(\*|\+|\-|\/|\%|\=)/,
        unaryOperatorRegEx = /^(\!)/,
        functionKeywordRegEx = /^(\()(\s)*function/,
        macroKeywordRegEx = /^(\()(\s)*macro\b/,
        varKeywordRegEx = /^(\()?(\s)*var/,
        ifKeywordRegEx = /^\((\s)*if/,
        fatArrowRegEx = /^\(\=\>/,
        commentRegEx  = /^\#.*\n?/,
        colonRegEx  = /^\:/,
        commaRegEx  = /^\,/,
        line = 1,
        macros = {}

    function consumer(regex, process) {
        return function () {
            var matches = regex.exec(src)
            if (!matches) return null
            // console.info("Matched "+regex)
            src = src.slice(matches[0].length)
            spaceParser()
            if (process)    return process(matches[0])
            return matches[0]
        }
    }

    function parserFactory() {
        var parsers = arguments
        return function () {
            for(index in parsers){
                var parser = parsers[index]
                spaceParser()
                var result = parser()
                if (result) {
                    // console.info("Consumed as "+result.type)
                    return result
                }
            }
            return null
        }
    }

    var spaceParser = consumer(spaceRegEx, function (val) {
            var match = val.match(newLineRegEx)
            var l = (match)? match.length : 0
            line+=l
            return true
        }),
        commentParser = consumer(commentRegEx, function () {
            line++
            return true
        }),
        nullParser = consumer(nullRegEx, function () {
            return {type: "Literal", value: null}
        }),
        booleanParser = consumer(booleanRegEx, function (val) {
            if (val === 'true')
                return {type: "Literal", value: true}
            else
                return {type: "Literal", value: false}
        }),
        numberParser = consumer(numberRegEx, function (val) {
            return {type: "Literal", value: Number(val)}
        }),
        stringParser = consumer(stringRegEx, function (val) {
            return {type: "Literal", value: val.slice(1,val.length-1)}
        }),
        literalParser = parserFactory(nullParser, booleanParser, numberParser, stringParser),
        identifierParser = consumer(identifierRegEx, function (val) {
            return {type: "Identifier", name: val}
        }),
        restParamParser = consumer(restParamRegEx, function (val) {
            var temp = src
            src = val.slice(3)  //Stripping the '...'
            argument = statementParser()
            src = temp
            return {type: "RestElement", argument: argument}
        }),
        elementParser = parserFactory(literalParser, identifierParser, restParamParser),
        rightParanthesesParser = consumer(rightParanthesesRegEx, function (val) {
            return true
        }),
        leftParanthesesParser = consumer(leftParanthesesRegEx, function (val) {
            return true
        }),
        rightSquareBracketParser = consumer(rightSquareBracketRegEx, function (val) {
            return true
        }),
        leftSquareBracketParser = consumer(leftSquareBracketRegEx, function (val) {
            return true
        }),
        rightCurlyBraceParser = consumer(rightCurlyBraceRegEx, function (val) {
            return true
        }),
        leftCurlyBraceParser = consumer(leftCurlyBraceRegEx, function (val) {
            return true
        }),
        operatorParser = consumer(operatorRegEx),
        unaryOperatorParser = consumer(unaryOperatorRegEx),
        varKeywordParser = consumer(varKeywordRegEx),
        functionKeywordParser = consumer(functionKeywordRegEx),
        ifKeywordParser = consumer(ifKeywordRegEx),
        macroKeywordParser = consumer(macroKeywordRegEx),
        fatArrowParser = consumer(fatArrowRegEx),
        colonParser = consumer(colonRegEx),
        commaParser = consumer(commaRegEx)

    function argumentsParser() {
        var expr = bodyParser(argStatementParser)
        leftParanthesesParser()
        return expr
    }

    function propertiesParser() {
        var properties = []
        while(!leftCurlyBraceParser()){
            properties.push(combinator({type: "Property"}, ["key", identifierParser], ["", colonParser], ["computed", false], ["value", statementParser], ["kind", "init"], ["method", false], ["shorthand", false]))
            commaParser()
        }
        return properties
    }

    function expressionParser() {
        if (!rightParanthesesParser()) return null
        // console.info("ExpressionParser "+src)
        return callExpressionParser() || unaryExpressionParser() || binaryExpressionParser() || statementParser()
    }

    function expressionStatementParser() {
        spaceParser()
        if (leftParanthesesParser())  return null
        // console.info("ExpressionStatementParser "+src)
        return combinator({type: "ExpressionStatement"}, ["expression", expressionParser])
    }

    function macroCallParser() {
        var temp = src
        if (!rightParanthesesParser()) return null
        if (macroId = identifierParser()) {
        // console.info("MacroCallParser "+src)
            if (macro = macros[macroId.name]) {
                var macroArgs = getArguments() || []
                var macroBody = macro.body
                for(param in macro.params){
                    var regex = new RegExp('~'+param.replace(/\./g,'\\.'), 'gi')
                    if (!Array.isArray(macro.params[param]))
                        val = macroArgs.shift()
                    else
                        val = macroArgs.join(" ")
                    macroBody = macroBody.replace(regex,val)
                }
                var temp = src
                src = macroBody
                var macroExpr = bodyParser()
                src = temp
                return macroExpr
            }
        }
        src = temp
        return null
    }

    function callExpressionParser() {
        // console.info("callExpressionParser "+src)
        return combinator({type: "CallExpression"}, ["callee", statementParser], ["arguments", argumentsParser])
    }
    function unaryExpressionParser() {
        // console.info("unaryExpressionParser "+src)
        return combinator({type: "UnaryExpression"}, ["operator", unaryOperatorParser], ["argument", argStatementParser], ["prefix", true], ["", leftParanthesesParser])
    }
    function binaryExpressionParser() {
        // console.info("binaryExpressionParser "+src)
        return combinator({type: "BinaryExpression"}, ["operator", operatorParser], ["left", argStatementParser], ["right", argStatementParser], ["", leftParanthesesParser])
    }
    function arrayExpressionParser() {
        // console.info("arrayExpressionParser "+src)
        if (!rightSquareBracketParser())   return null
        return combinator({type: "ArrayExpression"}, ["elements", argumentsParser], ["", leftSquareBracketParser])
    }
    function objectExpressionParser() {
        // console.info("objectExpressionParser "+src)
        if (!rightCurlyBraceParser())   return null
        return combinator({type: "ObjectExpression"}, ["properties", propertiesParser])
    }

    function extractExpression() {
        var found = false, parantheses = 1, i = 0
        // console.info("Inside extractExpression ")
        while(!found){
            if (src[i] == '(')
                parantheses++
            if (src[i] == ')')
                parantheses--
            if (parantheses == 0)
                found = true
            i++
        }

        return src.slice(0,i)
    }

    function getArguments(){
        var args = []
        // console.info("Inside getArguments ")
        while(!leftParanthesesParser()){
            if (matches = /^[a-z0-9]*\b/.exec(src) || stringRegEx.exec(src)) {
                args.push(matches[0])
            } else if (rightParanthesesParser()) {
                matches = [extractExpression()]
                args.push('('+matches[0])
            }

            if (matches) src = src.slice(matches[0].length)
            else    throw new SyntaxError("Unknown character at line: "+line)
            spaceParser()
        }
        return args
    }

    function macroDeclarationParser() {
        if (!macroKeywordParser())    return null
        // console.info("macroDeclarationParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        spaceParser()

        //id
        if (id = identifierParser())
            macroId = id.name
        else
            throw new SyntaxError("Expecting a macro identifier")
        spaceParser()

        //params
        if (!rightParanthesesParser())
            throw new SyntaxError("Expecting '(' after " + macroId)

        var macro = {}
        macro.params = {}
        while(!leftParanthesesParser()){
            if (param = identifierParser()) {
                param = param.name
                macro.params[param.toString()] = null
            } else if (param = restParamParser()) {
                param = '...'+param.argument.name
                macro.params[param.toString()] = []
            }
        }

        //body
        macro.body = src.slice(0,src.length-1)

        src = rest
        spaceParser()

        macros[macroId.toString()] = macro
        return true
    }

    function combinator(expr){
        for(var i=1; i<arguments.length; i++){
            var attr = arguments[i][0]
            var parser = arguments[i][1]
            var args = arguments[i][2]
            if (typeof parser == "function") {
                if (Array.isArray(args)) {
                    var result = parser(args[0],args[1])
                } else
                    var result = parser()
                if (result == null) return null
            } else {
                result = parser
            }

            if (attr) {
                expr[attr] = result
            }
        }
        return expr
    }

    function functionDeclarationParser() {
        if (!functionKeywordParser())    return null
        // console.info("functionDeclarationParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "FunctionDeclaration"}, ["id", identifierParser], ["",rightParanthesesParser], ["params",argumentsParser], ["defaults", []], ["body", functionBlockStatementParser], ["generator", false], ["expression", false])
        src = rest
        return expr
    }

    function variableDeclarationParser() {
        if (!varKeywordParser()) return null
        // console.info("variableDeclarationParser "+src)
        var expr = {type: "VariableDeclaration", declarations: [], kind: "var"}
        while(!leftParanthesesParser()){
            var innerExpr = combinator({type: "VariableDeclarator"}, ["id", identifierParser])
            innerExpr.init = argStatementParser()
            expr.declarations.push(innerExpr)
        }
        return expr
    }

    function blockStatementParser() {
        return combinator({type: "BlockStatement"}, ["body", bodyParser])
    }

    function functionBlockStatementParser() {
        return combinator({type: "BlockStatement"}, ["body", functionBodyParser])
    }

    function arrowFunctionParser() {
        if (!fatArrowParser())   return null
        // console.info("arrowFunctionParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "ArrowFunctionExpression"}, ["id", null], ["", rightParanthesesParser], ["params", argumentsParser], ["defaults", []], ["body", functionBlockStatementParser], ["generator", false], ["expression", false])
        src = rest
        return expr
    }

    function ifStatementParser() {
        if (!ifKeywordParser())   return null
        // console.info("ifStatementParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "IfStatement"}, ["test", argStatementParser], ["", rightParanthesesParser], ["consequent", blockStatementParser], ["", rightParanthesesParser], ["alternate", blockStatementParser])
        src = rest
        return expr
    }

    function functionBodyParser() {
        var stmts = bodyParser()
        if (stmts[stmts.length-1].type === "ExpressionStatement") {
            stmts[stmts.length-1] = {type: "ReturnStatement", argument: stmts[stmts.length-1].expression}
        } else {
            stmts[stmts.length-1] = {type: "ReturnStatement", argument: stmts[stmts.length-1]}
        }

        return stmts
    }

    function statementParser() {
        // console.info("statementParser "+src)
        return commentParser() || arrayExpressionParser() || objectExpressionParser() || ifStatementParser() || arrowFunctionParser() || macroDeclarationParser()|| functionDeclarationParser() || variableDeclarationParser() || elementParser() || macroCallParser() || expressionStatementParser()
    }

    function argStatementParser() {
        // console.info("argStatementParser "+src)
        return commentParser() || arrayExpressionParser() || objectExpressionParser() || ifStatementParser() || arrowFunctionParser() || macroDeclarationParser()|| functionDeclarationParser() || variableDeclarationParser() || elementParser() || macroCallParser() || expressionParser()
    }

    function arrToObj(arr){
        return arr.reduce(function (flat, current) {
                if (Array.isArray(current)) {
                    return flat.concat(arrToObj(current))
                }
                return flat.concat(current);
        }, [])
    }

    function bodyParser(parse) {
        if (!arguments[0])   parse = statementParser
        var body = []
        spaceParser()
        while(stmt = parse()){
            // console.info("Output: ",stmt)
            if (!stmt)
                throw new SyntaxError("Cannot parse statement at line: " + line)
            if (stmt !== true) {
                if (Array.isArray(stmt)) {
                    arrToObj(stmt).forEach(function (s) {
                        body.push(s)
                    })
                } else
                    body.push(stmt)
            }
            spaceParser()

        }
        return body
    }

    ast.body = bodyParser()
    return ast
}<commit_msg>Changes comment from '#' to ';'<commit_after>/*
 * Copyright (c) 2015 Mansi Shah, Santosh Rajan
*/

var ast = {
        type: "Program",
        body: []
    }

module.exports = function (src) {

    var spaceRegEx = /^[ \t\r\n\b\f]+/,
        newLineRegEx = /\r?\n/g,
        nullRegEx = /^null\b/i,
        booleanRegEx = /^(true|false)\b/i,
        numberRegEx = /^[\-+]?(\d+(\.\d*)?|\.\d+)([e][+\-]?\d+)?/i,
        stringRegEx = /^('|").*?[^\\]\1/,
        identifierRegEx = /^[a-z\~]+[a-z0-9_\[\]\.\*]*/i,
        restParamRegEx = /^\.\.\.[a-z]+[a-z0-9_\[\]\.\*]*/i,
        rightParanthesesRegEx = /^\(/,
        leftParanthesesRegEx = /^\)/,
        rightSquareBracketRegEx = /^\[/,
        leftSquareBracketRegEx = /^\]/,
        rightCurlyBraceRegEx = /^\{/,
        leftCurlyBraceRegEx = /^\}/,
        operatorRegEx = /^(\*|\+|\-|\/|\%|\=)/,
        unaryOperatorRegEx = /^(\!)/,
        functionKeywordRegEx = /^(\()(\s)*function/,
        macroKeywordRegEx = /^(\()(\s)*macro\b/,
        varKeywordRegEx = /^(\()?(\s)*var/,
        ifKeywordRegEx = /^\((\s)*if/,
        fatArrowRegEx = /^\(\=\>/,
        commentRegEx  = /^\;.*\n?/,
        colonRegEx  = /^\:/,
        commaRegEx  = /^\,/,
        line = 1,
        macros = {}

    function consumer(regex, process) {
        return function () {
            var matches = regex.exec(src)
            if (!matches) return null
            // console.info("Matched "+regex)
            src = src.slice(matches[0].length)
            spaceParser()
            if (process)    return process(matches[0])
            return matches[0]
        }
    }

    function parserFactory() {
        var parsers = arguments
        return function () {
            for(index in parsers){
                var parser = parsers[index]
                spaceParser()
                var result = parser()
                if (result) {
                    // console.info("Consumed as "+result.type)
                    return result
                }
            }
            return null
        }
    }

    var spaceParser = consumer(spaceRegEx, function (val) {
            var match = val.match(newLineRegEx)
            var l = (match)? match.length : 0
            line+=l
            return true
        }),
        commentParser = consumer(commentRegEx, function () {
            line++
            return true
        }),
        nullParser = consumer(nullRegEx, function () {
            return {type: "Literal", value: null}
        }),
        booleanParser = consumer(booleanRegEx, function (val) {
            if (val === 'true')
                return {type: "Literal", value: true}
            else
                return {type: "Literal", value: false}
        }),
        numberParser = consumer(numberRegEx, function (val) {
            return {type: "Literal", value: Number(val)}
        }),
        stringParser = consumer(stringRegEx, function (val) {
            return {type: "Literal", value: val.slice(1,val.length-1)}
        }),
        literalParser = parserFactory(nullParser, booleanParser, numberParser, stringParser),
        identifierParser = consumer(identifierRegEx, function (val) {
            return {type: "Identifier", name: val}
        }),
        restParamParser = consumer(restParamRegEx, function (val) {
            var temp = src
            src = val.slice(3)  //Stripping the '...'
            argument = statementParser()
            src = temp
            return {type: "RestElement", argument: argument}
        }),
        elementParser = parserFactory(literalParser, identifierParser, restParamParser),
        rightParanthesesParser = consumer(rightParanthesesRegEx, function (val) {
            return true
        }),
        leftParanthesesParser = consumer(leftParanthesesRegEx, function (val) {
            return true
        }),
        rightSquareBracketParser = consumer(rightSquareBracketRegEx, function (val) {
            return true
        }),
        leftSquareBracketParser = consumer(leftSquareBracketRegEx, function (val) {
            return true
        }),
        rightCurlyBraceParser = consumer(rightCurlyBraceRegEx, function (val) {
            return true
        }),
        leftCurlyBraceParser = consumer(leftCurlyBraceRegEx, function (val) {
            return true
        }),
        operatorParser = consumer(operatorRegEx),
        unaryOperatorParser = consumer(unaryOperatorRegEx),
        varKeywordParser = consumer(varKeywordRegEx),
        functionKeywordParser = consumer(functionKeywordRegEx),
        ifKeywordParser = consumer(ifKeywordRegEx),
        macroKeywordParser = consumer(macroKeywordRegEx),
        fatArrowParser = consumer(fatArrowRegEx),
        colonParser = consumer(colonRegEx),
        commaParser = consumer(commaRegEx)

    function argumentsParser() {
        var expr = bodyParser(argStatementParser)
        leftParanthesesParser()
        return expr
    }

    function propertiesParser() {
        var properties = []
        while(!leftCurlyBraceParser()){
            properties.push(combinator({type: "Property"}, ["key", identifierParser], ["", colonParser], ["computed", false], ["value", statementParser], ["kind", "init"], ["method", false], ["shorthand", false]))
            commaParser()
        }
        return properties
    }

    function expressionParser() {
        if (!rightParanthesesParser()) return null
        // console.info("ExpressionParser "+src)
        return callExpressionParser() || unaryExpressionParser() || binaryExpressionParser() || statementParser()
    }

    function expressionStatementParser() {
        spaceParser()
        if (leftParanthesesParser())  return null
        // console.info("ExpressionStatementParser "+src)
        return combinator({type: "ExpressionStatement"}, ["expression", expressionParser])
    }

    function macroCallParser() {
        var temp = src
        if (!rightParanthesesParser()) return null
        if (macroId = identifierParser()) {
        // console.info("MacroCallParser "+src)
            if (macro = macros[macroId.name]) {
                var macroArgs = getArguments() || []
                var macroBody = macro.body
                for(param in macro.params){
                    var regex = new RegExp('~'+param.replace(/\./g,'\\.'), 'gi')
                    if (!Array.isArray(macro.params[param]))
                        val = macroArgs.shift()
                    else
                        val = macroArgs.join(" ")
                    macroBody = macroBody.replace(regex,val)
                }
                var temp = src
                src = macroBody
                var macroExpr = bodyParser()
                src = temp
                return macroExpr
            }
        }
        src = temp
        return null
    }

    function callExpressionParser() {
        // console.info("callExpressionParser "+src)
        return combinator({type: "CallExpression"}, ["callee", statementParser], ["arguments", argumentsParser])
    }
    function unaryExpressionParser() {
        // console.info("unaryExpressionParser "+src)
        return combinator({type: "UnaryExpression"}, ["operator", unaryOperatorParser], ["argument", argStatementParser], ["prefix", true], ["", leftParanthesesParser])
    }
    function binaryExpressionParser() {
        // console.info("binaryExpressionParser "+src)
        return combinator({type: "BinaryExpression"}, ["operator", operatorParser], ["left", argStatementParser], ["right", argStatementParser], ["", leftParanthesesParser])
    }
    function arrayExpressionParser() {
        // console.info("arrayExpressionParser "+src)
        if (!rightSquareBracketParser())   return null
        return combinator({type: "ArrayExpression"}, ["elements", argumentsParser], ["", leftSquareBracketParser])
    }
    function objectExpressionParser() {
        // console.info("objectExpressionParser "+src)
        if (!rightCurlyBraceParser())   return null
        return combinator({type: "ObjectExpression"}, ["properties", propertiesParser])
    }

    function extractExpression() {
        var found = false, parantheses = 1, i = 0
        // console.info("Inside extractExpression ")
        while(!found){
            if (src[i] == '(')
                parantheses++
            if (src[i] == ')')
                parantheses--
            if (parantheses == 0)
                found = true
            i++
        }

        return src.slice(0,i)
    }

    function getArguments(){
        var args = []
        // console.info("Inside getArguments ")
        while(!leftParanthesesParser()){
            if (matches = /^[a-z0-9]*\b/.exec(src) || stringRegEx.exec(src)) {
                args.push(matches[0])
            } else if (rightParanthesesParser()) {
                matches = [extractExpression()]
                args.push('('+matches[0])
            }

            if (matches) src = src.slice(matches[0].length)
            else    throw new SyntaxError("Unknown character at line: "+line)
            spaceParser()
        }
        return args
    }

    function macroDeclarationParser() {
        if (!macroKeywordParser())    return null
        // console.info("macroDeclarationParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        spaceParser()

        //id
        if (id = identifierParser())
            macroId = id.name
        else
            throw new SyntaxError("Expecting a macro identifier")
        spaceParser()

        //params
        if (!rightParanthesesParser())
            throw new SyntaxError("Expecting '(' after " + macroId)

        var macro = {}
        macro.params = {}
        while(!leftParanthesesParser()){
            if (param = identifierParser()) {
                param = param.name
                macro.params[param.toString()] = null
            } else if (param = restParamParser()) {
                param = '...'+param.argument.name
                macro.params[param.toString()] = []
            }
        }

        //body
        macro.body = src.slice(0,src.length-1)

        src = rest
        spaceParser()

        macros[macroId.toString()] = macro
        return true
    }

    function combinator(expr){
        for(var i=1; i<arguments.length; i++){
            var attr = arguments[i][0]
            var parser = arguments[i][1]
            var args = arguments[i][2]
            if (typeof parser == "function") {
                if (Array.isArray(args)) {
                    var result = parser(args[0],args[1])
                } else
                    var result = parser()
                if (result == null) return null
            } else {
                result = parser
            }

            if (attr) {
                expr[attr] = result
            }
        }
        return expr
    }

    function functionDeclarationParser() {
        if (!functionKeywordParser())    return null
        // console.info("functionDeclarationParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "FunctionDeclaration"}, ["id", identifierParser], ["",rightParanthesesParser], ["params",argumentsParser], ["defaults", []], ["body", functionBlockStatementParser], ["generator", false], ["expression", false])
        src = rest
        return expr
    }

    function variableDeclarationParser() {
        if (!varKeywordParser()) return null
        // console.info("variableDeclarationParser "+src)
        var expr = {type: "VariableDeclaration", declarations: [], kind: "var"}
        while(!leftParanthesesParser()){
            var innerExpr = combinator({type: "VariableDeclarator"}, ["id", identifierParser])
            innerExpr.init = argStatementParser()
            expr.declarations.push(innerExpr)
        }
        return expr
    }

    function blockStatementParser() {
        return combinator({type: "BlockStatement"}, ["body", bodyParser])
    }

    function functionBlockStatementParser() {
        return combinator({type: "BlockStatement"}, ["body", functionBodyParser])
    }

    function arrowFunctionParser() {
        if (!fatArrowParser())   return null
        // console.info("arrowFunctionParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "ArrowFunctionExpression"}, ["id", null], ["", rightParanthesesParser], ["params", argumentsParser], ["defaults", []], ["body", functionBlockStatementParser], ["generator", false], ["expression", false])
        src = rest
        return expr
    }

    function ifStatementParser() {
        if (!ifKeywordParser())   return null
        // console.info("ifStatementParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "IfStatement"}, ["test", argStatementParser], ["", rightParanthesesParser], ["consequent", blockStatementParser], ["", rightParanthesesParser], ["alternate", blockStatementParser])
        src = rest
        return expr
    }

    function functionBodyParser() {
        var stmts = bodyParser()
        if (stmts[stmts.length-1].type === "ExpressionStatement") {
            stmts[stmts.length-1] = {type: "ReturnStatement", argument: stmts[stmts.length-1].expression}
        } else {
            stmts[stmts.length-1] = {type: "ReturnStatement", argument: stmts[stmts.length-1]}
        }

        return stmts
    }

    function statementParser() {
        // console.info("statementParser "+src)
        return commentParser() || arrayExpressionParser() || objectExpressionParser() || ifStatementParser() || arrowFunctionParser() || macroDeclarationParser()|| functionDeclarationParser() || variableDeclarationParser() || elementParser() || macroCallParser() || expressionStatementParser()
    }

    function argStatementParser() {
        // console.info("argStatementParser "+src)
        return commentParser() || arrayExpressionParser() || objectExpressionParser() || ifStatementParser() || arrowFunctionParser() || macroDeclarationParser()|| functionDeclarationParser() || variableDeclarationParser() || elementParser() || macroCallParser() || expressionParser()
    }

    function arrToObj(arr){
        return arr.reduce(function (flat, current) {
                if (Array.isArray(current)) {
                    return flat.concat(arrToObj(current))
                }
                return flat.concat(current);
        }, [])
    }

    function bodyParser(parse) {
        if (!arguments[0])   parse = statementParser
        var body = []
        spaceParser()
        while(stmt = parse()){
            // console.info("Output: ",stmt)
            if (!stmt)
                throw new SyntaxError("Cannot parse statement at line: " + line)
            if (stmt !== true) {
                if (Array.isArray(stmt)) {
                    arrToObj(stmt).forEach(function (s) {
                        body.push(s)
                    })
                } else
                    body.push(stmt)
            }
            spaceParser()

        }
        return body
    }

    ast.body = bodyParser()
    return ast
}<|endoftext|>


<commit_before>/*
*	Typographie extension for Google Chrome, v1.1
*	(c) 2014 Artyom "Sleepwalker" Fedosov <mail@asleepwalker.ru>
*	https://github.com/asleepwalker/chrome.typographie
*/

chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
	var longUrl = tabs[0].url; // from active tab
	var xmlhttp = new XMLHttpRequest();
	var url = 'https://www.googleapis.com/urlshortener/v1/url'; // goo.gl API
	var data = '{"longUrl":"'+longUrl+'"}';
	xmlhttp.open('POST', url, true);
	xmlhttp.setRequestHeader('Content-type', 'application/json');
	xmlhttp.send(data);

	xmlhttp.onreadystatechange = function() {
		if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { // success
			var response = JSON.parse(xmlhttp.responseText);
			document.getElementById('url').value = response.id;
			new QRCode(document.getElementById('qr'), {
				text: response.id,
				width: 128,
				height: 128
			});
			document.getElementById('qr').className = 'done';
			document.getElementById('url').removeAttribute('readonly');
		}
		else document.getElementById('qr').className = 'error';
	};
});<commit_msg>Updated copyright info<commit_after>/*
*	Short URL and QR-code generator for Google Chrome, v1.1
*	(c) 2014 Artyom "Sleepwalker" Fedosov <mail@asleepwalker.ru>
*	https://github.com/asleepwalker/chrome.short-url-and-qr
*/

chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
	var longUrl = tabs[0].url; // from active tab
	var xmlhttp = new XMLHttpRequest();
	var url = 'https://www.googleapis.com/urlshortener/v1/url'; // goo.gl API
	var data = '{"longUrl":"'+longUrl+'"}';
	xmlhttp.open('POST', url, true);
	xmlhttp.setRequestHeader('Content-type', 'application/json');
	xmlhttp.send(data);

	xmlhttp.onreadystatechange = function() {
		if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { // success
			var response = JSON.parse(xmlhttp.responseText);
			document.getElementById('url').value = response.id;
			new QRCode(document.getElementById('qr'), {
				text: response.id,
				width: 128,
				height: 128
			});
			document.getElementById('qr').className = 'done';
			document.getElementById('url').removeAttribute('readonly');
		}
		else document.getElementById('qr').className = 'error';
	};
});<|endoftext|>


<commit_before>const fs = require('fs-promise');
const cheerio = require('cheerio');

function parseHtml() {
    return fs.readFile('./lib/testHtml.html').then(function(sisu){
        $ = cheerio.load(sisu);

        let questions = [];

        $('.que').each(function(index, queBody) {
            try {
                question = {
                    id: null,
                    info: {}
                };

                // // INFO FROM QUESTION CLASS
                // // =======================================
                let classes = $(queBody).attr("class").split(" ");
                question.info.type = classes[1];
                question.info.feedbackType = classes[2];
                question.info.correctnessType = classes[3];

                // // INFO FROM INFO BLOCK
                // // =======================================
                question.id = getQuestionId(queBody);
                question.info.grade = question.info.correctnessType != "notanswered"
                                                                    ? $(queBody).find(".grade").text().split(" ")[1]
                                                                    : null;

                let questionBody = $(queBody).find(".formulation");
                let feedback = $(queBody).find(".outcome");

                switch(question.info.type) {
                    case "multianswer":
                        question.multianswer = parseMultianswer(questionBody);
                        question.feedback = parseFeedback(feedback);
                        break;
                    case "multichoice":
                        question.questionHtml = parseQText(questionBody);
                        question.answer = parseMultichoiceABlock(questionBody);
                        break;
                    case "shortanswer":
                        question.questionHtml = parseQText(questionBody);
                        question.answer = parseShortanswerABlock(questionBody);
                        question.feedback = parseFeedback(feedback);
                        break;
                    case "match":
                        question.questionHtml = parseQText(questionBody);
                        break;
                    case "calculated":
                        question.questionHtml = parseQText(questionBody);
                        break;
                    case "calculatedmulti":
                        question.questionHtml = parseQText(questionBody);
                        break;
                    default:
                        console.log("Sellist tüüpi test ei ole veel toetatud");
                }

                if (question.info.type == 'multichoice') {
                    questions.push(question);
                }

            } catch(err) {
                console.log("Something went wrong. ERROR: " + err)
            }

        });

        return questions;
    });
}

function parseQText(questionBody) {
    let qtext = questionBody.find(".qtext");
    let normalizedHtml = normalizeHtml(qtext.html());
    return normalizedHtml;
}

function parseShortanswerABlock(questionBody) {
    let ablock = questionBody.find(".ablock");
    let answer = {};
    let answerInputBox = ablock.find("input");

    answer.text = answerInputBox.attr("value");
    answer.correct = answerInputBox.hasClass("correct");

    return answer;
}

function parseMultianswer(questionBody) {
    multianswer = [];
    return normalizeHtml(questionBody.html());
}

function parseMultichoiceABlock(questionBody) {
    let answer = {};
    answer.prompt = questionBody.find(".prompt").text();
    answer.choices = {};

    // $(questionBody).find(".answer").find("div").each(function(i, el) {
    //     console.log(el);
    //     // let choice = {};
    //     // choice.correctnessType = el.hasClass(".correct") ? "correct" : (el.hasClass(".incorrect") ? "incorrect" : null)

    //     // choices.push(choice);
    // });

    return answer;
}

function parseFeedback(feedback) {
    if (feedback.length) {
        return normalizeHtml(feedback.html());
    } else {
        return {};
    }
}

function getQuestionId(queBody) {
    return $(queBody).find("input")
                     .filter(".questionflagpostdata")
                     .attr('value')
                     .split("&")
                     .filter(function(el){
                        return el.split("=")[0] == "qid";
                      })[0]
                     .split("=")[1];
}

function normalizeHtml(html) {
    return html.replace(/(\n|  )/gm,"");
}

module.exports.parseHtml = parseHtml;<commit_msg>Funish initial multichoice parsing<commit_after>const fs = require('fs-promise');
const cheerio = require('cheerio');

function parseHtml() {
    return fs.readFile('./lib/testHtml.html').then((sisu) => {
        $ = cheerio.load(sisu);

        let questions = [];

        $('.que').each((index, queBody) => {
            try {
                let question = {
                    id: null,
                    info: {}
                };

                // // INFO FROM QUESTION CLASS
                // // =======================================
                let classes = $(queBody).attr("class").split(" ");
                question.info.type = classes[1];
                question.info.feedbackType = classes[2];
                question.info.correctnessType = classes[3];

                // // INFO FROM INFO BLOCK
                // // =======================================
                question.id = getQuestionId(queBody);
                question.info.grade = question.info.correctnessType != "notanswered"
                                                                    ? $(queBody).find(".grade").text().split(" ")[1]
                                                                    : null;

                let questionBody = $(queBody).find(".formulation");
                let feedback = $(queBody).find(".outcome");
                let qtext = getQText(questionBody);
                let ablock = getABlock(questionBody);

                // if (question.id != '250083') {
                //     return;
                // }
                // if (question.info.type != 'multichoice') {
                //     return;
                // }

                switch(question.info.type) {
                    case "multianswer":
                        question.multianswer = parseMultianswer(questionBody);
                        question.feedback = parseFeedback(feedback);
                        break;
                    case "multichoice":
                        question.questionHtml = parseQText(qtext);
                        question.answer = parseMultichoiceABlock(ablock);
                        question.feedback = parseFeedback(feedback);
                        break;
                    case "shortanswer":
                        question.questionHtml = parseQText(qtext);
                        question.answer = parseShortanswerABlock(ablock);
                        question.feedback = parseFeedback(feedback);
                        break;
                    case "match":
                        question.questionHtml = parseQText(qtext);
                        break;
                    case "calculated":
                        question.questionHtml = parseQText(qtext);
                        break;
                    case "calculatedmulti":
                        question.questionHtml = parseQText(qtext);
                        break;
                    default:
                        console.log("Sellist tüüpi test ei ole veel toetatud");
                }

                questions.push(question);

            } catch(err) {
                console.log("Something went wrong. ERROR: " + err)
            }

        });

        return questions;
    });
}

function getABlock(questionBody) {
    return questionBody.find(".ablock");
}

function getQText(questionBody) {
    return questionBody.find(".qtext");
}

function parseQText(qtext) {
    let normalizedHtml = normalizeHtml(qtext.html());
    return normalizedHtml;
}

function parseShortanswerABlock(ablock) {
    let answer = {};
    let answerInputBox = ablock.find("input");

    answer.text = answerInputBox.attr("value");
    answer.correct = answerInputBox.hasClass("correct");

    return answer;
}

function parseMultianswer(questionBody) {
    let multianswer = [];
    return normalizeHtml(questionBody.html());
}

function parseMultichoiceABlock(ablock) {
    let answer = {
        prompt: null,
        type: null,
        choices: []
    };
    answer.prompt = ablock.find(".prompt").text();

    ablock.find("div").filter((i, el) => {
        return $(el).hasClass("r0") || $(el).hasClass("r1");
    }).each((i, el)=>{
        el = $(el);
        let checkbox = el.find("input");
        let value = el.find("label");

        choice = {};
        answer.type = checkbox.attr("type");

        choice.checked = checkbox.attr("checked") != undefined;
        choice.correctnessType = el.hasClass("correct") ? "correct" : (el.hasClass("incorrect") ? "incorrect" : (answer.type == "radio" ? "correct" : "unknown"));
        choice.text = value.text();

        answer.choices.push(choice);
    });

    // $(questionBody).find(".answer").find("div").each(function(i, el) {
    //     console.log(el);
    //     // let choice = {};
    //     // choice.correctnessType = el.hasClass(".correct") ? "correct" : (el.hasClass(".incorrect") ? "incorrect" : null)

    //     // choices.push(choice);
    // });

    return answer;
}

function parseFeedback(feedback) {
    if (feedback.length) {
        return normalizeHtml(feedback.html());
    } else {
        return {};
    }
}

function getQuestionId(queBody) {
    return $(queBody).find("input")
                     .filter(".questionflagpostdata")
                     .attr('value')
                     .split("&")
                     .filter(function(el){
                        return el.split("=")[0] == "qid";
                      })[0]
                     .split("=")[1];
}

function normalizeHtml(html) {
    return html.replace(/(\n|  )/gm,"");
}

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


<commit_before>(function() {

	var sys = require('sys');
	var events = require('events');
	var ntwitter = require('ntwitter');

	function TDTwitterStream(options) {
		if (!(this instanceof TDTwitterStream)) { return new TDTwitterStream(options); }

		if (typeof options != "undefined")
		{
			this.set_options(options);
		}
	}

	TDTwitterStream.prototype = new events.EventEmitter();

	TDTwitterStream.prototype.set_options = function(options)
	{
		if (typeof options != "object")
		{
			this.emit("error", "Options must be an object");
		}

		this.options = options;
	}

	TDTwitterStream.prototype.merge_options = function()
	{
		var defaults = {
			"auth": {
				"consumer_key": null,
				"consumer_secret": null,
				"access_token_key": null,
				"access_token_secret": null,
			},
			"follow": [],
			"with": "followings"
		};

		this.options = defaults.extend(this.options);

		this.check_options();
	}

	TDTwitterStream.prototype.check_options = function()
	{
		// Starting with OAuth tokens (They're all required)
		for (i in this.options.auth)
		{
			if (this.options.auth[i] == null)
			{
				this.emit("error", "Option "+i+" is required");
			}
		}

		// Then a list of people to follow
		if (this.options.follow.length < 1)
		{
			this.emit("error", "You need to follow at least one person's stream");
		}

	}

	TDTwitterStream.prototype.run = function()
	{
		var self = this; // Aliasing for later
		self.merge_options(); // Make sure we use defaults if we need

		// Fire up the ntwitter stream
		ntwit = new ntwitter(self.options.auth);
		ntwit.stream('site', {"follow": self.options.follow, "with": self.options.with}, function(stream) {

			stream.on("error", function (error) {
				console.log(sys.inspect(error));

				// Exit process so Forever can restart it
				stream.destroy();
				process.exit(1);
			});

			stream.on("end", function (end) {
				console.log(sys.inspect(end));

				// Exit process so Forever can restart it
				stream.destroy();
				process.exit(1);
			});

			stream.on('data', function (data) {
				// Aimed at the system
				self._control(data);

				// Aimed at a user
				// We call all of these functions, but most won't do anything
				if (typeof data.for_user != "undefined")
				{
					self._connect(data.for_user, data.message);
					self._tweet(data.for_user, data.message);

					if (typeof data.message != "undefined")
					{
						self._direct_message(data.for_user, data.message);

						if (typeof data.message.event != "undefined")
						{
							self._favourite(data.for_user, data.message);
							self._follow(data.for_user, data.message);
							self._user(data.for_user, data.message);
							self._block(data.for_user, data.message);
						}
					}

				}

				//console.log(sys.inspect(data));

			});
		});

	}

	// "Private" methods of taking an envelope and checking if we need to do anything with it

	TDTwitterStream.prototype._control = function(data)
	{
		if (typeof data.control != "undefined")
		{
			this.emit("control", data.control.control_uri);
		}
	}

	TDTwitterStream.prototype._connect = function(recipient, data)
	{
		if (typeof data.friends != "undefined")
		{
			this.emit("connect", recipient, data.friends);
		}
	}

	TDTwitterStream.prototype._direct_message = function(recipient, data)
	{
		//console.log(data);
		if (typeof data.direct_message != "undefined")
		{
			this.emit("direct_message", recipient, data.direct_message, data.direct_message.sender, data.direct_message.recipient);
		}

		if (typeof data.delete != "undefined")
		{
			if (typeof data.delete.direct_message != "undefined")
			{
				this.emit("direct_message_deleted", recipient, data.delete.direct_message.user_id, data.delete.direct_message.id_str);
			}
		}
	}

	TDTwitterStream.prototype._tweet = function(recipient, data)
	{
		if (typeof data.text != "undefined")
		{

			console.log(data);

			// If it was a RT
			if ( typeof data.retweeted_status != "undefined" )
			{
				this.emit("tweet", recipient, data.retweeted_status, data.retweeted_status.user);

				this.emit("user", recipient, data.retweeted_status.user);

				if (data.retweeted_status.in_reply_to_user_id_str == recipient){
					this.emit("mention", recipient, data.retweeted_status);
				}

				// Retweets
	            if (data.user.id_str == recipient){
					this.emit("retweet_by_me", recipient, data.retweeted_status, data);
		        }

				if (data.retweeted_status.user.id_str == recipient){
					this.emit("retweet_of_me", recipient, data.retweeted_status, data);
	        	}

	        	this.emit("retweet_by_following", recipient, data.retweeted_status, data);

			}

			// It's not a RT
			else
			{
				this.emit("tweet", recipient, data, data.user);
			}

			// Always, if it's a RT or not
			if (data.user.id_str == recipient){
              this.emit("own_tweet", recipient, data);
            }

			this.emit("user", recipient, data.user);

            // Once we get this point, we're using either the original tweet, or a RT if it exists

            if ( typeof data.retweeted_status != "undefined" )
            {
            	data = data.retweeted_status;
            }

            // Places
            if (data.place != null)
            {
            	this.emit("location", recipient, data, data.place);
            }

            // Entities

            for (i in data.entities.urls)
			{
				var link = data.entities.urls[i];
				this.emit("url", recipient, data, link.url, link.display_url, link.expanded_url);
			}

			for (i in data.entities.user_mentions)
			{
				var user = data.entities.user_mentions[i];
				this.emit("mention", recipient, data, user.id_str, user.screen_name);
			}

			for (i in data.entities.hashtags)
			{
				var hashtag = data.entities.hashtags[i];
				this.emit("hashtag", recipient, data, hashtag.text);
			}

		}

		// Deleting tweets
		if (typeof data.delete != "undefined")
		{
			if (typeof data.delete.direct_message == "undefined")
			{
				this.emit("tweet_deleted", data.delete.status.user_id_str, data.delete.status.id_str);
			}
		}
	}

	TDTwitterStream.prototype._favourite = function(recipient, data)
	{
		//console.log(data);
		if (data.event == "favorite")
		{
			this.emit("favourite", recipient, data.target_object, data.target_object.user, data.source);

			if (data.target_object.user.id_str == recipient)
			{
				this.emit("favourite_me", recipient, data.target_object, data.target_object.user, data.source);
			}
		}

		if (data.event == "unfavorite")
		{
			this.emit("unfavourite", recipient, data.target_object, data.target_object.user, data.source);

			if (data.target_object.user.id_str == recipient)
			{
				this.emit("unfavourite_me", recipient, data.target_object, data.target_object.user, data.source);
			}
		}
	}

	TDTwitterStream.prototype._follow = function(recipient, data)
	{
		if (data.event == "follow")
		{
			this.emit("follow", recipient, data.target, data.source);

			if (data.target.id_str == recipient)
			{
				this.emit("follow_me", recipient, data.target, data.source);
			}

			if (data.source.id_str == recipient)
			{
				this.emit("own_follow", recipient, data.target, data.source);
			}
		}

		if (data.event == "unfollow")
		{
			this.emit("unfollow", recipient, data.target, data.source);

			/*

			I'd like to do this, but Twitter don't emit an event, so we can't

			if (data.target.id_str == recipient)
			{
				this.emit("unfollow_me", recipient, data.target, data.source);
			}

			*/

			if (data.source.id_str == recipient)
			{
				this.emit("own_unfollow", recipient, data.target, data.source);
			}
		}
	}

	TDTwitterStream.prototype._user = function(recipient, data)
	{
		//console.log(data);
		if (data.event == "user_update")
		{
			this.emit("user_profile", recipient, data.target);
		}
	}

	TDTwitterStream.prototype._block = function(recipient, data)
	{
		//console.log(data);
		if (data.event == "block")
		{
			this.emit("block", recipient, data.target, data.source);

			if (recipient == data.source.id_str)
			{
				this.emit("own_block", recipient, data.target, data.source);
			}

			if (recipient == data.target.id_str)
			{
				this.emit("block_me", recipient, data.target, data.source);
			}
		}

		if (data.event == "unblock")
		{
			this.emit("unblock", recipient, data.target, data.source);

			if (recipient == data.source.id_str)
			{
				this.emit("own_unblock", recipient, data.target, data.source);
			}

			if (recipient == data.target.id_str)
			{
				this.emit("unblock_me", recipient, data.target, data.source);
			}
		}
	}

	module.exports = TDTwitterStream;
}).call(this);

// Helpers

// via http://onemoredigit.com/post/1527191998/extending-objects-in-node-js
Object.defineProperty(Object.prototype, "extend", {
    enumerable: false,
    value: function(from) {
        var props = Object.getOwnPropertyNames(from);
        var dest = this;
        props.forEach(function(name) {
            if (name in dest) {
                var destination = Object.getOwnPropertyDescriptor(from, name);
                Object.defineProperty(dest, name, destination);
            }
        });
        return this;
    }
});
<commit_msg>List events working<commit_after>(function() {

	var sys = require('sys');
	var events = require('events');
	var ntwitter = require('ntwitter');

	function TDTwitterStream(options) {
		if (!(this instanceof TDTwitterStream)) { return new TDTwitterStream(options); }

		if (typeof options != "undefined")
		{
			this.set_options(options);
		}
	}

	TDTwitterStream.prototype = new events.EventEmitter();

	TDTwitterStream.prototype.set_options = function(options)
	{
		if (typeof options != "object")
		{
			this.emit("error", "Options must be an object");
		}

		this.options = options;
	}

	TDTwitterStream.prototype.merge_options = function()
	{
		var defaults = {
			"auth": {
				"consumer_key": null,
				"consumer_secret": null,
				"access_token_key": null,
				"access_token_secret": null,
			},
			"follow": [],
			"with": "followings"
		};

		this.options = defaults.extend(this.options);

		this.check_options();
	}

	TDTwitterStream.prototype.check_options = function()
	{
		// Starting with OAuth tokens (They're all required)
		for (i in this.options.auth)
		{
			if (this.options.auth[i] == null)
			{
				this.emit("error", "Option "+i+" is required");
			}
		}

		// Then a list of people to follow
		if (this.options.follow.length < 1)
		{
			this.emit("error", "You need to follow at least one person's stream");
		}

	}

	TDTwitterStream.prototype.run = function()
	{
		var self = this; // Aliasing for later
		self.merge_options(); // Make sure we use defaults if we need

		// Fire up the ntwitter stream
		ntwit = new ntwitter(self.options.auth);
		ntwit.stream('site', {"follow": self.options.follow, "with": self.options.with}, function(stream) {

			stream.on("error", function (error) {
				console.log(sys.inspect(error));

				// Exit process so Forever can restart it
				stream.destroy();
				process.exit(1);
			});

			stream.on("end", function (end) {
				console.log(sys.inspect(end));

				// Exit process so Forever can restart it
				stream.destroy();
				process.exit(1);
			});

			stream.on('data', function (data) {
				// Aimed at the system
				self._control(data);

				// Aimed at a user
				// We call all of these functions, but most won't do anything
				if (typeof data.for_user != "undefined")
				{
					self._connect(data.for_user, data.message);
					self._tweet(data.for_user, data.message);

					if (typeof data.message != "undefined")
					{
						self._direct_message(data.for_user, data.message);

						if (typeof data.message.event != "undefined")
						{
							self._favourite(data.for_user, data.message);
							self._follow(data.for_user, data.message);
							self._user(data.for_user, data.message);
							self._block(data.for_user, data.message);
							self._list(data.for_user, data.message);
						}
					}

				}

				//console.log(sys.inspect(data));

			});
		});

	}

	// "Private" methods of taking an envelope and checking if we need to do anything with it

	TDTwitterStream.prototype._control = function(data)
	{
		if (typeof data.control != "undefined")
		{
			this.emit("control", data.control.control_uri);
		}
	}

	TDTwitterStream.prototype._connect = function(recipient, data)
	{
		if (typeof data.friends != "undefined")
		{
			this.emit("connect", recipient, data.friends);
		}
	}

	TDTwitterStream.prototype._direct_message = function(recipient, data)
	{
		//console.log(data);
		if (typeof data.direct_message != "undefined")
		{
			this.emit("direct_message", recipient, data.direct_message, data.direct_message.sender, data.direct_message.recipient);
		}

		if (typeof data.delete != "undefined")
		{
			if (typeof data.delete.direct_message != "undefined")
			{
				this.emit("direct_message_deleted", recipient, data.delete.direct_message.user_id, data.delete.direct_message.id_str);
			}
		}
	}

	TDTwitterStream.prototype._tweet = function(recipient, data)
	{
		if (typeof data.text != "undefined")
		{

			console.log(data);

			// If it was a RT
			if ( typeof data.retweeted_status != "undefined" )
			{
				this.emit("tweet", recipient, data.retweeted_status, data.retweeted_status.user);

				this.emit("user", recipient, data.retweeted_status.user);

				if (data.retweeted_status.in_reply_to_user_id_str == recipient){
					this.emit("mention", recipient, data.retweeted_status);
				}

				// Retweets
	            if (data.user.id_str == recipient){
					this.emit("retweet_by_me", recipient, data.retweeted_status, data);
		        }

				if (data.retweeted_status.user.id_str == recipient){
					this.emit("retweet_of_me", recipient, data.retweeted_status, data);
	        	}

	        	this.emit("retweet_by_following", recipient, data.retweeted_status, data);

			}

			// It's not a RT
			else
			{
				this.emit("tweet", recipient, data, data.user);
			}

			// Always, if it's a RT or not
			if (data.user.id_str == recipient){
              this.emit("own_tweet", recipient, data);
            }

			this.emit("user", recipient, data.user);

            // Once we get this point, we're using either the original tweet, or a RT if it exists

            if ( typeof data.retweeted_status != "undefined" )
            {
            	data = data.retweeted_status;
            }

            // Places
            if (data.place != null)
            {
            	this.emit("location", recipient, data, data.place);
            }

            // Entities

            for (i in data.entities.urls)
			{
				var link = data.entities.urls[i];
				this.emit("url", recipient, data, link.url, link.display_url, link.expanded_url);
			}

			for (i in data.entities.user_mentions)
			{
				var user = data.entities.user_mentions[i];
				this.emit("mention", recipient, data, user.id_str, user.screen_name);
			}

			for (i in data.entities.hashtags)
			{
				var hashtag = data.entities.hashtags[i];
				this.emit("hashtag", recipient, data, hashtag.text);
			}

		}

		// Deleting tweets
		if (typeof data.delete != "undefined")
		{
			if (typeof data.delete.direct_message == "undefined")
			{
				this.emit("tweet_deleted", data.delete.status.user_id_str, data.delete.status.id_str);
			}
		}
	}

	TDTwitterStream.prototype._favourite = function(recipient, data)
	{
		//console.log(data);
		if (data.event == "favorite")
		{
			this.emit("favourite", recipient, data.target_object, data.target_object.user, data.source);

			if (data.target_object.user.id_str == recipient)
			{
				this.emit("favourite_me", recipient, data.target_object, data.target_object.user, data.source);
			}
		}

		if (data.event == "unfavorite")
		{
			this.emit("unfavourite", recipient, data.target_object, data.target_object.user, data.source);

			if (data.target_object.user.id_str == recipient)
			{
				this.emit("unfavourite_me", recipient, data.target_object, data.target_object.user, data.source);
			}
		}
	}

	TDTwitterStream.prototype._follow = function(recipient, data)
	{
		if (data.event == "follow")
		{
			this.emit("follow", recipient, data.target, data.source);

			if (data.target.id_str == recipient)
			{
				this.emit("follow_me", recipient, data.target, data.source);
			}

			if (data.source.id_str == recipient)
			{
				this.emit("own_follow", recipient, data.target, data.source);
			}
		}

		if (data.event == "unfollow")
		{
			this.emit("unfollow", recipient, data.target, data.source);

			/*

			I'd like to do this, but Twitter don't emit an event, so we can't

			if (data.target.id_str == recipient)
			{
				this.emit("unfollow_me", recipient, data.target, data.source);
			}

			*/

			if (data.source.id_str == recipient)
			{
				this.emit("own_unfollow", recipient, data.target, data.source);
			}
		}
	}

	TDTwitterStream.prototype._user = function(recipient, data)
	{
		//console.log(data);
		if (data.event == "user_update")
		{
			this.emit("user_profile", recipient, data.target);
		}
	}

	TDTwitterStream.prototype._block = function(recipient, data)
	{
		//console.log(data);
		if (data.event == "block")
		{
			this.emit("block", recipient, data.target, data.source);

			if (recipient == data.source.id_str)
			{
				this.emit("own_block", recipient, data.target, data.source);
			}

			if (recipient == data.target.id_str)
			{
				this.emit("block_me", recipient, data.target, data.source);
			}
		}

		if (data.event == "unblock")
		{
			this.emit("unblock", recipient, data.target, data.source);

			if (recipient == data.source.id_str)
			{
				this.emit("own_unblock", recipient, data.target, data.source);
			}

			if (recipient == data.target.id_str)
			{
				this.emit("unblock_me", recipient, data.target, data.source);
			}
		}
	}

	TDTwitterStream.prototype._list = function(recipient, data)
	{
		if (data.event == "list_created")
		{
			this.emit("list_created", recipient, data.target_object, data.source);
		}

		if (data.event == "list_updated")
		{
			this.emit("list_updated", recipient, data.target_object, data.source);
		}

		if (data.event == "list_destroyed")
		{
			this.emit("list_destroyed", recipient, data.target_object, data.source);
		}

		if (data.event == "list_member_added")
		{
			this.emit("list_member_added", recipient, data.target_object, data.target, data.source);
		}

		if (data.event == "list_member_removed")
		{
			this.emit("list_member_removed", recipient, data.target_object, data.target, data.source);
		}
	}

	module.exports = TDTwitterStream;
}).call(this);

// Helpers

// via http://onemoredigit.com/post/1527191998/extending-objects-in-node-js
Object.defineProperty(Object.prototype, "extend", {
    enumerable: false,
    value: function(from) {
        var props = Object.getOwnPropertyNames(from);
        var dest = this;
        props.forEach(function(name) {
            if (name in dest) {
                var destination = Object.getOwnPropertyDescriptor(from, name);
                Object.defineProperty(dest, name, destination);
            }
        });
        return this;
    }
});
<|endoftext|>


<commit_before>var vm = require('vm')
var util = require('util')
var _ = require('underscore')

var utilities = require('../lib/utilities.js')

module.exports = {
  stateJcssVars: require('../helpers/helpers.js'),

  funcsToString: function (funcArr) {
    var returnString
    funcArr = funcArr.map(utilities.caller('toString'))
    console.log(funcArr)
    return funcArr.join('\n')
  },

  exec: function (javaScriptString) {
    var returnString = ''
    var sandbox = {
      $: this.stateJcssVars,
      returnString: '',
    }
    function css (cssString) {
      returnString += cssString
    }
    try {
      vm.runInNewContext(javaScriptString + '\n' + css.toString(), sandbox)
      this.stateJcssVars = sandbox.$
      return sandbox.returnString
    } catch (e) {
      console.log('Exception in your jcss')
      console.log(javaScriptString)
      console.log(e)
      return false
    }
  },

  parseCssVars: function (cssString) {
    /*
      \$\.
      [\w\,\.\d\_\-\$]+
      (
        \(
        [^\(\)]*
        \)
      )*
    */
    var self = this
    var varRegex = /\$\.[\w\,\.\d\_\-\$]+(\([^\(\)]*\))*/gm
    if(!cssString) return '';
    cssString = cssString.replace(varRegex, function (match) {
      var $ = self.stateJcssVars
      return eval(match)
    })
    return cssString
  },

  split: function (jcssString) {
    /*
      ^[
          \s\t
        ]*
        (
          (
            (
              (
                [\.\#]?
                [\w\-_\d]+
              )
              |
              \*
            )
            |
            (
              (
                \[
                |
                \:{1,2}
              ){1}
              [\w\-_\d\*\^\~\|\=\"\$]+
              (
                \([^\)\;]+\)
              )?
              \]?
            )
          )+
          [\n\,\s\>\+\~]*
        )+
      \{
      [^\}]*
      \}
      \n*
    */
    var cssRegex = /^[\s\t]*(((([\.\#]?[\w\-_\d]+)|\*)|((\[|\:{1,2}){1}[\w\-_\d\*\^\~\|\=\"\$]+(\([^\)\;]+\))?\]?))+[\n\,\s\>\+\~]*)+\{[^\}]*\}\n*/gm
    var cssRegexRes, returnLang
    if(!jcssString) return false
    cssRegexRes = cssRegex.exec(jcssString)
    if(!cssRegexRes) return ['js', jcssString, false]
    returnLang = jcssString.indexOf(cssRegexRes[0]) === 0 ? 'css' : 'js'
    return [returnLang].concat(this.splitAroundSubstring(cssRegexRes[0], jcssString))
  },

  splitAroundSubstring: function (substring, string) {
    var substringFirst = string.indexOf(substring)
    var substringLast = substringFirst + substring.length
    if(substringFirst === 0) {
      return [string.substr(0, substringLast), string.substr(substringLast)]
    } else {
      return [string.substr(0, substringFirst), string.substr(substringFirst)]
    }
  },

  interpret: function (someArr) {
    return (someArr[0] == 'js' ? this.exec(someArr[1]) : this.parseCssVars(someArr[1]))
  },

  parse: function (jcssString) {
    var splitJcss = []
    var buffer = ''
    var parsedCss = ''
    if(typeof jcssString != 'string') return false
    do {
      splitJcss = this.split(jcssString)
      parsedCss += (buffer = this.interpret(splitJcss))
      if(buffer === false) return false
    } while (jcssString = splitJcss[2])
    return parsedCss
  }
}
<commit_msg>Add manipulators as a seperate array<commit_after>var vm = require('vm')
var util = require('util')
var _ = require('underscore')

var utilities = require('../lib/utilities.js')

module.exports = {
  stateJcssVars: require('../helpers/helpers.js'),

  funcsToString: function (funcArr) {
    var returnString
    funcArr = [''].concat(funcArr.map(utilities.caller('toString')))
    return funcArr.join('\n')
  },

  manipulators: [
    function css (cssString) {
      returnString += cssString
    }
  ],

  exec: function (javaScriptString) {
    var returnString = ''
    var sandbox = {
      $: this.stateJcssVars,
      returnString: '',
    }
    try {
      vm.runInNewContext(javaScriptString + this.funcsToString(this.manipulators), sandbox)
      this.stateJcssVars = sandbox.$
      return sandbox.returnString
    } catch (e) {
      console.log('Exception in your jcss')
      console.log(javaScriptString)
      console.log(e)
      return false
    }
  },

  parseCssVars: function (cssString) {
    /*
      \$\.
      [\w\,\.\d\_\-\$]+
      (
        \(
        [^\(\)]*
        \)
      )*
    */
    var self = this
    var varRegex = /\$\.[\w\,\.\d\_\-\$]+(\([^\(\)]*\))*/gm
    if(!cssString) return '';
    cssString = cssString.replace(varRegex, function (match) {
      var $ = self.stateJcssVars
      return eval(match)
    })
    return cssString
  },

  split: function (jcssString) {
    /*
      ^[
          \s\t
        ]*
        (
          (
            (
              (
                [\.\#]?
                [\w\-_\d]+
              )
              |
              \*
            )
            |
            (
              (
                \[
                |
                \:{1,2}
              ){1}
              [\w\-_\d\*\^\~\|\=\"\$]+
              (
                \([^\)\;]+\)
              )?
              \]?
            )
          )+
          [\n\,\s\>\+\~]*
        )+
      \{
      [^\}]*
      \}
      \n*
    */
    var cssRegex = /^[\s\t]*(((([\.\#]?[\w\-_\d]+)|\*)|((\[|\:{1,2}){1}[\w\-_\d\*\^\~\|\=\"\$]+(\([^\)\;]+\))?\]?))+[\n\,\s\>\+\~]*)+\{[^\}]*\}\n*/gm
    var cssRegexRes, returnLang
    if(!jcssString) return false
    cssRegexRes = cssRegex.exec(jcssString)
    if(!cssRegexRes) return ['js', jcssString, false]
    returnLang = jcssString.indexOf(cssRegexRes[0]) === 0 ? 'css' : 'js'
    return [returnLang].concat(this.splitAroundSubstring(cssRegexRes[0], jcssString))
  },

  splitAroundSubstring: function (substring, string) {
    var substringFirst = string.indexOf(substring)
    var substringLast = substringFirst + substring.length
    if(substringFirst === 0) {
      return [string.substr(0, substringLast), string.substr(substringLast)]
    } else {
      return [string.substr(0, substringFirst), string.substr(substringFirst)]
    }
  },

  interpret: function (someArr) {
    return (someArr[0] == 'js' ? this.exec(someArr[1]) : this.parseCssVars(someArr[1]))
  },

  parse: function (jcssString) {
    var splitJcss = []
    var buffer = ''
    var parsedCss = ''
    if(typeof jcssString != 'string') return false
    do {
      splitJcss = this.split(jcssString)
      parsedCss += (buffer = this.interpret(splitJcss))
      if(buffer === false) return false
    } while (jcssString = splitJcss[2])
    return parsedCss
  }
}
<|endoftext|>