<commit_before>// A constant empty array (frozen if the JS engine supports it).
var _emptyArray = Object.freeze ? Object.freeze([]) : [];

// `[new] Blaze.DOMRange([nodeAndRangeArray])`
//
// A DOMRange consists of an array of consecutive nodes and DOMRanges,
// which may be replaced at any time with a new array.  If the DOMRange
// has been attached to the DOM at some location, then updating
// the array will cause the DOM to be updated at that location.
Blaze.DOMRange = function (nodeAndRangeArray) {
  if (! (this instanceof Blaze.DOMRange))
    // called without `new`
    return new Blaze.DOMRange(nodeAndRangeArray);

  var members = (nodeAndRangeArray || _emptyArray);
  if (! (members && (typeof members.length) === 'number'))
    throw new Error("Expected array");

  for (var i = 0; i < members.length; i++)
    this._memberIn(members[i]);

  this.members = members;
  this.placeholderComment = null;
  this.attached = false;
  this.parentElement = null;
  this.parentRange = null;
  this.stopCallbacks = _emptyArray;
};

// static methods
_.extend(Blaze.DOMRange, {
  attach: function (rangeOrNode, parentElement, nextNode) {
    var m = rangeOrNode;
    if (m instanceof Blaze.DOMRange) {
      m.attach(parentElement, nextNode);
    } else {
      parentElement.insertBefore(m, nextNode || null);
    }
  },
  detach: function (rangeOrNode) {
    var m = rangeOrNode;
    if (m instanceof Blaze.DOMRange) {
      m.detach();
    } else {
      m.parentNode.removeChild(m);
    }
  },
  firstNode: function (rangeOrNode) {
    var m = rangeOrNode;
    return (m instanceof Blaze.DOMRange) ? m.firstNode() : m;
  },
  lastNode: function (rangeOrNode) {
    var m = rangeOrNode;
    return (m instanceof Blaze.DOMRange) ? m.lastNode() : m;
  }
});

_.extend(Blaze.DOMRange.prototype, {
  attach: function (parentElement, nextNode) {
    // This method is called to insert the DOMRange into the DOM for
    // the first time, but it's also used internally when
    // updating the DOM.
    var members = this.members;
    if (members.length) {
      this.placeholderComment = null;
      for (var i = 0; i < members.length; i++) {
        Blaze.DOMRange.attach(members[i], parentElement, nextNode);
      }
    } else {
      var comment = document.createComment("empty");
      this.placeholderComment = comment;
      parentElement.insertBefore(comment, nextNode || null);
    }
    this.attached = true;
    this.parentElement = parentElement;
  },
  setMembers: function (newNodeAndRangeArray) {
    var newMembers = newNodeAndRangeArray;
    if (! (newMembers && (typeof newMembers.length) === 'number'))
      throw new Error("Expected array");

    var oldMembers = this.members;

    for (var i = 0; i < oldMembers.length; i++)
      this._memberOut(oldMembers[i]);
    for (var i = 0; i < newMembers.length; i++)
      this._memberIn(newMembers[i]);

    if (! this.attached) {
      this.members = newMembers;
    } else {
      // don't do anything if we're going from empty to empty
      if (newMembers.length || oldMembers.length) {
        // detach the old members and insert the new members
        var nextNode = this.lastNode().nextSibling;
        var parentElement = this.parentElement;
        this.detach();
        this.members = newMembers;
        this.attach(parentElement, nextNode);
      }
    }
  },
  firstNode: function () {
    if (! this.attached)
      throw new Error("Must be attached");

    if (! this.members.length)
      return this.placeholderComment;

    var m = this.members[0];
    return (m instanceof Blaze.DOMRange) ? m.firstNode() : m;
  },
  lastNode: function () {
    if (! this.attached)
      throw new Error("Must be attached");

    if (! this.members.length)
      return this.placeholderComment;

    var m = this.members[this.members.length - 1];
    return (m instanceof Blaze.DOMRange) ? m.lastNode() : m;
  },
  detach: function () {
    if (! this.attached)
      throw new Error("Must be attached");

    var members = this.members;
    if (members.length) {
      for (var i = 0; i < members.length; i++) {
        Blaze.DOMRange.detach(members[i]);
      }
    } else {
      var comment = this.placeholderComment;
      this.parentElement.removeChild(comment);
      this.placeholderComment = null;
    }
    this.attached = false;
    this.parentElement = null;
  },
  addMember: function (newMember, atIndex) {
    var members = this.members;
    if (! (atIndex >= 0 && atIndex <= members.length))
      throw new Error("Bad index in range.addMember: " + atIndex);

    this._memberIn(newMember);

    if (! this.attached) {
      // currently detached; just updated members
      members.splice(atIndex, 0, newMember);
    } else if (members.length === 0) {
      // empty; use the empty-to-nonempty handling of setMembers
      this.setMembers([newMember]);
    } else {
      var nextNode;
      if (atIndex === members.length) {
        // insert at end
        nextNode = this.lastNode().nextSibling;
      } else {
        nextNode = Blaze.DOMRange.firstNode(members[atIndex]);
      }
      members.splice(atIndex, 0, newMember);
      Blaze.DOMRange.attach(newMember, this.parentElement, nextNode);
    }
  },
  removeMember: function (atIndex) {
    var members = this.members;
    if (! (atIndex >= 0 && atIndex < members.length))
      throw new Error("Bad index in range.removeMember: " + atIndex);

    var oldMember = members[atIndex];
    this._memberOut(oldMember);

    if (members.length === 1) {
      // becoming empty; use the logic in setMembers
      this.setMembers(_emptyArray);
    } else {
      members.splice(atIndex, 1);
      if (this.attached)
        Blaze.DOMRange.detach(oldMember);
    }
  },
  getMember: function (atIndex) {
    var members = this.members;
    if (! (atIndex >= 0 && atIndex < members.length))
      throw new Error("Bad index in range.getMember: " + atIndex);
    return this.members[atIndex];
  },
  stop: function () {
    var stopCallbacks = this.stopCallbacks;
    for (var i = 0; i < stopCallbacks.length; i++)
      stopCallbacks[i].call(this);
    this.stopCallbacks = _emptyArray;
  },
  onstop: function (cb) {
    if (this.stopCallbacks === _emptyArray)
      this.stopCallbacks = [];
    this.stopCallbacks.push(cb);
  },
  _memberIn: function (m) {
    if (m instanceof Blaze.DOMRange)
      m.parentRange = this;
    else if (m.nodeType === 1) // DOM Element
      m.$blaze_range = this;
  },
  _memberOut: function (m) {
    // old members are almost always GCed immediately.
    // to avoid the potentialy performance hit of deleting
    // a property, we simple null it out.
    if (m instanceof Blaze.DOMRange)
      m.parentRange = null;
    else if (m.nodeType === 1) // DOM Element
      m.$blaze_range = null;
  },
  containsElement: function (elem) {
    if (! this.attached)
      throw new Error("Must be attached");

    // An element is contained in this DOMRange if it's possible to
    // reach it by walking parent pointers, first through the DOM and
    // then parentRange pointers.  In other words, the element or some
    // ancestor of it is at our level of the DOM (a child of our
    // parentElement), and this element is one of our members or
    // is a member of a descendant Range.

    if (! Blaze._elementContains(this.parentElement, elem))
      return false;

    while (elem.parentNode !== this.parentElement)
      elem = elem.parentElement;

    var range = elem.$blaze_range;
    while (range && range !== this)
      range = range.parentRange;

    return range === this;
  },
  containsRange: function (range) {
    if (! this.attached)
      throw new Error("Must be attached");

    if (! range.attached)
      return false;

    // A DOMRange is contained in this DOMRange if it's possible
    // to reach this range by following parent pointers.  If the
    // DOMRange has the same parentElement, then it should be
    // a member, or a member of a member etc.  Otherwise, we must
    // contain its parentElement.

    if (range.parentElement !== this.parentElement)
      return this.containsElement(range.parentElement);

    if (range === this)
      return false; // don't contain self

    while (range && range !== this)
      range = range.parentRange;

    return range === this;
  }
});

// Returns true if element a contains node b and is not node b.
//
// The restriction that `a` be an element (not a document fragment,
// say) is based on what's easy to implement cross-browser.
Blaze._elementContains = function (a, b) {
  if (a.nodeType !== 1) // ELEMENT
    return false;
  if (a === b)
    return false;

  if (a.compareDocumentPosition) {
    return a.compareDocumentPosition(b) & 0x10;
  } else {
    // Should be only old IE and maybe other old browsers here.
    // Modern Safari has both functions but seems to get contains() wrong.
    // IE can't handle b being a text node.  We work around this
    // by doing a direct parent test now.
    b = b.parentNode;
    if (! (b && b.nodeType === 1)) // ELEMENT
      return false;
    if (a === b)
      return true;

    return a.contains(b);
  }
};<commit_msg>Start of connecting events to new DOMRange<commit_after>// A constant empty array (frozen if the JS engine supports it).
var _emptyArray = Object.freeze ? Object.freeze([]) : [];

// `[new] Blaze.DOMRange([nodeAndRangeArray])`
//
// A DOMRange consists of an array of consecutive nodes and DOMRanges,
// which may be replaced at any time with a new array.  If the DOMRange
// has been attached to the DOM at some location, then updating
// the array will cause the DOM to be updated at that location.
Blaze.DOMRange = function (nodeAndRangeArray) {
  if (! (this instanceof Blaze.DOMRange))
    // called without `new`
    return new Blaze.DOMRange(nodeAndRangeArray);

  var members = (nodeAndRangeArray || _emptyArray);
  if (! (members && (typeof members.length) === 'number'))
    throw new Error("Expected array");

  for (var i = 0; i < members.length; i++)
    this._memberIn(members[i]);

  this.members = members;
  this.placeholderComment = null;
  this.attached = false;
  this.parentElement = null;
  this.parentRange = null;
  this.stopCallbacks = _emptyArray;
  this.augmenters = _emptyArray;
};

// static methods
_.extend(Blaze.DOMRange, {
  attach: function (rangeOrNode, parentElement, nextNode) {
    var m = rangeOrNode;
    if (m instanceof Blaze.DOMRange) {
      m.attach(parentElement, nextNode);
    } else {
      parentElement.insertBefore(m, nextNode || null);
    }
  },
  detach: function (rangeOrNode) {
    var m = rangeOrNode;
    if (m instanceof Blaze.DOMRange) {
      m.detach();
    } else {
      m.parentNode.removeChild(m);
    }
  },
  firstNode: function (rangeOrNode) {
    var m = rangeOrNode;
    return (m instanceof Blaze.DOMRange) ? m.firstNode() : m;
  },
  lastNode: function (rangeOrNode) {
    var m = rangeOrNode;
    return (m instanceof Blaze.DOMRange) ? m.lastNode() : m;
  }
});

