ETH Price: $3,473.38 (+1.59%)
Gas: 10 Gwei

Token

Impact Theory Founder's Key (ITFK)
 

Overview

Max Total Supply

12,739 ITFK

Holders

2,895

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
morganloewenherz.eth
Balance
1 ITFK
0xcc5a9c976a3becb20e334ec40fd4abdeba9e198f
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

The Founder’s Key is an NFT that unlocks the future of everything Impact Theory.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
ImpactTheoryFoundersKey

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-10-15
*/

// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol



pragma solidity ^0.8.0;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s;
        uint8 v;
        assembly {
            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            v := add(shr(255, vs), 27)
        }
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

// File: @openzeppelin/contracts/utils/math/SafeMath.sol



pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

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

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

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

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

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

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

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

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



pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @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] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

// File: @openzeppelin/contracts/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



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() {
        _setOwner(_msgSender());
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        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 {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/security/Pausable.sol



pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

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



pragma solidity ^0.8.0;

/**
 * @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
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 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 functionCall(target, data, "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");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(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) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(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) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason 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 {
            // 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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts/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 `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/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



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



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`, 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 be 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: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * 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 Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @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 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);

    /**
     * @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;
}

// File: @openzeppelin/contracts/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 tokenId);

    /**
     * @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



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



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: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        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) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        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 overriden 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 owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_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: transfer caller is not owner nor 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: transfer caller is not owner nor 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 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 _owners[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) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, 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);

        _balances[to] += 1;
        _owners[tokenId] = to;

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

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

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

    /**
     * @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 of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

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

    /**
     * @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 {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

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



pragma solidity ^0.8.0;



/**
 * @dev ERC721 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 */
abstract contract ERC721Pausable is ERC721, Pausable {
    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        require(!paused(), "ERC721Pausable: token transfer while paused");
    }
}

// File: @openzeppelin/contracts/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 Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        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/token/ERC721/extensions/ERC721Burnable.sol



pragma solidity ^0.8.0;



/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
        _burn(tokenId);
    }
}

// File: ImpactTheoryFoundersKey.sol


pragma solidity ^0.8.0;








/**
 *
 * Impact Theory Founders Key
 *
 */
contract ImpactTheoryFoundersKey is
    Ownable,
    ERC721Burnable,
    ERC721Enumerable,
    ERC721Pausable
{
    using SafeMath for uint256;
    using Strings for uint256;
    using ECDSA for bytes32;

    // Public tier info
    struct Tier {
        uint256 id;
        string name;
    }

    // Private tier info
    struct TierInfo {
        Tier tier;
        uint256 startingOffset;
        uint256 totalSupply;
        uint256 startingPrice;
        uint256 endingPrice;
        uint256 maxPerClosedPresale;
        uint256 maxTotalMint;
        bool saleEnded;
    }

    // Base token uri
    string private baseTokenURI; // baseTokenURI can point to IPFS folder like https://ipfs.io/ipfs/{cid}/ while
    string private baseTokenURIForMetadata; // baseTokenURIForMetadata should point to the raw IPFS endpoint because it will not use IPFS folders. For example: https://ipfs.io/ipfs/

    // For uint to bytes32 conversion
    bytes16 private constant HEX_ALPHABET = "0123456789abcdef";
    string private constant IPFS_PREFIX = "f01551220"; // IPFS byte (f) + CID v1 (0x01) + raw codec (0x55) + SHA256 (0x12) + 256 bits long (0x20)

    // Payment address
    address private paymentAddress = 0x681EA99a65E6f392f0F5276Af396AE8CaD140E6D;

    // Royalties address
    address private royaltyAddress = 0x681EA99a65E6f392f0F5276Af396AE8CaD140E6D;

    // Signer address
    address private signerAddress = 0x4A2034e724034F31b46117d918E789c42EBE0CF2;

    // Royalties basis points (percentage using 2 decimals - 10000 = 100, 0 = 0)
    uint256 private royaltyBasisPoints = 1000; // 10%

    // Token info
    string public constant TOKEN_NAME = "Impact Theory Founder's Key";
    string public constant TOKEN_SYMBOL = "ITFK";

    // Sale durations
    uint256 public constant CLOSED_PRESALE_DURATION = 1 days;
    uint256 public constant PRESALE_DURATION = 1 days;
    uint256 public constant AUCTION_DURATION = 1 days;
    uint256 public constant AUCTION_PRICE_CHANGE = 1 hours;
    uint256 public constant DURATION_BETWEEN_TIERS = 1 days;

    // Public sale params
    uint256 public publicSaleStartTime;
    bool public publicSaleActive;

    //-- Tiers --//
    // Tier 1 - public info
    Tier public tier1 = Tier({id: 1, name: "Legendary"});

    // Tier 1 - private info
    TierInfo private tier1Info =
        TierInfo({
            tier: tier1,
            startingOffset: 1,
            totalSupply: 2700,
            startingPrice: 3 ether,
            endingPrice: 1.5 ether,
            maxPerClosedPresale: 1,
            maxTotalMint: 4,
            saleEnded: false
        });

    // Tier 2 - public info
    Tier public tier2 = Tier({id: 2, name: "Heroic"});

    // Tier 2 - private info
    TierInfo private tier2Info =
        TierInfo({
            tier: tier2,
            startingOffset: 2701,
            totalSupply: 7300,
            startingPrice: 1.5 ether,
            endingPrice: .75 ether,
            maxPerClosedPresale: 2,
            maxTotalMint: 5,
            saleEnded: false
        });

    // Tier 3 - public info
    Tier public tier3 = Tier({id: 3, name: "Relentless"});

    // Tier 3 - private info
    TierInfo private tier3Info =
        TierInfo({
            tier: tier3,
            startingOffset: 10001,
            totalSupply: 10000,
            startingPrice: .1 ether,
            endingPrice: .05 ether,
            maxPerClosedPresale: 1,
            maxTotalMint: 5,
            saleEnded: false
        });

    Tier[] public allTiersArray;
    TierInfo[] private allTiersInfoArray;

    uint256[] public allTierIds;

    mapping(uint256 => Tier) public allTiers;
    mapping(uint256 => TierInfo) private allTiersInfo;

    mapping(uint256 => Tier) public tokenTier;

    mapping(uint256 => uint256) public tokenMintedAt;
    mapping(uint256 => uint256) public tokenLastTransferredAt;

    mapping(uint256 => uint256) public tierCounts;

    mapping(uint256 => bytes32[]) public tokenMetadata;

    // Presale whitelist per tier
    mapping(address => uint256[]) private presaleWhitelist;

    // Used nonces for mint signatures
    mapping(string => bool) private usedNonces;

    //-- Events --//

    event PublicSaleStart(uint256 indexed _saleStartTime);
    event PublicSalePaused(uint256 indexed _timeElapsed);
    event PublicSaleActive(bool indexed _publicSaleActive);
    event RoyaltyBasisPoints(uint256 indexed _royaltyBasisPoints);

    //-- Modifiers --//

    // Public sale active modifier
    modifier whenPublicSaleActive() {
        require(publicSaleActive, "Public sale is not active");
        _;
    }

    // Public sale not active modifier
    modifier whenPublicSaleNotActive() {
        require(
            !publicSaleActive && publicSaleStartTime == 0,
            "Public sale is already active"
        );
        _;
    }

    // Owner or public sale active modifier
    modifier whenOwnerOrPublicSaleActive() {
        require(
            owner() == _msgSender() || publicSaleActive,
            "Public sale is not active"
        );
        _;
    }

    // -- Constructor --//
    constructor(string memory _baseTokenURI) ERC721(TOKEN_NAME, TOKEN_SYMBOL) {
        baseTokenURI = _baseTokenURI;

        // Setup intial tiers and tiers info
        Tier[3] memory allTiersArrayMem = [tier1, tier2, tier3];
        TierInfo[3] memory allTiersInfoArrayMem = [
            tier1Info,
            tier2Info,
            tier3Info
        ];

        for (uint256 i = 0; i < allTiersArrayMem.length; i++) {
            uint256 tierId = allTiersArrayMem[i].id;

            // Tier arrays
            allTiersArray.push(allTiersArrayMem[i]);
            allTiersInfoArray.push(allTiersInfoArrayMem[i]);

            allTierIds.push(tierId);

            // Tier mappings
            allTiers[tierId] = allTiersArray[i];
            allTiersInfo[tierId] = allTiersInfoArray[i];
        }
    }

    // -- External Functions -- //

    // Start public sale
    function startPublicSale() external onlyOwner whenPublicSaleNotActive {
        publicSaleStartTime = block.timestamp;
        publicSaleActive = true;
        emit PublicSaleStart(publicSaleStartTime);
    }

    // Set this value to the block.timestamp you'd like to reset to
    // Created as a way to fast foward in time for tier timing unit tests
    // Can also be used if needing to pause and restart public sale from original start time (returned in startPublicSale() above)
    function setPublicSaleStartTime(uint256 _publicSaleStartTime)
        external
        onlyOwner
    {
        publicSaleStartTime = _publicSaleStartTime;
        emit PublicSaleStart(publicSaleStartTime);
    }

    // Toggle public sale
    function togglePublicSaleActive() external onlyOwner {
        publicSaleActive = !publicSaleActive;
        emit PublicSaleActive(publicSaleActive);
    }

    // Pause public sale
    function pausePublicSale() external onlyOwner whenPublicSaleActive {
        publicSaleActive = false;
        emit PublicSalePaused(getElapsedSaleTime());
    }

    // End tier sale
    function setTierSaleEnded(uint256 _tierId, bool _saleEnded)
        external
        onlyOwner
        whenPublicSaleActive
    {
        allTiersInfo[_tierId].saleEnded = _saleEnded;
    }

    // Get all tiers
    function getAllTiers() external view returns (Tier[] memory) {
        return allTiersArray;
    }

    // Get all tiers info
    function getAllTiersInfo()
        external
        view
        onlyOwner
        returns (TierInfo[] memory)
    {
        return allTiersInfoArray;
    }

    // Support royalty info - See {EIP-2981}: https://eips.ethereum.org/EIPS/eip-2981
    function royaltyInfo(uint256, uint256 _salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount)
    {
        return (
            royaltyAddress,
            (_salePrice.mul(royaltyBasisPoints)).div(10000)
        );
    }

    // Adds multiple address to presale whitelist for specific tier
    function addToPresaleWhitelist(uint256 _tierId, address[] memory _addresses)
        external
        onlyOwner
    {
        Tier memory tier = allTiers[_tierId];

        require(tier.id == _tierId, "Invalid tier");

        for (uint256 i = 0; i < _addresses.length; i++) {
            address _address = _addresses[i];

            uint256[] storage tierIds = presaleWhitelist[_address];

            bool exists = false;
            for (uint256 j = 0; j < tierIds.length; j++) {
                if (tierIds[j] == tier.id) {
                    exists = true;
                }
            }

            if (!exists) {
                tierIds.push(tier.id);
            }

            presaleWhitelist[_address] = tierIds;
        }
    }

    // Removes single address from whitelist for specific tier
    function removeFromPresaleWhitelist(uint256 _tierId, address _address)
        external
        onlyOwner
    {
        Tier memory tier = allTiers[_tierId];

        require(tier.id == _tierId, "Invalid tier");

        uint256[] storage tierIds = presaleWhitelist[_address];

        // Loop over each tier id
        for (uint256 i = 0; i < tierIds.length; i++) {
            if (tierIds[i] == tier.id) {
                // If tier id is found, replace with last tier id
                tierIds[i] = tierIds[tierIds.length - 1];
            }
        }

        // Remove last tier id, since it replaced the matched tier id
        tierIds.pop();

        presaleWhitelist[_address] = tierIds;
    }

    // Get all tiers address is whitelisted for
    function getPresaleWhitelist(address _address)
        external
        view
        onlyOwner
        returns (uint256[] memory)
    {
        return presaleWhitelist[_address];
    }

    //-- Public Functions --//

    // Get elapsed sale time
    function getElapsedSaleTime() public view returns (uint256) {
        return
            publicSaleStartTime > 0
                ? block.timestamp.sub(publicSaleStartTime)
                : 0;
    }

    // Get remaining closed presale time
    function getRemainingClosedPresaleTime(uint256 _tierId)
        public
        view
        whenPublicSaleActive
        returns (uint256)
    {
        Tier memory tier = allTiers[_tierId];

        require(tier.id == _tierId, "Invalid tier");

        // Get elapsed sale time
        uint256 elapsed = getElapsedSaleTime();

        // Time logic based on tier and constants
        uint256 closedPresaleStart = (tier.id - 1).mul(DURATION_BETWEEN_TIERS);
        uint256 closedPresaleEnd = closedPresaleStart.add(
            CLOSED_PRESALE_DURATION
        );

        // Tier not active
        require(elapsed >= closedPresaleStart, "Tier not active");

        // Tier finished presale
        if (elapsed >= closedPresaleEnd) {
            return 0;
        }

        // Elasped time since presale start
        uint256 elapsedSinceStart = elapsed.sub(closedPresaleStart);

        // Total duration minus elapsed time since presale start
        return CLOSED_PRESALE_DURATION.sub(elapsedSinceStart);
    }

    // Get remaining presale time
    function getRemainingPresaleTime(uint256 _tierId)
        public
        view
        whenPublicSaleActive
        returns (uint256)
    {
        Tier memory tier = allTiers[_tierId];

        require(tier.id == _tierId, "Invalid tier");

        // Get elapsed sale time
        uint256 elapsed = getElapsedSaleTime();

        // Time logic based on tier and constants
        uint256 closedPresaleStart = (tier.id - 1).mul(DURATION_BETWEEN_TIERS);
        uint256 closedPresaleEnd = closedPresaleStart.add(
            CLOSED_PRESALE_DURATION
        );
        uint256 presaleStart = closedPresaleEnd;
        uint256 presaleEnd = presaleStart.add(PRESALE_DURATION);

        // Tier not active
        require(elapsed >= presaleStart, "Tier not active");

        // Tier finished presale
        if (elapsed >= presaleEnd) {
            return 0;
        }

        // Elasped time since presale start
        uint256 elapsedSinceStart = elapsed.sub(presaleStart);

        // Total duration minus elapsed time since presale start
        return PRESALE_DURATION.sub(elapsedSinceStart);
    }

    // Get remaining auction time
    function getRemainingAuctionTime(uint256 _tierId)
        public
        view
        whenPublicSaleActive
        returns (uint256)
    {
        Tier memory tier = allTiers[_tierId];

        require(tier.id == _tierId, "Invalid tier");

        uint256 elapsed = getElapsedSaleTime();

        // Time logic based on tier and constants
        uint256 closedPresaleStart = (tier.id - 1).mul(DURATION_BETWEEN_TIERS);
        uint256 closedPresaleEnd = closedPresaleStart.add(
            CLOSED_PRESALE_DURATION
        );
        uint256 presaleStart = closedPresaleEnd;
        uint256 presaleEnd = presaleStart.add(PRESALE_DURATION);
        uint256 auctionStart = presaleEnd;
        uint256 auctionEnd = auctionStart.add(AUCTION_DURATION);

        // Tier not active
        require(elapsed >= auctionStart, "Tier not active");

        // Tier finished auction
        if (elapsed >= auctionEnd) {
            return 0;
        }

        // Elasped time since auction start
        uint256 elapsedSinceStart = elapsed.sub(auctionStart);

        // Total duration minus elapsed time since auction start
        return AUCTION_DURATION.sub(elapsedSinceStart);
    }

    // Mint token - requires tier and amount
    function mint(
        uint256 _tierId,
        uint256 _amount,
        bytes32 _hash,
        bytes memory _signature,
        string memory _nonce
    ) public payable whenOwnerOrPublicSaleActive {
        require(
            matchAddressSigner(_hash, _signature),
            "Direct mint disallowed"
        );
        require(!usedNonces[_nonce], "Hash already used");
        require(
            hashTransaction(_msgSender(), _amount, _nonce) == _hash,
            "Hash failed"
        );

        Tier memory tier = allTiers[_tierId];
        TierInfo memory tierInfo = allTiersInfo[_tierId];

        require(tier.id == _tierId, "Invalid tier");

        // Must mint at least one
        require(_amount > 0, "Must mint at least one");

        // Check there enough mints left for tier
        require(
            getMintsLeft(tier.id).sub(_amount) >= 0,
            "Minting would exceed max supply"
        );

        // Get current address total balance
        uint256 currentTotalAmount = super.balanceOf(_msgSender());

        // Loop over all tokens for address and get current tier count
        uint256 currentTierAmount = 0;
        for (uint256 i = 0; i < currentTotalAmount; i++) {
            uint256 tokenId = super.tokenOfOwnerByIndex(_msgSender(), i);
            Tier memory _tokenTier = tokenTier[tokenId];
            if (_tokenTier.id == tier.id) {
                currentTierAmount++;
            }
        }

        uint256 costToMint = 0;
        uint256 amount = _amount;

        // Is owner
        bool isOwner = owner() == _msgSender();

        // If not owner, check amounts are not more than max amounts
        if (!isOwner) {
            // Get elapsed sale time
            uint256 elapsed = getElapsedSaleTime();

            // Time logic based on tier and constants
            uint256 closedPresaleStart = (tier.id - 1).mul(
                DURATION_BETWEEN_TIERS
            );
            uint256 closedPresaleEnd = closedPresaleStart.add(
                CLOSED_PRESALE_DURATION
            );

            // If still in the closed whitelist, do not allow more than max per closed presale
            if (elapsed <= closedPresaleEnd) {
                require(
                    currentTierAmount.add(amount) <= tierInfo.maxPerClosedPresale,
                    "Requested amount exceeds maximum whitelist mint amount"
                );
            }

            // Do not allow more than max total mint
            require(
                currentTierAmount.add(amount) <= tierInfo.maxTotalMint,
                "Requested amount exceeds maximum total mint amount"
            );
        }

        // Get cost to mint
        costToMint = getMintPrice(tier.id).mul(amount);

        // Check cost to mint for tier, and if enough ETH is passed to mint
        require(costToMint <= msg.value, "ETH amount sent is not correct");

        for (uint256 i = 0; i < amount; i++) {
            // Token id is tier starting offset plus count of already minted
            uint256 tokenId = tierInfo.startingOffset.add(tierCounts[tier.id]);

            // Safe mint
            _safeMint(_msgSender(), tokenId);

            // Attribute token id with tier
            tokenTier[tokenId] = tier;

            // Store minted at timestamp by token id
            tokenMintedAt[tokenId] = block.timestamp;

            // Increment tier counter
            tierCounts[tier.id] = tierCounts[tier.id].add(1);
        }

        usedNonces[_nonce] = true;

        // Send mint cost to payment address
        Address.sendValue(payable(paymentAddress), costToMint);

        // Return unused value
        if (msg.value > costToMint) {
            Address.sendValue(payable(_msgSender()), msg.value.sub(costToMint));
        }
    }

    // Burn multiple
    function burnMultiple(uint256[] memory _tokenIds) public onlyOwner {
        for (uint256 i = 0; i < _tokenIds.length; i++) {
            // Token id
            uint256 tokenId = _tokenIds[i];

            _burn(tokenId);
        }
    }

    // Get mint price
    function getMintPrice(uint256 _tierId)
        public
        view
        whenOwnerOrPublicSaleActive
        returns (uint256)
    {
        Tier memory tier = allTiers[_tierId];
        TierInfo memory tierInfo = allTiersInfo[_tierId];

        require(tier.id == _tierId, "Invalid tier");

        // Is owner
        bool isOwner = owner() == _msgSender();

        // If owner, cost is 0
        if (isOwner) {
            return 0;
        }

        uint256 elapsed = getElapsedSaleTime();
        uint256 currentPrice = 0;

        // Setup starting and ending prices
        uint256 startingPrice = tierInfo.startingPrice;
        uint256 endingPrice = tierInfo.endingPrice;

        // Time logic based on tier and constants

        uint256 closedPresaleStart = (tier.id - 1).mul(DURATION_BETWEEN_TIERS);
        uint256 closedPresaleEnd = closedPresaleStart.add(
            CLOSED_PRESALE_DURATION
        );
        uint256 presaleStart = closedPresaleEnd;
        uint256 presaleEnd = presaleStart.add(PRESALE_DURATION);
        uint256 auctionStart = presaleEnd;
        uint256 auctionEnd = auctionStart.add(AUCTION_DURATION);

        // Tier not active
        require(elapsed >= closedPresaleStart, "Tier not active");

        // Closed presale - starting price
        if ((elapsed >= closedPresaleStart) && (elapsed < presaleStart)) {
            // Must be in presale whitelist to get price and mint
            uint256[] memory whitelistedTiers = presaleWhitelist[_msgSender()];
            bool isWhitelisted = false;
            for (uint256 i = 0; i < whitelistedTiers.length; i++) {
                if (whitelistedTiers[i] == tier.id) {
                    isWhitelisted = true;
                }
            }

            require(isWhitelisted, "Tier not active, not whitelisted");
            currentPrice = startingPrice;

            // Presale - starting price
        } else if ((elapsed >= presaleStart) && (elapsed < presaleEnd)) {
            currentPrice = startingPrice;

            // Dutch Auction - price descreses dynamically for duration
        } else if ((elapsed >= auctionStart) && (elapsed < auctionEnd)) {
            uint256 elapsedSinceAuctionStart = elapsed.sub(auctionStart); // Elapsed time since auction start
            uint256 totalPriceDiff = startingPrice.sub(endingPrice); // Total price diff between starting and ending price
            uint256 numPriceChanges = AUCTION_DURATION.div(
                AUCTION_PRICE_CHANGE
            ).sub(1); // Amount of price changes in the auction
            uint256 priceChangeAmount = totalPriceDiff.div(numPriceChanges); // Amount of price change per instance of price change
            uint256 elapsedRounded = elapsedSinceAuctionStart.div(
                AUCTION_PRICE_CHANGE
            ); // Elapsed time since auction start rounded to auction price change variable
            uint256 totalPriceChangeAmount = priceChangeAmount.mul(
                elapsedRounded
            ); // Total amount of price change based on time

            currentPrice = startingPrice.sub(totalPriceChangeAmount); // Starting price minus total price change

            // Post auction - ending price
        } else if (elapsed >= auctionEnd) {
            // Check if tier ended
            require(!tierInfo.saleEnded, "Tier not active");

            currentPrice = endingPrice;
        }

        // Double check current price is not lower than ending price
        return currentPrice < endingPrice ? endingPrice : currentPrice;
    }

    // Get mints left for tier
    function getMintsLeft(uint256 _tierId)
        public
        view
        whenOwnerOrPublicSaleActive
        returns (uint256)
    {
        Tier memory tier = allTiers[_tierId];
        TierInfo memory tierInfo = allTiersInfo[_tierId];

        require(tier.id == _tierId, "Invalid tier");

        // Get tier total supplys and counts
        uint256 tierSupply = tierInfo.totalSupply;
        uint256 tierCount = tierCounts[tier.id];

        return tierSupply.sub(tierCount);
    }

    function setPaymentAddress(address _address) public onlyOwner {
        paymentAddress = _address;
    }

    function setSignerAddress(address _address) public onlyOwner {
        signerAddress = _address;
    }

    // Set royalty wallet address
    function setRoyaltyAddress(address _address) public onlyOwner {
        royaltyAddress = _address;
    }

    // Set royalty basis points
    function setRoyaltyBasisPoints(uint256 _basisPoints) public onlyOwner {
        royaltyBasisPoints = _basisPoints;
        emit RoyaltyBasisPoints(_basisPoints);
    }

    // Set base URI
    function setBaseURI(string memory _uri) public onlyOwner {
        baseTokenURI = _uri;
    }

    function setBaseURIForMetadata(string memory _uri) public onlyOwner {
        baseTokenURIForMetadata = _uri;
    }

    // Append token metadata
    function appendTokenMetadata(uint256 _tokenId, bytes32 _metadataHash)
        public
        onlyOwner
    {
        require(_exists(_tokenId), "Nonexistent token");

        tokenMetadata[_tokenId].push(_metadataHash);
    }

    // Get all token metadata changes
    function getTokenMetadata(uint256 _tokenId)
        public
        view
        returns (bytes32[] memory)
    {
        require(_exists(_tokenId), "Nonexistent token");

        return tokenMetadata[_tokenId];
    }

    // Token URI (baseTokenURI + tokenId)
    function tokenURI(uint256 _tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(_exists(_tokenId), "Nonexistent token");

        uint256 tokenMetadataLength = tokenMetadata[_tokenId].length;

        if (tokenMetadataLength > 0) {
            uint256 _lastMetadataHash = uint256(
                tokenMetadata[_tokenId][tokenMetadataLength - 1]
            );

            // IPFS CID V1 is too long for Solidity byte32 but it contains the same prefix "f01551220" if it was added to IPFS with the same codec and hash function.
            // IPFS CID V1 Multihash example: bafkreif7gr5yvy5p65nbozy7o3f7m2tt2jkyhp5fgpd4cg5ljl4e7ohxxq
            // Explorer: https://cid.ipfs.io/#bafkreif7gr5yvy5p65nbozy7o3f7m2tt2jkyhp5fgpd4cg5ljl4e7ohxxq
            // It's prefix (f01551220) + SHA256 hash (BF347B8AE3AFF75A17671F76CBF66A73D25583BFA533C7C11BAB4AF84FB8F7BC)
            // List of codes: https://github.com/multiformats/multicodec/blob/master/table.csv
            // Prefix format: IPFS specific byte (f) + CID V1 (01) + multicodec code (0x55 for raw) + hash function code (0x12 for SHA256) + length (0x20 for 256-bits)
            // Final: f017012200C39FEAEE65382EFEDE80ED763CC922B280AE2A2A403C24FEE73B36D8A6AC7F7
            // Addressable as usual: http://ipfs.io/ipfs/f015512200874F3B3FEE8BFE197A86AB9F676F6246248B8FFE1F81111D1C44B11D41173CD
            // That way we can strip meaningless for blockchain "f01701220" and save huge amount of gas by storing it efficiently in byte32.
            // IMPORTANT: JSON files up to 256KB always have 0x55 (raw) codec.

            return
                string(
                    abi.encodePacked(
                        abi.encodePacked(baseTokenURIForMetadata, IPFS_PREFIX),
                        uintToHexString(_lastMetadataHash, 32)
                    )
                );
        }
        return
            string(abi.encodePacked(_baseURI(), "token/", _tokenId.toString()));
    }

    // Contract metadata URI - Support for OpenSea: https://docs.opensea.io/docs/contract-level-metadata
    function contractURI() public view returns (string memory) {
        return string(abi.encodePacked(_baseURI(), "contract"));
    }

    // Override supportsInterface - See {IERC165-supportsInterface}
    function supportsInterface(bytes4 _interfaceId)
        public
        view
        virtual
        override(ERC721, ERC721Enumerable)
        returns (bool)
    {
        return super.supportsInterface(_interfaceId);
    }

    // Pauses all token transfers - See {ERC721Pausable}
    function pause() public virtual onlyOwner {
        _pause();
    }

    // Unpauses all token transfers - See {ERC721Pausable}
    function unpause() public virtual onlyOwner {
        _unpause();
    }

    //-- Private Functions --/

    // Hash transaction
    function hashTransaction(
        address _sender,
        uint256 _amount,
        string memory _nonce
    ) private pure returns (bytes32) {
        bytes32 hash = keccak256(
            abi.encodePacked(
                "\x19Ethereum Signed Message:\n32",
                keccak256(abi.encodePacked(_sender, _amount, _nonce))
            )
        );

        return hash;
    }

    // Match address signer
    function matchAddressSigner(bytes32 _hash, bytes memory _signature)
        private
        view
        returns (bool)
    {
        return signerAddress == _hash.recover(_signature);
    }

    //-- Internal Functions --//

    // Get base URI
    function _baseURI() internal view override returns (string memory) {
        return baseTokenURI;
    }

    // Before all token transfer
    function _beforeTokenTransfer(
        address _from,
        address _to,
        uint256 _tokenId
    ) internal virtual override(ERC721, ERC721Enumerable, ERC721Pausable) {
        // Store token last transfer timestamp by id
        tokenLastTransferredAt[_tokenId] = block.timestamp;

        super._beforeTokenTransfer(_from, _to, _tokenId);
    }

    // Uint to hex string
    function uintToHexString(uint256 value, uint256 length)
        internal
        pure
        returns (string memory)
    {
        bytes memory buffer = new bytes(2 * length);

        for (uint256 i = 2 * length; i > 0; --i) {
            buffer[i - 1] = HEX_ALPHABET[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_baseTokenURI","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"_publicSaleActive","type":"bool"}],"name":"PublicSaleActive","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_timeElapsed","type":"uint256"}],"name":"PublicSalePaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_saleStartTime","type":"uint256"}],"name":"PublicSaleStart","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_royaltyBasisPoints","type":"uint256"}],"name":"RoyaltyBasisPoints","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"AUCTION_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AUCTION_PRICE_CHANGE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CLOSED_PRESALE_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DURATION_BETWEEN_TIERS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRESALE_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKEN_NAME","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKEN_SYMBOL","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tierId","type":"uint256"},{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"addToPresaleWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allTierIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allTiers","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allTiersArray","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes32","name":"_metadataHash","type":"bytes32"}],"name":"appendTokenMetadata","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"burnMultiple","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllTiers","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct ImpactTheoryFoundersKey.Tier[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllTiersInfo","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct ImpactTheoryFoundersKey.Tier","name":"tier","type":"tuple"},{"internalType":"uint256","name":"startingOffset","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"startingPrice","type":"uint256"},{"internalType":"uint256","name":"endingPrice","type":"uint256"},{"internalType":"uint256","name":"maxPerClosedPresale","type":"uint256"},{"internalType":"uint256","name":"maxTotalMint","type":"uint256"},{"internalType":"bool","name":"saleEnded","type":"bool"}],"internalType":"struct ImpactTheoryFoundersKey.TierInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getElapsedSaleTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tierId","type":"uint256"}],"name":"getMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tierId","type":"uint256"}],"name":"getMintsLeft","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getPresaleWhitelist","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tierId","type":"uint256"}],"name":"getRemainingAuctionTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tierId","type":"uint256"}],"name":"getRemainingClosedPresaleTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tierId","type":"uint256"}],"name":"getRemainingPresaleTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getTokenMetadata","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"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":"uint256","name":"_tierId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"string","name":"_nonce","type":"string"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pausePublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tierId","type":"uint256"},{"internalType":"address","name":"_address","type":"address"}],"name":"removeFromPresaleWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","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":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setBaseURIForMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setPaymentAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_publicSaleStartTime","type":"uint256"}],"name":"setPublicSaleStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setRoyaltyAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_basisPoints","type":"uint256"}],"name":"setRoyaltyBasisPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setSignerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tierId","type":"uint256"},{"internalType":"bool","name":"_saleEnded","type":"bool"}],"name":"setTierSaleEnded","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startPublicSale","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":[],"name":"tier1","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tier2","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tier3","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tierCounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"togglePublicSaleActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenLastTransferredAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenMetadata","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenMintedAt","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":"","type":"uint256"}],"name":"tokenTier","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"name","type":"string"}],"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":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]

