ETH Price: $2,666.54 (+2.12%)

Token

terrariumClub (SHROOM)
 

Overview

Max Total Supply

2,989 SHROOM

Holders

1,611

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
eccogrinder.eth
Balance
1 SHROOM
0x8Af6Ec0CdC9B4bf2A489Cf6DB7eCD961dF3c00B8
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
terrariumClub

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-06-24
*/

// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
// ⣿⣿⣿⣿⣿⣿⣿⠿⢛⣉⠀⠀⣤⣴⣶⡄⠀⠀⠀⠉⠙⠻⢿⣿⣿⣿⣿⣿⣿⣿
// ⣿⣿⣿⣿⡿⠋⠠⣾⣿⣿⣶⢶⣿⣿⣿⣷⣄⡀⠀⣀⣿⣷⣤⡈⠻⣿⣿⣿⣿⣿
// ⣿⣿⣿⠟⠀⠀⠀⠈⢿⡟⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⣿⣦⡈⢿⣿⣿⣿
// ⣿⣿⠏⢀⠀⠀⠀⠀⣾⣿⣤⣠⣼⣿⠿⠿⠿⢿⣿⣿⣿⡇⠀⠀⣻⣿⡄⢻⣿⣿
// ⣿⡿⠀⣿⣦⣤⣤⣾⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠙⣿⣿⣿⣶⣶⣿⣿⣷⠀⢿⣿
// ⣿⡇⢸⠿⢿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⣿⣿⡟⠋⠉⠉⠻⣿⡆⢸⣿
// ⣿⣧⠀⠀⠀⣿⣿⡿⠋⠉⠛⣿⣧⡀⠀⠀⠀⠀⣠⣿⣿⠀⠀⠀⠀⠀⠋⢀⣾⣿
// ⣿⣿⣷⣄⡈⠛⠻⠇⠀⠀⢠⣿⣿⣿⣷⣶⣶⣿⣿⡿⠿⠷⠀⠀⣀⣤⣶⣿⣿⣿
// ⣿⣿⣿⣿⣿⣿⣶⣶⣶⣶⣤⣤⣤⣤⣤⣤⣤⣤⣴⢶⣶⣶⣶⣿⣿⣿⣿⣿⣿⣿
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣿⣿⣿⣿⣿⣿⣿
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿
// ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣦⣤⣤⣤⣴⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
// shout outs:
// to dom, timshel, loot community and goblenz for the inspiration
// to msc18, 124, SHZ, og mushroomers and cool guys from thai and nigeria
// to mushrooms つ◕_◕つ 🍄
// =========================
// for the web3 frens with love

// SPDX-License-Identifier: MIT

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: ECDSA.sol


// OpenZeppelin Contracts v4.4.1 (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 = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 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 Message, created from `s`. 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(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

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

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private 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: Payment.sol


// OpenZeppelin Contracts v4.4.1 (finance/PaymentSplitter.sol)

pragma solidity ^0.8.0;



/**
 * @title PaymentSplitter
 * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
 * that the Ether will be split in this way, since it is handled transparently by the contract.
 *
 * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
 * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
 * an amount proportional to the percentage of total shares they were assigned.
 *
 * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
 * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
 * function.
 *
 * NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and
 * tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you
 * to run tests before sending real value to this contract.
 */
