<commit_before>'use strict';

const _          = require('lodash');
const fs         = require('fs');
const path       = require('path');
const assert     = require('assert');
const sinon      = require('sinon');
const async      = require('asyncawait/async');
const await      = require('asyncawait/await');
const ipfsDaemon = require('orbit-common/lib/ipfs-daemon');
const OrbitDB    = require('../src/OrbitDB');
const Log        = require('ipfs-log');

// Mute logging
// require('log4js').setGlobalLogLevel('ERROR');

// Orbit
const username = 'testrunner';
const password = '';
const user = { username: username };

describe('OrbitDB', function() {
  this.timeout(2000);

  let db, ipfs;
  let channel = 'orbit-db.test';

  before(async((done) => {
    try {
      const daemon = await(ipfsDaemon());
      ipfs = daemon.ipfs;
    } catch(e) {
      console.log(e);
      assert.equal(e, null);
    }
    done();
  }));

  describe('constructor', function() {
    it('sets defaults', async((done) => {
      db = new OrbitDB(ipfs);
      assert.notEqual(db._ipfs, null);
      assert.notEqual(db._logs, null);
      assert.notEqual(db.options, null);
      assert.equal(db.lastWrite, null);
      assert.equal(db._cached.length, 0);
      done();
    }));

    it('sets options', async((done) => {
      db = new OrbitDB(ipfs, { option1: 'hello', option2: 2 });
      assert.equal(db.options.option1, 'hello');
      assert.equal(db.options.option2, 2);
      done();
    }));
  });

  describe('use', function() {
    beforeEach(() => {
      db = new OrbitDB(ipfs);
    });

    it('sets user', (done) => {
      db.use(channel, user).then(() => {
        assert.equal(db.user.username, username);
        done();
      });
    });

    it('creates an empty log for the channel', (done) => {
      db.use(channel, user).then(() => {
        assert(db._logs[channel]);
        assert.equal(db._logs[channel].id, username);
        assert.equal(db._logs[channel].items.length, 0);
        done();
      });
    });

    it('creates event emitter for the channel', (done) => {
      const EventEmitter = require('events').EventEmitter;
      db.use(channel, user).then(() => {
        assert(db.events[channel]);
        assert.equal(db.events[channel] instanceof EventEmitter, true);
        done();
      });
    });
  });

  describe('sync', function() {
    let log, otherLogHash, otherDbHash;

    beforeEach(async((done) => {
      log = await(Log.create(ipfs, username));
      await(log.add("one"));
      await(log.add("two"));
      await(log.add("three"));
      otherLogHash = await(Log.getIpfsHash(ipfs, log));

      const cacheFile = path.join(process.cwd(), '/test', 'orbit-db-test-cache.json');

      let count = 0;
      const db2 = new OrbitDB(ipfs);
      await(db2.use(channel, user));
      db2.events[channel].on('write', async((channel, hash) => {
        otherDbHash = hash;
        if(count === 2) {
          const obj = Object.defineProperty({}, channel, {
            value: hash,
            writable: true
          });
          fs.writeFileSync(cacheFile, JSON.stringify(obj));

          db = new OrbitDB(ipfs, { cacheFile: cacheFile });
          await(db.use(channel, user));
          done();
        } else {
          count ++;
        }
      }));
      await(db2.add(channel, '', "hello world 1"));
      await(db2.add(channel, '', "hello world 2"));
      await(db2.add(channel, '', "hello world 3"));
    }));

    afterEach(() => {
      db = null;
    });

    describe('events', function() {
      it('emits \'loaded\' event when sync hash is null', async((done) => {
        db.events[channel].on('loaded', (src, channelName) => done());
        db.sync(channel, null);
      }));

      it('emits \'load\' event when sync starts', async((done) => {
        db.events[channel].on('load', (src, channelName) => done());
        db.sync(channel, otherDbHash);
      }));

      it('emits \'loaded\' event when sync finishes', async((done) => {
        db.events[channel].on('loaded', (src, channelName) => done());
        db.sync(channel, otherDbHash);
      }));

      it('emits \'sync\' event if items were merged', async((done) => {
        db.events[channel].on('sync', (channelName, hash) => {
          assert.equal(channelName, channel);
          assert.equal(hash, otherDbHash);
          done();
        });
        db.sync(channel, otherDbHash);
      }));

      it('doesn\'t emit \'sync\' event if items weren\'t merged', async((done) => {
        db._logs[channel] = log;
        db.events[channel].on('sync', (channelName, hash) => {
          assert.equal(false, true);
          done();
        });
        db.events[channel].on('loaded', (src, channelName) => done());
        db.sync(channel, otherLogHash);
      }));
    });

    describe('cache payloads', function() {
      it('fetches payloads', (done) => {
        assert.equal(db._cached.length, 0);
        db.events[channel].on('loaded', (src, channelName) => {
          assert.equal(db._cached.length, 3);
          done();
        });
        db.sync(channel, otherDbHash);
      });

      it('throws an error if fetching went wrong', (done) => {
        db.sync(channel, otherLogHash).catch((e) => {
          assert.equal(e.message, 'invalid ipfs ref path');
          done();
        })
      });
    });

  });
});
<commit_msg>Remove old module<commit_after>'use strict';

const _          = require('lodash');
const fs         = require('fs');
const path       = require('path');
const assert     = require('assert');
const async      = require('asyncawait/async');
const await      = require('asyncawait/await');
const ipfsDaemon = require('orbit-common/lib/ipfs-daemon');
const OrbitDB    = require('../src/OrbitDB');
const Log        = require('ipfs-log');

// Mute logging
// require('log4js').setGlobalLogLevel('ERROR');

// Orbit
const username = 'testrunner';
const password = '';
const user = { username: username };

describe('OrbitDB', function() {
  this.timeout(2000);

  let db, ipfs;
  let channel = 'orbit-db.test';

  before(async((done) => {
    try {
      const daemon = await(ipfsDaemon());
      ipfs = daemon.ipfs;
    } catch(e) {
      console.log(e);
      assert.equal(e, null);
    }
    done();
  }));

  describe('constructor', function() {
    it('sets defaults', async((done) => {
      db = new OrbitDB(ipfs);
      assert.notEqual(db._ipfs, null);
      assert.notEqual(db._logs, null);
      assert.notEqual(db.options, null);
      assert.equal(db.lastWrite, null);
      assert.equal(db._cached.length, 0);
      done();
    }));

    it('sets options', async((done) => {
      db = new OrbitDB(ipfs, { option1: 'hello', option2: 2 });
      assert.equal(db.options.option1, 'hello');
      assert.equal(db.options.option2, 2);
      done();
    }));
  });

  describe('use', function() {
    beforeEach(() => {
      db = new OrbitDB(ipfs);
    });

    it('sets user', (done) => {
      db.use(channel, user).then(() => {
        assert.equal(db.user.username, username);
        done();
      });
    });

    it('creates an empty log for the channel', (done) => {
      db.use(channel, user).then(() => {
        assert(db._logs[channel]);
        assert.equal(db._logs[channel].id, username);
        assert.equal(db._logs[channel].items.length, 0);
        done();
      });
    });

    it('creates event emitter for the channel', (done) => {
      const EventEmitter = require('events').EventEmitter;
      db.use(channel, user).then(() => {
        assert(db.events[channel]);
        assert.equal(db.events[channel] instanceof EventEmitter, true);
        done();
      });
    });
  });

  describe('sync', function() {
    let log, otherLogHash, otherDbHash;

    beforeEach(async((done) => {
      log = await(Log.create(ipfs, username));
      await(log.add("one"));
      await(log.add("two"));
      await(log.add("three"));
      otherLogHash = await(Log.getIpfsHash(ipfs, log));

      const cacheFile = path.join(process.cwd(), '/test', 'orbit-db-test-cache.json');

      let count = 0;
      const db2 = new OrbitDB(ipfs);
      await(db2.use(channel, user));
      db2.events[channel].on('write', async((channel, hash) => {
        otherDbHash = hash;
        if(count === 2) {
          const obj = Object.defineProperty({}, channel, {
            value: hash,
            writable: true
          });
          fs.writeFileSync(cacheFile, JSON.stringify(obj));

          db = new OrbitDB(ipfs, { cacheFile: cacheFile });
          await(db.use(channel, user));
          done();
        } else {
          count ++;
        }
      }));
      await(db2.add(channel, '', "hello world 1"));
      await(db2.add(channel, '', "hello world 2"));
      await(db2.add(channel, '', "hello world 3"));
    }));

    afterEach(() => {
      db = null;
    });

    describe('events', function() {
      it('emits \'loaded\' event when sync hash is null', async((done) => {
        db.events[channel].on('loaded', (src, channelName) => done());
        db.sync(channel, null);
      }));

      it('emits \'load\' event when sync starts', async((done) => {
        db.events[channel].on('load', (src, channelName) => done());
        db.sync(channel, otherDbHash);
      }));

      it('emits \'loaded\' event when sync finishes', async((done) => {
        db.events[channel].on('loaded', (src, channelName) => done());
        db.sync(channel, otherDbHash);
      }));

      it('emits \'sync\' event if items were merged', async((done) => {
        db.events[channel].on('sync', (channelName, hash) => {
          assert.equal(channelName, channel);
          assert.equal(hash, otherDbHash);
          done();
        });
        db.sync(channel, otherDbHash);
      }));

      it('doesn\'t emit \'sync\' event if items weren\'t merged', async((done) => {
        db._logs[channel] = log;
        db.events[channel].on('sync', (channelName, hash) => {
          assert.equal(false, true);
          done();
        });
        db.events[channel].on('loaded', (src, channelName) => done());
        db.sync(channel, otherLogHash);
      }));
    });

    describe('cache payloads', function() {
      it('fetches payloads', (done) => {
        assert.equal(db._cached.length, 0);
        db.events[channel].on('loaded', (src, channelName) => {
          assert.equal(db._cached.length, 3);
          done();
        });
        db.sync(channel, otherDbHash);
      });

      it('throws an error if fetching went wrong', (done) => {
        db.sync(channel, otherLogHash).catch((e) => {
          assert.equal(e.message, 'invalid ipfs ref path');
          done();
        })
      });
    });

  });
});
<|endoftext|>


