func: (isAgent(spender) && super._isApprovedOrOwner(tx.origin, tokenId)) ||
      
      owner() == spender
      );
    }
  
  
    
    function mint(address to, uint256 genes, uint256 level) public onlyAgent returns (uint) {
      lastId = lastId.add(1);
      return mint(lastId, to, genes, level);
  
  
  
  
    }
  
    
    function mint(uint256 tokenId, address to, uint256 genes, uint256 level) public onlyAgent returns (uint) {
      _mint(to, tokenId);
      _setMetadata(tokenId, genes, level);
      emit Mint(to, tokenId);
      return tokenId;
    }
  
  
    
    function burn(uint256 tokenId) public returns (uint) {
      require(_isApprovedOrOwner(msg.sender, tokenId));
      address owner = ownerOf(tokenId);
      _clearMetadata(tokenId);
      _burn(owner, tokenId);
      emit Burn(owner, tokenId);
      return tokenId;
    }
  
  
    
  
    function addWin(uint256 _tokenId, uint _winsCount, uint _levelUp) external onlyAgent returns (bool){
      require(_addWin(_tokenId, _winsCount, _levelUp));
      return true;
    }
  
    function addLoss(uint256 _tokenId, uint _lossesCount, uint _levelDown) external onlyAgent returns (bool){
      require(_addLoss(_tokenId, _lossesCount, _levelDown));
      return true;
    }
  
    
  
    
    function lock(uint256 _tokenId, uint256 _lockedTo, bool _onlyFreeze) external onlyAgent returns(bool) {
      require(_exists(_tokenId));
      uint agentId = getAgentId(msg.sender);
      Character storage c = characters[_tokenId];
      if (c.lockId != 0 && agentId != c.lockId) {
        
        address a = getAgentById(c.lockId);
        if (isAgentHasAllowance(a)) {
          AgentContract ac = AgentContract(a);
          require(ac.isAllowed(_tokenId));
        }
      }