<commit_before>var utils     = require('./utils')
  , implode   = require('implode')
  , Template  = require('./template')
  , Fragment  = require('./fragment')
  , Attribute = require('./attribute')
  , Element   = require('./element')

var State = module.exports = function() {
  this.fragments = {}
  this.sections = {}
  this.views = {}
  this.original = this
  this.currentView = null
  this.nextFragmentId = 0

  // per instance contract
  var contract = Array.apply(Array, this.$contract)
  contract.id = this.$contract.id
  Object.defineProperty(this, '$contract', { value: contract })
}

utils.eventify(State)
implode.register('swac/State', State, ['fragments', 'sections', 'views', 'path', 'events', 'nextFragmentId'])

State.prototype.HTML =
State.prototype.html =
State.prototype.formFor = require('./helper/form')

State.prototype.register = function(name, obj) {
  if (name in this) {
    if (Array.isArray(this[name]) && typeof this[name].reset === 'function')
      this[name].reset(obj)
    else {
      this[name] = obj
      this.emit('changed.' + name)
    }
    return
  }
  var that = this
    , value = null
  Object.defineProperty(this, name, {
    get: function get() {
      if (typeof get.caller.fragment != 'undefined')
        get.caller.fragment.observe(this, name)
      return value
    },
    set: function set(newValue) {
      if (value === newValue) return
      var old = value
      value = newValue
      if (set.caller === State.prototype.register) return
      if (old && typeof old.emit === 'function')
        old.emit('replaced')
      this.emit('changed.' + name)
    },
    enumerable: true
  })
  this[name] = obj
  this.$contract.push(name)
}

State.prototype.section = function section(name, opts) {
  var fragment = this.sections[name]
  if (!fragment && opts && opts.optional === true) {
    this.registerSection(name, 'function() {\n}')
    fragment = this.sections[name]
  } else if (!fragment) {
    throw new Error('Section ' + name + ' not defined')
  }

  var parent = section.caller.fragment
  if (parent) {
    parent.on('delete', fragment, 'dispose')
    fragment.once('delete', parent, 'off', parent, 'delete', fragment)
    parent.on('deleteContents', fragment, 'dispose')
    fragment.once('delete', parent, 'off', parent, 'deleteContents', fragment)
  }

  return fragment.wrap(fragment.render())
}

State.prototype.registerSection = function area(name, fn) {
  var template = new Template(fn)
  var fragment = createFragment(this.original, template, this.original)
  fragment.silent = true
  this.sections[name] = fragment

  if (!(this.currentView in this.views)) this.views[this.currentView] = {}
  this.views[this.currentView][name] = template
}

State.prototype.registerHelper = function(name, fn) {
  this.register(name, fn)
}

State.prototype.attr = function attr(/*attrName, [args.. ,] fn*/) {
  var args = Array.prototype.slice.call(arguments)
    , fn = args.pop()
    , attrName = args.shift()
    , template = new Template(fn, args)
    , attribute = createFragment(this.original, template, this.original, attr.caller.fragment, Attribute)

  var ret = 'data-bind-' + attrName + '="' + attribute.id + '" '
  ret += attrName + '="' + attribute.render() + '"'
  return ret
}

State.prototype.block = function block(/* [args.. ,] fn[, opts] */) {
  var args = Array.prototype.slice.call(arguments)
    , opts = args.pop()
    , fn = typeof opts === 'function' ? opts : args.pop()
    , template = new Template(fn, args)
    , fragment = createFragment(this.original, template, this.original, block.caller.fragment)
  if (typeof opts !== 'object') opts = {}
  if (opts.silent === true) fragment.silent = true
  return fragment.wrap(fragment.render())
}

State.prototype.collection = function collection(/* [tag, ]context[, args], fn[, opts] */) {
  var that = this
    , args = Array.prototype.slice.call(arguments)
    , opts = args.pop()
    , fn = typeof opts === 'function' ? opts : args.pop()
    , tag = args.shift()
    , context = Array.isArray(tag) ? tag : args.shift()
    , ret = ''
  if (typeof opts !== 'object') opts = {}
  if (tag === context) tag = undefined

  var template = new Template(fn, args)
    , list = createFragment(this.original, template, this.original, collection.caller.fragment)
  list.args = context
  if (tag) {
    if (typeof tag !== 'object') tag = { tag: tag }
    var attrs = {}
    for (var name in tag) {
      if (name === 'tag' || name === 'id') continue
      attrs[name] = tag[name]
    }
    list.factory = new utils.Factory(Element, tag.tag, attrs)
  }
  if (opts.silent) list.silent = true

  context.on('added', list, 'insert')
  list.once('delete', context, 'off', context, 'added', list)

  ret += '<!---{' + list.id + '-->'
  context.forEach(function(item) {
    var fragment = list.insert(item)
    fragment.id = that.original.nextFragmentId++
    that.original.fragments[fragment.id] = fragment

    ret += fragment.wrap(fragment.render())
  })
  ret += '<!---' + list.id + '}-->'
  return ret
}

State.prototype.serialize = function() {
  return JSON.stringify(implode(this.original))
}

State.deserialize = function(obj) {
  return implode.recover(obj)
}

State.prototype.$deserialize = function(obj) {
  var that = this
  Object.keys(obj).forEach(function(key) {
    switch(key) {
      case '_contract':
      case 'areas':
      case 'fragments':
      case 'original':
      case 'path':  return
      default:
        var val = obj[key]
        delete obj[key]
        obj.register(key, val)
    }
  })
  if (utils.isClient) {
    window.swac.views
    $(function() {
      utils.aquireFragments(document, window.app.fragments)
    })
  }
  return obj
}

function createFragment (app, template, context, parent, fn) {
  if (!fn) fn = Fragment
  var fragment = new fn(app.nextFragmentId++, template, context)
  app.fragments[fragment.id] = fragment

  if (parent) {
    parent.on('delete', fragment, 'dispose')
    fragment.once('delete', parent, 'off', parent, 'delete', fragment)
    parent.on('deleteContents', fragment, 'dispose')
    fragment.once('delete', parent, 'off', parent, 'deleteContents', fragment)
  }

  return fragment
}<commit_msg>Allow State Property Re-registration without a Value<commit_after>var utils     = require('./utils')
  , implode   = require('implode')
  , Template  = require('./template')
  , Fragment  = require('./fragment')
  , Attribute = require('./attribute')
  , Element   = require('./element')

var State = module.exports = function() {
  this.fragments = {}
  this.sections = {}
  this.views = {}
  this.original = this
  this.currentView = null
  this.nextFragmentId = 0

  // per instance contract
  var contract = Array.apply(Array, this.$contract)
  contract.id = this.$contract.id
  Object.defineProperty(this, '$contract', { value: contract })
}

utils.eventify(State)
implode.register('swac/State', State, ['fragments', 'sections', 'views', 'path', 'events', 'nextFragmentId'])

State.prototype.HTML =
State.prototype.html =
State.prototype.formFor = require('./helper/form')

State.prototype.register = function(name, obj) {
  if (name in this) {
    if (Array.isArray(this[name]) && typeof this[name].reset === 'function')
      this[name].reset(obj)
    else if(obj !== undefined) {
      this[name] = obj
      this.emit('changed.' + name)
    }
    return
  }
  var that = this
    , value = null
  Object.defineProperty(this, name, {
    get: function get() {
      if (typeof get.caller.fragment != 'undefined')
        get.caller.fragment.observe(this, name)
      return value
    },
    set: function set(newValue) {
      if (value === newValue) return
      var old = value
      value = newValue
      if (set.caller === State.prototype.register) return
      if (old && typeof old.emit === 'function')
        old.emit('replaced')
      this.emit('changed.' + name)
    },
    enumerable: true
  })
  this[name] = obj
  this.$contract.push(name)
}

State.prototype.section = function section(name, opts) {
  var fragment = this.sections[name]
  if (!fragment && opts && opts.optional === true) {
    this.registerSection(name, 'function() {\n}')
    fragment = this.sections[name]
  } else if (!fragment) {
    throw new Error('Section ' + name + ' not defined')
  }

  var parent = section.caller.fragment
  if (parent) {
    parent.on('delete', fragment, 'dispose')
    fragment.once('delete', parent, 'off', parent, 'delete', fragment)
    parent.on('deleteContents', fragment, 'dispose')
    fragment.once('delete', parent, 'off', parent, 'deleteContents', fragment)
  }

  return fragment.wrap(fragment.render())
}

