<commit_before>function hex(number, leading, usePrefix) {
	if (typeof(usePrefix) === 'undefined') {
		usePrefix = true;
	}
	if (typeof(leading) === 'undefined') {
		leading = 8;
	}
	var string = (number >>> 0).toString(16).toUpperCase();
	leading -= string.length;
	return (usePrefix ? '0x' : '')  + new Array(leading + 1).join('0') + string;
}

function Console(gba) {
	this.cpu = gba.cpu;
	this.gba = gba;
	this.ul = document.getElementById('console');
	this.gprs = document.getElementById('gprs');
	this.memory = new Memory(gba.mmu);
	this.updateGPRs();
	this.updateCPSR();
	this.breakpoints = [];
	this.memory.refreshAll();
	this.logQueue = [];
	var self = this;
	gba.setLogger(function (message) { self.log(message) });
	this.gba.doStep = function () { return self.testBreakpoints() };
}

Console.prototype.updateGPRs = function() {
	for (var i = 0; i < 16; ++i) {
		this.gprs.children[i].textContent = hex(this.cpu.gprs[i]);
	}
}

Console.prototype.updateCPSR = function() {
	var cpu = this.cpu;
	var bit = function(psr, member) {
		var element = document.getElementById(psr);
		if (cpu[member]) {
			element.removeAttribute('class');
		} else {
			element.setAttribute('class', 'disabled');
		}
	}
	bit('cpsrN', 'cpsrN');
	bit('cpsrZ', 'cpsrZ');
	bit('cpsrC', 'cpsrC');
	bit('cpsrV', 'cpsrV');
	bit('cpsrI', 'cpsrI');
	bit('cpsrT', 'execMode');

	var mode = document.getElementById('mode');
	switch (cpu.mode) {
	case cpu.MODE_USER:
		mode.textContent = 'USER';
		break;
	case cpu.MODE_IRQ:
		mode.textContent = 'IRQ';
		break;
	case cpu.MODE_FIQ:
		mode.textContent = 'FIQ';
		break;
	case cpu.MODE_SUPERVISOR:
		mode.textContent = 'SVC';
		break;
	case cpu.MODE_ABORT:
		mode.textContent = 'ABORT';
		break;
	case cpu.MODE_UNDEFINED:
		mode.textContent = 'UNDEFINED';
		break;
	case cpu.MODE_SYSTEM:
		mode.textContent = 'SYSTEM';
		break;
	default:
		mode.textContent = '???';
		break;
	}
}

Console.prototype.log = function(message) {
	this.logQueue.push(message);
	if (message.substring(0, '[ERROR]'.length) === '[ERROR]') {
		this.pause();
	}
	if (!this.stillRunning) {
		this.flushLog();
	}
}

Console.prototype.flushLog = function() {
	var doScroll = this.ul.scrollTop == this.ul.scrollHeight - this.ul.offsetHeight;
	while (this.logQueue.length) {
		var entry = document.createElement('li');
		entry.textContent = this.logQueue.shift();
		this.ul.appendChild(entry);
	}
	if (doScroll) {
		var ul = this.ul;
		var last = ul.scrollTop;
		var scrollUp = function() {
			if (ul.scrollTop == last) {
				ul.scrollTop = (ul.scrollHeight - ul.offsetHeight) * 0.2 + last * 0.8;
				last = ul.scrollTop;
				if (last != ul.scrollHeight - ul.offsetHeight) {
					setTimeout(scrollUp, 25);
				}
			}
		}
		setTimeout(scrollUp, 25);
	}

}

Console.prototype.step = function() {
	try {
		this.cpu.step();
		this.updateGPRs();
		this.updateCPSR();
		this.memory.refreshAll();
	} catch (exception) {
		this.log(exception);
		throw exception;
	}
}

Console.prototype.runVisible = function() {
	if (this.stillRunning) {
		return;
	}

	this.stillRunning = true;
	var self = this;
	run = function() {
		if (self.stillRunning) {
			try {
				self.step();
				if (self.breakpoints.length && self.breakpoints[self.cpu.gprs[self.cpu.PC]]) {
					self.breakpointHit();
					return;
				}
				self.flushLog();
				setTimeout(run, 0);
			} catch (exception) {
				self.log(exception);
				self.pause();
				throw exception;
			}
		}
	}
	setTimeout(run, 0);
}

Console.prototype.run = function() {
	if (this.stillRunning) {
		return;
	}

	this.stillRunning = true;
	var regs = document.getElementById('registers');
	var mem = document.getElementById('memory');
	var start = Date.now();
	regs.setAttribute('class', 'disabled');
	mem.setAttribute('class', 'disabled');
	var self = this;
	this.gba.runStable();
}

Console.prototype.runFrame = function() {
	if (this.stillRunning) {
		return;
	}

	this.stillRunning = true;
	var regs = document.getElementById('registers');
	var mem = document.getElementById('memory');
	var start = Date.now();
	regs.setAttribute('class', 'disabled');
	mem.setAttribute('class', 'disabled');
	var self = this;
	run = function() {
		self.gba.step();
		self.pause();
	}
	setTimeout(run, 0);
}

Console.prototype.pause = function() {
	this.stillRunning = false;
	this.gba.pause();
	var regs = document.getElementById('registers');
	var mem = document.getElementById('memory');
	mem.removeAttribute('class');
	regs.removeAttribute('class');
	this.updateGPRs();
	this.updateCPSR();
	this.memory.refreshAll();
	this.flushLog();
}

Console.prototype.breakpointHit = function() {
	this.pause();
	this.log('Hit breakpoint at ' + hex(this.cpu.gprs[this.cpu.PC]));
}

Console.prototype.addBreakpoint = function(addr) {
	this.breakpoints[addr] = true;
	var bpLi = document.getElementById('bp' + addr);
	if (!bpLi) {
		bpLi = document.createElement('li');
		bpLi.address = addr;
		var cb = document.createElement('input');
		cb.setAttribute('type', 'checkbox');
		cb.setAttribute('checked', 'checked');
		var self = this;
		cb.addEventListener('click', function() {
			self.breakpoints[addr] = cb.checked;
		}, false);
		bpLi.appendChild(cb);
		bpLi.appendChild(document.createTextNode(hex(addr)));
		document.getElementById('breakpointView').appendChild(bpLi);
	}
}

Console.prototype.testBreakpoints = function() {
	if (this.breakpoints.length && this.breakpoints[this.cpu.gprs[this.cpu.PC]]) {
		this.breakpointHit();
		return false;
	}
	return this.gba.waitFrame();
};

Memory = function(mmu) {
	this.mmu = mmu;
	this.ul = document.getElementById('memoryView');
	row = this.createRow(0);
	this.ul.appendChild(row);
	this.rowHeight = row.offsetHeight;
	this.numberRows = this.ul.parentNode.offsetHeight / this.rowHeight + 2;
	this.ul.removeChild(row);
	this.scrollTop = 50 - this.ul.parentElement.firstElementChild.offsetHeight;

	for (var i = 0; i < this.numberRows; ++i) {
		this.ul.appendChild(this.createRow(i << 4));
	}
	this.ul.parentElement.scrollTop = this.scrollTop;

	var self = this;
	this.ul.parentElement.addEventListener('scroll', function(e) { self.scroll(e) }, true);
	window.addEventListener('resize', function(e) { self.resize() }, true);
}

Memory.prototype.scroll = function(e) {
	while (this.ul.parentElement.scrollTop - this.scrollTop < this.rowHeight) {
		if (this.ul.firstChild.offset == 0) {
			break;
		}
		var victim = this.ul.lastChild;
		this.ul.removeChild(victim);
		victim.offset = this.ul.firstChild.offset - 16;
		this.refresh(victim);
		this.ul.insertBefore(victim, this.ul.firstChild);
		this.ul.parentElement.scrollTop += this.rowHeight;
	}
	while (this.ul.parentElement.scrollTop - this.scrollTop > this.rowHeight * 2) {
		var victim = this.ul.firstChild;
		this.ul.removeChild(victim);
		victim.offset = this.ul.lastChild.offset + 16;
		this.refresh(victim);
		this.ul.appendChild(victim);
		this.ul.parentElement.scrollTop -= this.rowHeight;
	}
	if (this.ul.parentElement.scrollTop < this.scrollTop) {
		this.ul.parentElement.scrollTop = this.scrollTop;
		e.preventDefault();
	}
}

Memory.prototype.resize = function() {
	this.numberRows = this.ul.parentNode.offsetHeight / this.rowHeight + 2;
	if (this.numberRows > this.ul.children.length) {
		var offset = this.ul.lastChild.offset + 16;
		for (var i = 0; i < this.numberRows - this.ul.children.length; ++i) {
			var row = this.createRow(offset);
			this.refresh(row);
			this.ul.appendChild(row);
			offset += 16;
		}
	} else {
		for (var i = 0; i < this.ul.children.length - this.numberRows; ++i) {
			this.ul.removeChild(this.ul.lastChild);
		}
	}
}

Memory.prototype.refresh = function(row) {
	var showChanged;
	var newValue;
	var child;
	row.firstChild.textContent = hex(row.offset);
	if (row.oldOffset == row.offset) {
		showChanged = true;
	} else {
		row.oldOffset = row.offset;
		showChanged = false;
	}
	for (var i = 0; i < 16; ++i) {
		child = row.children[i + 1];
		try {
			newValue = hex(this.mmu.loadU8(row.offset + i), 2, false);
			if (child.textContent == newValue) {
				child.setAttribute('class', 'memoryCell');
			} else if (showChanged) {
				child.setAttribute('class', 'memoryCell changed');
				child.textContent = newValue;
			} else {
				child.setAttribute('class', 'memoryCell');
				child.textContent = newValue;
			}
		} catch (exception) {
			child.setAttribute('class', 'memoryCell');
			child.textContent = '??';
		}
	}
}

Memory.prototype.refreshAll = function() {
	for (var i = 0; i < this.ul.children.length; ++i) {
		this.refresh(this.ul.children[i]);
	}
}

Memory.prototype.createRow = function(startOffset) {
	var li = document.createElement('li');
	var offset = document.createElement('span');
	offset.setAttribute('class', 'memoryOffset');
	offset.textContent = hex(startOffset);
	li.appendChild(offset);

	for (var i = 0; i < 16; ++i) {
		var b = document.createElement('span');
		b.textContent = '00';
		b.setAttribute('class', 'memoryCell');
		li.appendChild(b);
	}
	li.offset = startOffset;
	li.oldOffset = startOffset;
	return li;
}

Memory.prototype.scrollTo = function(offset) {
	offset &= 0xFFFFFFF0;
	if (offset) {
		for (var i = 0; i < this.ul.children.length; ++i) {
			var child = this.ul.children[i];
			child.offset = offset + (i - 1) * 16;
			this.refresh(child);
		}
		this.ul.parentElement.scrollTop = this.scrollTop + this.rowHeight;
	} else {
		for (var i = 0; i < this.ul.children.length; ++i) {
			var child = this.ul.children[i];
			child.offset = offset + i * 16;
			this.refresh(child);
		}
		this.ul.parentElement.scrollTop = this.scrollTop;
	}
}
<commit_msg>Fix exception-raising case in hex()<commit_after>function hex(number, leading, usePrefix) {
	if (typeof(usePrefix) === 'undefined') {
		usePrefix = true;
	}
	if (typeof(leading) === 'undefined') {
		leading = 8;
	}
	var string = (number >>> 0).toString(16).toUpperCase();
	leading -= string.length;
	if (leading < 0)
		return string;
	return (usePrefix ? '0x' : '') + new Array(leading + 1).join('0') + string;
}

function Console(gba) {
	this.cpu = gba.cpu;
	this.gba = gba;
	this.ul = document.getElementById('console');
	this.gprs = document.getElementById('gprs');
	this.memory = new Memory(gba.mmu);
	this.updateGPRs();
	this.updateCPSR();
	this.breakpoints = [];
	this.memory.refreshAll();
	this.logQueue = [];
	var self = this;
	gba.setLogger(function (message) { self.log(message) });
	this.gba.doStep = function () { return self.testBreakpoints() };
}

Console.prototype.updateGPRs = function() {
	for (var i = 0; i < 16; ++i) {
		this.gprs.children[i].textContent = hex(this.cpu.gprs[i]);
	}
}

