ETH Price: $2,345.68 (+0.12%)

Token

GPTMutants (GPT-M)
 

Overview

Max Total Supply

1,500 GPT-M

Holders

21

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
60 GPT-M
0x20941aed79456169052419633c1b3721d627a890
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
GPTMutants

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-01-25
*/

// File: IGPTCore.sol


pragma solidity 0.8.17;

interface IGPTCore {

}
// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

// File: @openzeppelin/contracts/utils/Strings.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)

pragma solidity ^0.8.0;


/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/utils/Address.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not token owner or approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
        _safeTransfer(from, to, tokenId, data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _ownerOf(tokenId) != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId, 1);

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

        _afterTokenTransfer(address(0), to, tokenId, 1);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId, 1);

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);

        _afterTokenTransfer(owner, address(0), tokenId, 1);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits an {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256, /* firstTokenId */
        uint256 batchSize
    ) internal virtual {
        if (batchSize > 1) {
            if (from != address(0)) {
                _balances[from] -= batchSize;
            }
            if (to != address(0)) {
                _balances[to] += batchSize;
            }
        }
    }

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721URIStorage.sol)

pragma solidity ^0.8.0;


/**
 * @dev ERC721 token with storage based token URI management.
 */
abstract contract ERC721URIStorage is ERC721 {
    using Strings for uint256;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }

        return super.tokenURI(tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev See {ERC721-_burn}. This override additionally checks to see if a
     * token-specific URI was set for the token, and if so, it deletes the token URI from
     * the storage mapping.
     */
    function _burn(uint256 tokenId) internal virtual override {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, firstTokenId, batchSize);

        if (batchSize > 1) {
            // Will only trigger during construction. Batch transferring (minting) is not available afterwards.
            revert("ERC721Enumerable: consecutive transfers not supported");
        }

        uint256 tokenId = firstTokenId;

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: GPTMutants.sol



pragma solidity ^0.8.17;






contract GPTMutants is ERC721Enumerable, ERC721URIStorage, Ownable, IGPTCore  {
    uint constant public maxSupply = 1500;
    uint public currentSupply;
    uint public PRICE = 0.01 ether;
    uint16[1500] public ids;
    uint16 private index;
    uint randNonce;
    uint lockCounter;
    address gameContract;

    string public baseURI;
    bool public paused = true;
    bool public burnOn = false;
    mapping(uint => string) public _tokenURIs;
    mapping(uint => bool) public mintedNFTs;

    uint[] public randomArray;
    uint[] public mintedArray;

    constructor(string memory baseURI_) ERC721("GPTMutants", "GPT-M") {
        baseURI = baseURI_;
    }
    
    modifier callerIsUser() {require(tx.origin == msg.sender, "No contract minting allowed!");_;}
    modifier onlyGame {require(tx.origin == gameContract, "Only callable by the game contract");_;}
    
    function setGame(address gameAddress) external onlyOwner
    {
        gameContract = gameAddress;
    }

    function totalMinted() external view returns(uint)
    {
        return currentSupply;
    }

    function uris(uint tokenId) external view returns(string memory, string memory)
    {
        return(baseURI,_tokenURIs[tokenId]);
    }


    function mint(uint amount) external payable {
        require(!paused, "Minting not started yet");
        require(msg.sender.balance >= PRICE * amount, "Not enough money to mint");
        require(msg.value >= PRICE * amount, "Not enough ETH sent: check price.");
        require(currentSupply + amount <= maxSupply, "Not enough NFTs left");
        for (uint i = 0; i < amount; i++) {
            randNonce++;
            uint result = _pickRandomUniqueId(uint(keccak256(abi.encodePacked(block.difficulty, randNonce, block.timestamp))));
            mintedNFTs[result] = true;
            mintedArray.push(result);
            string memory thisTokenURI = Strings.toString(result);
            //Mint token
            _safeMint(msg.sender, result);
            setTokenURI(result, thisTokenURI);
            currentSupply++;
        }
    }
 
    function _pickRandomUniqueId(uint256 random) internal returns (uint256 id) {
        uint256 len = ids.length - index++;
        require(len > 0, 'no ids left');
        uint256 randomIndex = random % len;
        id = ids[randomIndex] != 0 ? ids[randomIndex] : randomIndex;
        ids[randomIndex] = uint16(ids[len - 1] == 0 ? len - 1 : ids[len - 1]);
        ids[len - 1] = 0;
    }

    function premint(uint tokenId) external payable onlyOwner {
        require(paused, "True minting started!");
        require(currentSupply<= maxSupply, "Not enough NFTs left");
        uint256 id;
        uint256 len = ids.length - index++;
        require(len > 0, 'no ids left');
        id = ids[tokenId] != 0 ? ids[tokenId] : tokenId;
        ids[tokenId] = uint16(ids[len - 1] == 0 ? len - 1 : ids[len - 1]);
        ids[len - 1] = 0;
        mintedNFTs[id] = true;
        mintedArray.push(id);
        string memory thisTokenURI = Strings.toString(id);
        //Mint token
         _safeMint(msg.sender, id);
        setTokenURI(id, thisTokenURI);
        currentSupply++;
    }

    function setTokenURI(uint tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    function setPaused(bool _paused) public onlyOwner {
        paused = _paused;
    }

    function setBurnOn(bool _burnOn) public onlyOwner {
        burnOn = _burnOn;
    }

    function setBaseURI(string memory _uri) public onlyOwner {
        baseURI = _uri;
    }

    function walletOfOwner(address _owner) external view returns (uint[] memory)
    {
        uint ownerTokenCount = balanceOf(_owner);
        uint[] memory ownedTokenIds = new uint[](ownerTokenCount);
        uint currentTokenId = 1;
        uint ownedTokenIndex = 0;

        while (ownedTokenIndex < ownerTokenCount && currentTokenId <= maxSupply) {
            if (_exists(currentTokenId) == false) {
            currentTokenId++;
            continue;
            }
            address currentTokenOwner = ownerOf(currentTokenId);
            if (currentTokenOwner == _owner) {
            ownedTokenIds[ownedTokenIndex] = currentTokenId;

            ownedTokenIndex++;
            }

            currentTokenId++;
        }
        
        return ownedTokenIds;
    }

    function withdrawAll() public onlyOwner {
        require(address(this).balance > 0 , "Insufficent balance");
        payable(msg.sender).transfer(address(this).balance);
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, ERC721Enumerable) returns (bool) {
        return super.supportsInterface(interfaceId);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint tokenId,
        uint nextthing
    ) internal virtual override(ERC721,ERC721Enumerable) {}

    function burnToken(uint tokenId) public {
        require(msg.sender == ownerOf(tokenId), "You are not the owner of this NFT");
        require(burnOn == true, "Burning is not enabled!");
        _burn(tokenId);
    }

    function _burn(uint tokenId) internal virtual override(ERC721,ERC721URIStorage) {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }

    function totalSupply() public view virtual override returns (uint)
    {
        return maxSupply;
    }

    function tokenURI(uint tokenId) public view virtual override(ERC721,ERC721URIStorage) returns (string memory) {
        _requireMinted(tokenId);

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = baseURI;

        return string(abi.encodePacked(base, _tokenURI));

    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_tokenURIs","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnOn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burnToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ids","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mintedArray","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mintedNFTs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"premint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"randomArray","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_burnOn","type":"bool"}],"name":"setBurnOn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"gameAddress","type":"address"}],"name":"setGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uris","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052662386f26fc10000600d556001607160006101000a81548160ff0219169083151502179055506000607160016101000a81548160ff0219169083151502179055503480156200005257600080fd5b5060405162005681380380620056818339818101604052810190620000789190620003a4565b6040518060400160405280600a81526020017f4750544d7574616e7473000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f4750542d4d0000000000000000000000000000000000000000000000000000008152508160009081620000f5919062000640565b50806001908162000107919062000640565b5050506200012a6200011e6200014360201b60201c565b6200014b60201b60201c565b80607090816200013b919062000640565b505062000727565b600033905090565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200027a826200022f565b810181811067ffffffffffffffff821117156200029c576200029b62000240565b5b80604052505050565b6000620002b162000211565b9050620002bf82826200026f565b919050565b600067ffffffffffffffff821115620002e257620002e162000240565b5b620002ed826200022f565b9050602081019050919050565b60005b838110156200031a578082015181840152602081019050620002fd565b60008484015250505050565b60006200033d6200033784620002c4565b620002a5565b9050828152602081018484840111156200035c576200035b6200022a565b5b62000369848285620002fa565b509392505050565b600082601f83011262000389576200038862000225565b5b81516200039b84826020860162000326565b91505092915050565b600060208284031215620003bd57620003bc6200021b565b5b600082015167ffffffffffffffff811115620003de57620003dd62000220565b5b620003ec8482850162000371565b91505092915050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200044857607f821691505b6020821081036200045e576200045d62000400565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004c87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000489565b620004d4868362000489565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620005216200051b6200051584620004ec565b620004f6565b620004ec565b9050919050565b6000819050919050565b6200053d8362000500565b620005556200054c8262000528565b84845462000496565b825550505050565b600090565b6200056c6200055d565b6200057981848462000532565b505050565b5b81811015620005a1576200059560008262000562565b6001810190506200057f565b5050565b601f821115620005f057620005ba8162000464565b620005c58462000479565b81016020851015620005d5578190505b620005ed620005e48562000479565b8301826200057e565b50505b505050565b600082821c905092915050565b60006200061560001984600802620005f5565b1980831691505092915050565b600062000630838362000602565b9150826002028217905092915050565b6200064b82620003f5565b67ffffffffffffffff81111562000667576200066662000240565b5b6200067382546200042f565b62000680828285620005a5565b600060209050601f831160018114620006b85760008415620006a3578287015190505b620006af858262000622565b8655506200071f565b601f198416620006c88662000464565b60005b82811015620006f257848901518255600182019150602085019450602081019050620006cb565b868310156200071257848901516200070e601f89168262000602565b8355505b6001600288020188555050505b505050505050565b614f4a80620007376000396000f3fe6080604052600436106102465760003560e01c806370a08231116101395780639d5aef30116100b6578063c87b56dd1161007a578063c87b56dd14610899578063d036c544146108d6578063d5abeb0114610913578063e985e9c51461093e578063f2fde38b1461097b578063fac333ac146109a457610246565b80639d5aef30146107e4578063a0712d6814610800578063a22cb4651461081c578063a2309ff814610845578063b88d4fde1461087057610246565b8063819912a2116100fd578063819912a214610723578063853828b61461074c5780638d859f3e146107635780638da5cb5b1461078e57806395d89b41146107b957610246565b806370a082311461063e578063715018a61461067b578063771282f6146106925780637a2cb2c9146106bd5780637b47ec1a146106fa57610246565b806323b872dd116101c75780634f6ccce71161018b5780634f6ccce71461054557806355f804b3146105825780635c975abb146105ab5780636352211e146105d65780636c0360eb1461061357610246565b806323b872dd1461044e5780632f745c591461047757806342842e0e146104b4578063438b6300146104dd5780634d51f7a41461051a57610246565b80631253c5461161020e5780631253c5461461035657806316c38b3c1461039457806318160ddd146103bd5780631968b788146103e85780631ee9f1d51461041157610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f05780630bb78ec114610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d919061348d565b6109e1565b60405161027f91906134d5565b60405180910390f35b34801561029457600080fd5b5061029d6109f3565b6040516102aa9190613580565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d591906135d8565b610a85565b6040516102e79190613646565b60405180910390f35b3480156102fc57600080fd5b506103176004803603810190610312919061368d565b610acb565b005b34801561032557600080fd5b50610340600480360381019061033b91906135d8565b610be2565b60405161034d9190613580565b60405180910390f35b34801561036257600080fd5b5061037d600480360381019061037891906135d8565b610c82565b60405161038b9291906136cd565b60405180910390f35b3480156103a057600080fd5b506103bb60048036038101906103b69190613730565b610dbb565b005b3480156103c957600080fd5b506103d2610de0565b6040516103df919061376c565b60405180910390f35b3480156103f457600080fd5b5061040f600480360381019061040a9190613730565b610dea565b005b34801561041d57600080fd5b50610438600480360381019061043391906135d8565b610e0f565b60405161044591906134d5565b60405180910390f35b34801561045a57600080fd5b5061047560048036038101906104709190613787565b610e2f565b005b34801561048357600080fd5b5061049e6004803603810190610499919061368d565b610e8f565b6040516104ab919061376c565b60405180910390f35b3480156104c057600080fd5b506104db60048036038101906104d69190613787565b610f34565b005b3480156104e957600080fd5b5061050460048036038101906104ff91906137da565b610f54565b60405161051191906138c5565b60405180910390f35b34801561052657600080fd5b5061052f611085565b60405161053c91906134d5565b60405180910390f35b34801561055157600080fd5b5061056c600480360381019061056791906135d8565b611098565b604051610579919061376c565b60405180910390f35b34801561058e57600080fd5b506105a960048036038101906105a49190613a1c565b611109565b005b3480156105b757600080fd5b506105c0611124565b6040516105cd91906134d5565b60405180910390f35b3480156105e257600080fd5b506105fd60048036038101906105f891906135d8565b611137565b60405161060a9190613646565b60405180910390f35b34801561061f57600080fd5b506106286111bd565b6040516106359190613580565b60405180910390f35b34801561064a57600080fd5b50610665600480360381019061066091906137da565b61124b565b604051610672919061376c565b60405180910390f35b34801561068757600080fd5b50610690611302565b005b34801561069e57600080fd5b506106a7611316565b6040516106b4919061376c565b60405180910390f35b3480156106c957600080fd5b506106e460048036038101906106df91906135d8565b61131c565b6040516106f1919061376c565b60405180910390f35b34801561070657600080fd5b50610721600480360381019061071c91906135d8565b611340565b005b34801561072f57600080fd5b5061074a600480360381019061074591906137da565b611418565b005b34801561075857600080fd5b50610761611464565b005b34801561076f57600080fd5b506107786114f8565b604051610785919061376c565b60405180910390f35b34801561079a57600080fd5b506107a36114fe565b6040516107b09190613646565b60405180910390f35b3480156107c557600080fd5b506107ce611528565b6040516107db9190613580565b60405180910390f35b6107fe60048036038101906107f991906135d8565b6115ba565b005b61081a600480360381019061081591906135d8565b61190f565b005b34801561082857600080fd5b50610843600480360381019061083e9190613a65565b611b6e565b005b34801561085157600080fd5b5061085a611b84565b604051610867919061376c565b60405180910390f35b34801561087c57600080fd5b5061089760048036038101906108929190613b46565b611b8e565b005b3480156108a557600080fd5b506108c060048036038101906108bb91906135d8565b611bf0565b6040516108cd9190613580565b60405180910390f35b3480156108e257600080fd5b506108fd60048036038101906108f891906135d8565b611d55565b60405161090a919061376c565b60405180910390f35b34801561091f57600080fd5b50610928611d79565b604051610935919061376c565b60405180910390f35b34801561094a57600080fd5b5061096560048036038101906109609190613bc9565b611d7f565b60405161097291906134d5565b60405180910390f35b34801561098757600080fd5b506109a2600480360381019061099d91906137da565b611e13565b005b3480156109b057600080fd5b506109cb60048036038101906109c691906135d8565b611e96565b6040516109d89190613c26565b60405180910390f35b60006109ec82611ec5565b9050919050565b606060008054610a0290613c70565b80601f0160208091040260200160405190810160405280929190818152602001828054610a2e90613c70565b8015610a7b5780601f10610a5057610100808354040283529160200191610a7b565b820191906000526020600020905b815481529060010190602001808311610a5e57829003601f168201915b5050505050905090565b6000610a9082611f3f565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610ad682611137565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3d90613d13565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b65611f8a565b73ffffffffffffffffffffffffffffffffffffffff161480610b945750610b9381610b8e611f8a565b611d7f565b5b610bd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bca90613da5565b60405180910390fd5b610bdd8383611f92565b505050565b60726020528060005260406000206000915090508054610c0190613c70565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2d90613c70565b8015610c7a5780601f10610c4f57610100808354040283529160200191610c7a565b820191906000526020600020905b815481529060010190602001808311610c5d57829003601f168201915b505050505081565b606080607060726000858152602001908152602001600020818054610ca690613c70565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd290613c70565b8015610d1f5780601f10610cf457610100808354040283529160200191610d1f565b820191906000526020600020905b815481529060010190602001808311610d0257829003601f168201915b50505050509150808054610d3290613c70565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5e90613c70565b8015610dab5780601f10610d8057610100808354040283529160200191610dab565b820191906000526020600020905b815481529060010190602001808311610d8e57829003601f168201915b5050505050905091509150915091565b610dc361204b565b80607160006101000a81548160ff02191690831515021790555050565b60006105dc905090565b610df261204b565b80607160016101000a81548160ff02191690831515021790555050565b60736020528060005260406000206000915054906101000a900460ff1681565b610e40610e3a611f8a565b826120c9565b610e7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7690613e37565b60405180910390fd5b610e8a83838361215e565b505050565b6000610e9a8361124b565b8210610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed290613ec9565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b610f4f83838360405180602001604052806000815250611b8e565b505050565b60606000610f618361124b565b905060008167ffffffffffffffff811115610f7f57610f7e6138f1565b5b604051908082528060200260200182016040528015610fad5781602001602082028036833780820191505090505b50905060006001905060005b8381108015610fca57506105dc8211155b156110795760001515610fdc83612457565b151503610ff6578180610fee90613f18565b925050610fb9565b600061100183611137565b90508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611065578284838151811061104a57611049613f60565b5b602002602001018181525050818061106190613f18565b9250505b828061107090613f18565b93505050610fb9565b82945050505050919050565b607160019054906101000a900460ff1681565b60006110a2612498565b82106110e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110da90614001565b60405180910390fd5b600882815481106110f7576110f6613f60565b5b90600052602060002001549050919050565b61111161204b565b806070908161112091906141cd565b5050565b607160009054906101000a900460ff1681565b600080611143836124a5565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036111b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ab906142eb565b60405180910390fd5b80915050919050565b607080546111ca90613c70565b80601f01602080910402602001604051908101604052809291908181526020018280546111f690613c70565b80156112435780601f1061121857610100808354040283529160200191611243565b820191906000526020600020905b81548152906001019060200180831161122657829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036112bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b29061437d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61130a61204b565b61131460006124e2565b565b600c5481565b6074818154811061132c57600080fd5b906000526020600020016000915090505481565b61134981611137565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ad9061440f565b60405180910390fd5b60011515607160019054906101000a900460ff1615151461140c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114039061447b565b60405180910390fd5b611415816125a8565b50565b61142061204b565b80606f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61146c61204b565b600047116114af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a6906144e7565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f193505050501580156114f5573d6000803e3d6000fd5b50565b600d5481565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606001805461153790613c70565b80601f016020809104026020016040519081016040528092919081815260200182805461156390613c70565b80156115b05780601f10611585576101008083540402835291602001916115b0565b820191906000526020600020905b81548152906001019060200180831161159357829003601f168201915b5050505050905090565b6115c261204b565b607160009054906101000a900460ff16611611576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160890614553565b60405180910390fd5b6105dc600c541115611658576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164f906145bf565b60405180910390fd5b600080606c600081819054906101000a900461ffff168092919061167b906145df565b91906101000a81548161ffff021916908361ffff16021790555061ffff166105dc6116a69190614609565b9050600081116116eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e290614689565b60405180910390fd5b6000600e846105dc811061170257611701613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff160361172b578261175f565b600e836105dc81106117405761173f613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff165b91506000600e6001836117729190614609565b6105dc811061178457611783613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff16146117eb57600e6001826117b69190614609565b6105dc81106117c8576117c7613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff166117f9565b6001816117f89190614609565b5b600e846105dc811061180e5761180d613f60565b5b601091828204019190066002026101000a81548161ffff021916908361ffff1602179055506000600e6001836118449190614609565b6105dc811061185657611855613f60565b5b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555060016073600084815260200190815260200160002060006101000a81548160ff021916908315150217905550607582908060018154018082558091505060019003906000526020600020016000909190919091505560006118db836125fb565b90506118e733846126c9565b6118f183826126e7565b600c600081548092919061190490613f18565b919050555050505050565b607160009054906101000a900460ff161561195f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611956906146f5565b60405180910390fd5b80600d5461196d9190614715565b3373ffffffffffffffffffffffffffffffffffffffff163110156119c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119bd906147a3565b60405180910390fd5b80600d546119d49190614715565b341015611a16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a0d90614835565b60405180910390fd5b6105dc81600c54611a279190614855565b1115611a68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5f906145bf565b60405180910390fd5b60005b81811015611b6a57606d6000815480929190611a8690613f18565b91905055506000611ac544606d5442604051602001611aa7939291906148aa565b6040516020818303038152906040528051906020012060001c612754565b905060016073600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060758190806001815401808255809150506001900390600052602060002001600090919091909150556000611b27826125fb565b9050611b3333836126c9565b611b3d82826126e7565b600c6000815480929190611b5090613f18565b919050555050508080611b6290613f18565b915050611a6b565b5050565b611b80611b79611f8a565b838361298e565b5050565b6000600c54905090565b611b9f611b99611f8a565b836120c9565b611bde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bd590613e37565b60405180910390fd5b611bea84848484612afa565b50505050565b6060611bfb82611f3f565b6000607260008481526020019081526020016000208054611c1b90613c70565b80601f0160208091040260200160405190810160405280929190818152602001828054611c4790613c70565b8015611c945780601f10611c6957610100808354040283529160200191611c94565b820191906000526020600020905b815481529060010190602001808311611c7757829003601f168201915b50505050509050600060708054611caa90613c70565b80601f0160208091040260200160405190810160405280929190818152602001828054611cd690613c70565b8015611d235780601f10611cf857610100808354040283529160200191611d23565b820191906000526020600020905b815481529060010190602001808311611d0657829003601f168201915b505050505090508082604051602001611d3d929190614923565b60405160208183030381529060405292505050919050565b60758181548110611d6557600080fd5b906000526020600020016000915090505481565b6105dc81565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611e1b61204b565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e81906149b9565b60405180910390fd5b611e93816124e2565b50565b600e816105dc8110611ea757600080fd5b60109182820401919006600202915054906101000a900461ffff1681565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611f385750611f3782612b56565b5b9050919050565b611f4881612457565b611f87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f7e906142eb565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661200583611137565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612053611f8a565b73ffffffffffffffffffffffffffffffffffffffff166120716114fe565b73ffffffffffffffffffffffffffffffffffffffff16146120c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120be90614a25565b60405180910390fd5b565b6000806120d583611137565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061211757506121168185611d7f565b5b8061215557508373ffffffffffffffffffffffffffffffffffffffff1661213d84610a85565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661217e82611137565b73ffffffffffffffffffffffffffffffffffffffff16146121d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cb90614ab7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612243576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223a90614b49565b60405180910390fd5b6122508383836001612c38565b8273ffffffffffffffffffffffffffffffffffffffff1661227082611137565b73ffffffffffffffffffffffffffffffffffffffff16146122c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122bd90614ab7565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46124528383836001612c3e565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff16612479836124a5565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000600880549050905090565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6125b181612c44565b60006072600083815260200190815260200160002080546125d190613c70565b9050146125f8576072600082815260200190815260200160002060006125f791906133c4565b5b50565b60606000600161260a84612c97565b01905060008167ffffffffffffffff811115612629576126286138f1565b5b6040519080825280601f01601f19166020018201604052801561265b5781602001600182028036833780820191505090505b509050600082602001820190505b6001156126be578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816126b2576126b1614b69565b5b04945060008503612669575b819350505050919050565b6126e3828260405180602001604052806000815250612dea565b5050565b6126f082612457565b61272f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272690614c0a565b60405180910390fd5b8060726000848152602001908152602001600020908161274f91906141cd565b505050565b600080606c600081819054906101000a900461ffff1680929190612777906145df565b91906101000a81548161ffff021916908361ffff16021790555061ffff166105dc6127a29190614609565b9050600081116127e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127de90614689565b60405180910390fd5b600081846127f59190614c2a565b90506000600e826105dc811061280e5761280d613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff1603612837578061286b565b600e816105dc811061284c5761284b613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff165b92506000600e60018461287e9190614609565b6105dc81106128905761288f613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff16146128f757600e6001836128c29190614609565b6105dc81106128d4576128d3613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff16612905565b6001826129049190614609565b5b600e826105dc811061291a57612919613f60565b5b601091828204019190066002026101000a81548161ffff021916908361ffff1602179055506000600e6001846129509190614609565b6105dc811061296257612961613f60565b5b601091828204019190066002026101000a81548161ffff021916908361ffff1602179055505050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036129fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129f390614ca7565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612aed91906134d5565b60405180910390a3505050565b612b0584848461215e565b612b1184848484612e45565b612b50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b4790614d39565b60405180910390fd5b50505050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612c2157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612c315750612c3082612fcc565b5b9050919050565b50505050565b50505050565b612c4d81613036565b6000600a60008381526020019081526020016000208054612c6d90613c70565b905014612c9457600a60008281526020019081526020016000206000612c9391906133c4565b5b50565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612cf5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612ceb57612cea614b69565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612d32576d04ee2d6d415b85acef81000000008381612d2857612d27614b69565b5b0492506020810190505b662386f26fc100008310612d6157662386f26fc100008381612d5757612d56614b69565b5b0492506010810190505b6305f5e1008310612d8a576305f5e1008381612d8057612d7f614b69565b5b0492506008810190505b6127108310612daf576127108381612da557612da4614b69565b5b0492506004810190505b60648310612dd25760648381612dc857612dc7614b69565b5b0492506002810190505b600a8310612de1576001810190505b80915050919050565b612df48383613184565b612e016000848484612e45565b612e40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e3790614d39565b60405180910390fd5b505050565b6000612e668473ffffffffffffffffffffffffffffffffffffffff166133a1565b15612fbf578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612e8f611f8a565b8786866040518563ffffffff1660e01b8152600401612eb19493929190614dae565b6020604051808303816000875af1925050508015612eed57506040513d601f19601f82011682018060405250810190612eea9190614e0f565b60015b612f6f573d8060008114612f1d576040519150601f19603f3d011682016040523d82523d6000602084013e612f22565b606091505b506000815103612f67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5e90614d39565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612fc4565b600190505b949350505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600061304182611137565b9050613051816000846001612c38565b61305a82611137565b90506004600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613180816000846001612c3e565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036131f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131ea90614e88565b60405180910390fd5b6131fc81612457565b1561323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161323390614ef4565b60405180910390fd5b61324a600083836001612c38565b61325381612457565b15613293576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161328a90614ef4565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461339d600083836001612c3e565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5080546133d090613c70565b6000825580601f106133e25750613401565b601f0160209004906000526020600020908101906134009190613404565b5b50565b5b8082111561341d576000816000905550600101613405565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61346a81613435565b811461347557600080fd5b50565b60008135905061348781613461565b92915050565b6000602082840312156134a3576134a261342b565b5b60006134b184828501613478565b91505092915050565b60008115159050919050565b6134cf816134ba565b82525050565b60006020820190506134ea60008301846134c6565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561352a57808201518184015260208101905061350f565b60008484015250505050565b6000601f19601f8301169050919050565b6000613552826134f0565b61355c81856134fb565b935061356c81856020860161350c565b61357581613536565b840191505092915050565b6000602082019050818103600083015261359a8184613547565b905092915050565b6000819050919050565b6135b5816135a2565b81146135c057600080fd5b50565b6000813590506135d2816135ac565b92915050565b6000602082840312156135ee576135ed61342b565b5b60006135fc848285016135c3565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061363082613605565b9050919050565b61364081613625565b82525050565b600060208201905061365b6000830184613637565b92915050565b61366a81613625565b811461367557600080fd5b50565b60008135905061368781613661565b92915050565b600080604083850312156136a4576136a361342b565b5b60006136b285828601613678565b92505060206136c3858286016135c3565b9150509250929050565b600060408201905081810360008301526136e78185613547565b905081810360208301526136fb8184613547565b90509392505050565b61370d816134ba565b811461371857600080fd5b50565b60008135905061372a81613704565b92915050565b6000602082840312156137465761374561342b565b5b60006137548482850161371b565b91505092915050565b613766816135a2565b82525050565b6000602082019050613781600083018461375d565b92915050565b6000806000606084860312156137a05761379f61342b565b5b60006137ae86828701613678565b93505060206137bf86828701613678565b92505060406137d0868287016135c3565b9150509250925092565b6000602082840312156137f0576137ef61342b565b5b60006137fe84828501613678565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61383c816135a2565b82525050565b600061384e8383613833565b60208301905092915050565b6000602082019050919050565b600061387282613807565b61387c8185613812565b935061388783613823565b8060005b838110156138b857815161389f8882613842565b97506138aa8361385a565b92505060018101905061388b565b5085935050505092915050565b600060208201905081810360008301526138df8184613867565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61392982613536565b810181811067ffffffffffffffff82111715613948576139476138f1565b5b80604052505050565b600061395b613421565b90506139678282613920565b919050565b600067ffffffffffffffff821115613987576139866138f1565b5b61399082613536565b9050602081019050919050565b82818337600083830152505050565b60006139bf6139ba8461396c565b613951565b9050828152602081018484840111156139db576139da6138ec565b5b6139e684828561399d565b509392505050565b600082601f830112613a0357613a026138e7565b5b8135613a138482602086016139ac565b91505092915050565b600060208284031215613a3257613a3161342b565b5b600082013567ffffffffffffffff811115613a5057613a4f613430565b5b613a5c848285016139ee565b91505092915050565b60008060408385031215613a7c57613a7b61342b565b5b6000613a8a85828601613678565b9250506020613a9b8582860161371b565b9150509250929050565b600067ffffffffffffffff821115613ac057613abf6138f1565b5b613ac982613536565b9050602081019050919050565b6000613ae9613ae484613aa5565b613951565b905082815260208101848484011115613b0557613b046138ec565b5b613b1084828561399d565b509392505050565b600082601f830112613b2d57613b2c6138e7565b5b8135613b3d848260208601613ad6565b91505092915050565b60008060008060808587031215613b6057613b5f61342b565b5b6000613b6e87828801613678565b9450506020613b7f87828801613678565b9350506040613b90878288016135c3565b925050606085013567ffffffffffffffff811115613bb157613bb0613430565b5b613bbd87828801613b18565b91505092959194509250565b60008060408385031215613be057613bdf61342b565b5b6000613bee85828601613678565b9250506020613bff85828601613678565b9150509250929050565b600061ffff82169050919050565b613c2081613c09565b82525050565b6000602082019050613c3b6000830184613c17565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613c8857607f821691505b602082108103613c9b57613c9a613c41565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000613cfd6021836134fb565b9150613d0882613ca1565b604082019050919050565b60006020820190508181036000830152613d2c81613cf0565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000613d8f603d836134fb565b9150613d9a82613d33565b604082019050919050565b60006020820190508181036000830152613dbe81613d82565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000613e21602d836134fb565b9150613e2c82613dc5565b604082019050919050565b60006020820190508181036000830152613e5081613e14565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000613eb3602b836134fb565b9150613ebe82613e57565b604082019050919050565b60006020820190508181036000830152613ee281613ea6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f23826135a2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613f5557613f54613ee9565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000613feb602c836134fb565b9150613ff682613f8f565b604082019050919050565b6000602082019050818103600083015261401a81613fde565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026140837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614046565b61408d8683614046565b95508019841693508086168417925050509392505050565b6000819050919050565b60006140ca6140c56140c0846135a2565b6140a5565b6135a2565b9050919050565b6000819050919050565b6140e4836140af565b6140f86140f0826140d1565b848454614053565b825550505050565b600090565b61410d614100565b6141188184846140db565b505050565b5b8181101561413c57614131600082614105565b60018101905061411e565b5050565b601f8211156141815761415281614021565b61415b84614036565b8101602085101561416a578190505b61417e61417685614036565b83018261411d565b50505b505050565b600082821c905092915050565b60006141a460001984600802614186565b1980831691505092915050565b60006141bd8383614193565b9150826002028217905092915050565b6141d6826134f0565b67ffffffffffffffff8111156141ef576141ee6138f1565b5b6141f98254613c70565b614204828285614140565b600060209050601f8311600181146142375760008415614225578287015190505b61422f85826141b1565b865550614297565b601f19841661424586614021565b60005b8281101561426d57848901518255600182019150602085019450602081019050614248565b8683101561428a5784890151614286601f891682614193565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b60006142d56018836134fb565b91506142e08261429f565b602082019050919050565b60006020820190508181036000830152614304816142c8565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b60006143676029836134fb565b91506143728261430b565b604082019050919050565b600060208201905081810360008301526143968161435a565b9050919050565b7f596f7520617265206e6f7420746865206f776e6572206f662074686973204e4660008201527f5400000000000000000000000000000000000000000000000000000000000000602082015250565b60006143f96021836134fb565b91506144048261439d565b604082019050919050565b60006020820190508181036000830152614428816143ec565b9050919050565b7f4275726e696e67206973206e6f7420656e61626c656421000000000000000000600082015250565b60006144656017836134fb565b91506144708261442f565b602082019050919050565b6000602082019050818103600083015261449481614458565b9050919050565b7f496e737566666963656e742062616c616e636500000000000000000000000000600082015250565b60006144d16013836134fb565b91506144dc8261449b565b602082019050919050565b60006020820190508181036000830152614500816144c4565b9050919050565b7f54727565206d696e74696e672073746172746564210000000000000000000000600082015250565b600061453d6015836134fb565b915061454882614507565b602082019050919050565b6000602082019050818103600083015261456c81614530565b9050919050565b7f4e6f7420656e6f756768204e465473206c656674000000000000000000000000600082015250565b60006145a96014836134fb565b91506145b482614573565b602082019050919050565b600060208201905081810360008301526145d88161459c565b9050919050565b60006145ea82613c09565b915061ffff82036145fe576145fd613ee9565b5b600182019050919050565b6000614614826135a2565b915061461f836135a2565b925082820390508181111561463757614636613ee9565b5b92915050565b7f6e6f20696473206c656674000000000000000000000000000000000000000000600082015250565b6000614673600b836134fb565b915061467e8261463d565b602082019050919050565b600060208201905081810360008301526146a281614666565b9050919050565b7f4d696e74696e67206e6f74207374617274656420796574000000000000000000600082015250565b60006146df6017836134fb565b91506146ea826146a9565b602082019050919050565b6000602082019050818103600083015261470e816146d2565b9050919050565b6000614720826135a2565b915061472b836135a2565b9250828202614739816135a2565b915082820484148315176147505761474f613ee9565b5b5092915050565b7f4e6f7420656e6f756768206d6f6e657920746f206d696e740000000000000000600082015250565b600061478d6018836134fb565b915061479882614757565b602082019050919050565b600060208201905081810360008301526147bc81614780565b9050919050565b7f4e6f7420656e6f756768204554482073656e743a20636865636b20707269636560008201527f2e00000000000000000000000000000000000000000000000000000000000000602082015250565b600061481f6021836134fb565b915061482a826147c3565b604082019050919050565b6000602082019050818103600083015261484e81614812565b9050919050565b6000614860826135a2565b915061486b836135a2565b925082820190508082111561488357614882613ee9565b5b92915050565b6000819050919050565b6148a461489f826135a2565b614889565b82525050565b60006148b68286614893565b6020820191506148c68285614893565b6020820191506148d68284614893565b602082019150819050949350505050565b600081905092915050565b60006148fd826134f0565b61490781856148e7565b935061491781856020860161350c565b80840191505092915050565b600061492f82856148f2565b915061493b82846148f2565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006149a36026836134fb565b91506149ae82614947565b604082019050919050565b600060208201905081810360008301526149d281614996565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614a0f6020836134fb565b9150614a1a826149d9565b602082019050919050565b60006020820190508181036000830152614a3e81614a02565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000614aa16025836134fb565b9150614aac82614a45565b604082019050919050565b60006020820190508181036000830152614ad081614a94565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000614b336024836134fb565b9150614b3e82614ad7565b604082019050919050565b60006020820190508181036000830152614b6281614b26565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b6000614bf4602e836134fb565b9150614bff82614b98565b604082019050919050565b60006020820190508181036000830152614c2381614be7565b9050919050565b6000614c35826135a2565b9150614c40836135a2565b925082614c5057614c4f614b69565b5b828206905092915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000614c916019836134fb565b9150614c9c82614c5b565b602082019050919050565b60006020820190508181036000830152614cc081614c84565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000614d236032836134fb565b9150614d2e82614cc7565b604082019050919050565b60006020820190508181036000830152614d5281614d16565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614d8082614d59565b614d8a8185614d64565b9350614d9a81856020860161350c565b614da381613536565b840191505092915050565b6000608082019050614dc36000830187613637565b614dd06020830186613637565b614ddd604083018561375d565b8181036060830152614def8184614d75565b905095945050505050565b600081519050614e0981613461565b92915050565b600060208284031215614e2557614e2461342b565b5b6000614e3384828501614dfa565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614e726020836134fb565b9150614e7d82614e3c565b602082019050919050565b60006020820190508181036000830152614ea181614e65565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614ede601c836134fb565b9150614ee982614ea8565b602082019050919050565b60006020820190508181036000830152614f0d81614ed1565b905091905056fea2646970667358221220dace1d8caa3b7f72dff1ca25c5d252afa18099b0516d89c8c1b2faf230d190a064736f6c6343000811003300000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d5274724a396245325453334b535a386d4652346971796f4e315753366b78336f67564e3270573258524767672f00000000000000000000

Deployed Bytecode

0x6080604052600436106102465760003560e01c806370a08231116101395780639d5aef30116100b6578063c87b56dd1161007a578063c87b56dd14610899578063d036c544146108d6578063d5abeb0114610913578063e985e9c51461093e578063f2fde38b1461097b578063fac333ac146109a457610246565b80639d5aef30146107e4578063a0712d6814610800578063a22cb4651461081c578063a2309ff814610845578063b88d4fde1461087057610246565b8063819912a2116100fd578063819912a214610723578063853828b61461074c5780638d859f3e146107635780638da5cb5b1461078e57806395d89b41146107b957610246565b806370a082311461063e578063715018a61461067b578063771282f6146106925780637a2cb2c9146106bd5780637b47ec1a146106fa57610246565b806323b872dd116101c75780634f6ccce71161018b5780634f6ccce71461054557806355f804b3146105825780635c975abb146105ab5780636352211e146105d65780636c0360eb1461061357610246565b806323b872dd1461044e5780632f745c591461047757806342842e0e146104b4578063438b6300146104dd5780634d51f7a41461051a57610246565b80631253c5461161020e5780631253c5461461035657806316c38b3c1461039457806318160ddd146103bd5780631968b788146103e85780631ee9f1d51461041157610246565b806301ffc9a71461024b57806306fdde0314610288578063081812fc146102b3578063095ea7b3146102f05780630bb78ec114610319575b600080fd5b34801561025757600080fd5b50610272600480360381019061026d919061348d565b6109e1565b60405161027f91906134d5565b60405180910390f35b34801561029457600080fd5b5061029d6109f3565b6040516102aa9190613580565b60405180910390f35b3480156102bf57600080fd5b506102da60048036038101906102d591906135d8565b610a85565b6040516102e79190613646565b60405180910390f35b3480156102fc57600080fd5b506103176004803603810190610312919061368d565b610acb565b005b34801561032557600080fd5b50610340600480360381019061033b91906135d8565b610be2565b60405161034d9190613580565b60405180910390f35b34801561036257600080fd5b5061037d600480360381019061037891906135d8565b610c82565b60405161038b9291906136cd565b60405180910390f35b3480156103a057600080fd5b506103bb60048036038101906103b69190613730565b610dbb565b005b3480156103c957600080fd5b506103d2610de0565b6040516103df919061376c565b60405180910390f35b3480156103f457600080fd5b5061040f600480360381019061040a9190613730565b610dea565b005b34801561041d57600080fd5b50610438600480360381019061043391906135d8565b610e0f565b60405161044591906134d5565b60405180910390f35b34801561045a57600080fd5b5061047560048036038101906104709190613787565b610e2f565b005b34801561048357600080fd5b5061049e6004803603810190610499919061368d565b610e8f565b6040516104ab919061376c565b60405180910390f35b3480156104c057600080fd5b506104db60048036038101906104d69190613787565b610f34565b005b3480156104e957600080fd5b5061050460048036038101906104ff91906137da565b610f54565b60405161051191906138c5565b60405180910390f35b34801561052657600080fd5b5061052f611085565b60405161053c91906134d5565b60405180910390f35b34801561055157600080fd5b5061056c600480360381019061056791906135d8565b611098565b604051610579919061376c565b60405180910390f35b34801561058e57600080fd5b506105a960048036038101906105a49190613a1c565b611109565b005b3480156105b757600080fd5b506105c0611124565b6040516105cd91906134d5565b60405180910390f35b3480156105e257600080fd5b506105fd60048036038101906105f891906135d8565b611137565b60405161060a9190613646565b60405180910390f35b34801561061f57600080fd5b506106286111bd565b6040516106359190613580565b60405180910390f35b34801561064a57600080fd5b50610665600480360381019061066091906137da565b61124b565b604051610672919061376c565b60405180910390f35b34801561068757600080fd5b50610690611302565b005b34801561069e57600080fd5b506106a7611316565b6040516106b4919061376c565b60405180910390f35b3480156106c957600080fd5b506106e460048036038101906106df91906135d8565b61131c565b6040516106f1919061376c565b60405180910390f35b34801561070657600080fd5b50610721600480360381019061071c91906135d8565b611340565b005b34801561072f57600080fd5b5061074a600480360381019061074591906137da565b611418565b005b34801561075857600080fd5b50610761611464565b005b34801561076f57600080fd5b506107786114f8565b604051610785919061376c565b60405180910390f35b34801561079a57600080fd5b506107a36114fe565b6040516107b09190613646565b60405180910390f35b3480156107c557600080fd5b506107ce611528565b6040516107db9190613580565b60405180910390f35b6107fe60048036038101906107f991906135d8565b6115ba565b005b61081a600480360381019061081591906135d8565b61190f565b005b34801561082857600080fd5b50610843600480360381019061083e9190613a65565b611b6e565b005b34801561085157600080fd5b5061085a611b84565b604051610867919061376c565b60405180910390f35b34801561087c57600080fd5b5061089760048036038101906108929190613b46565b611b8e565b005b3480156108a557600080fd5b506108c060048036038101906108bb91906135d8565b611bf0565b6040516108cd9190613580565b60405180910390f35b3480156108e257600080fd5b506108fd60048036038101906108f891906135d8565b611d55565b60405161090a919061376c565b60405180910390f35b34801561091f57600080fd5b50610928611d79565b604051610935919061376c565b60405180910390f35b34801561094a57600080fd5b5061096560048036038101906109609190613bc9565b611d7f565b60405161097291906134d5565b60405180910390f35b34801561098757600080fd5b506109a2600480360381019061099d91906137da565b611e13565b005b3480156109b057600080fd5b506109cb60048036038101906109c691906135d8565b611e96565b6040516109d89190613c26565b60405180910390f35b60006109ec82611ec5565b9050919050565b606060008054610a0290613c70565b80601f0160208091040260200160405190810160405280929190818152602001828054610a2e90613c70565b8015610a7b5780601f10610a5057610100808354040283529160200191610a7b565b820191906000526020600020905b815481529060010190602001808311610a5e57829003601f168201915b5050505050905090565b6000610a9082611f3f565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610ad682611137565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610b46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3d90613d13565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b65611f8a565b73ffffffffffffffffffffffffffffffffffffffff161480610b945750610b9381610b8e611f8a565b611d7f565b5b610bd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bca90613da5565b60405180910390fd5b610bdd8383611f92565b505050565b60726020528060005260406000206000915090508054610c0190613c70565b80601f0160208091040260200160405190810160405280929190818152602001828054610c2d90613c70565b8015610c7a5780601f10610c4f57610100808354040283529160200191610c7a565b820191906000526020600020905b815481529060010190602001808311610c5d57829003601f168201915b505050505081565b606080607060726000858152602001908152602001600020818054610ca690613c70565b80601f0160208091040260200160405190810160405280929190818152602001828054610cd290613c70565b8015610d1f5780601f10610cf457610100808354040283529160200191610d1f565b820191906000526020600020905b815481529060010190602001808311610d0257829003601f168201915b50505050509150808054610d3290613c70565b80601f0160208091040260200160405190810160405280929190818152602001828054610d5e90613c70565b8015610dab5780601f10610d8057610100808354040283529160200191610dab565b820191906000526020600020905b815481529060010190602001808311610d8e57829003601f168201915b5050505050905091509150915091565b610dc361204b565b80607160006101000a81548160ff02191690831515021790555050565b60006105dc905090565b610df261204b565b80607160016101000a81548160ff02191690831515021790555050565b60736020528060005260406000206000915054906101000a900460ff1681565b610e40610e3a611f8a565b826120c9565b610e7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7690613e37565b60405180910390fd5b610e8a83838361215e565b505050565b6000610e9a8361124b565b8210610edb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed290613ec9565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b610f4f83838360405180602001604052806000815250611b8e565b505050565b60606000610f618361124b565b905060008167ffffffffffffffff811115610f7f57610f7e6138f1565b5b604051908082528060200260200182016040528015610fad5781602001602082028036833780820191505090505b50905060006001905060005b8381108015610fca57506105dc8211155b156110795760001515610fdc83612457565b151503610ff6578180610fee90613f18565b925050610fb9565b600061100183611137565b90508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611065578284838151811061104a57611049613f60565b5b602002602001018181525050818061106190613f18565b9250505b828061107090613f18565b93505050610fb9565b82945050505050919050565b607160019054906101000a900460ff1681565b60006110a2612498565b82106110e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110da90614001565b60405180910390fd5b600882815481106110f7576110f6613f60565b5b90600052602060002001549050919050565b61111161204b565b806070908161112091906141cd565b5050565b607160009054906101000a900460ff1681565b600080611143836124a5565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036111b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111ab906142eb565b60405180910390fd5b80915050919050565b607080546111ca90613c70565b80601f01602080910402602001604051908101604052809291908181526020018280546111f690613c70565b80156112435780601f1061121857610100808354040283529160200191611243565b820191906000526020600020905b81548152906001019060200180831161122657829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036112bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112b29061437d565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61130a61204b565b61131460006124e2565b565b600c5481565b6074818154811061132c57600080fd5b906000526020600020016000915090505481565b61134981611137565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146113b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ad9061440f565b60405180910390fd5b60011515607160019054906101000a900460ff1615151461140c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114039061447b565b60405180910390fd5b611415816125a8565b50565b61142061204b565b80606f60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b61146c61204b565b600047116114af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a6906144e7565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f193505050501580156114f5573d6000803e3d6000fd5b50565b600d5481565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606001805461153790613c70565b80601f016020809104026020016040519081016040528092919081815260200182805461156390613c70565b80156115b05780601f10611585576101008083540402835291602001916115b0565b820191906000526020600020905b81548152906001019060200180831161159357829003601f168201915b5050505050905090565b6115c261204b565b607160009054906101000a900460ff16611611576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160890614553565b60405180910390fd5b6105dc600c541115611658576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164f906145bf565b60405180910390fd5b600080606c600081819054906101000a900461ffff168092919061167b906145df565b91906101000a81548161ffff021916908361ffff16021790555061ffff166105dc6116a69190614609565b9050600081116116eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116e290614689565b60405180910390fd5b6000600e846105dc811061170257611701613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff160361172b578261175f565b600e836105dc81106117405761173f613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff165b91506000600e6001836117729190614609565b6105dc811061178457611783613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff16146117eb57600e6001826117b69190614609565b6105dc81106117c8576117c7613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff166117f9565b6001816117f89190614609565b5b600e846105dc811061180e5761180d613f60565b5b601091828204019190066002026101000a81548161ffff021916908361ffff1602179055506000600e6001836118449190614609565b6105dc811061185657611855613f60565b5b601091828204019190066002026101000a81548161ffff021916908361ffff16021790555060016073600084815260200190815260200160002060006101000a81548160ff021916908315150217905550607582908060018154018082558091505060019003906000526020600020016000909190919091505560006118db836125fb565b90506118e733846126c9565b6118f183826126e7565b600c600081548092919061190490613f18565b919050555050505050565b607160009054906101000a900460ff161561195f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611956906146f5565b60405180910390fd5b80600d5461196d9190614715565b3373ffffffffffffffffffffffffffffffffffffffff163110156119c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119bd906147a3565b60405180910390fd5b80600d546119d49190614715565b341015611a16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a0d90614835565b60405180910390fd5b6105dc81600c54611a279190614855565b1115611a68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5f906145bf565b60405180910390fd5b60005b81811015611b6a57606d6000815480929190611a8690613f18565b91905055506000611ac544606d5442604051602001611aa7939291906148aa565b6040516020818303038152906040528051906020012060001c612754565b905060016073600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060758190806001815401808255809150506001900390600052602060002001600090919091909150556000611b27826125fb565b9050611b3333836126c9565b611b3d82826126e7565b600c6000815480929190611b5090613f18565b919050555050508080611b6290613f18565b915050611a6b565b5050565b611b80611b79611f8a565b838361298e565b5050565b6000600c54905090565b611b9f611b99611f8a565b836120c9565b611bde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bd590613e37565b60405180910390fd5b611bea84848484612afa565b50505050565b6060611bfb82611f3f565b6000607260008481526020019081526020016000208054611c1b90613c70565b80601f0160208091040260200160405190810160405280929190818152602001828054611c4790613c70565b8015611c945780601f10611c6957610100808354040283529160200191611c94565b820191906000526020600020905b815481529060010190602001808311611c7757829003601f168201915b50505050509050600060708054611caa90613c70565b80601f0160208091040260200160405190810160405280929190818152602001828054611cd690613c70565b8015611d235780601f10611cf857610100808354040283529160200191611d23565b820191906000526020600020905b815481529060010190602001808311611d0657829003601f168201915b505050505090508082604051602001611d3d929190614923565b60405160208183030381529060405292505050919050565b60758181548110611d6557600080fd5b906000526020600020016000915090505481565b6105dc81565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611e1b61204b565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611e8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e81906149b9565b60405180910390fd5b611e93816124e2565b50565b600e816105dc8110611ea757600080fd5b60109182820401919006600202915054906101000a900461ffff1681565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611f385750611f3782612b56565b5b9050919050565b611f4881612457565b611f87576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f7e906142eb565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff1661200583611137565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b612053611f8a565b73ffffffffffffffffffffffffffffffffffffffff166120716114fe565b73ffffffffffffffffffffffffffffffffffffffff16146120c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120be90614a25565b60405180910390fd5b565b6000806120d583611137565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16148061211757506121168185611d7f565b5b8061215557508373ffffffffffffffffffffffffffffffffffffffff1661213d84610a85565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661217e82611137565b73ffffffffffffffffffffffffffffffffffffffff16146121d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121cb90614ab7565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612243576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161223a90614b49565b60405180910390fd5b6122508383836001612c38565b8273ffffffffffffffffffffffffffffffffffffffff1661227082611137565b73ffffffffffffffffffffffffffffffffffffffff16146122c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122bd90614ab7565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46124528383836001612c3e565b505050565b60008073ffffffffffffffffffffffffffffffffffffffff16612479836124a5565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6000600880549050905090565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6125b181612c44565b60006072600083815260200190815260200160002080546125d190613c70565b9050146125f8576072600082815260200190815260200160002060006125f791906133c4565b5b50565b60606000600161260a84612c97565b01905060008167ffffffffffffffff811115612629576126286138f1565b5b6040519080825280601f01601f19166020018201604052801561265b5781602001600182028036833780820191505090505b509050600082602001820190505b6001156126be578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816126b2576126b1614b69565b5b04945060008503612669575b819350505050919050565b6126e3828260405180602001604052806000815250612dea565b5050565b6126f082612457565b61272f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272690614c0a565b60405180910390fd5b8060726000848152602001908152602001600020908161274f91906141cd565b505050565b600080606c600081819054906101000a900461ffff1680929190612777906145df565b91906101000a81548161ffff021916908361ffff16021790555061ffff166105dc6127a29190614609565b9050600081116127e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127de90614689565b60405180910390fd5b600081846127f59190614c2a565b90506000600e826105dc811061280e5761280d613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff1603612837578061286b565b600e816105dc811061284c5761284b613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff165b92506000600e60018461287e9190614609565b6105dc81106128905761288f613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff16146128f757600e6001836128c29190614609565b6105dc81106128d4576128d3613f60565b5b601091828204019190066002029054906101000a900461ffff1661ffff16612905565b6001826129049190614609565b5b600e826105dc811061291a57612919613f60565b5b601091828204019190066002026101000a81548161ffff021916908361ffff1602179055506000600e6001846129509190614609565b6105dc811061296257612961613f60565b5b601091828204019190066002026101000a81548161ffff021916908361ffff1602179055505050919050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036129fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129f390614ca7565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612aed91906134d5565b60405180910390a3505050565b612b0584848461215e565b612b1184848484612e45565b612b50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b4790614d39565b60405180910390fd5b50505050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612c2157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612c315750612c3082612fcc565b5b9050919050565b50505050565b50505050565b612c4d81613036565b6000600a60008381526020019081526020016000208054612c6d90613c70565b905014612c9457600a60008281526020019081526020016000206000612c9391906133c4565b5b50565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612cf5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612ceb57612cea614b69565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612d32576d04ee2d6d415b85acef81000000008381612d2857612d27614b69565b5b0492506020810190505b662386f26fc100008310612d6157662386f26fc100008381612d5757612d56614b69565b5b0492506010810190505b6305f5e1008310612d8a576305f5e1008381612d8057612d7f614b69565b5b0492506008810190505b6127108310612daf576127108381612da557612da4614b69565b5b0492506004810190505b60648310612dd25760648381612dc857612dc7614b69565b5b0492506002810190505b600a8310612de1576001810190505b80915050919050565b612df48383613184565b612e016000848484612e45565b612e40576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e3790614d39565b60405180910390fd5b505050565b6000612e668473ffffffffffffffffffffffffffffffffffffffff166133a1565b15612fbf578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612e8f611f8a565b8786866040518563ffffffff1660e01b8152600401612eb19493929190614dae565b6020604051808303816000875af1925050508015612eed57506040513d601f19601f82011682018060405250810190612eea9190614e0f565b60015b612f6f573d8060008114612f1d576040519150601f19603f3d011682016040523d82523d6000602084013e612f22565b606091505b506000815103612f67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5e90614d39565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612fc4565b600190505b949350505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600061304182611137565b9050613051816000846001612c38565b61305a82611137565b90506004600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613180816000846001612c3e565b5050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036131f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131ea90614e88565b60405180910390fd5b6131fc81612457565b1561323c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161323390614ef4565b60405180910390fd5b61324a600083836001612c38565b61325381612457565b15613293576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161328a90614ef4565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461339d600083836001612c3e565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5080546133d090613c70565b6000825580601f106133e25750613401565b601f0160209004906000526020600020908101906134009190613404565b5b50565b5b8082111561341d576000816000905550600101613405565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61346a81613435565b811461347557600080fd5b50565b60008135905061348781613461565b92915050565b6000602082840312156134a3576134a261342b565b5b60006134b184828501613478565b91505092915050565b60008115159050919050565b6134cf816134ba565b82525050565b60006020820190506134ea60008301846134c6565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561352a57808201518184015260208101905061350f565b60008484015250505050565b6000601f19601f8301169050919050565b6000613552826134f0565b61355c81856134fb565b935061356c81856020860161350c565b61357581613536565b840191505092915050565b6000602082019050818103600083015261359a8184613547565b905092915050565b6000819050919050565b6135b5816135a2565b81146135c057600080fd5b50565b6000813590506135d2816135ac565b92915050565b6000602082840312156135ee576135ed61342b565b5b60006135fc848285016135c3565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061363082613605565b9050919050565b61364081613625565b82525050565b600060208201905061365b6000830184613637565b92915050565b61366a81613625565b811461367557600080fd5b50565b60008135905061368781613661565b92915050565b600080604083850312156136a4576136a361342b565b5b60006136b285828601613678565b92505060206136c3858286016135c3565b9150509250929050565b600060408201905081810360008301526136e78185613547565b905081810360208301526136fb8184613547565b90509392505050565b61370d816134ba565b811461371857600080fd5b50565b60008135905061372a81613704565b92915050565b6000602082840312156137465761374561342b565b5b60006137548482850161371b565b91505092915050565b613766816135a2565b82525050565b6000602082019050613781600083018461375d565b92915050565b6000806000606084860312156137a05761379f61342b565b5b60006137ae86828701613678565b93505060206137bf86828701613678565b92505060406137d0868287016135c3565b9150509250925092565b6000602082840312156137f0576137ef61342b565b5b60006137fe84828501613678565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61383c816135a2565b82525050565b600061384e8383613833565b60208301905092915050565b6000602082019050919050565b600061387282613807565b61387c8185613812565b935061388783613823565b8060005b838110156138b857815161389f8882613842565b97506138aa8361385a565b92505060018101905061388b565b5085935050505092915050565b600060208201905081810360008301526138df8184613867565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61392982613536565b810181811067ffffffffffffffff82111715613948576139476138f1565b5b80604052505050565b600061395b613421565b90506139678282613920565b919050565b600067ffffffffffffffff821115613987576139866138f1565b5b61399082613536565b9050602081019050919050565b82818337600083830152505050565b60006139bf6139ba8461396c565b613951565b9050828152602081018484840111156139db576139da6138ec565b5b6139e684828561399d565b509392505050565b600082601f830112613a0357613a026138e7565b5b8135613a138482602086016139ac565b91505092915050565b600060208284031215613a3257613a3161342b565b5b600082013567ffffffffffffffff811115613a5057613a4f613430565b5b613a5c848285016139ee565b91505092915050565b60008060408385031215613a7c57613a7b61342b565b5b6000613a8a85828601613678565b9250506020613a9b8582860161371b565b9150509250929050565b600067ffffffffffffffff821115613ac057613abf6138f1565b5b613ac982613536565b9050602081019050919050565b6000613ae9613ae484613aa5565b613951565b905082815260208101848484011115613b0557613b046138ec565b5b613b1084828561399d565b509392505050565b600082601f830112613b2d57613b2c6138e7565b5b8135613b3d848260208601613ad6565b91505092915050565b60008060008060808587031215613b6057613b5f61342b565b5b6000613b6e87828801613678565b9450506020613b7f87828801613678565b9350506040613b90878288016135c3565b925050606085013567ffffffffffffffff811115613bb157613bb0613430565b5b613bbd87828801613b18565b91505092959194509250565b60008060408385031215613be057613bdf61342b565b5b6000613bee85828601613678565b9250506020613bff85828601613678565b9150509250929050565b600061ffff82169050919050565b613c2081613c09565b82525050565b6000602082019050613c3b6000830184613c17565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613c8857607f821691505b602082108103613c9b57613c9a613c41565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000613cfd6021836134fb565b9150613d0882613ca1565b604082019050919050565b60006020820190508181036000830152613d2c81613cf0565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000613d8f603d836134fb565b9150613d9a82613d33565b604082019050919050565b60006020820190508181036000830152613dbe81613d82565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000613e21602d836134fb565b9150613e2c82613dc5565b604082019050919050565b60006020820190508181036000830152613e5081613e14565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000613eb3602b836134fb565b9150613ebe82613e57565b604082019050919050565b60006020820190508181036000830152613ee281613ea6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613f23826135a2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613f5557613f54613ee9565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000613feb602c836134fb565b9150613ff682613f8f565b604082019050919050565b6000602082019050818103600083015261401a81613fde565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026140837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614046565b61408d8683614046565b95508019841693508086168417925050509392505050565b6000819050919050565b60006140ca6140c56140c0846135a2565b6140a5565b6135a2565b9050919050565b6000819050919050565b6140e4836140af565b6140f86140f0826140d1565b848454614053565b825550505050565b600090565b61410d614100565b6141188184846140db565b505050565b5b8181101561413c57614131600082614105565b60018101905061411e565b5050565b601f8211156141815761415281614021565b61415b84614036565b8101602085101561416a578190505b61417e61417685614036565b83018261411d565b50505b505050565b600082821c905092915050565b60006141a460001984600802614186565b1980831691505092915050565b60006141bd8383614193565b9150826002028217905092915050565b6141d6826134f0565b67ffffffffffffffff8111156141ef576141ee6138f1565b5b6141f98254613c70565b614204828285614140565b600060209050601f8311600181146142375760008415614225578287015190505b61422f85826141b1565b865550614297565b601f19841661424586614021565b60005b8281101561426d57848901518255600182019150602085019450602081019050614248565b8683101561428a5784890151614286601f891682614193565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b60006142d56018836134fb565b91506142e08261429f565b602082019050919050565b60006020820190508181036000830152614304816142c8565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b60006143676029836134fb565b91506143728261430b565b604082019050919050565b600060208201905081810360008301526143968161435a565b9050919050565b7f596f7520617265206e6f7420746865206f776e6572206f662074686973204e4660008201527f5400000000000000000000000000000000000000000000000000000000000000602082015250565b60006143f96021836134fb565b91506144048261439d565b604082019050919050565b60006020820190508181036000830152614428816143ec565b9050919050565b7f4275726e696e67206973206e6f7420656e61626c656421000000000000000000600082015250565b60006144656017836134fb565b91506144708261442f565b602082019050919050565b6000602082019050818103600083015261449481614458565b9050919050565b7f496e737566666963656e742062616c616e636500000000000000000000000000600082015250565b60006144d16013836134fb565b91506144dc8261449b565b602082019050919050565b60006020820190508181036000830152614500816144c4565b9050919050565b7f54727565206d696e74696e672073746172746564210000000000000000000000600082015250565b600061453d6015836134fb565b915061454882614507565b602082019050919050565b6000602082019050818103600083015261456c81614530565b9050919050565b7f4e6f7420656e6f756768204e465473206c656674000000000000000000000000600082015250565b60006145a96014836134fb565b91506145b482614573565b602082019050919050565b600060208201905081810360008301526145d88161459c565b9050919050565b60006145ea82613c09565b915061ffff82036145fe576145fd613ee9565b5b600182019050919050565b6000614614826135a2565b915061461f836135a2565b925082820390508181111561463757614636613ee9565b5b92915050565b7f6e6f20696473206c656674000000000000000000000000000000000000000000600082015250565b6000614673600b836134fb565b915061467e8261463d565b602082019050919050565b600060208201905081810360008301526146a281614666565b9050919050565b7f4d696e74696e67206e6f74207374617274656420796574000000000000000000600082015250565b60006146df6017836134fb565b91506146ea826146a9565b602082019050919050565b6000602082019050818103600083015261470e816146d2565b9050919050565b6000614720826135a2565b915061472b836135a2565b9250828202614739816135a2565b915082820484148315176147505761474f613ee9565b5b5092915050565b7f4e6f7420656e6f756768206d6f6e657920746f206d696e740000000000000000600082015250565b600061478d6018836134fb565b915061479882614757565b602082019050919050565b600060208201905081810360008301526147bc81614780565b9050919050565b7f4e6f7420656e6f756768204554482073656e743a20636865636b20707269636560008201527f2e00000000000000000000000000000000000000000000000000000000000000602082015250565b600061481f6021836134fb565b915061482a826147c3565b604082019050919050565b6000602082019050818103600083015261484e81614812565b9050919050565b6000614860826135a2565b915061486b836135a2565b925082820190508082111561488357614882613ee9565b5b92915050565b6000819050919050565b6148a461489f826135a2565b614889565b82525050565b60006148b68286614893565b6020820191506148c68285614893565b6020820191506148d68284614893565b602082019150819050949350505050565b600081905092915050565b60006148fd826134f0565b61490781856148e7565b935061491781856020860161350c565b80840191505092915050565b600061492f82856148f2565b915061493b82846148f2565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006149a36026836134fb565b91506149ae82614947565b604082019050919050565b600060208201905081810360008301526149d281614996565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614a0f6020836134fb565b9150614a1a826149d9565b602082019050919050565b60006020820190508181036000830152614a3e81614a02565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000614aa16025836134fb565b9150614aac82614a45565b604082019050919050565b60006020820190508181036000830152614ad081614a94565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000614b336024836134fb565b9150614b3e82614ad7565b604082019050919050565b60006020820190508181036000830152614b6281614b26565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b6000614bf4602e836134fb565b9150614bff82614b98565b604082019050919050565b60006020820190508181036000830152614c2381614be7565b9050919050565b6000614c35826135a2565b9150614c40836135a2565b925082614c5057614c4f614b69565b5b828206905092915050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000614c916019836134fb565b9150614c9c82614c5b565b602082019050919050565b60006020820190508181036000830152614cc081614c84565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000614d236032836134fb565b9150614d2e82614cc7565b604082019050919050565b60006020820190508181036000830152614d5281614d16565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614d8082614d59565b614d8a8185614d64565b9350614d9a81856020860161350c565b614da381613536565b840191505092915050565b6000608082019050614dc36000830187613637565b614dd06020830186613637565b614ddd604083018561375d565b8181036060830152614def8184614d75565b905095945050505050565b600081519050614e0981613461565b92915050565b600060208284031215614e2557614e2461342b565b5b6000614e3384828501614dfa565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614e726020836134fb565b9150614e7d82614e3c565b602082019050919050565b60006020820190508181036000830152614ea181614e65565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614ede601c836134fb565b9150614ee982614ea8565b602082019050919050565b60006020820190508181036000830152614f0d81614ed1565b905091905056fea2646970667358221220dace1d8caa3b7f72dff1ca25c5d252afa18099b0516d89c8c1b2faf230d190a064736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000036697066733a2f2f516d5274724a396245325453334b535a386d4652346971796f4e315753366b78336f67564e3270573258524767672f00000000000000000000

-----Decoded View---------------
Arg [0] : baseURI_ (string): ipfs://QmRtrJ9bE2TS3KSZ8mFR4iqyoN1WS6kx3ogVN2pW2XRGgg/

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000036
Arg [2] : 697066733a2f2f516d5274724a396245325453334b535a386d4652346971796f
Arg [3] : 4e315753366b78336f67564e3270573258524767672f00000000000000000000


Deployed Bytecode Sourcemap

64536:6018:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69282:179;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40633:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42145:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41663:416;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64957:41;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65658:139;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;68007:85;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70124:107;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68100:85;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;65005:39;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42845:335;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58840:256;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43251:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68291:796;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64924:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59362:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68193:90;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64892:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40343:223;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64864:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40074:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18056:103;;;;;;;;;;;;;:::i;:::-;;64665:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65053;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69659:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;65440:107;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69095:179;;;;;;;;;;;;;:::i;:::-;;64697:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17408:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40802:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67075:703;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;65807:859;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42388:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;65555:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43507:322;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;70239:312;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65085:25;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64621:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42614:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18314:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64734:23;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69282:179;69393:4;69417:36;69441:11;69417:23;:36::i;:::-;69410:43;;69282:179;;;:::o;40633:100::-;40687:13;40720:5;40713:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40633:100;:::o;42145:171::-;42221:7;42241:23;42256:7;42241:14;:23::i;:::-;42284:15;:24;42300:7;42284:24;;;;;;;;;;;;;;;;;;;;;42277:31;;42145:171;;;:::o;41663:416::-;41744:13;41760:23;41775:7;41760:14;:23::i;:::-;41744:39;;41808:5;41802:11;;:2;:11;;;41794:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;41902:5;41886:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;41911:37;41928:5;41935:12;:10;:12::i;:::-;41911:16;:37::i;:::-;41886:62;41864:173;;;;;;;;;;;;:::i;:::-;;;;;;;;;42050:21;42059:2;42063:7;42050:8;:21::i;:::-;41733:346;41663:416;;:::o;64957:41::-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;65658:139::-;65708:13;65723;65761:7;65769:10;:19;65780:7;65769:19;;;;;;;;;;;65754:35;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65658:139;;;:::o;68007:85::-;17294:13;:11;:13::i;:::-;68077:7:::1;68068:6;;:16;;;;;;;;;;;;;;;;;;68007:85:::0;:::o;70124:107::-;70185:4;64654;70207:16;;70124:107;:::o;68100:85::-;17294:13;:11;:13::i;:::-;68170:7:::1;68161:6;;:16;;;;;;;;;;;;;;;;;;68100:85:::0;:::o;65005:39::-;;;;;;;;;;;;;;;;;;;;;;:::o;42845:335::-;43040:41;43059:12;:10;:12::i;:::-;43073:7;43040:18;:41::i;:::-;43032:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;43144:28;43154:4;43160:2;43164:7;43144:9;:28::i;:::-;42845:335;;;:::o;58840:256::-;58937:7;58973:23;58990:5;58973:16;:23::i;:::-;58965:5;:31;58957:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;59062:12;:19;59075:5;59062:19;;;;;;;;;;;;;;;:26;59082:5;59062:26;;;;;;;;;;;;59055:33;;58840:256;;;;:::o;43251:185::-;43389:39;43406:4;43412:2;43416:7;43389:39;;;;;;;;;;;;:16;:39::i;:::-;43251:185;;;:::o;68291:796::-;68353:13;68384:20;68407:17;68417:6;68407:9;:17::i;:::-;68384:40;;68435:27;68476:15;68465:27;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68435:57;;68503:19;68525:1;68503:23;;68537:20;68574:465;68599:15;68581;:33;:64;;;;;64654:4;68618:14;:27;;68581:64;68574:465;;;68693:5;68666:32;;:23;68674:14;68666:7;:23::i;:::-;:32;;;68662:108;;68715:16;;;;;:::i;:::-;;;;68746:8;;68662:108;68784:25;68812:23;68820:14;68812:7;:23::i;:::-;68784:51;;68875:6;68854:27;;:17;:27;;;68850:145;;68931:14;68898:13;68912:15;68898:30;;;;;;;;:::i;:::-;;;;;;;:47;;;;;68962:17;;;;;:::i;:::-;;;;68850:145;69011:16;;;;;:::i;:::-;;;;68647:392;68574:465;;;69066:13;69059:20;;;;;;68291:796;;;:::o;64924:26::-;;;;;;;;;;;;;:::o;59362:233::-;59437:7;59473:30;:28;:30::i;:::-;59465:5;:38;59457:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;59570:10;59581:5;59570:17;;;;;;;;:::i;:::-;;;;;;;;;;59563:24;;59362:233;;;:::o;68193:90::-;17294:13;:11;:13::i;:::-;68271:4:::1;68261:7;:14;;;;;;:::i;:::-;;68193:90:::0;:::o;64892:25::-;;;;;;;;;;;;;:::o;40343:223::-;40415:7;40435:13;40451:17;40460:7;40451:8;:17::i;:::-;40435:33;;40504:1;40487:19;;:5;:19;;;40479:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;40553:5;40546:12;;;40343:223;;;:::o;64864:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;40074:207::-;40146:7;40191:1;40174:19;;:5;:19;;;40166:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;40257:9;:16;40267:5;40257:16;;;;;;;;;;;;;;;;40250:23;;40074:207;;;:::o;18056:103::-;17294:13;:11;:13::i;:::-;18121:30:::1;18148:1;18121:18;:30::i;:::-;18056:103::o:0;64665:25::-;;;;:::o;65053:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;69659:221::-;69732:16;69740:7;69732;:16::i;:::-;69718:30;;:10;:30;;;69710:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;69815:4;69805:14;;:6;;;;;;;;;;;:14;;;69797:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;69858:14;69864:7;69858:5;:14::i;:::-;69659:221;:::o;65440:107::-;17294:13;:11;:13::i;:::-;65528:11:::1;65513:12;;:26;;;;;;;;;;;;;;;;;;65440:107:::0;:::o;69095:179::-;17294:13;:11;:13::i;:::-;69178:1:::1;69154:21;:25;69146:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;69223:10;69215:28;;:51;69244:21;69215:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;69095:179::o:0;64697:30::-;;;;:::o;17408:87::-;17454:7;17481:6;;;;;;;;;;;17474:13;;17408:87;:::o;40802:104::-;40858:13;40891:7;40884:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40802:104;:::o;67075:703::-;17294:13;:11;:13::i;:::-;67152:6:::1;;;;;;;;;;;67144:40;;;;;;;;;;;;:::i;:::-;;;;;;;;;64654:4;67203:13;;:25;;67195:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;67264:10;67285:11:::0;67312:5:::1;;:7;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;67299:20;;:10;:20;;;;:::i;:::-;67285:34;;67344:1;67338:3;:7;67330:31;;;;;;;;;;;;:::i;:::-;;;;;;;;;67393:1;67377:3;67381:7;67377:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;:17;;::::0;:42:::1;;67412:7;67377:42;;;67397:3;67401:7;67397:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;67377:42;;;67372:47;;67468:1;67452:3;67462:1;67456:3;:7;;;;:::i;:::-;67452:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;:17;;;:42;;67482:3;67492:1;67486:3;:7;;;;:::i;:::-;67482:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;67452:42;;;;;67478:1;67472:3;:7;;;;:::i;:::-;67452:42;67430:3;67434:7;67430:12;;;;;;;:::i;:::-;;;;;;;;;;;;;:65;;;;;;;;;;;;;;;;;;67521:1;67506:3;67516:1;67510:3;:7;;;;:::i;:::-;67506:12;;;;;;;:::i;:::-;;;;;;;;;;;;;:16;;;;;;;;;;;;;;;;;;67550:4;67533:10;:14;67544:2;67533:14;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;67565:11;67582:2;67565:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67596:26;67625:20;67642:2;67625:16;:20::i;:::-;67596:49;;67679:25;67689:10;67701:2;67679:9;:25::i;:::-;67715:29;67727:2;67731:12;67715:11;:29::i;:::-;67755:13;;:15;;;;;;;;;:::i;:::-;;;;;;67133:645;;;67075:703:::0;:::o;65807:859::-;65871:6;;;;;;;;;;;65870:7;65862:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;65954:6;65946:5;;:14;;;;:::i;:::-;65924:10;:18;;;:36;;65916:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;66029:6;66021:5;;:14;;;;:::i;:::-;66008:9;:27;;66000:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;64654:4;66108:6;66092:13;;:22;;;;:::i;:::-;:35;;66084:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;66168:6;66163:496;66184:6;66180:1;:10;66163:496;;;66212:9;;:11;;;;;;;;;:::i;:::-;;;;;;66238;66252:100;66304:16;66322:9;;66333:15;66287:62;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;66277:73;;;;;;66272:79;;66252:19;:100::i;:::-;66238:114;;66388:4;66367:10;:18;66378:6;66367:18;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;66407:11;66424:6;66407:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66446:26;66475:24;66492:6;66475:16;:24::i;:::-;66446:53;;66540:29;66550:10;66562:6;66540:9;:29::i;:::-;66584:33;66596:6;66604:12;66584:11;:33::i;:::-;66632:13;;:15;;;;;;;;;:::i;:::-;;;;;;66197:462;;66192:3;;;;;:::i;:::-;;;;66163:496;;;;65807:859;:::o;42388:155::-;42483:52;42502:12;:10;:12::i;:::-;42516:8;42526;42483:18;:52::i;:::-;42388:155;;:::o;65555:95::-;65600:4;65629:13;;65622:20;;65555:95;:::o;43507:322::-;43681:41;43700:12;:10;:12::i;:::-;43714:7;43681:18;:41::i;:::-;43673:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;43783:38;43797:4;43803:2;43807:7;43816:4;43783:13;:38::i;:::-;43507:322;;;;:::o;70239:312::-;70334:13;70360:23;70375:7;70360:14;:23::i;:::-;70396;70422:10;:19;70433:7;70422:19;;;;;;;;;;;70396:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70452:18;70473:7;70452:28;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70524:4;70530:9;70507:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;70493:48;;;;70239:312;;;:::o;65085:25::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;64621:37::-;64654:4;64621:37;:::o;42614:164::-;42711:4;42735:18;:25;42754:5;42735:25;;;;;;;;;;;;;;;:35;42761:8;42735:35;;;;;;;;;;;;;;;;;;;;;;;;;42728:42;;42614:164;;;;:::o;18314:201::-;17294:13;:11;:13::i;:::-;18423:1:::1;18403:22;;:8;:22;;::::0;18395:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;18479:28;18498:8;18479:18;:28::i;:::-;18314:201:::0;:::o;64734:23::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;58532:224::-;58634:4;58673:35;58658:50;;;:11;:50;;;;:90;;;;58712:36;58736:11;58712:23;:36::i;:::-;58658:90;58651:97;;58532:224;;;:::o;51964:135::-;52046:16;52054:7;52046;:16::i;:::-;52038:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;51964:135;:::o;15959:98::-;16012:7;16039:10;16032:17;;15959:98;:::o;51243:174::-;51345:2;51318:15;:24;51334:7;51318:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;51401:7;51397:2;51363:46;;51372:23;51387:7;51372:14;:23::i;:::-;51363:46;;;;;;;;;;;;51243:174;;:::o;17573:132::-;17648:12;:10;:12::i;:::-;17637:23;;:7;:5;:7::i;:::-;:23;;;17629:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;17573:132::o;45862:264::-;45955:4;45972:13;45988:23;46003:7;45988:14;:23::i;:::-;45972:39;;46041:5;46030:16;;:7;:16;;;:52;;;;46050:32;46067:5;46074:7;46050:16;:32::i;:::-;46030:52;:87;;;;46110:7;46086:31;;:20;46098:7;46086:11;:20::i;:::-;:31;;;46030:87;46022:96;;;45862:264;;;;:::o;49861:1263::-;50020:4;49993:31;;:23;50008:7;49993:14;:23::i;:::-;:31;;;49985:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;50099:1;50085:16;;:2;:16;;;50077:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;50155:42;50176:4;50182:2;50186:7;50195:1;50155:20;:42::i;:::-;50327:4;50300:31;;:23;50315:7;50300:14;:23::i;:::-;:31;;;50292:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;50445:15;:24;50461:7;50445:24;;;;;;;;;;;;50438:31;;;;;;;;;;;50940:1;50921:9;:15;50931:4;50921:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;50973:1;50956:9;:13;50966:2;50956:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;51015:2;50996:7;:16;51004:7;50996:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;51054:7;51050:2;51035:27;;51044:4;51035:27;;;;;;;;;;;;51075:41;51095:4;51101:2;51105:7;51114:1;51075:19;:41::i;:::-;49861:1263;;;:::o;45567:128::-;45632:4;45685:1;45656:31;;:17;45665:7;45656:8;:17::i;:::-;:31;;;;45649:38;;45567:128;;;:::o;59172:113::-;59233:7;59260:10;:17;;;;59253:24;;59172:113;:::o;45137:117::-;45203:7;45230;:16;45238:7;45230:16;;;;;;;;;;;;;;;;;;;;;45223:23;;45137:117;;;:::o;18675:191::-;18749:16;18768:6;;;;;;;;;;;18749:25;;18794:8;18785:6;;:17;;;;;;;;;;;;;;;;;;18849:8;18818:40;;18839:8;18818:40;;;;;;;;;;;;18738:128;18675:191;:::o;69888:228::-;69979:20;69991:7;69979:11;:20::i;:::-;70053:1;70022:10;:19;70033:7;70022:19;;;;;;;;;;;70016:33;;;;;:::i;:::-;;;:38;70012:97;;70078:10;:19;70089:7;70078:19;;;;;;;;;;;;70071:26;;;;:::i;:::-;70012:97;69888:228;:::o;13386:716::-;13442:13;13493:14;13530:1;13510:17;13521:5;13510:10;:17::i;:::-;:21;13493:38;;13546:20;13580:6;13569:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13546:41;;13602:11;13731:6;13727:2;13723:15;13715:6;13711:28;13704:35;;13768:288;13775:4;13768:288;;;13800:5;;;;;;;;13942:8;13937:2;13930:5;13926:14;13921:30;13916:3;13908:44;13998:2;13989:11;;;;;;:::i;:::-;;;;;14032:1;14023:5;:10;13768:288;14019:21;13768:288;14077:6;14070:13;;;;;13386:716;;;:::o;46468:110::-;46544:26;46554:2;46558:7;46544:26;;;;;;;;;;;;:9;:26::i;:::-;46468:110;;:::o;67786:213::-;67882:16;67890:7;67882;:16::i;:::-;67874:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;67982:9;67960:10;:19;67971:7;67960:19;;;;;;;;;;;:31;;;;;;:::i;:::-;;67786:213;;:::o;66675:392::-;66738:10;66761:11;66788:5;;:7;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;66775:20;;:10;:20;;;;:::i;:::-;66761:34;;66820:1;66814:3;:7;66806:31;;;;;;;;;;;;:::i;:::-;;;;;;;;;66848:19;66879:3;66870:6;:12;;;;:::i;:::-;66848:34;;66918:1;66898:3;66902:11;66898:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;:21;;;:54;;66941:11;66898:54;;;66922:3;66926:11;66922:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;66898:54;;;66893:59;;67005:1;66989:3;66999:1;66993:3;:7;;;;:::i;:::-;66989:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;:17;;;:42;;67019:3;67029:1;67023:3;:7;;;;:::i;:::-;67019:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;66989:42;;;;;67015:1;67009:3;:7;;;;:::i;:::-;66989:42;66963:3;66967:11;66963:16;;;;;;;:::i;:::-;;;;;;;;;;;;;:69;;;;;;;;;;;;;;;;;;67058:1;67043:3;67053:1;67047:3;:7;;;;:::i;:::-;67043:12;;;;;;;:::i;:::-;;;;;;;;;;;;;:16;;;;;;;;;;;;;;;;;;66750:317;;66675:392;;;:::o;51560:315::-;51715:8;51706:17;;:5;:17;;;51698:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;51802:8;51764:18;:25;51783:5;51764:25;;;;;;;;;;;;;;;:35;51790:8;51764:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;51848:8;51826:41;;51841:5;51826:41;;;51858:8;51826:41;;;;;;:::i;:::-;;;;;;;;51560:315;;;:::o;44710:313::-;44866:28;44876:4;44882:2;44886:7;44866:9;:28::i;:::-;44913:47;44936:4;44942:2;44946:7;44955:4;44913:22;:47::i;:::-;44905:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;44710:313;;;;:::o;39705:305::-;39807:4;39859:25;39844:40;;;:11;:40;;;;:105;;;;39916:33;39901:48;;;:11;:48;;;;39844:105;:158;;;;39966:36;39990:11;39966:23;:36::i;:::-;39844:158;39824:178;;39705:305;;;:::o;69469:182::-;;;;;:::o;55380:158::-;;;;;:::o;57293:206::-;57362:20;57374:7;57362:11;:20::i;:::-;57436:1;57405:10;:19;57416:7;57405:19;;;;;;;;;;;57399:33;;;;;:::i;:::-;;;:38;57395:97;;57461:10;:19;57472:7;57461:19;;;;;;;;;;;;57454:26;;;;:::i;:::-;57395:97;57293:206;:::o;10252:922::-;10305:7;10325:14;10342:1;10325:18;;10392:6;10383:5;:15;10379:102;;10428:6;10419:15;;;;;;:::i;:::-;;;;;10463:2;10453:12;;;;10379:102;10508:6;10499:5;:15;10495:102;;10544:6;10535:15;;;;;;:::i;:::-;;;;;10579:2;10569:12;;;;10495:102;10624:6;10615:5;:15;10611:102;;10660:6;10651:15;;;;;;:::i;:::-;;;;;10695:2;10685:12;;;;10611:102;10740:5;10731;:14;10727:99;;10775:5;10766:14;;;;;;:::i;:::-;;;;;10809:1;10799:11;;;;10727:99;10853:5;10844;:14;10840:99;;10888:5;10879:14;;;;;;:::i;:::-;;;;;10922:1;10912:11;;;;10840:99;10966:5;10957;:14;10953:99;;11001:5;10992:14;;;;;;:::i;:::-;;;;;11035:1;11025:11;;;;10953:99;11079:5;11070;:14;11066:66;;11115:1;11105:11;;;;11066:66;11160:6;11153:13;;;10252:922;;;:::o;46805:319::-;46934:18;46940:2;46944:7;46934:5;:18::i;:::-;46985:53;47016:1;47020:2;47024:7;47033:4;46985:22;:53::i;:::-;46963:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;46805:319;;;:::o;52663:853::-;52817:4;52838:15;:2;:13;;;:15::i;:::-;52834:675;;;52890:2;52874:36;;;52911:12;:10;:12::i;:::-;52925:4;52931:7;52940:4;52874:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;52870:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53132:1;53115:6;:13;:18;53111:328;;53158:60;;;;;;;;;;:::i;:::-;;;;;;;;53111:328;53389:6;53383:13;53374:6;53370:2;53366:15;53359:38;52870:584;53006:41;;;52996:51;;;:6;:51;;;;52989:58;;;;;52834:675;53493:4;53486:11;;52663:853;;;;;;;:::o;31137:157::-;31222:4;31261:25;31246:40;;;:11;:40;;;;31239:47;;31137:157;;;:::o;48741:783::-;48801:13;48817:23;48832:7;48817:14;:23::i;:::-;48801:39;;48853:51;48874:5;48889:1;48893:7;48902:1;48853:20;:51::i;:::-;49017:23;49032:7;49017:14;:23::i;:::-;49009:31;;49088:15;:24;49104:7;49088:24;;;;;;;;;;;;49081:31;;;;;;;;;;;49353:1;49333:9;:16;49343:5;49333:16;;;;;;;;;;;;;;;;:21;;;;;;;;;;;49383:7;:16;49391:7;49383:16;;;;;;;;;;;;49376:23;;;;;;;;;;;49445:7;49441:1;49417:36;;49426:5;49417:36;;;;;;;;;;;;49466:50;49486:5;49501:1;49505:7;49514:1;49466:19;:50::i;:::-;48790:734;48741:783;:::o;47460:942::-;47554:1;47540:16;;:2;:16;;;47532:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;47613:16;47621:7;47613;:16::i;:::-;47612:17;47604:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;47675:48;47704:1;47708:2;47712:7;47721:1;47675:20;:48::i;:::-;47822:16;47830:7;47822;:16::i;:::-;47821:17;47813:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;48237:1;48220:9;:13;48230:2;48220:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;48281:2;48262:7;:16;48270:7;48262:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;48326:7;48322:2;48301:33;;48318:1;48301:33;;;;;;;;;;;;48347:47;48375:1;48379:2;48383:7;48392:1;48347:19;:47::i;:::-;47460:942;;:::o;20106:326::-;20166:4;20423:1;20401:7;:19;;;:23;20394:30;;20106:326;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:514::-;5051:4;5089:2;5078:9;5074:18;5066:26;;5138:9;5132:4;5128:20;5124:1;5113:9;5109:17;5102:47;5166:78;5239:4;5230:6;5166:78;:::i;:::-;5158:86;;5291:9;5285:4;5281:20;5276:2;5265:9;5261:18;5254:48;5319:78;5392:4;5383:6;5319:78;:::i;:::-;5311:86;;4890:514;;;;;:::o;5410:116::-;5480:21;5495:5;5480:21;:::i;:::-;5473:5;5470:32;5460:60;;5516:1;5513;5506:12;5460:60;5410:116;:::o;5532:133::-;5575:5;5613:6;5600:20;5591:29;;5629:30;5653:5;5629:30;:::i;:::-;5532:133;;;;:::o;5671:323::-;5727:6;5776:2;5764:9;5755:7;5751:23;5747:32;5744:119;;;5782:79;;:::i;:::-;5744:119;5902:1;5927:50;5969:7;5960:6;5949:9;5945:22;5927:50;:::i;:::-;5917:60;;5873:114;5671:323;;;;:::o;6000:118::-;6087:24;6105:5;6087:24;:::i;:::-;6082:3;6075:37;6000:118;;:::o;6124:222::-;6217:4;6255:2;6244:9;6240:18;6232:26;;6268:71;6336:1;6325:9;6321:17;6312:6;6268:71;:::i;:::-;6124:222;;;;:::o;6352:619::-;6429:6;6437;6445;6494:2;6482:9;6473:7;6469:23;6465:32;6462:119;;;6500:79;;:::i;:::-;6462:119;6620:1;6645:53;6690:7;6681:6;6670:9;6666:22;6645:53;:::i;:::-;6635:63;;6591:117;6747:2;6773:53;6818:7;6809:6;6798:9;6794:22;6773:53;:::i;:::-;6763:63;;6718:118;6875:2;6901:53;6946:7;6937:6;6926:9;6922:22;6901:53;:::i;:::-;6891:63;;6846:118;6352:619;;;;;:::o;6977:329::-;7036:6;7085:2;7073:9;7064:7;7060:23;7056:32;7053:119;;;7091:79;;:::i;:::-;7053:119;7211:1;7236:53;7281:7;7272:6;7261:9;7257:22;7236:53;:::i;:::-;7226:63;;7182:117;6977:329;;;;:::o;7312:114::-;7379:6;7413:5;7407:12;7397:22;;7312:114;;;:::o;7432:184::-;7531:11;7565:6;7560:3;7553:19;7605:4;7600:3;7596:14;7581:29;;7432:184;;;;:::o;7622:132::-;7689:4;7712:3;7704:11;;7742:4;7737:3;7733:14;7725:22;;7622:132;;;:::o;7760:108::-;7837:24;7855:5;7837:24;:::i;:::-;7832:3;7825:37;7760:108;;:::o;7874:179::-;7943:10;7964:46;8006:3;7998:6;7964:46;:::i;:::-;8042:4;8037:3;8033:14;8019:28;;7874:179;;;;:::o;8059:113::-;8129:4;8161;8156:3;8152:14;8144:22;;8059:113;;;:::o;8208:732::-;8327:3;8356:54;8404:5;8356:54;:::i;:::-;8426:86;8505:6;8500:3;8426:86;:::i;:::-;8419:93;;8536:56;8586:5;8536:56;:::i;:::-;8615:7;8646:1;8631:284;8656:6;8653:1;8650:13;8631:284;;;8732:6;8726:13;8759:63;8818:3;8803:13;8759:63;:::i;:::-;8752:70;;8845:60;8898:6;8845:60;:::i;:::-;8835:70;;8691:224;8678:1;8675;8671:9;8666:14;;8631:284;;;8635:14;8931:3;8924:10;;8332:608;;;8208:732;;;;:::o;8946:373::-;9089:4;9127:2;9116:9;9112:18;9104:26;;9176:9;9170:4;9166:20;9162:1;9151:9;9147:17;9140:47;9204:108;9307:4;9298:6;9204:108;:::i;:::-;9196:116;;8946:373;;;;:::o;9325:117::-;9434:1;9431;9424:12;9448:117;9557:1;9554;9547:12;9571:180;9619:77;9616:1;9609:88;9716:4;9713:1;9706:15;9740:4;9737:1;9730:15;9757:281;9840:27;9862:4;9840:27;:::i;:::-;9832:6;9828:40;9970:6;9958:10;9955:22;9934:18;9922:10;9919:34;9916:62;9913:88;;;9981:18;;:::i;:::-;9913:88;10021:10;10017:2;10010:22;9800:238;9757:281;;:::o;10044:129::-;10078:6;10105:20;;:::i;:::-;10095:30;;10134:33;10162:4;10154:6;10134:33;:::i;:::-;10044:129;;;:::o;10179:308::-;10241:4;10331:18;10323:6;10320:30;10317:56;;;10353:18;;:::i;:::-;10317:56;10391:29;10413:6;10391:29;:::i;:::-;10383:37;;10475:4;10469;10465:15;10457:23;;10179:308;;;:::o;10493:146::-;10590:6;10585:3;10580;10567:30;10631:1;10622:6;10617:3;10613:16;10606:27;10493:146;;;:::o;10645:425::-;10723:5;10748:66;10764:49;10806:6;10764:49;:::i;:::-;10748:66;:::i;:::-;10739:75;;10837:6;10830:5;10823:21;10875:4;10868:5;10864:16;10913:3;10904:6;10899:3;10895:16;10892:25;10889:112;;;10920:79;;:::i;:::-;10889:112;11010:54;11057:6;11052:3;11047;11010:54;:::i;:::-;10729:341;10645:425;;;;;:::o;11090:340::-;11146:5;11195:3;11188:4;11180:6;11176:17;11172:27;11162:122;;11203:79;;:::i;:::-;11162:122;11320:6;11307:20;11345:79;11420:3;11412:6;11405:4;11397:6;11393:17;11345:79;:::i;:::-;11336:88;;11152:278;11090:340;;;;:::o;11436:509::-;11505:6;11554:2;11542:9;11533:7;11529:23;11525:32;11522:119;;;11560:79;;:::i;:::-;11522:119;11708:1;11697:9;11693:17;11680:31;11738:18;11730:6;11727:30;11724:117;;;11760:79;;:::i;:::-;11724:117;11865:63;11920:7;11911:6;11900:9;11896:22;11865:63;:::i;:::-;11855:73;;11651:287;11436:509;;;;:::o;11951:468::-;12016:6;12024;12073:2;12061:9;12052:7;12048:23;12044:32;12041:119;;;12079:79;;:::i;:::-;12041:119;12199:1;12224:53;12269:7;12260:6;12249:9;12245:22;12224:53;:::i;:::-;12214:63;;12170:117;12326:2;12352:50;12394:7;12385:6;12374:9;12370:22;12352:50;:::i;:::-;12342:60;;12297:115;11951:468;;;;;:::o;12425:307::-;12486:4;12576:18;12568:6;12565:30;12562:56;;;12598:18;;:::i;:::-;12562:56;12636:29;12658:6;12636:29;:::i;:::-;12628:37;;12720:4;12714;12710:15;12702:23;;12425:307;;;:::o;12738:423::-;12815:5;12840:65;12856:48;12897:6;12856:48;:::i;:::-;12840:65;:::i;:::-;12831:74;;12928:6;12921:5;12914:21;12966:4;12959:5;12955:16;13004:3;12995:6;12990:3;12986:16;12983:25;12980:112;;;13011:79;;:::i;:::-;12980:112;13101:54;13148:6;13143:3;13138;13101:54;:::i;:::-;12821:340;12738:423;;;;;:::o;13180:338::-;13235:5;13284:3;13277:4;13269:6;13265:17;13261:27;13251:122;;13292:79;;:::i;:::-;13251:122;13409:6;13396:20;13434:78;13508:3;13500:6;13493:4;13485:6;13481:17;13434:78;:::i;:::-;13425:87;;13241:277;13180:338;;;;:::o;13524:943::-;13619:6;13627;13635;13643;13692:3;13680:9;13671:7;13667:23;13663:33;13660:120;;;13699:79;;:::i;:::-;13660:120;13819:1;13844:53;13889:7;13880:6;13869:9;13865:22;13844:53;:::i;:::-;13834:63;;13790:117;13946:2;13972:53;14017:7;14008:6;13997:9;13993:22;13972:53;:::i;:::-;13962:63;;13917:118;14074:2;14100:53;14145:7;14136:6;14125:9;14121:22;14100:53;:::i;:::-;14090:63;;14045:118;14230:2;14219:9;14215:18;14202:32;14261:18;14253:6;14250:30;14247:117;;;14283:79;;:::i;:::-;14247:117;14388:62;14442:7;14433:6;14422:9;14418:22;14388:62;:::i;:::-;14378:72;;14173:287;13524:943;;;;;;;:::o;14473:474::-;14541:6;14549;14598:2;14586:9;14577:7;14573:23;14569:32;14566:119;;;14604:79;;:::i;:::-;14566:119;14724:1;14749:53;14794:7;14785:6;14774:9;14770:22;14749:53;:::i;:::-;14739:63;;14695:117;14851:2;14877:53;14922:7;14913:6;14902:9;14898:22;14877:53;:::i;:::-;14867:63;;14822:118;14473:474;;;;;:::o;14953:89::-;14989:7;15029:6;15022:5;15018:18;15007:29;;14953:89;;;:::o;15048:115::-;15133:23;15150:5;15133:23;:::i;:::-;15128:3;15121:36;15048:115;;:::o;15169:218::-;15260:4;15298:2;15287:9;15283:18;15275:26;;15311:69;15377:1;15366:9;15362:17;15353:6;15311:69;:::i;:::-;15169:218;;;;:::o;15393:180::-;15441:77;15438:1;15431:88;15538:4;15535:1;15528:15;15562:4;15559:1;15552:15;15579:320;15623:6;15660:1;15654:4;15650:12;15640:22;;15707:1;15701:4;15697:12;15728:18;15718:81;;15784:4;15776:6;15772:17;15762:27;;15718:81;15846:2;15838:6;15835:14;15815:18;15812:38;15809:84;;15865:18;;:::i;:::-;15809:84;15630:269;15579:320;;;:::o;15905:220::-;16045:34;16041:1;16033:6;16029:14;16022:58;16114:3;16109:2;16101:6;16097:15;16090:28;15905:220;:::o;16131:366::-;16273:3;16294:67;16358:2;16353:3;16294:67;:::i;:::-;16287:74;;16370:93;16459:3;16370:93;:::i;:::-;16488:2;16483:3;16479:12;16472:19;;16131:366;;;:::o;16503:419::-;16669:4;16707:2;16696:9;16692:18;16684:26;;16756:9;16750:4;16746:20;16742:1;16731:9;16727:17;16720:47;16784:131;16910:4;16784:131;:::i;:::-;16776:139;;16503:419;;;:::o;16928:248::-;17068:34;17064:1;17056:6;17052:14;17045:58;17137:31;17132:2;17124:6;17120:15;17113:56;16928:248;:::o;17182:366::-;17324:3;17345:67;17409:2;17404:3;17345:67;:::i;:::-;17338:74;;17421:93;17510:3;17421:93;:::i;:::-;17539:2;17534:3;17530:12;17523:19;;17182:366;;;:::o;17554:419::-;17720:4;17758:2;17747:9;17743:18;17735:26;;17807:9;17801:4;17797:20;17793:1;17782:9;17778:17;17771:47;17835:131;17961:4;17835:131;:::i;:::-;17827:139;;17554:419;;;:::o;17979:232::-;18119:34;18115:1;18107:6;18103:14;18096:58;18188:15;18183:2;18175:6;18171:15;18164:40;17979:232;:::o;18217:366::-;18359:3;18380:67;18444:2;18439:3;18380:67;:::i;:::-;18373:74;;18456:93;18545:3;18456:93;:::i;:::-;18574:2;18569:3;18565:12;18558:19;;18217:366;;;:::o;18589:419::-;18755:4;18793:2;18782:9;18778:18;18770:26;;18842:9;18836:4;18832:20;18828:1;18817:9;18813:17;18806:47;18870:131;18996:4;18870:131;:::i;:::-;18862:139;;18589:419;;;:::o;19014:230::-;19154:34;19150:1;19142:6;19138:14;19131:58;19223:13;19218:2;19210:6;19206:15;19199:38;19014:230;:::o;19250:366::-;19392:3;19413:67;19477:2;19472:3;19413:67;:::i;:::-;19406:74;;19489:93;19578:3;19489:93;:::i;:::-;19607:2;19602:3;19598:12;19591:19;;19250:366;;;:::o;19622:419::-;19788:4;19826:2;19815:9;19811:18;19803:26;;19875:9;19869:4;19865:20;19861:1;19850:9;19846:17;19839:47;19903:131;20029:4;19903:131;:::i;:::-;19895:139;;19622:419;;;:::o;20047:180::-;20095:77;20092:1;20085:88;20192:4;20189:1;20182:15;20216:4;20213:1;20206:15;20233:233;20272:3;20295:24;20313:5;20295:24;:::i;:::-;20286:33;;20341:66;20334:5;20331:77;20328:103;;20411:18;;:::i;:::-;20328:103;20458:1;20451:5;20447:13;20440:20;;20233:233;;;:::o;20472:180::-;20520:77;20517:1;20510:88;20617:4;20614:1;20607:15;20641:4;20638:1;20631:15;20658:231;20798:34;20794:1;20786:6;20782:14;20775:58;20867:14;20862:2;20854:6;20850:15;20843:39;20658:231;:::o;20895:366::-;21037:3;21058:67;21122:2;21117:3;21058:67;:::i;:::-;21051:74;;21134:93;21223:3;21134:93;:::i;:::-;21252:2;21247:3;21243:12;21236:19;;20895:366;;;:::o;21267:419::-;21433:4;21471:2;21460:9;21456:18;21448:26;;21520:9;21514:4;21510:20;21506:1;21495:9;21491:17;21484:47;21548:131;21674:4;21548:131;:::i;:::-;21540:139;;21267:419;;;:::o;21692:141::-;21741:4;21764:3;21756:11;;21787:3;21784:1;21777:14;21821:4;21818:1;21808:18;21800:26;;21692:141;;;:::o;21839:93::-;21876:6;21923:2;21918;21911:5;21907:14;21903:23;21893:33;;21839:93;;;:::o;21938:107::-;21982:8;22032:5;22026:4;22022:16;22001:37;;21938:107;;;;:::o;22051:393::-;22120:6;22170:1;22158:10;22154:18;22193:97;22223:66;22212:9;22193:97;:::i;:::-;22311:39;22341:8;22330:9;22311:39;:::i;:::-;22299:51;;22383:4;22379:9;22372:5;22368:21;22359:30;;22432:4;22422:8;22418:19;22411:5;22408:30;22398:40;;22127:317;;22051:393;;;;;:::o;22450:60::-;22478:3;22499:5;22492:12;;22450:60;;;:::o;22516:142::-;22566:9;22599:53;22617:34;22626:24;22644:5;22626:24;:::i;:::-;22617:34;:::i;:::-;22599:53;:::i;:::-;22586:66;;22516:142;;;:::o;22664:75::-;22707:3;22728:5;22721:12;;22664:75;;;:::o;22745:269::-;22855:39;22886:7;22855:39;:::i;:::-;22916:91;22965:41;22989:16;22965:41;:::i;:::-;22957:6;22950:4;22944:11;22916:91;:::i;:::-;22910:4;22903:105;22821:193;22745:269;;;:::o;23020:73::-;23065:3;23020:73;:::o;23099:189::-;23176:32;;:::i;:::-;23217:65;23275:6;23267;23261:4;23217:65;:::i;:::-;23152:136;23099:189;;:::o;23294:186::-;23354:120;23371:3;23364:5;23361:14;23354:120;;;23425:39;23462:1;23455:5;23425:39;:::i;:::-;23398:1;23391:5;23387:13;23378:22;;23354:120;;;23294:186;;:::o;23486:543::-;23587:2;23582:3;23579:11;23576:446;;;23621:38;23653:5;23621:38;:::i;:::-;23705:29;23723:10;23705:29;:::i;:::-;23695:8;23691:44;23888:2;23876:10;23873:18;23870:49;;;23909:8;23894:23;;23870:49;23932:80;23988:22;24006:3;23988:22;:::i;:::-;23978:8;23974:37;23961:11;23932:80;:::i;:::-;23591:431;;23576:446;23486:543;;;:::o;24035:117::-;24089:8;24139:5;24133:4;24129:16;24108:37;;24035:117;;;;:::o;24158:169::-;24202:6;24235:51;24283:1;24279:6;24271:5;24268:1;24264:13;24235:51;:::i;:::-;24231:56;24316:4;24310;24306:15;24296:25;;24209:118;24158:169;;;;:::o;24332:295::-;24408:4;24554:29;24579:3;24573:4;24554:29;:::i;:::-;24546:37;;24616:3;24613:1;24609:11;24603:4;24600:21;24592:29;;24332:295;;;;:::o;24632:1395::-;24749:37;24782:3;24749:37;:::i;:::-;24851:18;24843:6;24840:30;24837:56;;;24873:18;;:::i;:::-;24837:56;24917:38;24949:4;24943:11;24917:38;:::i;:::-;25002:67;25062:6;25054;25048:4;25002:67;:::i;:::-;25096:1;25120:4;25107:17;;25152:2;25144:6;25141:14;25169:1;25164:618;;;;25826:1;25843:6;25840:77;;;25892:9;25887:3;25883:19;25877:26;25868:35;;25840:77;25943:67;26003:6;25996:5;25943:67;:::i;:::-;25937:4;25930:81;25799:222;25134:887;;25164:618;25216:4;25212:9;25204:6;25200:22;25250:37;25282:4;25250:37;:::i;:::-;25309:1;25323:208;25337:7;25334:1;25331:14;25323:208;;;25416:9;25411:3;25407:19;25401:26;25393:6;25386:42;25467:1;25459:6;25455:14;25445:24;;25514:2;25503:9;25499:18;25486:31;;25360:4;25357:1;25353:12;25348:17;;25323:208;;;25559:6;25550:7;25547:19;25544:179;;;25617:9;25612:3;25608:19;25602:26;25660:48;25702:4;25694:6;25690:17;25679:9;25660:48;:::i;:::-;25652:6;25645:64;25567:156;25544:179;25769:1;25765;25757:6;25753:14;25749:22;25743:4;25736:36;25171:611;;;25134:887;;24724:1303;;;24632:1395;;:::o;26033:174::-;26173:26;26169:1;26161:6;26157:14;26150:50;26033:174;:::o;26213:366::-;26355:3;26376:67;26440:2;26435:3;26376:67;:::i;:::-;26369:74;;26452:93;26541:3;26452:93;:::i;:::-;26570:2;26565:3;26561:12;26554:19;;26213:366;;;:::o;26585:419::-;26751:4;26789:2;26778:9;26774:18;26766:26;;26838:9;26832:4;26828:20;26824:1;26813:9;26809:17;26802:47;26866:131;26992:4;26866:131;:::i;:::-;26858:139;;26585:419;;;:::o;27010:228::-;27150:34;27146:1;27138:6;27134:14;27127:58;27219:11;27214:2;27206:6;27202:15;27195:36;27010:228;:::o;27244:366::-;27386:3;27407:67;27471:2;27466:3;27407:67;:::i;:::-;27400:74;;27483:93;27572:3;27483:93;:::i;:::-;27601:2;27596:3;27592:12;27585:19;;27244:366;;;:::o;27616:419::-;27782:4;27820:2;27809:9;27805:18;27797:26;;27869:9;27863:4;27859:20;27855:1;27844:9;27840:17;27833:47;27897:131;28023:4;27897:131;:::i;:::-;27889:139;;27616:419;;;:::o;28041:220::-;28181:34;28177:1;28169:6;28165:14;28158:58;28250:3;28245:2;28237:6;28233:15;28226:28;28041:220;:::o;28267:366::-;28409:3;28430:67;28494:2;28489:3;28430:67;:::i;:::-;28423:74;;28506:93;28595:3;28506:93;:::i;:::-;28624:2;28619:3;28615:12;28608:19;;28267:366;;;:::o;28639:419::-;28805:4;28843:2;28832:9;28828:18;28820:26;;28892:9;28886:4;28882:20;28878:1;28867:9;28863:17;28856:47;28920:131;29046:4;28920:131;:::i;:::-;28912:139;;28639:419;;;:::o;29064:173::-;29204:25;29200:1;29192:6;29188:14;29181:49;29064:173;:::o;29243:366::-;29385:3;29406:67;29470:2;29465:3;29406:67;:::i;:::-;29399:74;;29482:93;29571:3;29482:93;:::i;:::-;29600:2;29595:3;29591:12;29584:19;;29243:366;;;:::o;29615:419::-;29781:4;29819:2;29808:9;29804:18;29796:26;;29868:9;29862:4;29858:20;29854:1;29843:9;29839:17;29832:47;29896:131;30022:4;29896:131;:::i;:::-;29888:139;;29615:419;;;:::o;30040:169::-;30180:21;30176:1;30168:6;30164:14;30157:45;30040:169;:::o;30215:366::-;30357:3;30378:67;30442:2;30437:3;30378:67;:::i;:::-;30371:74;;30454:93;30543:3;30454:93;:::i;:::-;30572:2;30567:3;30563:12;30556:19;;30215:366;;;:::o;30587:419::-;30753:4;30791:2;30780:9;30776:18;30768:26;;30840:9;30834:4;30830:20;30826:1;30815:9;30811:17;30804:47;30868:131;30994:4;30868:131;:::i;:::-;30860:139;;30587:419;;;:::o;31012:171::-;31152:23;31148:1;31140:6;31136:14;31129:47;31012:171;:::o;31189:366::-;31331:3;31352:67;31416:2;31411:3;31352:67;:::i;:::-;31345:74;;31428:93;31517:3;31428:93;:::i;:::-;31546:2;31541:3;31537:12;31530:19;;31189:366;;;:::o;31561:419::-;31727:4;31765:2;31754:9;31750:18;31742:26;;31814:9;31808:4;31804:20;31800:1;31789:9;31785:17;31778:47;31842:131;31968:4;31842:131;:::i;:::-;31834:139;;31561:419;;;:::o;31986:170::-;32126:22;32122:1;32114:6;32110:14;32103:46;31986:170;:::o;32162:366::-;32304:3;32325:67;32389:2;32384:3;32325:67;:::i;:::-;32318:74;;32401:93;32490:3;32401:93;:::i;:::-;32519:2;32514:3;32510:12;32503:19;;32162:366;;;:::o;32534:419::-;32700:4;32738:2;32727:9;32723:18;32715:26;;32787:9;32781:4;32777:20;32773:1;32762:9;32758:17;32751:47;32815:131;32941:4;32815:131;:::i;:::-;32807:139;;32534:419;;;:::o;32959:171::-;32997:3;33020:23;33037:5;33020:23;:::i;:::-;33011:32;;33065:6;33058:5;33055:17;33052:43;;33075:18;;:::i;:::-;33052:43;33122:1;33115:5;33111:13;33104:20;;32959:171;;;:::o;33136:194::-;33176:4;33196:20;33214:1;33196:20;:::i;:::-;33191:25;;33230:20;33248:1;33230:20;:::i;:::-;33225:25;;33274:1;33271;33267:9;33259:17;;33298:1;33292:4;33289:11;33286:37;;;33303:18;;:::i;:::-;33286:37;33136:194;;;;:::o;33336:161::-;33476:13;33472:1;33464:6;33460:14;33453:37;33336:161;:::o;33503:366::-;33645:3;33666:67;33730:2;33725:3;33666:67;:::i;:::-;33659:74;;33742:93;33831:3;33742:93;:::i;:::-;33860:2;33855:3;33851:12;33844:19;;33503:366;;;:::o;33875:419::-;34041:4;34079:2;34068:9;34064:18;34056:26;;34128:9;34122:4;34118:20;34114:1;34103:9;34099:17;34092:47;34156:131;34282:4;34156:131;:::i;:::-;34148:139;;33875:419;;;:::o;34300:173::-;34440:25;34436:1;34428:6;34424:14;34417:49;34300:173;:::o;34479:366::-;34621:3;34642:67;34706:2;34701:3;34642:67;:::i;:::-;34635:74;;34718:93;34807:3;34718:93;:::i;:::-;34836:2;34831:3;34827:12;34820:19;;34479:366;;;:::o;34851:419::-;35017:4;35055:2;35044:9;35040:18;35032:26;;35104:9;35098:4;35094:20;35090:1;35079:9;35075:17;35068:47;35132:131;35258:4;35132:131;:::i;:::-;35124:139;;34851:419;;;:::o;35276:410::-;35316:7;35339:20;35357:1;35339:20;:::i;:::-;35334:25;;35373:20;35391:1;35373:20;:::i;:::-;35368:25;;35428:1;35425;35421:9;35450:30;35468:11;35450:30;:::i;:::-;35439:41;;35629:1;35620:7;35616:15;35613:1;35610:22;35590:1;35583:9;35563:83;35540:139;;35659:18;;:::i;:::-;35540:139;35324:362;35276:410;;;;:::o;35692:174::-;35832:26;35828:1;35820:6;35816:14;35809:50;35692:174;:::o;35872:366::-;36014:3;36035:67;36099:2;36094:3;36035:67;:::i;:::-;36028:74;;36111:93;36200:3;36111:93;:::i;:::-;36229:2;36224:3;36220:12;36213:19;;35872:366;;;:::o;36244:419::-;36410:4;36448:2;36437:9;36433:18;36425:26;;36497:9;36491:4;36487:20;36483:1;36472:9;36468:17;36461:47;36525:131;36651:4;36525:131;:::i;:::-;36517:139;;36244:419;;;:::o;36669:220::-;36809:34;36805:1;36797:6;36793:14;36786:58;36878:3;36873:2;36865:6;36861:15;36854:28;36669:220;:::o;36895:366::-;37037:3;37058:67;37122:2;37117:3;37058:67;:::i;:::-;37051:74;;37134:93;37223:3;37134:93;:::i;:::-;37252:2;37247:3;37243:12;37236:19;;36895:366;;;:::o;37267:419::-;37433:4;37471:2;37460:9;37456:18;37448:26;;37520:9;37514:4;37510:20;37506:1;37495:9;37491:17;37484:47;37548:131;37674:4;37548:131;:::i;:::-;37540:139;;37267:419;;;:::o;37692:191::-;37732:3;37751:20;37769:1;37751:20;:::i;:::-;37746:25;;37785:20;37803:1;37785:20;:::i;:::-;37780:25;;37828:1;37825;37821:9;37814:16;;37849:3;37846:1;37843:10;37840:36;;;37856:18;;:::i;:::-;37840:36;37692:191;;;;:::o;37889:79::-;37928:7;37957:5;37946:16;;37889:79;;;:::o;37974:157::-;38079:45;38099:24;38117:5;38099:24;:::i;:::-;38079:45;:::i;:::-;38074:3;38067:58;37974:157;;:::o;38137:538::-;38305:3;38320:75;38391:3;38382:6;38320:75;:::i;:::-;38420:2;38415:3;38411:12;38404:19;;38433:75;38504:3;38495:6;38433:75;:::i;:::-;38533:2;38528:3;38524:12;38517:19;;38546:75;38617:3;38608:6;38546:75;:::i;:::-;38646:2;38641:3;38637:12;38630:19;;38666:3;38659:10;;38137:538;;;;;;:::o;38681:148::-;38783:11;38820:3;38805:18;;38681:148;;;;:::o;38835:390::-;38941:3;38969:39;39002:5;38969:39;:::i;:::-;39024:89;39106:6;39101:3;39024:89;:::i;:::-;39017:96;;39122:65;39180:6;39175:3;39168:4;39161:5;39157:16;39122:65;:::i;:::-;39212:6;39207:3;39203:16;39196:23;;38945:280;38835:390;;;;:::o;39231:435::-;39411:3;39433:95;39524:3;39515:6;39433:95;:::i;:::-;39426:102;;39545:95;39636:3;39627:6;39545:95;:::i;:::-;39538:102;;39657:3;39650:10;;39231:435;;;;;:::o;39672:225::-;39812:34;39808:1;39800:6;39796:14;39789:58;39881:8;39876:2;39868:6;39864:15;39857:33;39672:225;:::o;39903:366::-;40045:3;40066:67;40130:2;40125:3;40066:67;:::i;:::-;40059:74;;40142:93;40231:3;40142:93;:::i;:::-;40260:2;40255:3;40251:12;40244:19;;39903:366;;;:::o;40275:419::-;40441:4;40479:2;40468:9;40464:18;40456:26;;40528:9;40522:4;40518:20;40514:1;40503:9;40499:17;40492:47;40556:131;40682:4;40556:131;:::i;:::-;40548:139;;40275:419;;;:::o;40700:182::-;40840:34;40836:1;40828:6;40824:14;40817:58;40700:182;:::o;40888:366::-;41030:3;41051:67;41115:2;41110:3;41051:67;:::i;:::-;41044:74;;41127:93;41216:3;41127:93;:::i;:::-;41245:2;41240:3;41236:12;41229:19;;40888:366;;;:::o;41260:419::-;41426:4;41464:2;41453:9;41449:18;41441:26;;41513:9;41507:4;41503:20;41499:1;41488:9;41484:17;41477:47;41541:131;41667:4;41541:131;:::i;:::-;41533:139;;41260:419;;;:::o;41685:224::-;41825:34;41821:1;41813:6;41809:14;41802:58;41894:7;41889:2;41881:6;41877:15;41870:32;41685:224;:::o;41915:366::-;42057:3;42078:67;42142:2;42137:3;42078:67;:::i;:::-;42071:74;;42154:93;42243:3;42154:93;:::i;:::-;42272:2;42267:3;42263:12;42256:19;;41915:366;;;:::o;42287:419::-;42453:4;42491:2;42480:9;42476:18;42468:26;;42540:9;42534:4;42530:20;42526:1;42515:9;42511:17;42504:47;42568:131;42694:4;42568:131;:::i;:::-;42560:139;;42287:419;;;:::o;42712:223::-;42852:34;42848:1;42840:6;42836:14;42829:58;42921:6;42916:2;42908:6;42904:15;42897:31;42712:223;:::o;42941:366::-;43083:3;43104:67;43168:2;43163:3;43104:67;:::i;:::-;43097:74;;43180:93;43269:3;43180:93;:::i;:::-;43298:2;43293:3;43289:12;43282:19;;42941:366;;;:::o;43313:419::-;43479:4;43517:2;43506:9;43502:18;43494:26;;43566:9;43560:4;43556:20;43552:1;43541:9;43537:17;43530:47;43594:131;43720:4;43594:131;:::i;:::-;43586:139;;43313:419;;;:::o;43738:180::-;43786:77;43783:1;43776:88;43883:4;43880:1;43873:15;43907:4;43904:1;43897:15;43924:233;44064:34;44060:1;44052:6;44048:14;44041:58;44133:16;44128:2;44120:6;44116:15;44109:41;43924:233;:::o;44163:366::-;44305:3;44326:67;44390:2;44385:3;44326:67;:::i;:::-;44319:74;;44402:93;44491:3;44402:93;:::i;:::-;44520:2;44515:3;44511:12;44504:19;;44163:366;;;:::o;44535:419::-;44701:4;44739:2;44728:9;44724:18;44716:26;;44788:9;44782:4;44778:20;44774:1;44763:9;44759:17;44752:47;44816:131;44942:4;44816:131;:::i;:::-;44808:139;;44535:419;;;:::o;44960:176::-;44992:1;45009:20;45027:1;45009:20;:::i;:::-;45004:25;;45043:20;45061:1;45043:20;:::i;:::-;45038:25;;45082:1;45072:35;;45087:18;;:::i;:::-;45072:35;45128:1;45125;45121:9;45116:14;;44960:176;;;;:::o;45142:175::-;45282:27;45278:1;45270:6;45266:14;45259:51;45142:175;:::o;45323:366::-;45465:3;45486:67;45550:2;45545:3;45486:67;:::i;:::-;45479:74;;45562:93;45651:3;45562:93;:::i;:::-;45680:2;45675:3;45671:12;45664:19;;45323:366;;;:::o;45695:419::-;45861:4;45899:2;45888:9;45884:18;45876:26;;45948:9;45942:4;45938:20;45934:1;45923:9;45919:17;45912:47;45976:131;46102:4;45976:131;:::i;:::-;45968:139;;45695:419;;;:::o;46120:237::-;46260:34;46256:1;46248:6;46244:14;46237:58;46329:20;46324:2;46316:6;46312:15;46305:45;46120:237;:::o;46363:366::-;46505:3;46526:67;46590:2;46585:3;46526:67;:::i;:::-;46519:74;;46602:93;46691:3;46602:93;:::i;:::-;46720:2;46715:3;46711:12;46704:19;;46363:366;;;:::o;46735:419::-;46901:4;46939:2;46928:9;46924:18;46916:26;;46988:9;46982:4;46978:20;46974:1;46963:9;46959:17;46952:47;47016:131;47142:4;47016:131;:::i;:::-;47008:139;;46735:419;;;:::o;47160:98::-;47211:6;47245:5;47239:12;47229:22;;47160:98;;;:::o;47264:168::-;47347:11;47381:6;47376:3;47369:19;47421:4;47416:3;47412:14;47397:29;;47264:168;;;;:::o;47438:373::-;47524:3;47552:38;47584:5;47552:38;:::i;:::-;47606:70;47669:6;47664:3;47606:70;:::i;:::-;47599:77;;47685:65;47743:6;47738:3;47731:4;47724:5;47720:16;47685:65;:::i;:::-;47775:29;47797:6;47775:29;:::i;:::-;47770:3;47766:39;47759:46;;47528:283;47438:373;;;;:::o;47817:640::-;48012:4;48050:3;48039:9;48035:19;48027:27;;48064:71;48132:1;48121:9;48117:17;48108:6;48064:71;:::i;:::-;48145:72;48213:2;48202:9;48198:18;48189:6;48145:72;:::i;:::-;48227;48295:2;48284:9;48280:18;48271:6;48227:72;:::i;:::-;48346:9;48340:4;48336:20;48331:2;48320:9;48316:18;48309:48;48374:76;48445:4;48436:6;48374:76;:::i;:::-;48366:84;;47817:640;;;;;;;:::o;48463:141::-;48519:5;48550:6;48544:13;48535:22;;48566:32;48592:5;48566:32;:::i;:::-;48463:141;;;;:::o;48610:349::-;48679:6;48728:2;48716:9;48707:7;48703:23;48699:32;48696:119;;;48734:79;;:::i;:::-;48696:119;48854:1;48879:63;48934:7;48925:6;48914:9;48910:22;48879:63;:::i;:::-;48869:73;;48825:127;48610:349;;;;:::o;48965:182::-;49105:34;49101:1;49093:6;49089:14;49082:58;48965:182;:::o;49153:366::-;49295:3;49316:67;49380:2;49375:3;49316:67;:::i;:::-;49309:74;;49392:93;49481:3;49392:93;:::i;:::-;49510:2;49505:3;49501:12;49494:19;;49153:366;;;:::o;49525:419::-;49691:4;49729:2;49718:9;49714:18;49706:26;;49778:9;49772:4;49768:20;49764:1;49753:9;49749:17;49742:47;49806:131;49932:4;49806:131;:::i;:::-;49798:139;;49525:419;;;:::o;49950:178::-;50090:30;50086:1;50078:6;50074:14;50067:54;49950:178;:::o;50134:366::-;50276:3;50297:67;50361:2;50356:3;50297:67;:::i;:::-;50290:74;;50373:93;50462:3;50373:93;:::i;:::-;50491:2;50486:3;50482:12;50475:19;;50134:366;;;:::o;50506:419::-;50672:4;50710:2;50699:9;50695:18;50687:26;;50759:9;50753:4;50749:20;50745:1;50734:9;50730:17;50723:47;50787:131;50913:4;50787:131;:::i;:::-;50779:139;;50506:419;;;:::o

Swarm Source

ipfs://dace1d8caa3b7f72dff1ca25c5d252afa18099b0516d89c8c1b2faf230d190a0
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.