600e80546001600160a01b031990811673681ea99a65e6f392f0f5276af396ae8cad140e6d908117909255600f8054821690921790915560108054909116734a2034e724034f31b46117d918e789c42ebe0cf21790556103e860115560016080818152610100604052600960c0818152684c6567656e6461727960b81b60e090815260a09190915260149384559192916200009e916015919062000f61565b505050604051806101000160405280601460405180604001604052908160008201548152602001600182018054620000d69062001167565b80601f0160208091040260200160405190810160405280929190818152602001828054620001049062001167565b8015620001555780601f10620001295761010080835404028352916020019162000155565b820191906000526020600020905b8154815290600101906020018083116200013757829003601f168201915b50505091909252505050815260016020808301829052610a8c60408401526729a2241af62c000060608401526714d1120d7b160000608084015260a0830191909152600460c0830152600060e09092019190915281518051601690815581830151805191938492620001cc92601792019062000f61565b5050506020828101516002838101919091556040808501516003850155606085015160048501556080850151600585015560a085015160068086019190915560c0860151600786015560e0909501516008909401805460ff191694151594909417909355825180840184529081528251808401909352928252654865726f696360d01b8282019081528382018390528351601f90815592516200027192919062000f61565b505050604051806101000160405280601f60405180604001604052908160008201548152602001600182018054620002a99062001167565b80601f0160208091040260200160405190810160405280929190818152602001828054620002d79062001167565b8015620003285780601f10620002fc5761010080835404028352916020019162000328565b820191906000526020600020905b8154815290600101906020018083116200030a57829003601f168201915b505050919092525050508152610a8d602080830191909152611c8460408301526714d1120d7b1600006060830152670a688906bd8b00006080830152600260a0830152600560c0830152600060e09092019190915281518051602190815581830151805191938492620003a092602292019062000f61565b5050506020828101516002830155604080840151600380850191909155606085015160048501556080850151600585015560a0850151600685015560c0850151600785015560e0909401516008909301805460ff191693151593909317909255815180830183529283528151808301909252600a82526952656c656e746c65737360b01b8282019081529083018290528251602a90815591516200044791602b9162000f61565b505050604051806101000160405280602a604051806040016040529081600082015481526020016001820180546200047f9062001167565b80601f0160208091040260200160405190810160405280929190818152602001828054620004ad9062001167565b8015620004fe5780601f10620004d257610100808354040283529160200191620004fe565b820191906000526020600020905b815481529060010190602001808311620004e057829003601f168201915b505050919092525050508152612711602080830191909152612710604083015267016345785d8a0000606083015266b1a2bc2ec500006080830152600160a0830152600560c0830152600060e09092019190915281518051602c908155818301518051919384926200057592602d92019062000f61565b5050506020820151600282015560408201516003820155606082015160048201556080820151600582015560a0820151600682015560c0820151600782015560e0909101516008909101805460ff1916911515919091179055348015620005db57600080fd5b5060405162006a4b38038062006a4b833981016040819052620005fe916200108b565b6040518060400160405280601b81526020017f496d70616374205468656f727920466f756e6465722773204b65790000000000815250604051806040016040528060048152602001634954464b60e01b8152506200066b6200066562000f0d60201b60201c565b62000f11565b81516200068090600190602085019062000f61565b5080516200069690600290602084019062000f61565b5050600b805460ff19169055508051620006b890600c90602084019062000f61565b5060006040518060600160405280601460405180604001604052908160008201548152602001600182018054620006ef9062001167565b80601f01602080910402602001604051908101604052809291908181526020018280546200071d9062001167565b80156200076e5780601f1062000742576101008083540402835291602001916200076e565b820191906000526020600020905b8154815290600101906020018083116200075057829003601f168201915b5050505050815250508152602001601f60405180604001604052908160008201548152602001600182018054620007a59062001167565b80601f0160208091040260200160405190810160405280929190818152602001828054620007d39062001167565b8015620008245780601f10620007f85761010080835404028352916020019162000824565b820191906000526020600020905b8154815290600101906020018083116200080657829003601f168201915b5050505050815250508152602001602a604051806040016040529081600082015481526020016001820180546200085b9062001167565b80601f0160208091040260200160405190810160405280929190818152602001828054620008899062001167565b8015620008da5780601f10620008ae57610100808354040283529160200191620008da565b820191906000526020600020905b815481529060010190602001808311620008bc57829003601f168201915b505050919092525050509052604080516101a081019091526016805461016083019081526017805494955060009484936060850193909284928491610180880191620009269062001167565b80601f0160208091040260200160405190810160405280929190818152602001828054620009549062001167565b8015620009a55780601f106200097957610100808354040283529160200191620009a5565b820191906000526020600020905b8154815290600101906020018083116200098757829003601f168201915b50505050508152505081526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820160009054906101000a900460ff1615151515815250508152602001602160405180610100016040529081600082016040518060400160405290816000820154815260200160018201805462000a489062001167565b80601f016020809104026020016040519081016040528092919081815260200182805462000a769062001167565b801562000ac75780601f1062000a9b5761010080835404028352916020019162000ac7565b820191906000526020600020905b81548152906001019060200180831162000aa957829003601f168201915b50505050508152505081526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820160009054906101000a900460ff1615151515815250508152602001602c60405180610100016040529081600082016040518060400160405290816000820154815260200160018201805462000b6a9062001167565b80601f016020809104026020016040519081016040528092919081815260200182805462000b989062001167565b801562000be95780601f1062000bbd5761010080835404028352916020019162000be9565b820191906000526020600020905b81548152906001019060200180831162000bcb57829003601f168201915b50505091909252505050815260028201546020820152600382015460408201526004820154606082015260058201546080820152600682015460a0820152600782015460c082015260089091015460ff16151560e0909101529052905060005b600381101562000f0357600083826003811062000c6a5762000c6a620011ce565b6020020151519050603584836003811062000c895762000c89620011ce565b6020908102919091015182546001818101855560009485529383902082516002909202019081558183015180519294919362000ccc939285019291019062000f61565b505050603683836003811062000ce65762000ce6620011ce565b60209081029190910151825460018181018555600094855293839020825180516009909302909101918255808401518051939592949193859362000d309390850192019062000f61565b5050506020820151600282015560408201516003820155606082015160048201556080820151600582015560a0820151600682015560c0820151600782015560e0909101516008909101805460ff1916911515919091179055603780546001810182556000919091527f42a7b7dd785cd69714a189dffb3fd7d7174edc9ece837694ce50f7078f7c31ae01819055603580548390811062000dd55762000dd5620011ce565b90600052602060002090600202016038600083815260200190815260200160002060008201548160000155600182018160010190805462000e169062001167565b62000e2392919062000ff0565b509050506036828154811062000e3d5762000e3d620011ce565b906000526020600020906009020160396000838152602001908152602001600020600082018160000160008201548160000155600182018160010190805462000e869062001167565b62000e9392919062000ff0565b5050506002828101549082015560038083015490820155600480830154908201556005808301549082015560068083015490820155600780830154908201556008918201549101805460ff191660ff9092161515919091179055508062000efa81620011a4565b91505062000c49565b50505050620011fa565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805462000f6f9062001167565b90600052602060002090601f01602090048101928262000f93576000855562000fde565b82601f1062000fae57805160ff191683800117855562000fde565b8280016001018555821562000fde579182015b8281111562000fde57825182559160200191906001019062000fc1565b5062000fec92915062001074565b5090565b82805462000ffe9062001167565b90600052602060002090601f01602090048101928262001022576000855562000fde565b82601f1062001035578054855562000fde565b8280016001018555821562000fde57600052602060002091601f016020900482015b8281111562000fde57825482559160010191906001019062001057565b5b8082111562000fec576000815560010162001075565b600060208083850312156200109f57600080fd5b82516001600160401b0380821115620010b757600080fd5b818501915085601f830112620010cc57600080fd5b815181811115620010e157620010e1620011e4565b604051601f8201601f19908116603f011681019083821181831017156200110c576200110c620011e4565b8160405282815288868487010111156200112557600080fd5b600093505b828410156200114957848401860151818501870152928501926200112a565b828411156200115b5760008684830101525b98975050505050505050565b600181811c908216806200117c57607f821691505b602082108114156200119e57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415620011c757634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b615841806200120a6000396000f3fe6080604052600436106104105760003560e01c80636ab49a5b1161021e578063a422948a11610123578063c87b56dd116100ab578063e8a3d4851161007a578063e8a3d48514610c1a578063e985e9c514610c2f578063eaaf369a14610c78578063eeab99aa14610c98578063f2fde38b14610cae57600080fd5b8063c87b56dd14610b9a578063d229491714610bba578063d60f8f3f14610bda578063dc566b8314610bfa57600080fd5b8063b88d4fde116100f2578063b88d4fde14610b18578063ba3ca30514610b38578063bb6b13a114610b4b578063bc8893b414610b60578063c4f3829014610b7a57600080fd5b8063a422948a14610a98578063b0e0d80614610ab8578063b17a4b9814610ad8578063b6b8194014610af857600080fd5b80638da5cb5b116101a657806392ed0d1b1161017557806392ed0d1b14610a36578063945e4013146109b757806395d89b4114610a63578063a22cb46514610a78578063a271e525146109b757600080fd5b80638da5cb5b146109e35780638e70e30a14610a015780638ec4972114610a1657806392cda4cd146109b757600080fd5b8063715018a6116101ed578063715018a61461095557806376772cf81461096a5780637c2cce9e146109975780637d9762da146109b75780638456cb59146109ce57600080fd5b80636ab49a5b146108df5780636bb7b1d9146108ff5780636d5d40c61461091557806370a082311461093557600080fd5b806336341c0411610324578063559e775b116102ac578063603168011161027b578063603168011461083d5780636352211e1461085d5780636471af831461087d578063649e705f1461089f57806368d9aa0b146108bf57600080fd5b8063559e775b146107c557806355f804b3146107e55780635c975abb146108055780635e1e10041461081d57600080fd5b806342966c68116102f357806342966c68146107235780634369f4e5146107435780634b1740ad146107705780634f6ccce714610785578063514a39a9146107a557600080fd5b806336341c04146106a95780633806153e146106cb5780633f4ba83a146106ee57806342842e0e1461070357600080fd5b80630c894cfe116103a7578063230b0c7011610376578063230b0c70146105cd57806323b872dd146105fa5780632a55205a1461061a5780632a905318146106595780632f745c591461068957600080fd5b80630c894cfe1461053057806318160ddd1461054557806318821400146105645780631d980acb146105ad57600080fd5b8063081812fc116103e3578063081812fc146104ae578063095ea7b3146104e65780630c1c972a146105065780630c41f4971461051b57600080fd5b806301ffc9a714610415578063046dc1661461044a57806306d254da1461046c57806306fdde031461048c575b600080fd5b34801561042157600080fd5b50610435610430366004614ea8565b610cce565b60405190151581526020015b60405180910390f35b34801561045657600080fd5b5061046a610465366004614cc5565b610cdf565b005b34801561047857600080fd5b5061046a610487366004614cc5565b610d34565b34801561049857600080fd5b506104a1610d80565b6040516104419190615458565b3480156104ba57600080fd5b506104ce6104c9366004614f17565b610e12565b6040516001600160a01b039091168152602001610441565b3480156104f257600080fd5b5061046a610501366004614de1565b610e9a565b34801561051257600080fd5b5061046a610fb0565b34801561052757600080fd5b5061046a611077565b34801561053c57600080fd5b5061046a611100565b34801561055157600080fd5b506009545b604051908152602001610441565b34801561057057600080fd5b506104a16040518060400160405280601b81526020017f496d70616374205468656f727920466f756e6465722773204b6579000000000081525081565b3480156105b957600080fd5b5061046a6105c8366004614ee2565b61116f565b3480156105d957600080fd5b506105ed6105e8366004614cc5565b6111b0565b60405161044191906152fc565b34801561060657600080fd5b5061046a610615366004614d13565b611248565b34801561062657600080fd5b5061063a610635366004615021565b61127a565b604080516001600160a01b039093168352602083019190915201610441565b34801561066557600080fd5b506104a1604051806040016040528060048152602001634954464b60e01b81525081565b34801561069557600080fd5b506105566106a4366004614de1565b6112b6565b3480156106b557600080fd5b506106be61134c565b6040516104419190615340565b3480156106d757600080fd5b506106e06114d3565b6040516104419291906155f4565b3480156106fa57600080fd5b5061046a61156a565b34801561070f57600080fd5b5061046a61071e366004614d13565b61159e565b34801561072f57600080fd5b5061046a61073e366004614f17565b6115b9565b34801561074f57600080fd5b5061055661075e366004614f17565b603c6020526000908152604090205481565b34801561077c57600080fd5b506106e0611633565b34801561079157600080fd5b506105566107a0366004614f17565b611647565b3480156107b157600080fd5b506105566107c0366004614f17565b6116da565b3480156107d157600080fd5b506105566107e0366004614f17565b6118a4565b3480156107f157600080fd5b5061046a610800366004614ee2565b611d92565b34801561081157600080fd5b50600b5460ff16610435565b34801561082957600080fd5b5061046a610838366004614cc5565b611dcf565b34801561084957600080fd5b506105ed610858366004614f17565b611e1b565b34801561086957600080fd5b506104ce610878366004614f17565b611ea0565b34801561088957600080fd5b50610892611f17565b60405161044191906153f6565b3480156108ab57600080fd5b506106e06108ba366004614f17565b612009565b3480156108cb57600080fd5b506105566108da366004614f17565b61202b565b3480156108eb57600080fd5b5061046a6108fa366004614e0b565b61204c565b34801561090b57600080fd5b5061055660125481565b34801561092157600080fd5b5061046a610930366004614f17565b6120bc565b34801561094157600080fd5b50610556610950366004614cc5565b612119565b34801561096157600080fd5b5061046a6121a0565b34801561097657600080fd5b50610556610985366004614f17565b603b6020526000908152604090205481565b3480156109a357600080fd5b506105566109b2366004614f17565b6121d4565b3480156109c357600080fd5b506105566201518081565b3480156109da57600080fd5b5061046a612382565b3480156109ef57600080fd5b506000546001600160a01b03166104ce565b348015610a0d57600080fd5b506105566123b4565b348015610a2257600080fd5b5061046a610a31366004614ffe565b6123d8565b348015610a4257600080fd5b50610556610a51366004614f17565b603d6020526000908152604090205481565b348015610a6f57600080fd5b506104a1612447565b348015610a8457600080fd5b5061046a610a93366004614db7565b612456565b348015610aa457600080fd5b506106e0610ab3366004614f17565b61251b565b348015610ac457600080fd5b5061046a610ad3366004614f53565b612550565b348015610ae457600080fd5b50610556610af3366004614f17565b61274c565b348015610b0457600080fd5b5061046a610b13366004614f17565b6128e4565b348015610b2457600080fd5b5061046a610b33366004614d4f565b612941565b61046a610b46366004615043565b612973565b348015610b5757600080fd5b506106e061315a565b348015610b6c57600080fd5b506013546104359060ff1681565b348015610b8657600080fd5b5061046a610b95366004615021565b61316e565b348015610ba657600080fd5b506104a1610bb5366004614f17565b6131e0565b348015610bc657600080fd5b50610556610bd5366004614f17565b6132fe565b348015610be657600080fd5b506106e0610bf5366004614f17565b61355f565b348015610c0657600080fd5b5061046a610c15366004614f30565b613581565b348015610c2657600080fd5b506104a1613788565b348015610c3b57600080fd5b50610435610c4a366004614ce0565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b348015610c8457600080fd5b50610556610c93366004615021565b6137b6565b348015610ca457600080fd5b50610556610e1081565b348015610cba57600080fd5b5061046a610cc9366004614cc5565b6137e7565b6000610cd98261387f565b92915050565b6000546001600160a01b03163314610d125760405162461bcd60e51b8152600401610d0990615545565b60405180910390fd5b601080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610d5e5760405162461bcd60e51b8152600401610d0990615545565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b606060018054610d8f90615707565b80601f0160208091040260200160405190810160405280929190818152602001828054610dbb90615707565b8015610e085780601f10610ddd57610100808354040283529160200191610e08565b820191906000526020600020905b815481529060010190602001808311610deb57829003601f168201915b5050505050905090565b6000610e1d826138a4565b610e7e5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610d09565b506000908152600560205260409020546001600160a01b031690565b6000610ea582611ea0565b9050806001600160a01b0316836001600160a01b03161415610f135760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610d09565b336001600160a01b0382161480610f2f5750610f2f8133610c4a565b610fa15760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610d09565b610fab83836138c1565b505050565b6000546001600160a01b03163314610fda5760405162461bcd60e51b8152600401610d0990615545565b60135460ff16158015610fed5750601254155b6110395760405162461bcd60e51b815260206004820152601d60248201527f5075626c69632073616c6520697320616c7265616479206163746976650000006044820152606401610d09565b4260128190556013805460ff191660011790556040517fb14aa2dad53a0090fda3c97971fdc6c84331eff6fc43a584628e5d83e131a30990600090a2565b6000546001600160a01b031633146110a15760405162461bcd60e51b8152600401610d0990615545565b60135460ff166110c35760405162461bcd60e51b8152600401610d099061550e565b6013805460ff191690556110d56123b4565b6040517fb94d4ebcdba018821f2c6ae2fb3a03d4023685b1c78faa4fe43dada42890cd2d90600090a2565b6000546001600160a01b0316331461112a5760405162461bcd60e51b8152600401610d0990615545565b6013805460ff19811660ff9182161590811790925560405191161515907fafa97d89ca766bd74e787f7998a071ea20f4ddeea353499106df17bc9cf4deb890600090a2565b6000546001600160a01b031633146111995760405162461bcd60e51b8152600401610d0990615545565b80516111ac90600d906020840190614b55565b5050565b6000546060906001600160a01b031633146111dd5760405162461bcd60e51b8152600401610d0990615545565b6001600160a01b0382166000908152603f60209081526040918290208054835181840281018401909452808452909183018282801561123b57602002820191906000526020600020905b815481526020019060010190808311611227575b505050505090505b919050565b611253335b8261392f565b61126f5760405162461bcd60e51b8152600401610d09906155a3565b610fab838383613a19565b600f5460115460009182916001600160a01b03909116906112aa90612710906112a4908790613bc4565b90613bd7565b915091505b9250929050565b60006112c183612119565b82106113235760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610d09565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6000546060906001600160a01b031633146113795760405162461bcd60e51b8152600401610d0990615545565b6036805480602002602001604051908101604052809291908181526020016000905b828210156114ca5760008481526020902060408051610140810190915260098402909101805461010083019081526001820180548492918491610120850191906113e490615707565b80601f016020809104026020016040519081016040528092919081815260200182805461141090615707565b801561145d5780601f106114325761010080835404028352916020019161145d565b820191906000526020600020905b81548152906001019060200180831161144057829003601f168201915b5050509190925250505081526002820154602080830191909152600383015460408301526004830154606083015260058301546080830152600683015460a0830152600783015460c083015260089092015460ff16151560e090910152908252600192909201910161139b565b50505050905090565b601f8054602080549192916114e790615707565b80601f016020809104026020016040519081016040528092919081815260200182805461151390615707565b80156115605780601f1061153557610100808354040283529160200191611560565b820191906000526020600020905b81548152906001019060200180831161154357829003601f168201915b5050505050905082565b6000546001600160a01b031633146115945760405162461bcd60e51b8152600401610d0990615545565b61159c613be3565b565b610fab83838360405180602001604052806000815250612941565b6115c23361124d565b6116275760405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201526f1b995c881b9bdc88185c1c1c9bdd995960821b6064820152608401610d09565b61163081613c76565b50565b602a8054602b80549192916114e790615707565b600061165260095490565b82106116b55760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610d09565b600982815481106116c8576116c86157c9565b90600052602060002001549050919050565b60135460009060ff166116ff5760405162461bcd60e51b8152600401610d099061550e565b6000603860008481526020019081526020016000206040518060400160405290816000820154815260200160018201805461173990615707565b80601f016020809104026020016040519081016040528092919081815260200182805461176590615707565b80156117b25780601f10611787576101008083540402835291602001916117b2565b820191906000526020600020905b81548152906001019060200180831161179557829003601f168201915b5050505050815250509050828160000151146117e05760405162461bcd60e51b8152600401610d09906154bd565b60006117ea6123b4565b9050600061180c620151806001856000015161180691906156ad565b90613bc4565b9050600061181d8262015180613d1d565b905080600061182f8262015180613d1d565b90508060006118418262015180613d1d565b9050818710156118635760405162461bcd60e51b8152600401610d099061557a565b80871061187a575060009998505050505050505050565b60006118868884613d29565b90506118956201518082613d29565b9b9a5050505050505050505050565b600080546001600160a01b03163314806118c0575060135460ff165b6118dc5760405162461bcd60e51b8152600401610d099061550e565b6000603860008481526020019081526020016000206040518060400160405290816000820154815260200160018201805461191690615707565b80601f016020809104026020016040519081016040528092919081815260200182805461194290615707565b801561198f5780601f106119645761010080835404028352916020019161198f565b820191906000526020600020905b81548152906001019060200180831161197257829003601f168201915b50505050508152505090506000603960008581526020019081526020016000206040518061010001604052908160008201604051806040016040529081600082015481526020016001820180546119e590615707565b80601f0160208091040260200160405190810160405280929190818152602001828054611a1190615707565b8015611a5e5780601f10611a3357610100808354040283529160200191611a5e565b820191906000526020600020905b815481529060010190602001808311611a4157829003601f168201915b50505091909252505050815260028201546020820152600382015460408201526004820154606082015260058201546080820152600682015460a0820152600782015460c082015260089091015460ff16151560e09091015282519091508414611ada5760405162461bcd60e51b8152600401610d09906154bd565b6000546001600160a01b031633148015611af957506000949350505050565b6000611b036123b4565b6060840151608085015186519293506000928390611b2c906201518090611806906001906156ad565b90506000611b3d8262015180613d1d565b9050806000611b4f8262015180613d1d565b9050806000611b618262015180613d1d565b9050858a1015611b835760405162461bcd60e51b8152600401610d099061557a565b858a10158015611b925750838a105b15611c9657336000908152603f6020908152604080832080548251818502810185019093528083529192909190830182828015611bee57602002820191906000526020600020905b815481526020019060010190808311611bda575b505050505090506000805b8251811015611c3e578f60000151838281518110611c1957611c196157c9565b60200260200101511415611c2c57600191505b80611c3681615742565b915050611bf9565b5080611c8c5760405162461bcd60e51b815260206004820181905260248201527f54696572206e6f74206163746976652c206e6f742077686974656c69737465646044820152606401610d09565b899a505050611d70565b838a10158015611ca55750828a105b15611cb257879850611d70565b818a10158015611cc15750808a105b15611d43576000611cd28b84613d29565b90506000611ce08a8a613d29565b90506000611cfe6001611cf862015180610e10613bd7565b90613d29565b90506000611d0c8383613bd7565b90506000611d1c85610e10613bd7565b90506000611d2a8383613bc4565b9050611d368e82613d29565b9e50505050505050611d70565b808a10611d70578b60e0015115611d6c5760405162461bcd60e51b8152600401610d099061557a565b8698505b868910611d7d5788611d7f565b865b9f9e505050505050505050505050505050565b6000546001600160a01b03163314611dbc5760405162461bcd60e51b8152600401610d0990615545565b80516111ac90600c906020840190614b55565b6000546001600160a01b03163314611df95760405162461bcd60e51b8152600401610d0990615545565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6060611e26826138a4565b611e425760405162461bcd60e51b8152600401610d09906154e3565b6000828152603e60209081526040918290208054835181840281018401909452808452909183018282801561123b57602002820191906000526020600020908154815260200190600101908083116112275750505050509050919050565b6000818152600360205260408120546001600160a01b031680610cd95760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610d09565b60606035805480602002602001604051908101604052809291908181526020016000905b828210156114ca578382906000526020600020906002020160405180604001604052908160008201548152602001600182018054611f7890615707565b80601f0160208091040260200160405190810160405280929190818152602001828054611fa490615707565b8015611ff15780601f10611fc657610100808354040283529160200191611ff1565b820191906000526020600020905b815481529060010190602001808311611fd457829003601f168201915b50505050508152505081526020019060010190611f3b565b603a60205260009081526040902080546001820180549192916114e790615707565b6037818154811061203b57600080fd5b600091825260209091200154905081565b6000546001600160a01b031633146120765760405162461bcd60e51b8152600401610d0990615545565b60005b81518110156111ac576000828281518110612096576120966157c9565b602002602001015190506120a981613c76565b50806120b481615742565b915050612079565b6000546001600160a01b031633146120e65760405162461bcd60e51b8152600401610d0990615545565b601281905560405181907fb14aa2dad53a0090fda3c97971fdc6c84331eff6fc43a584628e5d83e131a30990600090a250565b60006001600160a01b0382166121845760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610d09565b506001600160a01b031660009081526004602052604090205490565b6000546001600160a01b031633146121ca5760405162461bcd60e51b8152600401610d0990615545565b61159c6000613d35565b60135460009060ff166121f95760405162461bcd60e51b8152600401610d099061550e565b6000603860008481526020019081526020016000206040518060400160405290816000820154815260200160018201805461223390615707565b80601f016020809104026020016040519081016040528092919081815260200182805461225f90615707565b80156122ac5780601f10612281576101008083540402835291602001916122ac565b820191906000526020600020905b81548152906001019060200180831161228f57829003601f168201915b5050505050815250509050828160000151146122da5760405162461bcd60e51b8152600401610d09906154bd565b60006122e46123b4565b90506000612300620151806001856000015161180691906156ad565b905060006123118262015180613d1d565b90508060006123238262015180613d1d565b9050818510156123455760405162461bcd60e51b8152600401610d099061557a565b80851061235a57506000979650505050505050565b60006123668684613d29565b90506123756201518082613d29565b9998505050505050505050565b6000546001600160a01b031633146123ac5760405162461bcd60e51b8152600401610d0990615545565b61159c613d85565b600080601254116123c55750600090565b6012546123d3904290613d29565b905090565b6000546001600160a01b031633146124025760405162461bcd60e51b8152600401610d0990615545565b60135460ff166124245760405162461bcd60e51b8152600401610d099061550e565b600091825260396020526040909120600801805460ff1916911515919091179055565b606060028054610d8f90615707565b6001600160a01b0382163314156124af5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d09565b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6035818154811061252b57600080fd5b600091825260209091206002909102018054600182018054919350906114e790615707565b6000546001600160a01b0316331461257a5760405162461bcd60e51b8152600401610d0990615545565b600060386000848152602001908152602001600020604051806040016040529081600082015481526020016001820180546125b490615707565b80601f01602080910402602001604051908101604052809291908181526020018280546125e090615707565b801561262d5780601f106126025761010080835404028352916020019161262d565b820191906000526020600020905b81548152906001019060200180831161261057829003601f168201915b50505050508152505090508281600001511461265b5760405162461bcd60e51b8152600401610d09906154bd565b60005b825181101561274657600083828151811061267b5761267b6157c9565b6020908102919091018101516001600160a01b0381166000908152603f9092526040822090925090805b82548110156126ed5785600001518382815481106126c5576126c56157c9565b906000526020600020015414156126db57600191505b806126e581615742565b9150506126a5565b5080612709578451825460018101845560008481526020902001555b6001600160a01b0383166000908152603f60205260409020825461272f91908490614bd9565b50505050808061273e90615742565b91505061265e565b50505050565b60135460009060ff166127715760405162461bcd60e51b8152600401610d099061550e565b600060386000848152602001908152602001600020604051806040016040529081600082015481526020016001820180546127ab90615707565b80601f01602080910402602001604051908101604052809291908181526020018280546127d790615707565b80156128245780601f106127f957610100808354040283529160200191612824565b820191906000526020600020905b81548152906001019060200180831161280757829003601f168201915b5050505050815250509050828160000151146128525760405162461bcd60e51b8152600401610d09906154bd565b600061285c6123b4565b90506000612878620151806001856000015161180691906156ad565b905060006128898262015180613d1d565b9050818310156128ab5760405162461bcd60e51b8152600401610d099061557a565b8083106128be5750600095945050505050565b60006128ca8484613d29565b90506128d96201518082613d29565b979650505050505050565b6000546001600160a01b0316331461290e5760405162461bcd60e51b8152600401610d0990615545565b601181905560405181907fce3498f3236889c7e9256b3643e0f7fae5a1b912f2ac0daa1d89236c70b522c690600090a250565b61294b338361392f565b6129675760405162461bcd60e51b8152600401610d09906155a3565b61274684848484613e00565b6000546001600160a01b031633148061298e575060135460ff165b6129aa5760405162461bcd60e51b8152600401610d099061550e565b6129b48383613e33565b6129f95760405162461bcd60e51b8152602060048201526016602482015275111a5c9958dd081b5a5b9d08191a5cd85b1b1bddd95960521b6044820152606401610d09565b604081604051612a099190615199565b9081526040519081900360200190205460ff1615612a5d5760405162461bcd60e51b815260206004820152601160248201527012185cda08185b1c9958591e481d5cd959607a1b6044820152606401610d09565b82612a69338684613e57565b14612aa45760405162461bcd60e51b815260206004820152600b60248201526a12185cda0819985a5b195960aa1b6044820152606401610d09565b60006038600087815260200190815260200160002060405180604001604052908160008201548152602001600182018054612ade90615707565b80601f0160208091040260200160405190810160405280929190818152602001828054612b0a90615707565b8015612b575780601f10612b2c57610100808354040283529160200191612b57565b820191906000526020600020905b815481529060010190602001808311612b3a57829003601f168201915b5050505050815250509050600060396000888152602001908152602001600020604051806101000160405290816000820160405180604001604052908160008201548152602001600182018054612bad90615707565b80601f0160208091040260200160405190810160405280929190818152602001828054612bd990615707565b8015612c265780601f10612bfb57610100808354040283529160200191612c26565b820191906000526020600020905b815481529060010190602001808311612c0957829003601f168201915b50505091909252505050815260028201546020820152600382015460408201526004820154606082015260058201546080820152600682015460a0820152600782015460c082015260089091015460ff16151560e09091015282519091508714612ca25760405162461bcd60e51b8152600401610d09906154bd565b60008611612ceb5760405162461bcd60e51b81526020600482015260166024820152754d757374206d696e74206174206c65617374206f6e6560501b6044820152606401610d09565b6000612cfe87611cf885600001516132fe565b1015612d4c5760405162461bcd60e51b815260206004820152601f60248201527f4d696e74696e6720776f756c6420657863656564206d617820737570706c79006044820152606401610d09565b6000612d5733612119565b90506000805b82811015612e64576000612d7133836112b6565b90506000603a600083815260200190815260200160002060405180604001604052908160008201548152602001600182018054612dad90615707565b80601f0160208091040260200160405190810160405280929190818152602001828054612dd990615707565b8015612e265780601f10612dfb57610100808354040283529160200191612e26565b820191906000526020600020905b815481529060010190602001808311612e0957829003601f168201915b5050505050815250509050866000015181600001511415612e4f5783612e4b81615742565b9450505b50508080612e5c90615742565b915050612d5d565b5060008881336001600160a01b0316612e856000546001600160a01b031690565b6001600160a01b031614905080612fce576000612ea06123b4565b90506000612ebc6201518060018b6000015161180691906156ad565b90506000612ecd8262015180613d1d565b9050808311612f525760a0890151612ee58887613d1d565b1115612f525760405162461bcd60e51b815260206004820152603660248201527f52657175657374656420616d6f756e742065786365656473206d6178696d756d604482015275081dda1a5d195b1a5cdd081b5a5b9d08185b5bdd5b9d60521b6064820152608401610d09565b60c0890151612f618887613d1d565b1115612fca5760405162461bcd60e51b815260206004820152603260248201527f52657175657374656420616d6f756e742065786365656473206d6178696d756d604482015271081d1bdd185b081b5a5b9d08185b5bdd5b9d60721b6064820152608401610d09565b5050505b612fdf8261180689600001516118a4565b9250348311156130315760405162461bcd60e51b815260206004820152601e60248201527f45544820616d6f756e742073656e74206973206e6f7420636f727265637400006044820152606401610d09565b60005b828110156130e85787516000908152603d602090815260408220549089015161305c91613d1d565b90506130683382613ed9565b6000818152603a602090815260409091208a518155818b015180518c93613096926001850192910190614b55565b5050506000818152603b602090815260408083204290558b518352603d9091529020546130c4906001613d1d565b89516000908152603d602052604090205550806130e081615742565b915050613034565b5060016040896040516130fb9190615199565b908152604051908190036020019020805491151560ff19909216919091179055600e54613131906001600160a01b031684613ef3565b8234111561314c5761314c336131473486613d29565b613ef3565b505050505050505050505050565b60148054601580549192916114e790615707565b6000546001600160a01b031633146131985760405162461bcd60e51b8152600401610d0990615545565b6131a1826138a4565b6131bd5760405162461bcd60e51b8152600401610d09906154e3565b6000918252603e6020908152604083208054600181018255908452922090910155565b60606131eb826138a4565b6132075760405162461bcd60e51b8152600401610d09906154e3565b6000828152603e602052604090205480156132c5576000838152603e602052604081206132356001846156ad565b81548110613245576132456157c9565b60009182526020918290200154604080518082018252600981526806630313535313232360bc1b81850152905191935061328292600d9201615222565b60405160208183030381529060405261329c82602061400c565b6040516020016132ad92919061516a565b60405160208183030381529060405292505050919050565b6132cd61413b565b6132d68461414a565b6040516020016132e79291906151b5565b604051602081830303815290604052915050919050565b600080546001600160a01b031633148061331a575060135460ff165b6133365760405162461bcd60e51b8152600401610d099061550e565b6000603860008481526020019081526020016000206040518060400160405290816000820154815260200160018201805461337090615707565b80601f016020809104026020016040519081016040528092919081815260200182805461339c90615707565b80156133e95780601f106133be576101008083540402835291602001916133e9565b820191906000526020600020905b8154815290600101906020018083116133cc57829003601f168201915b505050505081525050905060006039600085815260200190815260200160002060405180610100016040529081600082016040518060400160405290816000820154815260200160018201805461343f90615707565b80601f016020809104026020016040519081016040528092919081815260200182805461346b90615707565b80156134b85780601f1061348d576101008083540402835291602001916134b8565b820191906000526020600020905b81548152906001019060200180831161349b57829003601f168201915b50505091909252505050815260028201546020820152600382015460408201526004820154606082015260058201546080820152600682015460a0820152600782015460c082015260089091015460ff16151560e090910152825190915084146135345760405162461bcd60e51b8152600401610d09906154bd565b60408082015183516000908152603d60205291909120546135558282613d29565b9695505050505050565b603860205260009081526040902080546001820180549192916114e790615707565b6000546001600160a01b031633146135ab5760405162461bcd60e51b8152600401610d0990615545565b600060386000848152602001908152602001600020604051806040016040529081600082015481526020016001820180546135e590615707565b80601f016020809104026020016040519081016040528092919081815260200182805461361190615707565b801561365e5780601f106136335761010080835404028352916020019161365e565b820191906000526020600020905b81548152906001019060200180831161364157829003601f168201915b50505050508152505090508281600001511461368c5760405162461bcd60e51b8152600401610d09906154bd565b6001600160a01b0382166000908152603f60205260408120905b81548110156137335782600001518282815481106136c6576136c66157c9565b9060005260206000200154141561372157815482906136e7906001906156ad565b815481106136f7576136f76157c9565b9060005260206000200154828281548110613714576137146157c9565b6000918252602090912001555b8061372b81615742565b9150506136a6565b5080805480613744576137446157b3565b6000828152602080822083016000199081018390559092019092556001600160a01b0385168252603f905260409020815461378191908390614bd9565b5050505050565b606061379261413b565b6040516020016137a291906151f6565b604051602081830303815290604052905090565b603e60205281600052604060002081815481106137d257600080fd5b90600052602060002001600091509150505481565b6000546001600160a01b031633146138115760405162461bcd60e51b8152600401610d0990615545565b6001600160a01b0381166138765760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d09565b61163081613d35565b60006001600160e01b0319821663780e9d6360e01b1480610cd95750610cd982614248565b6000908152600360205260409020546001600160a01b0316151590565b600081815260056020526040902080546001600160a01b0319166001600160a01b03841690811790915581906138f682611ea0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061393a826138a4565b61399b5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610d09565b60006139a683611ea0565b9050806001600160a01b0316846001600160a01b031614806139e15750836001600160a01b03166139d684610e12565b6001600160a01b0316145b80613a1157506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316613a2c82611ea0565b6001600160a01b031614613a945760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610d09565b6001600160a01b038216613af65760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610d09565b613b01838383614298565b613b0c6000826138c1565b6001600160a01b0383166000908152600460205260408120805460019290613b359084906156ad565b90915550506001600160a01b0382166000908152600460205260408120805460019290613b63908490615662565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000613bd0828461568e565b9392505050565b6000613bd0828461567a565b600b5460ff16613c2c5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610d09565b600b805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000613c8182611ea0565b9050613c8f81600084614298565b613c9a6000836138c1565b6001600160a01b0381166000908152600460205260408120805460019290613cc39084906156ad565b909155505060008281526003602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000613bd08284615662565b6000613bd082846156ad565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600b5460ff1615613dcb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610d09565b600b805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613c593390565b613e0b848484613a19565b613e17848484846142b4565b6127465760405162461bcd60e51b8152600401610d099061546b565b6000613e3f83836143c1565b6010546001600160a01b039182169116149392505050565b600080848484604051602001613e6f9392919061512b565b60408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160408051808303601f19018152919052805160209091012095945050505050565b6111ac8282604051806020016040528060008152506143e5565b80471015613f435760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610d09565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613f90576040519150601f19603f3d011682016040523d82523d6000602084013e613f95565b606091505b5050905080610fab5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610d09565b6060600061401b83600261568e565b67ffffffffffffffff811115614033576140336157df565b6040519080825280601f01601f19166020018201604052801561405d576020820181803683370190505b509050600061406d84600261568e565b90505b80156140ec576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061409e5761409e6157c9565b1a60f81b826140ae6001846156ad565b815181106140be576140be6157c9565b60200101906001600160f81b031916908160001a90535060049490941c936140e5816156f0565b9050614070565b508315613bd05760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610d09565b6060600c8054610d8f90615707565b60608161416e5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115614198578061418281615742565b91506141919050600a8361567a565b9150614172565b60008167ffffffffffffffff8111156141b3576141b36157df565b6040519080825280601f01601f1916602001820160405280156141dd576020820181803683370190505b5090505b8415613a11576141f26001836156ad565b91506141ff600a8661575d565b61420a906030615662565b60f81b81838151811061421f5761421f6157c9565b60200101906001600160f81b031916908160001a905350614241600a8661567a565b94506141e1565b60006001600160e01b031982166380ac58cd60e01b148061427957506001600160e01b03198216635b5e139f60e01b145b80610cd957506301ffc9a760e01b6001600160e01b0319831614610cd9565b6000818152603c60205260409020429055610fab838383614418565b60006001600160a01b0384163b156143b657604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906142f89033908990889088906004016152c9565b602060405180830381600087803b15801561431257600080fd5b505af1925050508015614342575060408051601f3d908101601f1916820190925261433f91810190614ec5565b60015b61439c573d808015614370576040519150601f19603f3d011682016040523d82523d6000602084013e614375565b606091505b5080516143945760405162461bcd60e51b8152600401610d099061546b565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050613a11565b506001949350505050565b60008060006143d0858561448a565b915091506143dd816144f7565b509392505050565b6143ef83836146b2565b6143fc60008484846142b4565b610fab5760405162461bcd60e51b8152600401610d099061546b565b6144238383836147f1565b600b5460ff1615610fab5760405162461bcd60e51b815260206004820152602b60248201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760448201526a1a1a5b19481c185d5cd95960aa1b6064820152608401610d09565b6000808251604114156144c15760208301516040840151606085015160001a6144b5878285856148a9565b945094505050506112af565b8251604014156144eb57602083015160408401516144e0868383614996565b9350935050506112af565b506000905060026112af565b600081600481111561450b5761450b61579d565b14156145145750565b60018160048111156145285761452861579d565b14156145765760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610d09565b600281600481111561458a5761458a61579d565b14156145d85760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610d09565b60038160048111156145ec576145ec61579d565b14156146455760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610d09565b60048160048111156146595761465961579d565b14156116305760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610d09565b6001600160a01b0382166147085760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d09565b614711816138a4565b1561475e5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d09565b61476a60008383614298565b6001600160a01b0382166000908152600460205260408120805460019290614793908490615662565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160a01b03831661484c5761484781600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b61486f565b816001600160a01b0316836001600160a01b03161461486f5761486f83826149c5565b6001600160a01b03821661488657610fab81614a62565b826001600160a01b0316826001600160a01b031614610fab57610fab8282614b11565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156148e0575060009050600361498d565b8460ff16601b141580156148f857508460ff16601c14155b15614909575060009050600461498d565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561495d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166149865760006001925092505061498d565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b016149b7878288856148a9565b935093505050935093915050565b600060016149d284612119565b6149dc91906156ad565b600083815260086020526040902054909150808214614a2f576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b600954600090614a74906001906156ad565b6000838152600a602052604081205460098054939450909284908110614a9c57614a9c6157c9565b906000526020600020015490508060098381548110614abd57614abd6157c9565b6000918252602080832090910192909255828152600a90915260408082208490558582528120556009805480614af557614af56157b3565b6001900381819060005260206000200160009055905550505050565b6000614b1c83612119565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b828054614b6190615707565b90600052602060002090601f016020900481019282614b835760008555614bc9565b82601f10614b9c57805160ff1916838001178555614bc9565b82800160010185558215614bc9579182015b82811115614bc9578251825591602001919060010190614bae565b50614bd5929150614c19565b5090565b828054828255906000526020600020908101928215614bc95760005260206000209182015b82811115614bc9578254825591600101919060010190614bfe565b5b80821115614bd55760008155600101614c1a565b80356001600160a01b038116811461124357600080fd5b8035801515811461124357600080fd5b600082601f830112614c6657600080fd5b813567ffffffffffffffff811115614c8057614c806157df565b614c93601f8201601f191660200161560d565b818152846020838601011115614ca857600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215614cd757600080fd5b613bd082614c2e565b60008060408385031215614cf357600080fd5b614cfc83614c2e565b9150614d0a60208401614c2e565b90509250929050565b600080600060608486031215614d2857600080fd5b614d3184614c2e565b9250614d3f60208501614c2e565b9150604084013590509250925092565b60008060008060808587031215614d6557600080fd5b614d6e85614c2e565b9350614d7c60208601614c2e565b925060408501359150606085013567ffffffffffffffff811115614d9f57600080fd5b614dab87828801614c55565b91505092959194509250565b60008060408385031215614dca57600080fd5b614dd383614c2e565b9150614d0a60208401614c45565b60008060408385031215614df457600080fd5b614dfd83614c2e565b946020939093013593505050565b60006020808385031215614e1e57600080fd5b823567ffffffffffffffff811115614e3557600080fd5b8301601f81018513614e4657600080fd5b8035614e59614e548261563e565b61560d565b80828252848201915084840188868560051b8701011115614e7957600080fd5b600094505b83851015614e9c578035835260019490940193918501918501614e7e565b50979650505050505050565b600060208284031215614eba57600080fd5b8135613bd0816157f5565b600060208284031215614ed757600080fd5b8151613bd0816157f5565b600060208284031215614ef457600080fd5b813567ffffffffffffffff811115614f0b57600080fd5b613a1184828501614c55565b600060208284031215614f2957600080fd5b5035919050565b60008060408385031215614f4357600080fd5b82359150614d0a60208401614c2e565b60008060408385031215614f6657600080fd5b8235915060208084013567ffffffffffffffff811115614f8557600080fd5b8401601f81018613614f9657600080fd5b8035614fa4614e548261563e565b80828252848201915084840189868560051b8701011115614fc457600080fd5b600094505b83851015614fee57614fda81614c2e565b835260019490940193918501918501614fc9565b5080955050505050509250929050565b6000806040838503121561501157600080fd5b82359150614d0a60208401614c45565b6000806040838503121561503457600080fd5b50508035926020909101359150565b600080600080600060a0868803121561505b57600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff8082111561508857600080fd5b61509489838a01614c55565b935060808801359150808211156150aa57600080fd5b506150b788828901614c55565b9150509295509295909350565b600081518084526150dc8160208601602086016156c4565b601f01601f19169290920160200192915050565b600081516151028185602086016156c4565b9290920192915050565b805182526000602082015160406020850152613a1160408501826150c4565b6bffffffffffffffffffffffff198460601b1681528260148201526000825161515b8160348501602087016156c4565b91909101603401949350505050565b6000835161517c8184602088016156c4565b8351908301906151908183602088016156c4565b01949350505050565b600082516151ab8184602087016156c4565b9190910192915050565b600083516151c78184602088016156c4565b65746f6b656e2f60d01b90830190815283516151ea8160068401602088016156c4565b01600601949350505050565b600082516152088184602087016156c4565b6718dbdb9d1c9858dd60c21b920191825250600801919050565b600080845481600182811c91508083168061523e57607f831692505b602080841082141561525e57634e487b7160e01b86526022600452602486fd5b8180156152725760018114615283576152b0565b60ff198616895284890196506152b0565b60008b81526020902060005b868110156152a85781548b82015290850190830161528f565b505084890196505b5050505050506152c081856150f0565b95945050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613555908301846150c4565b6020808252825182820181905260009190848201906040850190845b8181101561533457835183529284019291840191600101615318565b50909695505050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156153e857603f198984030185528151610100815181865261538e8287018261510c565b838b0151878c0152898401518a880152606080850151908801526080808501519088015260a0808501519088015260c0808501519088015260e0938401511515939096019290925250509386019390860190600101615367565b509098975050505050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561544b57603f1988860301845261543985835161510c565b9450928501929085019060010161541d565b5092979650505050505050565b602081526000613bd060208301846150c4565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252600c908201526b24b73b30b634b2103a34b2b960a11b604082015260600190565b6020808252601190820152702737b732bc34b9ba32b73a103a37b5b2b760791b604082015260600190565b60208082526019908201527f5075626c69632073616c65206973206e6f742061637469766500000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600f908201526e54696572206e6f742061637469766560881b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b828152604060208201526000613a1160408301846150c4565b604051601f8201601f1916810167ffffffffffffffff81118282101715615636576156366157df565b604052919050565b600067ffffffffffffffff821115615658576156586157df565b5060051b60200190565b6000821982111561567557615675615771565b500190565b60008261568957615689615787565b500490565b60008160001904831182151516156156a8576156a8615771565b500290565b6000828210156156bf576156bf615771565b500390565b60005b838110156156df5781810151838201526020016156c7565b838111156127465750506000910152565b6000816156ff576156ff615771565b506000190190565b600181811c9082168061571b57607f821691505b6020821081141561573c57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561575657615756615771565b5060010190565b60008261576c5761576c615787565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461163057600080fdfea26469706673582212208092bf4a4b990ae542576b8489967690dddd31f2d9832361509650d142f773c464736f6c634300080700330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a687474703a2f2f6170692e666f756e646572736b65792e696f2f000000000000

