<commit_before>/*!
 * flow.js v0.0.14
 * https://github.com/minodisk/flow-js
 * Author: Daisuke MINO
 * Licensed under the MIT license.
 * https://github.com/minodisk/flow-js/raw/master/LICENSE
 */
(function () {
  function Flow(type, actors) {
    switch (type) {
      case 'serial':
        this._serial(actors);
        break;
      case 'parallel':
        this._parallel(actors);
        break;
      case 'repeat':
        this._repeat(actors[0], actors[1]);
        break;
      default:
        throw new Error(type + 'is not implemented.');
        break;
    }
  }

  Flow.serial = function (/*...actors*/) {
    return Flow.serialActors(Array.prototype.slice.call(arguments));
  };

  Flow.serialActors = function (actors) {
    return new Flow('serial', actors);
  };

  Flow.parallel = function (/*...actors*/) {
    return Flow.parallelActors(Array.prototype.slice.call(arguments));
  };

  Flow.parallelActors = function (actors) {
    return new Flow('parallel', actors);
  };

  Flow.repeat = function (actor, repeatCount) {
    return new Flow('repeat', [actor, repeatCount]);
  };

  Flow.wait = function (delay) {
    return function (flow) {
      setTimeout(flow.next, delay);
    };
  };

  Flow.prototype = {};

  /*Flow.prototype.running;
   Flow.prototype.currentPhase;
   Flow.prototype.totalPhase;
   Flow.prototype.userData;
   Flow.prototype._actors;*/

  Flow.prototype._serial = function (actors) {
    var that = this;
    this._actors = actors;
    this.running = false;
    this.currentPhase = 0;
    this.totalPhase = actors.length;
    this.userData = {};
    this.start = function () {
      that._serialStart.apply(that, arguments);
    };
    this.next = function () {
      that._serialNext.apply(that, arguments);
    };
    this.stop = function () {
      that._stop.apply(that, arguments);
    };
    this.reset = function () {
      that._reset.apply(that, arguments);
    };
  };

  Flow.prototype._parallel = function (actors) {
    var that = this;
    this._actors = actors;
    this.running = false;
    this.currentPhase = 0;
    this.totalPhase = actors.length;
    this.userData = {};
    this.start = function () {
      that._parallelStart.apply(that, arguments);
    };
    this.next = function () {
      that._parallelNext.apply(that, arguments);
    };
    this.stop = function () {
      that._stop.apply(that, arguments);
    };
    this.reset = function () {
      that._reset.apply(that, arguments);
    };
  };

  Flow.prototype._repeat = function (actor, repeatCount) {
    var that = this;
    this._actors = [];
    this.running = false;
    this.currentPhase = 0;
    this.totalPhase = repeatCount;
    this.userData = {};
    while (repeatCount--) {
      this._actors.push(actor);
    }
    this.start = function () {
      that._serialStart.apply(that, arguments);
    };
    this.next = function () {
      if (actor instanceof Flow) {
        actor.reset();
      }
      that._serialNext.apply(that, arguments);
    };
    this.stop = function () {
      that._stop.apply(that, arguments);
    };
    this.reset = function () {
      that._reset.apply(that, arguments);
    };
  };

  /*Flow.prototype.start;
   Flow.prototype.next;
   Flow.prototype.stop;
   Flow.prototype.reset;
   Flow.prototype.onComplete;
   Flow.prototype.onError;*/

  Flow.prototype._serialStart = function () {
    if (!this.running && this.currentPhase < this.totalPhase) {
      this.running = true;
      var actor = this._actors[this.currentPhase];
      if (actor instanceof Flow) {
        if (this.onError) {
          actor.onError = this.onError;
        }
        actor.onComplete = this.next;
        actor.start();
      } else {
        var args = Array.prototype.slice.call(arguments);
        args[0] = this;
        actor.apply(null, args);
      }
    }
  };

  Flow.prototype._serialNext = function () {
    if (this.running) {
      if (++this.currentPhase < this.totalPhase) {
        var actor = this._actors[this.currentPhase];
        if (actor instanceof Flow) {
          if (this.onError) {
            actor.onError = this.onError;
          }
          actor.onComplete = this.next;
          actor.start();
        } else {
          var args = Array.prototype.slice.call(arguments);
          if (args[0] === null || args[0] === undefined ||
            args[0] instanceof Error) {
            var err = args.shift();
            if (err && this.onError) {
              this.onError(err);
              return;
            }
          }
          args.unshift(this);
          actor.apply(null, args);
        }
      } else {
        this.stop();
        if (this.onComplete) {
          this.onComplete();
        }
      }
    }
  };

  Flow.prototype._parallelStart = function () {
    if (!this.running && this.currentPhase < this.totalPhase) {
      this.running = true;
      var actor;
      for (var i = 0, len = this._actors.length; i < len; i++) {
        actor = this._actors[i];
        if (actor instanceof Flow) {
          if (this.onError) {
            actor.onError = this.onError;
          }
          actor.onComplete = this.next;
          actor.start();
        } else {
          actor.apply(null, [this]);
        }
      }
    }
  };

  Flow.prototype._parallelNext = function (err) {
    var that = this;
    setTimeout(function () {
      if (err) {
        if (that.onError) {
          that.onError(err);
          return;
        }
        return;
      }
      if (that.running) {
        if (++that.currentPhase >= that.totalPhase) {
          that.stop();
          if (that.onComplete) {
            that.onComplete();
          }
        }
      }
    }, 0);
  };

  Flow.prototype._stop = function () {
    this.running = false;
    var i = this._actors.length;
    while (i--) {
      if (this._actors[i] instanceof Flow) {
        this._actors[i].stop();
      }
    }
  };

  Flow.prototype._reset = function () {
    this.running = false;
    this.currentPhase = 0;
    var i = this._actors.length;
    while (i--) {
      if (this._actors[i] instanceof Flow) {
        this._actors[i].reset();
      }
    }
  };

  if (typeof exports !== 'undefined') {
    // Node.js
    exports.Flow = Flow;
  } else if (typeof define !== 'undefined') {
    // RequireJS
    define(function () {
      return Flow;
    });
  } else if (typeof window !== 'undefined') {
    // browser
    window.Flow = Flow;
  }
})();<commit_msg>Update version.<commit_after>/*!
 * flow.js v0.0.15
 * https://github.com/minodisk/flow-js
 * Author: Daisuke MINO
 * Licensed under the MIT license.
 * https://github.com/minodisk/flow-js/raw/master/LICENSE
 */
(function () {
  function Flow(type, actors) {
    switch (type) {
      case 'serial':
        this._serial(actors);
        break;
      case 'parallel':
        this._parallel(actors);
        break;
      case 'repeat':
        this._repeat(actors[0], actors[1]);
        break;
      default:
        throw new Error(type + 'is not implemented.');
        break;
    }
  }

  Flow.serial = function (/*...actors*/) {
    return Flow.serialActors(Array.prototype.slice.call(arguments));
  };

  Flow.serialActors = function (actors) {
    return new Flow('serial', actors);
  };

  Flow.parallel = function (/*...actors*/) {
    return Flow.parallelActors(Array.prototype.slice.call(arguments));
  };

  Flow.parallelActors = function (actors) {
    return new Flow('parallel', actors);
  };

  Flow.repeat = function (actor, repeatCount) {
    return new Flow('repeat', [actor, repeatCount]);
  };

  Flow.wait = function (delay) {
    return function (flow) {
      setTimeout(flow.next, delay);
    };
  };

  Flow.prototype = {};

  /*Flow.prototype.running;
   Flow.prototype.currentPhase;
   Flow.prototype.totalPhase;
   Flow.prototype.userData;
   Flow.prototype._actors;*/

  Flow.prototype._serial = function (actors) {
    var that = this;
    this._actors = actors;
    this.running = false;
    this.currentPhase = 0;
    this.totalPhase = actors.length;
    this.userData = {};
    this.start = function () {
      that._serialStart.apply(that, arguments);
    };
    this.next = function () {
      that._serialNext.apply(that, arguments);
    };
    this.stop = function () {
      that._stop.apply(that, arguments);
    };
    this.reset = function () {
      that._reset.apply(that, arguments);
    };
  };

  Flow.prototype._parallel = function (actors) {
    var that = this;
    this._actors = actors;
    this.running = false;
    this.currentPhase = 0;
    this.totalPhase = actors.length;
    this.userData = {};
    this.start = function () {
      that._parallelStart.apply(that, arguments);
    };
    this.next = function () {
      that._parallelNext.apply(that, arguments);
    };
    this.stop = function () {
      that._stop.apply(that, arguments);
    };
    this.reset = function () {
      that._reset.apply(that, arguments);
    };
  };

  Flow.prototype._repeat = function (actor, repeatCount) {
    var that = this;
    this._actors = [];
    this.running = false;
    this.currentPhase = 0;
    this.totalPhase = repeatCount;
    this.userData = {};
    while (repeatCount--) {
      this._actors.push(actor);
    }
    this.start = function () {
      that._serialStart.apply(that, arguments);
    };
    this.next = function () {
      if (actor instanceof Flow) {
        actor.reset();
      }
      that._serialNext.apply(that, arguments);
    };
    this.stop = function () {
      that._stop.apply(that, arguments);
    };
    this.reset = function () {
      that._reset.apply(that, arguments);
    };
  };

  /*Flow.prototype.start;
   Flow.prototype.next;
   Flow.prototype.stop;
   Flow.prototype.reset;
   Flow.prototype.onComplete;
   Flow.prototype.onError;*/

  Flow.prototype._serialStart = function () {
    if (!this.running && this.currentPhase < this.totalPhase) {
      this.running = true;
      var actor = this._actors[this.currentPhase];
      if (actor instanceof Flow) {
        if (this.onError) {
          actor.onError = this.onError;
        }
        actor.onComplete = this.next;
        actor.start();
      } else {
        var args = Array.prototype.slice.call(arguments);
        args[0] = this;
        actor.apply(null, args);
      }
    }
  };

  Flow.prototype._serialNext = function () {
    if (this.running) {
      if (++this.currentPhase < this.totalPhase) {
        var actor = this._actors[this.currentPhase];
        if (actor instanceof Flow) {
          if (this.onError) {
            actor.onError = this.onError;
          }
          actor.onComplete = this.next;
          actor.start();
        } else {
          var args = Array.prototype.slice.call(arguments);
          if (args[0] === null || args[0] === undefined ||
            args[0] instanceof Error) {
            var err = args.shift();
            if (err && this.onError) {
              this.onError(err);
              return;
            }
          }
          args.unshift(this);
          actor.apply(null, args);
        }
      } else {
        this.stop();
        if (this.onComplete) {
          this.onComplete();
        }
      }
    }
  };

  Flow.prototype._parallelStart = function () {
    if (!this.running && this.currentPhase < this.totalPhase) {
      this.running = true;
      var actor;
      for (var i = 0, len = this._actors.length; i < len; i++) {
        actor = this._actors[i];
        if (actor instanceof Flow) {
          if (this.onError) {
            actor.onError = this.onError;
          }
          actor.onComplete = this.next;
          actor.start();
        } else {
          actor.apply(null, [this]);
        }
      }
    }
  };

  Flow.prototype._parallelNext = function (err) {
    var that = this;
    setTimeout(function () {
      if (err) {
        if (that.onError) {
          that.onError(err);
          return;
        }
        return;
      }
      if (that.running) {
        if (++that.currentPhase >= that.totalPhase) {
          that.stop();
          if (that.onComplete) {
            that.onComplete();
          }
        }
      }
    }, 0);
  };

  Flow.prototype._stop = function () {
    this.running = false;
    var i = this._actors.length;
    while (i--) {
      if (this._actors[i] instanceof Flow) {
        this._actors[i].stop();
      }
    }
  };

  Flow.prototype._reset = function () {
    this.running = false;
    this.currentPhase = 0;
    var i = this._actors.length;
    while (i--) {
      if (this._actors[i] instanceof Flow) {
        this._actors[i].reset();
      }
    }
  };

  if (typeof exports !== 'undefined') {
    // Node.js
    exports.Flow = Flow;
  } else if (typeof define !== 'undefined') {
    // RequireJS
    define(function () {
      return Flow;
    });
  } else if (typeof window !== 'undefined') {
    // browser
    window.Flow = Flow;
  }
})();<|endoftext|>


