contract BonusableCrowdsale is Consts, Crowdsale {
    /**
     * @dev Override to extend the way in which ether is converted to tokens.
     * @param _weiAmount Value in wei to be converted into tokens
     * @return Number of tokens that can be purchased with the specified _weiAmount
     */
    function _getTokenAmount(uint256 _weiAmount)
        internal view returns (uint256)
    {
        uint256 bonusRate = getBonusRate(_weiAmount);
        return _weiAmount.mul(bonusRate).div(1 ether);
    }

    function getBonusRate(uint256 _weiAmount) internal view returns (uint256) {
        uint256 bonusRate = rate;

        
        // apply bonus for time & weiRaised
        uint[3] memory weiRaisedStartsBounds = [uint(11111111111111111111111),uint(111111111111111111111111),uint(1000000000000000000000000)];
        uint[3] memory weiRaisedEndsBounds = [uint(111111111111111111111111),uint(1000000000000000000000000),uint(1111111111111111111111111)];
        uint64[3] memory timeStartsBounds = [uint64(1577856000),uint64(1577856000),uint64(1577856000)];
        uint64[3] memory timeEndsBounds = [uint64(1641005935),uint64(1641005935),uint64(1641005935)];
        uint[3] memory weiRaisedAndTimeRates = [uint(100),uint(150),uint(250)];

        for (uint i = 0; i < 3; i++) {
            bool weiRaisedInBound = (weiRaisedStartsBounds[i] <= weiRaised) && (weiRaised < weiRaisedEndsBounds[i]);
            bool timeInBound = (timeStartsBounds[i] <= now) && (now < timeEndsBounds[i]);
            if (weiRaisedInBound && timeInBound) {
                bonusRate += bonusRate * weiRaisedAndTimeRates[i] / 1000;
            }
        }
        

        

        return bonusRate;
    }
}
function _getTokenAmount(uint256 _weiAmount)
    internal view returns (uint256)
{
    uint256 bonusRate = getBonusRate(_weiAmount);
    return _weiAmount.mul(bonusRate).div(1 ether);
}

/**
 * @dev Override to extend the way in which ether is converted to tokens.
 * @param _weiAmount Value in wei to be converted into tokens
 * @return Number of tokens that can be purchased with the specified _weiAmount
 */