ETH Price: $3,454.79 (-0.65%)
Gas: 3 Gwei

Token

Ivana Tattoo Art (ITA)
 

Overview

Max Total Supply

580 ITA

Holders

351

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
1 ITA
0x5f8599e636d3b720c073744660AB0B778F237EfB
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:
IvanaTattooArt

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-12-27
*/

// 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/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: @openzeppelin/contracts/utils/Counters.sol


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

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

// File: contracts/IvanaTattooArt.sol



pragma solidity 0.8.17;




contract IvanaTattooArt is ERC721Enumerable, Ownable {
  using Strings for uint256;
  using Counters for Counters.Counter;
    
  Counters.Counter private _tokenIds;

  string public baseURI;
  string public baseExtension = ".json";
  string public notRevealedUri;
  uint256 public cost = 1 ether;
  uint256 public airDropCost = 1 ether;
  uint256 public maxSupply = 1000;
  uint256 public maxMintAmount = 20;
  uint256 public nftPerAddressLimit = 3;
  bool public paused = false;
  bool public revealed = false;
  bool public onlyWhitelisted = true;
  address[] public whitelistedAddresses;
  mapping(address => uint256) public addressMintedBalance;

  constructor(
    string memory _name,
    string memory _symbol,
    string memory _initBaseURI,
    string memory _initNotRevealedUri
  ) ERC721(_name, _symbol) {
    setBaseURI(_initBaseURI);
    setNotRevealedURI(_initNotRevealedUri);
  }

  // internal
  function _baseURI() internal view virtual override returns (string memory) {
    return baseURI;
  }

  function airDropNfts(address[] calldata wAddresses) public onlyOwner payable {
      uint256 supply = totalSupply();

      for (uint i = 1; i < wAddresses.length; i++) {
              require(msg.value >= airDropCost, "insufficient funds");
              require(supply <= maxSupply, "max NFT limit exceeded");
              _safeMint(wAddresses[i], supply + i);
      }
  }

  // public
  function mint(uint256 _mintAmount) public payable {
    uint256 supply = totalSupply();
    require(_mintAmount > 0, "need to mint at least 1 NFT");
    require(_mintAmount <= maxMintAmount, "max mint amount per session exceeded");
    require(supply + _mintAmount <= maxSupply, "max NFT limit exceeded");

    if (msg.sender != owner()) {
        if(onlyWhitelisted == true) {
            require(isWhitelisted(msg.sender), "user is not whitelisted");
            uint256 ownerMintedCount = addressMintedBalance[msg.sender];
            require(ownerMintedCount + _mintAmount <= nftPerAddressLimit, "max NFT per address exceeded");
        }
        require(msg.value >= cost * _mintAmount, "insufficient funds");
    }

    for (uint256 i = 1; i <= _mintAmount; i++) {
      addressMintedBalance[msg.sender]++;
      _safeMint(msg.sender, supply + i);
    }
  }
  
  function isWhitelisted(address _user) public view returns (bool) {
    for (uint i = 0; i < whitelistedAddresses.length; i++) {
      if (whitelistedAddresses[i] == _user) {
          return true;
      }
    }
    return false;
  }

  function walletOfOwner(address _owner)
    public
    view
    returns (uint256[] memory)
  {
    uint256 ownerTokenCount = balanceOf(_owner);
    uint256[] memory tokenIds = new uint256[](ownerTokenCount);
    for (uint256 i; i < ownerTokenCount; i++) {
      tokenIds[i] = tokenOfOwnerByIndex(_owner, i);
    }
    return tokenIds;
  }

  function tokenURI(uint256 tokenId)
    public
    view
    virtual
    override
    returns (string memory)
  {
    require(
      _exists(tokenId),
      "ERC721Metadata: URI query for nonexistent token"
    );
    
    if(revealed == false) {
        return notRevealedUri;
    }

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

  //only owner
  function reveal() public onlyOwner {
      revealed = true;
  }
  
  function setNftPerAddressLimit(uint256 _limit) public onlyOwner {
    nftPerAddressLimit = _limit;
  }
  
  function setCost(uint256 _newCost) public onlyOwner {
    cost = _newCost;
  }

  function setAirDropCost(uint256 _newCost) public onlyOwner {
    airDropCost = _newCost;
  }

  function setmaxMintAmount(uint256 _newmaxMintAmount) public onlyOwner {
    maxMintAmount = _newmaxMintAmount;
  }

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

  function setBaseExtension(string memory _newBaseExtension) public onlyOwner {
    baseExtension = _newBaseExtension;
  }
  
  function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner {
    notRevealedUri = _notRevealedURI;
  }

  function pause(bool _state) public onlyOwner {
    paused = _state;
  }
  
  function setOnlyWhitelisted(bool _state) public onlyOwner {
    onlyWhitelisted = _state;
  }
  
  function whitelistUsers(address[] calldata _users) public onlyOwner {
    delete whitelistedAddresses;
    whitelistedAddresses = _users;
  }
 
  function withdraw() public payable onlyOwner {
    
    // This will payout the owner 100% of the contract balance.
    // Do not remove this otherwise you will not be able to withdraw the funds.
    // =============================================================================
    (bool os, ) = payable(owner()).call{value: address(this).balance}("");
    require(os);
    // =============================================================================
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_initBaseURI","type":"string"},{"internalType":"string","name":"_initNotRevealedUri","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":[{"internalType":"address","name":"","type":"address"}],"name":"addressMintedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"airDropCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"wAddresses","type":"address[]"}],"name":"airDropNfts","outputs":[],"stateMutability":"payable","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":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","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":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftPerAddressLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notRevealedUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"onlyWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"uint256","name":"_newCost","type":"uint256"}],"name":"setAirDropCost","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":"_newBaseExtension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setNftPerAddressLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_notRevealedURI","type":"string"}],"name":"setNotRevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setOnlyWhitelisted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newmaxMintAmount","type":"uint256"}],"name":"setmaxMintAmount","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":"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":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"whitelistUsers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"whitelistedAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]

60806040526040518060400160405280600581526020017f2e6a736f6e000000000000000000000000000000000000000000000000000000815250600d90816200004a9190620005b8565b50670de0b6b3a7640000600f55670de0b6b3a76400006010556103e8601155601460125560036013556000601460006101000a81548160ff0219169083151502179055506000601460016101000a81548160ff0219169083151502179055506001601460026101000a81548160ff021916908315150217905550348015620000d157600080fd5b5060405162005896380380620058968339818101604052810190620000f7919062000803565b838381600090816200010a9190620005b8565b5080600190816200011c9190620005b8565b5050506200013f620001336200016b60201b60201c565b6200017360201b60201c565b62000150826200023960201b60201c565b62000161816200025e60201b60201c565b5050505062000974565b600033905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620002496200028360201b60201c565b80600c90816200025a9190620005b8565b5050565b6200026e6200028360201b60201c565b80600e90816200027f9190620005b8565b5050565b620002936200016b60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620002b96200031460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161462000312576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003099062000952565b60405180910390fd5b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620003c057607f821691505b602082108103620003d657620003d562000378565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620004407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000401565b6200044c868362000401565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600062000499620004936200048d8462000464565b6200046e565b62000464565b9050919050565b6000819050919050565b620004b58362000478565b620004cd620004c482620004a0565b8484546200040e565b825550505050565b600090565b620004e4620004d5565b620004f1818484620004aa565b505050565b5b8181101562000519576200050d600082620004da565b600181019050620004f7565b5050565b601f82111562000568576200053281620003dc565b6200053d84620003f1565b810160208510156200054d578190505b620005656200055c85620003f1565b830182620004f6565b50505b505050565b600082821c905092915050565b60006200058d600019846008026200056d565b1980831691505092915050565b6000620005a883836200057a565b9150826002028217905092915050565b620005c3826200033e565b67ffffffffffffffff811115620005df57620005de62000349565b5b620005eb8254620003a7565b620005f88282856200051d565b600060209050601f8311600181146200063057600084156200061b578287015190505b6200062785826200059a565b86555062000697565b601f1984166200064086620003dc565b60005b828110156200066a5784890151825560018201915060208501945060208101905062000643565b868310156200068a578489015162000686601f8916826200057a565b8355505b6001600288020188555050505b505050505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b620006d982620006bd565b810181811067ffffffffffffffff82111715620006fb57620006fa62000349565b5b80604052505050565b6000620007106200069f565b90506200071e8282620006ce565b919050565b600067ffffffffffffffff82111562000741576200074062000349565b5b6200074c82620006bd565b9050602081019050919050565b60005b83811015620007795780820151818401526020810190506200075c565b60008484015250505050565b60006200079c620007968462000723565b62000704565b905082815260208101848484011115620007bb57620007ba620006b8565b5b620007c884828562000759565b509392505050565b600082601f830112620007e857620007e7620006b3565b5b8151620007fa84826020860162000785565b91505092915050565b6000806000806080858703121562000820576200081f620006a9565b5b600085015167ffffffffffffffff811115620008415762000840620006ae565b5b6200084f87828801620007d0565b945050602085015167ffffffffffffffff811115620008735762000872620006ae565b5b6200088187828801620007d0565b935050604085015167ffffffffffffffff811115620008a557620008a4620006ae565b5b620008b387828801620007d0565b925050606085015167ffffffffffffffff811115620008d757620008d6620006ae565b5b620008e587828801620007d0565b91505092959194509250565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006200093a602083620008f1565b9150620009478262000902565b602082019050919050565b600060208201905081810360008301526200096d816200092b565b9050919050565b614f1280620009846000396000f3fe6080604052600436106102935760003560e01c80635ed3daa31161015a578063b88d4fde116100c1578063d5abeb011161007a578063d5abeb01146109ed578063da3ef23f14610a18578063e985e9c514610a41578063edec5f2714610a7e578063f2c4ce1e14610aa7578063f2fde38b14610ad057610293565b8063b88d4fde146108cb578063ba4e5c49146108f4578063ba7d2c7614610931578063c66828621461095c578063c87b56dd14610987578063d0eb26b0146109c457610293565b80638da5cb5b116101135780638da5cb5b146107ee57806395d89b41146108195780639c70b51214610844578063a0712d681461086f578063a22cb4651461088b578063a475b5dd146108b457610293565b80635ed3daa3146106e05780636352211e146107095780636c0360eb1461074657806370a0823114610771578063715018a6146107ae5780637f00c7a6146107c557610293565b80633af32abf116101fe578063451f6807116101b7578063451f6807146105dd5780634f6ccce7146105f9578063518302271461063657806355e4bf9c1461066157806355f804b31461068c5780635c975abb146106b557610293565b80633af32abf146104de5780633c9527641461051b5780633ccfd60b1461054457806342842e0e1461054e578063438b63001461057757806344a0d68a146105b457610293565b806313faede61161025057806313faede6146103ba57806318160ddd146103e557806318cae26914610410578063239c70ae1461044d57806323b872dd146104785780632f745c59146104a157610293565b806301ffc9a71461029857806302329a29146102d557806306fdde03146102fe578063081812fc14610329578063081c8c4414610366578063095ea7b314610391575b600080fd5b3480156102a457600080fd5b506102bf60048036038101906102ba91906134a3565b610af9565b6040516102cc91906134eb565b60405180910390f35b3480156102e157600080fd5b506102fc60048036038101906102f79190613532565b610b73565b005b34801561030a57600080fd5b50610313610b98565b60405161032091906135ef565b60405180910390f35b34801561033557600080fd5b50610350600480360381019061034b9190613647565b610c2a565b60405161035d91906136b5565b60405180910390f35b34801561037257600080fd5b5061037b610c70565b60405161038891906135ef565b60405180910390f35b34801561039d57600080fd5b506103b860048036038101906103b391906136fc565b610cfe565b005b3480156103c657600080fd5b506103cf610e15565b6040516103dc919061374b565b60405180910390f35b3480156103f157600080fd5b506103fa610e1b565b604051610407919061374b565b60405180910390f35b34801561041c57600080fd5b5061043760048036038101906104329190613766565b610e28565b604051610444919061374b565b60405180910390f35b34801561045957600080fd5b50610462610e40565b60405161046f919061374b565b60405180910390f35b34801561048457600080fd5b5061049f600480360381019061049a9190613793565b610e46565b005b3480156104ad57600080fd5b506104c860048036038101906104c391906136fc565b610ea6565b6040516104d5919061374b565b60405180910390f35b3480156104ea57600080fd5b5061050560048036038101906105009190613766565b610f4b565b60405161051291906134eb565b60405180910390f35b34801561052757600080fd5b50610542600480360381019061053d9190613532565b610ff9565b005b61054c61101e565b005b34801561055a57600080fd5b5061057560048036038101906105709190613793565b6110a6565b005b34801561058357600080fd5b5061059e60048036038101906105999190613766565b6110c6565b6040516105ab91906138a4565b60405180910390f35b3480156105c057600080fd5b506105db60048036038101906105d69190613647565b611174565b005b6105f760048036038101906105f2919061392b565b611186565b005b34801561060557600080fd5b50610620600480360381019061061b9190613647565b61128b565b60405161062d919061374b565b60405180910390f35b34801561064257600080fd5b5061064b6112fc565b60405161065891906134eb565b60405180910390f35b34801561066d57600080fd5b5061067661130f565b604051610683919061374b565b60405180910390f35b34801561069857600080fd5b506106b360048036038101906106ae9190613aa8565b611315565b005b3480156106c157600080fd5b506106ca611330565b6040516106d791906134eb565b60405180910390f35b3480156106ec57600080fd5b5061070760048036038101906107029190613647565b611343565b005b34801561071557600080fd5b50610730600480360381019061072b9190613647565b611355565b60405161073d91906136b5565b60405180910390f35b34801561075257600080fd5b5061075b6113db565b60405161076891906135ef565b60405180910390f35b34801561077d57600080fd5b5061079860048036038101906107939190613766565b611469565b6040516107a5919061374b565b60405180910390f35b3480156107ba57600080fd5b506107c3611520565b005b3480156107d157600080fd5b506107ec60048036038101906107e79190613647565b611534565b005b3480156107fa57600080fd5b50610803611546565b60405161081091906136b5565b60405180910390f35b34801561082557600080fd5b5061082e611570565b60405161083b91906135ef565b60405180910390f35b34801561085057600080fd5b50610859611602565b60405161086691906134eb565b60405180910390f35b61088960048036038101906108849190613647565b611615565b005b34801561089757600080fd5b506108b260048036038101906108ad9190613af1565b61190d565b005b3480156108c057600080fd5b506108c9611923565b005b3480156108d757600080fd5b506108f260048036038101906108ed9190613bd2565b611948565b005b34801561090057600080fd5b5061091b60048036038101906109169190613647565b6119aa565b60405161092891906136b5565b60405180910390f35b34801561093d57600080fd5b506109466119e9565b604051610953919061374b565b60405180910390f35b34801561096857600080fd5b506109716119ef565b60405161097e91906135ef565b60405180910390f35b34801561099357600080fd5b506109ae60048036038101906109a99190613647565b611a7d565b6040516109bb91906135ef565b60405180910390f35b3480156109d057600080fd5b506109eb60048036038101906109e69190613647565b611bd5565b005b3480156109f957600080fd5b50610a02611be7565b604051610a0f919061374b565b60405180910390f35b348015610a2457600080fd5b50610a3f6004803603810190610a3a9190613aa8565b611bed565b005b348015610a4d57600080fd5b50610a686004803603810190610a639190613c55565b611c08565b604051610a7591906134eb565b60405180910390f35b348015610a8a57600080fd5b50610aa56004803603810190610aa0919061392b565b611c9c565b005b348015610ab357600080fd5b50610ace6004803603810190610ac99190613aa8565b611cc8565b005b348015610adc57600080fd5b50610af76004803603810190610af29190613766565b611ce3565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610b6c5750610b6b82611d66565b5b9050919050565b610b7b611e48565b80601460006101000a81548160ff02191690831515021790555050565b606060008054610ba790613cc4565b80601f0160208091040260200160405190810160405280929190818152602001828054610bd390613cc4565b8015610c205780601f10610bf557610100808354040283529160200191610c20565b820191906000526020600020905b815481529060010190602001808311610c0357829003601f168201915b5050505050905090565b6000610c3582611ec6565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600e8054610c7d90613cc4565b80601f0160208091040260200160405190810160405280929190818152602001828054610ca990613cc4565b8015610cf65780601f10610ccb57610100808354040283529160200191610cf6565b820191906000526020600020905b815481529060010190602001808311610cd957829003601f168201915b505050505081565b6000610d0982611355565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610d79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7090613d67565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610d98611f11565b73ffffffffffffffffffffffffffffffffffffffff161480610dc75750610dc681610dc1611f11565b611c08565b5b610e06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dfd90613df9565b60405180910390fd5b610e108383611f19565b505050565b600f5481565b6000600880549050905090565b60166020528060005260406000206000915090505481565b60125481565b610e57610e51611f11565b82611fd2565b610e96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8d90613e8b565b60405180910390fd5b610ea1838383612067565b505050565b6000610eb183611469565b8210610ef2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee990613f1d565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b600080600090505b601580549050811015610fee578273ffffffffffffffffffffffffffffffffffffffff1660158281548110610f8b57610f8a613f3d565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610fdb576001915050610ff4565b8080610fe690613f9b565b915050610f53565b50600090505b919050565b611001611e48565b80601460026101000a81548160ff02191690831515021790555050565b611026611e48565b6000611030611546565b73ffffffffffffffffffffffffffffffffffffffff164760405161105390614014565b60006040518083038185875af1925050503d8060008114611090576040519150601f19603f3d011682016040523d82523d6000602084013e611095565b606091505b50509050806110a357600080fd5b50565b6110c183838360405180602001604052806000815250611948565b505050565b606060006110d383611469565b905060008167ffffffffffffffff8111156110f1576110f061397d565b5b60405190808252806020026020018201604052801561111f5781602001602082028036833780820191505090505b50905060005b82811015611169576111378582610ea6565b82828151811061114a57611149613f3d565b5b602002602001018181525050808061116190613f9b565b915050611125565b508092505050919050565b61117c611e48565b80600f8190555050565b61118e611e48565b6000611198610e1b565b90506000600190505b83839050811015611285576010543410156111f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e890614075565b60405180910390fd5b601154821115611236576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122d906140e1565b60405180910390fd5b61127284848381811061124c5761124b613f3d565b5b90506020020160208101906112619190613766565b828461126d9190614101565b612360565b808061127d90613f9b565b9150506111a1565b50505050565b6000611295610e1b565b82106112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906141a7565b60405180910390fd5b600882815481106112ea576112e9613f3d565b5b90600052602060002001549050919050565b601460019054906101000a900460ff1681565b60105481565b61131d611e48565b80600c908161132c9190614373565b5050565b601460009054906101000a900460ff1681565b61134b611e48565b8060108190555050565b6000806113618361237e565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c990614491565b60405180910390fd5b80915050919050565b600c80546113e890613cc4565b80601f016020809104026020016040519081016040528092919081815260200182805461141490613cc4565b80156114615780601f1061143657610100808354040283529160200191611461565b820191906000526020600020905b81548152906001019060200180831161144457829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036114d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114d090614523565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611528611e48565b61153260006123bb565b565b61153c611e48565b8060128190555050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606001805461157f90613cc4565b80601f01602080910402602001604051908101604052809291908181526020018280546115ab90613cc4565b80156115f85780601f106115cd576101008083540402835291602001916115f8565b820191906000526020600020905b8154815290600101906020018083116115db57829003601f168201915b5050505050905090565b601460029054906101000a900460ff1681565b600061161f610e1b565b905060008211611664576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165b9061458f565b60405180910390fd5b6012548211156116a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a090614621565b60405180910390fd5b60115482826116b89190614101565b11156116f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116f0906140e1565b60405180910390fd5b611701611546565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461187d5760011515601460029054906101000a900460ff1615150361182c5761175733610f4b565b611796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178d9061468d565b60405180910390fd5b6000601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060135483826117e99190614101565b111561182a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611821906146f9565b60405180910390fd5b505b81600f5461183a9190614719565b34101561187c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187390614075565b60405180910390fd5b5b6000600190505b82811161190857601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906118db90613f9b565b91905055506118f53382846118f09190614101565b612360565b808061190090613f9b565b915050611884565b505050565b61191f611918611f11565b8383612481565b5050565b61192b611e48565b6001601460016101000a81548160ff021916908315150217905550565b611959611953611f11565b83611fd2565b611998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161198f90613e8b565b60405180910390fd5b6119a4848484846125ed565b50505050565b601581815481106119ba57600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60135481565b600d80546119fc90613cc4565b80601f0160208091040260200160405190810160405280929190818152602001828054611a2890613cc4565b8015611a755780601f10611a4a57610100808354040283529160200191611a75565b820191906000526020600020905b815481529060010190602001808311611a5857829003601f168201915b505050505081565b6060611a8882612649565b611ac7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611abe906147cd565b60405180910390fd5b60001515601460019054906101000a900460ff16151503611b7457600e8054611aef90613cc4565b80601f0160208091040260200160405190810160405280929190818152602001828054611b1b90613cc4565b8015611b685780601f10611b3d57610100808354040283529160200191611b68565b820191906000526020600020905b815481529060010190602001808311611b4b57829003601f168201915b50505050509050611bd0565b6000611b7e61268a565b90506000815111611b9e5760405180602001604052806000815250611bcc565b80611ba88461271c565b600d604051602001611bbc939291906148ac565b6040516020818303038152906040525b9150505b919050565b611bdd611e48565b8060138190555050565b60115481565b611bf5611e48565b80600d9081611c049190614373565b5050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ca4611e48565b60156000611cb29190613359565b818160159190611cc392919061337a565b505050565b611cd0611e48565b80600e9081611cdf9190614373565b5050565b611ceb611e48565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d519061494f565b60405180910390fd5b611d63816123bb565b50565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611e3157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611e415750611e40826127ea565b5b9050919050565b611e50611f11565b73ffffffffffffffffffffffffffffffffffffffff16611e6e611546565b73ffffffffffffffffffffffffffffffffffffffff1614611ec4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ebb906149bb565b60405180910390fd5b565b611ecf81612649565b611f0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0590614491565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611f8c83611355565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080611fde83611355565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612020575061201f8185611c08565b5b8061205e57508373ffffffffffffffffffffffffffffffffffffffff1661204684610c2a565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661208782611355565b73ffffffffffffffffffffffffffffffffffffffff16146120dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120d490614a4d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361214c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214390614adf565b60405180910390fd5b6121598383836001612854565b8273ffffffffffffffffffffffffffffffffffffffff1661217982611355565b73ffffffffffffffffffffffffffffffffffffffff16146121cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121c690614a4d565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461235b83838360016129b2565b505050565b61237a8282604051806020016040528060008152506129b8565b5050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e690614b4b565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516125e091906134eb565b60405180910390a3505050565b6125f8848484612067565b61260484848484612a13565b612643576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161263a90614bdd565b60405180910390fd5b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff1661266b8361237e565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6060600c805461269990613cc4565b80601f01602080910402602001604051908101604052809291908181526020018280546126c590613cc4565b80156127125780601f106126e757610100808354040283529160200191612712565b820191906000526020600020905b8154815290600101906020018083116126f557829003601f168201915b5050505050905090565b60606000600161272b84612b9a565b01905060008167ffffffffffffffff81111561274a5761274961397d565b5b6040519080825280601f01601f19166020018201604052801561277c5781602001600182028036833780820191505090505b509050600082602001820190505b6001156127df578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816127d3576127d2614bfd565b5b0494506000850361278a575b819350505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61286084848484612ced565b60018111156128a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161289b90614c9e565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036128eb576128e681612e13565b61292a565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614612929576129288582612e5c565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361296c5761296781612fc9565b6129ab565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146129aa576129a9848261309a565b5b5b5050505050565b50505050565b6129c28383613119565b6129cf6000848484612a13565b612a0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a0590614bdd565b60405180910390fd5b505050565b6000612a348473ffffffffffffffffffffffffffffffffffffffff16613336565b15612b8d578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612a5d611f11565b8786866040518563ffffffff1660e01b8152600401612a7f9493929190614d13565b6020604051808303816000875af1925050508015612abb57506040513d601f19601f82011682018060405250810190612ab89190614d74565b60015b612b3d573d8060008114612aeb576040519150601f19603f3d011682016040523d82523d6000602084013e612af0565b606091505b506000815103612b35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b2c90614bdd565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612b92565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612bf8577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612bee57612bed614bfd565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612c35576d04ee2d6d415b85acef81000000008381612c2b57612c2a614bfd565b5b0492506020810190505b662386f26fc100008310612c6457662386f26fc100008381612c5a57612c59614bfd565b5b0492506010810190505b6305f5e1008310612c8d576305f5e1008381612c8357612c82614bfd565b5b0492506008810190505b6127108310612cb2576127108381612ca857612ca7614bfd565b5b0492506004810190505b60648310612cd55760648381612ccb57612cca614bfd565b5b0492506002810190505b600a8310612ce4576001810190505b80915050919050565b6001811115612e0d57600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612d815780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612d799190614da1565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612e0c5780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612e049190614101565b925050819055505b5b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612e6984611469565b612e739190614da1565b9050600060076000848152602001908152602001600020549050818114612f58576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050612fdd9190614da1565b905060006009600084815260200190815260200160002054905060006008838154811061300d5761300c613f3d565b5b90600052602060002001549050806008838154811061302f5761302e613f3d565b5b90600052602060002001819055508160096000838152602001908152602001600020819055506009600085815260200190815260200160002060009055600880548061307e5761307d614dd5565b5b6001900381819060005260206000200160009055905550505050565b60006130a583611469565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161317f90614e50565b60405180910390fd5b61319181612649565b156131d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131c890614ebc565b60405180910390fd5b6131df600083836001612854565b6131e881612649565b15613228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161321f90614ebc565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46133326000838360016129b2565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5080546000825590600052602060002090810190613377919061341a565b50565b828054828255906000526020600020908101928215613409579160200282015b8281111561340857823573ffffffffffffffffffffffffffffffffffffffff168260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509160200191906001019061339a565b5b509050613416919061341a565b5090565b5b8082111561343357600081600090555060010161341b565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6134808161344b565b811461348b57600080fd5b50565b60008135905061349d81613477565b92915050565b6000602082840312156134b9576134b8613441565b5b60006134c78482850161348e565b91505092915050565b60008115159050919050565b6134e5816134d0565b82525050565b600060208201905061350060008301846134dc565b92915050565b61350f816134d0565b811461351a57600080fd5b50565b60008135905061352c81613506565b92915050565b60006020828403121561354857613547613441565b5b60006135568482850161351d565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561359957808201518184015260208101905061357e565b60008484015250505050565b6000601f19601f8301169050919050565b60006135c18261355f565b6135cb818561356a565b93506135db81856020860161357b565b6135e4816135a5565b840191505092915050565b6000602082019050818103600083015261360981846135b6565b905092915050565b6000819050919050565b61362481613611565b811461362f57600080fd5b50565b6000813590506136418161361b565b92915050565b60006020828403121561365d5761365c613441565b5b600061366b84828501613632565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061369f82613674565b9050919050565b6136af81613694565b82525050565b60006020820190506136ca60008301846136a6565b92915050565b6136d981613694565b81146136e457600080fd5b50565b6000813590506136f6816136d0565b92915050565b6000806040838503121561371357613712613441565b5b6000613721858286016136e7565b925050602061373285828601613632565b9150509250929050565b61374581613611565b82525050565b6000602082019050613760600083018461373c565b92915050565b60006020828403121561377c5761377b613441565b5b600061378a848285016136e7565b91505092915050565b6000806000606084860312156137ac576137ab613441565b5b60006137ba868287016136e7565b93505060206137cb868287016136e7565b92505060406137dc86828701613632565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61381b81613611565b82525050565b600061382d8383613812565b60208301905092915050565b6000602082019050919050565b6000613851826137e6565b61385b81856137f1565b935061386683613802565b8060005b8381101561389757815161387e8882613821565b975061388983613839565b92505060018101905061386a565b5085935050505092915050565b600060208201905081810360008301526138be8184613846565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126138eb576138ea6138c6565b5b8235905067ffffffffffffffff811115613908576139076138cb565b5b602083019150836020820283011115613924576139236138d0565b5b9250929050565b6000806020838503121561394257613941613441565b5b600083013567ffffffffffffffff8111156139605761395f613446565b5b61396c858286016138d5565b92509250509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6139b5826135a5565b810181811067ffffffffffffffff821117156139d4576139d361397d565b5b80604052505050565b60006139e7613437565b90506139f382826139ac565b919050565b600067ffffffffffffffff821115613a1357613a1261397d565b5b613a1c826135a5565b9050602081019050919050565b82818337600083830152505050565b6000613a4b613a46846139f8565b6139dd565b905082815260208101848484011115613a6757613a66613978565b5b613a72848285613a29565b509392505050565b600082601f830112613a8f57613a8e6138c6565b5b8135613a9f848260208601613a38565b91505092915050565b600060208284031215613abe57613abd613441565b5b600082013567ffffffffffffffff811115613adc57613adb613446565b5b613ae884828501613a7a565b91505092915050565b60008060408385031215613b0857613b07613441565b5b6000613b16858286016136e7565b9250506020613b278582860161351d565b9150509250929050565b600067ffffffffffffffff821115613b4c57613b4b61397d565b5b613b55826135a5565b9050602081019050919050565b6000613b75613b7084613b31565b6139dd565b905082815260208101848484011115613b9157613b90613978565b5b613b9c848285613a29565b509392505050565b600082601f830112613bb957613bb86138c6565b5b8135613bc9848260208601613b62565b91505092915050565b60008060008060808587031215613bec57613beb613441565b5b6000613bfa878288016136e7565b9450506020613c0b878288016136e7565b9350506040613c1c87828801613632565b925050606085013567ffffffffffffffff811115613c3d57613c3c613446565b5b613c4987828801613ba4565b91505092959194509250565b60008060408385031215613c6c57613c6b613441565b5b6000613c7a858286016136e7565b9250506020613c8b858286016136e7565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613cdc57607f821691505b602082108103613cef57613cee613c95565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000613d5160218361356a565b9150613d5c82613cf5565b604082019050919050565b60006020820190508181036000830152613d8081613d44565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000613de3603d8361356a565b9150613dee82613d87565b604082019050919050565b60006020820190508181036000830152613e1281613dd6565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000613e75602d8361356a565b9150613e8082613e19565b604082019050919050565b60006020820190508181036000830152613ea481613e68565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000613f07602b8361356a565b9150613f1282613eab565b604082019050919050565b60006020820190508181036000830152613f3681613efa565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613fa682613611565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fd857613fd7613f6c565b5b600182019050919050565b600081905092915050565b50565b6000613ffe600083613fe3565b915061400982613fee565b600082019050919050565b600061401f82613ff1565b9150819050919050565b7f696e73756666696369656e742066756e64730000000000000000000000000000600082015250565b600061405f60128361356a565b915061406a82614029565b602082019050919050565b6000602082019050818103600083015261408e81614052565b9050919050565b7f6d6178204e4654206c696d697420657863656564656400000000000000000000600082015250565b60006140cb60168361356a565b91506140d682614095565b602082019050919050565b600060208201905081810360008301526140fa816140be565b9050919050565b600061410c82613611565b915061411783613611565b925082820190508082111561412f5761412e613f6c565b5b92915050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614191602c8361356a565b915061419c82614135565b604082019050919050565b600060208201905081810360008301526141c081614184565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026142297fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826141ec565b61423386836141ec565b95508019841693508086168417925050509392505050565b6000819050919050565b600061427061426b61426684613611565b61424b565b613611565b9050919050565b6000819050919050565b61428a83614255565b61429e61429682614277565b8484546141f9565b825550505050565b600090565b6142b36142a6565b6142be818484614281565b505050565b5b818110156142e2576142d76000826142ab565b6001810190506142c4565b5050565b601f821115614327576142f8816141c7565b614301846141dc565b81016020851015614310578190505b61432461431c856141dc565b8301826142c3565b50505b505050565b600082821c905092915050565b600061434a6000198460080261432c565b1980831691505092915050565b60006143638383614339565b9150826002028217905092915050565b61437c8261355f565b67ffffffffffffffff8111156143955761439461397d565b5b61439f8254613cc4565b6143aa8282856142e6565b600060209050601f8311600181146143dd57600084156143cb578287015190505b6143d58582614357565b86555061443d565b601f1984166143eb866141c7565b60005b82811015614413578489015182556001820191506020850194506020810190506143ee565b86831015614430578489015161442c601f891682614339565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b600061447b60188361356a565b915061448682614445565b602082019050919050565b600060208201905081810360008301526144aa8161446e565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b600061450d60298361356a565b9150614518826144b1565b604082019050919050565b6000602082019050818103600083015261453c81614500565b9050919050565b7f6e65656420746f206d696e74206174206c656173742031204e46540000000000600082015250565b6000614579601b8361356a565b915061458482614543565b602082019050919050565b600060208201905081810360008301526145a88161456c565b9050919050565b7f6d6178206d696e7420616d6f756e74207065722073657373696f6e206578636560008201527f6564656400000000000000000000000000000000000000000000000000000000602082015250565b600061460b60248361356a565b9150614616826145af565b604082019050919050565b6000602082019050818103600083015261463a816145fe565b9050919050565b7f75736572206973206e6f742077686974656c6973746564000000000000000000600082015250565b600061467760178361356a565b915061468282614641565b602082019050919050565b600060208201905081810360008301526146a68161466a565b9050919050565b7f6d6178204e465420706572206164647265737320657863656564656400000000600082015250565b60006146e3601c8361356a565b91506146ee826146ad565b602082019050919050565b60006020820190508181036000830152614712816146d6565b9050919050565b600061472482613611565b915061472f83613611565b925082820261473d81613611565b9150828204841483151761475457614753613f6c565b5b5092915050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b60006147b7602f8361356a565b91506147c28261475b565b604082019050919050565b600060208201905081810360008301526147e6816147aa565b9050919050565b600081905092915050565b60006148038261355f565b61480d81856147ed565b935061481d81856020860161357b565b80840191505092915050565b6000815461483681613cc4565b61484081866147ed565b9450600182166000811461485b5760018114614870576148a3565b60ff19831686528115158202860193506148a3565b614879856141c7565b60005b8381101561489b5781548189015260018201915060208101905061487c565b838801955050505b50505092915050565b60006148b882866147f8565b91506148c482856147f8565b91506148d08284614829565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061493960268361356a565b9150614944826148dd565b604082019050919050565b600060208201905081810360008301526149688161492c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006149a560208361356a565b91506149b08261496f565b602082019050919050565b600060208201905081810360008301526149d481614998565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000614a3760258361356a565b9150614a42826149db565b604082019050919050565b60006020820190508181036000830152614a6681614a2a565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000614ac960248361356a565b9150614ad482614a6d565b604082019050919050565b60006020820190508181036000830152614af881614abc565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000614b3560198361356a565b9150614b4082614aff565b602082019050919050565b60006020820190508181036000830152614b6481614b28565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000614bc760328361356a565b9150614bd282614b6b565b604082019050919050565b60006020820190508181036000830152614bf681614bba565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b6000614c8860358361356a565b9150614c9382614c2c565b604082019050919050565b60006020820190508181036000830152614cb781614c7b565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614ce582614cbe565b614cef8185614cc9565b9350614cff81856020860161357b565b614d08816135a5565b840191505092915050565b6000608082019050614d2860008301876136a6565b614d3560208301866136a6565b614d42604083018561373c565b8181036060830152614d548184614cda565b905095945050505050565b600081519050614d6e81613477565b92915050565b600060208284031215614d8a57614d89613441565b5b6000614d9884828501614d5f565b91505092915050565b6000614dac82613611565b9150614db783613611565b9250828203905081811115614dcf57614dce613f6c565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614e3a60208361356a565b9150614e4582614e04565b602082019050919050565b60006020820190508181036000830152614e6981614e2d565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614ea6601c8361356a565b9150614eb182614e70565b602082019050919050565b60006020820190508181036000830152614ed581614e99565b905091905056fea2646970667358221220b1932e8ebb589cb34da0241d75dd5a30f4f0a23f171c6a3092ad278586e1f82364736f6c63430008110033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000104976616e6120546174746f6f204172740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034954410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006468747470733a2f2f626166796265696177686b6c637a6466703477707337367435347176726272736737376b6c3332366f6b34367075636366766e35766a34343464692e697066732e6e667473746f726167652e6c696e6b2f68696464656e2e6a736f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006468747470733a2f2f626166796265696177686b6c637a6466703477707337367435347176726272736737376b6c3332366f6b34367075636366766e35766a34343464692e697066732e6e667473746f726167652e6c696e6b2f68696464656e2e6a736f6e00000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106102935760003560e01c80635ed3daa31161015a578063b88d4fde116100c1578063d5abeb011161007a578063d5abeb01146109ed578063da3ef23f14610a18578063e985e9c514610a41578063edec5f2714610a7e578063f2c4ce1e14610aa7578063f2fde38b14610ad057610293565b8063b88d4fde146108cb578063ba4e5c49146108f4578063ba7d2c7614610931578063c66828621461095c578063c87b56dd14610987578063d0eb26b0146109c457610293565b80638da5cb5b116101135780638da5cb5b146107ee57806395d89b41146108195780639c70b51214610844578063a0712d681461086f578063a22cb4651461088b578063a475b5dd146108b457610293565b80635ed3daa3146106e05780636352211e146107095780636c0360eb1461074657806370a0823114610771578063715018a6146107ae5780637f00c7a6146107c557610293565b80633af32abf116101fe578063451f6807116101b7578063451f6807146105dd5780634f6ccce7146105f9578063518302271461063657806355e4bf9c1461066157806355f804b31461068c5780635c975abb146106b557610293565b80633af32abf146104de5780633c9527641461051b5780633ccfd60b1461054457806342842e0e1461054e578063438b63001461057757806344a0d68a146105b457610293565b806313faede61161025057806313faede6146103ba57806318160ddd146103e557806318cae26914610410578063239c70ae1461044d57806323b872dd146104785780632f745c59146104a157610293565b806301ffc9a71461029857806302329a29146102d557806306fdde03146102fe578063081812fc14610329578063081c8c4414610366578063095ea7b314610391575b600080fd5b3480156102a457600080fd5b506102bf60048036038101906102ba91906134a3565b610af9565b6040516102cc91906134eb565b60405180910390f35b3480156102e157600080fd5b506102fc60048036038101906102f79190613532565b610b73565b005b34801561030a57600080fd5b50610313610b98565b60405161032091906135ef565b60405180910390f35b34801561033557600080fd5b50610350600480360381019061034b9190613647565b610c2a565b60405161035d91906136b5565b60405180910390f35b34801561037257600080fd5b5061037b610c70565b60405161038891906135ef565b60405180910390f35b34801561039d57600080fd5b506103b860048036038101906103b391906136fc565b610cfe565b005b3480156103c657600080fd5b506103cf610e15565b6040516103dc919061374b565b60405180910390f35b3480156103f157600080fd5b506103fa610e1b565b604051610407919061374b565b60405180910390f35b34801561041c57600080fd5b5061043760048036038101906104329190613766565b610e28565b604051610444919061374b565b60405180910390f35b34801561045957600080fd5b50610462610e40565b60405161046f919061374b565b60405180910390f35b34801561048457600080fd5b5061049f600480360381019061049a9190613793565b610e46565b005b3480156104ad57600080fd5b506104c860048036038101906104c391906136fc565b610ea6565b6040516104d5919061374b565b60405180910390f35b3480156104ea57600080fd5b5061050560048036038101906105009190613766565b610f4b565b60405161051291906134eb565b60405180910390f35b34801561052757600080fd5b50610542600480360381019061053d9190613532565b610ff9565b005b61054c61101e565b005b34801561055a57600080fd5b5061057560048036038101906105709190613793565b6110a6565b005b34801561058357600080fd5b5061059e60048036038101906105999190613766565b6110c6565b6040516105ab91906138a4565b60405180910390f35b3480156105c057600080fd5b506105db60048036038101906105d69190613647565b611174565b005b6105f760048036038101906105f2919061392b565b611186565b005b34801561060557600080fd5b50610620600480360381019061061b9190613647565b61128b565b60405161062d919061374b565b60405180910390f35b34801561064257600080fd5b5061064b6112fc565b60405161065891906134eb565b60405180910390f35b34801561066d57600080fd5b5061067661130f565b604051610683919061374b565b60405180910390f35b34801561069857600080fd5b506106b360048036038101906106ae9190613aa8565b611315565b005b3480156106c157600080fd5b506106ca611330565b6040516106d791906134eb565b60405180910390f35b3480156106ec57600080fd5b5061070760048036038101906107029190613647565b611343565b005b34801561071557600080fd5b50610730600480360381019061072b9190613647565b611355565b60405161073d91906136b5565b60405180910390f35b34801561075257600080fd5b5061075b6113db565b60405161076891906135ef565b60405180910390f35b34801561077d57600080fd5b5061079860048036038101906107939190613766565b611469565b6040516107a5919061374b565b60405180910390f35b3480156107ba57600080fd5b506107c3611520565b005b3480156107d157600080fd5b506107ec60048036038101906107e79190613647565b611534565b005b3480156107fa57600080fd5b50610803611546565b60405161081091906136b5565b60405180910390f35b34801561082557600080fd5b5061082e611570565b60405161083b91906135ef565b60405180910390f35b34801561085057600080fd5b50610859611602565b60405161086691906134eb565b60405180910390f35b61088960048036038101906108849190613647565b611615565b005b34801561089757600080fd5b506108b260048036038101906108ad9190613af1565b61190d565b005b3480156108c057600080fd5b506108c9611923565b005b3480156108d757600080fd5b506108f260048036038101906108ed9190613bd2565b611948565b005b34801561090057600080fd5b5061091b60048036038101906109169190613647565b6119aa565b60405161092891906136b5565b60405180910390f35b34801561093d57600080fd5b506109466119e9565b604051610953919061374b565b60405180910390f35b34801561096857600080fd5b506109716119ef565b60405161097e91906135ef565b60405180910390f35b34801561099357600080fd5b506109ae60048036038101906109a99190613647565b611a7d565b6040516109bb91906135ef565b60405180910390f35b3480156109d057600080fd5b506109eb60048036038101906109e69190613647565b611bd5565b005b3480156109f957600080fd5b50610a02611be7565b604051610a0f919061374b565b60405180910390f35b348015610a2457600080fd5b50610a3f6004803603810190610a3a9190613aa8565b611bed565b005b348015610a4d57600080fd5b50610a686004803603810190610a639190613c55565b611c08565b604051610a7591906134eb565b60405180910390f35b348015610a8a57600080fd5b50610aa56004803603810190610aa0919061392b565b611c9c565b005b348015610ab357600080fd5b50610ace6004803603810190610ac99190613aa8565b611cc8565b005b348015610adc57600080fd5b50610af76004803603810190610af29190613766565b611ce3565b005b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610b6c5750610b6b82611d66565b5b9050919050565b610b7b611e48565b80601460006101000a81548160ff02191690831515021790555050565b606060008054610ba790613cc4565b80601f0160208091040260200160405190810160405280929190818152602001828054610bd390613cc4565b8015610c205780601f10610bf557610100808354040283529160200191610c20565b820191906000526020600020905b815481529060010190602001808311610c0357829003601f168201915b5050505050905090565b6000610c3582611ec6565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600e8054610c7d90613cc4565b80601f0160208091040260200160405190810160405280929190818152602001828054610ca990613cc4565b8015610cf65780601f10610ccb57610100808354040283529160200191610cf6565b820191906000526020600020905b815481529060010190602001808311610cd957829003601f168201915b505050505081565b6000610d0982611355565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610d79576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7090613d67565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610d98611f11565b73ffffffffffffffffffffffffffffffffffffffff161480610dc75750610dc681610dc1611f11565b611c08565b5b610e06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dfd90613df9565b60405180910390fd5b610e108383611f19565b505050565b600f5481565b6000600880549050905090565b60166020528060005260406000206000915090505481565b60125481565b610e57610e51611f11565b82611fd2565b610e96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8d90613e8b565b60405180910390fd5b610ea1838383612067565b505050565b6000610eb183611469565b8210610ef2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ee990613f1d565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b600080600090505b601580549050811015610fee578273ffffffffffffffffffffffffffffffffffffffff1660158281548110610f8b57610f8a613f3d565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610fdb576001915050610ff4565b8080610fe690613f9b565b915050610f53565b50600090505b919050565b611001611e48565b80601460026101000a81548160ff02191690831515021790555050565b611026611e48565b6000611030611546565b73ffffffffffffffffffffffffffffffffffffffff164760405161105390614014565b60006040518083038185875af1925050503d8060008114611090576040519150601f19603f3d011682016040523d82523d6000602084013e611095565b606091505b50509050806110a357600080fd5b50565b6110c183838360405180602001604052806000815250611948565b505050565b606060006110d383611469565b905060008167ffffffffffffffff8111156110f1576110f061397d565b5b60405190808252806020026020018201604052801561111f5781602001602082028036833780820191505090505b50905060005b82811015611169576111378582610ea6565b82828151811061114a57611149613f3d565b5b602002602001018181525050808061116190613f9b565b915050611125565b508092505050919050565b61117c611e48565b80600f8190555050565b61118e611e48565b6000611198610e1b565b90506000600190505b83839050811015611285576010543410156111f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e890614075565b60405180910390fd5b601154821115611236576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161122d906140e1565b60405180910390fd5b61127284848381811061124c5761124b613f3d565b5b90506020020160208101906112619190613766565b828461126d9190614101565b612360565b808061127d90613f9b565b9150506111a1565b50505050565b6000611295610e1b565b82106112d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112cd906141a7565b60405180910390fd5b600882815481106112ea576112e9613f3d565b5b90600052602060002001549050919050565b601460019054906101000a900460ff1681565b60105481565b61131d611e48565b80600c908161132c9190614373565b5050565b601460009054906101000a900460ff1681565b61134b611e48565b8060108190555050565b6000806113618361237e565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113c990614491565b60405180910390fd5b80915050919050565b600c80546113e890613cc4565b80601f016020809104026020016040519081016040528092919081815260200182805461141490613cc4565b80156114615780601f1061143657610100808354040283529160200191611461565b820191906000526020600020905b81548152906001019060200180831161144457829003601f168201915b505050505081565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036114d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114d090614523565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611528611e48565b61153260006123bb565b565b61153c611e48565b8060128190555050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606001805461157f90613cc4565b80601f01602080910402602001604051908101604052809291908181526020018280546115ab90613cc4565b80156115f85780601f106115cd576101008083540402835291602001916115f8565b820191906000526020600020905b8154815290600101906020018083116115db57829003601f168201915b5050505050905090565b601460029054906101000a900460ff1681565b600061161f610e1b565b905060008211611664576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161165b9061458f565b60405180910390fd5b6012548211156116a9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116a090614621565b60405180910390fd5b60115482826116b89190614101565b11156116f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116f0906140e1565b60405180910390fd5b611701611546565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461187d5760011515601460029054906101000a900460ff1615150361182c5761175733610f4b565b611796576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178d9061468d565b60405180910390fd5b6000601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060135483826117e99190614101565b111561182a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611821906146f9565b60405180910390fd5b505b81600f5461183a9190614719565b34101561187c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187390614075565b60405180910390fd5b5b6000600190505b82811161190857601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906118db90613f9b565b91905055506118f53382846118f09190614101565b612360565b808061190090613f9b565b915050611884565b505050565b61191f611918611f11565b8383612481565b5050565b61192b611e48565b6001601460016101000a81548160ff021916908315150217905550565b611959611953611f11565b83611fd2565b611998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161198f90613e8b565b60405180910390fd5b6119a4848484846125ed565b50505050565b601581815481106119ba57600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60135481565b600d80546119fc90613cc4565b80601f0160208091040260200160405190810160405280929190818152602001828054611a2890613cc4565b8015611a755780601f10611a4a57610100808354040283529160200191611a75565b820191906000526020600020905b815481529060010190602001808311611a5857829003601f168201915b505050505081565b6060611a8882612649565b611ac7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611abe906147cd565b60405180910390fd5b60001515601460019054906101000a900460ff16151503611b7457600e8054611aef90613cc4565b80601f0160208091040260200160405190810160405280929190818152602001828054611b1b90613cc4565b8015611b685780601f10611b3d57610100808354040283529160200191611b68565b820191906000526020600020905b815481529060010190602001808311611b4b57829003601f168201915b50505050509050611bd0565b6000611b7e61268a565b90506000815111611b9e5760405180602001604052806000815250611bcc565b80611ba88461271c565b600d604051602001611bbc939291906148ac565b6040516020818303038152906040525b9150505b919050565b611bdd611e48565b8060138190555050565b60115481565b611bf5611e48565b80600d9081611c049190614373565b5050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ca4611e48565b60156000611cb29190613359565b818160159190611cc392919061337a565b505050565b611cd0611e48565b80600e9081611cdf9190614373565b5050565b611ceb611e48565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611d5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d519061494f565b60405180910390fd5b611d63816123bb565b50565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611e3157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80611e415750611e40826127ea565b5b9050919050565b611e50611f11565b73ffffffffffffffffffffffffffffffffffffffff16611e6e611546565b73ffffffffffffffffffffffffffffffffffffffff1614611ec4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ebb906149bb565b60405180910390fd5b565b611ecf81612649565b611f0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0590614491565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611f8c83611355565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080611fde83611355565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612020575061201f8185611c08565b5b8061205e57508373ffffffffffffffffffffffffffffffffffffffff1661204684610c2a565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661208782611355565b73ffffffffffffffffffffffffffffffffffffffff16146120dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120d490614a4d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361214c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214390614adf565b60405180910390fd5b6121598383836001612854565b8273ffffffffffffffffffffffffffffffffffffffff1661217982611355565b73ffffffffffffffffffffffffffffffffffffffff16146121cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121c690614a4d565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461235b83838360016129b2565b505050565b61237a8282604051806020016040528060008152506129b8565b5050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e690614b4b565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516125e091906134eb565b60405180910390a3505050565b6125f8848484612067565b61260484848484612a13565b612643576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161263a90614bdd565b60405180910390fd5b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff1661266b8361237e565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6060600c805461269990613cc4565b80601f01602080910402602001604051908101604052809291908181526020018280546126c590613cc4565b80156127125780601f106126e757610100808354040283529160200191612712565b820191906000526020600020905b8154815290600101906020018083116126f557829003601f168201915b5050505050905090565b60606000600161272b84612b9a565b01905060008167ffffffffffffffff81111561274a5761274961397d565b5b6040519080825280601f01601f19166020018201604052801561277c5781602001600182028036833780820191505090505b509050600082602001820190505b6001156127df578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816127d3576127d2614bfd565b5b0494506000850361278a575b819350505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61286084848484612ced565b60018111156128a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161289b90614c9e565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036128eb576128e681612e13565b61292a565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614612929576129288582612e5c565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361296c5761296781612fc9565b6129ab565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146129aa576129a9848261309a565b5b5b5050505050565b50505050565b6129c28383613119565b6129cf6000848484612a13565b612a0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a0590614bdd565b60405180910390fd5b505050565b6000612a348473ffffffffffffffffffffffffffffffffffffffff16613336565b15612b8d578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612a5d611f11565b8786866040518563ffffffff1660e01b8152600401612a7f9493929190614d13565b6020604051808303816000875af1925050508015612abb57506040513d601f19601f82011682018060405250810190612ab89190614d74565b60015b612b3d573d8060008114612aeb576040519150601f19603f3d011682016040523d82523d6000602084013e612af0565b606091505b506000815103612b35576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b2c90614bdd565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612b92565b600190505b949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612bf8577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381612bee57612bed614bfd565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612c35576d04ee2d6d415b85acef81000000008381612c2b57612c2a614bfd565b5b0492506020810190505b662386f26fc100008310612c6457662386f26fc100008381612c5a57612c59614bfd565b5b0492506010810190505b6305f5e1008310612c8d576305f5e1008381612c8357612c82614bfd565b5b0492506008810190505b6127108310612cb2576127108381612ca857612ca7614bfd565b5b0492506004810190505b60648310612cd55760648381612ccb57612cca614bfd565b5b0492506002810190505b600a8310612ce4576001810190505b80915050919050565b6001811115612e0d57600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614612d815780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612d799190614da1565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612e0c5780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612e049190614101565b925050819055505b5b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612e6984611469565b612e739190614da1565b9050600060076000848152602001908152602001600020549050818114612f58576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050612fdd9190614da1565b905060006009600084815260200190815260200160002054905060006008838154811061300d5761300c613f3d565b5b90600052602060002001549050806008838154811061302f5761302e613f3d565b5b90600052602060002001819055508160096000838152602001908152602001600020819055506009600085815260200190815260200160002060009055600880548061307e5761307d614dd5565b5b6001900381819060005260206000200160009055905550505050565b60006130a583611469565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603613188576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161317f90614e50565b60405180910390fd5b61319181612649565b156131d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131c890614ebc565b60405180910390fd5b6131df600083836001612854565b6131e881612649565b15613228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161321f90614ebc565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46133326000838360016129b2565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b5080546000825590600052602060002090810190613377919061341a565b50565b828054828255906000526020600020908101928215613409579160200282015b8281111561340857823573ffffffffffffffffffffffffffffffffffffffff168260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509160200191906001019061339a565b5b509050613416919061341a565b5090565b5b8082111561343357600081600090555060010161341b565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6134808161344b565b811461348b57600080fd5b50565b60008135905061349d81613477565b92915050565b6000602082840312156134b9576134b8613441565b5b60006134c78482850161348e565b91505092915050565b60008115159050919050565b6134e5816134d0565b82525050565b600060208201905061350060008301846134dc565b92915050565b61350f816134d0565b811461351a57600080fd5b50565b60008135905061352c81613506565b92915050565b60006020828403121561354857613547613441565b5b60006135568482850161351d565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561359957808201518184015260208101905061357e565b60008484015250505050565b6000601f19601f8301169050919050565b60006135c18261355f565b6135cb818561356a565b93506135db81856020860161357b565b6135e4816135a5565b840191505092915050565b6000602082019050818103600083015261360981846135b6565b905092915050565b6000819050919050565b61362481613611565b811461362f57600080fd5b50565b6000813590506136418161361b565b92915050565b60006020828403121561365d5761365c613441565b5b600061366b84828501613632565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061369f82613674565b9050919050565b6136af81613694565b82525050565b60006020820190506136ca60008301846136a6565b92915050565b6136d981613694565b81146136e457600080fd5b50565b6000813590506136f6816136d0565b92915050565b6000806040838503121561371357613712613441565b5b6000613721858286016136e7565b925050602061373285828601613632565b9150509250929050565b61374581613611565b82525050565b6000602082019050613760600083018461373c565b92915050565b60006020828403121561377c5761377b613441565b5b600061378a848285016136e7565b91505092915050565b6000806000606084860312156137ac576137ab613441565b5b60006137ba868287016136e7565b93505060206137cb868287016136e7565b92505060406137dc86828701613632565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61381b81613611565b82525050565b600061382d8383613812565b60208301905092915050565b6000602082019050919050565b6000613851826137e6565b61385b81856137f1565b935061386683613802565b8060005b8381101561389757815161387e8882613821565b975061388983613839565b92505060018101905061386a565b5085935050505092915050565b600060208201905081810360008301526138be8184613846565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126138eb576138ea6138c6565b5b8235905067ffffffffffffffff811115613908576139076138cb565b5b602083019150836020820283011115613924576139236138d0565b5b9250929050565b6000806020838503121561394257613941613441565b5b600083013567ffffffffffffffff8111156139605761395f613446565b5b61396c858286016138d5565b92509250509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6139b5826135a5565b810181811067ffffffffffffffff821117156139d4576139d361397d565b5b80604052505050565b60006139e7613437565b90506139f382826139ac565b919050565b600067ffffffffffffffff821115613a1357613a1261397d565b5b613a1c826135a5565b9050602081019050919050565b82818337600083830152505050565b6000613a4b613a46846139f8565b6139dd565b905082815260208101848484011115613a6757613a66613978565b5b613a72848285613a29565b509392505050565b600082601f830112613a8f57613a8e6138c6565b5b8135613a9f848260208601613a38565b91505092915050565b600060208284031215613abe57613abd613441565b5b600082013567ffffffffffffffff811115613adc57613adb613446565b5b613ae884828501613a7a565b91505092915050565b60008060408385031215613b0857613b07613441565b5b6000613b16858286016136e7565b9250506020613b278582860161351d565b9150509250929050565b600067ffffffffffffffff821115613b4c57613b4b61397d565b5b613b55826135a5565b9050602081019050919050565b6000613b75613b7084613b31565b6139dd565b905082815260208101848484011115613b9157613b90613978565b5b613b9c848285613a29565b509392505050565b600082601f830112613bb957613bb86138c6565b5b8135613bc9848260208601613b62565b91505092915050565b60008060008060808587031215613bec57613beb613441565b5b6000613bfa878288016136e7565b9450506020613c0b878288016136e7565b9350506040613c1c87828801613632565b925050606085013567ffffffffffffffff811115613c3d57613c3c613446565b5b613c4987828801613ba4565b91505092959194509250565b60008060408385031215613c6c57613c6b613441565b5b6000613c7a858286016136e7565b9250506020613c8b858286016136e7565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613cdc57607f821691505b602082108103613cef57613cee613c95565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000613d5160218361356a565b9150613d5c82613cf5565b604082019050919050565b60006020820190508181036000830152613d8081613d44565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000613de3603d8361356a565b9150613dee82613d87565b604082019050919050565b60006020820190508181036000830152613e1281613dd6565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000613e75602d8361356a565b9150613e8082613e19565b604082019050919050565b60006020820190508181036000830152613ea481613e68565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000613f07602b8361356a565b9150613f1282613eab565b604082019050919050565b60006020820190508181036000830152613f3681613efa565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613fa682613611565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613fd857613fd7613f6c565b5b600182019050919050565b600081905092915050565b50565b6000613ffe600083613fe3565b915061400982613fee565b600082019050919050565b600061401f82613ff1565b9150819050919050565b7f696e73756666696369656e742066756e64730000000000000000000000000000600082015250565b600061405f60128361356a565b915061406a82614029565b602082019050919050565b6000602082019050818103600083015261408e81614052565b9050919050565b7f6d6178204e4654206c696d697420657863656564656400000000000000000000600082015250565b60006140cb60168361356a565b91506140d682614095565b602082019050919050565b600060208201905081810360008301526140fa816140be565b9050919050565b600061410c82613611565b915061411783613611565b925082820190508082111561412f5761412e613f6c565b5b92915050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b6000614191602c8361356a565b915061419c82614135565b604082019050919050565b600060208201905081810360008301526141c081614184565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026142297fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826141ec565b61423386836141ec565b95508019841693508086168417925050509392505050565b6000819050919050565b600061427061426b61426684613611565b61424b565b613611565b9050919050565b6000819050919050565b61428a83614255565b61429e61429682614277565b8484546141f9565b825550505050565b600090565b6142b36142a6565b6142be818484614281565b505050565b5b818110156142e2576142d76000826142ab565b6001810190506142c4565b5050565b601f821115614327576142f8816141c7565b614301846141dc565b81016020851015614310578190505b61432461431c856141dc565b8301826142c3565b50505b505050565b600082821c905092915050565b600061434a6000198460080261432c565b1980831691505092915050565b60006143638383614339565b9150826002028217905092915050565b61437c8261355f565b67ffffffffffffffff8111156143955761439461397d565b5b61439f8254613cc4565b6143aa8282856142e6565b600060209050601f8311600181146143dd57600084156143cb578287015190505b6143d58582614357565b86555061443d565b601f1984166143eb866141c7565b60005b82811015614413578489015182556001820191506020850194506020810190506143ee565b86831015614430578489015161442c601f891682614339565b8355505b6001600288020188555050505b505050505050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b600061447b60188361356a565b915061448682614445565b602082019050919050565b600060208201905081810360008301526144aa8161446e565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b600061450d60298361356a565b9150614518826144b1565b604082019050919050565b6000602082019050818103600083015261453c81614500565b9050919050565b7f6e65656420746f206d696e74206174206c656173742031204e46540000000000600082015250565b6000614579601b8361356a565b915061458482614543565b602082019050919050565b600060208201905081810360008301526145a88161456c565b9050919050565b7f6d6178206d696e7420616d6f756e74207065722073657373696f6e206578636560008201527f6564656400000000000000000000000000000000000000000000000000000000602082015250565b600061460b60248361356a565b9150614616826145af565b604082019050919050565b6000602082019050818103600083015261463a816145fe565b9050919050565b7f75736572206973206e6f742077686974656c6973746564000000000000000000600082015250565b600061467760178361356a565b915061468282614641565b602082019050919050565b600060208201905081810360008301526146a68161466a565b9050919050565b7f6d6178204e465420706572206164647265737320657863656564656400000000600082015250565b60006146e3601c8361356a565b91506146ee826146ad565b602082019050919050565b60006020820190508181036000830152614712816146d6565b9050919050565b600061472482613611565b915061472f83613611565b925082820261473d81613611565b9150828204841483151761475457614753613f6c565b5b5092915050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b60006147b7602f8361356a565b91506147c28261475b565b604082019050919050565b600060208201905081810360008301526147e6816147aa565b9050919050565b600081905092915050565b60006148038261355f565b61480d81856147ed565b935061481d81856020860161357b565b80840191505092915050565b6000815461483681613cc4565b61484081866147ed565b9450600182166000811461485b5760018114614870576148a3565b60ff19831686528115158202860193506148a3565b614879856141c7565b60005b8381101561489b5781548189015260018201915060208101905061487c565b838801955050505b50505092915050565b60006148b882866147f8565b91506148c482856147f8565b91506148d08284614829565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061493960268361356a565b9150614944826148dd565b604082019050919050565b600060208201905081810360008301526149688161492c565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006149a560208361356a565b91506149b08261496f565b602082019050919050565b600060208201905081810360008301526149d481614998565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000614a3760258361356a565b9150614a42826149db565b604082019050919050565b60006020820190508181036000830152614a6681614a2a565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b6000614ac960248361356a565b9150614ad482614a6d565b604082019050919050565b60006020820190508181036000830152614af881614abc565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000614b3560198361356a565b9150614b4082614aff565b602082019050919050565b60006020820190508181036000830152614b6481614b28565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b6000614bc760328361356a565b9150614bd282614b6b565b604082019050919050565b60006020820190508181036000830152614bf681614bba565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b6000614c8860358361356a565b9150614c9382614c2c565b604082019050919050565b60006020820190508181036000830152614cb781614c7b565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614ce582614cbe565b614cef8185614cc9565b9350614cff81856020860161357b565b614d08816135a5565b840191505092915050565b6000608082019050614d2860008301876136a6565b614d3560208301866136a6565b614d42604083018561373c565b8181036060830152614d548184614cda565b905095945050505050565b600081519050614d6e81613477565b92915050565b600060208284031215614d8a57614d89613441565b5b6000614d9884828501614d5f565b91505092915050565b6000614dac82613611565b9150614db783613611565b9250828203905081811115614dcf57614dce613f6c565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614e3a60208361356a565b9150614e4582614e04565b602082019050919050565b60006020820190508181036000830152614e6981614e2d565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000614ea6601c8361356a565b9150614eb182614e70565b602082019050919050565b60006020820190508181036000830152614ed581614e99565b905091905056fea2646970667358221220b1932e8ebb589cb34da0241d75dd5a30f4f0a23f171c6a3092ad278586e1f82364736f6c63430008110033

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

000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000104976616e6120546174746f6f204172740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034954410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006468747470733a2f2f626166796265696177686b6c637a6466703477707337367435347176726272736737376b6c3332366f6b34367075636366766e35766a34343464692e697066732e6e667473746f726167652e6c696e6b2f68696464656e2e6a736f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006468747470733a2f2f626166796265696177686b6c637a6466703477707337367435347176726272736737376b6c3332366f6b34367075636366766e35766a34343464692e697066732e6e667473746f726167652e6c696e6b2f68696464656e2e6a736f6e00000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): Ivana Tattoo Art
Arg [1] : _symbol (string): ITA
Arg [2] : _initBaseURI (string): https://bafybeiawhklczdfp4wps76t54qvrbrsg77kl326ok46puccfvn5vj444di.ipfs.nftstorage.link/hidden.json
Arg [3] : _initNotRevealedUri (string): https://bafybeiawhklczdfp4wps76t54qvrbrsg77kl326ok46puccfvn5vj444di.ipfs.nftstorage.link/hidden.json

-----Encoded View---------------
18 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [3] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000010
Arg [5] : 4976616e6120546174746f6f2041727400000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [7] : 4954410000000000000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [9] : 68747470733a2f2f626166796265696177686b6c637a64667034777073373674
Arg [10] : 35347176726272736737376b6c3332366f6b34367075636366766e35766a3434
Arg [11] : 3464692e697066732e6e667473746f726167652e6c696e6b2f68696464656e2e
Arg [12] : 6a736f6e00000000000000000000000000000000000000000000000000000000
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [14] : 68747470733a2f2f626166796265696177686b6c637a64667034777073373674
Arg [15] : 35347176726272736737376b6c3332366f6b34367075636366766e35766a3434
Arg [16] : 3464692e697066732e6e667473746f726167652e6c696e6b2f68696464656e2e
Arg [17] : 6a736f6e00000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

63968:5122:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56490:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68283:73;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;40552:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42064:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64211:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41582:416;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64244:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57130:113;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64580:55;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64355:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;42764:335;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;56798:256;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66312:239;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68364:95;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68618:469;;;:::i;:::-;;43170:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66557:348;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67615:80;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;65020:383;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57320:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64466:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64278:36;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67923:98;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64435:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67701:94;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;40262:223;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64143:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39993:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17975:103;;;;;;;;;;;;;:::i;:::-;;67801:116;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;17327:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;40721:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64499:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65422:882;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42307:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67430:65;;;;;;;;;;;;;:::i;:::-;;43426:322;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64538:37;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64393;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64169;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;66911:497;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67503:104;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;64319:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68027:122;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42533:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68467:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68157:120;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;18233:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;56490:224;56592:4;56631:35;56616:50;;;:11;:50;;;;:90;;;;56670:36;56694:11;56670:23;:36::i;:::-;56616:90;56609:97;;56490:224;;;:::o;68283:73::-;17213:13;:11;:13::i;:::-;68344:6:::1;68335;;:15;;;;;;;;;;;;;;;;;;68283:73:::0;:::o;40552:100::-;40606:13;40639:5;40632:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40552:100;:::o;42064:171::-;42140:7;42160:23;42175:7;42160:14;:23::i;:::-;42203:15;:24;42219:7;42203:24;;;;;;;;;;;;;;;;;;;;;42196:31;;42064:171;;;:::o;64211:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;41582:416::-;41663:13;41679:23;41694:7;41679:14;:23::i;:::-;41663:39;;41727:5;41721:11;;:2;:11;;;41713:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;41821:5;41805:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;41830:37;41847:5;41854:12;:10;:12::i;:::-;41830:16;:37::i;:::-;41805:62;41783:173;;;;;;;;;;;;:::i;:::-;;;;;;;;;41969:21;41978:2;41982:7;41969:8;:21::i;:::-;41652:346;41582:416;;:::o;64244:29::-;;;;:::o;57130:113::-;57191:7;57218:10;:17;;;;57211:24;;57130:113;:::o;64580:55::-;;;;;;;;;;;;;;;;;:::o;64355:33::-;;;;:::o;42764:335::-;42959:41;42978:12;:10;:12::i;:::-;42992:7;42959:18;:41::i;:::-;42951:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;43063:28;43073:4;43079:2;43083:7;43063:9;:28::i;:::-;42764:335;;;:::o;56798:256::-;56895:7;56931:23;56948:5;56931:16;:23::i;:::-;56923:5;:31;56915:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;57020:12;:19;57033:5;57020:19;;;;;;;;;;;;;;;:26;57040:5;57020:26;;;;;;;;;;;;57013:33;;56798:256;;;;:::o;66312:239::-;66371:4;66389:6;66398:1;66389:10;;66384:143;66405:20;:27;;;;66401:1;:31;66384:143;;;66479:5;66452:32;;:20;66473:1;66452:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;:32;;;66448:72;;66506:4;66499:11;;;;;66448:72;66434:3;;;;;:::i;:::-;;;;66384:143;;;;66540:5;66533:12;;66312:239;;;;:::o;68364:95::-;17213:13;:11;:13::i;:::-;68447:6:::1;68429:15;;:24;;;;;;;;;;;;;;;;;;68364:95:::0;:::o;68618:469::-;17213:13;:11;:13::i;:::-;68909:7:::1;68930;:5;:7::i;:::-;68922:21;;68951;68922:55;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68908:69;;;68992:2;68984:11;;;::::0;::::1;;68663:424;68618:469::o:0;43170:185::-;43308:39;43325:4;43331:2;43335:7;43308:39;;;;;;;;;;;;:16;:39::i;:::-;43170:185;;;:::o;66557:348::-;66632:16;66660:23;66686:17;66696:6;66686:9;:17::i;:::-;66660:43;;66710:25;66752:15;66738:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66710:58;;66780:9;66775:103;66795:15;66791:1;:19;66775:103;;;66840:30;66860:6;66868:1;66840:19;:30::i;:::-;66826:8;66835:1;66826:11;;;;;;;;:::i;:::-;;;;;;;:44;;;;;66812:3;;;;;:::i;:::-;;;;66775:103;;;;66891:8;66884:15;;;;66557:348;;;:::o;67615:80::-;17213:13;:11;:13::i;:::-;67681:8:::1;67674:4;:15;;;;67615:80:::0;:::o;65020:383::-;17213:13;:11;:13::i;:::-;65106:14:::1;65123:13;:11;:13::i;:::-;65106:30;;65152:6;65161:1;65152:10;;65147:251;65168:10;;:17;;65164:1;:21;65147:251;;;65230:11;;65217:9;:24;;65209:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;65299:9;;65289:6;:19;;65281:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;65352:36;65362:10;;65373:1;65362:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;65386:1;65377:6;:10;;;;:::i;:::-;65352:9;:36::i;:::-;65187:3;;;;;:::i;:::-;;;;65147:251;;;;65097:306;65020:383:::0;;:::o;57320:233::-;57395:7;57431:30;:28;:30::i;:::-;57423:5;:38;57415:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;57528:10;57539:5;57528:17;;;;;;;;:::i;:::-;;;;;;;;;;57521:24;;57320:233;;;:::o;64466:28::-;;;;;;;;;;;;;:::o;64278:36::-;;;;:::o;67923:98::-;17213:13;:11;:13::i;:::-;68004:11:::1;67994:7;:21;;;;;;:::i;:::-;;67923:98:::0;:::o;64435:26::-;;;;;;;;;;;;;:::o;67701:94::-;17213:13;:11;:13::i;:::-;67781:8:::1;67767:11;:22;;;;67701:94:::0;:::o;40262:223::-;40334:7;40354:13;40370:17;40379:7;40370:8;:17::i;:::-;40354:33;;40423:1;40406:19;;:5;:19;;;40398:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;40472:5;40465:12;;;40262:223;;;:::o;64143:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;39993:207::-;40065:7;40110:1;40093:19;;:5;:19;;;40085:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;40176:9;:16;40186:5;40176:16;;;;;;;;;;;;;;;;40169:23;;39993:207;;;:::o;17975:103::-;17213:13;:11;:13::i;:::-;18040:30:::1;18067:1;18040:18;:30::i;:::-;17975:103::o:0;67801:116::-;17213:13;:11;:13::i;:::-;67894:17:::1;67878:13;:33;;;;67801:116:::0;:::o;17327:87::-;17373:7;17400:6;;;;;;;;;;;17393:13;;17327:87;:::o;40721:104::-;40777:13;40810:7;40803:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40721:104;:::o;64499:34::-;;;;;;;;;;;;;:::o;65422:882::-;65479:14;65496:13;:11;:13::i;:::-;65479:30;;65538:1;65524:11;:15;65516:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;65601:13;;65586:11;:28;;65578:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;65694:9;;65679:11;65670:6;:20;;;;:::i;:::-;:33;;65662:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;65757:7;:5;:7::i;:::-;65743:21;;:10;:21;;;65739:416;;65799:4;65780:23;;:15;;;;;;;;;;;:23;;;65777:298;;65828:25;65842:10;65828:13;:25::i;:::-;65820:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;65896:24;65923:20;:32;65944:10;65923:32;;;;;;;;;;;;;;;;65896:59;;66012:18;;65997:11;65978:16;:30;;;;:::i;:::-;:52;;65970:93;;;;;;;;;;;;:::i;:::-;;;;;;;;;65805:270;65777:298;66113:11;66106:4;;:18;;;;:::i;:::-;66093:9;:31;;66085:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;65739:416;66168:9;66180:1;66168:13;;66163:136;66188:11;66183:1;:16;66163:136;;66215:20;:32;66236:10;66215:32;;;;;;;;;;;;;;;;:34;;;;;;;;;:::i;:::-;;;;;;66258:33;66268:10;66289:1;66280:6;:10;;;;:::i;:::-;66258:9;:33::i;:::-;66201:3;;;;;:::i;:::-;;;;66163:136;;;;65472:832;65422:882;:::o;42307:155::-;42402:52;42421:12;:10;:12::i;:::-;42435:8;42445;42402:18;:52::i;:::-;42307:155;;:::o;67430:65::-;17213:13;:11;:13::i;:::-;67485:4:::1;67474:8;;:15;;;;;;;;;;;;;;;;;;67430:65::o:0;43426:322::-;43600:41;43619:12;:10;:12::i;:::-;43633:7;43600:18;:41::i;:::-;43592:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;43702:38;43716:4;43722:2;43726:7;43735:4;43702:13;:38::i;:::-;43426:322;;;;:::o;64538:37::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;64393:::-;;;;:::o;64169:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;66911:497::-;67009:13;67050:16;67058:7;67050;:16::i;:::-;67034:97;;;;;;;;;;;;:::i;:::-;;;;;;;;;67159:5;67147:17;;:8;;;;;;;;;;;:17;;;67144:62;;67184:14;67177:21;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67144:62;67214:28;67245:10;:8;:10::i;:::-;67214:41;;67300:1;67275:14;67269:28;:32;:133;;;;;;;;;;;;;;;;;67337:14;67353:18;:7;:16;:18::i;:::-;67373:13;67320:67;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;67269:133;67262:140;;;66911:497;;;;:::o;67503:104::-;17213:13;:11;:13::i;:::-;67595:6:::1;67574:18;:27;;;;67503:104:::0;:::o;64319:31::-;;;;:::o;68027:122::-;17213:13;:11;:13::i;:::-;68126:17:::1;68110:13;:33;;;;;;:::i;:::-;;68027:122:::0;:::o;42533:164::-;42630:4;42654:18;:25;42673:5;42654:25;;;;;;;;;;;;;;;:35;42680:8;42654:35;;;;;;;;;;;;;;;;;;;;;;;;;42647:42;;42533:164;;;;:::o;68467:144::-;17213:13;:11;:13::i;:::-;68549:20:::1;;68542:27;;;;:::i;:::-;68599:6;;68576:20;:29;;;;;;;:::i;:::-;;68467:144:::0;;:::o;68157:120::-;17213:13;:11;:13::i;:::-;68256:15:::1;68239:14;:32;;;;;;:::i;:::-;;68157:120:::0;:::o;18233:201::-;17213:13;:11;:13::i;:::-;18342:1:::1;18322:22;;:8;:22;;::::0;18314:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;18398:28;18417:8;18398:18;:28::i;:::-;18233:201:::0;:::o;39624:305::-;39726:4;39778:25;39763:40;;;:11;:40;;;;:105;;;;39835:33;39820:48;;;:11;:48;;;;39763:105;:158;;;;39885:36;39909:11;39885:23;:36::i;:::-;39763:158;39743:178;;39624:305;;;:::o;17492:132::-;17567:12;:10;:12::i;:::-;17556:23;;:7;:5;:7::i;:::-;:23;;;17548:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;17492:132::o;51883:135::-;51965:16;51973:7;51965;:16::i;:::-;51957:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;51883:135;:::o;15878:98::-;15931:7;15958:10;15951:17;;15878:98;:::o;51162:174::-;51264:2;51237:15;:24;51253:7;51237:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;51320:7;51316:2;51282:46;;51291:23;51306:7;51291:14;:23::i;:::-;51282:46;;;;;;;;;;;;51162:174;;:::o;45781:264::-;45874:4;45891:13;45907:23;45922:7;45907:14;:23::i;:::-;45891:39;;45960:5;45949:16;;:7;:16;;;:52;;;;45969:32;45986:5;45993:7;45969:16;:32::i;:::-;45949:52;:87;;;;46029:7;46005:31;;:20;46017:7;46005:11;:20::i;:::-;:31;;;45949:87;45941:96;;;45781:264;;;;:::o;49780:1263::-;49939:4;49912:31;;:23;49927:7;49912:14;:23::i;:::-;:31;;;49904:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;50018:1;50004:16;;:2;:16;;;49996:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;50074:42;50095:4;50101:2;50105:7;50114:1;50074:20;:42::i;:::-;50246:4;50219:31;;:23;50234:7;50219:14;:23::i;:::-;:31;;;50211:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;50364:15;:24;50380:7;50364:24;;;;;;;;;;;;50357:31;;;;;;;;;;;50859:1;50840:9;:15;50850:4;50840:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;50892:1;50875:9;:13;50885:2;50875:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;50934:2;50915:7;:16;50923:7;50915:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;50973:7;50969:2;50954:27;;50963:4;50954:27;;;;;;;;;;;;50994:41;51014:4;51020:2;51024:7;51033:1;50994:19;:41::i;:::-;49780:1263;;;:::o;46387:110::-;46463:26;46473:2;46477:7;46463:26;;;;;;;;;;;;:9;:26::i;:::-;46387:110;;:::o;45056:117::-;45122:7;45149;:16;45157:7;45149:16;;;;;;;;;;;;;;;;;;;;;45142:23;;45056:117;;;:::o;18594:191::-;18668:16;18687:6;;;;;;;;;;;18668:25;;18713:8;18704:6;;:17;;;;;;;;;;;;;;;;;;18768:8;18737:40;;18758:8;18737:40;;;;;;;;;;;;18657:128;18594:191;:::o;51479:315::-;51634:8;51625:17;;:5;:17;;;51617:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;51721:8;51683:18;:25;51702:5;51683:25;;;;;;;;;;;;;;;:35;51709:8;51683:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;51767:8;51745:41;;51760:5;51745:41;;;51777:8;51745:41;;;;;;:::i;:::-;;;;;;;;51479:315;;;:::o;44629:313::-;44785:28;44795:4;44801:2;44805:7;44785:9;:28::i;:::-;44832:47;44855:4;44861:2;44865:7;44874:4;44832:22;:47::i;:::-;44824:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;44629:313;;;;:::o;45486:128::-;45551:4;45604:1;45575:31;;:17;45584:7;45575:8;:17::i;:::-;:31;;;;45568:38;;45486:128;;;:::o;64912:102::-;64972:13;65001:7;64994:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64912:102;:::o;13305:716::-;13361:13;13412:14;13449:1;13429:17;13440:5;13429:10;:17::i;:::-;:21;13412:38;;13465:20;13499:6;13488:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13465:41;;13521:11;13650:6;13646:2;13642:15;13634:6;13630:28;13623:35;;13687:288;13694:4;13687:288;;;13719:5;;;;;;;;13861:8;13856:2;13849:5;13845:14;13840:30;13835:3;13827:44;13917:2;13908:11;;;;;;:::i;:::-;;;;;13951:1;13942:5;:10;13687:288;13938:21;13687:288;13996:6;13989:13;;;;;13305:716;;;:::o;31056:157::-;31141:4;31180:25;31165:40;;;:11;:40;;;;31158:47;;31056:157;;;:::o;57627:915::-;57804:61;57831:4;57837:2;57841:12;57855:9;57804:26;:61::i;:::-;57894:1;57882:9;:13;57878:222;;;58025:63;;;;;;;;;;:::i;:::-;;;;;;;;57878:222;58112:15;58130:12;58112:30;;58175:1;58159:18;;:4;:18;;;58155:187;;58194:40;58226:7;58194:31;:40::i;:::-;58155:187;;;58264:2;58256:10;;:4;:10;;;58252:90;;58283:47;58316:4;58322:7;58283:32;:47::i;:::-;58252:90;58155:187;58370:1;58356:16;;:2;:16;;;58352:183;;58389:45;58426:7;58389:36;:45::i;:::-;58352:183;;;58462:4;58456:10;;:2;:10;;;58452:83;;58483:40;58511:2;58515:7;58483:27;:40::i;:::-;58452:83;58352:183;57793:749;57627:915;;;;:::o;55299:158::-;;;;;:::o;46724:319::-;46853:18;46859:2;46863:7;46853:5;:18::i;:::-;46904:53;46935:1;46939:2;46943:7;46952:4;46904:22;:53::i;:::-;46882:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;46724:319;;;:::o;52582:853::-;52736:4;52757:15;:2;:13;;;:15::i;:::-;52753:675;;;52809:2;52793:36;;;52830:12;:10;:12::i;:::-;52844:4;52850:7;52859:4;52793:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;52789:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53051:1;53034:6;:13;:18;53030:328;;53077:60;;;;;;;;;;:::i;:::-;;;;;;;;53030:328;53308:6;53302:13;53293:6;53289:2;53285:15;53278:38;52789:584;52925:41;;;52915:51;;;:6;:51;;;;52908:58;;;;;52753:675;53412:4;53405:11;;52582:853;;;;;;;:::o;10171:922::-;10224:7;10244:14;10261:1;10244:18;;10311:6;10302:5;:15;10298:102;;10347:6;10338:15;;;;;;:::i;:::-;;;;;10382:2;10372:12;;;;10298:102;10427:6;10418:5;:15;10414:102;;10463:6;10454:15;;;;;;:::i;:::-;;;;;10498:2;10488:12;;;;10414:102;10543:6;10534:5;:15;10530:102;;10579:6;10570:15;;;;;;:::i;:::-;;;;;10614:2;10604:12;;;;10530:102;10659:5;10650;:14;10646:99;;10694:5;10685:14;;;;;;:::i;:::-;;;;;10728:1;10718:11;;;;10646:99;10772:5;10763;:14;10759:99;;10807:5;10798:14;;;;;;:::i;:::-;;;;;10841:1;10831:11;;;;10759:99;10885:5;10876;:14;10872:99;;10920:5;10911:14;;;;;;:::i;:::-;;;;;10954:1;10944:11;;;;10872:99;10998:5;10989;:14;10985:66;;11034:1;11024:11;;;;10985:66;11079:6;11072:13;;;10171:922;;;:::o;54167:410::-;54357:1;54345:9;:13;54341:229;;;54395:1;54379:18;;:4;:18;;;54375:87;;54437:9;54418;:15;54428:4;54418:15;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;54375:87;54494:1;54480:16;;:2;:16;;;54476:83;;54534:9;54517;:13;54527:2;54517:13;;;;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;54476:83;54341:229;54167:410;;;;:::o;59265:164::-;59369:10;:17;;;;59342:15;:24;59358:7;59342:24;;;;;;;;;;;:44;;;;59397:10;59413:7;59397:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59265:164;:::o;60056:988::-;60322:22;60372:1;60347:22;60364:4;60347:16;:22::i;:::-;:26;;;;:::i;:::-;60322:51;;60384:18;60405:17;:26;60423:7;60405:26;;;;;;;;;;;;60384:47;;60552:14;60538:10;:28;60534:328;;60583:19;60605:12;:18;60618:4;60605:18;;;;;;;;;;;;;;;:34;60624:14;60605:34;;;;;;;;;;;;60583:56;;60689:11;60656:12;:18;60669:4;60656:18;;;;;;;;;;;;;;;:30;60675:10;60656:30;;;;;;;;;;;:44;;;;60806:10;60773:17;:30;60791:11;60773:30;;;;;;;;;;;:43;;;;60568:294;60534:328;60958:17;:26;60976:7;60958:26;;;;;;;;;;;60951:33;;;61002:12;:18;61015:4;61002:18;;;;;;;;;;;;;;;:34;61021:14;61002:34;;;;;;;;;;;60995:41;;;60137:907;;60056:988;;:::o;61339:1079::-;61592:22;61637:1;61617:10;:17;;;;:21;;;;:::i;:::-;61592:46;;61649:18;61670:15;:24;61686:7;61670:24;;;;;;;;;;;;61649:45;;62021:19;62043:10;62054:14;62043:26;;;;;;;;:::i;:::-;;;;;;;;;;62021:48;;62107:11;62082:10;62093;62082:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;62218:10;62187:15;:28;62203:11;62187:28;;;;;;;;;;;:41;;;;62359:15;:24;62375:7;62359:24;;;;;;;;;;;62352:31;;;62394:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;61410:1008;;;61339:1079;:::o;58843:221::-;58928:14;58945:20;58962:2;58945:16;:20::i;:::-;58928:37;;59003:7;58976:12;:16;58989:2;58976:16;;;;;;;;;;;;;;;:24;58993:6;58976:24;;;;;;;;;;;:34;;;;59050:6;59021:17;:26;59039:7;59021:26;;;;;;;;;;;:35;;;;58917:147;58843:221;;:::o;47379:942::-;47473:1;47459:16;;:2;:16;;;47451:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;47532:16;47540:7;47532;:16::i;:::-;47531:17;47523:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;47594:48;47623:1;47627:2;47631:7;47640:1;47594:20;:48::i;:::-;47741:16;47749:7;47741;:16::i;:::-;47740:17;47732:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;48156:1;48139:9;:13;48149:2;48139:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;48200:2;48181:7;:16;48189:7;48181:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;48245:7;48241:2;48220:33;;48237:1;48220:33;;;;;;;;;;;;48266:47;48294:1;48298:2;48302:7;48311:1;48266:19;:47::i;:::-;47379:942;;:::o;20025:326::-;20085:4;20342:1;20320:7;:19;;;:23;20313:30;;20025:326;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::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:116::-;1588:21;1603:5;1588:21;:::i;:::-;1581:5;1578:32;1568:60;;1624:1;1621;1614:12;1568:60;1518:116;:::o;1640:133::-;1683:5;1721:6;1708:20;1699:29;;1737:30;1761:5;1737:30;:::i;:::-;1640:133;;;;:::o;1779:323::-;1835:6;1884:2;1872:9;1863:7;1859:23;1855:32;1852:119;;;1890:79;;:::i;:::-;1852:119;2010:1;2035:50;2077:7;2068:6;2057:9;2053:22;2035:50;:::i;:::-;2025:60;;1981:114;1779:323;;;;:::o;2108:99::-;2160:6;2194:5;2188:12;2178:22;;2108:99;;;:::o;2213:169::-;2297:11;2331:6;2326:3;2319:19;2371:4;2366:3;2362:14;2347:29;;2213:169;;;;:::o;2388:246::-;2469:1;2479:113;2493:6;2490:1;2487:13;2479:113;;;2578:1;2573:3;2569:11;2563:18;2559:1;2554:3;2550:11;2543:39;2515:2;2512:1;2508:10;2503:15;;2479:113;;;2626:1;2617:6;2612:3;2608:16;2601:27;2450:184;2388:246;;;:::o;2640:102::-;2681:6;2732:2;2728:7;2723:2;2716:5;2712:14;2708:28;2698:38;;2640:102;;;:::o;2748:377::-;2836:3;2864:39;2897:5;2864:39;:::i;:::-;2919:71;2983:6;2978:3;2919:71;:::i;:::-;2912:78;;2999:65;3057:6;3052:3;3045:4;3038:5;3034:16;2999:65;:::i;:::-;3089:29;3111:6;3089:29;:::i;:::-;3084:3;3080:39;3073:46;;2840:285;2748:377;;;;:::o;3131:313::-;3244:4;3282:2;3271:9;3267:18;3259:26;;3331:9;3325:4;3321:20;3317:1;3306:9;3302:17;3295:47;3359:78;3432:4;3423:6;3359:78;:::i;:::-;3351:86;;3131:313;;;;:::o;3450:77::-;3487:7;3516:5;3505:16;;3450:77;;;:::o;3533:122::-;3606:24;3624:5;3606:24;:::i;:::-;3599:5;3596:35;3586:63;;3645:1;3642;3635:12;3586:63;3533:122;:::o;3661:139::-;3707:5;3745:6;3732:20;3723:29;;3761:33;3788:5;3761:33;:::i;:::-;3661:139;;;;:::o;3806:329::-;3865:6;3914:2;3902:9;3893:7;3889:23;3885:32;3882:119;;;3920:79;;:::i;:::-;3882:119;4040:1;4065:53;4110:7;4101:6;4090:9;4086:22;4065:53;:::i;:::-;4055:63;;4011:117;3806:329;;;;:::o;4141:126::-;4178:7;4218:42;4211:5;4207:54;4196:65;;4141:126;;;:::o;4273:96::-;4310:7;4339:24;4357:5;4339:24;:::i;:::-;4328:35;;4273:96;;;:::o;4375:118::-;4462:24;4480:5;4462:24;:::i;:::-;4457:3;4450:37;4375:118;;:::o;4499:222::-;4592:4;4630:2;4619:9;4615:18;4607:26;;4643:71;4711:1;4700:9;4696:17;4687:6;4643:71;:::i;:::-;4499:222;;;;:::o;4727:122::-;4800:24;4818:5;4800:24;:::i;:::-;4793:5;4790:35;4780:63;;4839:1;4836;4829:12;4780:63;4727:122;:::o;4855:139::-;4901:5;4939:6;4926:20;4917:29;;4955:33;4982:5;4955:33;:::i;:::-;4855:139;;;;:::o;5000:474::-;5068:6;5076;5125:2;5113:9;5104:7;5100:23;5096:32;5093:119;;;5131:79;;:::i;:::-;5093:119;5251:1;5276:53;5321:7;5312:6;5301:9;5297:22;5276:53;:::i;:::-;5266:63;;5222:117;5378:2;5404:53;5449:7;5440:6;5429:9;5425:22;5404:53;:::i;:::-;5394:63;;5349:118;5000:474;;;;;:::o;5480:118::-;5567:24;5585:5;5567:24;:::i;:::-;5562:3;5555:37;5480:118;;:::o;5604:222::-;5697:4;5735:2;5724:9;5720:18;5712:26;;5748:71;5816:1;5805:9;5801:17;5792:6;5748:71;:::i;:::-;5604:222;;;;:::o;5832:329::-;5891:6;5940:2;5928:9;5919:7;5915:23;5911:32;5908:119;;;5946:79;;:::i;:::-;5908:119;6066:1;6091:53;6136:7;6127:6;6116:9;6112:22;6091:53;:::i;:::-;6081:63;;6037:117;5832:329;;;;:::o;6167:619::-;6244:6;6252;6260;6309:2;6297:9;6288:7;6284:23;6280:32;6277:119;;;6315:79;;:::i;:::-;6277:119;6435:1;6460:53;6505:7;6496:6;6485:9;6481:22;6460:53;:::i;:::-;6450:63;;6406:117;6562:2;6588:53;6633:7;6624:6;6613:9;6609:22;6588:53;:::i;:::-;6578:63;;6533:118;6690:2;6716:53;6761:7;6752:6;6741:9;6737:22;6716:53;:::i;:::-;6706:63;;6661:118;6167:619;;;;;:::o;6792:114::-;6859:6;6893:5;6887:12;6877:22;;6792:114;;;:::o;6912:184::-;7011:11;7045:6;7040:3;7033:19;7085:4;7080:3;7076:14;7061:29;;6912:184;;;;:::o;7102:132::-;7169:4;7192:3;7184:11;;7222:4;7217:3;7213:14;7205:22;;7102:132;;;:::o;7240:108::-;7317:24;7335:5;7317:24;:::i;:::-;7312:3;7305:37;7240:108;;:::o;7354:179::-;7423:10;7444:46;7486:3;7478:6;7444:46;:::i;:::-;7522:4;7517:3;7513:14;7499:28;;7354:179;;;;:::o;7539:113::-;7609:4;7641;7636:3;7632:14;7624:22;;7539:113;;;:::o;7688:732::-;7807:3;7836:54;7884:5;7836:54;:::i;:::-;7906:86;7985:6;7980:3;7906:86;:::i;:::-;7899:93;;8016:56;8066:5;8016:56;:::i;:::-;8095:7;8126:1;8111:284;8136:6;8133:1;8130:13;8111:284;;;8212:6;8206:13;8239:63;8298:3;8283:13;8239:63;:::i;:::-;8232:70;;8325:60;8378:6;8325:60;:::i;:::-;8315:70;;8171:224;8158:1;8155;8151:9;8146:14;;8111:284;;;8115:14;8411:3;8404:10;;7812:608;;;7688:732;;;;:::o;8426:373::-;8569:4;8607:2;8596:9;8592:18;8584:26;;8656:9;8650:4;8646:20;8642:1;8631:9;8627:17;8620:47;8684:108;8787:4;8778:6;8684:108;:::i;:::-;8676:116;;8426:373;;;;:::o;8805:117::-;8914:1;8911;8904:12;8928:117;9037:1;9034;9027:12;9051:117;9160:1;9157;9150:12;9191:568;9264:8;9274:6;9324:3;9317:4;9309:6;9305:17;9301:27;9291:122;;9332:79;;:::i;:::-;9291:122;9445:6;9432:20;9422:30;;9475:18;9467:6;9464:30;9461:117;;;9497:79;;:::i;:::-;9461:117;9611:4;9603:6;9599:17;9587:29;;9665:3;9657:4;9649:6;9645:17;9635:8;9631:32;9628:41;9625:128;;;9672:79;;:::i;:::-;9625:128;9191:568;;;;;:::o;9765:559::-;9851:6;9859;9908:2;9896:9;9887:7;9883:23;9879:32;9876:119;;;9914:79;;:::i;:::-;9876:119;10062:1;10051:9;10047:17;10034:31;10092:18;10084:6;10081:30;10078:117;;;10114:79;;:::i;:::-;10078:117;10227:80;10299:7;10290:6;10279:9;10275:22;10227:80;:::i;:::-;10209:98;;;;10005:312;9765:559;;;;;:::o;10330:117::-;10439:1;10436;10429:12;10453:180;10501:77;10498:1;10491:88;10598:4;10595:1;10588:15;10622:4;10619:1;10612:15;10639:281;10722:27;10744:4;10722:27;:::i;:::-;10714:6;10710:40;10852:6;10840:10;10837:22;10816:18;10804:10;10801:34;10798:62;10795:88;;;10863:18;;:::i;:::-;10795:88;10903:10;10899:2;10892:22;10682:238;10639:281;;:::o;10926:129::-;10960:6;10987:20;;:::i;:::-;10977:30;;11016:33;11044:4;11036:6;11016:33;:::i;:::-;10926:129;;;:::o;11061:308::-;11123:4;11213:18;11205:6;11202:30;11199:56;;;11235:18;;:::i;:::-;11199:56;11273:29;11295:6;11273:29;:::i;:::-;11265:37;;11357:4;11351;11347:15;11339:23;;11061:308;;;:::o;11375:146::-;11472:6;11467:3;11462;11449:30;11513:1;11504:6;11499:3;11495:16;11488:27;11375:146;;;:::o;11527:425::-;11605:5;11630:66;11646:49;11688:6;11646:49;:::i;:::-;11630:66;:::i;:::-;11621:75;;11719:6;11712:5;11705:21;11757:4;11750:5;11746:16;11795:3;11786:6;11781:3;11777:16;11774:25;11771:112;;;11802:79;;:::i;:::-;11771:112;11892:54;11939:6;11934:3;11929;11892:54;:::i;:::-;11611:341;11527:425;;;;;:::o;11972:340::-;12028:5;12077:3;12070:4;12062:6;12058:17;12054:27;12044:122;;12085:79;;:::i;:::-;12044:122;12202:6;12189:20;12227:79;12302:3;12294:6;12287:4;12279:6;12275:17;12227:79;:::i;:::-;12218:88;;12034:278;11972:340;;;;:::o;12318:509::-;12387:6;12436:2;12424:9;12415:7;12411:23;12407:32;12404:119;;;12442:79;;:::i;:::-;12404:119;12590:1;12579:9;12575:17;12562:31;12620:18;12612:6;12609:30;12606:117;;;12642:79;;:::i;:::-;12606:117;12747:63;12802:7;12793:6;12782:9;12778:22;12747:63;:::i;:::-;12737:73;;12533:287;12318:509;;;;:::o;12833:468::-;12898:6;12906;12955:2;12943:9;12934:7;12930:23;12926:32;12923:119;;;12961:79;;:::i;:::-;12923:119;13081:1;13106:53;13151:7;13142:6;13131:9;13127:22;13106:53;:::i;:::-;13096:63;;13052:117;13208:2;13234:50;13276:7;13267:6;13256:9;13252:22;13234:50;:::i;:::-;13224:60;;13179:115;12833:468;;;;;:::o;13307:307::-;13368:4;13458:18;13450:6;13447:30;13444:56;;;13480:18;;:::i;:::-;13444:56;13518:29;13540:6;13518:29;:::i;:::-;13510:37;;13602:4;13596;13592:15;13584:23;;13307:307;;;:::o;13620:423::-;13697:5;13722:65;13738:48;13779:6;13738:48;:::i;:::-;13722:65;:::i;:::-;13713:74;;13810:6;13803:5;13796:21;13848:4;13841:5;13837:16;13886:3;13877:6;13872:3;13868:16;13865:25;13862:112;;;13893:79;;:::i;:::-;13862:112;13983:54;14030:6;14025:3;14020;13983:54;:::i;:::-;13703:340;13620:423;;;;;:::o;14062:338::-;14117:5;14166:3;14159:4;14151:6;14147:17;14143:27;14133:122;;14174:79;;:::i;:::-;14133:122;14291:6;14278:20;14316:78;14390:3;14382:6;14375:4;14367:6;14363:17;14316:78;:::i;:::-;14307:87;;14123:277;14062:338;;;;:::o;14406:943::-;14501:6;14509;14517;14525;14574:3;14562:9;14553:7;14549:23;14545:33;14542:120;;;14581:79;;:::i;:::-;14542:120;14701:1;14726:53;14771:7;14762:6;14751:9;14747:22;14726:53;:::i;:::-;14716:63;;14672:117;14828:2;14854:53;14899:7;14890:6;14879:9;14875:22;14854:53;:::i;:::-;14844:63;;14799:118;14956:2;14982:53;15027:7;15018:6;15007:9;15003:22;14982:53;:::i;:::-;14972:63;;14927:118;15112:2;15101:9;15097:18;15084:32;15143:18;15135:6;15132:30;15129:117;;;15165:79;;:::i;:::-;15129:117;15270:62;15324:7;15315:6;15304:9;15300:22;15270:62;:::i;:::-;15260:72;;15055:287;14406:943;;;;;;;:::o;15355:474::-;15423:6;15431;15480:2;15468:9;15459:7;15455:23;15451:32;15448:119;;;15486:79;;:::i;:::-;15448:119;15606:1;15631:53;15676:7;15667:6;15656:9;15652:22;15631:53;:::i;:::-;15621:63;;15577:117;15733:2;15759:53;15804:7;15795:6;15784:9;15780:22;15759:53;:::i;:::-;15749:63;;15704:118;15355:474;;;;;:::o;15835:180::-;15883:77;15880:1;15873:88;15980:4;15977:1;15970:15;16004:4;16001:1;15994:15;16021:320;16065:6;16102:1;16096:4;16092:12;16082:22;;16149:1;16143:4;16139:12;16170:18;16160:81;;16226:4;16218:6;16214:17;16204:27;;16160:81;16288:2;16280:6;16277:14;16257:18;16254:38;16251:84;;16307:18;;:::i;:::-;16251:84;16072:269;16021:320;;;:::o;16347:220::-;16487:34;16483:1;16475:6;16471:14;16464:58;16556:3;16551:2;16543:6;16539:15;16532:28;16347:220;:::o;16573:366::-;16715:3;16736:67;16800:2;16795:3;16736:67;:::i;:::-;16729:74;;16812:93;16901:3;16812:93;:::i;:::-;16930:2;16925:3;16921:12;16914:19;;16573:366;;;:::o;16945:419::-;17111:4;17149:2;17138:9;17134:18;17126:26;;17198:9;17192:4;17188:20;17184:1;17173:9;17169:17;17162:47;17226:131;17352:4;17226:131;:::i;:::-;17218:139;;16945:419;;;:::o;17370:248::-;17510:34;17506:1;17498:6;17494:14;17487:58;17579:31;17574:2;17566:6;17562:15;17555:56;17370:248;:::o;17624:366::-;17766:3;17787:67;17851:2;17846:3;17787:67;:::i;:::-;17780:74;;17863:93;17952:3;17863:93;:::i;:::-;17981:2;17976:3;17972:12;17965:19;;17624:366;;;:::o;17996:419::-;18162:4;18200:2;18189:9;18185:18;18177:26;;18249:9;18243:4;18239:20;18235:1;18224:9;18220:17;18213:47;18277:131;18403:4;18277:131;:::i;:::-;18269:139;;17996:419;;;:::o;18421:232::-;18561:34;18557:1;18549:6;18545:14;18538:58;18630:15;18625:2;18617:6;18613:15;18606:40;18421:232;:::o;18659:366::-;18801:3;18822:67;18886:2;18881:3;18822:67;:::i;:::-;18815:74;;18898:93;18987:3;18898:93;:::i;:::-;19016:2;19011:3;19007:12;19000:19;;18659:366;;;:::o;19031:419::-;19197:4;19235:2;19224:9;19220:18;19212:26;;19284:9;19278:4;19274:20;19270:1;19259:9;19255:17;19248:47;19312:131;19438:4;19312:131;:::i;:::-;19304:139;;19031:419;;;:::o;19456:230::-;19596:34;19592:1;19584:6;19580:14;19573:58;19665:13;19660:2;19652:6;19648:15;19641:38;19456:230;:::o;19692:366::-;19834:3;19855:67;19919:2;19914:3;19855:67;:::i;:::-;19848:74;;19931:93;20020:3;19931:93;:::i;:::-;20049:2;20044:3;20040:12;20033:19;;19692:366;;;:::o;20064:419::-;20230:4;20268:2;20257:9;20253:18;20245:26;;20317:9;20311:4;20307:20;20303:1;20292:9;20288:17;20281:47;20345:131;20471:4;20345:131;:::i;:::-;20337:139;;20064:419;;;:::o;20489:180::-;20537:77;20534:1;20527:88;20634:4;20631:1;20624:15;20658:4;20655:1;20648:15;20675:180;20723:77;20720:1;20713:88;20820:4;20817:1;20810:15;20844:4;20841:1;20834:15;20861:233;20900:3;20923:24;20941:5;20923:24;:::i;:::-;20914:33;;20969:66;20962:5;20959:77;20956:103;;21039:18;;:::i;:::-;20956:103;21086:1;21079:5;21075:13;21068:20;;20861:233;;;:::o;21100:147::-;21201:11;21238:3;21223:18;;21100:147;;;;:::o;21253:114::-;;:::o;21373:398::-;21532:3;21553:83;21634:1;21629:3;21553:83;:::i;:::-;21546:90;;21645:93;21734:3;21645:93;:::i;:::-;21763:1;21758:3;21754:11;21747:18;;21373:398;;;:::o;21777:379::-;21961:3;21983:147;22126:3;21983:147;:::i;:::-;21976:154;;22147:3;22140:10;;21777:379;;;:::o;22162:168::-;22302:20;22298:1;22290:6;22286:14;22279:44;22162:168;:::o;22336:366::-;22478:3;22499:67;22563:2;22558:3;22499:67;:::i;:::-;22492:74;;22575:93;22664:3;22575:93;:::i;:::-;22693:2;22688:3;22684:12;22677:19;;22336:366;;;:::o;22708:419::-;22874:4;22912:2;22901:9;22897:18;22889:26;;22961:9;22955:4;22951:20;22947:1;22936:9;22932:17;22925:47;22989:131;23115:4;22989:131;:::i;:::-;22981:139;;22708:419;;;:::o;23133:172::-;23273:24;23269:1;23261:6;23257:14;23250:48;23133:172;:::o;23311:366::-;23453:3;23474:67;23538:2;23533:3;23474:67;:::i;:::-;23467:74;;23550:93;23639:3;23550:93;:::i;:::-;23668:2;23663:3;23659:12;23652:19;;23311:366;;;:::o;23683:419::-;23849:4;23887:2;23876:9;23872:18;23864:26;;23936:9;23930:4;23926:20;23922:1;23911:9;23907:17;23900:47;23964:131;24090:4;23964:131;:::i;:::-;23956:139;;23683:419;;;:::o;24108:191::-;24148:3;24167:20;24185:1;24167:20;:::i;:::-;24162:25;;24201:20;24219:1;24201:20;:::i;:::-;24196:25;;24244:1;24241;24237:9;24230:16;;24265:3;24262:1;24259:10;24256:36;;;24272:18;;:::i;:::-;24256:36;24108:191;;;;:::o;24305:231::-;24445:34;24441:1;24433:6;24429:14;24422:58;24514:14;24509:2;24501:6;24497:15;24490:39;24305:231;:::o;24542:366::-;24684:3;24705:67;24769:2;24764:3;24705:67;:::i;:::-;24698:74;;24781:93;24870:3;24781:93;:::i;:::-;24899:2;24894:3;24890:12;24883:19;;24542:366;;;:::o;24914:419::-;25080:4;25118:2;25107:9;25103:18;25095:26;;25167:9;25161:4;25157:20;25153:1;25142:9;25138:17;25131:47;25195:131;25321:4;25195:131;:::i;:::-;25187:139;;24914:419;;;:::o;25339:141::-;25388:4;25411:3;25403:11;;25434:3;25431:1;25424:14;25468:4;25465:1;25455:18;25447:26;;25339:141;;;:::o;25486:93::-;25523:6;25570:2;25565;25558:5;25554:14;25550:23;25540:33;;25486:93;;;:::o;25585:107::-;25629:8;25679:5;25673:4;25669:16;25648:37;;25585:107;;;;:::o;25698:393::-;25767:6;25817:1;25805:10;25801:18;25840:97;25870:66;25859:9;25840:97;:::i;:::-;25958:39;25988:8;25977:9;25958:39;:::i;:::-;25946:51;;26030:4;26026:9;26019:5;26015:21;26006:30;;26079:4;26069:8;26065:19;26058:5;26055:30;26045:40;;25774:317;;25698:393;;;;;:::o;26097:60::-;26125:3;26146:5;26139:12;;26097:60;;;:::o;26163:142::-;26213:9;26246:53;26264:34;26273:24;26291:5;26273:24;:::i;:::-;26264:34;:::i;:::-;26246:53;:::i;:::-;26233:66;;26163:142;;;:::o;26311:75::-;26354:3;26375:5;26368:12;;26311:75;;;:::o;26392:269::-;26502:39;26533:7;26502:39;:::i;:::-;26563:91;26612:41;26636:16;26612:41;:::i;:::-;26604:6;26597:4;26591:11;26563:91;:::i;:::-;26557:4;26550:105;26468:193;26392:269;;;:::o;26667:73::-;26712:3;26667:73;:::o;26746:189::-;26823:32;;:::i;:::-;26864:65;26922:6;26914;26908:4;26864:65;:::i;:::-;26799:136;26746:189;;:::o;26941:186::-;27001:120;27018:3;27011:5;27008:14;27001:120;;;27072:39;27109:1;27102:5;27072:39;:::i;:::-;27045:1;27038:5;27034:13;27025:22;;27001:120;;;26941:186;;:::o;27133:543::-;27234:2;27229:3;27226:11;27223:446;;;27268:38;27300:5;27268:38;:::i;:::-;27352:29;27370:10;27352:29;:::i;:::-;27342:8;27338:44;27535:2;27523:10;27520:18;27517:49;;;27556:8;27541:23;;27517:49;27579:80;27635:22;27653:3;27635:22;:::i;:::-;27625:8;27621:37;27608:11;27579:80;:::i;:::-;27238:431;;27223:446;27133:543;;;:::o;27682:117::-;27736:8;27786:5;27780:4;27776:16;27755:37;;27682:117;;;;:::o;27805:169::-;27849:6;27882:51;27930:1;27926:6;27918:5;27915:1;27911:13;27882:51;:::i;:::-;27878:56;27963:4;27957;27953:15;27943:25;;27856:118;27805:169;;;;:::o;27979:295::-;28055:4;28201:29;28226:3;28220:4;28201:29;:::i;:::-;28193:37;;28263:3;28260:1;28256:11;28250:4;28247:21;28239:29;;27979:295;;;;:::o;28279:1395::-;28396:37;28429:3;28396:37;:::i;:::-;28498:18;28490:6;28487:30;28484:56;;;28520:18;;:::i;:::-;28484:56;28564:38;28596:4;28590:11;28564:38;:::i;:::-;28649:67;28709:6;28701;28695:4;28649:67;:::i;:::-;28743:1;28767:4;28754:17;;28799:2;28791:6;28788:14;28816:1;28811:618;;;;29473:1;29490:6;29487:77;;;29539:9;29534:3;29530:19;29524:26;29515:35;;29487:77;29590:67;29650:6;29643:5;29590:67;:::i;:::-;29584:4;29577:81;29446:222;28781:887;;28811:618;28863:4;28859:9;28851:6;28847:22;28897:37;28929:4;28897:37;:::i;:::-;28956:1;28970:208;28984:7;28981:1;28978:14;28970:208;;;29063:9;29058:3;29054:19;29048:26;29040:6;29033:42;29114:1;29106:6;29102:14;29092:24;;29161:2;29150:9;29146:18;29133:31;;29007:4;29004:1;29000:12;28995:17;;28970:208;;;29206:6;29197:7;29194:19;29191:179;;;29264:9;29259:3;29255:19;29249:26;29307:48;29349:4;29341:6;29337:17;29326:9;29307:48;:::i;:::-;29299:6;29292:64;29214:156;29191:179;29416:1;29412;29404:6;29400:14;29396:22;29390:4;29383:36;28818:611;;;28781:887;;28371:1303;;;28279:1395;;:::o;29680:174::-;29820:26;29816:1;29808:6;29804:14;29797:50;29680:174;:::o;29860:366::-;30002:3;30023:67;30087:2;30082:3;30023:67;:::i;:::-;30016:74;;30099:93;30188:3;30099:93;:::i;:::-;30217:2;30212:3;30208:12;30201:19;;29860:366;;;:::o;30232:419::-;30398:4;30436:2;30425:9;30421:18;30413:26;;30485:9;30479:4;30475:20;30471:1;30460:9;30456:17;30449:47;30513:131;30639:4;30513:131;:::i;:::-;30505:139;;30232:419;;;:::o;30657:228::-;30797:34;30793:1;30785:6;30781:14;30774:58;30866:11;30861:2;30853:6;30849:15;30842:36;30657:228;:::o;30891:366::-;31033:3;31054:67;31118:2;31113:3;31054:67;:::i;:::-;31047:74;;31130:93;31219:3;31130:93;:::i;:::-;31248:2;31243:3;31239:12;31232:19;;30891:366;;;:::o;31263:419::-;31429:4;31467:2;31456:9;31452:18;31444:26;;31516:9;31510:4;31506:20;31502:1;31491:9;31487:17;31480:47;31544:131;31670:4;31544:131;:::i;:::-;31536:139;;31263:419;;;:::o;31688:177::-;31828:29;31824:1;31816:6;31812:14;31805:53;31688:177;:::o;31871:366::-;32013:3;32034:67;32098:2;32093:3;32034:67;:::i;:::-;32027:74;;32110:93;32199:3;32110:93;:::i;:::-;32228:2;32223:3;32219:12;32212:19;;31871:366;;;:::o;32243:419::-;32409:4;32447:2;32436:9;32432:18;32424:26;;32496:9;32490:4;32486:20;32482:1;32471:9;32467:17;32460:47;32524:131;32650:4;32524:131;:::i;:::-;32516:139;;32243:419;;;:::o;32668:223::-;32808:34;32804:1;32796:6;32792:14;32785:58;32877:6;32872:2;32864:6;32860:15;32853:31;32668:223;:::o;32897:366::-;33039:3;33060:67;33124:2;33119:3;33060:67;:::i;:::-;33053:74;;33136:93;33225:3;33136:93;:::i;:::-;33254:2;33249:3;33245:12;33238:19;;32897:366;;;:::o;33269:419::-;33435:4;33473:2;33462:9;33458:18;33450:26;;33522:9;33516:4;33512:20;33508:1;33497:9;33493:17;33486:47;33550:131;33676:4;33550:131;:::i;:::-;33542:139;;33269:419;;;:::o;33694:173::-;33834:25;33830:1;33822:6;33818:14;33811:49;33694:173;:::o;33873:366::-;34015:3;34036:67;34100:2;34095:3;34036:67;:::i;:::-;34029:74;;34112:93;34201:3;34112:93;:::i;:::-;34230:2;34225:3;34221:12;34214:19;;33873:366;;;:::o;34245:419::-;34411:4;34449:2;34438:9;34434:18;34426:26;;34498:9;34492:4;34488:20;34484:1;34473:9;34469:17;34462:47;34526:131;34652:4;34526:131;:::i;:::-;34518:139;;34245:419;;;:::o;34670:178::-;34810:30;34806:1;34798:6;34794:14;34787:54;34670:178;:::o;34854:366::-;34996:3;35017:67;35081:2;35076:3;35017:67;:::i;:::-;35010:74;;35093:93;35182:3;35093:93;:::i;:::-;35211:2;35206:3;35202:12;35195:19;;34854:366;;;:::o;35226:419::-;35392:4;35430:2;35419:9;35415:18;35407:26;;35479:9;35473:4;35469:20;35465:1;35454:9;35450:17;35443:47;35507:131;35633:4;35507:131;:::i;:::-;35499:139;;35226:419;;;:::o;35651:410::-;35691:7;35714:20;35732:1;35714:20;:::i;:::-;35709:25;;35748:20;35766:1;35748:20;:::i;:::-;35743:25;;35803:1;35800;35796:9;35825:30;35843:11;35825:30;:::i;:::-;35814:41;;36004:1;35995:7;35991:15;35988:1;35985:22;35965:1;35958:9;35938:83;35915:139;;36034:18;;:::i;:::-;35915:139;35699:362;35651:410;;;;:::o;36067:234::-;36207:34;36203:1;36195:6;36191:14;36184:58;36276:17;36271:2;36263:6;36259:15;36252:42;36067:234;:::o;36307:366::-;36449:3;36470:67;36534:2;36529:3;36470:67;:::i;:::-;36463:74;;36546:93;36635:3;36546:93;:::i;:::-;36664:2;36659:3;36655:12;36648:19;;36307:366;;;:::o;36679:419::-;36845:4;36883:2;36872:9;36868:18;36860:26;;36932:9;36926:4;36922:20;36918:1;36907:9;36903:17;36896:47;36960:131;37086:4;36960:131;:::i;:::-;36952:139;;36679:419;;;:::o;37104:148::-;37206:11;37243:3;37228:18;;37104:148;;;;:::o;37258:390::-;37364:3;37392:39;37425:5;37392:39;:::i;:::-;37447:89;37529:6;37524:3;37447:89;:::i;:::-;37440:96;;37545:65;37603:6;37598:3;37591:4;37584:5;37580:16;37545:65;:::i;:::-;37635:6;37630:3;37626:16;37619:23;;37368:280;37258:390;;;;:::o;37678:874::-;37781:3;37818:5;37812:12;37847:36;37873:9;37847:36;:::i;:::-;37899:89;37981:6;37976:3;37899:89;:::i;:::-;37892:96;;38019:1;38008:9;38004:17;38035:1;38030:166;;;;38210:1;38205:341;;;;37997:549;;38030:166;38114:4;38110:9;38099;38095:25;38090:3;38083:38;38176:6;38169:14;38162:22;38154:6;38150:35;38145:3;38141:45;38134:52;;38030:166;;38205:341;38272:38;38304:5;38272:38;:::i;:::-;38332:1;38346:154;38360:6;38357:1;38354:13;38346:154;;;38434:7;38428:14;38424:1;38419:3;38415:11;38408:35;38484:1;38475:7;38471:15;38460:26;;38382:4;38379:1;38375:12;38370:17;;38346:154;;;38529:6;38524:3;38520:16;38513:23;;38212:334;;37997:549;;37785:767;;37678:874;;;;:::o;38558:589::-;38783:3;38805:95;38896:3;38887:6;38805:95;:::i;:::-;38798:102;;38917:95;39008:3;38999:6;38917:95;:::i;:::-;38910:102;;39029:92;39117:3;39108:6;39029:92;:::i;:::-;39022:99;;39138:3;39131:10;;38558:589;;;;;;:::o;39153:225::-;39293:34;39289:1;39281:6;39277:14;39270:58;39362:8;39357:2;39349:6;39345:15;39338:33;39153:225;:::o;39384:366::-;39526:3;39547:67;39611:2;39606:3;39547:67;:::i;:::-;39540:74;;39623:93;39712:3;39623:93;:::i;:::-;39741:2;39736:3;39732:12;39725:19;;39384:366;;;:::o;39756:419::-;39922:4;39960:2;39949:9;39945:18;39937:26;;40009:9;40003:4;39999:20;39995:1;39984:9;39980:17;39973:47;40037:131;40163:4;40037:131;:::i;:::-;40029:139;;39756:419;;;:::o;40181:182::-;40321:34;40317:1;40309:6;40305:14;40298:58;40181:182;:::o;40369:366::-;40511:3;40532:67;40596:2;40591:3;40532:67;:::i;:::-;40525:74;;40608:93;40697:3;40608:93;:::i;:::-;40726:2;40721:3;40717:12;40710:19;;40369:366;;;:::o;40741:419::-;40907:4;40945:2;40934:9;40930:18;40922:26;;40994:9;40988:4;40984:20;40980:1;40969:9;40965:17;40958:47;41022:131;41148:4;41022:131;:::i;:::-;41014:139;;40741:419;;;:::o;41166:224::-;41306:34;41302:1;41294:6;41290:14;41283:58;41375:7;41370:2;41362:6;41358:15;41351:32;41166:224;:::o;41396:366::-;41538:3;41559:67;41623:2;41618:3;41559:67;:::i;:::-;41552:74;;41635:93;41724:3;41635:93;:::i;:::-;41753:2;41748:3;41744:12;41737:19;;41396:366;;;:::o;41768:419::-;41934:4;41972:2;41961:9;41957:18;41949:26;;42021:9;42015:4;42011:20;42007:1;41996:9;41992:17;41985:47;42049:131;42175:4;42049:131;:::i;:::-;42041:139;;41768:419;;;:::o;42193:223::-;42333:34;42329:1;42321:6;42317:14;42310:58;42402:6;42397:2;42389:6;42385:15;42378:31;42193:223;:::o;42422:366::-;42564:3;42585:67;42649:2;42644:3;42585:67;:::i;:::-;42578:74;;42661:93;42750:3;42661:93;:::i;:::-;42779:2;42774:3;42770:12;42763:19;;42422:366;;;:::o;42794:419::-;42960:4;42998:2;42987:9;42983:18;42975:26;;43047:9;43041:4;43037:20;43033:1;43022:9;43018:17;43011:47;43075:131;43201:4;43075:131;:::i;:::-;43067:139;;42794:419;;;:::o;43219:175::-;43359:27;43355:1;43347:6;43343:14;43336:51;43219:175;:::o;43400:366::-;43542:3;43563:67;43627:2;43622:3;43563:67;:::i;:::-;43556:74;;43639:93;43728:3;43639:93;:::i;:::-;43757:2;43752:3;43748:12;43741:19;;43400:366;;;:::o;43772:419::-;43938:4;43976:2;43965:9;43961:18;43953:26;;44025:9;44019:4;44015:20;44011:1;44000:9;43996:17;43989:47;44053:131;44179:4;44053:131;:::i;:::-;44045:139;;43772:419;;;:::o;44197:237::-;44337:34;44333:1;44325:6;44321:14;44314:58;44406:20;44401:2;44393:6;44389:15;44382:45;44197:237;:::o;44440:366::-;44582:3;44603:67;44667:2;44662:3;44603:67;:::i;:::-;44596:74;;44679:93;44768:3;44679:93;:::i;:::-;44797:2;44792:3;44788:12;44781:19;;44440:366;;;:::o;44812:419::-;44978:4;45016:2;45005:9;45001:18;44993:26;;45065:9;45059:4;45055:20;45051:1;45040:9;45036:17;45029:47;45093:131;45219:4;45093:131;:::i;:::-;45085:139;;44812:419;;;:::o;45237:180::-;45285:77;45282:1;45275:88;45382:4;45379:1;45372:15;45406:4;45403:1;45396:15;45423:240;45563:34;45559:1;45551:6;45547:14;45540:58;45632:23;45627:2;45619:6;45615:15;45608:48;45423:240;:::o;45669:366::-;45811:3;45832:67;45896:2;45891:3;45832:67;:::i;:::-;45825:74;;45908:93;45997:3;45908:93;:::i;:::-;46026:2;46021:3;46017:12;46010:19;;45669:366;;;:::o;46041:419::-;46207:4;46245:2;46234:9;46230:18;46222:26;;46294:9;46288:4;46284:20;46280:1;46269:9;46265:17;46258:47;46322:131;46448:4;46322:131;:::i;:::-;46314:139;;46041:419;;;:::o;46466:98::-;46517:6;46551:5;46545:12;46535:22;;46466:98;;;:::o;46570:168::-;46653:11;46687:6;46682:3;46675:19;46727:4;46722:3;46718:14;46703:29;;46570:168;;;;:::o;46744:373::-;46830:3;46858:38;46890:5;46858:38;:::i;:::-;46912:70;46975:6;46970:3;46912:70;:::i;:::-;46905:77;;46991:65;47049:6;47044:3;47037:4;47030:5;47026:16;46991:65;:::i;:::-;47081:29;47103:6;47081:29;:::i;:::-;47076:3;47072:39;47065:46;;46834:283;46744:373;;;;:::o;47123:640::-;47318:4;47356:3;47345:9;47341:19;47333:27;;47370:71;47438:1;47427:9;47423:17;47414:6;47370:71;:::i;:::-;47451:72;47519:2;47508:9;47504:18;47495:6;47451:72;:::i;:::-;47533;47601:2;47590:9;47586:18;47577:6;47533:72;:::i;:::-;47652:9;47646:4;47642:20;47637:2;47626:9;47622:18;47615:48;47680:76;47751:4;47742:6;47680:76;:::i;:::-;47672:84;;47123:640;;;;;;;:::o;47769:141::-;47825:5;47856:6;47850:13;47841:22;;47872:32;47898:5;47872:32;:::i;:::-;47769:141;;;;:::o;47916:349::-;47985:6;48034:2;48022:9;48013:7;48009:23;48005:32;48002:119;;;48040:79;;:::i;:::-;48002:119;48160:1;48185:63;48240:7;48231:6;48220:9;48216:22;48185:63;:::i;:::-;48175:73;;48131:127;47916:349;;;;:::o;48271:194::-;48311:4;48331:20;48349:1;48331:20;:::i;:::-;48326:25;;48365:20;48383:1;48365:20;:::i;:::-;48360:25;;48409:1;48406;48402:9;48394:17;;48433:1;48427:4;48424:11;48421:37;;;48438:18;;:::i;:::-;48421:37;48271:194;;;;:::o;48471:180::-;48519:77;48516:1;48509:88;48616:4;48613:1;48606:15;48640:4;48637:1;48630:15;48657:182;48797:34;48793:1;48785:6;48781:14;48774:58;48657:182;:::o;48845:366::-;48987:3;49008:67;49072:2;49067:3;49008:67;:::i;:::-;49001:74;;49084:93;49173:3;49084:93;:::i;:::-;49202:2;49197:3;49193:12;49186:19;;48845:366;;;:::o;49217:419::-;49383:4;49421:2;49410:9;49406:18;49398:26;;49470:9;49464:4;49460:20;49456:1;49445:9;49441:17;49434:47;49498:131;49624:4;49498:131;:::i;:::-;49490:139;;49217:419;;;:::o;49642:178::-;49782:30;49778:1;49770:6;49766:14;49759:54;49642:178;:::o;49826:366::-;49968:3;49989:67;50053:2;50048:3;49989:67;:::i;:::-;49982:74;;50065:93;50154:3;50065:93;:::i;:::-;50183:2;50178:3;50174:12;50167:19;;49826:366;;;:::o;50198:419::-;50364:4;50402:2;50391:9;50387:18;50379:26;;50451:9;50445:4;50441:20;50437:1;50426:9;50422:17;50415:47;50479:131;50605:4;50479:131;:::i;:::-;50471:139;;50198:419;;;:::o

Swarm Source

ipfs://b1932e8ebb589cb34da0241d75dd5a30f4f0a23f171c6a3092ad278586e1f823
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.