<commit_before>'use strict';

var Sono = require('../src/sono.js');

describe('Sono playback', function() {

    var baseURL = 'http://ianmcgregor.me/prototypes/assets/audio/';

    describe('create', function() {
        var config = {
                id: 'foo',
                url: [
                    baseURL + 'bullet.ogg',
                    baseURL + 'bullet.mp3'
                ]
            },
            sound;

        beforeEach(function(done) {
            sound = Sono.createSound(config);
            sound.onEnded(function() {
                done();
            });
            sound.play();
        });

        afterEach(function() {
            Sono.destroySound(sound.id);
        });

        it('should get ended callback', function(){
            expect(sound).to.exist;
        });
    });

    describe('play and end', function() {
        var sound,
            ended = false;

        beforeEach(function(done) {
            var onComplete = function(loadedSound) {
                sound = loadedSound;
                sound.onEnded(function() {
                    ended = true;
                    done();
                });
                sound.play();
            };
            Sono.load({
                url: [
                    baseURL + 'hit.ogg',
                    baseURL + 'hit.mp3'
                ],
                onComplete: onComplete
            });
        });

        afterEach(function() {
            Sono.destroySound(sound.id);
        });

        it('should get ended callback', function(){
            expect(sound).to.exist;
            expect(ended).to.be.true;
        });
    });

    describe('play when ready', function() {
        var sound,
            ended = false;

        beforeEach(function(done) {
            sound = Sono.createSound({
                url: [baseURL + 'select.ogg', baseURL + 'select.mp3']
            }).onEnded(function() {
                ended = true;
                done();
            }).play(0.1, 0.1);
        });

        afterEach(function() {
            Sono.destroySound(sound);
        });

        it('should have played', function(){
            expect(sound).to.exist;
            expect(ended).to.be.true;
        });
    });

    describe('fade master', function() {
        beforeEach(function(done) {
            setTimeout(function() {
                done();
            }, 500);
        });
        Sono.volume = 1;
        Sono.fade(0, 0.2);
        // console.log('1:', Sono.context.currentTime.toFixed(3), Sono.volume.toFixed(3));

        it('should have faded to zero volume', function() {
            // console.log('2:', Sono.context.currentTime.toFixed(3), Sono.volume.toFixed(3));
            expect(Sono.volume).to.eql(0);
        });

    });

    describe('fade sound', function() {
        var sound = Sono.createSound('sine');
        sound.play();
        sound.fade(0, 0.2);

        beforeEach(function(done) {
            setTimeout(function() {
                done();
            }, 500);
        });

        it('should have faded to zero volume', function() {
            expect(sound.volume).to.eql(0);
        });

    });

});
<commit_msg>exclude firefox from fade tests for now<commit_after>'use strict';

var Sono = require('../src/sono.js');

describe('Sono playback', function() {

    var baseURL = 'http://ianmcgregor.me/prototypes/assets/audio/';

    describe('create', function() {
        var config = {
                id: 'foo',
                url: [
                    baseURL + 'bullet.ogg',
                    baseURL + 'bullet.mp3'
                ]
            },
            sound;

        beforeEach(function(done) {
            sound = Sono.createSound(config);
            sound.onEnded(function() {
                done();
            });
            sound.play();
        });

        afterEach(function() {
            Sono.destroySound(sound.id);
        });

        it('should get ended callback', function(){
            expect(sound).to.exist;
        });
    });

    describe('play and end', function() {
        var sound,
            ended = false;

        beforeEach(function(done) {
            var onComplete = function(loadedSound) {
                sound = loadedSound;
                sound.onEnded(function() {
                    ended = true;
                    done();
                });
                sound.play();
            };
            Sono.load({
                url: [
                    baseURL + 'hit.ogg',
                    baseURL + 'hit.mp3'
                ],
                onComplete: onComplete
            });
        });

        afterEach(function() {
            Sono.destroySound(sound.id);
        });

        it('should get ended callback', function(){
            expect(sound).to.exist;
            expect(ended).to.be.true;
        });
    });

    describe('play when ready', function() {
        var sound,
            ended = false;

        beforeEach(function(done) {
            sound = Sono.createSound({
                url: [baseURL + 'select.ogg', baseURL + 'select.mp3']
            }).onEnded(function() {
                ended = true;
                done();
            }).play(0.1, 0.1);
        });

        afterEach(function() {
            Sono.destroySound(sound);
        });

        it('should have played', function(){
            expect(sound).to.exist;
            expect(ended).to.be.true;
        });
    });

    // Firefox 35 and less has a bug where audio param ramping does not change the readable value in the param itself
    // Fading still audibly affects the sound, but the value is untouched
    if(navigator.userAgent.toLowerCase().indexOf('firefox') > -1) { return; }

    describe('fade master', function() {
        beforeEach(function(done) {
            setTimeout(function() {
                done();
            }, 500);
        });
        Sono.volume = 1;
        Sono.fade(0, 0.2);
        // console.log('1:', Sono.context.currentTime.toFixed(3), Sono.volume.toFixed(3));

        it('should have faded to zero volume', function() {
            // console.log('2:', Sono.context.currentTime.toFixed(3), Sono.volume.toFixed(3));
            expect(Sono.volume).to.eql(0);
        });

    });

    describe('fade sound', function() {
        var sound = Sono.createSound('sine');
        sound.play();
        sound.fade(0, 0.2);

        beforeEach(function(done) {
            setTimeout(function() {
                done();
            }, 500);
        });

        it('should have faded to zero volume', function() {
            expect(sound.volume).to.eql(0);
        });

    });

});
<|endoftext|>


