text: module.exports.BitBuffer = (function(){ "use strict";
  
  var BitBuffer = function(bufferOrLength, mode) {
  	if (typeof(bufferOrLength) === 'object') {
  		this.bytes = (bufferOrLength instanceof Uint8Array)
  			? bufferOrLength 
  			: new Uint8Array(bufferOrLength);
  
  		this.byteLength = this.bytes.length;
  	}
  	else {
  		this.bytes = new Uint8Array(bufferOrLength || 1024*1024);	
  		this.byteLength = 0;
  	}
  
  	this.mode = mode || BitBuffer.MODE.EXPAND;
  	this.index = 0;
  };
  
  BitBuffer.prototype.resize = function(size) {
  	var newBytes = new Uint8Array(size);
  	if (this.byteLength !== 0) {
  		this.byteLength = Math.min(this.byteLength, size);
  		newBytes.set(this.bytes, 0, this.byteLength);
  	}
  	this.bytes = newBytes;
  	this.index = Math.min(this.index, this.byteLength << 3);
  };
  
  BitBuffer.prototype.evict = function(sizeNeeded) {
  	var bytePos = this.index >> 3,
  		available = this.bytes.length - this.byteLength;
  	
  	// If the current index is the write position, we can simply reset both
  	// to 0. Also reset (and throw away yet unread data) if we won't be able
  	// to fit the new data in even after a normal eviction.
  	if (
  		this.index === this.byteLength << 3 ||
  		sizeNeeded > available + bytePos // emergency evac
  	) {
  		this.byteLength = 0;
  		this.index = 0;
  		return;
  	}
  	else if (bytePos === 0) {
  		// Nothing read yet - we can't evict anything
  		return;
  	}
  	
  	// Some browsers don't support copyWithin() yet - we may have to do 
  	// it manually using set and a subarray
  	if (this.bytes.copyWithin) {
  		this.bytes.copyWithin(0, bytePos, this.byteLength);
  	}
  	else {
  		this.bytes.set(this.bytes.subarray(bytePos, this.byteLength));
  	}
  
  	this.byteLength = this.byteLength - bytePos;
  	this.index -= bytePos << 3;
  	return;
  };
  
  BitBuffer.prototype.write = function(buffers) {
  	var isArrayOfBuffers = (typeof(buffers[0]) === 'object'),
  		totalLength = 0,
  		available = this.bytes.length - this.byteLength;
  
  	// Calculate total byte length
  	if (isArrayOfBuffers) {
  		var totalLength = 0;
  		for (var i = 0; i < buffers.length; i++) {
  			totalLength += buffers[i].byteLength;
  		}
  	}
  	else {
  		totalLength = buffers.byteLength;
  	}
  
  	// Do we need to resize or evict?
  	if (totalLength > available) {
  		if (this.mode === BitBuffer.MODE.EXPAND) {
  			var newSize = Math.max(
  				this.bytes.length * 2,
  				totalLength - available
  			);
  			this.resize(newSize)
  		}
  		else {
  			this.evict(totalLength);
  		}
  	}
  
  	if (isArrayOfBuffers) {
  		for (var i = 0; i < buffers.length; i++) {
  			this.appendSingleBuffer(buffers[i]);
  		}
  	}
  	else {
  		this.appendSingleBuffer(buffers);
  	}
  
  	return totalLength;
  };
  
  BitBuffer.prototype.appendSingleBuffer = function(buffer) {
  	buffer = buffer instanceof Uint8Array
  		? buffer 
  		: new Uint8Array(buffer);
  	
  	this.bytes.set(buffer, this.byteLength);
  	this.byteLength += buffer.length;
  };
  
  BitBuffer.prototype.findNextStartCode = function() {	
  	for (var i = (this.index+7 >> 3); i < this.byteLength; i++) {
  		if(
  			this.bytes[i] == 0x00 &&
  			this.bytes[i+1] == 0x00 &&
  			this.bytes[i+2] == 0x01
  		) {
  			this.index = (i+4) << 3;
  			return this.bytes[i+3];
  		}
  	}
  	this.index = (this.byteLength << 3);
  	return -1;
  };
  
  BitBuffer.prototype.findStartCode = function(code) {
  	var current = 0;
  	while (true) {
  		current = this.findNextStartCode();
  		if (current === code || current === -1) {
  			return current;
  		}
  	}
  	return -1;
  };
  
  BitBuffer.prototype.nextBytesAreStartCode = function() {
  	var i = (this.index+7 >> 3);
  	return (
  		i >= this.byteLength || (
  			this.bytes[i] == 0x00 && 
  			this.bytes[i+1] == 0x00 &&
  			this.bytes[i+2] == 0x01
  		)
  	);
  };
  
  BitBuffer.prototype.peek = function(count) {
  	var offset = this.index;
  	var value = 0;
  	while (count) {
  		var currentByte = this.bytes[offset >> 3],
  			remaining = 8 - (offset & 7), // remaining bits in byte
  			read = remaining < count ? remaining : count, // bits in this run
  			shift = remaining - read,
  			mask = (0xff >> (8-read));
  
  		value = (value << read) | ((currentByte & (mask << shift)) >> shift);
  
  		offset += read;
  		count -= read;
  	}
  
  	return value;
  }
  
  BitBuffer.prototype.read = function(count) {
  	var value = this.peek(count);
  	this.index += count;
  	return value;
  };
  
  BitBuffer.prototype.skip = function(count) {
  	return (this.index += count);
  };
  
  BitBuffer.prototype.rewind = function(count) {
  	this.index = Math.max(this.index - count, 0);
  };
  
  BitBuffer.prototype.has = function(count) {
  	return ((this.byteLength << 3) - this.index) >= count;
  };
  
  BitBuffer.MODE = {
  	EVICT: 1,
  	EXPAND: 2
  };
  
  return BitBuffer;
  
  })();
  
  
  