<commit_before>var ide = require('./ide.js');
var diffSystems = global.diffSystems;
var codeToSystem = global.codeToSystem;
var uiDiffRenderer = global.uiDiffRenderer;
var examples = global.examples;
var tests = global.tests || {};

//---------------------------------------------------------
// State
//---------------------------------------------------------

function getLocal(k, otherwise) {
  if(localStorage[k]) {
    return JSON.parse(localStorage[k])
  }
  return otherwise;
}

function setLocal(k, v) {
  localStorage[k] = JSON.stringify(v);
}

var prevVersion = getLocal("prevVersion");
var stacks = getLocal("stacks");
var exampleStacks = Object.keys(examples);
var testStacks = []; //Object.keys(tests);

//stacks = ["Tutorial", "Incrementer", "Net worth", "Department heads", "Graph paths", "TodoMVC", "Turing machine", "Clock", "Chat", "Game", "My Stack", "Editor", "Runtime", "Editor injection"];
stacks = (stacks || []).concat(exampleStacks);
stacks.sort();
var uniqueStacks = [];
var prev;
for(var stackIx = 0; stackIx < stacks.length; stackIx++) {
  var stack = stacks[stackIx];
  if(stack !== prev) {
    prev = stack;
    uniqueStacks.push(stack);
  }
}
stacks = uniqueStacks;
setLocal("stacks", stacks);
// setLocal("Editor-code", examples["Editor"]);

var client = getLocal("client", uuid());
global.client = client;
setLocal("client", client);

//---------------------------------------------------------
// renderer
//---------------------------------------------------------

var renderer = {"programQueue": [], "queued": false}

function drainRenderQueue() {
  var start = now();
  storage["rootParent"] = $(".uiCard").get(0);
  if(storage["rootParent"] && renderer["programQueue"].length > 0) {
    for(var i = 0, len = renderer["programQueue"].length; i < len; i++) {
      var queued = renderer["programQueue"][i];
      var program = queued[0];
      var diff = queued[1];
      uiDiffRenderer(diff, storage, program);
    }
    var eveRoot = $(storage["builtEls"]["eve-root"]);
    if(!eveRoot.closest(document.documentElement).size()) {
      storage["rootParent"].appendChild(eveRoot.get(0));
    }
    renderer["programQueue"] = [];
  }
  var end = now();
  if(end - start > 10) {
    console.error("Long render: " + (end - start));
  }
//   console.log("Render loop:", end - start);
  renderer["queued"] = false;
}

function queueRender() {
  if(!renderer["queued"]) {
    renderer["queued"] = true;
    requestAnimationFrame(drainRenderQueue);
  }
}

//---------------------------------------------------------
// worker
//---------------------------------------------------------

var system;
var storage = {};
var workers = {};

function onWorkerMessage(event) {
  switch(event.data.type) {
    case "log":
      console.log.apply(console, event.data.args);
      break;
    case "renderUI":
      renderer["programQueue"].push([event.data.from, event.data.diff]);
      queueRender();
      break;
    case "diffs":
      var diffs = event.data.diffs;
      applySystemDiff({system: system}, diffs);

      ide.render(diffs, system);
      programWorker.postMessage({type: "pull", runNumber: event.data.runNumber});
      break;
  }
}

function createWorker() {
  var worker = new Worker("../build/worker.js");
  worker.onmessage = onWorkerMessage;
  return worker;
}

var programWorker = global.programWorker = createWorker();

var system = codeToSystem( examples["Runtime"] + "\n\n" + examples["Incrementer"]);
system.updateStore("workspaceView", [["event"], ["increment button"]], []);
system.updateStore("subscription", [["event"], ["increment button"]], []);
programWorker.postMessage({type: "diffs", diffs: diffSystems(system, null, null)});

var workspaceViews = system.getStore("workspaceView").getFacts().map(function(row) {
  return row[0];
});
console.log(workspaceViews);

var initialDiff = system.getStore('view').getFacts().reduce(function(memo, view) {
  memo[view[0]] = {adds: system.getStore(view[0]).getFacts()};
  return memo;
}, {});

//---------------------------------------------------------
// socket.io
//---------------------------------------------------------

if(window["io"]) {
  var socket = io.connect('/');
  socket.on("message", function (data) {
    onWorkerMessage({data: data});
  });

  var server = {
    postMessage: function(data) {
      socket.emit("message", data);
    },
    terminate: function() {}
  };

  workers["server"] = server;
}

//---------------------------------------------------------
// Go!
//---------------------------------------------------------

ide.render(initialDiff, system);
programWorker.postMessage({type: "pull"});
<commit_msg>Removes old testing code + swaps example to clock<commit_after>var ide = require('./ide.js');
var diffSystems = global.diffSystems;
var codeToSystem = global.codeToSystem;
var uiDiffRenderer = global.uiDiffRenderer;
var examples = global.examples;
var tests = global.tests || {};

//---------------------------------------------------------
// State
//---------------------------------------------------------

function getLocal(k, otherwise) {
  if(localStorage[k]) {
    return JSON.parse(localStorage[k])
  }
  return otherwise;
}

function setLocal(k, v) {
  localStorage[k] = JSON.stringify(v);
}

var prevVersion = getLocal("prevVersion");
var stacks = getLocal("stacks");
var exampleStacks = Object.keys(examples);
var testStacks = []; //Object.keys(tests);

//stacks = ["Tutorial", "Incrementer", "Net worth", "Department heads", "Graph paths", "TodoMVC", "Turing machine", "Clock", "Chat", "Game", "My Stack", "Editor", "Runtime", "Editor injection"];
stacks = (stacks || []).concat(exampleStacks);
stacks.sort();
var uniqueStacks = [];
var prev;
for(var stackIx = 0; stackIx < stacks.length; stackIx++) {
  var stack = stacks[stackIx];
  if(stack !== prev) {
    prev = stack;
    uniqueStacks.push(stack);
  }
}
stacks = uniqueStacks;
setLocal("stacks", stacks);
// setLocal("Editor-code", examples["Editor"]);

var client = getLocal("client", uuid());
global.client = client;
setLocal("client", client);

//---------------------------------------------------------
// renderer
//---------------------------------------------------------

var renderer = {"programQueue": [], "queued": false}

function drainRenderQueue() {
  var start = now();
  storage["rootParent"] = $(".uiCard").get(0);
  if(storage["rootParent"] && renderer["programQueue"].length > 0) {
    for(var i = 0, len = renderer["programQueue"].length; i < len; i++) {
      var queued = renderer["programQueue"][i];
      var program = queued[0];
      var diff = queued[1];
      uiDiffRenderer(diff, storage, program);
    }
    var eveRoot = $(storage["builtEls"]["eve-root"]);
    if(!eveRoot.closest(document.documentElement).size()) {
      storage["rootParent"].appendChild(eveRoot.get(0));
    }
    renderer["programQueue"] = [];
  }
  var end = now();
  if(end - start > 10) {
    console.error("Long render: " + (end - start));
  }
//   console.log("Render loop:", end - start);
  renderer["queued"] = false;
}

function queueRender() {
  if(!renderer["queued"]) {
    renderer["queued"] = true;
    requestAnimationFrame(drainRenderQueue);
  }
}

//---------------------------------------------------------
// worker
//---------------------------------------------------------

var system;
var storage = {};
var workers = {};

function onWorkerMessage(event) {
  switch(event.data.type) {
    case "log":
      console.log.apply(console, event.data.args);
      break;
    case "renderUI":
      renderer["programQueue"].push([event.data.from, event.data.diff]);
      queueRender();
      break;
    case "diffs":
      var diffs = event.data.diffs;
      applySystemDiff({system: system}, diffs);

      ide.render(diffs, system);
      programWorker.postMessage({type: "pull", runNumber: event.data.runNumber});
      break;
  }
}

function createWorker() {
  var worker = new Worker("../build/worker.js");
  worker.onmessage = onWorkerMessage;
  return worker;
}

var programWorker = global.programWorker = createWorker();

var system = codeToSystem( examples["Runtime"] + "\n\n" + examples["Clock"]);
programWorker.postMessage({type: "diffs", diffs: diffSystems(system, null, null)});

var workspaceViews = system.getStore("workspaceView").getFacts().map(function(row) {
  return row[0];
});
console.log(workspaceViews);

var initialDiff = system.getStore('view').getFacts().reduce(function(memo, view) {
  memo[view[0]] = {adds: system.getStore(view[0]).getFacts()};
  return memo;
}, {});

//---------------------------------------------------------
// socket.io
//---------------------------------------------------------

if(window["io"]) {
  var socket = io.connect('/');
  socket.on("message", function (data) {
    onWorkerMessage({data: data});
  });

  var server = {
    postMessage: function(data) {
      socket.emit("message", data);
    },
    terminate: function() {}
  };

  workers["server"] = server;
}

//---------------------------------------------------------
// Go!
//---------------------------------------------------------

ide.render(initialDiff, system);
programWorker.postMessage({type: "pull"});
<|endoftext|>


<commit_before>'use strict';

var debug = require('debug')('pipes:fittings');
var path = require('path');
var util = require('util');
var assert = require('assert');

module.exports = function createFitting(pipes, fittingDef) {

  assert(fittingDef.name, util.format('name is required on fitting: %j', fittingDef));
  if (!pipes.config.userFittingsDirs) { return null; }

  for (var i = 0; i < pipes.config.userFittingsDirs.length; i++) {
    var dir = pipes.config.userFittingsDirs[i];

    var modulePath = path.resolve(dir, fittingDef.name);
    try {
      var module = require(modulePath);
      var fitting = module(fittingDef, pipes);
      debug('loaded user fitting %s from %s', fittingDef.name, dir);
      return fitting;
    } catch (err) {
      if (err.code !== 'MODULE_NOT_FOUND') { throw err; }
      var pathFromError = err.message.match(/'.*?'/)[0];
      var fittingIndex = err.message.indexOf(fittingDef.name);
      if (err.message[fittingIndex - 1] === path.sep && err.message[fittingDef.name.length] !== path.sep) {
        debug('no user fitting %s in %s', fittingDef.name, dir);
      } else {
        throw err;
      }
    }
  }

  if (fittingDef.type !== 'user') {
    return null;
  }

  throw new Error('user fitting %s not found in %s', fittingDef, pipes.config.userFittingsDirs);
};
<commit_msg>support default exports<commit_after>'use strict';

var debug = require('debug')('pipes:fittings');
var path = require('path');
var util = require('util');
var assert = require('assert');

