<commit_before>var render = {
  roots: [],
  templates: {}
}
var runs = {}
render.redraw = function(module) {
  this.fun || (this.fun = debounce(function() {
    for (var i = 0, root; root = render.roots[i]; i++) {
      if (module.controllers[i]) {

        var elementClone = module.elements[i]
        var args = module.getArgs(i)

        module.modules[i].view(elementClone, module.controllers[i], args)

        Object.observe(args[0], debounce(function(elementClone, i, module, changes) {
          var args = module.getArgs(i)
          render.interpolate(elementClone, args[0])
        }.bind(null, elementClone, i, module)))

        render.interpolate(elementClone, args[0])
      }
    }
  }))
  this.fun()
}

render.isTypeOf = function(type, thing) {
  if (this.toString.call(thing) === '[object ' + type + ']') {
    return true
  }
}
render.types = ['Array', 'String', 'Object', 'Function']

render.interpolate = function(elementClone, data) {
  console.log('called')
  for (var prop in data) {

    if (render.isTypeOf('Array', data[prop])) {
      // loop
      // recursive
      if (render.cache[prop] != JSON.stringify(data[prop])) {
        // get element to clone
        var eles = domElement.findByKey(elementClone, prop)
        if (eles.length < 1) continue;

        var template
        var myNode = eles[0].item(elementClone).parentNode

        if (!render.templates[prop]) {
          template = eles[0].item(elementClone).cloneNode(true)
          //save template
        } else {
          // remove all existing node
          // do a diff?

          while (myNode.firstChild) {
            myNode.removeChild(myNode.firstChild)
          }
          template = render.templates[prop]
        }

        for (var i = 0; i < data[prop].length; i++) {

          var newest = template.cloneNode(true);
          var val = data[prop][i];

          // simple list no sub objects or functions

          domElement.setTextContent(newest, val)

          myNode.appendChild(newest)
        }
        if (!render.templates[prop]) {
          render.templates[prop] = template

          myNode.removeChild(eles[0].item(elementClone))
        }
        render.cache[prop] = JSON.stringify(data[prop])
      }
    } else if (render.isTypeOf('Object', data[prop])) {
      // don't run twice unceccesarily
      // has this keys values change since the previous call
      //check the cache
      if (render.cache[prop] != JSON.stringify(data[prop])) {
        handleObject(elementClone, prop, data[prop])
        render.cache[prop] = JSON.stringify(data[prop])
      }
    } else if (!render.isTypeOf('Function', data[prop])) {
      if (render.cache[prop] != JSON.stringify(data[prop])) {
        domElement.val(elementClone, prop, data[prop])
        render.cache[prop] = JSON.stringify(data[prop])
      }
    }
  }
}

var debounce = function(fn, threshhold) {
  var last, threshhold = threshhold || 250,
    deferTimer

  return function() {

    var now = +new Date

    if (last && now < last + threshhold) {
      // hold on to it
      clearTimeout(deferTimer);
      deferTimer = setTimeout(function() {
        last = now;
        fn.apply(this, arguments);
      }, threshhold);
    } else {
      last = now
      fn.apply(this, arguments);
    }
  }
}

  function handleObject(node, key, object) {
    // get all keys with _ "underscore"
    var attrs = {}
    Object.keys(object).forEach(function(k, i) {
      if (k.substr(0, 1) == '_') {
        attrs[k.substr(1)] = object[k]
      }
    })

    domElement.event(node, key, attrs)
    domElement.setAttrs(node, key, attrs)
    // set all key vals
    for (var k in object) {
      // if starts with underscore its an attribute
      domElement.replaceWithin(node, k, object[k])
    }
  }

render.cache = {}
<commit_msg>Update render.js<commit_after>var render = {
  roots: [],
  templates: {},
  cache: {}
}
var unloaders = [],
  cached = [],
  pendingRequests = 0

  function callView(elementClone, module, i) {
    var args = module.getArgs(i)

    var mod = module.modules[i]
    var controller = module.controllers[i]

    // var controllerConstructor = mod.controller.$original || mod.controller
    // var controller = controllerConstructor === cached.controllerConstructor ? cached.controller : new(mod.controller || function() {})

    mod.view(elementClone, controller)

    // if (controller.onunload) unloaders.push({
    //   controller: controller,
    //   handler: controller.onunload
    // })
  }
render.callConfigs = function() {
  //for (var i = 0, len = configs.length; i < len; i++) configs[i]()
}
render.redraw = function(module) {
  module = module || render.module || {}
  this.fun || (this.fun = debounce(function() {
    var prev
    for (var i = 0, root; root = render.roots[i]; i++) {
      if (module.controllers[i]) {
        var elementClone = module.elements[i]

        callView(elementClone, module, i)
        var args = module.getArgs(i)

        watch(args[0], debounce(function(ele, i, module, prop, type, newVal, oldVal) {
          console.time('Mag.JS:re-render')
          var args = module.getArgs(i)

          // check if data changed
          if (prev !== JSON.stringify(args[0])) {
            callView(ele, module, i)
            fill(ele, args[0])
            WatchJS.noMore = true
            render.callConfigs()
            prev = JSON.stringify(args[0])
          }
          console.timeEnd('Mag.JS:re-render')
        }.bind(null, elementClone, i, module)))

        fill(elementClone, args[0])
        render.callConfigs()
        prev = JSON.stringify(args[0])
      }
    }
    console.timeEnd("MagnumJS:init")
  }))
  this.fun()
}

var $cancelAnimationFrame = window.cancelAnimationFrame || window.clearTimeout;
var $requestAnimationFrame = window.requestAnimationFrame || window.setTimeout;

var debounce = function(fn, threshhold) {
  var lastRedrawCallTime, FRAME_BUDGET = threshhold || 16,
    deferTimer

  return function() {
    if (+new Date - lastRedrawCallTime > FRAME_BUDGET || $requestAnimationFrame === window.requestAnimationFrame) {
      // hold on to it
      if (deferTimer > 0) $cancelAnimationFrame(deferTimer)

      deferTimer = $requestAnimationFrame(function() {
        lastRedrawCallTime = +new Date
        fn.apply(this, arguments);
      }, FRAME_BUDGET);
    } else {
      lastRedrawCallTime = +new Date
      fn.apply(this, arguments);
    }
  }
}
<|endoftext|>


<commit_before>function Paddle(){
 this.x = 200;
 this.y = 370;
 this.width = 50;
 this.height = 10;
 this.speed = 50;
}

Paddle.prototype.leftArrowWasPressed = function() {
    if(this.x - this.width >= 0){
      this.x = this.x - this.speed;
    }
};

Paddle.prototype.rightArrowWasPressed = function() {
    if(this.x + this.width < 800){
      this.x = this.x + this.speed;
    }
};

Paddle.prototype.top = function() {
  return this.x + this.width;
};

module.exports = Paddle;
<commit_msg>Longer paddle<commit_after>function Paddle(){
 this.x = 200;
 this.y = 370;
 this.width = 100;
 this.height = 10;
 this.speed = 50;
}

Paddle.prototype.leftArrowWasPressed = function() {
    if(this.x - this.speed >= 0){
      this.x = this.x - this.speed;
    }
};

Paddle.prototype.rightArrowWasPressed = function() {
    if(this.x + this.width < 800){
      this.x = this.x + this.speed;
    }
};

Paddle.prototype.top = function() {
  return this.x + this.width;
};

module.exports = Paddle;
<|endoftext|>


<commit_before>const ACTIONS = {
    PROFILE: {
      REQUEST: {
        INITIATE: 'profile.request.initiate',
        LOAD: 'profile.request.load',
        SUCCESS: 'profile.request.success',
        FAIL: 'profile.request.fail'
      },
      MODIFY: {
        ACTIVE: 'profile.modify.active',
        EMAIL: 'profile.modify.email',
        FIRST_NAME: 'profile.modify.name.first',
        LAST_NAME: 'profile.modify.name.last',
        DATE_OF_BIRTH: 'profile.modify.dob'
      }
    },
    PROFILES : {
      REQUEST: {
        INITIATE: 'profile.request.initiate',
        LOAD: 'profile.request.load',
        SUCCESS: 'profile.request.success',
        FAIL: 'profile.request.fail'
      },
    }
  };

export {ACTIONS as default};

<commit_msg>Fixed a massive mistake with the actions. I noticed that get profile was fired when get profile(S) was called.<commit_after>const ACTIONS = {
    PROFILE: {
      REQUEST: {
        INITIATE: 'profile.request.initiate',
        LOAD: 'profile.request.load',
        SUCCESS: 'profile.request.success',
        FAIL: 'profile.request.fail'
      },
      MODIFY: {
        ACTIVE: 'profile.modify.active',
        EMAIL: 'profile.modify.email',
        FIRST_NAME: 'profile.modify.name.first',
        LAST_NAME: 'profile.modify.name.last',
        DATE_OF_BIRTH: 'profile.modify.dob'
      }
    },
    PROFILES : {
      REQUEST: {
        INITIATE: 'profiles.request.initiate',
        LOAD: 'profiles.request.load',
        SUCCESS: 'profiles.request.success',
        FAIL: 'profiles.request.fail'
      },
    }
  };

export {ACTIONS as default};

<|endoftext|>


<commit_before>const exec = require('child_process').execSync

const portmap = {
  http: 80,
  https: 443,
  ssh: 22,
  dns: 53,
  ftp: 20,
  telnet: 23,
  smtp: 25,
  ntp: 37,
  pop2: 109,
  pop3: 110,
  sftp: 115,
  nntp: 119,
  snmp: 169,
  bgp: 179,
  gacp: 190,
  irc: 194,
  dls: 197,
  ldap: 389,
  snpp: 444,
  sldap: 689
}

let cr = '\n'

class Parser {
  static windows (port) {
    let results = {}
    let stdout

    cr = '\r' + cr

    try {
      stdout = exec('netstat -aon | findstr :' + port + ' | findstr LISTENING').toString().trim().split(cr)
    } catch (e) {
      stdout = []
    }

    stdout.forEach((row) => {
      let item = row.trim().split(/\s{1,500}/)
      let processport = item[1].split(':').pop()

      if (!isNaN(processport)) {
        processport = parseInt(processport, 10)

        if (processport === parseInt(port, 10)) {
          results[item.pop()] = {}
        }
      }
    })

    Object.keys(results).forEach((pid) => {
      let out = exec('tasklist /FI \"PID eq ' + pid + '\" /FO CSV /NH /V').toString().trim().split(cr)
      out.forEach((row) => {
        let col = row.split(',')

        results[pid] = {
          process: col[0].substr(1, col[0].length - 2),
          user: col[6].substr(1, col[6].length - 2)
        }
      })
    })

    return results
  }

  static linux (port) {
    // Attempt lsof first
    try {
      return this.ss(port)
    } catch (e) {
      console.log(e)
      // Attempt ss next
      try {
        return this.lsof(port)
      } catch (e) {
        // Attempt netstat last
        try {
          return this.netstat(port)
        } catch (e) {
          console.log('Could not find lsof, ss, or netstat to determine port usage.')
          return {}
        }
      }
    }
  }

  static lsof (port) {
    let stdout = exec('lsof -i :' + port).toString().trim().split('\n')
    let results = {}

    if (stdout.length === 0) {
      return {}
    }

    stdout.shift()

    stdout.forEach(row => {
      if (row.indexOf('(LISTEN)') > 0) {
        let item = row.split(/\s{1,500}/)

        item.pop()

        let processport = item.pop().replace(/[^0-9]/gi, '')

        if (!isNaN(processport)) {
          processport = parseInt(processport, 10)

          let detail = this.linuxProcessDetails(item[1])

          results[item[1]] = {
            process: processport === parseInt(port, 10) ? detail.title : item[0],
            user: detail.user
          }
        }
      }
    })

    return results
  }