_.extend(Blaze.DOMRange.prototype, {
  attach: function (parentElement, nextNode) {
    // This method is called to insert the DOMRange into the DOM for
    // the first time, but it's also used internally when
    // updating the DOM.
    var members = this.members;
    if (members.length) {
      this.placeholderComment = null;
      for (var i = 0; i < members.length; i++) {
        Blaze.DOMRange.attach(members[i], parentElement, nextNode);
      }
    } else {
      var comment = document.createComment("empty");
      this.placeholderComment = comment;
      parentElement.insertBefore(comment, nextNode || null);
    }
    this.attached = true;
    this.parentElement = parentElement;

    for(var i = 0; i < this.augmenters.length; i++)
      this.augmenters[i].attach(parentElement);
  },
  setMembers: function (newNodeAndRangeArray) {
    var newMembers = newNodeAndRangeArray;
    if (! (newMembers && (typeof newMembers.length) === 'number'))
      throw new Error("Expected array");

    var oldMembers = this.members;

    for (var i = 0; i < oldMembers.length; i++)
      this._memberOut(oldMembers[i]);
    for (var i = 0; i < newMembers.length; i++)
      this._memberIn(newMembers[i]);

    if (! this.attached) {
      this.members = newMembers;
    } else {
      // don't do anything if we're going from empty to empty
      if (newMembers.length || oldMembers.length) {
        // detach the old members and insert the new members
        var nextNode = this.lastNode().nextSibling;
        var parentElement = this.parentElement;
        this.detach();
        this.members = newMembers;
        this.attach(parentElement, nextNode);
      }
    }
  },
  firstNode: function () {
    if (! this.attached)
      throw new Error("Must be attached");

    if (! this.members.length)
      return this.placeholderComment;

    var m = this.members[0];
    return (m instanceof Blaze.DOMRange) ? m.firstNode() : m;
  },
  lastNode: function () {
    if (! this.attached)
      throw new Error("Must be attached");

    if (! this.members.length)
      return this.placeholderComment;

    var m = this.members[this.members.length - 1];
    return (m instanceof Blaze.DOMRange) ? m.lastNode() : m;
  },
  detach: function () {
    if (! this.attached)
      throw new Error("Must be attached");

    var members = this.members;
    if (members.length) {
      for (var i = 0; i < members.length; i++) {
        Blaze.DOMRange.detach(members[i]);
      }
    } else {
      var comment = this.placeholderComment;
      this.parentElement.removeChild(comment);
      this.placeholderComment = null;
    }
    this.attached = false;
    this.parentElement = null;

    for(var i = 0; i < this.augmenters.length; i++)
      this.augmenters[i].detach();
  },
  addMember: function (newMember, atIndex) {
    var members = this.members;
    if (! (atIndex >= 0 && atIndex <= members.length))
      throw new Error("Bad index in range.addMember: " + atIndex);

    this._memberIn(newMember);

    if (! this.attached) {
      // currently detached; just updated members
      members.splice(atIndex, 0, newMember);
    } else if (members.length === 0) {
      // empty; use the empty-to-nonempty handling of setMembers
      this.setMembers([newMember]);
    } else {
      var nextNode;
      if (atIndex === members.length) {
        // insert at end
        nextNode = this.lastNode().nextSibling;
      } else {
        nextNode = Blaze.DOMRange.firstNode(members[atIndex]);
      }
      members.splice(atIndex, 0, newMember);
      Blaze.DOMRange.attach(newMember, this.parentElement, nextNode);
    }
  },
  removeMember: function (atIndex) {
    var members = this.members;
    if (! (atIndex >= 0 && atIndex < members.length))
      throw new Error("Bad index in range.removeMember: " + atIndex);

    var oldMember = members[atIndex];
    this._memberOut(oldMember);

    if (members.length === 1) {
      // becoming empty; use the logic in setMembers
      this.setMembers(_emptyArray);
    } else {
      members.splice(atIndex, 1);
      if (this.attached)
        Blaze.DOMRange.detach(oldMember);
    }
  },
  getMember: function (atIndex) {
    var members = this.members;
    if (! (atIndex >= 0 && atIndex < members.length))
      throw new Error("Bad index in range.getMember: " + atIndex);
    return this.members[atIndex];
  },
  stop: function () {
    var stopCallbacks = this.stopCallbacks;
    for (var i = 0; i < stopCallbacks.length; i++)
      stopCallbacks[i].call(this);
    this.stopCallbacks = _emptyArray;
  },
  onstop: function (cb) {
    if (this.stopCallbacks === _emptyArray)
      this.stopCallbacks = [];
    this.stopCallbacks.push(cb);
  },
  _memberIn: function (m) {
    if (m instanceof Blaze.DOMRange)
      m.parentRange = this;
    else if (m.nodeType === 1) // DOM Element
      m.$blaze_range = this;
  },
  _memberOut: function (m) {
    // old members are almost always GCed immediately.
    // to avoid the potentialy performance hit of deleting
    // a property, we simple null it out.
    if (m instanceof Blaze.DOMRange)
      m.parentRange = null;
    else if (m.nodeType === 1) // DOM Element
      m.$blaze_range = null;
  },
  containsElement: function (elem) {
    if (! this.attached)
      throw new Error("Must be attached");

    // An element is contained in this DOMRange if it's possible to
    // reach it by walking parent pointers, first through the DOM and
    // then parentRange pointers.  In other words, the element or some
    // ancestor of it is at our level of the DOM (a child of our
    // parentElement), and this element is one of our members or
    // is a member of a descendant Range.

    if (! Blaze._elementContains(this.parentElement, elem))
      return false;

    while (elem.parentNode !== this.parentElement)
      elem = elem.parentElement;

    var range = elem.$blaze_range;
    while (range && range !== this)
      range = range.parentRange;

    return range === this;
  },
  containsRange: function (range) {
    if (! this.attached)
      throw new Error("Must be attached");

    if (! range.attached)
      return false;

    // A DOMRange is contained in this DOMRange if it's possible
    // to reach this range by following parent pointers.  If the
    // DOMRange has the same parentElement, then it should be
    // a member, or a member of a member etc.  Otherwise, we must
    // contain its parentElement.

    if (range.parentElement !== this.parentElement)
      return this.containsElement(range.parentElement);

    if (range === this)
      return false; // don't contain self

    while (range && range !== this)
      range = range.parentRange;

    return range === this;
  },
  addDOMAugmenter: function (augmenter) {
    if (this.augmenters === _emptyArray)
      this.augmenters = [];
    this.augmenters.push(augmenter);
  }
});

Blaze.DOMAugmenter = function () {};
_.extend(Blaze.DOMAugmenter, {
  attach: function (element) {},
  detach: function () {}
});

Blaze.EventAugmenter = function (eventMap) {
  this.eventMap = eventMap;
};
Blaze.EventAugmenter.prototype = new Blaze.DOMAugmenter;
_.extend(Blaze.EventAugmenter.prototype, {
  attach: function (element) {
    // XXX TODO
  },
  detach: function () {
    // XXX TODO
  }
});

// Returns true if element a contains node b and is not node b.
//
// The restriction that `a` be an element (not a document fragment,
// say) is based on what's easy to implement cross-browser.
Blaze._elementContains = function (a, b) {
  if (a.nodeType !== 1) // ELEMENT
    return false;
  if (a === b)
    return false;

  if (a.compareDocumentPosition) {
    return a.compareDocumentPosition(b) & 0x10;
  } else {
    // Should be only old IE and maybe other old browsers here.
    // Modern Safari has both functions but seems to get contains() wrong.
    // IE can't handle b being a text node.  We work around this
    // by doing a direct parent test now.
    b = b.parentNode;
    if (! (b && b.nodeType === 1)) // ELEMENT
      return false;
    if (a === b)
      return true;

    return a.contains(b);
  }
};<|endoftext|>


<commit_before>// Simple Swarm sync server: picks model classes from a directory,
// starts a WebSocket server at a port. Serves some static content,
// although I'd recomment to shield it with nginx.
var fs = require('fs');
var path = require('path');
var url = require('url');
var http = require('http');

var nopt = require('nopt');
var koa = require('koa');
var ws_lib = require('ws');

var Swarm = require('./lib/NodeServer.js');
var EinarosWSStream = require('./lib/EinarosWSStream');

var app = koa();

var options = nopt({
    models : path,
    port : Number
});

var koa_static = require('koa-static-cache');
app.use(koa_static('.'));

// boot model classes
var modelPathList = options.models||'model/';
modelPathList.split(/[\:;,]/g).forEach(function (modelPath) {
    modelPath = path.resolve(modelPath);
    console.log('scanning',modelPath);
    var modelClasses = fs.readdirSync(modelPath), modelFile;
    while (modelFile = modelClasses.pop()) {
        if (!/^\w+\.js$/.test(modelFile)) continue;
        var modpath = path.join(modelPath, modelFile);
        console.log('Loading model file', modpath);
        var mod = require(modpath);
        for (var item in mod) {
            var fn = mod[item];
            console.log('checking',item);
            if (fn.constructor !== Function) continue;
            console.log('...');
            if (fn.extend !== Swarm.Syncable.extend) continue;
            console.log('\tmodel class found:\t', item);
        }
    }
});

// use file storage
var fileStorage = new Swarm.FileStorage('.swarm');

// create Swarm Host
var swarmHost = new Swarm.Host('swarm~nodejs', 0, fileStorage);
Swarm.localhost = swarmHost;

// start the HTTP server
var port = options.port || 8000;
var httpServer = http.createServer(app.callback()).listen(port);
console.log('Swarm server started port',port);

// start WebSocket server
var wsServer = new ws_lib.Server({
    server: httpServer
});

// add pipes
wsServer.on('connection', function(ws) {
    var params = url.parse(ws.upgradeReq.url,true);
    console.log('incomingWS %s', params.path);
    // check the secret
    // FIXME grant ssn
    swarmHost.accept(new EinarosWSStream(ws), { delay: 50 });
});

// TODO pexing
<commit_msg>fix: model loading commonjs'ed<commit_after>// Simple Swarm sync server: picks model classes from a directory,
// starts a WebSocket server at a port. Serves some static content,
// although I'd recomment to shield it with nginx.
var fs = require('fs');
var path = require('path');
var url = require('url');
var http = require('http');

var nopt = require('nopt');
var koa = require('koa');
var ws_lib = require('ws');

var Swarm = require('./lib/NodeServer.js');
var EinarosWSStream = require('./lib/EinarosWSStream');

var app = koa();

var options = nopt({
    models : path,
    port : Number
});

var koa_static = require('koa-static-cache');
app.use(koa_static('.'));

// boot model classes
var modelPathList = options.models||'model/';
modelPathList.split(/[\:;,]/g).forEach(function (modelPath) {
    modelPath = path.resolve(modelPath);
    console.log('scanning',modelPath);
    var modelClasses = fs.readdirSync(modelPath), modelFile;
    while (modelFile = modelClasses.pop()) {
        if (!/^\w+\.js$/.test(modelFile)) continue;
        var modpath = path.join(modelPath, modelFile);
        var fn = require(modpath);
        if (fn.constructor !== Function) continue;
        if (fn.extend !== Swarm.Syncable.extend) continue;
        console.log('Model loaded', fn.prototype._type, ' at ', modpath);
    }
});

// use file storage
var fileStorage = new Swarm.FileStorage('.swarm');

// create Swarm Host
var swarmHost = new Swarm.Host('swarm~nodejs', 0, fileStorage);
Swarm.localhost = swarmHost;