State.prototype.registerSection = function area(name, fn) {
  var template = new Template(fn)
  var fragment = createFragment(this.original, template, this.original)
  fragment.silent = true
  this.sections[name] = fragment

  if (!(this.currentView in this.views)) this.views[this.currentView] = {}
  this.views[this.currentView][name] = template
}

State.prototype.registerHelper = function(name, fn) {
  this.register(name, fn)
}

State.prototype.attr = function attr(/*attrName, [args.. ,] fn*/) {
  var args = Array.prototype.slice.call(arguments)
    , fn = args.pop()
    , attrName = args.shift()
    , template = new Template(fn, args)
    , attribute = createFragment(this.original, template, this.original, attr.caller.fragment, Attribute)

  var ret = 'data-bind-' + attrName + '="' + attribute.id + '" '
  ret += attrName + '="' + attribute.render() + '"'
  return ret
}

State.prototype.block = function block(/* [args.. ,] fn[, opts] */) {
  var args = Array.prototype.slice.call(arguments)
    , opts = args.pop()
    , fn = typeof opts === 'function' ? opts : args.pop()
    , template = new Template(fn, args)
    , fragment = createFragment(this.original, template, this.original, block.caller.fragment)
  if (typeof opts !== 'object') opts = {}
  if (opts.silent === true) fragment.silent = true
  return fragment.wrap(fragment.render())
}

State.prototype.collection = function collection(/* [tag, ]context[, args], fn[, opts] */) {
  var that = this
    , args = Array.prototype.slice.call(arguments)
    , opts = args.pop()
    , fn = typeof opts === 'function' ? opts : args.pop()
    , tag = args.shift()
    , context = Array.isArray(tag) ? tag : args.shift()
    , ret = ''
  if (typeof opts !== 'object') opts = {}
  if (tag === context) tag = undefined

  var template = new Template(fn, args)
    , list = createFragment(this.original, template, this.original, collection.caller.fragment)
  list.args = context
  if (tag) {
    if (typeof tag !== 'object') tag = { tag: tag }
    var attrs = {}
    for (var name in tag) {
      if (name === 'tag' || name === 'id') continue
      attrs[name] = tag[name]
    }
    list.factory = new utils.Factory(Element, tag.tag, attrs)
  }
  if (opts.silent) list.silent = true

  context.on('added', list, 'insert')
  list.once('delete', context, 'off', context, 'added', list)

  ret += '<!---{' + list.id + '-->'
  context.forEach(function(item) {
    var fragment = list.insert(item)
    fragment.id = that.original.nextFragmentId++
    that.original.fragments[fragment.id] = fragment

    ret += fragment.wrap(fragment.render())
  })
  ret += '<!---' + list.id + '}-->'
  return ret
}

State.prototype.serialize = function() {
  return JSON.stringify(implode(this.original))
}

State.deserialize = function(obj) {
  return implode.recover(obj)
}

State.prototype.$deserialize = function(obj) {
  var that = this
  Object.keys(obj).forEach(function(key) {
    switch(key) {
      case '_contract':
      case 'areas':
      case 'fragments':
      case 'original':
      case 'path':  return
      default:
        var val = obj[key]
        delete obj[key]
        obj.register(key, val)
    }
  })
  if (utils.isClient) {
    window.swac.views
    $(function() {
      utils.aquireFragments(document, window.app.fragments)
    })
  }
  return obj
}

function createFragment (app, template, context, parent, fn) {
  if (!fn) fn = Fragment
  var fragment = new fn(app.nextFragmentId++, template, context)
  app.fragments[fragment.id] = fragment

  if (parent) {
    parent.on('delete', fragment, 'dispose')
    fragment.once('delete', parent, 'off', parent, 'delete', fragment)
    parent.on('deleteContents', fragment, 'dispose')
    fragment.once('delete', parent, 'off', parent, 'deleteContents', fragment)
  }

  return fragment
}<|endoftext|>


<commit_before>const os = require('os');
const fs = require('fs');
const path = require('path');
const sleep = require('sleep');
const decompress = require('decompress');
const csvParse = require('csv-parse/lib/sync');

const utils = require('./utils');

const LAYER = 'stop';

/** return the records array */
function makeRecord(rec, agencyId) {
    const id = `${rec.stop_id}::${agencyId}`;
    var name = rec.stop_name;
    if(name == null)
        name = rec.stop_desc;
    var retVal = utils.makePeliasRecord(LAYER, id, name, rec.stop_lat, rec.stop_lon);
    return retVal;
}

/** parse stops.txt and return a record */
function stopsTxtFileToRecords(stopsPath, agencyId, doAdminLookup) {

    // step 1: open stops.txt
    fs.readFile(stopsPath, 'utf8', function (err, data) {
        if (err) {
            utils.logger.error(err);
            return;
        }

        // step 2: parse the csv data from stops.txt
        var csvArray = csvParse(data, {
            skip_empty_lines: true,
            columns: true
        });

        // step 3: create Pelias/ES records for each .csv record
        var recArray = [];
        if(csvArray) {
            for(var i = 0; i < csvArray.length; i++) {
                var rec = makeRecord(csvArray[i], agencyId);
                recArray.push(rec);
            }
        }

    });

    //const lat = record['Geocoded Location'].match(latLonRegex);

}

/** load a stops.txt file and return it as a record */
function loadGtfsStops(filePath, agencyId, doAdminLookup) {
    records = [];
    if(filePath.endsWith(".zip")) {
        const tmp = os.tmpdir();
        decompress(filePath, tmp, {filter: file => file.path == 'stops.txt'}).then(files => {
            var stopsPath = path.join(tmp, 'stops.txt');
            stopsTxtFileToRecords(stopsPath, agencyId, doAdminLookup);
        });
    } else {
        stopsTxtFileToRecords(filePath, agencyId, doAdminLookup);
    }
}

module.exports = {
    loadGtfsStops : loadGtfsStops
};<commit_msg>move admin lookup crap out of transit config<commit_after>const os = require('os');
const fs = require('fs');
const path = require('path');
const sleep = require('sleep');
const decompress = require('decompress');
const csvParse = require('csv-parse/lib/sync');

const utils = require('./utils');

const LAYER = 'stop';

/** return the records array */
function makeRecord(rec, agencyId) {
    const id = `${rec.stop_id}::${agencyId}`;
    var name = rec.stop_name;
    if(name == null)
        name = rec.stop_desc;
    var retVal = utils.makePeliasRecord(LAYER, id, name, rec.stop_lat, rec.stop_lon);
    return retVal;
}

/** parse stops.txt and return a record */
function stopsTxtFileToRecords(stopsPath, agencyId) {

    // step 1: open stops.txt
    fs.readFile(stopsPath, 'utf8', function (err, data) {
        if (err) {
            utils.logger.error(err);
            return;
        }

        // step 2: parse the csv data from stops.txt
        var csvArray = csvParse(data, {
            skip_empty_lines: true,
            columns: true
        });

        // step 3: create Pelias/ES records for each .csv record
        var recArray = [];
        if(csvArray) {
            for(var i = 0; i < csvArray.length; i++) {
                var rec = makeRecord(csvArray[i], agencyId);
                recArray.push(rec);
            }
        }
    });
}

/** load a stops.txt file and return it as a record */
function loadGtfsStops(filePath, agencyId) {
    records = [];
    if(filePath.endsWith(".zip")) {
        const tmp = os.tmpdir();
        decompress(filePath, tmp, {filter: file => file.path == 'stops.txt'}).then(files => {
            var stopsPath = path.join(tmp, 'stops.txt');
            stopsTxtFileToRecords(stopsPath, agencyId);
        });
    } else {
        stopsTxtFileToRecords(filePath, agencyId);
    }
}

module.exports = {
    loadGtfsStops : loadGtfsStops
};<|endoftext|>


