(function () {
  'use strict';

  // TOTP part inspired from https://github.com/bellstrand/totp-generator
  // Copyright: 2016 Magnus Bellstrand, license MIT
  var base32tohex, dec2hex, getToken, go, hex2dec, leftpad, tryFingerprint;
  $(document).ready(function () {
    if (window.requestIdleCallback) {
      return requestIdleCallback(function () {
        return go();
      });
    } else {
      return setTimeout(go, 500);
    }
  });
  go = function go() {
    var e, script, secret, usetotp;
    usetotp = Boolean(parseInt($('#usetotp').attr("value")));
    if (window.localStorage && usetotp) {
      secret = $('#totpsecret').attr("value");
      if (secret) {
        try {
          localStorage.setItem("stayconnectedkey", secret);
        } catch (error) {
          e = error;
          console.error("Unable to register key in storage", e);
        }
      } else {
        secret = localStorage.getItem("stayconnectedkey");
      }
      if (secret) {
        try {
          $('#fg').attr("value", "TOTP_".concat(getToken(secret)));
          $('#form').submit();
          return;
        } catch (error) {
          e = error;
          console.error("Unable to register key in storage", e);
        }
      }
    }
    // Load fingerprint2
    script = document.createElement('script');
    script.src = window.staticPrefix + "bwr/fingerprintjs2/fingerprint2.js";
    script.async = false;
    document.body.append(script);
    script.onload = tryFingerprint;
    // If script not loaded after 1s, skip its load
    return setTimeout(tryFingerprint, 1000);
  };
  tryFingerprint = function tryFingerprint() {
    console.debug("Trying fingerprint");
    if (window.Fingerprint2) {
      return Fingerprint2.get(function (components) {
        var result, values;
        values = components.map(function (component) {
          return component.value;
        });
        result = Fingerprint2.x64hash128(values.join(''), 31);
        $('#fg').attr("value", result);
        return $('#form').submit();
      });
    } else {
      console.error('No way to register this device');
      return $('#form').submit();
    }
  };
  getToken = function getToken(key) {
    var hmac, offset, otp, shaObj, time;
    key = base32tohex(key);
    time = leftpad(dec2hex(Math.floor(Date.now() / 30000)), 16, "0");
    shaObj = new jsSHA("SHA-1", "HEX");
    shaObj.setHMACKey(key, "HEX");
    shaObj.update(time);
    hmac = shaObj.getHMAC("HEX");
    offset = hex2dec(hmac.substring(hmac.length - 1));
    otp = (hex2dec(hmac.substr(offset * 2, 8)) & hex2dec("7fffffff")) + "";
    // take last 6 digits and add padding if needed
    return leftpad(otp.substr(Math.max(otp.length - 6, 0), 6), 6, "0");
  };
  hex2dec = function hex2dec(s) {
    return parseInt(s, 16);
  };
  dec2hex = function dec2hex(s) {
    return (s < 15.5 ? "0" : "") + Math.round(s).toString(16);
  };
  base32tohex = function base32tohex(base32) {
    var base32chars, bits, chunk, hex, i, j, k, ref, ref1, val;
    base32chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
    bits = "";
    hex = "";
    base32 = base32.replace(/=+$/, "");
    for (i = j = 0, ref = base32.length - 1; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) {
      val = base32chars.indexOf(base32.charAt(i).toUpperCase());
      if (val === -1) {
        throw new Error("Invalid base32 character in key");
      }
      bits += leftpad(val.toString(2), 5, "0");
    }
    for (i = k = 0, ref1 = bits.length - 8; k <= ref1; i = k += 8) {
      chunk = bits.substr(i, 8);
      hex = hex + leftpad(parseInt(chunk, 2).toString(16), 2, "0");
    }
    return hex;
  };
  leftpad = function leftpad(str, len, pad) {
    if (len + 1 >= str.length) {
      str = Array(len + 1 - str.length).join(pad) + str;
    }
    return str;
  };

})();