// start the HTTP server
var port = options.port || 8000;
var httpServer = http.createServer(app.callback()).listen(port);
console.log('Swarm server started port',port);

// start WebSocket server
var wsServer = new ws_lib.Server({
    server: httpServer
});

// add pipes
wsServer.on('connection', function(ws) {
    var params = url.parse(ws.upgradeReq.url,true);
    console.log('incomingWS %s', params.path);
    // check the secret
    // FIXME grant ssn
    swarmHost.accept(new EinarosWSStream(ws), { delay: 50 });
});

// TODO pexing
<|endoftext|>


<commit_before>/**
 * Created by Brandon on 2017-03-25.
 */

var request = require('request');
var fs = require('fs');

var url = 'https://www.padherder.com/'

// Make's an GET request to url and get a lit of monsters
function getUSmonsters(getEvolutions) {
    request(url + 'api/monsters/', function (err, res, body) {
        if (err) console.log("ERROR ", err);
        var response = JSON.parse(body);

        var NAmonsters = [];

        response.forEach(function (monster) {
            if (!monster.jp_only) {
                NAmonsters.push(monster);
            };
        })

        if (NAmonsters) getEvolutions(NAmonsters);
        else console.log("ERROR no monsters found!")
    });
}

function getEvolutions(NAmonsters) {
    request(url + 'api/evolutions/', function (err, res, body) {
        if (err) console.log("ERROR ", err);
        var response = JSON.parse(body);
       if (response) store(response,NAmonsters);
        console.log("Got evolutions")
    });
}

function store(evolutions,NAmonsters){

    NAmonsters.forEach(function(monster){
        var m = {
            name : monster.name,
            id : monster.id.toString(),
            materials : {}
        }
    });

    var materials = {};
    getAllMats('3266',evolutions,materials)

    console.log(materials)
    console.log("Stored")
}

function getAllMats(id,evoMats,materials) {

    // Check if this is the most basic stage
    // if so, end search
    if (evoMats[id] == undefined) return;

    var idEvoMat = evoMats[id][0].materials;
    var evoFrom = evoMats[id][0].evolves_to;

    // Check if there's no evolution available,
    // if not, end search
    if (idEvoMat == undefined) return;

    // If this is not the most basic evolution, recursively call
    // getAllMats on the previous stage of evolution
    if (canUnEvo(idEvoMat)) {
        getAllMats(evoFrom,evoMats,materials)
    }

    //if (evoMats[evoFrom] == undefined) return;

    // if there's more than one path, search for the one
    // that leads to the desired stage, then set IdEvoMat as that
    evoMats[evoFrom].forEach(function(mat){
        if (mat.evolves_to == id){
            idEvoMat = mat.materials
        }
    });

    // Look for the materials required for the current level to
    // reach the desired level
    idEvoMat.forEach(function (mat) {
        if (materials[mat[0]] == undefined) materials[mat[0]] = mat[1];
        else materials[mat[0]] = materials[mat[0]] + mat[1];
        getAllMats(mat[0], evoMats, materials)
    });

}

function canUnEvo(materials){
    // Compare each material to check if there is a path that leads to
    // the current node
    return materials[0][0] == 155 && materials[1][0] == 156 && materials[2][0] == 157
        materials[3][0] == 158 && materials[4][0] == 159 ;
}

// used to download images of all evolution materials
var download = function(uri, filename, callback){
    var path = "./public/images/";

    request.head(uri, function(err, res, body){
        console.log('content-type:', res.headers['content-type']);
        console.log('content-length:', res.headers['content-length']);
        request(uri).pipe(fs.createWriteStream(path+filename)).on('close', callback);
    });
};

/*
download( url + '/static/img/monsters/40x40/1087.86c7840800d0.png', 'google.png', function(){
    console.log('done');
});
*/

getUSmonsters(getEvolutions)<commit_msg>fixed error, can parse monsters with single evolutions<commit_after>/**
 * Created by Brandon on 2017-03-25.
 */

var request = require('request');
var fs = require('fs');

var url = 'https://www.padherder.com/'

// Make's an GET request to url and get a lit of monsters
function getUSmonsters(getEvolutions) {
    request(url + 'api/monsters/', function (err, res, body) {
        if (err) console.log("ERROR ", err);
        var response = JSON.parse(body);

        var NAmonsters = [];

        response.forEach(function (monster) {
            if (!monster.jp_only) {
                NAmonsters.push(monster);
            };
        })

        if (NAmonsters) getEvolutions(NAmonsters);
        else console.log("ERROR no monsters found!")
    });
}

function getEvolutions(NAmonsters) {
    request(url + 'api/evolutions/', function (err, res, body) {
        if (err) console.log("ERROR ", err);
        var response = JSON.parse(body);
       if (response) store(response,NAmonsters);
        console.log("Got evolutions")
    });
}

function store(evolutions,NAmonsters){

    NAmonsters.forEach(function(monster){
        var m = {
            name : monster.name,
            id : monster.id.toString(),
        }
    });

    var materials = {};
    getAllMats('3266',evolutions,materials)

    console.log(materials)
    console.log("Stored")
}

function getAllMats(id,evolutions,materials) {

    // Check if this is the most basic stage
    // if so, end search
    if (evolutions[id] == undefined) {
        cantUnEvo(id,evolutions,materials)
        return;
    }

    var idEvoMat = evolutions[id][0].materials;
    var evoFrom = evolutions[id][0].evolves_to;

    // Check if there's no evolution available,
    // if not, end search
    if (idEvoMat == undefined) return;

    // If this is not the most basic evolution, recursively call
    // getAllMats on the previous stage of evolution
    if (canUnEvo(idEvoMat)) {

        getAllMats(evoFrom,evolutions,materials)

        // if there's more than one path, search for the one
        // that leads to the desired stage, then set IdEvoMat as that
        evolutions[evoFrom].forEach(function(mat){
            if (mat.evolves_to == id){
                idEvoMat = mat.materials
            }
        });

        // Look for the materials required for the current level to
        // reach the desired level
        idEvoMat.forEach(function (mat) {
            if (materials[mat[0]] == undefined) materials[mat[0]] = mat[1];
            else materials[mat[0]] = materials[mat[0]] + mat[1];
            getAllMats(mat[0], evolutions, materials)
        });

    } else {
        if (materials[id] == undefined) materials[id] = 1;
        else materials[id] = materials[id] + 1;
    }

}

function canUnEvo(materials){
    // Compare each material to check if there is a path that leads to
    // the current node
    return materials[0][0] == 155 && materials[1][0] == 156 && materials[2][0] == 157
        materials[3][0] == 158 && materials[4][0] == 159 ;
}

function cantUnEvo(id,evolutions,materials){

    Object.keys(evolutions).forEach(function (key) {
        var val = evolutions[key][0];

        if (val != undefined && val.evolves_to == id) {
            val.materials.forEach(function (mat) {
                if (materials[mat[0]] == undefined) materials[mat[0]] = mat[1];
                else materials[mat[0]] = materials[mat[0]] + mat[1];
            });
        }

    });
}

// used to download images of all evolution materials
var download = function(uri, filename, callback){
    var path = "./public/images/";

    request.head(uri, function(err, res, body){
        console.log('content-type:', res.headers['content-type']);
        console.log('content-length:', res.headers['content-length']);
        request(uri).pipe(fs.createWriteStream(path+filename)).on('close', callback);
    });
};

/*
download( url + '/static/img/monsters/40x40/1087.86c7840800d0.png', 'google.png', function(){
    console.log('done');
});
*/

getUSmonsters(getEvolutions)<|endoftext|>


<commit_before>/**
 * Configure app in a block instead of hard-coding values inside the scripts.
 */
var config = {
    //domain: 'http://localhost:63342/FeatureScapeApps',
    domain: '/featurescapeapps',
    quipUrl: '/camicroscope/osdCamicroscope.php',
    //reserve4Url: 'http://reserve4.informatics.stonybrook.edu/dev1/osdCamicroscope.php',
    imgcoll: 'images',
    quot: "%22",
    iiifServer: location.hostname,
    iiifPrefix: 'fcgi-bin/iipsrv.fcgi?iiif=',
    default_execution_id: 'tahsin-test-1',
    default_db: 'u24_luad',
    default_subject_id: 'TCGA-05-4396',
    default_case_id: 'TCGA-05-4396-01Z-00-DX1'
};
<commit_msg>Change quipUrl to camicroscopeDS<commit_after>/**
 * Configure app in a block instead of hard-coding values inside the scripts.
 */
var config = {
    //domain: 'http://localhost:63342/FeatureScapeApps',
    domain: '/featurescapeapps',
    quipUrl: '/camicroscopeDS/osdCamicroscope.php',
    //reserve4Url: 'http://reserve4.informatics.stonybrook.edu/dev1/osdCamicroscope.php',
    imgcoll: 'images',
    quot: "%22",
    iiifServer: location.hostname,
    iiifPrefix: 'fcgi-bin/iipsrv.fcgi?iiif=',
    default_execution_id: 'tahsin-test-1',
    default_db: 'u24_luad',
    default_subject_id: 'TCGA-05-4396',
    default_case_id: 'TCGA-05-4396-01Z-00-DX1'
};
<|endoftext|>


<commit_before>'use strict';
/* jshint node: true */
/* jshint esnext: true */
/* global jasmine, describe, it, expect, beforeEach, afterAll, spyOn */

const mockery = require('mockery');