<commit_before>(function() {
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
	module.exports = Domt;
} else {
	window.Domt = Domt;
}

Domt.ns = {
	repeat: 'repeat',
	bind: 'bind',
	holder: 'holder',
	expr: '[*]'
};

function Filters(obj) {
	if (obj && typeof obj == "object") for (var name in obj) {
		this[name] = obj[name];
	}
}

Domt.filters = Filters.prototype;

Filters.prototype.upper = function(val) {
	if (val == null) return val;
	return (val + "").toUpperCase();
};
Filters.prototype.lower = function(val) {
	if (val == null) return val;
	return (val + "").toLowerCase();
};
Filters.prototype.br = function(val) {
	if (val == null) return val;
	return (val + "").replace(/\n/g, "
");
};
Filters.prototype.text = function(val) {
	if (val == null) return val;
	return escapeText(val);
};
Filters.prototype.esc = function(val) {
	if (val == null) return val;
	return encodeURIComponent(val + "");
};
Filters.prototype.unesc = function(val) {
	if (val == null) return val;
	return decodeURIComponent(val + "");
};
Filters.prototype.json = function(val) {
	return JSON.stringify(val);
};
Filters.prototype.empty = function(val) {
	if (val === undefined) return null;
	else return "";
};
Filters.prototype.notempty = function(val) {
	if (val === undefined) return "";
	else return null;
};

var escaper = document.createElement('p');
escaper.appendChild(document.createTextNode(""));
function escapeText(str) {
	escaper.firstChild.nodeValue = str;
	return escaper.innerHTML;
}

function match(re, str) {
	var m = re.exec(str);
	if (m && m.length == 2) return m[1];
}

function Holder(node) {
	if (!(this instanceof Holder)) return new Holder(node);
	var container, REPEAT = Domt.ns.repeat, BIND = Domt.ns.bind;
	if (node.tagName == "SCRIPT" && node.type == "text/template") {
		this.container = container = node;
		var orig = node[Domt.ns.holder];
		if (orig) {
			this.repeat = orig.repeat;
			this.template = orig.template;
			this.invert = orig.invert;
			this.bind = orig.bind;
		} else {
			this.reload();
		}
		node.removeAttribute(REPEAT);
	} else if (node.hasAttribute(REPEAT)) {
		this.template = node;
		this.container = container = document.createElement("script");
		container.type = "text/template";
		this.repeat = node.getAttribute(REPEAT) || "";
		this.invert = node.hasAttribute(REPEAT + '-invert');
		if (this.invert) container.setAttribute(REPEAT + '-invert', "");
		if (node.hasAttribute(BIND)) {
			this.bind = node.getAttribute(BIND);
			node.removeAttribute(BIND);
		}
		node.removeAttribute(REPEAT);
		node.removeAttribute(REPEAT + '-invert');
		node.parentNode.insertBefore(container, node);
		container.text = node.outerHTML;
		node.parentNode.removeChild(node);
		var begin = document.createElement("script");
		begin.setAttribute(Domt.ns.repeat + "-tail", "");
		begin.setAttribute("type", "text/template");
		if (this.invert) {
			if (container.nextSibling) container.parentNode.insertBefore(begin, container.nextSibling);
			else container.parentNode.appendChild(begin);
		} else {
			container.parentNode.insertBefore(begin, container);
		}
	} else {
		if (node.hasAttribute(BIND)) {
			this.bind = node.getAttribute(BIND);
			node.removeAttribute(BIND);
		}
		this.container = container = node;
	}
	container[Domt.ns.holder] = this;
	return this;
};
Holder.prototype.close = function() {
	var node = this.container;
	if (this.repeat !== undefined) {
		node.setAttribute(Domt.ns.repeat, this.repeat);
	}
	if (this.bind !== undefined) {
		node.setAttribute(Domt.ns.bind, this.bind);
	}
};
Holder.prototype.reload = function() {
	var container = this.container;
	var REPEAT = Domt.ns.repeat;
	this.repeat = container.getAttribute(REPEAT) || this.repeat || "";
	this.invert = container.hasAttribute(REPEAT + '-invert') || this.invert;
	this.bind = container.getAttribute(Domt.ns.bind) || this.bind || undefined;
	var doc = document.implementation && document.implementation.createHTMLDocument ?
		document.implementation.createHTMLDocument() : document;
	var div = doc.createElement('div');
	var html = container.text.replace(/^\s+|\s+$/g, '');
	var tagName = match(/<(\w+)[\s>]/i, html);
	if (tagName) {
		tagName = tagName.toLowerCase();
		if (tagName == "td") {
			html = '

' + html + '

';
		} else if (tagName == "tr") {
			html = '
' + html + '
';
		}
		div.innerHTML = html;
		this.template = div.querySelector(tagName);
	}
	if (!this.template) throw DomtError("problem parsing template\n" + html);
};

function iterate(obj, fun) {
	if (obj == null) return 0;
	var i, len;
	if (Object.prototype.toString.call(obj) === '[object Array]') {
		len = obj.length;
		for (i=0; i < len; i++) fun(i, obj[i]);
	} else if (obj.length !== undefined && typeof obj.item == "function") {
		len = obj.length;
		for (i=0; i < len; i++) fun(i, obj.item(i));
	} else if (obj instanceof Object) {
		var keys = Object.keys(obj);
		len = keys.length;
		var key;
		for (i=0; i < len; i++) {
			key = keys[i];
			fun(key, obj[key]);
		}
	}
	return len;
}

function Domt(parent, filters) {
	if (!(this instanceof Domt)) return new Domt(parent, filters);
	if (typeof parent == "string") {
		parent = document.querySelector(parent);
	}
	if (!parent) throw DomtError("missing parent");
	this.filters = new Filters(filters);
	this.node = parent;

	this.reBind = new RegExp("^" + Domt.ns.bind + "-(.*)$", "i");

	var delims = Domt.ns.expr.split('*');
	if (delims.length != 2) throw DomtError("bad Domt.ns.expr");
	var start = '\\' + delims[0], end = '\\' + delims[1];
	this.reExpr = new RegExp(start + '([^' + start + end + ']*)' + end, "g");
};

Domt.prototype.empty = function() {
	this.merge(undefined, {empty:true});
	return this;
};

Domt.prototype.merge = function(obj, opts) {
	var bound, repeated, holder, container, path, len, parentNode;
	opts = opts || {};
	var node = opts.node || this.node;
	var parent = node;
	var REPEAT = Domt.ns.repeat;
	var BIND = Domt.ns.bind;
	var holders = [];
	do {
		holder = Holder(node);
		holders.push(holder);
		container = holder.container;
		parentNode = container.parentNode;
		bound = holder.bind ? find(obj, holder.bind, undefined, this.filters).val : obj;
		if (holder.repeat !== undefined) {
			if (opts.empty) {
				if (holder.invert) {
					while ((curNode = container.nextSibling) && !curNode.hasAttribute(REPEAT + '-tail')) {
						parentNode.removeChild(curNode);
					}
				} else {
					while ((curNode = container.previousSibling) && !curNode.hasAttribute(REPEAT + '-tail')) {
						parentNode.removeChild(curNode);
					}
				}
				// restore holder.template modified by current.value === undefined (see after)
				holder.reload();
			}
			repeated = find(bound, holder.repeat, undefined, this.filters);
			if (repeated.val === undefined) {
				// merge inside template (that won't be selected because it's now out of the DOM)
				this.merge(bound, {node: holder.template});
			} else {
				var self = this;
				iterate(repeated.val, function(key, val) {
					var clone = holder.template.cloneNode(true);
					// overwrite obj
					bound[repeated.name] = val;
					self.replace(bound, clone, key);
					parentNode.insertBefore(clone, holder.invert ? container.nextSibling : container);
				});
				// restore obj
				bound[repeated.name] = repeated.val;
			}
		} else {
			this.replace(bound, node);
		}
	} while ((node = parent.querySelector('[' + REPEAT + '],[' + BIND + ']')));

	len = holders.length;
	for (i=0; i < len; i++) {
		holders[i].close();
	}
	return this;
};

Domt.prototype.replace = function(obj, node, key) {
	var descendants = node.querySelectorAll('*');
	var i = 0;
	var len = descendants.length;
	var val, reExpr = this.reExpr, reBind = this.reBind;
	var filters = this.filters;
	do {
		iterate(Array.prototype.slice.call(node.attributes, 0), function(index, att) { // iterates over a copy
			var name = match(reBind, att.name);
			if (!name) return;
			if (key != null) {
				node.removeAttribute(att.name);
			}
			if (name == "text" || name == "html") {
				val = node.innerHTML;
			}	else {
				val = node.getAttribute(name);
			}
			var replacements = 0, initial = val;
			if (att.value) initial = att.value;
			if (initial == null) initial = "";
			val = initial.replace(reExpr, function(str, path) {
				var repl = find(obj, path, key, filters).val;
				if (repl === undefined || repl !== null && typeof repl == "object") return "";
				replacements++;
				if (repl == null) return "";
				else if (name == "text") return escapeText(repl);
				else return repl;
			});
			if (replacements) {
				if (!att.value) att.value = initial;
			} else {
				val = find(obj, att.value, key, filters).val;
				if (name == "text" && val != null && typeof val != "object") val = escapeText(val);
			}
			replace(node, name, val);
		});
	} while (i < len && (node = descendants.item(i++)));
};

function replace(node, name, val) {
	if (val === undefined || val !== null && typeof val == "object") return;
	if (name == "text" || name == "html") node.innerHTML = val;
	else if (val !== null) node.setAttribute(name, val);
	else node.removeAttribute(name);
}

function find(scope, path, key, filters) {
	var name, last, val = scope, filterNames, filter;
	path = (path || "").split('|');
	filterNames = path;
	path = path.shift();
	if (scope == null) {
		if (path) val = undefined;
		return {val: val};
	}
	path = path ? path.split('.') : [];
	if (typeof val == "function") val = val(scope, path);
	while ((name = path.shift()) !== undefined) {
		scope = val;
		if (key !== undefined && path.length == 0) {
			if (name == '#key') {
				val = key;
				break;
			} else if (name == '#val') {
				break;
			}
		}
		if (!scope || name == "" && !(typeof scope == "object")) break;
		val = scope[name];
		if (typeof val == "function") val = val(scope, path);
		last = name;
	}
	for (var i=0; i < filterNames.length; i++) {
		filter = filters[filterNames[i]];
		if (filter) val = filter(val);
	}
	if (last == null) last = "";
	return {val: val, name: last};
};

function DomtError(message) {
	var error = new Error(message);
	error.name = arguments.callee.name;
	return error;
}

})();
<commit_msg>Filter update, "" and "no" covers most cases of undefined-ness<commit_after>(function() {
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
	module.exports = Domt;
} else {
	window.Domt = Domt;
}

Domt.ns = {
	repeat: 'repeat',
	bind: 'bind',
	holder: 'holder',
	expr: '[*]'
};

function Filters(obj) {
	if (obj && typeof obj == "object") for (var name in obj) {
		this[name] = obj[name];
	}
}

Domt.filters = Filters.prototype;

Filters.prototype.upper = function(val) {
	if (val == null) return val;
	return (val + "").toUpperCase();
};
Filters.prototype.lower = function(val) {
	if (val == null) return val;
	return (val + "").toLowerCase();
};
Filters.prototype.br = function(val) {
	if (val == null) return val;
	return (val + "").replace(/\n/g, "
");
};
Filters.prototype.text = function(val) {
	if (val == null) return val;
	return escapeText(val);
};
Filters.prototype.esc = function(val) {
	if (val == null) return val;
	return encodeURIComponent(val + "");
};
Filters.prototype.unesc = function(val) {
	if (val == null) return val;
	return decodeURIComponent(val + "");
};
Filters.prototype.json = function(val) {
	return JSON.stringify(val);
};
Filters.prototype.no = function(val) {
	if (val == null) return "";
	else return null;
};
Filters.prototype[''] = function(val) {
	if (val === undefined) return null;
	else return val;
};

var escaper = document.createElement('p');
escaper.appendChild(document.createTextNode(""));
function escapeText(str) {
	escaper.firstChild.nodeValue = str;
	return escaper.innerHTML;
}

function match(re, str) {
	var m = re.exec(str);
	if (m && m.length == 2) return m[1];
}

function Holder(node) {
	if (!(this instanceof Holder)) return new Holder(node);
	var container, REPEAT = Domt.ns.repeat, BIND = Domt.ns.bind;
	if (node.tagName == "SCRIPT" && node.type == "text/template") {
		this.container = container = node;
		var orig = node[Domt.ns.holder];
		if (orig) {
			this.repeat = orig.repeat;
			this.template = orig.template;
			this.invert = orig.invert;
			this.bind = orig.bind;
		} else {
			this.reload();
		}
		node.removeAttribute(REPEAT);
	} else if (node.hasAttribute(REPEAT)) {
		this.template = node;
		this.container = container = document.createElement("script");
		container.type = "text/template";
		this.repeat = node.getAttribute(REPEAT) || "";
		this.invert = node.hasAttribute(REPEAT + '-invert');
		if (this.invert) container.setAttribute(REPEAT + '-invert', "");
		if (node.hasAttribute(BIND)) {
			this.bind = node.getAttribute(BIND);
			node.removeAttribute(BIND);
		}
		node.removeAttribute(REPEAT);
		node.removeAttribute(REPEAT + '-invert');
		node.parentNode.insertBefore(container, node);
		container.text = node.outerHTML;
		node.parentNode.removeChild(node);
		var begin = document.createElement("script");
		begin.setAttribute(Domt.ns.repeat + "-tail", "");
		begin.setAttribute("type", "text/template");
		if (this.invert) {
			if (container.nextSibling) container.parentNode.insertBefore(begin, container.nextSibling);
			else container.parentNode.appendChild(begin);
		} else {
			container.parentNode.insertBefore(begin, container);
		}
	} else {
		if (node.hasAttribute(BIND)) {
			this.bind = node.getAttribute(BIND);
			node.removeAttribute(BIND);
		}
		this.container = container = node;
	}
	container[Domt.ns.holder] = this;
	return this;
};
Holder.prototype.close = function() {
	var node = this.container;
	if (this.repeat !== undefined) {
		node.setAttribute(Domt.ns.repeat, this.repeat);
	}
	if (this.bind !== undefined) {
		node.setAttribute(Domt.ns.bind, this.bind);
	}
};
Holder.prototype.reload = function() {
	var container = this.container;
	var REPEAT = Domt.ns.repeat;
	this.repeat = container.getAttribute(REPEAT) || this.repeat || "";
	this.invert = container.hasAttribute(REPEAT + '-invert') || this.invert;
	this.bind = container.getAttribute(Domt.ns.bind) || this.bind || undefined;
	var doc = document.implementation && document.implementation.createHTMLDocument ?
		document.implementation.createHTMLDocument() : document;
	var div = doc.createElement('div');
	var html = container.text.replace(/^\s+|\s+$/g, '');
	var tagName = match(/<(\w+)[\s>]/i, html);
	if (tagName) {
		tagName = tagName.toLowerCase();
		if (tagName == "td") {
			html = '

' + html + '

';
		} else if (tagName == "tr") {
			html = '
' + html + '
';
		}
		div.innerHTML = html;
		this.template = div.querySelector(tagName);
	}
	if (!this.template) throw DomtError("problem parsing template\n" + html);
};

function iterate(obj, fun) {
	if (obj == null) return 0;
	var i, len;
	if (Object.prototype.toString.call(obj) === '[object Array]') {
		len = obj.length;
		for (i=0; i < len; i++) fun(i, obj[i]);
	} else if (obj.length !== undefined && typeof obj.item == "function") {
		len = obj.length;
		for (i=0; i < len; i++) fun(i, obj.item(i));
	} else if (obj instanceof Object) {
		var keys = Object.keys(obj);
		len = keys.length;
		var key;
		for (i=0; i < len; i++) {
			key = keys[i];
			fun(key, obj[key]);
		}
	}
	return len;
}

function Domt(parent, filters) {
	if (!(this instanceof Domt)) return new Domt(parent, filters);
	if (typeof parent == "string") {
		parent = document.querySelector(parent);
	}
	if (!parent) throw DomtError("missing parent");
	this.filters = new Filters(filters);
	this.node = parent;

	this.reBind = new RegExp("^" + Domt.ns.bind + "-(.*)$", "i");

	var delims = Domt.ns.expr.split('*');
	if (delims.length != 2) throw DomtError("bad Domt.ns.expr");
	var start = '\\' + delims[0], end = '\\' + delims[1];
	this.reExpr = new RegExp(start + '([^' + start + end + ']*)' + end, "g");
};

Domt.prototype.empty = function() {
	this.merge(undefined, {empty:true});
	return this;
};

Domt.prototype.merge = function(obj, opts) {
	var bound, repeated, holder, container, path, len, parentNode;
	opts = opts || {};
	var node = opts.node || this.node;
	var parent = node;
	var REPEAT = Domt.ns.repeat;
	var BIND = Domt.ns.bind;
	var holders = [];
	do {
		holder = Holder(node);
		holders.push(holder);
		container = holder.container;
		parentNode = container.parentNode;
		bound = holder.bind ? find(obj, holder.bind, undefined, this.filters).val : obj;
		if (holder.repeat !== undefined) {
			if (opts.empty) {
				if (holder.invert) {
					while ((curNode = container.nextSibling) && !curNode.hasAttribute(REPEAT + '-tail')) {
						parentNode.removeChild(curNode);
					}
				} else {
					while ((curNode = container.previousSibling) && !curNode.hasAttribute(REPEAT + '-tail')) {
						parentNode.removeChild(curNode);
					}
				}
				// restore holder.template modified by current.value === undefined (see after)
				holder.reload();
			}
			repeated = find(bound, holder.repeat, undefined, this.filters);
			if (repeated.val === undefined) {
				// merge inside template (that won't be selected because it's now out of the DOM)
				this.merge(bound, {node: holder.template});
			} else {
				var self = this;
				iterate(repeated.val, function(key, val) {
					var clone = holder.template.cloneNode(true);
					// overwrite obj
					bound[repeated.name] = val;
					self.replace(bound, clone, key);
					parentNode.insertBefore(clone, holder.invert ? container.nextSibling : container);
				});
				// restore obj
				bound[repeated.name] = repeated.val;
			}
		} else {
			this.replace(bound, node);
		}
	} while ((node = parent.querySelector('[' + REPEAT + '],[' + BIND + ']')));

	len = holders.length;
	for (i=0; i < len; i++) {
		holders[i].close();
	}
	return this;
};

Domt.prototype.replace = function(obj, node, key) {
	var descendants = node.querySelectorAll('*');
	var i = 0;
	var len = descendants.length;
	var val, reExpr = this.reExpr, reBind = this.reBind;
	var filters = this.filters;
	do {
		iterate(Array.prototype.slice.call(node.attributes, 0), function(index, att) { // iterates over a copy
			var name = match(reBind, att.name);
			if (!name) return;
			if (key != null) {
				node.removeAttribute(att.name);
			}
			if (name == "text" || name == "html") {
				val = node.innerHTML;
			}	else {
				val = node.getAttribute(name);
			}
			var replacements = 0, initial = val;
			if (att.value) initial = att.value;
			if (initial == null) initial = "";
			val = initial.replace(reExpr, function(str, path) {
				var repl = find(obj, path, key, filters).val;
				if (repl === undefined || repl !== null && typeof repl == "object") return "";
				replacements++;
				if (repl == null) return "";
				else if (name == "text") return escapeText(repl);
				else return repl;
			});
			if (replacements) {
				if (!att.value) att.value = initial;
			} else {
				val = find(obj, att.value, key, filters).val;
				if (name == "text" && val != null && typeof val != "object") val = escapeText(val);
			}
			replace(node, name, val);
		});
	} while (i < len && (node = descendants.item(i++)));
};

function replace(node, name, val) {
	if (val === undefined || val !== null && typeof val == "object") return;
	if (name == "text" || name == "html") node.innerHTML = val;
	else if (val !== null) node.setAttribute(name, val);
	else node.removeAttribute(name);
}

function find(scope, path, key, filters) {
	var name, last, val = scope, filterNames, filter;
	path = (path || "").split('|');
	filterNames = path;
	path = path.shift();
	if (scope == null) {
		if (path) val = undefined;
		return {val: val};
	}
	path = path ? path.split('.') : [];
	if (typeof val == "function") val = val(scope, path);
	while ((name = path.shift()) !== undefined) {
		scope = val;
		if (key !== undefined && path.length == 0) {
			if (name == '#key') {
				val = key;
				break;
			} else if (name == '#val') {
				break;
			}
		}
		if (!scope || name == "" && !(typeof scope == "object")) break;
		val = scope[name];
		if (typeof val == "function") val = val(scope, path);
		last = name;
	}
	for (var i=0; i < filterNames.length; i++) {
		filter = filters[filterNames[i]];
		if (filter) val = filter(val);
	}
	if (last == null) last = "";
	return {val: val, name: last};
};

function DomtError(message) {
	var error = new Error(message);
	error.name = arguments.callee.name;
	return error;
}

})();
<|endoftext|>