module.exports = function createFitting(pipes, fittingDef) {

  assert(fittingDef.name, util.format('name is required on fitting: %j', fittingDef));
  if (!pipes.config.userFittingsDirs) { return null; }

  for (var i = 0; i < pipes.config.userFittingsDirs.length; i++) {
    var dir = pipes.config.userFittingsDirs[i];

    var modulePath = path.resolve(dir, fittingDef.name);
    try {
      var module = require(modulePath);
      if (module.default && typeof module.default === 'function') {
        module = module.default;
      }

      var fitting = module(fittingDef, pipes);
      debug('loaded user fitting %s from %s', fittingDef.name, dir);
      return fitting;
    } catch (err) {
      if (err.code !== 'MODULE_NOT_FOUND') { throw err; }
      var pathFromError = err.message.match(/'.*?'/)[0];
      var fittingIndex = err.message.indexOf(fittingDef.name);
      if (err.message[fittingIndex - 1] === path.sep && err.message[fittingDef.name.length] !== path.sep) {
        debug('no user fitting %s in %s', fittingDef.name, dir);
      } else {
        throw err;
      }
    }
  }

  if (fittingDef.type !== 'user') {
    return null;
  }

  throw new Error('user fitting %s not found in %s', fittingDef, pipes.config.userFittingsDirs);
};
<|endoftext|>


<commit_before>var path = require('path');
var Module = require('module');
var MendelTree = require('mendel/trees');

var nodeRequire = module.constructor.prototype.require;

module.exports = MendelLoader;

function MendelLoader(config) {
    var self = this;
    self._basedir = config.basedir || process.cwd();
    self._mountdir = config.mountdir || process.cwd();
    self._tree = new MendelTree({
        basedir: self._basedir
    });
}

MendelLoader.prototype.resolver = function(context) {
    var variations = this._getVariationMap(context);
    return new MendelResolver(variations, this._mountdir);
}

MendelLoader.prototype.register = function(context) {
    return this.resolver(context).register();
}

MendelLoader.prototype._getVariationMap = function(context) {
    //TODO(dgomez): this tree could be cached.
    return this._tree.findTreeForVariations('main', context).variationMap;
}

function MendelResolver(variations, mountdir) {
    this._variations = variations;
    this._mountdir = mountdir;
    this._resolveCache = {};
}

MendelResolver.prototype.register = function() {
    var resolver = this;
    module.constructor.prototype.require = function (mod) {
        var rmod = resolver.resolve(mod);
        return nodeRequire.call(this, rmod || mod);
    };
    return this;
}

MendelResolver.prototype.unregister = function() {
    module.constructor.prototype.require = nodeRequire;
    return this;
}

MendelResolver.prototype.resolve = function(mod) {
    if (!this._resolveCache[mod]) {
        var variation = this._variations[mod];
        if (variation) {
            this._resolveCache[mod] = path.resolve(path.join(this._mountdir, variation, mod));
        }
    }
    return this._resolveCache[mod];
}
<commit_msg>Pass bundle name in context.<commit_after>var path = require('path');
var Module = require('module');
var MendelTree = require('mendel/trees');

var nodeRequire = module.constructor.prototype.require;

module.exports = MendelLoader;

function MendelLoader(config) {
    var self = this;
    self._basedir = config.basedir || process.cwd();
    self._mountdir = config.mountdir || process.cwd();
    self._tree = new MendelTree({
        basedir: self._basedir
    });
}

MendelLoader.prototype.resolver = function(context) {
    var variations = this._getVariationMap(context);
    return new MendelResolver(variations, this._mountdir);
}

MendelLoader.prototype.register = function(context) {
    return this.resolver(context).register();
}

MendelLoader.prototype._getVariationMap = function(context) {
    //TODO(dgomez): this tree could be cached.
    var tree = this._tree.findTreeForVariations(context.bundle, context.variations);
    return tree.variationMap;
}

function MendelResolver(variations, mountdir) {
    this._variations = variations;
    this._mountdir = mountdir;
    this._resolveCache = {};
}

MendelResolver.prototype.register = function() {
    var resolver = this;
    module.constructor.prototype.require = function (mod) {
        var rmod = resolver.resolve(mod);
        return nodeRequire.call(this, rmod || mod);
    };
    return this;
}

MendelResolver.prototype.unregister = function() {
    module.constructor.prototype.require = nodeRequire;
    return this;
}

MendelResolver.prototype.resolve = function(mod) {
    if (!this._resolveCache[mod]) {
        var variation = this._variations[mod];
        if (variation) {
            this._resolveCache[mod] = path.resolve(path.join(this._mountdir, variation, mod));
        }
    }
    return this._resolveCache[mod];
}
<|endoftext|>


<commit_before>

export default ({ maxWidth }) => `

body {
  margin: 0;
}

.idyll-root {
  box-sizing: border-box;
  margin: 0 auto;
  padding: 60px 0;
  margin-bottom: 60px;
}

.section {
  padding: 0 10px;
  margin: 0 auto;
}

.article-header {
  width: 600px;
  max-width: 90vw;
  margin-bottom: 45px;
}

.inset {
  max-width: 400px;
  margin: 0 auto;
}

input {
  cursor: pointer;
}

.relative {
  position: relative;
}
.aside-container {
  position: relative;
}
.aside {
  position: absolute;
  width: 300px;
  right: calc((10vw + 600px + 150px) / -2);
}

.fixed {
  position: fixed;
  display: flex;
  align-self: center;
  flex-direction: column;
  align-items: center;
  right: 25px;
  top: 0;
  bottom: 0;
  width: calc((80vw - 600px) - 50px);
  justify-content: center;
}

.fixed div {
  width: 100%;
}

.idyll-scroll-graphic {
  position: -webkit-sticky;
  position: sticky;
}

.idyll-scroll-graphic img {
  max-height: 100vh;
}

.component-debug-view {
  position: relative;
  transition: background-color 0.3s ease-in;
}

.author-view-button {
  position: absolute;
  top: 3px;
  right: 0;
  opacity: .38;
  background-color: #E7E3D0;
  background-image: url('https://idyll-lang.org/static/images/quill-icon.png');
  background-repeat: no-repeat;
  background-size: contain;
  width: 24px;
  height: 24px;
  margin-right: 10px;
  box-sizing: border-box;
  border-radius: 12px;
  cursor: pointer;
}

.author-view-button:focus {
  outline: none;
}

.component-debug-view:hover > .author-view-button {
  opacity: 0.87;
  transition: opacity 600ms linear;
}

.author-component-view {
  display: flex;
  flex-direction: column;
}

.author-component-view h2, .author-component-view h3 {
  margin-top: 5px;
  margin-bottom: 5px;
}

.props-table {
  width: 90%;
  display: table;
  border: 1px solid #A4A2A2;
  border-radius: 20px;
  margin: 0 auto;
}

.props-table-type {
  font-family: 'Courier-New';
}

.props-table-row {
  text-align: center;
}

.debug-collapse {
  overflow: hidden;
  transition: height 0.3s ease-in;
  margin: 0;
  box-sizing: border-box;
}

.icon-links {
  margin-top: 13px;
  text-align: center;
  display: flex;
  flex-direction: row;
  justify-content: center;
}

.icon-link {
  width: 24px;
  height: 24px;
}

.icon-link-image {
  cursor: pointer;
}

.button-tooltip {
  background-color: black !important;
  padding: 0 5px;
}

.tooltip-header {
  line-height: 1;
  margin: 6px 0;
  font-size: 18px;
}

.tooltip-subtitle {
  font-style: italic;
}

@media all and (max-width: 1600px) {
  .fixed {
    width: calc((85vw - 600px) - 50px);
  }
}

@media all and (max-width: 1000px) {
  /* put your css styles in here */
  .desktop {
    display: none;
  }
  .relative {
    position: static;
  }
  .aside {
    position: static;
    width: 100%;
    right: 0;
  }

  .hed {
    width: 100%;
  }

  .idyll-root {
    padding: 15px 0;
  }

  .idyll-root {
    width: 90vw;
    max-width: 600px;
    margin: 0 auto;
    padding-bottom: 80vh;
  }
  .fixed {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100vw;
    top: initial;
    background: white;
    padding: 20px 0;
    border-top: solid 2px black;
  }
}
`
<commit_msg>make tooltip border bottom black<commit_after>

export default ({ maxWidth }) => `

body {
  margin: 0;
}

.idyll-root {
  box-sizing: border-box;
  margin: 0 auto;
  padding: 60px 0;
  margin-bottom: 60px;
}

.section {
  padding: 0 10px;
  margin: 0 auto;
}

.article-header {
  width: 600px;
  max-width: 90vw;
  margin-bottom: 45px;
}

.inset {
  max-width: 400px;
  margin: 0 auto;
}

input {
  cursor: pointer;
}

.relative {
  position: relative;
}
.aside-container {
  position: relative;
}
.aside {
  position: absolute;
  width: 300px;
  right: calc((10vw + 600px + 150px) / -2);
}

.fixed {
  position: fixed;
  display: flex;
  align-self: center;
  flex-direction: column;
  align-items: center;
  right: 25px;
  top: 0;
  bottom: 0;
  width: calc((80vw - 600px) - 50px);
  justify-content: center;
}

.fixed div {
  width: 100%;
}

.idyll-scroll-graphic {
  position: -webkit-sticky;
  position: sticky;
}

.idyll-scroll-graphic img {
  max-height: 100vh;
}

.component-debug-view {
  position: relative;
  transition: background-color 0.3s ease-in;
}

.author-view-button {
  position: absolute;
  top: 3px;
  right: 0;
  opacity: .38;
  background-color: #E7E3D0;
  background-image: url('https://idyll-lang.org/static/images/quill-icon.png');
  background-repeat: no-repeat;
  background-size: contain;
  width: 24px;
  height: 24px;
  margin-right: 10px;
  box-sizing: border-box;
  border-radius: 12px;
  cursor: pointer;
}

.author-view-button:focus {
  outline: none;
}

.component-debug-view:hover > .author-view-button {
  opacity: 0.87;
  transition: opacity 600ms linear;
}

.author-component-view {
  display: flex;
  flex-direction: column;
}

.author-component-view h2, .author-component-view h3 {
  margin-top: 5px;
  margin-bottom: 5px;
}

.props-table {
  width: 90%;
  display: table;
  border: 1px solid #A4A2A2;
  border-radius: 20px;
  margin: 0 auto;
}

.props-table-type {
  font-family: 'Courier-New';
}

.props-table-row {
  text-align: center;
}

.debug-collapse {
  overflow: hidden;
  transition: height 0.3s ease-in;
  margin: 0;
  box-sizing: border-box;
}

.icon-links {
  margin-top: 13px;
  text-align: center;
  display: flex;
  flex-direction: row;
  justify-content: center;
}

.icon-link {
  width: 24px;
  height: 24px;
}

.icon-link-image {
  cursor: pointer;
}

.button-tooltip {
  background-color: black !important;
  padding: 0 5px;
}

.button-tooltip.place-top:after {
  border-top-color: black !important;
}

.button-tooltip.place-right:after {
  border-right-color: black !important;
}

.button-tooltip.place-bottom:after {
  border-bottom-color: black !important;
}

.button-tooltip.place-left:after {
  border-left-color: black !important;
}

.tooltip-header {
  line-height: 1;
  margin: 6px 0;
  font-size: 18px;
}

.tooltip-subtitle {
  font-style: italic;
}

@media all and (max-width: 1600px) {
  .fixed {
    width: calc((85vw - 600px) - 50px);
  }
}

@media all and (max-width: 1000px) {
  /* put your css styles in here */
  .desktop {
    display: none;
  }
  .relative {
    position: static;
  }
  .aside {
    position: static;
    width: 100%;
    right: 0;
  }

  .hed {
    width: 100%;
  }

  .idyll-root {
    padding: 15px 0;
  }

  .idyll-root {
    width: 90vw;
    max-width: 600px;
    margin: 0 auto;
    padding-bottom: 80vh;
  }
  .fixed {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100vw;
    top: initial;
    background: white;
    padding: 20px 0;
    border-top: solid 2px black;
  }
}
`
<|endoftext|>