describe('pdfGeneration', () => {

  let pdfGeneration, documentMock, qrCodeMock;
  let startNumberData;

  beforeEach(() => {

    mockery.enable({
      useCleanCache: true,
      warnOnReplace: false,
      warnOnUnregistered: false
    });

    mockery.resetCache();

    documentMock = {
      pipe: jasmine.createSpy('pipe'),
      fontSize: function () {
        return documentMock;
      },
      font: function () {
        return documentMock;
      },
      fillColor: function () {
        return documentMock;
      },
      text: jasmine.createSpy('text'),
      scale: function () {
        return documentMock;
      },
      translate: function () {
        return documentMock;
      },
      path: function () {
        return documentMock;
      },
      lineWidth: function () {
        return documentMock;
      },
      stroke: jasmine.createSpy('stroke'),
      addPage: jasmine.createSpy('addPage'),
      image: jasmine.createSpy('image'),
      fill: jasmine.createSpy('fill'),
      end: jasmine.createSpy('end')
    };

    qrCodeMock = {
      svgObject: () => {
        return qrCodeMock;
      },
      path: jasmine.createSpy('path')
    };

    mockery.registerMock('qr-image', qrCodeMock);

    pdfGeneration = require('../../pdf/pdfGeneration');

    startNumberData = {
      startNumber: '1234',
      firstname: 'Digital',
      team: 'Unicorns',
      startBlock: '1',
      startBlockColor: '#123456',
      tshirt: {
        size: 'S',
        model: 'unisex'
      },
      hasPayed: true,
      onSiteRegistration: false,
      secureUrl: 'https://example.com/asjkd12234'
    };

    qrCodeMock.path.and.returnValue('some qr code path');
  });

  afterAll(() => {
    mockery.deregisterAll();
    mockery.disable();
  });

  describe('createStartNumberPage', () => {
    it('should add the barcode three times for easier scanning', () => {
      let numberOfOtherImageCalls = 3;

      pdfGeneration.createStartNumberPage(documentMock, startNumberData);
      expect(documentMock.image).toHaveBeenCalledTimes(3 + numberOfOtherImageCalls);
    });

    it('should add the background image and the logos', () => {
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.image.calls.argsFor(0)[0]).toMatch(/pdf\/images\/background_light\.jpg/);
      expect(documentMock.image.calls.argsFor(1)[0]).toMatch(/pdf\/images\/lauf_gegen_rechts_logo\.jpg/);
      expect(documentMock.image.calls.argsFor(2)[0]).toMatch(/pdf\/images\/fc_st_pauli_marathon_logo\.png/);
    });

    it('should add tshirt details', () => {
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.text.calls.argsFor(4)).toEqual(['S unisex', 500, 315]);
    });

    it('should add a checkmark symbol only if the participant has payed', () => {
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.stroke).toHaveBeenCalledTimes(1);
    });

    it('should add start number and name', () => {
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.text.calls.argsFor(0)).toEqual(['1234', 0, 130, {align: 'center'}]);
      expect(documentMock.text.calls.argsFor(1)).toEqual(['Digital', 0, 300, {align: 'center'}]);
    });

    it('should add the team name if it exits', () => {
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.text.calls.argsFor(2)).toEqual(['Unicorns', 0, 350, {align: 'center'}]);
    });

    it('should add the startblock', () => {
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.text.calls.argsFor(3)).toEqual(['Startblock: 1', 20, 150, {align: 'left'}]);
    });

    it('should add the QR code to the self-service link', () => {
      startNumberData.onSiteRegistration = true;
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.fill).toHaveBeenCalledWith('black', 'even-odd');
    });

    it('should not add the payment checkmark if not payed', () => {
      startNumberData.hasPayed = false;
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.stroke).not.toHaveBeenCalled();
    });
  });

});
<commit_msg>fix tests<commit_after>'use strict';
/* jshint node: true */
/* jshint esnext: true */
/* global jasmine, describe, it, expect, beforeEach, afterAll, spyOn */

const mockery = require('mockery');

describe('pdfGeneration', () => {

  let pdfGeneration, documentMock, qrCodeMock;
  let startNumberData;

  beforeEach(() => {

    mockery.enable({
      useCleanCache: true,
      warnOnReplace: false,
      warnOnUnregistered: false
    });

    mockery.resetCache();

    documentMock = {
      pipe: jasmine.createSpy('pipe'),
      fontSize: function () {
        return documentMock;
      },
      font: function () {
        return documentMock;
      },
      fillColor: function () {
        return documentMock;
      },
      text: jasmine.createSpy('text'),
      scale: function () {
        return documentMock;
      },
      translate: function () {
        return documentMock;
      },
      path: function () {
        return documentMock;
      },
      lineWidth: function () {
        return documentMock;
      },
      stroke: jasmine.createSpy('stroke'),
      addPage: jasmine.createSpy('addPage'),
      image: jasmine.createSpy('image'),
      fill: jasmine.createSpy('fill'),
      end: jasmine.createSpy('end')
    };

    qrCodeMock = {
      svgObject: () => {
        return qrCodeMock;
      },
      path: jasmine.createSpy('path')
    };

    mockery.registerMock('qr-image', qrCodeMock);

    pdfGeneration = require('../../pdf/pdfGeneration');

    startNumberData = {
      startNumber: '1234',
      firstname: 'Digital',
      team: 'Unicorns',
      startBlock: '1',
      startBlockColor: '#123456',
      tshirt: {
        size: 'S',
        model: 'unisex'
      },
      hasPayed: true,
      onSiteRegistration: false,
      secureUrl: 'https://example.com/asjkd12234'
    };

    qrCodeMock.path.and.returnValue('some qr code path');
  });

  afterAll(() => {
    mockery.deregisterAll();
    mockery.disable();
  });

  describe('createStartNumberPage', () => {
    it('should add the barcode three times for easier scanning', () => {
      let numberOfOtherImageCalls = 3;

      pdfGeneration.createStartNumberPage(documentMock, startNumberData);
      expect(documentMock.image).toHaveBeenCalledTimes(4 + numberOfOtherImageCalls);
    });

    it('should add the background image and the logos', () => {
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.image.calls.argsFor(0)[0]).toMatch(/pdf\/images\/background_light\.jpg/);
      expect(documentMock.image.calls.argsFor(1)[0]).toMatch(/pdf\/images\/lauf_gegen_rechts_logo\.jpg/);
      expect(documentMock.image.calls.argsFor(2)[0]).toMatch(/pdf\/images\/fc_st_pauli_marathon_logo\.png/);
    });

    it('should add tshirt details', () => {
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.text.calls.argsFor(4)).toEqual(['S unisex', 500, 315]);
    });

    it('should add a checkmark symbol only if the participant has payed', () => {
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.stroke).toHaveBeenCalledTimes(1);
    });

    it('should add start number and name', () => {
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.text.calls.argsFor(0)).toEqual(['1234', 0, 130, {align: 'center'}]);
      expect(documentMock.text.calls.argsFor(1)).toEqual(['Digital', 0, 300, {align: 'center'}]);
    });

    it('should add the team name if it exits', () => {
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.text.calls.argsFor(2)).toEqual(['Unicorns', 0, 350, {align: 'center'}]);
    });

    it('should add the startblock', () => {
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.text.calls.argsFor(3)).toEqual(['Startblock: 1', 200, 20, {align: 'left'}]);
    });

    it('should add the QR code to the self-service link', () => {
      startNumberData.onSiteRegistration = true;
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.fill).toHaveBeenCalledWith('black', 'even-odd');
    });

    it('should not add the payment checkmark if not payed', () => {
      startNumberData.hasPayed = false;
      pdfGeneration.createStartNumberPage(documentMock, startNumberData);

      expect(documentMock.stroke).not.toHaveBeenCalled();
    });
  });

});
<|endoftext|>


<commit_before>;new Vue({
  el: '#documentation-page',
  data: {
    titles: [],
    paddingTop: 50,
    searchPage: 1,
    searchPageSize: 10,
    searchInput: '',
    searchCount: 0,
    searchLoading: true,
    searchResult: []
  },
  computed: {
    showLoadMore: function () {
     return (this.searchPage) * this.searchPageSize < this.searchCount && !this.searchLoading
    }
  },
  filters: {
    docUrl: function (url) {
      if (Config.environment == 'development') {
        return url
      } else {
        console.log(url)
        return '/' + config.sdk + '/documentation' + url
      }
    },
  },
  ready: function () {
    this.initToc()
    this.initScrollFollow()
  },
  methods: {
    initToc: function () {
      var self = this,
        titlesDom = document.querySelectorAll('.article h2')

      for (var i = 0, l = titlesDom.length; i < l; i++) {
        var item = titlesDom[i]
        this.titles.push({
          hash: '#' + item.getAttribute('id'),
          text: item.innerText,
          titleDom: item,
          active: false
        })
      }
    },
    initScrollFollow: function () {
      var self = this
      $(window).on('scroll', function () {
        for (var i = 0, length = self.titles.length; i < length; i++) {
          if (i == length - 1) {
            if ($(self.titles[i].titleDom).position().top - $(window).scrollTop() < self.paddingTop) {
              self.highlight(self.titles[i])
            }
          } else {
            if ($(self.titles[i].titleDom).position().top - $(window).scrollTop() <= self.paddingTop
              &&
              $(self.titles[i + 1].titleDom).position().top - $(window).scrollTop() > self.paddingTop) {
              self.highlight(self.titles[i])
            }
          }
        }
      })
    },
    jump: function (t, e) {
      e.preventDefault()
      this.scrollTo(t.titleDom, function () {
        window.history.pushState(null, null, t.hash)
      })
    },
    scrollTo: function (target, cb) {
      cb = cb || function() {}
      $('html, body').stop().animate({scrollTop: Math.ceil($(target).position().top - this.paddingTop)}, cb);
    },
    highlight: function (target) {
      if (!target.active) {
        for (var i = 0, length = this.titles.length; i < length; i++) {
          if (this.titles[i] == target) {
            this.titles[i].active = true
          } else {
            this.titles[i].active = false
          }
        }
      }
    },
    resetSearch: function () {
      this.searchResult = []
      this.searchPage = 1
      this.searchCount = 0
      this.searchLoading = true
    },
    search: function () {
      if (!this.searchInput) return false
      var self = this
      var sdk = Config.sdk.replace('-sdk', '')
      this.resetSearch()
      // send ga
      ga('send', 'event', sdk, 'doc-search', this.searchInput)
      AjaxManager.searchDoc({keyword: this.searchInput, page: this.searchPage, locale: Config.locale, sdk: sdk}).done(function (data) {
        self.searchResult = data.results
        self.searchPageSize = data.page_size || 10
        self.searchCount = data.total_count
        self.searchLoading = false
        self.showSearch()
      }).fail(function () {
        self.searchLoading = false
        alert('Server Error')
      })
    },
    loadMoreSearch: function () {
      var self = this
      var sdk = Config.sdk.replace('-sdk', '')
      this.searchPage += 1
      self.searchLoading = true
      AjaxManager.searchDoc({keyword: this.searchInput, page: this.searchPage, locale: Config.locale, sdk: sdk}).done(function (data) {
        self.searchResult = self.searchResult.concat(data.results)
        self.searchLoading = false
      }).fail(function () {
        alert('Server Error')
        self.searchLoading = false
      })
    },
    showSearch: function () {
      $('#search-modal').modal({
        show: true,
        // backdrop: 'static',
        keyboard: false
      })
    },
    closeSearch: function () {
      $('#search-modal').modal('hide')
    }
  }
})
<commit_msg>hide log<commit_after>;new Vue({
  el: '#documentation-page',
  data: {
    titles: [],
    paddingTop: 50,
    searchPage: 1,
    searchPageSize: 10,
    searchInput: '',
    searchCount: 0,
    searchLoading: true,
    searchResult: []
  },
  computed: {
    showLoadMore: function () {
     return (this.searchPage) * this.searchPageSize < this.searchCount && !this.searchLoading
    }
  },
  filters: {
    docUrl: function (url) {
      if (Config.environment == 'development') {
        return url
      } else {
        return '/' + config.sdk + '/documentation' + url
      }
    },
  },
  ready: function () {
    this.initToc()
    this.initScrollFollow()
  },
  methods: {
    initToc: function () {
      var self = this,
        titlesDom = document.querySelectorAll('.article h2')

      for (var i = 0, l = titlesDom.length; i < l; i++) {
        var item = titlesDom[i]
        this.titles.push({
          hash: '#' + item.getAttribute('id'),
          text: item.innerText,
          titleDom: item,
          active: false
        })
      }
    },
    initScrollFollow: function () {
      var self = this
      $(window).on('scroll', function () {
        for (var i = 0, length = self.titles.length; i < length; i++) {
          if (i == length - 1) {
            if ($(self.titles[i].titleDom).position().top - $(window).scrollTop() < self.paddingTop) {
              self.highlight(self.titles[i])
            }
          } else {
            if ($(self.titles[i].titleDom).position().top - $(window).scrollTop() <= self.paddingTop
              &&
              $(self.titles[i + 1].titleDom).position().top - $(window).scrollTop() > self.paddingTop) {
              self.highlight(self.titles[i])
            }
          }
        }
      })
    },
    jump: function (t, e) {
      e.preventDefault()
      this.scrollTo(t.titleDom, function () {
        window.history.pushState(null, null, t.hash)
      })
    },
    scrollTo: function (target, cb) {
      cb = cb || function() {}
      $('html, body').stop().animate({scrollTop: Math.ceil($(target).position().top - this.paddingTop)}, cb);
    },
    highlight: function (target) {
      if (!target.active) {
        for (var i = 0, length = this.titles.length; i < length; i++) {
          if (this.titles[i] == target) {
            this.titles[i].active = true
          } else {
            this.titles[i].active = false
          }
        }
      }
    },
    resetSearch: function () {
      this.searchResult = []
      this.searchPage = 1
      this.searchCount = 0
      this.searchLoading = true
    },
    search: function () {
      if (!this.searchInput) return false
      var self = this
      var sdk = Config.sdk.replace('-sdk', '')
      this.resetSearch()
      // send ga
      ga('send', 'event', sdk, 'doc-search', this.searchInput)
      AjaxManager.searchDoc({keyword: this.searchInput, page: this.searchPage, locale: Config.locale, sdk: sdk}).done(function (data) {
        self.searchResult = data.results
        self.searchPageSize = data.page_size || 10
        self.searchCount = data.total_count
        self.searchLoading = false
        self.showSearch()
      }).fail(function () {
        self.searchLoading = false
        alert('Server Error')
      })
    },
    loadMoreSearch: function () {
      var self = this
      var sdk = Config.sdk.replace('-sdk', '')
      this.searchPage += 1
      self.searchLoading = true
      AjaxManager.searchDoc({keyword: this.searchInput, page: this.searchPage, locale: Config.locale, sdk: sdk}).done(function (data) {
        self.searchResult = self.searchResult.concat(data.results)
        self.searchLoading = false
      }).fail(function () {
        alert('Server Error')
        self.searchLoading = false
      })
    },
    showSearch: function () {
      $('#search-modal').modal({
        show: true,
        // backdrop: 'static',
        keyboard: false
      })
    },
    closeSearch: function () {
      $('#search-modal').modal('hide')
    }
  }
})
<|endoftext|>