<commit_before>$(document).ready(function init() {
  var canvas = document.getElementById('magic-triangles'),
  stage = new createjs.Stage(canvas),
  initial_triangle_size = canvas.width * 0.8,
  initial_triangle_x = canvas.width / 2,
  initial_triangle_y = canvas.height / 2,
  vertical_ratio = 0.866,
  rotation_speed = 330;

  function createTriangle(size, x, y, upside_down) {
    var shape = new createjs.Shape(),
    g = shape.graphics,
    horizontal_offset = size / 2,
    vertical_offset = size * vertical_ratio / 3;

    shape.x = x;
    shape.y = y;
    shape.size = size;
    shape.upside_down = upside_down ? true : false;

    if (upside_down) {
      vertical_offset = vertical_offset * -1;
    }

    g.setStrokeStyle(1);
    g.beginStroke("black");

    g.moveTo(0, -2 * vertical_offset);
    g.lineTo(-1 * horizontal_offset, vertical_offset);
    g.lineTo(horizontal_offset, vertical_offset);
    g.lineTo(0, -2 * vertical_offset);

    return shape;
  }

  function remove_from_stage(child) {
    stage.removeChild(child);
  }

  function rotate(triangles) {
    $.each(triangles, function(k, v) {
      stage.addChild(v);
      var direction = !v.upside_down ? 1 : -1;
      createjs.Tween.get(v)
        .to({rotation: direction * 60}, rotation_speed, createjs.Ease.quadInOut);
      if (v.hasOwnProperty("children")){
        createjs.Tween.get(v)
                      .wait(rotation_speed * 2)
                      .call(rotate, [v.children]);
      }
      else {
        createjs.Tween.get(v)
                      .wait(rotation_speed * 2)
                      .call(reset, [v]);
      }
    });
  }

  function reset(triangle) {
    createjs.Tween.get(triangle)
        .to({rotation: 0}, rotation_speed, createjs.Ease.quadInOut)
        .call(remove_from_stage, [triangle]);

    if ( triangle.t_parent ) {
      console.log(triangle);
      createjs.Tween.get(triangle.t_parent)
                    .wait(rotation_speed * 2)
                    .call(reset, [triangle.t_parent]);
    }

    if ( triangle.iAmTheRoot ) {
      createjs.Tween.get(triangle.t_parent)
                    .wait(rotation_speed * 2)
                    .call(rotate, [[triangle]]);
    }
  }

  function createSubTriangles(parent, x, y, size, depth){
    parent.children = [];
    var height = size * vertical_ratio;

    // top
    parent.children.push(createTriangle(size, x, y - (height * 4 / 3)));
    // bottom-left
    parent.children.push(createTriangle(size, x - size, y + (height * 2 / 3)));
    // bottom-right
    parent.children.push(createTriangle(size, x + size, y + (height * 2 / 3)));
    // upside-down triangles
    // top-left
    parent.children.push(createTriangle(size, x - size, y - (height * 2 / 3), true));
    // top-right
    parent.children.push(createTriangle(size, x + size, y - (height * 2 / 3), true));
    // bottom
    parent.children.push(createTriangle(size, x, y + (height * 4 / 3), true));

    // only the first child has a reference to it's parent
    // this prevents multiple children from calling reset on their parent
    parent.children[0].t_parent = parent;

    // do we create sub triangles of the sub-triangles?
    if (depth < 4) {
      $.each(parent.children,  function(i, t) {
        createSubTriangles(t, t.x, t.y, t.size / 3, depth + 1);
      });
    }
  }

  function setupAndAnimate() {
    // static triangle that never changes
    stage.addChild(createTriangle(initial_triangle_size, initial_triangle_x, initial_triangle_y));
    rootTriangle = createTriangle(initial_triangle_size, initial_triangle_x, initial_triangle_y);
    rootTriangle.iAmTheRoot = true;
    createSubTriangles(rootTriangle, initial_triangle_x, initial_triangle_y, initial_triangle_size / 3, 1);

    // start the party
    rotate([rootTriangle]);
    createjs.Ticker.setFPS(60);
    createjs.Ticker.addEventListener("tick", stage);
  }

  setupAndAnimate();
})

<commit_msg>Phrasing.<commit_after>$(document).ready(function init() {
  var canvas = document.getElementById('magic-triangles'),
  stage = new createjs.Stage(canvas),
  initial_triangle_size = canvas.width * 0.8,
  initial_triangle_x = canvas.width / 2,
  initial_triangle_y = canvas.height / 2,
  vertical_ratio = 0.866,
  rotation_speed = 330;

  function createTriangle(size, x, y, upside_down) {
    var shape = new createjs.Shape(),
    g = shape.graphics,
    horizontal_offset = size / 2,
    vertical_offset = size * vertical_ratio / 3;

    shape.x = x;
    shape.y = y;
    shape.size = size;
    shape.upside_down = upside_down ? true : false;

    if (upside_down) {
      vertical_offset = vertical_offset * -1;
    }

    g.setStrokeStyle(1);
    g.beginStroke("black");

    g.moveTo(0, -2 * vertical_offset);
    g.lineTo(-1 * horizontal_offset, vertical_offset);
    g.lineTo(horizontal_offset, vertical_offset);
    g.lineTo(0, -2 * vertical_offset);

    return shape;
  }

  function remove_from_stage(child) {
    stage.removeChild(child);
  }

  function rotate(triangles) {
    $.each(triangles, function(k, v) {
      stage.addChild(v);
      var direction = !v.upside_down ? 1 : -1;
      createjs.Tween.get(v)
        .to({rotation: direction * 60}, rotation_speed, createjs.Ease.quadInOut);
      if (v.hasOwnProperty("children")){
        createjs.Tween.get(v)
                      .wait(rotation_speed * 2)
                      .call(rotate, [v.children]);
      }
      else {
        createjs.Tween.get(v)
                      .wait(rotation_speed * 2)
                      .call(reset, [v]);
      }
    });
  }

  function reset(triangle) {
    createjs.Tween.get(triangle)
        .to({rotation: 0}, rotation_speed, createjs.Ease.quadInOut)
        .call(remove_from_stage, [triangle]);

    if ( triangle.t_parent ) {
      console.log(triangle);
      createjs.Tween.get(triangle.t_parent)
                    .wait(rotation_speed * 2)
                    .call(reset, [triangle.t_parent]);
    }

    if ( triangle.iAmTheRoot ) {
      createjs.Tween.get(triangle.t_parent)
                    .wait(rotation_speed * 2)
                    .call(rotate, [[triangle]]);
    }
  }

  function createSubTriangles(parent, x, y, size, depth){
    parent.children = [];
    var height = size * vertical_ratio;

    // top
    parent.children.push(createTriangle(size, x, y - (height * 4 / 3)));
    // bottom-left
    parent.children.push(createTriangle(size, x - size, y + (height * 2 / 3)));
    // bottom-right
    parent.children.push(createTriangle(size, x + size, y + (height * 2 / 3)));
    // upside-down triangles
    // top-left
    parent.children.push(createTriangle(size, x - size, y - (height * 2 / 3), true));
    // top-right
    parent.children.push(createTriangle(size, x + size, y - (height * 2 / 3), true));
    // bottom
    parent.children.push(createTriangle(size, x, y + (height * 4 / 3), true));

    // only the first child has a reference to it's parent
    // this prevents multiple children from calling reset on their parent
    parent.children[0].t_parent = parent;

    // create subtriangles up to a certain depth
    if (depth < 4) {
      $.each(parent.children,  function(i, t) {
        createSubTriangles(t, t.x, t.y, t.size / 3, depth + 1);
      });
    }
  }

  function setupAndAnimate() {
    // static triangle that never changes
    stage.addChild(createTriangle(initial_triangle_size, initial_triangle_x, initial_triangle_y));
    rootTriangle = createTriangle(initial_triangle_size, initial_triangle_x, initial_triangle_y);
    rootTriangle.iAmTheRoot = true;
    createSubTriangles(rootTriangle, initial_triangle_x, initial_triangle_y, initial_triangle_size / 3, 1);

    // start the party
    rotate([rootTriangle]);
    createjs.Ticker.setFPS(60);
    createjs.Ticker.addEventListener("tick", stage);
  }

  setupAndAnimate();
})

<|endoftext|>