<commit_before>"use strict";

var ImageLoader = require("./image-loader");
var Input = require("./input");
var Scene = require("./scene");
var SoundLoader = require("./sound-loader");

function clone(obj) {
	if (obj === undefined) {
		return undefined;
	}
	return JSON.parse(JSON.stringify(obj));
}

function splitFilmStripAnimations(animations) {
	Object.keys(animations).forEach(function(key) {
		var firstFrame = animations[key][0];
		if (firstFrame.filmstripFrames) {
			splitFilmStripAnimation(animations, key);
		}
	});
}
function splitFilmStripAnimation(animations, key) {
	var firstFrame = animations[key][0];
	if (firstFrame.properties.image.sourceWidth % firstFrame.filmstripFrames != 0) {
		console.warn("The \"" + key + "\" animation is " + firstFrame.properties.image.sourceWidth + " pixels wide and that is is not evenly divisible by " + firstFrame.filmstripFrames + " frames.");
	}
	for (var i = 0; i < firstFrame.filmstripFrames; i++) {
		var frameWidth = firstFrame.properties.image.sourceWidth / firstFrame.filmstripFrames;
		var newFrame = clone(firstFrame);
		newFrame.properties.image.sourceX = frameWidth * i;
		newFrame.properties.image.sourceWidth = frameWidth;
		animations[key].push(newFrame);
	}
	animations[key].splice(0,1);
}

function Game(canvas, customRequire) {
	this.animations = customRequire("./data/animations");
	splitFilmStripAnimations(this.animations);
	this.canvas = canvas;
	this.context = canvas.getContext("2d");
	this.entities = customRequire("./data/entities");
	this.images = new ImageLoader();
	this.images.loadFromManifest(customRequire("./data/images"));
	this.inputs = new Input(customRequire("./data/inputs"), canvas);
	this.require = customRequire;
	this.scenes = customRequire("./data/scenes");
	this.sounds = new SoundLoader();
	this.sounds.loadFromManifest(customRequire("./data/sounds"));
	this.systems = customRequire("./data/systems");
	this.prefabs = customRequire("./data/prefabs");

	this.scaleCanvasToCssSize();
	window.addEventListener("resize", this.onCanvasResize.bind(this));

	this.makeScenes(this.scenes);
}
Game.prototype.makeScenes = function(sceneList) {
	Object.keys(sceneList).forEach(function(scene) {
		if (sceneList[scene].first) {
			this.scene = this.makeScene(scene, sceneList[scene], {});
		}
	}.bind(this));
};
Game.prototype.makeScene = function(name, sceneData, sceneArgs) {
	var scene = new Scene();

	var data = this.makeSceneData(scene.entities, sceneArgs);
	scene.simulation.add(function() {
		data.inputs.processUpdates();
	});
	this.installSystems(name, this.systems.simulation, scene.simulation, data);
	this.installSystems(name, this.systems.renderer, scene.renderer, data);
	scene.entities.load(clone(this.entities[name]));

	if (typeof sceneData.onEnter === "string") {
		var enterScript = this.require(sceneData.onEnter);
		if (typeof enterScript === "function") {
			enterScript = enterScript.bind(scene, data);
		}
		scene.onEnter = enterScript;
	}
	if (typeof sceneData.onExit === "string") {
		var exitScript = this.require(sceneData.onExit);
		if (typeof exitScript === "function") {
			exitScript = exitScript.bind(scene, data);
		}
		scene.onExit = exitScript;
	}

	return scene;
};
Game.prototype.makeSceneData = function(entities, sceneArgs) {
	return {
		animations: this.animations,
		arguments: sceneArgs || {},
		canvas: this.canvas,
		context: this.context,
		entities: entities,
		images: this.images,
		inputs: this.inputs,
		require: this.require,
		scaleCanvasToCssSize: this.scaleCanvasToCssSize.bind(this),
		scaleCanvasToFitRectangle: this.scaleCanvasToFitRectangle.bind(this),
		sounds: this.sounds,
		switchScene: this.switchScene.bind(this),
		instantiatePrefab: this.instantiatePrefab.bind(this),
		registerPrefab: this.registerPrefab.bind(this),
		registerPrefabs: this.registerPrefabs.bind(this)
	};
};
Game.prototype.installSystems = function(scene, systems, ecs, data) {
	systems.forEach(function(system) {
		if (system.scenes.indexOf(scene) === -1) {
			return;
		}
		var script = this.require(system.name);
		if (script === undefined) {
			console.error("failed to load script", system.name);
		}
		script(ecs, data);
	}.bind(this));
};
Game.prototype.switchScene = function(name, sceneArgs) {
	if (this.scene !== undefined) {
		this.scene.stop();
	}
	this.scene = this.makeScene(name, this.scenes[name], sceneArgs);
	this.scene.start(this.context);
};
Game.prototype.onCanvasResize = function() {
	this.resizer();
};
Game.prototype.scaleCanvasToCssSize = function() {
	this.resizer = function() {
		var canvasStyle = window.getComputedStyle(this.canvas);
		var width = parseInt(canvasStyle.width);
		var height = parseInt(canvasStyle.height);
		this.canvas.width = width;
		this.canvas.height = height;
	}.bind(this);
	this.resizer();
};
Game.prototype.scaleCanvasToFitRectangle = function(width, height) {
	this.resizer = function() {
		var canvasStyle = window.getComputedStyle(this.canvas);
		var cssWidth = parseInt(canvasStyle.width);
		var cssHeight = parseInt(canvasStyle.height);
		var cssAspectRatio = cssWidth / cssHeight;

		var desiredWidth = width;
		var desiredHeight = height;
		var desiredAspectRatio = width / height;
		if (desiredAspectRatio > cssAspectRatio) {
			desiredHeight = Math.floor(width / cssAspectRatio);
		} else if (desiredAspectRatio < cssAspectRatio) {
			desiredWidth = Math.floor(height * cssAspectRatio);
		}

		this.canvas.width = desiredWidth;
		this.canvas.height = desiredHeight;
	}.bind(this);
	this.resizer();
};
Game.prototype.instantiatePrefab = function(name) {
	var id = this.scene.entities.create();
	var prefab = this.prefabs[name];
	Object.keys(prefab).forEach(function(key) {
		if (key === "id") {
			return;
		}
		this.scene.entities.set(id, key, clone(prefab[key]));
	}.bind(this));
	return id;
};
Game.prototype.registerPrefab = function(name, components) {
	this.prefabs[name] = components;
};
Game.prototype.registerPrefabs = function(prefabs) {
	Object.keys(prefabs).forEach(function(key) {
		this.registerPrefab(key, prefabs[key]);
	}.bind(this));
};

module.exports = Game;
<commit_msg>Fix #35.<commit_after>"use strict";

var ImageLoader = require("./image-loader");
var Input = require("./input");
var Scene = require("./scene");
var SoundLoader = require("./sound-loader");

function clone(obj) {
	if (obj === undefined) {
		return undefined;
	}
	return JSON.parse(JSON.stringify(obj));
}

function splitFilmStripAnimations(animations) {
	Object.keys(animations).forEach(function(key) {
		var firstFrame = animations[key][0];
		if (firstFrame.filmstripFrames) {
			splitFilmStripAnimation(animations, key);
		}
	});
}
function splitFilmStripAnimation(animations, key) {
	var firstFrame = animations[key][0];
	if (firstFrame.properties.image.sourceWidth % firstFrame.filmstripFrames != 0) {
		console.warn("The \"" + key + "\" animation is " + firstFrame.properties.image.sourceWidth + " pixels wide and that is is not evenly divisible by " + firstFrame.filmstripFrames + " frames.");
	}
	for (var i = 0; i < firstFrame.filmstripFrames; i++) {
		var frameWidth = firstFrame.properties.image.sourceWidth / firstFrame.filmstripFrames;
		var newFrame = clone(firstFrame);
		newFrame.properties.image.sourceX = frameWidth * i;
		newFrame.properties.image.sourceWidth = frameWidth;
		animations[key].push(newFrame);
	}
	animations[key].splice(0,1);
}

function Game(canvas, customRequire) {
	this.animations = customRequire("./data/animations");
	splitFilmStripAnimations(this.animations);
	this.canvas = canvas;
	this.context = canvas.getContext("2d");
	this.entities = customRequire("./data/entities");
	this.images = new ImageLoader();
	this.images.loadFromManifest(customRequire("./data/images"));
	this.inputs = new Input(customRequire("./data/inputs"), canvas);
	this.require = customRequire;
	this.scenes = customRequire("./data/scenes");
	this.sounds = new SoundLoader();
	this.sounds.loadFromManifest(customRequire("./data/sounds"));
	this.systems = customRequire("./data/systems");
	this.prefabs = customRequire("./data/prefabs");

	this.scaleCanvasToCssSize();
	window.addEventListener("resize", this.onCanvasResize.bind(this));

	this.makeScenes(this.scenes);
}
Game.prototype.makeScenes = function(sceneList) {
	Object.keys(sceneList).forEach(function(scene) {
		if (sceneList[scene].first) {
			this.scene = this.makeScene(scene, sceneList[scene], {});
		}
	}.bind(this));
};
Game.prototype.makeScene = function(name, sceneData, sceneArgs) {
	var scene = new Scene();

	var data = this.makeSceneData(scene.entities, sceneArgs);
	scene.simulation.add(function() {
		data.inputs.processUpdates();
	});
	this.installSystems(name, this.systems.simulation, scene.simulation, data);
	this.installSystems(name, this.systems.renderer, scene.renderer, data);
	scene.entities.load(clone(this.entities[name]));

	if (typeof sceneData.onEnter === "string") {
		var enterScript = this.require(sceneData.onEnter);
		if (typeof enterScript === "function") {
			enterScript = enterScript.bind(scene, data);
		}
		scene.onEnter = enterScript;
	}
	if (typeof sceneData.onExit === "string") {
		var exitScript = this.require(sceneData.onExit);
		if (typeof exitScript === "function") {
			exitScript = exitScript.bind(scene, data);
		}
		scene.onExit = exitScript;
	}

	return scene;
};
Game.prototype.makeSceneData = function(entities, sceneArgs) {
	return {
		animations: this.animations,
		arguments: sceneArgs || {},
		canvas: this.canvas,
		context: this.context,
		entities: entities,
		images: this.images,
		inputs: this.inputs,
		require: this.require,
		scaleCanvasToCssSize: this.scaleCanvasToCssSize.bind(this),
		scaleCanvasToFitRectangle: this.scaleCanvasToFitRectangle.bind(this),
		sounds: this.sounds,
		switchScene: this.switchScene.bind(this),
		instantiatePrefab: this.instantiatePrefab.bind(this),
		registerPrefab: this.registerPrefab.bind(this),
		registerPrefabs: this.registerPrefabs.bind(this)
	};
};
Game.prototype.installSystems = function(scene, systems, ecs, data) {
	systems.forEach(function(system) {
		if (system.scenes.indexOf(scene) === -1 && system.scenes !== "all") {
			return;
		}
		var script = this.require(system.name);
		if (script === undefined) {
			console.error("failed to load script", system.name);
		}
		script(ecs, data);
	}.bind(this));
};
Game.prototype.switchScene = function(name, sceneArgs) {
	if (this.scene !== undefined) {
		this.scene.stop();
	}
	this.scene = this.makeScene(name, this.scenes[name], sceneArgs);
	this.scene.start(this.context);
};
Game.prototype.onCanvasResize = function() {
	this.resizer();
};
Game.prototype.scaleCanvasToCssSize = function() {
	this.resizer = function() {
		var canvasStyle = window.getComputedStyle(this.canvas);
		var width = parseInt(canvasStyle.width);
		var height = parseInt(canvasStyle.height);
		this.canvas.width = width;
		this.canvas.height = height;
	}.bind(this);
	this.resizer();
};
Game.prototype.scaleCanvasToFitRectangle = function(width, height) {
	this.resizer = function() {
		var canvasStyle = window.getComputedStyle(this.canvas);
		var cssWidth = parseInt(canvasStyle.width);
		var cssHeight = parseInt(canvasStyle.height);
		var cssAspectRatio = cssWidth / cssHeight;

		var desiredWidth = width;
		var desiredHeight = height;
		var desiredAspectRatio = width / height;
		if (desiredAspectRatio > cssAspectRatio) {
			desiredHeight = Math.floor(width / cssAspectRatio);
		} else if (desiredAspectRatio < cssAspectRatio) {
			desiredWidth = Math.floor(height * cssAspectRatio);
		}

		this.canvas.width = desiredWidth;
		this.canvas.height = desiredHeight;
	}.bind(this);
	this.resizer();
};
Game.prototype.instantiatePrefab = function(name) {
	var id = this.scene.entities.create();
	var prefab = this.prefabs[name];
	Object.keys(prefab).forEach(function(key) {
		if (key === "id") {
			return;
		}
		this.scene.entities.set(id, key, clone(prefab[key]));
	}.bind(this));
	return id;
};
Game.prototype.registerPrefab = function(name, components) {
	this.prefabs[name] = components;
};
Game.prototype.registerPrefabs = function(prefabs) {
	Object.keys(prefabs).forEach(function(key) {
		this.registerPrefab(key, prefabs[key]);
	}.bind(this));
};

