text:
<?php
namespace Lobby\App\admin\Fr;

/**
.---------------------------------------------------------------------------.
|  Software:      PHP Login System - PHP logSys                             |
|  Version:       0.6.3 (Last Updated on 2016 July 30)                      |
|  Documentation: http://subinsb.com/php-logsys                             |
|  Contribute:    https://github.com/subins2000/logSys                      |
'---------------------------------------------------------------------------'
*/

class LS {

  /**
   * ------------
   * BEGIN CONFIG
   * ------------
   * Edit the configuraion
   */

  public static $default_config = array(
    /**
     * Basic Config of logSys
     */
    "basic" => array(
      "company" => "My Site",
      "email" => "email@mysite.com",
      "email_callback" => 0
    ),

    /**
     * Database Configuration
     */
    "db" => array(
      "host" => "",
      "port" => 3306,
      "username" => "",
      "password" => "",
      "name" => "",
      "table" => "users",
      "token_table" => "resetTokens"
    ),

    /**
     * Keys used for encryption
     * DONT MAKE THIS PUBLIC
     */
    "keys" => array(
      /**
       * Changing cookie key will expire all current active login sessions
       */
      "cookie" => "ckxc436jd*^30f840v*9!@#$",
      /**
       * `salt` should not be changed after users are created
       */
      "salt" => "^#$4%9f+1^p9)M@4M)V$"
    ),

    /**
     * Enable/Disable certain features
     */
    "features" => array(
      /**
       * Should I Call session_start();
       */
      "start_session" => true,
      /**
       * Enable/Disable Login using Username & E-Mail
       */
      "email_login" => true,
      /**
       * Enable/Disable `Remember Me` feature
       */
      "remember_me" => true,
      /**
       * Should \Fr\LS::init() be called automatically
       */
      "auto_init" => false,

      /**
       * Prevent Brute Forcing
       * ---------------------
       * By enabling this, logSys will deny login for the time mentioned
       * in the "brute_force"->"time_limit" seconds after "brute_force"->"tries"
       * number of incorrect login tries.
       */
      "block_brute_force" => true,

      /**
       * Two Step Login
       * --------------
       * By enabling this, a checking is done when user visits
       * whether the device he/she uses is approved by the user.
       * Allows the original user to revoke logins in other devices/places
       * Useful if the user forgot to logout in some place.
       */
      "two_step_login" => false
    ),

    /**
     * `Blocking Brute Force Attacks` options
     */
    "brute_force" => array(
      /**
       * No of tries alloted to each user
       */
      "tries" => 5,
      /**
       * The time IN SECONDS for which block from login action should be done after
       * incorrect login attempts. Use http://www.easysurf.cc/utime.htm#m60s
       * for converting minutes to seconds. Default : 5 minutes
       */
      "time_limit" => 300
    ),

    /**
     * Information about pages
     */
    "pages" => array(
      /**
       * Pages that doesn't require logging in.
       * Exclude login page, but include REGISTER page.
       * Use RELATIVE links. To find the relative link of
       * a page, do var_dump(Fr\LS::curPage());
       */
      "no_login" => array(),

      /**
       * Pages that both logged in and not logged in users can access
       */
      "everyone" => array(),

      /**
       * The login page. ex : /login.php or /accounts/login.php
       */
      "login_page" => "",

      /**
       * The home page. The main page for logged in users.
       * logSys redirects to here after user logs in
       */
      "home_page" => ""
    ),

    /**
     * Settings about cookie creation
     */
    "cookies" => array(
      /**
       * Default : cookies expire in 30 days. The value is
       * for setting in strtotime() function
       * http://php.net/manual/en/function.strtotime.php
       */
      "expire" => "+30 days",
      "path" => "/",
      "domain" => "",
    ),

    /**
     * 2 Step Login
     */
    'two_step_login' => array(
      /**
       * Message to show before displaying "Enter Token" form.
       */
      'instruction' => '',

      /**
       * Callback when token is generated.
       * Used to send message to user (Phone/E-Mail)
       */
      'send_callback' => '',

      /**
       * The table to stoe user's sessions
       */
      'devices_table' => 'user_devices',

      /**
       * The length of token generated.
       * A low value is better for tokens sent via Mobile SMS
       */
      'token_length' => 4,

      /**
       * Whether the token should be numeric only ?
       * Default Token : Alphabetic + Numeric mixed strings
       */
      'numeric' => false,

      /**
       * The expire time of cookie that authorizes the device
       * to login using the user's account with 2 Step Verification
       * The value is for setting in strtotime() function
       * http://php.net/manual/en/function.strtotime.php
       */
      'expire' => '+45 days',

      /**
       * Should logSys checks if device is valid, everytime
       * logSys is initiated ie everytime a page loads
       * If you want to check only the first time a user loads
       * a page, then set the value to TRUE, else FALSE
       */
      'first_check_only' => true
    )
  );

  /* ------------
   * END Config.
   * ------------
   * No more editing after this line.
   */

  public static $config = array();
  private static $constructed = false;

  /**
   * Merge user config and default config
   * $direct is for knowing whether the function is called by self::construct()
   */
  public static function config($config = null, $direct = true){
    if($config != null){
      self::$config = $config;
    }
    self::$config = array_replace_recursive(self::$default_config, self::$config);
    if($direct == true){
      self::construct();
    }
  }

  /**
   * Log something in the Francium.log file.
   * To enable logging, make a file called "Francium.log" in the directory
   * where "class.logsys.php" file is situated
   */
  public static function log($msg = ""){
    $log_file = __DIR__ . "/Francium.log";
    if(file_exists($log_file)){
      if($msg != ""){
        $message = "[" . date("Y-m-d H:i:s") . "] $msg";
        $fh = fopen($log_file, 'a');
        fwrite($fh, $message . "\n");
        fclose($fh);
      }
    }
  }

  public static $loggedIn = false;
  public static $db = true;
  public static $user = false;
  private static $init_called = false;
  private static $cookie, $session, $remember_cookie, $dbh;

  public static function construct($called_from = ""){
    if(self::$constructed === false){
      self::config(null, false);
      self::$constructed = true;

      if(self::$config['features']['start_session'] === true){
        session_start();
      }
      /**
      * Try connecting to Database Server
      */
      try{
        /**
        * Add the login page to the array of pages that doesn't need logging in
        */
        array_push(self::$config['pages']['no_login'], self::$config['pages']['login_page']);

        self::$dbh = new \Lobby\App\admin\DB;
        self::$db = true;

        self::$cookie = isset($_COOKIE['logSyslogin']) ? $_COOKIE['logSyslogin'] : false;
        self::$session = isset($_SESSION['logSyscuruser']) ? $_SESSION['logSyscuruser'] : false;
        self::$remember_cookie = isset($_COOKIE['logSysrememberMe']) ? $_COOKIE['logSysrememberMe'] : false;

        $encUserID = hash("sha256", self::$config['keys']['cookie'] . self::$session . self::$config['keys']['cookie']);

        if(self::$cookie == $encUserID){
          self::$loggedIn = true;
        }else{
          self::$loggedIn = false;
        }

        /**
        * If there is a Remember Me Cookie and the user is not logged in,
        * then log in the user with the ID in the remember cookie, if it
        * matches with the decrypted value in `logSyslogin` cookie
        */
        if(self::$config['features']['remember_me'] === true && self::$remember_cookie !== false && self::$loggedIn === false){
          $encUserID = hash("sha256", self::$config['keys']['cookie']. self::$remember_cookie . self::$config['keys']['cookie']);
          if(self::$cookie == $encUserID){
            self::$loggedIn = true;
          }else{
            self::$loggedIn = false;
          }

          if(self::$loggedIn === true){
            $_SESSION['logSyscuruser'] = self::$remember_cookie;
            self::$session = self::$remember_cookie;
          }
        }

        self::$user = self::$session;

        /**
         * Check if devices is authorized to use the account
         */
        if(self::$config['features']['two_step_login'] === true && self::$loggedIn){
          $login_page = self::curPage() === self::$config['pages']['login_page'];

          if(!isset($_SESSION['device_check']) && !isset($_COOKIE['logSysdevice']) && $login_page === false){
            /**
             * The device cookie is not even set. So, logout
             */
            self::logout();
            $called_from = "login";
          }else if(self::$config['two_step_login']['first_check_only'] === false || (self::$config['two_step_login']['first_check_only'] === true && !isset($_SESSION['device_check']))){
            $sql = self::$dbh->prepare("SELECT '1' FROM `". self::$config['two_step_login']['devices_table'] ."` WHERE `uid` = ? AND `token` = ?");
            $sql->execute(array(self::$user, $_COOKIE['logSysdevice']));

            /**
             * Device not authorized, so remove device cookie & logout
             */
            if($sql->fetchColumn() !== '1' && $login_page === false){
              setcookie("logSysdevice", "", time() - 10);
              self::logout();
              $called_from = "login";
            }else{
              /**
               * This session has been checked and verified
               */
              $_SESSION['device_check'] = 1;
            }
          }
        }

        if(self::$config['features']['auto_init'] === true && $called_from != "logout" && $called_from != "login"){
          self::init();
        }
        return true;
      }catch(\PDOException $e) {
        /**
         * Couldn't connect to Database
         */
        self::log('Couldn\'t connect to database. Check \Fr\LS::$config["db"] credentials');
        return false;
      }
    }
  }

  /**
   * A function that will automatically redirect user according to his/her login status
   */
  public static function init() {
    self::construct();
    if(in_array(self::curPage(), self::$config['pages']['everyone'])){
      /**
       * No redirects as this page can be accessed
       * by anyone whether he/she is logged in or not
       */
    }else if(self::$loggedIn === true && in_array(self::curPage(), self::$config['pages']['no_login'])){
      self::redirect(self::$config['pages']['home_page']);
    }else if(self::$loggedIn === false && array_search(self::curPage(), self::$config['pages']['no_login']) === false){
      self::redirect(self::$config['pages']['login_page']);
    }
    self::$init_called = true;
  }