<commit_before>var CHANGE_EVENT = 'changed';
var _ = require('underscore');
var uuid = require('./utils/uuid');
var Dispatcher = require('./dispatcher');
var Diagnostics = require('./diagnostics');
var NotFoundError = require('./errors/notFound');
var EventEmitter = require('events').EventEmitter;
var CompoundError = require('./errors/compoundError');
var Statuses = require('./internalConstants').Statuses;
var ActionHandlerNotFoundError = require('./errors/actionHandlerNotFound');
var ActionPredicateUndefinedError = require('./errors/actionPredicateUndefined');

Store.defaultMaxListeners = 10000000;

function Store(options) {
  var state;
  var store = this;
  var failedFetches = {};
  var defaultState = {};
  var fetchInProgress = {};
  var emitter = new EventEmitter();
  var dispatcher = options.dispatcher || Dispatcher.getCurrent();

  this.handlers = {};
  this.fetch = fetch;
  this.clear = clear;
  this.dispose = dispose;
  this.waitFor = waitFor;
  this.id = uuid.small();
  this.setState = setState;
  this.getState = getState;
  this.hasChanged = hasChanged;
  this.handleAction = handleAction;
  this.getInitialState = getInitialState;
  this.addChangeListener = addChangeListener;

  fetch.done = fetchDone;
  fetch.failed = fetchFailed;
  fetch.pending = fetchPending;

  emitter.setMaxListeners(options.maxListeners || Store.defaultMaxListeners);

  extendStore(this, options);
  validateHandlers(this);

  this.dispatchToken = dispatcher.register(_.bind(this.handleAction, this));
  state = this.getInitialState();

  if (_.isNull(state) || _.isUndefined(state)) {
    state = defaultState;
  }

  Object.defineProperty(this, 'state', {
    get: function () {
      return getState();
    },
    set: function (value) {
      this.setState(value);
    }
  });

  function validateHandlers(store) {
    _.each(store.handlers, function (actionPredicate, handlerName) {
      var actionHandler = store[handlerName];

      if (_.isUndefined(actionHandler) || _.isNull(actionHandler)) {
        throw new ActionHandlerNotFoundError(handlerName, store);
      }

      if (!actionPredicate) {
        throw new ActionPredicateUndefinedError(handlerName, store);
      }
    });
  }

  function extendStore(store, options) {
    var handlers = _.map(options.mixins, function (mixin) {
      return mixin.handlers;
    });

    var mixins = _.map(options.mixins, function (mixin) {
      return _.omit(mixin, 'handlers');
    });

    _.extend.apply(_, [store, options].concat(mixins));
    _.extend.apply(_, [store.handlers].concat(handlers));
  }

  function getInitialState() {
    return defaultState;
  }

  function dispose() {
    emitter.removeAllListeners(CHANGE_EVENT);
    store.clear();
  }

  function fetch(id, local, remote) {
    var options, result, error, cacheError;

    if (_.isObject(id)) {
      options = id;
    } else {
      options = {
        id: id,
        locally: local,
        remotely: remote
      };
    }

    if (!options || !options.id) {
      throw new Error('must specify an id');
    }

    result = dependencyResult(options);

    if (result) {
      return result;
    }

    cacheError = _.isUndefined(options.cacheError) || options.cacheError;

    if (cacheError) {
      error = failedFetches[options.id];

      if (error) {
        return fetch.failed(error);
      }
    }

    if (fetchInProgress[options.id]) {
      return fetch.pending();
    }

    return tryAndGetLocally() || tryAndGetRemotely();

    function tryAndGetLocally() {
      try {
        var result = options.locally.call(store);

        if (result) {
          return fetch.done(result);
        }
      } catch (error) {
        failedFetches[options.id] = error;

        return fetch.failed(error);
      }
    }

    function tryAndGetRemotely() {
      try {
        result = options.remotely.call(store);

        if (result) {
          if (_.isFunction(result.then)) {
            fetchInProgress[options.id] = true;

            result.then(function () {
              result = tryAndGetLocally();

              if (result) {
                fetchFinished();
                hasChanged();
              } else {
                failed(new NotFoundError());
                hasChanged();
              }
            }).catch(function (error) {
              failed(error);
              hasChanged();
            });

            return fetch.pending();
          } else {
            result = tryAndGetLocally();

            if (result) {
              return result;
            }
          }
        }

        return failed(new NotFoundError());
      } catch (error) {
        return failed(error);
      }
    }

    function fetchFinished() {
      delete fetchInProgress[options.id];
    }

    function failed(error) {
      if (cacheError) {
        failedFetches[options.id] = error;
      }

      return fetch.failed(error);
    }
  }

  function dependencyResult(options) {
    if (options.dependsOn) {
      if (_.isArray(options.dependsOn)) {
        var pending = false;
        var dependencyErrors = [];
        for (var i = 0; i < options.dependsOn.length; i++) {
          var dependency = options.dependsOn[i];

          switch (dependency.status) {
            case Statuses.PENDING:
              pending = true;
              break;
            case Statuses.FAILED:
              dependencyErrors.push(dependency.error);
              break;
          }
        }

        if (dependencyErrors.length) {
          return fetch.failed(new CompoundError(dependencyErrors));
        }

        if (pending) {
          return fetch.pending();
        }
      } else {
        if (!options.dependsOn.done) {
          return options.dependsOn;
        }
      }
    }
  }

  function fetchPending() {
    return fetchResult({
      pending: true,
      status: 'PENDING'
    });
  }

  function fetchFailed(error) {
    return fetchResult({
      error: error,
      failed: true,
      status: 'FAILED'
    });
  }

  function fetchDone(result) {
    return fetchResult({
      done: true,
      status: 'DONE',
      result: result
    });
  }

  function fetchResult(result) {
    result.when = when;

    return result;
  }

  function when(handlers) {
    handlers || (handlers = {});

    var status = this.status;
    var handler = handlers[status.toLowerCase()];

    if (!handler) {
      throw new Error('Could not find a ' + status + ' handler');
    }

    switch (status) {
      case Statuses.PENDING:
        return handler();
      case Statuses.FAILED:
        return handler(this.error);
      case Statuses.DONE:
        return handler(this.result);
    }
  }

  function clear() {
    failedFetches = {};
    fetchInProgress = {};
    store.state = store.getInitialState();
  }

  function setState(newState) {
    if (state !== newState) {
      state = newState;
      store.hasChanged(state);
    }
  }

  function getState() {
    return state;
  }

  function addChangeListener(callback, context) {
    if (context) {
      callback = _.bind(callback, context);
    }

    Diagnostics.trace('The', store.name, 'store (' + store.id + ') is adding a change listener');
    emitter.on(CHANGE_EVENT, callback);

    return {
      dispose: function () {
        Diagnostics.trace('The', store.name, 'store (' + store.id + ') is disposing of a change listener');
        emitter.removeListener(CHANGE_EVENT, callback);
      }
    };
  }

  function hasChanged(eventArgs) {
    emitter.emit.call(emitter, CHANGE_EVENT, store.state, store, eventArgs);
  }

  function handleAction(action) {
    var handlers = _.object(_.map(store.handlers, getHandlerWithPredicates));

    _.each(handlers, function (predicates, handlerName) {
      _.each(predicates, function (predicate) {
        if (predicate(action)) {
          var rollbackHandler, actionHandler;
          var handler = action.addStoreHandler(this, handlerName, predicate.toJSON());

          try {
            this.action = action;
            actionHandler = this[handlerName];

            if (actionHandler) {
              rollbackHandler = actionHandler.apply(this, action.arguments);
            } else {
              throw new ActionHandlerNotFoundError(handlerName, this);
            }
          } catch (e) {
            handler.failed(e);
            throw e;
          } finally {
            this.action = null;

            action.addRollbackHandler(rollbackHandler, this);

            if (handler) {
              handler.dispose();
            }
          }
        }
      }, this);
    }, this);

    function getHandlerWithPredicates(actionPredicates, handler) {
      _.isArray(actionPredicates) || (actionPredicates = [actionPredicates]);

      var predicates = _.map(actionPredicates, toFunc);

      return [handler, predicates];

      function toFunc(actionPredicate) {
        if (_.isString(actionPredicate)) {
          actionPredicate = {
            type: actionPredicate
          };
        }

        var func = _.matches(actionPredicate);

        func.toJSON = function () {
          return actionPredicate;
        };

        return func;
      }
    }
  }

  function waitFor(stores) {
    if (!_.isArray(stores)) {
      stores = _.toArray(arguments);
    }

    dispatcher.waitFor(dispatchTokens(stores));

    function dispatchTokens(stores) {
      var tokens = [];

      _.each(stores, function (store) {
        if (store.dispatchToken) {
          tokens.push(store.dispatchToken);
        }

        if (_.isString(store)) {
          tokens.push(store);
        }
      });

      return tokens;
    }
  }
}

