function Encoder() { this.data = ''; this.stack = 0; this.size = 0; } Encoder.prototype.push = function(one) { if(this.size > 7) { this.flush(); } this.stack = 2*this.stack + (one ? 1 : 0); this.size++; }; Encoder.prototype.flush = function() { this.data = this.data + String.fromCharCode(this.stack); this.stack = 0; this.size = 0; }; Encoder.prototype.output = function() { while(this.size < 8) { this.push(0); } this.flush(); return btoa(this.data); }; Encoder.prototype.variableLength3 = function(n) { if(n > 0) { this.push(1); } this.push(n > 1); }; Encoder.prototype.variableLength6 = function(n) { if(n > 1) { this.push(1); } this.push(n > 3); this.push(n % 2); }; Encoder.prototype.int = function(size) { var encoder = this; return function(n) { for(var i = 0; i < size; i++) { encoder.push(n > 3); n = (2*n) & 7; } } }; return { make: function() {return new Encoder();} };