  /**
   * A function to login the user with the username and password.
   * As of version 0.4, it is required to include the remember_me parameter
   * when calling this function to avail the "Remember Me" feature.
   */
  public static function login($username, $password, $remember_me = false, $cookies = true){
    self::construct("login");
    if(self::$db === true){
      /**
       * We Add LIMIT to 1 in SQL query because to
       * get an array with key as the column name.
       */
      if(self::$config['features']['email_login'] === true){
        $query = "SELECT `id`, `password`, `attempt` FROM `". self::$config['db']['table'] ."` WHERE `username`=:login OR `email`=:login ORDER BY `id` LIMIT 1";
      }else{
        $query = "SELECT `id`, `password`, `attempt` FROM `". self::$config['db']['table'] ."` WHERE `username`=:login ORDER BY `id` LIMIT 1";
      }

      $sql = self::$dbh->prepare($query);
      $sql->bindValue(":login", $username);

      $sql->execute();
      $cols = $sql->fetch(\PDO::FETCH_ASSOC);

      if(empty($cols)){
        // No such user like that
        return false;
      }else{
        /**
         * Get the user details
         */
        $us_id = $cols['id'];
        $us_pass = $cols['password'];
        $status = $cols['attempt'];

        if(substr($status, 0, 2) == "b-"){
          $blockedTime = substr($status, 2);
          if(time() < $blockedTime){
            $blocked = true;
            return array(
              "status"  => "blocked",
              "minutes" => round(abs($blockedTime - time()) / 60, 0),
              "seconds" => round(abs($blockedTime - time()) / 60*60, 2)
            );
          }else{
            // remove the block, because the time limit is over
            self::updateUser(array(
              "attempt" => "" // No tries at all
            ), $us_id);
          }
        }
        /**
         * Why login if password is empty ?
         * --------------------------------
         * If using OAuth, you have to login someone without knowing their password,
         * this usage is helpful. But, it makes a serious security problem too.
         * Hence, before calling \Fr\LS::login() in the login page, it is
         * required to check whether the password fieldis left blank
         */
        if(!isset($blocked) && ($password === "" || password_verify($password . self::$config['keys']['salt'], $us_pass) )){
          if($cookies === true){

            $_SESSION['logSyscuruser'] = $us_id;

            setcookie("logSyslogin", hash("sha256", self::$config['keys']['cookie'] . $us_id . self::$config['keys']['cookie']), strtotime(self::$config['cookies']['expire']), self::$config['cookies']['path'], self::$config['cookies']['domain']);

            if( $remember_me === true && self::$config['features']['remember_me'] === true ){
              setcookie("logSysrememberMe", $us_id, strtotime(self::$config['cookies']['expire']), self::$config['cookies']['path'], self::$config['cookies']['domain']);
            }
            self::$loggedIn = true;

            if(self::$config['features']['block_brute_force'] === true){
              /**
               * If Brute Force Protection is Enabled,
               * Reset the attempt status
               */
              self::updateUser(array(
                "attempt" => "0"
              ), $us_id);
            }

            // Redirect
            if(self::$init_called){
              self::redirect(self::$config['pages']['home_page']);
            }
            return true;
          }else{
            /**
             * If cookies shouldn't be set,
             * it means login() was called
             * to get the user's ID. So, return it
             */
            return $us_id;
          }
        }else{
          /**
           * Incorrect password
           * ------------------
           * Check if brute force protection is enabled
           */
          if(self::$config['features']['block_brute_force'] === true){
            $max_tries = self::$config['brute_force']['tries'];

            if($status == ""){
              // User was not logged in before
              self::updateUser(array(
                "attempt" => "1" // Tried 1 time
              ), $us_id);
            }else if($status == $max_tries){
              /**
               * Account Blocked. User will be only able to
               * re-login at the time in UNIX timestamp
               */
              $eligible_for_next_login_time = strtotime("+". self::$config['brute_force']['time_limit'] ." seconds", time());
              self::updateUser(array(
                "attempt" => "b-" . $eligible_for_next_login_time
              ), $us_id);
              return array(
                "status"  => "blocked",
                "minutes" => round(abs($eligible_for_next_login_time - time()) / 60, 0),
                "seconds" => round(abs($eligible_for_next_login_time - time()) / 60*60, 2)
              );
            }else if($status < $max_tries){
              // If the attempts are less than Max and not Max
              self::updateUser(array(
                "attempt" => $status + 1 // Increase the no of tries by +1.
              ), $us_id);
            }
          }
          return false;
        }
      }
    }
  }

  /**
   * A function to register a user with passing the username, password
   * and optionally any other additional fields.
   */
  public static function register( $id, $password, $other = array() ){
    self::construct();
    if( self::userExists($id) || (isset($other['email']) && self::userExists($other['email'])) ){
      return "exists";
    }else{
      $hashedPass = password_hash($password. self::$config['keys']['salt'], PASSWORD_DEFAULT);

      if( count($other) == 0 ){
        /* If there is no other fields mentioned, make the default query */
        $sql = self::$dbh->prepare("INSERT INTO `". self::$config['db']['table'] ."` (`username`, `password`) VALUES(:username, :password)");
      }else{
        /* if there are other fields to add value to, make the query and bind values according to it */
        $keys   = array_keys($other);
        $columns = implode(",", $keys);
        $colVals = implode(",:", $keys);
        $sql   = self::$dbh->prepare("INSERT INTO `". self::$config['db']['table'] ."` (`username`, `password`, $columns) VALUES(:username, :password, :$colVals)");
        foreach($other as $key => $value){
          $value = htmlspecialchars($value);
          $sql->bindValue(":$key", $value);
        }
      }
      /* Bind the default values */
      $sql->bindValue(":username", $id);
      $sql->bindValue(":password", $hashedPass);
      $sql->execute();
      return true;
    }
  }

  /**
   * Logout the current logged in user by deleting the cookies and destroying session
   */
  public static function logout(){
    self::construct("logout");
    session_destroy();
    setcookie("logSyslogin", "", time() - 10, self::$config['cookies']['path'], self::$config['cookies']['domain']);
    setcookie("logSysrememberMe", "", time() - 10, self::$config['cookies']['path'], self::$config['cookies']['domain']);

    /**
     * Wait for the cookies to be removed, then redirect
     */
    usleep(2000);
    self::redirect(self::$config['pages']['login_page']);
    return true;
  }

  /**
   * A function to handle the Forgot Password process
   */
  public static function forgotPassword(){
    self::construct();
    $curStatus = "initial";  // The Current Status of Forgot Password process
    $identName = self::$config['features']['email_login'] === false ? "Username" : "Username / E-Mail";

    if( !isset($_POST['logSysForgotPass']) && !isset($_GET['resetPassToken']) && !isset($_POST['logSysForgotPassChange']) ){
      $html = '<form action="'. self::curPageURL() .'" method="POST">';
        $html .= "";
          $html .= "
{$identName}
";
          $html .= "<input type='text' id='logSysIdentification' placeholder='Enter your {$identName}' size='25' name='identification' />";
        $html .= "";
        $html .= "
<button name='logSysForgotPass' type='submit'>Reset Password</button>
";
      $html .= "</form>";
      echo $html;
      /**
       * The user had moved to the reset password form ie she/he is currently seeing the forgot password form
       */
      $curStatus = "resetPasswordForm";
    }elseif( isset($_GET['resetPassToken']) && !isset($_POST['logSysForgotPassChange']) ){
      /**
       * The user gave the password reset token. Check if the token is valid.
       */
      $reset_pass_token = urldecode($_GET['resetPassToken']);
      $sql = self::$dbh->prepare("SELECT COUNT(1) FROM `". self::$config['db']['token_table'] ."` WHERE `token` = ?");
      $sql->execute(array($reset_pass_token));

      if($sql->fetchColumn() == 0 || $reset_pass_token == ""){
        echo "
Error : Wrong/Invalid Token
";
        $curStatus = "invalidToken"; // The token user gave was not valid
      }else{
        /**
         * The token is valid, display the new password form
         */
        $html = "
The Token key was Authorized. Now, you can change the password
";
        $html .= "<form action='{$_SERVER['PHP_SELF']}' method='POST'>";
          $html .= "<input type='hidden' name='token' value='{$reset_pass_token}' />";
          $html .= "";
            $html .= "
New Password
";
            $html .= "<input type='password' name='logSysForgotPassNewPassword' />";
          $html .= "
";
          $html .= "";
            $html .= "
Retype Password
";
            $html .= "<input type='password' name='logSysForgotPassRetypedPassword'/>";
          $html .= "
";
          $html .= "
<button name='logSysForgotPassChange'>Reset Password</button>
";
        $html .= "</form>";
        echo $html;
        /**
         * The token was correct, displayed the change/new password form
         */
        $curStatus = "changePasswordForm";
      }
    }elseif(isset($_POST['logSysForgotPassChange']) && isset($_POST['logSysForgotPassNewPassword']) && isset($_POST['logSysForgotPassRetypedPassword'])){
      $reset_pass_token = urldecode($_POST['token']);
      $sql = self::$dbh->prepare("SELECT `uid` FROM `". self::$config['db']['token_table'] ."` WHERE `token` = ?");
      $sql->execute(array($reset_pass_token));

      $user = $sql->fetchColumn();

      if( $user == null || $reset_pass_token == null ){
        echo "
Error : Wrong/Invalid Token
";
        $curStatus = "invalidToken"; // The token user gave was not valid
      }else{
        if($_POST['logSysForgotPassNewPassword'] == "" || $_POST['logSysForgotPassRetypedPassword'] == ""){
          echo "
Error : Passwords Fields Left Blank
";
          $curStatus = "fieldsLeftBlank";
        }elseif( $_POST['logSysForgotPassNewPassword'] != $_POST['logSysForgotPassRetypedPassword'] ){
          echo "
Error : Passwords Don't Match
";
          $curStatus = "passwordDontMatch"; // The new password and retype password submitted didn't match
        }else{
          /**
           * We must create a fake assumption that the user is logged in to
           * change the password as \Fr\LS::changePassword()
           * requires the user to be logged in.
           */
          self::$user = $user;
          self::$loggedIn = true;

          if(self::changePassword($_POST['logSysForgotPassNewPassword'])){
            self::$user = false;
            self::$loggedIn = false;

            /**
             * The token shall not be used again, so remove it.
             */
            $sql = self::$dbh->prepare("DELETE FROM `". self::$config['db']['token_table'] ."` WHERE `token` = ?");
            $sql->execute(array($reset_pass_token));

            echo "
Success : Password Reset Successful

You may now login with your new password.
";
            $curStatus = "passwordChanged"; // The password was successfully changed
          }
        }
      }
    }elseif(isset($_POST['identification'])){
      /**
       * Check if username/email is provided and if it's valid and exists
       */
      $identification = $_POST['identification'];
      if($identification == ""){
        echo "
Error : {$identName} not provided
";
        $curStatus = "identityNotProvided"; // The identity was not given
      }else{
        $sql = self::$dbh->prepare("SELECT `email`, `id` FROM `". self::$config['db']['table'] ."` WHERE `username`=:login OR `email`=:login");
        $sql->bindValue(":login", $identification);

        $sql->execute();
        $cols  = $sql->fetch(\PDO::FETCH_ASSOC);

        if(empty($cols)){
          echo "
Error : User Not Found
";
          $curStatus = "userNotFound"; // The user with the identity given was not found in the users database
        }else{
          $email = $cols['email'];
          $uid   = $cols['id'];

          /**
           * Make token and insert into the table
           */
          $token = self::rand_string(40);
          $sql = self::$dbh->prepare("INSERT INTO `". self::$config['db']['token_table'] ."` (`token`, `uid`, `requested`) VALUES (?, ?, NOW())");
          $sql->execute(array($token, $uid));
          $encodedToken = urlencode($token);

          /**
           * Prepare the email to be sent
           */
          $subject = "Reset Password";
          $body   = "You requested for resetting your password on ". self::$config['basic']['company'] .". For this, please click the following link :

            Reset Password : {$token}

";
          self::sendMail($email, $subject, $body);

          echo "
An email has been sent to your email inbox with instructions. Check Your Mail Inbox and SPAM Folders.

You can close this window.
";
          $curStatus = "emailSent"; // E-Mail has been sent
        }
      }
    }
    return $curStatus;
  }