contract Payment is Context {
    event PayeeAdded(address account, uint256 shares);
    event PaymentReleased(address to, uint256 amount);
    event PaymentReceived(address from, uint256 amount);

    uint256 private _totalShares;
    uint256 private _totalReleased;

    mapping(address => uint256) private _shares;
    mapping(address => uint256) private _released;
    address[] private _payees;

    /**
     * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
     * the matching position in the `shares` array.
     *
     * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
     * duplicates in `payees`.
     */
    constructor(address[] memory payees, uint256[] memory shares_) payable {
        require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch");
        require(payees.length > 0, "PaymentSplitter: no payees");

        for (uint256 i = 0; i < payees.length; i++) {
            _addPayee(payees[i], shares_[i]);
        }
    }

    /**
     * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
     * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
     * reliability of the events, and not the actual splitting of Ether.
     *
     * To learn more about this see the Solidity documentation for
     * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback
     * functions].
     */
    receive() external payable virtual {
        emit PaymentReceived(_msgSender(), msg.value);
    }

    /**
     * @dev Getter for the total shares held by payees.
     */
    function totalShares() public view returns (uint256) {
        return _totalShares;
    }

    /**
     * @dev Getter for the total amount of Ether already released.
     */
    function totalReleased() public view returns (uint256) {
        return _totalReleased;
    }


    /**
     * @dev Getter for the amount of shares held by an account.
     */
    function shares(address account) public view returns (uint256) {
        return _shares[account];
    }

    /**
     * @dev Getter for the amount of Ether already released to a payee.
     */
    function released(address account) public view returns (uint256) {
        return _released[account];
    }


    /**
     * @dev Getter for the address of the payee number `index`.
     */
    function payee(uint256 index) public view returns (address) {
        return _payees[index];
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
     * total shares and their previous withdrawals.
     */
    function release(address payable account) public virtual {
        require(_shares[account] > 0, "PaymentSplitter: account has no shares");

        uint256 totalReceived = address(this).balance + totalReleased();
        uint256 payment = _pendingPayment(account, totalReceived, released(account));

        require(payment != 0, "PaymentSplitter: account is not due payment");

        _released[account] += payment;
        _totalReleased += payment;

        Address.sendValue(account, payment);
        emit PaymentReleased(account, payment);
    }


    /**
     * @dev internal logic for computing the pending payment of an `account` given the token historical balances and
     * already released amounts.
     */
    function _pendingPayment(
        address account,
        uint256 totalReceived,
        uint256 alreadyReleased
    ) private view returns (uint256) {
        return (totalReceived * _shares[account]) / _totalShares - alreadyReleased;
    }

    /**
     * @dev Add a new payee to the contract.
     * @param account The address of the payee to add.
     * @param shares_ The number of shares owned by the payee.
     */
    function _addPayee(address account, uint256 shares_) private {
        require(account != address(0), "PaymentSplitter: account is the zero address");
        require(shares_ > 0, "PaymentSplitter: shares are 0");
        require(_shares[account] == 0, "PaymentSplitter: account already has shares");

        _payees.push(account);
        _shares[account] = shares_;
        _totalShares = _totalShares + shares_;
        emit PayeeAdded(account, shares_);
    }
}
// File: 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: 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: 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: 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: 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: 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: ERC721A.sol


pragma solidity ^0.8.0;









contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {
    using Address for address;
    using Strings for uint256;

    struct TokenOwnership {
        address addr;
        uint64 startTimestamp;
    }

    struct AddressData {
        uint128 balance;
        uint128 numberMinted;
    }

    uint256 internal currentIndex;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned. See ownershipOf implementation for details.
    mapping(uint256 => TokenOwnership) internal _ownerships;

    // Mapping owner address to address data
    mapping(address => AddressData) private _addressData;

    // 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;

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view override returns (uint256) {
        require(index < totalSupply(), 'ERC721A: global index out of bounds');
        return index;
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     * This read function is O(totalSupply). If calling from a separate contract, be sure to test gas first.
     * It may also degrade with extremely large collection sizes (e.g >> 10000), test for your use case.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {
        require(index < balanceOf(owner), 'ERC721A: owner index out of bounds');
        uint256 numMintedSoFar = totalSupply();
        uint256 tokenIdsIdx;
        address currOwnershipAddr;

        // Counter overflow is impossible as the loop breaks when uint256 i is equal to another uint256 numMintedSoFar.
        unchecked {
            for (uint256 i; i < numMintedSoFar; i++) {
                TokenOwnership memory ownership = _ownerships[i];
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    if (tokenIdsIdx == index) {
                        return i;
                    }
                    tokenIdsIdx++;
                }
            }
        }

        revert('ERC721A: unable to get token of owner by index');
    }

    /**
     * @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 ||
            interfaceId == type(IERC721Enumerable).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        require(owner != address(0), 'ERC721A: balance query for the zero address');
        return uint256(_addressData[owner].balance);
    }

    function _numberMinted(address owner) internal view returns (uint256) {
        require(owner != address(0), 'ERC721A: number minted query for the zero address');
        return uint256(_addressData[owner].numberMinted);
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
        require(_exists(tokenId), 'ERC721A: owner query for nonexistent token');

        unchecked {
            for (uint256 curr = tokenId; curr >= 0; curr--) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (ownership.addr != address(0)) {
                    return ownership;
                }
            }
        }

        revert('ERC721A: unable to determine the owner of token');
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view override returns (address) {
        return ownershipOf(tokenId).addr;
    }

    /**
     * @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 override {
        address owner = ERC721A.ownerOf(tokenId);
        require(to != owner, 'ERC721A: approval to current owner');

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            'ERC721A: approve caller is not owner nor approved for all'
        );

        _approve(to, tokenId, owner);
    }

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

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public override {
        require(operator != _msgSender(), 'ERC721A: 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 override {
        _transfer(from, to, tokenId);
    }

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public override {
        _transfer(from, to, tokenId);
        require(
            _checkOnERC721Received(from, to, tokenId, _data),
            'ERC721A: 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`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return tokenId < currentIndex;
    }

    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        _mint(to, quantity, _data, true);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _mint(
        address to,
        uint256 quantity,
        bytes memory _data,
        bool safe
    ) internal {
        uint256 startTokenId = currentIndex;
        require(to != address(0), 'ERC721A: mint to the zero address');
        require(quantity != 0, 'ERC721A: quantity must be greater than 0');

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 3.4e38 (2**128) - 1
        // updatedIndex overflows if currentIndex + quantity > 1.56e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint128(quantity);
            _addressData[to].numberMinted += uint128(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;

            for (uint256 i; i < quantity; i++) {
                emit Transfer(address(0), to, updatedIndex);
                if (safe) {
                    require(
                        _checkOnERC721Received(address(0), to, updatedIndex, _data),
                        'ERC721A: transfer to non ERC721Receiver implementer'
                    );
                }

                updatedIndex++;
            }

            currentIndex = updatedIndex;
        }

        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * 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
    ) private {
        TokenOwnership memory prevOwnership = ownershipOf(tokenId);

        bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr ||
            getApproved(tokenId) == _msgSender() ||
            isApprovedForAll(prevOwnership.addr, _msgSender()));

        require(isApprovedOrOwner, 'ERC721A: transfer caller is not owner nor approved');

        require(prevOwnership.addr == from, 'ERC721A: transfer from incorrect owner');
        require(to != address(0), 'ERC721A: transfer to the zero address');

        _beforeTokenTransfers(from, to, tokenId, 1);

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

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            _ownerships[tokenId].addr = to;
            _ownerships[tokenId].startTimestamp = uint64(block.timestamp);

            // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            if (_ownerships[nextTokenId].addr == address(0)) {
                if (_exists(nextTokenId)) {
                    _ownerships[nextTokenId].addr = prevOwnership.addr;
                    _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(
        address to,
        uint256 tokenId,
        address owner
    ) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(owner, 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(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert('ERC721A: transfer to non ERC721Receiver implementer');
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * 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`.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
     * minting.
     *
     * startTokenId - the first token id to be transferred
     * quantity - the amount to be transferred
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}
}

// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}



pragma solidity ^0.8.0;

/**********************************************************\
* Author: alxi <[email protected]> (https://twitter.com/0xalxi)
* EIP-5050 Token Interaction Standard: [tbd]
*
* Implementation of an interactive token protocol.
/**********************************************************/

/// @title ERC-5050 Token Interaction Standard
/// @dev See https://eips.ethereum.org/EIPS/eip-xxx
interface IERC5050Sender {
    /// @notice Send an action to the target address
    /// @dev The action's `fromContract` is automatically set to `address(this)`,
    /// and the `from` parameter is set to `msg.sender`.
    /// @param action The action to send
    function sendAction(Action memory action) external payable;

    /// @notice Check if an action is valid based on its hash and nonce
    /// @dev When an action passes through all three possible contracts
    /// (`fromContract`, `to`, and `state`) the `state` contract validates the
    /// action with the initating `fromContract` using a nonced action hash.
    /// This hash is calculated and saved to storage on the `fromContract` before
    /// action handling is initiated. The `state` contract calculates the hash
    /// and verifies it and nonce with the `fromContract`.
    /// @param _hash The hash to validate
    /// @param _nonce The nonce to validate
    function isValid(bytes32 _hash, uint256 _nonce) external returns (bool);

    /// @notice Retrieve list of actions that can be sent.
    /// @dev Intended for use by off-chain applications to query compatible contracts,
    /// and to advertise functionality in human-readable form.
    function sendableActions() external view returns (string[] memory);

    /// @notice Change or reaffirm the approved address for an action
    /// @dev The zero address indicates there is no approved address.
    ///  Throws unless `msg.sender` is the `_account`, or an authorized
    ///  operator of the `_account`.
    /// @param _account The account of the account-action pair to approve
    /// @param _action The action of the account-action pair to approve
    /// @param _approved The new approved account-action controller
    function approveForAction(
        address _account,
        bytes4 _action,
        address _approved
    ) external returns (bool);

    /// @notice Enable or disable approval for a third party ("operator") to conduct
    ///  all actions on behalf of `msg.sender`
    /// @dev Emits the ApprovalForAll event. The contract MUST allow
    ///  an unbounded number of operators per owner.
    /// @param _operator Address to add to the set of authorized operators
    /// @param _approved True if the operator is approved, false to revoke approval
    function setApprovalForAllActions(address _operator, bool _approved)
        external;

    /// @notice Get the approved address for an account-action pair
    /// @dev Throws if `_tokenId` is not a valid NFT.
    /// @param _account The account of the account-action to find the approved address for
    /// @param _action The action of the account-action to find the approved address for
    /// @return The approved address for this account-action, or the zero address if
    ///  there is none
    function getApprovedForAction(address _account, bytes4 _action)
        external
        view
        returns (address);

    /// @notice Query if an address is an authorized operator for another address
    /// @param _account The address on whose behalf actions are performed
    /// @param _operator The address that acts on behalf of the account
    /// @return True if `_operator` is an approved operator for `_account`, false otherwise
    function isApprovedForAllActions(address _account, address _operator)
        external
        view
        returns (bool);

    /// @dev This emits when an action is sent (`sendAction()`)
    event SendAction(
        bytes4 indexed name,
        address _from,
        address indexed _fromContract,
        uint256 _tokenId,
        address indexed _to,
        uint256 _toTokenId,
        address _state,
        bytes _data
    );

    /// @dev This emits when the approved address for an account-action pair
    ///  is changed or reaffirmed. The zero address indicates there is no
    ///  approved address.
    event ApprovalForAction(
        address indexed _account,
        bytes4 indexed _action,
        address indexed _approved
    );

    /// @dev This emits when an operator is enabled or disabled for an account.
    ///  The operator can conduct all actions on behalf of the account.
    event ApprovalForAllActions(
        address indexed _account,
        address indexed _operator,
        bool _approved
    );
}

interface IERC5050Receiver {
    /// @notice Handle an action
    /// @dev Both the `to` contract and `state` contract are called via
    /// `onActionReceived()`.
    /// @param action The action to handle
    function onActionReceived(Action calldata action, uint256 _nonce)
        external
        payable;

    /// @notice Retrieve list of actions that can be received.
    /// @dev Intended for use by off-chain applications to query compatible contracts,
    /// and to advertise functionality in human-readable form.
    function receivableActions() external view returns (string[] memory);

    /// @dev This emits when a valid action is received.
    event ActionReceived(
        bytes4 indexed name,
        address _from,
        address indexed _fromContract,
        uint256 _tokenId,
        address indexed _to,
        uint256 _toTokenId,
        address _state,
        bytes _data
    );
}

/// @param _address The address of the interactive object
/// @param tokenId The token that is interacting (optional)
struct Object {
    address _address;
    uint256 _tokenId;
}

/// @param selector The bytes4(keccack256()) encoding of the action string
/// @param user The address of the sender
/// @param from The initiating object
/// @param to The receiving object
/// @param state The state contract
/// @param data Additional data with no specified format
struct Action {
    bytes4 selector;
    address user;
    Object from;
    Object to;
    address state;
    bytes data;
}

// Barely modified version of OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)

pragma solidity ^0.8.0;

library ActionsSet {
    struct Set {
        // Storage of action names
        string[] _names;
        // Storage of action selectors
        bytes4[] _selectors;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes4 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Set storage set, string memory name) internal returns (bool) {
        bytes4 selector = bytes4(keccak256(bytes(name)));
        if (!contains(set, selector)) {
            set._selectors.push(selector);
            set._names.push(name);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[selector] = set._selectors.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Set storage set, bytes4 value) internal returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _selectors array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._selectors.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes4 lastValue = set._selectors[lastIndex];

                // Move the last value to the index where the value to delete is
                set._selectors[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._selectors.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Set storage set, bytes4 value)
        internal
        view
        returns (bool)
    {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(Set storage set) internal view returns (uint256) {
        return set._selectors.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Set storage set, uint256 index) internal view returns (bytes4) {
        return set._selectors[index];
    }

    /**
     * @dev Return the entire set of action names
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function names(Set storage set) internal view returns (string[] memory) {
        return set._names;
    }
    
    /**
     * @dev Return the entire set of action selectors
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function selectors(Set storage set) internal view returns (bytes4[] memory) {
        return set._selectors;
    }
    
    
}

pragma solidity ^0.8.0;

/**********************************************************\
* Author: alxi <[email protected]> (https://twitter.com/0xalxi)
* EIP-5050 Token Interaction Standard: [tbd]
*
* Implementation of an interactive token protocol.
/**********************************************************/

interface IControllable {
    event ControllerApproval(
        address indexed _controller,
        bytes4 indexed _action
    );
    
    event ControllerApprovalForAll(
        address indexed _controller,
        bool _approved
    );
    
    function approveController(address _controller, bytes4 _action)
        external;

    function setControllerApprovalForAll(address _controller, bool _approved)
        external;

    function isApprovedController(address _controller, bytes4 _action)
        external
        view
        returns (bool);
}


pragma solidity ^0.8.0;

/**********************************************************\
* Author: alxi <[email protected]> (https://twitter.com/0xalxi)
* EIP-5050 Token Interaction Standard: [tbd]
*
* Implementation of an interactive token protocol.
/**********************************************************/

contract Controllable is IControllable {
    mapping(address => mapping(bytes4 => bool)) private _actionControllers;
    mapping(address => bool) private _universalControllers;

    function approveController(address _controller, bytes4 _action)
        external
        virtual
    {
        _actionControllers[_controller][_action] = true;
        emit ControllerApproval(
            _controller,
            _action
        );
    }
    
    function setControllerApprovalForAll(address _controller, bool _approved)
        external
        virtual
    {
        _universalControllers[_controller] = _approved;
        emit ControllerApprovalForAll(
            _controller,
            _approved
        );
    }

    function isApprovedController(address _controller, bytes4 _action)
        external
        view
        returns (bool)
    {
        return _isApprovedController(_controller, _action);
    }

    function _isApprovedController(address _controller, bytes4 _action)
        internal
        view
        returns (bool)
    {
        if (_universalControllers[_controller]) {
            return true;
        }
        return _actionControllers[_controller][_action];
    }
}

pragma solidity ^0.8.0;

/**********************************************************\
* Author: alxi <[email protected]> (https://twitter.com/0xalxi)
* EIP-5050 Token Interaction Standard: [tbd]
*
* Implementation of an interactive token protocol.
/**********************************************************/

contract ERC5050Sender is Controllable, IERC5050Sender {
    using Address for address;
    using ActionsSet for ActionsSet.Set;

    ActionsSet.Set _sendableActions;

    uint256 private _nonce;
    bytes32 private _hash;

    mapping(address => mapping(bytes4 => address)) actionApprovals;
    mapping(address => mapping(address => bool)) operatorApprovals;

    function sendAction(Action memory action)
        external
        payable
        virtual
        override
    {
        _sendAction(action);
    }

    function isValid(bytes32 actionHash, uint256 nonce)
        external
        view
        returns (bool)
    {
        return actionHash == _hash && nonce == _nonce;
    }

    function sendableActions() external view returns (string[] memory) {
        return _sendableActions.names();
    }

    modifier onlySendableAction(Action memory action) {
        if (_isApprovedController(msg.sender, action.selector)) {
            return;
        }
        require(
            _sendableActions.contains(action.selector),
            "ERC5050: invalid action"
        );
        require(
            _isApprovedOrSelf(action.user, action.selector),
            "ERC5050: unapproved sender"
        );
        _;
    }

    function approveForAction(
        address _account,
        bytes4 _action,
        address _approved
    ) public virtual override returns (bool) {
        require(_approved != _account, "ERC5050: approve to caller");

        require(
            msg.sender == _account ||
                isApprovedForAllActions(_account, msg.sender),
            "ERC5050: approve caller is not account nor approved for all"
        );

        actionApprovals[_account][_action] = _approved;
        emit ApprovalForAction(_account, _action, _approved);

        return true;
    }

    function setApprovalForAllActions(address _operator, bool _approved)
        public
        virtual
        override
    {
        require(msg.sender != _operator, "ERC5050: approve to caller");

        operatorApprovals[msg.sender][_operator] = _approved;

        emit ApprovalForAllActions(msg.sender, _operator, _approved);
    }

    function getApprovedForAction(address _account, bytes4 _action)
        public
        view
        returns (address)
    {
        return actionApprovals[_account][_action];
    }

    function isApprovedForAllActions(address _account, address _operator)
        public
        view
        returns (bool)
    {
        return operatorApprovals[_account][_operator];
    }

    function _sendAction(Action memory action) internal {
        if (!_isApprovedController(msg.sender, action.selector)) {
            action.from._address = address(this);
            bool toIsContract = action.to._address.isContract();
            bool stateIsContract = action.state.isContract();
            address next;
            if (toIsContract) {
                next = action.to._address;
            } else if (stateIsContract) {
                next = action.state;
            }
            uint256 nonce;
            if (toIsContract && stateIsContract) {
                _validate(action);
                nonce = _nonce;
            }
            if (next.isContract()) {
                try
                    IERC5050Receiver(next).onActionReceived{value: msg.value}(
                        action,
                        nonce
                    )
                {} catch Error(string memory err) {
                    revert(err);
                } catch (bytes memory returnData) {
                    if (returnData.length > 0) {
                        revert(string(returnData));
                    }
                }
            }
        }
        emit SendAction(
            action.selector,
            action.user,
            action.from._address,
            action.from._tokenId,
            action.to._address,
            action.to._tokenId,
            action.state,
            action.data
        );
    }

    function _validate(Action memory action) internal {
        ++_nonce;
        _hash = bytes32(
            keccak256(
                abi.encodePacked(
                    action.selector,
                    action.user,
                    action.from._address,
                    action.from._tokenId,
                    action.to._address,
                    action.to._tokenId,
                    action.state,
                    action.data,
                    _nonce
                )
            )
        );
    }

    function _isApprovedOrSelf(address account, bytes4 action)
        internal
        view
        returns (bool)
    {
        return (msg.sender == account ||
            isApprovedForAllActions(account, msg.sender) ||
            getApprovedForAction(account, action) == msg.sender);
    }

    function _registerSendable(string memory action) internal {
        _sendableActions.add(action);
    }
}

pragma solidity ^0.8.0;

/**********************************************************\
* Author: alxi <[email protected]> (https://twitter.com/0xalxi)
* EIP-5050 Token Interaction Standard: [tbd]
*
* Implementation of an interactive token protocol.
/**********************************************************/


contract ERC5050Receiver is Controllable, IERC5050Receiver {
    using Address for address;
    using ActionsSet for ActionsSet.Set;

    ActionsSet.Set _receivableActions;

    modifier onlyReceivableAction(Action calldata action, uint256 nonce) {
        if (_isApprovedController(msg.sender, action.selector)) {
            return;
        }
        require(
            action.to._address == address(this),
            "ERC5050: invalid receiver"
        );
        require(
            _receivableActions.contains(action.selector),
            "ERC5050: invalid action"
        );
        require(
            action.from._address == address(0) ||
                action.from._address == msg.sender,
            "ERC5050: invalid sender"
        );
        require(
            (action.from._address != address(0) && action.user == tx.origin) ||
                action.user == msg.sender,
            "ERC5050: invalid sender"
        );
        _;
    }

    function receivableActions() external view returns (string[] memory) {
        return _receivableActions.names();
    }

    function onActionReceived(Action calldata action, uint256 nonce)
        external
        payable
        virtual
        override
        onlyReceivableAction(action, nonce)
    {
        _onActionReceived(action, nonce);
    }

    function _onActionReceived(Action calldata action, uint256 nonce)
        internal
        virtual
    {
        if (!_isApprovedController(msg.sender, action.selector)) {
            if (action.state != address(0)) {
                require(action.state.isContract(), "ERC5050: invalid state");
                try
                    IERC5050Receiver(action.state).onActionReceived{
                        value: msg.value
                    }(action, nonce)
                {} catch (bytes memory reason) {
                    if (reason.length == 0) {
                        revert("ERC5050: call to non ERC5050Receiver");
                    } else {
                        assembly {
                            revert(add(32, reason), mload(reason))
                        }
                    }
                }
            }
        }
        emit ActionReceived(
            action.selector,
            action.user,
            action.from._address,
            action.from._tokenId,
            action.to._address,
            action.to._tokenId,
            action.state,
            action.data
        );
    }

    function _registerReceivable(string memory action) internal {
        _receivableActions.add(action);
    }
}

pragma solidity ^0.8.0;

/**********************************************************\
* Author: alxi <[email protected]> (https://twitter.com/0xalxi)
* EIP-5050 Token Interaction Standard: [tbd]
*
* Implementation of an interactive token protocol.
/**********************************************************/

contract ERC5050 is ERC5050Sender, ERC5050Receiver {
    function _registerAction(string memory action) internal {
        _registerReceivable(action);
        _registerSendable(action);
    }
}

// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

pragma solidity ^0.8.2;

interface IToken {
    function balanceOf(address) external view returns (uint256);
}


contract terrariumClub is ERC721A, ERC5050, Ownable, ReentrancyGuard {  
    using Strings for uint256;
    string public _shroomies;
    string public _magicShroomies;
    string public mycelianTruth = unicode"つ◕_◕つ 🍄";
    bool public mushroomization = false;
    uint256 public mushrooms = 10000;
    uint256 public royalSpores = 10;
    uint256 public myceliumMana = 420;
    uint256 public grewUpOnTheDead = 0;
    uint256 public shroomsMintLimit = 24;
    bool public teamMinted = false;
    mapping(address => bool) public claimStatuses;
    mapping(address => uint256) public mushroomCounter;
    mapping(uint256 => bool) public sporeMushrooms;
    mapping(uint256 => bool) public magicMushrooms;
    mapping(uint256 => uint256) public eatCooldown;
    mapping(uint256 => bool) public isRoyal;

    address spells;

    bytes4 public constant CAST_SELECTOR = bytes4(keccak256("cast"));
    bytes4 public constant EAT_SHROOM_SELECTOR = bytes4(keccak256("eat_shroom"));

    uint256 constant MUSHROOM_PRICE = 0.0420 ether;
    uint256 constant LEET_PRICE = 0.31337 ether;


    event MushroomEaten(uint shroomId);

	constructor() ERC721A("terrariumClub", "SHROOM") {
        _registerReceivable("cast");
        _registerReceivable("eat_shroom");
    }

    address constant internal fertile_ground = 0x000000000000000000000000000000000000dEaD;
    address constant internal goblintown_address = 0xbCe3781ae7Ca1a5e050Bd9C4c77369867eBc307e;
    address constant internal hyperloot_address = 0x0290d49f53A8d186973B82faaFdaFe696B29AcBb;
    address constant internal loot_address = 0xFF9C1b15B16263C61d017ee9F65C50e4AE0113D7;
    address constant internal genesis_adventurers_address = 0x8dB687aCEb92c66f013e1D614137238Cc698fEdb;
    address constant internal cryptoadz_address = 0x1CB1A5e65610AEFF2551A50f76a87a7d3fB649C6;
    address constant internal blitnauts_address = 0x448f3219CF2A23b0527A7a0158e7264B87f635Db;
    address constant internal chainrunners_address = 0x97597002980134beA46250Aa0510C9B90d87A587;
    address constant internal nouns_address = 0x9C8fF314C9Bc7F6e59A9d9225Fb22946427eDC03;
    address constant internal wagdie_address = 0x659A4BdaAaCc62d2bd9Cb18225D9C89b5B697A5A;
    address constant internal grugs_lair_address = 0xFA9Ed22ca5D329eCaee9347F72E18C1fC291471b;


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

    function _magicURI() internal view virtual returns (string memory) {
        return _magicShroomies;
    }


    // for cc0 frens つ◕_◕つ 🍄
 	function claimMushroom() external nonReentrant {
  	    uint256 shroomId = totalSupply();
        require(mushroomization, "Mushroomization isn't started");
        require(shroomId < mushrooms, "No spores left...");
        require(msg.sender == tx.origin);
    	require(!claimStatuses[msg.sender], "Mushroom already claimed");
        require(
            IToken(goblintown_address).balanceOf(msg.sender) > 0 ||
            IToken(hyperloot_address).balanceOf(msg.sender) > 0 ||
            IToken(loot_address).balanceOf(msg.sender) > 0 ||
            IToken(genesis_adventurers_address).balanceOf(msg.sender) > 0 ||
            IToken(cryptoadz_address).balanceOf(msg.sender) > 0 ||
            IToken(blitnauts_address).balanceOf(msg.sender) > 0 ||
            IToken(chainrunners_address).balanceOf(msg.sender) > 0 ||
            IToken(nouns_address).balanceOf(msg.sender) > 0 ||
            IToken(wagdie_address).balanceOf(msg.sender) > 0 ||
            IToken(grugs_lair_address).balanceOf(msg.sender) > 0,
            "u dont l00k l1k3 cc0 / fren =_="
        );
        _safeMint(msg.sender, 1);
        claimStatuses[msg.sender] = true;
        sporeMushrooms[shroomId] = true;
    }

    // つ◕_◕つ 🍄🙏
    function mintMushrooms(uint256 _mushrooms) external payable nonReentrant mintConditions(_mushrooms) {
        uint256 mintedMushrooms = mushroomCounter[msg.sender];
        require(mintedMushrooms + _mushrooms <= shroomsMintLimit, "User max mint limit");
        require(msg.value >= (MUSHROOM_PRICE * _mushrooms), unicode"Wow, pls attach 0.0420 ether per mushroom つ◕_◕つ");
        _safeMint(msg.sender, _mushrooms);
        mushroomCounter[msg.sender] = (mintedMushrooms + _mushrooms);
    }

    // つ◕_◕つ 🍄💀
    function rebirthTheDead() external nonReentrant mintConditions(1) {
    	require(!claimStatuses[msg.sender], "Mushroom already claimed");
        require(
            grewUpOnTheDead < IToken(wagdie_address).balanceOf(fertile_ground),
            "All the dead already reborn."
        );
        _safeMint(msg.sender, 1);
        grewUpOnTheDead += 1;
        claimStatuses[msg.sender] = true;
    }

    // つ◕_◕つ 🍄👑
    function mintRoyal() external payable nonReentrant {
        uint256 shroomId = totalSupply();
        require(mushroomization, "Mushroomization isn't started");
        require(royalSpores > 0, "No more leet spores...");
        require(shroomId < mushrooms, "No spores left...");
        require(msg.sender == tx.origin);
        require(msg.value >= LEET_PRICE, unicode"Royal Shrooms requiring つ◕_◕つ 0.31337 ether");
        _safeMint(msg.sender, 1);
        royalSpores -= 1;
        isRoyal[shroomId] = true;

    }

    // in case of mushroomed ser want to send a shroom to fren つ◕_◕つ 🍄
    function dropSporeToFren(address fren, uint256 shroomId) external nonReentrant mintConditions(1) {
        require(msg.sender != fren);
        require(ownerOf(shroomId) == msg.sender);
        require(sporeMushrooms[shroomId], "no spores in ur shroom");
        _safeMint(fren, 1);
        sporeMushrooms[shroomId] = false;
    }

    // つ◕_◕つ 🔮
    function onActionReceived(Action calldata action, uint256 _nonce)
        external
        payable
        override
        onlyReceivableAction(action, _nonce)
    {
        require(action.selector == CAST_SELECTOR || action.selector == EAT_SHROOM_SELECTOR, "Mushrooms: invalid action.selector");
        if (action.selector == CAST_SELECTOR){
            require(action.from._address == spells, "Mushrooms: invalid action.from");
            require(action.user == ownerOf(action.to._tokenId), "Mushrooms: sender not owner of this mushroom");
            require(!magicMushrooms[action.to._tokenId], "Only one cast per tokenID");
            require(myceliumMana > 0, "No mana left");
            magicMushrooms[action.to._tokenId] = true;
            myceliumMana -= 1;
        }
        if (action.selector == EAT_SHROOM_SELECTOR){
            require(action.user == ownerOf(action.to._tokenId), "Mushrooms: sender not owner of this mushroom");
            require(eatCooldown[action.to._tokenId] - block.number < 5000, "You can eat mushrooms only once per 5000 blocks");
            emit MushroomEaten(action.to._tokenId);
            eatCooldown[action.to._tokenId] = block.number;
        }
        _onActionReceived(action, _nonce);
    }

    // つ◕_◕つ 💬
    function broadcastMycelialMessage (uint256 shroomId, string calldata message) public {
        require(msg.sender == ownerOf(shroomId), "Mushrooms: sender not owner");
        require(isRoyal[shroomId], "Mushroom isn't royal");
        mycelianTruth = message;
    }

    // つ◕_◕つ 🍄
 	function teamHarvest(uint256 _mushrooms) public onlyOwner {
        require(!teamMinted);
  	    uint256 totalmushrooms = totalSupply();
	    require(totalmushrooms + _mushrooms <= mushrooms);
        _safeMint(msg.sender, _mushrooms);
        teamMinted = true;
    }

    // つ◕_◕つ 🍄
    function startMushroomization(bool _mushroomization) external onlyOwner {
        mushroomization = _mushroomization;
    }

     // つ◕_◕つ 🍄
    function visualize(string memory link) external onlyOwner {
        _shroomies = link;
    }

    // つ◕_◕つ 🔮
    function doSomethingMagic(string memory magicLink) external onlyOwner {
        _magicShroomies = magicLink;
    }

    // つ◕_◕つ thought to rename but deployed to blockchain how it was in goblintown
    function sumthinboutfunds() public payable onlyOwner {
	(bool success, ) = payable(msg.sender).call{value: address(this).balance}("");
		require(success);
	}

    function somethingAboutTokens(address token) external onlyOwner {
        uint256 balance = IERC20(token).balanceOf(address(this));
        IERC20(token).transfer(msg.sender, balance);
    }

    function setSpellsAddress(address _spells) external onlyOwner {
        spells = _spells;
    }

    function tokenURI(uint256 _tokenId) public view override returns (string memory) {
        require(_exists(_tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory baseURI = _baseURI();
        string memory magicURI = _magicURI();
        if (magicMushrooms[_tokenId] && bytes(magicURI).length != 0) {
            return string(abi.encodePacked(magicURI, _tokenId.toString()));
        }
        else {
            return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _tokenId.toString())) : '';
        }
    }

    modifier mintConditions(uint256 _mushrooms) {
        require(mushroomization, "Mushroomization isn't started");
        require(totalSupply() + _mushrooms <= mushrooms, "No spores left...");
        require(tx.origin == msg.sender, unicode"ಠ_ಠ");
        _;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes4","name":"name","type":"bytes4"},{"indexed":false,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_fromContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_toTokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"_state","type":"address"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"ActionReceived","type":"event"},{"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":"_account","type":"address"},{"indexed":true,"internalType":"bytes4","name":"_action","type":"bytes4"},{"indexed":true,"internalType":"address","name":"_approved","type":"address"}],"name":"ApprovalForAction","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":"_account","type":"address"},{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ApprovalForAllActions","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_controller","type":"address"},{"indexed":true,"internalType":"bytes4","name":"_action","type":"bytes4"}],"name":"ControllerApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_controller","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ControllerApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"shroomId","type":"uint256"}],"name":"MushroomEaten","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes4","name":"name","type":"bytes4"},{"indexed":false,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_fromContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_toTokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"_state","type":"address"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"SendAction","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"CAST_SELECTOR","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EAT_SHROOM_SELECTOR","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_magicShroomies","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_shroomies","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"},{"internalType":"bytes4","name":"_action","type":"bytes4"}],"name":"approveController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bytes4","name":"_action","type":"bytes4"},{"internalType":"address","name":"_approved","type":"address"}],"name":"approveForAction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"shroomId","type":"uint256"},{"internalType":"string","name":"message","type":"string"}],"name":"broadcastMycelialMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimMushroom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimStatuses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"magicLink","type":"string"}],"name":"doSomethingMagic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fren","type":"address"},{"internalType":"uint256","name":"shroomId","type":"uint256"}],"name":"dropSporeToFren","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"eatCooldown","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bytes4","name":"_action","type":"bytes4"}],"name":"getApprovedForAction","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"grewUpOnTheDead","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"},{"internalType":"bytes4","name":"_action","type":"bytes4"}],"name":"isApprovedController","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAllActions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isRoyal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"actionHash","type":"bytes32"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"isValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"magicMushrooms","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mushrooms","type":"uint256"}],"name":"mintMushrooms","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintRoyal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mushroomCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mushroomization","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mushrooms","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mycelianTruth","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"myceliumMana","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes4","name":"selector","type":"bytes4"},{"internalType":"address","name":"user","type":"address"},{"components":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"internalType":"struct Object","name":"from","type":"tuple"},{"components":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"internalType":"struct Object","name":"to","type":"tuple"},{"internalType":"address","name":"state","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Action","name":"action","type":"tuple"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"onActionReceived","outputs":[],"stateMutability":"payable","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":"rebirthTheDead","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"receivableActions","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"royalSpores","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":"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":[{"components":[{"internalType":"bytes4","name":"selector","type":"bytes4"},{"internalType":"address","name":"user","type":"address"},{"components":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"internalType":"struct Object","name":"from","type":"tuple"},{"components":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"internalType":"struct Object","name":"to","type":"tuple"},{"internalType":"address","name":"state","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Action","name":"action","type":"tuple"}],"name":"sendAction","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"sendableActions","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAllActions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setControllerApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_spells","type":"address"}],"name":"setSpellsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shroomsMintLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"somethingAboutTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"sporeMushrooms","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_mushroomization","type":"bool"}],"name":"startMushroomization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sumthinboutfunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mushrooms","type":"uint256"}],"name":"teamHarvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"teamMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"link","type":"string"}],"name":"visualize","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c0604052601260808190527138e06938a5e557f8a5e578e069083c27e36160721b60a09081526200003591601791906200029a565b506018805460ff199081168255612710601955600a601a556101a4601b556000601c55601d91909155601e805490911690553480156200007457600080fd5b50604080518082018252600d81526c3a32b93930b934bab6a1b63ab160991b6020808301918252835180850190945260068452655348524f4f4d60d01b908401528151919291620000c8916001916200029a565b508051620000de9060029060208401906200029a565b505050620000fb620000f56200015860201b60201c565b6200015c565b600160145560408051808201909152600481526318d85cdd60e21b60208201526200012690620001ae565b60408051808201909152600a8152696561745f7368726f6f6d60b01b60208201526200015290620001ae565b6200037c565b3390565b601380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620001c9816010620001cd60201b62002e581790919060201c565b5050565b80516020808301919091206001600160e01b0319811660009081526002850190925260408220546200028e57600184810180548083018255600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e087901c9390930292909217909155865492830187558682529081902085516200025f9391909101918601906200029a565b506001808501546001600160e01b03199092166000908152600286016020526040902091909155905062000294565b60009150505b92915050565b828054620002a89062000340565b90600052602060002090601f016020900481019282620002cc576000855562000317565b82601f10620002e757805160ff191683800117855562000317565b8280016001018555821562000317579182015b8281111562000317578251825591602001919060010190620002fa565b506200032592915062000329565b5090565b5b808211156200032557600081556001016200032a565b600181811c908216806200035557607f821691505b6020821081036200037657634e487b7160e01b600052602260045260246000fd5b50919050565b614c65806200038c6000396000f3fe6080604052600436106103ad5760003560e01c80638da5cb5b116101e7578063c0bf3e2d1161010d578063d960e59c116100a0578063e8b5498d1161006f578063e8b5498d14610b37578063e985e9c514610b51578063edf1633b14610b9a578063f2fde38b14610bb057600080fd5b8063d960e59c14610acf578063df89318814610ae2578063e0f11fc914610b02578063e3a5da2a14610b2257600080fd5b8063c918c931116100dc578063c918c93114610a0d578063cc4269b514610a56578063d3eff42014610a6b578063d715d0ec14610a9f57600080fd5b8063c0bf3e2d14610987578063c1e27865146109b7578063c22515c5146109d7578063c87b56dd146109ed57600080fd5b8063a22cb46511610185578063b19b91bd11610154578063b19b91bd14610927578063b88d4fde1461093c578063b91b07731461095c578063bc3b0d491461097157600080fd5b8063a22cb465146108a1578063ac8fa4ed146108c1578063ad504321146108d7578063af388a741461090757600080fd5b806391e31131116101c157806391e311311461081057806395d89b41146108305780639601ed6214610845578063a0768c531461087557600080fd5b80638da5cb5b146107bf578063900bdd57146107dd578063913c5c81146107fd57600080fd5b806347fa15f9116102d75780636352211e1161026a5780637534cb68116102395780637534cb681461074857806375b161961461077557806378f14b9c146107955780638b035e75146107aa57600080fd5b80636352211e146106d357806369d8e231146106f357806370a0823114610713578063715018a61461073357600080fd5b806352873694116102a6578063528736941461065d5780635c073c391461067d578063606c2a1f146106935780636233b0ba146106b357600080fd5b806347fa15f9146105f05780634c79aeec1461060a5780634cf362bb1461061d5780634f6ccce71461063d57600080fd5b8063286cc2401161034f5780633d643cca1161031e5780633d643cca146105595780633f8d90391461056157806342842e0e146105b057806344365db1146105d057600080fd5b8063286cc240146104c25780632f745c591461050f57806333958a181461052f578063395288891461053757600080fd5b8063095ea7b31161038b578063095ea7b31461044157806316d1910a1461046357806318160ddd1461048357806323b872dd146104a257600080fd5b806301ffc9a7146103b257806306fdde03146103e7578063081812fc14610409575b600080fd5b3480156103be57600080fd5b506103d26103cd366004613edf565b610bd0565b60405190151581526020015b60405180910390f35b3480156103f357600080fd5b506103fc610c3d565b6040516103de9190613f54565b34801561041557600080fd5b50610429610424366004613f67565b610ccf565b6040516001600160a01b0390911681526020016103de565b34801561044d57600080fd5b5061046161045c366004613f97565b610d5f565b005b34801561046f57600080fd5b5061046161047e366004613fcf565b610e76565b34801561048f57600080fd5b506000545b6040519081526020016103de565b3480156104ae57600080fd5b506104616104bd366004613fec565b610eb3565b3480156104ce57600080fd5b506104f67f416136f98a37e21524754716a91ac1d0c28c851be9745167497f08b033e0808281565b6040516001600160e01b031990911681526020016103de565b34801561051b57600080fd5b5061049461052a366004613f97565b610ebe565b610461611018565b34801561054357600080fd5b5061054c61109a565b6040516103de9190614028565b6104616110ab565b34801561056d57600080fd5b5061042961057c36600461408a565b6001600160a01b039182166000908152600e602090815260408083206001600160e01b031994909416835292905220541690565b3480156105bc57600080fd5b506104616105cb366004613fec565b611227565b3480156105dc57600080fd5b506104616105eb3660046140c1565b611242565b3480156105fc57600080fd5b506018546103d29060ff1681565b610461610618366004613f67565b611312565b34801561062957600080fd5b50610461610638366004613f97565b6114c4565b34801561064957600080fd5b50610494610658366004613f67565b611617565b34801561066957600080fd5b5061046161067836600461413c565b611679565b34801561068957600080fd5b50610494601d5481565b34801561069f57600080fd5b506104616106ae36600461421b565b6116c5565b3480156106bf57600080fd5b506104616106ce36600461413c565b611706565b3480156106df57600080fd5b506104296106ee366004613f67565b61180f565b3480156106ff57600080fd5b506103d261070e36600461408a565b611821565b34801561071f57600080fd5b5061049461072e36600461413c565b611834565b34801561073f57600080fd5b506104616118c5565b34801561075457600080fd5b50610494610763366004613f67565b60236020526000908152604090205481565b34801561078157600080fd5b50610461610790366004614263565b6118fb565b3480156107a157600080fd5b5061046161195a565b3480156107b657600080fd5b5061054c611b60565b3480156107cb57600080fd5b506013546001600160a01b0316610429565b3480156107e957600080fd5b506104616107f8366004614263565b611b6c565b61046161080b36600461428f565b611c31565b34801561081c57600080fd5b506103d261082b3660046142cb565b612209565b34801561083c57600080fd5b506103fc61238c565b34801561085157600080fd5b506103d2610860366004613f67565b60246020526000908152604090205460ff1681565b34801561088157600080fd5b5061049461089036600461413c565b602080526000908152604090205481565b3480156108ad57600080fd5b506104616108bc366004614263565b61239b565b3480156108cd57600080fd5b50610494601a5481565b3480156108e357600080fd5b506103d26108f2366004613f67565b60226020526000908152604090205460ff1681565b34801561091357600080fd5b5061046161092236600461408a565b612458565b34801561093357600080fd5b506103fc6124bc565b34801561094857600080fd5b50610461610957366004614330565b61254a565b34801561096857600080fd5b506103fc61257d565b34801561097d57600080fd5b50610494601c5481565b34801561099357600080fd5b506103d26109a236600461413c565b601f6020526000908152604090205460ff1681565b3480156109c357600080fd5b506104616109d236600461421b565b61258a565b3480156109e357600080fd5b5061049460195481565b3480156109f957600080fd5b506103fc610a08366004613f67565b6125c7565b348015610a1957600080fd5b506103d2610a28366004614397565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205460ff1690565b348015610a6257600080fd5b506104616126d7565b348015610a7757600080fd5b506104f67fc87efa307383f1235ff7b0df46a7017e5bdc9dcb3964f21a9b5d6f1cf723702d81565b348015610aab57600080fd5b506103d2610aba366004613f67565b60216020526000908152604090205460ff1681565b610461610add366004614420565b612d22565b348015610aee57600080fd5b506103d2610afd3660046144e8565b612d2b565b348015610b0e57600080fd5b50610461610b1d366004613f67565b612d43565b348015610b2e57600080fd5b506103fc612db3565b348015610b4357600080fd5b50601e546103d29060ff1681565b348015610b5d57600080fd5b506103d2610b6c366004614397565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b348015610ba657600080fd5b50610494601b5481565b348015610bbc57600080fd5b50610461610bcb36600461413c565b612dc0565b60006001600160e01b031982166380ac58cd60e01b1480610c0157506001600160e01b03198216635b5e139f60e01b145b80610c1c57506001600160e01b0319821663780e9d6360e01b145b80610c3757506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060018054610c4c9061450a565b80601f0160208091040260200160405190810160405280929190818152602001828054610c789061450a565b8015610cc55780601f10610c9a57610100808354040283529160200191610cc5565b820191906000526020600020905b815481529060010190602001808311610ca857829003601f168201915b5050505050905090565b6000610cdc826000541190565b610d435760405162461bcd60e51b815260206004820152602d60248201527f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560448201526c3c34b9ba32b73a103a37b5b2b760991b60648201526084015b60405180910390fd5b506000908152600560205260409020546001600160a01b031690565b6000610d6a8261180f565b9050806001600160a01b0316836001600160a01b031603610dd85760405162461bcd60e51b815260206004820152602260248201527f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60448201526132b960f11b6064820152608401610d3a565b336001600160a01b0382161480610df45750610df48133610b6c565b610e665760405162461bcd60e51b815260206004820152603960248201527f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656420666f7220616c6c000000000000006064820152608401610d3a565b610e71838383612f1f565b505050565b6013546001600160a01b03163314610ea05760405162461bcd60e51b8152600401610d3a90614544565b6018805460ff1916911515919091179055565b610e71838383612f7b565b6000610ec983611834565b8210610f225760405162461bcd60e51b815260206004820152602260248201527f455243373231413a206f776e657220696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610d3a565b600080549080805b83811015610fb8576000818152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b03169183019190915215610f7c57805192505b876001600160a01b0316836001600160a01b031603610faf57868403610fa857509350610c3792505050565b6001909301925b50600101610f2a565b5060405162461bcd60e51b815260206004820152602e60248201527f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060448201526d0deeedccae440c4f240d2dcc8caf60931b6064820152608401610d3a565b6013546001600160a01b031633146110425760405162461bcd60e51b8152600401610d3a90614544565b604051600090339047908381818185875af1925050503d8060008114611084576040519150601f19603f3d011682016040523d82523d6000602084013e611089565b606091505b505090508061109757600080fd5b50565b60606110a6600961325e565b905090565b6002601454036110cd5760405162461bcd60e51b8152600401610d3a90614579565b600260145560005460185460ff166110f75760405162461bcd60e51b8152600401610d3a906145b0565b6000601a54116111425760405162461bcd60e51b815260206004820152601660248201527527379036b7b932903632b2ba1039b837b932b997171760511b6044820152606401610d3a565b60195481106111635760405162461bcd60e51b8152600401610d3a906145e7565b33321461116f57600080fd5b670459505acd43a0003410156111e35760405162461bcd60e51b815260206004820152603360248201527f526f79616c205368726f6f6d7320726571756972696e6720e381a4e297955fe26044820152724bcaf1c0d2101817199899999b9032ba3432b960691b6064820152608401610d3a565b6111ee33600161333b565b6001601a60008282546112019190614628565b90915550506000908152602460205260409020805460ff19166001908117909155601455565b610e718383836040518060200160405280600081525061254a565b61124b8361180f565b6001600160a01b0316336001600160a01b0316146112ab5760405162461bcd60e51b815260206004820152601b60248201527f4d757368726f6f6d733a2073656e646572206e6f74206f776e657200000000006044820152606401610d3a565b60008381526024602052604090205460ff166113005760405162461bcd60e51b8152602060048201526014602482015273135d5cda1c9bdbdb481a5cdb89dd081c9bde585b60621b6044820152606401610d3a565b61130c60178383613db0565b50505050565b6002601454036113345760405162461bcd60e51b8152600401610d3a90614579565b6002601455601854819060ff1661135d5760405162461bcd60e51b8152600401610d3a906145b0565b6019548161136a60005490565b611374919061463f565b11156113925760405162461bcd60e51b8152600401610d3a906145e7565b3233146113b15760405162461bcd60e51b8152600401610d3a90614657565b336000908152602080526040902054601d546113cd848361463f565b11156114115760405162461bcd60e51b8152602060048201526013602482015272155cd95c881b585e081b5a5b9d081b1a5b5a5d606a1b6044820152606401610d3a565b61142283669536c708910000614678565b3410156114975760405162461bcd60e51b815260206004820152603760248201527f576f772c20706c732061747461636820302e303432302065746865722070657260448201527f206d757368726f6f6d20e381a4e297955fe29795e381a40000000000000000006064820152608401610d3a565b6114a1338461333b565b6114ab838261463f565b3360009081526020805260409020555050600160145550565b6002601454036114e65760405162461bcd60e51b8152600401610d3a90614579565b600260145560185460019060ff166115105760405162461bcd60e51b8152600401610d3a906145b0565b6019548161151d60005490565b611527919061463f565b11156115455760405162461bcd60e51b8152600401610d3a906145e7565b3233146115645760405162461bcd60e51b8152600401610d3a90614657565b6001600160a01b038316330361157957600080fd5b336115838361180f565b6001600160a01b03161461159657600080fd5b60008281526021602052604090205460ff166115ed5760405162461bcd60e51b81526020600482015260166024820152756e6f2073706f72657320696e207572207368726f6f6d60501b6044820152606401610d3a565b6115f883600161333b565b506000908152602160205260409020805460ff19169055506001601455565b6000805482106116755760405162461bcd60e51b815260206004820152602360248201527f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f756044820152626e647360e81b6064820152608401610d3a565b5090565b6013546001600160a01b031633146116a35760405162461bcd60e51b8152600401610d3a90614544565b602580546001600160a01b0319166001600160a01b0392909216919091179055565b6013546001600160a01b031633146116ef5760405162461bcd60e51b8152600401610d3a90614544565b8051611702906016906020840190613e30565b5050565b6013546001600160a01b031633146117305760405162461bcd60e51b8152600401610d3a90614544565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611777573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179b9190614697565b60405163a9059cbb60e01b8152336004820152602481018290529091506001600160a01b0383169063a9059cbb906044016020604051808303816000875af11580156117eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7191906146b0565b600061181a82613355565b5192915050565b600061182d838361342b565b9392505050565b60006001600160a01b0382166118a05760405162461bcd60e51b815260206004820152602b60248201527f455243373231413a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b6064820152608401610d3a565b506001600160a01b03166000908152600460205260409020546001600160801b031690565b6013546001600160a01b031633146118ef5760405162461bcd60e51b8152600401610d3a90614544565b6118f9600061348c565b565b6001600160a01b038216600081815260086020908152604091829020805460ff191685151590811790915591519182527fb033bedede81cc9e0eb1e2341b52e2c78e2ec38ba3e979113dd42533a3958325910160405180910390a25050565b60026014540361197c5760405162461bcd60e51b8152600401610d3a90614579565b600260145560185460019060ff166119a65760405162461bcd60e51b8152600401610d3a906145b0565b601954816119b360005490565b6119bd919061463f565b11156119db5760405162461bcd60e51b8152600401610d3a906145e7565b3233146119fa5760405162461bcd60e51b8152600401610d3a90614657565b336000908152601f602052604090205460ff1615611a555760405162461bcd60e51b8152602060048201526018602482015277135d5cda1c9bdbdb48185b1c9958591e4818db185a5b595960421b6044820152606401610d3a565b6040516370a0823160e01b815261dead600482015273659a4bdaaacc62d2bd9cb18225d9c89b5b697a5a906370a0823190602401602060405180830381865afa158015611aa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aca9190614697565b601c5410611b1a5760405162461bcd60e51b815260206004820152601c60248201527f416c6c20746865206465616420616c7265616479207265626f726e2e000000006044820152606401610d3a565b611b2533600161333b565b6001601c6000828254611b38919061463f565b9091555050336000908152601f60205260409020805460ff1916600190811790915560145550565b60606110a6601061325e565b6001600160a01b0382163303611bc45760405162461bcd60e51b815260206004820152601a60248201527f455243353035303a20617070726f766520746f2063616c6c65720000000000006044820152606401610d3a565b336000818152600f602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917fe37230f00e3b15e90e6a606f3b77be179b2808cc3bc970e51c9e046f8a6683e091015b60405180910390a35050565b8181611c4933611c446020850185613edf565b61342b565b61130c5730611c5e60a084016080850161413c565b6001600160a01b031614611cb45760405162461bcd60e51b815260206004820152601960248201527f455243353035303a20696e76616c6964207265636569766572000000000000006044820152606401610d3a565b611ce2611cc46020840184613edf565b6001600160e01b031916600090815260126020526040902054151590565b611d2e5760405162461bcd60e51b815260206004820152601760248201527f455243353035303a20696e76616c696420616374696f6e0000000000000000006044820152606401610d3a565b6000611d40606084016040850161413c565b6001600160a01b03161480611d6c575033611d61606084016040850161413c565b6001600160a01b0316145b611db25760405162461bcd60e51b815260206004820152601760248201527622a9219a981a981d1034b73b30b634b21039b2b73232b960491b6044820152606401610d3a565b6000611dc4606084016040850161413c565b6001600160a01b031614158015611df2575032611de7604084016020850161413c565b6001600160a01b0316145b80611e14575033611e09604084016020850161413c565b6001600160a01b0316145b611e5a5760405162461bcd60e51b815260206004820152601760248201527622a9219a981a981d1034b73b30b634b21039b2b73232b960491b6044820152606401610d3a565b63416136f960e01b611e6f6020860186613edf565b6001600160e01b0319161480611ea15750630c87efa360e41b611e956020860186613edf565b6001600160e01b031916145b611ef85760405162461bcd60e51b815260206004820152602260248201527f4d757368726f6f6d733a20696e76616c696420616374696f6e2e73656c65637460448201526137b960f11b6064820152608401610d3a565b63416136f960e01b611f0d6020860186613edf565b6001600160e01b031916036120b9576025546001600160a01b0316611f38606086016040870161413c565b6001600160a01b031614611f8e5760405162461bcd60e51b815260206004820152601e60248201527f4d757368726f6f6d733a20696e76616c696420616374696f6e2e66726f6d00006044820152606401610d3a565b611f9b60a085013561180f565b6001600160a01b0316611fb4604086016020870161413c565b6001600160a01b031614611fda5760405162461bcd60e51b8152600401610d3a906146cd565b60a084013560009081526022602052604090205460ff161561203e5760405162461bcd60e51b815260206004820152601960248201527f4f6e6c79206f6e6520636173742070657220746f6b656e4944000000000000006044820152606401610d3a565b6000601b541161207f5760405162461bcd60e51b815260206004820152600c60248201526b139bc81b585b98481b19599d60a21b6044820152606401610d3a565b60a08401356000908152602260205260408120805460ff19166001908117909155601b8054919290916120b3908490614628565b90915550505b630c87efa360e41b6120ce6020860186613edf565b6001600160e01b031916036121ff576120ea60a085013561180f565b6001600160a01b0316612103604086016020870161413c565b6001600160a01b0316146121295760405162461bcd60e51b8152600401610d3a906146cd565b60a08401356000908152602360205260409020546113889061214c904390614628565b106121b15760405162461bcd60e51b815260206004820152602f60248201527f596f752063616e20656174206d757368726f6f6d73206f6e6c79206f6e63652060448201526e706572203530303020626c6f636b7360881b6064820152608401610d3a565b60405160a085013581527f6af461f4cf15493d302e35a159caaf851c28f69956626168ff6fd5530bce984e9060200160405180910390a160a084013560009081526023602052604090204390555b61130c84846134de565b6000836001600160a01b0316826001600160a01b03160361226c5760405162461bcd60e51b815260206004820152601a60248201527f455243353035303a20617070726f766520746f2063616c6c65720000000000006044820152606401610d3a565b336001600160a01b03851614806122a657506001600160a01b0384166000908152600f6020908152604080832033845290915290205460ff165b6123185760405162461bcd60e51b815260206004820152603b60248201527f455243353035303a20617070726f76652063616c6c6572206973206e6f74206160448201527f63636f756e74206e6f7220617070726f76656420666f7220616c6c00000000006064820152608401610d3a565b6001600160a01b038481166000818152600e602090815260408083206001600160e01b03198916808552925280832080546001600160a01b0319169588169586179055519092917f57f9e4aa0c479eb6b4954eeaf36d835de17e7b2df00ce50976dfeba4eff89bbc91a45060019392505050565b606060028054610c4c9061450a565b336001600160a01b038316036123f35760405162461bcd60e51b815260206004820152601a60248201527f455243373231413a20617070726f766520746f2063616c6c65720000000000006044820152606401610d3a565b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319101611c25565b6001600160a01b03821660008181526007602090815260408083206001600160e01b031986168085529252808320805460ff19166001179055519092917f1f4f9056d5481d98c73db2f5a7dc2f115ea15727de4cebe53204edaa4afe831791a35050565b601680546124c99061450a565b80601f01602080910402602001604051908101604052809291908181526020018280546124f59061450a565b80156125425780601f1061251757610100808354040283529160200191612542565b820191906000526020600020905b81548152906001019060200180831161252557829003601f168201915b505050505081565b612555848484612f7b565b6125618484848461373b565b61130c5760405162461bcd60e51b8152600401610d3a90614719565b601580546124c99061450a565b6013546001600160a01b031633146125b45760405162461bcd60e51b8152600401610d3a90614544565b8051611702906015906020840190613e30565b60606125d4826000541190565b6126385760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610d3a565b6000612642613834565b9050600061264e613843565b60008581526022602052604090205490915060ff16801561266f5750805115155b156126a7578061267e85613852565b60405160200161268f92919061476c565b60405160208183030381529060405292505050919050565b81516000036126c557604051806020016040528060008152506126cf565b8161267e85613852565b949350505050565b6002601454036126f95760405162461bcd60e51b8152600401610d3a90614579565b600260145560005460185460ff166127235760405162461bcd60e51b8152600401610d3a906145b0565b60195481106127445760405162461bcd60e51b8152600401610d3a906145e7565b33321461275057600080fd5b336000908152601f602052604090205460ff16156127ab5760405162461bcd60e51b8152602060048201526018602482015277135d5cda1c9bdbdb48185b1c9958591e4818db185a5b595960421b6044820152606401610d3a565b6040516370a0823160e01b815233600482015260009073bce3781ae7ca1a5e050bd9c4c77369867ebc307e906370a0823190602401602060405180830381865afa1580156127fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128219190614697565b11806128a057506040516370a0823160e01b8152336004820152600090730290d49f53a8d186973b82faafdafe696b29acbb906370a0823190602401602060405180830381865afa15801561287a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061289e9190614697565b115b8061291e57506040516370a0823160e01b815233600482015260009073ff9c1b15b16263c61d017ee9f65c50e4ae0113d7906370a0823190602401602060405180830381865afa1580156128f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061291c9190614697565b115b8061299c57506040516370a0823160e01b8152336004820152600090738db687aceb92c66f013e1d614137238cc698fedb906370a0823190602401602060405180830381865afa158015612976573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299a9190614697565b115b80612a1a57506040516370a0823160e01b8152336004820152600090731cb1a5e65610aeff2551a50f76a87a7d3fb649c6906370a0823190602401602060405180830381865afa1580156129f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a189190614697565b115b80612a9857506040516370a0823160e01b815233600482015260009073448f3219cf2a23b0527a7a0158e7264b87f635db906370a0823190602401602060405180830381865afa158015612a72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a969190614697565b115b80612b1657506040516370a0823160e01b81523360048201526000907397597002980134bea46250aa0510c9b90d87a587906370a0823190602401602060405180830381865afa158015612af0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b149190614697565b115b80612b9457506040516370a0823160e01b8152336004820152600090739c8ff314c9bc7f6e59a9d9225fb22946427edc03906370a0823190602401602060405180830381865afa158015612b6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b929190614697565b115b80612c1257506040516370a0823160e01b815233600482015260009073659a4bdaaacc62d2bd9cb18225d9c89b5b697a5a906370a0823190602401602060405180830381865afa158015612bec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c109190614697565b115b80612c9057506040516370a0823160e01b815233600482015260009073fa9ed22ca5d329ecaee9347f72e18c1fc291471b906370a0823190602401602060405180830381865afa158015612c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8e9190614697565b115b612cdc5760405162461bcd60e51b815260206004820152601f60248201527f7520646f6e74206c30306b206c316b3320636330202f206672656e203d5f3d006044820152606401610d3a565b612ce733600161333b565b336000908152601f602090815260408083208054600160ff199182168117909255948452602190925290912080549092168117909155601455565b61109781613952565b6000600d548314801561182d575050600c5414919050565b6013546001600160a01b03163314612d6d5760405162461bcd60e51b8152600401610d3a90614544565b601e5460ff1615612d7d57600080fd5b600054601954612d8d838361463f565b1115612d9857600080fd5b612da2338361333b565b5050601e805460ff19166001179055565b601780546124c99061450a565b6013546001600160a01b03163314612dea5760405162461bcd60e51b8152600401610d3a90614544565b6001600160a01b038116612e4f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d3a565b6110978161348c565b80516020808301919091206001600160e01b031981166000908152600285019092526040822054612f1557600184810180548083018255600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e087901c939093029290921790915586549283018755868252908190208551612ee7939190910191860190613e30565b506001808501546001600160e01b031990921660009081526002860160205260409020919091559050610c37565b6000915050610c37565b60008281526005602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000612f8682613355565b80519091506000906001600160a01b0316336001600160a01b03161480612fbd575033612fb284610ccf565b6001600160a01b0316145b80612fcf57508151612fcf9033610b6c565b9050806130395760405162461bcd60e51b815260206004820152603260248201527f455243373231413a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b6064820152608401610d3a565b846001600160a01b031682600001516001600160a01b0316146130ad5760405162461bcd60e51b815260206004820152602660248201527f455243373231413a207472616e736665722066726f6d20696e636f72726563746044820152651037bbb732b960d11b6064820152608401610d3a565b6001600160a01b0384166131115760405162461bcd60e51b815260206004820152602560248201527f455243373231413a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610d3a565b6131216000848460000151612f1f565b6001600160a01b03858116600090815260046020908152604080832080546001600160801b03198082166001600160801b03928316600019018316179092558986168086528386208054938416938316600190810190931693909317909255888552600390935281842080546001600160e01b031916909117600160a01b426001600160401b031602179055908601808352912054909116613214576131c8816000541190565b1561321457825160008281526003602090815260409091208054918601516001600160401b0316600160a01b026001600160e01b03199092166001600160a01b03909316929092171790555b5082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b5050505050565b606081600001805480602002602001604051908101604052809291908181526020016000905b828210156133305783829060005260206000200180546132a39061450a565b80601f01602080910402602001604051908101604052809291908181526020018280546132cf9061450a565b801561331c5780601f106132f15761010080835404028352916020019161331c565b820191906000526020600020905b8154815290600101906020018083116132ff57829003601f168201915b505050505081526020019060010190613284565b505050509050919050565b611702828260405180602001604052806000815250613b68565b6040805180820190915260008082526020820152613374826000541190565b6133d35760405162461bcd60e51b815260206004820152602a60248201527f455243373231413a206f776e657220717565727920666f72206e6f6e657869736044820152693a32b73a103a37b5b2b760b11b6064820152608401610d3a565b815b6000818152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b03169183019190915215613421579392505050565b50600019016133d5565b6001600160a01b03821660009081526008602052604081205460ff161561345457506001610c37565b506001600160a01b03821660009081526007602090815260408083206001600160e01b03198516845290915290205460ff1692915050565b601380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6134ef33611c446020850185613edf565b61367c57600061350560e0840160c0850161413c565b6001600160a01b03161461367c5761353561352660e0840160c0850161413c565b6001600160a01b03163b151590565b61357a5760405162461bcd60e51b8152602060048201526016602482015275455243353035303a20696e76616c696420737461746560501b6044820152606401610d3a565b61358a60e0830160c0840161413c565b6001600160a01b031663913c5c813484846040518463ffffffff1660e01b81526004016135b89291906147e3565b6000604051808303818588803b1580156135d157600080fd5b505af1935050505080156135e3575060015b61367c573d808015613611576040519150601f19603f3d011682016040523d82523d6000602084013e613616565b606091505b5080516000036136745760405162461bcd60e51b8152602060048201526024808201527f455243353035303a2063616c6c20746f206e6f6e20455243353035305265636560448201526334bb32b960e11b6064820152608401610d3a565b805181602001fd5b61368c60a083016080840161413c565b6001600160a01b03166136a5606084016040850161413c565b6001600160a01b03166136bb6020850185613edf565b6001600160e01b0319167f631a64c22ececeb533942f6a78b2f9a947d96349ef6d663b74e4732ac90061026136f6604087016020880161413c565b606087013560a088013561371060e08a0160c08b0161413c565b61371d60e08b018b6148c4565b60405161372f96959493929190614911565b60405180910390a45050565b60006001600160a01b0384163b1561382957604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061377f903390899088908890600401614958565b6020604051808303816000875af19250505080156137ba575060408051601f3d908101601f191682019092526137b791810190614995565b60015b61380f573d8080156137e8576040519150601f19603f3d011682016040523d82523d6000602084013e6137ed565b606091505b5080516000036136745760405162461bcd60e51b8152600401610d3a90614719565b6001600160e01b031916630a85bd0160e11b1490506126cf565b506001949350505050565b606060158054610c4c9061450a565b606060168054610c4c9061450a565b6060816000036138795750506040805180820190915260018152600360fc1b602082015290565b8160005b81156138a3578061388d816149b2565b915061389c9050600a836149e1565b915061387d565b6000816001600160401b038111156138bd576138bd614157565b6040519080825280601f01601f1916602001820160405280156138e7576020820181803683370190505b5090505b84156126cf576138fc600183614628565b9150613909600a866149f5565b61391490603061463f565b60f81b81838151811061392957613929614a09565b60200101906001600160f81b031916908160001a90535061394b600a866149e1565b94506138eb565b61396033826000015161342b565b613ad757604081015130905260608101515160808201516001600160a01b039182163b158015929091163b1515906000906139a157506060830151516139ae565b81156139ae575060808301515b60008380156139ba5750825b156139cd576139c885613b75565b50600c545b6001600160a01b0382163b15613ad25760405163913c5c8160e01b81526001600160a01b0383169063913c5c81903490613a0d9089908690600401614a1f565b6000604051808303818588803b158015613a2657600080fd5b505af193505050508015613a38575060015b613ad257613a44614ac2565b806308c379a003613a7d5750613a58614ade565b80613a635750613a7f565b8060405162461bcd60e51b8152600401610d3a9190613f54565b505b3d808015613aa9576040519150601f19603f3d011682016040523d82523d6000602084013e613aae565b606091505b50805115613ad0578060405162461bcd60e51b8152600401610d3a9190613f54565b505b505050505b8060600151600001516001600160a01b03168160400151600001516001600160a01b031682600001516001600160e01b0319167f0f884f8c03436e1dac6ede6cd6437e534a3c785d07aebe49186ceed53610bdd3846020015185604001516020015186606001516020015187608001518860a00151604051613b5d959493929190614b67565b60405180910390a450565b610e718383836001613beb565b600c60008154613b84906149b2565b9091555080516020808301516040808501518051908401516060870151805190860151608089015160a08a0151600c549651613bcd9a9996979596949593949293919201614bac565b60408051601f198184030181529190528051602090910120600d5550565b6000546001600160a01b038516613c4e5760405162461bcd60e51b815260206004820152602160248201527f455243373231413a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610d3a565b83600003613caf5760405162461bcd60e51b815260206004820152602860248201527f455243373231413a207175616e74697479206d75737420626520677265617465604482015267072207468616e20360c41b6064820152608401610d3a565b6001600160a01b03851660008181526004602090815260408083208054600160801b6001600160801b031982166001600160801b039283168c01831690811782900483168c01909216021790558483526003909152812080546001600160e01b031916909217600160a01b426001600160401b0316021790915581905b85811015613da75760405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48315613d9b57613d7f600088848861373b565b613d9b5760405162461bcd60e51b8152600401610d3a90614719565b60019182019101613d2c565b50600055613257565b828054613dbc9061450a565b90600052602060002090601f016020900481019282613dde5760008555613e24565b82601f10613df75782800160ff19823516178555613e24565b82800160010185558215613e24579182015b82811115613e24578235825591602001919060010190613e09565b50611675929150613ea4565b828054613e3c9061450a565b90600052602060002090601f016020900481019282613e5e5760008555613e24565b82601f10613e7757805160ff1916838001178555613e24565b82800160010185558215613e24579182015b82811115613e24578251825591602001919060010190613e89565b5b808211156116755760008155600101613ea5565b6001600160e01b03198116811461109757600080fd5b8035613eda81613eb9565b919050565b600060208284031215613ef157600080fd5b813561182d81613eb9565b60005b83811015613f17578181015183820152602001613eff565b8381111561130c5750506000910152565b60008151808452613f40816020860160208601613efc565b601f01601f19169290920160200192915050565b60208152600061182d6020830184613f28565b600060208284031215613f7957600080fd5b5035919050565b80356001600160a01b0381168114613eda57600080fd5b60008060408385031215613faa57600080fd5b613fb383613f80565b946020939093013593505050565b801515811461109757600080fd5b600060208284031215613fe157600080fd5b813561182d81613fc1565b60008060006060848603121561400157600080fd5b61400a84613f80565b925061401860208501613f80565b9150604084013590509250925092565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561407d57603f1988860301845261406b858351613f28565b9450928501929085019060010161404f565b5092979650505050505050565b6000806040838503121561409d57600080fd5b6140a683613f80565b915060208301356140b681613eb9565b809150509250929050565b6000806000604084860312156140d657600080fd5b8335925060208401356001600160401b03808211156140f457600080fd5b818601915086601f83011261410857600080fd5b81358181111561411757600080fd5b87602082850101111561412957600080fd5b6020830194508093505050509250925092565b60006020828403121561414e57600080fd5b61182d82613f80565b634e487b7160e01b600052604160045260246000fd5b60c081018181106001600160401b038211171561418c5761418c614157565b60405250565b601f8201601f191681016001600160401b03811182821017156141b7576141b7614157565b6040525050565b60006001600160401b038311156141d7576141d7614157565b6040516141ee601f8501601f191660200182614192565b80915083815284848401111561420357600080fd5b83836020830137600060208583010152509392505050565b60006020828403121561422d57600080fd5b81356001600160401b0381111561424357600080fd5b8201601f8101841361425457600080fd5b6126cf848235602084016141be565b6000806040838503121561427657600080fd5b61427f83613f80565b915060208301356140b681613fc1565b600080604083850312156142a257600080fd5b82356001600160401b038111156142b857600080fd5b83016101008186031215613fb357600080fd5b6000806000606084860312156142e057600080fd5b6142e984613f80565b925060208401356142f981613eb9565b915061430760408501613f80565b90509250925092565b600082601f83011261432157600080fd5b61182d838335602085016141be565b6000806000806080858703121561434657600080fd5b61434f85613f80565b935061435d60208601613f80565b92506040850135915060608501356001600160401b0381111561437f57600080fd5b61438b87828801614310565b91505092959194509250565b600080604083850312156143aa57600080fd5b6143b383613f80565b91506143c160208401613f80565b90509250929050565b6000604082840312156143dc57600080fd5b604051604081018181106001600160401b03821117156143fe576143fe614157565b60405290508061440d83613f80565b8152602083013560208201525092915050565b60006020828403121561443257600080fd5b81356001600160401b038082111561444957600080fd5b90830190610100828603121561445e57600080fd5b60405161446a8161416d565b61447383613ecf565b815261448160208401613f80565b602082015261449386604085016143ca565b60408201526144a586608085016143ca565b60608201526144b660c08401613f80565b608082015260e0830135828111156144cd57600080fd5b6144d987828601614310565b60a08301525095945050505050565b600080604083850312156144fb57600080fd5b50508035926020909101359150565b600181811c9082168061451e57607f821691505b60208210810361453e57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601d908201527f4d757368726f6f6d697a6174696f6e2069736e27742073746172746564000000604082015260600190565b60208082526011908201527027379039b837b932b9903632b33a17171760791b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008282101561463a5761463a614612565b500390565b6000821982111561465257614652614612565b500190565b60208082526007908201526607059502ff059560cd1b604082015260600190565b600081600019048311821515161561469257614692614612565b500290565b6000602082840312156146a957600080fd5b5051919050565b6000602082840312156146c257600080fd5b815161182d81613fc1565b6020808252602c908201527f4d757368726f6f6d733a2073656e646572206e6f74206f776e6572206f66207460408201526b686973206d757368726f6f6d60a01b606082015260800190565b60208082526033908201527f455243373231413a207472616e7366657220746f206e6f6e204552433732315260408201527232b1b2b4bb32b91034b6b83632b6b2b73a32b960691b606082015260800190565b6000835161477e818460208801613efc565b835190830190614792818360208801613efc565b01949350505050565b6001600160a01b036147ac82613f80565b168252602090810135910152565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60408152600083356147f481613eb9565b6001600160e01b031916604083015261480f60208501613f80565b6001600160a01b03818116606085015261482f608085016040880161479b565b61483f60c085016080880161479b565b61484b60c08701613f80565b91506101008183168186015260e08701359250601e1987360301831261487057600080fd5b91860191823591506001600160401b0382111561488c57600080fd5b81360387131561489b57600080fd5b6101208501526148b3610140850182602085016147ba565b925050508260208301529392505050565b6000808335601e198436030181126148db57600080fd5b8301803591506001600160401b038211156148f557600080fd5b60200191503681900382131561490a57600080fd5b9250929050565b6001600160a01b03878116825260208201879052604082018690528416606082015260a06080820181905260009061494c90830184866147ba565b98975050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061498b90830184613f28565b9695505050505050565b6000602082840312156149a757600080fd5b815161182d81613eb9565b6000600182016149c4576149c4614612565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826149f0576149f06149cb565b500490565b600082614a0457614a046149cb565b500690565b634e487b7160e01b600052603260045260246000fd5b604080825283516001600160e01b031916828201526020808501516001600160a01b039081166060850152918501518051831660808501529081015160a0840152600091606086015180516001600160a01b031660c0860152602081015160e086015291506080860151166101008481019190915260a08601516101208501919091529050614ab2610140840182613f28565b9150508260208301529392505050565b600060033d1115614adb5760046000803e5060005160e01c5b90565b600060443d1015614aec5790565b6040516003193d81016004833e81513d6001600160401b038160248401118184111715614b1b57505050505090565b8285019150815181811115614b335750505050505090565b843d8701016020828501011115614b4d5750505050505090565b614b5c60208286010187614192565b509095945050505050565b6001600160a01b03868116825260208201869052604082018590528316606082015260a060808201819052600090614ba190830184613f28565b979650505050505050565b63ffffffff60e01b8a16815260006bffffffffffffffffffffffff19808b60601b166004840152808a60601b16601884015288602c840152808860601b16604c840152866060840152808660601b166080840152508351614c14816094850160208801613efc565b609492019182019290925260b401999850505050505050505056fea26469706673582212206d0908a0a7508346349dac082e182c5f0af4b7587b78a7139da0117d0a3d79ac64736f6c634300080d0033

