function Decoder(input) { this.input = atob(input); this.cache = 0; this.size = 0; } Decoder.prototype.pop = function() { if(this.size < 1) { if(this.input.length < 1) { return null; } else { this.cache = this.input.charCodeAt(0); this.size = 8; this.input = this.input.slice(1); } } this.size--; var wasFirstBitOne = this.cache > 0x7f; this.cache = (2*this.cache) & 0xff; return wasFirstBitOne ? 1 : 0; }; Decoder.prototype.variableLength3 = function() { if(this.pop() == 1) { return this.pop() + 1; } else { return 0; } }; Decoder.prototype.variableLength6 = function() { if(this.pop() == 1) { return 2 + this.int(2); } else { return this.pop(); } }; Decoder.prototype.int = function(size) { var result = 0; for(var i = 0; i < size; i++) { result = 2*result + this.pop(); } return result; }; return { make: function(input) {return new Decoder(input);} };