module.exports = Game;
<|endoftext|>


<commit_before>'use strict';

import React from 'react';

const DOM = React.DOM;

/**
 * @param {number} col
 * @param {number} row
 * @return {string}
 */
const getCellName = (col, row) => {
    const first = 'a'.charCodeAt();
    const length = 'z'.charCodeAt() - first + 1;

    const x = String.fromCharCode(first + (col % length));
    const y = row + 1;
    return x + y;
};

export default class ReactBoardCell extends React.Component {
    shouldComponentUpdate(nextProps) {
        return (
            this.props.value !== nextProps.value ||
            this.props.isHighlighted !== nextProps.isHighlighted ||
            this.props.clickHandler !== nextProps.clickHandler
        );
    }

    render() {
        const cellName = getCellName(this.props.col, this.props.row);
        const cellValue = (this.props.value === null) ? '' : this.props.value;

        const classNames = [ 'react-board-cell' ];
        if (this.props.isHighlighted) {
            classNames.push('react-board-highlighted');
        }

        return DOM.div({
            className: classNames.join(' '),
            'data-cell-value': cellValue,
            'data-cell-name': cellName,
            onClick: () => this.props.clickHandler({
                col: this.props.col,
                row: this.props.row,
                cellName,
                cellValue,
            })
        });
    }
}

ReactBoardCell.propTypes = {
    row: React.PropTypes.number.isRequired,
    col: React.PropTypes.number.isRequired,
    value: (props, propName) => {
        const value = props[propName];
        const validTypes = [ 'undefined', 'string', 'number', 'boolean' ];
        if (value !== null && validTypes.indexOf(typeof value) === -1) {
            return new Error('The value of the cell should be a primitive ' +
                'value (number, string, null, undefined or boolean)!');
        }
    },
    isHighlighted: React.PropTypes.bool,
    clickHandler: React.PropTypes.func,
};

ReactBoardCell.defaultProps = {
    value: null,
    isHighlighted: false,
    clickHandler: function() {},
};
<commit_msg>Add support for large boards (larger than 28 column)<commit_after>'use strict';

import React from 'react';

const DOM = React.DOM;

/**
 * Returns an array of elements from start to end, inclusive
 * @param {number} start
 * @param {number} end
 * @return {Array.<number>}
 */
const range = function(start, end) {
    return Array.from(
        new Array(end - start + 1),
        (_, i) => start + i
    );
};

/**
 * @param {number} col
 * @return {string}
 */
const getColName = (function() {
    const signs = range('a'.charCodeAt(), 'z'.charCodeAt()).
        map((code) => String.fromCharCode(code));

    return function getColName(col) {
        if (col < signs.length) {
            return signs[col];
        }
        return getColName(Math.floor(col / signs.length) - 1) +
            getColName(col % signs.length);
    };
}());

/**
 * @param {number} row
 * @return {string}
 */
const getRowName = function(row) {
    return (row + 1).toString();
};

/**
 * @param {number} col
 * @param {number} row
 * @return {string}
 */
const getCellName = function(col, row) {
    return getColName(col) + getRowName(row);
};

export default class ReactBoardCell extends React.Component {
    shouldComponentUpdate(nextProps) {
        return (
            this.props.value !== nextProps.value ||
            this.props.isHighlighted !== nextProps.isHighlighted ||
            this.props.clickHandler !== nextProps.clickHandler
        );
    }

    render() {
        const cellName = getCellName(this.props.col, this.props.row);
        const cellValue = (this.props.value === null) ? '' : this.props.value;

        const classNames = [ 'react-board-cell' ];
        if (this.props.isHighlighted) {
            classNames.push('react-board-highlighted');
        }

        return DOM.div({
            className: classNames.join(' '),
            'data-cell-value': cellValue,
            'data-cell-name': cellName,
            onClick: () => this.props.clickHandler({
                col: this.props.col,
                row: this.props.row,
                cellName,
                cellValue,
            })
        });
    }
}

ReactBoardCell.propTypes = {
    row: React.PropTypes.number.isRequired,
    col: React.PropTypes.number.isRequired,
    value: (props, propName) => {
        const value = props[propName];
        const validTypes = [ 'undefined', 'string', 'number', 'boolean' ];
        if (value !== null && validTypes.indexOf(typeof value) === -1) {
            return new Error('The value of the cell should be a primitive ' +
                'value (number, string, null, undefined or boolean)!');
        }
    },
    isHighlighted: React.PropTypes.bool,
    clickHandler: React.PropTypes.func,
};

ReactBoardCell.defaultProps = {
    value: null,
    isHighlighted: false,
    clickHandler: function() {},
};
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the MIT license
 * If a copy of the MIT license was not distributed with this file, you can
 * obtain one at http://www.mozillapopcorn.org/butter-license.txt */

(function() {

  define( [ "core/eventmanager",
            "core/trackevent",
            "./editor"
          ], function(
            EventManagerWrapper,
            TrackEvent,
            Editor
          ){

    function EventEditor( butter, moduleOptions ){

      moduleOptions = moduleOptions || {};

      var _currentEditor,
          _this = this;

      EventManagerWrapper( _this );

      function openEditor( trackEvent ) {
        var editorType = Editor.isRegistered( trackEvent.type ) || "default";
        if( _currentEditor ) {
          _currentEditor.close();
        }
        _currentEditor = Editor.create( editorType, butter );
        _currentEditor.open( butter.ui.areas.editor.element, trackEvent );
        return _currentEditor;
      }

      butter.listen( "trackeventcreated", function( e ){
        if( [ "target", "media" ].indexOf( e.data.by ) > -1 && butter.ui.contentState === "timeline" ){
          _this.edit( e.data.trackEvent );
        }
      });

      this.edit = function( trackEvent ){
        if ( !trackEvent || !( trackEvent instanceof TrackEvent ) ){
          throw new Error( "trackEvent must be valid to start an editor." );
        }
        return openEditor( trackEvent );
      };

      butter.listen( "trackeventadded", function ( e ) {
        var trackEvent = e.data;

        var trackEventMouseUp = function ( e ) {
          if( butter.selectedEvents.length === 1 && !trackEvent.dragging ){
            openEditor( trackEvent );
          }
        };

        e.data.view.element.addEventListener( "click", trackEventMouseUp, false );

        butter.listen( "trackeventremoved", function ( e ) {
          if ( e.data === trackEvent ) {
            e.data.view.element.removeEventListener( "mouseup", trackEventMouseUp, true );
          }
        });
      });

      this._start = function( onModuleReady ){
        onModuleReady();
      };

    }

    this.register = Editor.register;

    EventEditor.__moduleName = "editor";

    return EventEditor;

  }); //define
}());
<commit_msg>[t1174] src/editor/module documentation<commit_after>/* This Source Code Form is subject to the terms of the MIT license
 * If a copy of the MIT license was not distributed with this file, you can
 * obtain one at http://www.mozillapopcorn.org/butter-license.txt */

/**
 * Module: EditorModule
 *
 * Butter Module for Editors
 */
define( [ "core/eventmanager",
          "core/trackevent",
          "./editor"
        ], function(
          EventManagerWrapper,
          TrackEvent,
          Editor
        ){

  /**
   * Class: EventEditor
   *
   * Module which provides Editor functionality to Butter
   */
  function EventEditor( butter, moduleOptions ){

    moduleOptions = moduleOptions || {};

    var _currentEditor,
        _this = this;

    EventManagerWrapper( _this );

    /**
     * Member: openEditor
     *
     * Open the editor corresponding to the type of the given TrackEvent
     *
     * @param {TrackEvent} trackEvent: TrackEvent to edit
     */
    function openEditor( trackEvent ) {
      var editorType = Editor.isRegistered( trackEvent.type ) || "default";
      if( _currentEditor ) {
        _currentEditor.close();
      }
      _currentEditor = Editor.create( editorType, butter );
      _currentEditor.open( butter.ui.areas.editor.element, trackEvent );
      return _currentEditor;
    }

    // When a TrackEvent is somewhere in butter, open its editor immediately.
    butter.listen( "trackeventcreated", function( e ){
      if( [ "target", "media" ].indexOf( e.data.by ) > -1 && butter.ui.contentState === "timeline" ){
        openEditor( e.data.trackEvent );
      }
    });

    /**
     * Member: edit
     *
     * Open the editor of corresponding to the type of the given TrackEvent
     *
     * @param {TrackEvent} trackEvent: TrackEvent to edit
     */
    this.edit = function( trackEvent ){
      if ( !trackEvent || !( trackEvent instanceof TrackEvent ) ){
        throw new Error( "trackEvent must be valid to start an editor." );
      }
      return openEditor( trackEvent );
    };

    butter.listen( "trackeventadded", function ( e ) {
      var trackEvent = e.data;

      var trackEventMouseUp = function ( e ) {
        if( butter.selectedEvents.length === 1 && !trackEvent.dragging ){
          openEditor( trackEvent );
        }
      };

      trackEvent.view.element.addEventListener( "mouseup", trackEventMouseUp, true );

      butter.listen( "trackeventremoved", function ( e ) {
        if ( e.data === trackEvent ) {
          e.data.view.element.removeEventListener( "mouseup", trackEventMouseUp, true );
        }
      });

    });

    /**
     * Member: _start
     *
     * Prepares this module for Butter startup
     *
     * @param {Function} onModuleReady: Callback to signify that module is ready
     */
    this._start = function( onModuleReady ){
      onModuleReady();
    };

  }

  this.register = Editor.register;

  EventEditor.__moduleName = "editor";

  return EventEditor;

}); //define
<|endoftext|>