Deployed Bytecode

0x6080604052600436106103ad5760003560e01c80638da5cb5b116101e7578063c0bf3e2d1161010d578063d960e59c116100a0578063e8b5498d1161006f578063e8b5498d14610b37578063e985e9c514610b51578063edf1633b14610b9a578063f2fde38b14610bb057600080fd5b8063d960e59c14610acf578063df89318814610ae2578063e0f11fc914610b02578063e3a5da2a14610b2257600080fd5b8063c918c931116100dc578063c918c93114610a0d578063cc4269b514610a56578063d3eff42014610a6b578063d715d0ec14610a9f57600080fd5b8063c0bf3e2d14610987578063c1e27865146109b7578063c22515c5146109d7578063c87b56dd146109ed57600080fd5b8063a22cb46511610185578063b19b91bd11610154578063b19b91bd14610927578063b88d4fde1461093c578063b91b07731461095c578063bc3b0d491461097157600080fd5b8063a22cb465146108a1578063ac8fa4ed146108c1578063ad504321146108d7578063af388a741461090757600080fd5b806391e31131116101c157806391e311311461081057806395d89b41146108305780639601ed6214610845578063a0768c531461087557600080fd5b80638da5cb5b146107bf578063900bdd57146107dd578063913c5c81146107fd57600080fd5b806347fa15f9116102d75780636352211e1161026a5780637534cb68116102395780637534cb681461074857806375b161961461077557806378f14b9c146107955780638b035e75146107aa57600080fd5b80636352211e146106d357806369d8e231146106f357806370a0823114610713578063715018a61461073357600080fd5b806352873694116102a6578063528736941461065d5780635c073c391461067d578063606c2a1f146106935780636233b0ba146106b357600080fd5b806347fa15f9146105f05780634c79aeec1461060a5780634cf362bb1461061d5780634f6ccce71461063d57600080fd5b8063286cc2401161034f5780633d643cca1161031e5780633d643cca146105595780633f8d90391461056157806342842e0e146105b057806344365db1146105d057600080fd5b8063286cc240146104c25780632f745c591461050f57806333958a181461052f578063395288891461053757600080fd5b8063095ea7b31161038b578063095ea7b31461044157806316d1910a1461046357806318160ddd1461048357806323b872dd146104a257600080fd5b806301ffc9a7146103b257806306fdde03146103e7578063081812fc14610409575b600080fd5b3480156103be57600080fd5b506103d26103cd366004613edf565b610bd0565b60405190151581526020015b60405180910390f35b3480156103f357600080fd5b506103fc610c3d565b6040516103de9190613f54565b34801561041557600080fd5b50610429610424366004613f67565b610ccf565b6040516001600160a01b0390911681526020016103de565b34801561044d57600080fd5b5061046161045c366004613f97565b610d5f565b005b34801561046f57600080fd5b5061046161047e366004613fcf565b610e76565b34801561048f57600080fd5b506000545b6040519081526020016103de565b3480156104ae57600080fd5b506104616104bd366004613fec565b610eb3565b3480156104ce57600080fd5b506104f67f416136f98a37e21524754716a91ac1d0c28c851be9745167497f08b033e0808281565b6040516001600160e01b031990911681526020016103de565b34801561051b57600080fd5b5061049461052a366004613f97565b610ebe565b610461611018565b34801561054357600080fd5b5061054c61109a565b6040516103de9190614028565b6104616110ab565b34801561056d57600080fd5b5061042961057c36600461408a565b6001600160a01b039182166000908152600e602090815260408083206001600160e01b031994909416835292905220541690565b3480156105bc57600080fd5b506104616105cb366004613fec565b611227565b3480156105dc57600080fd5b506104616105eb3660046140c1565b611242565b3480156105fc57600080fd5b506018546103d29060ff1681565b610461610618366004613f67565b611312565b34801561062957600080fd5b50610461610638366004613f97565b6114c4565b34801561064957600080fd5b50610494610658366004613f67565b611617565b34801561066957600080fd5b5061046161067836600461413c565b611679565b34801561068957600080fd5b50610494601d5481565b34801561069f57600080fd5b506104616106ae36600461421b565b6116c5565b3480156106bf57600080fd5b506104616106ce36600461413c565b611706565b3480156106df57600080fd5b506104296106ee366004613f67565b61180f565b3480156106ff57600080fd5b506103d261070e36600461408a565b611821565b34801561071f57600080fd5b5061049461072e36600461413c565b611834565b34801561073f57600080fd5b506104616118c5565b34801561075457600080fd5b50610494610763366004613f67565b60236020526000908152604090205481565b34801561078157600080fd5b50610461610790366004614263565b6118fb565b3480156107a157600080fd5b5061046161195a565b3480156107b657600080fd5b5061054c611b60565b3480156107cb57600080fd5b506013546001600160a01b0316610429565b3480156107e957600080fd5b506104616107f8366004614263565b611b6c565b61046161080b36600461428f565b611c31565b34801561081c57600080fd5b506103d261082b3660046142cb565b612209565b34801561083c57600080fd5b506103fc61238c565b34801561085157600080fd5b506103d2610860366004613f67565b60246020526000908152604090205460ff1681565b34801561088157600080fd5b5061049461089036600461413c565b602080526000908152604090205481565b3480156108ad57600080fd5b506104616108bc366004614263565b61239b565b3480156108cd57600080fd5b50610494601a5481565b3480156108e357600080fd5b506103d26108f2366004613f67565b60226020526000908152604090205460ff1681565b34801561091357600080fd5b5061046161092236600461408a565b612458565b34801561093357600080fd5b506103fc6124bc565b34801561094857600080fd5b50610461610957366004614330565b61254a565b34801561096857600080fd5b506103fc61257d565b34801561097d57600080fd5b50610494601c5481565b34801561099357600080fd5b506103d26109a236600461413c565b601f6020526000908152604090205460ff1681565b3480156109c357600080fd5b506104616109d236600461421b565b61258a565b3480156109e357600080fd5b5061049460195481565b3480156109f957600080fd5b506103fc610a08366004613f67565b6125c7565b348015610a1957600080fd5b506103d2610a28366004614397565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205460ff1690565b348015610a6257600080fd5b506104616126d7565b348015610a7757600080fd5b506104f67fc87efa307383f1235ff7b0df46a7017e5bdc9dcb3964f21a9b5d6f1cf723702d81565b348015610aab57600080fd5b506103d2610aba366004613f67565b60216020526000908152604090205460ff1681565b610461610add366004614420565b612d22565b348015610aee57600080fd5b506103d2610afd3660046144e8565b612d2b565b348015610b0e57600080fd5b50610461610b1d366004613f67565b612d43565b348015610b2e57600080fd5b506103fc612db3565b348015610b4357600080fd5b50601e546103d29060ff1681565b348015610b5d57600080fd5b506103d2610b6c366004614397565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b348015610ba657600080fd5b50610494601b5481565b348015610bbc57600080fd5b50610461610bcb36600461413c565b612dc0565b60006001600160e01b031982166380ac58cd60e01b1480610c0157506001600160e01b03198216635b5e139f60e01b145b80610c1c57506001600160e01b0319821663780e9d6360e01b145b80610c3757506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060018054610c4c9061450a565b80601f0160208091040260200160405190810160405280929190818152602001828054610c789061450a565b8015610cc55780601f10610c9a57610100808354040283529160200191610cc5565b820191906000526020600020905b815481529060010190602001808311610ca857829003601f168201915b5050505050905090565b6000610cdc826000541190565b610d435760405162461bcd60e51b815260206004820152602d60248201527f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560448201526c3c34b9ba32b73a103a37b5b2b760991b60648201526084015b60405180910390fd5b506000908152600560205260409020546001600160a01b031690565b6000610d6a8261180f565b9050806001600160a01b0316836001600160a01b031603610dd85760405162461bcd60e51b815260206004820152602260248201527f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60448201526132b960f11b6064820152608401610d3a565b336001600160a01b0382161480610df45750610df48133610b6c565b610e665760405162461bcd60e51b815260206004820152603960248201527f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656420666f7220616c6c000000000000006064820152608401610d3a565b610e71838383612f1f565b505050565b6013546001600160a01b03163314610ea05760405162461bcd60e51b8152600401610d3a90614544565b6018805460ff1916911515919091179055565b610e71838383612f7b565b6000610ec983611834565b8210610f225760405162461bcd60e51b815260206004820152602260248201527f455243373231413a206f776e657220696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610d3a565b600080549080805b83811015610fb8576000818152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b03169183019190915215610f7c57805192505b876001600160a01b0316836001600160a01b031603610faf57868403610fa857509350610c3792505050565b6001909301925b50600101610f2a565b5060405162461bcd60e51b815260206004820152602e60248201527f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060448201526d0deeedccae440c4f240d2dcc8caf60931b6064820152608401610d3a565b6013546001600160a01b031633146110425760405162461bcd60e51b8152600401610d3a90614544565b604051600090339047908381818185875af1925050503d8060008114611084576040519150601f19603f3d011682016040523d82523d6000602084013e611089565b606091505b505090508061109757600080fd5b50565b60606110a6600961325e565b905090565b6002601454036110cd5760405162461bcd60e51b8152600401610d3a90614579565b600260145560005460185460ff166110f75760405162461bcd60e51b8152600401610d3a906145b0565b6000601a54116111425760405162461bcd60e51b815260206004820152601660248201527527379036b7b932903632b2ba1039b837b932b997171760511b6044820152606401610d3a565b60195481106111635760405162461bcd60e51b8152600401610d3a906145e7565b33321461116f57600080fd5b670459505acd43a0003410156111e35760405162461bcd60e51b815260206004820152603360248201527f526f79616c205368726f6f6d7320726571756972696e6720e381a4e297955fe26044820152724bcaf1c0d2101817199899999b9032ba3432b960691b6064820152608401610d3a565b6111ee33600161333b565b6001601a60008282546112019190614628565b90915550506000908152602460205260409020805460ff19166001908117909155601455565b610e718383836040518060200160405280600081525061254a565b61124b8361180f565b6001600160a01b0316336001600160a01b0316146112ab5760405162461bcd60e51b815260206004820152601b60248201527f4d757368726f6f6d733a2073656e646572206e6f74206f776e657200000000006044820152606401610d3a565b60008381526024602052604090205460ff166113005760405162461bcd60e51b8152602060048201526014602482015273135d5cda1c9bdbdb481a5cdb89dd081c9bde585b60621b6044820152606401610d3a565b61130c60178383613db0565b50505050565b6002601454036113345760405162461bcd60e51b8152600401610d3a90614579565b6002601455601854819060ff1661135d5760405162461bcd60e51b8152600401610d3a906145b0565b6019548161136a60005490565b611374919061463f565b11156113925760405162461bcd60e51b8152600401610d3a906145e7565b3233146113b15760405162461bcd60e51b8152600401610d3a90614657565b336000908152602080526040902054601d546113cd848361463f565b11156114115760405162461bcd60e51b8152602060048201526013602482015272155cd95c881b585e081b5a5b9d081b1a5b5a5d606a1b6044820152606401610d3a565b61142283669536c708910000614678565b3410156114975760405162461bcd60e51b815260206004820152603760248201527f576f772c20706c732061747461636820302e303432302065746865722070657260448201527f206d757368726f6f6d20e381a4e297955fe29795e381a40000000000000000006064820152608401610d3a565b6114a1338461333b565b6114ab838261463f565b3360009081526020805260409020555050600160145550565b6002601454036114e65760405162461bcd60e51b8152600401610d3a90614579565b600260145560185460019060ff166115105760405162461bcd60e51b8152600401610d3a906145b0565b6019548161151d60005490565b611527919061463f565b11156115455760405162461bcd60e51b8152600401610d3a906145e7565b3233146115645760405162461bcd60e51b8152600401610d3a90614657565b6001600160a01b038316330361157957600080fd5b336115838361180f565b6001600160a01b03161461159657600080fd5b60008281526021602052604090205460ff166115ed5760405162461bcd60e51b81526020600482015260166024820152756e6f2073706f72657320696e207572207368726f6f6d60501b6044820152606401610d3a565b6115f883600161333b565b506000908152602160205260409020805460ff19169055506001601455565b6000805482106116755760405162461bcd60e51b815260206004820152602360248201527f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f756044820152626e647360e81b6064820152608401610d3a565b5090565b6013546001600160a01b031633146116a35760405162461bcd60e51b8152600401610d3a90614544565b602580546001600160a01b0319166001600160a01b0392909216919091179055565b6013546001600160a01b031633146116ef5760405162461bcd60e51b8152600401610d3a90614544565b8051611702906016906020840190613e30565b5050565b6013546001600160a01b031633146117305760405162461bcd60e51b8152600401610d3a90614544565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611777573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061179b9190614697565b60405163a9059cbb60e01b8152336004820152602481018290529091506001600160a01b0383169063a9059cbb906044016020604051808303816000875af11580156117eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e7191906146b0565b600061181a82613355565b5192915050565b600061182d838361342b565b9392505050565b60006001600160a01b0382166118a05760405162461bcd60e51b815260206004820152602b60248201527f455243373231413a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b6064820152608401610d3a565b506001600160a01b03166000908152600460205260409020546001600160801b031690565b6013546001600160a01b031633146118ef5760405162461bcd60e51b8152600401610d3a90614544565b6118f9600061348c565b565b6001600160a01b038216600081815260086020908152604091829020805460ff191685151590811790915591519182527fb033bedede81cc9e0eb1e2341b52e2c78e2ec38ba3e979113dd42533a3958325910160405180910390a25050565b60026014540361197c5760405162461bcd60e51b8152600401610d3a90614579565b600260145560185460019060ff166119a65760405162461bcd60e51b8152600401610d3a906145b0565b601954816119b360005490565b6119bd919061463f565b11156119db5760405162461bcd60e51b8152600401610d3a906145e7565b3233146119fa5760405162461bcd60e51b8152600401610d3a90614657565b336000908152601f602052604090205460ff1615611a555760405162461bcd60e51b8152602060048201526018602482015277135d5cda1c9bdbdb48185b1c9958591e4818db185a5b595960421b6044820152606401610d3a565b6040516370a0823160e01b815261dead600482015273659a4bdaaacc62d2bd9cb18225d9c89b5b697a5a906370a0823190602401602060405180830381865afa158015611aa6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aca9190614697565b601c5410611b1a5760405162461bcd60e51b815260206004820152601c60248201527f416c6c20746865206465616420616c7265616479207265626f726e2e000000006044820152606401610d3a565b611b2533600161333b565b6001601c6000828254611b38919061463f565b9091555050336000908152601f60205260409020805460ff1916600190811790915560145550565b60606110a6601061325e565b6001600160a01b0382163303611bc45760405162461bcd60e51b815260206004820152601a60248201527f455243353035303a20617070726f766520746f2063616c6c65720000000000006044820152606401610d3a565b336000818152600f602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917fe37230f00e3b15e90e6a606f3b77be179b2808cc3bc970e51c9e046f8a6683e091015b60405180910390a35050565b8181611c4933611c446020850185613edf565b61342b565b61130c5730611c5e60a084016080850161413c565b6001600160a01b031614611cb45760405162461bcd60e51b815260206004820152601960248201527f455243353035303a20696e76616c6964207265636569766572000000000000006044820152606401610d3a565b611ce2611cc46020840184613edf565b6001600160e01b031916600090815260126020526040902054151590565b611d2e5760405162461bcd60e51b815260206004820152601760248201527f455243353035303a20696e76616c696420616374696f6e0000000000000000006044820152606401610d3a565b6000611d40606084016040850161413c565b6001600160a01b03161480611d6c575033611d61606084016040850161413c565b6001600160a01b0316145b611db25760405162461bcd60e51b815260206004820152601760248201527622a9219a981a981d1034b73b30b634b21039b2b73232b960491b6044820152606401610d3a565b6000611dc4606084016040850161413c565b6001600160a01b031614158015611df2575032611de7604084016020850161413c565b6001600160a01b0316145b80611e14575033611e09604084016020850161413c565b6001600160a01b0316145b611e5a5760405162461bcd60e51b815260206004820152601760248201527622a9219a981a981d1034b73b30b634b21039b2b73232b960491b6044820152606401610d3a565b63416136f960e01b611e6f6020860186613edf565b6001600160e01b0319161480611ea15750630c87efa360e41b611e956020860186613edf565b6001600160e01b031916145b611ef85760405162461bcd60e51b815260206004820152602260248201527f4d757368726f6f6d733a20696e76616c696420616374696f6e2e73656c65637460448201526137b960f11b6064820152608401610d3a565b63416136f960e01b611f0d6020860186613edf565b6001600160e01b031916036120b9576025546001600160a01b0316611f38606086016040870161413c565b6001600160a01b031614611f8e5760405162461bcd60e51b815260206004820152601e60248201527f4d757368726f6f6d733a20696e76616c696420616374696f6e2e66726f6d00006044820152606401610d3a565b611f9b60a085013561180f565b6001600160a01b0316611fb4604086016020870161413c565b6001600160a01b031614611fda5760405162461bcd60e51b8152600401610d3a906146cd565b60a084013560009081526022602052604090205460ff161561203e5760405162461bcd60e51b815260206004820152601960248201527f4f6e6c79206f6e6520636173742070657220746f6b656e4944000000000000006044820152606401610d3a565b6000601b541161207f5760405162461bcd60e51b815260206004820152600c60248201526b139bc81b585b98481b19599d60a21b6044820152606401610d3a565b60a08401356000908152602260205260408120805460ff19166001908117909155601b8054919290916120b3908490614628565b90915550505b630c87efa360e41b6120ce6020860186613edf565b6001600160e01b031916036121ff576120ea60a085013561180f565b6001600160a01b0316612103604086016020870161413c565b6001600160a01b0316146121295760405162461bcd60e51b8152600401610d3a906146cd565b60a08401356000908152602360205260409020546113889061214c904390614628565b106121b15760405162461bcd60e51b815260206004820152602f60248201527f596f752063616e20656174206d757368726f6f6d73206f6e6c79206f6e63652060448201526e706572203530303020626c6f636b7360881b6064820152608401610d3a565b60405160a085013581527f6af461f4cf15493d302e35a159caaf851c28f69956626168ff6fd5530bce984e9060200160405180910390a160a084013560009081526023602052604090204390555b61130c84846134de565b6000836001600160a01b0316826001600160a01b03160361226c5760405162461bcd60e51b815260206004820152601a60248201527f455243353035303a20617070726f766520746f2063616c6c65720000000000006044820152606401610d3a565b336001600160a01b03851614806122a657506001600160a01b0384166000908152600f6020908152604080832033845290915290205460ff165b6123185760405162461bcd60e51b815260206004820152603b60248201527f455243353035303a20617070726f76652063616c6c6572206973206e6f74206160448201527f63636f756e74206e6f7220617070726f76656420666f7220616c6c00000000006064820152608401610d3a565b6001600160a01b038481166000818152600e602090815260408083206001600160e01b03198916808552925280832080546001600160a01b0319169588169586179055519092917f57f9e4aa0c479eb6b4954eeaf36d835de17e7b2df00ce50976dfeba4eff89bbc91a45060019392505050565b606060028054610c4c9061450a565b336001600160a01b038316036123f35760405162461bcd60e51b815260206004820152601a60248201527f455243373231413a20617070726f766520746f2063616c6c65720000000000006044820152606401610d3a565b3360008181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319101611c25565b6001600160a01b03821660008181526007602090815260408083206001600160e01b031986168085529252808320805460ff19166001179055519092917f1f4f9056d5481d98c73db2f5a7dc2f115ea15727de4cebe53204edaa4afe831791a35050565b601680546124c99061450a565b80601f01602080910402602001604051908101604052809291908181526020018280546124f59061450a565b80156125425780601f1061251757610100808354040283529160200191612542565b820191906000526020600020905b81548152906001019060200180831161252557829003601f168201915b505050505081565b612555848484612f7b565b6125618484848461373b565b61130c5760405162461bcd60e51b8152600401610d3a90614719565b601580546124c99061450a565b6013546001600160a01b031633146125b45760405162461bcd60e51b8152600401610d3a90614544565b8051611702906015906020840190613e30565b60606125d4826000541190565b6126385760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610d3a565b6000612642613834565b9050600061264e613843565b60008581526022602052604090205490915060ff16801561266f5750805115155b156126a7578061267e85613852565b60405160200161268f92919061476c565b60405160208183030381529060405292505050919050565b81516000036126c557604051806020016040528060008152506126cf565b8161267e85613852565b949350505050565b6002601454036126f95760405162461bcd60e51b8152600401610d3a90614579565b600260145560005460185460ff166127235760405162461bcd60e51b8152600401610d3a906145b0565b60195481106127445760405162461bcd60e51b8152600401610d3a906145e7565b33321461275057600080fd5b336000908152601f602052604090205460ff16156127ab5760405162461bcd60e51b8152602060048201526018602482015277135d5cda1c9bdbdb48185b1c9958591e4818db185a5b595960421b6044820152606401610d3a565b6040516370a0823160e01b815233600482015260009073bce3781ae7ca1a5e050bd9c4c77369867ebc307e906370a0823190602401602060405180830381865afa1580156127fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128219190614697565b11806128a057506040516370a0823160e01b8152336004820152600090730290d49f53a8d186973b82faafdafe696b29acbb906370a0823190602401602060405180830381865afa15801561287a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061289e9190614697565b115b8061291e57506040516370a0823160e01b815233600482015260009073ff9c1b15b16263c61d017ee9f65c50e4ae0113d7906370a0823190602401602060405180830381865afa1580156128f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061291c9190614697565b115b8061299c57506040516370a0823160e01b8152336004820152600090738db687aceb92c66f013e1d614137238cc698fedb906370a0823190602401602060405180830381865afa158015612976573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299a9190614697565b115b80612a1a57506040516370a0823160e01b8152336004820152600090731cb1a5e65610aeff2551a50f76a87a7d3fb649c6906370a0823190602401602060405180830381865afa1580156129f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a189190614697565b115b80612a9857506040516370a0823160e01b815233600482015260009073448f3219cf2a23b0527a7a0158e7264b87f635db906370a0823190602401602060405180830381865afa158015612a72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a969190614697565b115b80612b1657506040516370a0823160e01b81523360048201526000907397597002980134bea46250aa0510c9b90d87a587906370a0823190602401602060405180830381865afa158015612af0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b149190614697565b115b80612b9457506040516370a0823160e01b8152336004820152600090739c8ff314c9bc7f6e59a9d9225fb22946427edc03906370a0823190602401602060405180830381865afa158015612b6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b929190614697565b115b80612c1257506040516370a0823160e01b815233600482015260009073659a4bdaaacc62d2bd9cb18225d9c89b5b697a5a906370a0823190602401602060405180830381865afa158015612bec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c109190614697565b115b80612c9057506040516370a0823160e01b815233600482015260009073fa9ed22ca5d329ecaee9347f72e18c1fc291471b906370a0823190602401602060405180830381865afa158015612c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c8e9190614697565b115b612cdc5760405162461bcd60e51b815260206004820152601f60248201527f7520646f6e74206c30306b206c316b3320636330202f206672656e203d5f3d006044820152606401610d3a565b612ce733600161333b565b336000908152601f602090815260408083208054600160ff199182168117909255948452602190925290912080549092168117909155601455565b61109781613952565b6000600d548314801561182d575050600c5414919050565b6013546001600160a01b03163314612d6d5760405162461bcd60e51b8152600401610d3a90614544565b601e5460ff1615612d7d57600080fd5b600054601954612d8d838361463f565b1115612d9857600080fd5b612da2338361333b565b5050601e805460ff19166001179055565b601780546124c99061450a565b6013546001600160a01b03163314612dea5760405162461bcd60e51b8152600401610d3a90614544565b6001600160a01b038116612e4f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610d3a565b6110978161348c565b80516020808301919091206001600160e01b031981166000908152600285019092526040822054612f1557600184810180548083018255600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e087901c939093029290921790915586549283018755868252908190208551612ee7939190910191860190613e30565b506001808501546001600160e01b031990921660009081526002860160205260409020919091559050610c37565b6000915050610c37565b60008281526005602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6000612f8682613355565b80519091506000906001600160a01b0316336001600160a01b03161480612fbd575033612fb284610ccf565b6001600160a01b0316145b80612fcf57508151612fcf9033610b6c565b9050806130395760405162461bcd60e51b815260206004820152603260248201527f455243373231413a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b6064820152608401610d3a565b846001600160a01b031682600001516001600160a01b0316146130ad5760405162461bcd60e51b815260206004820152602660248201527f455243373231413a207472616e736665722066726f6d20696e636f72726563746044820152651037bbb732b960d11b6064820152608401610d3a565b6001600160a01b0384166131115760405162461bcd60e51b815260206004820152602560248201527f455243373231413a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610d3a565b6131216000848460000151612f1f565b6001600160a01b03858116600090815260046020908152604080832080546001600160801b03198082166001600160801b03928316600019018316179092558986168086528386208054938416938316600190810190931693909317909255888552600390935281842080546001600160e01b031916909117600160a01b426001600160401b031602179055908601808352912054909116613214576131c8816000541190565b1561321457825160008281526003602090815260409091208054918601516001600160401b0316600160a01b026001600160e01b03199092166001600160a01b03909316929092171790555b5082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b5050505050565b606081600001805480602002602001604051908101604052809291908181526020016000905b828210156133305783829060005260206000200180546132a39061450a565b80601f01602080910402602001604051908101604052809291908181526020018280546132cf9061450a565b801561331c5780601f106132f15761010080835404028352916020019161331c565b820191906000526020600020905b8154815290600101906020018083116132ff57829003601f168201915b505050505081526020019060010190613284565b505050509050919050565b611702828260405180602001604052806000815250613b68565b6040805180820190915260008082526020820152613374826000541190565b6133d35760405162461bcd60e51b815260206004820152602a60248201527f455243373231413a206f776e657220717565727920666f72206e6f6e657869736044820152693a32b73a103a37b5b2b760b11b6064820152608401610d3a565b815b6000818152600360209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b03169183019190915215613421579392505050565b50600019016133d5565b6001600160a01b03821660009081526008602052604081205460ff161561345457506001610c37565b506001600160a01b03821660009081526007602090815260408083206001600160e01b03198516845290915290205460ff1692915050565b601380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6134ef33611c446020850185613edf565b61367c57600061350560e0840160c0850161413c565b6001600160a01b03161461367c5761353561352660e0840160c0850161413c565b6001600160a01b03163b151590565b61357a5760405162461bcd60e51b8152602060048201526016602482015275455243353035303a20696e76616c696420737461746560501b6044820152606401610d3a565b61358a60e0830160c0840161413c565b6001600160a01b031663913c5c813484846040518463ffffffff1660e01b81526004016135b89291906147e3565b6000604051808303818588803b1580156135d157600080fd5b505af1935050505080156135e3575060015b61367c573d808015613611576040519150601f19603f3d011682016040523d82523d6000602084013e613616565b606091505b5080516000036136745760405162461bcd60e51b8152602060048201526024808201527f455243353035303a2063616c6c20746f206e6f6e20455243353035305265636560448201526334bb32b960e11b6064820152608401610d3a565b805181602001fd5b61368c60a083016080840161413c565b6001600160a01b03166136a5606084016040850161413c565b6001600160a01b03166136bb6020850185613edf565b6001600160e01b0319167f631a64c22ececeb533942f6a78b2f9a947d96349ef6d663b74e4732ac90061026136f6604087016020880161413c565b606087013560a088013561371060e08a0160c08b0161413c565b61371d60e08b018b6148c4565b60405161372f96959493929190614911565b60405180910390a45050565b60006001600160a01b0384163b1561382957604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061377f903390899088908890600401614958565b6020604051808303816000875af19250505080156137ba575060408051601f3d908101601f191682019092526137b791810190614995565b60015b61380f573d8080156137e8576040519150601f19603f3d011682016040523d82523d6000602084013e6137ed565b606091505b5080516000036136745760405162461bcd60e51b8152600401610d3a90614719565b6001600160e01b031916630a85bd0160e11b1490506126cf565b506001949350505050565b606060158054610c4c9061450a565b606060168054610c4c9061450a565b6060816000036138795750506040805180820190915260018152600360fc1b602082015290565b8160005b81156138a3578061388d816149b2565b915061389c9050600a836149e1565b915061387d565b6000816001600160401b038111156138bd576138bd614157565b6040519080825280601f01601f1916602001820160405280156138e7576020820181803683370190505b5090505b84156126cf576138fc600183614628565b9150613909600a866149f5565b61391490603061463f565b60f81b81838151811061392957613929614a09565b60200101906001600160f81b031916908160001a90535061394b600a866149e1565b94506138eb565b61396033826000015161342b565b613ad757604081015130905260608101515160808201516001600160a01b039182163b158015929091163b1515906000906139a157506060830151516139ae565b81156139ae575060808301515b60008380156139ba5750825b156139cd576139c885613b75565b50600c545b6001600160a01b0382163b15613ad25760405163913c5c8160e01b81526001600160a01b0383169063913c5c81903490613a0d9089908690600401614a1f565b6000604051808303818588803b158015613a2657600080fd5b505af193505050508015613a38575060015b613ad257613a44614ac2565b806308c379a003613a7d5750613a58614ade565b80613a635750613a7f565b8060405162461bcd60e51b8152600401610d3a9190613f54565b505b3d808015613aa9576040519150601f19603f3d011682016040523d82523d6000602084013e613aae565b606091505b50805115613ad0578060405162461bcd60e51b8152600401610d3a9190613f54565b505b505050505b8060600151600001516001600160a01b03168160400151600001516001600160a01b031682600001516001600160e01b0319167f0f884f8c03436e1dac6ede6cd6437e534a3c785d07aebe49186ceed53610bdd3846020015185604001516020015186606001516020015187608001518860a00151604051613b5d959493929190614b67565b60405180910390a450565b610e718383836001613beb565b600c60008154613b84906149b2565b9091555080516020808301516040808501518051908401516060870151805190860151608089015160a08a0151600c549651613bcd9a9996979596949593949293919201614bac565b60408051601f198184030181529190528051602090910120600d5550565b6000546001600160a01b038516613c4e5760405162461bcd60e51b815260206004820152602160248201527f455243373231413a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610d3a565b83600003613caf5760405162461bcd60e51b815260206004820152602860248201527f455243373231413a207175616e74697479206d75737420626520677265617465604482015267072207468616e20360c41b6064820152608401610d3a565b6001600160a01b03851660008181526004602090815260408083208054600160801b6001600160801b031982166001600160801b039283168c01831690811782900483168c01909216021790558483526003909152812080546001600160e01b031916909217600160a01b426001600160401b0316021790915581905b85811015613da75760405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a48315613d9b57613d7f600088848861373b565b613d9b5760405162461bcd60e51b8152600401610d3a90614719565b60019182019101613d2c565b50600055613257565b828054613dbc9061450a565b90600052602060002090601f016020900481019282613dde5760008555613e24565b82601f10613df75782800160ff19823516178555613e24565b82800160010185558215613e24579182015b82811115613e24578235825591602001919060010190613e09565b50611675929150613ea4565b828054613e3c9061450a565b90600052602060002090601f016020900481019282613e5e5760008555613e24565b82601f10613e7757805160ff1916838001178555613e24565b82800160010185558215613e24579182015b82811115613e24578251825591602001919060010190613e89565b5b808211156116755760008155600101613ea5565b6001600160e01b03198116811461109757600080fd5b8035613eda81613eb9565b919050565b600060208284031215613ef157600080fd5b813561182d81613eb9565b60005b83811015613f17578181015183820152602001613eff565b8381111561130c5750506000910152565b60008151808452613f40816020860160208601613efc565b601f01601f19169290920160200192915050565b60208152600061182d6020830184613f28565b600060208284031215613f7957600080fd5b5035919050565b80356001600160a01b0381168114613eda57600080fd5b60008060408385031215613faa57600080fd5b613fb383613f80565b946020939093013593505050565b801515811461109757600080fd5b600060208284031215613fe157600080fd5b813561182d81613fc1565b60008060006060848603121561400157600080fd5b61400a84613f80565b925061401860208501613f80565b9150604084013590509250925092565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561407d57603f1988860301845261406b858351613f28565b9450928501929085019060010161404f565b5092979650505050505050565b6000806040838503121561409d57600080fd5b6140a683613f80565b915060208301356140b681613eb9565b809150509250929050565b6000806000604084860312156140d657600080fd5b8335925060208401356001600160401b03808211156140f457600080fd5b818601915086601f83011261410857600080fd5b81358181111561411757600080fd5b87602082850101111561412957600080fd5b6020830194508093505050509250925092565b60006020828403121561414e57600080fd5b61182d82613f80565b634e487b7160e01b600052604160045260246000fd5b60c081018181106001600160401b038211171561418c5761418c614157565b60405250565b601f8201601f191681016001600160401b03811182821017156141b7576141b7614157565b6040525050565b60006001600160401b038311156141d7576141d7614157565b6040516141ee601f8501601f191660200182614192565b80915083815284848401111561420357600080fd5b83836020830137600060208583010152509392505050565b60006020828403121561422d57600080fd5b81356001600160401b0381111561424357600080fd5b8201601f8101841361425457600080fd5b6126cf848235602084016141be565b6000806040838503121561427657600080fd5b61427f83613f80565b915060208301356140b681613fc1565b600080604083850312156142a257600080fd5b82356001600160401b038111156142b857600080fd5b83016101008186031215613fb357600080fd5b6000806000606084860312156142e057600080fd5b6142e984613f80565b925060208401356142f981613eb9565b915061430760408501613f80565b90509250925092565b600082601f83011261432157600080fd5b61182d838335602085016141be565b6000806000806080858703121561434657600080fd5b61434f85613f80565b935061435d60208601613f80565b92506040850135915060608501356001600160401b0381111561437f57600080fd5b61438b87828801614310565b91505092959194509250565b600080604083850312156143aa57600080fd5b6143b383613f80565b91506143c160208401613f80565b90509250929050565b6000604082840312156143dc57600080fd5b604051604081018181106001600160401b03821117156143fe576143fe614157565b60405290508061440d83613f80565b8152602083013560208201525092915050565b60006020828403121561443257600080fd5b81356001600160401b038082111561444957600080fd5b90830190610100828603121561445e57600080fd5b60405161446a8161416d565b61447383613ecf565b815261448160208401613f80565b602082015261449386604085016143ca565b60408201526144a586608085016143ca565b60608201526144b660c08401613f80565b608082015260e0830135828111156144cd57600080fd5b6144d987828601614310565b60a08301525095945050505050565b600080604083850312156144fb57600080fd5b50508035926020909101359150565b600181811c9082168061451e57607f821691505b60208210810361453e57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601d908201527f4d757368726f6f6d697a6174696f6e2069736e27742073746172746564000000604082015260600190565b60208082526011908201527027379039b837b932b9903632b33a17171760791b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008282101561463a5761463a614612565b500390565b6000821982111561465257614652614612565b500190565b60208082526007908201526607059502ff059560cd1b604082015260600190565b600081600019048311821515161561469257614692614612565b500290565b6000602082840312156146a957600080fd5b5051919050565b6000602082840312156146c257600080fd5b815161182d81613fc1565b6020808252602c908201527f4d757368726f6f6d733a2073656e646572206e6f74206f776e6572206f66207460408201526b686973206d757368726f6f6d60a01b606082015260800190565b60208082526033908201527f455243373231413a207472616e7366657220746f206e6f6e204552433732315260408201527232b1b2b4bb32b91034b6b83632b6b2b73a32b960691b606082015260800190565b6000835161477e818460208801613efc565b835190830190614792818360208801613efc565b01949350505050565b6001600160a01b036147ac82613f80565b168252602090810135910152565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60408152600083356147f481613eb9565b6001600160e01b031916604083015261480f60208501613f80565b6001600160a01b03818116606085015261482f608085016040880161479b565b61483f60c085016080880161479b565b61484b60c08701613f80565b91506101008183168186015260e08701359250601e1987360301831261487057600080fd5b91860191823591506001600160401b0382111561488c57600080fd5b81360387131561489b57600080fd5b6101208501526148b3610140850182602085016147ba565b925050508260208301529392505050565b6000808335601e198436030181126148db57600080fd5b8301803591506001600160401b038211156148f557600080fd5b60200191503681900382131561490a57600080fd5b9250929050565b6001600160a01b03878116825260208201879052604082018690528416606082015260a06080820181905260009061494c90830184866147ba565b98975050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061498b90830184613f28565b9695505050505050565b6000602082840312156149a757600080fd5b815161182d81613eb9565b6000600182016149c4576149c4614612565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826149f0576149f06149cb565b500490565b600082614a0457614a046149cb565b500690565b634e487b7160e01b600052603260045260246000fd5b604080825283516001600160e01b031916828201526020808501516001600160a01b039081166060850152918501518051831660808501529081015160a0840152600091606086015180516001600160a01b031660c0860152602081015160e086015291506080860151166101008481019190915260a08601516101208501919091529050614ab2610140840182613f28565b9150508260208301529392505050565b600060033d1115614adb5760046000803e5060005160e01c5b90565b600060443d1015614aec5790565b6040516003193d81016004833e81513d6001600160401b038160248401118184111715614b1b57505050505090565b8285019150815181811115614b335750505050505090565b843d8701016020828501011115614b4d5750505050505090565b614b5c60208286010187614192565b509095945050505050565b6001600160a01b03868116825260208201869052604082018590528316606082015260a060808201819052600090614ba190830184613f28565b979650505050505050565b63ffffffff60e01b8a16815260006bffffffffffffffffffffffff19808b60601b166004840152808a60601b16601884015288602c840152808860601b16604c840152866060840152808660601b166080840152508351614c14816094850160208801613efc565b609492019182019290925260b401999850505050505050505056fea26469706673582212206d0908a0a7508346349dac082e182c5f0af4b7587b78a7139da0117d0a3d79ac64736f6c634300080d0033