<commit_before>if (Meteor.isServer) {
    // Start a server to test HTTP client streams.
    var http = Npm.require("http");
    var server = http.createServer(function(req, res) {
        var url = req.url;

        switch (url) {
            case "/test1":
                res.write("OK");
                res.end();
                break;

            case "/test2":
                res.write("1");
                setTimeout(function() { res.write("2"); }, 10);
                setTimeout(function() { res.write("3"); }, 20);
                setTimeout(function() { res.write("4"); }, 30);
                setTimeout(function() { res.write("5"); }, 40);
                setTimeout(function() { res.end(); }, 50);
                break;

            case "/method":
                res.setHeader("X-METHOD", "HEAD");

                if (req.method !== "HEAD") {
                    res.write(req.method);
                }

                res.end();
                break;

            case "/echo":
                var body = "";

                req.on("data", function(data) {
                    body += data;
                });

                req.on("end", function() {
                    res.write(body);
                    res.end();
                });

                break;
        }
    });

    var port = 10492;
    server.listen(port, "127.0.0.1");

    var makeAddr = function(path) {
        return "http://127.0.0.1:" + port + path;
    };

    Tinytest.add("GET /test1", function(test) {
        var addr = makeAddr("/test1");
        var res = request.getSync(addr);
        test.equal(res.body, "OK");
    });

    Tinytest.add("GET /test2", function(test) {
        var addr = makeAddr("/test2");
        var res = request.getSync(addr);
        test.equal(res.body, "12345");
    });

    Tinytest.add("PATCH /echo", function(test) {
        var addr = makeAddr("/echo");
        var res = request.patchSync(addr, {
            body: "patch test"
        });
        test.equal(res.body, "patch test");
    });

    Tinytest.add("POST /echo", function(test) {
        var addr = makeAddr("/echo");
        var res = request.postSync(addr, {
            body: "post test"
        });
        test.equal(res.body, "post test");
    });

    Tinytest.add("PUT /echo", function(test) {
        var addr = makeAddr("/echo");
        var res = request.putSync(addr, {
            body: "put test"
        });
        test.equal(res.body, "put test");
    });

    Tinytest.add("GET /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.getSync(addr);
        test.equal(res.body, "GET");
    });

    Tinytest.add("PUT /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.putSync(addr);
        test.equal(res.body, "PUT");
    });

    Tinytest.add("PATCH /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.patchSync(addr);
        test.equal(res.body, "PATCH");
    });

    Tinytest.add("POST /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.postSync(addr);
        test.equal(res.body, "POST");
    });

    Tinytest.add("HEAD /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.headSync(addr);
        var method = res.response.headers["x-method"];
        test.equal(method, "HEAD");
    });

    Tinytest.add("DELETE /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.delSync(addr);
        test.equal(res.body, "DELETE");
    });
}