  static ss (port = '') {
console.log('>>>', port)
    let stdout = exec('ss -ptls | grep LISTEN').toString().trim().split('\n')
    let results = {}

    if (stdout.length === 0) {
      return {}
    }

    port = port.toString().split(' ').filter(number => !isNaN(number))
console.log(port)
    stdout.forEach(row => {
      // Group 1 is port
      let data = /:{1,3}([A-Za-z0-9]+)/i.exec(row)
console.log(row, data)
      // Handle named ports
      if (data !== null) {
        if (isNaN(data[1]) && portmap.hasOwnProperty(data[1].toLowerCase())) {
          data[1] = portmap[data[1].toLowerCase()].toString()
        }
      }

      if (port.indexOf(data[1].toString()) >= 0) {
        let ct = 0
        let PID = /\(\"([A-Za-z]+)\".*\,[pid=]{0,4}([0-9]+)\,/i.exec(data.input)

        while (PID !== null && ct < 100) {
          let detail = this.linuxProcessDetails(PID[2])

          results[PID[2]] = {
            process: detail.title,
            user: detail.user
          }

          data.input = data.input.replace(`pid=${PID[2]}`)
          PID = /\(\"([A-Za-z]+)\".*pid=([0-9]+)/i.exec(data.input)
          ct++
        }
      }
    })

    return results
  }

  static netstat (port) {
    let stdout = exec('netstat -tulnp | grep ' + port)
    let results = {}

    if (stdout.length === 0) {
      return {}
    }

    stdout.split('\n').forEach(row => {
      let data = row.split(/\s+/).pop().split(/\/|\\/)
      let detail = this.linuxProcessDetails(data[0])

      results[data[0]] = {
        process: detail.title,
        user: detail.user
      }
    })

    return results
  }

  static linuxProcessDetails (pid) {
console.log(exec('ps axco pid,user,command | grep ' + pid).toString())
    let processDetail = exec('ps axco pid,user,command | grep ' + pid)
      .toString()
      .split('\n')
      .filter(line => line.indexOf('grep') < 0)[0]
      .trim()
      .split(/\s+/)

    let user = processDetail[1]
console.log(processDetail)
    processDetail.splice(0, 3)

    return {
      user,
      title: processDetail.join(' ')
    }
  }
}

module.exports = Parser
<commit_msg>Linux testing<commit_after>const exec = require('child_process').execSync

const portmap = {
  http: 80,
  https: 443,
  ssh: 22,
  dns: 53,
  ftp: 20,
  telnet: 23,
  smtp: 25,
  ntp: 37,
  pop2: 109,
  pop3: 110,
  sftp: 115,
  nntp: 119,
  snmp: 169,
  bgp: 179,
  gacp: 190,
  irc: 194,
  dls: 197,
  ldap: 389,
  snpp: 444,
  sldap: 689
}

let cr = '\n'

class Parser {
  static windows (port) {
    let results = {}
    let stdout

    cr = '\r' + cr

    try {
      stdout = exec('netstat -aon | findstr :' + port + ' | findstr LISTENING').toString().trim().split(cr)
    } catch (e) {
      stdout = []
    }

    stdout.forEach((row) => {
      let item = row.trim().split(/\s{1,500}/)
      let processport = item[1].split(':').pop()

      if (!isNaN(processport)) {
        processport = parseInt(processport, 10)

        if (processport === parseInt(port, 10)) {
          results[item.pop()] = {}
        }
      }
    })

    Object.keys(results).forEach((pid) => {
      let out = exec('tasklist /FI \"PID eq ' + pid + '\" /FO CSV /NH /V').toString().trim().split(cr)
      out.forEach((row) => {
        let col = row.split(',')

        results[pid] = {
          process: col[0].substr(1, col[0].length - 2),
          user: col[6].substr(1, col[6].length - 2)
        }
      })
    })

    return results
  }

  static linux (port) {
    // Attempt lsof first
    try {
      return this.ss(port)
    } catch (e) {
      console.log(e)
      // Attempt ss next
      try {
        return this.lsof(port)
      } catch (e) {
        // Attempt netstat last
        try {
          return this.netstat(port)
        } catch (e) {
          console.log('Could not find lsof, ss, or netstat to determine port usage.')
          return {}
        }
      }
    }
  }

  static lsof (port) {
    let stdout = exec('lsof -i :' + port).toString().trim().split('\n')
    let results = {}

    if (stdout.length === 0) {
      return {}
    }

    stdout.shift()

    stdout.forEach(row => {
      if (row.indexOf('(LISTEN)') > 0) {
        let item = row.split(/\s{1,500}/)

        item.pop()

        let processport = item.pop().replace(/[^0-9]/gi, '')

        if (!isNaN(processport)) {
          processport = parseInt(processport, 10)

          let detail = this.linuxProcessDetails(item[1])

          results[item[1]] = {
            process: processport === parseInt(port, 10) ? detail.title : item[0],
            user: detail.user
          }
        }
      }
    })

    return results
  }

  static ss (port = '') {
console.log('>>>', port)
    let stdout = exec('ss -ptls | grep LISTEN').toString().trim().split('\n')
    let results = {}

    if (stdout.length === 0) {
      return {}
    }

    port = port.toString().split(' ').filter(number => !isNaN(number))
console.log(port)
    stdout.forEach(row => {
      // Group 1 is port
      let data = /:{1,3}([A-Za-z0-9]+)/i.exec(row)
console.log(row, data)
      // Handle named ports
      if (data !== null) {
        if (isNaN(data[1]) && portmap.hasOwnProperty(data[1].toLowerCase())) {
          data[1] = portmap[data[1].toLowerCase()].toString()
        }
      }

      if (port.indexOf(data[1].toString()) >= 0) {
        let ct = 0
        let PID = /\(\"([A-Za-z]+)\".*\,[pid=]{0,4}([0-9]+)\,/i.exec(data.input)

        while (PID !== null && ct < 100) {
          let detail = this.linuxProcessDetails(PID[2])

          results[PID[2]] = {
            process: detail.title,
            user: detail.user
          }

          data.input = data.input.replace(`pid=${PID[2]}`)
          PID = /\(\"([A-Za-z]+)\".*pid=([0-9]+)/i.exec(data.input)
          ct++
        }
      }
    })

    return results
  }

  static netstat (port) {
    let stdout = exec('netstat -tulnp | grep ' + port)
    let results = {}

    if (stdout.length === 0) {
      return {}
    }

    stdout.split('\n').forEach(row => {
      let data = row.split(/\s+/).pop().split(/\/|\\/)
      let detail = this.linuxProcessDetails(data[0])

      results[data[0]] = {
        process: detail.title,
        user: detail.user
      }
    })

    return results
  }

  static linuxProcessDetails (pid) {
console.log(exec('ps axco pid,user,command | grep ' + pid).toString())
    let processDetail = exec('ps axco pid,user,command | grep ' + pid)
      .toString()
      .split('\n')
      .filter(line => line.indexOf('grep') < 0)[0]
      .trim()
      .split(/\s+/)

    let user = processDetail[1]
    let title = processDetail.length === 3 ? processDetail[2] : processDetail.slice(2).join(' ')

    return {
      user,
      title
    }
  }
}

module.exports = Parser
<|endoftext|>


<commit_before>'use strict';

var esprima = require('esprima');
var doctrine = require('doctrine');
var _ = require('underscore');
var traverse = require('./traverse.js').traverse;
var Syntax = require('./syntax.js');
var Visitor = require('./visitor.js');
var def = require('./default.js');

/**
 * @param {Object=} opt_options .
 * @constructor
 */
var Parser = function(opt_options) {
  var options = opt_options || {};
  this.roots_ = def.getRoots();
  if (options.roots) {
    options.roots.forEach(function(root) {
      this.roots_[root] = true;
    }, this);
  }

  this.replaceMap_ = def.getReplaceMap();
  if (options.replaceMap) {
    _.extend(this.replaceMap_, options.replaceMap);
  }

  this.packageMethods_ = def.getPackageMethods();
  if (options.packageMethods) {
    options.packageMethods.forEach(function(method) {
      this.packageMethods_[method] = true;
    }, this);
  }

  this.ignorePackages_ = ['goog.global'];
};

/**
 * @param {string} src .
 * @return {{
 *   'provided': Array.<string>,
 *   'required': Array.<string>,
 *   'toRequire': Array.<string>
 * }}
 */
Parser.prototype.parse = function(src) {
  var options = {
    comment: true,
    loc: true
  };
  var ast = esprima.parse(src, options);
  var parsed = this.parseAst_(ast);
  var provided = this.extractProvided_(parsed);
  var required = this.extractRequired_(parsed);
  var suppressed = this.extractSuppressUnused_(parsed, ast.comments);
  var toProvide = this.extractToProvide_(parsed, ast.comments);
  var toRequireFromJsDoc = this.extractToRequireFromJsDoc_(ast.comments);
  var toRequire = this.extractToRequire_(parsed, toProvide, ast.comments, toRequireFromJsDoc);

  return {
    'provided': provided,
    'required': required,
    'toProvide': toProvide,
    'toRequire': toRequire,
    'suppressed': suppressed,
    'provideStart': this.min_,
    'provideEnd': this.max_
  };
};

/**
 * @param {Array} parsed .
 * @param {Array} comments .
 * @return {Array} .
 * @private
 */
Parser.prototype.extractToProvide_ = function(parsed, comments) {
  var typedefs = comments.filter(function(comment) {
    if (comment.type === 'Block' && /^\*/.test(comment.value)) {
      var jsdoc = doctrine.parse('/*' + comment.value + '*/', {unwrap: true});
      return !!jsdoc.tags.some(function(tag) {
        return tag.title === 'typedef';
      });
    }
  });

  return parsed.
    map(this.toProvideMapper_.bind(this, typedefs)).
    filter(this.isDefAndNotNull_).
    filter(this.rootFilter_.bind(this)).
    sort().
    reduce(this.uniq_, []);
};

/**
 * @param {Array} parsed .
 * @param {Array} toProvide .
 * @param {Array} comments .
 * @param {Array=} opt_required .
 * @return {Array} .
 * @private
 */
Parser.prototype.extractToRequire_ = function(parsed, toProvide, comments, opt_required) {
  var additional = opt_required || [];
  var suppressComments = comments.filter(function(comment) {
    return comment.type === 'Line' &&
      /^\s*fixclosure\s*:\s*suppressRequire\s*$/.test(comment.value);
  });
  var toRequire = parsed.
    filter(this.toRequireFilter_.bind(this)).
    filter(this.toRequireSuppressFilter_.bind(this, suppressComments)).
    map(this.toRequireMapper_.bind(this)).
    concat(additional).
    filter(this.isDefAndNotNull_).
    filter(this.rootFilter_.bind(this)).
    sort().
    reduce(this.uniq_, []);
  return _.difference(toRequire, toProvide);
};

/**
 * Require "@implements" classes.
 * @param {Array} comments .
 * @return {Array.<string>} .
 * @private
 */
Parser.prototype.extractToRequireFromJsDoc_ = function(comments) {
  return comments.filter(function(comment) {
    // JSDoc Style
    return comment.type === 'Block' && /^\*/.test(comment.value);
  }).reduce(function(prev, comment) {
    var jsdoc = doctrine.parse('/*' + comment.value + '*/', {unwrap: true});
    jsdoc.tags.forEach(function(tag) {
      if (tag.title === 'implements' && tag.type.type === 'NameExpression') {
        prev.push(tag.type.name);
      }
    });
    return prev;
  }, []);
};

/**
 * Extract "goog.require('goog.foo') // fixclosure: suppress unused".
 * @param {Array} parsed .
 * @param {Array} comments .
 * @return {Array.<string>} .
 * @private
 */
Parser.prototype.extractSuppressUnused_ = function(parsed, comments) {
  var suppresses = comments.filter(function(comment) {
    var a = comment.type === 'Line' &&
      comment.loc.start.line >= this.min_ &&
      comment.loc.start.line <= this.max_ &&
      /^\s*fixclosure\s*:\s*suppressUnused\s*$/.test(comment.value);
    return a;
  }, this).reduce(function(prev, item) {
    prev[item.loc.start.line] = true;
    return prev;
  }, {});

  if (_.isEmpty(suppresses)) {
    return [];
  }

  return parsed.
    filter(this.callExpFilter_.bind(this, 'goog.require')).
    filter(function(req) {
      return !!suppresses[req.node.loc.start.line];
    }).
    map(this.callExpMapper_).
    filter(this.isDefAndNotNull_).
    sort();
};

/**
 * @param {Array.<string>} prev .
 * @param {string} cur .
 * @return {Array.<string>} .
 * @private
 */
Parser.prototype.uniq_ = function(prev, cur) {
  if (prev[prev.length - 1] !== cur) {
    prev.push(cur);
  }
  return prev;
};

/**
 * @param {Array} parsed .
 * @return {Array} .
 * @private
 */
Parser.prototype.extractProvided_ = function(parsed) {
  return parsed.
    filter(this.callExpFilter_.bind(this, 'goog.provide')).
    map(this.callExpMapper_).
    filter(this.isDefAndNotNull_).
    sort();
};

/**
 * @param {Array} parsed .
 * @return {Array} .
 * @private
 */
Parser.prototype.extractRequired_ = function(parsed) {
  return parsed.
    filter(this.callExpFilter_.bind(this, 'goog.require')).
    map(this.callExpMapper_).
    filter(this.isDefAndNotNull_).
    sort();
};

/**
 * @param {Object} node .
 * @return {Array.<Object>} .
 * @private
 */
Parser.prototype.parseAst_ = function(node) {
  var visitor = new Visitor();
  traverse(node, visitor);
  return visitor.uses;
};

/**
 * @param {*} item .
 * @return {boolean} True if the item is not null nor undefined.
 * @private
 */
Parser.prototype.isDefAndNotNull_ = function(item) {
  return item != null;
};

/**
 * @param {string} item .
 * @return {boolean} True if the item has a root namespace to extract.
 * @private
 */
Parser.prototype.rootFilter_ = function(item) {
  var root = item.split('.')[0];
  return root in this.roots_;
};

/**
 * @param {Array} comments "@typedef" comments
 * @param {Object} use .
 * @return {?string} Used namespace.
 * @private
 */
Parser.prototype.toProvideMapper_ = function(comments, use) {
  var name = use.name.join('.');
  switch (use.node.type) {
    case Syntax.AssignmentExpression:
      if (use.key === 'left') {
        return this.getPackageName_(name);
      }
      break;
    case Syntax.ExpressionStatement:
      if (use.node.loc.start.column === 0) {
        var start = use.node.loc.start.line;
        var match = comments.some(function(comment) {
          return comment.loc.end.line + 1 === start;
        });
        if (match) {
          return this.getPackageName_(name);
        }
      }
      break;

    default:
      break;
  }
  return null;
};

/**
 * @param {Object} use .
 * @return {?string} Used namespace.
 * @private
 */
Parser.prototype.toRequireMapper_ = function(use) {
  var name = use.name.join('.');
  return this.getPackageName_(name);
};

/**
 * @param {Object} use .
 * @return {?string} Used namespace.
 * @private
 */
Parser.prototype.toRequireFilter_ = function(use) {
  switch (use.node.type) {
    case Syntax.ArrayExpression:
    case Syntax.BinaryExpression:
    case Syntax.CallExpression:
    case Syntax.ConditionalExpression:
    case Syntax.DoWhileStatement:
    case Syntax.ForInStatement:
    case Syntax.ForStatement:
    case Syntax.IfStatement:
    case Syntax.LogicalExpression:
    case Syntax.MemberExpression:
    case Syntax.NewExpression:
    case Syntax.Property:
    case Syntax.ReturnStatement:
    case Syntax.SequenceExpression:
    case Syntax.SwitchCase:
    case Syntax.SwitchStatement:
    case Syntax.ThrowStatement:
    case Syntax.UnaryExpression:
    case Syntax.UpdateExpression:
    case Syntax.WhileStatement:
      return true;

    case Syntax.AssignmentExpression:
      if (use.key === 'right') {
        return true;
      }
      break;

    case Syntax.VariableDeclarator:
      if (use.key === 'init') {
        return true;
      }
      break;

    default:
      break;
  }

  return false;
};

/**
 * @param {Array} comments .
 * @param {Object} use .
 * @return {?string} Used namespace.
 * @private
 */
Parser.prototype.toRequireSuppressFilter_ = function(comments, use) {
  var start = use.node.loc.start.line;
  var suppressComment = comments.some(function(comment) {
    // same line or next line
    return comment.loc.start.line <= start &&
      comment.loc.start.line + 2 > start;
  });
  return !suppressComment;
};

/**
 * @param {string} name .
 * @return {?string} .
 * @private
 */
Parser.prototype.getPackageName_ = function(name) {
  if (this.isInIgnorePackages_(name)) {
    return null;
  }
  name = this.replaceMethod_(name);
  var names = name.split('.');
  if (this.isPrivateProp_(names)) {
    return null;
  }
  var lastname = names[names.length - 1];
  // Remove calling with apply or call.
  if ('apply' === lastname || 'call' === lastname) {
    names.pop();
    lastname = names[names.length - 1];
  }
  // Remove prototype or superClass_.
  names = names.reduceRight(function(prev, cur) {
    if (cur === 'prototype') {
      return [];
    } else {
      prev.unshift(cur);
      return prev;
    }
  }, []);
  if (!this.isPackageMethod_(name)) {
    lastname = names[names.length - 1];
    if (/^[a-z$]/.test(lastname)) {
      // Remove the last method name.
      names.pop();
    }

    while (names.length > 0) {
      lastname = names[names.length - 1];
      if (/^[A-Z][_0-9A-Z]*$/.test(lastname)) {
        // Remove the last constant name.
        names.pop();
      } else {
        break;
      }
    }

    // Remove the static property.
    if (names.length > 2) {
      lastname = names[names.length - 1];
      var parentClass = names[names.length - 2];
      if (/^[a-z]/.test(lastname) && /^[A-Z]/.test(parentClass)) {
        names.pop();
      }
    }
  }

  if (names.length > 1) {
    return this.replaceMethod_(names.join('.'));
  } else {
    // Ignore just one word namespace like 'goog'.
    return null;
  }
};

/**
 * @param {string} name .
 * @return {boolean} .
 * @private
 */
Parser.prototype.isInIgnorePackages_ = function(name) {
  return this.ignorePackages_.some(function(pack) {
    return name.indexOf(pack, 0) === 0;
  });
};

/**
 * @param {Array.<string>} names .
 * @return {boolean} .
 * @private
 */
Parser.prototype.isPrivateProp_ = function(names) {
  return names.some(function(name) {
    return (/_$/).test(name);
  });
};

/**
 * @param {string} method Method name.
 * @return {string} .
 * @private
 */
Parser.prototype.replaceMethod_ = function(method) {
  return this.replaceMap_[method] || method;
};

/**
 * @param {string} method Method name.
 * @return {boolean} .
 * @private
 */
Parser.prototype.isPackageMethod_ = function(method) {
  return method in this.packageMethods_;
};

/**
 * @type {number}
 * @private
 */
Parser.prototype.min_ = Number.MAX_VALUE;

/**
 * @type {number}
 * @private
 */
Parser.prototype.max_ = 0;

/**
 * @param {string} method Method name.
 * @param {Object} use .
 * @return {?string} .
 * @private
 */
Parser.prototype.callExpFilter_ = function(method, use) {
  var name = use.name.join('.');
  switch (use.node.type) {
    case Syntax.CallExpression:
      if (method === name) {
        var start = use.node.loc.start.line;
        var end = use.node.loc.end.line;
        this.min_ = Math.min(this.min_, start);
        this.max_ = Math.max(this.max_, end);
        return true;
      }
      break;
    default:
      break;
  }
  return false;
};

/**
 * @param {Object} use .
 * @return {?string} .
 * @private
 */
Parser.prototype.callExpMapper_ = function(use) {
  return use.node.arguments[0].value;
};

/**
 * export Pareser
 */
module.exports = Parser;
<commit_msg>Refactoring @typedef<commit_after>'use strict';

var esprima = require('esprima');
var doctrine = require('doctrine');
var _ = require('underscore');
var traverse = require('./traverse.js').traverse;
var Syntax = require('./syntax.js');
var Visitor = require('./visitor.js');
var def = require('./default.js');

/**
 * @param {Object=} opt_options .
 * @constructor
 */
var Parser = function(opt_options) {
  var options = opt_options || {};
  this.roots_ = def.getRoots();
  if (options.roots) {
    options.roots.forEach(function(root) {
      this.roots_[root] = true;
    }, this);
  }

  this.replaceMap_ = def.getReplaceMap();
  if (options.replaceMap) {
    _.extend(this.replaceMap_, options.replaceMap);
  }

  this.packageMethods_ = def.getPackageMethods();
  if (options.packageMethods) {
    options.packageMethods.forEach(function(method) {
      this.packageMethods_[method] = true;
    }, this);
  }

  this.ignorePackages_ = ['goog.global'];
};

/**
 * @param {string} src .
 * @return {{
 *   'provided': Array.<string>,
 *   'required': Array.<string>,
 *   'toRequire': Array.<string>
 * }}
 */
Parser.prototype.parse = function(src) {
  var options = {
    comment: true,
    loc: true
  };
  var ast = esprima.parse(src, options);
  var parsed = this.parseAst_(ast);
  var provided = this.extractProvided_(parsed);
  var required = this.extractRequired_(parsed);
  var suppressed = this.extractSuppressUnused_(parsed, ast.comments);
  var toProvide = this.extractToProvide_(parsed, ast.comments);
  var toRequireFromJsDoc = this.extractToRequireFromJsDoc_(ast.comments);
  var toRequire = this.extractToRequire_(parsed, toProvide, ast.comments, toRequireFromJsDoc);

  return {
    'provided': provided,
    'required': required,
    'toProvide': toProvide,
    'toRequire': toRequire,
    'suppressed': suppressed,
    'provideStart': this.min_,
    'provideEnd': this.max_
  };
};

/**
 * @param {Array} parsed .
 * @param {Array} comments .
 * @return {Array} .
 * @private
 */
Parser.prototype.extractToProvide_ = function(parsed, comments) {
  return parsed.
    map(this.toProvideMapper_.bind(this, this.getTypedefComments_(comments))).
    filter(this.isDefAndNotNull_).
    filter(this.rootFilter_.bind(this)).
    sort().
    reduce(this.uniq_, []);
};

/**
 * @param {Array} comments .
 * @return {Array} .
 * @private
 */
Parser.prototype.getTypedefComments_ = function(comments) {
  return comments.filter(function(comment) {
    if (comment.type === 'Block' && /^\*/.test(comment.value)) {
      var jsdoc = doctrine.parse('/*' + comment.value + '*/', {unwrap: true});
      return !!jsdoc.tags.some(function(tag) {
        return tag.title === 'typedef';
      });
    }
  });
};

/**
 * @param {Array} comments .
 * @return {Array} .
 * @private
 */
Parser.prototype.getSuppressRequireComments_ = function(comments) {
  return comments.filter(function(comment) {
    return comment.type === 'Line' &&
      /^\s*fixclosure\s*:\s*suppressRequire\s*$/.test(comment.value);
  });
};

/**
 * @param {Array} parsed .
 * @param {Array} toProvide .
 * @param {Array} comments .
 * @param {Array=} opt_required .
 * @return {Array} .
 * @private
 */
Parser.prototype.extractToRequire_ = function(parsed, toProvide, comments, opt_required) {
  var additional = opt_required || [];
  var suppressComments = this.getSuppressRequireComments_(comments);
  var toRequire = parsed.
    filter(this.toRequireFilter_.bind(this)).
    filter(this.toRequireSuppressFilter_.bind(this, suppressComments)).
    map(this.toRequireMapper_.bind(this)).
    concat(additional).
    filter(this.isDefAndNotNull_).
    filter(this.rootFilter_.bind(this)).
    sort().
    reduce(this.uniq_, []);
  return _.difference(toRequire, toProvide);
};

/**
 * Require "@implements" classes.
 * @param {Array} comments .
 * @return {Array.<string>} .
 * @private
 */
Parser.prototype.extractToRequireFromJsDoc_ = function(comments) {
  return comments.filter(function(comment) {
    // JSDoc Style
    return comment.type === 'Block' && /^\*/.test(comment.value);
  }).reduce(function(prev, comment) {
    var jsdoc = doctrine.parse('/*' + comment.value + '*/', {unwrap: true});
    jsdoc.tags.forEach(function(tag) {
      if (tag.title === 'implements' && tag.type.type === 'NameExpression') {
        prev.push(tag.type.name);
      }
    });
    return prev;
  }, []);
};

/**
 * Extract "goog.require('goog.foo') // fixclosure: suppress unused".
 * @param {Array} parsed .
 * @param {Array} comments .
 * @return {Array.<string>} .
 * @private
 */
Parser.prototype.extractSuppressUnused_ = function(parsed, comments) {
  var suppresses = comments.filter(function(comment) {
    var a = comment.type === 'Line' &&
      comment.loc.start.line >= this.min_ &&
      comment.loc.start.line <= this.max_ &&
      /^\s*fixclosure\s*:\s*suppressUnused\s*$/.test(comment.value);
    return a;
  }, this).reduce(function(prev, item) {
    prev[item.loc.start.line] = true;
    return prev;
  }, {});

  if (_.isEmpty(suppresses)) {
    return [];
  }

  return parsed.
    filter(this.callExpFilter_.bind(this, 'goog.require')).
    filter(function(req) {
      return !!suppresses[req.node.loc.start.line];
    }).
    map(this.callExpMapper_).
    filter(this.isDefAndNotNull_).
    sort();
};

/**
 * @param {Array.<string>} prev .
 * @param {string} cur .
 * @return {Array.<string>} .
 * @private
 */
Parser.prototype.uniq_ = function(prev, cur) {
  if (prev[prev.length - 1] !== cur) {
    prev.push(cur);
  }
  return prev;
};

/**
 * @param {Array} parsed .
 * @return {Array} .
 * @private
 */
Parser.prototype.extractProvided_ = function(parsed) {
  return parsed.
    filter(this.callExpFilter_.bind(this, 'goog.provide')).
    map(this.callExpMapper_).
    filter(this.isDefAndNotNull_).
    sort();
};

/**
 * @param {Array} parsed .
 * @return {Array} .
 * @private
 */
Parser.prototype.extractRequired_ = function(parsed) {
  return parsed.
    filter(this.callExpFilter_.bind(this, 'goog.require')).
    map(this.callExpMapper_).
    filter(this.isDefAndNotNull_).
    sort();
};

/**
 * @param {Object} node .
 * @return {Array.<Object>} .
 * @private
 */
Parser.prototype.parseAst_ = function(node) {
  var visitor = new Visitor();
  traverse(node, visitor);
  return visitor.uses;
};

/**
 * @param {*} item .
 * @return {boolean} True if the item is not null nor undefined.
 * @private
 */
Parser.prototype.isDefAndNotNull_ = function(item) {
  return item != null;
};

/**
 * @param {string} item .
 * @return {boolean} True if the item has a root namespace to extract.
 * @private
 */
Parser.prototype.rootFilter_ = function(item) {
  var root = item.split('.')[0];
  return root in this.roots_;
};

/**
 * @param {Array} comments "@typedef" comments
 * @param {Object} use .
 * @return {?string} Used namespace.
 * @private
 */
Parser.prototype.toProvideMapper_ = function(comments, use) {
  var name = use.name.join('.');
  switch (use.node.type) {
    case Syntax.AssignmentExpression:
      if (use.key === 'left') {
        return this.getPackageName_(name);
      }
      break;
    case Syntax.ExpressionStatement:
      if (use.node.loc.start.column === 0) {
        var start = use.node.loc.start.line;
        var match = comments.some(function(comment) {
          return comment.loc.end.line + 1 === start;
        });
        if (match) {
          return this.getPackageName_(name);
        }
      }
      break;

    default:
      break;
  }
  return null;
};

/**
 * @param {Object} use .
 * @return {?string} Used namespace.
 * @private
 */
Parser.prototype.toRequireMapper_ = function(use) {
  var name = use.name.join('.');
  return this.getPackageName_(name);
};

/**
 * @param {Object} use .
 * @return {?string} Used namespace.
 * @private
 */
Parser.prototype.toRequireFilter_ = function(use) {
  switch (use.node.type) {
    case Syntax.ArrayExpression:
    case Syntax.BinaryExpression:
    case Syntax.CallExpression:
    case Syntax.ConditionalExpression:
    case Syntax.DoWhileStatement:
    case Syntax.ForInStatement:
    case Syntax.ForStatement:
    case Syntax.IfStatement:
    case Syntax.LogicalExpression:
    case Syntax.MemberExpression:
    case Syntax.NewExpression:
    case Syntax.Property:
    case Syntax.ReturnStatement:
    case Syntax.SequenceExpression:
    case Syntax.SwitchCase:
    case Syntax.SwitchStatement:
    case Syntax.ThrowStatement:
    case Syntax.UnaryExpression:
    case Syntax.UpdateExpression:
    case Syntax.WhileStatement:
      return true;

    case Syntax.AssignmentExpression:
      if (use.key === 'right') {
        return true;
      }
      break;

    case Syntax.VariableDeclarator:
      if (use.key === 'init') {
        return true;
      }
      break;

    default:
      break;
  }

  return false;
};

/**
 * @param {Array} comments .
 * @param {Object} use .
 * @return {?string} Used namespace.
 * @private
 */
Parser.prototype.toRequireSuppressFilter_ = function(comments, use) {
  var start = use.node.loc.start.line;
  var suppressComment = comments.some(function(comment) {
    // same line or next line
    return comment.loc.start.line <= start &&
      comment.loc.start.line + 2 > start;
  });
  return !suppressComment;
};

/**
 * @param {string} name .
 * @return {?string} .
 * @private
 */
Parser.prototype.getPackageName_ = function(name) {
  if (this.isInIgnorePackages_(name)) {
    return null;
  }
  name = this.replaceMethod_(name);
  var names = name.split('.');
  if (this.isPrivateProp_(names)) {
    return null;
  }
  var lastname = names[names.length - 1];
  // Remove calling with apply or call.
  if ('apply' === lastname || 'call' === lastname) {
    names.pop();
    lastname = names[names.length - 1];
  }
  // Remove prototype or superClass_.
  names = names.reduceRight(function(prev, cur) {
    if (cur === 'prototype') {
      return [];
    } else {
      prev.unshift(cur);
      return prev;
    }
  }, []);
  if (!this.isPackageMethod_(name)) {
    lastname = names[names.length - 1];
    if (/^[a-z$]/.test(lastname)) {
      // Remove the last method name.
      names.pop();
    }

    while (names.length > 0) {
      lastname = names[names.length - 1];
      if (/^[A-Z][_0-9A-Z]*$/.test(lastname)) {
        // Remove the last constant name.
        names.pop();
      } else {
        break;
      }
    }

    // Remove the static property.
    if (names.length > 2) {
      lastname = names[names.length - 1];
      var parentClass = names[names.length - 2];
      if (/^[a-z]/.test(lastname) && /^[A-Z]/.test(parentClass)) {
        names.pop();
      }
    }
  }

  if (names.length > 1) {
    return this.replaceMethod_(names.join('.'));
  } else {
    // Ignore just one word namespace like 'goog'.
    return null;
  }
};

/**
 * @param {string} name .
 * @return {boolean} .
 * @private
 */
Parser.prototype.isInIgnorePackages_ = function(name) {
  return this.ignorePackages_.some(function(pack) {
    return name.indexOf(pack, 0) === 0;
  });
};

/**
 * @param {Array.<string>} names .
 * @return {boolean} .
 * @private
 */
Parser.prototype.isPrivateProp_ = function(names) {
  return names.some(function(name) {
    return (/_$/).test(name);
  });
};

/**
 * @param {string} method Method name.
 * @return {string} .
 * @private
 */
Parser.prototype.replaceMethod_ = function(method) {
  return this.replaceMap_[method] || method;
};

/**
 * @param {string} method Method name.
 * @return {boolean} .
 * @private
 */
Parser.prototype.isPackageMethod_ = function(method) {
  return method in this.packageMethods_;
};

/**
 * @type {number}
 * @private
 */
Parser.prototype.min_ = Number.MAX_VALUE;

/**
 * @type {number}
 * @private
 */
Parser.prototype.max_ = 0;

/**
 * @param {string} method Method name.
 * @param {Object} use .
 * @return {?string} .
 * @private
 */
Parser.prototype.callExpFilter_ = function(method, use) {
  var name = use.name.join('.');
  switch (use.node.type) {
    case Syntax.CallExpression:
      if (method === name) {
        var start = use.node.loc.start.line;
        var end = use.node.loc.end.line;
        this.min_ = Math.min(this.min_, start);
        this.max_ = Math.max(this.max_, end);
        return true;
      }
      break;
    default:
      break;
  }
  return false;
};

/**
 * @param {Object} use .
 * @return {?string} .
 * @private
 */
Parser.prototype.callExpMapper_ = function(use) {
  return use.node.arguments[0].value;
};

/**
 * export Pareser
 */
module.exports = Parser;
<|endoftext|>


<commit_before>// pushing data to the renderer

//  // hierarchy
//  bq.on('**/*:add', function(uuid, entity){
//    console.log('Added entity to scene. uuid:'+entity)
//  })
//  // geometry
//  bq.on('**/*:data:geometry', function(uuid, entity, geometry){
//    console.log('Entity geometry data updated (loaded or updated by param change). uuid:'+geometry)
//  })
//  // material
//  bq.on('**/*:data:material', function(uuid, entity, material){
//    console.log('Entity material data updated (loaded or updated by param change). uuid:'+geometry)
//  })

var s3Key = '/3f995099-d624-4c8e-ab6b-1fd5e3799173/170420-1105-7yb890/8db476b3-7eb7-45a7-a09b-03e965f12685.gz.data3d.buffer'

var s3Prefix = 'https://dnvf9esa6v418.cloudfront.net'
var url = s3Prefix + s3Key

// send request
fetch(url).then(function(res) {
  return res.arrayBuffer()
}).then(BASE.data3d.decodeBuffer).then(function(data3d){
  console.log('Data3d has '+Object.keys(data3d.materials).length+' materials.')
})<commit_msg>removes comments<commit_after>var s3Key = '/3f995099-d624-4c8e-ab6b-1fd5e3799173/170420-1105-7yb890/8db476b3-7eb7-45a7-a09b-03e965f12685.gz.data3d.buffer'

var s3Prefix = 'https://dnvf9esa6v418.cloudfront.net'
var url = s3Prefix + s3Key

// send request
fetch(url).then(function(res) {
  return res.arrayBuffer()
}).then(BASE.data3d.decodeBuffer).then(function(data3d){
  console.log('Data3d has '+Object.keys(data3d.materials).length+' materials.')
})<|endoftext|>


<commit_before>default_window_settings = {
	menubar: 'no',
	status: 'no',
	toolbar: 'no',
	location: 'no',
	directories: 'no',
	resizable: 'yes',
	scrollbars: 'auto',
	width: null,
	height: null,
}

function inspect(obj){
	var output = '';
	for(p in obj){
		if(!(obj[p] instanceof Function)){
			output += p + ': ' + obj[p] + "\n";
		}
	}
	alert(output);
}

function alertFailure(failure){
	alert(failure.error);
}

function buildWindowString(attribs){
	output = [];
	for(key in default_window_settings){
		setting = key + '='
		if(attribs[key]){
			setting += attribs[key];
		}
		else{
			setting += default_window_settings[key];
		}
		output.push(setting);
	}
	return output.join(',');
}<commit_msg>improving error reporting<commit_after>default_window_settings = {
	menubar: 'no',
	status: 'no',
	toolbar: 'no',
	location: 'no',
	directories: 'no',
	resizable: 'yes',
	scrollbars: 'auto',
	width: null,
	height: null,
}

function inspect(obj){
	var output = '';
	for(p in obj){
		if(!(obj[p] instanceof Function)){
			output += p + ': ' + obj[p] + "\n";
		}
	}
	alert(output);
}

function alertFailure(failure){
	if(failure.error.stack){
        var frames = failure.parseStack();
        var ret = [];
        for (var i = 0; i < frames.length; ++i) {
            var f = frames[i];
            if (f.fname == "" && f.lineNumber == 0) {
                // ret.pop();
                continue;
            }
            else if(f.func.indexOf('_startRunCallbacks') != -1) {
                continue;
            }
            else if(f.func.indexOf('_runCallbacks') != -1) {
                continue;
            }
            var parts = f.fname.split('/');
            f.fname = parts.slice(parts.length - 2).join('/');

            ret.push(f);
        }
		alert(failure.toPrettyText(ret));
	}
	else{
		alert(failure.toString() + ' (No traceback available)');
	}
}

function buildWindowString(attribs){
	output = [];
	for(key in default_window_settings){
		setting = key + '='
		if(attribs[key]){
			setting += attribs[key];
		}
		else{
			setting += default_window_settings[key];
		}
		output.push(setting);
	}
	return output.join(',');
}<|endoftext|>


<commit_before>import Discover from 'node-discover'
import EventEmitter from 'events'

const CHANNEL = 'clipboard'

export default class Discovery extends EventEmitter {
  constructor() {
    super()
    this.d = Discover()
    this.d.join(CHANNEL, this.handleReceive.bind(this));
  }

  send(data) {
    this.d.send(CHANNEL, data);
  }

  handleReceive(data, obj) {
    this.emit('receive', {
      address: this.findNodeById(obj.iid).address,
      data: data,
      obj: obj
    })
  }

  findNodeById(id) {
    var node;
    this.d.eachNode((n) => {
      if (n.id === id) {
        node = n
      }
    })
    return node
  }
}
<commit_msg>update channel name to handover<commit_after>import Discover from 'node-discover'
import EventEmitter from 'events'

const CHANNEL = 'handover'

export default class Discovery extends EventEmitter {
  constructor() {
    super()
    this.d = Discover()
    this.d.join(CHANNEL, this.handleReceive.bind(this));
  }

  send(data) {
    this.d.send(CHANNEL, data);
  }

  handleReceive(data, obj) {
    this.emit('receive', {
      address: this.findNodeById(obj.iid).address,
      data: data,
      obj: obj
    })
  }

  findNodeById(id) {
    var node;
    this.d.eachNode((n) => {
      if (n.id === id) {
        node = n
      }
    })
    return node
  }
}
<|endoftext|>


<commit_before>'use strict';

var util = require('util');

var re4Integer = '-?(?:0|[1-9][0-9]*)';

var re = exports.re = {
    identifier: new RegExp('^[a-zA-Z_\$]+[a-zA-Z0-9_]*'),
    integer: new RegExp(re4Integer),
    range: new RegExp(util.format('^(%s)?\\:(%s)?(?:\\:(%s)?)?', re4Integer, re4Integer, re4Integer)),
    q_string: new RegExp('^\'(?:\\\\[\'bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\'\\\\])*\''),
    qq_string: new RegExp('^\"(?:\\\\[\"bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\"\\\\])*\"')
};

var types = {
    ROOT: {
        type: 'root'
    },
    WILDCARD: {
        type: 'wildcard'
    },
    RECURSIVE_DESCENT: {
        type: 'recursive_descent'
    },
    PARENT: {
        type: 'parent'
    }
};

var propertyUpdate = {
    identifier: function (properties, reExecResult) {
        properties.push(reExecResult[0]);
    },
    integer: function (properties, reExecResult) {
        var i = parseInt(reExecResult[0], 10);
        properties.push(i);
    },
    q_string: function (properties, reExecResult) {
        var r = reExecResult[0];
        properties.push(r.substring(1, r.length - 1));
    },
    qq_string: function (properties, reExecResult) {
        var r = reExecResult[0];
        properties.push(r.substring(1, r.length - 1));
    },
    range: function (properties, reExecResult) {
        var start = (reExecResult[1] && parseInt(reExecResult[1], 10)) || 0;
        var end = (reExecResult[2] && parseInt(reExecResult[2], 10)) || null;
        var step = (reExecResult[3] && parseInt(reExecResult[3], 10)) || 1;
        properties.push({
            start: start,
            end: end,
            step: step
        });
    }
};

var expandSubscriptProperties = exports.expandSubscriptProperties = function expandSubscriptProperties(subscript, properties) {
    var reKeys = ['range', 'identifier', 'integer', 'q_string', 'qq_string'];
    var n = reKeys.length;
    for (var i = 0; i < n; ++i) {
        var key = reKeys[i];
        var r = re[key];
        var result = r.exec(subscript);
        if (result) {
            propertyUpdate[key](properties, result);
            var nResult = result[0].length;
            if (nResult === subscript.length) {
                return true;
            }
            if (subscript[nResult] !== ',') {
                var msg = util.format('Invalid character "%s" in %s.', subscript[nResult], subscript);
                throw new Error(msg);
            }
            subscript = subscript.substring(nResult + 1);
            return expandSubscriptProperties(subscript, properties);
        }
    }
    return false;
};

var subscriptToNode = function (subscript) {
    var n = subscript.length;
    if (n === 0) {
        throw new Error('Empty subscript in path.');
    }

    if (subscript === '*') {
        return types.WILDCARD;
    }

    var c = subscript.charAt(0);
    var ce = subscript.charAt(n - 1);

    if (c === '(') {
        if (ce !== ')') {
            throw new Error('Subscript starts with "(" but does not end with ")".');
        }
        return {
            type: 'script',
            parameter: subscript.substring(1, n - 1)
        };
    }

    if (c === '?') {
        if ((n < 2) || (subscript.charAt(1) !== '(')) {
            throw new Error('Subscript start with "?" but the second character is not "("');
        }
        if (ce !== ')') {
            throw new Error('Subscript starts with "?(" but does not end with ")".');
        }
        return {
            type: 'filter_script',
            parameter: subscript.substring(2, n - 1)
        };
    }

    if ((c === '$') && (n > 1) && (subscript.charAt(1) === '.')) {
        return {
            type: 'subpath',
            parameter: subscript
        };
    }

    var properties = [];
    var result = expandSubscriptProperties(subscript, properties);
    if (result) {
        var single = (properties.length === 1) && (typeof properties[0] !== 'object');
        return {
            type: single ? 'property' : 'properties',
            parameter: single ? properties[0] : properties
        };
    }

    throw new Error('Invalid subscript: ' + subscript);
};

var updateNodesWithProperty = function (property, nodes) {
    var n = property.length;
    if (property.substring(n - 2, n) === '()') {
        nodes.push({
            type: 'fn',
            parameter: property.substring(0, n - 2)
        });
        return;
    }
    nodes.push({
        type: 'property',
        parameter: property
    });
};

var findMatchingSquareBracket = function (path, index) {
    var length = path.length;
    var openBrackets = 1;
    while (index < length) {
        var c = path.charAt(index);
        if (c === '[') {
            ++openBrackets;
            ++index;
        } else if (c === ']') {
            --openBrackets;
            if (openBrackets === 0) {
                return index;
            }
            ++index;
        } else {
            ++index;
        }
    }
    throw new Error('Closing square brackets is not found');
};

var nodeAccumulator = (function () {
    var prototype = {
        pushNode: function (node) {
            this.exprList.push(node);
            ++this.index;
            this.lastIndex = this.index;
        },
        clearBuffer: function () {
            if (this.lastIndex < this.index) {
                var subExpr = this.expr.substring(this.lastIndex, this.index);
                updateNodesWithProperty(subExpr, this.exprList);
            }
        },
        '.': function () {
            this.clearBuffer();
            ++this.index;
            var cp1 = this.expr.charAt(this.index);
            if (cp1 === '.') {
                this.exprList.push(types.RECURSIVE_DESCENT);
                ++this.index;
            } else if (this.index === this.length) {
                throw new Error('Incomplete path.');
            }
            if (this.expr.charAt(this.index) === '.') {
                throw new Error('Invalid syntax "...".');
            }
            this.lastIndex = this.index;
            return true;
        },
        '[': function () {
            this.clearBuffer();
            ++this.index;
            this.lastIndex = this.index;
            this.index = findMatchingSquareBracket(this.expr, this.index);
            var subExprInside = this.expr.substring(this.lastIndex, this.index);
            var scriptResult = subscriptToNode(subExprInside);
            this.pushNode(scriptResult);
            return true;
        },
        '*': function () {
            if (this.lastIndex === this.index) {
                this.pushNode(types.WILDCARD);
                return true;
            } else {
                return false;
            }
        },
        '$': function () {
            if ((this.index === 0) && (this.expr.charAt(1) === '.')) {
                this.pushNode(types.ROOT);
                return true;
            } else {
                return false;
            }
        },
        '^': function () {
            this.clearBuffer();
            this.pushNode(types.PARENT);
            return true;
        }
    };

    return function (expr) {
        var result = Object.create(prototype);
        result.expr = expr;
        result.exprList = [];
        result.index = 0;
        result.length = expr.length;
        result.lastIndex = 0;
        return result;
    };
})();

exports.normalize = function (expr) {
    var accum = nodeAccumulator(expr);
    while (accum.index < accum.length) {
        var c = expr.charAt(accum.index);
        var handler = accum[c];
        if (handler) {
            var r = handler.call(accum);
            if (r) {
                continue;
            }
        }
        ++accum.index;
    }
    accum.clearBuffer();
    return accum.exprList;
};
<commit_msg>code cleaning<commit_after>'use strict';

var util = require('util');

var re4Integer = '-?(?:0|[1-9][0-9]*)';

var re = exports.re = {
    identifier: new RegExp('^[a-zA-Z_\\$]+[a-zA-Z0-9_]*'),
    integer: new RegExp(re4Integer),
    range: new RegExp(util.format('^(%s)?\\:(%s)?(?:\\:(%s)?)?', re4Integer, re4Integer, re4Integer)),
    q_string: new RegExp('^\'(?:\\\\[\'bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\'\\\\])*\''),
    qq_string: new RegExp('^\"(?:\\\\[\"bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\"\\\\])*\"')
};

var types = {
    ROOT: {
        type: 'root'
    },
    WILDCARD: {
        type: 'wildcard'
    },
    RECURSIVE_DESCENT: {
        type: 'recursive_descent'
    },
    PARENT: {
        type: 'parent'
    }
};

var propertyUpdate = {
    identifier: function (properties, reExecResult) {
        properties.push(reExecResult[0]);
    },
    integer: function (properties, reExecResult) {
        var i = parseInt(reExecResult[0], 10);
        properties.push(i);
    },
    q_string: function (properties, reExecResult) {
        var r = reExecResult[0];
        properties.push(r.substring(1, r.length - 1));
    },
    qq_string: function (properties, reExecResult) {
        var r = reExecResult[0];
        properties.push(r.substring(1, r.length - 1));
    },
    range: function (properties, reExecResult) {
        var start = (reExecResult[1] && parseInt(reExecResult[1], 10)) || 0;
        var end = (reExecResult[2] && parseInt(reExecResult[2], 10)) || null;
        var step = (reExecResult[3] && parseInt(reExecResult[3], 10)) || 1;
        properties.push({
            start: start,
            end: end,
            step: step
        });
    }
};

var expandSubscriptProperties = exports.expandSubscriptProperties = function expandSubscriptProperties(subscript, properties) {
    var reKeys = ['range', 'identifier', 'integer', 'q_string', 'qq_string'];
    var n = reKeys.length;
    for (var i = 0; i < n; ++i) {
        var key = reKeys[i];
        var r = re[key];
        var result = r.exec(subscript);
        if (result) {
            propertyUpdate[key](properties, result);
            var nResult = result[0].length;
            if (nResult === subscript.length) {
                return true;
            }
            if (subscript[nResult] !== ',') {
                var msg = util.format('Invalid character "%s" in %s.', subscript[nResult], subscript);
                throw new Error(msg);
            }
            subscript = subscript.substring(nResult + 1);
            return expandSubscriptProperties(subscript, properties);
        }
    }
    return false;
};

var subscriptHandlers = {
    '$': {
        verify: function (subscript) {
            return (subscript.length > 1) && (subscript.charAt(1) === '.');
        },
        node: function (subscript) {
            return {
                type: 'subpath',
                parameter: subscript
            };
        }
    },
    '?': {
        verify: function (subscript) {
            var n = subscript.length;
            if ((n < 2) || (subscript.charAt(1) !== '(')) {
                throw new Error('Subscript start with "?" but the second character is not "("');
            }
            if (subscript.charAt(n - 1) !== ')') {
                throw new Error('Subscript starts with "?(" but does not end with ")".');
            }
            return true;
        },
        node: function (subscript) {
            var n = subscript.length;
            return {
                type: 'filter_script',
                parameter: subscript.substring(2, n - 1)
            };
        }
    },
    '(': {
        verify: function (subscript) {
            var n = subscript.length;
            if (subscript.charAt(n - 1) !== ')') {
                throw new Error('Subscript starts with "(" but does not end with ")".');
            }
            return true;
        },
        node: function (subscript) {
            var n = subscript.length;
            return {
                type: 'script',
                parameter: subscript.substring(1, n - 1)
            };
        }
    },
    '*': {
        verify: function (subscript) {
            return subscript.length === 1;
        },
        node: function (subscript) {
            return types.WILDCARD;
        }
    }
};

var subscriptToNode = function (subscript) {
    if (subscript.length === 0) {
        throw new Error('Empty subscript in path.');
    }

    var c = subscript.charAt(0);
    var handler = subscriptHandlers[c];
    if (handler && handler.verify(subscript)) {
        return handler.node(subscript);
    }

    var properties = [];
    var result = expandSubscriptProperties(subscript, properties);
    if (result) {
        var single = (properties.length === 1) && (typeof properties[0] !== 'object');
        return {
            type: single ? 'property' : 'properties',
            parameter: single ? properties[0] : properties
        };
    }

    throw new Error('Invalid subscript: ' + subscript);
};

var updateNodesWithProperty = function (property, nodes) {
    var n = property.length;
    if (property.substring(n - 2, n) === '()') {
        nodes.push({
            type: 'fn',
            parameter: property.substring(0, n - 2)
        });
        return;
    }
    nodes.push({
        type: 'property',
        parameter: property
    });
};

var findMatchingSquareBracket = function (path, index) {
    var length = path.length;
    var openBrackets = 1;
    while (index < length) {
        var c = path.charAt(index);
        if (c === '[') {
            ++openBrackets;
            ++index;
        } else if (c === ']') {
            --openBrackets;
            if (openBrackets === 0) {
                return index;
            }
            ++index;
        } else {
            ++index;
        }
    }
    throw new Error('Closing square brackets is not found');
};

var nodeAccumulator = (function () {
    var prototype = {
        pushNode: function (node) {
            this.exprList.push(node);
            ++this.index;
            this.lastIndex = this.index;
        },
        clearBuffer: function () {
            if (this.lastIndex < this.index) {
                var subExpr = this.expr.substring(this.lastIndex, this.index);
                updateNodesWithProperty(subExpr, this.exprList);
            }
        },
        '.': function () {
            this.clearBuffer();
            ++this.index;
            this.lastIndex = this.index;
            var cp1 = this.expr.charAt(this.index);
            if (cp1 === '.') {
                this.exprList.push(types.RECURSIVE_DESCENT);
                ++this.index;
                this.lastIndex = this.index;
            } else if (this.index === this.length) {
                throw new Error('Incomplete path.');
            }
            if (this.expr.charAt(this.index) === '.') {
                throw new Error('Invalid syntax "...".');
            }
            return true;
        },
        '[': function () {
            this.clearBuffer();
            ++this.index;
            this.lastIndex = this.index;
            this.index = findMatchingSquareBracket(this.expr, this.index);
            var subExprInside = this.expr.substring(this.lastIndex, this.index);
            var scriptResult = subscriptToNode(subExprInside);
            this.pushNode(scriptResult);
            return true;
        },
        '*': function () {
            if (this.lastIndex === this.index) {
                this.pushNode(types.WILDCARD);
                return true;
            } else {
                return false;
            }
        },
        '$': function () {
            if ((this.index === 0) && (this.expr.charAt(1) === '.')) {
                this.pushNode(types.ROOT);
                return true;
            } else {
                return false;
            }
        },
        '^': function () {
            this.clearBuffer();
            this.pushNode(types.PARENT);
            return true;
        }
    };

    return function (expr) {
        var result = Object.create(prototype);
        result.expr = expr;
        result.exprList = [];
        result.index = 0;
        result.length = expr.length;
        result.lastIndex = 0;
        return result;
    };
})();

exports.normalize = function (expr) {
    var accum = nodeAccumulator(expr);
    while (accum.index < accum.length) {
        var c = expr.charAt(accum.index);
        var handler = accum[c];
        if (handler) {
            var r = handler.call(accum);
            if (r) {
                continue;
            }
        }
        ++accum.index;
    }
    accum.clearBuffer();
    return accum.exprList;
};
<|endoftext|>


<commit_before>'use strict';

var parser = module.exports = {};

var glob = require('glob');
var node_path = require('path');
var node_fs = require('fs');
var sep = node_path.sep;

// parse the tree structure of the document
// basic infomations
// @param {path} dir absolute dir of the document root

// tree:
// {
//     index: 'index.md',
//     depth: 0,
//     pages: {
//         '1_a.md': {
//             parent: <recursive>
//             depth: 1,
//             // empty array indicates there're no sub pages
//             pages: []
//         }
//     }
// }

parser.tree = function (dir, callback) {
    glob('**/*.md', {
        cwd: dir,
        strict: true

    }, function (err, files) {
        if ( err ) {
            return callback(err);
        }

        var tree = {
            depth: 0,
            type: 'dir',
            pages: {}
        };

        files.forEach(function (file) {
            parser._save_item(tree, file, dir);
        });

        callback(null, tree);
    });
};

parser._save_item = function (tree, path, root) {
    var parent = tree;
    var abs = root;

    path.split(sep).some(function (slice, i) {
        abs = node_path.join(abs, slice);

        if ( slice === 'index.md' ) {
            parent.path = abs;
            return true;
        }

        if ( !('slice' in parent.pages) ) {
            var current = parent.pages[slice] = {
                parent: parent,
                depth: i + 1,
                path: abs
            };

            if ( node_fs.statSync(abs).isDirectory() ) {
                current.pages = {};
                current.type = 'dir';

            } else {
                current.type = 'file';
                // if file occurs, skip parsing
                return true;
            }
        }

        parent = current;
    });
};

// options.
parser.markdown = function (code, callback) {
    marked(code, callback);
};

<commit_msg>complete parser<commit_after>'use strict';

var parser = module.exports = {};

var glob        = require('glob');
var node_path   = require('path');
var sep         = node_path.sep;
var node_fs     = require('fs');
var lang        = require('./lang');
var queue       = require('async');

// parse the tree structure of the document
// basic infomations
// @param {path} dir absolute dir of the document root

// tree:
// {
//     index: 'README.md',
//     depth: 0,
//     pages: {
//         '1_a.md': {
//             parent: <recursive>
//             depth: 1,
//             // empty array indicates there're no sub pages
//             pages: {}
//         }
//     }
// }
parser.raw_tree = function (dir, callback) {
    glob('**/*.md', {
        cwd: dir,
        strict: true

    }, function (err, files) {
        if ( err ) {
            return callback(err);
        }

        var tree = {
            depth: 0,
            type: 'dir',
            pages: {}
        };

        files.forEach(function (file) {
            parser._save_item(tree, file, dir);
        });

        callback(null, tree);
    });
};

parser._save_item = function (tree, path, root) {
    var parent = tree;
    var abs = root;

    path.split(sep).some(function (slice, i) {
        abs = node_path.join(abs, slice);

        if ( slice === 'README.md' ) {
            parent.path = abs;
            return true;
        }

        if ( !(slice in parent.pages) ) {
            var current = parent.pages[slice] = {
                // duplicate data for more easily parsing
                name: slice,
                // parent: parent,
                depth: i + 1,
                path: abs
            };

            if ( node_fs.statSync(abs).isDirectory() ) {
                current.pages = {};
                current.type = 'dir';
                parent = current;

            } else {
                current.type = 'file';
                // if file occurs, skip parsing
                return true;
            }
        }
    });
};

// @param {Object=} languages
// {
//     "zh-CN": {
//     }
// }
parser.language_tree = function (raw_tree, languages) {
    if ( lang.isEmptyObject(languages) ) {
        languages = null;
    }

    var ret = {};

    if ( languages ) {
        var root = raw_tree.pages || {};

        lang.each(languages, function (name, language) {
            ret[language] = {
                name: name,
                tree: root[language] || {}
            };
        });

    } else {
        return {
            default: {
                tree: raw_tree
            }
        };
    }
};

// options.
parser.markdown = function (code, callback) {
    marked(code, callback);
};

// @param {Object} options
// - define
parser.sort_tree = function (tree, options, callback) {

};

// create a cache
parser.create_data = function (language_tree, callback) {
    var counter = Object.keys(language_tree).length;
    var error;

    function iterator (node, done) {
        if ( node.type === 'file' ) {
            var file = node.path;

            node_fs.readFile(file, function (err, content) {
                if ( err ) {
                    return done(err);
                }

                parser.markdown(content, function (err, html) {
                    if ( err ) {
                        return done(err);
                    }

                    node.html = html;
                    done(null);
                });
            });

        } else {
            done(null);
        }
    };

    lang.each(language_tree, function (tree, language) {
        parser.walk(tree, function (err) {
            if ( err ) {
                error = err;
                return callback(err);

            } else if (error) {
                return;

            } else if ( -- counter === 0 ) {
                return callback(null, language_tree);
            }
        });
    });
};

// walk a tree
parser.walk = function (tree, iterator, callback) {
    var q = async.queue(iterator);
    var errors = [];

    q.drain = function () {
        callback( errors.length ? errors : null );
    };

    function walk (node) {
        q.push(node, function (err){
            errors.push(err);
        });

        if ( node.pages ) {
            lang.each(node.pages, function (sub_node, name) {
                walk(sub_node);
            });
        }
    }
};

<|endoftext|>


<commit_before>(function () {

    angular
        .module('app')
        .controller('DoctorController', ['$scope', 'Restangular',  '$translate','$mdToast', 'AuthService', 'AUTH_EVENTS',
            DoctorController
        ]);

    function DoctorController($scope, Restangular, $translate, $mdToast, AuthService, AUTH_EVENTS) {

        //TODO get not user ID but doctor ID
        $scope.account = AuthService.getUser();

        //FIXME: Change to constant
        //FIXME: Change to permissions
        if ($scope.account.role === "doctor" ||
            $scope.account.role === "chief"
        ) {
            $scope.doctor = $scope.account.person;
        } else {
            Restangular.one('doctors', $scope.account.id).get()
                .then(function (response) {
                    $scope.doctor = response;
                });
        }

        $scope.updateInfo = function () {
            console.log($scope.doctor);
            $scope.doctor.put()
                    .then(function (response) {
                        $scope.showSimpleToast($translate.instant('DONE'));
                    },
                    function (errors) {
                        // TODO differrent typer of erroros
                    });
        };

        $scope.showSimpleToast = function (text) {
            $mdToast.show(
                    $mdToast.simple()
                    .textContent(text)
                    .position('top right')
                    .hideDelay(3000)
                    );
        };
    }
})();

<commit_msg>doctor controller put<commit_after>(function () {

    angular
        .module('app')
        .controller('DoctorController', ['$scope', 'Restangular', '$translate', '$mdToast', 'AuthService', 'AUTH_EVENTS',
            DoctorController
        ]);

    function DoctorController($scope, Restangular, $translate, $mdToast, AuthService, AUTH_EVENTS) {

        //TODO get not user ID but doctor ID
        $scope.account = AuthService.getUser();

        //FIXME: Change to constant
        //FIXME: Change to permissions
        if ($scope.account.role === "doctor" ||
            $scope.account.role === "chief"
        ) {
            $scope.doctor = $scope.account.person;
        } else {
            Restangular.one('doctors', $scope.account.id).get()
                .then(function (response) {
                    $scope.doctor = response;
                });
        }

        $scope.updateInfo = function () {
            Restangular.one('doctors', $scope.doctor.id).get()
                .then(function (doctor) {
                    for (var property in doctor) {
                        if ($scope.doctor.hasOwnProperty(property)) {
                            doctor[property] = $scope.doctor[property];
                        }
                    }
                    return doctor;
                })
                .then(function (editedDoctor) {
                    return editedDoctor.put();
                })
                .then(function (response) {
                        $scope.showSimpleToast($translate.instant('DONE'));
                    },
                    function (errors) {
                        // TODO differrent typer of erroros
                    });
        };

        $scope.showSimpleToast = function (text) {
            $mdToast.show(
                $mdToast.simple()
                    .textContent(text)
                    .position('top right')
                    .hideDelay(3000)
            );
        };
    }
})();

<|endoftext|>


<commit_before>var fs = require("fs");
var path = require("path");
var util = require("util");
var _ = require("underscore");
var markdown = require("marked");
var findFiles = require("./utils/find_files");

var app = {};

function Parser(_app)
{
	var self = this;

	// Global Variables
	app = _app;

	// Class Variables
	self.parsers = {};
	self.parsedFileElements = [];
	self.parsedFiles = [];

	// Markdown settings
	markdown.setOptions(app.options.marked);

	// Parser laden
	var parsers = Object.keys(app.parsers);
	parsers.forEach(function(parser) {
		var filename = app.parsers[parser];
		app.debug("load parser: " + parser + ", " + filename);
		self.addParser(parser, require(filename));
	});
} // Parser

/**
 * Inherit
 */
util.inherits(Parser, Object);

/**
 * Exports
 */
module.exports = Parser;

/**
 * Add a Parser
 */
Parser.prototype.addParser = function(name, parser)
{
	this.parsers[name] = parser;
}; // addParser

/**
 * Parse files in specified folder.
 * @param {Object} options The options used to parse and filder the files.
 * @param {Object[]} parsedFiles List of parsed files.
 * @param {String[]} parsedFilenames List of parsed files, with full path.
 */
Parser.prototype.parseFiles = function(options, parsedFiles, parsedFilenames)
{
    var self = this;

    var files = findFiles(options);
    // Parser
    for(var i = 0; i < files.length; i += 1) {
        var filename = options.src + files[i];
        var parsedFile = self.parseFile(filename);
        if(parsedFile) {
            app.log("parse file: " + filename);
            parsedFiles.push(parsedFile);
            parsedFilenames.push(filename);
        }
    } // for
}; // parseFiles

/**
 * Execute Fileparsing
 */
Parser.prototype.parseFile = function(filename)
{
    var self = this;

    app.debug("inspect file: " + filename);

    self.filename = filename;
    self.extension = path.extname(filename).toLowerCase();
    self.src = fs.readFileSync(filename, "utf8").toString();
    app.debug("size: " + self.src.length);

    // Unify Linebreaks
    self.src = self.src.replace(/\r\n/g, "\n");

    self.blocks = [];
    self.indexApiBlocks = [];

    // Determine Blocks
    self.blocks = self._findBlocks();
    if(self.blocks.length === 0) return;
    app.debug("count blocks: " + self.blocks.length);

    // Determine Elements of Blocks
    self.elements = self.blocks.map(function(block, i){
        app.debug("count elements in block " + i + ": " + block.length);
        return self._findElements(block);
    });
    if(self.elements.length === 0) return;

    // Determine List of Blocks with API-Elements
    self.indexApiBlocks = self._findBlockWithApiGetIndex(self.elements);
    if(self.indexApiBlocks.length === 0) return;

    return self._parseBlockElements(self.indexApiBlocks, self.elements);
}; // parseFile

/**
 * Parse API Elements with Plugins
 *
 * @param indexApiBlocks
 * @param detectedElements
 * @returns {___anonymous2249_2250}
 */
Parser.prototype._parseBlockElements = function(indexApiBlocks, detectedElements)
{
	var self = this;
	var parsedBlocks = [];
	for(var i = 0; i < indexApiBlocks.length; i += 1)
	{
		var blockIndex = indexApiBlocks[i];
		var elements = detectedElements[blockIndex];
		var blockData = {
			global: {},
			local: {}
		};
		var preventGlobal = false;
		var countAllowedMultiple = 0;
		for(var j = 0; j < elements.length; j += 1)
		{
			var element = elements[j];
			if(self.parsers[element.name])
			{
				// Determine Fieldvalues
				var result = null;
				try {
					result = self.parsers[element.name].parse(element.content, element.source);

					// Markdown
					// TODO: Evaluate if better add a function in specific worker_{name}.js
					if(  result &&
                         app.options.marked.gfm &&
						 self.parsers[element.name].markdownFields &&
						 self.parsers[element.name].markdownFields.length > 0
					)
					{
						for(var markdownIndex = 0; markdownIndex < self.parsers[element.name].markdownFields.length; markdownIndex += 1)
						{
							var markdownField = self.parsers[element.name].markdownFields[markdownIndex];
							if(result[markdownField])
							{
								result[markdownField] = markdown(result[markdownField]);
								// remove line breaks.
								result[markdownField] = result[markdownField].replace(/(\r\n|\n|\r)/g, "");
							}
						} // for
					}
				}
				catch(e)
				{
					throw new Error("\"@" + element.sourceName + "\" in file \"" + self.filename +
						"\" block number " + (blockIndex + 1) + ", source \"" + element.source + "\" " + e
					);
				}

				if( ! result)
				{
					throw new Error("Empty parser result for \"@" + element.sourceName + "\" in file \"" + self.filename +
						"\" block number " + (blockIndex + 1) + ", source \"" + element.source + "\""
					);
				}

				// Check if it is allowed to add to global namespace.
				if(self.parsers[element.name].preventGlobal && self.parsers[element.name].preventGlobal === true)
				{
					preventGlobal = true;
					// Check if count global namespace entries > count allowed
					// (e.g. @successTitle is global, but should co-exist with @apiErrorStructure)
					if(Object.keys(blockData.global).length > countAllowedMultiple)
					{
						throw new Error("Can't set \"@" + element.sourceName + "\" in file \"" + self.filename +
							"\" block number " + (blockIndex + 1) + ", only one definition or use is allowed in the same block."
						);
					}
				}
				if(self.parsers[element.name].pushTo)
				{
					// Fieldvalues will be inserted into subpath
					var pushTo = self.parsers[element.name].pushTo();

					// Only one global allowed per block
					if(pushTo === "global" || pushTo.substr(0, 7) === "global.")
					{
						var allowMultiple = self.parsers[element.name].allowMultiple || false;

						if(allowMultiple)
						{
							countAllowedMultiple += 1;
						}
						else
						{
							if(Object.keys(blockData.global).length > 0)
							{
								throw new Error("Can't set \"@" + element.sourceName + "\" in file \"" + self.filename +
									"\" block number " + (blockIndex + 1) + ", only one definition per block allowed."
								);
							}

							if(preventGlobal === true)
							{
								throw new Error("Can't set \"@" + element.sourceName + "\" in file \"" + self.filename +
									"\" block number " + (blockIndex + 1) + ", only one definition or use is allowed in the same block."
								);
							}
						}
					}

					if( ! blockData[pushTo])
					{
						// Create path
						self._createObjectPath(blockData, pushTo);
					}

					var blockDataPath = _pathToObject(pushTo, blockData);

					// Insert Fieldvalues in Path-Array
					if(typeof(blockData[pushTo]) === "object")
					{
						_.extend(blockData[pushTo], result);
					}
					else
					{
						blockDataPath.push(result);
					}

					if(self.parsers[element.name].extendRoot === true)
					{
						// Insert Fieldvalues in Mainpath
						_.extend(blockData, result);
					}
				}
				else
				{
					// Insert Fieldvalues in Mainpath
					_.extend(blockData, result);
				}
				blockData.index = blockIndex + 1;
			}
			else
			{
				app.logWarn("parser plugin \"" + element.name + "\" not found.");
			}
		} // for
		parsedBlocks.push(blockData);
	} // for
	return parsedBlocks;
};

/**
 * Return Path to Object.
 */
function _pathToObject(path, src) {
	if( ! path) return src;
	var pathParts = path.split(".");
	var current = src;
	for(var i = 0; i < pathParts.length; i += 1)
	{
		var part = pathParts[i];
		current = current[part];
	} // for
  return current;
} // _pathToObject

/**
 * Create a not existing Path in an Object.
 *
 * @param src
 * @param path
 * @returns {Object}
 */
Parser.prototype._createObjectPath = function(src, path)
{
	if( ! path) return src;
	var pathParts = path.split(".");
	var current = src;
	for(var i = 0; i < pathParts.length; i += 1)
	{
		var part = pathParts[i];
		if( ! current[part])
		{
			if(i === (pathParts.length - 1) ) current[part] = [];
			else current[part] = {};
		}
		current = current[part];
	} // for
	return current;
}; // _createObjectPath

/**
 * Determine Blocks
 */
Parser.prototype._findBlocks = function()
{
    var self = this;
    var blocks = [];
    var src = self.src;

    // Replace Linebreak with Unicode
    src = src.replace(/\n/g, "\uffff");

    var regexs = {
        ".coffee": {
            // Find document blocks between "###" and "###"
            docBlocksRegExp: /###\uffff?(.+?)###/g,
            // Remove not needed "	" (tabs) at the beginning
            inlineRegExp: /^(\t+)?[ ]?/gm
        },
        ".erl": {
            // Find document blocks between "%{" and "%}"
            docBlocksRegExp: /\%\{\uffff?(.+?)\%\}/g,
            // Remove not needed " % " and "	" (tabs) at the beginning
            // HINT: Not sure if erlang developer use the %, but i think it should be no problem
            inlineRegExp: /^(\t+)?(\%)[ ]?/gm
        },
        ".py": {
            // Find document blocks between """ and """
            docBlocksRegExp: /\"\"\"\uffff?(.+?)\"\"\"/g,
            // Remove not needed "	" (tabs) at the beginning
            inlineRegExp: /^(\t+)?[ ]?/gm
        },
        ".rb": {
            // Find document blocks between "=begin" and "=end"
            docBlocksRegExp: /\=begin\uffff?(.+?)\=end/g,
            // Remove not needed "	" (tabs) at the beginning
            inlineRegExp: /^(\t+)?[ ]?/gm
        },
        ".pm": {
            // Find document blocks between "#**" and "#*"
            // or between "=pod" and "=cut"
            docBlocksRegExp: /#\*\*\uffff?(.+?)#\*|=pod\uffff?(.+?)=cut/g,
            // Remove not needed " # " and "    " (tabs) at the beginning
            inlineRegExp: /^(\s+)?(#)[ ]?/gm
        },
        "default": {
            // Find document blocks between "#**" and "#*"
            docBlocksRegExp: /\/\*\*\uffff?(.+?)\*\//g,
            // Remove not needed " # " and "	" (tabs) at the beginning
            inlineRegExp: /^(\s+)?(\*)[ ]?/gm
        }
    };
    var regexForFile = regexs[self.extension] || regexs["default"];
    var matches = regexForFile.docBlocksRegExp.exec(src);
    while(matches)
    {
        var block = matches[2] || matches[1];

        // Reverse Unicode Linebreaks
        block = block.replace(/\uffff/g, "\n");

        block = block.replace(regexForFile.inlineRegExp, "");

        blocks.push(block);

        // Find next
        matches = regexForFile.docBlocksRegExp.exec(src);
    } // while
    return blocks;

}; // _findBlocks

/**
 * Check if block has API elements and return block indexes.
 */
Parser.prototype._findBlockWithApiGetIndex = function(blocks)
{
    var foundIndexes = [];
    blocks.forEach(function(block, i){
        var add;
        block.forEach(function(element)
        {
            if(add !== false){
                add = element.name.substr(0, 3) === "api" && element.name.substr(0, 9) !== "apiignore";
            }
        });
        if(add)
        {
            foundIndexes.push(i);
            app.debug("api found in block: " + i);
        }
    });
    return foundIndexes;
}; // _findBlockWithApiGetIndex

/**
 * Get Elements of Blocks.
 */
Parser.prototype._findElements = function(block)
{
	var self = this;
	var elements = [];

	// Replace Linebreak with Unicode
	block = block.replace(/\n/g, "\uffff");

	// Elements start with @
	var elementsRegExp = /(@(\w*)\s?(.+?)(?=\uffff[\s\*]*@|$))/gm;
	var matches = elementsRegExp.exec(block);
	while(matches)
	{
		var element = {
			source: matches[1],
			name: matches[2].toLowerCase(),
			sourceName: matches[2],
			content: matches[3]
		};

		// Reverse Unicode Linebreaks
		element.content = element.content.replace(/\uffff/g, "\n");
		element.source = element.source.replace(/\uffff/g, "\n");

		elements.push(element);

		// Next Match
		matches = elementsRegExp.exec(block);
	}
	return elements;
}; // _findElements
<commit_msg>Correctly handle Erlang comments.<commit_after>var fs = require("fs");
var path = require("path");
var util = require("util");
var _ = require("underscore");
var markdown = require("marked");
var findFiles = require("./utils/find_files");

var app = {};

function Parser(_app)
{
	var self = this;

	// Global Variables
	app = _app;

	// Class Variables
	self.parsers = {};
	self.parsedFileElements = [];
	self.parsedFiles = [];

	// Markdown settings
	markdown.setOptions(app.options.marked);

	// Parser laden
	var parsers = Object.keys(app.parsers);
	parsers.forEach(function(parser) {
		var filename = app.parsers[parser];
		app.debug("load parser: " + parser + ", " + filename);
		self.addParser(parser, require(filename));
	});
} // Parser

/**
 * Inherit
 */
util.inherits(Parser, Object);

/**
 * Exports
 */
module.exports = Parser;

/**
 * Add a Parser
 */
Parser.prototype.addParser = function(name, parser)
{
	this.parsers[name] = parser;
}; // addParser

/**
 * Parse files in specified folder.
 * @param {Object} options The options used to parse and filder the files.
 * @param {Object[]} parsedFiles List of parsed files.
 * @param {String[]} parsedFilenames List of parsed files, with full path.
 */
Parser.prototype.parseFiles = function(options, parsedFiles, parsedFilenames)
{
    var self = this;

    var files = findFiles(options);
    // Parser
    for(var i = 0; i < files.length; i += 1) {
        var filename = options.src + files[i];
        var parsedFile = self.parseFile(filename);
        if(parsedFile) {
            app.log("parse file: " + filename);
            parsedFiles.push(parsedFile);
            parsedFilenames.push(filename);
        }
    } // for
}; // parseFiles

/**
 * Execute Fileparsing
 */
Parser.prototype.parseFile = function(filename)
{
    var self = this;

    app.debug("inspect file: " + filename);

    self.filename = filename;
    self.extension = path.extname(filename).toLowerCase();
    self.src = fs.readFileSync(filename, "utf8").toString();
    app.debug("size: " + self.src.length);

    // Unify Linebreaks
    self.src = self.src.replace(/\r\n/g, "\n");

    self.blocks = [];
    self.indexApiBlocks = [];

    // Determine Blocks
    self.blocks = self._findBlocks();
    if(self.blocks.length === 0) return;
    app.debug("count blocks: " + self.blocks.length);

    // Determine Elements of Blocks
    self.elements = self.blocks.map(function(block, i){
        app.debug("count elements in block " + i + ": " + block.length);
        return self._findElements(block);
    });
    if(self.elements.length === 0) return;

    // Determine List of Blocks with API-Elements
    self.indexApiBlocks = self._findBlockWithApiGetIndex(self.elements);
    if(self.indexApiBlocks.length === 0) return;

    return self._parseBlockElements(self.indexApiBlocks, self.elements);
}; // parseFile

/**
 * Parse API Elements with Plugins
 *
 * @param indexApiBlocks
 * @param detectedElements
 * @returns {___anonymous2249_2250}
 */
Parser.prototype._parseBlockElements = function(indexApiBlocks, detectedElements)
{
	var self = this;
	var parsedBlocks = [];
	for(var i = 0; i < indexApiBlocks.length; i += 1)
	{
		var blockIndex = indexApiBlocks[i];
		var elements = detectedElements[blockIndex];
		var blockData = {
			global: {},
			local: {}
		};
		var preventGlobal = false;
		var countAllowedMultiple = 0;
		for(var j = 0; j < elements.length; j += 1)
		{
			var element = elements[j];
			if(self.parsers[element.name])
			{
				// Determine Fieldvalues
				var result = null;
				try {
					result = self.parsers[element.name].parse(element.content, element.source);

					// Markdown
					// TODO: Evaluate if better add a function in specific worker_{name}.js
					if(  result &&
                         app.options.marked.gfm &&
						 self.parsers[element.name].markdownFields &&
						 self.parsers[element.name].markdownFields.length > 0
					)
					{
						for(var markdownIndex = 0; markdownIndex < self.parsers[element.name].markdownFields.length; markdownIndex += 1)
						{
							var markdownField = self.parsers[element.name].markdownFields[markdownIndex];
							if(result[markdownField])
							{
								result[markdownField] = markdown(result[markdownField]);
								// remove line breaks.
								result[markdownField] = result[markdownField].replace(/(\r\n|\n|\r)/g, "");
							}
						} // for
					}
				}
				catch(e)
				{
					throw new Error("\"@" + element.sourceName + "\" in file \"" + self.filename +
						"\" block number " + (blockIndex + 1) + ", source \"" + element.source + "\" " + e
					);
				}

				if( ! result)
				{
					throw new Error("Empty parser result for \"@" + element.sourceName + "\" in file \"" + self.filename +
						"\" block number " + (blockIndex + 1) + ", source \"" + element.source + "\""
					);
				}

				// Check if it is allowed to add to global namespace.
				if(self.parsers[element.name].preventGlobal && self.parsers[element.name].preventGlobal === true)
				{
					preventGlobal = true;
					// Check if count global namespace entries > count allowed
					// (e.g. @successTitle is global, but should co-exist with @apiErrorStructure)
					if(Object.keys(blockData.global).length > countAllowedMultiple)
					{
						throw new Error("Can't set \"@" + element.sourceName + "\" in file \"" + self.filename +
							"\" block number " + (blockIndex + 1) + ", only one definition or use is allowed in the same block."
						);
					}
				}
				if(self.parsers[element.name].pushTo)
				{
					// Fieldvalues will be inserted into subpath
					var pushTo = self.parsers[element.name].pushTo();

					// Only one global allowed per block
					if(pushTo === "global" || pushTo.substr(0, 7) === "global.")
					{
						var allowMultiple = self.parsers[element.name].allowMultiple || false;

						if(allowMultiple)
						{
							countAllowedMultiple += 1;
						}
						else
						{
							if(Object.keys(blockData.global).length > 0)
							{
								throw new Error("Can't set \"@" + element.sourceName + "\" in file \"" + self.filename +
									"\" block number " + (blockIndex + 1) + ", only one definition per block allowed."
								);
							}

							if(preventGlobal === true)
							{
								throw new Error("Can't set \"@" + element.sourceName + "\" in file \"" + self.filename +
									"\" block number " + (blockIndex + 1) + ", only one definition or use is allowed in the same block."
								);
							}
						}
					}

					if( ! blockData[pushTo])
					{
						// Create path
						self._createObjectPath(blockData, pushTo);
					}

					var blockDataPath = _pathToObject(pushTo, blockData);

					// Insert Fieldvalues in Path-Array
					if(typeof(blockData[pushTo]) === "object")
					{
						_.extend(blockData[pushTo], result);
					}
					else
					{
						blockDataPath.push(result);
					}

					if(self.parsers[element.name].extendRoot === true)
					{
						// Insert Fieldvalues in Mainpath
						_.extend(blockData, result);
					}
				}
				else
				{
					// Insert Fieldvalues in Mainpath
					_.extend(blockData, result);
				}
				blockData.index = blockIndex + 1;
			}
			else
			{
				app.logWarn("parser plugin \"" + element.name + "\" not found.");
			}
		} // for
		parsedBlocks.push(blockData);
	} // for
	return parsedBlocks;
};

/**
 * Return Path to Object.
 */
function _pathToObject(path, src) {
	if( ! path) return src;
	var pathParts = path.split(".");
	var current = src;
	for(var i = 0; i < pathParts.length; i += 1)
	{
		var part = pathParts[i];
		current = current[part];
	} // for
  return current;
} // _pathToObject

/**
 * Create a not existing Path in an Object.
 *
 * @param src
 * @param path
 * @returns {Object}
 */
Parser.prototype._createObjectPath = function(src, path)
{
	if( ! path) return src;
	var pathParts = path.split(".");
	var current = src;
	for(var i = 0; i < pathParts.length; i += 1)
	{
		var part = pathParts[i];
		if( ! current[part])
		{
			if(i === (pathParts.length - 1) ) current[part] = [];
			else current[part] = {};
		}
		current = current[part];
	} // for
	return current;
}; // _createObjectPath

/**
 * Determine Blocks
 */
Parser.prototype._findBlocks = function()
{
    var self = this;
    var blocks = [];
    var src = self.src;

    // Replace Linebreak with Unicode
    src = src.replace(/\n/g, "\uffff");

    var regexs = {
        ".coffee": {
            // Find document blocks between "###" and "###"
            docBlocksRegExp: /###\uffff?(.+?)###/g,
            // Remove not needed "	" (tabs) at the beginning
            inlineRegExp: /^(\t+)?[ ]?/gm
        },
        ".erl": {
            // Find document blocks between "%{" and "%}"
            docBlocksRegExp: /\%+\{\uffff?(.+?)\%+\}/g,
            // Remove not needed " % " and "	" (tabs) at the beginning
            // HINT: Not sure if erlang developer use the %, but i think it should be no problem
            inlineRegExp: /^(\t+)?(\%+)[ ]?/gm
        },
        ".py": {
            // Find document blocks between """ and """
            docBlocksRegExp: /\"\"\"\uffff?(.+?)\"\"\"/g,
            // Remove not needed "	" (tabs) at the beginning
            inlineRegExp: /^(\t+)?[ ]?/gm
        },
        ".rb": {
            // Find document blocks between "=begin" and "=end"
            docBlocksRegExp: /\=begin\uffff?(.+?)\=end/g,
            // Remove not needed "	" (tabs) at the beginning
            inlineRegExp: /^(\t+)?[ ]?/gm
        },
        ".pm": {
            // Find document blocks between "#**" and "#*"
            // or between "=pod" and "=cut"
            docBlocksRegExp: /#\*\*\uffff?(.+?)#\*|=pod\uffff?(.+?)=cut/g,
            // Remove not needed " # " and "    " (tabs) at the beginning
            inlineRegExp: /^(\s+)?(#)[ ]?/gm
        },
        "default": {
            // Find document blocks between "#**" and "#*"
            docBlocksRegExp: /\/\*\*\uffff?(.+?)\*\//g,
            // Remove not needed " # " and "	" (tabs) at the beginning
            inlineRegExp: /^(\s+)?(\*)[ ]?/gm
        }
    };
    var regexForFile = regexs[self.extension] || regexs["default"];
    var matches = regexForFile.docBlocksRegExp.exec(src);
    while(matches)
    {
        var block = matches[2] || matches[1];

        // Reverse Unicode Linebreaks
        block = block.replace(/\uffff/g, "\n");

        block = block.replace(regexForFile.inlineRegExp, "");

        blocks.push(block);

        // Find next
        matches = regexForFile.docBlocksRegExp.exec(src);
    } // while
    return blocks;

}; // _findBlocks

/**
 * Check if block has API elements and return block indexes.
 */
Parser.prototype._findBlockWithApiGetIndex = function(blocks)
{
    var foundIndexes = [];
    blocks.forEach(function(block, i){
        var add;
        block.forEach(function(element)
        {
            if(add !== false){
                add = element.name.substr(0, 3) === "api" && element.name.substr(0, 9) !== "apiignore";
            }
        });
        if(add)
        {
            foundIndexes.push(i);
            app.debug("api found in block: " + i);
        }
    });
    return foundIndexes;
}; // _findBlockWithApiGetIndex

/**
 * Get Elements of Blocks.
 */
Parser.prototype._findElements = function(block)
{
	var self = this;
	var elements = [];

	// Replace Linebreak with Unicode
	block = block.replace(/\n/g, "\uffff");

	// Elements start with @
	var elementsRegExp = /(@(\w*)\s?(.+?)(?=\uffff[\s\*]*@|$))/gm;
	var matches = elementsRegExp.exec(block);
	while(matches)
	{
		var element = {
			source: matches[1],
			name: matches[2].toLowerCase(),
			sourceName: matches[2],
			content: matches[3]
		};

		// Reverse Unicode Linebreaks
		element.content = element.content.replace(/\uffff/g, "\n");
		element.source = element.source.replace(/\uffff/g, "\n");

		elements.push(element);

		// Next Match
		matches = elementsRegExp.exec(block);
	}
	return elements;
}; // _findElements
<|endoftext|>