  /**
   * A function that handles the logged in user to change her/his password
   */
  public static function changePassword($newpass){
    self::construct();
    if(self::$loggedIn){
      $hashedPass = password_hash($newpass . self::$config['keys']['salt'], PASSWORD_DEFAULT);
      $sql = self::$dbh->prepare("UPDATE `". self::$config['db']['table'] ."` SET `password` = ? WHERE `id` = ?");
      $sql->execute(array($hashedPass, self::$user));
      return true;
    }else{
      echo "
Error : Not Logged In
";
      return "notLoggedIn";
    }
  }

  /**
   * Check if user exists with ther username/email given
   * $identification - Either email/username
   */
  public static function userExists($identification){
    self::construct();
    if(self::$config['features']['email_login'] === true){
      $query = "SELECT COUNT(1) FROM `". self::$config['db']['table'] ."` WHERE `username`=:login OR `email`=:login";
    }else{
      $query = "SELECT COUNT(1) FROM `". self::$config['db']['table'] ."` WHERE `username`=:login";
    }
    $sql = self::$dbh->prepare($query);
    $sql->execute(array(
      ":login" => $identification
    ));
    return $sql->fetchColumn() == "0" ? false : true;
  }

  /**
   * Fetches data of user in database. Returns a single value or an
   * array of value according to parameteres given to the function
   */
  public static function getUser($what = "*", $user = null){
    self::construct();
    if($user == null){
      $user = self::$user;
    }
    if( is_array($what) ){
      $columns = implode("`,`", $what);
      $columns  = "`{$columns}`";
    }else{
      $columns = $what != "*" ? "`$what`" : "*";
    }

    $sql = self::$dbh->prepare("SELECT {$columns} FROM `". self::$config['db']['table'] ."` WHERE `id` = ? ORDER BY `id` LIMIT 1");
    $sql->execute(array($user));

    $data = $sql->fetch(\PDO::FETCH_ASSOC);
    if( !is_array($what) ){
      $data = $what == "*" ? $data : $data[$what];
    }
    return $data;
  }

  /**
   * Updates the info of user in DB
   */
  public static function updateUser($toUpdate = array(), $user = null){
    self::construct();
    if( is_array($toUpdate) && !isset($toUpdate['id']) ){
      if($user == null){
        $user = self::$user;
      }
      $columns = "";
      foreach($toUpdate as $k => $v){
        $columns .= "`$k` = :$k, ";
      }
      $columns = substr($columns, 0, -2); // Remove last ","

      $sql = self::$dbh->prepare("UPDATE `". self::$config['db']['table'] ."` SET {$columns} WHERE `id`=:id");
      $sql->bindValue(":id", $user);
      foreach($toUpdate as $key => $value){
        $value = htmlspecialchars($value);
        $sql->bindValue(":$key", $value);
      }
      $sql->execute();

    }else{
      return false;
    }
  }

  /**
   * Returns a string which shows the time since the user has joined
   */
  public static function joinedSince($user = null){
    self::construct();
    if($user == null){
      $user = self::$user;
    }
    $created = self::getUser("created");
    $timeFirst  = strtotime($created);
    $timeSecond = strtotime("now");
    $memsince   = $timeSecond - strtotime($created);
    $regged     = date("n/j/Y", strtotime($created));

    if($memsince < 60) {
      $memfor = $memsince . " Seconds";
    }else if($memsince < 120){
      $memfor = floor ($memsince / 60) . " Minute";
    }else if($memsince < 3600 && $memsince > 120){
      $memfor = floor($memsince / 60) . " Minutes";
    }else if($memsince < 7200 && $memsince > 3600){
      $memfor = floor($memsince / 3600) . " Hour";
    }else if($memsince < 86400 && $memsince > 3600){
      $memfor = floor($memsince / 3600) . " Hours";
    }else if($memsince < 172800){
      $memfor = floor($memsince / 86400) . " Day";
    }else if($memsince < 604800 && $memsince > 172800){
      $memfor = floor($memsince / 86400) . " Days";
    }else if($memsince < 1209600 && $memsince > 604800){
      $memfor = floor($memsince / 604800) . " Week";
    }else if($memsince < 2419200 && $memsince > 1209600){
      $memfor = floor($memsince / 604800) . " Weeks";
    }else if($memsince < 4838400){
      $memfor = floor($memsince / 2419200) . " Month";
    }else if($memsince < 31536000 && $memsince > 4838400){
      $memfor = floor($memsince / 2419200) . " Months";
    }else if($memsince < 63072000){
      $memfor = floor($memsince / 31536000) . " Year";
    }else if($memsince > 63072000){
      $memfor = floor($memsince / 31536000) . " Years";
    }
    return (string) $memfor;
  }

  /**
   * 2 Step Verification Login Process
   * ---------------------------------
   * When user logs in, it checks whether there is a cookie named "logSysdevice" and if there is :
   *    1. Checks `config` -> `two_step_login` -> `devices_table` table in DB whethere there is a token with value as that of $_COOKIES['logSysdevice']
   *    2. If there is a row in table, then the "Enter Received Token" form is not shown and is directly logged in if username & pass is correct
   * If there is not a cookie, then :
   *    1. The "Enter Received token" form is shown
   *    2. If the token entered is correct, then a unique string is set as $_COOKIE['logSysdevice'] value and inserted to `config` -> `two_step_login` -> `devices_table` table in DB
   *    3. The $_COOKIE['logSysdevice'] is set to be stored for 4 months
   * ---------------------
   * ^ In the above instructions, the token sending to E-Mail/SMS is not mentioned. Assume that it is done
   */
  public static function twoStepLogin($identification = "", $password = "", $remember_me = false){
    if(isset($_POST['logSys_two_step_login-token']) && isset($_POST['logSys_two_step_login-uid']) && $_SESSION['logSys_two_step_login-first_step'] === '1'){
      /**
       * The user's ID and token is got through the form
       * User = One who is about to log in and is stuck at 2 step verification
       */
      $uid = $_POST['logSys_two_step_login-uid'];
      $token = $_POST['logSys_two_step_login-token'];

      $sql = self::$dbh->prepare("SELECT COUNT(1) FROM `". self::$config['db']['token_table'] ."` WHERE `token` = ? AND `uid` = ?");
      $sql->execute(array($token, $uid));

      if($sql->fetchColumn() == 0){
        /**
         * To prevent user from Brute Forcing the token, we set the
         * status of the first login step to false,
         * so that the user would have to login again
         */
        $_SESSION['logSys_two_step_login-first_step'] = '0';
        echo "
Error : Wrong/Invalid Token
";
        return "invalidToken";
      }else{
        /**
         * Register User's new device if and only if
         * the user wants to remember the device from
         * which the user is logging in
         */
        if(isset($_POST['logSys_two_step_login-dontask'])){
          $device_token = self::rand_string(10);
          $sql = self::$dbh->prepare("INSERT INTO `". self::$config['two_step_login']['devices_table'] ."` (`uid`, `token`, `last_access`) VALUES (?, ?, NOW())");
          $sql->execute(array($uid, $device_token));
          setcookie("logSysdevice", $device_token, strtotime(self::$config['two_step_login']['expire']), self::$config['cookies']['path'], self::$config['cookies']['domain']);
        }else{
          /**
           * Verify login for this session
           */
          $_SESSION["device_check"] = "1";
        }

        /**
         * Revoke token from reusing
         */
        $sql = self::$dbh->prepare("DELETE FROM `". self::$config['db']['token_table'] ."` WHERE `token` = ? AND `uid` = ?");
        $sql->execute(array($token, $uid));
        self::login(self::getUser("username", $uid), "", isset($_POST['logSys_two_step_login-remember_me']));
      }
      return true;
    }else if($identification != "" && $password != ""){
      $login = self::login($identification, $password, $remember_me, false);
      if($login === false){
        /**
         * Username/Password wrong
         */
        return false;
      }else if(is_array($login) && $login['status'] == "blocked"){
        return $login;
      }else{
        /**
         * Get the user ID from \Fr\LS::login()
         */
        $uid = $login;

        /**
         * Check if device is verfied so that 2 Step Verification can be skipped
         */
        if(isset($_COOKIE['logSysdevice'])){
          $sql = self::$dbh->prepare("SELECT 1 FROM `". self::$config['two_step_login']['devices_table'] ."` WHERE `uid` = ? AND `token` = ?");
          $sql->execute(array($uid, $_COOKIE['logSysdevice']));
          if($sql->fetchColumn() == "1"){
            $verfied = true;
            /**
             * Update last accessed time
             */
            $sql = self::$dbh->prepare("UPDATE `". self::$config['two_step_login']['devices_table'] ."` SET `last_access` = NOW() WHERE `uid` = ? AND `token` = ?");
            $sql->execute(array($uid, $_COOKIE['logSysdevice']));

            self::login(self::getUser("username", $uid), "", $remember_me);
            return true;
          }
        }
        /**
         * Start the 2 Step Verification Process
         * Do only if callback is present and if
         * the device is not verified
         */
        if(is_callable(self::$config['two_step_login']['send_callback']) && !isset($verified)){
          /**
           * The first part of 2 Step Login is completed
           */
          $_SESSION['logSys_two_step_login-first_step'] = '1';

          /**
           * The 2nd parameter depends on `config` -> `two_step_login` -> `numeric`
           */
          $token = self::rand_string(self::$config['two_step_login']['token_length'], self::$config['two_step_login']['numeric']);

          /**
           * Save the token in DB
           */
          $sql = self::$dbh->prepare("INSERT INTO `". self::$config['db']['token_table'] ."` (`token`, `uid`, `requested`) VALUES (?, ?, NOW())");
          $sql->execute(array($token, $uid));

          call_user_func_array(self::$config['two_step_login']['send_callback'], array($uid, $token));

          /**
           * Display the form
           */
          $html = "<form action='". self::curPageURL() ."' method='POST'>

". self::$config['two_step_login']['instruction'] ."

Token Received

              <input type='text' name='logSys_two_step_login-token' placeholder='Paste the token here... (case sensitive)' />

              Remember this device ?
              <input type='checkbox' name='logSys_two_step_login-dontask' />

            <input type='hidden' name='logSys_two_step_login-uid' value='". $uid ."' />
            ". ($remember_me === true ? "<input type='hidden' name='logSys_two_step_login-remember_me' />" : "") ."

              <button>Verify</button>

          </form>";
          echo $html;
          return "formDisplay";
        }else{
          self::log("two_step_login: Token Callback not present");
        }
      }
    }
    /**
     * 2 Step Login is not doing any actions or
     * hasn't returned anything before. If so,
     * then return false to indicate that the
     * function is not doing anything
     */
    return false;
  }

