contract BankorusToken is ERC20Capped, ERC20Pausable, ERC20Detailed {
    event PausedAddress(address pausedAddress, address acount);
    event UnpausedAddress(address unpausedAddress, address acount);

    event ApproveBurnEvent(address owner, address burner, uint256 amount);

    mapping(address => bool) _pausedAddress;

    mapping(address => mapping(address => uint256)) _burnApproved;

    constructor()
    ERC20Capped(3500000000000000)
    ERC20Pausable()
    ERC20Detailed("Bankorus Token", "BKTS", 8)
    public {}

    /**
     * @dev Modifier to make a function callable only when the account is not paused.
     */
    modifier whenAddressIsNotPuased(address to) {
        require(!_pausedAddress[msg.sender]);
        require(!_pausedAddress[to]);
        _;
    }

    /**
     * @dev true if the account is paused, false otherwise.
     */
    function addressPaused(address account) public view returns (bool) {
        return _pausedAddress[account];
    }

     /**
     * @dev called by the owner to pause an address, returns to normal state
     */
    function pauseAddress(address pausedAddress) public onlyPauser whenNotPaused{
        _pausedAddress[pausedAddress] = true;
        emit PausedAddress(pausedAddress, msg.sender);
    }

    /**
     * @dev called by the owner to unpause an address, returns to normal state
     */
    function unpauseAddress(address unpausedAddress) public onlyPauser whenNotPaused {
        _pausedAddress[unpausedAddress] = false;
        emit UnpausedAddress(unpausedAddress, msg.sender);
    }

    function transfer(address to, uint256 value) public whenAddressIsNotPuased(to) returns (bool) {
        return super.transfer(to, value);
    }

    function transferFrom(address from, address to, uint256 value) public whenAddressIsNotPuased(to) returns (bool) {
        require(!_pausedAddress[from]);
        return super.transferFrom(from, to, value);
    }

    function approve(address spender, uint256 value) public whenAddressIsNotPuased(spender) returns (bool) {
        return super.approve(spender, value);
    }

    function increaseAllowance(address spender, uint addedValue) public whenAddressIsNotPuased(spender) returns (bool) {
        return super.increaseAllowance(spender, addedValue);
    }

    function decreaseAllowance(address spender, uint subtractedValue) public whenAddressIsNotPuased(spender) returns (bool) {
        return super.decreaseAllowance(spender, subtractedValue);
    }

    /**
     * @dev Destoys `amount` tokens from the caller.
     *
     * See `ERC20._burn`.
     */
    function burn(uint256 amount) public whenNotPaused {
        _burn(msg.sender, amount);
    }


    /**
     * @dev allow account to burn `amount` tokens 
     * Requirements:
     * - `burner` cannot be zero address
     * - 
     */
    function approveBurn(address burner, uint256 amount) public returns (bool) {
        require(burner != address(0));
        require(amount > 0);
        _burnApproved[msg.sender][burner] = amount;
    }

    /**
     * @dev See `ERC20._burnFrom`.
     */
    function burnFrom(address from, uint256 amount) public whenNotPaused {
        require(from != address(0));
        require(amount > 0);
        _burnApproved[from][msg.sender] = _burnApproved[from][msg.sender].sub(amount);
        _burnFrom(from, amount);
    }

    /**
     * @dev batchMint
     */

    function batchMint(address[] memory accounts, uint256[] memory amounts) public whenNotPaused onlyMinter {
        require(accounts.length == amounts.length);
        require(accounts.length < 50);

        for (uint i = 0; i < accounts.length; i++) {
            mint(accounts[i], amounts[i]);
        }
        
    }
}
function approveBurn(address burner, uint256 amount) public returns (bool) {
    require(burner != address(0));
    require(amount > 0);
    _burnApproved[msg.sender][burner] = amount;
}

/**
 * @dev allow account to burn `amount` tokens 
 * Requirements:
 * - `burner` cannot be zero address
 * - 
 */