module.exports = Store;<commit_msg>Fix context object for status store handlers<commit_after>var CHANGE_EVENT = 'changed';
var _ = require('underscore');
var uuid = require('./utils/uuid');
var Dispatcher = require('./dispatcher');
var Diagnostics = require('./diagnostics');
var NotFoundError = require('./errors/notFound');
var EventEmitter = require('events').EventEmitter;
var CompoundError = require('./errors/compoundError');
var Statuses = require('./internalConstants').Statuses;
var ActionHandlerNotFoundError = require('./errors/actionHandlerNotFound');
var ActionPredicateUndefinedError = require('./errors/actionPredicateUndefined');

Store.defaultMaxListeners = 10000000;

function Store(options) {
  var state;
  var store = this;
  var failedFetches = {};
  var defaultState = {};
  var fetchInProgress = {};
  var emitter = new EventEmitter();
  var dispatcher = options.dispatcher || Dispatcher.getCurrent();

  this.handlers = {};
  this.fetch = fetch;
  this.clear = clear;
  this.dispose = dispose;
  this.waitFor = waitFor;
  this.id = uuid.small();
  this.setState = setState;
  this.getState = getState;
  this.hasChanged = hasChanged;
  this.handleAction = handleAction;
  this.getInitialState = getInitialState;
  this.addChangeListener = addChangeListener;

  fetch.done = fetchDone;
  fetch.failed = fetchFailed;
  fetch.pending = fetchPending;

  emitter.setMaxListeners(options.maxListeners || Store.defaultMaxListeners);

  extendStore(this, options);
  validateHandlers(this);

  this.dispatchToken = dispatcher.register(_.bind(this.handleAction, this));
  state = this.getInitialState();

  if (_.isNull(state) || _.isUndefined(state)) {
    state = defaultState;
  }

  Object.defineProperty(this, 'state', {
    get: function () {
      return getState();
    },
    set: function (value) {
      this.setState(value);
    }
  });

  function validateHandlers(store) {
    _.each(store.handlers, function (actionPredicate, handlerName) {
      var actionHandler = store[handlerName];

      if (_.isUndefined(actionHandler) || _.isNull(actionHandler)) {
        throw new ActionHandlerNotFoundError(handlerName, store);
      }

      if (!actionPredicate) {
        throw new ActionPredicateUndefinedError(handlerName, store);
      }
    });
  }

  function extendStore(store, options) {
    var handlers = _.map(options.mixins, function (mixin) {
      return mixin.handlers;
    });

    var mixins = _.map(options.mixins, function (mixin) {
      return _.omit(mixin, 'handlers');
    });

    _.extend.apply(_, [store, options].concat(mixins));
    _.extend.apply(_, [store.handlers].concat(handlers));
  }

  function getInitialState() {
    return defaultState;
  }

  function dispose() {
    emitter.removeAllListeners(CHANGE_EVENT);
    store.clear();
  }

  function fetch(id, local, remote) {
    var options, result, error, cacheError;

    if (_.isObject(id)) {
      options = id;
    } else {
      options = {
        id: id,
        locally: local,
        remotely: remote
      };
    }

    if (!options || !options.id) {
      throw new Error('must specify an id');
    }

    result = dependencyResult(options);

    if (result) {
      return result;
    }

    cacheError = _.isUndefined(options.cacheError) || options.cacheError;

    if (cacheError) {
      error = failedFetches[options.id];

      if (error) {
        return fetch.failed(error);
      }
    }

    if (fetchInProgress[options.id]) {
      return fetch.pending();
    }

    return tryAndGetLocally() || tryAndGetRemotely();

    function tryAndGetLocally() {
      try {
        var result = options.locally.call(store);

        if (result) {
          return fetch.done(result);
        }
      } catch (error) {
        failedFetches[options.id] = error;

        return fetch.failed(error);
      }
    }

    function tryAndGetRemotely() {
      try {
        result = options.remotely.call(store);

        if (result) {
          if (_.isFunction(result.then)) {
            fetchInProgress[options.id] = true;

            result.then(function () {
              result = tryAndGetLocally();

              if (result) {
                fetchFinished();
                hasChanged();
              } else {
                failed(new NotFoundError());
                hasChanged();
              }
            }).catch(function (error) {
              failed(error);
              hasChanged();
            });

            return fetch.pending();
          } else {
            result = tryAndGetLocally();

            if (result) {
              return result;
            }
          }
        }

        return failed(new NotFoundError());
      } catch (error) {
        return failed(error);
      }
    }

    function fetchFinished() {
      delete fetchInProgress[options.id];
    }

    function failed(error) {
      if (cacheError) {
        failedFetches[options.id] = error;
      }

      return fetch.failed(error);
    }
  }

  function dependencyResult(options) {
    if (options.dependsOn) {
      if (_.isArray(options.dependsOn)) {
        var pending = false;
        var dependencyErrors = [];
        for (var i = 0; i < options.dependsOn.length; i++) {
          var dependency = options.dependsOn[i];

          switch (dependency.status) {
            case Statuses.PENDING:
              pending = true;
              break;
            case Statuses.FAILED:
              dependencyErrors.push(dependency.error);
              break;
          }
        }

        if (dependencyErrors.length) {
          return fetch.failed(new CompoundError(dependencyErrors));
        }

        if (pending) {
          return fetch.pending();
        }
      } else {
        if (!options.dependsOn.done) {
          return options.dependsOn;
        }
      }
    }
  }

  function fetchPending() {
    return fetchResult({
      pending: true,
      status: 'PENDING'
    });
  }

  function fetchFailed(error) {
    return fetchResult({
      error: error,
      failed: true,
      status: 'FAILED'
    });
  }

  function fetchDone(result) {
    return fetchResult({
      done: true,
      status: 'DONE',
      result: result
    });
  }

  function fetchResult(result) {
    result.when = when;

    return result;
  }

  function when(handlers) {
    handlers || (handlers = {});

    var status = this.status;
    var handler = handlers[status.toLowerCase()];

    if (!handler) {
      throw new Error('Could not find a ' + status + ' handler');
    }

    switch (status) {
      case Statuses.PENDING:
        return handler.call(handlers);
      case Statuses.FAILED:
        return handler.call(handlers, this.error);
      case Statuses.DONE:
        return handler.call(handlers, this.result);
    }
  }

  function clear() {
    failedFetches = {};
    fetchInProgress = {};
    store.state = store.getInitialState();
  }

  function setState(newState) {
    if (state !== newState) {
      state = newState;
      store.hasChanged(state);
    }
  }

  function getState() {
    return state;
  }

  function addChangeListener(callback, context) {
    if (context) {
      callback = _.bind(callback, context);
    }

    Diagnostics.trace('The', store.name, 'store (' + store.id + ') is adding a change listener');
    emitter.on(CHANGE_EVENT, callback);

    return {
      dispose: function () {
        Diagnostics.trace('The', store.name, 'store (' + store.id + ') is disposing of a change listener');
        emitter.removeListener(CHANGE_EVENT, callback);
      }
    };
  }

  function hasChanged(eventArgs) {
    emitter.emit.call(emitter, CHANGE_EVENT, store.state, store, eventArgs);
  }

  function handleAction(action) {
    var handlers = _.object(_.map(store.handlers, getHandlerWithPredicates));

    _.each(handlers, function (predicates, handlerName) {
      _.each(predicates, function (predicate) {
        if (predicate(action)) {
          var rollbackHandler, actionHandler;
          var handler = action.addStoreHandler(this, handlerName, predicate.toJSON());

          try {
            this.action = action;
            actionHandler = this[handlerName];

            if (actionHandler) {
              rollbackHandler = actionHandler.apply(this, action.arguments);
            } else {
              throw new ActionHandlerNotFoundError(handlerName, this);
            }
          } catch (e) {
            handler.failed(e);
            throw e;
          } finally {
            this.action = null;

            action.addRollbackHandler(rollbackHandler, this);

            if (handler) {
              handler.dispose();
            }
          }
        }
      }, this);
    }, this);

    function getHandlerWithPredicates(actionPredicates, handler) {
      _.isArray(actionPredicates) || (actionPredicates = [actionPredicates]);

      var predicates = _.map(actionPredicates, toFunc);

      return [handler, predicates];

      function toFunc(actionPredicate) {
        if (_.isString(actionPredicate)) {
          actionPredicate = {
            type: actionPredicate
          };
        }

        var func = _.matches(actionPredicate);

        func.toJSON = function () {
          return actionPredicate;
        };

        return func;
      }
    }
  }

  function waitFor(stores) {
    if (!_.isArray(stores)) {
      stores = _.toArray(arguments);
    }

    dispatcher.waitFor(dispatchTokens(stores));

    function dispatchTokens(stores) {
      var tokens = [];

      _.each(stores, function (store) {
        if (store.dispatchToken) {
          tokens.push(store.dispatchToken);
        }

        if (_.isString(store)) {
          tokens.push(store);
        }
      });

      return tokens;
    }
  }
}