<commit_before>/*
 @author Zakai Hamilton
 @component CoreHttp
 */

package.core.http = function CoreHttp(me) {
    var core = me.package.core;
    if (package.platform === "server") {
        me.port = process.env.PORT || 8080;
    } else {
        me.port = 80;
    }
    me.listeners = [];
    me.init = function () {
        if (me.package.platform === "server") {
            me.http = require("http");
            me.server = me.http.createServer(function (request, response) {
                var body = [];
                request.on('error', function (err) {
                    console.error(err);
                }).on('data', function (chunk) {
                    body.push(chunk);
                }).on('end', function () {
                    if(request.url.includes("private")) {
                        response.writeHead(200);
                        response.end("cannot load private files remotely");
                    }
                    else {
                        me.handleRequest(request, response, body);
                    }
                });
            });
            me.server.listen(me.port, function (err) {
                if (err) {
                    return core.console.log("something bad happened", err);
                }
                core.console.log("server is listening on " + core.http.port);
            });
        }
    };
    me.handleRequest = function (request, response, body) {
        if(body) {
            body = Buffer.concat(body).toString();
        }
        var job = core.job.open();
        var url = request.url;
        var query = "";
        var query_offset = url.lastIndexOf("?");
        if (query_offset !== -1) {
            url = request.url.substring(0, query_offset);
            query = request.url.substring(query_offset + 1);
        }
        var info = {
            method: request.method,
            url: decodeURIComponent(url),
            query: core.http.parse_query(query),
            headers: request.headers,
            code: 200,
            "content-type": "application/json",
            body: body,
            job: job,
            response: response,
            custom: false
        };
        core.object.attach(info, me);
        core.property.set(info, "receive");
        core.job.close(job, function () {
            if(info.custom === false) {
                response.writeHead(info.code, {
                    "Content-Type": info["content-type"],
                });
                response.end(info.body);
            }
        });
    };
    me.parse_query = function (query) {
        var array = {};
        if (query !== "") {
            var a = (query[0] === '?' ? query.substr(1) : query).split('&');
            for (var i = 0; i < a.length; i++) {
                var b = a[i].split('=');
                array[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
            }
        }
        return array;
    };
    me.send = function (info, async = true) {
        if (me.package.platform === "server") {
            var request = {
                url:info.url,
                headers:null,
                method:info.method.toUpperCase()
            };
            var response = {
                writeHead : function() { },
                end : function(body) {
                    if (info.callback) {
                        info.response = body;
                        info.callback(info);
                    }
                }
            };
            core.console.log("sending request:"  + JSON.stringify(request) + " body: " + info.body);
            me.handleRequest(request, response, info.body);
        } else {
            var request = new XMLHttpRequest();
            if (info.mimeType && request.overrideMimeType) {
                request.overrideMimeType(info.mimeType);
            }
            core.console.log("sending request info:" + JSON.stringify(info));
            request.open(info.method, info.url, async);
            if (async) {
                request.onreadystatechange = function (e) {
                    if (request.readyState === 4) {
                        if (request.status === 200 || request.status === 201) {
                            if (info.callback) {
                                info.response = request.responseText;
                                info.callback(info);
                            }
                        } else if (info.hasOwnProperty("failure")) {
                            if (info.callback) {
                                info.status = request.status;
                                info.callback(info);
                            }
                        }
                    }
                };
            }
            request.send(info.body);
            if (!async && request.status === 200) {
                return request.responseText;
            }
        }
    };
};
<commit_msg>local port fix<commit_after>/*
 @author Zakai Hamilton
 @component CoreHttp
 */

package.core.http = function CoreHttp(me) {
    var core = me.package.core;
    if (package.platform === "server") {
        me.port = process.env.PORT || 4040;
    } else {
        me.port = 80;
    }
    me.listeners = [];
    me.init = function () {
        if (me.package.platform === "server") {
            me.http = require("http");
            me.server = me.http.createServer(function (request, response) {
                var body = [];
                request.on('error', function (err) {
                    console.error(err);
                }).on('data', function (chunk) {
                    body.push(chunk);
                }).on('end', function () {
                    if(request.url.includes("private")) {
                        response.writeHead(200);
                        response.end("cannot load private files remotely");
                    }
                    else {
                        me.handleRequest(request, response, body);
                    }
                });
            });
            me.server.listen(me.port, function (err) {
                if (err) {
                    return core.console.log("something bad happened", err);
                }
                core.console.log("server is listening on " + core.http.port);
            });
        }
    };
    me.handleRequest = function (request, response, body) {
        if(body) {
            body = Buffer.concat(body).toString();
        }
        var job = core.job.open();
        var url = request.url;
        var query = "";
        var query_offset = url.lastIndexOf("?");
        if (query_offset !== -1) {
            url = request.url.substring(0, query_offset);
            query = request.url.substring(query_offset + 1);
        }
        var info = {
            method: request.method,
            url: decodeURIComponent(url),
            query: core.http.parse_query(query),
            headers: request.headers,
            code: 200,
            "content-type": "application/json",
            body: body,
            job: job,
            response: response,
            custom: false
        };
        core.object.attach(info, me);
        core.property.set(info, "receive");
        core.job.close(job, function () {
            if(info.custom === false) {
                response.writeHead(info.code, {
                    "Content-Type": info["content-type"],
                });
                response.end(info.body);
            }
        });
    };
    me.parse_query = function (query) {
        var array = {};
        if (query !== "") {
            var a = (query[0] === '?' ? query.substr(1) : query).split('&');
            for (var i = 0; i < a.length; i++) {
                var b = a[i].split('=');
                array[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
            }
        }
        return array;
    };
    me.send = function (info, async = true) {
        if (me.package.platform === "server") {
            var request = {
                url:info.url,
                headers:null,
                method:info.method.toUpperCase()
            };
            var response = {
                writeHead : function() { },
                end : function(body) {
                    if (info.callback) {
                        info.response = body;
                        info.callback(info);
                    }
                }
            };
            core.console.log("sending request:"  + JSON.stringify(request) + " body: " + info.body);
            me.handleRequest(request, response, info.body);
        } else {
            var request = new XMLHttpRequest();
            if (info.mimeType && request.overrideMimeType) {
                request.overrideMimeType(info.mimeType);
            }
            core.console.log("sending request info:" + JSON.stringify(info));
            request.open(info.method, info.url, async);
            if (async) {
                request.onreadystatechange = function (e) {
                    if (request.readyState === 4) {
                        if (request.status === 200 || request.status === 201) {
                            if (info.callback) {
                                info.response = request.responseText;
                                info.callback(info);
                            }
                        } else if (info.hasOwnProperty("failure")) {
                            if (info.callback) {
                                info.status = request.status;
                                info.callback(info);
                            }
                        }
                    }
                };
            }
            request.send(info.body);
            if (!async && request.status === 200) {
                return request.responseText;
            }
        }
    };
};
<|endoftext|>


<commit_before>// javascript for the httpclient
url = "/http/proxy/";

$(document).ready(function(){
	$('#form').submit(function(){ sendMsg(); return false; });
	setInterval("checkMsgs()", 500);
});

function sendMsg() {
	if ($('#phone').val().length > 0 && $('#message').val().length > 0) {
		req = url + $('#phone').val() + "/" + $('#message').val();
		$.getJSON(
			req,
			function (response) { if (response) {
				snippet = '
' + response.phone + '	«	' + decode(response.message) + '	' + decode(response.message).length + ' characters
';
				$('#log').append(snippet);
				fixClasses();
				$('div.tester').scrollTo('#log tr:last', 800);
				$('#message').val("");
			}}
		);
	}
}

function fixClasses(){
	$('#log tr').removeClass('first');
	$('#log tr').removeClass('last');
	$('#log tr:first').addClass('first');
	$('#log tr:last').addClass('last');
}

function decode(str) {
	str = str.replace(/%23/gi, "#");
	str = str.replace(/%24/gi, "$");
	str = str.replace(/%26/gi, "&");
	str = str.replace(/%3D/gi, "=");
	str = str.replace(/%3B/gi, ";");
	str = str.replace(/%2C/gi, ",");
	str = str.replace(/%3A/gi, ":");
	str = str.replace(/%3F/gi, "?");
	str = decodeURI(str);
	return str;
}

function checkMsgs() {
	if ($('#phone').val().length > 0) {
		req = url + $('#phone').val() + "/json_resp";
		$.getJSON(
			req,
			function (response) { if (response) {
				snippet = '
' + response.phone + '	»	' + decode(response.message) + '	' + decode(response.message).length + ' characters
';
				$('#log').append(snippet);
				fixClasses();
				$('div.tester').scrollTo('#log tr:last', 800);
			}}

		);
	}
}
<commit_msg>adding logic to url escape the messages in the tester (cherry picked from commit e4dff7ff19bc981c3b1a064a52be7fe5d2cfd339)<commit_after>// javascript for the httpclient
url = "/http/proxy/";

$(document).ready(function(){
	$('#form').submit(function(){ sendMsg(); return false; });
	setInterval("checkMsgs()", 500);
});

function sendMsg() {
	if ($('#phone').val().length > 0 && $('#message').val().length > 0) {
		req = url + $('#phone').val() + "/" + escape($('#message').val());
		$.getJSON(
			req,
			function (response) { if (response) {
				snippet = '
' + response.phone + '	«	' + decode(response.message) + '	' + decode(response.message).length + ' characters
';
				$('#log').append(snippet);
				fixClasses();
				$('div.tester').scrollTo('#log tr:last', 800);
				$('#message').val("");
			}}
		);
	}
}

function fixClasses(){
	$('#log tr').removeClass('first');
	$('#log tr').removeClass('last');
	$('#log tr:first').addClass('first');
	$('#log tr:last').addClass('last');
}

function decode(str) {
	str = str.replace(/%23/gi, "#");
	str = str.replace(/%24/gi, "$");
	str = str.replace(/%26/gi, "&");
	str = str.replace(/%3D/gi, "=");
	str = str.replace(/%3B/gi, ";");
	str = str.replace(/%2C/gi, ",");
	str = str.replace(/%3A/gi, ":");
	str = str.replace(/%3F/gi, "?");
	str = decodeURI(str);
	return str;
}

function checkMsgs() {
	if ($('#phone').val().length > 0) {
		req = url + $('#phone').val() + "/json_resp";
		$.getJSON(
			req,
			function (response) { if (response) {
				snippet = '
' + response.phone + '	»	' + decode(response.message) + '	' + decode(response.message).length + ' characters
';
				$('#log').append(snippet);
				fixClasses();
				$('div.tester').scrollTo('#log tr:last', 800);
			}}

		);
	}
}
<|endoftext|>


<commit_before>import { getBindingIdentifiers } from "./retrievers";
import esutils from "esutils";
import * as t from "./index";
import { BLOCK_SCOPED_SYMBOL } from "./constants";

/**
 * Check if the input `node` is a binding identifier.
 */

export function isBinding(node: Object, parent: Object): boolean {
  const keys = getBindingIdentifiers.keys[parent.type];
  if (keys) {
    for (let i = 0; i < keys.length; i++) {
      const key = keys[i];
      const val = parent[key];
      if (Array.isArray(val)) {
        if (val.indexOf(node) >= 0) return true;
      } else {
        if (val === node) return true;
      }
    }
  }

  return false;
}

/**
 * Check if the input `node` is a reference to a bound variable.
 */

export function isReferenced(node: Object, parent: Object): boolean {
  switch (parent.type) {
    // yes: object::NODE
    // yes: NODE::callee
    case "BindExpression":
      return parent.object === node || parent.callee === node;

    // yes: PARENT[NODE]
    // yes: NODE.child
    // no: parent.NODE
    case "MemberExpression":
    case "JSXMemberExpression":
      if (parent.property === node && parent.computed) {
        return true;
      } else if (parent.object === node) {
        return true;
      } else {
        return false;
      }

    // no: new.NODE
    // no: NODE.target
    case "MetaProperty":
      return false;

    // yes: { [NODE]: "" }
    // yes: { NODE }
    // no: { NODE: "" }
    case "ObjectProperty":
      if (parent.key === node) {
        return parent.computed;
      }

    // no: let NODE = init;
    // yes: let id = NODE;
    case "VariableDeclarator":
      return parent.id !== node;

    // no: function NODE() {}
    // no: function foo(NODE) {}
    case "ArrowFunctionExpression":
    case "FunctionDeclaration":
    case "FunctionExpression":
      for (const param of (parent.params: Array<any>)) {
        if (param === node) return false;
      }

      return parent.id !== node;

    // no: export { foo as NODE };
    // yes: export { NODE as foo };
    // no: export { NODE as foo } from "foo";
    case "ExportSpecifier":
      if (parent.source) {
        return false;
      } else {
        return parent.local === node;
      }

    // no: export NODE from "foo";
    // no: export * as NODE from "foo";
    case "ExportNamespaceSpecifier":
    case "ExportDefaultSpecifier":
      return false;

    // no:

    case "JSXAttribute":
      return parent.name !== node;

    // no: class { NODE = value; }
    // yes: class { [NODE] = value; }
    // yes: class { key = NODE; }
    case "ClassProperty":
      if (parent.key === node) {
        return parent.computed;
      } else {
        return parent.value === node;
      }

    // no: import NODE from "foo";
    // no: import * as NODE from "foo";
    // no: import { NODE as foo } from "foo";
    // no: import { foo as NODE } from "foo";
    // no: import NODE from "bar";
    case "ImportDefaultSpecifier":
    case "ImportNamespaceSpecifier":
    case "ImportSpecifier":
      return false;

    // no: class NODE {}
    case "ClassDeclaration":
    case "ClassExpression":
      return parent.id !== node;

    // yes: class { [NODE]() {} }
    case "ClassMethod":
    case "ObjectMethod":
      return parent.key === node && parent.computed;

    // no: NODE: for (;;) {}
    case "LabeledStatement":
      return false;

    // no: try {} catch (NODE) {}
    case "CatchClause":
      return parent.param !== node;

    // no: function foo(...NODE) {}
    case "RestElement":
      return false;

    // yes: left = NODE;
    // no: NODE = right;
    case "AssignmentExpression":
      return parent.right === node;

    // no: [NODE = foo] = [];
    // yes: [foo = NODE] = [];
    case "AssignmentPattern":
      return parent.right === node;

    // no: [NODE] = [];
    // no: ({ NODE }) = [];
    case "ObjectPattern":
    case "ArrayPattern":
      return false;
  }

  return true;
}

/**
 * Check if the input `name` is a valid identifier name
 * and isn't a reserved word.
 */

export function isValidIdentifier(name: string): boolean {
  if (typeof name !== "string" || esutils.keyword.isReservedWordES6(name, true)) {
    return false;
  } else if (name === "await") {
    // invalid in module, valid in script; better be safe (see #4952)
    return false;
  } else {
    return esutils.keyword.isIdentifierNameES6(name);
  }
}

/**
 * Check if the input `node` is a `let` variable declaration.
 */

export function isLet(node: Object): boolean {
  return t.isVariableDeclaration(node) && (node.kind !== "var" || node[BLOCK_SCOPED_SYMBOL]);
}

/**
 * Check if the input `node` is block scoped.
 */

export function isBlockScoped(node: Object): boolean {
  return t.isFunctionDeclaration(node) || t.isClassDeclaration(node) || t.isLet(node);
}

/**
 * Check if the input `node` is a variable declaration.
 */

export function isVar(node: Object): boolean {
  return t.isVariableDeclaration(node, { kind: "var" }) && !node[BLOCK_SCOPED_SYMBOL];
}

/**
 * Check if the input `specifier` is a `default` import or export.
 */

export function isSpecifierDefault(specifier: Object): boolean {
  return t.isImportDefaultSpecifier(specifier) ||
         t.isIdentifier(specifier.imported || specifier.exported, { name: "default" });
}

/**
 * Check if the input `node` is a scope.
 */

export function isScope(node: Object, parent: Object): boolean {
  if (t.isBlockStatement(node) && t.isFunction(parent, { body: node })) {
    return false;
  }

  return t.isScopable(node);
}

/**
 * Check if the input `node` is definitely immutable.
 */

export function isImmutable(node: Object): boolean {
  if (t.isType(node.type, "Immutable")) return true;

  if (t.isIdentifier(node)) {
    if (node.name === "undefined") {
      // immutable!
      return true;
    } else {
      // no idea...
      return false;
    }
  }

  return false;
}

/**
 * Check if two nodes are equivalent
 */

export function isNodesEquivalent(a, b) {
  if (typeof a !== "object" || typeof a !== "object" || a == null || b == null) {
    return a === b;
  }

  if (a.type !== b.type) {
    return false;
  }

  const fields = Object.keys(t.NODE_FIELDS[a.type] || a.type);

  for (const field of fields) {
    if (typeof a[field] !== typeof b[field]) {
      return false;
    }

    if (Array.isArray(a[field])) {
      if (!Array.isArray(b[field])) {
        return false;
      }
      if (a[field].length !== b[field].length) {
        return false;
      }

      for (let i = 0; i < a[field].length; i++) {
        if (!isNodesEquivalent(a[field][i], b[field][i])) {
          return false;
        }
      }
      continue;
    }

    if (!isNodesEquivalent(a[field], b[field])) {
      return false;
    }
  }

  return true;
}
<commit_msg>Fix typo a => b<commit_after>import { getBindingIdentifiers } from "./retrievers";
import esutils from "esutils";
import * as t from "./index";
import { BLOCK_SCOPED_SYMBOL } from "./constants";

/**
 * Check if the input `node` is a binding identifier.
 */

export function isBinding(node: Object, parent: Object): boolean {
  const keys = getBindingIdentifiers.keys[parent.type];
  if (keys) {
    for (let i = 0; i < keys.length; i++) {
      const key = keys[i];
      const val = parent[key];
      if (Array.isArray(val)) {
        if (val.indexOf(node) >= 0) return true;
      } else {
        if (val === node) return true;
      }
    }
  }

  return false;
}

/**
 * Check if the input `node` is a reference to a bound variable.
 */

export function isReferenced(node: Object, parent: Object): boolean {
  switch (parent.type) {
    // yes: object::NODE
    // yes: NODE::callee
    case "BindExpression":
      return parent.object === node || parent.callee === node;

    // yes: PARENT[NODE]
    // yes: NODE.child
    // no: parent.NODE
    case "MemberExpression":
    case "JSXMemberExpression":
      if (parent.property === node && parent.computed) {
        return true;
      } else if (parent.object === node) {
        return true;
      } else {
        return false;
      }

    // no: new.NODE
    // no: NODE.target
    case "MetaProperty":
      return false;

    // yes: { [NODE]: "" }
    // yes: { NODE }
    // no: { NODE: "" }
    case "ObjectProperty":
      if (parent.key === node) {
        return parent.computed;
      }

    // no: let NODE = init;
    // yes: let id = NODE;
    case "VariableDeclarator":
      return parent.id !== node;

    // no: function NODE() {}
    // no: function foo(NODE) {}
    case "ArrowFunctionExpression":
    case "FunctionDeclaration":
    case "FunctionExpression":
      for (const param of (parent.params: Array<any>)) {
        if (param === node) return false;
      }

      return parent.id !== node;

    // no: export { foo as NODE };
    // yes: export { NODE as foo };
    // no: export { NODE as foo } from "foo";
    case "ExportSpecifier":
      if (parent.source) {
        return false;
      } else {
        return parent.local === node;
      }

    // no: export NODE from "foo";
    // no: export * as NODE from "foo";
    case "ExportNamespaceSpecifier":
    case "ExportDefaultSpecifier":
      return false;

    // no:

    case "JSXAttribute":
      return parent.name !== node;

    // no: class { NODE = value; }
    // yes: class { [NODE] = value; }
    // yes: class { key = NODE; }
    case "ClassProperty":
      if (parent.key === node) {
        return parent.computed;
      } else {
        return parent.value === node;
      }

    // no: import NODE from "foo";
    // no: import * as NODE from "foo";
    // no: import { NODE as foo } from "foo";
    // no: import { foo as NODE } from "foo";
    // no: import NODE from "bar";
    case "ImportDefaultSpecifier":
    case "ImportNamespaceSpecifier":
    case "ImportSpecifier":
      return false;

    // no: class NODE {}
    case "ClassDeclaration":
    case "ClassExpression":
      return parent.id !== node;

    // yes: class { [NODE]() {} }
    case "ClassMethod":
    case "ObjectMethod":
      return parent.key === node && parent.computed;

    // no: NODE: for (;;) {}
    case "LabeledStatement":
      return false;

    // no: try {} catch (NODE) {}
    case "CatchClause":
      return parent.param !== node;

    // no: function foo(...NODE) {}
    case "RestElement":
      return false;

    // yes: left = NODE;
    // no: NODE = right;
    case "AssignmentExpression":
      return parent.right === node;

    // no: [NODE = foo] = [];
    // yes: [foo = NODE] = [];
    case "AssignmentPattern":
      return parent.right === node;

    // no: [NODE] = [];
    // no: ({ NODE }) = [];
    case "ObjectPattern":
    case "ArrayPattern":
      return false;
  }

  return true;
}

/**
 * Check if the input `name` is a valid identifier name
 * and isn't a reserved word.
 */

export function isValidIdentifier(name: string): boolean {
  if (typeof name !== "string" || esutils.keyword.isReservedWordES6(name, true)) {
    return false;
  } else if (name === "await") {
    // invalid in module, valid in script; better be safe (see #4952)
    return false;
  } else {
    return esutils.keyword.isIdentifierNameES6(name);
  }
}

/**
 * Check if the input `node` is a `let` variable declaration.
 */

export function isLet(node: Object): boolean {
  return t.isVariableDeclaration(node) && (node.kind !== "var" || node[BLOCK_SCOPED_SYMBOL]);
}

/**
 * Check if the input `node` is block scoped.
 */

export function isBlockScoped(node: Object): boolean {
  return t.isFunctionDeclaration(node) || t.isClassDeclaration(node) || t.isLet(node);
}

/**
 * Check if the input `node` is a variable declaration.
 */

export function isVar(node: Object): boolean {
  return t.isVariableDeclaration(node, { kind: "var" }) && !node[BLOCK_SCOPED_SYMBOL];
}

/**
 * Check if the input `specifier` is a `default` import or export.
 */

export function isSpecifierDefault(specifier: Object): boolean {
  return t.isImportDefaultSpecifier(specifier) ||
         t.isIdentifier(specifier.imported || specifier.exported, { name: "default" });
}

/**
 * Check if the input `node` is a scope.
 */

export function isScope(node: Object, parent: Object): boolean {
  if (t.isBlockStatement(node) && t.isFunction(parent, { body: node })) {
    return false;
  }

  return t.isScopable(node);
}

/**
 * Check if the input `node` is definitely immutable.
 */

export function isImmutable(node: Object): boolean {
  if (t.isType(node.type, "Immutable")) return true;

  if (t.isIdentifier(node)) {
    if (node.name === "undefined") {
      // immutable!
      return true;
    } else {
      // no idea...
      return false;
    }
  }

  return false;
}

/**
 * Check if two nodes are equivalent
 */

export function isNodesEquivalent(a, b) {
  if (typeof a !== "object" || typeof b !== "object" || a == null || b == null) {
    return a === b;
  }

  if (a.type !== b.type) {
    return false;
  }

  const fields = Object.keys(t.NODE_FIELDS[a.type] || a.type);

  for (const field of fields) {
    if (typeof a[field] !== typeof b[field]) {
      return false;
    }

    if (Array.isArray(a[field])) {
      if (!Array.isArray(b[field])) {
        return false;
      }
      if (a[field].length !== b[field].length) {
        return false;
      }

      for (let i = 0; i < a[field].length; i++) {
        if (!isNodesEquivalent(a[field][i], b[field][i])) {
          return false;
        }
      }
      continue;
    }

    if (!isNodesEquivalent(a[field], b[field])) {
      return false;
    }
  }

  return true;
}
<|endoftext|>


<commit_before>(function(SirTrevor, document) {
  'use strict';

  var Quote = SirTrevor.Formatter.extend({

    title: 'quote',
    keyCode: 49,
    text: '”',

    onClick: function() {
      var selection = document.getSelection();
      if (selection.type !== 'Range' || selection.rangeCount === 0) {
        return; // no ranges
      }
      var range = selection.getRangeAt(0);
      var block = this._getSelectedBlock(range);
      var blockInner = block.getElementsByClassName('st-text-block')[0];
      var editor = SirTrevor.getInstance(block.getAttribute('data-instance'));

      if (this.isActive()) {
        SirTrevor.TextAndQuote.merge(range, block, blockInner, editor);
      } else {
        SirTrevor.TextAndQuote.split(range, block, blockInner, editor);
      }
      SirTrevor.EventBus.trigger("formatbar:hide", editor);
    },

    addQuoteBlocks: function(paragraphs, addAt, editor) {
      return SirTrevor.TextAndQuote.addQuoteBlocks(paragraphs, addAt, editor);
    },

    /**
     * Sometimes range containers will be text fragments
     * or HTML elements
     */
    _getRangeContainerElement: function(container) {
      if (container.nodeName === '#text') {
        return container.parentNode;
      }

      return container;
    },

    _getSelectedBlock: function(range) {
      var block = this._getRangeContainerElement(range.startContainer);
      while (!block.classList.contains('st-block')) {
        block = block.parentNode;
      }
      return block;
    },

    isActive: function() {
      var selection = document.getSelection();
      if (selection.rangeCount > 0) {
        var range = selection.getRangeAt(0);
        var block = this._getSelectedBlock(range);
        return block.getAttribute('data-type') === SirTrevor.Blocks.Quote.prototype.type;
      } else {
        return false;
      }
    }

  });

  SirTrevor.Formatters.Quote = new Quote();

}(SirTrevor, document));
<commit_msg>Change quote button icon to right double quote character<commit_after>(function(SirTrevor, document) {
  'use strict';

  var Quote = SirTrevor.Formatter.extend({

    title: 'quote',
    keyCode: 49,
    text: '“',

    onClick: function() {
      var selection = document.getSelection();
      if (selection.type !== 'Range' || selection.rangeCount === 0) {
        return; // no ranges
      }
      var range = selection.getRangeAt(0);
      var block = this._getSelectedBlock(range);
      var blockInner = block.getElementsByClassName('st-text-block')[0];
      var editor = SirTrevor.getInstance(block.getAttribute('data-instance'));

      if (this.isActive()) {
        SirTrevor.TextAndQuote.merge(range, block, blockInner, editor);
      } else {
        SirTrevor.TextAndQuote.split(range, block, blockInner, editor);
      }
      SirTrevor.EventBus.trigger("formatbar:hide", editor);
    },

    addQuoteBlocks: function(paragraphs, addAt, editor) {
      return SirTrevor.TextAndQuote.addQuoteBlocks(paragraphs, addAt, editor);
    },

    /**
     * Sometimes range containers will be text fragments
     * or HTML elements
     */
    _getRangeContainerElement: function(container) {
      if (container.nodeName === '#text') {
        return container.parentNode;
      }

      return container;
    },

    _getSelectedBlock: function(range) {
      var block = this._getRangeContainerElement(range.startContainer);
      while (!block.classList.contains('st-block')) {
        block = block.parentNode;
      }
      return block;
    },

    isActive: function() {
      var selection = document.getSelection();
      if (selection.rangeCount > 0) {
        var range = selection.getRangeAt(0);
        var block = this._getSelectedBlock(range);
        return block.getAttribute('data-type') === SirTrevor.Blocks.Quote.prototype.type;
      } else {
        return false;
      }
    }

  });

  SirTrevor.Formatters.Quote = new Quote();

}(SirTrevor, document));
<|endoftext|>


<commit_before>/**
 * @author mrdoob / http://mrdoob.com/
 */

var Timeline = function ( editor ) {

	var signals = editor.signals;
	var player = editor.player;

	var container = new UI.Panel();
	container.setId( 'timeline' );

	// controls

	/*
	var buttons = new UI.Div();
	buttons.setPosition( 'absolute' );
	buttons.setTop( '5px' );
	buttons.setRight( '5px' );
	controls.add( buttons );

	var button = new UI.Button();
	button.setLabel( 'ANIMATIONS' );
	button.onClick( function () {

		elements.setDisplay( '' );
		curves.setDisplay( 'none' );

	 } );
	buttons.add( button );

	var button = new UI.Button();
	button.setLabel( 'CURVES' );
	button.setMarginLeft( '4px' );
	button.onClick( function () {

		scroller.style.background = '';

		elements.setDisplay( 'none' );
		curves.setDisplay( '' );

	} );
	buttons.add( button );
	*/

	// timeline

	var keysDown = {};
	document.addEventListener( 'keydown', function ( event ) { keysDown[ event.keyCode ] = true; } );
	document.addEventListener( 'keyup',   function ( event ) { keysDown[ event.keyCode ] = false; } );

	var scale = 32;
	var prevScale = scale;

	var timeline = new UI.Panel();
	timeline.setPosition( 'absolute' );
	timeline.setTop( '0px' );
	timeline.setBottom( '0px' );
	timeline.setWidth( '100%' );
	timeline.setOverflow( 'hidden' );
	timeline.dom.addEventListener( 'wheel', function ( event ) {

		if ( event.altKey === true ) {

			event.preventDefault();

			scale = Math.max( 2, scale + ( event.deltaY / 10 ) );

			signals.timelineScaled.dispatch( scale );

		}

	} );
	container.add( timeline );

	var canvas = document.createElement( 'canvas' );
	canvas.height = 32;
	canvas.style.position = 'absolute';
	canvas.addEventListener( 'mousedown', function ( event ) {

		event.preventDefault();

		function onMouseMove( event ) {

			editor.setTime( ( event.offsetX + scroller.scrollLeft ) / scale );

		}

		function onMouseUp( event ) {

			onMouseMove( event );

			document.removeEventListener( 'mousemove', onMouseMove );
			document.removeEventListener( 'mouseup', onMouseUp );

		}

		document.addEventListener( 'mousemove', onMouseMove, false );
		document.addEventListener( 'mouseup', onMouseUp, false );

	}, false );
	timeline.dom.appendChild( canvas );

	function updateMarks() {

		canvas.width = scroller.clientWidth;

		var context = canvas.getContext( '2d', { alpha: false } );

		context.fillStyle = '#555';
		context.fillRect( 0, 0, canvas.width, canvas.height );

		context.strokeStyle = '#888';
		context.beginPath();

		context.translate( - scroller.scrollLeft, 0 );

		var duration = editor.duration;
		var width = duration * scale;
		var scale4 = scale / 4;

		for ( var i = 0.5; i <= width; i += scale ) {

			context.moveTo( i + ( scale4 * 0 ), 18 ); context.lineTo( i + ( scale4 * 0 ), 26 );

			if ( scale > 16 ) context.moveTo( i + ( scale4 * 1 ), 22 ), context.lineTo( i + ( scale4 * 1 ), 26 );
			if ( scale >  8 ) context.moveTo( i + ( scale4 * 2 ), 22 ), context.lineTo( i + ( scale4 * 2 ), 26 );
			if ( scale > 16 ) context.moveTo( i + ( scale4 * 3 ), 22 ), context.lineTo( i + ( scale4 * 3 ), 26 );

		}

		context.stroke();

		context.font = '10px Arial';
		context.fillStyle = '#888'
		context.textAlign = 'center';

		var step = Math.max( 1, Math.floor( 64 / scale ) );

		for ( var i = 0; i < duration; i += step ) {

			var minute = Math.floor( i / 60 );
			var second = Math.floor( i % 60 );

			var text = ( minute > 0 ? minute + ':' : '' ) + ( '0' + second ).slice( - 2 );

			context.fillText( text, i * scale, 13 );

		}

	}

	var scroller = document.createElement( 'div' );
	scroller.style.position = 'absolute';
	scroller.style.top = '32px';
	scroller.style.bottom = '0px';
	scroller.style.width = '100%';
	scroller.style.overflow = 'auto';
	scroller.addEventListener( 'scroll', function ( event ) {

		updateMarks();
		updateTimeMark();

	}, false );
	timeline.dom.appendChild( scroller );

	var elements = new Timeline.Animations( editor );
	scroller.appendChild( elements.dom );

	/*
	var curves = new Timeline.Curves( editor );
	curves.setDisplay( 'none' );
	scroller.appendChild( curves.dom );
	*/

	function updateContainers() {

		var width = editor.duration * scale;

		elements.setWidth( width + 'px' );
		// curves.setWidth( width + 'px' );

	}

	//

	var loopMark = document.createElement( 'div' );
	loopMark.style.position = 'absolute';
	loopMark.style.top = 0;
	loopMark.style.height = 100 + '%';
	loopMark.style.width = 0;
	loopMark.style.background = 'rgba( 255, 255, 255, 0.1 )';
	loopMark.style.pointerEvents = 'none';
	loopMark.style.display = 'none';
	timeline.dom.appendChild( loopMark );

	var timeMark = document.createElement( 'div' );
	timeMark.style.position = 'absolute';
	timeMark.style.top = '0px';
	timeMark.style.left = '-8px';
	timeMark.style.width = '16px';
	timeMark.style.height = '100%';
	timeMark.style.background = 'linear-gradient(90deg, transparent 8px, #f00 8px, #f00 9px, transparent 9px) 0% 0% / 16px 16px repeat-y';
	timeMark.style.pointerEvents = 'none';
	timeline.dom.appendChild( timeMark );

	function updateTimeMark() {

		timeMark.style.left = ( player.currentTime * scale ) - scroller.scrollLeft - 8 + 'px';

		// TODO Optimise this

		var loop = player.getLoop();

		if ( Array.isArray( loop ) ) {

			var loopStart = loop[ 0 ] * scale;
			var loopEnd = loop[ 1 ] * scale;

			loopMark.style.display = '';
			loopMark.style.left = ( loopStart - scroller.scrollLeft ) + 'px';
			loopMark.style.width = ( loopEnd - loopStart ) + 'px';

		} else {

			loopMark.style.display = 'none';

		}

	}

	// signals

	signals.timeChanged.add( function () {

		updateTimeMark();

	} );

	signals.timelineScaled.add( function ( value ) {

		scale = value;

		scroller.scrollLeft = ( scroller.scrollLeft * value ) / prevScale;

		updateMarks();
		updateTimeMark();
		updateContainers();

		prevScale = value;

	} );

	signals.windowResized.add( function () {

		updateMarks();
		updateContainers();

	} );

	return container;

};
<commit_msg>Changed timeline to scroll when the time mark hits the end of the visible area<commit_after>/**
 * @author mrdoob / http://mrdoob.com/
 */

var Timeline = function ( editor ) {

	var signals = editor.signals;
	var player = editor.player;

	var container = new UI.Panel();
	container.setId( 'timeline' );

	// controls

	/*
	var buttons = new UI.Div();
	buttons.setPosition( 'absolute' );
	buttons.setTop( '5px' );
	buttons.setRight( '5px' );
	controls.add( buttons );

	var button = new UI.Button();
	button.setLabel( 'ANIMATIONS' );
	button.onClick( function () {

		elements.setDisplay( '' );
		curves.setDisplay( 'none' );

	 } );
	buttons.add( button );

	var button = new UI.Button();
	button.setLabel( 'CURVES' );
	button.setMarginLeft( '4px' );
	button.onClick( function () {

		scroller.style.background = '';

		elements.setDisplay( 'none' );
		curves.setDisplay( '' );

	} );
	buttons.add( button );
	*/

	// timeline

	var keysDown = {};
	document.addEventListener( 'keydown', function ( event ) { keysDown[ event.keyCode ] = true; } );
	document.addEventListener( 'keyup',   function ( event ) { keysDown[ event.keyCode ] = false; } );

	var scale = 32;
	var prevScale = scale;

	var timeline = new UI.Panel();
	timeline.setPosition( 'absolute' );
	timeline.setTop( '0px' );
	timeline.setBottom( '0px' );
	timeline.setWidth( '100%' );
	timeline.setOverflow( 'hidden' );
	timeline.dom.addEventListener( 'wheel', function ( event ) {

		if ( event.altKey === true ) {

			event.preventDefault();

			scale = Math.max( 2, scale + ( event.deltaY / 10 ) );

			signals.timelineScaled.dispatch( scale );

		}

	} );
	container.add( timeline );

	var canvas = document.createElement( 'canvas' );
	canvas.height = 32;
	canvas.style.position = 'absolute';
	canvas.addEventListener( 'mousedown', function ( event ) {

		event.preventDefault();

		function onMouseMove( event ) {

			editor.setTime( ( event.offsetX + scroller.scrollLeft ) / scale );

		}

		function onMouseUp( event ) {

			onMouseMove( event );

			document.removeEventListener( 'mousemove', onMouseMove );
			document.removeEventListener( 'mouseup', onMouseUp );

		}

		document.addEventListener( 'mousemove', onMouseMove, false );
		document.addEventListener( 'mouseup', onMouseUp, false );

	}, false );
	timeline.dom.appendChild( canvas );

	function updateMarks() {

		canvas.width = scroller.clientWidth;

		var context = canvas.getContext( '2d', { alpha: false } );

		context.fillStyle = '#555';
		context.fillRect( 0, 0, canvas.width, canvas.height );

		context.strokeStyle = '#888';
		context.beginPath();

		context.translate( - scroller.scrollLeft, 0 );

		var duration = editor.duration;
		var width = duration * scale;
		var scale4 = scale / 4;

		for ( var i = 0.5; i <= width; i += scale ) {

			context.moveTo( i + ( scale4 * 0 ), 18 ); context.lineTo( i + ( scale4 * 0 ), 26 );

			if ( scale > 16 ) context.moveTo( i + ( scale4 * 1 ), 22 ), context.lineTo( i + ( scale4 * 1 ), 26 );
			if ( scale >  8 ) context.moveTo( i + ( scale4 * 2 ), 22 ), context.lineTo( i + ( scale4 * 2 ), 26 );
			if ( scale > 16 ) context.moveTo( i + ( scale4 * 3 ), 22 ), context.lineTo( i + ( scale4 * 3 ), 26 );

		}

		context.stroke();

		context.font = '10px Arial';
		context.fillStyle = '#888'
		context.textAlign = 'center';

		var step = Math.max( 1, Math.floor( 64 / scale ) );

		for ( var i = 0; i < duration; i += step ) {

			var minute = Math.floor( i / 60 );
			var second = Math.floor( i % 60 );

			var text = ( minute > 0 ? minute + ':' : '' ) + ( '0' + second ).slice( - 2 );

			context.fillText( text, i * scale, 13 );

		}

	}

	var scroller = document.createElement( 'div' );
	scroller.style.position = 'absolute';
	scroller.style.top = '32px';
	scroller.style.bottom = '0px';
	scroller.style.width = '100%';
	scroller.style.overflow = 'auto';
	scroller.addEventListener( 'scroll', function ( event ) {

		updateMarks();
		updateTimeMark();

	}, false );
	timeline.dom.appendChild( scroller );

	var elements = new Timeline.Animations( editor );
	scroller.appendChild( elements.dom );

	/*
	var curves = new Timeline.Curves( editor );
	curves.setDisplay( 'none' );
	scroller.appendChild( curves.dom );
	*/

	function updateContainers() {

		var width = editor.duration * scale;

		elements.setWidth( width + 'px' );
		// curves.setWidth( width + 'px' );

	}

	//

	var loopMark = document.createElement( 'div' );
	loopMark.style.position = 'absolute';
	loopMark.style.top = 0;
	loopMark.style.height = 100 + '%';
	loopMark.style.width = 0;
	loopMark.style.background = 'rgba( 255, 255, 255, 0.1 )';
	loopMark.style.pointerEvents = 'none';
	loopMark.style.display = 'none';
	timeline.dom.appendChild( loopMark );

	var timeMark = document.createElement( 'div' );
	timeMark.style.position = 'absolute';
	timeMark.style.top = '0px';
	timeMark.style.left = '-8px';
	timeMark.style.width = '16px';
	timeMark.style.height = '100%';
	timeMark.style.background = 'linear-gradient(90deg, transparent 8px, #f00 8px, #f00 9px, transparent 9px) 0% 0% / 16px 16px repeat-y';
	timeMark.style.pointerEvents = 'none';
	timeline.dom.appendChild( timeMark );

	var timelineWidth;
	setTimeout(function() {
		timelineWidth = timeline.dom.offsetWidth - 8;
	}, 200);

	function updateTimeMark() {
		var offsetLeft = (player.currentTime * scale) - scroller.scrollLeft - 8;
		timeMark.style.left = offsetLeft + 'px';

		// Auto-scroll if end is reached
		if (editor.player.isPlaying && offsetLeft > timelineWidth) scroller.scrollLeft += timelineWidth;

		// TODO Optimise this

		var loop = player.getLoop();

		if ( Array.isArray( loop ) ) {

			var loopStart = loop[ 0 ] * scale;
			var loopEnd = loop[ 1 ] * scale;

			loopMark.style.display = '';
			loopMark.style.left = ( loopStart - scroller.scrollLeft ) + 'px';
			loopMark.style.width = ( loopEnd - loopStart ) + 'px';

		} else {

			loopMark.style.display = 'none';

		}

	}

	// signals

	signals.timeChanged.add( function () {

		updateTimeMark();

	} );

	signals.timelineScaled.add( function ( value ) {

		scale = value;

		scroller.scrollLeft = ( scroller.scrollLeft * value ) / prevScale;

		updateMarks();
		updateTimeMark();
		updateContainers();

		prevScale = value;

	} );

	signals.windowResized.add( function () {

		updateMarks();
		updateContainers();

	} );

	return container;

};
<|endoftext|>