library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}
/**
 * Efinity is developed by Enjin. Enjin pioneered the NFT industry in 2017 - authors of ERC-1155, the groundbreaking NFT token standard, and the first NFT creation platform.
 *
 * Efinity is the world’s cross-chain NFT blockchain. Powered by the deflationary EFI Token, the network is environmentally friendly, scalable, and built for games, apps, enterprises and creators to deliver their own non-fungible tokens to mainstream audiences.
 * 
 * https://enjin.io/
 * 
 * https://t.me/enjin
 * 
 * https://twitter.com/enjin
 * 
 * https://www.reddit.com/r/EnjinCoin/
 
 `--:/++oooooooooooooo++/:--.                                       
 `.:/+oooooooooooooooooooooooooooooo+/:.`                                 
 `.:+oooooooooooooooooooooooooooooooooooooooo+:-`                             
 `-/oooooooooooooooooooooooooooooooooooooooooooooooo+-`                          
 `-+oooooooooooooooooooooooooooooooooooooooooooooooooooooo+-`                       
 `:oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo/.                     
 ./oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo/.                   
 `/oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo/.                 
 `:oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo:`               
 .+oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+-              
 :ooooooooooooooooooooooooo++////::::::::::::::::::::::::::://///++ooooooooooooo:             
 `/oooooooooooooooooooo+/:.```                                      ``.:ooooooooooo+`           
 `+oooooooooooooooooo/-`                                                 :ooooooooooo+`          
 `+oooooooooooooooo+-`                                                    -oooooooooooo+`         
 /oooooooooooooooo:`                                                      /ooooooooooooo+`        
 :oooooooooooooooo.                 ``..................................-:+ooooooooooooooo/        
 .oooooooooooooooo-              .-/++oooooooooooooooooooooooooooooooooooooooooooooooooooooo.       
 +ooooooooooooooo+             -+ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+       
 .oooooooooooooooo:            /oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo-      
 /oooooooooooooooo-           :ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo/      
 ooooooooooooooooo-           :+++++++++++++++++++++++++++++++++++++++++++ooooooooooooooooooooo`     
 ooooooooooooooooo-           `````````````````````````````````````````````-+oooooooooooooooooo.     
 ooooooooooooooooo-                                                          /ooooooooooooooooo-     
 ooooooooooooooooo-                                                          -ooooooooooooooooo-     
 ooooooooooooooooo-                                                          /ooooooooooooooooo-     
 ooooooooooooooooo-                                                      ``./oooooooooooooooooo.     
 ooooooooooooooooo-           :++++++++++++++++++++++++++++++++++++++++++++oooooooooooooooooooo`     
 /oooooooooooooooo-           :ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+      
 .oooooooooooooooo:           `/oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo-      
 +ooooooooooooooo+             -+ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+       
 .oooooooooooooooo-              .:/++oooooooooooooooooooooooooooooooooooooooooooooooooooooo-       
 :oooooooooooooooo.                 ``.................................--:+ooooooooooooooo/        
 +oooooooooooooooo-                                                      `+ooooooooooooo+`        
 `+oooooooooooooooo+-`                                                    -oooooooooooo+`         
 `+ooooooooooooooooo+:.`                                                 -ooooooooooo+`          
 `/oooooooooooooooooooo+:-.``                                       ``.:ooooooooooo+`           
 :ooooooooooooooooooooooooo+///:::::::::::::::::::::::::::::::////+ooooooooooooo/`            
 -+ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo-              
 `/oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo/`               
 ./oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+.                 
 .+oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+-                   
 ./oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo/.                     
 `-+oooooooooooooooooooooooooooooooooooooooooooooooooooooo+:`                       
 .:+oooooooooooooooooooooooooooooooooooooooooooooooo+:.                          
 `-/+ooooooooooooooooooooooooooooooooooooooooo/-`                             
 `-:+oooooooooooooooooooooooooooooooo+:-`                                 
 `.-:/++oooooooooooooooo++/:-.`                                      
 ```......```                                               
 
 * 
 * 
 * 
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }
/**
 * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
 * overflow (when the result is negative).
 *
 * Counterpart to Solidity's `-` operator.
 *
 * Requirements:
 * - Subtraction cannot overflow.
 *
 * _Available since v2.4.0._
 */