<commit_before>/*
    SimpleProtocols - A protocol generator
    Copyright (C) 2017 Andrew S

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
module.exports = function (obj, data, parse, lvl) {
    var length = obj[0].split(" ")[1];

    data.get.push("var data" + lvl + " = [];")
    data.get.push("for (var i" + lvl + " = 0; i" + lvl + " < " + length + "; i" + lvl + " ++) {")
    data.get.push4("}")

    var lvl2 = lvl + 1;
    data.set.push("for (var i" + lvl + " = 0; i" + lvl + " < " + length + "; i" + lvl + " ++) {")
    data.set.push("var data" + lvl2 + " = data" + lvl + "[i" + lvl + "];")
    data.set.push4("}")

    var now = data.count.index;
    data.count.push("for (var i" + lvl + " = 0; i" + lvl + " < " + length + "; i" + lvl + " ++) {")
    data.count.push("var data" + lvl2 + " = data" + lvl + "[i" + lvl + "];")
    data.count.push4("}")

    var r = parse(obj[1], false, 2);
    if (r) {
        console.log(obj[1])
        data.count.data.splice(now, data.count.index - now)
        data.count.index = now;
        data.count.append.splice(0, 1);
    }
    return r;

}
<commit_msg>Update fixedArrayManager.js<commit_after>/*
    SimpleProtocols - A protocol generator
    Copyright (C) 2017 Andrew S

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
module.exports = function (obj, data, parse, lvl) {
    var length = obj[0].split(" ")[1];

    data.get.push("var data" + lvl + " = [];")
    data.get.push("for (var i" + lvl + " = 0; i" + lvl + " < " + length + "; i" + lvl + " ++) {")
    data.get.push4("}")

    var lvl2 = lvl + 1;
    data.set.push("for (var i" + lvl + " = 0; i" + lvl + " < " + length + "; i" + lvl + " ++) {")
    data.set.push("var data" + lvl2 + " = data" + lvl + "[i" + lvl + "];")
    data.set.push4("}")

    var now = data.count.index;
    data.count.push("for (var i" + lvl + " = 0; i" + lvl + " < " + length + "; i" + lvl + " ++) {")
    data.count.push("var data" + lvl2 + " = data" + lvl + "[i" + lvl + "];")
    data.count.push4("}")

    var r = parse(obj[1], false, 2);
    if (r) {
        data.count.data.splice(now, data.count.index - now)
        data.count.index = now;
        data.count.append.splice(0, 1);
    }
    return r;

}
<|endoftext|>


<commit_before>//Copyright 2014, Thomas Pronk
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.

/**
 * Init JASMIN namespace
 * @private
 */
if( jasmin === undefined ) { var jasmin = function() {}; }

/**
 * Features for making AJAX requests, loading CSS and loading images
 * is set up to actively send any outstanding requests. It can
 * be configured to (a) actively send outstanding requests or not; (b) immediately
 * send a request or to wait until the next try (for bulk sending); (c) flush
 * all open request and call a callback once all have been sent (to send remaining
 * logs at the end of a participation
 * @constructor
 * @param {Function}  fail                callback called if RequestManager fails
 * @param {int}       timeout             Default number of ms waited until retrying a request (can be overriden by individual request), default = 4000
 * @param {int}       retries             Default number of retries until failing (can be overriden by individual request), default = 8
 * @param {int}       active              Will always sending and retry requests (true) or only when flushing (false), default = true
 * @param {int}       checkInterval       Number of ms between checking if we should resend anything; default = 300
 */
jasmin.RequestManager = function (
   fail,
   timeout,
   retries,
   active,
   checkInterval
) {
   this.fail          = fail === undefined? function () {}: fail;
   this.timeout       = timeout === undefined? 4000: timeout;
   this.retries       = retries === undefined? 8: retries;
   this.active        = active  === undefined? true: active;
   this.checkInterval = checkInterval === undefined? 300: checkInterval;

   // For flushing (sending all remaining requests)
   this.flushing        = false;
   this.flushCallback   = undefined;

   // Constants for request states
   this.STATE_OPEN   = 1;  // Request is being transmitted
   this.STATE_FAILED = 2;  // Request failed
   this.STATE_FIRST  = 3;  // Request that haven't been sent yet

   this.states = {};       // Data on current AJAX states we are working with
   this.stateCounter = 0;  // stateCounter - Assigns unique stateId for each request
   this.transactionCounter = 0; // Counts individual transactions
   this.errorLogs = []; // Log of all errors

   this.failed = false;    // If we permanently failed; don't attempt any ajax requests anymore

   // If we're active; start checking whether there is anything to do
   if(this.active) {
      this.check();
   }
};

jasmin.RequestManager.prototype.error = function (errorMessage) {
   this.errorLogs.push(errorMessage);
}

/**
 * Constant for AJAX type requests
 * @constant
 */
jasmin.RequestManager.TYPE_AJAX = "ajax";

/**
 * Constant for img type requests
 * @constant
 */
jasmin.RequestManager.TYPE_IMG = "img";

/**
 * Make a single request
 * @param {const}    type         jasmin.RequestManager.TYPE_AJAX (request is passed on to jQuery.ajax or jasmin.RequestManager.TYPE_IMG (request is url of img)
 * @param {Object}   request      The request (what do say to which url)
 * @param {function} callback     Callback called on reply (with data replied by target url as argument)
 * @param {int}      timeout      Overrides default value set in constructor
 * @param {int}      retries      Overrides default value set in constructor
 * @return stateId of the request to be sent
 * @public
 */
jasmin.RequestManager.prototype.request = function (type, request, callback, timeout, retries) {
   // Setup state
   var counter = this.stateCounter;
   this.states[counter] = {
      // Copy arguments
      "type"            : type,
      "request"         : request,
      "callback"        : callback,
      "timeout"         : timeout,
      "retries"         : retries,

      // Stuff to initialize
      "state"           : this.STATE_FIRST,
      "retryCounter"    : 0,
      "handled"         : false
   };
   this.stateCounter++;

   // Report
   DEBUG & console.log("RequestManager.request, stateId " + counter);
   DEBUG & console.log(request);

   // If active; send immediately
   if (this.active) {
      this.sendOpenRequests();
   };

   return counter;
};

/**
 * Send all open states (that should be sent)
 * @private
 */
jasmin.RequestManager.prototype.sendOpenRequests = function () {
   // Only continue if we are active or flushing and didn't fail
   if (!((this.active || this.flushing) && !this.failed)) {
     return;
   }
   // Get stateIds to send
   var stateIds = this.statesToSend();
   // If anything to send, then send it
   if (stateIds.length > 0) {
      // Send each request on the list
      var stateId;
      for (var i in stateIds) {
         stateId = stateIds[i];
         transactionId = this.transactionCounter;
         switch (this.states[stateId]["type"]) {
            case jasmin.RequestManager.TYPE_AJAX:
               this.ajaxRequest(stateId, transactionId);
               break;
            case jasmin.RequestManager.TYPE_IMG:
               this.imgRequest(stateId, transactionId);
               break;
         }

         this.transactionCounter++;

         // Update state
         this.states[stateId]["state"] = this.STATE_OPEN;
         this.states[stateId]["retryCounter" ]++;
         this.states[stateId]["attemptTime"] = new Date().getTime();
      }
   }
};

/**
 * Process all open states (do nothing, add to sendlist, or fail)
 * @return stateIds to retry
 * @private
 */
jasmin.RequestManager.prototype.statesToSend = function () {
   var time      = new Date().getTime();        // Get time
   var sendList  = new Array();       // Requests to retry

   // Check which states to add to sendList
   var timeout, retries;
   for (var i in this.states) {
      // Check for now and open
      switch (this.states[i]["state"]) {
         // Now? immediately add to sendList
         case this.STATE_FIRST:
            sendList.push(i);
            DEBUG && console.log("RequestManager.statesToSend, stateId " + i + ", STATE_FIRST");
            break;
         // Open? Fail if timed out
         case this.STATE_OPEN:
            // get default or overriden value of timeout
            timeout = this.states[i]["timeout"] === undefined? this.timeout : this.states[i]["timeout"];
            // If timed out, then failed, add to list
            if (time - this.states[i]["attemptTime"] > timeout) {
               DEBUG && console.log("RequestManager.statesToSend, stateId " + i + " open and timed out");
               // Timed out -> state to failed
               this.states[i]["state"] = this.STATE_FAILED;
            }
            break;
      }

      // Handle failed request -> retry if attempts not exceeded
      if (this.states[i]["state"] === this.STATE_FAILED) {
         // get default or overriden value of retries
         retries = this.states[i]["retries"] === undefined? this.retries : this.states[i]["retries"];

         // Check if max attempts exceeded
         if (this.states[i]["retryCounter"] >= this.retries) {
            DEBUG && console.log("RequestManager.statesToSend, stateId " + i + " failed; Exceeded " + this.retries + " attempts");

            // We officially failed
            if (!this.failed) {
               this.failed = true;
               this.error("Max attempts exceeded");
               this.fail(this.errorLogs);
            }
         } else {
            DEBUG && console.log("RequestManager.statesToSend, stateId " + i + " added to sendList");
            sendList.push(i);
         }
      }
   }
   return sendList;
};

/**
 * Do an (asynchronous) AJAX request. Request is associative array passed on
 * to jQuery.ajax
 * @param stateId
 * @param transactionId
 * @private
 */
jasmin.RequestManager.prototype.ajaxRequest = function (stateId, transactionId) {
   // arguments to pass to jQuery.ajax
   var ajaxArgs = this.states[stateId]["request"];

   // Report ajax
   DEBUG && console.log("RequestManager.ajaxRequest, stateId = " + stateId + ", transactionId = " + transactionId);
   DEBUG && console.log(ajaxArgs);

   // Send
   var self = this;
   var ajax = $.ajax(ajaxArgs);
   ajax.done(
      function (response, status) {
         // Report replies
         DEBUG && console.log("RequestManager ajax.done, stateId " + stateId + ", transactionId " + transactionId + ", status " + status);
         DEBUG && console.log(ajaxArgs);
         DEBUG && console.log(response);
         self.success( stateId, response );
      }
   );
   ajax.fail(
      function (response, status) {
         DEBUG && console.log("RequestManager ajax.fail, stateId " + stateId + ", transactionId " + transactionId + ", status " + status);
         DEBUG && console.log(ajaxArgs);
         DEBUG && console.log(response);
         // Error; only report it, let the request time out and retry
         self.error("ajax.fail, stateId " + stateId + ", transactionId " + transactionId + ", status " + status + ", ajaxArgs: " + JSON.stringify(ajaxArgs) + ", response:" + JSON.stringify(response));
      }
   );
};