<commit_msg>Add response Buffer test.<commit_after>if (Meteor.isServer) {
    // Start a server to test HTTP client streams.
    var http = Npm.require("http");
    var server = http.createServer(function(req, res) {
        var url = req.url;

        switch (url) {
            case "/test1":
                res.write("OK");
                res.end();
                break;

            case "/test2":
                res.write("1");
                setTimeout(function() { res.write("2"); }, 10);
                setTimeout(function() { res.write("3"); }, 20);
                setTimeout(function() { res.write("4"); }, 30);
                setTimeout(function() { res.write("5"); }, 40);
                setTimeout(function() { res.end(); }, 50);
                break;

            case "/test3":
                var buf1 = new Buffer([1,2,3,4]);
                res.write(buf1);

                setTimeout(function() {
                    var buf2 = new Buffer([5,6,7,8]);
                    res.write(buf2);

                    res.end();
                }, 50);

                break;

            case "/method":
                res.setHeader("X-METHOD", "HEAD");

                if (req.method !== "HEAD") {
                    res.write(req.method);
                }

                res.end();
                break;

            case "/echo":
                var body = "";

                req.on("data", function(data) {
                    body += data;
                });

                req.on("end", function() {
                    res.write(body);
                    res.end();
                });

                break;
        }
    });

    var port = 10492;
    server.listen(port, "127.0.0.1");

    var makeAddr = function(path) {
        return "http://127.0.0.1:" + port + path;
    };

    Tinytest.add("GET /test1", function(test) {
        var addr = makeAddr("/test1");
        var res = request.getSync(addr);
        test.equal(res.body, "OK");
    });

    Tinytest.add("GET /test2", function(test) {
        var addr = makeAddr("/test2");
        var res = request.getSync(addr);
        test.equal(res.body, "12345");
    });

    Tinytest.add("GET /test3 (buffer)", function(test) {
        var addr = makeAddr("/test3");
        var res = request.getSync(addr, {
            encoding: null
        });

        test.isTrue(res.body instanceof Buffer, "res.body should be a Buffer");
        for (var i = 0; i < 8; i++) {
            test.equal(res.body[i], i + 1);
        }
    });

    Tinytest.add("PATCH /echo", function(test) {
        var addr = makeAddr("/echo");
        var res = request.patchSync(addr, {
            body: "patch test"
        });
        test.equal(res.body, "patch test");
    });

    Tinytest.add("POST /echo", function(test) {
        var addr = makeAddr("/echo");
        var res = request.postSync(addr, {
            body: "post test"
        });
        test.equal(res.body, "post test");
    });

    Tinytest.add("PUT /echo", function(test) {
        var addr = makeAddr("/echo");
        var res = request.putSync(addr, {
            body: "put test"
        });
        test.equal(res.body, "put test");
    });

    Tinytest.add("GET /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.getSync(addr);
        test.equal(res.body, "GET");
    });

    Tinytest.add("PUT /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.putSync(addr);
        test.equal(res.body, "PUT");
    });

    Tinytest.add("PATCH /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.patchSync(addr);
        test.equal(res.body, "PATCH");
    });

    Tinytest.add("POST /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.postSync(addr);
        test.equal(res.body, "POST");
    });

    Tinytest.add("HEAD /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.headSync(addr);
        var method = res.response.headers["x-method"];
        test.equal(method, "HEAD");
    });

    Tinytest.add("DELETE /method", function(test) {
        var addr = makeAddr("/method");
        var res = request.delSync(addr);
        test.equal(res.body, "DELETE");
    });
}

<|endoftext|>