Deployed Bytecode Sourcemap

83590:9633:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42042:372;;;;;;;;;;-1:-1:-1;42042:372:0;;;;;:::i;:::-;;:::i;:::-;;;702:14:1;;695:22;677:41;;665:2;650:18;42042:372:0;;;;;;;;43928:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;45490:214::-;;;;;;;;;;-1:-1:-1;45490:214:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1829:32:1;;;1811:51;;1799:2;1784:18;45490:214:0;1665:203:1;45011:413:0;;;;;;;;;;-1:-1:-1;45011:413:0;;;;;:::i;:::-;;:::i;:::-;;91391:125;;;;;;;;;;-1:-1:-1;91391:125:0;;;;;:::i;:::-;;:::i;40299:100::-;;;;;;;;;;-1:-1:-1;40352:7:0;40379:12;40299:100;;;2825:25:1;;;2813:2;2798:18;40299:100:0;2679:177:1;46366:162:0;;;;;;;;;;-1:-1:-1;46366:162:0;;;;;:::i;:::-;;:::i;84450:64::-;;;;;;;;;;;;84496:17;84450:64;;;;;-1:-1:-1;;;;;;3356:33:1;;;3338:52;;3326:2;3311:18;84450:64:0;3194:202:1;40963:1007:0;;;;;;;;;;-1:-1:-1;40963:1007:0;;;;;:::i;:::-;;:::i;91897:160::-;;;:::i;72784:117::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;88475:539::-;;;:::i;74293:186::-;;;;;;;;;;-1:-1:-1;74293:186:0;;;;;:::i;:::-;-1:-1:-1;;;;;74437:25:0;;;74405:7;74437:25;;;:15;:25;;;;;;;;-1:-1:-1;;;;;;74437:34:0;;;;;;;;;;;;;74293:186;46599:177;;;;;;;;;;-1:-1:-1;46599:177:0;;;;;:::i;:::-;;:::i;90779:270::-;;;;;;;;;;-1:-1:-1;90779:270:0;;;;;:::i;:::-;;:::i;83831:35::-;;;;;;;;;;-1:-1:-1;83831:35:0;;;;;;;;87482:506;;;;;;:::i;:::-;;:::i;89105:336::-;;;;;;;;;;-1:-1:-1;89105:336:0;;;;;:::i;:::-;;:::i;40476:187::-;;;;;;;;;;-1:-1:-1;40476:187:0;;;;;:::i;:::-;;:::i;92266:97::-;;;;;;;;;;-1:-1:-1;92266:97:0;;;;;:::i;:::-;;:::i;84031:36::-;;;;;;;;;;;;;;;;91681:116;;;;;;;;;;-1:-1:-1;91681:116:0;;;;;:::i;:::-;;:::i;92065:193::-;;;;;;;;;;-1:-1:-1;92065:193:0;;;;;:::i;:::-;;:::i;43737:124::-;;;;;;;;;;-1:-1:-1;43737:124:0;;;;;:::i;:::-;;:::i;71248:197::-;;;;;;;;;;-1:-1:-1;71248:197:0;;;;;:::i;:::-;;:::i;42478:221::-;;;;;;;;;;-1:-1:-1;42478:221:0;;;;;:::i;:::-;;:::i;15629:94::-;;;;;;;;;;;;;:::i;84326:46::-;;;;;;;;;;-1:-1:-1;84326:46:0;;;;;:::i;:::-;;;;;;;;;;;;;;70960:280;;;;;;;;;;-1:-1:-1;70960:280:0;;;;;:::i;:::-;;:::i;88027:409::-;;;;;;;;;;;;;:::i;78472:121::-;;;;;;;;;;;;;:::i;14978:87::-;;;;;;;;;;-1:-1:-1;15051:6:0;;-1:-1:-1;;;;;15051:6:0;14978:87;;73941:344;;;;;;;;;;-1:-1:-1;73941:344:0;;;;;:::i;:::-;;:::i;89476:1268::-;;;;;;:::i;:::-;;:::i;73346:587::-;;;;;;;;;;-1:-1:-1;73346:587:0;;;;;:::i;:::-;;:::i;44097:104::-;;;;;;;;;;;;;:::i;84379:39::-;;;;;;;;;;-1:-1:-1;84379:39:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;84163:50;;;;;;;;;;-1:-1:-1;84163:50:0;;;;;:::i;:::-;;;;;;;;;;;;;;45776:288;;;;;;;;;;-1:-1:-1;45776:288:0;;;;;:::i;:::-;;:::i;83912:31::-;;;;;;;;;;;;;;;;84273:46;;;;;;;;;;-1:-1:-1;84273:46:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;70685:263;;;;;;;;;;-1:-1:-1;70685:263:0;;;;;:::i;:::-;;:::i;83731:29::-;;;;;;;;;;;;;:::i;46847:355::-;;;;;;;;;;-1:-1:-1;46847:355:0;;;;;:::i;:::-;;:::i;83700:24::-;;;;;;;;;;;;;:::i;83990:34::-;;;;;;;;;;;;;;;;84111:45;;;;;;;;;;-1:-1:-1;84111:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;91552:94;;;;;;;;;;-1:-1:-1;91552:94:0;;;;;:::i;:::-;;:::i;83873:32::-;;;;;;;;;;;;;;;;92371:568;;;;;;;;;;-1:-1:-1;92371:568:0;;;;;:::i;:::-;;:::i;74487:193::-;;;;;;;;;;-1:-1:-1;74487:193:0;;;;;:::i;:::-;-1:-1:-1;;;;;74634:27:0;;;74605:4;74634:27;;;:17;:27;;;;;;;;:38;;;;;;;;;;;;;;;74487:193;86225:1218;;;;;;;;;;;;;:::i;84521:76::-;;;;;;;;;;;;84573:23;84521:76;;84220:46;;;;;;;;;;-1:-1:-1;84220:46:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;72436:155;;;;;;:::i;:::-;;:::i;72599:177::-;;;;;;;;;;-1:-1:-1;72599:177:0;;;;;:::i;:::-;;:::i;91082:274::-;;;;;;;;;;-1:-1:-1;91082:274:0;;;;;:::i;:::-;;:::i;83767:57::-;;;;;;;;;;;;;:::i;84074:30::-;;;;;;;;;;-1:-1:-1;84074:30:0;;;;;;;;46135:164;;;;;;;;;;-1:-1:-1;46135:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;46256:25:0;;;46232:4;46256:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;46135:164;83950:33;;;;;;;;;;;;;;;;15878:192;;;;;;;;;;-1:-1:-1;15878:192:0;;;;;:::i;:::-;;:::i;42042:372::-;42144:4;-1:-1:-1;;;;;;42181:40:0;;-1:-1:-1;;;42181:40:0;;:105;;-1:-1:-1;;;;;;;42238:48:0;;-1:-1:-1;;;42238:48:0;42181:105;:172;;;-1:-1:-1;;;;;;;42303:50:0;;-1:-1:-1;;;42303:50:0;42181:172;:225;;;-1:-1:-1;;;;;;;;;;32539:40:0;;;42370:36;42161:245;42042:372;-1:-1:-1;;42042:372:0:o;43928:100::-;43982:13;44015:5;44008:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43928:100;:::o;45490:214::-;45558:7;45586:16;45594:7;47514:4;47548:12;-1:-1:-1;47538:22:0;47457:111;45586:16;45578:74;;;;-1:-1:-1;;;45578:74:0;;11479:2:1;45578:74:0;;;11461:21:1;11518:2;11498:18;;;11491:30;11557:34;11537:18;;;11530:62;-1:-1:-1;;;11608:18:1;;;11601:43;11661:19;;45578:74:0;;;;;;;;;-1:-1:-1;45672:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;45672:24:0;;45490:214::o;45011:413::-;45084:13;45100:24;45116:7;45100:15;:24::i;:::-;45084:40;;45149:5;-1:-1:-1;;;;;45143:11:0;:2;-1:-1:-1;;;;;45143:11:0;;45135:58;;;;-1:-1:-1;;;45135:58:0;;11893:2:1;45135:58:0;;;11875:21:1;11932:2;11912:18;;;11905:30;11971:34;11951:18;;;11944:62;-1:-1:-1;;;12022:18:1;;;12015:32;12064:19;;45135:58:0;11691:398:1;45135:58:0;13879:10;-1:-1:-1;;;;;45228:21:0;;;;:62;;-1:-1:-1;45253:37:0;45270:5;13879:10;46135:164;:::i;45253:37::-;45206:169;;;;-1:-1:-1;;;45206:169:0;;12296:2:1;45206:169:0;;;12278:21:1;12335:2;12315:18;;;12308:30;12374:34;12354:18;;;12347:62;12445:27;12425:18;;;12418:55;12490:19;;45206:169:0;12094:421:1;45206:169:0;45388:28;45397:2;45401:7;45410:5;45388:8;:28::i;:::-;45073:351;45011:413;;:::o;91391:125::-;15051:6;;-1:-1:-1;;;;;15051:6:0;13879:10;15198:23;15190:68;;;;-1:-1:-1;;;15190:68:0;;;;;;;:::i;:::-;91474:15:::1;:34:::0;;-1:-1:-1;;91474:34:0::1;::::0;::::1;;::::0;;;::::1;::::0;;91391:125::o;46366:162::-;46492:28;46502:4;46508:2;46512:7;46492:9;:28::i;40963:1007::-;41052:7;41088:16;41098:5;41088:9;:16::i;:::-;41080:5;:24;41072:71;;;;-1:-1:-1;;;41072:71:0;;13083:2:1;41072:71:0;;;13065:21:1;13122:2;13102:18;;;13095:30;13161:34;13141:18;;;13134:62;-1:-1:-1;;;13212:18:1;;;13205:32;13254:19;;41072:71:0;12881:398:1;41072:71:0;41154:22;40379:12;;;41154:22;;41417:466;41437:14;41433:1;:18;41417:466;;;41477:31;41511:14;;;:11;:14;;;;;;;;;41477:48;;;;;;;;;-1:-1:-1;;;;;41477:48:0;;;;;-1:-1:-1;;;41477:48:0;;;-1:-1:-1;;;;;41477:48:0;;;;;;;;41548:28;41544:111;;41621:14;;;-1:-1:-1;41544:111:0;41698:5;-1:-1:-1;;;;;41677:26:0;:17;-1:-1:-1;;;;;41677:26:0;;41673:195;;41747:5;41732:11;:20;41728:85;;-1:-1:-1;41788:1:0;-1:-1:-1;41781:8:0;;-1:-1:-1;;;41781:8:0;41728:85;41835:13;;;;;41673:195;-1:-1:-1;41453:3:0;;41417:466;;;-1:-1:-1;41906:56:0;;-1:-1:-1;;;41906:56:0;;13486:2:1;41906:56:0;;;13468:21:1;13525:2;13505:18;;;13498:30;13564:34;13544:18;;;13537:62;-1:-1:-1;;;13615:18:1;;;13608:44;13669:19;;41906:56:0;13284:410:1;91897:160:0;15051:6;;-1:-1:-1;;;;;15051:6:0;13879:10;15198:23;15190:68;;;;-1:-1:-1;;;15190:68:0;;;;;;;:::i;:::-;91973:58:::1;::::0;91955:12:::1;::::0;91981:10:::1;::::0;92005:21:::1;::::0;91955:12;91973:58;91955:12;91973:58;92005:21;91981:10;91973:58:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91954:77;;;92044:7;92036:16;;;::::0;::::1;;91950:107;91897:160::o:0;72784:117::-;72834:15;72869:24;:16;:22;:24::i;:::-;72862:31;;72784:117;:::o;88475:539::-;56911:1;57509:7;;:19;57501:63;;;;-1:-1:-1;;;57501:63:0;;;;;;;:::i;:::-;56911:1;57642:7;:18;88537:16:::1;40379:12:::0;88588:15:::1;::::0;::::1;;88580:57;;;;-1:-1:-1::0;;;88580:57:0::1;;;;;;;:::i;:::-;88670:1;88656:11;;:15;88648:50;;;::::0;-1:-1:-1;;;88648:50:0;;14829:2:1;88648:50:0::1;::::0;::::1;14811:21:1::0;14868:2;14848:18;;;14841:30;-1:-1:-1;;;14887:18:1;;;14880:52;14949:18;;88648:50:0::1;14627:346:1::0;88648:50:0::1;88728:9;;88717:8;:20;88709:50;;;;-1:-1:-1::0;;;88709:50:0::1;;;;;;;:::i;:::-;88778:10;88792:9;88778:23;88770:32;;;::::0;::::1;;84689:13;88821:9;:23;;88813:94;;;::::0;-1:-1:-1;;;88813:94:0;;15526:2:1;88813:94:0::1;::::0;::::1;15508:21:1::0;15565:2;15545:18;;;15538:30;15604:66;15584:18;;;15577:94;-1:-1:-1;;;15687:18:1;;;15680:78;15775:19;;88813:94:0::1;15324:476:1::0;88813:94:0::1;88918:24;88928:10;88940:1;88918:9;:24::i;:::-;88968:1;88953:11;;:16;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;88980:17:0::1;::::0;;;:7:::1;:17;::::0;;;;:24;;-1:-1:-1;;88980:24:0::1;89000:4;88980:24:::0;;::::1;::::0;;;57821:7;:22;88475:539::o;46599:177::-;46729:39;46746:4;46752:2;46756:7;46729:39;;;;;;;;;;;;:16;:39::i;90779:270::-;90897:17;90905:8;90897:7;:17::i;:::-;-1:-1:-1;;;;;90883:31:0;:10;-1:-1:-1;;;;;90883:31:0;;90875:71;;;;-1:-1:-1;;;90875:71:0;;16269:2:1;90875:71:0;;;16251:21:1;16308:2;16288:18;;;16281:30;16347:29;16327:18;;;16320:57;16394:18;;90875:71:0;16067:351:1;90875:71:0;90965:17;;;;:7;:17;;;;;;;;90957:50;;;;-1:-1:-1;;;90957:50:0;;16625:2:1;90957:50:0;;;16607:21:1;16664:2;16644:18;;;16637:30;-1:-1:-1;;;16683:18:1;;;16676:50;16743:18;;90957:50:0;16423:344:1;90957:50:0;91018:23;:13;91034:7;;91018:23;:::i;:::-;;90779:270;;;:::o;87482:506::-;56911:1;57509:7;;:19;57501:63;;;;-1:-1:-1;;;57501:63:0;;;;;;;:::i;:::-;56911:1;57642:7;:18;93010:15:::1;::::0;87570:10;;93010:15:::1;;93002:57;;;;-1:-1:-1::0;;;93002:57:0::1;;;;;;;:::i;:::-;93108:9;;93094:10;93078:13;40352:7:::0;40379:12;;40299:100;93078:13:::1;:26;;;;:::i;:::-;:39;;93070:69;;;;-1:-1:-1::0;;;93070:69:0::1;;;;;;;:::i;:::-;93158:9;93171:10;93158:23;93150:50;;;;-1:-1:-1::0;;;93150:50:0::1;;;;;;;:::i;:::-;87635:10:::2;87593:23;87619:27:::0;;;:15:::2;:27:::0;;;;;;87697:16:::2;::::0;87665:28:::2;87683:10:::0;87619:27;87665:28:::2;:::i;:::-;:48;;87657:80;;;::::0;-1:-1:-1;;;87657:80:0;;17459:2:1;87657:80:0::2;::::0;::::2;17441:21:1::0;17498:2;17478:18;;;17471:30;-1:-1:-1;;;17517:18:1;;;17510:49;17576:18;;87657:80:0::2;17257:343:1::0;87657:80:0::2;87770:27;87787:10:::0;84640:12:::2;87770:27;:::i;:::-;87756:9;:42;;87748:117;;;::::0;-1:-1:-1;;;87748:117:0;;17980:2:1;87748:117:0::2;::::0;::::2;17962:21:1::0;18019:2;17999:18;;;17992:30;18058:34;18038:18;;;18031:62;18129:66;18109:18;;;18102:94;18213:19;;87748:117:0::2;17778:460:1::0;87748:117:0::2;87876:33;87886:10;87898;87876:9;:33::i;:::-;87951:28;87969:10:::0;87951:15;:28:::2;:::i;:::-;87936:10;87920:27;::::0;;;:15:::2;:27:::0;;;;;:60;-1:-1:-1;;56867:1:0;57821:7;:22;-1:-1:-1;87482:506:0:o;89105:336::-;56911:1;57509:7;;:19;57501:63;;;;-1:-1:-1;;;57501:63:0;;;;;;;:::i;:::-;56911:1;57642:7;:18;93010:15:::1;::::0;89199:1:::1;::::0;93010:15:::1;;93002:57;;;;-1:-1:-1::0;;;93002:57:0::1;;;;;;;:::i;:::-;93108:9;;93094:10;93078:13;40352:7:::0;40379:12;;40299:100;93078:13:::1;:26;;;;:::i;:::-;:39;;93070:69;;;;-1:-1:-1::0;;;93070:69:0::1;;;;;;;:::i;:::-;93158:9;93171:10;93158:23;93150:50;;;;-1:-1:-1::0;;;93150:50:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;89221:18:0;::::2;:10;:18:::0;89213:27:::2;;;::::0;::::2;;89280:10;89259:17;89267:8:::0;89259:7:::2;:17::i;:::-;-1:-1:-1::0;;;;;89259:31:0::2;;89251:40;;;::::0;::::2;;89310:24;::::0;;;:14:::2;:24;::::0;;;;;::::2;;89302:59;;;::::0;-1:-1:-1;;;89302:59:0;;18445:2:1;89302:59:0::2;::::0;::::2;18427:21:1::0;18484:2;18464:18;;;18457:30;-1:-1:-1;;;18503:18:1;;;18496:52;18565:18;;89302:59:0::2;18243:346:1::0;89302:59:0::2;89372:18;89382:4;89388:1;89372:9;:18::i;:::-;-1:-1:-1::0;89428:5:0::2;89401:24:::0;;;:14:::2;:24;::::0;;;;:32;;-1:-1:-1;;89401:32:0::2;::::0;;-1:-1:-1;89401:32:0;57821:7;:22;89105:336::o;40476:187::-;40543:7;40379:12;;40571:5;:21;40563:69;;;;-1:-1:-1;;;40563:69:0;;18796:2:1;40563:69:0;;;18778:21:1;18835:2;18815:18;;;18808:30;18874:34;18854:18;;;18847:62;-1:-1:-1;;;18925:18:1;;;18918:33;18968:19;;40563:69:0;18594:399:1;40563:69:0;-1:-1:-1;40650:5:0;40476:187::o;92266:97::-;15051:6;;-1:-1:-1;;;;;15051:6:0;13879:10;15198:23;15190:68;;;;-1:-1:-1;;;15190:68:0;;;;;;;:::i;:::-;92339:6:::1;:16:::0;;-1:-1:-1;;;;;;92339:16:0::1;-1:-1:-1::0;;;;;92339:16:0;;;::::1;::::0;;;::::1;::::0;;92266:97::o;91681:116::-;15051:6;;-1:-1:-1;;;;;15051:6:0;13879:10;15198:23;15190:68;;;;-1:-1:-1;;;15190:68:0;;;;;;;:::i;:::-;91762:27;;::::1;::::0;:15:::1;::::0;:27:::1;::::0;::::1;::::0;::::1;:::i;:::-;;91681:116:::0;:::o;92065:193::-;15051:6;;-1:-1:-1;;;;;15051:6:0;13879:10;15198:23;15190:68;;;;-1:-1:-1;;;15190:68:0;;;;;;;:::i;:::-;92158:38:::1;::::0;-1:-1:-1;;;92158:38:0;;92190:4:::1;92158:38;::::0;::::1;1811:51:1::0;92140:15:0::1;::::0;-1:-1:-1;;;;;92158:23:0;::::1;::::0;::::1;::::0;1784:18:1;;92158:38:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92207:43;::::0;-1:-1:-1;;;92207:43:0;;92230:10:::1;92207:43;::::0;::::1;19361:51:1::0;19428:18;;;19421:34;;;92140:56:0;;-1:-1:-1;;;;;;92207:22:0;::::1;::::0;::::1;::::0;19334:18:1;;92207:43:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;43737:124::-:0;43801:7;43828:20;43840:7;43828:11;:20::i;:::-;:25;;43737:124;-1:-1:-1;;43737:124:0:o;71248:197::-;71365:4;71394:43;71416:11;71429:7;71394:21;:43::i;:::-;71387:50;71248:197;-1:-1:-1;;;71248:197:0:o;42478:221::-;42542:7;-1:-1:-1;;;;;42570:19:0;;42562:75;;;;-1:-1:-1;;;42562:75:0;;19918:2:1;42562:75:0;;;19900:21:1;19957:2;19937:18;;;19930:30;19996:34;19976:18;;;19969:62;-1:-1:-1;;;20047:18:1;;;20040:41;20098:19;;42562:75:0;19716:407:1;42562:75:0;-1:-1:-1;;;;;;42663:19:0;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;42663:27:0;;42478:221::o;15629:94::-;15051:6;;-1:-1:-1;;;;;15051:6:0;13879:10;15198:23;15190:68;;;;-1:-1:-1;;;15190:68:0;;;;;;;:::i;:::-;15694:21:::1;15712:1;15694:9;:21::i;:::-;15629:94::o:0;70960:280::-;-1:-1:-1;;;;;71085:34:0;;;;;;:21;:34;;;;;;;;;:46;;-1:-1:-1;;71085:46:0;;;;;;;;;;71147:85;;677:41:1;;;71147:85:0;;650:18:1;71147:85:0;;;;;;;70960:280;;:::o;88027:409::-;56911:1;57509:7;;:19;57501:63;;;;-1:-1:-1;;;57501:63:0;;;;;;;:::i;:::-;56911:1;57642:7;:18;93010:15:::1;::::0;88090:1:::1;::::0;93010:15:::1;;93002:57;;;;-1:-1:-1::0;;;93002:57:0::1;;;;;;;:::i;:::-;93108:9;;93094:10;93078:13;40352:7:::0;40379:12;;40299:100;93078:13:::1;:26;;;;:::i;:::-;:39;;93070:69;;;;-1:-1:-1::0;;;93070:69:0::1;;;;;;;:::i;:::-;93158:9;93171:10;93158:23;93150:50;;;;-1:-1:-1::0;;;93150:50:0::1;;;;;;;:::i;:::-;88124:10:::2;88110:25;::::0;;;:13:::2;:25;::::0;;;;;::::2;;88109:26;88101:63;;;::::0;-1:-1:-1;;;88101:63:0;;20330:2:1;88101:63:0::2;::::0;::::2;20312:21:1::0;20369:2;20349:18;;;20342:30;-1:-1:-1;;;20388:18:1;;;20381:54;20452:18;;88101:63:0::2;20128:348:1::0;88101:63:0::2;88215:48;::::0;-1:-1:-1;;;88215:48:0;;84943:42:::2;88215:48;::::0;::::2;1811:51:1::0;85800:42:0::2;::::0;88215:32:::2;::::0;1784:18:1;;88215:48:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88197:15;;:66;88175:144;;;::::0;-1:-1:-1;;;88175:144:0;;20683:2:1;88175:144:0::2;::::0;::::2;20665:21:1::0;20722:2;20702:18;;;20695:30;20761;20741:18;;;20734:58;20809:18;;88175:144:0::2;20481:352:1::0;88175:144:0::2;88330:24;88340:10;88352:1;88330:9;:24::i;:::-;88384:1;88365:15;;:20;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;88410:10:0::2;88396:25;::::0;;;:13:::2;:25;::::0;;;;:32;;-1:-1:-1;;88396:32:0::2;88424:4;88396:32:::0;;::::2;::::0;;;57821:7;:22;-1:-1:-1;88027:409:0:o;78472:121::-;78524:15;78559:26;:18;:24;:26::i;73941:344::-;-1:-1:-1;;;;;74085:23:0;;:10;:23;74077:62;;;;-1:-1:-1;;;74077:62:0;;21040:2:1;74077:62:0;;;21022:21:1;21079:2;21059:18;;;21052:30;21118:28;21098:18;;;21091:56;21164:18;;74077:62:0;20838:350:1;74077:62:0;74170:10;74152:29;;;;:17;:29;;;;;;;;-1:-1:-1;;;;;74152:40:0;;;;;;;;;;;;:52;;-1:-1:-1;;74152:52:0;;;;;;;;;;74222:55;;677:41:1;;;74152:40:0;;74170:10;74222:55;;650:18:1;74222:55:0;;;;;;;;73941:344;;:::o;89476:1268::-;89625:6;89633;77744:50;77766:10;77778:15;;;;89625:6;77778:15;:::i;:::-;77744:21;:50::i;:::-;77811:7;77740:89;77891:4;77861:18;;;;:9;;;:18;:::i;:::-;-1:-1:-1;;;;;77861:35:0;;77839:110;;;;-1:-1:-1;;;77839:110:0;;21395:2:1;77839:110:0;;;21377:21:1;21434:2;21414:18;;;21407:30;21473:27;21453:18;;;21446:55;21518:18;;77839:110:0;21193:349:1;77839:110:0;77982:44;78010:15;;;;:6;:15;:::i;:::-;-1:-1:-1;;;;;;67221:19:0;67192:4;67221:19;;;:12;:19;;;;;;:24;;;67093:160;77982:44;77960:117;;;;-1:-1:-1;;;77960:117:0;;21749:2:1;77960:117:0;;;21731:21:1;21788:2;21768:18;;;21761:30;21827:25;21807:18;;;21800:53;21870:18;;77960:117:0;21547:347:1;77960:117:0;78142:1;78110:20;;;;:11;;;:20;:::i;:::-;-1:-1:-1;;;;;78110:34:0;;:89;;;-1:-1:-1;78189:10:0;78165:20;;;;:11;;;:20;:::i;:::-;-1:-1:-1;;;;;78165:34:0;;78110:89;78088:162;;;;-1:-1:-1;;;78088:162:0;;22101:2:1;78088:162:0;;;22083:21:1;22140:2;22120:18;;;22113:30;-1:-1:-1;;;22159:18:1;;;22152:53;22222:18;;78088:162:0;21899:347:1;78088:162:0;78316:1;78284:20;;;;:11;;;:20;:::i;:::-;-1:-1:-1;;;;;78284:34:0;;;:62;;;;-1:-1:-1;78337:9:0;78322:11;;;;;;;;:::i;:::-;-1:-1:-1;;;;;78322:24:0;;78284:62;78283:110;;;-1:-1:-1;78383:10:0;78368:11;;;;;;;;:::i;:::-;-1:-1:-1;;;;;78368:25:0;;78283:110;78261:183;;;;-1:-1:-1;;;78261:183:0;;22101:2:1;78261:183:0;;;22083:21:1;22140:2;22120:18;;;22113:30;-1:-1:-1;;;22159:18:1;;;22152:53;22222:18;;78261:183:0;21899:347:1;78261:183:0;-1:-1:-1;;;89665:15:0::1;;::::0;::::1;:6:::0;:15:::1;:::i;:::-;-1:-1:-1::0;;;;;;89665:32:0::1;;::::0;:74:::1;;-1:-1:-1::0;;;;89701:15:0::1;;::::0;::::1;:6:::0;:15:::1;:::i;:::-;-1:-1:-1::0;;;;;;89701:38:0::1;;89665:74;89657:121;;;::::0;-1:-1:-1;;;89657:121:0;;22453:2:1;89657:121:0::1;::::0;::::1;22435:21:1::0;22492:2;22472:18;;;22465:30;22531:34;22511:18;;;22504:62;-1:-1:-1;;;22582:18:1;;;22575:32;22624:19;;89657:121:0::1;22251:398:1::0;89657:121:0::1;-1:-1:-1::0;;;89793:15:0::1;;::::0;::::1;:6:::0;:15:::1;:::i;:::-;-1:-1:-1::0;;;;;;89793:32:0::1;::::0;89789:483:::1;;89873:6;::::0;-1:-1:-1;;;;;89873:6:0::1;89849:20;::::0;;;:11:::1;::::0;::::1;:20;:::i;:::-;-1:-1:-1::0;;;;;89849:30:0::1;;89841:73;;;::::0;-1:-1:-1;;;89841:73:0;;22856:2:1;89841:73:0::1;::::0;::::1;22838:21:1::0;22895:2;22875:18;;;22868:30;22934:32;22914:18;;;22907:60;22984:18;;89841:73:0::1;22654:354:1::0;89841:73:0::1;89952:27;89960:18:::0;;;::::1;89952:7;:27::i;:::-;-1:-1:-1::0;;;;;89937:42:0::1;:11;::::0;;;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;89937:42:0::1;;89929:99;;;;-1:-1:-1::0;;;89929:99:0::1;;;;;;;:::i;:::-;90067:18:::0;;;::::1;90052:34;::::0;;;:14:::1;90067:18;90052:34:::0;;;;;::::1;;90051:35;90043:73;;;::::0;-1:-1:-1;;;90043:73:0;;23628:2:1;90043:73:0::1;::::0;::::1;23610:21:1::0;23667:2;23647:18;;;23640:30;23706:27;23686:18;;;23679:55;23751:18;;90043:73:0::1;23426:349:1::0;90043:73:0::1;90154:1;90139:12;;:16;90131:41;;;::::0;-1:-1:-1;;;90131:41:0;;23982:2:1;90131:41:0::1;::::0;::::1;23964:21:1::0;24021:2;24001:18;;;23994:30;-1:-1:-1;;;24040:18:1;;;24033:42;24092:18;;90131:41:0::1;23780:336:1::0;90131:41:0::1;90202:18:::0;;;::::1;90187:34;::::0;;;:14:::1;90202:18;90187:34:::0;;;;:41;;-1:-1:-1;;90187:41:0::1;90224:4;90187:41:::0;;::::1;::::0;;;90243:12:::1;:17:::0;;90224:4;;90243:12;;:17:::1;::::0;90224:4;;90243:17:::1;:::i;:::-;::::0;;;-1:-1:-1;;89789:483:0::1;-1:-1:-1::0;;;90286:15:0::1;;::::0;::::1;:6:::0;:15:::1;:::i;:::-;-1:-1:-1::0;;;;;;90286:38:0::1;::::0;90282:411:::1;;90363:27;90371:18:::0;;;::::1;90363:7;:27::i;:::-;-1:-1:-1::0;;;;;90348:42:0::1;:11;::::0;;;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;90348:42:0::1;;90340:99;;;;-1:-1:-1::0;;;90340:99:0::1;;;;;;;:::i;:::-;90474:18:::0;;;::::1;90462:31;::::0;;;:11:::1;90474:18;90462:31:::0;;;;;90511:4:::1;::::0;90462:46:::1;::::0;90496:12:::1;::::0;90462:46:::1;:::i;:::-;:53;90454:113;;;::::0;-1:-1:-1;;;90454:113:0;;24323:2:1;90454:113:0::1;::::0;::::1;24305:21:1::0;24362:2;24342:18;;;24335:30;24401:34;24381:18;;;24374:62;-1:-1:-1;;;24452:18:1;;;24445:45;24507:19;;90454:113:0::1;24121:411:1::0;90454:113:0::1;90587:33;::::0;90601:18;;;::::1;2825:25:1::0;;90587:33:0::1;::::0;2813:2:1;2798:18;90587:33:0::1;;;;;;;90647:18:::0;;;::::1;90635:31;::::0;;;:11:::1;90647:18;90635:31:::0;;;;90669:12:::1;90635:46:::0;;90282:411:::1;90703:33;90721:6;90729;90703:17;:33::i;73346:587::-:0;73492:4;73530:8;-1:-1:-1;;;;;73517:21:0;:9;-1:-1:-1;;;;;73517:21:0;;73509:60;;;;-1:-1:-1;;;73509:60:0;;21040:2:1;73509:60:0;;;21022:21:1;21079:2;21059:18;;;21052:30;21118:28;21098:18;;;21091:56;21164:18;;73509:60:0;20838:350:1;73509:60:0;73604:10;-1:-1:-1;;;;;73604:22:0;;;;:88;;-1:-1:-1;;;;;;74634:27:0;;74605:4;74634:27;;;:17;:27;;;;;;;;73681:10;74634:38;;;;;;;;;;73647:45;73582:197;;;;-1:-1:-1;;;73582:197:0;;24739:2:1;73582:197:0;;;24721:21:1;24778:2;24758:18;;;24751:30;24817:34;24797:18;;;24790:62;24888:29;24868:18;;;24861:57;24935:19;;73582:197:0;24537:423:1;73582:197:0;-1:-1:-1;;;;;73792:25:0;;;;;;;:15;:25;;;;;;;;-1:-1:-1;;;;;;73792:34:0;;;;;;;;;;:46;;-1:-1:-1;;;;;;73792:46:0;;;;;;;;;73854:47;73792:34;;:25;73854:47;;;-1:-1:-1;73921:4:0;73346:587;;;;;:::o;44097:104::-;44153:13;44186:7;44179:14;;;;;:::i;45776:288::-;13879:10;-1:-1:-1;;;;;45871:24:0;;;45863:63;;;;-1:-1:-1;;;45863:63:0;;25167:2:1;45863:63:0;;;25149:21:1;25206:2;25186:18;;;25179:30;25245:28;25225:18;;;25218:56;25291:18;;45863:63:0;24965:350:1;45863:63:0;13879:10;45939:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;45939:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;45939:53:0;;;;;;;;;;46008:48;;677:41:1;;;45939:42:0;;13879:10;46008:48;;650:18:1;46008:48:0;537:187:1;70685:263:0;-1:-1:-1;;;;;70800:31:0;;;;;;:18;:31;;;;;;;;-1:-1:-1;;;;;;70800:40:0;;;;;;;;;;:47;;-1:-1:-1;;70800:47:0;70843:4;70800:47;;;70863:77;70800:40;;:31;70863:77;;;70685:263;;:::o;83731:29::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;46847:355::-;47006:28;47016:4;47022:2;47026:7;47006:9;:28::i;:::-;47067:48;47090:4;47096:2;47100:7;47109:5;47067:22;:48::i;:::-;47045:149;;;;-1:-1:-1;;;47045:149:0;;;;;;;:::i;83700:24::-;;;;;;;:::i;91552:94::-;15051:6;;-1:-1:-1;;;;;15051:6:0;13879:10;15198:23;15190:68;;;;-1:-1:-1;;;15190:68:0;;;;;;;:::i;:::-;91621:17;;::::1;::::0;:10:::1;::::0;:17:::1;::::0;::::1;::::0;::::1;:::i;92371:568::-:0;92437:13;92471:17;92479:8;47514:4;47548:12;-1:-1:-1;47538:22:0;47457:111;92471:17;92463:77;;;;-1:-1:-1;;;92463:77:0;;25942:2:1;92463:77:0;;;25924:21:1;25981:2;25961:18;;;25954:30;26020:34;26000:18;;;25993:62;-1:-1:-1;;;26071:18:1;;;26064:45;26126:19;;92463:77:0;25740:411:1;92463:77:0;92553:21;92577:10;:8;:10::i;:::-;92553:34;;92598:22;92623:11;:9;:11::i;:::-;92649:24;;;;:14;:24;;;;;;92598:36;;-1:-1:-1;92649:24:0;;:55;;;;-1:-1:-1;92677:22:0;;:27;;92649:55;92645:287;;;92752:8;92762:19;:8;:17;:19::i;:::-;92735:47;;;;;;;;;:::i;:::-;;;;;;;;;;;;;92721:62;;;;92371:568;;;:::o;92645:287::-;92838:7;92832:21;92857:1;92832:26;:88;;;;;;;;;;;;;;;;;92885:7;92894:19;:8;:17;:19::i;92832:88::-;92825:95;92371:568;-1:-1:-1;;;;92371:568:0:o;86225:1218::-;56911:1;57509:7;;:19;57501:63;;;;-1:-1:-1;;;57501:63:0;;;;;;;:::i;:::-;56911:1;57642:7;:18;86282:16:::1;40379:12:::0;86333:15:::1;::::0;::::1;;86325:57;;;;-1:-1:-1::0;;;86325:57:0::1;;;;;;;:::i;:::-;86412:9;;86401:8;:20;86393:50;;;;-1:-1:-1::0;;;86393:50:0::1;;;;;;;:::i;:::-;86462:10;86476:9;86462:23;86454:32;;;::::0;::::1;;86517:10;86503:25;::::0;;;:13:::1;:25;::::0;;;;;::::1;;86502:26;86494:63;;;::::0;-1:-1:-1;;;86494:63:0;;20330:2:1;86494:63:0::1;::::0;::::1;20312:21:1::0;20369:2;20349:18;;;20342:30;-1:-1:-1;;;20388:18:1;;;20381:54;20452:18;;86494:63:0::1;20128:348:1::0;86494:63:0::1;86590:48;::::0;-1:-1:-1;;;86590:48:0;;86627:10:::1;86590:48;::::0;::::1;1811:51:1::0;86641:1:0::1;::::0;85039:42:::1;::::0;86590:36:::1;::::0;1784:18:1;;86590:48:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;:120;;;-1:-1:-1::0;86659:47:0::1;::::0;-1:-1:-1;;;86659:47:0;;86695:10:::1;86659:47;::::0;::::1;1811:51:1::0;86709:1:0::1;::::0;85134:42:::1;::::0;86659:35:::1;::::0;1784:18:1;;86659:47:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:51;86590:120;:183;;;-1:-1:-1::0;86727:42:0::1;::::0;-1:-1:-1;;;86727:42:0;;86758:10:::1;86727:42;::::0;::::1;1811:51:1::0;86772:1:0::1;::::0;85224:42:::1;::::0;86727:30:::1;::::0;1784:18:1;;86727:42:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;86590:183;:261;;;-1:-1:-1::0;86790:57:0::1;::::0;-1:-1:-1;;;86790:57:0;;86836:10:::1;86790:57;::::0;::::1;1811:51:1::0;86850:1:0::1;::::0;85329:42:::1;::::0;86790:45:::1;::::0;1784:18:1;;86790:57:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:61;86590:261;:329;;;-1:-1:-1::0;86868:47:0::1;::::0;-1:-1:-1;;;86868:47:0;;86904:10:::1;86868:47;::::0;::::1;1811:51:1::0;86918:1:0::1;::::0;85424:42:::1;::::0;86868:35:::1;::::0;1784:18:1;;86868:47:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:51;86590:329;:397;;;-1:-1:-1::0;86936:47:0::1;::::0;-1:-1:-1;;;86936:47:0;;86972:10:::1;86936:47;::::0;::::1;1811:51:1::0;86986:1:0::1;::::0;85519:42:::1;::::0;86936:35:::1;::::0;1784:18:1;;86936:47:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:51;86590:397;:468;;;-1:-1:-1::0;87004:50:0::1;::::0;-1:-1:-1;;;87004:50:0;;87043:10:::1;87004:50;::::0;::::1;1811:51:1::0;87057:1:0::1;::::0;85617:42:::1;::::0;87004:38:::1;::::0;1784:18:1;;87004:50:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:54;86590:468;:532;;;-1:-1:-1::0;87075:43:0::1;::::0;-1:-1:-1;;;87075:43:0;;87107:10:::1;87075:43;::::0;::::1;1811:51:1::0;87121:1:0::1;::::0;85708:42:::1;::::0;87075:31:::1;::::0;1784:18:1;;87075:43:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;86590:532;:597;;;-1:-1:-1::0;87139:44:0::1;::::0;-1:-1:-1;;;87139:44:0;;87172:10:::1;87139:44;::::0;::::1;1811:51:1::0;87186:1:0::1;::::0;85800:42:::1;::::0;87139:32:::1;::::0;1784:18:1;;87139:44:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:48;86590:597;:666;;;-1:-1:-1::0;87204:48:0::1;::::0;-1:-1:-1;;;87204:48:0;;87241:10:::1;87204:48;::::0;::::1;1811:51:1::0;87255:1:0::1;::::0;85896:42:::1;::::0;87204:36:::1;::::0;1784:18:1;;87204:48:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:52;86590:666;86568:747;;;::::0;-1:-1:-1;;;86568:747:0;;26833:2:1;86568:747:0::1;::::0;::::1;26815:21:1::0;26872:2;26852:18;;;26845:30;26911:33;26891:18;;;26884:61;26962:18;;86568:747:0::1;26631:355:1::0;86568:747:0::1;87326:24;87336:10;87348:1;87326:9;:24::i;:::-;87375:10;87361:25;::::0;;;:13:::1;:25;::::0;;;;;;;:32;;87389:4:::1;-1:-1:-1::0;;87361:32:0;;::::1;::::0;::::1;::::0;;;87404:24;;;:14:::1;:24:::0;;;;;;:31;;;;::::1;::::0;::::1;::::0;;;57821:7;:22;86225:1218::o;72436:155::-;72564:19;72576:6;72564:11;:19::i;72599:177::-;72701:4;72744:5;;72730:10;:19;:38;;;;-1:-1:-1;;72762:6:0;;72753:15;;72599:177;-1:-1:-1;72599:177:0:o;91082:274::-;15051:6;;-1:-1:-1;;;;;15051:6:0;13879:10;15198:23;15190:68;;;;-1:-1:-1;;;15190:68:0;;;;;;;:::i;:::-;91160:10:::1;::::0;::::1;;91159:11;91151:20;;;::::0;::::1;;91181:22;40379:12:::0;91266:9:::1;::::0;91235:27:::1;91252:10:::0;40379:12;91235:27:::1;:::i;:::-;:40;;91227:49;;;::::0;::::1;;91287:33;91297:10;91309;91287:9;:33::i;:::-;-1:-1:-1::0;;91331:10:0::1;:17:::0;;-1:-1:-1;;91331:17:0::1;91344:4;91331:17;::::0;;91082:274::o;83767:57::-;;;;;;;:::i;15878:192::-;15051:6;;-1:-1:-1;;;;;15051:6:0;13879:10;15198:23;15190:68;;;;-1:-1:-1;;;15190:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;15967:22:0;::::1;15959:73;;;::::0;-1:-1:-1;;;15959:73:0;;27193:2:1;15959:73:0::1;::::0;::::1;27175:21:1::0;27232:2;27212:18;;;27205:30;27271:34;27251:18;;;27244:62;-1:-1:-1;;;27322:18:1;;;27315:36;27368:19;;15959:73:0::1;26991:402:1::0;15959:73:0::1;16043:19;16053:8;16043:9;:19::i;64870:528::-:0;64980:22;;;;;;;;;;-1:-1:-1;;;;;;67221:19:0;;64938:4;67221:19;;;:12;;;:19;;;;;;;65014:377;;65059:14;;;;:29;;;;;;;-1:-1:-1;65059:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65103:21;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;65287:14:0;;;;:21;-1:-1:-1;;;;;;65262:22:0;;;;;;;:12;;;:22;;;;;:46;;;;65287:14;-1:-1:-1;65323:11:0;;65014:377;65374:5;65367:12;;;;;52377:196;52492:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;52492:29:0;-1:-1:-1;;;;;52492:29:0;;;;;;;;;52537:28;;52492:24;;52537:28;;;;;;;52377:196;;;:::o;50257:2002::-;50372:35;50410:20;50422:7;50410:11;:20::i;:::-;50485:18;;50372:58;;-1:-1:-1;50443:22:0;;-1:-1:-1;;;;;50469:34:0;13879:10;-1:-1:-1;;;;;50469:34:0;;:87;;;-1:-1:-1;13879:10:0;50520:20;50532:7;50520:11;:20::i;:::-;-1:-1:-1;;;;;50520:36:0;;50469:87;:154;;;-1:-1:-1;50590:18:0;;50573:50;;13879:10;46135:164;:::i;50573:50::-;50443:181;;50645:17;50637:80;;;;-1:-1:-1;;;50637:80:0;;27600:2:1;50637:80:0;;;27582:21:1;27639:2;27619:18;;;27612:30;27678:34;27658:18;;;27651:62;-1:-1:-1;;;27729:18:1;;;27722:48;27787:19;;50637:80:0;27398:414:1;50637:80:0;50760:4;-1:-1:-1;;;;;50738:26:0;:13;:18;;;-1:-1:-1;;;;;50738:26:0;;50730:77;;;;-1:-1:-1;;;50730:77:0;;28019:2:1;50730:77:0;;;28001:21:1;28058:2;28038:18;;;28031:30;28097:34;28077:18;;;28070:62;-1:-1:-1;;;28148:18:1;;;28141:36;28194:19;;50730:77:0;27817:402:1;50730:77:0;-1:-1:-1;;;;;50826:16:0;;50818:66;;;;-1:-1:-1;;;50818:66:0;;28426:2:1;50818:66:0;;;28408:21:1;28465:2;28445:18;;;28438:30;28504:34;28484:18;;;28477:62;-1:-1:-1;;;28555:18:1;;;28548:35;28600:19;;50818:66:0;28224:401:1;50818:66:0;51005:49;51022:1;51026:7;51035:13;:18;;;51005:8;:49::i;:::-;-1:-1:-1;;;;;51350:18:0;;;;;;;:12;:18;;;;;;;;:31;;-1:-1:-1;;;;;;51350:31:0;;;-1:-1:-1;;;;;51350:31:0;;;-1:-1:-1;;51350:31:0;;;;;;;51396:16;;;;;;;;;:29;;;;;;;;-1:-1:-1;51396:29:0;;;;;;;;;;;;;51442:20;;;:11;:20;;;;;;:30;;-1:-1:-1;;;;;;51487:61:0;;;;-1:-1:-1;;;51532:15:0;-1:-1:-1;;;;;51487:61:0;;;;;51822:11;;;51852:24;;;;;:29;51822:11;;51852:29;51848:295;;51920:20;51928:11;47514:4;47548:12;-1:-1:-1;47538:22:0;47457:111;51920:20;51916:212;;;51997:18;;;51965:24;;;:11;:24;;;;;;;;:50;;52080:28;;;;-1:-1:-1;;;;;52038:70:0;-1:-1:-1;;;52038:70:0;-1:-1:-1;;;;;;52038:70:0;;;-1:-1:-1;;;;;51965:50:0;;;52038:70;;;;;;;51916:212;51325:829;52190:7;52186:2;-1:-1:-1;;;;;52171:27:0;52180:4;-1:-1:-1;;;;;52171:27:0;;;;;;;;;;;52209:42;50361:1898;;50257:2002;;;:::o;68481:108::-;68536:15;68571:3;:10;;68564:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68481:108;;;:::o;47576:104::-;47645:27;47655:2;47659:8;47645:27;;;;;;;;;;;;:9;:27::i;43138:537::-;-1:-1:-1;;;;;;;;;;;;;;;;;43241:16:0;43249:7;47514:4;47548:12;-1:-1:-1;47538:22:0;47457:111;43241:16;43233:71;;;;-1:-1:-1;;;43233:71:0;;28832:2:1;43233:71:0;;;28814:21:1;28871:2;28851:18;;;28844:30;28910:34;28890:18;;;28883:62;-1:-1:-1;;;28961:18:1;;;28954:40;29011:19;;43233:71:0;28630:406:1;43233:71:0;43362:7;43342:245;43409:31;43443:17;;;:11;:17;;;;;;;;;43409:51;;;;;;;;;-1:-1:-1;;;;;43409:51:0;;;;;-1:-1:-1;;;43409:51:0;;;-1:-1:-1;;;;;43409:51:0;;;;;;;;43483:28;43479:93;;43543:9;43138:537;-1:-1:-1;;;43138:537:0:o;43479:93::-;-1:-1:-1;;;43382:6:0;43342:245;;71453:283;-1:-1:-1;;;;;71597:34:0;;71571:4;71597:34;;;:21;:34;;;;;;;;71593:78;;;-1:-1:-1;71655:4:0;71648:11;;71593:78;-1:-1:-1;;;;;;71688:31:0;;;;;;:18;:31;;;;;;;;-1:-1:-1;;;;;;71688:40:0;;;;;;;;;;;;71453:283;;;;:::o;16078:173::-;16153:6;;;-1:-1:-1;;;;;16170:17:0;;;-1:-1:-1;;;;;;16170:17:0;;;;;;;16203:40;;16153:6;;;16170:17;16153:6;;16203:40;;16134:16;;16203:40;16123:128;16078:173;:::o;78845:1164::-;78967:50;78989:10;79001:15;;;;:6;:15;:::i;78967:50::-;78962:754;;79062:1;79038:12;;;;;;;;:::i;:::-;-1:-1:-1;;;;;79038:26:0;;79034:671;;79093:25;:12;;;;;;;;:::i;:::-;-1:-1:-1;;;;;79093:23:0;17315:20;17363:8;;;16992:387;79093:25;79085:60;;;;-1:-1:-1;;;79085:60:0;;29659:2:1;79085:60:0;;;29641:21:1;29698:2;29678:18;;;29671:30;-1:-1:-1;;;29717:18:1;;;29710:52;29779:18;;79085:60:0;29457:346:1;79085:60:0;79206:12;;;;;;;;:::i;:::-;-1:-1:-1;;;;;79189:47:0;;79270:9;79303:6;79311:5;79189:128;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79164:526;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79393:6;:13;79410:1;79393:18;79389:282;;79440:46;;-1:-1:-1;;;79440:46:0;;31906:2:1;79440:46:0;;;31888:21:1;31945:2;31925:18;;;31918:30;31984:34;31964:18;;;31957:62;-1:-1:-1;;;32035:18:1;;;32028:34;32079:19;;79440:46:0;31704:400:1;79389:282:0;79613:6;79607:13;79598:6;79594:2;79590:15;79583:38;79164:526;79886:18;;;;:9;;;:18;:::i;:::-;-1:-1:-1;;;;;79731:270:0;79816:20;;;;:11;;;:20;:::i;:::-;-1:-1:-1;;;;;79731:270:0;79760:15;;;;:6;:15;:::i;:::-;-1:-1:-1;;;;;;79731:270:0;;79790:11;;;;;;;;:::i;:::-;79851:20;;;;79919:18;;;;79952:12;;;;;;;;:::i;:::-;79979:11;;;;:6;:11;:::i;:::-;79731:270;;;;;;;;;;;:::i;:::-;;;;;;;;78845:1164;;:::o;53138:804::-;53293:4;-1:-1:-1;;;;;53314:13:0;;17315:20;17363:8;53310:625;;53350:72;;-1:-1:-1;;;53350:72:0;;-1:-1:-1;;;;;53350:36:0;;;;;:72;;13879:10;;53401:4;;53407:7;;53416:5;;53350:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53350:72:0;;;;;;;;-1:-1:-1;;53350:72:0;;;;;;;;;;;;:::i;:::-;;;53346:534;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53596:6;:13;53613:1;53596:18;53592:273;;53639:61;;-1:-1:-1;;;53639:61:0;;;;;;;:::i;53346:534::-;-1:-1:-1;;;;;;53473:55:0;-1:-1:-1;;;53473:55:0;;-1:-1:-1;53466:62:0;;53310:625;-1:-1:-1;53919:4:0;53138:804;;;;;;:::o;85949:111::-;86009:13;86042:10;86035:17;;;;;:::i;86068:108::-;86120:13;86153:15;86146:22;;;;;:::i;1973:723::-;2029:13;2250:5;2259:1;2250:10;2246:53;;-1:-1:-1;;2277:10:0;;;;;;;;;;;;-1:-1:-1;;;2277:10:0;;;;;1973:723::o;2246:53::-;2324:5;2309:12;2365:78;2372:9;;2365:78;;2398:8;;;;:::i;:::-;;-1:-1:-1;2421:10:0;;-1:-1:-1;2429:2:0;2421:10;;:::i;:::-;;;2365:78;;;2453:19;2485:6;-1:-1:-1;;;;;2475:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2475:17:0;;2453:39;;2503:154;2510:10;;2503:154;;2537:11;2547:1;2537:11;;:::i;:::-;;-1:-1:-1;2606:10:0;2614:2;2606:5;:10;:::i;:::-;2593:24;;:2;:24;:::i;:::-;2580:39;;2563:6;2570;2563:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;2563:56:0;;;;;;;;-1:-1:-1;2634:11:0;2643:2;2634:11;;:::i;:::-;;;2503:154;;74688:1491;74756:50;74778:10;74790:6;:15;;;74756:21;:50::i;:::-;74751:1139;;74823:11;;;;74854:4;74823:36;;74894:9;;;;:18;74963:12;;;;-1:-1:-1;;;;;74894:29:0;;;17315:20;17363:8;;;;74963:23;;;17315:20;17363:8;;;74823:20;;75030:159;;-1:-1:-1;75074:9:0;;;;:18;75030:159;;;75118:15;75114:75;;;-1:-1:-1;75161:12:0;;;;75114:75;75203:13;75235:12;:31;;;;;75251:15;75235:31;75231:122;;;75287:17;75297:6;75287:9;:17::i;:::-;-1:-1:-1;75331:6:0;;75231:122;-1:-1:-1;;;;;75371:15:0;;17315:20;17363:8;75367:512;;75434:145;;-1:-1:-1;;;75434:145:0;;-1:-1:-1;;;;;75434:39:0;;;;;75481:9;;75434:145;;75518:6;;75551:5;;75434:145;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75409:455;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;75661:3;75654:11;;-1:-1:-1;;;75654:11:0;;;;;;;;:::i;75409:455::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75745:17:0;;:21;75741:104;;75809:10;75795:26;;-1:-1:-1;;;75795:26:0;;;;;;;;:::i;75741:104::-;75686:178;75409:455;74808:1082;;;;74751:1139;76056:6;:9;;;:18;;;-1:-1:-1;;;;;75905:266:0;75986:6;:11;;;:20;;;-1:-1:-1;;;;;75905:266:0;75930:6;:15;;;-1:-1:-1;;;;;75905:266:0;;;75960:6;:11;;;76021:6;:11;;;:20;;;76089:6;:9;;;:18;;;76122:6;:12;;;76149:6;:11;;;75905:266;;;;;;;;;;:::i;:::-;;;;;;;;74688:1491;:::o;48043:163::-;48166:32;48172:2;48176:8;48186:5;48193:4;48166:5;:32::i;76187:545::-;76250:6;;76248:8;;;;;:::i;:::-;;;;-1:-1:-1;76364:15:0;;76402:11;;;;;76436;;;;;:20;;76479;;;;76522:9;;;;:18;;76563;;;;76604:12;;;;76639:11;;;;76673:6;;76325:373;;;;76364:15;76436:20;;76479;;76522:18;;76563;;76604:12;;76639:11;;76325:373;;:::i;:::-;;;;-1:-1:-1;;76325:373:0;;;;;;;;;76297:416;;76325:373;76297:416;;;;76267:5;:457;-1:-1:-1;76187:545:0:o;48465:1538::-;48604:20;48627:12;-1:-1:-1;;;;;48658:16:0;;48650:62;;;;-1:-1:-1;;;48650:62:0;;38446:2:1;48650:62:0;;;38428:21:1;38485:2;38465:18;;;38458:30;38524:34;38504:18;;;38497:62;-1:-1:-1;;;38575:18:1;;;38568:31;38616:19;;48650:62:0;38244:397:1;48650:62:0;48731:8;48743:1;48731:13;48723:66;;;;-1:-1:-1;;;48723:66:0;;38848:2:1;48723:66:0;;;38830:21:1;38887:2;38867:18;;;38860:30;38926:34;38906:18;;;38899:62;-1:-1:-1;;;38977:18:1;;;38970:38;39025:19;;48723:66:0;38646:404:1;48723:66:0;-1:-1:-1;;;;;49141:16:0;;;;;;:12;:16;;;;;;;;:45;;-1:-1:-1;;;;;;;;;49141:45:0;;-1:-1:-1;;;;;49141:45:0;;;;;;;;;;49201:50;;;;;;;;;;;;;;49268:25;;;:11;:25;;;;;:35;;-1:-1:-1;;;;;;49318:66:0;;;;-1:-1:-1;;;49368:15:0;-1:-1:-1;;;;;49318:66:0;;;;;;49268:25;;49453:415;49473:8;49469:1;:12;49453:415;;;49512:38;;49537:12;;-1:-1:-1;;;;;49512:38:0;;;49529:1;;49512:38;;49529:1;;49512:38;49573:4;49569:249;;;49636:59;49667:1;49671:2;49675:12;49689:5;49636:22;:59::i;:::-;49602:196;;;;-1:-1:-1;;;49602:196:0;;;;;;;:::i;:::-;49838:14;;;;;49483:3;49453:415;;;-1:-1:-1;49884:12:0;:27;49935:60;90779:270;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:132;217:20;;246:30;217:20;246:30;:::i;:::-;150:132;;;:::o;287:245::-;345:6;398:2;386:9;377:7;373:23;369:32;366:52;;;414:1;411;404:12;366:52;453:9;440:23;472:30;496:5;472:30;:::i;729:258::-;801:1;811:113;825:6;822:1;819:13;811:113;;;901:11;;;895:18;882:11;;;875:39;847:2;840:10;811:113;;;942:6;939:1;936:13;933:48;;;-1:-1:-1;;977:1:1;959:16;;952:27;729:258::o;992:::-;1034:3;1072:5;1066:12;1099:6;1094:3;1087:19;1115:63;1171:6;1164:4;1159:3;1155:14;1148:4;1141:5;1137:16;1115:63;:::i;:::-;1232:2;1211:15;-1:-1:-1;;1207:29:1;1198:39;;;;1239:4;1194:50;;992:258;-1:-1:-1;;992:258:1:o;1255:220::-;1404:2;1393:9;1386:21;1367:4;1424:45;1465:2;1454:9;1450:18;1442:6;1424:45;:::i;1480:180::-;1539:6;1592:2;1580:9;1571:7;1567:23;1563:32;1560:52;;;1608:1;1605;1598:12;1560:52;-1:-1:-1;1631:23:1;;1480:180;-1:-1:-1;1480:180:1:o;1873:173::-;1941:20;;-1:-1:-1;;;;;1990:31:1;;1980:42;;1970:70;;2036:1;2033;2026:12;2051:254;2119:6;2127;2180:2;2168:9;2159:7;2155:23;2151:32;2148:52;;;2196:1;2193;2186:12;2148:52;2219:29;2238:9;2219:29;:::i;:::-;2209:39;2295:2;2280:18;;;;2267:32;;-1:-1:-1;;;2051:254:1:o;2310:118::-;2396:5;2389:13;2382:21;2375:5;2372:32;2362:60;;2418:1;2415;2408:12;2433:241;2489:6;2542:2;2530:9;2521:7;2517:23;2513:32;2510:52;;;2558:1;2555;2548:12;2510:52;2597:9;2584:23;2616:28;2638:5;2616:28;:::i;2861:328::-;2938:6;2946;2954;3007:2;2995:9;2986:7;2982:23;2978:32;2975:52;;;3023:1;3020;3013:12;2975:52;3046:29;3065:9;3046:29;:::i;:::-;3036:39;;3094:38;3128:2;3117:9;3113:18;3094:38;:::i;:::-;3084:48;;3179:2;3168:9;3164:18;3151:32;3141:42;;2861:328;;;;;:::o;3401:803::-;3563:4;3592:2;3632;3621:9;3617:18;3662:2;3651:9;3644:21;3685:6;3720;3714:13;3751:6;3743;3736:22;3789:2;3778:9;3774:18;3767:25;;3851:2;3841:6;3838:1;3834:14;3823:9;3819:30;3815:39;3801:53;;3889:2;3881:6;3877:15;3910:1;3920:255;3934:6;3931:1;3928:13;3920:255;;;4027:2;4023:7;4011:9;4003:6;3999:22;3995:36;3990:3;3983:49;4055:40;4088:6;4079;4073:13;4055:40;:::i;:::-;4045:50;-1:-1:-1;4153:12:1;;;;4118:15;;;;3956:1;3949:9;3920:255;;;-1:-1:-1;4192:6:1;;3401:803;-1:-1:-1;;;;;;;3401:803:1:o;4209:319::-;4276:6;4284;4337:2;4325:9;4316:7;4312:23;4308:32;4305:52;;;4353:1;4350;4343:12;4305:52;4376:29;4395:9;4376:29;:::i;:::-;4366:39;;4455:2;4444:9;4440:18;4427:32;4468:30;4492:5;4468:30;:::i;:::-;4517:5;4507:15;;;4209:319;;;;;:::o;4533:660::-;4613:6;4621;4629;4682:2;4670:9;4661:7;4657:23;4653:32;4650:52;;;4698:1;4695;4688:12;4650:52;4734:9;4721:23;4711:33;;4795:2;4784:9;4780:18;4767:32;-1:-1:-1;;;;;4859:2:1;4851:6;4848:14;4845:34;;;4875:1;4872;4865:12;4845:34;4913:6;4902:9;4898:22;4888:32;;4958:7;4951:4;4947:2;4943:13;4939:27;4929:55;;4980:1;4977;4970:12;4929:55;5020:2;5007:16;5046:2;5038:6;5035:14;5032:34;;;5062:1;5059;5052:12;5032:34;5107:7;5102:2;5093:6;5089:2;5085:15;5081:24;5078:37;5075:57;;;5128:1;5125;5118:12;5075:57;5159:2;5155;5151:11;5141:21;;5181:6;5171:16;;;;;4533:660;;;;;:::o;5198:186::-;5257:6;5310:2;5298:9;5289:7;5285:23;5281:32;5278:52;;;5326:1;5323;5316:12;5278:52;5349:29;5368:9;5349:29;:::i;5389:127::-;5450:10;5445:3;5441:20;5438:1;5431:31;5481:4;5478:1;5471:15;5505:4;5502:1;5495:15;5521:225;5607:4;5599:6;5595:17;5678:6;5666:10;5663:22;-1:-1:-1;;;;;5630:10:1;5627:34;5624:62;5621:88;;;5689:18;;:::i;:::-;5725:2;5718:22;-1:-1:-1;5521:225:1:o;5751:249::-;5861:2;5842:13;;-1:-1:-1;;5838:27:1;5826:40;;-1:-1:-1;;;;;5881:34:1;;5917:22;;;5878:62;5875:88;;;5943:18;;:::i;:::-;5979:2;5972:22;-1:-1:-1;;5751:249:1:o;6005:469::-;6070:5;-1:-1:-1;;;;;6096:6:1;6093:30;6090:56;;;6126:18;;:::i;:::-;6175:2;6169:9;6187:69;6244:2;6223:15;;-1:-1:-1;;6219:29:1;6250:4;6215:40;6169:9;6187:69;:::i;:::-;6274:6;6265:15;;6304:6;6296;6289:22;6344:3;6335:6;6330:3;6326:16;6323:25;6320:45;;;6361:1;6358;6351:12;6320:45;6411:6;6406:3;6399:4;6391:6;6387:17;6374:44;6466:1;6459:4;6450:6;6442;6438:19;6434:30;6427:41;;6005:469;;;;;:::o;6479:451::-;6548:6;6601:2;6589:9;6580:7;6576:23;6572:32;6569:52;;;6617:1;6614;6607:12;6569:52;6657:9;6644:23;-1:-1:-1;;;;;6682:6:1;6679:30;6676:50;;;6722:1;6719;6712:12;6676:50;6745:22;;6798:4;6790:13;;6786:27;-1:-1:-1;6776:55:1;;6827:1;6824;6817:12;6776:55;6850:74;6916:7;6911:2;6898:16;6893:2;6889;6885:11;6850:74;:::i;6935:315::-;7000:6;7008;7061:2;7049:9;7040:7;7036:23;7032:32;7029:52;;;7077:1;7074;7067:12;7029:52;7100:29;7119:9;7100:29;:::i;:::-;7090:39;;7179:2;7168:9;7164:18;7151:32;7192:28;7214:5;7192:28;:::i;7255:454::-;7349:6;7357;7410:2;7398:9;7389:7;7385:23;7381:32;7378:52;;;7426:1;7423;7416:12;7378:52;7466:9;7453:23;-1:-1:-1;;;;;7491:6:1;7488:30;7485:50;;;7531:1;7528;7521:12;7485:50;7554:22;;7610:3;7592:16;;;7588:26;7585:46;;;7627:1;7624;7617:12;7714:393;7790:6;7798;7806;7859:2;7847:9;7838:7;7834:23;7830:32;7827:52;;;7875:1;7872;7865:12;7827:52;7898:29;7917:9;7898:29;:::i;:::-;7888:39;;7977:2;7966:9;7962:18;7949:32;7990:30;8014:5;7990:30;:::i;:::-;8039:5;-1:-1:-1;8063:38:1;8097:2;8082:18;;8063:38;:::i;:::-;8053:48;;7714:393;;;;;:::o;8112:221::-;8154:5;8207:3;8200:4;8192:6;8188:17;8184:27;8174:55;;8225:1;8222;8215:12;8174:55;8247:80;8323:3;8314:6;8301:20;8294:4;8286:6;8282:17;8247:80;:::i;8338:537::-;8433:6;8441;8449;8457;8510:3;8498:9;8489:7;8485:23;8481:33;8478:53;;;8527:1;8524;8517:12;8478:53;8550:29;8569:9;8550:29;:::i;:::-;8540:39;;8598:38;8632:2;8621:9;8617:18;8598:38;:::i;:::-;8588:48;;8683:2;8672:9;8668:18;8655:32;8645:42;;8738:2;8727:9;8723:18;8710:32;-1:-1:-1;;;;;8757:6:1;8754:30;8751:50;;;8797:1;8794;8787:12;8751:50;8820:49;8861:7;8852:6;8841:9;8837:22;8820:49;:::i;:::-;8810:59;;;8338:537;;;;;;;:::o;8880:260::-;8948:6;8956;9009:2;8997:9;8988:7;8984:23;8980:32;8977:52;;;9025:1;9022;9015:12;8977:52;9048:29;9067:9;9048:29;:::i;:::-;9038:39;;9096:38;9130:2;9119:9;9115:18;9096:38;:::i;:::-;9086:48;;8880:260;;;;;:::o;9145:481::-;9198:5;9246:4;9234:9;9229:3;9225:19;9221:30;9218:50;;;9264:1;9261;9254:12;9218:50;9297:4;9291:11;9341:4;9333:6;9329:17;9412:6;9400:10;9397:22;-1:-1:-1;;;;;9364:10:1;9361:34;9358:62;9355:88;;;9423:18;;:::i;:::-;9459:4;9452:24;9494:6;-1:-1:-1;9494:6:1;9524:29;9543:9;9524:29;:::i;:::-;9516:6;9509:45;9615:2;9604:9;9600:18;9587:32;9582:2;9574:6;9570:15;9563:57;;9145:481;;;;:::o;9631:1003::-;9714:6;9767:2;9755:9;9746:7;9742:23;9738:32;9735:52;;;9783:1;9780;9773:12;9735:52;9823:9;9810:23;-1:-1:-1;;;;;9893:2:1;9885:6;9882:14;9879:34;;;9909:1;9906;9899:12;9879:34;9932:22;;;;9988:6;9970:16;;;9966:29;9963:49;;;10008:1;10005;9998:12;9963:49;10041:2;10035:9;10053:32;10078:6;10053:32;:::i;:::-;10109:21;10127:2;10109:21;:::i;:::-;10101:6;10094:37;10164:31;10191:2;10187;10183:11;10164:31;:::i;:::-;10159:2;10151:6;10147:15;10140:56;10229:46;10267:7;10262:2;10258;10254:11;10229:46;:::i;:::-;10224:2;10216:6;10212:15;10205:71;10311:47;10350:7;10344:3;10340:2;10336:12;10311:47;:::i;:::-;10304:4;10296:6;10292:17;10285:74;10393:33;10420:4;10416:2;10412:13;10393:33;:::i;:::-;10387:3;10379:6;10375:16;10368:59;10473:3;10469:2;10465:12;10452:26;10503:2;10493:8;10490:16;10487:36;;;10519:1;10516;10509:12;10487:36;10558:44;10594:7;10583:8;10579:2;10575:17;10558:44;:::i;:::-;10551:4;10539:17;;10532:71;-1:-1:-1;10543:6:1;9631:1003;-1:-1:-1;;;;;9631:1003:1:o;10639:248::-;10707:6;10715;10768:2;10756:9;10747:7;10743:23;10739:32;10736:52;;;10784:1;10781;10774:12;10736:52;-1:-1:-1;;10807:23:1;;;10877:2;10862:18;;;10849:32;;-1:-1:-1;10639:248:1:o;10892:380::-;10971:1;10967:12;;;;11014;;;11035:61;;11089:4;11081:6;11077:17;11067:27;;11035:61;11142:2;11134:6;11131:14;11111:18;11108:38;11105:161;;11188:10;11183:3;11179:20;11176:1;11169:31;11223:4;11220:1;11213:15;11251:4;11248:1;11241:15;11105:161;;10892:380;;;:::o;12520:356::-;12722:2;12704:21;;;12741:18;;;12734:30;12800:34;12795:2;12780:18;;12773:62;12867:2;12852:18;;12520:356::o;13909:355::-;14111:2;14093:21;;;14150:2;14130:18;;;14123:30;14189:33;14184:2;14169:18;;14162:61;14255:2;14240:18;;13909:355::o;14269:353::-;14471:2;14453:21;;;14510:2;14490:18;;;14483:30;14549:31;14544:2;14529:18;;14522:59;14613:2;14598:18;;14269:353::o;14978:341::-;15180:2;15162:21;;;15219:2;15199:18;;;15192:30;-1:-1:-1;;;15253:2:1;15238:18;;15231:47;15310:2;15295:18;;14978:341::o;15805:127::-;15866:10;15861:3;15857:20;15854:1;15847:31;15897:4;15894:1;15887:15;15921:4;15918:1;15911:15;15937:125;15977:4;16005:1;16002;15999:8;15996:34;;;16010:18;;:::i;:::-;-1:-1:-1;16047:9:1;;15937:125::o;16772:128::-;16812:3;16843:1;16839:6;16836:1;16833:13;16830:39;;;16849:18;;:::i;:::-;-1:-1:-1;16885:9:1;;16772:128::o;16905:347::-;17107:2;17089:21;;;17146:1;17126:18;;;17119:29;-1:-1:-1;;;17179:2:1;17164:18;;17157:54;17243:2;17228:18;;16905:347::o;17605:168::-;17645:7;17711:1;17707;17703:6;17699:14;17696:1;17693:21;17688:1;17681:9;17674:17;17670:45;17667:71;;;17718:18;;:::i;:::-;-1:-1:-1;17758:9:1;;17605:168::o;18998:184::-;19068:6;19121:2;19109:9;19100:7;19096:23;19092:32;19089:52;;;19137:1;19134;19127:12;19089:52;-1:-1:-1;19160:16:1;;18998:184;-1:-1:-1;18998:184:1:o;19466:245::-;19533:6;19586:2;19574:9;19565:7;19561:23;19557:32;19554:52;;;19602:1;19599;19592:12;19554:52;19634:9;19628:16;19653:28;19675:5;19653:28;:::i;23013:408::-;23215:2;23197:21;;;23254:2;23234:18;;;23227:30;23293:34;23288:2;23273:18;;23266:62;-1:-1:-1;;;23359:2:1;23344:18;;23337:42;23411:3;23396:19;;23013:408::o;25320:415::-;25522:2;25504:21;;;25561:2;25541:18;;;25534:30;25600:34;25595:2;25580:18;;25573:62;-1:-1:-1;;;25666:2:1;25651:18;;25644:49;25725:3;25710:19;;25320:415::o;26156:470::-;26335:3;26373:6;26367:13;26389:53;26435:6;26430:3;26423:4;26415:6;26411:17;26389:53;:::i;:::-;26505:13;;26464:16;;;;26527:57;26505:13;26464:16;26561:4;26549:17;;26527:57;:::i;:::-;26600:20;;26156:470;-1:-1:-1;;;;26156:470:1:o;29808:202::-;-1:-1:-1;;;;;29893:25:1;29912:5;29893:25;:::i;:::-;29889:51;29877:64;;29997:4;29986:16;;;29973:30;29957:14;;29950:54;29808:202::o;30015:266::-;30103:6;30098:3;30091:19;30155:6;30148:5;30141:4;30136:3;30132:14;30119:43;-1:-1:-1;30207:1:1;30182:16;;;30200:4;30178:27;;;30171:38;;;;30263:2;30242:15;;;-1:-1:-1;;30238:29:1;30229:39;;;30225:50;;30015:266::o;30286:1413::-;30493:2;30482:9;30475:21;30456:4;30531:6;30518:20;30547:30;30571:5;30547:30;:::i;:::-;-1:-1:-1;;;;;;30613:32:1;30608:2;30593:18;;30586:60;30675:37;30706:4;30694:17;;30675:37;:::i;:::-;-1:-1:-1;;;;;30786:21:1;;;30781:2;30766:18;;30759:49;30817:71;30883:3;30868:19;;30863:2;30851:15;;30817:71;:::i;:::-;30897:72;30964:3;30953:9;30949:19;30943:3;30935:6;30931:16;30897:72;:::i;:::-;31000:36;31031:3;31023:6;31019:16;31000:36;:::i;:::-;30978:58;;31055:6;31117:2;31101:14;31097:23;31092:2;31081:9;31077:18;31070:51;31181:4;31173:6;31169:17;31156:31;31130:57;;31267:2;31263:7;31254:6;31238:14;31234:27;31230:41;31210:18;31206:66;31196:94;;31286:1;31283;31276:12;31196:94;31314:31;;;;31368:21;;;-1:-1:-1;;;;;;31401:30:1;;31398:50;;;31444:1;31441;31434:12;31398:50;31492:6;31476:14;31472:27;31464:6;31460:40;31457:60;;;31513:1;31510;31503:12;31457:60;31548:3;31533:19;;31526:31;31574:74;31643:3;31628:19;;31620:6;31613:4;31600:18;;31574:74;:::i;:::-;31566:82;;;;31686:6;31679:4;31668:9;31664:20;31657:36;30286:1413;;;;;:::o;32109:521::-;32186:4;32192:6;32252:11;32239:25;32346:2;32342:7;32331:8;32315:14;32311:29;32307:43;32287:18;32283:68;32273:96;;32365:1;32362;32355:12;32273:96;32392:33;;32444:20;;;-1:-1:-1;;;;;;32476:30:1;;32473:50;;;32519:1;32516;32509:12;32473:50;32552:4;32540:17;;-1:-1:-1;32583:14:1;32579:27;;;32569:38;;32566:58;;;32620:1;32617;32610:12;32566:58;32109:521;;;;;:::o;32635:587::-;-1:-1:-1;;;;;32942:15:1;;;32924:34;;32989:2;32974:18;;32967:34;;;33032:2;33017:18;;33010:34;;;33080:15;;33075:2;33060:18;;33053:43;32904:3;33127;33112:19;;33105:32;;;32867:4;;33154:62;;33196:19;;33188:6;33180;33154:62;:::i;:::-;33146:70;32635:587;-1:-1:-1;;;;;;;;32635:587:1:o;33227:489::-;-1:-1:-1;;;;;33496:15:1;;;33478:34;;33548:15;;33543:2;33528:18;;33521:43;33595:2;33580:18;;33573:34;;;33643:3;33638:2;33623:18;;33616:31;;;33421:4;;33664:46;;33690:19;;33682:6;33664:46;:::i;:::-;33656:54;33227:489;-1:-1:-1;;;;;;33227:489:1:o;33721:249::-;33790:6;33843:2;33831:9;33822:7;33818:23;33814:32;33811:52;;;33859:1;33856;33849:12;33811:52;33891:9;33885:16;33910:30;33934:5;33910:30;:::i;33975:135::-;34014:3;34035:17;;;34032:43;;34055:18;;:::i;:::-;-1:-1:-1;34102:1:1;34091:13;;33975:135::o;34115:127::-;34176:10;34171:3;34167:20;34164:1;34157:31;34207:4;34204:1;34197:15;34231:4;34228:1;34221:15;34247:120;34287:1;34313;34303:35;;34318:18;;:::i;:::-;-1:-1:-1;34352:9:1;;34247:120::o;34372:112::-;34404:1;34430;34420:35;;34435:18;;:::i;:::-;-1:-1:-1;34469:9:1;;34372:112::o;34489:127::-;34550:10;34545:3;34541:20;34538:1;34531:31;34581:4;34578:1;34571:15;34605:4;34602:1;34595:15;34799:1036;35004:2;34986:21;;;35047:13;;-1:-1:-1;;;;;;35043:40:1;35023:18;;;35016:68;35131:4;35119:17;;;35113:24;-1:-1:-1;;;;;35211:21:1;;;35206:2;35191:18;;35184:49;35270:15;;;35264:22;34697:12;;34693:38;;35351:3;35336:19;;34681:51;34770:16;;;34764:23;34748:14;;;34741:47;-1:-1:-1;;35405:2:1;35393:15;;35387:22;34697:12;;-1:-1:-1;;;;;34693:38:1;35474:3;35459:19;;34681:51;34781:4;34770:16;;34764:23;34748:14;;;34741:47;35387:22;-1:-1:-1;35528:3:1;35516:16;;35510:23;35594;35552:6;35574:18;;;35567:51;;;;35667:4;35655:17;;35649:24;35704:3;35689:19;;35682:31;;;;35649:24;-1:-1:-1;35730:54:1;35779:3;35764:19;;35649:24;35730:54;:::i;:::-;35722:62;;;35822:6;35815:4;35804:9;35800:20;35793:36;34799:1036;;;;;:::o;35840:179::-;35875:3;35917:1;35899:16;35896:23;35893:120;;;35963:1;35960;35957;35942:23;-1:-1:-1;36000:1:1;35994:8;35989:3;35985:18;35893:120;35840:179;:::o;36024:671::-;36063:3;36105:4;36087:16;36084:26;36081:39;;;36024:671;:::o;36081:39::-;36147:2;36141:9;-1:-1:-1;;36212:16:1;36208:25;;36205:1;36141:9;36184:50;36263:4;36257:11;36287:16;-1:-1:-1;;;;;36393:2:1;36386:4;36378:6;36374:17;36371:25;36366:2;36358:6;36355:14;36352:45;36349:58;;;36400:5;;;;;36024:671;:::o;36349:58::-;36437:6;36431:4;36427:17;36416:28;;36473:3;36467:10;36500:2;36492:6;36489:14;36486:27;;;36506:5;;;;;;36024:671;:::o;36486:27::-;36590:2;36571:16;36565:4;36561:27;36557:36;36550:4;36541:6;36536:3;36532:16;36528:27;36525:69;36522:82;;;36597:5;;;;;;36024:671;:::o;36522:82::-;36613:57;36664:4;36655:6;36647;36643:19;36639:30;36633:4;36613:57;:::i;:::-;-1:-1:-1;36686:3:1;;36024:671;-1:-1:-1;;;;;36024:671:1:o;36700:561::-;-1:-1:-1;;;;;36997:15:1;;;36979:34;;37044:2;37029:18;;37022:34;;;37087:2;37072:18;;37065:34;;;37135:15;;37130:2;37115:18;;37108:43;36959:3;37182;37167:19;;37160:32;;;36922:4;;37209:46;;37235:19;;37227:6;37209:46;:::i;:::-;37201:54;36700:561;-1:-1:-1;;;;;;;36700:561:1:o;37266:973::-;37668:10;37663:3;37659:20;37651:6;37647:33;37642:3;37635:46;37617:3;37704:26;37700:31;37781:2;37772:6;37768:2;37764:15;37760:24;37756:1;37751:3;37747:11;37740:45;37836:2;37827:6;37823:2;37819:15;37815:24;37810:2;37805:3;37801:12;37794:46;37870:6;37865:2;37860:3;37856:12;37849:28;37928:2;37919:6;37915:2;37911:15;37907:24;37902:2;37897:3;37893:12;37886:46;37962:6;37957:2;37952:3;37948:12;37941:28;38021:2;38012:6;38008:2;38004:15;38000:24;37994:3;37989;37985:13;37978:47;;38054:6;38048:13;38070:63;38126:6;38120:3;38115;38111:13;38104:4;38096:6;38092:17;38070:63;:::i;:::-;38192:3;38152:16;;38184:12;;;38177:28;;;;38229:3;38221:12;;37266:973;-1:-1:-1;;;;;;;;;37266:973:1:o

Swarm Source

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