func: function buyTokens(address beneficiary) public whenNotPaused payable {
          require(startTime <= now && now <= endTime);
  
          uint weiAmount = msg.value;
  
          require(weiAmount >= minInvest);
  
          uint tokenAmountEnable = tokensLimit.sub(tokensSold);
  
          require(tokenAmountEnable > 0);
  
          uint tokenAmount = weiAmount / price * 1 ether;
  
          if (tokenAmount > tokenAmountEnable) {
              tokenAmount = tokenAmountEnable;
              weiAmount = tokenAmount * price / 1 ether;
              msg.sender.transfer(msg.value.sub(weiAmount));
  
  
              if (msg.data.length > 0) {
                  Promo storage promo = promoMap[sha3(msg.data)];
                  if (promo.enable && promo.dealerPercentETH > 0) {
                      uint dealerEthAmount = weiAmount * promo.dealerPercentETH / 10000;
                      promo.dealer.transfer(dealerEthAmount);
                      weiAmount = weiAmount.sub(dealerEthAmount);
  
                      promo.dealerEthAmount += dealerEthAmount;
                  }
              }
          }
          else {
              uint countBonusAmount = tokenAmount * getCountBonus(weiAmount) / 1000;
              uint timeBonusAmount = tokenAmount * getTimeBonus(now) / 1000;
  
              if (msg.data.length > 0) {
                  bytes32 promoPublicKey = sha3(msg.data);
                  promo = promoMap[promoPublicKey];
                  if (promo.enable) {
                      
                      promo.buyCount++;
                      promo.investorTokenAmount += tokenAmount;
                      promo.investorEthAmount += weiAmount;
                      
                      if (promo.dealerPercentToken > 0) {
                          uint dealerTokenAmount = tokenAmount * promo.dealerPercentToken / 10000;
                          sendTokens(promo.dealer, dealerTokenAmount);
                          promo.dealerTokenAmount += dealerTokenAmount;
                      }
  
                      if (promo.dealerPercentETH > 0) {
                          dealerEthAmount = weiAmount * promo.dealerPercentETH / 10000;
                          promo.dealer.transfer(dealerEthAmount);
                          weiAmount = weiAmount.sub(dealerEthAmount);
                          promo.dealerEthAmount += dealerEthAmount;
                      }
  
                          
                      if (promo.investorPercentToken > 0) {
                          uint promoBonusAmount = tokenAmount * promo.investorPercentToken / 10000;
                          tokenAmount += promoBonusAmount;
                      }
  
                  }
              }
  
              tokenAmount += countBonusAmount + timeBonusAmount;
  
              if (tokenAmount > tokenAmountEnable) {
                  tokenAmount = tokenAmountEnable;
              }
          }
  
  
          if (purchaseTokens[beneficiary] == 0) investorCount++;
  
          purchaseTokens[beneficiary] = purchaseTokens[beneficiary].add(tokenAmount);
  
          sendTokens(beneficiary, tokenAmount);
  
          weiRaised = weiRaised.add(weiAmount);
  
          TokenPurchase(msg.sender, beneficiary, weiAmount, tokenAmount);
      }