// Downloading an img
jasmin.RequestManager.prototype.imgRequest = function (stateId, transactionId) {
   var url = this.states[stateId]["request"];

   // Report ajax
   DEBUG && console.log("RequestManager.imgRequest, stateId = " + stateId + ", transactionId = " + transactionId + ", url = " + url);

   var self = this;
   this.states[stateId]["reply"] = $("<img>").attr(
      "src", url + "?_=" + new Date().getTime()
   ).load(function () {
      if (self.states[stateId]["reply"] === undefined) {
         self.error("img reply undefined, stateId " + stateId + ", transactionId " + transactionId + ", url " + url);
      }
      DEBUG && console.log("RequestManager img load, stateId " + stateId + ", transactionId " + transactionId);
      self.success(stateId, self.states[stateId]["reply"]);
   }).error(function () {
       self.error("img error, stateId " + stateId + ", transactionId " + transactionId + ", url " + url);
   });
};

/**
 * On success, handle request; call callback with argument reply and remove state
 * @param stateId
 * @param reply
 * @private
 */
jasmin.RequestManager.prototype.success = function (stateId, reply) {
   // Check if state still exists and is not handled, if so, handle it
   if (this.states[stateId] !== undefined && !this.states[stateId]["handled"]) {
      // Request is now handled
      this.states[stateId]["handled"] = true;

      // Call callback (if defined)
      if (this.states[stateId]["callback"] !== undefined) {
         try {
            this.states[stateId]["callback"](reply);
         } catch(e) {}
      }

      // Remove state
      delete this.states[stateId];
   }

   // If flushing; check if all requests are sent, then call flushCallback
   if (this.flushing && $.isEmptyObject(this.states)) {
      this.flushing = false;
      if (this.flushCallback !== undefined) {
          this.flushCallback();
      }
   }
};

/**
 * Check if we should send open requests
 * @private
 */
jasmin.RequestManager.prototype.check = function () {
   // Keep sending open requests if we are active or flushing and haven't failed yet
   // NB - the same expression is also evaluated at start of sendOpenRequests
   if ((this.active || this.flushing) && !this.failed) {
      this.sendOpenRequests();
      var self = this;
      setTimeout(
         function () {
            self.check();
         },
         this.checkInterval
      );
   }
};

/**
 * Make sure that all open requests are being sent and then call this callback
 * (open requests are retried even regardless of active)
 * @param {Function} flushCallback After flushing this callback is called
 */
jasmin.RequestManager.prototype.flush = function (flushCallback) {
   this.flushing      = true;
	this.flushCallback = flushCallback;
   if ($.isEmptyObject(this.states)) {
      if (this.flushCallback !== undefined) {
         this.flushCallback();
      }
   }

   this.check();
};<commit_msg>bugfix<commit_after>//Copyright 2014, Thomas Pronk
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.

/**
 * Init JASMIN namespace
 * @private
 */
if( jasmin === undefined ) { var jasmin = function() {}; }

/**
 * Features for making AJAX requests, loading CSS and loading images
 * is set up to actively send any outstanding requests. It can
 * be configured to (a) actively send outstanding requests or not; (b) immediately
 * send a request or to wait until the next try (for bulk sending); (c) flush
 * all open request and call a callback once all have been sent (to send remaining
 * logs at the end of a participation
 * @constructor
 * @param {Function}  fail                callback called if RequestManager fails
 * @param {int}       timeout             Default number of ms waited until retrying a request (can be overriden by individual request), default = 4000
 * @param {int}       retries             Default number of retries until failing (can be overriden by individual request), default = 8
 * @param {int}       active              Will always sending and retry requests (true) or only when flushing (false), default = true
 * @param {int}       checkInterval       Number of ms between checking if we should resend anything; default = 300
 */
jasmin.RequestManager = function (
   fail,
   timeout,
   retries,
   active,
   checkInterval
) {
   this.fail          = fail === undefined? function () {}: fail;
   this.timeout       = timeout === undefined? 4000: timeout;
   this.retries       = retries === undefined? 8: retries;
   this.active        = active  === undefined? true: active;
   this.checkInterval = checkInterval === undefined? 300: checkInterval;

   // For flushing (sending all remaining requests)
   this.flushing        = false;
   this.flushCallback   = undefined;

   // Constants for request states
   this.STATE_OPEN   = 1;  // Request is being transmitted
   this.STATE_FAILED = 2;  // Request failed
   this.STATE_FIRST  = 3;  // Request that haven't been sent yet

   this.states = {};       // Data on current AJAX states we are working with
   this.stateCounter = 0;  // stateCounter - Assigns unique stateId for each request
   this.transactionCounter = 0; // Counts individual transactions
   this.errorLogs = []; // Log of all errors

   this.failed = false;    // If we permanently failed; don't attempt any ajax requests anymore

   // If we're active; start checking whether there is anything to do
   if(this.active) {
      this.check();
   }
};

jasmin.RequestManager.prototype.error = function (errorMessage) {
   this.errorLogs.push(errorMessage);
}

/**
 * Constant for AJAX type requests
 * @constant
 */
jasmin.RequestManager.TYPE_AJAX = "ajax";

/**
 * Constant for img type requests
 * @constant
 */
jasmin.RequestManager.TYPE_IMG = "img";

/**
 * Make a single request
 * @param {const}    type         jasmin.RequestManager.TYPE_AJAX (request is passed on to jQuery.ajax or jasmin.RequestManager.TYPE_IMG (request is url of img)
 * @param {Object}   request      The request (what do say to which url)
 * @param {function} callback     Callback called on reply (with data replied by target url as argument)
 * @param {int}      timeout      Overrides default value set in constructor
 * @param {int}      retries      Overrides default value set in constructor
 * @return stateId of the request to be sent
 * @public
 */
jasmin.RequestManager.prototype.request = function (type, request, callback, timeout, retries) {
   // Setup state
   var counter = this.stateCounter;
   this.states[counter] = {
      // Copy arguments
      "type"            : type,
      "request"         : request,
      "callback"        : callback,
      "timeout"         : timeout,
      "retries"         : retries,

      // Stuff to initialize
      "state"           : this.STATE_FIRST,
      "retryCounter"    : 0,
      "handled"         : false
   };
   this.stateCounter++;

   // Report
   DEBUG && console.log("RequestManager.request, stateId " + counter);
   DEBUG && console.log(request);

   // If active; send immediately
   if (this.active) {
      this.sendOpenRequests();
   };

   return counter;
};

/**
 * Send all open states (that should be sent)
 * @private
 */
jasmin.RequestManager.prototype.sendOpenRequests = function () {
   // Only continue if we are active or flushing and didn't fail
   if (!((this.active || this.flushing) && !this.failed)) {
     return;
   }
   // Get stateIds to send
   var stateIds = this.statesToSend();
   // If anything to send, then send it
   if (stateIds.length > 0) {
      // Send each request on the list
      var stateId;
      for (var i in stateIds) {
         stateId = stateIds[i];
         transactionId = this.transactionCounter;
         switch (this.states[stateId]["type"]) {
            case jasmin.RequestManager.TYPE_AJAX:
               this.ajaxRequest(stateId, transactionId);
               break;
            case jasmin.RequestManager.TYPE_IMG:
               this.imgRequest(stateId, transactionId);
               break;
         }

         this.transactionCounter++;

         // Update state
         this.states[stateId]["state"] = this.STATE_OPEN;
         this.states[stateId]["retryCounter" ]++;
         this.states[stateId]["attemptTime"] = new Date().getTime();
      }
   }
};

/**
 * Process all open states (do nothing, add to sendlist, or fail)
 * @return stateIds to retry
 * @private
 */
jasmin.RequestManager.prototype.statesToSend = function () {
   var time      = new Date().getTime();        // Get time
   var sendList  = new Array();       // Requests to retry

   // Check which states to add to sendList
   var timeout, retries;
   for (var i in this.states) {
      // Check for now and open
      switch (this.states[i]["state"]) {
         // Now? immediately add to sendList
         case this.STATE_FIRST:
            sendList.push(i);
            DEBUG && console.log("RequestManager.statesToSend, stateId " + i + ", STATE_FIRST");
            break;
         // Open? Fail if timed out
         case this.STATE_OPEN:
            // get default or overriden value of timeout
            timeout = this.states[i]["timeout"] === undefined? this.timeout : this.states[i]["timeout"];
            // If timed out, then failed, add to list
            if (time - this.states[i]["attemptTime"] > timeout) {
               DEBUG && console.log("RequestManager.statesToSend, stateId " + i + " open and timed out");
               // Timed out -> state to failed
               this.states[i]["state"] = this.STATE_FAILED;
            }
            break;
      }

      // Handle failed request -> retry if attempts not exceeded
      if (this.states[i]["state"] === this.STATE_FAILED) {
         // get default or overriden value of retries
         retries = this.states[i]["retries"] === undefined? this.retries : this.states[i]["retries"];

         // Check if max attempts exceeded
         if (this.states[i]["retryCounter"] >= this.retries) {
            DEBUG && console.log("RequestManager.statesToSend, stateId " + i + " failed; Exceeded " + this.retries + " attempts");

            // We officially failed
            if (!this.failed) {
               this.failed = true;
               this.error("Max attempts exceeded");
               this.fail(this.errorLogs);
            }
         } else {
            DEBUG && console.log("RequestManager.statesToSend, stateId " + i + " added to sendList");
            sendList.push(i);
         }
      }
   }
   return sendList;
};

/**
 * Do an (asynchronous) AJAX request. Request is associative array passed on
 * to jQuery.ajax
 * @param stateId
 * @param transactionId
 * @private
 */
jasmin.RequestManager.prototype.ajaxRequest = function (stateId, transactionId) {
   // arguments to pass to jQuery.ajax
   var ajaxArgs = this.states[stateId]["request"];

   // Report ajax
   DEBUG && console.log("RequestManager.ajaxRequest, stateId = " + stateId + ", transactionId = " + transactionId);
   DEBUG && console.log(ajaxArgs);

   // Send
   var self = this;
   var ajax = $.ajax(ajaxArgs);
   ajax.done(
      function (response, status) {
         // Report replies
         DEBUG && console.log("RequestManager ajax.done, stateId " + stateId + ", transactionId " + transactionId + ", status " + status);
         DEBUG && console.log(ajaxArgs);
         DEBUG && console.log(response);
         self.success( stateId, response );
      }
   );
   ajax.fail(
      function (response, status) {
         DEBUG && console.log("RequestManager ajax.fail, stateId " + stateId + ", transactionId " + transactionId + ", status " + status);
         DEBUG && console.log(ajaxArgs);
         DEBUG && console.log(response);
         // Error; only report it, let the request time out and retry
         self.error("ajax.fail, stateId " + stateId + ", transactionId " + transactionId + ", status " + status + ", ajaxArgs: " + JSON.stringify(ajaxArgs) + ", response:" + JSON.stringify(response));
      }
   );
};

// Downloading an img
jasmin.RequestManager.prototype.imgRequest = function (stateId, transactionId) {
   var url = this.states[stateId]["request"];

   // Report ajax
   DEBUG && console.log("RequestManager.imgRequest, stateId = " + stateId + ", transactionId = " + transactionId + ", url = " + url);

   var self = this;
   this.states[stateId]["reply"] = $("<img>").attr(
      "src", url + "?_=" + new Date().getTime()
   ).load(function () {
      if (self.states[stateId]["reply"] === undefined) {
         self.error("img reply undefined, stateId " + stateId + ", transactionId " + transactionId + ", url " + url);
      }
      DEBUG && console.log("RequestManager img load, stateId " + stateId + ", transactionId " + transactionId);
      self.success(stateId, self.states[stateId]["reply"]);
   }).error(function () {
       self.error("img error, stateId " + stateId + ", transactionId " + transactionId + ", url " + url);
   });
};

