contract liyk002Token is StandardToken, Ownable{
    
    string public version = "v1.0";
    string public name = "liyk002Token";
    string public symbol = "lyk2";
    string public website = "https://www.liyk002Token.com";
    uint8 public  decimals = 18;

    mapping(address=>uint256)  lockedBalance;
    mapping(address=>uint)     timeRelease; 
    
    uint256 internal constant INITIAL_SUPPLY = 100 * (10**8) * (10**18);
    
    //address public developer;
    //uint256 internal crowdsaleAvaible;


    event Burn(address indexed burner, uint256 value);
    event Lock(address indexed locker, uint256 value, uint releaseTime);
    event UnLock(address indexed unlocker, uint256 value);
    

    // constructor
    constructor() public { 
        address onwer = msg.sender;
        balances[onwer] = INITIAL_SUPPLY;
        totalSupply = INITIAL_SUPPLY;
    }

    //balance of locked
    function lockedOf(address _owner) public constant returns (uint256 balance) {
        return lockedBalance[_owner];
    }

    //release time of locked
    function unlockTimeOf(address _owner) public constant returns (uint timelimit) {
        return timeRelease[_owner];
    }


    // transfer to and lock it
    function transferAndLock(address _to, uint256 _value, uint _releaseTime) public returns (bool success) {
        require(_to != 0x0);
        require(_value <= balances[msg.sender]);
        require(_value > 0);
        require(_releaseTime > now && _releaseTime <= now + 60*60*24*365*5);

        // SafeMath.sub will throw if there is not enough balance.
        balances[msg.sender] = balances[msg.sender].sub(_value);
       
        //if preLock can release 
        uint preRelease = timeRelease[_to];
        if (preRelease <= now && preRelease != 0x0) {
            balances[_to] = balances[_to].add(lockedBalance[_to]);
            lockedBalance[_to] = 0;
        }

        lockedBalance[_to] = lockedBalance[_to].add(_value);
        timeRelease[_to] =  _releaseTime >= timeRelease[_to] ? _releaseTime : timeRelease[_to]; 
        emit Transfer(msg.sender, _to, _value);
        emit Lock(_to, _value, _releaseTime);
        return true;
    }


   /**
   * @notice Transfers tokens held by lock.
   */
   function unlock() public  payable returns (bool success) {
        uint256 amount = lockedBalance[msg.sender];
        require(amount > 0);
        require(now >= timeRelease[msg.sender]);

        balances[msg.sender] = balances[msg.sender].add(amount);
        lockedBalance[msg.sender] = 0;
        timeRelease[msg.sender] = 0;

        emit Transfer(0x0, msg.sender, amount);
        emit UnLock(msg.sender, amount);

        return true;

    }


    /**
     * @dev Burns a specific amount of tokens.
     * @param _value The amount of token to be burned.
     */
    function burn(uint256 _value) public returns (bool success) {
        require(_value > 0);
        require(_value <= balances[msg.sender]);
    
        address burner = msg.sender;
        balances[burner] = balances[burner].sub(_value);
        totalSupply = totalSupply.sub(_value);
        emit Burn(burner, _value);
        return true;
    }

    


}
function unlock() public  payable returns (bool success) {
     uint256 amount = lockedBalance[msg.sender];
     require(amount > 0);
     require(now >= timeRelease[msg.sender]);

     balances[msg.sender] = balances[msg.sender].add(amount);
     lockedBalance[msg.sender] = 0;
     timeRelease[msg.sender] = 0;

     emit Transfer(0x0, msg.sender, amount);
     emit UnLock(msg.sender, amount);

     return true;

 }

/**
 * @notice Transfers tokens held by lock.
 */