Deployed Bytecode

0x6080604052600436106104105760003560e01c80636ab49a5b1161021e578063a422948a11610123578063c87b56dd116100ab578063e8a3d4851161007a578063e8a3d48514610c1a578063e985e9c514610c2f578063eaaf369a14610c78578063eeab99aa14610c98578063f2fde38b14610cae57600080fd5b8063c87b56dd14610b9a578063d229491714610bba578063d60f8f3f14610bda578063dc566b8314610bfa57600080fd5b8063b88d4fde116100f2578063b88d4fde14610b18578063ba3ca30514610b38578063bb6b13a114610b4b578063bc8893b414610b60578063c4f3829014610b7a57600080fd5b8063a422948a14610a98578063b0e0d80614610ab8578063b17a4b9814610ad8578063b6b8194014610af857600080fd5b80638da5cb5b116101a657806392ed0d1b1161017557806392ed0d1b14610a36578063945e4013146109b757806395d89b4114610a63578063a22cb46514610a78578063a271e525146109b757600080fd5b80638da5cb5b146109e35780638e70e30a14610a015780638ec4972114610a1657806392cda4cd146109b757600080fd5b8063715018a6116101ed578063715018a61461095557806376772cf81461096a5780637c2cce9e146109975780637d9762da146109b75780638456cb59146109ce57600080fd5b80636ab49a5b146108df5780636bb7b1d9146108ff5780636d5d40c61461091557806370a082311461093557600080fd5b806336341c0411610324578063559e775b116102ac578063603168011161027b578063603168011461083d5780636352211e1461085d5780636471af831461087d578063649e705f1461089f57806368d9aa0b146108bf57600080fd5b8063559e775b146107c557806355f804b3146107e55780635c975abb146108055780635e1e10041461081d57600080fd5b806342966c68116102f357806342966c68146107235780634369f4e5146107435780634b1740ad146107705780634f6ccce714610785578063514a39a9146107a557600080fd5b806336341c04146106a95780633806153e146106cb5780633f4ba83a146106ee57806342842e0e1461070357600080fd5b80630c894cfe116103a7578063230b0c7011610376578063230b0c70146105cd57806323b872dd146105fa5780632a55205a1461061a5780632a905318146106595780632f745c591461068957600080fd5b80630c894cfe1461053057806318160ddd1461054557806318821400146105645780631d980acb146105ad57600080fd5b8063081812fc116103e3578063081812fc146104ae578063095ea7b3146104e65780630c1c972a146105065780630c41f4971461051b57600080fd5b806301ffc9a714610415578063046dc1661461044a57806306d254da1461046c57806306fdde031461048c575b600080fd5b34801561042157600080fd5b50610435610430366004614ea8565b610cce565b60405190151581526020015b60405180910390f35b34801561045657600080fd5b5061046a610465366004614cc5565b610cdf565b005b34801561047857600080fd5b5061046a610487366004614cc5565b610d34565b34801561049857600080fd5b506104a1610d80565b6040516104419190615458565b3480156104ba57600080fd5b506104ce6104c9366004614f17565b610e12565b6040516001600160a01b039091168152602001610441565b3480156104f257600080fd5b5061046a610501366004614de1565b610e9a565b34801561051257600080fd5b5061046a610fb0565b34801561052757600080fd5b5061046a611077565b34801561053c57600080fd5b5061046a611100565b34801561055157600080fd5b506009545b604051908152602001610441565b34801561057057600080fd5b506104a16040518060400160405280601b81526020017f496d70616374205468656f727920466f756e6465722773204b6579000000000081525081565b3480156105b957600080fd5b5061046a6105c8366004614ee2565b61116f565b3480156105d957600080fd5b506105ed6105e8366004614cc5565b6111b0565b60405161044191906152fc565b34801561060657600080fd5b5061046a610615366004614d13565b611248565b34801561062657600080fd5b5061063a610635366004615021565b61127a565b604080516001600160a01b039093168352602083019190915201610441565b34801561066557600080fd5b506104a1604051806040016040528060048152602001634954464b60e01b81525081565b34801561069557600080fd5b506105566106a4366004614de1565b6112b6565b3480156106b557600080fd5b506106be61134c565b6040516104419190615340565b3480156106d757600080fd5b506106e06114d3565b6040516104419291906155f4565b3480156106fa57600080fd5b5061046a61156a565b34801561070f57600080fd5b5061046a61071e366004614d13565b61159e565b34801561072f57600080fd5b5061046a61073e366004614f17565b6115b9565b34801561074f57600080fd5b5061055661075e366004614f17565b603c6020526000908152604090205481565b34801561077c57600080fd5b506106e0611633565b34801561079157600080fd5b506105566107a0366004614f17565b611647565b3480156107b157600080fd5b506105566107c0366004614f17565b6116da565b3480156107d157600080fd5b506105566107e0366004614f17565b6118a4565b3480156107f157600080fd5b5061046a610800366004614ee2565b611d92565b34801561081157600080fd5b50600b5460ff16610435565b34801561082957600080fd5b5061046a610838366004614cc5565b611dcf565b34801561084957600080fd5b506105ed610858366004614f17565b611e1b565b34801561086957600080fd5b506104ce610878366004614f17565b611ea0565b34801561088957600080fd5b50610892611f17565b60405161044191906153f6565b3480156108ab57600080fd5b506106e06108ba366004614f17565b612009565b3480156108cb57600080fd5b506105566108da366004614f17565b61202b565b3480156108eb57600080fd5b5061046a6108fa366004614e0b565b61204c565b34801561090b57600080fd5b5061055660125481565b34801561092157600080fd5b5061046a610930366004614f17565b6120bc565b34801561094157600080fd5b50610556610950366004614cc5565b612119565b34801561096157600080fd5b5061046a6121a0565b34801561097657600080fd5b50610556610985366004614f17565b603b6020526000908152604090205481565b3480156109a357600080fd5b506105566109b2366004614f17565b6121d4565b3480156109c357600080fd5b506105566201518081565b3480156109da57600080fd5b5061046a612382565b3480156109ef57600080fd5b506000546001600160a01b03166104ce565b348015610a0d57600080fd5b506105566123b4565b348015610a2257600080fd5b5061046a610a31366004614ffe565b6123d8565b348015610a4257600080fd5b50610556610a51366004614f17565b603d6020526000908152604090205481565b348015610a6f57600080fd5b506104a1612447565b348015610a8457600080fd5b5061046a610a93366004614db7565b612456565b348015610aa457600080fd5b506106e0610ab3366004614f17565b61251b565b348015610ac457600080fd5b5061046a610ad3366004614f53565b612550565b348015610ae457600080fd5b50610556610af3366004614f17565b61274c565b348015610b0457600080fd5b5061046a610b13366004614f17565b6128e4565b348015610b2457600080fd5b5061046a610b33366004614d4f565b612941565b61046a610b46366004615043565b612973565b348015610b5757600080fd5b506106e061315a565b348015610b6c57600080fd5b506013546104359060ff1681565b348015610b8657600080fd5b5061046a610b95366004615021565b61316e565b348015610ba657600080fd5b506104a1610bb5366004614f17565b6131e0565b348015610bc657600080fd5b50610556610bd5366004614f17565b6132fe565b348015610be657600080fd5b506106e0610bf5366004614f17565b61355f565b348015610c0657600080fd5b5061046a610c15366004614f30565b613581565b348015610c2657600080fd5b506104a1613788565b348015610c3b57600080fd5b50610435610c4a366004614ce0565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b348015610c8457600080fd5b50610556610c93366004615021565b6137b6565b348015610ca457600080fd5b50610556610e1081565b348015610cba57600080fd5b5061046a610cc9366004614cc5565b6137e7565b6000610cd98261387f565b92915050565b6000546001600160a01b03163314610d125760405162461bcd60e51b8152600401610d0990615545565b60405180910390fd5b601080546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314610d5e5760405162461bcd60e51b8152600401610d0990615545565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b606060018054610d8f90615707565b80601f0160208091040260200160405190810160405280929190818152602001828054610dbb90615707565b8015610e085780601f10610ddd57610100808354040283529160200191610e08565b820191906000526020600020905b815481529060010190602001808311610deb57829003601f168201915b5050505050905090565b6000610e1d826138a4565b610e7e5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610d09565b506000908152600560205260409020546001600160a01b031690565b6000610ea582611ea0565b9050806001600160a01b0316836001600160a01b03161415610f135760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610d09565b336001600160a01b0382161480610f2f5750610f2f8133610c4a565b610fa15760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610d09565b610fab83836138c1565b505050565b6000546001600160a01b03163314610fda5760405162461bcd60e51b8152600401610d0990615545565b60135460ff16158015610fed5750601254155b6110395760405162461bcd60e51b815260206004820152601d60248201527f5075626c69632073616c6520697320616c7265616479206163746976650000006044820152606401610d09565b4260128190556013805460ff191660011790556040517fb14aa2dad53a0090fda3c97971fdc6c84331eff6fc43a584628e5d83e131a30990600090a2565b6000546001600160a01b031633146110a15760405162461bcd60e51b8152600401610d0990615545565b60135460ff166110c35760405162461bcd60e51b8152600401610d099061550e565b6013805460ff191690556110d56123b4565b6040517fb94d4ebcdba018821f2c6ae2fb3a03d4023685b1c78faa4fe43dada42890cd2d90600090a2565b6000546001600160a01b0316331461112a5760405162461bcd60e51b8152600401610d0990615545565b6013805460ff19811660ff9182161590811790925560405191161515907fafa97d89ca766bd74e787f7998a071ea20f4ddeea353499106df17bc9cf4deb890600090a2565b6000546001600160a01b031633146111995760405162461bcd60e51b8152600401610d0990615545565b80516111ac90600d906020840190614b55565b5050565b6000546060906001600160a01b031633146111dd5760405162461bcd60e51b8152600401610d0990615545565b6001600160a01b0382166000908152603f60209081526040918290208054835181840281018401909452808452909183018282801561123b57602002820191906000526020600020905b815481526020019060010190808311611227575b505050505090505b919050565b611253335b8261392f565b61126f5760405162461bcd60e51b8152600401610d09906155a3565b610fab838383613a19565b600f5460115460009182916001600160a01b03909116906112aa90612710906112a4908790613bc4565b90613bd7565b915091505b9250929050565b60006112c183612119565b82106113235760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610d09565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b6000546060906001600160a01b031633146113795760405162461bcd60e51b8152600401610d0990615545565b6036805480602002602001604051908101604052809291908181526020016000905b828210156114ca5760008481526020902060408051610140810190915260098402909101805461010083019081526001820180548492918491610120850191906113e490615707565b80601f016020809104026020016040519081016040528092919081815260200182805461141090615707565b801561145d5780601f106114325761010080835404028352916020019161145d565b820191906000526020600020905b81548152906001019060200180831161144057829003601f168201915b5050509190925250505081526002820154602080830191909152600383015460408301526004830154606083015260058301546080830152600683015460a0830152600783015460c083015260089092015460ff16151560e090910152908252600192909201910161139b565b50505050905090565b601f8054602080549192916114e790615707565b80601f016020809104026020016040519081016040528092919081815260200182805461151390615707565b80156115605780601f1061153557610100808354040283529160200191611560565b820191906000526020600020905b81548152906001019060200180831161154357829003601f168201915b5050505050905082565b6000546001600160a01b031633146115945760405162461bcd60e51b8152600401610d0990615545565b61159c613be3565b565b610fab83838360405180602001604052806000815250612941565b6115c23361124d565b6116275760405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201526f1b995c881b9bdc88185c1c1c9bdd995960821b6064820152608401610d09565b61163081613c76565b50565b602a8054602b80549192916114e790615707565b600061165260095490565b82106116b55760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610d09565b600982815481106116c8576116c86157c9565b90600052602060002001549050919050565b60135460009060ff166116ff5760405162461bcd60e51b8152600401610d099061550e565b6000603860008481526020019081526020016000206040518060400160405290816000820154815260200160018201805461173990615707565b80601f016020809104026020016040519081016040528092919081815260200182805461176590615707565b80156117b25780601f10611787576101008083540402835291602001916117b2565b820191906000526020600020905b81548152906001019060200180831161179557829003601f168201915b5050505050815250509050828160000151146117e05760405162461bcd60e51b8152600401610d09906154bd565b60006117ea6123b4565b9050600061180c620151806001856000015161180691906156ad565b90613bc4565b9050600061181d8262015180613d1d565b905080600061182f8262015180613d1d565b90508060006118418262015180613d1d565b9050818710156118635760405162461bcd60e51b8152600401610d099061557a565b80871061187a575060009998505050505050505050565b60006118868884613d29565b90506118956201518082613d29565b9b9a5050505050505050505050565b600080546001600160a01b03163314806118c0575060135460ff165b6118dc5760405162461bcd60e51b8152600401610d099061550e565b6000603860008481526020019081526020016000206040518060400160405290816000820154815260200160018201805461191690615707565b80601f016020809104026020016040519081016040528092919081815260200182805461194290615707565b801561198f5780601f106119645761010080835404028352916020019161198f565b820191906000526020600020905b81548152906001019060200180831161197257829003601f168201915b50505050508152505090506000603960008581526020019081526020016000206040518061010001604052908160008201604051806040016040529081600082015481526020016001820180546119e590615707565b80601f0160208091040260200160405190810160405280929190818152602001828054611a1190615707565b8015611a5e5780601f10611a3357610100808354040283529160200191611a5e565b820191906000526020600020905b815481529060010190602001808311611a4157829003601f168201915b50505091909252505050815260028201546020820152600382015460408201526004820154606082015260058201546080820152600682015460a0820152600782015460c082015260089091015460ff16151560e09091015282519091508414611ada5760405162461bcd60e51b8152600401610d09906154bd565b6000546001600160a01b031633148015611af957506000949350505050565b6000611b036123b4565b6060840151608085015186519293506000928390611b2c906201518090611806906001906156ad565b90506000611b3d8262015180613d1d565b9050806000611b4f8262015180613d1d565b9050806000611b618262015180613d1d565b9050858a1015611b835760405162461bcd60e51b8152600401610d099061557a565b858a10158015611b925750838a105b15611c9657336000908152603f6020908152604080832080548251818502810185019093528083529192909190830182828015611bee57602002820191906000526020600020905b815481526020019060010190808311611bda575b505050505090506000805b8251811015611c3e578f60000151838281518110611c1957611c196157c9565b60200260200101511415611c2c57600191505b80611c3681615742565b915050611bf9565b5080611c8c5760405162461bcd60e51b815260206004820181905260248201527f54696572206e6f74206163746976652c206e6f742077686974656c69737465646044820152606401610d09565b899a505050611d70565b838a10158015611ca55750828a105b15611cb257879850611d70565b818a10158015611cc15750808a105b15611d43576000611cd28b84613d29565b90506000611ce08a8a613d29565b90506000611cfe6001611cf862015180610e10613bd7565b90613d29565b90506000611d0c8383613bd7565b90506000611d1c85610e10613bd7565b90506000611d2a8383613bc4565b9050611d368e82613d29565b9e50505050505050611d70565b808a10611d70578b60e0015115611d6c5760405162461bcd60e51b8152600401610d099061557a565b8698505b868910611d7d5788611d7f565b865b9f9e505050505050505050505050505050565b6000546001600160a01b03163314611dbc5760405162461bcd60e51b8152600401610d0990615545565b80516111ac90600c906020840190614b55565b6000546001600160a01b03163314611df95760405162461bcd60e51b8152600401610d0990615545565b600e80546001600160a01b0319166001600160a01b0392909216919091179055565b6060611e26826138a4565b611e425760405162461bcd60e51b8152600401610d09906154e3565b6000828152603e60209081526040918290208054835181840281018401909452808452909183018282801561123b57602002820191906000526020600020908154815260200190600101908083116112275750505050509050919050565b6000818152600360205260408120546001600160a01b031680610cd95760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610d09565b60606035805480602002602001604051908101604052809291908181526020016000905b828210156114ca578382906000526020600020906002020160405180604001604052908160008201548152602001600182018054611f7890615707565b80601f0160208091040260200160405190810160405280929190818152602001828054611fa490615707565b8015611ff15780601f10611fc657610100808354040283529160200191611ff1565b820191906000526020600020905b815481529060010190602001808311611fd457829003601f168201915b50505050508152505081526020019060010190611f3b565b603a60205260009081526040902080546001820180549192916114e790615707565b6037818154811061203b57600080fd5b600091825260209091200154905081565b6000546001600160a01b031633146120765760405162461bcd60e51b8152600401610d0990615545565b60005b81518110156111ac576000828281518110612096576120966157c9565b602002602001015190506120a981613c76565b50806120b481615742565b915050612079565b6000546001600160a01b031633146120e65760405162461bcd60e51b8152600401610d0990615545565b601281905560405181907fb14aa2dad53a0090fda3c97971fdc6c84331eff6fc43a584628e5d83e131a30990600090a250565b60006001600160a01b0382166121845760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610d09565b506001600160a01b031660009081526004602052604090205490565b6000546001600160a01b031633146121ca5760405162461bcd60e51b8152600401610d0990615545565b61159c6000613d35565b60135460009060ff166121f95760405162461bcd60e51b8152600401610d099061550e565b6000603860008481526020019081526020016000206040518060400160405290816000820154815260200160018201805461223390615707565b80601f016020809104026020016040519081016040528092919081815260200182805461225f90615707565b80156122ac5780601f10612281576101008083540402835291602001916122ac565b820191906000526020600020905b81548152906001019060200180831161228f57829003601f168201915b5050505050815250509050828160000151146122da5760405162461bcd60e51b8152600401610d09906154bd565b60006122e46123b4565b90506000612300620151806001856000015161180691906156ad565b905060006123118262015180613d1d565b90508060006123238262015180613d1d565b9050818510156123455760405162461bcd60e51b8152600401610d099061557a565b80851061235a57506000979650505050505050565b60006123668684613d29565b90506123756201518082613d29565b9998505050505050505050565b6000546001600160a01b031633146123ac5760405162461bcd60e51b8152600401610d0990615545565b61159c613d85565b600080601254116123c55750600090565b6012546123d3904290613d29565b905090565b6000546001600160a01b031633146124025760405162461bcd60e51b8152600401610d0990615545565b60135460ff166124245760405162461bcd60e51b8152600401610d099061550e565b600091825260396020526040909120600801805460ff1916911515919091179055565b606060028054610d8f90615707565b6001600160a01b0382163314156124af5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d09565b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6035818154811061252b57600080fd5b600091825260209091206002909102018054600182018054919350906114e790615707565b6000546001600160a01b0316331461257a5760405162461bcd60e51b8152600401610d0990615545565b600060386000848152602001908152602001600020604051806040016040529081600082015481526020016001820180546125b490615707565b80601f01602080910402602001604051908101604052809291908181526020018280546125e090615707565b801561262d5780601f106126025761010080835404028352916020019161262d565b820191906000526020600020905b81548152906001019060200180831161261057829003601f168201915b50505050508152505090508281600001511461265b5760405162461bcd60e51b8152600401610d09906154bd565b60005b825181101561274657600083828151811061267b5761267b6157c9565b6020908102919091018101516001600160a01b0381166000908152603f9092526040822090925090805b82548110156126ed5785600001518382815481106126c5576126c56157c9565b906000526020600020015414156126db57600191505b806126e581615742565b9150506126a5565b5080612709578451825460018101845560008481526020902001555b6001600160a01b0383166000908152603f60205260409020825461272f91908490614bd9565b50505050808061273e90615742565b91505061265e565b50505050565b60135460009060ff166127715760405162461bcd60e51b8152600401610d099061550e565b600060386000848152602001908152602001600020604051806040016040529081600082015481526020016001820180546127ab90615707565b80601f01602080910402602001604051908101604052809291908181526020018280546127d790615707565b80156128245780601f106127f957610100808354040283529160200191612824565b820191906000526020600020905b81548152906001019060200180831161280757829003601f168201915b5050505050815250509050828160000151146128525760405162461bcd60e51b8152600401610d09906154bd565b600061285c6123b4565b90506000612878620151806001856000015161180691906156ad565b905060006128898262015180613d1d565b9050818310156128ab5760405162461bcd60e51b8152600401610d099061557a565b8083106128be5750600095945050505050565b60006128ca8484613d29565b90506128d96201518082613d29565b979650505050505050565b6000546001600160a01b0316331461290e5760405162461bcd60e51b8152600401610d0990615545565b601181905560405181907fce3498f3236889c7e9256b3643e0f7fae5a1b912f2ac0daa1d89236c70b522c690600090a250565b61294b338361392f565b6129675760405162461bcd60e51b8152600401610d09906155a3565b61274684848484613e00565b6000546001600160a01b031633148061298e575060135460ff165b6129aa5760405162461bcd60e51b8152600401610d099061550e565b6129b48383613e33565b6129f95760405162461bcd60e51b8152602060048201526016602482015275111a5c9958dd081b5a5b9d08191a5cd85b1b1bddd95960521b6044820152606401610d09565b604081604051612a099190615199565b9081526040519081900360200190205460ff1615612a5d5760405162461bcd60e51b815260206004820152601160248201527012185cda08185b1c9958591e481d5cd959607a1b6044820152606401610d09565b82612a69338684613e57565b14612aa45760405162461bcd60e51b815260206004820152600b60248201526a12185cda0819985a5b195960aa1b6044820152606401610d09565b60006038600087815260200190815260200160002060405180604001604052908160008201548152602001600182018054612ade90615707565b80601f0160208091040260200160405190810160405280929190818152602001828054612b0a90615707565b8015612b575780601f10612b2c57610100808354040283529160200191612b57565b820191906000526020600020905b815481529060010190602001808311612b3a57829003601f168201915b5050505050815250509050600060396000888152602001908152602001600020604051806101000160405290816000820160405180604001604052908160008201548152602001600182018054612bad90615707565b80601f0160208091040260200160405190810160405280929190818152602001828054612bd990615707565b8015612c265780601f10612bfb57610100808354040283529160200191612c26565b820191906000526020600020905b815481529060010190602001808311612c0957829003601f168201915b50505091909252505050815260028201546020820152600382015460408201526004820154606082015260058201546080820152600682015460a0820152600782015460c082015260089091015460ff16151560e09091015282519091508714612ca25760405162461bcd60e51b8152600401610d09906154bd565b60008611612ceb5760405162461bcd60e51b81526020600482015260166024820152754d757374206d696e74206174206c65617374206f6e6560501b6044820152606401610d09565b6000612cfe87611cf885600001516132fe565b1015612d4c5760405162461bcd60e51b815260206004820152601f60248201527f4d696e74696e6720776f756c6420657863656564206d617820737570706c79006044820152606401610d09565b6000612d5733612119565b90506000805b82811015612e64576000612d7133836112b6565b90506000603a600083815260200190815260200160002060405180604001604052908160008201548152602001600182018054612dad90615707565b80601f0160208091040260200160405190810160405280929190818152602001828054612dd990615707565b8015612e265780601f10612dfb57610100808354040283529160200191612e26565b820191906000526020600020905b815481529060010190602001808311612e0957829003601f168201915b5050505050815250509050866000015181600001511415612e4f5783612e4b81615742565b9450505b50508080612e5c90615742565b915050612d5d565b5060008881336001600160a01b0316612e856000546001600160a01b031690565b6001600160a01b031614905080612fce576000612ea06123b4565b90506000612ebc6201518060018b6000015161180691906156ad565b90506000612ecd8262015180613d1d565b9050808311612f525760a0890151612ee58887613d1d565b1115612f525760405162461bcd60e51b815260206004820152603660248201527f52657175657374656420616d6f756e742065786365656473206d6178696d756d604482015275081dda1a5d195b1a5cdd081b5a5b9d08185b5bdd5b9d60521b6064820152608401610d09565b60c0890151612f618887613d1d565b1115612fca5760405162461bcd60e51b815260206004820152603260248201527f52657175657374656420616d6f756e742065786365656473206d6178696d756d604482015271081d1bdd185b081b5a5b9d08185b5bdd5b9d60721b6064820152608401610d09565b5050505b612fdf8261180689600001516118a4565b9250348311156130315760405162461bcd60e51b815260206004820152601e60248201527f45544820616d6f756e742073656e74206973206e6f7420636f727265637400006044820152606401610d09565b60005b828110156130e85787516000908152603d602090815260408220549089015161305c91613d1d565b90506130683382613ed9565b6000818152603a602090815260409091208a518155818b015180518c93613096926001850192910190614b55565b5050506000818152603b602090815260408083204290558b518352603d9091529020546130c4906001613d1d565b89516000908152603d602052604090205550806130e081615742565b915050613034565b5060016040896040516130fb9190615199565b908152604051908190036020019020805491151560ff19909216919091179055600e54613131906001600160a01b031684613ef3565b8234111561314c5761314c336131473486613d29565b613ef3565b505050505050505050505050565b60148054601580549192916114e790615707565b6000546001600160a01b031633146131985760405162461bcd60e51b8152600401610d0990615545565b6131a1826138a4565b6131bd5760405162461bcd60e51b8152600401610d09906154e3565b6000918252603e6020908152604083208054600181018255908452922090910155565b60606131eb826138a4565b6132075760405162461bcd60e51b8152600401610d09906154e3565b6000828152603e602052604090205480156132c5576000838152603e602052604081206132356001846156ad565b81548110613245576132456157c9565b60009182526020918290200154604080518082018252600981526806630313535313232360bc1b81850152905191935061328292600d9201615222565b60405160208183030381529060405261329c82602061400c565b6040516020016132ad92919061516a565b60405160208183030381529060405292505050919050565b6132cd61413b565b6132d68461414a565b6040516020016132e79291906151b5565b604051602081830303815290604052915050919050565b600080546001600160a01b031633148061331a575060135460ff165b6133365760405162461bcd60e51b8152600401610d099061550e565b6000603860008481526020019081526020016000206040518060400160405290816000820154815260200160018201805461337090615707565b80601f016020809104026020016040519081016040528092919081815260200182805461339c90615707565b80156133e95780601f106133be576101008083540402835291602001916133e9565b820191906000526020600020905b8154815290600101906020018083116133cc57829003601f168201915b505050505081525050905060006039600085815260200190815260200160002060405180610100016040529081600082016040518060400160405290816000820154815260200160018201805461343f90615707565b80601f016020809104026020016040519081016040528092919081815260200182805461346b90615707565b80156134b85780601f1061348d576101008083540402835291602001916134b8565b820191906000526020600020905b81548152906001019060200180831161349b57829003601f168201915b50505091909252505050815260028201546020820152600382015460408201526004820154606082015260058201546080820152600682015460a0820152600782015460c082015260089091015460ff16151560e090910152825190915084146135345760405162461bcd60e51b8152600401610d09906154bd565b60408082015183516000908152603d60205291909120546135558282613d29565b9695505050505050565b603860205260009081526040902080546001820180549192916114e790615707565b6000546001600160a01b031633146135ab5760405162461bcd60e51b8152600401610d0990615545565b600060386000848152602001908152602001600020604051806040016040529081600082015481526020016001820180546135e590615707565b80601f016020809104026020016040519081016040528092919081815260200182805461361190615707565b801561365e5780601f106136335761010080835404028352916020019161365e565b820191906000526020600020905b81548152906001019060200180831161364157829003601f168201915b50505050508152505090508281600001511461368c5760405162461bcd60e51b8152600401610d09906154bd565b6001600160a01b0382166000908152603f60205260408120905b81548110156137335782600001518282815481106136c6576136c66157c9565b9060005260206000200154141561372157815482906136e7906001906156ad565b815481106136f7576136f76157c9565b9060005260206000200154828281548110613714576137146157c9565b6000918252602090912001555b8061372b81615742565b9150506136a6565b5080805480613744576137446157b3565b6000828152602080822083016000199081018390559092019092556001600160a01b0385168252603f905260409020815461378191908390614bd9565b5050505050565b606061379261413b565b6040516020016137a291906151f6565b604051602081830303815290604052905090565b603e60205281600052604060002081815481106137d257600080fd5b90600052602060002001600091509150505481565b6000546001600160a01b031633146138115760405162461bcd60e51b8152600401610d0990615545565b6001600160a01b0381166138765760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d09565b61163081613d35565b60006001600160e01b0319821663780e9d6360e01b1480610cd95750610cd982614248565b6000908152600360205260409020546001600160a01b0316151590565b600081815260056020526040902080546001600160a01b0319166001600160a01b03841690811790915581906138f682611ea0565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061393a826138a4565b61399b5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610d09565b60006139a683611ea0565b9050806001600160a01b0316846001600160a01b031614806139e15750836001600160a01b03166139d684610e12565b6001600160a01b0316145b80613a1157506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316613a2c82611ea0565b6001600160a01b031614613a945760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610d09565b6001600160a01b038216613af65760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610d09565b613b01838383614298565b613b0c6000826138c1565b6001600160a01b0383166000908152600460205260408120805460019290613b359084906156ad565b90915550506001600160a01b0382166000908152600460205260408120805460019290613b63908490615662565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000613bd0828461568e565b9392505050565b6000613bd0828461567a565b600b5460ff16613c2c5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610d09565b600b805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000613c8182611ea0565b9050613c8f81600084614298565b613c9a6000836138c1565b6001600160a01b0381166000908152600460205260408120805460019290613cc39084906156ad565b909155505060008281526003602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000613bd08284615662565b6000613bd082846156ad565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600b5460ff1615613dcb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610d09565b600b805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613c593390565b613e0b848484613a19565b613e17848484846142b4565b6127465760405162461bcd60e51b8152600401610d099061546b565b6000613e3f83836143c1565b6010546001600160a01b039182169116149392505050565b600080848484604051602001613e6f9392919061512b565b60408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c0160408051808303601f19018152919052805160209091012095945050505050565b6111ac8282604051806020016040528060008152506143e5565b80471015613f435760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610d09565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613f90576040519150601f19603f3d011682016040523d82523d6000602084013e613f95565b606091505b5050905080610fab5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610d09565b6060600061401b83600261568e565b67ffffffffffffffff811115614033576140336157df565b6040519080825280601f01601f19166020018201604052801561405d576020820181803683370190505b509050600061406d84600261568e565b90505b80156140ec576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061409e5761409e6157c9565b1a60f81b826140ae6001846156ad565b815181106140be576140be6157c9565b60200101906001600160f81b031916908160001a90535060049490941c936140e5816156f0565b9050614070565b508315613bd05760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610d09565b6060600c8054610d8f90615707565b60608161416e5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115614198578061418281615742565b91506141919050600a8361567a565b9150614172565b60008167ffffffffffffffff8111156141b3576141b36157df565b6040519080825280601f01601f1916602001820160405280156141dd576020820181803683370190505b5090505b8415613a11576141f26001836156ad565b91506141ff600a8661575d565b61420a906030615662565b60f81b81838151811061421f5761421f6157c9565b60200101906001600160f81b031916908160001a905350614241600a8661567a565b94506141e1565b60006001600160e01b031982166380ac58cd60e01b148061427957506001600160e01b03198216635b5e139f60e01b145b80610cd957506301ffc9a760e01b6001600160e01b0319831614610cd9565b6000818152603c60205260409020429055610fab838383614418565b60006001600160a01b0384163b156143b657604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906142f89033908990889088906004016152c9565b602060405180830381600087803b15801561431257600080fd5b505af1925050508015614342575060408051601f3d908101601f1916820190925261433f91810190614ec5565b60015b61439c573d808015614370576040519150601f19603f3d011682016040523d82523d6000602084013e614375565b606091505b5080516143945760405162461bcd60e51b8152600401610d099061546b565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050613a11565b506001949350505050565b60008060006143d0858561448a565b915091506143dd816144f7565b509392505050565b6143ef83836146b2565b6143fc60008484846142b4565b610fab5760405162461bcd60e51b8152600401610d099061546b565b6144238383836147f1565b600b5460ff1615610fab5760405162461bcd60e51b815260206004820152602b60248201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760448201526a1a1a5b19481c185d5cd95960aa1b6064820152608401610d09565b6000808251604114156144c15760208301516040840151606085015160001a6144b5878285856148a9565b945094505050506112af565b8251604014156144eb57602083015160408401516144e0868383614996565b9350935050506112af565b506000905060026112af565b600081600481111561450b5761450b61579d565b14156145145750565b60018160048111156145285761452861579d565b14156145765760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610d09565b600281600481111561458a5761458a61579d565b14156145d85760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610d09565b60038160048111156145ec576145ec61579d565b14156146455760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610d09565b60048160048111156146595761465961579d565b14156116305760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610d09565b6001600160a01b0382166147085760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d09565b614711816138a4565b1561475e5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d09565b61476a60008383614298565b6001600160a01b0382166000908152600460205260408120805460019290614793908490615662565b909155505060008181526003602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6001600160a01b03831661484c5761484781600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b61486f565b816001600160a01b0316836001600160a01b03161461486f5761486f83826149c5565b6001600160a01b03821661488657610fab81614a62565b826001600160a01b0316826001600160a01b031614610fab57610fab8282614b11565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156148e0575060009050600361498d565b8460ff16601b141580156148f857508460ff16601c14155b15614909575060009050600461498d565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561495d573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166149865760006001925092505061498d565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b016149b7878288856148a9565b935093505050935093915050565b600060016149d284612119565b6149dc91906156ad565b600083815260086020526040902054909150808214614a2f576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b600954600090614a74906001906156ad565b6000838152600a602052604081205460098054939450909284908110614a9c57614a9c6157c9565b906000526020600020015490508060098381548110614abd57614abd6157c9565b6000918252602080832090910192909255828152600a90915260408082208490558582528120556009805480614af557614af56157b3565b6001900381819060005260206000200160009055905550505050565b6000614b1c83612119565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b828054614b6190615707565b90600052602060002090601f016020900481019282614b835760008555614bc9565b82601f10614b9c57805160ff1916838001178555614bc9565b82800160010185558215614bc9579182015b82811115614bc9578251825591602001919060010190614bae565b50614bd5929150614c19565b5090565b828054828255906000526020600020908101928215614bc95760005260206000209182015b82811115614bc9578254825591600101919060010190614bfe565b5b80821115614bd55760008155600101614c1a565b80356001600160a01b038116811461124357600080fd5b8035801515811461124357600080fd5b600082601f830112614c6657600080fd5b813567ffffffffffffffff811115614c8057614c806157df565b614c93601f8201601f191660200161560d565b818152846020838601011115614ca857600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215614cd757600080fd5b613bd082614c2e565b60008060408385031215614cf357600080fd5b614cfc83614c2e565b9150614d0a60208401614c2e565b90509250929050565b600080600060608486031215614d2857600080fd5b614d3184614c2e565b9250614d3f60208501614c2e565b9150604084013590509250925092565b60008060008060808587031215614d6557600080fd5b614d6e85614c2e565b9350614d7c60208601614c2e565b925060408501359150606085013567ffffffffffffffff811115614d9f57600080fd5b614dab87828801614c55565b91505092959194509250565b60008060408385031215614dca57600080fd5b614dd383614c2e565b9150614d0a60208401614c45565b60008060408385031215614df457600080fd5b614dfd83614c2e565b946020939093013593505050565b60006020808385031215614e1e57600080fd5b823567ffffffffffffffff811115614e3557600080fd5b8301601f81018513614e4657600080fd5b8035614e59614e548261563e565b61560d565b80828252848201915084840188868560051b8701011115614e7957600080fd5b600094505b83851015614e9c578035835260019490940193918501918501614e7e565b50979650505050505050565b600060208284031215614eba57600080fd5b8135613bd0816157f5565b600060208284031215614ed757600080fd5b8151613bd0816157f5565b600060208284031215614ef457600080fd5b813567ffffffffffffffff811115614f0b57600080fd5b613a1184828501614c55565b600060208284031215614f2957600080fd5b5035919050565b60008060408385031215614f4357600080fd5b82359150614d0a60208401614c2e565b60008060408385031215614f6657600080fd5b8235915060208084013567ffffffffffffffff811115614f8557600080fd5b8401601f81018613614f9657600080fd5b8035614fa4614e548261563e565b80828252848201915084840189868560051b8701011115614fc457600080fd5b600094505b83851015614fee57614fda81614c2e565b835260019490940193918501918501614fc9565b5080955050505050509250929050565b6000806040838503121561501157600080fd5b82359150614d0a60208401614c45565b6000806040838503121561503457600080fd5b50508035926020909101359150565b600080600080600060a0868803121561505b57600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff8082111561508857600080fd5b61509489838a01614c55565b935060808801359150808211156150aa57600080fd5b506150b788828901614c55565b9150509295509295909350565b600081518084526150dc8160208601602086016156c4565b601f01601f19169290920160200192915050565b600081516151028185602086016156c4565b9290920192915050565b805182526000602082015160406020850152613a1160408501826150c4565b6bffffffffffffffffffffffff198460601b1681528260148201526000825161515b8160348501602087016156c4565b91909101603401949350505050565b6000835161517c8184602088016156c4565b8351908301906151908183602088016156c4565b01949350505050565b600082516151ab8184602087016156c4565b9190910192915050565b600083516151c78184602088016156c4565b65746f6b656e2f60d01b90830190815283516151ea8160068401602088016156c4565b01600601949350505050565b600082516152088184602087016156c4565b6718dbdb9d1c9858dd60c21b920191825250600801919050565b600080845481600182811c91508083168061523e57607f831692505b602080841082141561525e57634e487b7160e01b86526022600452602486fd5b8180156152725760018114615283576152b0565b60ff198616895284890196506152b0565b60008b81526020902060005b868110156152a85781548b82015290850190830161528f565b505084890196505b5050505050506152c081856150f0565b95945050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613555908301846150c4565b6020808252825182820181905260009190848201906040850190845b8181101561533457835183529284019291840191600101615318565b50909695505050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156153e857603f198984030185528151610100815181865261538e8287018261510c565b838b0151878c0152898401518a880152606080850151908801526080808501519088015260a0808501519088015260c0808501519088015260e0938401511515939096019290925250509386019390860190600101615367565b509098975050505050505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561544b57603f1988860301845261543985835161510c565b9450928501929085019060010161541d565b5092979650505050505050565b602081526000613bd060208301846150c4565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252600c908201526b24b73b30b634b2103a34b2b960a11b604082015260600190565b6020808252601190820152702737b732bc34b9ba32b73a103a37b5b2b760791b604082015260600190565b60208082526019908201527f5075626c69632073616c65206973206e6f742061637469766500000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252600f908201526e54696572206e6f742061637469766560881b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b828152604060208201526000613a1160408301846150c4565b604051601f8201601f1916810167ffffffffffffffff81118282101715615636576156366157df565b604052919050565b600067ffffffffffffffff821115615658576156586157df565b5060051b60200190565b6000821982111561567557615675615771565b500190565b60008261568957615689615787565b500490565b60008160001904831182151516156156a8576156a8615771565b500290565b6000828210156156bf576156bf615771565b500390565b60005b838110156156df5781810151838201526020016156c7565b838111156127465750506000910152565b6000816156ff576156ff615771565b506000190190565b600181811c9082168061571b57607f821691505b6020821081141561573c57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561575657615756615771565b5060010190565b60008261576c5761576c615787565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461163057600080fdfea26469706673582212208092bf4a4b990ae542576b8489967690dddd31f2d9832361509650d142f773c464736f6c63430008070033

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