  /**
   * Returns array of devices that are authorized
   * to login by user's account credentials
   */
  public static function getDevices(){
    if(self::$loggedIn){
      $sql = self::$dbh->prepare("SELECT * FROM `". self::$config['two_step_login']['devices_table'] ."` WHERE `uid` = ?");
      $sql->execute(array(self::$user));
      return $sql->fetchAll(\PDO::FETCH_ASSOC);
    }else{
      return false;
    }
  }

  /**
   * Revoke a device
   */
  public static function revokeDevice($device_token){
    if(self::$loggedIn){
      $sql = self::$dbh->prepare("DELETE FROM `". self::$config['two_step_login']['devices_table'] ."` WHERE `uid` = ? AND `token` = ?");
      $sql->execute(array(self::$user, $device_token));
      if(isset($_SESSION['device_check'])){
        unset($_SESSION['device_check']);
      }
      return $sql->rowCount() == 1;
    }
  }

  /**
   * ---------------------
   * Extra Tools/Functions
   * ---------------------
   */

  /**
   * Check if E-Mail is valid
   */
  public static function validEmail($email = ""){
    return filter_var($email, FILTER_VALIDATE_EMAIL);
  }

  /**
   * Get the current page URL
   */
  public static function curPageURL() {
    $pageURL = 'http';
    if(isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on"){$pageURL .= "s";}
    $pageURL .= "://";
    if($_SERVER["SERVER_PORT"] != "80") {
      $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
    }else{
      $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
    }
    return $pageURL;
  }

  /**
   * Generate a Random String
   * $int - Whether numeric string should be output
   */
  public static function rand_string($length, $int = false) {
    $random_str = "";
    $chars = $int ? "0516243741506927589" : "subinsblogabcdefghijklmanopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    $size = strlen($chars) - 1;
    for($i = 0;$i < $length;$i++) {
      $random_str .= $chars[rand(0, $size)];
    }
    return $random_str;
  }

  /**
   * Get the current page path.
   * Eg: /mypage, /folder/mypage.php
   */
  public static function curPage(){
    $parts = parse_url(self::curPageURL());
    return $parts["path"];
  }

  /**
   * Do a redirect
   */
  public static function redirect($url, $status = 302){
    header("Location: $url", true, $status);
    exit;
  }

  /**
   * Any mails need to be sent by logSys goes to here
   */
  public static function sendMail($email, $subject, $body){
    /**
     * If there is a callback for email sending, use it else PHP's mail()
     */
    if(is_callable(self::$config['basic']['email_callback'])){
      call_user_func_array(self::$config['basic']['email_callback'], array($email, $subject, $body));
    }else{
      $headers = array();
      $headers[] = "MIME-Version: 1.0";
      $headers[] = "Content-type: text/html; charset=iso-8859-1";
      $headers[] = "From: ". self::$config['basic']['email'];
      $headers[] = "Reply-To: ". self::$config['basic']['email'];
      mail($email, $subject, $body, implode("\r\n", $headers));
    }
  }

  /**
   * CSRF Protection
   */
  public static function csrf($type = ""){
    if(!isset($_COOKIE['csrf_token'])){
      $csrf_token = self::rand_string(5);
      setcookie("csrf_token", $csrf_token, 0, self::$config['cookies']['path'], self::$config['cookies']['domain']);
    }else{
      $csrf_token = $_COOKIE['csrf_token'];
    }
    if($type == "s"){
      /**
       * Output as string
       */
      return urlencode($csrf_token);
    }elseif($type == "g"){
      /**
       * Output as a GET parameter
       */
      return "&csrf_token=" . urlencode($csrf_token);
    }elseif($type == "i"){
      /**
       * Output as an input field
       */
      echo "<input type='hidden' name='csrf_token' value='{$csrf_token}' />";
    }else{
      /**
       * Check CSRF validity
       */
      if((isset($_POST['csrf_token']) && $_COOKIE['csrf_token'] == $_POST['csrf_token']) || (isset($_GET['csrf_token']) && $_COOKIE['csrf_token'] == $_GET['csrf_token'])){
        return true;
      }else{
        /**
         * CSRF Token doesn't match.
         */
        return false;
      }
    }
  }

  /**
   * -------------------------
   * End Extra Tools/Functions
   * -------------------------
   */
}


text:
package seph.lang.compiler;

import java.util.*;

import seph.lang.*;

import java.lang.invoke.CallSite;
import java.lang.invoke.ConstantCallSite;
import java.lang.invoke.MutableCallSite;
import java.lang.invoke.MethodType;
import static java.lang.invoke.MethodType.*;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;

import static java.lang.invoke.MethodHandles.invoker;
import static java.lang.invoke.MethodHandles.exactInvoker;
import static java.lang.invoke.MethodHandles.dropArguments;
import static java.lang.invoke.MethodHandles.insertArguments;
import static java.lang.invoke.MethodHandles.filterArguments;
import static java.lang.invoke.MethodHandles.foldArguments;
import static java.lang.invoke.MethodHandles.constant;
import static java.lang.invoke.MethodHandles.identity;
import static java.lang.invoke.MethodHandles.guardWithTest;
import static java.lang.invoke.MethodHandles.filterReturnValue;
import static seph.lang.compiler.CompilationHelpers.*;
import static seph.lang.ActivationHelpers.*;
import static seph.lang.Types.*;

public class SephCallSite extends MutableCallSite {
    public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, Object... arguments) {
        if(name.intern() == "seph:pumpTailCall") {
            return new ConstantCallSite(PUMP_MH.bindTo(SThread.TAIL_MARKER));
            // return genMH(SThread.TAIL_MARKER);
        } else if(name.startsWith("seph:activationFor:")) {
            return new ConstantCallSite(createActivationForMH(name, (MethodHandle)arguments[0], (MethodHandle)arguments[1]));
        } else {
            return new SephCallSite(lookup, name, type, arguments);
        }
    }

    private static MethodHandle createActivationForMH(String name, MethodHandle specific, MethodHandle generic) {
        String[] pieces = name.split(":");
        String realName = decode(pieces[2]);
        int arity = Integer.valueOf(pieces[3]);
        boolean keywords = Boolean.valueOf(pieces[4]);

        MethodHandle testSpecificArity = dropArguments(dropArguments(insertArguments(INT_EQ, 0, arity), 0, Object.class), 2, boolean.class);
        MethodHandle testGenericArity  = dropArguments(dropArguments(insertArguments(INT_EQ, 0, -1), 0, Object.class), 2, boolean.class);
        MethodHandle testKeywords      = dropArguments(identity(boolean.class), 0, Object.class, int.class);
        MethodHandle thenSpecific      = dropArguments(BIND_TO.bindTo(specific), 1, int.class, boolean.class);
        MethodHandle thenGeneric       = dropArguments(BIND_TO.bindTo(generic), 1, int.class, boolean.class);

        MethodHandle arityProblem      = dropArguments(dropArguments(insertArguments(insertArguments(ARITY_ERROR, 0, arity), 1, realName), 0, Object.class), 2, boolean.class);

        MethodHandle guardedOnArity    = guardWithTest(testSpecificArity,
                                                       thenSpecific,
                                                       guardWithTest(testGenericArity,
                                                                     thenGeneric,
                                                                     arityProblem));
        if(keywords) {
            return guardWithTest(testKeywords,
                                 guardedOnArity,
                                 arityProblem);
        } else {
            return guardWithTest(testKeywords,
                                 arityProblem,
                                 guardedOnArity);
        }
    }

    public static SephObject pump(SephObject marker, SephObject receiver, SThread thread) throws Throwable {
        SephObject result = receiver;
        while(marker == result) {
            MethodHandle mh = thread.tail;
            result = (SephObject)mh.invokeExact();
        }
        return result;
    }

    public static CallSite genMH(SephObject marker) {
        MutableCallSite mcs = new MutableCallSite(methodType(SephObject.class, SephObject.class, SThread.class));
        MethodHandle _test = dropArguments(REF_EQ.bindTo(marker), 1, SThread.class);
        MethodHandle combiner = filterReturnValue(dropArguments(THREAD_TAIL_GETTER, 0, SephObject.class), exactInvoker(methodType(SephObject.class)));
        MethodHandle _then = foldArguments(dropArguments(mcs.dynamicInvoker(), 1, SephObject.class), combiner);
        MethodHandle _else = dropArguments(identity(SephObject.class), 1, SThread.class);
        MethodHandle pumper = guardWithTest(_test,
                                            _then,
                                            _else);
        mcs.setTarget(pumper);
        return mcs;
    }

    private final static MethodHandle PUMP_MH = findStatic(SephCallSite.class, "pump", methodType(SephObject.class, SephObject.class, SephObject.class, SThread.class));

    private final boolean lexical;
    private final Integer lexicalDepth;
    private final Integer lexicalIndex;
    private final String messageKind;
    private final String messageName;
    private final MethodHandle slowPath;
    private final MethodHandle[] argumentMHs;
    private final MethodHandle[] argumentASTMHs;

    private SephCallSite(MethodHandles.Lookup lookup, String name, MethodType type, Object[] argumentMHs) {
        super(type);

        Object[] pieces = kindNameAndExtraInfo(name.split(":"));
        this.messageKind  = (String)pieces[0];
        this.messageName  = (String)pieces[1];
        this.lexical      = (Boolean)pieces[2];
        this.lexicalDepth = (Integer)pieces[3];
        this.lexicalIndex = (Integer)pieces[4];

        int argumentLength = argumentMHs.length/2;
        this.argumentMHs  = new MethodHandle[argumentLength];
        this.argumentASTMHs  = new MethodHandle[argumentLength];
        for(int i = 0; i<argumentLength; i++) {
            this.argumentMHs[i]    = (MethodHandle)argumentMHs[i * 2];
            this.argumentASTMHs[i] = (MethodHandle)argumentMHs[i * 2 + 1];
        }

        this.slowPath     = computeSlowPath();

        if(lexical && "lookup".equals(messageKind)) {
            setTarget(computeLexicalLookupPath());
        } else if("invoke".equals(messageKind) || "tailInvoke".equals(messageKind)) {
            setTarget(computeInvokeOnCurrentObject());

        } else {
            setNeutral();
        }
    }