<commit_before>jQuery(document).ready(function($){

var $timeline = $('#timeline');

function add_event(event)
{
    update_row(event);
    update_segment_dividers();
}

function determine_row(event)
{
    // seek existing segment
    var $row = $timeline.find('.row.segment[data-segment="' + event.segment + '"]');

    if($row.length <= 0)
    {
        // create and insert new segment - latest segment first

        $rows = $timeline.find('.row.segment[data-segment]'); // the [attr] skips .reference rows

        $row = $('

');

        var _insertBefore = false;
        for(var i=0; i < $rows.length; i++)
        {
            var current_row = $rows[i];
            var next_segment = $(current_row).attr("data-segment");
            if(event.segment > next_segment)
            {
                _insertBefore = current_row;
                break;
            }
        }

        if(_insertBefore === false)
        {
            $row.appendTo($timeline);
        }
        else
        {
            $row.insertBefore(_insertBefore);
        }
    }

    return $row;
}

function update_row(event)
{
    var $row = determine_row(event);

    var $cell = new_cell(event);

    var _insert = false;
    var $cells = $row.find(".cell");
    for(var i=0; i < $cells.length; i++)
    {
        var current_cell = $cells[i];
        if(event.Date > $(current_cell).data("event").Date)
        {
            $cell.insertBefore(current_cell);
            _insert = true;
            break;
        }
    }
    if(!_insert)
    {
        $cell.appendTo($row);
    }

    return true;
}

function update_segment_dividers()
{
    var $prev_segment = false;
    var Segments = $timeline.find(".segment");
    for(var i=0; i < Segments.length; i++)
    {
        var $segment = $(Segments[i]);
        var $next_segment = false;

        if(i < (Segments.length - 1))
        {
            $next_segment = $(Segments[i+1]);
        }
        else
        {
            $next_segment = false;
        }

        var _boundary = {
            "signature" : "unknown",
            "title" : "unknown"
        };

        if($prev_segment == false)
        {
            _boundary.title = "START";
            _boundary.signature = "start";

            $timeline.prepend(the_boundary(_boundary));
        }

        if($next_segment == false)
        {
            _boundary.title = "END";
            _boundary.signature = "end";

            $timeline.append(the_boundary(_boundary));
        }
        else
        {
            _boundary.title = "AFTER " + $segment.attr("data-segment");
            _boundary.signature = "after-" + $segment.attr("data-segment");

            the_boundary(_boundary).insertBefore($next_segment);
        }

        $prev_segment = $segment;
    }
}

function the_boundary(_boundary)
{
    var $boundary = false;

    var existing = $timeline.find('.boundary[data-signature="' + _boundary.signature + '"]');
    if(existing.length <= 0)
    {
        $boundary = $('

' + _boundary.title + '

')
        $boundary.attr("data-signature", _boundary.signature);
    }
    else
    {
        $boundary = $(existing.get(0));
    }

    return $boundary;
}

var _cell_counter = 0;
var _event_counter = 0;

function new_cell(event)
{
    $cell = $('
');
    $cell.attr("id", "-cell-" + _event_counter++);
    $cell.data("event", event);

    $event = $('

')
    $event.attr("id", "-event-" + _event_counter++);
    $event.append($('

'));
    $event.append($('

'));
    $event.append($('' /*+ event.Date.getMonth() + "/" */+ event.Date.getDate() + ""));
    $event.append(event.title + ' (' + event.Date.toString() + ', ' + event.segment + ')');

    $cell.append($event);

    return $cell;
}

function segment_from_event(event)
{
    var theDate = event.Date;
    return (theDate.getFullYear() * 100) + theDate.getMonth(); // XXX: produces YYYYMM as integer
}

var layout_configurations = [
    {
        "cols": 2,
        "css": {
            "min-width": 768
        },
        "bootstrap": {
            "size": "sm",
            "column-multiplier": 6
        }
    },
    {
        "cols": 4,
        "css": {
            "min-width": 992
        },
        "bootstrap": {
            "size": "md",
            "column-multiplier": 3
        }
    }
];

function arrange_events($row)
{
    var $cells = $row.find(".cell");

    var css_text = [];
    var autogenerated_block = $("head").find("style#timeline-autogenerated-css");
    if(autogenerated_block.length <= 0)
    {
        autogenerated_block = $('');
        $("head").append(autogenerated_block);
    }
    autogenerated_block.empty();

    for(var i=0; i < layout_configurations.length; i++)
    {
        layout_config = layout_configurations[i];
        console.log("configuring for columns:", layout_config);

        // build a media-query rule

        var _media_query = [];
        if(layout_config.css["min-width"])
        {
            _media_query.push("min-width: " + layout_config.css["min-width"] + "px");
        }
        if(layout_config.css["max-width"])
        {
            _media_query.push("max-width: " + layout_config.css["max-width"] + "px");
        }
        css_text.push("@media (" + _media_query.join(" and ") + ")");
        css_text.push("{");

        // initialise stacks
        var height_stacks = [];

        // iterate through each cell/event (should be chronological)
        for(var j=0; j < $cells.length; j++)
        {
            var $cell = $($cells[j]);
            var cell_height = $cell.outerHeight();

            // iterate through each height stack and find the smallest
            var candidate_stack = -1;
            var minimum_height = -1;
            for(var k=0; k < layout_config.cols; k++)
            {
                if(typeof height_stacks[k] == "undefined")
                {
                    height_stacks[k] = 0;
                }

                if(height_stacks[k] < minimum_height || minimum_height == -1)
                {
                    // found the lowest stack (or this is first iteration)
                    minimum_height = height_stacks[k];
                    candidate_stack = k;
                }
            }

            // a stack has been identified
            var cell_top = height_stacks[candidate_stack];
            var cell_column_enumeration = candidate_stack;

            // add to the height stack
            height_stacks[candidate_stack] += cell_height;

            // XXX: apply styling
            css_text.push("#" + $cell.attr("id"));
            css_text.push("{");
            css_text.push("position: absolute;");
            css_text.push("top: " + cell_top + "px;");
            css_text.push("}");

            $cell.addClass("col-" + layout_config.bootstrap["size"] + "-offset-" + (layout_config.bootstrap["column-multiplier"] * cell_column_enumeration));
        }

        css_text.push("}");

        autogenerated_block.html(css_text.join("\n"));
    }
}

$(window).resize(function(e){
    arrange_events($("#timeline .row.segment"));
});

function debug_add_random_event()
{
    var event_date = debugGenerate_randomDate(new Date(2015, 0, 1), new Date(2015, 0, 31));
    var event =
    {
        Date: event_date,
        segment: false,
        title: debugGenerate_loremIpsum(20, 3)
    };
    event.segment = segment_from_event(event);
    add_event(event);
}

$("#add-event").click(function(e){
    debug_add_random_event();
});

debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();

$(window).resize();

});<commit_msg>bugfix: non-removal of previously set offset classes during resize<commit_after>jQuery(document).ready(function($){

var $timeline = $('#timeline');

function add_event(event)
{
    update_row(event);
    update_segment_dividers();
}

function determine_row(event)
{
    // seek existing segment
    var $row = $timeline.find('.row.segment[data-segment="' + event.segment + '"]');

    if($row.length <= 0)
    {
        // create and insert new segment - latest segment first

        $rows = $timeline.find('.row.segment[data-segment]'); // the [attr] skips .reference rows

        $row = $('

');

        var _insertBefore = false;
        for(var i=0; i < $rows.length; i++)
        {
            var current_row = $rows[i];
            var next_segment = $(current_row).attr("data-segment");
            if(event.segment > next_segment)
            {
                _insertBefore = current_row;
                break;
            }
        }

        if(_insertBefore === false)
        {
            $row.appendTo($timeline);
        }
        else
        {
            $row.insertBefore(_insertBefore);
        }
    }

    return $row;
}

function update_row(event)
{
    var $row = determine_row(event);

    var $cell = new_cell(event);

    var _insert = false;
    var $cells = $row.find(".cell");
    for(var i=0; i < $cells.length; i++)
    {
        var current_cell = $cells[i];
        if(event.Date > $(current_cell).data("event").Date)
        {
            $cell.insertBefore(current_cell);
            _insert = true;
            break;
        }
    }
    if(!_insert)
    {
        $cell.appendTo($row);
    }

    return true;
}

function update_segment_dividers()
{
    var $prev_segment = false;
    var Segments = $timeline.find(".segment");
    for(var i=0; i < Segments.length; i++)
    {
        var $segment = $(Segments[i]);
        var $next_segment = false;

        if(i < (Segments.length - 1))
        {
            $next_segment = $(Segments[i+1]);
        }
        else
        {
            $next_segment = false;
        }

        var _boundary = {
            "signature" : "unknown",
            "title" : "unknown"
        };

        if($prev_segment == false)
        {
            _boundary.title = "START";
            _boundary.signature = "start";

            $timeline.prepend(the_boundary(_boundary));
        }

        if($next_segment == false)
        {
            _boundary.title = "END";
            _boundary.signature = "end";

            $timeline.append(the_boundary(_boundary));
        }
        else
        {
            _boundary.title = "AFTER " + $segment.attr("data-segment");
            _boundary.signature = "after-" + $segment.attr("data-segment");

            the_boundary(_boundary).insertBefore($next_segment);
        }

        $prev_segment = $segment;
    }
}

function the_boundary(_boundary)
{
    var $boundary = false;

    var existing = $timeline.find('.boundary[data-signature="' + _boundary.signature + '"]');
    if(existing.length <= 0)
    {
        $boundary = $('

' + _boundary.title + '

')
        $boundary.attr("data-signature", _boundary.signature);
    }
    else
    {
        $boundary = $(existing.get(0));
    }

    return $boundary;
}

var _cell_counter = 0;
var _event_counter = 0;

function new_cell(event)
{
    $cell = $('
');
    $cell.attr("id", "-cell-" + _event_counter++);
    $cell.data("event", event);

    $event = $('

')
    $event.attr("id", "-event-" + _event_counter++);
    $event.append($('

'));
    $event.append($('

'));
    $event.append($('' /*+ event.Date.getMonth() + "/" */+ event.Date.getDate() + ""));
    $event.append(event.title + ' (' + event.Date.toString() + ', ' + event.segment + ')');

    $cell.append($event);

    return $cell;
}

function segment_from_event(event)
{
    var theDate = event.Date;
    return (theDate.getFullYear() * 100) + theDate.getMonth(); // XXX: produces YYYYMM as integer
}

var layout_configurations = [
    {
        "cols": 2,
        "css": {
            "min-width": 768
        },
        "bootstrap": {
            "size": "sm",
            "column-multiplier": 6
        }
    },
    {
        "cols": 4,
        "css": {
            "min-width": 992
        },
        "bootstrap": {
            "size": "md",
            "column-multiplier": 3
        }
    }
];

// track which bootstrap classes are applied to the element

function arrange_events($row)
{
    var $cells = $row.find(".cell");

    var css_text = [];
    var autogenerated_block = $("head").find("style#timeline-autogenerated-css");
    if(autogenerated_block.length <= 0)
    {
        autogenerated_block = $('');
        $("head").append(autogenerated_block);
    }
    autogenerated_block.empty();

    for(var i=0; i < layout_configurations.length; i++)
    {
        layout_config = layout_configurations[i];
        console.log("configuring for columns:", layout_config);

        // build a media-query rule

        var _media_query = [];
        if(layout_config.css["min-width"])
        {
            _media_query.push("min-width: " + layout_config.css["min-width"] + "px");
        }
        if(layout_config.css["max-width"])
        {
            _media_query.push("max-width: " + layout_config.css["max-width"] + "px");
        }
        css_text.push("@media (" + _media_query.join(" and ") + ")");
        css_text.push("{");

        // initialise stacks
        var height_stacks = [];

        // iterate through each cell/event (should be chronological)
        for(var j=0; j < $cells.length; j++)
        {
            var $cell = $($cells[j]);
            var cell_id = $cell.attr("id");
            var cell_height = $cell.outerHeight();

            // iterate through each height stack and find the smallest
            var candidate_stack = -1;
            var minimum_height = -1;
            for(var k=0; k < layout_config.cols; k++)
            {
                if(typeof height_stacks[k] == "undefined")
                {
                    height_stacks[k] = 0;
                }

                if(height_stacks[k] < minimum_height || minimum_height == -1)
                {
                    // found the lowest stack (or this is first iteration)
                    minimum_height = height_stacks[k];
                    candidate_stack = k;
                }
            }

            // a stack has been identified
            var cell_top = height_stacks[candidate_stack];
            var cell_column_enumeration = candidate_stack;

            // add to the height stack
            height_stacks[candidate_stack] += cell_height;

            // apply absolute styles into the page header

            css_text.push("#" + cell_id);
            css_text.push("{");
            css_text.push("position: absolute;");
            css_text.push("top: " + cell_top + "px;");
            css_text.push("}");

            // remove previous offsets for this size class
            var _candidate_classes = [];
            for(var k=0; k < 12; k+= layout_config.bootstrap["column-multiplier"])
            {
                _candidate_classes.push("col-" + layout_config.bootstrap["size"] + "-offset-" + k);
            }
            $cell.removeClass(_candidate_classes.join(" "));

            // apply offset classes to simulate columns

            bootstrap_offset_class = "col-" + layout_config.bootstrap["size"] + "-offset-" + (layout_config.bootstrap["column-multiplier"] * cell_column_enumeration);
            $cell.addClass(bootstrap_offset_class);

        }

        css_text.push("}");

        autogenerated_block.html(css_text.join("\n"));
    }
}

$(window).resize(function(e){
    setTimeout(function(){
        arrange_events($("#timeline .row.segment"));
    }, 1000);
});

function debug_add_random_event()
{
    var event_date = debugGenerate_randomDate(new Date(2015, 0, 1), new Date(2015, 0, 31));
    var event =
    {
        Date: event_date,
        segment: false,
        title: debugGenerate_loremIpsum(20, 3)
    };
    event.segment = segment_from_event(event);
    add_event(event);
}

$("#add-event").click(function(e){
    debug_add_random_event();
});

debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();
debug_add_random_event();

$(window).resize();

});<|endoftext|>


<commit_before>import isDOMElement from './isDOMElement';
import isDOMRoot from './isDOMRoot';

export default function isDOMChild() {
  return isDOMElement(elm) || !isDOMRoot(elm)
}
<commit_msg>isDOMChild: Add missing argument<commit_after>import isDOMElement from './isDOMElement';
import isDOMRoot from './isDOMRoot';

export default function isDOMChild(elm) {
  return isDOMElement(elm) && !isDOMRoot(elm);
}
<|endoftext|>


<commit_before>'use strict';

const Logger = require('./logger');
const GpioPin = require('./GPIOPin');

const wpi = require('wiring-pi');

class GpioController {

    constructor(ipAddress) {
        this.logger = new Logger();
        this.buttonPin = new GpioPin(19, 0);
        this.butonLedPin = new GpioPin(18, 0);
        this.ledPin1 = new GpioPin(13, 0);
        this.ledPin2 = new GpioPin(15, 0);
    }

    init() {
        wpi.setup('phys');
        wpi.pinMode(this.ledPin1.number, wpi.OUTPUT);
        wpi.pinMode(this.ledPin2.number, wpi.OUTPUT);
        wpi.pinMode(this.butonLedPin.number, wpi.OUTPUT);
        wpi.pinMode(this.buttonPin.number, wpi.INPUT);
        wpi.pullUpDnControl(this.butonLedPin.number, wpi.PUD_UP);
    }

    getStatus() {
        return "status";
    }

    turnLEDOn() {
        this.logger.log("turning leds on");
        wpi.digitalWrite(this.ledPin1.number, 1);
        wpi.digitalWrite(this.ledPin2.number, 1);
        wpi.digitalWrite(this.butonLedPin.number, 1);
    }

    turnLEDOff() {
        this.logger.log("turning leds off");
        wpi.digitalWrite(this.ledPin1.number, 0);
        wpi.digitalWrite(this.ledPin2.number, 0);
        wpi.digitalWrite(this.butonLedPin.number, 0);
    }

    startButtonListener() {
        console.log("starting listening");
        let status = this.buttonPin.status;
        console.log('current button status: ' + this.butonLedPin.status);
        wpi.wiringPiISR(this.buttonPin.number, wpi.INT_EDGE_BOTH, () =>  {
            if (wpi.digitalRead(this.buttonPin.number)) {
                if (false === status) {
                    status = 1;
                    handleButton();
                }
            }
            else {
                status = 0;
            }
        });

        function handleButton() {
            if (wpi.digitalRead(this.buttonPin.number)) {
                console.log('On');
                this.turnLEDOn();
            } else {
                console.log('Off');
                this.turnLEDOff();
            }
        }
    }

}

module.exports = GpioController;
<commit_msg>give it another try<commit_after>'use strict';

const Logger = require('./logger');
const GpioPin = require('./GPIOPin');

const wpi = require('wiring-pi');

class GpioController {

    constructor(ipAddress) {
        this.logger = new Logger();
        this.buttonPin = new GpioPin(19, 0);
        this.butonLedPin = new GpioPin(18, 0);
        this.ledPin1 = new GpioPin(13, 0);
        this.ledPin2 = new GpioPin(15, 0);
    }

    init() {
        wpi.setup('phys');
        wpi.pinMode(this.ledPin1.number, wpi.OUTPUT);
        wpi.pinMode(this.ledPin2.number, wpi.OUTPUT);
        wpi.pinMode(this.butonLedPin.number, wpi.OUTPUT);
        wpi.pinMode(this.buttonPin.number, wpi.INPUT);
        wpi.pullUpDnControl(this.butonLedPin.number, wpi.PUD_UP);
    }

    getStatus() {
        return "status";
    }

    turnLEDOn() {
        this.logger.log("turning leds on");
        wpi.digitalWrite(this.ledPin1.number, 1);
        wpi.digitalWrite(this.ledPin2.number, 1);
        wpi.digitalWrite(this.butonLedPin.number, 1);
    }

    turnLEDOff() {
        this.logger.log("turning leds off");
        wpi.digitalWrite(this.ledPin1.number, 0);
        wpi.digitalWrite(this.ledPin2.number, 0);
        wpi.digitalWrite(this.butonLedPin.number, 0);
    }

    startButtonListener() {
        console.log("starting listening");
        wpi.wiringPiISR(this.buttonPin.number, wpi.INT_EDGE_BOTH, () => {
            console.log('button clicked');
            console.log('button clicked' + this.buttonPin.number);
            if (wpi.digitalRead(this.buttonPin.number)) {
                console.log('button On');
                handleButton();
            }
            else {
                console.log('button Off');

            }
        });

        function handleButton() {
            if (wpi.digitalRead(this.buttonPin.number)) {
                console.log('On');
                this.turnLEDOn();
            } else {
                console.log('Off');
                this.turnLEDOff();
            }
        }
    }

}

module.exports = GpioController;
<|endoftext|>


<commit_before>var test = require('tape');
var resolve = require('../');
var path = require('path');

test('shadowed core module names agree with require.resolve()', function (t) {
    t.plan(2);

    resolve('util', { basedir: path.join(__dirname, 'shadowed_core') }, function (err, res) {
        t.ifError(err);
        t.equal(res, 'util');
    });
});

test('shadowed core module names can be accessed with `name/`', function (t) {
    t.plan(2);

    resolve('util/', { basedir: path.join(__dirname, 'shadowed_core') }, function (err, res) {
        t.ifError(err);
        t.equal(res, path.join(__dirname, 'shadowed_core/node_modules/util/index.js'));
    });
});
<commit_msg>Update test names<commit_after>var test = require('tape');
var resolve = require('../');
var path = require('path');

test('shadowed core modules still return core module', function (t) {
    t.plan(2);

    resolve('util', { basedir: path.join(__dirname, 'shadowed_core') }, function (err, res) {
        t.ifError(err);
        t.equal(res, 'util');
    });
});

test('shadowed core modules return shadow when appending `/`', function (t) {
    t.plan(2);

    resolve('util/', { basedir: path.join(__dirname, 'shadowed_core') }, function (err, res) {
        t.ifError(err);
        t.equal(res, path.join(__dirname, 'shadowed_core/node_modules/util/index.js'));
    });
});
<|endoftext|>


<commit_before>/*global define*/
define(['lodash'], function(_) {
    'use strict';

    // Cluster Service is a service which is injected into other services.
    // We do this so we have only one service tracking the active cluster
    // FSID, simplifying updates across the app.
    //
    // This service is slightly different because it has an initialize
    // method, which is a simple bootstrap that requests the current list
    // of Cluster FSIDs known about and picks the very first one returned.
    //
    // In the future this will have to be a guided, by either the User's
    // profile and/or saved defaults.
    //
    var ClusterService = function(Restangular, $location, ErrorService) {
        // This custom response extractor handles the paginated response
        // from our Calamari Django JSON API.
        var djangoPaginationResponseExtractor = function(response /*, operation, what, url */ ) {
            if (response.count !== undefined && response.results !== undefined) {
                var newResponse = response.results;
                // Add a new object **pagnation** which contains the next, previous urls and count.
                // These are currently unused.
                newResponse.pagnation = {
                    next: response.next,
                    previous: response.previous,
                    count: response.count
                };
                return newResponse;
            }
            return response;
        };

        // We use Restangular to wrap $http and give us a more natural interface
        // to the Calamari JSON API that returns $q promises.
        //
        // We instantiate 2 root restangular instances with different configurations.
        // The first one is for simple JSON API requests.
        var restangular = Restangular.withConfig(function(RestangularConfigurer) {
            RestangularConfigurer.setBaseUrl('/api/v2').setResponseExtractor(djangoPaginationResponseExtractor).setErrorInterceptor(ErrorService.errorInterceptor);
        });
        // The second gives us access to the raw response so we can look at the status code.
        // Useful for APIs that return 202 responses for asynchronous tasks.
        var restangularFull = Restangular.withConfig(function(RestangularConfigurer) {
            RestangularConfigurer.setBaseUrl('/api/v2').setFullResponse(true).setResponseExtractor(djangoPaginationResponseExtractor).setErrorInterceptor(ErrorService.errorInterceptor);
        });
        // **constructor**
        var Service = function() {
            this.restangular = restangular;
            this.restangularFull = restangularFull;
        };
        Service.prototype = _.extend(Service.prototype, {
            // **initialize**
            // This must be run before any other service to
            // initialize the cluster model and fsid values.
            initialize: function() {
                var self = this;
                return this.getList().then(function(clusters) {
                    if (clusters.length) {
                        var cluster = _.first(clusters);
                        self.clusterId = cluster.id;
                        self.clusterModel = cluster;
                        return;
                    }
                    self.clusterId = null;
                    self.clusterModel = null;
                    $location.path('/first');
                });
            },
            // **getList**
            // Return list of all the clusters Calamari knows about.
            getList: function() {
                return this.restangular.all('cluster').getList().then(function(clusters) {
                    return clusters;
                });
            },
            // **get**
            // Return a specific cluster based on it's FSID.
            get: function(id) {
                return this.cluster(id).get().then(function(cluster) {
                    return cluster;
                });
            },
            // **cluster**
            // A base function that defines the root of the request.
            // It's designed to be called by other methods.
            cluster: function(id) {
                if (id === undefined) {
                    id = this.clusterId;
                }
                return this.restangular.one('cluster', id);
            },
            // **clusterFull**
            // A base function that defines the root of the request.
            // It's designed to be called by other methods.
            // Responses are raw and contain extra fields such as
            // status code.
            clusterFull: function(id) {
                if (id === undefined) {
                    id = this.clusterId;
                }
                return this.restangularFull.one('cluster', id);
            },
            // **base**
            // Return the raw restangular reference.
            base: function() {
                return this.restangular;
            }
        });
        var service = new Service();
        return service;
    };
    return ['Restangular', '$location', 'ErrorService', ClusterService];
});
<commit_msg>Fix spelling mistake<commit_after>/*global define*/
define(['lodash'], function(_) {
    'use strict';

    // Cluster Service is a service which is injected into other services.
    // We do this so we have only one service tracking the active cluster
    // FSID, simplifying updates across the app.
    //
    // This service is slightly different because it has an initialize
    // method, which is a simple bootstrap that requests the current list
    // of Cluster FSIDs known about and picks the very first one returned.
    //
    // In the future this will have to be a guided, by either the User's
    // profile and/or saved defaults.
    //
    var ClusterService = function(Restangular, $location, ErrorService) {
        // This custom response extractor handles the paginated response
        // from our Calamari Django JSON API.
        var djangoPaginationResponseExtractor = function(response /*, operation, what, url */ ) {
            if (response.count !== undefined && response.results !== undefined) {
                var newResponse = response.results;
                // Add a new object **pagination** which contains the next, previous urls and count.
                // These are currently unused.
                newResponse.pagination = {
                    next: response.next,
                    previous: response.previous,
                    count: response.count
                };
                return newResponse;
            }
            return response;
        };

        // We use Restangular to wrap $http and give us a more natural interface
        // to the Calamari JSON API that returns $q promises.
        //
        // We instantiate 2 root restangular instances with different configurations.
        // The first one is for simple JSON API requests.
        var restangular = Restangular.withConfig(function(RestangularConfigurer) {
            RestangularConfigurer.setBaseUrl('/api/v2').setResponseExtractor(djangoPaginationResponseExtractor).setErrorInterceptor(ErrorService.errorInterceptor);
        });
        // The second gives us access to the raw response so we can look at the status code.
        // Useful for APIs that return 202 responses for asynchronous tasks.
        var restangularFull = Restangular.withConfig(function(RestangularConfigurer) {
            RestangularConfigurer.setBaseUrl('/api/v2').setFullResponse(true).setResponseExtractor(djangoPaginationResponseExtractor).setErrorInterceptor(ErrorService.errorInterceptor);
        });
        // **constructor**
        var Service = function() {
            this.restangular = restangular;
            this.restangularFull = restangularFull;
        };
        Service.prototype = _.extend(Service.prototype, {
            // **initialize**
            // This must be run before any other service to
            // initialize the cluster model and fsid values.
            initialize: function() {
                var self = this;
                return this.getList().then(function(clusters) {
                    if (clusters.length) {
                        var cluster = _.first(clusters);
                        self.clusterId = cluster.id;
                        self.clusterModel = cluster;
                        return;
                    }
                    self.clusterId = null;
                    self.clusterModel = null;
                    $location.path('/first');
                });
            },
            // **getList**
            // Return list of all the clusters Calamari knows about.
            getList: function() {
                return this.restangular.all('cluster').getList().then(function(clusters) {
                    return clusters;
                });
            },
            // **get**
            // Return a specific cluster based on it's FSID.
            get: function(id) {
                return this.cluster(id).get().then(function(cluster) {
                    return cluster;
                });
            },
            // **cluster**
            // A base function that defines the root of the request.
            // It's designed to be called by other methods.
            cluster: function(id) {
                if (id === undefined) {
                    id = this.clusterId;
                }
                return this.restangular.one('cluster', id);
            },
            // **clusterFull**
            // A base function that defines the root of the request.
            // It's designed to be called by other methods.
            // Responses are raw and contain extra fields such as
            // status code.
            clusterFull: function(id) {
                if (id === undefined) {
                    id = this.clusterId;
                }
                return this.restangularFull.one('cluster', id);
            },
            // **base**
            // Return the raw restangular reference.
            base: function() {
                return this.restangular;
            }
        });
        var service = new Service();
        return service;
    };
    return ['Restangular', '$location', 'ErrorService', ClusterService];
});
<|endoftext|>


<commit_before>"use strict";

var Discord = require("discord.io");
var fs = require('fs');
var logger = require("winston");
var dlog = require("./lib/dlog.js");

var lib = {};

lib.comic = require("./lib/comic.js");
lib.dave = async function(logger, client, user, userID, channelID, args) {
				client.sendMessage({
					to: channelID,
					message: "OtherDave is not David."
				});
		   };
lib.drunkdraw = require("./lib/drunkdraw.js");
lib.haiku = require("./lib/haiku.js");
lib.mimic = require("./lib/mimic.js");
lib.pedant = require("./lib/pedant.js");
lib.prompt = require("./lib/prompt.js");
lib.respect = require("./lib/respect.js");
lib.update = require("./lib/update.js");

var auth = require("./data/auth.json");
// Configure logger settings
logger.remove(logger.transports.Console);
logger.add(logger.transports.Console, {
    colorize: true
});
logger.level = "debug";
// Initialize Discord Bot
var client = new Discord.Client({
    token: auth.token,
    autorun: true
});
client.on("ready", function (evt) {
    logger.info("Connected");
    logger.info("Logged in as: ");
    logger.info(client.username + " - (" + client.id + ")");
});
client.on("message", function (user, userID, channelID, message, evt) {
	// OtherDave shouldn't talk to himself.
	if(userID == client.id) {
		return;
	}

	if (message.substring(0, 1) == "!") {
		var args = message.trim().substring(1).split(" ");
        var cmd = args[0];

        args = args.splice(1);

		if(cmd == "haiku") {
			lib.haiku(logger, client, user, userID,
				channelID, args.join(" "), true)
		} else if(cmd == "quack") {
			client.sendMessage({
				to: channelID,
				message: "quack"
			});
		} else if(cmd in lib) {
			lib[cmd](logger, client, user, userID, channelID, args)
				.catch(function(error) { dlog(client, error) });
		} else {
			client.sendMessage({
				to: channelID,
				message: "I'm sorry Dave, I'm afraid I can't do that."
			});
		}
    } else if(message.indexOf("<@" + client.id + ">") == 0) {
		client.sendMessage({
			to: channelID,
			message: "Hey, you talkin to me?"
		});
	}
	else {
		lib.pedant(logger, client, user, userID, channelID, message)
			.catch(function() {});
		lib.haiku(logger, client, user, userID, channelID, message, false)
			.catch(function() {});

		// OtherDave is always listening...
		fs.appendFile("./data/markov/" + userID + ".txt", message + "\n", function(error) {
			if(error) {
				logger.error(error);
			}
		});
	}
});
<commit_msg>Add boot dlog<commit_after>"use strict";

var Discord = require("discord.io");
var fs = require('fs');
var logger = require("winston");
var dlog = require("./lib/dlog.js");

var lib = {};

lib.comic = require("./lib/comic.js");
lib.dave = async function(logger, client, user, userID, channelID, args) {
				client.sendMessage({
					to: channelID,
					message: "OtherDave is not David."
				});
		   };
lib.drunkdraw = require("./lib/drunkdraw.js");
lib.haiku = require("./lib/haiku.js");
lib.mimic = require("./lib/mimic.js");
lib.pedant = require("./lib/pedant.js");
lib.prompt = require("./lib/prompt.js");
lib.respect = require("./lib/respect.js");
lib.update = require("./lib/update.js");

var auth = require("./data/auth.json");
// Configure logger settings
logger.remove(logger.transports.Console);
logger.add(logger.transports.Console, {
    colorize: true
});
logger.level = "debug";
// Initialize Discord Bot
var client = new Discord.Client({
    token: auth.token,
    autorun: true
});
client.on("ready", function (evt) {
    logger.info("Connected");
    logger.info("Logged in as: ");
	logger.info(client.username + " - (" + client.id + ")");
	dlog(client, "Hi, I'm OtherDave and I'm BACK FOR BUSINESS.");
});
client.on("message", function (user, userID, channelID, message, evt) {
	// OtherDave shouldn't talk to himself.
	if(userID == client.id) {
		return;
	}

	if (message.substring(0, 1) == "!") {
		var args = message.trim().substring(1).split(" ");
        var cmd = args[0];

        args = args.splice(1);

		if(cmd == "haiku") {
			lib.haiku(logger, client, user, userID,
				channelID, args.join(" "), true)
		} else if(cmd == "quack") {
			client.sendMessage({
				to: channelID,
				message: "quack"
			});
		} else if(cmd in lib) {
			lib[cmd](logger, client, user, userID, channelID, args)
				.catch(function(error) { dlog(client, error) });
		} else {
			client.sendMessage({
				to: channelID,
				message: "I'm sorry Dave, I'm afraid I can't do that."
			});
		}
    } else if(message.indexOf("<@" + client.id + ">") == 0) {
		client.sendMessage({
			to: channelID,
			message: "Hey, you talkin to me?"
		});
	}
	else {
		lib.pedant(logger, client, user, userID, channelID, message)
			.catch(function() {});
		lib.haiku(logger, client, user, userID, channelID, message, false)
			.catch(function() {});

		// OtherDave is always listening...
		fs.appendFile("./data/markov/" + userID + ".txt", message + "\n", function(error) {
			if(error) {
				logger.error(error);
			}
		});
	}
});
<|endoftext|>