0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a687474703a2f2f6170692e666f756e646572736b65792e696f2f000000000000

-----Decoded View---------------
Arg [0] : _baseTokenURI (string): http://api.founderskey.io/

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 000000000000000000000000000000000000000000000000000000000000001a
Arg [2] : 687474703a2f2f6170692e666f756e646572736b65792e696f2f000000000000


Deployed Bytecode Sourcemap

63060:28357:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89170:231;;;;;;;;;;-1:-1:-1;89170:231:0;;;;;:::i;:::-;;:::i;:::-;;;17062:14:1;;17055:22;17037:41;;17025:2;17010:18;89170:231:0;;;;;;;;85486:104;;;;;;;;;;-1:-1:-1;85486:104:0;;;;;:::i;:::-;;:::i;:::-;;85633:106;;;;;;;;;;-1:-1:-1;85633:106:0;;;;;:::i;:::-;;:::i;43082:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;44641:221::-;;;;;;;;;;-1:-1:-1;44641:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;12371:32:1;;;12353:51;;12341:2;12326:18;44641:221:0;12207:203:1;44164:411:0;;;;;;;;;;-1:-1:-1;44164:411:0;;;;;:::i;:::-;;:::i;69225:212::-;;;;;;;;;;;;;:::i;70165:164::-;;;;;;;;;;;;;:::i;69973:158::-;;;;;;;;;;;;;:::i;56711:113::-;;;;;;;;;;-1:-1:-1;56799:10:0;:17;56711:113;;;17235:25:1;;;17223:2;17208:18;56711:113:0;17089:177:1;64729:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86082:117;;;;;;;;;;-1:-1:-1;86082:117:0;;;;;:::i;:::-;;:::i;72951:191::-;;;;;;;;;;-1:-1:-1;72951:191:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;45531:339::-;;;;;;;;;;-1:-1:-1;45531:339:0;;;;;:::i;:::-;;:::i;70977:274::-;;;;;;;;;;-1:-1:-1;70977:274:0;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;13111:32:1;;;13093:51;;13175:2;13160:18;;13153:34;;;;13066:18;70977:274:0;12919::1;64801:44:0;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;64801:44:0;;;;;56379:256;;;;;;;;;;-1:-1:-1;56379:256:0;;;;;:::i;:::-;;:::i;70719:163::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;65782:49::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;89604:73::-;;;;;;;;;;;;;:::i;45941:185::-;;;;;;;;;;-1:-1:-1;45941:185:0;;;;;:::i;:::-;;:::i;62676:245::-;;;;;;;;;;-1:-1:-1;62676:245:0;;;;;:::i;:::-;;:::i;66987:57::-;;;;;;;;;;-1:-1:-1;66987:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;66234:53;;;;;;;;;;;;;:::i;56901:233::-;;;;;;;;;;-1:-1:-1;56901:233:0;;;;;:::i;:::-;;:::i;75734:1209::-;;;;;;;;;;-1:-1:-1;75734:1209:0;;;;;:::i;:::-;;:::i;81198:3623::-;;;;;;;;;;-1:-1:-1;81198:3623:0;;;;;:::i;:::-;;:::i;85979:95::-;;;;;;;;;;-1:-1:-1;85979:95:0;;;;;:::i;:::-;;:::i;22224:86::-;;;;;;;;;;-1:-1:-1;22295:7:0;;;;22224:86;;85372:106;;;;;;;;;;-1:-1:-1;85372:106:0;;;;;:::i;:::-;;:::i;86516:224::-;;;;;;;;;;-1:-1:-1;86516:224:0;;;;;:::i;:::-;;:::i;42776:239::-;;;;;;;;;;-1:-1:-1;42776:239:0;;;;;:::i;:::-;;:::i;70584:100::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;66882:41::-;;;;;;;;;;-1:-1:-1;66882:41:0;;;;;:::i;:::-;;:::i;66741:27::-;;;;;;;;;;-1:-1:-1;66741:27:0;;;;;:::i;:::-;;:::i;80922:245::-;;;;;;;;;;-1:-1:-1;80922:245:0;;;;;:::i;:::-;;:::i;65204:34::-;;;;;;;;;;;;;;;;69721:217;;;;;;;;;;-1:-1:-1;69721:217:0;;;;;:::i;:::-;;:::i;42506:208::-;;;;;;;;;;-1:-1:-1;42506:208:0;;;;;:::i;:::-;;:::i;20521:94::-;;;;;;;;;;;;;:::i;66932:48::-;;;;;;;;;;-1:-1:-1;66932:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;74558:1133;;;;;;;;;;-1:-1:-1;74558:1133:0;;;;;:::i;:::-;;:::i;65113:55::-;;;;;;;;;;;;65162:6;65113:55;;89467:69;;;;;;;;;;;;;:::i;19870:87::-;;;;;;;;;;-1:-1:-1;19916:7:0;19943:6;-1:-1:-1;;;;;19943:6:0;19870:87;;73214:203;;;;;;;;;;;;;:::i;70359:195::-;;;;;;;;;;-1:-1:-1;70359:195:0;;;;;:::i;:::-;;:::i;67053:45::-;;;;;;;;;;-1:-1:-1;67053:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;43251:104;;;;;;;;;;;;;:::i;44934:295::-;;;;;;;;;;-1:-1:-1;44934:295:0;;;;;:::i;:::-;;:::i;66662:27::-;;;;;;;;;;-1:-1:-1;66662:27:0;;;;;:::i;:::-;;:::i;71328:770::-;;;;;;;;;;-1:-1:-1;71328:770:0;;;;;:::i;:::-;;:::i;73467:1048::-;;;;;;;;;;-1:-1:-1;73467:1048:0;;;;;:::i;:::-;;:::i;85780:170::-;;;;;;;;;;-1:-1:-1;85780:170:0;;;;;:::i;:::-;;:::i;46197:328::-;;;;;;;;;;-1:-1:-1;46197:328:0;;;;;:::i;:::-;;:::i;76997:3895::-;;;;;;:::i;:::-;;:::i;65332:52::-;;;;;;;;;;;;;:::i;65245:28::-;;;;;;;;;;-1:-1:-1;65245:28:0;;;;;;;;86237:232;;;;;;;;;;-1:-1:-1;86237:232:0;;;;;:::i;:::-;;:::i;86791:2055::-;;;;;;;;;;-1:-1:-1;86791:2055:0;;;;;:::i;:::-;;:::i;84861:503::-;;;;;;;;;;-1:-1:-1;84861:503:0;;;;;:::i;:::-;;:::i;66777:40::-;;;;;;;;;;-1:-1:-1;66777:40:0;;;;;:::i;:::-;;:::i;72170:724::-;;;;;;;;;;-1:-1:-1;72170:724:0;;;;;:::i;:::-;;:::i;88960:133::-;;;;;;;;;;;;;:::i;45300:164::-;;;;;;;;;;-1:-1:-1;45300:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;45421:25:0;;;45397:4;45421:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;45300:164;67107:50;;;;;;;;;;-1:-1:-1;67107:50:0;;;;;:::i;:::-;;:::i;65052:54::-;;;;;;;;;;;;65099:7;65052:54;;20770:192;;;;;;;;;;-1:-1:-1;20770:192:0;;;;;:::i;:::-;;:::i;89170:231::-;89327:4;89356:37;89380:12;89356:23;:37::i;:::-;89349:44;89170:231;-1:-1:-1;;89170:231:0:o;85486:104::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;;;;;;;;;85558:13:::1;:24:::0;;-1:-1:-1;;;;;;85558:24:0::1;-1:-1:-1::0;;;;;85558:24:0;;;::::1;::::0;;;::::1;::::0;;85486:104::o;85633:106::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;85706:14:::1;:25:::0;;-1:-1:-1;;;;;;85706:25:0::1;-1:-1:-1::0;;;;;85706:25:0;;;::::1;::::0;;;::::1;::::0;;85633:106::o;43082:100::-;43136:13;43169:5;43162:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43082:100;:::o;44641:221::-;44717:7;44745:16;44753:7;44745;:16::i;:::-;44737:73;;;;-1:-1:-1;;;44737:73:0;;29570:2:1;44737:73:0;;;29552:21:1;29609:2;29589:18;;;29582:30;29648:34;29628:18;;;29621:62;-1:-1:-1;;;29699:18:1;;;29692:42;29751:19;;44737:73:0;29368:408:1;44737:73:0;-1:-1:-1;44830:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;44830:24:0;;44641:221::o;44164:411::-;44245:13;44261:23;44276:7;44261:14;:23::i;:::-;44245:39;;44309:5;-1:-1:-1;;;;;44303:11:0;:2;-1:-1:-1;;;;;44303:11:0;;;44295:57;;;;-1:-1:-1;;;44295:57:0;;31444:2:1;44295:57:0;;;31426:21:1;31483:2;31463:18;;;31456:30;31522:34;31502:18;;;31495:62;-1:-1:-1;;;31573:18:1;;;31566:31;31614:19;;44295:57:0;31242:397:1;44295:57:0;18738:10;-1:-1:-1;;;;;44387:21:0;;;;:62;;-1:-1:-1;44412:37:0;44429:5;18738:10;45300:164;:::i;44412:37::-;44365:168;;;;-1:-1:-1;;;44365:168:0;;26081:2:1;44365:168:0;;;26063:21:1;26120:2;26100:18;;;26093:30;26159:34;26139:18;;;26132:62;26230:26;26210:18;;;26203:54;26274:19;;44365:168:0;25879:420:1;44365:168:0;44546:21;44555:2;44559:7;44546:8;:21::i;:::-;44234:341;44164:411;;:::o;69225:212::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;67926:16:::1;::::0;::::1;;67925:17;:45:::0;::::1;;;-1:-1:-1::0;67946:19:0::1;::::0;:24;67925:45:::1;67903:124;;;::::0;-1:-1:-1;;;67903:124:0;;33017:2:1;67903:124:0::1;::::0;::::1;32999:21:1::0;33056:2;33036:18;;;33029:30;33095:31;33075:18;;;33068:59;33144:18;;67903:124:0::1;32815:353:1::0;67903:124:0::1;69328:15:::2;69306:19;:37:::0;;;69354:16:::2;:23:::0;;-1:-1:-1;;69354:23:0::2;69373:4;69354:23;::::0;;69393:36:::2;::::0;::::2;::::0;69354:16:::2;::::0;69393:36:::2;69225:212::o:0;70165:164::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;67743:16:::1;::::0;::::1;;67735:54;;;;-1:-1:-1::0;;;67735:54:0::1;;;;;;;:::i;:::-;70243:16:::2;:24:::0;;-1:-1:-1;;70243:24:0::2;::::0;;70300:20:::2;:18;:20::i;:::-;70283:38;::::0;::::2;::::0;;;::::2;70165:164::o:0;69973:158::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;70057:16:::1;::::0;;-1:-1:-1;;70037:36:0;::::1;70057:16;::::0;;::::1;70056:17;70037:36:::0;;::::1;::::0;;;70089:34:::1;::::0;70106:16;;70089:34:::1;;::::0;::::1;::::0;70057:16:::1;::::0;70089:34:::1;69973:158::o:0;86082:117::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;86161:30;;::::1;::::0;:23:::1;::::0;:30:::1;::::0;::::1;::::0;::::1;:::i;:::-;;86082:117:::0;:::o;72951:191::-;19916:7;19943:6;73067:16;;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;73108:26:0;::::1;;::::0;;;:16:::1;:26;::::0;;;;;;;;73101:33;;;;;;::::1;::::0;;;;;;;;;;73108:26;;73101:33;::::1;73108:26:::0;73101:33;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20161:1;72951:191:::0;;;:::o;45531:339::-;45726:41;18738:10;45745:12;45759:7;45726:18;:41::i;:::-;45718:103;;;;-1:-1:-1;;;45718:103:0;;;;;;;:::i;:::-;45834:28;45844:4;45850:2;45854:7;45834:9;:28::i;70977:274::-;71156:14;;71201:18;;71077:16;;;;-1:-1:-1;;;;;71156:14:0;;;;71185:47;;71226:5;;71186:34;;:10;;:14;:34::i;:::-;71185:40;;:47::i;:::-;71134:109;;;;70977:274;;;;;;:::o;56379:256::-;56476:7;56512:23;56529:5;56512:16;:23::i;:::-;56504:5;:31;56496:87;;;;-1:-1:-1;;;56496:87:0;;19946:2:1;56496:87:0;;;19928:21:1;19985:2;19965:18;;;19958:30;20024:34;20004:18;;;19997:62;-1:-1:-1;;;20075:18:1;;;20068:41;20126:19;;56496:87:0;19744:407:1;56496:87:0;-1:-1:-1;;;;;;56601:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;56379:256::o;70719:163::-;19916:7;19943:6;70815:17;;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;70857:17:::1;70850:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;;::::1;::::0;;::::1;::::0;;;;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;;;;;;;::::1;::::0;::::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;70850:24:0;;;;-1:-1:-1;;;70850:24:0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;::::1;;;;::::0;;;;;;;;;;;;::::1;::::0;::::1;;;;;;;;;;70719:163:::0;:::o;65782:49::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;89604:73::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;89659:10:::1;:8;:10::i;:::-;89604:73::o:0;45941:185::-;46079:39;46096:4;46102:2;46106:7;46079:39;;;;;;;;;;;;:16;:39::i;62676:245::-;62794:41;18738:10;62813:12;18658:98;62794:41;62786:102;;;;-1:-1:-1;;;62786:102:0;;33375:2:1;62786:102:0;;;33357:21:1;33414:2;33394:18;;;33387:30;33453:34;33433:18;;;33426:62;-1:-1:-1;;;33504:18:1;;;33497:46;33560:19;;62786:102:0;33173:412:1;62786:102:0;62899:14;62905:7;62899:5;:14::i;:::-;62676:245;:::o;66234:53::-;;;;;;;;;;;;;:::i;56901:233::-;56976:7;57012:30;56799:10;:17;;56711:113;57012:30;57004:5;:38;56996:95;;;;-1:-1:-1;;;56996:95:0;;32604:2:1;56996:95:0;;;32586:21:1;32643:2;32623:18;;;32616:30;32682:34;32662:18;;;32655:62;-1:-1:-1;;;32733:18:1;;;32726:42;32785:19;;56996:95:0;32402:408:1;56996:95:0;57109:10;57120:5;57109:17;;;;;;;;:::i;:::-;;;;;;;;;57102:24;;56901:233;;;:::o;75734:1209::-;67743:16;;75862:7;;67743:16;;67735:54;;;;-1:-1:-1;;;67735:54:0;;;;;;;:::i;:::-;75887:16:::1;75906:8;:17;75915:7;75906:17;;;;;;;;;;;75887:36;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;75955:7;75944:4;:7;;;:18;75936:43;;;;-1:-1:-1::0;;;75936:43:0::1;;;;;;;:::i;:::-;75992:15;76010:20;:18;:20::i;:::-;75992:38;;76094:26;76123:41;65162:6;76134:1;76124:4;:7;;;:11;;;;:::i;:::-;76123:17:::0;::::1;:41::i;:::-;76094:70:::0;-1:-1:-1;76175:24:0::1;76202:71;76094:70:::0;64927:6:::1;76202:22;:71::i;:::-;76175:98:::0;-1:-1:-1;76175:98:0;76284:20:::1;76355:34;76175:98:::0;64983:6:::1;76355:16;:34::i;:::-;76334:55:::0;-1:-1:-1;76334:55:0;76400:20:::1;76465:34;76334:55:::0;65039:6:::1;76465:16;:34::i;:::-;76444:55;;76559:12;76548:7;:23;;76540:51;;;;-1:-1:-1::0;;;76540:51:0::1;;;;;;;:::i;:::-;76653:10;76642:7;:21;76638:62;;-1:-1:-1::0;76687:1:0::1;::::0;72951:191;-1:-1:-1;;;;;;;;;72951:191:0:o;76638:62::-:1;76757:25;76785;:7:::0;76797:12;76785:11:::1;:25::i;:::-;76757:53:::0;-1:-1:-1;76896:39:0::1;65039:6;76757:53:::0;76896:20:::1;:39::i;:::-;76889:46:::0;75734:1209;-1:-1:-1;;;;;;;;;;;75734:1209:0:o;81198:3623::-;81322:7;19943:6;;-1:-1:-1;;;;;19943:6:0;18738:10;68172:23;;:43;;-1:-1:-1;68199:16:0;;;;68172:43;68150:118;;;;-1:-1:-1;;;68150:118:0;;;;;;;:::i;:::-;81347:16:::1;81366:8;:17;81375:7;81366:17;;;;;;;;;;;81347:36;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;81394:24;81421:12;:21;81434:7;81421:21;;;;;;;;;;;81394:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;81394:48:0;;;;-1:-1:-1;;;81394:48:0;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;::::1;;;;::::0;;;;;81463:7;;81394:48;;-1:-1:-1;81463:18:0;::::1;81455:43;;;;-1:-1:-1::0;;;81455:43:0::1;;;;;;;:::i;:::-;81532:12;19943:6:::0;-1:-1:-1;;;;;19943:6:0;18738:10;81547:23:::1;81615:48:::0;::::1;;;-1:-1:-1::0;81650:1:0::1;::::0;72951:191;-1:-1:-1;;;;72951:191:0:o;81615:48::-:1;81675:15;81693:20;:18;:20::i;:::-;81830:22;::::0;::::1;::::0;81885:20:::1;::::0;::::1;::::0;82001:7;;81675:38;;-1:-1:-1;81724:20:0::1;::::0;;;82000:41:::1;::::0;65162:6:::1;::::0;82001:11:::1;::::0;82011:1:::1;::::0;82001:11:::1;:::i;82000:41::-;81971:70:::0;-1:-1:-1;82052:24:0::1;82079:71;81971:70:::0;64927:6:::1;82079:22;:71::i;:::-;82052:98:::0;-1:-1:-1;82052:98:0;82161:20:::1;82232:34;82052:98:::0;64983:6:::1;82232:16;:34::i;:::-;82211:55:::0;-1:-1:-1;82211:55:0;82277:20:::1;82342:34;82211:55:::0;65039:6:::1;82342:16;:34::i;:::-;82321:55;;82436:18;82425:7;:29;;82417:57;;;;-1:-1:-1::0;;;82417:57:0::1;;;;;;;:::i;:::-;82547:18;82536:7;:29;;82535:59;;;;;82581:12;82571:7;:22;82535:59;82531:2138;;;18738:10:::0;82678:33:::1;82714:30:::0;;;:16:::1;:30;::::0;;;;;;;82678:66;;;;;;::::1;::::0;;;;;;;;;;;;82714:30;;82678:66;;::::1;82714:30:::0;82678:66;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82759:18;82805:9:::0;82800:187:::1;82824:16;:23;82820:1;:27;82800:187;;;82900:4;:7;;;82877:16;82894:1;82877:19;;;;;;;;:::i;:::-;;;;;;;:30;82873:99;;;82948:4;82932:20;;82873:99;82849:3:::0;::::1;::::0;::::1;:::i;:::-;;;;82800:187;;;;83011:13;83003:58;;;::::0;-1:-1:-1;;;83003:58:0;;24952:2:1;83003:58:0::1;::::0;::::1;24934:21:1::0;;;24971:18;;;24964:30;25030:34;25010:18;;;25003:62;25082:18;;83003:58:0::1;24750:356:1::0;83003:58:0::1;83091:13;83076:28;;82596:563;;82531:2138;;;83181:12;83170:7;:23;;83169:51;;;;;83209:10;83199:7;:20;83169:51;83165:1504;;;83252:13;83237:28;;83165:1504;;;83374:12;83363:7;:23;;83362:51;;;;;83402:10;83392:7;:20;83362:51;83358:1311;;;83430:32;83465:25;:7:::0;83477:12;83465:11:::1;:25::i;:::-;83430:60:::0;-1:-1:-1;83541:22:0::1;83566:30;:13:::0;83584:11;83566:17:::1;:30::i;:::-;83541:55:::0;-1:-1:-1;83665:23:0::1;83691:81;83770:1;83691:74;65039:6;65099:7;83691:20;:74::i;:::-;:78:::0;::::1;:81::i;:::-;83665:107:::0;-1:-1:-1;83829:25:0::1;83857:35;:14:::0;83665:107;83857:18:::1;:35::i;:::-;83829:63:::0;-1:-1:-1;83962:22:0::1;83987:82;:24:::0;65099:7:::1;83987:28;:82::i;:::-;83962:107:::0;-1:-1:-1;84161:30:0::1;84194:69;:17:::0;83962:107;84194:21:::1;:69::i;:::-;84161:102:::0;-1:-1:-1;84341:41:0::1;:13:::0;84161:102;84341:17:::1;:41::i;:::-;84326:56;;83415:1068;;;;;;83358:1311;;;84504:10;84493:7;:21;84489:180;;84576:8;:18;;;84575:19;84567:47;;;;-1:-1:-1::0;;;84567:47:0::1;;;;;;;:::i;:::-;84646:11;84631:26;;84489:180;84773:11;84758:12;:26;:55;;84801:12;84758:55;;;84787:11;84758:55;84751:62:::0;81198:3623;-1:-1:-1;;;;;;;;;;;;;;;81198:3623:0:o;85979:95::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;86047:19;;::::1;::::0;:12:::1;::::0;:19:::1;::::0;::::1;::::0;::::1;:::i;85372:106::-:0;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;85445:14:::1;:25:::0;;-1:-1:-1;;;;;;85445:25:0::1;-1:-1:-1::0;;;;;85445:25:0;;;::::1;::::0;;;::::1;::::0;;85372:106::o;86516:224::-;86608:16;86650:17;86658:8;86650:7;:17::i;:::-;86642:47;;;;-1:-1:-1;;;86642:47:0;;;;;;;:::i;:::-;86709:23;;;;:13;:23;;;;;;;;;86702:30;;;;;;;;;;;;;;;;;86709:23;;86702:30;;86709:23;86702:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86516:224;;;:::o;42776:239::-;42848:7;42884:16;;;:7;:16;;;;;;-1:-1:-1;;;;;42884:16:0;42919:19;42911:73;;;;-1:-1:-1;;;42911:73:0;;27682:2:1;42911:73:0;;;27664:21:1;27721:2;27701:18;;;27694:30;27760:34;27740:18;;;27733:62;-1:-1:-1;;;27811:18:1;;;27804:39;27860:19;;42911:73:0;27480:405:1;70584:100:0;70630:13;70663;70656:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66882:41;;;;;;;;;;;;;;;;;;;;;;;;:::i;66741:27::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66741:27:0;:::o;80922:245::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;81005:9:::1;81000:160;81024:9;:16;81020:1;:20;81000:160;;;81087:15;81105:9;81115:1;81105:12;;;;;;;;:::i;:::-;;;;;;;81087:30;;81134:14;81140:7;81134:5;:14::i;:::-;-1:-1:-1::0;81042:3:0;::::1;::::0;::::1;:::i;:::-;;;;81000:160;;69721:217:::0;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;69836:19:::1;:42:::0;;;69894:36:::1;::::0;69858:20;;69894:36:::1;::::0;;;::::1;69721:217:::0;:::o;42506:208::-;42578:7;-1:-1:-1;;;;;42606:19:0;;42598:74;;;;-1:-1:-1;;;42598:74:0;;27271:2:1;42598:74:0;;;27253:21:1;27310:2;27290:18;;;27283:30;27349:34;27329:18;;;27322:62;-1:-1:-1;;;27400:18:1;;;27393:40;27450:19;;42598:74:0;27069:406:1;42598:74:0;-1:-1:-1;;;;;;42690:16:0;;;;;:9;:16;;;;;;;42506:208::o;20521:94::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;20586:21:::1;20604:1;20586:9;:21::i;74558:1133::-:0;67743:16;;74686:7;;67743:16;;67735:54;;;;-1:-1:-1;;;67735:54:0;;;;;;;:::i;:::-;74711:16:::1;74730:8;:17;74739:7;74730:17;;;;;;;;;;;74711:36;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;74779:7;74768:4;:7;;;:18;74760:43;;;;-1:-1:-1::0;;;74760:43:0::1;;;;;;;:::i;:::-;74850:15;74868:20;:18;:20::i;:::-;74850:38;;74952:26;74981:41;65162:6;74992:1;74982:4;:7;;;:11;;;;:::i;74981:41::-;74952:70:::0;-1:-1:-1;75033:24:0::1;75060:71;74952:70:::0;64927:6:::1;75060:22;:71::i;:::-;75033:98:::0;-1:-1:-1;75033:98:0;75142:20:::1;75213:34;75033:98:::0;64983:6:::1;75213:16;:34::i;:::-;75192:55;;75307:12;75296:7;:23;;75288:51;;;;-1:-1:-1::0;;;75288:51:0::1;;;;;;;:::i;:::-;75401:10;75390:7;:21;75386:62;;-1:-1:-1::0;75435:1:0::1;::::0;72951:191;-1:-1:-1;;;;;;;72951:191:0:o;75386:62::-:1;75505:25;75533;:7:::0;75545:12;75533:11:::1;:25::i;:::-;75505:53:::0;-1:-1:-1;75644:39:0::1;64983:6;75505:53:::0;75644:20:::1;:39::i;:::-;75637:46:::0;74558:1133;-1:-1:-1;;;;;;;;;74558:1133:0:o;89467:69::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;89520:8:::1;:6;:8::i;73214:203::-:0;73265:7;73327:1;73305:19;;:23;:104;;-1:-1:-1;73408:1:0;;73214:203::o;73305:104::-;73368:19;;73348:40;;:15;;:19;:40::i;:::-;73285:124;;73214:203;:::o;70359:195::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;67743:16:::1;::::0;::::1;;67735:54;;;;-1:-1:-1::0;;;67735:54:0::1;;;;;;;:::i;:::-;70502:21:::2;::::0;;;:12:::2;:21;::::0;;;;;:31:::2;;:44:::0;;-1:-1:-1;;70502:44:0::2;::::0;::::2;;::::0;;;::::2;::::0;;70359:195::o;43251:104::-;43307:13;43340:7;43333:14;;;;;:::i;44934:295::-;-1:-1:-1;;;;;45037:24:0;;18738:10;45037:24;;45029:62;;;;-1:-1:-1;;;45029:62:0;;22997:2:1;45029:62:0;;;22979:21:1;23036:2;23016:18;;;23009:30;23075:27;23055:18;;;23048:55;23120:18;;45029:62:0;22795:349:1;45029:62:0;18738:10;45104:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;45104:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;45104:53:0;;;;;;;;;;45173:48;;17037:41:1;;;45104:42:0;;18738:10;45173:48;;17010:18:1;45173:48:0;;;;;;;44934:295;;:::o;66662:27::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66662:27:0;;;;:::i;71328:770::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;71458:16:::1;71477:8;:17;71486:7;71477:17;;;;;;;;;;;71458:36;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;71526:7;71515:4;:7;;;:18;71507:43;;;;-1:-1:-1::0;;;71507:43:0::1;;;;;;;:::i;:::-;71568:9;71563:528;71587:10;:17;71583:1;:21;71563:528;;;71626:16;71645:10;71656:1;71645:13;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;-1:-1:-1;;;;;71703:26:0;::::1;71675:25;71703:26:::0;;;:16:::1;:26:::0;;;;;;71645:13;;-1:-1:-1;71703:26:0;71675:25;71780:162:::1;71804:14:::0;;71800:18;::::1;71780:162;;;71862:4;:7;;;71848;71856:1;71848:10;;;;;;;;:::i;:::-;;;;;;;;;:21;71844:83;;;71903:4;71894:13;;71844:83;71820:3:::0;::::1;::::0;::::1;:::i;:::-;;;;71780:162;;;;71963:6;71958:69;;72003:7:::0;;71990:21;;::::1;::::0;::::1;::::0;;72003:7:::1;71990:21:::0;;;::::1;::::0;;::::1;::::0;71958:69:::1;-1:-1:-1::0;;;;;72043:26:0;::::1;;::::0;;;:16:::1;:26;::::0;;;;:36;;::::1;::::0;:26;72072:7;;72043:36:::1;:::i;:::-;;71611:480;;;71606:3;;;;;:::i;:::-;;;;71563:528;;;;71447:651;71328:770:::0;;:::o;73467:1048::-;67743:16;;73601:7;;67743:16;;67735:54;;;;-1:-1:-1;;;67735:54:0;;;;;;;:::i;:::-;73626:16:::1;73645:8;:17;73654:7;73645:17;;;;;;;;;;;73626:36;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;73694:7;73683:4;:7;;;:18;73675:43;;;;-1:-1:-1::0;;;73675:43:0::1;;;;;;;:::i;:::-;73765:15;73783:20;:18;:20::i;:::-;73765:38;;73867:26;73896:41;65162:6;73907:1;73897:4;:7;;;:11;;;;:::i;73896:41::-;73867:70:::0;-1:-1:-1;73948:24:0::1;73975:71;73867:70:::0;64927:6:::1;73975:22;:71::i;:::-;73948:98;;74106:18;74095:7;:29;;74087:57;;;;-1:-1:-1::0;;;74087:57:0::1;;;;;;;:::i;:::-;74206:16;74195:7;:27;74191:68;;-1:-1:-1::0;74246:1:0::1;::::0;72951:191;-1:-1:-1;;;;;72951:191:0:o;74191:68::-:1;74316:25;74344:31;:7:::0;74356:18;74344:11:::1;:31::i;:::-;74316:59:::0;-1:-1:-1;74461:46:0::1;64927:6;74316:59:::0;74461:27:::1;:46::i;:::-;74454:53:::0;73467:1048;-1:-1:-1;;;;;;;73467:1048:0:o;85780:170::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;85861:18:::1;:33:::0;;;85910:32:::1;::::0;85882:12;;85910:32:::1;::::0;;;::::1;85780:170:::0;:::o;46197:328::-;46372:41;18738:10;46405:7;46372:18;:41::i;:::-;46364:103;;;;-1:-1:-1;;;46364:103:0;;;;;;;:::i;:::-;46478:39;46492:4;46498:2;46502:7;46511:5;46478:13;:39::i;76997:3895::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;68172:23;;:43;;-1:-1:-1;68199:16:0;;;;68172:43;68150:118;;;;-1:-1:-1;;;68150:118:0;;;;;;;:::i;:::-;77235:37:::1;77254:5;77261:10;77235:18;:37::i;:::-;77213:109;;;::::0;-1:-1:-1;;;77213:109:0;;22241:2:1;77213:109:0::1;::::0;::::1;22223:21:1::0;22280:2;22260:18;;;22253:30;-1:-1:-1;;;22299:18:1;;;22292:52;22361:18;;77213:109:0::1;22039:346:1::0;77213:109:0::1;77342:10;77353:6;77342:18;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;;::::1;;77341:19;77333:49;;;::::0;-1:-1:-1;;;77333:49:0;;30754:2:1;77333:49:0::1;::::0;::::1;30736:21:1::0;30793:2;30773:18;;;30766:30;-1:-1:-1;;;30812:18:1;;;30805:47;30869:18;;77333:49:0::1;30552:341:1::0;77333:49:0::1;77465:5:::0;77415:46:::1;18738:10:::0;77445:7:::1;77454:6;77415:15;:46::i;:::-;:55;77393:116;;;::::0;-1:-1:-1;;;77393:116:0;;31846:2:1;77393:116:0::1;::::0;::::1;31828:21:1::0;31885:2;31865:18;;;31858:30;-1:-1:-1;;;31904:18:1;;;31897:41;31955:18;;77393:116:0::1;31644:335:1::0;77393:116:0::1;77522:16;77541:8;:17;77550:7;77541:17;;;;;;;;;;;77522:36;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;77569:24;77596:12;:21;77609:7;77596:21;;;;;;;;;;;77569:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;77569:48:0;;;;-1:-1:-1;;;77569:48:0;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;::::1;;;;::::0;;;;;77638:7;;77569:48;;-1:-1:-1;77638:18:0;::::1;77630:43;;;;-1:-1:-1::0;;;77630:43:0::1;;;;;;;:::i;:::-;77739:1;77729:7;:11;77721:46;;;::::0;-1:-1:-1;;;77721:46:0;;33792:2:1;77721:46:0::1;::::0;::::1;33774:21:1::0;33831:2;33811:18;;;33804:30;-1:-1:-1;;;33850:18:1;;;33843:52;33912:18;;77721:46:0::1;33590:346:1::0;77721:46:0::1;77891:1;77853:34;77879:7;77853:21;77866:4;:7;;;77853:12;:21::i;:34::-;:39;;77831:120;;;::::0;-1:-1:-1;;;77831:120:0;;28446:2:1;77831:120:0::1;::::0;::::1;28428:21:1::0;28485:2;28465:18;;;28458:30;28524:33;28504:18;;;28497:61;28575:18;;77831:120:0::1;28244:355:1::0;77831:120:0::1;78010:26;78039:29;18738:10:::0;42506:208;:::i;78039:29::-:1;78010:58;;78153:25;78198:9:::0;78193:292:::1;78217:18;78213:1;:22;78193:292;;;78257:15;78275:42;18738:10:::0;78315:1:::1;78275:25;:42::i;:::-;78257:60;;78332:22;78357:9;:18;78367:7;78357:18;;;;;;;;;;;78332:43;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;78411:4;:7;;;78394:10;:13;;;:24;78390:84;;;78439:19:::0;::::1;::::0;::::1;:::i;:::-;;;;78390:84;78242:243;;78237:3;;;;;:::i;:::-;;;;78193:292;;;-1:-1:-1::0;78497:18:0::1;78547:7:::0;78497:18;18738:10;-1:-1:-1;;;;;78603:23:0::1;:7;19916::::0;19943:6;-1:-1:-1;;;;;19943:6:0;;19870:87;78603:7:::1;-1:-1:-1::0;;;;;78603:23:0::1;;78588:38;;78714:7;78709:1018;;78776:15;78794:20;:18;:20::i;:::-;78776:38;;78886:26;78915:73;65162:6;78926:1;78916:4;:7;;;:11;;;;:::i;78915:73::-;78886:102:::0;-1:-1:-1;79003:24:0::1;79030:79;78886:102:::0;64927:6:::1;79030:22;:79::i;:::-;79003:106;;79237:16;79226:7;:27;79222:257;;79337:28;::::0;::::1;::::0;79304:29:::1;:17:::0;79326:6;79304:21:::1;:29::i;:::-;:61;;79274:189;;;::::0;-1:-1:-1;;;79274:189:0;;25313:2:1;79274:189:0::1;::::0;::::1;25295:21:1::0;25352:2;25332:18;;;25325:30;25391:34;25371:18;;;25364:62;-1:-1:-1;;;25442:18:1;;;25435:52;25504:19;;79274:189:0::1;25111:418:1::0;79274:189:0::1;79608:21;::::0;::::1;::::0;79575:29:::1;:17:::0;79597:6;79575:21:::1;:29::i;:::-;:54;;79549:166;;;::::0;-1:-1:-1;;;79549:166:0;;26852:2:1;79549:166:0::1;::::0;::::1;26834:21:1::0;26891:2;26871:18;;;26864:30;26930:34;26910:18;;;26903:62;-1:-1:-1;;;26981:18:1;;;26974:48;27039:19;;79549:166:0::1;26650:414:1::0;79549:166:0::1;78723:1004;;;78709:1018;79781:33;79807:6;79781:21;79794:4;:7;;;79781:12;:21::i;:33::-;79768:46;;79926:9;79912:10;:23;;79904:66;;;::::0;-1:-1:-1;;;79904:66:0;;20358:2:1;79904:66:0::1;::::0;::::1;20340:21:1::0;20397:2;20377:18;;;20370:30;20436:32;20416:18;;;20409:60;20486:18;;79904:66:0::1;20156:354:1::0;79904:66:0::1;79988:9;79983:585;80007:6;80003:1;:10;79983:585;;;80170:7:::0;;80113:15:::1;80159:19:::0;;;:10:::1;:19;::::0;;;;;;;80131:23;;::::1;::::0;:48:::1;::::0;:27:::1;:48::i;:::-;80113:66:::0;-1:-1:-1;80222:32:0::1;18738:10:::0;80246:7:::1;80222:9;:32::i;:::-;80316:18;::::0;;;:9:::1;:18;::::0;;;;;;;:25;;;;;;::::1;::::0;;;80337:4;;80316:25:::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;;;80412:22:0::1;::::0;;;:13:::1;:22;::::0;;;;;;;80437:15:::1;80412:40:::0;;80541:7;;80530:19;;:10:::1;:19:::0;;;;;;:26:::1;::::0;80554:1:::1;80530:23;:26::i;:::-;80519:7:::0;;80508:19:::1;::::0;;;:10:::1;:19;::::0;;;;:48;-1:-1:-1;80015:3:0;::::1;::::0;::::1;:::i;:::-;;;;79983:585;;;;80601:4;80580:10;80591:6;80580:18;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;:25;;;::::1;;-1:-1:-1::0;;80580:25:0;;::::1;::::0;;;::::1;::::0;;80690:14:::1;::::0;80664:54:::1;::::0;-1:-1:-1;;;;;80690:14:0::1;80707:10:::0;80664:17:::1;:54::i;:::-;80779:10;80767:9;:22;80763:122;;;80806:67;18738:10:::0;80847:25:::1;:9;80861:10:::0;80847:13:::1;:25::i;:::-;80806:17;:67::i;:::-;77202:3690;;;;;;;76997:3895:::0;;;;;:::o;65332:52::-;;;;;;;;;;;;;:::i;86237:232::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;86366:17:::1;86374:8;86366:7;:17::i;:::-;86358:47;;;;-1:-1:-1::0;;;86358:47:0::1;;;;;;;:::i;:::-;86418:23;::::0;;;:13:::1;:23;::::0;;;;;;:43;;::::1;::::0;::::1;::::0;;;;;;;;;::::1;::::0;86237:232::o;86791:2055::-;86910:13;86949:17;86957:8;86949:7;:17::i;:::-;86941:47;;;;-1:-1:-1;;;86941:47:0;;;;;;;:::i;:::-;87001:27;87031:23;;;:13;:23;;;;;:30;87078:23;;87074:1667;;87118:25;87172:23;;;:13;:23;;;;;87196;87218:1;87196:19;:23;:::i;:::-;87172:48;;;;;;;;:::i;:::-;;;;;;;;;;;;88610:11;;;;;;;;;;;-1:-1:-1;;;88610:11:0;;;;88568:54;;87172:48;;-1:-1:-1;88568:54:0;;88585:23;;88568:54;;:::i;:::-;;;;;;;;;;;;;88649:38;88665:17;88684:2;88649:15;:38::i;:::-;88525:185;;;;;;;;;:::i;:::-;;;;;;;;;;;;;88472:257;;;;86791:2055;;;:::o;87074:1667::-;88795:10;:8;:10::i;:::-;88817:19;:8;:17;:19::i;:::-;88778:59;;;;;;;;;:::i;:::-;;;;;;;;;;;;;88751:87;;;86791:2055;;;:::o;84861:503::-;84985:7;19943:6;;-1:-1:-1;;;;;19943:6:0;18738:10;68172:23;;:43;;-1:-1:-1;68199:16:0;;;;68172:43;68150:118;;;;-1:-1:-1;;;68150:118:0;;;;;;;:::i;:::-;85010:16:::1;85029:8;:17;85038:7;85029:17;;;;;;;;;;;85010:36;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;85057:24;85084:12;:21;85097:7;85084:21;;;;;;;;;;;85057:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;85057:48:0;;;;-1:-1:-1;;;85057:48:0;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;::::1;;;;::::0;;;;;85126:7;;85057:48;;-1:-1:-1;85126:18:0;::::1;85118:43;;;;-1:-1:-1::0;;;85118:43:0::1;;;;;;;:::i;:::-;85241:20;::::0;;::::1;::::0;85303:7;;85220:18:::1;85292:19:::0;;;:10:::1;:19;::::0;;;;;;85331:25:::1;85241:20:::0;85292:19;85331:14:::1;:25::i;:::-;85324:32:::0;84861:503;-1:-1:-1;;;;;;84861:503:0:o;66777:40::-;;;;;;;;;;;;;;;;;;;;;;;;:::i;72170:724::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;72294:16:::1;72313:8;:17;72322:7;72313:17;;;;;;;;;;;72294:36;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;72362:7;72351:4;:7;;;:18;72343:43;;;;-1:-1:-1::0;;;72343:43:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;72427:26:0;::::1;72399:25;72427:26:::0;;;:16:::1;:26;::::0;;;;;72501:240:::1;72525:14:::0;;72521:18;::::1;72501:240;;;72579:4;:7;;;72565;72573:1;72565:10;;;;;;;;:::i;:::-;;;;;;;;;:21;72561:169;;;72695:14:::0;;72687:7;;72695:18:::1;::::0;72712:1:::1;::::0;72695:18:::1;:::i;:::-;72687:27;;;;;;;;:::i;:::-;;;;;;;;;72674:7;72682:1;72674:10;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;:40:::0;72561:169:::1;72541:3:::0;::::1;::::0;::::1;:::i;:::-;;;;72501:240;;;;72824:7;:13;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;;-1:-1:-1;;72824:13:0;;;;;;;;;;;;-1:-1:-1;;;;;72850:26:0;::::1;::::0;;:16:::1;:26:::0;;;;;:36;;::::1;::::0;:26;72879:7;;72850:36:::1;:::i;:::-;;72283:611;;72170:724:::0;;:::o;88960:133::-;89004:13;89061:10;:8;:10::i;:::-;89044:40;;;;;;;;:::i;:::-;;;;;;;;;;;;;89030:55;;88960:133;:::o;67107:50::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;20770:192::-;19916:7;19943:6;-1:-1:-1;;;;;19943:6:0;18738:10;20090:23;20082:68;;;;-1:-1:-1;;;20082:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;20859:22:0;::::1;20851:73;;;::::0;-1:-1:-1;;;20851:73:0;;21477:2:1;20851:73:0::1;::::0;::::1;21459:21:1::0;21516:2;21496:18;;;21489:30;21555:34;21535:18;;;21528:62;-1:-1:-1;;;21606:18:1;;;21599:36;21652:19;;20851:73:0::1;21275:402:1::0;20851:73:0::1;20935:19;20945:8;20935:9;:19::i;56071:224::-:0;56173:4;-1:-1:-1;;;;;;56197:50:0;;-1:-1:-1;;;56197:50:0;;:90;;;56251:36;56275:11;56251:23;:36::i;48035:127::-;48100:4;48124:16;;;:7;:16;;;;;;-1:-1:-1;;;;;48124:16:0;:30;;;48035:127::o;52017:174::-;52092:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;52092:29:0;-1:-1:-1;;;;;52092:29:0;;;;;;;;:24;;52146:23;52092:24;52146:14;:23::i;:::-;-1:-1:-1;;;;;52137:46:0;;;;;;;;;;;52017:174;;:::o;48329:348::-;48422:4;48447:16;48455:7;48447;:16::i;:::-;48439:73;;;;-1:-1:-1;;;48439:73:0;;24539:2:1;48439:73:0;;;24521:21:1;24578:2;24558:18;;;24551:30;24617:34;24597:18;;;24590:62;-1:-1:-1;;;24668:18:1;;;24661:42;24720:19;;48439:73:0;24337:408:1;48439:73:0;48523:13;48539:23;48554:7;48539:14;:23::i;:::-;48523:39;;48592:5;-1:-1:-1;;;;;48581:16:0;:7;-1:-1:-1;;;;;48581:16:0;;:51;;;;48625:7;-1:-1:-1;;;;;48601:31:0;:20;48613:7;48601:11;:20::i;:::-;-1:-1:-1;;;;;48601:31:0;;48581:51;:87;;;-1:-1:-1;;;;;;45421:25:0;;;45397:4;45421:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;48636:32;48573:96;48329:348;-1:-1:-1;;;;48329:348:0:o;51321:578::-;51480:4;-1:-1:-1;;;;;51453:31:0;:23;51468:7;51453:14;:23::i;:::-;-1:-1:-1;;;;;51453:31:0;;51445:85;;;;-1:-1:-1;;;51445:85:0;;30344:2:1;51445:85:0;;;30326:21:1;30383:2;30363:18;;;30356:30;30422:34;30402:18;;;30395:62;-1:-1:-1;;;30473:18:1;;;30466:39;30522:19;;51445:85:0;30142:405:1;51445:85:0;-1:-1:-1;;;;;51549:16:0;;51541:65;;;;-1:-1:-1;;;51541:65:0;;22592:2:1;51541:65:0;;;22574:21:1;22631:2;22611:18;;;22604:30;22670:34;22650:18;;;22643:62;-1:-1:-1;;;22721:18:1;;;22714:34;22765:19;;51541:65:0;22390:400:1;51541:65:0;51619:39;51640:4;51646:2;51650:7;51619:20;:39::i;:::-;51723:29;51740:1;51744:7;51723:8;:29::i;:::-;-1:-1:-1;;;;;51765:15:0;;;;;;:9;:15;;;;;:20;;51784:1;;51765:15;:20;;51784:1;;51765:20;:::i;:::-;;;;-1:-1:-1;;;;;;;51796:13:0;;;;;;:9;:13;;;;;:18;;51813:1;;51796:13;:18;;51813:1;;51796:18;:::i;:::-;;;;-1:-1:-1;;51825:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;51825:21:0;-1:-1:-1;;;;;51825:21:0;;;;;;;;;51864:27;;51825:16;;51864:27;;;;;;;51321:578;;;:::o;12536:98::-;12594:7;12621:5;12625:1;12621;:5;:::i;:::-;12614:12;12536:98;-1:-1:-1;;;12536:98:0:o;12935:::-;12993:7;13020:5;13024:1;13020;:5;:::i;23283:120::-;22295:7;;;;22819:41;;;;-1:-1:-1;;;22819:41:0;;19237:2:1;22819:41:0;;;19219:21:1;19276:2;19256:18;;;19249:30;-1:-1:-1;;;19295:18:1;;;19288:50;19355:18;;22819:41:0;19035:344:1;22819:41:0;23342:7:::1;:15:::0;;-1:-1:-1;;23342:15:0::1;::::0;;23373:22:::1;18738:10:::0;23382:12:::1;23373:22;::::0;-1:-1:-1;;;;;12371:32:1;;;12353:51;;12341:2;12326:18;23373:22:0::1;;;;;;;23283:120::o:0;50624:360::-;50684:13;50700:23;50715:7;50700:14;:23::i;:::-;50684:39;;50736:48;50757:5;50772:1;50776:7;50736:20;:48::i;:::-;50825:29;50842:1;50846:7;50825:8;:29::i;:::-;-1:-1:-1;;;;;50867:16:0;;;;;;:9;:16;;;;;:21;;50887:1;;50867:16;:21;;50887:1;;50867:21;:::i;:::-;;;;-1:-1:-1;;50906:16:0;;;;:7;:16;;;;;;50899:23;;-1:-1:-1;;;;;;50899:23:0;;;50940:36;50914:7;;50906:16;-1:-1:-1;;;;;50940:36:0;;;;;50906:16;;50940:36;50673:311;50624:360;:::o;11798:98::-;11856:7;11883:5;11887:1;11883;:5;:::i;12179:98::-;12237:7;12264:5;12268:1;12264;:5;:::i;20970:173::-;21026:16;21045:6;;-1:-1:-1;;;;;21062:17:0;;;-1:-1:-1;;;;;;21062:17:0;;;;;;21095:40;;21045:6;;;;;;;21095:40;;21026:16;21095:40;21015:128;20970:173;:::o;23024:118::-;22295:7;;;;22549:9;22541:38;;;;-1:-1:-1;;;22541:38:0;;25736:2:1;22541:38:0;;;25718:21:1;25775:2;25755:18;;;25748:30;-1:-1:-1;;;25794:18:1;;;25787:46;25850:18;;22541:38:0;25534:340:1;22541:38:0;23084:7:::1;:14:::0;;-1:-1:-1;;23084:14:0::1;23094:4;23084:14;::::0;;23114:20:::1;23121:12;18738:10:::0;;18658:98;47407:315;47564:28;47574:4;47580:2;47584:7;47564:9;:28::i;:::-;47611:48;47634:4;47640:2;47644:7;47653:5;47611:22;:48::i;:::-;47603:111;;;;-1:-1:-1;;;47603:111:0;;;;;;;:::i;90176:196::-;90293:4;90339:25;:5;90353:10;90339:13;:25::i;:::-;90322:13;;-1:-1:-1;;;;;90322:42:0;;;:13;;:42;;90176:196;-1:-1:-1;;;90176:196:0:o;89744:395::-;89881:7;89901:12;90055:7;90064;90073:6;90038:42;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;90038:42:0;;;;;;;;;;90028:53;;90038:42;90028:53;;;;11854:66:1;89940:156:0;;;11842:79:1;;;;11937:12;;;11930:28;11974:12;;89940:156:0;;;;;;-1:-1:-1;;89940:156:0;;;;;;89916:191;;89940:156;89916:191;;;;;89744:395;-1:-1:-1;;;;;89744:395:0:o;49019:110::-;49095:26;49105:2;49109:7;49095:26;;;;;;;;;;;;:9;:26::i;25498:317::-;25613:6;25588:21;:31;;25580:73;;;;-1:-1:-1;;;25580:73:0;;24181:2:1;25580:73:0;;;24163:21:1;24220:2;24200:18;;;24193:30;24259:31;24239:18;;;24232:59;24308:18;;25580:73:0;23979:353:1;25580:73:0;25667:12;25685:9;-1:-1:-1;;;;;25685:14:0;25707:6;25685:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25666:52;;;25737:7;25729:78;;;;-1:-1:-1;;;25729:78:0;;23351:2:1;25729:78:0;;;23333:21:1;23390:2;23370:18;;;23363:30;23429:34;23409:18;;;23402:62;23500:28;23480:18;;;23473:56;23546:19;;25729:78:0;23149:422:1;90981:433:0;91087:13;91118:19;91150:10;91154:6;91150:1;:10;:::i;:::-;91140:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;91140:21:0;-1:-1:-1;91118:43:0;-1:-1:-1;91179:9:0;91191:10;91195:6;91191:1;:10;:::i;:::-;91179:22;;91174:135;91203:5;;91174:135;;-1:-1:-1;;;91259:5:0;91267:3;91259:11;91246:25;;;;;;;:::i;:::-;;;;91230:6;91237:5;91241:1;91237;:5;:::i;:::-;91230:13;;;;;;;;:::i;:::-;;;;:41;-1:-1:-1;;;;;91230:41:0;;;;;;;;-1:-1:-1;91296:1:0;91286:11;;;;;91210:3;;;:::i;:::-;;;91174:135;;;-1:-1:-1;91327:10:0;;91319:55;;;;-1:-1:-1;;;91319:55:0;;18464:2:1;91319:55:0;;;18446:21:1;;;18483:18;;;18476:30;18542:34;18522:18;;;18515:62;18594:18;;91319:55:0;18262:356:1;90437:105:0;90489:13;90522:12;90515:19;;;;;:::i;16274:723::-;16330:13;16551:10;16547:53;;-1:-1:-1;;16578:10:0;;;;;;;;;;;;-1:-1:-1;;;16578:10:0;;;;;16274:723::o;16547:53::-;16625:5;16610:12;16666:78;16673:9;;16666:78;;16699:8;;;;:::i;:::-;;-1:-1:-1;16722:10:0;;-1:-1:-1;16730:2:0;16722:10;;:::i;:::-;;;16666:78;;;16754:19;16786:6;16776:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;16776:17:0;;16754:39;;16804:154;16811:10;;16804:154;;16838:11;16848:1;16838:11;;:::i;:::-;;-1:-1:-1;16907:10:0;16915:2;16907:5;:10;:::i;:::-;16894:24;;:2;:24;:::i;:::-;16881:39;;16864:6;16871;16864:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;16864:56:0;;;;;;;;-1:-1:-1;16935:11:0;16944:2;16935:11;;:::i;:::-;;;16804:154;;42137:305;42239:4;-1:-1:-1;;;;;;42276:40:0;;-1:-1:-1;;;42276:40:0;;:105;;-1:-1:-1;;;;;;;42333:48:0;;-1:-1:-1;;;42333:48:0;42276:105;:158;;;-1:-1:-1;;;;;;;;;;34225:40:0;;;42398:36;34116:157;90584:362;90827:32;;;;:22;:32;;;;;90862:15;90827:50;;90890:48;90917:5;90924:3;90850:8;90890:26;:48::i;52756:799::-;52911:4;-1:-1:-1;;;;;52932:13:0;;24499:20;24547:8;52928:620;;52968:72;;-1:-1:-1;;;52968:72:0;;-1:-1:-1;;;;;52968:36:0;;;;;:72;;18738:10;;53019:4;;53025:7;;53034:5;;52968:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52968:72:0;;;;;;;;-1:-1:-1;;52968:72:0;;;;;;;;;;;;:::i;:::-;;;52964:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53210:13:0;;53206:272;;53253:60;;-1:-1:-1;;;53253:60:0;;;;;;;:::i;53206:272::-;53428:6;53422:13;53413:6;53409:2;53405:15;53398:38;52964:529;-1:-1:-1;;;;;;53091:51:0;-1:-1:-1;;;53091:51:0;;-1:-1:-1;53084:58:0;;52928:620;-1:-1:-1;53532:4:0;52756:799;;;;;;:::o;4335:231::-;4413:7;4434:17;4453:18;4475:27;4486:4;4492:9;4475:10;:27::i;:::-;4433:69;;;;4513:18;4525:5;4513:11;:18::i;:::-;-1:-1:-1;4549:9:0;4335:231;-1:-1:-1;;;4335:231:0:o;49356:321::-;49486:18;49492:2;49496:7;49486:5;:18::i;:::-;49537:54;49568:1;49572:2;49576:7;49585:5;49537:22;:54::i;:::-;49515:154;;;;-1:-1:-1;;;49515:154:0;;;;;;;:::i;54859:275::-;55003:45;55030:4;55036:2;55040:7;55003:26;:45::i;:::-;22295:7;;;;55069:9;55061:65;;;;-1:-1:-1;;;55061:65:0;;18825:2:1;55061:65:0;;;18807:21:1;18864:2;18844:18;;;18837:30;18903:34;18883:18;;;18876:62;-1:-1:-1;;;18954:18:1;;;18947:41;19005:19;;55061:65:0;18623:407:1;2225:1308:0;2306:7;2315:12;2540:9;:16;2560:2;2540:22;2536:990;;;2836:4;2821:20;;2815:27;2886:4;2871:20;;2865:27;2944:4;2929:20;;2923:27;2579:9;2915:36;2987:25;2998:4;2915:36;2815:27;2865;2987:10;:25::i;:::-;2980:32;;;;;;;;;2536:990;3034:9;:16;3054:2;3034:22;3030:496;;;3309:4;3294:20;;3288:27;3360:4;3345:20;;3339:27;3402:23;3413:4;3288:27;3339;3402:10;:23::i;:::-;3395:30;;;;;;;;3030:496;-1:-1:-1;3474:1:0;;-1:-1:-1;3478:35:0;3458:56;;496:643;574:20;565:5;:29;;;;;;;;:::i;:::-;;561:571;;;496:643;:::o;561:571::-;672:29;663:5;:38;;;;;;;;:::i;:::-;;659:473;;;718:34;;-1:-1:-1;;;718:34:0;;18111:2:1;718:34:0;;;18093:21:1;18150:2;18130:18;;;18123:30;18189:26;18169:18;;;18162:54;18233:18;;718:34:0;17909:348:1;659:473:0;783:35;774:5;:44;;;;;;;;:::i;:::-;;770:362;;;835:41;;-1:-1:-1;;;835:41:0;;19586:2:1;835:41:0;;;19568:21:1;19625:2;19605:18;;;19598:30;19664:33;19644:18;;;19637:61;19715:18;;835:41:0;19384:355:1;770:362:0;907:30;898:5;:39;;;;;;;;:::i;:::-;;894:238;;;954:44;;-1:-1:-1;;;954:44:0;;23778:2:1;954:44:0;;;23760:21:1;23817:2;23797:18;;;23790:30;23856:34;23836:18;;;23829:62;-1:-1:-1;;;23907:18:1;;;23900:32;23949:19;;954:44:0;23576:398:1;894:238:0;1029:30;1020:5;:39;;;;;;;;:::i;:::-;;1016:116;;;1076:44;;-1:-1:-1;;;1076:44:0;;28806:2:1;1076:44:0;;;28788:21:1;28845:2;28825:18;;;28818:30;28884:34;28864:18;;;28857:62;-1:-1:-1;;;28935:18:1;;;28928:32;28977:19;;1076:44:0;28604:398:1;50013:382:0;-1:-1:-1;;;;;50093:16:0;;50085:61;;;;-1:-1:-1;;;50085:61:0;;29209:2:1;50085:61:0;;;29191:21:1;;;29228:18;;;29221:30;29287:34;29267:18;;;29260:62;29339:18;;50085:61:0;29007:356:1;50085:61:0;50166:16;50174:7;50166;:16::i;:::-;50165:17;50157:58;;;;-1:-1:-1;;;50157:58:0;;21884:2:1;50157:58:0;;;21866:21:1;21923:2;21903:18;;;21896:30;21962;21942:18;;;21935:58;22010:18;;50157:58:0;21682:352:1;50157:58:0;50228:45;50257:1;50261:2;50265:7;50228:20;:45::i;:::-;-1:-1:-1;;;;;50286:13:0;;;;;;:9;:13;;;;;:18;;50303:1;;50286:13;:18;;50303:1;;50286:18;:::i;:::-;;;;-1:-1:-1;;50315:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;50315:21:0;-1:-1:-1;;;;;50315:21:0;;;;;;;;50354:33;;50315:16;;;50354:33;;50315:16;;50354:33;50013:382;;:::o;57747:589::-;-1:-1:-1;;;;;57953:18:0;;57949:187;;57988:40;58020:7;59163:10;:17;;59136:24;;;;:15;:24;;;;;:44;;;59191:24;;;;;;;;;;;;59059:164;57988:40;57949:187;;;58058:2;-1:-1:-1;;;;;58050:10:0;:4;-1:-1:-1;;;;;58050:10:0;;58046:90;;58077:47;58110:4;58116:7;58077:32;:47::i;:::-;-1:-1:-1;;;;;58150:16:0;;58146:183;;58183:45;58220:7;58183:36;:45::i;58146:183::-;58256:4;-1:-1:-1;;;;;58250:10:0;:2;-1:-1:-1;;;;;58250:10:0;;58246:83;;58277:40;58305:2;58309:7;58277:27;:40::i;5834:1632::-;5965:7;;6899:66;6886:79;;6882:163;;;-1:-1:-1;6998:1:0;;-1:-1:-1;7002:30:0;6982:51;;6882:163;7059:1;:7;;7064:2;7059:7;;:18;;;;;7070:1;:7;;7075:2;7070:7;;7059:18;7055:102;;;-1:-1:-1;7110:1:0;;-1:-1:-1;7114:30:0;7094:51;;7055:102;7271:24;;;7254:14;7271:24;;;;;;;;;17498:25:1;;;17571:4;17559:17;;17539:18;;;17532:45;;;;17593:18;;;17586:34;;;17636:18;;;17629:34;;;7271:24:0;;17470:19:1;;7271:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7271:24:0;;-1:-1:-1;;7271:24:0;;;-1:-1:-1;;;;;;;7310:20:0;;7306:103;;7363:1;7367:29;7347:50;;;;;;;7306:103;7429:6;-1:-1:-1;7437:20:0;;-1:-1:-1;5834:1632:0;;;;;;;;:::o;4829:391::-;4943:7;;-1:-1:-1;;;;;5044:75:0;;5146:3;5142:12;;;5156:2;5138:21;5187:25;5198:4;5138:21;5207:1;5044:75;5187:10;:25::i;:::-;5180:32;;;;;;4829:391;;;;;;:::o;59850:988::-;60116:22;60166:1;60141:22;60158:4;60141:16;:22::i;:::-;:26;;;;:::i;:::-;60178:18;60199:26;;;:17;:26;;;;;;60116:51;;-1:-1:-1;60332:28:0;;;60328:328;;-1:-1:-1;;;;;60399:18:0;;60377:19;60399:18;;;:12;:18;;;;;;;;:34;;;;;;;;;60450:30;;;;;;:44;;;60567:30;;:17;:30;;;;;:43;;;60328:328;-1:-1:-1;60752:26:0;;;;:17;:26;;;;;;;;60745:33;;;-1:-1:-1;;;;;60796:18:0;;;;;:12;:18;;;;;:34;;;;;;;60789:41;59850:988::o;61133:1079::-;61411:10;:17;61386:22;;61411:21;;61431:1;;61411:21;:::i;:::-;61443:18;61464:24;;;:15;:24;;;;;;61837:10;:26;;61386:46;;-1:-1:-1;61464:24:0;;61386:46;;61837:26;;;;;;:::i;:::-;;;;;;;;;61815:48;;61901:11;61876:10;61887;61876:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;61981:28;;;:15;:28;;;;;;;:41;;;62153:24;;;;;62146:31;62188:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;61204:1008;;;61133:1079;:::o;58637:221::-;58722:14;58739:20;58756:2;58739:16;:20::i;:::-;-1:-1:-1;;;;;58770:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;58815:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;58637:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:173:1;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;192:160;257:20;;313:13;;306:21;296:32;;286:60;;342:1;339;332:12;357:530;399:5;452:3;445:4;437:6;433:17;429:27;419:55;;470:1;467;460:12;419:55;506:6;493:20;532:18;528:2;525:26;522:52;;;554:18;;:::i;:::-;598:55;641:2;622:13;;-1:-1:-1;;618:27:1;647:4;614:38;598:55;:::i;:::-;678:2;669:7;662:19;724:3;717:4;712:2;704:6;700:15;696:26;693:35;690:55;;;741:1;738;731:12;690:55;806:2;799:4;791:6;787:17;780:4;771:7;767:18;754:55;854:1;829:16;;;847:4;825:27;818:38;;;;833:7;357:530;-1:-1:-1;;;357:530:1:o;892:186::-;951:6;1004:2;992:9;983:7;979:23;975:32;972:52;;;1020:1;1017;1010:12;972:52;1043:29;1062:9;1043:29;:::i;1083:260::-;1151:6;1159;1212:2;1200:9;1191:7;1187:23;1183:32;1180:52;;;1228:1;1225;1218:12;1180:52;1251:29;1270:9;1251:29;:::i;:::-;1241:39;;1299:38;1333:2;1322:9;1318:18;1299:38;:::i;:::-;1289:48;;1083:260;;;;;:::o;1348:328::-;1425:6;1433;1441;1494:2;1482:9;1473:7;1469:23;1465:32;1462:52;;;1510:1;1507;1500:12;1462:52;1533:29;1552:9;1533:29;:::i;:::-;1523:39;;1581:38;1615:2;1604:9;1600:18;1581:38;:::i;:::-;1571:48;;1666:2;1655:9;1651:18;1638:32;1628:42;;1348:328;;;;;:::o;1681:537::-;1776:6;1784;1792;1800;1853:3;1841:9;1832:7;1828:23;1824:33;1821:53;;;1870:1;1867;1860:12;1821:53;1893:29;1912:9;1893:29;:::i;:::-;1883:39;;1941:38;1975:2;1964:9;1960:18;1941:38;:::i;:::-;1931:48;;2026:2;2015:9;2011:18;1998:32;1988:42;;2081:2;2070:9;2066:18;2053:32;2108:18;2100:6;2097:30;2094:50;;;2140:1;2137;2130:12;2094:50;2163:49;2204:7;2195:6;2184:9;2180:22;2163:49;:::i;:::-;2153:59;;;1681:537;;;;;;;:::o;2223:254::-;2288:6;2296;2349:2;2337:9;2328:7;2324:23;2320:32;2317:52;;;2365:1;2362;2355:12;2317:52;2388:29;2407:9;2388:29;:::i;:::-;2378:39;;2436:35;2467:2;2456:9;2452:18;2436:35;:::i;2482:254::-;2550:6;2558;2611:2;2599:9;2590:7;2586:23;2582:32;2579:52;;;2627:1;2624;2617:12;2579:52;2650:29;2669:9;2650:29;:::i;:::-;2640:39;2726:2;2711:18;;;;2698:32;;-1:-1:-1;;;2482:254:1:o;2741:902::-;2825:6;2856:2;2899;2887:9;2878:7;2874:23;2870:32;2867:52;;;2915:1;2912;2905:12;2867:52;2955:9;2942:23;2988:18;2980:6;2977:30;2974:50;;;3020:1;3017;3010:12;2974:50;3043:22;;3096:4;3088:13;;3084:27;-1:-1:-1;3074:55:1;;3125:1;3122;3115:12;3074:55;3161:2;3148:16;3184:60;3200:43;3240:2;3200:43;:::i;:::-;3184:60;:::i;:::-;3266:3;3290:2;3285:3;3278:15;3318:2;3313:3;3309:12;3302:19;;3349:2;3345;3341:11;3397:7;3392:2;3386;3383:1;3379:10;3375:2;3371:19;3367:28;3364:41;3361:61;;;3418:1;3415;3408:12;3361:61;3440:1;3431:10;;3450:163;3464:2;3461:1;3458:9;3450:163;;;3521:17;;3509:30;;3482:1;3475:9;;;;;3559:12;;;;3591;;3450:163;;;-1:-1:-1;3632:5:1;2741:902;-1:-1:-1;;;;;;;2741:902:1:o;3648:245::-;3706:6;3759:2;3747:9;3738:7;3734:23;3730:32;3727:52;;;3775:1;3772;3765:12;3727:52;3814:9;3801:23;3833:30;3857:5;3833:30;:::i;3898:249::-;3967:6;4020:2;4008:9;3999:7;3995:23;3991:32;3988:52;;;4036:1;4033;4026:12;3988:52;4068:9;4062:16;4087:30;4111:5;4087:30;:::i;4152:321::-;4221:6;4274:2;4262:9;4253:7;4249:23;4245:32;4242:52;;;4290:1;4287;4280:12;4242:52;4330:9;4317:23;4363:18;4355:6;4352:30;4349:50;;;4395:1;4392;4385:12;4349:50;4418:49;4459:7;4450:6;4439:9;4435:22;4418:49;:::i;4478:180::-;4537:6;4590:2;4578:9;4569:7;4565:23;4561:32;4558:52;;;4606:1;4603;4596:12;4558:52;-1:-1:-1;4629:23:1;;4478:180;-1:-1:-1;4478:180:1:o;4663:254::-;4731:6;4739;4792:2;4780:9;4771:7;4767:23;4763:32;4760:52;;;4808:1;4805;4798:12;4760:52;4844:9;4831:23;4821:33;;4873:38;4907:2;4896:9;4892:18;4873:38;:::i;4922:976::-;5015:6;5023;5076:2;5064:9;5055:7;5051:23;5047:32;5044:52;;;5092:1;5089;5082:12;5044:52;5128:9;5115:23;5105:33;;5157:2;5210;5199:9;5195:18;5182:32;5237:18;5229:6;5226:30;5223:50;;;5269:1;5266;5259:12;5223:50;5292:22;;5345:4;5337:13;;5333:27;-1:-1:-1;5323:55:1;;5374:1;5371;5364:12;5323:55;5410:2;5397:16;5433:60;5449:43;5489:2;5449:43;:::i;5433:60::-;5515:3;5539:2;5534:3;5527:15;5567:2;5562:3;5558:12;5551:19;;5598:2;5594;5590:11;5646:7;5641:2;5635;5632:1;5628:10;5624:2;5620:19;5616:28;5613:41;5610:61;;;5667:1;5664;5657:12;5610:61;5689:1;5680:10;;5699:169;5713:2;5710:1;5707:9;5699:169;;;5770:23;5789:3;5770:23;:::i;:::-;5758:36;;5731:1;5724:9;;;;;5814:12;;;;5846;;5699:169;;;5703:3;5887:5;5877:15;;;;;;;4922:976;;;;;:::o;5903:248::-;5968:6;5976;6029:2;6017:9;6008:7;6004:23;6000:32;5997:52;;;6045:1;6042;6035:12;5997:52;6081:9;6068:23;6058:33;;6110:35;6141:2;6130:9;6126:18;6110:35;:::i;6156:248::-;6224:6;6232;6285:2;6273:9;6264:7;6260:23;6256:32;6253:52;;;6301:1;6298;6291:12;6253:52;-1:-1:-1;;6324:23:1;;;6394:2;6379:18;;;6366:32;;-1:-1:-1;6156:248:1:o;6662:746::-;6776:6;6784;6792;6800;6808;6861:3;6849:9;6840:7;6836:23;6832:33;6829:53;;;6878:1;6875;6868:12;6829:53;6914:9;6901:23;6891:33;;6971:2;6960:9;6956:18;6943:32;6933:42;;7022:2;7011:9;7007:18;6994:32;6984:42;;7077:2;7066:9;7062:18;7049:32;7100:18;7141:2;7133:6;7130:14;7127:34;;;7157:1;7154;7147:12;7127:34;7180:49;7221:7;7212:6;7201:9;7197:22;7180:49;:::i;:::-;7170:59;;7282:3;7271:9;7267:19;7254:33;7238:49;;7312:2;7302:8;7299:16;7296:36;;;7328:1;7325;7318:12;7296:36;;7351:51;7394:7;7383:8;7372:9;7368:24;7351:51;:::i;:::-;7341:61;;;6662:746;;;;;;;;:::o;7413:268::-;7465:3;7503:5;7497:12;7530:6;7525:3;7518:19;7546:63;7602:6;7595:4;7590:3;7586:14;7579:4;7572:5;7568:16;7546:63;:::i;:::-;7663:2;7642:15;-1:-1:-1;;7638:29:1;7629:39;;;;7670:4;7625:50;;7413:268;-1:-1:-1;;7413:268:1:o;7686:184::-;7727:3;7765:5;7759:12;7780:52;7825:6;7820:3;7813:4;7806:5;7802:16;7780:52;:::i;:::-;7848:16;;;;;7686:184;-1:-1:-1;;7686:184:1:o;7875:258::-;7958:5;7952:12;7947:3;7940:25;7922:3;8011:4;8004:5;8000:16;7994:23;8049:4;8042;8037:3;8033:14;8026:28;8070:57;8121:4;8116:3;8112:14;8098:12;8070:57;:::i;8138:462::-;8380:26;8376:31;8367:6;8363:2;8359:15;8355:53;8350:3;8343:66;8439:6;8434:2;8429:3;8425:12;8418:28;8325:3;8475:6;8469:13;8491:62;8546:6;8541:2;8536:3;8532:12;8525:4;8517:6;8513:17;8491:62;:::i;:::-;8573:16;;;;8591:2;8569:25;;8138:462;-1:-1:-1;;;;8138:462:1:o;8605:468::-;8782:3;8820:6;8814:13;8836:53;8882:6;8877:3;8870:4;8862:6;8858:17;8836:53;:::i;:::-;8952:13;;8911:16;;;;8974:57;8952:13;8911:16;9008:4;8996:17;;8974:57;:::i;:::-;9047:20;;8605:468;-1:-1:-1;;;;8605:468:1:o;9078:276::-;9209:3;9247:6;9241:13;9263:53;9309:6;9304:3;9297:4;9289:6;9285:17;9263:53;:::i;:::-;9332:16;;;;;9078:276;-1:-1:-1;;9078:276:1:o;9359:619::-;9639:3;9677:6;9671:13;9693:53;9739:6;9734:3;9727:4;9719:6;9715:17;9693:53;:::i;:::-;-1:-1:-1;;;9768:16:1;;;9793:23;;;9841:13;;9863:65;9841:13;9915:1;9904:13;;9897:4;9885:17;;9863:65;:::i;:::-;9948:20;9970:1;9944:28;;9359:619;-1:-1:-1;;;;9359:619:1:o;9983:446::-;10215:3;10253:6;10247:13;10269:53;10315:6;10310:3;10303:4;10295:6;10291:17;10269:53;:::i;:::-;-1:-1:-1;;;10344:16:1;;10369:25;;;-1:-1:-1;10421:1:1;10410:13;;9983:446;-1:-1:-1;9983:446:1:o;10434:1173::-;10610:3;10639:1;10672:6;10666:13;10702:3;10724:1;10752:9;10748:2;10744:18;10734:28;;10812:2;10801:9;10797:18;10834;10824:61;;10878:4;10870:6;10866:17;10856:27;;10824:61;10904:2;10952;10944:6;10941:14;10921:18;10918:38;10915:165;;;-1:-1:-1;;;10979:33:1;;11035:4;11032:1;11025:15;11065:4;10986:3;11053:17;10915:165;11096:18;11123:104;;;;11241:1;11236:320;;;;11089:467;;11123:104;-1:-1:-1;;11156:24:1;;11144:37;;11201:16;;;;-1:-1:-1;11123:104:1;;11236:320;34970:1;34963:14;;;35007:4;34994:18;;11331:1;11345:165;11359:6;11356:1;11353:13;11345:165;;;11437:14;;11424:11;;;11417:35;11480:16;;;;11374:10;;11345:165;;;11349:3;;11539:6;11534:3;11530:16;11523:23;;11089:467;;;;;;;11572:29;11597:3;11589:6;11572:29;:::i;:::-;11565:36;10434:1173;-1:-1:-1;;;;;10434:1173:1:o;12415:499::-;-1:-1:-1;;;;;12684:15:1;;;12666:34;;12736:15;;12731:2;12716:18;;12709:43;12783:2;12768:18;;12761:34;;;12831:3;12826:2;12811:18;;12804:31;;;12609:4;;12852:56;;12888:19;;12880:6;12852:56;:::i;13198:632::-;13369:2;13421:21;;;13491:13;;13394:18;;;13513:22;;;13340:4;;13369:2;13592:15;;;;13566:2;13551:18;;;13340:4;13635:169;13649:6;13646:1;13643:13;13635:169;;;13710:13;;13698:26;;13779:15;;;;13744:12;;;;13671:1;13664:9;13635:169;;;-1:-1:-1;13821:3:1;;13198:632;-1:-1:-1;;;;;;13198:632:1:o;13835:1583::-;14029:4;14058:2;14098;14087:9;14083:18;14128:2;14117:9;14110:21;14151:6;14186;14180:13;14217:6;14209;14202:22;14243:2;14233:12;;14276:2;14265:9;14261:18;14254:25;;14338:2;14328:6;14325:1;14321:14;14310:9;14306:30;14302:39;14376:2;14368:6;14364:15;14397:1;14407:982;14421:6;14418:1;14415:13;14407:982;;;14514:2;14510:7;14498:9;14490:6;14486:22;14482:36;14477:3;14470:49;14548:6;14542:13;14578:6;14623:2;14617:9;14654:2;14646:6;14639:18;14684:53;14733:2;14725:6;14721:15;14707:12;14684:53;:::i;:::-;14780:11;;;14774:18;14757:15;;;14750:43;14836:11;;;14830:18;14813:15;;;14806:43;14872:4;14919:11;;;14913:18;14896:15;;;14889:43;14955:4;15002:11;;;14996:18;14979:15;;;14972:43;15038:4;15085:11;;;15079:18;15062:15;;;15055:43;15121:4;15168:11;;;15162:18;15145:15;;;15138:43;15204:4;15265:11;;;15259:18;15252:26;15245:34;15228:15;;;;15221:59;;;;-1:-1:-1;;15367:12:1;;;;15332:15;;;;14443:1;14436:9;14407:982;;;-1:-1:-1;15406:6:1;;13835:1583;-1:-1:-1;;;;;;;;13835:1583:1:o;15423:832::-;15609:4;15638:2;15678;15667:9;15663:18;15708:2;15697:9;15690:21;15731:6;15766;15760:13;15797:6;15789;15782:22;15835:2;15824:9;15820:18;15813:25;;15897:2;15887:6;15884:1;15880:14;15869:9;15865:30;15861:39;15847:53;;15935:2;15927:6;15923:15;15956:1;15966:260;15980:6;15977:1;15974:13;15966:260;;;16073:2;16069:7;16057:9;16049:6;16045:22;16041:36;16036:3;16029:49;16101:45;16139:6;16130;16124:13;16101:45;:::i;:::-;16091:55;-1:-1:-1;16204:12:1;;;;16169:15;;;;16002:1;15995:9;15966:260;;;-1:-1:-1;16243:6:1;;15423:832;-1:-1:-1;;;;;;;15423:832:1:o;17674:230::-;17823:2;17812:9;17805:21;17786:4;17843:55;17894:2;17883:9;17879:18;17871:6;17843:55;:::i;20515:414::-;20717:2;20699:21;;;20756:2;20736:18;;;20729:30;20795:34;20790:2;20775:18;;20768:62;-1:-1:-1;;;20861:2:1;20846:18;;20839:48;20919:3;20904:19;;20515:414::o;20934:336::-;21136:2;21118:21;;;21175:2;21155:18;;;21148:30;-1:-1:-1;;;21209:2:1;21194:18;;21187:42;21261:2;21246:18;;20934:336::o;26304:341::-;26506:2;26488:21;;;26545:2;26525:18;;;26518:30;-1:-1:-1;;;26579:2:1;26564:18;;26557:47;26636:2;26621:18;;26304:341::o;27890:349::-;28092:2;28074:21;;;28131:2;28111:18;;;28104:30;28170:27;28165:2;28150:18;;28143:55;28230:2;28215:18;;27890:349::o;29781:356::-;29983:2;29965:21;;;30002:18;;;29995:30;30061:34;30056:2;30041:18;;30034:62;30128:2;30113:18;;29781:356::o;30898:339::-;31100:2;31082:21;;;31139:2;31119:18;;;31112:30;-1:-1:-1;;;31173:2:1;31158:18;;31151:45;31228:2;31213:18;;30898:339::o;31984:413::-;32186:2;32168:21;;;32225:2;32205:18;;;32198:30;32264:34;32259:2;32244:18;;32237:62;-1:-1:-1;;;32330:2:1;32315:18;;32308:47;32387:3;32372:19;;31984:413::o;34123:301::-;34300:6;34289:9;34282:25;34343:2;34338;34327:9;34323:18;34316:30;34263:4;34363:55;34414:2;34403:9;34399:18;34391:6;34363:55;:::i;34429:275::-;34500:2;34494:9;34565:2;34546:13;;-1:-1:-1;;34542:27:1;34530:40;;34600:18;34585:34;;34621:22;;;34582:62;34579:88;;;34647:18;;:::i;:::-;34683:2;34676:22;34429:275;;-1:-1:-1;34429:275:1:o;34709:183::-;34769:4;34802:18;34794:6;34791:30;34788:56;;;34824:18;;:::i;:::-;-1:-1:-1;34869:1:1;34865:14;34881:4;34861:25;;34709:183::o;35023:128::-;35063:3;35094:1;35090:6;35087:1;35084:13;35081:39;;;35100:18;;:::i;:::-;-1:-1:-1;35136:9:1;;35023:128::o;35156:120::-;35196:1;35222;35212:35;;35227:18;;:::i;:::-;-1:-1:-1;35261:9:1;;35156:120::o;35281:168::-;35321:7;35387:1;35383;35379:6;35375:14;35372:1;35369:21;35364:1;35357:9;35350:17;35346:45;35343:71;;;35394:18;;:::i;:::-;-1:-1:-1;35434:9:1;;35281:168::o;35454:125::-;35494:4;35522:1;35519;35516:8;35513:34;;;35527:18;;:::i;:::-;-1:-1:-1;35564:9:1;;35454:125::o;35584:258::-;35656:1;35666:113;35680:6;35677:1;35674:13;35666:113;;;35756:11;;;35750:18;35737:11;;;35730:39;35702:2;35695:10;35666:113;;;35797:6;35794:1;35791:13;35788:48;;;-1:-1:-1;;35832:1:1;35814:16;;35807:27;35584:258::o;35847:136::-;35886:3;35914:5;35904:39;;35923:18;;:::i;:::-;-1:-1:-1;;;35959:18:1;;35847:136::o;35988:380::-;36067:1;36063:12;;;;36110;;;36131:61;;36185:4;36177:6;36173:17;36163:27;;36131:61;36238:2;36230:6;36227:14;36207:18;36204:38;36201:161;;;36284:10;36279:3;36275:20;36272:1;36265:31;36319:4;36316:1;36309:15;36347:4;36344:1;36337:15;36201:161;;35988:380;;;:::o;36373:135::-;36412:3;-1:-1:-1;;36433:17:1;;36430:43;;;36453:18;;:::i;:::-;-1:-1:-1;36500:1:1;36489:13;;36373:135::o;36513:112::-;36545:1;36571;36561:35;;36576:18;;:::i;:::-;-1:-1:-1;36610:9:1;;36513:112::o;36630:127::-;36691:10;36686:3;36682:20;36679:1;36672:31;36722:4;36719:1;36712:15;36746:4;36743:1;36736:15;36762:127;36823:10;36818:3;36814:20;36811:1;36804:31;36854:4;36851:1;36844:15;36878:4;36875:1;36868:15;36894:127;36955:10;36950:3;36946:20;36943:1;36936:31;36986:4;36983:1;36976:15;37010:4;37007:1;37000:15;37026:127;37087:10;37082:3;37078:20;37075:1;37068:31;37118:4;37115:1;37108:15;37142:4;37139:1;37132:15;37158:127;37219:10;37214:3;37210:20;37207:1;37200:31;37250:4;37247:1;37240:15;37274:4;37271:1;37264:15;37290:127;37351:10;37346:3;37342:20;37339:1;37332:31;37382:4;37379:1;37372:15;37406:4;37403:1;37396:15;37422:131;-1:-1:-1;;;;;;37496:32:1;;37486:43;;37476:71;;37543:1;37540;37533:12

Swarm Source

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