Console.prototype.updateCPSR = function() {
	var cpu = this.cpu;
	var bit = function(psr, member) {
		var element = document.getElementById(psr);
		if (cpu[member]) {
			element.removeAttribute('class');
		} else {
			element.setAttribute('class', 'disabled');
		}
	}
	bit('cpsrN', 'cpsrN');
	bit('cpsrZ', 'cpsrZ');
	bit('cpsrC', 'cpsrC');
	bit('cpsrV', 'cpsrV');
	bit('cpsrI', 'cpsrI');
	bit('cpsrT', 'execMode');

	var mode = document.getElementById('mode');
	switch (cpu.mode) {
	case cpu.MODE_USER:
		mode.textContent = 'USER';
		break;
	case cpu.MODE_IRQ:
		mode.textContent = 'IRQ';
		break;
	case cpu.MODE_FIQ:
		mode.textContent = 'FIQ';
		break;
	case cpu.MODE_SUPERVISOR:
		mode.textContent = 'SVC';
		break;
	case cpu.MODE_ABORT:
		mode.textContent = 'ABORT';
		break;
	case cpu.MODE_UNDEFINED:
		mode.textContent = 'UNDEFINED';
		break;
	case cpu.MODE_SYSTEM:
		mode.textContent = 'SYSTEM';
		break;
	default:
		mode.textContent = '???';
		break;
	}
}

Console.prototype.log = function(message) {
	this.logQueue.push(message);
	if (message.substring(0, '[ERROR]'.length) === '[ERROR]') {
		this.pause();
	}
	if (!this.stillRunning) {
		this.flushLog();
	}
}

Console.prototype.flushLog = function() {
	var doScroll = this.ul.scrollTop == this.ul.scrollHeight - this.ul.offsetHeight;
	while (this.logQueue.length) {
		var entry = document.createElement('li');
		entry.textContent = this.logQueue.shift();
		this.ul.appendChild(entry);
	}
	if (doScroll) {
		var ul = this.ul;
		var last = ul.scrollTop;
		var scrollUp = function() {
			if (ul.scrollTop == last) {
				ul.scrollTop = (ul.scrollHeight - ul.offsetHeight) * 0.2 + last * 0.8;
				last = ul.scrollTop;
				if (last != ul.scrollHeight - ul.offsetHeight) {
					setTimeout(scrollUp, 25);
				}
			}
		}
		setTimeout(scrollUp, 25);
	}

}

Console.prototype.step = function() {
	try {
		this.cpu.step();
		this.updateGPRs();
		this.updateCPSR();
		this.memory.refreshAll();
	} catch (exception) {
		this.log(exception);
		throw exception;
	}
}

Console.prototype.runVisible = function() {
	if (this.stillRunning) {
		return;
	}

	this.stillRunning = true;
	var self = this;
	run = function() {
		if (self.stillRunning) {
			try {
				self.step();
				if (self.breakpoints.length && self.breakpoints[self.cpu.gprs[self.cpu.PC]]) {
					self.breakpointHit();
					return;
				}
				self.flushLog();
				setTimeout(run, 0);
			} catch (exception) {
				self.log(exception);
				self.pause();
				throw exception;
			}
		}
	}
	setTimeout(run, 0);
}

Console.prototype.run = function() {
	if (this.stillRunning) {
		return;
	}

	this.stillRunning = true;
	var regs = document.getElementById('registers');
	var mem = document.getElementById('memory');
	var start = Date.now();
	regs.setAttribute('class', 'disabled');
	mem.setAttribute('class', 'disabled');
	var self = this;
	this.gba.runStable();
}

Console.prototype.runFrame = function() {
	if (this.stillRunning) {
		return;
	}

	this.stillRunning = true;
	var regs = document.getElementById('registers');
	var mem = document.getElementById('memory');
	var start = Date.now();
	regs.setAttribute('class', 'disabled');
	mem.setAttribute('class', 'disabled');
	var self = this;
	run = function() {
		self.gba.step();
		self.pause();
	}
	setTimeout(run, 0);
}

Console.prototype.pause = function() {
	this.stillRunning = false;
	this.gba.pause();
	var regs = document.getElementById('registers');
	var mem = document.getElementById('memory');
	mem.removeAttribute('class');
	regs.removeAttribute('class');
	this.updateGPRs();
	this.updateCPSR();
	this.memory.refreshAll();
	this.flushLog();
}

Console.prototype.breakpointHit = function() {
	this.pause();
	this.log('Hit breakpoint at ' + hex(this.cpu.gprs[this.cpu.PC]));
}

Console.prototype.addBreakpoint = function(addr) {
	this.breakpoints[addr] = true;
	var bpLi = document.getElementById('bp' + addr);
	if (!bpLi) {
		bpLi = document.createElement('li');
		bpLi.address = addr;
		var cb = document.createElement('input');
		cb.setAttribute('type', 'checkbox');
		cb.setAttribute('checked', 'checked');
		var self = this;
		cb.addEventListener('click', function() {
			self.breakpoints[addr] = cb.checked;
		}, false);
		bpLi.appendChild(cb);
		bpLi.appendChild(document.createTextNode(hex(addr)));
		document.getElementById('breakpointView').appendChild(bpLi);
	}
}

Console.prototype.testBreakpoints = function() {
	if (this.breakpoints.length && this.breakpoints[this.cpu.gprs[this.cpu.PC]]) {
		this.breakpointHit();
		return false;
	}
	return this.gba.waitFrame();
};

Memory = function(mmu) {
	this.mmu = mmu;
	this.ul = document.getElementById('memoryView');
	row = this.createRow(0);
	this.ul.appendChild(row);
	this.rowHeight = row.offsetHeight;
	this.numberRows = this.ul.parentNode.offsetHeight / this.rowHeight + 2;
	this.ul.removeChild(row);
	this.scrollTop = 50 - this.ul.parentElement.firstElementChild.offsetHeight;

	for (var i = 0; i < this.numberRows; ++i) {
		this.ul.appendChild(this.createRow(i << 4));
	}
	this.ul.parentElement.scrollTop = this.scrollTop;

	var self = this;
	this.ul.parentElement.addEventListener('scroll', function(e) { self.scroll(e) }, true);
	window.addEventListener('resize', function(e) { self.resize() }, true);
}

Memory.prototype.scroll = function(e) {
	while (this.ul.parentElement.scrollTop - this.scrollTop < this.rowHeight) {
		if (this.ul.firstChild.offset == 0) {
			break;
		}
		var victim = this.ul.lastChild;
		this.ul.removeChild(victim);
		victim.offset = this.ul.firstChild.offset - 16;
		this.refresh(victim);
		this.ul.insertBefore(victim, this.ul.firstChild);
		this.ul.parentElement.scrollTop += this.rowHeight;
	}
	while (this.ul.parentElement.scrollTop - this.scrollTop > this.rowHeight * 2) {
		var victim = this.ul.firstChild;
		this.ul.removeChild(victim);
		victim.offset = this.ul.lastChild.offset + 16;
		this.refresh(victim);
		this.ul.appendChild(victim);
		this.ul.parentElement.scrollTop -= this.rowHeight;
	}
	if (this.ul.parentElement.scrollTop < this.scrollTop) {
		this.ul.parentElement.scrollTop = this.scrollTop;
		e.preventDefault();
	}
}

Memory.prototype.resize = function() {
	this.numberRows = this.ul.parentNode.offsetHeight / this.rowHeight + 2;
	if (this.numberRows > this.ul.children.length) {
		var offset = this.ul.lastChild.offset + 16;
		for (var i = 0; i < this.numberRows - this.ul.children.length; ++i) {
			var row = this.createRow(offset);
			this.refresh(row);
			this.ul.appendChild(row);
			offset += 16;
		}
	} else {
		for (var i = 0; i < this.ul.children.length - this.numberRows; ++i) {
			this.ul.removeChild(this.ul.lastChild);
		}
	}
}

Memory.prototype.refresh = function(row) {
	var showChanged;
	var newValue;
	var child;
	row.firstChild.textContent = hex(row.offset);
	if (row.oldOffset == row.offset) {
		showChanged = true;
	} else {
		row.oldOffset = row.offset;
		showChanged = false;
	}
	for (var i = 0; i < 16; ++i) {
		child = row.children[i + 1];
		try {
			newValue = hex(this.mmu.loadU8(row.offset + i), 2, false);
			if (newValue >= 0) {
				if (child.textContent == newValue) {
					child.setAttribute('class', 'memoryCell');
				} else if (showChanged) {
					child.setAttribute('class', 'memoryCell changed');
					child.textContent = newValue;
				} else {
					child.setAttribute('class', 'memoryCell');
					child.textContent = newValue;
				}
			} else {
				child.setAttribute('class', 'memoryCell');
				child.textContent = '--';
			}
		} catch (exception) {
			child.setAttribute('class', 'memoryCell');
			child.textContent = '--';
		}
	}
}

Memory.prototype.refreshAll = function() {
	for (var i = 0; i < this.ul.children.length; ++i) {
		this.refresh(this.ul.children[i]);
	}
}

Memory.prototype.createRow = function(startOffset) {
	var li = document.createElement('li');
	var offset = document.createElement('span');
	offset.setAttribute('class', 'memoryOffset');
	offset.textContent = hex(startOffset);
	li.appendChild(offset);

	for (var i = 0; i < 16; ++i) {
		var b = document.createElement('span');
		b.textContent = '00';
		b.setAttribute('class', 'memoryCell');
		li.appendChild(b);
	}
	li.offset = startOffset;
	li.oldOffset = startOffset;
	return li;
}

Memory.prototype.scrollTo = function(offset) {
	offset &= 0xFFFFFFF0;
	if (offset) {
		for (var i = 0; i < this.ul.children.length; ++i) {
			var child = this.ul.children[i];
			child.offset = offset + (i - 1) * 16;
			this.refresh(child);
		}
		this.ul.parentElement.scrollTop = this.scrollTop + this.rowHeight;
	} else {
		for (var i = 0; i < this.ul.children.length; ++i) {
			var child = this.ul.children[i];
			child.offset = offset + i * 16;
			this.refresh(child);
		}
		this.ul.parentElement.scrollTop = this.scrollTop;
	}
}
<|endoftext|>


<commit_before>var hue = require("node-hue-api"),
    HueApi = hue.HueApi,
    lightState = hue.lightState;

var ip = '192.168.1.148';
var user = '173b7ba927ae37972420dced2e2f10bb'; // worthless outside of the lan
var api = new HueApi(ip, user);

var readline = require('readline');
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.setPrompt('hue> ');
rl.prompt();

var strobe = false;
var dance = null;
rl.on('line', function (line) {
  var parts = line.split(' ');
  var cmd = parts.shift();

  if (strobe) {
    if (cmd == 'q') {
      strobe = false;
        api.setGroupLightState(0, lightState.create().brightness(90));
    } else if (cmd == '') {
      api.setGroupLightState(0, lightState.create().brightness(100).transition(0));
      setTimeout(function () {
        api.setGroupLightState(0, lightState.create().brightness(1).transition(0));
      }, 50);
    }
  }
  if (cmd == 'strobe') {
    strobe = true;
    api.setGroupLightState(0, lightState.create().brightness(1).on());
  }

  if (cmd == 'on') {
    if (parts.length) {
      api.setLightState(parts[0], lightState.create().on().brightness(95));
    } else {
      api.setGroupLightState(0, lightState.create().on().brightness(95));
    }
  }
  if (cmd == 'off') {
    if (parts.length) {
      api.setLightState(parts[0], lightState.create().off());
    } else {
      api.setGroupLightState(0, lightState.create().off());
    }
  }

  if (cmd == 'b') {
    if (parts.length > 1) {
      api.setLightState(parts[1], lightState.create().brightness(+parts[0]));
    } else {
      api.setGroupLightState(0, lightState.create().brightness(+parts[0]));
    }
  }

  if (cmd == 'alert') {
    api.setGroupLightState(0, lightState.create().alert());
  }
  if (cmd == 'ALERT') {
    api.setGroupLightState(0, lightState.create().alert(true)); // 10 times
  }

  if (cmd == 'colorloop') {
    var state1 = lightState.create().on().hsl(0,   100, 95).effect('none');
    var state2 = lightState.create().on().hsl(120, 100, 95).effect('none');
    var state3 = lightState.create().on().hsl(240, 100, 95).effect('none');
    api.setLightState(1, state1).done();
    api.setLightState(2, state2).done();
    api.setLightState(3, state3).done();

    setTimeout(function () {
      api.setGroupLightState(0, lightState.create().effect('colorloop'));
    }, 10);
  }

  if (dance) {
    clearInterval(dance);
    dance = null;
  }
  if (cmd == 'dance') {
    dance = setInterval(function () {
      for (var l = 1; l <= 3; l++) {
        api.setLightState(l, lightState.create().on().transition(0).hsl(Math.round(Math.random() * 360), 100, 95).effect('none'));
      }
    }, 500);
  }

  if (cmd == 'random') {
    for (var l = 1; l <= 3; l++) {
      api.setLightState(l, lightState.create().on().hsl(Math.round(Math.random() * 360), 100, 95).effect('none'));
    }
  }

  rl.prompt();
});