module.exports = Store;<|endoftext|>


<commit_before>
var count = require('./count')
var getSBOL = require('./getSBOL')
var searchMetadata = require('./searchMetadata')
var getMetadata = require('./getMetadata')
var searchSBOL = require('./searchSBOL')
var doSparql = require('./sparql')
var doUpload = require('./upload')

function Store(storeUrl, auth) {

    this.storeUrl = storeUrl
    this.auth = auth

}

module.exports = Store

Store.prototype = {

    sparql: sparql,

    upload: upload,

    countComponents: countComponents,
    countSequences: countSequences,
    countModules: countModules,
    countCollections: countCollections,

    searchComponentSBOL: searchComponentSBOL,
    searchComponentMetadata: searchComponentMetadata,

    getComponentSBOL: getComponentSBOL,
    getCollectionSBOL: getCollectionSBOL,

    getComponentMetadata: getComponentMetadata
}

function sparql(query, accept, callback) {

    var args = [].slice.call(arguments, 0)

    if(args.length < 3) {
        query = args[0]
        callback = args[1]
        accept = null
    }

    doSparql(this.storeUrl, this.auth, query, accept, callback)
}

function countComponents(callback) {
    count('component', this.storeUrl, this.auth, callback);
}

function countSequences(callback) {
    count('sequence', this.storeUrl, this.auth, callback);
}

function countModules(callback) {
    count('module', this.storeUrl, this.auth, callback);
}

function countCollections(callback) {
    count('collection', this.storeUrl, this.auth, callback);
}

function searchComponentSBOL(criteria, callback) {
    searchSBOL('component', this.storeUrl, this.auth, criteria, callback);
}

function searchComponentMetadata(criteria, callback) {
    searchMetadata('component', this.storeUrl, this.auth, criteria, callback);
}

function getComponentSBOL(prefix, uri, callback) {

    var args = [].slice.call(arguments, 0)

    if(args.length < 3) {
        uri = args[0]
        callback = args[1]
        prefix = null
    }

    getSBOL('component', this.storeUrl, this.auth, prefix, uri, function(err, sbol) {

        if(err) {
            callback(err)
        } else {
            callback(null, sbol, sbol.lookupURI(uri))
        }
    });
}

function getCollectionSBOL(prefix, uri, callback) {

    var args = [].slice.call(arguments, 0)

    if(args.length < 3) {
        uri = args[0]
        callback = args[1]
        prefix = null
    }

    getSBOL('collection', this.storeUrl, this.auth, prefix, uri, function(err, sbol) {

        if(err) {
            callback(err)
        } else {
            callback(null, sbol, sbol.lookupURI(uri))
        }
    });
}

function upload(data, callback) {

    doUpload(this.storeUrl, this.auth, data, callback)

}

function getComponentMetadata(prefix, uri, callback) {

    var args = [].slice.call(arguments, 0)

    if(args.length < 3) {
        uri = args[0]
        callback = args[1]
        prefix = null
    }

    getMetadata('component', this.storeUrl, this.auth, prefix, uri, callback);

}

<commit_msg>Added module get methods<commit_after>
var count = require('./count')
var getSBOL = require('./getSBOL')
var searchMetadata = require('./searchMetadata')
var getMetadata = require('./getMetadata')
var searchSBOL = require('./searchSBOL')
var doSparql = require('./sparql')
var doUpload = require('./upload')

function Store(storeUrl, auth) {

    this.storeUrl = storeUrl
    this.auth = auth

}

module.exports = Store

Store.prototype = {

    sparql: sparql,

    upload: upload,

    countComponents: countComponents,
    countSequences: countSequences,
    countModules: countModules,
    countCollections: countCollections,

    searchComponentSBOL: searchComponentSBOL,
    searchComponentMetadata: searchComponentMetadata,

    getComponentSBOL: getComponentSBOL,
    getModuleSBOL: getModuleSBOL,
    getCollectionSBOL: getCollectionSBOL,

    getComponentMetadata: getComponentMetadata,
    getModuleMetadata: getModuleMetadata
}

function sparql(query, accept, callback) {

    var args = [].slice.call(arguments, 0)

    if(args.length < 3) {
        query = args[0]
        callback = args[1]
        accept = null
    }

    doSparql(this.storeUrl, this.auth, query, accept, callback)
}

function countComponents(callback) {
    count('component', this.storeUrl, this.auth, callback);
}

function countSequences(callback) {
    count('sequence', this.storeUrl, this.auth, callback);
}

function countModules(callback) {
    count('module', this.storeUrl, this.auth, callback);
}

function countCollections(callback) {
    count('collection', this.storeUrl, this.auth, callback);
}

function searchComponentSBOL(criteria, callback) {
    searchSBOL('component', this.storeUrl, this.auth, criteria, callback);
}

function searchComponentMetadata(criteria, callback) {
    searchMetadata('component', this.storeUrl, this.auth, criteria, callback);
}

function getComponentSBOL(prefix, uri, callback) {

    var args = [].slice.call(arguments, 0)

    if(args.length < 3) {
        uri = args[0]
        callback = args[1]
        prefix = null
    }

    getSBOL('component', this.storeUrl, this.auth, prefix, uri, function(err, sbol) {

        if(err) {
            callback(err)
        } else {
            callback(null, sbol, sbol.lookupURI(uri))
        }
    });
}

function getModuleSBOL(prefix, uri, callback) {

    var args = [].slice.call(arguments, 0)

    if(args.length < 3) {
        uri = args[0]
        callback = args[1]
        prefix = null
    }

    getSBOL('module', this.storeUrl, this.auth, prefix, uri, function(err, sbol) {

        if(err) {
            callback(err)
        } else {
            callback(null, sbol, sbol.lookupURI(uri))
        }
    });
}

function getCollectionSBOL(prefix, uri, callback) {

    var args = [].slice.call(arguments, 0)

    if(args.length < 3) {
        uri = args[0]
        callback = args[1]
        prefix = null
    }

    getSBOL('collection', this.storeUrl, this.auth, prefix, uri, function(err, sbol) {

        if(err) {
            callback(err)
        } else {
            callback(null, sbol, sbol.lookupURI(uri))
        }
    });
}

function upload(data, callback) {

    doUpload(this.storeUrl, this.auth, data, callback)

}

function getComponentMetadata(prefix, uri, callback) {

    var args = [].slice.call(arguments, 0)

    if(args.length < 3) {
        uri = args[0]
        callback = args[1]
        prefix = null
    }

    getMetadata('component', this.storeUrl, this.auth, prefix, uri, callback);

}

function getModuleMetadata(prefix, uri, callback) {

    var args = [].slice.call(arguments, 0)

    if(args.length < 3) {
        uri = args[0]
        callback = args[1]
        prefix = null
    }

    getMetadata('module', this.storeUrl, this.auth, prefix, uri, callback);

}

<|endoftext|>