    private MethodHandle computeLexicalPath() {
        MethodHandle current = identity(LexicalScope.class);

        int currentDepth = lexicalDepth;
        while(currentDepth-- > 0) {
            current = filterArguments(current, 0, PARENT_SCOPE_METHOD);
        }

        MethodHandle valueMH = null;
        switch(lexicalIndex) {
        case 0:
            valueMH = filterArguments(SCOPE_0_GETTER_M, 0, current);
            break;
        case 1:
            valueMH = filterArguments(SCOPE_1_GETTER_M, 0, current);
            break;
        case 2:
            valueMH = filterArguments(SCOPE_2_GETTER_M, 0, current);
            break;
        case 3:
            valueMH = filterArguments(SCOPE_3_GETTER_M, 0, current);
            break;
        case 4:
            valueMH = filterArguments(SCOPE_4_GETTER_M, 0, current);
            break;
        case 5:
            valueMH = filterArguments(SCOPE_5_GETTER_M, 0, current);
            break;
        default:
            valueMH = filterArguments(insertArguments(SCOPE_N_GETTER_M, 1, lexicalIndex-6), 0, current);
            break;
        }

        MethodHandle all = null;
        if(messageKind == "message") {
            all = computeRegularMessage(type());
        } else if(messageKind == "tailMessage") {
            all = computeTailMessage(type());
        }
        return foldArguments(all,
                             dropArguments(dropArguments(valueMH, 0, SephObject.class, SThread.class), 3, type().dropParameterTypes(0, 3).parameterArray()));
    }

    private MethodHandle computeInvokeOnCurrentObject() {
        MethodHandle all = null;
        if(messageKind == "invoke") {
            all = computeRegularMessage(type().dropParameterTypes(0,1));
        } else if(messageKind == "tailInvoke") {
            all = computeTailMessage(type().dropParameterTypes(0,1));
        }
        return all;
    }

    private MethodHandle computeLexicalLookupPath() {
        MethodHandle current = identity(LexicalScope.class);

        int currentDepth = lexicalDepth;
        while(currentDepth-- > 0) {
            current = filterArguments(current, 0, PARENT_SCOPE_METHOD);
        }

        MethodHandle valueMH = null;
        switch(lexicalIndex) {
        case 0:
            valueMH = filterArguments(SCOPE_0_GETTER_M, 0, current);
            break;
        case 1:
            valueMH = filterArguments(SCOPE_1_GETTER_M, 0, current);
            break;
        case 2:
            valueMH = filterArguments(SCOPE_2_GETTER_M, 0, current);
            break;
        case 3:
            valueMH = filterArguments(SCOPE_3_GETTER_M, 0, current);
            break;
        case 4:
            valueMH = filterArguments(SCOPE_4_GETTER_M, 0, current);
            break;
        case 5:
            valueMH = filterArguments(SCOPE_5_GETTER_M, 0, current);
            break;
        default:
            valueMH = filterArguments(insertArguments(SCOPE_N_GETTER_M, 1, lexicalIndex-6), 0, current);
            break;
        }

        return valueMH;
    }

    private MethodHandle computeRegularMessage(MethodType theType) {
        MethodHandle _test = dropArguments(findVirtual(SephObject.class, "isActivatable", methodType(boolean.class)), 1, theType.parameterArray());

        MethodHandle invoker = MethodHandles.exactInvoker(theType);
        MethodHandle _then = filterArguments(invoker, 0, insertArguments(findVirtual(SephObject.class, "activationFor", methodType(MethodHandle.class, int.class, boolean.class)), 1, arity(), keywords()));
        MethodHandle _else = dropArguments(identity(SephObject.class), 1, theType.parameterArray());
        return guardWithTest(_test, _then, _else);
    }

    private MethodHandle computeTailMessage(MethodType theType) {
        MethodHandle _test = dropArguments(findVirtual(SephObject.class, "isActivatable", methodType(boolean.class)), 1, theType.parameterArray());
        MethodHandle _insertArguments = insertArguments(findStatic(MethodHandles.class, "insertArguments", methodType(MethodHandle.class, MethodHandle.class, int.class, Object[].class)), 1, 0).asCollector(Object[].class, theType.parameterCount()).asType(theType.insertParameterTypes(0, MethodHandle.class).changeReturnType(MethodHandle.class));
        MethodHandle _activationFor = insertArguments(findVirtual(SephObject.class, "activationFor", methodType(MethodHandle.class, int.class, boolean.class)), 1, arity(), keywords());
        MethodHandle _filtered = filterArguments( _insertArguments, 0 ,_activationFor);
        MethodHandle _then = foldArguments(dropArguments(dropArguments(SET_TAIL_MH, 1, SephObject.class, SephObject.class), 4, theType.dropParameterTypes(0, 2).parameterArray()),
                                               _filtered);
        MethodHandle _else = dropArguments(identity(SephObject.class), 1, theType.parameterArray());
        return guardWithTest(_test, _then, _else);
    }

    private int arity = -2;
    private boolean keywords = false;;

    private void computeArity() {
        int diff = 3;
        if("invoke".equals(messageKind) || "tailInvoke".equals(messageKind)) {
            diff = 4;
        }
        int num = type().parameterCount() - diff;

        if(num == 0) {
            keywords = false;
            arity = 0;
        } else {
            Class<?>[] tp = type().parameterArray();
            int minus = 0;
            if(tp[tp.length-2] == String[].class) {
                keywords = true;
                minus = 2;
            }
            if(num == 1 && tp[diff] == MethodHandle[].class) {
                arity = -1;
            } else {
                arity = num - minus;
            }
        }
    }

    private int arity() {
        if(arity == -2) {
            computeArity();
        }
        return arity;
    }

    private boolean keywords() {
        if(arity == -2) {
            computeArity();
        }
        return keywords;
    }

    private static Object[] kindNameAndExtraInfo(Object[] nc) {
        String kind = ((String)nc[1]).intern();
        String name = decode((String)nc[2]).intern();
        boolean lexical   = nc.length == 6 && "lexical".equals(nc[3]);
        Integer lexicalDepth = lexical ? Integer.valueOf((String)nc[4]) : null;
        Integer lexicalIndex = lexical ? Integer.valueOf((String)nc[5]) : null;

        return new Object[] { kind, name, lexical, lexicalDepth, lexicalIndex };
    }

    public static SephObject setTail(MethodHandle h, SThread thread) {
        thread.tail = h;
        return SThread.TAIL_MARKER;
    }

    public final static MethodHandle SET_TAIL_MH = findStatic(SephCallSite.class, "setTail", methodType(SephObject.class, MethodHandle.class, SThread.class));
    public final static MethodType SLOW_PATH_TYPE    = methodType(SephObject.class, SephCallSite.class, String.class, SephObject.class, SThread.class, LexicalScope.class, Object[].class);

    public static void checkForNull(String name, SephObject value, SephObject receiver) {
         if(null == value) {
             throw new RuntimeException(" *** couldn't find: " + name + " on " + receiver);
         }
    }

    public final static MethodHandle CHECK_FOR_NULL_MH = findStatic(SephCallSite.class, "checkForNull", methodType(void.class, String.class, SephObject.class, SephObject.class));

    MethodHandle computeSlowPath() {
        MethodHandle all = null;
        if(messageKind == "message") {
            all = computeRegularMessage(type());
        } else if(messageKind == "tailMessage") {
            all = computeTailMessage(type());
        } else {
            return null;
        }

        MethodHandle _nullCheck = dropArguments(insertArguments(CHECK_FOR_NULL_MH, 0, messageName),
                                                2,
                                                type().dropParameterTypes(0, 1).parameterArray());

        return foldArguments(foldArguments(all, _nullCheck),
                             dropArguments(insertArguments(findVirtual(SephObject.class, "get", methodType(SephObject.class, String.class)), 1, messageName), 1, type().dropParameterTypes(0, 1).parameterArray()));
    }

    public void setNeutral() {
        specializedMisses = 0;
        setTarget(filterArguments(slowPath, 0, computeProfiler(false)));
    }

    public void setMegamorphic() {
        setTarget(slowPath);
        resetProfile();
    }

    TypeProfile typeProfile;
    int profileCount;
    int specializedMisses;

    public void resetProfile() {
        typeProfile = null;
        specializedMisses = 0;
    }

    public int incrementProfileCount() {
        int cc1 = profileCount;
        int cc2 = cc1 + 1;
        if(cc2 <= 0)
            return cc1;
        profileCount = cc2;
        return cc2;
    }

    protected TypeProfile makeTypeProfile(SephObject receiver) {
        return TypeProfile.forIdentity(receiver);
    }

    private static final MethodHandle MH_profileReceiver = findVirtual(SephCallSite.class, "profileReceiver", methodType(SephObject.class, SephObject.class));
    private static final MethodHandle MH_profileReceiverForMiss = findVirtual(SephCallSite.class, "profileReceiverForMiss", methodType(SephObject.class, SephObject.class));

    private static int MONO_TARGET_COUNT = 3;
    private static int POLY_TARGET_COUNT = 5;
    private static int MAX_SPECIALIZED_MISSES = MONO_TARGET_COUNT+2;
    private static int MAX_TOTAL_PROFILES = POLY_TARGET_COUNT*2;

    protected void doPolicy(boolean sawMiss) {
        TypeProfile prof = typeProfile;
        if(prof == null) return;
        int pc = incrementProfileCount();
        if(pc >= MAX_TOTAL_PROFILES) {
            setMegamorphic();
            return;
        }
        if(sawMiss) {
            if(++specializedMisses < MAX_SPECIALIZED_MISSES)
                return;
            specializedMisses >>= 1;
        } else {
            int targetCount = MONO_TARGET_COUNT;
            if(prof.isMonomorphic())
                targetCount = POLY_TARGET_COUNT;
            if(prof.count() <= targetCount)
                return;
        }
        setSpecialized(prof);
    }

    public void setSpecialized(TypeProfile allProfiles) {
        MethodType type = this.type();
        MethodHandle elsePath = slowPath;
        elsePath = filterArguments(elsePath, 0, computeProfiler(true));
        TypeProfile[] cases = allProfiles.cases();
        int casesToCode = cases.length;
        for(int i = casesToCode - 1; i >= 0; i--) {
            MethodHandle[] guardAndFastPath = computeGuardAndFastPath(cases[i]);
            if(guardAndFastPath == null) {
                continue;
            }
            MethodHandle guard = guardAndFastPath[0];
            MethodHandle fastPath = guardAndFastPath[1];

            elsePath = guardWithTest(guard, fastPath, elsePath);
        }
        setTarget(elsePath);
    }

    private Class[] dropClasses() {
        return type().dropParameterTypes(2, type().parameterCount() - 3).parameterArray();
    }

    private final static MethodHandle INSERT_ARGUMENTS_MH = findStatic(MethodHandles.class, "insertArguments", methodType(MethodHandle.class, MethodHandle.class, int.class, Object[].class));