/**
 * On success, handle request; call callback with argument reply and remove state
 * @param stateId
 * @param reply
 * @private
 */
jasmin.RequestManager.prototype.success = function (stateId, reply) {
   // Check if state still exists and is not handled, if so, handle it
   if (this.states[stateId] !== undefined && !this.states[stateId]["handled"]) {
      // Request is now handled
      this.states[stateId]["handled"] = true;

      // Call callback (if defined)
      if (this.states[stateId]["callback"] !== undefined) {
         try {
            this.states[stateId]["callback"](reply);
         } catch(e) {}
      }

      // Remove state
      delete this.states[stateId];
   }

   // If flushing; check if all requests are sent, then call flushCallback
   if (this.flushing && $.isEmptyObject(this.states)) {
      this.flushing = false;
      if (this.flushCallback !== undefined) {
          this.flushCallback();
      }
   }
};

/**
 * Check if we should send open requests
 * @private
 */
jasmin.RequestManager.prototype.check = function () {
   // Keep sending open requests if we are active or flushing and haven't failed yet
   // NB - the same expression is also evaluated at start of sendOpenRequests
   if ((this.active || this.flushing) && !this.failed) {
      this.sendOpenRequests();
      var self = this;
      setTimeout(
         function () {
            self.check();
         },
         this.checkInterval
      );
   }
};

/**
 * Make sure that all open requests are being sent and then call this callback
 * (open requests are retried even regardless of active)
 * @param {Function} flushCallback After flushing this callback is called
 */
jasmin.RequestManager.prototype.flush = function (flushCallback) {
   this.flushing      = true;
	this.flushCallback = flushCallback;
   if ($.isEmptyObject(this.states)) {
      if (this.flushCallback !== undefined) {
         this.flushCallback();
      }
   }

   this.check();
};<|endoftext|>


<commit_before>function Game (board) {
  this.board = board;
  this.turn = "white";
}

Game.prototype.toggleTurn = function () {
  if (this.turn === "white") {
    this.turn = "black";
  } else if (this.turn === "black") {
    this.turn = "white";
  }
};

module.exports = Game;
<commit_msg>Adds inCheck method to the turn toggle closure.<commit_after>function Game (board) {
  this.board = board;
  this.turn = "white";
}

Game.prototype.toggleTurn = function () {
  if (this.turn === "white") {
    this.turn = "black";
  } else if (this.turn === "black") {
    this.turn = "white";
  }
  if (this.inCheck()) {
    console.log("check");
  }
};

Game.prototype.inCheck = function () {
  var kingsSquare = this.board.currentKingSquare();
  var attackingPieces = this.board.opponentCanMoveHere(kingsSquare);
  return attackingPieces.length > 0
};

module.exports = Game;
<|endoftext|>


<commit_before>import log from "loglevel";

import Core from "./core";

const State = {
  Begin: "begin",
  Create: "create",
  DelayShow: "delay-show",
  Show: "show",
  CheckDead: "check-dead",
  CheckDrop: "check-drop",
  DelayDrop: "delay-drop",
  Drop: "drop",
  DelayLock: "delay-lock",
  Lock: "lock",
  End: "end",
};

export default class Engine {
  constructor() {
    this.frame = 0;
    this.core = new Core();
    this.state = State.Begin;
    this.delays = {
      show: 0,
      drop: 0,
      lock: 0,
    };
  }
  trace(...args) {
    log.trace("%o [%s]", this.frame, String(this.state).toUpperCase(), ...args);
  }
  delay(name, config) {
    this.delays[name]++;
    const result = this.delays[name] > config.delay[name];
    if (result) {
      this.delays[name] = 0;
    }
    return result;
  }
  resetLockDelay() {
    // FIXME
    this.delays.lock = 0;
  }
  actKey() {
    const hasMoved = false;
    return hasMoved;
  }
  act({ config }) {
    const core = this.core;
    switch (this.state) {
      case State.Begin: {
        this.trace();
        this.state = State.Create;
        break;
      }

      case State.Create: {
        core.next();
        core.showBlock = false;
        this.trace(core.block);
        this.state = State.DelayShow;
        break;
      }

      case State.DelayShow: {
        if (this.delays.show >= config.delay.show) {
          this.delays.show = 0;
          this.state = State.Show;
          break;
        }
        this.delays.show++;
        break;
      }

      case State.Show: {
        core.showBlock = true;
        // TODO: IRS & IHS
        this.state = State.CheckDead;
        break;
      }

      case State.CheckDead: {
        if (core.isDead()) {
          this.state = State.End;
          break;
        }
        this.state = State.CheckDrop;
        break;
      }

      case State.CheckDrop: {
        if (core.canDrop()) {
          this.state = State.DelayDrop;
        } else {
          this.resetLockDelay();
          this.state = State.DelayLock;
        }
        break;
      }

      case State.DelayDrop: {
        if (!core.canDrop()) {
          this.state = State.CheckDrop;
          break;
        }
        if (this.delays.drop >= config.delay.drop) {
          this.delays.drop = 0;
          this.state = State.Drop;
          break;
        }
        // TODO: handle input
        this.delays.drop++;
        break;
      }

      case State.Drop: {
        core.drop();
        this.state = State.CheckDrop;
        break;
      }

      case State.DelayLock: {
        if (core.canDrop()) {
          this.state = State.CheckDrop;
          break;
        }
        if (this.delays.lock >= config.delay.lock) {
          this.delays.lock = 0;
          this.state = State.Lock;
          break;
        }
        // TODO: handle input
        this.delays.lock++;
        break;
      }

      case State.Lock: {
        core.lock();
        this.trace();
        this.state = State.Create;
        break;
      }

      case State.End: {
        // TODO
        this.trace();
        break;
      }
    }
  }
  loop(data) {
    let previousState = null;
    while (previousState !== this.state) {
      previousState = this.state;
      this.act(data);
    }
  }
  next({ frame, config, input }) {
    for (let __ = 0; __ < frame; __++) {
      this.frame++;
      this.loop({ config, input });
    }
    if (this.state === State.End) {
      return {
        action: "complete",
      };
    }
    return {
      action: "next",
      data: this.core,
    };
  }
}
<commit_msg>remove unused function<commit_after>import log from "loglevel";

import Core from "./core";

const State = {
  Begin: "begin",
  Create: "create",
  DelayShow: "delay-show",
  Show: "show",
  CheckDead: "check-dead",
  CheckDrop: "check-drop",
  DelayDrop: "delay-drop",
  Drop: "drop",
  DelayLock: "delay-lock",
  Lock: "lock",
  End: "end",
};

export default class Engine {
  constructor() {
    this.frame = 0;
    this.core = new Core();
    this.state = State.Begin;
    this.delays = {
      show: 0,
      drop: 0,
      lock: 0,
    };
  }
  trace(...args) {
    log.trace("%o [%s]", this.frame, String(this.state).toUpperCase(), ...args);
  }
  resetLockDelay() {
    // TODO
    this.delays.lock = 0;
  }
  actKey() {
    const hasMoved = false;
    return hasMoved;
  }
  act({ config }) {
    const core = this.core;
    switch (this.state) {
      case State.Begin: {
        this.trace();
        this.state = State.Create;
        break;
      }

      case State.Create: {
        core.next();
        core.showBlock = false;
        this.trace(core.block);
        this.state = State.DelayShow;
        break;
      }

      case State.DelayShow: {
        if (this.delays.show >= config.delay.show) {
          this.delays.show = 0;
          this.state = State.Show;
          break;
        }
        this.delays.show++;
        break;
      }

      case State.Show: {
        core.showBlock = true;
        // TODO: IRS & IHS
        this.state = State.CheckDead;
        break;
      }

      case State.CheckDead: {
        if (core.isDead()) {
          this.state = State.End;
          break;
        }
        this.state = State.CheckDrop;
        break;
      }

      case State.CheckDrop: {
        if (core.canDrop()) {
          this.state = State.DelayDrop;
        } else {
          this.resetLockDelay();
          this.state = State.DelayLock;
        }
        break;
      }

      case State.DelayDrop: {
        if (!core.canDrop()) {
          this.state = State.CheckDrop;
          break;
        }
        if (this.delays.drop >= config.delay.drop) {
          this.delays.drop = 0;
          this.state = State.Drop;
          break;
        }
        // TODO: handle input
        this.delays.drop++;
        break;
      }

      case State.Drop: {
        core.drop();
        this.state = State.CheckDrop;
        break;
      }

      case State.DelayLock: {
        if (core.canDrop()) {
          this.state = State.CheckDrop;
          break;
        }
        if (this.delays.lock >= config.delay.lock) {
          this.delays.lock = 0;
          this.state = State.Lock;
          break;
        }
        // TODO: handle input
        this.delays.lock++;
        break;
      }

      case State.Lock: {
        core.lock();
        this.trace();
        this.state = State.Create;
        break;
      }

      case State.End: {
        // TODO
        this.trace();
        break;
      }
    }
  }
  loop(data) {
    let previousState = null;
    while (previousState !== this.state) {
      previousState = this.state;
      this.act(data);
    }
  }
  next({ frame, config, input }) {
    for (let __ = 0; __ < frame; __++) {
      this.frame++;
      this.loop({ config, input });
    }
    if (this.state === State.End) {
      return {
        action: "complete",
      };
    }
    return {
      action: "next",
      data: this.core,
    };
  }
}
<|endoftext|>


<commit_before>import escapeRegExp from 'lodash/escapeRegExp'
import Type from './type'

export const matcher = /^unit\(.*\)/gim

export default params => {
  const units = params.match(/\(([^)]+)\)/)[1].split(',')
  const argsMatch = params.match(/\{([^}]+)\}/)
  const args = (argsMatch && argsMatch[1] && argsMatch[1].split(',')) || ['1'] // defaults to 1

  return class Unit extends Type {
    static errorMessage = `has invalid value: $value for type Unit, only accepts (${units.join(
      ', ',
    )}) units and ${args.join(' to ')} member(s)`

    constructor(value) {
      super(value)

      this.matchers = [
        new RegExp(
          `^(((\\d|,|.){1,}(${units.map(escapeRegExp).join('|')})|0)( )?){${args.join(
            ',',
          )}}$`,
        ),
      ]
    }
  }
}
<commit_msg>change wording<commit_after>import escapeRegExp from 'lodash/escapeRegExp'
import Type from './type'

export const matcher = /^unit\(.*\)/gim

export default params => {
  const units = params.match(/\(([^)]+)\)/)[1].split(',')
  const argsMatch = params.match(/\{([^}]+)\}/)
  const args = (argsMatch && argsMatch[1] && argsMatch[1].split(',')) || ['1'] // defaults to 1

  return class Unit extends Type {
    static errorMessage = `has invalid value: $value for type Unit, only accepts (${units.join(
      ', ',
    )}) units and ${args.join(' to ')} value(s)`

    constructor(value) {
      super(value)

      this.matchers = [
        new RegExp(
          `^(((\\d|,|.){1,}(${units.map(escapeRegExp).join('|')})|0)( )?){${args.join(
            ',',
          )}}$`,
        ),
      ]
    }
  }
}
<|endoftext|>