<commit_before>
(function(undefined) {

  var Sysmo = {
    stub: function(){},
    makeArray: function(args) {
      return Array.prototype.slice.call(args);
    },
    type: function(value) {
      return Object.prototype.toString.call(value).match(/(\S+)\]$/)[1];
    },
    isType: function(value, type) {
      return Sysmo.type(value) == type;
    },
    isArray: function(value) {
      return Sysmo.isType(value, "Array");
    },
    isArrayLike: function(value) {
      return !!value && (Sysmo.isArray(value) || value.hasOwnProperty('length') && Sysmo.makeArray(value).length);
    },
    isFunction: function(value) {
      return Sysmo.isType(value, "Function");
    },
    isPlainObject: function(value) {
      return Sysmo.isType(value, "Object") && value.constructor === Object;
    },
    isObject: function(value) {
      return !!value && !Sysmo.isArray(value) && typeof value == "object";
    },
    isNumber: function(value) {
      return Sysmo.isType(value, "Number");
    },
    isString: function(value) {
      return Sysmo.isType(value, "String");
    },
    isNumeric: function(value) {
      return Number(value) + "" === value + ""
    },
    isUndefined: function(value) {
      return value === void(0);
    },
    isNull: function(value) {
      return value === null;
    },
    extend: function(target, values, deep) {
      target = target || {};

      for (var property in values) {

        var value = values[property];

        if (!(property in target)) {

          target[property] = !deep ? value :
                             (value == null || Sysmo.isObject(value)) ? Sysmo.extend({}, value) :
                             (Sysmo.isArray(value)) ? value.slice(0) : value;

        // compares objects that already exist in target if "deep" is true
        // copies properties or object if the target is NULL or an object
        } else if (deep && Sysmo.isObject(value) &&
                  (target[property] == null || Sysmo.isObject(target[property]))) {
          //don't need to set property because the object is updated by reference
          Sysmo.extend(target[property] || {}, value, deep);
        }
      }
      return target;
    },
    //include an object graph in another
    include: function(target, namespace, graph) {

      //if the first param is a string,
      //we are including the namespace on Sysmo
      if (typeof target == 'string') {
        graph = namespace;
        namespace = target;
        target = Sysmo;
      }

      //create namespace on target
      Sysmo.namespace(namespace, target);
      //get inner most object in namespace
      target = Sysmo.getDeepValue(target, namespace);
      //merge graph on inner most object in namespace
      return Sysmo.extend(target, graph);

    },
    //build an object graph from a namespace.
    //adds properties to the target object or
    //returns a new object graph.
    namespace: function(namespace, target) {

      target = target || {};

      var names = namespace.split('.'),
          context = target;

      for (var i = 0; i < names.length; i++) {
        var name = names[i];
        context = (name in context) ? context[name] : (context[name] = {});
      }

      return target;
    },
    //get the value of a property deeply nested in an object hierarchy
    getDeepValue: function (target, path, traverseArrays) {

      // if traversing arrays is enabled and this is an array, loop
      // may be a "array-like" node list (or similar), in which case it needs to be converted
      if (traverseArrays && Sysmo.isArrayLike(target)) {

        target = Sysmo.makeArray(target);

        var children = [];

        for (var i = 0; i < target.length; i++) {
          // recursively loop through children
          var child = Sysmo.getDeepValue(target[i], path, traverseArrays);

          // ignore if undefined
          if (typeof child != "undefined") {
            //flatten array because the original path points to one flat result set
            if (Sysmo.isArray(child)) {

              for (var j = 0; j < child.length; j++) {
                children.push(child[j]);
              }

            } else {

              children.push(child);

            }
          }
        }

        return (children.length) ? children : void(0);
      }

      var invoke_regex = /\(\)$/,
          properties = path.split('.'),
          property;

      if (target != null && properties.length) {

        var propertyName = properties.shift(),
            invoke = invoke_regex.test(propertyName)

        if (invoke) {
          propertyName = propertyName.replace(invoke_regex, "");
        }

        if (invoke && propertyName in target) {
          target = target[propertyName]();
        } else {
          target = target[propertyName];
        }

        path = properties.join('.');

        if (path) {
          target = Sysmo.getDeepValue(target, path, traverseArrays);
        }
      }

      return target;
    },
    //format a string using indexes, e.g. formatString("first name: {0}, last name: {1}", "Albert", "Einstein")
    formatString: function(template, args) {
      args = (args.constructor !== Array) ? Sysmo.makeArray(arguments).splice(1) : args;

      return template.replace(/\{(\d+)\}/g, function(match, capture) {
        return args[capture];
      });
    },
    //Allows you to chain multiple callbacks together.
    //The first parameter for each callback is the "next" function
    //that allows you to pass arguments to the next function.
    //Pass each function that should be a part of the chain
    //as a parameter to chain() function.
    //NOTE* You can pass an object as the first parameter before a callback
    //      to use as "this" context when the callback is called
    steps: function(self) {
      var steps = Sysmo.makeArray(arguments),
          next = function() {
            var args = Sysmo.makeArray(arguments),
                step = steps.shift();

            args.unshift(next);
            step.apply(self, args);
          };

      //an argument that is not a function is assumed to be the "this" context
      if (!/^function/i.test(self)) {
        steps.shift();
      } else {
        self = this;//next;
      }

      steps.length && next();
    },
    /*
     ****** Overview ******
     *
     * Strongly type a function's arguments to allow for any arguments to be optional.
     *
     * Other resources:
     * http://ejohn.org/blog/javascript-method-overloading/
     *
     ****** Example implementation ******
     *
     * //all args are optional... will display overlay with default settings
     * var displayOverlay = function() {
     *   return Sysmo.optionalArgs(arguments,
     *            String, [Number, false, 0], Function,
     *            function(message, timeout, callback) {
     *              var overlay = new Overlay(message);
     *              overlay.timeout = timeout;
     *              overlay.display({onDisplayed: callback});
     *            });
     * }
     *
     ****** Example function call ******
     *
     * //the window.alert() function is the callback, message and timeout are not defined.
     * displayOverlay(alert);
     *
     * //displays the overlay after 500 miliseconds, then alerts... message is not defined.
     * displayOverlay(500, alert);
     *
     ****** Setup ******
     *
     * arguments = the original arguments to the function defined in your javascript API.
     * config = describe the argument type
     *  - Class - specify the type (e.g. String, Number, Function, Array)
     *  - [Class/function, boolean, default] - pass an array where the first value is a class or a function...
     *                                         The "boolean" indicates if the first value should be treated as a function.
     *                                         The "default" is an optional default value to use instead of undefined.
     *
     */
    arrangeArgs: function (/* arguments, config1 [, config2] , callback */) {
      //config format: [String, false, ''], [Number, false, 0], [Function, false, function(){}]
      //config doesn't need a default value.
      //config can also be classes instead of an array if not required and no default value.

      var configs = Sysmo.makeArray(arguments),
          //original arguments that we need to verify
          values = Sysmo.makeArray(configs.shift()),
          //the function that will receive the verified arguments
          callback = configs.pop(),
          //the verified argumetns to pass to the callback
          args = [],
          //send the verified arguments to the callback
          done = function() {
            //add the proper number of arguments before adding remaining values
            if (!args.length) {
              args = Array(configs.length);
            }
            //fire callback with args and remaining values concatenated
            return callback.apply(null, args.concat(values));
          };

      //if there are not values to process, just fire callback
      if (!values.length) {
        return done();
      }

      //loop through configs to create more easily readable objects
      for (var i = 0; i < configs.length; i++) {

        var config = configs[i];

        //make sure there's a value
        if (values.length) {

          //type or validator function
          var fn = config[0] || config,
              //if config[1] is true, use fn as validator,
              //otherwise create a validator from a closure to preserve fn for later use
              validate = (config[1]) ? fn : function(value) {
                return value.constructor === fn;
              };

          //see if arg value matches config
          if (validate(values[0])) {
            args.push(values.shift());
            continue;
          }
        }

        //add a default value if there is no value in the original args
        //or if the type didn't match
        args.push(config[2]);
      }

      return done();
    }

  };

  if (typeof module !== "undefined" && module !== null) {
    module.exports = Sysmo;
  } else {
    window.Sysmo = Sysmo;
  }

})();
<commit_msg>added comment<commit_after>
(function(undefined) {

  var Sysmo = {
    stub: function(){},
    makeArray: function(args) {
      return Array.prototype.slice.call(args);
    },
    type: function(value) {
      return Object.prototype.toString.call(value).match(/(\S+)\]$/)[1];
    },
    isType: function(value, type) {
      return Sysmo.type(value) == type;
    },
    isArray: function(value) {
      return Sysmo.isType(value, "Array");
    },
    isArrayLike: function(value) {
      return !!value && (Sysmo.isArray(value) || value.hasOwnProperty('length') && Sysmo.makeArray(value).length);
    },
    isFunction: function(value) {
      return Sysmo.isType(value, "Function");
    },
    isPlainObject: function(value) {
      return Sysmo.isType(value, "Object") && value.constructor === Object;
    },
    isObject: function(value) {
      return !!value && !Sysmo.isArray(value) && typeof value == "object";
    },
    isNumber: function(value) {
      return Sysmo.isType(value, "Number");
    },
    isString: function(value) {
      return Sysmo.isType(value, "String");
    },
    isNumeric: function(value) {
      return Number(value) + "" === value + ""
    },
    isUndefined: function(value) {
      return value === void(0);
    },
    isNull: function(value) {
      return value === null;
    },
    extend: function(target, values, deep) {
      target = target || {};

      for (var property in values) {

        var value = values[property];

        if (!(property in target)) {

          target[property] = !deep ? value :
                             (value == null || Sysmo.isObject(value)) ? Sysmo.extend({}, value) :
                             (Sysmo.isArray(value)) ? value.slice(0) : value;

        // compares objects that already exist in target if "deep" is true
        // copies properties or object if the target is NULL or an object
        } else if (deep && Sysmo.isObject(value) &&
                  (target[property] == null || Sysmo.isObject(target[property]))) {
          //don't need to set property because the object is updated by reference
          Sysmo.extend(target[property] || {}, value, deep);
        }
      }
      return target;
    },
    //include an object graph in another
    include: function(target, namespace, graph) {

      //if the first param is a string,
      //we are including the namespace on Sysmo
      if (typeof target == 'string') {
        graph = namespace;
        namespace = target;
        target = Sysmo;
      }

      //create namespace on target
      Sysmo.namespace(namespace, target);
      //get inner most object in namespace
      target = Sysmo.getDeepValue(target, namespace);
      //merge graph on inner most object in namespace
      return Sysmo.extend(target, graph);

    },
    //build an object graph from a namespace.
    //adds properties to the target object or
    //returns a new object graph.
    namespace: function(namespace, target) {

      target = target || {};

      var names = namespace.split('.'),
          context = target;

      for (var i = 0; i < names.length; i++) {
        var name = names[i];
        context = (name in context) ? context[name] : (context[name] = {});
      }

      return target;
    },
    //get the value of a property deeply nested in an object hierarchy
    getDeepValue: function (target, path, traverseArrays) {

      // if traversing arrays is enabled and this is an array, loop
      // may be a "array-like" node list (or similar), in which case it needs to be converted
      if (traverseArrays && Sysmo.isArrayLike(target)) {

        target = Sysmo.makeArray(target);

        var children = [];

        for (var i = 0; i < target.length; i++) {
          // recursively loop through children
          var child = Sysmo.getDeepValue(target[i], path, traverseArrays);

          // ignore if undefined
          if (typeof child != "undefined") {
            //flatten array because the original path points to one flat result set
            if (Sysmo.isArray(child)) {

              for (var j = 0; j < child.length; j++) {
                children.push(child[j]);
              }

            } else {

              children.push(child);

            }
          }
        }

        return (children.length) ? children : void(0);
      }

      var invoke_regex = /\(\)$/,
          properties = path.split('.'),
          property;

      if (target != null && properties.length) {

        var propertyName = properties.shift(),
            invoke = invoke_regex.test(propertyName)

        if (invoke) {
          propertyName = propertyName.replace(invoke_regex, "");
        }

        if (invoke && propertyName in target) {
          target = target[propertyName]();
        } else {
          target = target[propertyName];
        }

        path = properties.join('.');

        if (path) {
          target = Sysmo.getDeepValue(target, path, traverseArrays);
        }
      }

      return target;
    },
    //format a string using indexes, e.g. formatString("first name: {0}, last name: {1}", "Albert", "Einstein")
    formatString: function(template, args) {
      args = (args.constructor !== Array) ? Sysmo.makeArray(arguments).splice(1) : args;

      return template.replace(/\{(\d+)\}/g, function(match, capture) {
        return args[capture];
      });
    },
    //Allows you to chain multiple callbacks together.
    //The first parameter for each callback is the "next" function
    //that allows you to pass arguments to the next function.
    //Pass each function that should be a part of the chain
    //as a parameter to chain() function.
    //NOTE* You can pass an object as the first parameter before a callback
    //      to use as "this" context when the callback is called
    steps: function(self) {
      var steps = Sysmo.makeArray(arguments),
          next = function() {
            var args = Sysmo.makeArray(arguments),
                step = steps.shift();

            args.unshift(next);
            step.apply(self, args);
          };

      //an argument that is not a function is assumed to be the "this" context
      if (!/^function/i.test(self)) {
        steps.shift();
      } else {
        self = this;//next;
      }

      steps.length && next();
    },
    /*
     ****** Overview ******
     *
     * Strongly type a function's arguments to allow for any arguments to be optional.
     *
     * Other resources:
     * http://ejohn.org/blog/javascript-method-overloading/
     *
     ****** Example implementation ******
     *
     * //all args are optional... will display overlay with default settings
     * var displayOverlay = function() {
     *   return Sysmo.optionalArgs(arguments,
     *            String, [Number, false, 0], Function,
     *            function(message, timeout, callback) {
     *              var overlay = new Overlay(message);
     *              overlay.timeout = timeout;
     *              overlay.display({onDisplayed: callback});
     *            });
     * }
     *
     ****** Example function call ******
     *
     * //the window.alert() function is the callback, message and timeout are not defined.
     * displayOverlay(alert);
     *
     * //displays the overlay after 500 miliseconds, then alerts... message is not defined.
     * displayOverlay(500, alert);
     *
     ****** Setup ******
     *
     * arguments = the original arguments to the function defined in your javascript API.
     * config = describe the argument type
     *  - Class - specify the type (e.g. String, Number, Function, Array)
     *  - [Class/function, boolean, default] - pass an array where the first value is a class or a function...
     *                                         The "boolean" indicates if the first value should be treated as a function.
     *                                         The "default" is an optional default value to use instead of undefined.
     *
     */
    arrangeArgs: function (/* arguments, config1 [, config2] , callback */) {
      //config format: [String, false, ''], [Number, false, 0], [Function, false, function(){}]
      //config doesn't need a default value.
      //config can also be classes instead of an array if not required and no default value.

      var configs = Sysmo.makeArray(arguments),
          //original arguments that we need to verify
          values = Sysmo.makeArray(configs.shift()),
          //the function that will receive the verified arguments
          callback = configs.pop(),
          //the verified argumetns to pass to the callback
          args = [],
          //send the verified arguments to the callback
          done = function() {
            //add the proper number of arguments before adding remaining values
            if (!args.length) {
              args = Array(configs.length);
            }
            //fire callback with args and remaining values concatenated
            return callback.apply(null, args.concat(values));
          };

      //if there are not values to process, just fire callback
      if (!values.length) {
        return done();
      }

      //loop through configs to create more easily readable objects
      for (var i = 0; i < configs.length; i++) {

        var config = configs[i];

        //make sure there's a value
        if (values.length) {

          //type or validator function
          var fn = config[0] || config,
              //if config[1] is true, use fn as validator,
              //otherwise create a validator from a closure to preserve fn for later use
              validate = (config[1]) ? fn : function(value) {
                return value.constructor === fn;
              };

          //see if arg value matches config
          if (validate(values[0])) {
            args.push(values.shift());
            continue;
          }
        }

        //add a default value if there is no value in the original args
        //or if the type didn't match
        args.push(config[2]);
      }

      return done();
    }

  };

  // Support CommonJS/Node.js
  if (typeof module !== "undefined" && module !== null) {
    module.exports = Sysmo;
  } else {
    window.Sysmo = Sysmo;
  }

})();
<|endoftext|>