    protected MethodHandle[] computeGuardAndFastPath(TypeProfile prof) {
        if(prof instanceof TypeProfile.ForIdentity) {
            MethodHandle fastPath = null;

            Class[] argumentsToDrop = type().dropParameterTypes(0, 1).parameterArray();
            MethodHandle guard = dropArguments(EQ.bindTo(((TypeProfile.ForIdentity)prof).matchIdentity()), 1, argumentsToDrop);

            SephObject receiver = ((TypeProfile.ForIdentity)prof).matchValue();
            SephObject value = receiver.get(messageName);

            if(value.isActivatable()) {
                MethodHandle activation = value.activationFor(arity(), keywords());
                if(messageKind == "message") {
                    fastPath = activation;
                } else {
                    MethodHandle one = insertArguments(INSERT_ARGUMENTS_MH, 0, activation, 0);
                    MethodHandle two = one.asCollector(Object[].class, type().parameterCount());
                    MethodHandle three = two.asType(type().changeReturnType(MethodHandle.class));
                    MethodHandle four = dropArguments(dropArguments(SET_TAIL_MH, 1, SephObject.class), 3, type().dropParameterTypes(0, 2).parameterArray());
                    MethodHandle folded = foldArguments(four, three);
                    fastPath = folded;
                }
            } else {
                fastPath = dropArguments(constant(SephObject.class, value), 0, type().parameterArray());
            }

            return new MethodHandle[] {guard, fastPath};
        }

        return null;
    }

    protected SephObject profileReceiver(SephObject receiver) {
        return profileReceiver(receiver, false);
    }

    protected SephObject profileReceiverForMiss(SephObject receiver) {
        return profileReceiver(receiver, true);
    }

    protected SephObject profileReceiver(SephObject receiver, boolean sawMiss) {
        TypeProfile prof = typeProfile;
        if(prof == null) {
            typeProfile = prof = makeTypeProfile(receiver);
        } else if(!prof.matchAndIncrement(receiver)) {
            typeProfile = prof = prof.append(makeTypeProfile(receiver));
        }
        doPolicy(sawMiss);
        return receiver;
    }

    MethodHandle computeProfiler(boolean forMissPath) {
        MethodHandle profiler = (forMissPath ? MH_profileReceiverForMiss : MH_profileReceiver);
        profiler = insertArguments(profiler, 0, this);
        return profiler;
    }

    public static boolean eq(Object first, SephObject receiver) {
        return first == receiver.identity();
    }

    public static boolean ref_eq(SephObject first, SephObject second) {
        return first == second;
    }

    public static boolean int_eq(int first, int second) {
        return first == second;
    }

    private final static MethodHandle EQ = findStatic(SephCallSite.class, "eq", MethodType.methodType(boolean.class, Object.class, SephObject.class));
    private final static MethodHandle REF_EQ = findStatic(SephCallSite.class, "ref_eq", MethodType.methodType(boolean.class, SephObject.class, SephObject.class));
    private final static MethodHandle INT_EQ = findStatic(SephCallSite.class, "int_eq", MethodType.methodType(boolean.class, int.class, int.class));

