// Generated by IcedCoffeeScript 1.7.1-f
(function() {
  var FF, GG, Global, HH, Hasher, II, MD5, WordArray, glbl,
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  WordArray = require('./wordarray').WordArray;

  Hasher = require('./algbase').Hasher;

  Global = (function() {
    function Global() {
      var i;
      this.T = (function() {
        var _i, _results;
        _results = [];
        for (i = _i = 0; _i < 64; i = ++_i) {
          _results.push((Math.abs(Math.sin(i + 1)) * 0x100000000) | 0);
        }
        return _results;
      })();
    }

    return Global;

  })();

  glbl = new Global();

  exports.MD5 = MD5 = (function(_super) {
    __extends(MD5, _super);

    function MD5() {
      return MD5.__super__.constructor.apply(this, arguments);
    }

    MD5.blockSize = 512 / 32;

    MD5.prototype.blockSize = MD5.blockSize;

    MD5.output_size = 16;

    MD5.prototype.output_size = MD5.output_size;

    MD5.prototype._doReset = function() {
      return this._hash = new WordArray([0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]);
    };

    MD5.prototype._doProcessBlock = function(M, offset) {
      var H, M_offset_0, M_offset_1, M_offset_10, M_offset_11, M_offset_12, M_offset_13, M_offset_14, M_offset_15, M_offset_2, M_offset_3, M_offset_4, M_offset_5, M_offset_6, M_offset_7, M_offset_8, M_offset_9, M_offset_i, a, b, c, d, i, offset_i, _i;
      for (i = _i = 0; _i < 16; i = ++_i) {
        offset_i = offset + i;
        M_offset_i = M[offset_i];
        M[offset_i] = (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00);
      }
      H = this._hash.words;
      M_offset_0 = M[offset + 0];
      M_offset_1 = M[offset + 1];
      M_offset_2 = M[offset + 2];
      M_offset_3 = M[offset + 3];
      M_offset_4 = M[offset + 4];
      M_offset_5 = M[offset + 5];
      M_offset_6 = M[offset + 6];
      M_offset_7 = M[offset + 7];
      M_offset_8 = M[offset + 8];
      M_offset_9 = M[offset + 9];
      M_offset_10 = M[offset + 10];
      M_offset_11 = M[offset + 11];
      M_offset_12 = M[offset + 12];
      M_offset_13 = M[offset + 13];
      M_offset_14 = M[offset + 14];
      M_offset_15 = M[offset + 15];
      a = H[0];
      b = H[1];
      c = H[2];
      d = H[3];
      a = FF(a, b, c, d, M_offset_0, 7, glbl.T[0]);
      d = FF(d, a, b, c, M_offset_1, 12, glbl.T[1]);
      c = FF(c, d, a, b, M_offset_2, 17, glbl.T[2]);
      b = FF(b, c, d, a, M_offset_3, 22, glbl.T[3]);
      a = FF(a, b, c, d, M_offset_4, 7, glbl.T[4]);
      d = FF(d, a, b, c, M_offset_5, 12, glbl.T[5]);
      c = FF(c, d, a, b, M_offset_6, 17, glbl.T[6]);
      b = FF(b, c, d, a, M_offset_7, 22, glbl.T[7]);
      a = FF(a, b, c, d, M_offset_8, 7, glbl.T[8]);
      d = FF(d, a, b, c, M_offset_9, 12, glbl.T[9]);
      c = FF(c, d, a, b, M_offset_10, 17, glbl.T[10]);
      b = FF(b, c, d, a, M_offset_11, 22, glbl.T[11]);
      a = FF(a, b, c, d, M_offset_12, 7, glbl.T[12]);
      d = FF(d, a, b, c, M_offset_13, 12, glbl.T[13]);
      c = FF(c, d, a, b, M_offset_14, 17, glbl.T[14]);
      b = FF(b, c, d, a, M_offset_15, 22, glbl.T[15]);
      a = GG(a, b, c, d, M_offset_1, 5, glbl.T[16]);
      d = GG(d, a, b, c, M_offset_6, 9, glbl.T[17]);
      c = GG(c, d, a, b, M_offset_11, 14, glbl.T[18]);
      b = GG(b, c, d, a, M_offset_0, 20, glbl.T[19]);
      a = GG(a, b, c, d, M_offset_5, 5, glbl.T[20]);
      d = GG(d, a, b, c, M_offset_10, 9, glbl.T[21]);
      c = GG(c, d, a, b, M_offset_15, 14, glbl.T[22]);
      b = GG(b, c, d, a, M_offset_4, 20, glbl.T[23]);
      a = GG(a, b, c, d, M_offset_9, 5, glbl.T[24]);
      d = GG(d, a, b, c, M_offset_14, 9, glbl.T[25]);
      c = GG(c, d, a, b, M_offset_3, 14, glbl.T[26]);
      b = GG(b, c, d, a, M_offset_8, 20, glbl.T[27]);
      a = GG(a, b, c, d, M_offset_13, 5, glbl.T[28]);
      d = GG(d, a, b, c, M_offset_2, 9, glbl.T[29]);
      c = GG(c, d, a, b, M_offset_7, 14, glbl.T[30]);
      b = GG(b, c, d, a, M_offset_12, 20, glbl.T[31]);
      a = HH(a, b, c, d, M_offset_5, 4, glbl.T[32]);
      d = HH(d, a, b, c, M_offset_8, 11, glbl.T[33]);
      c = HH(c, d, a, b, M_offset_11, 16, glbl.T[34]);
      b = HH(b, c, d, a, M_offset_14, 23, glbl.T[35]);
      a = HH(a, b, c, d, M_offset_1, 4, glbl.T[36]);
      d = HH(d, a, b, c, M_offset_4, 11, glbl.T[37]);
      c = HH(c, d, a, b, M_offset_7, 16, glbl.T[38]);
      b = HH(b, c, d, a, M_offset_10, 23, glbl.T[39]);
      a = HH(a, b, c, d, M_offset_13, 4, glbl.T[40]);
      d = HH(d, a, b, c, M_offset_0, 11, glbl.T[41]);
      c = HH(c, d, a, b, M_offset_3, 16, glbl.T[42]);
      b = HH(b, c, d, a, M_offset_6, 23, glbl.T[43]);
      a = HH(a, b, c, d, M_offset_9, 4, glbl.T[44]);
      d = HH(d, a, b, c, M_offset_12, 11, glbl.T[45]);
      c = HH(c, d, a, b, M_offset_15, 16, glbl.T[46]);
      b = HH(b, c, d, a, M_offset_2, 23, glbl.T[47]);
      a = II(a, b, c, d, M_offset_0, 6, glbl.T[48]);
      d = II(d, a, b, c, M_offset_7, 10, glbl.T[49]);
      c = II(c, d, a, b, M_offset_14, 15, glbl.T[50]);
      b = II(b, c, d, a, M_offset_5, 21, glbl.T[51]);
      a = II(a, b, c, d, M_offset_12, 6, glbl.T[52]);
      d = II(d, a, b, c, M_offset_3, 10, glbl.T[53]);
      c = II(c, d, a, b, M_offset_10, 15, glbl.T[54]);
      b = II(b, c, d, a, M_offset_1, 21, glbl.T[55]);
      a = II(a, b, c, d, M_offset_8, 6, glbl.T[56]);
      d = II(d, a, b, c, M_offset_15, 10, glbl.T[57]);
      c = II(c, d, a, b, M_offset_6, 15, glbl.T[58]);
      b = II(b, c, d, a, M_offset_13, 21, glbl.T[59]);
      a = II(a, b, c, d, M_offset_4, 6, glbl.T[60]);
      d = II(d, a, b, c, M_offset_11, 10, glbl.T[61]);
      c = II(c, d, a, b, M_offset_2, 15, glbl.T[62]);
      b = II(b, c, d, a, M_offset_9, 21, glbl.T[63]);
      H[0] = (H[0] + a) | 0;
      H[1] = (H[1] + b) | 0;
      H[2] = (H[2] + c) | 0;
      return H[3] = (H[3] + d) | 0;
    };

    MD5.prototype._doFinalize = function() {
      var H, H_i, data, dataWords, hash, i, nBitsLeft, nBitsTotal, nBitsTotalH, nBitsTotalL, _i;
      data = this._data;
      dataWords = data.words;
      nBitsTotal = this._nDataBytes * 8;
      nBitsLeft = data.sigBytes * 8;
      dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
      nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
      nBitsTotalL = nBitsTotal;
      dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (((nBitsTotalH << 8) | (nBitsTotalH >>> 24)) & 0x00ff00ff) | (((nBitsTotalH << 24) | (nBitsTotalH >>> 8)) & 0xff00ff00);
      dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (((nBitsTotalL << 8) | (nBitsTotalL >>> 24)) & 0x00ff00ff) | (((nBitsTotalL << 24) | (nBitsTotalL >>> 8)) & 0xff00ff00);
      data.sigBytes = (dataWords.length + 1) * 4;
      this._process();
      hash = this._hash;
      H = hash.words;
      for (i = _i = 0; _i < 4; i = ++_i) {
        H_i = H[i];
        H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00);
      }
      return hash;
    };

    MD5.prototype.copy_to = function(obj) {
      MD5.__super__.copy_to.call(this, obj);
      return obj._hash = this._hash.clone();
    };

    MD5.prototype.clone = function() {
      var out;
      out = new MD5();
      this.copy_to(out);
      return out;
    };

    return MD5;

  })(Hasher);

  FF = function(a, b, c, d, x, s, t) {
    var n;
    n = a + ((b & c) | (~b & d)) + x + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };

  GG = function(a, b, c, d, x, s, t) {
    var n;
    n = a + ((b & d) | (c & ~d)) + x + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };

  HH = function(a, b, c, d, x, s, t) {
    var n;
    n = a + (b ^ c ^ d) + x + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };

  II = function(a, b, c, d, x, s, t) {
    var n;
    n = a + (c ^ (b | ~d)) + x + t;
    return ((n << s) | (n >>> (32 - s))) + b;
  };

  exports.transform = function(x) {
    var out;
    out = (new MD5).finalize(x);
    x.scrub();
    return out;
  };

}).call(this);