/*
var displayBridges = function(bridge) {
  var bridge = bridge[0];

  var huee = new hue.HueApi();

  var displayUserResult = function(result) {
      console.log("Created user: " + JSON.stringify(result));
  };

  var displayError = function(err) {
      console.log(err);
  };

  huee.registerUser(bridge.ipaddress, null, 'node shenanigans')
    .then(displayUserResult)
    .fail(displayError)
    .done();
};

hue.locateBridges().then(displayBridges).done();
*/
<commit_msg>Add link command<commit_after>var hue = require("node-hue-api"),
    HueApi = hue.HueApi,
    lightState = hue.lightState;

var ip = '192.168.1.148';
var user = 'c0ff1603d31754f4587db05ca753f'; // worthless outside of the lan
var api = new HueApi(ip, user);

var readline = require('readline');
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.setPrompt('hue> ');
rl.prompt();

var strobe = false;
var dance = null;
rl.on('line', function (line) {
  var parts = line.split(' ');
  var cmd = parts.shift();

  if (strobe) {
    if (cmd == 'q') {
      strobe = false;
        api.setGroupLightState(0, lightState.create().brightness(90));
    } else if (cmd == '') {
      api.setGroupLightState(0, lightState.create().brightness(100).transition(0));
      setTimeout(function () {
        api.setGroupLightState(0, lightState.create().brightness(1).transition(0));
      }, 50);
    }
  }
  if (cmd == 'strobe') {
    strobe = true;
    api.setGroupLightState(0, lightState.create().brightness(1).on());
  }

  if (cmd == 'on') {
    if (parts.length) {
      api.setLightState(parts[0], lightState.create().on().brightness(95));
    } else {
      api.setGroupLightState(0, lightState.create().on().brightness(95));
    }
  }
  if (cmd == 'off') {
    if (parts.length) {
      api.setLightState(parts[0], lightState.create().off());
    } else {
      api.setGroupLightState(0, lightState.create().off());
    }
  }

  if (cmd == 'b') {
    if (parts.length > 1) {
      api.setLightState(parts[1], lightState.create().brightness(+parts[0]));
    } else {
      api.setGroupLightState(0, lightState.create().brightness(+parts[0]));
    }
  }

  if (cmd == 'link') {
    console.log(api.pressLinkButton());
  }

  if (cmd == 'alert') {
    api.setGroupLightState(0, lightState.create().alert());
  }
  if (cmd == 'ALERT') {
    api.setGroupLightState(0, lightState.create().alert(true)); // 10 times
  }

  if (cmd == 'colorloop') {
    var state1 = lightState.create().on().hsl(0,   100, 95).effect('none');
    var state2 = lightState.create().on().hsl(120, 100, 95).effect('none');
    var state3 = lightState.create().on().hsl(240, 100, 95).effect('none');
    api.setLightState(1, state1).done();
    api.setLightState(2, state2).done();
    api.setLightState(3, state3).done();

    setTimeout(function () {
      api.setGroupLightState(0, lightState.create().effect('colorloop'));
    }, 10);
  }

  if (dance) {
    clearInterval(dance);
    dance = null;
  }
  if (cmd == 'dance') {
    dance = setInterval(function () {
      for (var l = 1; l <= 3; l++) {
        api.setLightState(l, lightState.create().on().transition(0).hsl(Math.round(Math.random() * 360), 100, 95).effect('none'));
      }
    }, 500);
  }

  if (cmd == 'random') {
    for (var l = 1; l <= 3; l++) {
      api.setLightState(l, lightState.create().hsl(Math.round(Math.random() * 360), 100, 95).transition(0));
    }
  }

  rl.prompt();
});

/*
var displayBridges = function(bridge) {
  var bridge = bridge[0];

  var huee = new hue.HueApi();

  var displayUserResult = function(result) {
      console.log("Created user: " + JSON.stringify(result));
  };

  var displayError = function(err) {
      console.log(err);
  };

  huee.registerUser(bridge.ipaddress, null, 'node shenanigans')
    .then(displayUserResult)
    .fail(displayError)
    .done();
};

hue.locateBridges().then(displayBridges).done();
*/
<|endoftext|>


<commit_before>/*!
 * reveal-code-focus 1.0.0
 * Copyright 2015-2018 Benjamin Tan <https://bnjmnt4n.now.sh/>
 * Available under MIT license <https://github.com/bnjmnt4n/reveal-code-focus/blob/master/LICENSE>
 */