    public static MethodHandle findStatic(Class target, String name, MethodType type) {
        try {
            return MethodHandles.lookup().findStatic(target, name, type);
        } catch(NoSuchMethodException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public static MethodHandle findVirtual(Class target, String name, MethodType type) {
        try {
            return MethodHandles.lookup().findVirtual(target, name, type);
        } catch(NoSuchMethodException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public static MethodHandle findArrayGetter(Class target) {
        try {
            return MethodHandles.arrayElementGetter(target);
        } catch(IllegalArgumentException e) {
            throw new RuntimeException(e);
        }
    }
}// SephCallSite

redpajama_set_name: RedPajamaGithub


text:
package com.intellij.openapi.options;

import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Factory;
import com.intellij.ui.UserActivityListener;
import com.intellij.ui.UserActivityWatcher;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.util.ArrayList;
import java.util.List;

/**
 * This class presents an abstraction of user interface transactional editor provider of some abstract data type.
 * {@link #getComponent()} should be called before {@link #resetFrom(Object)}
 */
public abstract class SettingsEditor<Settings> implements Disposable {
  private List<SettingsEditorListener<Settings>> myListeners;
  private UserActivityWatcher myWatcher;
  private UserActivityListener myUserActivityListener;
  private boolean myIsInUpdate = false;
  private Factory<Settings> mySettingsFactory;
  private CompositeSettingsEditor<Settings> myOwner;
  private JComponent myEditorComponent;

  protected abstract void resetEditorFrom(Settings s);
  protected abstract void applyEditorTo(Settings s) throws ConfigurationException;

  @NotNull
  protected abstract JComponent createEditor();
  protected abstract void disposeEditor();

  public SettingsEditor() {
    this(null);
  }

  public SettingsEditor(Factory<Settings> settingsFactory) {
    mySettingsFactory = settingsFactory;
    Disposer.register(this, new Disposable() {
      public void dispose() {
        disposeEditor();
        uninstallWatcher();
      }
    });
  }

  public Settings getSnapshot() throws ConfigurationException {
    if (myOwner != null) return myOwner.getSnapshot();

    Settings settings = mySettingsFactory.create();
    applyTo(settings);
    return settings;
  }

  final void setOwner(CompositeSettingsEditor<Settings> owner) {
    myOwner = owner;
  }

  public final CompositeSettingsEditor<Settings> getOwner() {
    return myOwner;
  }

  public Factory<Settings> getFactory() {
    return mySettingsFactory;
  }

  public final void resetFrom(Settings s) {
    myIsInUpdate = true;
    try {
      resetEditorFrom(s);
    }
    finally {
      myIsInUpdate = false;
    }
  }

  public final void applyTo(Settings s) throws ConfigurationException {
    applyEditorTo(s);
  }

  public final JComponent getComponent() {
    if (myEditorComponent == null) {
      myEditorComponent = createEditor();
      installWatcher(myEditorComponent);
    }
    return myEditorComponent;
  }

  public final void dispose() {
  }

  protected void uninstallWatcher() {
    myWatcher = null;
  }

  protected void installWatcher(JComponent c) {
    myWatcher = new UserActivityWatcher();
    myWatcher.register(c);
    myUserActivityListener = new UserActivityListener() {
      public void stateChanged() {
        fireEditorStateChanged();
      }
    };
    myWatcher.addUserActivityListener(myUserActivityListener, this);
  }

  public final void addSettingsEditorListener(SettingsEditorListener<Settings> listener) {
    if (myListeners == null) myListeners = new ArrayList<SettingsEditorListener<Settings>>();
    myListeners.add(listener);
  }

  public final void removeSettingsEditorListener(SettingsEditorListener<Settings> listener) {
    if (myListeners == null) return;
    myListeners.remove(listener);
    if (myListeners.size() == 0) myListeners = null;
  }

  protected final void fireEditorStateChanged() {
    if (myIsInUpdate || myListeners == null) return;
    SettingsEditorListener[] listeners = myListeners.toArray(new SettingsEditorListener[myListeners.size()]);
    for (int i = 0; i < listeners.length; i++) {
      listeners[i].stateChanged(this);
    }
  }
}


text:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Timers;
using System.Xml.Linq;
using NuSync.Api.Extensions;
using NuSync.Api.Helpers;
using NuSync.Api.Settings;
using Umbraco.Core;
using Umbraco.Core.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Services;

namespace NuSync.Api.Synchronizers
{
    /// <summary>
    /// syncs the data types.
    /// </summary>
    public class SyncDataType
    {
        public static void SaveToDisk(IDataTypeDefinition item)
        {
            if (item != null)
            {
                var packagingService = ApplicationContext.Current.Services.PackagingService;
                try
                {
                    var node = packagingService.Export(item);
                   // node.AddMD5Hash(true); // md5 hash of file with pre-value ids blanked.
                    node = ReplaceCotentNodes(node);
                    // content node hunting goes here....

                    XmlDoc.SaveElement("DataTypeDefinition", XmlDoc.ScrubFile(item.Name), node);
                }
                catch (Exception ex)
                {
                    LogHelper.Error<SyncDataType>(string.Format("DataType Failed {0}", item.Name), ex);
                }
            }
            else
            {
                LogHelper.Debug<SyncDataType>("Null DataType Save attempt - aborted");
            }
        }

        public static void SaveAllToDisk()
        {
            try
            {
                var sw = new Stopwatch();
                sw.Start();

                var dataTypeService = ApplicationContext.Current.Services.DataTypeService;

                foreach (var item in dataTypeService.GetAllDataTypeDefinitions() )
                {
                    if (item != null)
                    {
                        SaveToDisk(item);
                    }
                }

                sw.Stop();
                LogHelper.Info<NuSync>("Data types to disk ({0}ms)", () => sw.ElapsedMilliseconds);
            }
            catch (Exception ex)
            {
                LogHelper.Debug<SyncDataType>("Error saving all DataTypes, {0}", ()=> ex.ToString());
            }
        }

        public static void ReadAllFromDisk()
        {
            var sw = new Stopwatch();
            sw.Start();

            var path = IOHelper.MapPath(string.Format("{0}{1}",
                NuSyncIo.RootFolder,
                "DataTypeDefinition"));

            ReadFromDisk(path);

            sw.Stop();
            LogHelper.Info<NuSync>("Processed data types ({0}ms)", () => sw.ElapsedMilliseconds);
        }

        public static void ReadFromDisk(string path)
        {
            if (!Directory.Exists(path))
            {
                return;
            }

            var packagingService = ApplicationContext.Current.Services.PackagingService;

            foreach (var file in Directory.GetFiles(path, "*.config"))
            {
                var element = XElement.Load(file);

                if (!Tracker.DataTypeChanged(element))
                {
                    continue;
                }

                LogHelper.Debug<SyncDataType>("Syncing {0}", () => file);

                var name = element.Name.LocalName;

                var dataTypeElements = name.Equals("DataTypes")
                    ? (from doc in element.Elements("DataType") select doc).ToList()
                    : new List<XElement> { element };

                var dataTypeService = ApplicationContext.Current.Services.DataTypeService;

                foreach (var node in dataTypeElements)
                {
                    packagingService.ImportDataTypeDefinitions(node);

                    var def = node.Attribute("Definition");

                    if (def == null)
                    {
                        continue;
                    }

                    var dataTypeDefinitionId = new Guid(def.Value);
                    var definition = dataTypeService.GetDataTypeDefinitionById(dataTypeDefinitionId);

                    if (definition == null)
                    {
                        continue;
                    }

                    var cNode = HuntContentNodes(node);
                    UpdatePreValues(definition, cNode);
                    dataTypeService.Save(definition);
                }
            }
        }

        private static void UpdatePreValues(IDataTypeDefinition dataType, XElement node)
        {
            LogHelper.Debug<SyncDataType>("Pre-Values");

            var preValues = node.Element("PreValues");
            var dataTypeSerivce = ApplicationContext.Current.Services.DataTypeService;
            var existingPreValues = dataTypeSerivce.GetPreValuesCollectionByDataTypeId(dataType.Id).FormatAsDictionary();

            if (preValues == null)
            {
                return;
            }

            var toRemove = new List<string>();

            // alter any values (add new ones)
            foreach (var preVal in existingPreValues)
            {
                var updateVal = preValues.Elements("PreValue").FirstOrDefault(x => (x.Attribute("Alias").Value == preVal.Key));

                if (updateVal != null)
                {
                    preVal.Value.Value = updateVal.Attribute("Value").Value;
                }
                else
                {
                    // this is a delete...
                    LogHelper.Debug<SyncDataType>("Deleting pre-value {0}", ()=> preVal.Key);
                    toRemove.Add(preVal.Key);
                }
            }

            // remove the ones we don't have anymore...
            foreach (var removeKey in toRemove)
            {
                existingPreValues.Remove(removeKey);
            }

            // add the new ones..
            var valuesWithKeys = preValues.Elements("PreValue")
                .Where(x => ((string)x.Attribute("Alias")).IsNullOrWhiteSpace() == false)
                .ToDictionary(key => (string)key.Attribute("Alias"), val => (string)val.Attribute("Value"));

            foreach (var newVal in valuesWithKeys.Where(newVal => !existingPreValues.ContainsKey(newVal.Key)))
            {
                LogHelper.Debug<SyncDataType>("Adding pre-value {0}", ()=> newVal.Key);
                existingPreValues.Add(newVal.Key,new PreValue(newVal.Value));
            }

            var valuesWithoutKeys = preValues.Elements("PreValue")
                .Where(x => ((string)x.Attribute("Alias")).IsNullOrWhiteSpace())
                .Select(x => x.Attribute("Value").Value);

            dataTypeSerivce.SavePreValues(dataType, existingPreValues);
            dataTypeSerivce.SavePreValues(dataType.Id, valuesWithoutKeys);
        }

        private static Timer _saveTimer;
        private static Queue<int> _saveQueue;
        private static object _saveLock;

        public static void AttachEvents()
        {
            DataTypeService.Saved += DataTypeService_Saved;
            DataTypeService.Deleted += DataTypeService_Deleted;

            // delay trigger - used (up to and including Umbraco 7.1.4
            // saved event on a data type is called before pre-values
            // are saved - so we just wait a little while before
            // we save our datatype...
            //  not ideal but them's the breaks.
            _saveTimer = new Timer(8128); // a perfect waiting time
            _saveTimer.Elapsed += _saveTimer_Elapsed;

            _saveQueue = new Queue<int>();
            _saveLock = new object();
        }

        static void DataTypeService_Deleted(IDataTypeService sender, DeleteEventArgs<IDataTypeDefinition> e)
        {
            if (NuSync.EventsPaused)
            {
                return;
            }

            foreach (var item in e.DeletedEntities)
            {
                XmlDoc.ArchiveFile("DataTypeDefinition", XmlDoc.ScrubFile(item.Name));
            }
        }

        static void DataTypeService_Saved(IDataTypeService sender, SaveEventArgs<IDataTypeDefinition> e)
        {
            if (NuSync.EventsPaused)
            {
                return;
            }

            if (!e.SavedEntities.Any())
            {
                return;
            }

            if (uSyncSettings.dataTypeSettings.WaitAndSave)
            {
                // we lock so saves can't happen while we add to the queue.
                lock (_saveLock)
                {
                    // we reset the time, this means if two or more saves
                    // happen close together, then they will be queued up
                    // only when no data type saves have happened in the
                    // timer elapsed period will saves start to happen.
                    _saveTimer.Stop();
                    _saveTimer.Start();

                    foreach (var item in e.SavedEntities)
                    {
                        _saveQueue.Enqueue(item.Id);
                    }
                }
            }
            else
            {
                foreach (var item in e.SavedEntities)
                {
                    SaveToDisk(item);
                }
            }
        }

        static void _saveTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            // we lock so things can't be added to the queue while we save them.
            // typically a save is ~ 50ms
            lock (_saveLock)
            {
                while (_saveQueue.Count > 0)
                {
                    var dataTypeService = ApplicationContext.Current.Services.DataTypeService;

                    var typeId = _saveQueue.Dequeue();

                    var item = dataTypeService.GetDataTypeDefinitionById(typeId);

                    if (item != null)
                    {
                        SaveToDisk(item);
                    }
                }
            }
        }

        #region Node Hunting (the MultiNode Tree Picker fix)

        /// <summary>
        ///  goes through the pre-values and makes content ids portable.
        /// </summary>
        private static XElement ReplaceCotentNodes(XElement node)
        {
            XElement nodepaths = null;

            var preValueRoot = node.Element("PreValues");

            if (!preValueRoot.HasElements)
            {
                return node;
            }

            var preValues = preValueRoot.Elements("PreValue");

            foreach (var preValue in preValues)
            {
                if (!((string)preValue.Attribute("Alias")).IsNullOrWhiteSpace())
                {
                    // look for an alias name that contains a content node
                    if (uSyncSettings.dataTypeSettings.ContentPreValueAliases.Contains((string)preValue.Attribute("Alias")))
                    {
                        LogHelper.Info<SyncDataType>("Mapping Content Ids in PreValue {0}", () => preValue.Attribute("Alias"));
                        var propVal = (string)preValue.Attribute("Value");

                        if (!String.IsNullOrWhiteSpace(propVal))
                        {
                            foreach(Match m in Regex.Matches(propVal, @"\d{1,9}"))
                            {
                                int id;

                                if (int.TryParse(m.Value, out id))
                                {
                                    // we have an ID : time to do some walking...
                                    var type = "content";

                                    var cw = new ContentWalker();
                                    var nodePath = cw.GetPathFromId(id);

                                    // Didn't find the content id try media ...
                                    if (string.IsNullOrWhiteSpace(nodePath))
                                    {
                                        type = "media";
                                        var mw = new MediaWalker();
                                        nodePath = mw.GetPathFromId(id);
                                    }

                                    if (!string.IsNullOrWhiteSpace(nodePath))
                                    {
                                        // attach the node tree to the XElement
                                        if (nodepaths == null)
                                        {
                                            nodepaths = new XElement("Nodes");
                                            node.Add(nodepaths);
                                        }

                                        nodepaths.Add(new XElement("Node",
                                            new XAttribute("Id", m.Value),
                                            new XAttribute("Value", nodePath),
                                            new XAttribute("Alias", (string)preValue.Attribute("Alias")),
                                            new XAttribute("Type", type)));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return node;
        }

        /// <summary>
        ///  turns portable content ids back into static ones.
        /// </summary>
        private static XElement HuntContentNodes(XElement node)
        {
            var nodes = node.Element("Nodes");
            var preValues = node.Element("PreValues");

            if (nodes == null || preValues == null)
            {
                return node;
            }

            if (!nodes.HasElements || !preValues.HasElements)
            {
                return node;
            }

            LogHelper.Info<SyncDataType>("Mapping PreValue Content Ids to Local Content Id Values");

            foreach(var nodepath in nodes.Elements("Node"))
            {
                // go through the mapped things, and see if they are
                var alias = (string)nodepath.Attribute("Alias");

                if (String.IsNullOrWhiteSpace(alias))
                {
                    continue;
                }

                // find the alias in the preValues...
                var preVal = preValues.Elements().FirstOrDefault(x => (string)x.Attribute("Alias") == alias);

                if (preVal == null)
                {
                    continue;
                }

                var preValVal = (string)preVal.Attribute("Value");

                if (string.IsNullOrWhiteSpace(preValVal))
                {
                    continue;
                }

                LogHelper.Debug<SyncDataType>("We have the preValue (we think....) {0}", ()=> preValVal);

                var nodeidPath = (string)nodepath.Attribute("Value");
                var nodeid = (string)nodepath.Attribute("Id");

                if ( !string.IsNullOrWhiteSpace(nodeidPath)) {

                    var id = -1;

                    var nodeType = (string)nodepath.Attribute("Type");

                    switch (nodeType)
                    {
                        case "stylesheet":
                            // it's a stylesheet id - quick swapsy ...
                            // the core api - doesn't do getStyleSheetByID... so we're not doing this just yet
                            //
                            break;
                        case "media":
                            LogHelper.Debug<SyncDataType>("searching for a media node");
                            var mw = new MediaWalker();
                            id = mw.GetIdFromPath(nodeidPath);
                            break;
                        default:
                            // content
                            LogHelper.Debug<SyncDataType>("searching for a content node");
                            var cw = new ContentWalker();
                            id = cw.GetIdFromPath(nodeidPath);
                            break;
                    }

                    if (id != -1)
                    {
                        // Try to eliminate changes for changes sake.
                        if (!preValVal.Contains(nodeid) || nodeid == id.ToString())
                        {
                            continue;
                        }

                        preVal.SetAttributeValue("Value", preValVal.Replace(nodeid, id.ToString()));
                        LogHelper.Debug<SyncDataType>("Set preValue value to {0}", () => preVal.Attribute("Value"));
                    }
                    else
                    {
                        LogHelper.Debug<SyncDataType>("We didn't match the pre-value so we're leaving it alone");
                    }
                }
                else
                {
                    LogHelper.Info<SyncDataType>("Couldn't retrieve nodeIdPath from Value");
                }
            }

            return node;
        }

        #endregion
    }
}


text:
function getClosestNum(num, ar) {
    var i = 0, closest, closestDiff, currentDiff;
    closest = ar[0];
    for (i; i < ar.length; i++) {
        closestDiff = Math.abs(num - closest);
        currentDiff = Math.abs(num - ar[i]);
        if (currentDiff < closestDiff) {
            closest = ar[i];
        }
        closestDiff = null;
        currentDiff = null;
    }
    return closest;
}

var s, old_name, old_lenght, prep;

var angels_g = [177, -177, -150, -130, -129, -125, -115, -110, -105, -90, -83, -70, -50, 30, 70];

function box_and_array_to_name(box, arr, e, debug) {
    b = typeof b !== 'undefined' ? b : false;

    var boxCenter = [box.offset().left + box.width() / 2, box.offset().top + box.height() / 2];
    var to_mouse_angle = Math.atan2(e.pageX - boxCenter[0], e.pageY - boxCenter[1]) * (180 / Math.PI);
    var our_paren = $.inArray(getClosestNum(to_mouse_angle, arr), arr);

    s = our_paren + 1 + "";
    while (s.length < 3) s = "0" + s;

    if (debug) {
        console.log(s, to_mouse_angle);
    }
    return s + ".jpg"
}

function isScrolledIntoView(elem) {
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

function Utils() {

}

Utils.prototype = {
    constructor: Utils,
    isElementInView: function (element, fullyInView) {
        var pageTop = $(window).scrollTop();
        var pageBottom = pageTop + $(window).height();
        var elementTop = $(element).offset().top;
        var elementBottom = elementTop + $(element).height();

        if (fullyInView === true) {
            return ((pageTop < elementTop) && (pageBottom > elementBottom));
        } else {
            return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
        }
    }
};

var Utils = new Utils();

$(document).mousemove(function (e) {

    var names = ['alena', 'vanya', 'sasha', 'kolya', 'pasha', 'roct'];

    for (var i = 0; i < names.length; i += 1) {
        prep = $('#' + names[i] + ' img');
        old_lenght = prep.attr('src').length;
        old_name = prep.attr('src').slice(0, old_lenght - 7);
        prep.attr('src', old_name + box_and_array_to_name(prep, angels_g, e));
    }
});

var locker_shars = false;


text:
<?php

namespace Urbanplum\Bmp\Reader;

class ReaderFilesystem implements ReaderInterface
{
    /**
     * @var string
     */
    private $filepath;

    /**
     * @var resource
     */
    private $resource;

    /**
     * @param string $string
     */
    public function setFilepath($filepath)
    {
        $this->filepath = $filepath;
    }

    /**
     * @param int $length
     * @return string
     */
    public function read($length)
    {
        if (!$this->resource) {
            $this->getResource();
        }

        return fread($this->resource, $length);
    }

    private function getResource()
    {
        if (!$this->filepath) {
            throw new \RuntimeException('no filepath set, have you called setFilepath?');
        }

        $this->resource = @fopen($this->filepath, 'rb');
        if (!$this->resource) {
            throw new \RuntimeException(sprintf('unable to open [%s]', $this->filepath));
        }
    }

    /**
     * @return int
     */
    public function size()
    {
        $size = @filesize($this->filepath);
        if (!$size) {
            throw new \RuntimeException(sprintf('failed to read size from [%s]', $this->filepath));
        }

        return $size;
    }
}


text:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import os

# instantiate a chrome options object so you can set the size and headless preference
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--window-size=1920x1080")

# download the chrome driver from https://sites.google.com/a/chromium.org/chromedriver/downloads and put it in the
# current directory
chrome_driver = os.getcwd() +"\\chromedriver.exe"

### Launch:

# go to Google and click the I'm Feeling Lucky button
driver = webdriver.Chrome(chrome_options=chrome_options, executable_path=chrome_driver)
driver.get("https://www.google.com")
lucky_button = driver.find_element_by_css_selector("[name=btnI]")
lucky_button.click()

# capture the screen
driver.get_screenshot_as_file("capture.png")

# You should now have a screenshot of the I'm Feeling Lucky page in your project folder!


text:
var daysPerPage = 1;

var coreSubscriptions = new SubsManager({
  // cache recent 50 subscriptions
  cacheLimit: 50,
  // expire any subscription after 30 minutes
  // expireIn: 30
});

PostsDailyController = RouteController.extend({

  template: function() {
    return getTemplate('postsDaily');
  },

  subscriptions: function () {
    this.days = this.params.days ? this.params.days : daysPerPage;
    // this.days = Session.get('postsDays') ? Session.get('postsDays') : 3;

    var terms = {
      view: 'daily',
      days: this.days,
      after: moment().subtract(this.days, 'days').startOf('day').toDate()
    };

    this.postsSubscription = coreSubscriptions.subscribe('postsList', terms, function() {
      Session.set('postsLoaded', true);
    });

    // this.postsUsersSubscription = coreSubscriptions.subscribe('postsListUsers', terms);

  },

  data: function () {
    Session.set('postsDays', this.days);
    return {
      days: this.days
    };
  },

  getTitle: function () {
    return i18n.t('daily') + ' - ' + getSetting('title');
  },

  fastRender: true
});

Meteor.startup(function () {

  Router.route('/daily/:days?', {
    name: 'postsDaily',
    controller: PostsDailyController
  });

});


text:
package smplweb

import (
  "net/http"
  "regexp"
)

type PathConfig struct {
  Template string
  Static string
  Redirect string
}

var paths PathConfig

func SetPathConfig(c *PathConfig) {
  paths = PathConfig{
    Template: c.Template,
    Static: c.Static,
    Redirect: c.Redirect,
  }
}

func MakeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
  return func(w http.ResponseWriter, r *http.Request) {
    m := GetPath(r.URL.Path)
    if m == nil {
      http.Redirect(w, r, paths.Redirect, http.StatusFound)
      return
    }
    fn(w, r, m[2])
  }
}

//Make sure the requested path is what we expect and return items from path
var validPath = regexp.MustCompile("^/(about|contact|index|howto)/([a-zA-Z0-9]+)$")

func GetPath (path string) []string{
  return validPath.FindStringSubmatch(path)
}


text:
package routers

import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.Directives._

/**
  * All routers (in package routers) are combined here in MainRouter
  */
class MainRouter(routers: Router*) extends Router {
  override def route: Route = {
    routers.reduce((r1, r2) => (r1.route ~ r2.route).asInstanceOf[Router]).route
  }
}


text:
'''
Tests for intuition.data.universe
'''

import os
import unittest
from nose.tools import eq_
import dna.test_utils
import intuition.data.forex as forex

class TruefxUtilsTestCase(unittest.TestCase):

    def test__clean_pairs(self):
        cleaned = forex._clean_pairs('usd/gbp')
        eq_(cleaned, 'USD/GBP')
        cleaned = forex._clean_pairs(['usd/gbp', 'USD/JPY'])
        eq_(cleaned, 'USD/GBP,USD/JPY')

    def test__fx_mapping(self):
        pass

# TODO Test api calls
class TruefxTestCase(unittest.TestCase):

    def setUp(self):
        dna.test_utils.setup_logger(self)

    def tearDown(self):
        dna.test_utils.teardown_logger(self)

    def test_initialize_truefx_with_credentials(self):
        fake_credentials = 'login:pass'
        fx = forex.TrueFX(credentials=fake_credentials)
        eq_(fx._user, 'login')
        eq_(fx._pwd, 'pass')
        eq_(fx._full_snapshot, 'y')
        eq_(fx._output_format, 'csv')

    def test_initialize_truefx_with_environ(self):
        os.environ['TRUEFX_API'] = 'login:pass'
        fx = forex.TrueFX()
        eq_(fx._user, 'login')
        eq_(fx._pwd, 'pass')

    def test_initialize_truefx_without_key(self):
        os.environ.pop('TRUEFX_API', None)
        fx = forex.TrueFX()
        eq_(fx._user, '')
        eq_(fx._pwd, '')

    def test_initialize_truefx_with_pairs(self):
        fx = forex.TrueFX(pairs='usd/gbp')
        eq_(fx.state_pairs, 'USD/GBP')
        fx = forex.TrueFX(pairs=['usd/gbp', 'usd/jpy'])
        eq_(fx.state_pairs, 'USD/GBP,USD/JPY')


text:
<!DOCTYPE html>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>mne.io.read_raw_fif — MNE 0.11.0 documentation</title>

    <link rel="stylesheet" href="../_static/basic.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="../_static/gallery.css" type="text/css" />
    <link rel="stylesheet" href="../_static/bootswatch-3.3.4/flatly/bootstrap.min.css" type="text/css" />
    <link rel="stylesheet" href="../_static/bootstrap-sphinx.css" type="text/css" />
    <link rel="stylesheet" href="../_static/style.css" type="text/css" />

    <link rel="shortcut icon" href="../_static/favicon.ico"/>
    <link rel="top" title="MNE 0.11.0 documentation" href="../index.html" />
    <link rel="up" title="API Reference" href="../python_reference.html" />
    <link rel="next" title="mne.io.kit.read_mrk" href="mne.io.kit.read_mrk.html" />
    <link rel="prev" title="mne.io.read_raw_egi" href="mne.io.read_raw_egi.html" />

<link href='http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700' rel='stylesheet' type='text/css'>

  <link rel="canonical" href="https://mne.tools/stable/index.html" />

        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">

        </button>

        0.11.0

Tutorials

Gallery

Manual

API

FAQ

Cite

  Site

Getting Started

What’s new

Cite MNE

Related publications

Tutorials

Examples Gallery

Manual

API Reference

Frequently Asked Questions

Advanced installation and setup

MNE with CPP

  Page

mne.io.read_raw_fif

<form class="navbar-form navbar-right" action="../search.html" method="get">

  <input type="text" name="q" class="form-control" placeholder="Search" />

  <input type="hidden" name="check_keywords" value="yes" />
  <input type="hidden" name="area" value="default" />
</form>

mne.io.read_raw_fif

    « mne.io.read_r...

    mne.io.kit.re... »

<form action="../search.html" method="get">

  <input type="text" name="q" class="form-control" placeholder="Search" />

  <input type="hidden" name="check_keywords" value="yes" />
  <input type="hidden" name="area" value="default" />
</form>

mne.io.read_raw_fif¶

mne.io.read_raw_fif(fnames, allow_maxshield=False, preload=False, proj=False, compensation=None, add_eeg_ref=True, verbose=None)¶

Reader function for Raw FIF data

<col class="field-name" />
<col class="field-body" />

Parameters:
fnames : list, or string

A list of the raw files to treat as a Raw instance, or a single
raw file. For files that have automatically been split, only the
name of the first file has to be specified. Filenames should end
with raw.fif, raw.fif.gz, raw_sss.fif, raw_sss.fif.gz,
raw_tsss.fif or raw_tsss.fif.gz.

allow_maxshield : bool, (default False)

allow_maxshield if True, allow loading of data that has been
processed with Maxshield. Maxshield-processed data should generally
not be loaded directly, but should be processed using SSS first.

preload : bool or str (default False)

Preload data into memory for data manipulation and faster indexing.
If True, the data will be preloaded into memory (fast, requires
large amount of memory). If preload is a string, preload is the
file name of a memory-mapped file which is used to store the data
on the hard drive (slower, requires less memory).

proj : bool

Apply the signal space projection (SSP) operators present in
the file to the data. Note: Once the projectors have been
applied, they can no longer be removed. It is usually not
recommended to apply the projectors at this point as they are
applied automatically later on (e.g. when computing inverse
solutions).

compensation : None | int

If None the compensation in the data is not modified.
If set to n, e.g. 3, apply gradient compensation of grade n as
for CTF systems.

add_eeg_ref : bool

If True, add average EEG reference projector (if it’s not already
present).

verbose : bool, str, int, or None

If not None, override default verbose level (see mne.verbose).

Returns:
raw : Instance of RawFIF

A Raw object containing FIF data.

Notes

New in version 0.9.0.

      Back to top

        © Copyright 2012-2015, MNE Developers.