;(function(window, Reveal, hljs) {
  if (typeof window.RevealCodeFocus == 'function') {
    return;
  }

  var currentSlide, currentFragments, scrollToFocused = true, prevSlideData = null;

  // Iterates through `array`, running `callback` for each `array` element.
  function forEach(array, callback) {
    var i = -1, length = array ? array.length : 0;
    while (++i < length) {
      callback(array[i]);
    }
  }

  function indexOf(array, elem) {
    var i = -1, length = array ? array.length : 0;
    while (++i < length) {
      if (array[i] === elem) {
        return i;
      }
    }
  }

  var initialized = false;
  function initialize(e) {
    // Initialize code only once.
    // TODO: figure out why `initialize` is being called twice.
    if (initialized) {
      return;
    }
    initialized = true;

    // TODO: mark as parsed.
    forEach(document.querySelectorAll('pre code'), function(element) {
      // Trim whitespace if the `data-trim` attribute is present.
      if (element.hasAttribute('data-trim') && typeof element.innerHTML.trim == 'function') {
        element.innerHTML = element.innerHTML.trim();
      }

      // Highlight code using highlight.js.
      hljs.highlightBlock(element);

      // Split highlighted code into lines.
      var openTags = [];
      var reHtmlTag = /<(\/?)span(?:\s+(?:class=(['"])hljs-.*?\2)?\s*|\s*)>/g;

      element.innerHTML = element.innerHTML.replace(/(.*?)\r?\n/g, function(_, string) {
        if (!string) {
          return ' ';
        }

        var openTag, stringPrepend;

        // Re-open all tags that were previously closed.
        if (openTags.length) {
          stringPrepend = openTags.join('');
        }

        // Match all HTML `<span>` tags.
        reHtmlTag.lastIndex = 0;
        while (openTag = reHtmlTag.exec(string)) {
          // If it is a closing tag, remove the opening tag from the list.
          if (openTag[1]) {
            openTags.pop();
          }
          // Otherwise if it is an opening tag, push it to the list.
          else {
            openTags.push(openTag[0]);
          }
        }

        // Close all opened tags, so that strings can be wrapped with `span.line`.
        if (openTags.length) {
          string += Array(openTags.length + 1).join('');
        }
        if (stringPrepend) {
          string = stringPrepend + string;
        }

        return '' + string + '';
      });
    });

    Reveal.addEventListener('slidechanged', updateCurrentSlide);

    Reveal.addEventListener('fragmentshown', function(e) {
      focusFragment(e.fragment);
    });

    // TODO: make this configurable.
    // When a fragment is hidden, clear the current focused fragment,
    // and focus on the previous fragment.
    Reveal.addEventListener('fragmenthidden', function(e) {
      var index = indexOf(currentFragments, e.fragment);
      focusFragment(currentFragments[index - 1]);
    });

    updateCurrentSlide(e);
  }

  function updateCurrentSlide(e) {
    currentSlide = e.currentSlide;
    currentFragments = currentSlide.getElementsByClassName('fragment');
    clearPreviousFocus();

    // If moving back to a previous slide…
    if (
      currentFragments.length &&
      prevSlideData &&
      (
        prevSlideData.indexh > e.indexh ||
        (prevSlideData.indexh == e.indexh && prevSlideData.indexv > e.indexv)
      )
    ) {
      // …return to the last fragment and highlight the code.
      while (Reveal.nextFragment()) {}
      var currentFragment = currentFragments[currentFragments.length - 1];
      currentFragment.classList.add('current-fragment');
      focusFragment(currentFragment);
    }

    // Update previous slide information.
    prevSlideData = {
      'indexh': e.indexh,
      'indexv': e.indexv
    };
  }

  // Removes any previously focused lines.
  function clearPreviousFocus() {
    forEach(currentSlide.querySelectorAll('pre code .line.focus'), function(line) {
      line.classList.remove('focus');
    });
  }

  function focusFragment(fragment) {
    clearPreviousFocus();
    if (!fragment) {
      return;
    }

    var lines = fragment.getAttribute('data-code-focus');
    if (!lines) {
      return;
    }

    var codeBlock = parseInt(fragment.getAttribute('data-code-block'));
    if (isNaN(codeBlock)) {
      codeBlock = 1;
    }

    var preElems = currentSlide.querySelectorAll('pre');
    if (!preElems.length) {
      return;
    }

    var pre = preElems[codeBlock - 1];
    var code = pre.querySelectorAll('code .line');
    if (!code.length) {
      return;
    }

    var topLineNumber, bottomLineNumber;

    forEach(lines.split(','), function(line) {
      lines = line.split('-');
      if (lines.length == 1) {
        focusLine(lines[0]);
      } else {
        var i = lines[0] - 1, j = lines[1];

        while (++i <= j) {
          focusLine(i);
        }
      }
    });

    function focusLine(lineNumber) {
      // Convert from 1-based index to 0-based index.
      lineNumber -= 1;

      var line = code[lineNumber];
      if (!line) {
        return;
      }

      line.classList.add('focus');

      if (scrollToFocused) {
        if (topLineNumber == null) {
          topLineNumber = bottomLineNumber = lineNumber;
        } else {
          if (lineNumber < topLineNumber) {
            topLineNumber = lineNumber;
          }
          if (lineNumber > bottomLineNumber) {
            bottomLineNumber = lineNumber;
          }
        }
      }
    }

    if (scrollToFocused && topLineNumber != null) {
      var topLine =  code[topLineNumber];
      var bottomLine = code[bottomLineNumber];
      var codeParent = topLine.parentNode;
      var scrollTop = topLine.offsetTop;
      var scrollBottom = bottomLine.offsetTop + bottomLine.clientHeight;
      codeParent.scrollTop = scrollTop - (codeParent.clientHeight - (scrollBottom - scrollTop)) / 2;
    }
  }

  function RevealCodeFocus(options) {
    if (!options) {
      options = { 'scrollToFocused': true };
    }

    if (options.scrollToFocused != null) {
      scrollToFocused = options.scrollToFocused;
    }

    if (Reveal.isReady()) {
      initialize({ 'currentSlide': Reveal.getCurrentSlide() });
    } else {
      Reveal.addEventListener('ready', initialize);
    }
  }

  window.RevealCodeFocus = RevealCodeFocus;
}(this, this.Reveal, this.hljs));
<commit_msg>Fix focusing last line when using data-trim (#18).<commit_after>/*!
 * reveal-code-focus 1.0.0
 * Copyright 2015-2018 Benjamin Tan <https://bnjmnt4n.now.sh/>
 * Available under MIT license <https://github.com/bnjmnt4n/reveal-code-focus/blob/master/LICENSE>
 */
;(function(window, Reveal, hljs) {
  if (typeof window.RevealCodeFocus == 'function') {
    return;
  }

  var currentSlide, currentFragments, scrollToFocused = true, prevSlideData = null;

  // Iterates through `array`, running `callback` for each `array` element.
  function forEach(array, callback) {
    var i = -1, length = array ? array.length : 0;
    while (++i < length) {
      callback(array[i]);
    }
  }

  function indexOf(array, elem) {
    var i = -1, length = array ? array.length : 0;
    while (++i < length) {
      if (array[i] === elem) {
        return i;
      }
    }
  }

  var initialized = false;
  function initialize(e) {
    // Initialize code only once.
    // TODO: figure out why `initialize` is being called twice.
    if (initialized) {
      return;
    }
    initialized = true;

    // TODO: mark as parsed.
    forEach(document.querySelectorAll('pre code'), function(element) {
      // Trim whitespace if the `data-trim` attribute is present.
      if (element.hasAttribute('data-trim') && typeof element.innerHTML.trim == 'function') {
        element.innerHTML = element.innerHTML.trim() + "\n";
      }

      // Highlight code using highlight.js.
      hljs.highlightBlock(element);

      // Split highlighted code into lines.
      var openTags = [];
      var reHtmlTag = /<(\/?)span(?:\s+(?:class=(['"])hljs-.*?\2)?\s*|\s*)>/g;

      element.innerHTML = element.innerHTML.replace(/(.*?)\r?\n/g, function(_, string) {
        if (!string) {
          return ' ';
        }

        var openTag, stringPrepend;

        // Re-open all tags that were previously closed.
        if (openTags.length) {
          stringPrepend = openTags.join('');
        }

        // Match all HTML `<span>` tags.
        reHtmlTag.lastIndex = 0;
        while (openTag = reHtmlTag.exec(string)) {
          // If it is a closing tag, remove the opening tag from the list.
          if (openTag[1]) {
            openTags.pop();
          }
          // Otherwise if it is an opening tag, push it to the list.
          else {
            openTags.push(openTag[0]);
          }
        }

        // Close all opened tags, so that strings can be wrapped with `span.line`.
        if (openTags.length) {
          string += Array(openTags.length + 1).join('');
        }
        if (stringPrepend) {
          string = stringPrepend + string;
        }

        return '' + string + '';
      });
    });

    Reveal.addEventListener('slidechanged', updateCurrentSlide);

    Reveal.addEventListener('fragmentshown', function(e) {
      focusFragment(e.fragment);
    });

    // TODO: make this configurable.
    // When a fragment is hidden, clear the current focused fragment,
    // and focus on the previous fragment.
    Reveal.addEventListener('fragmenthidden', function(e) {
      var index = indexOf(currentFragments, e.fragment);
      focusFragment(currentFragments[index - 1]);
    });

    updateCurrentSlide(e);
  }

  function updateCurrentSlide(e) {
    currentSlide = e.currentSlide;
    currentFragments = currentSlide.getElementsByClassName('fragment');
    clearPreviousFocus();

    // If moving back to a previous slide…
    if (
      currentFragments.length &&
      prevSlideData &&
      (
        prevSlideData.indexh > e.indexh ||
        (prevSlideData.indexh == e.indexh && prevSlideData.indexv > e.indexv)
      )
    ) {
      // …return to the last fragment and highlight the code.
      while (Reveal.nextFragment()) {}
      var currentFragment = currentFragments[currentFragments.length - 1];
      currentFragment.classList.add('current-fragment');
      focusFragment(currentFragment);
    }

    // Update previous slide information.
    prevSlideData = {
      'indexh': e.indexh,
      'indexv': e.indexv
    };
  }

  // Removes any previously focused lines.
  function clearPreviousFocus() {
    forEach(currentSlide.querySelectorAll('pre code .line.focus'), function(line) {
      line.classList.remove('focus');
    });
  }

  function focusFragment(fragment) {
    clearPreviousFocus();
    if (!fragment) {
      return;
    }

    var lines = fragment.getAttribute('data-code-focus');
    if (!lines) {
      return;
    }

    var codeBlock = parseInt(fragment.getAttribute('data-code-block'));
    if (isNaN(codeBlock)) {
      codeBlock = 1;
    }

    var preElems = currentSlide.querySelectorAll('pre');
    if (!preElems.length) {
      return;
    }

    var pre = preElems[codeBlock - 1];
    var code = pre.querySelectorAll('code .line');
    if (!code.length) {
      return;
    }

    var topLineNumber, bottomLineNumber;

    forEach(lines.split(','), function(line) {
      lines = line.split('-');
      if (lines.length == 1) {
        focusLine(lines[0]);
      } else {
        var i = lines[0] - 1, j = lines[1];

        while (++i <= j) {
          focusLine(i);
        }
      }
    });

    function focusLine(lineNumber) {
      // Convert from 1-based index to 0-based index.
      lineNumber -= 1;

      var line = code[lineNumber];
      if (!line) {
        return;
      }

      line.classList.add('focus');

      if (scrollToFocused) {
        if (topLineNumber == null) {
          topLineNumber = bottomLineNumber = lineNumber;
        } else {
          if (lineNumber < topLineNumber) {
            topLineNumber = lineNumber;
          }
          if (lineNumber > bottomLineNumber) {
            bottomLineNumber = lineNumber;
          }
        }
      }
    }

    if (scrollToFocused && topLineNumber != null) {
      var topLine =  code[topLineNumber];
      var bottomLine = code[bottomLineNumber];
      var codeParent = topLine.parentNode;
      var scrollTop = topLine.offsetTop;
      var scrollBottom = bottomLine.offsetTop + bottomLine.clientHeight;
      codeParent.scrollTop = scrollTop - (codeParent.clientHeight - (scrollBottom - scrollTop)) / 2;
    }
  }

  function RevealCodeFocus(options) {
    if (!options) {
      options = { 'scrollToFocused': true };
    }

    if (options.scrollToFocused != null) {
      scrollToFocused = options.scrollToFocused;
    }

    if (Reveal.isReady()) {
      initialize({ 'currentSlide': Reveal.getCurrentSlide() });
    } else {
      Reveal.addEventListener('ready', initialize);
    }
  }

  window.RevealCodeFocus = RevealCodeFocus;
}(this, this.Reveal, this.hljs));
<|endoftext|>


<commit_before>//bug- extraction functions:  nested extractions
//hide functions hide target without removing el.
//if no tag ID or class, then no output.
//function: hideTags -done
//function: hideIds -done
//function: hideClasses -done
//hide el functions remove the target from the heirarchy
//function: hideElementsByClass - done
//function: hideElementsById - done
//remove el functions remove the el with children
//function: removeElementsByClass -done
//function: removeElementsById -done
//tract el pull target and childrenfrom heirarchy to top level
//function: extractByClass - done
//function: extractById - done
//reduce siblings to single representations
//function reduceSiblings -done
//function: combineSimilarParents -done

//htmlToScss working good for now.  Just need to figure out the react implemenation.

//ToAdd:
//removeSiblingIteratingClasses
//removeClassesPartial - for iterating or random
//remove classes

export default class HtmlToScss {
  constructor() {
    this.newDom = null
    this.output = null
  }

  hideTags(dom, include = [], exclude = [], hideAll = false) {
    let newDom = this.deepCopy(dom)

    newDom.forEach(el => {
      let isInExcludeList = (exclude.indexOf(el.tag) !== -1)
      let isInIncludeList = (include.indexOf(el.tag) !== -1)

      if ((!isInExcludeList && hideAll) || (isInIncludeList && !hideAll)) el.tag = ''

      el.children = this.hideTags(el.children, include, exclude, hideAll)
    })

    return newDom
  }

  //todo fix this hit
  hideIds(dom, include = [], exclude = [], hideAll = false) {
    let newDom = this.deepCopy(dom)

    newDom.forEach(el => {
      el.ids = el.ids.filter(id => {
        let isInExcludeList = (exclude.indexOf(id) !== -1)
        let isInIncludeList = (include.indexOf(id) !== -1)
        return !((hideAll && isInExcludeList) || (!hideAll && isInIncludeList))
      })

      el.children = this.hideIds(el.children, include, exclude, hideAll)
    })
    return newDom
  }

  //todo fix this hit
  hideClasses(dom, include = [], exclude = [], hideAll = false) {
    let newDom = this.deepCopy(dom)

    newDom.forEach(el => {
      el.classes = el.classes.filter(theClass => {
        let isInExcludeList = (exclude.indexOf(theClass) !== -1)
        let isInIncludeList = (include.indexOf(theClass) !== -1)
        return !((hideAll && isInExcludeList) || (!hideAll && isInIncludeList))
      })

      el.children = this.hideClasses(el.children, include, exclude, hideAll)
    })

    return newDom
  }

  hideElementsByClass(dom, hideList = []) {
    let newDom = this.deepCopy(dom)

    newDom.forEach(el => {
      el.classes.forEach(theClass => {
        let isInHideList = (hideList.indexOf(theClass) !== -1)
        if (isInHideList) el = this.emptyElementValues(el)
      })
      el.children = this.hideElementsByClass(el.children, hideList)
    })

    return newDom
  }

  hideElementsById(dom, hideList = []) {
    let newDom = this.deepCopy(dom)

    newDom.forEach(el => {
      el.ids.forEach(id => {
        let isInHideList = (hideList.indexOf(id) !== -1)
        if (isInHideList) el = this.emptyElementValues(el)
      })
      el.children = this.hideElementsById(el.children, hideList)
    })

    return newDom
  }

  removeElementsByClass(dom, removeList = []) {
    let newDom = this.deepCopy(dom)

    newDom = newDom.filter((el) => {
      let keep = el.classes.every((theClass) => {
        let isNotInRemoveList = !(removeList.indexOf(theClass) !== -1)
        return isNotInRemoveList
      })

      return keep
    })
    newDom.forEach((el, index) => {
      el.children = this.removeElementsByClass(el.children, removeList)

    })
    return newDom
  }

  removeElementsById(dom, removeList = []) {
    let newDom = this.deepCopy(dom)
    let remove = false
    newDom = newDom.filter((el) => {

      let keep = el.ids.every((id) => {
        let isNotInRemoveList = !(removeList.indexOf(id) !== -1)
        return isNotInRemoveList
      })

      return keep
    })

    newDom.forEach((el, index) => {
      el.children = this.removeElementsById(el.children, removeList)

    })
    return newDom
  }

  extractByClass(dom, extractList = []) {
    let newDom = this.deepCopy(dom)
    let domLength = newDom.length - 1
    let extracted = []

    function extract(dom, extractList) {
      let extracted = []
      dom.forEach((el) => {
        el.classes.forEach(theClass => {
          if (extractList.indexOf(theClass) !== -1) {
            extracted.push(el)
          }
        })
        extracted = extracted.concat(extract(el.children, extractList))
      })
      return extracted;
    }

    extracted = extracted.concat(extract(newDom, extractList))

    newDom = this.removeElementsByClass(newDom, extractList)
    newDom = newDom.concat(extracted)
    newDom.forEach((el, index) => {
      if (index > domLength) {
        el.children = this.removeElementsByClass(el.children, extractList)
      }
    })
    return newDom
  }
  // addButtonStates(){

  // }
  // addClassStates(){

  // }

  // compressDepth(){

  // }

  extractById(dom, extractList = []) {
    let newDom = this.deepCopy(dom)
    let domLength = newDom.length - 1
    let extracted = []

    function extract(dom, extractList) {
      let extracted = []
      dom.forEach((el) => {
        el.ids.forEach(id => {
          if (extractList.indexOf(id) !== -1) {
            extracted.push(el)
          }
        })
        extracted = extracted.concat(extract(el.children, extractList))
      })
      return extracted;
    }

    extracted = extracted.concat(extract(newDom, extractList))
    newDom = this.removeElementsById(newDom, extractList)
    newDom = newDom.concat(extracted)
    newDom.forEach((el, index) => {
      if (index > domLength) {
        el.children = this.removeElementsById(el.children, extractList)
      }
    })
    return newDom
  }

  reduceSiblings(dom) {
    let newDom = this.deepCopy(dom)
    let removeIndexes = []
    if (newDom.length > 1) {
      newDom = newDom.filter((el, index, arr) => {
        let filter = true
        for (var i = index; i < arr.length; i++) {
          if (i + 1 !== arr.length && this.compareElements(el, arr[i + 1])) {
            filter = false
          }
        }
        return filter
      })
    }
    newDom.forEach(el => {
      el.children = this.reduceSiblings(el.children)
    })

    return newDom
  }

  combineSimilarParents(dom) {
    let newDom = this.deepCopy(dom)
    if (newDom.length > 1) {
      newDom = newDom.filter((el, index, arr) => {
        let filter = true
        for (var i = index; i < arr.length; i++) {
          if (i + 1 !== arr.length && this.compareElementsWithoutChildren(el, arr[i + 1])) {
            arr[i + 1].children = arr[i + 1].children.concat(el.children)
            filter = false
          }
        }
        return filter
      })
    }
    newDom.forEach(el => {
      el.children = this.combineSimilarParents(el.children)
    })

    return newDom

  }

  convertBEM(dom, parentString) {

    let newDom = this.deepCopy(dom)

    newDom = newDom.map((el) => this.convertBEMRecursive(el))

    return newDom
  }

  convertBEMRecursive(parent) {

    parent.children = parent.children.map((el) => this.convertBEMRecursive(el))

    let bemParentClassIndex = -1
    parent.children.forEach((child) => {
      let isBemChild = false
      let bemClassIndex = -1
      child.classes = child.classes.map((childClass, childClassIndex) => {
        let childClassOutput = childClass
        parent.classes.forEach((parentClass, index) => {
          if (childClassOutput.indexOf(parentClass + '__') !== -1) {
            isBemChild = true
            childClassOutput = childClassOutput.replace(parentClass + '__', '&__')
            bemParentClassIndex = index
            bemClassIndex = childClassIndex
          }
        })
        return childClassOutput
      })

      if (isBemChild) {
        child.tag = ''
        if (bemClassIndex > 0) {
          let bemClass = child.classes[bemClassIndex]
          let newClasses = []
          child.classes = child.classes.slice(bemClassIndex, bemClassIndex)

          newClasses.push(bemClass)
          // newClasses.concat(child.classes)
          child.classes = newClasses
        }

      }
    })
    //move bem parent to end of array
    if (bemParentClassIndex > 0) {
      let bemParent = parent.classes[bemParentClassIndex]
      parent.classes = parent.classes.slice(bemParentClassIndex, bemParentClassIndex)
      parent.classes.push(bemParent)
    }

    return parent
  }

  compareElements(el1, el2) {

    if (JSON.stringify(el1) === JSON.stringify(el2)) {
      return true;
    } else {
      return false
    }
  }
  compareElementsWithoutChildren(el1, el2) {

    let tagsMatch = (el1.tag === el2.tag)
    let idsMatch = (JSON.stringify(el1.ids) === JSON.stringify(el2.ids))
    let classesMatch = (JSON.stringify(el1.classes) === JSON.stringify(el2.classes))
    if (tagsMatch && idsMatch && classesMatch) {
      return true;
    } else {
      return false
    }

  }

  emptyElementValues(el) {
    let newElement = this.deepCopy(el)
    newElement.tag = ''
    newElement.ids = []
    newElement.classes = []
    return newElement
  }

  toArray(obj) {
    var array = [];
    // iterate backwards ensuring that length is an UInt32
    for (var i = obj.length >>> 0; i--;) {
      array[i] = obj[i];
    }
    return array;
  }

  deepCopy(obj) {
    return JSON.parse(JSON.stringify(obj))
  }

  extractHtml(inputHtml) {
    let parsedHtml = (typeof inputHtml === 'string') ? $.parseHTML(inputHtml) : inputHtml
    let nodes = []
    $.each(parsedHtml, (i, el) => {
      if (el.nodeName !== '#text') {

        let ids = (el.id === "") ? [] : el.id.split(' ')
        nodes.push({
          tag: el.nodeName.toLowerCase(),
          classes: this.toArray(el.classList),
          ids: ids,
          children: this.extractHtml(el.children)
        })
      }
    });
    return nodes
  }

  convertToScss(DOMObject, nest = 1) {
    let sass = ""
    let spacing = '  '.repeat(nest)
    $.each(DOMObject, (i, el) => {
      let classesDotted = el.classes.map((theclass) => {
        if (theclass.indexOf('&') === -1) {
          theclass = '.' + theclass

        }

        return theclass
      })
      let classes = (classesDotted.length > 0) ? classesDotted.join('') : ''
      let ids = (el.ids.length) ? '#' + el.ids.join('#') : ''
      let tag = el.tag
      if (classes !== '' || ids !== '' || tag !== '') {
        sass = sass.concat(`
${spacing}${el.tag}${ids}${classes} {
${spacing}  ${this.convertToScss(el.children, nest + 1)}
${spacing}}`)
      } else {
        sass = sass.concat(`${spacing}  ${this.convertToScss(el.children, nest)}`)
      }

    })
    return sass
  }
}<commit_msg>moved options and conversion run into the convert class<commit_after>//bug- extraction functions:  nested extractions
//hide functions hide target without removing el.
//if no tag ID or class, then no output.
//function: hideTags -done
//function: hideIds -done
//function: hideClasses -done
//hide el functions remove the target from the heirarchy
//function: hideElementsByClass - done
//function: hideElementsById - done
//remove el functions remove the el with children
//function: removeElementsByClass -done
//function: removeElementsById -done
//tract el pull target and childrenfrom heirarchy to top level
//function: extractByClass - done
//function: extractById - done
//reduce siblings to single representations
//function reduceSiblings -done
//function: combineSimilarParents -done

//htmlToScss working good for now.  Just need to figure out the react implemenation.

//ToAdd:
//removeSiblingIteratingClasses
//removeClassesPartial - for iterating or random
//remove classes

export default class HtmlToScss {
  constructor(optionsInput) {
    let options = this.deepCopy(optionsInput)
    this.options = {
      hideTagsInclude: this.setDefault(options.hideTagsInclude, ['div']),
      hideTagsExclude: this.setDefault(options.hideTagsExclude, []),
      hideTagsAll: this.setDefault(options.hideTagsAll, false),
      hideIdsInclude: this.setDefault(options.hideIdsInclude, []),
      hideIdsExclude: this.setDefault(options.hideIdsExclude, []),
      hideIdsAll: this.setDefault(options.hideIdsAll, false),
      hideClassesInclude: this.setDefault(options.hideClassesInclude, []),
      hideClassesExclude: this.setDefault(options.hideClassesExclude, []),
      hideClassesAll: this.setDefault(options.hideClassesAll, false),
      hideElementsById: this.setDefault(options.hideElementsById, []),
      hideElementsByClass: this.setDefault(options.hideElementsByClass, []),
      removeElementsById: this.setDefault(options.removeElementsById, []),
      removeElementsByClass: this.setDefault(options.removeElementsByClass, []),
      extractElementsById: this.setDefault(options.extractElementsById, []),
      extractElementsByClass: this.setDefault(options.extractElementsByClass, []),
      reduceSiblings: this.setDefault(options.reduceSiblings, true),
      combineParents: this.setDefault(options.combineParents, true),
      convertBEM: this.setDefault(options.convertBEM, true),
    }
    this.newDom = null
    this.output = null
  }

  convert(dom) {
    let html = this.deepCopy(dom)
    let extractedHtml = this.extractHtml(html)
    let tagsHidden = this.hideTags(extractedHtml, this.options.hideTagsInclude, this.options.hideTagsExclude, this.options.hideTagsAll)
    let idsHidden = this.hideIds(tagsHidden, this.options.hideIdsInclude, this.options.hideIdsExclude, this.options.hideIdsAll)
    let hiddenByClass = this.hideElementsByClass(idsHidden, this.options.hideElementsByClass)
    let classesHidden = this.hideClasses(hiddenByClass, this.options.hideClassesInclude, this.options.hideClassesExclude, this.options.hideClassesAll)
    let hiddenById = this.hideElementsById(classesHidden, this.options.hideElementsById)
    let removedByClass = this.removeElementsByClass(hiddenById, this.options.removeElementsByClass)
    let removedById = this.removeElementsById(removedByClass, this.options.removeElementsById)
    let extracted = this.extractByClass(removedById, this.options.extractElementsByClass)
    let extractedById = this.extractById(extracted, this.options.extractElementsById)
    let reduced = (this.options.reduceSiblings) ? this.reduceSiblings(extractedById) : extractedById
    let combinedParents = (this.options.combineParents) ? this.combineSimilarParents(reduced) : reduced
    let BEMConverted = (this.options.convertBEM) ? this.convertBEM(combinedParents) : combinedParents
    let scss = this.convertToScss(BEMConverted)

    return scss
  }

  changeOptions(newOptionsInput) {
    let newOptions = this.deepCopy(newOptionsInput)
    let optionKeys = Object.keys(newOptions)
    optionKeys.forEach(optionKey => {
      this.options[optionKey] = newOptions[optionKey]
    })
  }
  hideTags(dom, include = [], exclude = [], hideAll = false) {
    let newDom = this.deepCopy(dom)

    newDom.forEach(el => {
      let isInExcludeList = (exclude.indexOf(el.tag) !== -1)
      let isInIncludeList = (include.indexOf(el.tag) !== -1)

      if ((!isInExcludeList && hideAll) || (isInIncludeList && !hideAll)) el.tag = ''

      el.children = this.hideTags(el.children, include, exclude, hideAll)
    })

    return newDom
  }

  //todo fix this hit
  hideIds(dom, include = [], exclude = [], hideAll = false) {
    let newDom = this.deepCopy(dom)

    newDom.forEach(el => {
      el.ids = el.ids.filter(id => {
        let isInExcludeList = (exclude.indexOf(id) !== -1)
        let isInIncludeList = (include.indexOf(id) !== -1)
        return !((hideAll && isInExcludeList) || (!hideAll && isInIncludeList))
      })

      el.children = this.hideIds(el.children, include, exclude, hideAll)
    })
    return newDom
  }

  //todo fix this hit
  hideClasses(dom, include = [], exclude = [], hideAll = false) {
    let newDom = this.deepCopy(dom)

    newDom.forEach(el => {
      el.classes = el.classes.filter(theClass => {
        let isInExcludeList = (exclude.indexOf(theClass) !== -1)
        let isInIncludeList = (include.indexOf(theClass) !== -1)
        return !((hideAll && isInExcludeList) || (!hideAll && isInIncludeList))
      })

      el.children = this.hideClasses(el.children, include, exclude, hideAll)
    })

    return newDom
  }

  hideElementsByClass(dom, hideList = []) {
    let newDom = this.deepCopy(dom)

    newDom.forEach(el => {
      el.classes.forEach(theClass => {
        let isInHideList = (hideList.indexOf(theClass) !== -1)
        if (isInHideList) el = this.emptyElementValues(el)
      })
      el.children = this.hideElementsByClass(el.children, hideList)
    })

    return newDom
  }

  hideElementsById(dom, hideList = []) {
    let newDom = this.deepCopy(dom)

    newDom.forEach(el => {
      el.ids.forEach(id => {
        let isInHideList = (hideList.indexOf(id) !== -1)
        if (isInHideList) el = this.emptyElementValues(el)
      })
      el.children = this.hideElementsById(el.children, hideList)
    })

    return newDom
  }

  removeElementsByClass(dom, removeList = []) {
    let newDom = this.deepCopy(dom)

    newDom = newDom.filter((el) => {
      let keep = el.classes.every((theClass) => {
        let isNotInRemoveList = !(removeList.indexOf(theClass) !== -1)
        return isNotInRemoveList
      })

      return keep
    })
    newDom.forEach((el, index) => {
      el.children = this.removeElementsByClass(el.children, removeList)

    })
    return newDom
  }

  removeElementsById(dom, removeList = []) {
    let newDom = this.deepCopy(dom)
    let remove = false
    newDom = newDom.filter((el) => {

      let keep = el.ids.every((id) => {
        let isNotInRemoveList = !(removeList.indexOf(id) !== -1)
        return isNotInRemoveList
      })

      return keep
    })

    newDom.forEach((el, index) => {
      el.children = this.removeElementsById(el.children, removeList)

    })
    return newDom
  }

  extractByClass(dom, extractList = []) {
    let newDom = this.deepCopy(dom)
    let domLength = newDom.length - 1
    let extracted = []

    function extract(dom, extractList) {
      let extracted = []
      dom.forEach((el) => {
        el.classes.forEach(theClass => {
          if (extractList.indexOf(theClass) !== -1) {
            extracted.push(el)
          }
        })
        extracted = extracted.concat(extract(el.children, extractList))
      })
      return extracted
    }

    extracted = extracted.concat(extract(newDom, extractList))

    newDom = this.removeElementsByClass(newDom, extractList)
    newDom = newDom.concat(extracted)
    newDom.forEach((el, index) => {
      if (index > domLength) {
        el.children = this.removeElementsByClass(el.children, extractList)
      }
    })
    return newDom
  }
  // addButtonStates(){

  // }
  // addClassStates(){

  // }

  // compressDepth(){

  // }

  extractById(dom, extractList = []) {
    let newDom = this.deepCopy(dom)
    let domLength = newDom.length - 1
    let extracted = []

    function extract(dom, extractList) {
      let extracted = []
      dom.forEach((el) => {
        el.ids.forEach(id => {
          if (extractList.indexOf(id) !== -1) {
            extracted.push(el)
          }
        })
        extracted = extracted.concat(extract(el.children, extractList))
      })
      return extracted
    }

    extracted = extracted.concat(extract(newDom, extractList))
    newDom = this.removeElementsById(newDom, extractList)
    newDom = newDom.concat(extracted)
    newDom.forEach((el, index) => {
      if (index > domLength) {
        el.children = this.removeElementsById(el.children, extractList)
      }
    })
    return newDom
  }

  reduceSiblings(dom) {
    let newDom = this.deepCopy(dom)
    let removeIndexes = []
    if (newDom.length > 1) {
      newDom = newDom.filter((el, index, arr) => {
        let filter = true
        for (var i = index i < arr.length i++) {
          if (i + 1 !== arr.length && this.compareElements(el, arr[i + 1])) {
            filter = false
          }
        }
        return filter
      })
    }
    newDom.forEach(el => {
      el.children = this.reduceSiblings(el.children)
    })

    return newDom
  }

  combineSimilarParents(dom) {
    let newDom = this.deepCopy(dom)
    if (newDom.length > 1) {
      newDom = newDom.filter((el, index, arr) => {
        let filter = true
        for (var i = index i < arr.length i++) {
          if (i + 1 !== arr.length && this.compareElementsWithoutChildren(el, arr[i + 1])) {
            arr[i + 1].children = arr[i + 1].children.concat(el.children)
            filter = false
          }
        }
        return filter
      })
    }
    newDom.forEach(el => {
      el.children = this.combineSimilarParents(el.children)
    })

    return newDom

  }

  convertBEM(dom, parentString) {

    let newDom = this.deepCopy(dom)

    newDom = newDom.map((el) => this.convertBEMRecursive(el))

    return newDom
  }

  convertBEMRecursive(parent) {

    parent.children = parent.children.map((el) => this.convertBEMRecursive(el))

    let bemParentClassIndex = -1
    parent.children.forEach((child) => {
      let isBemChild = false
      let bemClassIndex = -1
      child.classes = child.classes.map((childClass, childClassIndex) => {
        let childClassOutput = childClass
        parent.classes.forEach((parentClass, index) => {
          if (childClassOutput.indexOf(parentClass + '__') !== -1) {
            isBemChild = true
            childClassOutput = childClassOutput.replace(parentClass + '__', '&__')
            bemParentClassIndex = index
            bemClassIndex = childClassIndex
          }
        })
        return childClassOutput
      })

      if (isBemChild) {
        child.tag = ''
        if (bemClassIndex > 0) {
          let bemClass = child.classes[bemClassIndex]
          let newClasses = []
          child.classes = child.classes.slice(bemClassIndex, bemClassIndex)

          newClasses.push(bemClass)
          // newClasses.concat(child.classes)
          child.classes = newClasses
        }

      }
    })
    //move bem parent to end of array
    if (bemParentClassIndex > 0) {
      let bemParent = parent.classes[bemParentClassIndex]
      parent.classes = parent.classes.slice(bemParentClassIndex, bemParentClassIndex)
      parent.classes.push(bemParent)
    }

    return parent
  }

  compareElements(el1, el2) {

    if (JSON.stringify(el1) === JSON.stringify(el2)) {
      return true
    } else {
      return false
    }
  }
  compareElementsWithoutChildren(el1, el2) {

    let tagsMatch = (el1.tag === el2.tag)
    let idsMatch = (JSON.stringify(el1.ids) === JSON.stringify(el2.ids))
    let classesMatch = (JSON.stringify(el1.classes) === JSON.stringify(el2.classes))
    if (tagsMatch && idsMatch && classesMatch) {
      return true
    } else {
      return false
    }

  }

  emptyElementValues(el) {
    let newElement = this.deepCopy(el)
    newElement.tag = ''
    newElement.ids = []
    newElement.classes = []
    return newElement
  }

  toArray(obj) {
    var array = []
    // iterate backwards ensuring that length is an UInt32
    for (var i = obj.length >>> 0 i--) {
      array[i] = obj[i]
    }
    return array
  }

  deepCopy(obj) {
    return JSON.parse(JSON.stringify(obj))
  }

  setDefault(source, defaultVal) {
    return (typeof source !== 'undefined') ? source : defaultVal
  }

  extractHtml(inputHtml) {
    let parsedHtml = (typeof inputHtml === 'string') ? $.parseHTML(inputHtml) : inputHtml
    let nodes = []
    $.each(parsedHtml, (i, el) => {
      if (el.nodeName !== '#text') {

        let ids = (el.id === "") ? [] : el.id.split(' ')
        nodes.push({
          tag: el.nodeName.toLowerCase(),
          classes: this.toArray(el.classList),
          ids: ids,
          children: this.extractHtml(el.children)
        })
      }
    })
    return nodes
  }

  convertToScss(DOMObject, nest = 1) {
    let sass = ""
    let spacing = '  '.repeat(nest)
    $.each(DOMObject, (i, el) => {
      let classesDotted = el.classes.map((theclass) => {
        if (theclass.indexOf('&') === -1) {
          theclass = '.' + theclass

        }

        return theclass
      })
      let classes = (classesDotted.length > 0) ? classesDotted.join('') : ''
      let ids = (el.ids.length) ? '#' + el.ids.join('#') : ''
      let tag = el.tag
      if (classes !== '' || ids !== '' || tag !== '') {
        sass = sass.concat(`
${spacing}${el.tag}${ids}${classes} {
${spacing}  ${this.convertToScss(el.children, nest + 1)}
${spacing}}`)
      } else {
        sass = sass.concat(`${spacing}  ${this.convertToScss(el.children, nest)}`)
      }

    })
    return sass
  }
}<|endoftext|>


<commit_before>// __Dependencies__
var deco = require('deco');

// __Module Definition__
var middleware = module.exports = deco(__dirname, [
  'deprecated',
  'allowHeader',
  'acceptHeader',
  'checkMethodSupported',
  'validateId',
  'setConditions'
]);
<commit_msg>Activate streams decorator.<commit_after>// __Dependencies__
var deco = require('deco');

// __Module Definition__
var middleware = module.exports = deco(__dirname, [
  'deprecated',
  'allowHeader',
  'acceptHeader',
  'checkMethodSupported',
  'validateId',
  'setConditions',
  'streams'
]);
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

import PropTypes from "prop-types";
import ReactAudioPlayer from 'react-audio-player';
import axios from "axios";

class AvailableDatalist extends React.Component {
  render() {
    console.log("props during render songs")
    console.log(this.props)
    var ret = []
    if(this.props.songs[0] != 0){
      ret = this.props.songs.map(c =>

{c.songName[0]}

{c.album}

{c.author}

{c.date}

      )
    }else{
      ret[0] = "test"
    }
    console.log("ret nach bearbeitung")
    console.log(ret)
    return(
{ret}
)
  }
}

AvailableDatalist.propTypes = {
  songs: PropTypes.array.isRequired
};

class SongBoard extends React.Component {
state = {
  songs: [0:{name:"none", album:"none", author:"none"}]
};

componentDidMount() {
  axios
  .get("http://192.168.1.107:8000/album/")
  .then(response => {
    const songs = response.data.map(c => {

      return{
        songName: c.songs.map(d => {return(d.name)}),
        album: c.name,
        author: c.author,
        date: c.release_date
      };
    });

    const newState = Object.assign({}, this.state, {
          songs: songs
    });
    this.setState(newState);
    console.log("state after api request")
    console.log(this.state)

  })
  .catch(error => console.log(error));

}

  render() {

    return(

            <button className="song">
              Song
            </button>
            <button className="album">
              Album
            </button>

          <AvailableDatalist songs={this.state.songs}/> {/*songs={this.state.contacts}*/}

    )
  }
}

class Player extends React.Component {
  render() {
    return(
      <ReactAudioPlayer
        src="my_audio_file.ogg"
        autoPlay
        controls
      />
    )
  }
}

class Site extends React.Component {
  render() {
    return (

          <Player />

          <SongBoard />

    )
  }
}

ReactDOM.render(
  <Site />,
  document.getElementById('root')
);
<commit_msg>songs<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

import PropTypes from "prop-types";
import ReactAudioPlayer from 'react-audio-player';
import axios from "axios";

class AvailableDatalist extends React.Component {
  render() {
    console.log("props during render songs")
    console.log(this.props)
    var ret = []
    if(this.props.songs[0] != 0){
      ret = this.props.songs.map(c =>

{c.songName[0]}

{c.album}

{c.author}

{c.date}

      )
    }else{
      ret[0] = "test"
    }
    console.log("ret nach bearbeitung")
    console.log(ret)
    return(
{ret}
)
  }
}

AvailableDatalist.propTypes = {
  songs: PropTypes.array.isRequired
};

class SongBoard extends React.Component {
state = {
  songs: [0:{name:"none", album:"none", author:"none"}]
};

componentDidMount() {
  axios
  .get("http://192.168.1.107:8000/album/")
  .then(response => {
    const songs = response.data.map(c => {

      return{
        songName: c.songs.map(d => {return(d.name)}),
        album: c.name,
        author: c.author,
        date: c.release_date
      };
    });

    const newState = Object.assign({}, this.state, {
          songs: songs
    });
    this.setState(newState);
    console.log("state after api request")
    console.log(this.state)

  })
  .catch(error => console.log(error));

}

  render() {

    return(

            <button className="song">
              Song
            </button>
            <button className="album">
              Album
            </button>

          <AvailableDatalist songs={this.state.songs}/> {/*songs={this.state.contacts}*/}

    )
  }
}

class Player extends React.Component {
  render() {
    return(
      <ReactAudioPlayer
        src="my_audio_file.ogg"
        autoPlay
        controls
      />
    )
  }
}

class Site extends React.Component {
  render() {
    return (

          <Player />

          <SongBoard />

    )
  }
}

ReactDOM.render(
  <Site />,
  document.getElementById('root')
);
<|endoftext|>


<commit_before>var config          = require('./config.js').loadConfig('./config.json');
var http            = require('./http.js').createServer(config.get('http'));
var auth            = require('./auth.js').createAuth(config.get('app'));
var api             = require('./api.js');

var MongoClient = require('mongodb').MongoClient;
MongoClient.connect(config.get('mongodb'), function(err, mongo) {
    if(err) throw err;
    db = mongo;
});

api.loadDict(config.get('dict_dir'));
http.on('callback', auth.callback);
auth.on('config', config.set);
console.log(auth.authorize_url);

var since_id = 0;
var new_since_id = 0;
//var interval = 1000 * 3600 / 150;
var crawler = config.get('crawler');
var interval = crawler.interval;
var count = crawler.count;

function timeline (param) {
    api.status('home_timeline', config.get('auth'), param, function (err, wbs) {
        if(err) {
            console.log(wbs);
            throw err;
        }

        var collection = db.collection('status');
        var cnt = 0;

        wbs.statuses.forEach(function ( weibo, index ) {
            if (weibo.id > since_id ) {
                cnt++;
                collection.insert(weibo, function (err, docs) {
                    if(err) throw err;
                });
            }
        });

        console.log('-------------------------------' + cnt);
        if(since_id == 0) {
            since_id = wbs.since_id; //如果是第一次取，只取一次
            setTimeout(timeline, interval, {'since_id': wbs.since_id, 'count': count}); //本次读结束
            console.log('第一次取，只取一次');
        } else if (since_id < wbs.max_id) { //上次取完成的点为 since_id，
            //setTimeout(timeline, interval, {'max_id': wbs.max_id, 'count': count});
            setTimeout(timeline, 1000, {'max_id': wbs.max_id, 'count': count});
            console.log('上次取完的点为' + since_id);
            console.log('这次取到的点为' + wbs.max_id);
        } else {
            since_id = new_since_id; //取到了上次结束的点
            setTimeout(timeline, interval, {'since_id': wbs.since_id, 'count': count}); //本次读结束
            console.log('全部取完');
        }

        if(wbs.since_id > new_since_id) new_since_id = wbs.since_id;
    });
}

timeline({'count':count});
<commit_msg>weibo.js: db is not defined<commit_after>var config          = require('./config.js').loadConfig('./config.json');
var http            = require('./http.js').createServer(config.get('http'));
var auth            = require('./auth.js').createAuth(config.get('app'));
var api             = require('./api.js');

api.loadDict(config.get('dict_dir'));
http.on('callback', auth.callback);
auth.on('config', config.set);
console.log(auth.authorize_url);

var MongoClient = require('mongodb').MongoClient;
MongoClient.connect(config.get('mongodb'), function(err, mongo) {
    if(err) throw err;
    var db = mongo;

    var since_id = 0;
    var new_since_id = 0;
    //var interval = 1000 * 3600 / 150;
    var crawler = config.get('crawler');
    var interval = crawler.interval;
    var count = crawler.count;

    function timeline (param) {
        api.status('home_timeline', config.get('auth'), param, function (err, wbs) {
            if(err) {
                console.log(wbs);
                throw err;
            }

            var collection = db.collection('status');
            var cnt = 0;

            wbs.statuses.forEach(function ( weibo, index ) {
                if (weibo.id > since_id ) {
                    cnt++;
                    collection.insert(weibo, function (err, docs) {
                        if(err) throw err;
                    });
                }
            });

            console.log('-------------------------------' + cnt);
            if(since_id == 0) {
                since_id = wbs.since_id; //如果是第一次取，只取一次
                setTimeout(timeline, interval, {'since_id': wbs.since_id, 'count': count}); //本次读结束
                console.log('第一次取，只取一次');
            } else if (since_id < wbs.max_id) { //上次取完成的点为 since_id，
                //setTimeout(timeline, interval, {'max_id': wbs.max_id, 'count': count});
                setTimeout(timeline, 1000, {'max_id': wbs.max_id, 'count': count});
                console.log('上次取完的点为' + since_id);
                console.log('这次取到的点为' + wbs.max_id);
            } else {
                since_id = new_since_id; //取到了上次结束的点
                setTimeout(timeline, interval, {'since_id': wbs.since_id, 'count': count}); //本次读结束
                console.log('全部取完');
            }

            if(wbs.since_id > new_since_id) new_since_id = wbs.since_id;
        });
    }

    timeline({'count':count});
});
<|endoftext|>


<commit_before>module.exports = {
    run: function(creep) {
            if (creep.memory.working == true && creep.carry.energy == 0) {
            creep.memory.working = false;
        }
        else if (creep.memory.working == false && creep.carry.energy == creep.carryCapacity) {
            creep.memory.working = true;
        }

        if (creep.memory.working == true) {
            var structure = creep.pos.findClosestByPath(FIND_STRUCTURES, {
              filter: (s) => (s.structureType == STRUCTURE_LINK
                            || s.structureType == STRUCTURE_CONTAINER
                            || s.structureType == STRUCTURE_TOWER
                            || s.structureType == STRUCTURE_SPAWN
                            || s.structureType == STRUCTURE_EXTENSION
                            && s.energy < s.energyCapacity
            });
            if (structure != undefined) {
                if (creep.transfer(structure, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(structure);
                }
            }
        }
        else {
            var source = Game.getObjectById('576a9bd757110ab231d880c8');
            if (creep.harvest(source) == ERR_NOT_IN_RANGE) {
                creep.moveTo(source);
            }
        }
    }
};

// var source =
// creep.memory.sourceId = source.id;
<commit_msg>Removed bracket<commit_after>module.exports = {
    run: function(creep) {
            if (creep.memory.working == true && creep.carry.energy == 0) {
            creep.memory.working = false;
        }
        else if (creep.memory.working == false && creep.carry.energy == creep.carryCapacity) {
            creep.memory.working = true;
        }

        if (creep.memory.working == true) {
            var structure = creep.pos.findClosestByPath(FIND_STRUCTURES, {
              filter: (s) => (s.structureType == STRUCTURE_LINK
                            || s.structureType == STRUCTURE_CONTAINER
                            || s.structureType == STRUCTURE_TOWER
                            || s.structureType == STRUCTURE_SPAWN
                            || s.structureType == STRUCTURE_EXTENSION
                            && s.energy < s.energyCapacity
            );
            if (structure != undefined) {
                if (creep.transfer(structure, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(structure);
                }
            }
        }
        else {
            var source = Game.getObjectById('576a9bd757110ab231d880c8');
            if (creep.harvest(source) == ERR_NOT_IN_RANGE) {
                creep.moveTo(source);
            }
        }
    }
};

// var source =
// creep.memory.sourceId = source.id;
<|endoftext|>


<commit_before>Package.describe({
  summary: "Password support for accounts",
  // Note: 2.2.0-beta.3 was published during the Meteor 1.6 prerelease
  // process, so it might be best to skip to 2.3.x instead of reusing
  // 2.2.x in the future. The version was also bumped to 2.0.0 temporarily
  // during the Meteor 1.5.1 release process, so versions 2.0.0-beta.2
  // through -beta.5 and -rc.0 have already been published.
  version: "1.5.2"
});

Package.onUse(api => {
  api.versionsFrom("1.8.1");
  api.use('npm-bcrypt', 'server');

  api.use([
    'accounts-base',
    'srp',
    'sha',
    'ejson',
    'ddp'
  ], ['client', 'server']);

  // Export Accounts (etc) to packages using this one.
  api.imply('accounts-base', ['client', 'server']);

  api.use('email', 'server');
  api.use('random', 'server');
  api.use('check', 'server');
  api.use('ecmascript');

  api.addFiles('email_templates.js', 'server');
  api.addFiles('password_server.js', 'server');
  api.addFiles('password_client.js', 'client');
});

Package.onTest(api => {
  api.use(['accounts-password', 'tinytest', 'test-helpers', 'tracker',
           'accounts-base', 'random', 'email', 'check', 'ddp', 'ecmascript']);
  api.addFiles('password_tests_setup.js', 'server');
  api.addFiles('password_tests.js', ['client', 'server']);
  api.addFiles('email_tests_setup.js', 'server');
  api.addFiles('email_tests.js', 'client');
});
<commit_msg>Revert "Update accounts-password to version 1.5.2. - api versions from 1.8.1"<commit_after>Package.describe({
  summary: "Password support for accounts",
  // Note: 2.2.0-beta.3 was published during the Meteor 1.6 prerelease
  // process, so it might be best to skip to 2.3.x instead of reusing
  // 2.2.x in the future. The version was also bumped to 2.0.0 temporarily
  // during the Meteor 1.5.1 release process, so versions 2.0.0-beta.2
  // through -beta.5 and -rc.0 have already been published.
  version: "1.5.2"
});

Package.onUse(api => {
  api.use('npm-bcrypt', 'server');

  api.use([
    'accounts-base',
    'srp',
    'sha',
    'ejson',
    'ddp'
  ], ['client', 'server']);

  // Export Accounts (etc) to packages using this one.
  api.imply('accounts-base', ['client', 'server']);

  api.use('email', 'server');
  api.use('random', 'server');
  api.use('check', 'server');
  api.use('ecmascript');

  api.addFiles('email_templates.js', 'server');
  api.addFiles('password_server.js', 'server');
  api.addFiles('password_client.js', 'client');
});

Package.onTest(api => {
  api.use(['accounts-password', 'tinytest', 'test-helpers', 'tracker',
           'accounts-base', 'random', 'email', 'check', 'ddp', 'ecmascript']);
  api.addFiles('password_tests_setup.js', 'server');
  api.addFiles('password_tests.js', ['client', 'server']);
  api.addFiles('email_tests_setup.js', 'server');
  api.addFiles('email_tests.js', 'client');
});
<|endoftext|>


<commit_before>// var tasks = require('tasks');
var utils = require('utils');

module.exports = {
	run : function(creep){
		var mineral = creep.room.find(FIND_MINERALS)[0];
        var myContainer = mineral.pos.findInRange(FIND_STRUCTURES,1,{filter: (s) => s.structureType == STRUCTURE_CONTAINER})[0];
		if(!utils.isPosEqual(creep.pos,myContainer.pos)){
            creep.moveTo(myContainer);
        }
        else{
            creep.harvest(mineral);
        }
		if(mineral.mineralAmount == 0){
			creep.memory.role = 'recycler';
		}
	}
}
<commit_msg>stability fix to mineralMiner<commit_after>// var tasks = require('tasks');
var utils = require('utils');

module.exports = {
	run : function(creep){
		var mineral = creep.room.find(FIND_MINERALS)[0];
        var myContainer = mineral.pos.findInRange(FIND_STRUCTURES,1,{filter: (s) => s.structureType == STRUCTURE_CONTAINER})[0];
		if(myContainer && !utils.isPosEqual(creep.pos,myContainer.pos)){
            creep.moveTo(myContainer);
        }
        else{
            creep.harvest(mineral);
        }
		if(mineral.mineralAmount == 0){
			creep.memory.role = 'recycler';
		}
	}
}
<|endoftext|>


<commit_before>// @flow

import React, { Component } from 'react';
import Cropper from 'react-cropper';
import 'cropperjs/dist/cropper.css';
import fetch from 'isomorphic-fetch';
import { imageApiUrl } from '../config';
import { getTokenFromLocalCookie } from '../lib/fetch';

type Props = {
  imageUrl?: string
};

type State = {
  ratio: number,
  imageApiBody?: any,
  existingParameters?: any,
  postResult?: string
};

class Crop extends Component<Props, State> {
  state = { ratio: 0.81, imageApiBody: null, existingParameters: null };

  toPercentages = c => {
    var data = c.getData();
    return {
      cropStartX: Math.max(
        0,
        Math.round((data.x / c.getImageData().naturalWidth) * 100)
      ),
      cropEndX: Math.min(
        100,
        Math.round(
          ((data.x + data.width) / c.getImageData().naturalWidth) * 100
        )
      ),
      cropStartY: Math.max(
        0,
        Math.round((data.y / c.getImageData().naturalHeight) * 100)
      ),

      cropEndY: Math.min(
        100,
        Math.round(
          ((data.y + data.height) / c.getImageData().naturalHeight) * 100
        )
      )
    };
  };

  toImageApiBody = pcnt => {
    const existingParametersForCurrentRatio =
      this.state.existingParameters &&
      this.state.existingParameters.find(
        p => p.forRatio === String(this.state.ratio)
      );
    const revision =
      (existingParametersForCurrentRatio &&
        existingParametersForCurrentRatio.revision) ||
      1;

    return {
      forRatio: String(this.state.ratio),
      revision: revision,
      imageUrl:
        this.props.imageUrl &&
        this.props.imageUrl.substr(this.props.imageUrl.lastIndexOf('/')),
      rawImageQueryParameters: {
        cropStartX: pcnt.cropStartX,
        cropEndX: pcnt.cropEndX,
        cropStartY: pcnt.cropStartY,
        cropEndY: pcnt.cropEndY
      }
    };
  };

  crop = () => {
    var pcnt = this.toPercentages(this.refs.cropper);
    this.setState({ imageApiBody: this.toImageApiBody(pcnt) });
  };

  postToImageApi = async () => {
    if (this.state.imageApiBody !== null) {
      this.setState({ postResult: 'Posting…' });
      const response = await fetch(`${imageApiUrl}/images/stored-parameters`, {
        method: 'POST',
        headers: {
          Authorization: 'Bearer ' + getTokenFromLocalCookie(),
          Accept: 'application/json'
        },
        body: JSON.stringify(this.state.imageApiBody)
      });

      if (response.ok) {
        this.setState({ postResult: 'Ok!' });
      } else if (response.status === 401) {
        this.setState({ postResult: 'Unauthorized, please login' });
      } else {
        this.setState({ postResult: `Unknown error: ${response.status}` });
      }
      await this.getExistingParameters();
    }
  };

  getExistingParameters = async () => {
    const imageUrl =
      this.props.imageUrl &&
      this.props.imageUrl.substr(this.props.imageUrl.lastIndexOf('/'));
    const url =
      imageUrl && `${imageApiUrl}/images/stored-parameters${imageUrl}`;
    const response = await fetch(url);
    if (response.status === 200) {
      this.setState({ existingParameters: await response.json() });
    } else {
      this.setState({ existingParameters: null });
    }
  };

  toggleRatio = e => {
    e.preventDefault();
    if (this.state.ratio === 0.81) {
      this.setState({ ratio: 2.63 });
    } else {
      this.setState({ ratio: 0.81 });
    }
    this.getExistingParameters();
    this.refs.cropper.replace(this.props.imageUrl);
  };

  componentDidMount() {
    this.getExistingParameters();
  }

  displayPostResult() {
    if (this.state.postResult !== null) {
      return
{this.state.postResult}
;
    } else {
      return null;
    }
  }

  existingParametersToCropData = ps => {
    const p = ps && ps.find(x => x.forRatio === String(this.state.ratio));
    const imageWidth = this.refs.cropper.getImageData().naturalWidth;
    const imageHeight = this.refs.cropper.getImageData().naturalHeight;
    if (p && p.rawImageQueryParameters) {
      const r = p.rawImageQueryParameters;
      return {
        x: imageWidth * (r.cropStartX / 100),
        y: imageHeight * (r.cropStartY / 100),
        width: imageWidth * ((r.cropEndX - r.cropStartX) / 100),
        height: imageHeight * ((r.cropEndY - r.cropStartY) / 100)
      };
    }
  };

  onReady = () => {
    const data = this.existingParametersToCropData(
      this.state.existingParameters
    );
    if (data !== null) {
      this.refs.cropper.setData(data);
    }
  };

  render() {
    return (

          <button onClick={this.toggleRatio}>Toggle ratio</button>

        <Cropper
          ref="cropper"
          src={this.props.imageUrl}
          aspectRatio={this.state.ratio}
          guides={false}
          viewMode={2}
          zoomable={false}
          dragMode={'move'}
          preview={'.preview'}
          crop={this.crop}
          ready={this.onReady}
        />

        <button onClick={this.postToImageApi}>
          Save this crop config for ratio={this.state.ratio}
        </button>
        {this.displayPostResult()}

    );
  }
}

const CropPage = ({ imageUrl }: { imageUrl?: string }) => (

Crop

    {imageUrl == null ? (

        You need to specify <tt>imageUrl</tt> in the URL

    ) : (
      <Crop imageUrl={imageUrl} />
    )}

);

CropPage.getInitialProps = context => {
  const imageUrl = context.query.imageUrl;

  return {
    imageUrl
  };
};

export default CropPage;
<commit_msg>#368: s/var/const GlobalDigitalLibraryio/issues#367<commit_after>// @flow

import React, { Component } from 'react';
import Cropper from 'react-cropper';
import 'cropperjs/dist/cropper.css';
import fetch from 'isomorphic-fetch';
import { imageApiUrl } from '../config';
import { getTokenFromLocalCookie } from '../lib/fetch';

type Props = {
  imageUrl?: string
};

type State = {
  ratio: number,
  imageApiBody?: any,
  existingParameters?: any,
  postResult?: string
};

class Crop extends Component<Props, State> {
  state = { ratio: 0.81, imageApiBody: null, existingParameters: null };

  toPercentages = c => {
    const data = c.getData();
    return {
      cropStartX: Math.max(
        0,
        Math.round((data.x / c.getImageData().naturalWidth) * 100)
      ),
      cropEndX: Math.min(
        100,
        Math.round(
          ((data.x + data.width) / c.getImageData().naturalWidth) * 100
        )
      ),
      cropStartY: Math.max(
        0,
        Math.round((data.y / c.getImageData().naturalHeight) * 100)
      ),

      cropEndY: Math.min(
        100,
        Math.round(
          ((data.y + data.height) / c.getImageData().naturalHeight) * 100
        )
      )
    };
  };

  toImageApiBody = pcnt => {
    const existingParametersForCurrentRatio =
      this.state.existingParameters &&
      this.state.existingParameters.find(
        p => p.forRatio === String(this.state.ratio)
      );
    const revision =
      (existingParametersForCurrentRatio &&
        existingParametersForCurrentRatio.revision) ||
      1;

    return {
      forRatio: String(this.state.ratio),
      revision: revision,
      imageUrl:
        this.props.imageUrl &&
        this.props.imageUrl.substr(this.props.imageUrl.lastIndexOf('/')),
      rawImageQueryParameters: {
        cropStartX: pcnt.cropStartX,
        cropEndX: pcnt.cropEndX,
        cropStartY: pcnt.cropStartY,
        cropEndY: pcnt.cropEndY
      }
    };
  };

  crop = () => {
    const pcnt = this.toPercentages(this.refs.cropper);
    this.setState({ imageApiBody: this.toImageApiBody(pcnt) });
  };

  postToImageApi = async () => {
    if (this.state.imageApiBody !== null) {
      this.setState({ postResult: 'Posting…' });
      const response = await fetch(`${imageApiUrl}/images/stored-parameters`, {
        method: 'POST',
        headers: {
          Authorization: 'Bearer ' + getTokenFromLocalCookie(),
          Accept: 'application/json'
        },
        body: JSON.stringify(this.state.imageApiBody)
      });

      if (response.ok) {
        this.setState({ postResult: 'Ok!' });
      } else if (response.status === 401) {
        this.setState({ postResult: 'Unauthorized, please login' });
      } else {
        this.setState({ postResult: `Unknown error: ${response.status}` });
      }
      await this.getExistingParameters();
    }
  };

  getExistingParameters = async () => {
    const imageUrl =
      this.props.imageUrl &&
      this.props.imageUrl.substr(this.props.imageUrl.lastIndexOf('/'));
    const url =
      imageUrl && `${imageApiUrl}/images/stored-parameters${imageUrl}`;
    const response = await fetch(url);
    if (response.status === 200) {
      this.setState({ existingParameters: await response.json() });
    } else {
      this.setState({ existingParameters: null });
    }
  };

  toggleRatio = e => {
    e.preventDefault();
    if (this.state.ratio === 0.81) {
      this.setState({ ratio: 2.63 });
    } else {
      this.setState({ ratio: 0.81 });
    }
    this.getExistingParameters();
    this.refs.cropper.replace(this.props.imageUrl);
  };

  componentDidMount() {
    this.getExistingParameters();
  }

  displayPostResult() {
    if (this.state.postResult !== null) {
      return
{this.state.postResult}
;
    } else {
      return null;
    }
  }

  existingParametersToCropData = ps => {
    const p = ps && ps.find(x => x.forRatio === String(this.state.ratio));
    const imageWidth = this.refs.cropper.getImageData().naturalWidth;
    const imageHeight = this.refs.cropper.getImageData().naturalHeight;
    if (p && p.rawImageQueryParameters) {
      const r = p.rawImageQueryParameters;
      return {
        x: imageWidth * (r.cropStartX / 100),
        y: imageHeight * (r.cropStartY / 100),
        width: imageWidth * ((r.cropEndX - r.cropStartX) / 100),
        height: imageHeight * ((r.cropEndY - r.cropStartY) / 100)
      };
    }
  };

  onReady = () => {
    const data = this.existingParametersToCropData(
      this.state.existingParameters
    );
    if (data !== null) {
      this.refs.cropper.setData(data);
    }
  };

  render() {
    return (

          <button onClick={this.toggleRatio}>Toggle ratio</button>

        <Cropper
          ref="cropper"
          src={this.props.imageUrl}
          aspectRatio={this.state.ratio}
          guides={false}
          viewMode={2}
          zoomable={false}
          dragMode={'move'}
          preview={'.preview'}
          crop={this.crop}
          ready={this.onReady}
        />

        <button onClick={this.postToImageApi}>
          Save this crop config for ratio={this.state.ratio}
        </button>
        {this.displayPostResult()}

    );
  }
}

const CropPage = ({ imageUrl }: { imageUrl?: string }) => (

Crop

    {imageUrl == null ? (

        You need to specify <tt>imageUrl</tt> in the URL

    ) : (
      <Crop imageUrl={imageUrl} />
    )}

);

CropPage.getInitialProps = context => {
  const imageUrl = context.query.imageUrl;

  return {
    imageUrl
  };
};

export default CropPage;
<|endoftext|>


<commit_before>import * as Kind from './kindNames';
import {RGB, CMYK, GREY} from './model/model';

const kinds = {};

kinds[Kind.BINARY] = {
    components: 1,
    alpha: 0,
    bitDepth: 1,
    colorModel: GREY
};

kinds[Kind.GREYA] = {
    components: 1,
    alpha: 1,
    bitDepth: 8,
    colorModel: GREY
};

kinds[Kind.GREY] = {
    components: 1,
    alpha: 0,
    bitDepth: 8,
    colorModel: GREY
};

kinds[Kind.RGBA] = {
    components: 3,
    alpha: 1,
    bitDepth: 8,
    colorModel: RGB
};

kinds[Kind.RGB] = {
    components: 3,
    alpha: 0,
    bitDepth: 8,
    colorModel: RGB
};

kinds[Kind.CMYK] = {
    components: 4,
    alpha: 0,
    bitDepth: 8,
    colorModel: CMYK
};

kinds[Kind.CMYKA] = {
    components: 4,
    alpha: 1,
    bitDepth: 8,
    colorModel: CMYK
};

export function getKind(kind) {
    return kinds[kind];
}

export function computeKind(image) {
    outer: for (const kind in kinds) {
        const kindData = kinds[kind];
        for (const prop in kindData) {
            if (image[prop] !== kindData[prop]) {
                continue outer;
            }
        }
        return kind;
    }
    return 'UNKNOWN';
}

export function getTheoreticalPixelArraySize(image) {
    let length = image.channels * image.size;
    if (image.bitDepth === 1) {
        length = Math.ceil(length / 8);
    }
    return length;
}

export function createPixelArray(image) {
    let length = image.channels * image.size;
    let arr;
    switch (image.bitDepth) {
        case 1:
            arr = new Uint8Array(Math.ceil(length / 8));
            break;
        case 8:
            arr = new Uint8ClampedArray(length);
            break;
        case 16:
            arr = new Uint16Array(length);
            break;
        case 32:
            arr = new Float32Array(length);
            break;
        default:
            throw new Error('Cannot create pixel array for bit depth ' + image.bitDepth);
    }

    // alpha channel is 100% by default
    if (image.alpha) {
        for (let i = image.components; i < arr.length; i += image.channels) {
            arr[i] = image.maxValue;
        }
    }

    return arr;
}
<commit_msg>fix computeKind for 16 bit images<commit_after>import * as Kind from './kindNames';
import {RGB, CMYK, GREY} from './model/model';

const kinds = {};

kinds[Kind.BINARY] = {
    components: 1,
    alpha: 0,
    bitDepth: 1,
    colorModel: GREY
};

kinds[Kind.GREYA] = {
    components: 1,
    alpha: 1,
    bitDepth: 8,
    colorModel: GREY
};

kinds[Kind.GREY] = {
    components: 1,
    alpha: 0,
    bitDepth: 8,
    colorModel: GREY
};

kinds[Kind.RGBA] = {
    components: 3,
    alpha: 1,
    bitDepth: 8,
    colorModel: RGB
};

kinds[Kind.RGB] = {
    components: 3,
    alpha: 0,
    bitDepth: 8,
    colorModel: RGB
};

kinds[Kind.CMYK] = {
    components: 4,
    alpha: 0,
    bitDepth: 8,
    colorModel: CMYK
};

kinds[Kind.CMYKA] = {
    components: 4,
    alpha: 1,
    bitDepth: 8,
    colorModel: CMYK
};

export function getKind(kind) {
    return kinds[kind];
}

export function computeKind(image) {
    outer: for (const kind in kinds) {
        const kindData = kinds[kind];
        for (const prop in kindData) {
            if (prop === 'bitDepth') continue;
            if (image[prop] !== kindData[prop]) {
                continue outer;
            }
        }
        return kind;
    }
    return 'UNKNOWN';
}

export function getTheoreticalPixelArraySize(image) {
    let length = image.channels * image.size;
    if (image.bitDepth === 1) {
        length = Math.ceil(length / 8);
    }
    return length;
}

export function createPixelArray(image) {
    let length = image.channels * image.size;
    let arr;
    switch (image.bitDepth) {
        case 1:
            arr = new Uint8Array(Math.ceil(length / 8));
            break;
        case 8:
            arr = new Uint8ClampedArray(length);
            break;
        case 16:
            arr = new Uint16Array(length);
            break;
        case 32:
            arr = new Float32Array(length);
            break;
        default:
            throw new Error('Cannot create pixel array for bit depth ' + image.bitDepth);
    }

    // alpha channel is 100% by default
    if (image.alpha) {
        for (let i = image.components; i < arr.length; i += image.channels) {
            arr[i] = image.maxValue;
        }
    }

    return arr;
}
<|endoftext|>