FTM Price: $0.5209 (+8.42%)
 

Overview

Max Total Supply

922 GHOSTLY

Holders

444

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
Ghostlys

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 15000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at ftmscan.com on 2021-10-30
*/

/**
   ▄██████▄     ▄█    █▄     ▄██████▄     ▄████████     ███      ▄█       ▄██   ▄      ▄████████
  ███    ███   ███    ███   ███    ███   ███    ███ ▀█████████▄ ███       ███   ██▄   ███    ███
  ███    █▀    ███    ███   ███    ███   ███    █▀     ▀███▀▀██ ███       ███▄▄▄███   ███    █▀
 ▄███         ▄███▄▄▄▄███▄▄ ███    ███   ███            ███   ▀ ███       ▀▀▀▀▀▀███   ███
▀▀███ ████▄  ▀▀███▀▀▀▀███▀  ███    ███ ▀███████████     ███     ███       ▄██   ███ ▀███████████
  ███    ███   ███    ███   ███    ███          ███     ███     ███       ███   ███          ███
  ███    ███   ███    ███   ███    ███    ▄█    ███     ███     ███▌    ▄ ███   ███    ▄█    ███
  ████████▀    ███    █▀     ▀██████▀   ▄████████▀     ▄████▀   █████▄▄██  ▀█████▀   ▄████████▀
                                                                ▀

  █████▒█    ██  ███▄    █ ▓█████  ██▀███   ▄▄▄       ██▓
▓██   ▒ ██  ▓██▒ ██ ▀█   █ ▓█   ▀ ▓██ ▒ ██▒▒████▄    ▓██▒
▒████ ░▓██  ▒██░▓██  ▀█ ██▒▒███   ▓██ ░▄█ ▒▒██  ▀█▄  ▒██░
░▓█▒  ░▓▓█  ░██░▓██▒  ▐▌██▒▒▓█  ▄ ▒██▀▀█▄  ░██▄▄▄▄██ ▒██░
░▒█░   ▒▒█████▓ ▒██░   ▓██░░▒████▒░██▓ ▒██▒ ▓█   ▓██▒░██████▒
 ▒ ░   ░▒▓▒ ▒ ▒ ░ ▒░   ▒ ▒ ░░ ▒░ ░░ ▒▓ ░▒▓░ ▒▒   ▓▒█░░ ▒░▓  ░
 ░     ░░▒░ ░ ░ ░ ░░   ░ ▒░ ░ ░  ░  ░▒ ░ ▒░  ▒   ▒▒ ░░ ░ ▒  ░
 ░ ░    ░░░ ░ ░    ░   ░ ░    ░     ░░   ░   ░   ▒     ░ ░
          ░              ░    ░  ░   ░           ░  ░    ░  ░

   ██╗      █████╗ ██████╗ ██╗  ██╗██╗███╗   ██╗
   ██║     ██╔══██╗██╔══██╗██║ ██╔╝██║████╗  ██║
   ██║     ███████║██████╔╝█████╔╝ ██║██╔██╗ ██║
   ██║     ██╔══██║██╔══██╗██╔═██╗ ██║██║╚██╗██║
   ███████╗██║  ██║██║  ██║██║  ██╗██║██║ ╚████║
   ╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝╚═╝  ╚═══╝
**/
// Sources flattened with hardhat v2.6.7 https://hardhat.org

// File @openzeppelin/contracts/utils/introspection/[email protected]

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

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


// File @openzeppelin/contracts/token/ERC721/[email protected]





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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

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

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

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


// File @openzeppelin/contracts/token/ERC721/[email protected]





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


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]





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

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

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


// File @openzeppelin/contracts/utils/[email protected]





/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

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

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

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

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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


// File @openzeppelin/contracts/utils/[email protected]





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

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


// File @openzeppelin/contracts/utils/[email protected]





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

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

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

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

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


// File @openzeppelin/contracts/utils/introspection/[email protected]





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


// File @openzeppelin/contracts/token/ERC721/[email protected]











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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

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

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


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]





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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");

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

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

        return super.tokenURI(tokenId);
    }

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

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

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


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]





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

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

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


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]






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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/utils/math/[email protected]





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

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

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

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

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

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/utils/introspection/[email protected]





/**
 * @dev Storage based implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
abstract contract ERC165Storage is ERC165 {
    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}


// File @openzeppelin/contracts/interfaces/[email protected]






// File @openzeppelin/contracts/interfaces/[email protected]





/**
 * @dev Interface for the NFT Royalty Standard
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Called with the sale price to determine how much royalty is owed and to whom.
     * @param tokenId - the NFT asset queried for royalty information
     * @param salePrice - the sale price of the NFT asset specified by `tokenId`
     * @return receiver - address of who should be sent the royalty payment
     * @return royaltyAmount - the royalty payment amount for `salePrice`
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}


// File contracts/ERC2981.sol

/***
 *    ███████╗██████╗  ██████╗██████╗  █████╗  █████╗  ██╗
 *    ██╔════╝██╔══██╗██╔════╝╚════██╗██╔══██╗██╔══██╗███║
 *    █████╗  ██████╔╝██║      █████╔╝╚██████║╚█████╔╝╚██║
 *    ██╔══╝  ██╔══██╗██║     ██╔═══╝  ╚═══██║██╔══██╗ ██║
 *    ███████╗██║  ██║╚██████╗███████╗ █████╔╝╚█████╔╝ ██║
 *    ╚══════╝╚═╝  ╚═╝ ╚═════╝╚══════╝ ╚════╝  ╚════╝  ╚═╝
 * Written by MaxflowO2
 * You can follow along at https://github.com/MaxflowO2/ERC2981
 */







abstract contract ERC2981 is IERC2981, ERC165Storage {
  using SafeMath for uint256;

  // Bytes4 Code for EIP-2981
  bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;

  // Mappings _tokenID -> values
  address receiver;
  uint256 royaltyPercentage;

  constructor() {

    // Using ERC165Storage set EIP-2981
    _registerInterface(_INTERFACE_ID_ERC2981);

  }

  // Set to be internal function _setReceiver
  function _setReceiver(address _address) internal {
    receiver = _address;
  }

  // Set to be internal function _setRoyaltyPercentage
  function _setRoyaltyPercentage(uint256 _royaltyPercentage) internal {
    royaltyPercentage = _royaltyPercentage;
  }

  // Override for royaltyInfo(uint256, uint256)
  // uses SafeMath for uint256
  function royaltyInfo(uint256 _tokenId, uint256 _salePrice) external view override(IERC2981) returns (address Receiver, uint256 royaltyAmount) {
    Receiver = receiver;
    royaltyAmount = _salePrice.div(100).mul(royaltyPercentage);
  }
}


// File contracts/Ghostlys.sol




/**
   ▄██████▄     ▄█    █▄     ▄██████▄     ▄████████     ███      ▄█       ▄██   ▄      ▄████████
  ███    ███   ███    ███   ███    ███   ███    ███ ▀█████████▄ ███       ███   ██▄   ███    ███
  ███    █▀    ███    ███   ███    ███   ███    █▀     ▀███▀▀██ ███       ███▄▄▄███   ███    █▀
 ▄███         ▄███▄▄▄▄███▄▄ ███    ███   ███            ███   ▀ ███       ▀▀▀▀▀▀███   ███
▀▀███ ████▄  ▀▀███▀▀▀▀███▀  ███    ███ ▀███████████     ███     ███       ▄██   ███ ▀███████████
  ███    ███   ███    ███   ███    ███          ███     ███     ███       ███   ███          ███
  ███    ███   ███    ███   ███    ███    ▄█    ███     ███     ███▌    ▄ ███   ███    ▄█    ███
  ████████▀    ███    █▀     ▀██████▀   ▄████████▀     ▄████▀   █████▄▄██  ▀█████▀   ▄████████▀
                                                                ▀
**/





contract Ghostlys is ERC721Enumerable, ERC2981 {

    using SafeMath for uint;
    using SafeMath for uint256;

    enum Status {
        Closed,
        PresaleStart,
        PublicSaleStart
    }

    string public PROVENANCE = "";
    string private _baseURIextended = "";

    uint constant public MAX_GHOSTLYS = 8888;
    uint constant public MAX_MINT = 20;
    uint constant public GHOSTLYS_PRICE = 50 ether;

    uint public presaleStartTime = 1635624000; // default to some time far in the future
    uint public publicSaleStartTime = presaleStartTime + 24 hours; // starts 24 hours after the presale

    uint constant private RAND_ID_POOL_SIZE = 100;
    uint private randIdPoolSize = RAND_ID_POOL_SIZE;
    uint[RAND_ID_POOL_SIZE] private randIdPool;
    //uint[] private ;

    mapping(address => bool) private isTeam;
    mapping(address => uint) public freeMints;

    // Team Addresses
    address[] private _team = [
        0xC87bf1972Dd048404CBd3FbA300b69277552C472, // 38 - FUNERAL - Art, Generative Art, UI, Community
        0x14E8F54f35eE42Cdf436A19086659B34dA6D9D47, // 12 - LARKIN  - Dev
        0xA4f7a42F2569f97de8218Aa875F58533Fe842FEe  // 50 - Community

    ];

    // team address and community wallet payout shares
    uint256[] private _team_shares = [38, 12, 50];  // 38 and 12 for team, and then 50% for community wallet


    // For EIP-2981
    uint256 constant private ROYALTIES_PERCENTAGE = 5;

    constructor()
        ERC721("Ghostlys... Enter the summoning circle.", "GHOSTLY")
    {
        isTeam[msg.sender] = true;
        isTeam[0xC87bf1972Dd048404CBd3FbA300b69277552C472] = true;
        isTeam[0x14E8F54f35eE42Cdf436A19086659B34dA6D9D47] = true;

        _setReceiver(address(this));
        _setRoyaltyPercentage(ROYALTIES_PERCENTAGE);

        for (uint i = 0; i < RAND_ID_POOL_SIZE; i++) {
            randIdPool[i] = i+1;
        }
        // initialize tokenIdsLeft to range(1, 100)
        // choose a random index into tokenIdsLeft, mint that ID
        // delete that ID from tokenIdsLeft, add totalSupply() + 1 to tokenIdsLeft
    }

    modifier onlyTeam() {
        require(isTeam[msg.sender], "Can't do that, you are not part of the team");
        _;
    }

    modifier verifyFreeMint(address _to) {
        require(freeMints[_to] > 0, "Must have a skully before snapshot for free mint");
        require(getStatus() == Status.PresaleStart || getStatus() == Status.PublicSaleStart, "Minting has not started");
        require(totalSupply() < MAX_GHOSTLYS, "Sold out");
        _;
    }

    modifier verifyMint(address _to, uint _amount) {
        require(_amount <= MAX_MINT, "Tried to mint too many at once");
        require(getStatus() == Status.PublicSaleStart, "Public sale has not started");
        require(GHOSTLYS_PRICE * _amount <= msg.value, "Didn't send enough payment");
        require(totalSupply().add(_amount) <= MAX_GHOSTLYS, "Sold out");
        _;
    }

    function setProvenanceHash(string memory _provenanceHash) external onlyTeam {
        PROVENANCE = _provenanceHash;
    }

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

    function setBaseURI(string memory baseURI_) external onlyTeam {
        _baseURIextended = baseURI_;
    }

    function setManyWhiteList(address[] memory _addr, uint[] memory _bals) external onlyTeam {
        require(_addr.length == _bals.length, "Addresses and balances must have same array length");
        for(uint i = 0; i < _addr.length; i++){
            freeMints[_addr[i]] = _bals[i];
        }
    }

    function getStatus() public view returns (Status) {
        if(block.timestamp >= publicSaleStartTime) {
            return Status.PublicSaleStart;
        } else if (block.timestamp >= presaleStartTime) {
            return Status.PresaleStart;
        }
        return Status.Closed;
    }

    function setPreSaleTime(uint _newTime) public onlyTeam {
        presaleStartTime = _newTime;
        publicSaleStartTime = _newTime + 24 hours;
    }

    function _safeRandMint(address _to, uint256 _idx) internal {
        uint mintIdx = random("MINT_FREE", _idx) % randIdPoolSize;
        uint tokenId = randIdPool[mintIdx];
        // If the randIdPool hasn't reached the end of the supply yet,
        // replace the chosen tokenId with the next one in the supply
        // Example:
        //     RAND_ID_POOL_SIZE=100
        //     randIdPool is initialized to just an enumerated list from 1 to 100 inclusive
        //     For the first mint, say the random index 20 is chosen, which corresponds to tokenId 20 in randIdPool (since it is initialized as just 1 to 100)
        //     Since we are nowhere near the end of the supply yet on this first iteration,
        //     index 20 in randIdPool is replaced with the next unminted tokenId that has been
        //     outside of the randIdPool thus far: 101
        //     Mint is completed, and next time, if index 20 is randomly chosen, it will be tokenId 101
        // Edge case:
        //     Once mints near the end of the max supply, begin decremeting the size of the randIdPool
        //     Instead of just replacing the tokenId being currently claimed wtih
        //     the next one outside the pool, just replace it wiht the last ID in the pool.
        //     If it IS the last ID in the pool, replace with the second-to-last
        //     If this is the last token in the supply, skip all of this and just mint
        if (totalSupply().add(1) < MAX_GHOSTLYS) {
            if (MAX_GHOSTLYS.sub(totalSupply()) >= RAND_ID_POOL_SIZE) {
                randIdPool[mintIdx] = totalSupply().add(RAND_ID_POOL_SIZE).add(1);
            } else {
                randIdPoolSize = randIdPoolSize.sub(1);
                if (randIdPool[mintIdx] == randIdPool[randIdPoolSize]) {
                    randIdPool[mintIdx] = randIdPool[randIdPoolSize.sub(1)];
                } else {
                    randIdPool[mintIdx] = randIdPool[randIdPoolSize];
                }
            }
        }

        _safeMint(_to, tokenId);
    }

    function teamMint() external onlyTeam {
        _safeRandMint(msg.sender, 0);
    }

    function mintFreeGhostlys() external verifyFreeMint(msg.sender) {
        // amount is the lesser of freeMints and remaining supply
        uint _amount = freeMints[msg.sender] < MAX_GHOSTLYS - totalSupply() ? freeMints[msg.sender] : MAX_GHOSTLYS - totalSupply();
        for (uint i = 0; i < _amount; i++) {
            _safeRandMint(msg.sender, i);
        }
        freeMints[msg.sender] = 0;
    }

    function mintGhostlys(uint _amount) external payable verifyMint(msg.sender, _amount) {
        for (uint i = 0; i < _amount; i++) {
            _safeRandMint(msg.sender, i);
        }
        payable(_team[0]).transfer(msg.value.sub(msg.value.div(4)));  // team member 0 gets 75% of mint revenue
        payable(_team[1]).transfer(msg.value.div(4));                 // team member 1 gets 25% of mint revenue
    }

    function totalSupply() public view override(ERC721Enumerable) returns (uint256) {
        return super.totalSupply();
    }


    function _getTotalPaymentShares() internal view returns (uint256) {
        uint256 totalShares = 0;
        for (uint i = 0; i < _team.length; i++) {
            totalShares += _team_shares[i];
        }
        return totalShares;
    }

    function withdrawAll() public onlyTeam {
        require(address(this).balance > 0, "Cannot withdraw, balance is empty");

        uint256 totalShares = _getTotalPaymentShares();

        uint256 totalReceived = address(this).balance;

        for (uint i = 0; i < _team.length; i++) {
            address payable wallet = payable(_team[i]);
            uint256 payment = (totalReceived * _team_shares[i]) / totalShares;
            Address.sendValue(wallet, payment);
        }
    }

    // ensure this contract can receive payments (royalties)
    receive () external payable {}

    /**************************************************************************
     * Helper functions
     **************************************************************************/
    function random(string memory _tag, uint256 _int0) internal view returns (uint256) {
        return uint256(keccak256(abi.encodePacked(_tag, toString(_int0), toString(block.timestamp), msg.sender)));
    }

    function toString(uint256 value) internal pure returns (string memory) {
    // Inspired by OraclizeAPI's implementation - MIT license
    // 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);
    }
    /* End helper functions
     **************************************************************************/
}
/**

 Art, Generative Art, UI: Funeral - @yolofinancial
 Solidity & React:        Larkin  - @CodeLarkin
 Community: @farmgoddao, @SkullysNFT

  █████▒█    ██  ███▄    █ ▓█████  ██▀███   ▄▄▄       ██▓
▓██   ▒ ██  ▓██▒ ██ ▀█   █ ▓█   ▀ ▓██ ▒ ██▒▒████▄    ▓██▒
▒████ ░▓██  ▒██░▓██  ▀█ ██▒▒███   ▓██ ░▄█ ▒▒██  ▀█▄  ▒██░
░▓█▒  ░▓▓█  ░██░▓██▒  ▐▌██▒▒▓█  ▄ ▒██▀▀█▄  ░██▄▄▄▄██ ▒██░
░▒█░   ▒▒█████▓ ▒██░   ▓██░░▒████▒░██▓ ▒██▒ ▓█   ▓██▒░██████▒
 ▒ ░   ░▒▓▒ ▒ ▒ ░ ▒░   ▒ ▒ ░░ ▒░ ░░ ▒▓ ░▒▓░ ▒▒   ▓▒█░░ ▒░▓  ░
 ░     ░░▒░ ░ ░ ░ ░░   ░ ▒░ ░ ░  ░  ░▒ ░ ▒░  ▒   ▒▒ ░░ ░ ▒  ░
 ░ ░    ░░░ ░ ░    ░   ░ ░    ░     ░░   ░   ░   ▒     ░ ░
          ░              ░    ░  ░   ░           ░  ░    ░  ░

   ██╗      █████╗ ██████╗ ██╗  ██╗██╗███╗   ██╗
   ██║     ██╔══██╗██╔══██╗██║ ██╔╝██║████╗  ██║
   ██║     ███████║██████╔╝█████╔╝ ██║██╔██╗ ██║
   ██║     ██╔══██║██╔══██╗██╔═██╗ ██║██║╚██╗██║
   ███████╗██║  ██║██║  ██║██║  ██╗██║██║ ╚████║
   ╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝╚═╝  ╚═══╝
**/

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"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":"GHOSTLYS_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_GHOSTLYS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_MINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROVENANCE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"freeMints","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":[],"name":"getStatus","outputs":[{"internalType":"enum Ghostlys.Status","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintFreeGhostlys","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintGhostlys","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"presaleStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"Receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addr","type":"address[]"},{"internalType":"uint256[]","name":"_bals","type":"uint256[]"}],"name":"setManyWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newTime","type":"uint256"}],"name":"setPreSaleTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_provenanceHash","type":"string"}],"name":"setProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"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":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a06040819052600060808190526200001b91600d91620002fa565b506040805160208101918290526000908190526200003c91600e91620002fa565b5063617da440600f8190556200005690620151806200043b565b60105560646011556040805160608101825273c87bf1972dd048404cbd3fba300b69277552c47281527314e8f54f35ee42cdf436a19086659b34da6d9d47602082015273a4f7a42f2569f97de8218aa875f58533fe842fee91810191909152620000c590607890600362000389565b506040805160608101825260268152600c6020820152603291810191909152620000f4906079906003620003e1565b503480156200010257600080fd5b5060405180606001604052806027815260200162003b73602791396040518060400160405280600781526020016647484f53544c5960c81b815250816000908051906020019062000155929190620002fa565b5080516200016b906001906020840190620002fa565b5062000182915063152a902d60e11b905062000276565b336000908152607660205260408120805460ff1990811660019081179092557fbe332edf964b6de0dc4be7554af461ced14fa3b1c2d8227816983a17ca6e587780548216831790557314e8f54f35ee42cdf436a19086659b34da6d9d479092527f82ed00761aa6ff2dbeb86ea25fc5dc46bc540a73e2c0435284f8a09f413355808054909216179055600b80546001600160a01b03191630179055620002286005600c55565b60005b60648110156200026f57620002428160016200043b565b60128260648110620002585762000258620004c7565b015580620002668162000493565b9150506200022b565b50620004dd565b6001600160e01b03198082161415620002d55760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640160405180910390fd5b6001600160e01b0319166000908152600a60205260409020805460ff19166001179055565b828054620003089062000456565b90600052602060002090601f0160209004810192826200032c576000855562000377565b82601f106200034757805160ff191683800117855562000377565b8280016001018555821562000377579182015b82811115620003775782518255916020019190600101906200035a565b506200038592915062000424565b5090565b82805482825590600052602060002090810192821562000377579160200282015b828111156200037757825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620003aa565b82805482825590600052602060002090810192821562000377579160200282015b8281111562000377578251829060ff1690559160200191906001019062000402565b5b8082111562000385576000815560010162000425565b60008219821115620004515762000451620004b1565b500190565b600181811c908216806200046b57607f821691505b602082108114156200048d57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415620004aa57620004aa620004b1565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b61368680620004ed6000396000f3fe6080604052600436106102025760003560e01c80636352211e1161011d578063a82524b2116100b0578063c87b56dd1161007f578063e422522b11610064578063e422522b146105f0578063e985e9c514610605578063f0292a031461065b57600080fd5b8063c87b56dd146105b3578063cb0f5411146105d357600080fd5b8063a82524b214610548578063b88d4fde1461055e578063b92bbc081461057e578063ba7a86b81461059e57600080fd5b806370a08231116100ec57806370a08231146104de578063853828b6146104fe57806395d89b4114610513578063a22cb4651461052857600080fd5b80636352211e146104665780636373a6b1146104865780636bb7b1d91461049b5780636d41d4fb146104b157600080fd5b806323b872dd1161019557806342842e0e1161016457806342842e0e146103e45780634e69d560146104045780634f6ccce71461042657806355f804b31461044657600080fd5b806323b872dd146103425780632a55205a146103625780632f745c59146103ae57806340c98001146103ce57600080fd5b80630f0e4f73116101d15780630f0e4f73146102cc57806310969523146102ec57806311b1c31a1461030c57806318160ddd1461031f57600080fd5b806301ffc9a71461020e57806306fdde0314610243578063081812fc14610265578063095ea7b3146102aa57600080fd5b3661020957005b600080fd5b34801561021a57600080fd5b5061022e610229366004613105565b610670565b60405190151581526020015b60405180910390f35b34801561024f57600080fd5b506102586106bd565b60405161023a9190613338565b34801561027157600080fd5b50610285610280366004613188565b61074f565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023a565b3480156102b657600080fd5b506102ca6102c5366004613014565b610814565b005b3480156102d857600080fd5b506102ca6102e7366004613188565b61096d565b3480156102f857600080fd5b506102ca61030736600461313f565b610a0a565b6102ca61031a366004613188565b610aa6565b34801561032b57600080fd5b50610334610d37565b60405190815260200161023a565b34801561034e57600080fd5b506102ca61035d366004612f20565b610d47565b34801561036e57600080fd5b5061038261037d3660046131a1565b610dce565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260208301919091520161023a565b3480156103ba57600080fd5b506103346103c9366004613014565b610e0e565b3480156103da57600080fd5b506103346122b881565b3480156103f057600080fd5b506102ca6103ff366004612f20565b610ec3565b34801561041057600080fd5b50610419610ede565b60405161023a91906132f7565b34801561043257600080fd5b50610334610441366004613188565b610f04565b34801561045257600080fd5b506102ca61046136600461313f565b610fa8565b34801561047257600080fd5b50610285610481366004613188565b611040565b34801561049257600080fd5b506102586110d8565b3480156104a757600080fd5b5061033460105481565b3480156104bd57600080fd5b506103346104cc366004612edb565b60776020526000908152604090205481565b3480156104ea57600080fd5b506103346104f9366004612edb565b611166565b34801561050a57600080fd5b506102ca61121a565b34801561051f57600080fd5b506102586113c0565b34801561053457600080fd5b506102ca610543366004612fd8565b6113cf565b34801561055457600080fd5b50610334600f5481565b34801561056a57600080fd5b506102ca610579366004612f5c565b6114cc565b34801561058a57600080fd5b506102ca61059936600461303e565b611554565b3480156105aa57600080fd5b506102ca6116e5565b3480156105bf57600080fd5b506102586105ce366004613188565b611777565b3480156105df57600080fd5b506103346802b5e3af16b188000081565b3480156105fc57600080fd5b506102ca61186d565b34801561061157600080fd5b5061022e610620366004612ef6565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561066757600080fd5b50610334601481565b600061067b82611a65565b806106b757507fffffffff0000000000000000000000000000000000000000000000000000000082166000908152600a602052604090205460ff165b92915050565b6060600080546106cc9061346a565b80601f01602080910402602001604051908101604052809291908181526020018280546106f89061346a565b80156107455780601f1061071a57610100808354040283529160200191610745565b820191906000526020600020905b81548152906001019060200180831161072857829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff166107eb5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b600061081f82611040565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156108c35760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016107e2565b3373ffffffffffffffffffffffffffffffffffffffff821614806108ec57506108ec8133610620565b61095e5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016107e2565b6109688383611abb565b505050565b3360009081526076602052604090205460ff166109f25760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d00000000000000000000000000000000000000000060648201526084016107e2565b600f819055610a0481620151806133be565b60105550565b3360009081526076602052604090205460ff16610a8f5760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d00000000000000000000000000000000000000000060648201526084016107e2565b8051610aa290600d906020840190612d31565b5050565b33816014811115610af95760405162461bcd60e51b815260206004820152601e60248201527f547269656420746f206d696e7420746f6f206d616e79206174206f6e6365000060448201526064016107e2565b6002610b03610ede565b6002811115610b1457610b14613563565b14610b615760405162461bcd60e51b815260206004820152601b60248201527f5075626c69632073616c6520686173206e6f742073746172746564000000000060448201526064016107e2565b34610b75826802b5e3af16b18800006133ea565b1115610bc35760405162461bcd60e51b815260206004820152601a60248201527f4469646e27742073656e6420656e6f756768207061796d656e7400000000000060448201526064016107e2565b6122b8610bd882610bd2610d37565b90611b5b565b1115610c265760405162461bcd60e51b815260206004820152600860248201527f536f6c64206f757400000000000000000000000000000000000000000000000060448201526064016107e2565b60005b83811015610c4d57610c3b3382611b67565b80610c45816134b8565b915050610c29565b506078600081548110610c6257610c626135c1565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff166108fc610c9c610c95346004611cdd565b3490611ce9565b6040518115909202916000818181858888f19350505050158015610cc4573d6000803e3d6000fd5b506078600181548110610cd957610cd96135c1565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff166108fc610d09346004611cdd565b6040518115909202916000818181858888f19350505050158015610d31573d6000803e3d6000fd5b50505050565b6000610d4260085490565b905090565b610d513382611cf5565b610dc35760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016107e2565b610968838383611e4b565b600b54600c5473ffffffffffffffffffffffffffffffffffffffff90911690600090610e0590610dff856064611cdd565b90612089565b90509250929050565b6000610e1983611166565b8210610e8d5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e647300000000000000000000000000000000000000000060648201526084016107e2565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600660209081526040808320938352929052205490565b610968838383604051806020016040528060008152506114cc565b60006010544210610eef5750600290565b600f544210610efe5750600190565b50600090565b6000610f0f60085490565b8210610f835760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e6473000000000000000000000000000000000000000060648201526084016107e2565b60088281548110610f9657610f966135c1565b90600052602060002001549050919050565b3360009081526076602052604090205460ff1661102d5760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d00000000000000000000000000000000000000000060648201526084016107e2565b8051610aa290600e906020840190612d31565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16806106b75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016107e2565b600d80546110e59061346a565b80601f01602080910402602001604051908101604052809291908181526020018280546111119061346a565b801561115e5780601f106111335761010080835404028352916020019161115e565b820191906000526020600020905b81548152906001019060200180831161114157829003601f168201915b505050505081565b600073ffffffffffffffffffffffffffffffffffffffff82166111f15760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016107e2565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b3360009081526076602052604090205460ff1661129f5760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d00000000000000000000000000000000000000000060648201526084016107e2565b600047116113155760405162461bcd60e51b815260206004820152602160248201527f43616e6e6f742077697468647261772c2062616c616e636520697320656d707460448201527f790000000000000000000000000000000000000000000000000000000000000060648201526084016107e2565b600061131f612095565b90504760005b60785481101561096857600060788281548110611344576113446135c1565b60009182526020822001546079805473ffffffffffffffffffffffffffffffffffffffff909216935086918590811061137f5761137f6135c1565b90600052602060002001548561139591906133ea565b61139f91906133d6565b90506113ab82826120e7565b505080806113b8906134b8565b915050611325565b6060600180546106cc9061346a565b73ffffffffffffffffffffffffffffffffffffffff82163314156114355760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016107e2565b33600081815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6114d63383611cf5565b6115485760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016107e2565b610d318484848461220d565b3360009081526076602052604090205460ff166115d95760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d00000000000000000000000000000000000000000060648201526084016107e2565b80518251146116505760405162461bcd60e51b815260206004820152603260248201527f41646472657373657320616e642062616c616e636573206d757374206861766560448201527f2073616d65206172726179206c656e677468000000000000000000000000000060648201526084016107e2565b60005b82518110156109685781818151811061166e5761166e6135c1565b60200260200101516077600085848151811061168c5761168c6135c1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080806116dd906134b8565b915050611653565b3360009081526076602052604090205460ff1661176a5760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d00000000000000000000000000000000000000000060648201526084016107e2565b611775336000611b67565b565b60008181526002602052604090205460609073ffffffffffffffffffffffffffffffffffffffff166118115760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e000000000000000000000000000000000060648201526084016107e2565b600061181b612296565b9050600081511161183b5760405180602001604052806000815250611866565b80611845846122a5565b60405160200161185692919061320d565b6040516020818303038152906040525b9392505050565b336000818152607760205260409020546118ef5760405162461bcd60e51b815260206004820152603060248201527f4d7573742068617665206120736b756c6c79206265666f726520736e6170736860448201527f6f7420666f722066726565206d696e740000000000000000000000000000000060648201526084016107e2565b60016118f9610ede565b600281111561190a5761190a613563565b148061192e5750600261191b610ede565b600281111561192c5761192c613563565b145b61197a5760405162461bcd60e51b815260206004820152601760248201527f4d696e74696e6720686173206e6f74207374617274656400000000000000000060448201526064016107e2565b6122b8611985610d37565b106119d25760405162461bcd60e51b815260206004820152600860248201527f536f6c64206f757400000000000000000000000000000000000000000000000060448201526064016107e2565b60006119dc610d37565b6119e8906122b8613427565b3360009081526077602052604090205410611a1657611a05610d37565b611a11906122b8613427565b611a27565b336000908152607760205260409020545b905060005b81811015611a5057611a3e3382611b67565b80611a48816134b8565b915050611a2c565b50503360009081526077602052604081205550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d630000000000000000000000000000000000000000000000000000000014806106b757506106b7826123d7565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091558190611b1582611040565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061186682846133be565b6000601154611bab6040518060400160405280600981526020017f4d494e545f465245450000000000000000000000000000000000000000000000815250846124ba565b611bb591906134f1565b9050600060128260648110611bcc57611bcc6135c1565b015490506122b8611be06001610bd2610d37565b1015611cd3576064611bfc611bf3610d37565b6122b890611ce9565b10611c2d57611c136001610bd26064610bd2610d37565b60128360648110611c2657611c266135c1565b0155611cd3565b601154611c3b906001611ce9565b601181905560129060648110611c5357611c536135c1565b015460128360648110611c6857611c686135c1565b01541415611ca657601154601290611c81906001611ce9565b60648110611c9157611c916135c1565b015460128360648110611c2657611c266135c1565b601260115460648110611cbb57611cbb6135c1565b015460128360648110611cd057611cd06135c1565b01555b610d318482612520565b600061186682846133d6565b60006118668284613427565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16611d8c5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084016107e2565b6000611d9783611040565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e0657508373ffffffffffffffffffffffffffffffffffffffff16611dee8461074f565b73ffffffffffffffffffffffffffffffffffffffff16145b80611e43575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16611e6b82611040565b73ffffffffffffffffffffffffffffffffffffffff1614611ef45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e000000000000000000000000000000000000000000000060648201526084016107e2565b73ffffffffffffffffffffffffffffffffffffffff8216611f7c5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016107e2565b611f8783838361253a565b611f92600082611abb565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120805460019290611fc8908490613427565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906120039084906133be565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061186682846133ea565b600080805b6078548110156120e157607981815481106120b7576120b76135c1565b9060005260206000200154826120cd91906133be565b9150806120d9816134b8565b91505061209a565b50919050565b804710156121375760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016107e2565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114612191576040519150601f19603f3d011682016040523d82523d6000602084013e612196565b606091505b50509050806109685760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016107e2565b612218848484611e4b565b61222484848484612640565b610d315760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016107e2565b6060600e80546106cc9061346a565b6060816122e557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561230f57806122f9816134b8565b91506123089050600a836133d6565b91506122e9565b60008167ffffffffffffffff81111561232a5761232a6135f0565b6040519080825280601f01601f191660200182016040528015612354576020820181803683370190505b5090505b8415611e4357612369600183613427565b9150612376600a866134f1565b6123819060306133be565b60f81b818381518110612396576123966135c1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506123d0600a866133d6565b9450612358565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061246a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806106b757507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146106b7565b6000826124c683612825565b6124cf42612825565b336040516020016124e3949392919061323c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b610aa2828260405180602001604052806000815250612957565b73ffffffffffffffffffffffffffffffffffffffff83166125a25761259d81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6125df565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146125df576125df83826129e0565b73ffffffffffffffffffffffffffffffffffffffff82166126035761096881612a97565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610968576109688282612b46565b600073ffffffffffffffffffffffffffffffffffffffff84163b1561281a576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a02906126b79033908990889088906004016132ae565b602060405180830381600087803b1580156126d157600080fd5b505af192505050801561271f575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261271c91810190613122565b60015b6127cf573d80801561274d576040519150601f19603f3d011682016040523d82523d6000602084013e612752565b606091505b5080516127c75760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016107e2565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050611e43565b506001949350505050565b60608161286557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561288f5780612879816134b8565b91506128889050600a836133d6565b9150612869565b60008167ffffffffffffffff8111156128aa576128aa6135f0565b6040519080825280601f01601f1916602001820160405280156128d4576020820181803683370190505b5090505b8415611e43576128e9600183613427565b91506128f6600a866134f1565b6129019060306133be565b60f81b818381518110612916576129166135c1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612950600a866133d6565b94506128d8565b6129618383612b97565b61296e6000848484612640565b6109685760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016107e2565b600060016129ed84611166565b6129f79190613427565b600083815260076020526040902054909150808214612a575773ffffffffffffffffffffffffffffffffffffffff841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b50600091825260076020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600681528383209183525290812055565b600854600090612aa990600190613427565b60008381526009602052604081205460088054939450909284908110612ad157612ad16135c1565b906000526020600020015490508060088381548110612af257612af26135c1565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612b2a57612b2a613592565b6001900381819060005260206000200160009055905550505050565b6000612b5183611166565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b73ffffffffffffffffffffffffffffffffffffffff8216612bfa5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016107e2565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1615612c6c5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016107e2565b612c786000838361253a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805460019290612cae9084906133be565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b828054612d3d9061346a565b90600052602060002090601f016020900481019282612d5f5760008555612da5565b82601f10612d7857805160ff1916838001178555612da5565b82800160010185558215612da5579182015b82811115612da5578251825591602001919060010190612d8a565b50612db1929150612db5565b5090565b5b80821115612db15760008155600101612db6565b600067ffffffffffffffff831115612de457612de46135f0565b612e1560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8601160161334b565b9050828152838383011115612e2957600080fd5b828260208301376000602084830101529392505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612e6457600080fd5b919050565b600082601f830112612e7a57600080fd5b81356020612e8f612e8a8361339a565b61334b565b80838252828201915082860187848660051b8901011115612eaf57600080fd5b60005b85811015612ece57813584529284019290840190600101612eb2565b5090979650505050505050565b600060208284031215612eed57600080fd5b61186682612e40565b60008060408385031215612f0957600080fd5b612f1283612e40565b9150610e0560208401612e40565b600080600060608486031215612f3557600080fd5b612f3e84612e40565b9250612f4c60208501612e40565b9150604084013590509250925092565b60008060008060808587031215612f7257600080fd5b612f7b85612e40565b9350612f8960208601612e40565b925060408501359150606085013567ffffffffffffffff811115612fac57600080fd5b8501601f81018713612fbd57600080fd5b612fcc87823560208401612dca565b91505092959194509250565b60008060408385031215612feb57600080fd5b612ff483612e40565b91506020830135801515811461300957600080fd5b809150509250929050565b6000806040838503121561302757600080fd5b61303083612e40565b946020939093013593505050565b6000806040838503121561305157600080fd5b823567ffffffffffffffff8082111561306957600080fd5b818501915085601f83011261307d57600080fd5b8135602061308d612e8a8361339a565b8083825282820191508286018a848660051b89010111156130ad57600080fd5b600096505b848710156130d7576130c381612e40565b8352600196909601959183019183016130b2565b50965050860135925050808211156130ee57600080fd5b506130fb85828601612e69565b9150509250929050565b60006020828403121561311757600080fd5b81356118668161361f565b60006020828403121561313457600080fd5b81516118668161361f565b60006020828403121561315157600080fd5b813567ffffffffffffffff81111561316857600080fd5b8201601f8101841361317957600080fd5b611e4384823560208401612dca565b60006020828403121561319a57600080fd5b5035919050565b600080604083850312156131b457600080fd5b50508035926020909101359150565b600081518084526131db81602086016020860161343e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000835161321f81846020880161343e565b83519083019061323381836020880161343e565b01949350505050565b6000855161324e818460208a0161343e565b855190830190613262818360208a0161343e565b855191019061327581836020890161343e565b60609490941b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016930192835250506014019392505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526132ed60808301846131c3565b9695505050505050565b6020810160038310613332577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60208152600061186660208301846131c3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613392576133926135f0565b604052919050565b600067ffffffffffffffff8211156133b4576133b46135f0565b5060051b60200190565b600082198211156133d1576133d1613505565b500190565b6000826133e5576133e5613534565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561342257613422613505565b500290565b60008282101561343957613439613505565b500390565b60005b83811015613459578181015183820152602001613441565b83811115610d315750506000910152565b600181811c9082168061347e57607f821691505b602082108114156120e1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156134ea576134ea613505565b5060010190565b60008261350057613500613534565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7fffffffff000000000000000000000000000000000000000000000000000000008116811461364d57600080fd5b5056fea264697066735822122095b838a3dd3608cfd5dc8efd118e151e1f688321cd72670daf4e922eee1177b664736f6c6343000807003347686f73746c79732e2e2e20456e746572207468652073756d6d6f6e696e6720636972636c652e

Deployed Bytecode

0x6080604052600436106102025760003560e01c80636352211e1161011d578063a82524b2116100b0578063c87b56dd1161007f578063e422522b11610064578063e422522b146105f0578063e985e9c514610605578063f0292a031461065b57600080fd5b8063c87b56dd146105b3578063cb0f5411146105d357600080fd5b8063a82524b214610548578063b88d4fde1461055e578063b92bbc081461057e578063ba7a86b81461059e57600080fd5b806370a08231116100ec57806370a08231146104de578063853828b6146104fe57806395d89b4114610513578063a22cb4651461052857600080fd5b80636352211e146104665780636373a6b1146104865780636bb7b1d91461049b5780636d41d4fb146104b157600080fd5b806323b872dd1161019557806342842e0e1161016457806342842e0e146103e45780634e69d560146104045780634f6ccce71461042657806355f804b31461044657600080fd5b806323b872dd146103425780632a55205a146103625780632f745c59146103ae57806340c98001146103ce57600080fd5b80630f0e4f73116101d15780630f0e4f73146102cc57806310969523146102ec57806311b1c31a1461030c57806318160ddd1461031f57600080fd5b806301ffc9a71461020e57806306fdde0314610243578063081812fc14610265578063095ea7b3146102aa57600080fd5b3661020957005b600080fd5b34801561021a57600080fd5b5061022e610229366004613105565b610670565b60405190151581526020015b60405180910390f35b34801561024f57600080fd5b506102586106bd565b60405161023a9190613338565b34801561027157600080fd5b50610285610280366004613188565b61074f565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023a565b3480156102b657600080fd5b506102ca6102c5366004613014565b610814565b005b3480156102d857600080fd5b506102ca6102e7366004613188565b61096d565b3480156102f857600080fd5b506102ca61030736600461313f565b610a0a565b6102ca61031a366004613188565b610aa6565b34801561032b57600080fd5b50610334610d37565b60405190815260200161023a565b34801561034e57600080fd5b506102ca61035d366004612f20565b610d47565b34801561036e57600080fd5b5061038261037d3660046131a1565b610dce565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260208301919091520161023a565b3480156103ba57600080fd5b506103346103c9366004613014565b610e0e565b3480156103da57600080fd5b506103346122b881565b3480156103f057600080fd5b506102ca6103ff366004612f20565b610ec3565b34801561041057600080fd5b50610419610ede565b60405161023a91906132f7565b34801561043257600080fd5b50610334610441366004613188565b610f04565b34801561045257600080fd5b506102ca61046136600461313f565b610fa8565b34801561047257600080fd5b50610285610481366004613188565b611040565b34801561049257600080fd5b506102586110d8565b3480156104a757600080fd5b5061033460105481565b3480156104bd57600080fd5b506103346104cc366004612edb565b60776020526000908152604090205481565b3480156104ea57600080fd5b506103346104f9366004612edb565b611166565b34801561050a57600080fd5b506102ca61121a565b34801561051f57600080fd5b506102586113c0565b34801561053457600080fd5b506102ca610543366004612fd8565b6113cf565b34801561055457600080fd5b50610334600f5481565b34801561056a57600080fd5b506102ca610579366004612f5c565b6114cc565b34801561058a57600080fd5b506102ca61059936600461303e565b611554565b3480156105aa57600080fd5b506102ca6116e5565b3480156105bf57600080fd5b506102586105ce366004613188565b611777565b3480156105df57600080fd5b506103346802b5e3af16b188000081565b3480156105fc57600080fd5b506102ca61186d565b34801561061157600080fd5b5061022e610620366004612ef6565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561066757600080fd5b50610334601481565b600061067b82611a65565b806106b757507fffffffff0000000000000000000000000000000000000000000000000000000082166000908152600a602052604090205460ff165b92915050565b6060600080546106cc9061346a565b80601f01602080910402602001604051908101604052809291908181526020018280546106f89061346a565b80156107455780601f1061071a57610100808354040283529160200191610745565b820191906000526020600020905b81548152906001019060200180831161072857829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff166107eb5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b600061081f82611040565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156108c35760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016107e2565b3373ffffffffffffffffffffffffffffffffffffffff821614806108ec57506108ec8133610620565b61095e5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016107e2565b6109688383611abb565b505050565b3360009081526076602052604090205460ff166109f25760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d00000000000000000000000000000000000000000060648201526084016107e2565b600f819055610a0481620151806133be565b60105550565b3360009081526076602052604090205460ff16610a8f5760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d00000000000000000000000000000000000000000060648201526084016107e2565b8051610aa290600d906020840190612d31565b5050565b33816014811115610af95760405162461bcd60e51b815260206004820152601e60248201527f547269656420746f206d696e7420746f6f206d616e79206174206f6e6365000060448201526064016107e2565b6002610b03610ede565b6002811115610b1457610b14613563565b14610b615760405162461bcd60e51b815260206004820152601b60248201527f5075626c69632073616c6520686173206e6f742073746172746564000000000060448201526064016107e2565b34610b75826802b5e3af16b18800006133ea565b1115610bc35760405162461bcd60e51b815260206004820152601a60248201527f4469646e27742073656e6420656e6f756768207061796d656e7400000000000060448201526064016107e2565b6122b8610bd882610bd2610d37565b90611b5b565b1115610c265760405162461bcd60e51b815260206004820152600860248201527f536f6c64206f757400000000000000000000000000000000000000000000000060448201526064016107e2565b60005b83811015610c4d57610c3b3382611b67565b80610c45816134b8565b915050610c29565b506078600081548110610c6257610c626135c1565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff166108fc610c9c610c95346004611cdd565b3490611ce9565b6040518115909202916000818181858888f19350505050158015610cc4573d6000803e3d6000fd5b506078600181548110610cd957610cd96135c1565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff166108fc610d09346004611cdd565b6040518115909202916000818181858888f19350505050158015610d31573d6000803e3d6000fd5b50505050565b6000610d4260085490565b905090565b610d513382611cf5565b610dc35760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016107e2565b610968838383611e4b565b600b54600c5473ffffffffffffffffffffffffffffffffffffffff90911690600090610e0590610dff856064611cdd565b90612089565b90509250929050565b6000610e1983611166565b8210610e8d5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e647300000000000000000000000000000000000000000060648201526084016107e2565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600660209081526040808320938352929052205490565b610968838383604051806020016040528060008152506114cc565b60006010544210610eef5750600290565b600f544210610efe5750600190565b50600090565b6000610f0f60085490565b8210610f835760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e6473000000000000000000000000000000000000000060648201526084016107e2565b60088281548110610f9657610f966135c1565b90600052602060002001549050919050565b3360009081526076602052604090205460ff1661102d5760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d00000000000000000000000000000000000000000060648201526084016107e2565b8051610aa290600e906020840190612d31565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16806106b75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016107e2565b600d80546110e59061346a565b80601f01602080910402602001604051908101604052809291908181526020018280546111119061346a565b801561115e5780601f106111335761010080835404028352916020019161115e565b820191906000526020600020905b81548152906001019060200180831161114157829003601f168201915b505050505081565b600073ffffffffffffffffffffffffffffffffffffffff82166111f15760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016107e2565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b3360009081526076602052604090205460ff1661129f5760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d00000000000000000000000000000000000000000060648201526084016107e2565b600047116113155760405162461bcd60e51b815260206004820152602160248201527f43616e6e6f742077697468647261772c2062616c616e636520697320656d707460448201527f790000000000000000000000000000000000000000000000000000000000000060648201526084016107e2565b600061131f612095565b90504760005b60785481101561096857600060788281548110611344576113446135c1565b60009182526020822001546079805473ffffffffffffffffffffffffffffffffffffffff909216935086918590811061137f5761137f6135c1565b90600052602060002001548561139591906133ea565b61139f91906133d6565b90506113ab82826120e7565b505080806113b8906134b8565b915050611325565b6060600180546106cc9061346a565b73ffffffffffffffffffffffffffffffffffffffff82163314156114355760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016107e2565b33600081815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6114d63383611cf5565b6115485760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016107e2565b610d318484848461220d565b3360009081526076602052604090205460ff166115d95760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d00000000000000000000000000000000000000000060648201526084016107e2565b80518251146116505760405162461bcd60e51b815260206004820152603260248201527f41646472657373657320616e642062616c616e636573206d757374206861766560448201527f2073616d65206172726179206c656e677468000000000000000000000000000060648201526084016107e2565b60005b82518110156109685781818151811061166e5761166e6135c1565b60200260200101516077600085848151811061168c5761168c6135c1565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555080806116dd906134b8565b915050611653565b3360009081526076602052604090205460ff1661176a5760405162461bcd60e51b815260206004820152602b60248201527f43616e277420646f20746861742c20796f7520617265206e6f7420706172742060448201527f6f6620746865207465616d00000000000000000000000000000000000000000060648201526084016107e2565b611775336000611b67565b565b60008181526002602052604090205460609073ffffffffffffffffffffffffffffffffffffffff166118115760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e000000000000000000000000000000000060648201526084016107e2565b600061181b612296565b9050600081511161183b5760405180602001604052806000815250611866565b80611845846122a5565b60405160200161185692919061320d565b6040516020818303038152906040525b9392505050565b336000818152607760205260409020546118ef5760405162461bcd60e51b815260206004820152603060248201527f4d7573742068617665206120736b756c6c79206265666f726520736e6170736860448201527f6f7420666f722066726565206d696e740000000000000000000000000000000060648201526084016107e2565b60016118f9610ede565b600281111561190a5761190a613563565b148061192e5750600261191b610ede565b600281111561192c5761192c613563565b145b61197a5760405162461bcd60e51b815260206004820152601760248201527f4d696e74696e6720686173206e6f74207374617274656400000000000000000060448201526064016107e2565b6122b8611985610d37565b106119d25760405162461bcd60e51b815260206004820152600860248201527f536f6c64206f757400000000000000000000000000000000000000000000000060448201526064016107e2565b60006119dc610d37565b6119e8906122b8613427565b3360009081526077602052604090205410611a1657611a05610d37565b611a11906122b8613427565b611a27565b336000908152607760205260409020545b905060005b81811015611a5057611a3e3382611b67565b80611a48816134b8565b915050611a2c565b50503360009081526077602052604081205550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d630000000000000000000000000000000000000000000000000000000014806106b757506106b7826123d7565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091558190611b1582611040565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061186682846133be565b6000601154611bab6040518060400160405280600981526020017f4d494e545f465245450000000000000000000000000000000000000000000000815250846124ba565b611bb591906134f1565b9050600060128260648110611bcc57611bcc6135c1565b015490506122b8611be06001610bd2610d37565b1015611cd3576064611bfc611bf3610d37565b6122b890611ce9565b10611c2d57611c136001610bd26064610bd2610d37565b60128360648110611c2657611c266135c1565b0155611cd3565b601154611c3b906001611ce9565b601181905560129060648110611c5357611c536135c1565b015460128360648110611c6857611c686135c1565b01541415611ca657601154601290611c81906001611ce9565b60648110611c9157611c916135c1565b015460128360648110611c2657611c266135c1565b601260115460648110611cbb57611cbb6135c1565b015460128360648110611cd057611cd06135c1565b01555b610d318482612520565b600061186682846133d6565b60006118668284613427565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16611d8c5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084016107e2565b6000611d9783611040565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611e0657508373ffffffffffffffffffffffffffffffffffffffff16611dee8461074f565b73ffffffffffffffffffffffffffffffffffffffff16145b80611e43575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16611e6b82611040565b73ffffffffffffffffffffffffffffffffffffffff1614611ef45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e000000000000000000000000000000000000000000000060648201526084016107e2565b73ffffffffffffffffffffffffffffffffffffffff8216611f7c5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016107e2565b611f8783838361253a565b611f92600082611abb565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120805460019290611fc8908490613427565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906120039084906133be565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600061186682846133ea565b600080805b6078548110156120e157607981815481106120b7576120b76135c1565b9060005260206000200154826120cd91906133be565b9150806120d9816134b8565b91505061209a565b50919050565b804710156121375760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016107e2565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114612191576040519150601f19603f3d011682016040523d82523d6000602084013e612196565b606091505b50509050806109685760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016107e2565b612218848484611e4b565b61222484848484612640565b610d315760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016107e2565b6060600e80546106cc9061346a565b6060816122e557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561230f57806122f9816134b8565b91506123089050600a836133d6565b91506122e9565b60008167ffffffffffffffff81111561232a5761232a6135f0565b6040519080825280601f01601f191660200182016040528015612354576020820181803683370190505b5090505b8415611e4357612369600183613427565b9150612376600a866134f1565b6123819060306133be565b60f81b818381518110612396576123966135c1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506123d0600a866133d6565b9450612358565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061246a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806106b757507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146106b7565b6000826124c683612825565b6124cf42612825565b336040516020016124e3949392919061323c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b610aa2828260405180602001604052806000815250612957565b73ffffffffffffffffffffffffffffffffffffffff83166125a25761259d81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6125df565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146125df576125df83826129e0565b73ffffffffffffffffffffffffffffffffffffffff82166126035761096881612a97565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610968576109688282612b46565b600073ffffffffffffffffffffffffffffffffffffffff84163b1561281a576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a02906126b79033908990889088906004016132ae565b602060405180830381600087803b1580156126d157600080fd5b505af192505050801561271f575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261271c91810190613122565b60015b6127cf573d80801561274d576040519150601f19603f3d011682016040523d82523d6000602084013e612752565b606091505b5080516127c75760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016107e2565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050611e43565b506001949350505050565b60608161286557505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b811561288f5780612879816134b8565b91506128889050600a836133d6565b9150612869565b60008167ffffffffffffffff8111156128aa576128aa6135f0565b6040519080825280601f01601f1916602001820160405280156128d4576020820181803683370190505b5090505b8415611e43576128e9600183613427565b91506128f6600a866134f1565b6129019060306133be565b60f81b818381518110612916576129166135c1565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612950600a866133d6565b94506128d8565b6129618383612b97565b61296e6000848484612640565b6109685760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016107e2565b600060016129ed84611166565b6129f79190613427565b600083815260076020526040902054909150808214612a575773ffffffffffffffffffffffffffffffffffffffff841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b50600091825260076020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600681528383209183525290812055565b600854600090612aa990600190613427565b60008381526009602052604081205460088054939450909284908110612ad157612ad16135c1565b906000526020600020015490508060088381548110612af257612af26135c1565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612b2a57612b2a613592565b6001900381819060005260206000200160009055905550505050565b6000612b5183611166565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b73ffffffffffffffffffffffffffffffffffffffff8216612bfa5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016107e2565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1615612c6c5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016107e2565b612c786000838361253a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805460019290612cae9084906133be565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b828054612d3d9061346a565b90600052602060002090601f016020900481019282612d5f5760008555612da5565b82601f10612d7857805160ff1916838001178555612da5565b82800160010185558215612da5579182015b82811115612da5578251825591602001919060010190612d8a565b50612db1929150612db5565b5090565b5b80821115612db15760008155600101612db6565b600067ffffffffffffffff831115612de457612de46135f0565b612e1560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8601160161334b565b9050828152838383011115612e2957600080fd5b828260208301376000602084830101529392505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612e6457600080fd5b919050565b600082601f830112612e7a57600080fd5b81356020612e8f612e8a8361339a565b61334b565b80838252828201915082860187848660051b8901011115612eaf57600080fd5b60005b85811015612ece57813584529284019290840190600101612eb2565b5090979650505050505050565b600060208284031215612eed57600080fd5b61186682612e40565b60008060408385031215612f0957600080fd5b612f1283612e40565b9150610e0560208401612e40565b600080600060608486031215612f3557600080fd5b612f3e84612e40565b9250612f4c60208501612e40565b9150604084013590509250925092565b60008060008060808587031215612f7257600080fd5b612f7b85612e40565b9350612f8960208601612e40565b925060408501359150606085013567ffffffffffffffff811115612fac57600080fd5b8501601f81018713612fbd57600080fd5b612fcc87823560208401612dca565b91505092959194509250565b60008060408385031215612feb57600080fd5b612ff483612e40565b91506020830135801515811461300957600080fd5b809150509250929050565b6000806040838503121561302757600080fd5b61303083612e40565b946020939093013593505050565b6000806040838503121561305157600080fd5b823567ffffffffffffffff8082111561306957600080fd5b818501915085601f83011261307d57600080fd5b8135602061308d612e8a8361339a565b8083825282820191508286018a848660051b89010111156130ad57600080fd5b600096505b848710156130d7576130c381612e40565b8352600196909601959183019183016130b2565b50965050860135925050808211156130ee57600080fd5b506130fb85828601612e69565b9150509250929050565b60006020828403121561311757600080fd5b81356118668161361f565b60006020828403121561313457600080fd5b81516118668161361f565b60006020828403121561315157600080fd5b813567ffffffffffffffff81111561316857600080fd5b8201601f8101841361317957600080fd5b611e4384823560208401612dca565b60006020828403121561319a57600080fd5b5035919050565b600080604083850312156131b457600080fd5b50508035926020909101359150565b600081518084526131db81602086016020860161343e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000835161321f81846020880161343e565b83519083019061323381836020880161343e565b01949350505050565b6000855161324e818460208a0161343e565b855190830190613262818360208a0161343e565b855191019061327581836020890161343e565b60609490941b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016930192835250506014019392505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526132ed60808301846131c3565b9695505050505050565b6020810160038310613332577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60208152600061186660208301846131c3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613392576133926135f0565b604052919050565b600067ffffffffffffffff8211156133b4576133b46135f0565b5060051b60200190565b600082198211156133d1576133d1613505565b500190565b6000826133e5576133e5613534565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561342257613422613505565b500290565b60008282101561343957613439613505565b500390565b60005b83811015613459578181015183820152602001613441565b83811115610d315750506000910152565b600181811c9082168061347e57607f821691505b602082108114156120e1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156134ea576134ea613505565b5060010190565b60008261350057613500613534565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7fffffffff000000000000000000000000000000000000000000000000000000008116811461364d57600080fd5b5056fea264697066735822122095b838a3dd3608cfd5dc8efd118e151e1f688321cd72670daf4e922eee1177b664736f6c63430008070033

Deployed Bytecode Sourcemap

59112:9411:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53701:190;;;;;;;;;;-1:-1:-1;53701:190:0;;;;;:::i;:::-;;:::i;:::-;;;9058:14:1;;9051:22;9033:41;;9021:2;9006:18;53701:190:0;;;;;;;;25093:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;26652:221::-;;;;;;;;;;-1:-1:-1;26652:221:0;;;;;:::i;:::-;;:::i;:::-;;;8020:42:1;8008:55;;;7990:74;;7978:2;7963:18;26652:221:0;7844:226:1;26175:411:0;;;;;;;;;;-1:-1:-1;26175:411:0;;;;;:::i;:::-;;:::i;:::-;;63119:153;;;;;;;;;;-1:-1:-1;63119:153:0;;;;;:::i;:::-;;:::i;62137:123::-;;;;;;;;;;-1:-1:-1;62137:123:0;;;;;:::i;:::-;;:::i;65873:419::-;;;;;;:::i;:::-;;:::i;66300:125::-;;;;;;;;;;;;;:::i;:::-;;;20488:25:1;;;20476:2;20461:18;66300:125:0;20342:177:1;27542:339:0;;;;;;;;;;-1:-1:-1;27542:339:0;;;;;:::i;:::-;;:::i;57168:239::-;;;;;;;;;;-1:-1:-1;57168:239:0;;;;;:::i;:::-;;:::i;:::-;;;;8795:42:1;8783:55;;;8765:74;;8870:2;8855:18;;8848:34;;;;8738:18;57168:239:0;8591:297:1;40373:256:0;;;;;;;;;;-1:-1:-1;40373:256:0;;;;;:::i;:::-;;:::i;59407:40::-;;;;;;;;;;;;59443:4;59407:40;;27952:185;;;;;;;;;;-1:-1:-1;27952:185:0;;;;;:::i;:::-;;:::i;62813:298::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;40895:233::-;;;;;;;;;;-1:-1:-1;40895:233:0;;;;;:::i;:::-;;:::i;62385:108::-;;;;;;;;;;-1:-1:-1;62385:108:0;;;;;:::i;:::-;;:::i;24787:239::-;;;;;;;;;;-1:-1:-1;24787:239:0;;;;;:::i;:::-;;:::i;59326:29::-;;;;;;;;;;;;;:::i;59640:61::-;;;;;;;;;;;;;;;;59974:41;;;;;;;;;;-1:-1:-1;59974:41:0;;;;;:::i;:::-;;;;;;;;;;;;;;24517:208;;;;;;;;;;-1:-1:-1;24517:208:0;;;;;:::i;:::-;;:::i;66687:496::-;;;;;;;;;;;;;:::i;25262:104::-;;;;;;;;;;;;;:::i;26945:295::-;;;;;;;;;;-1:-1:-1;26945:295:0;;;;;:::i;:::-;;:::i;59550:41::-;;;;;;;;;;;;;;;;28208:328;;;;;;;;;;-1:-1:-1;28208:328:0;;;;;:::i;:::-;;:::i;62501:304::-;;;;;;;;;;-1:-1:-1;62501:304:0;;;;;:::i;:::-;;:::i;65364:85::-;;;;;;;;;;;;;:::i;25437:334::-;;;;;;;;;;-1:-1:-1;25437:334:0;;;;;:::i;:::-;;:::i;59495:46::-;;;;;;;;;;;;59533:8;59495:46;;65457:408;;;;;;;;;;;;;:::i;27311:164::-;;;;;;;;;;-1:-1:-1;27311:164:0;;;;;:::i;:::-;27432:25;;;;27408:4;27432:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;27311:164;59454:34;;;;;;;;;;;;59486:2;59454:34;;53701:190;53786:4;53810:36;53834:11;53810:23;:36::i;:::-;:73;;;-1:-1:-1;53850:33:0;;;;;;;:20;:33;;;;;;;;53810:73;53803:80;53701:190;-1:-1:-1;;53701:190:0:o;25093:100::-;25147:13;25180:5;25173:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25093:100;:::o;26652:221::-;26728:7;30135:16;;;:7;:16;;;;;;:30;:16;26748:73;;;;-1:-1:-1;;;26748:73:0;;16608:2:1;26748:73:0;;;16590:21:1;16647:2;16627:18;;;16620:30;16686:34;16666:18;;;16659:62;16757:14;16737:18;;;16730:42;16789:19;;26748:73:0;;;;;;;;;-1:-1:-1;26841:24:0;;;;:15;:24;;;;;;;;;26652:221::o;26175:411::-;26256:13;26272:23;26287:7;26272:14;:23::i;:::-;26256:39;;26320:5;26314:11;;:2;:11;;;;26306:57;;;;-1:-1:-1;;;26306:57:0;;18264:2:1;26306:57:0;;;18246:21:1;18303:2;18283:18;;;18276:30;18342:34;18322:18;;;18315:62;18413:3;18393:18;;;18386:31;18434:19;;26306:57:0;18062:397:1;26306:57:0;19699:10;26398:21;;;;;:62;;-1:-1:-1;26423:37:0;26440:5;19699:10;27311:164;:::i;26423:37::-;26376:168;;;;-1:-1:-1;;;26376:168:0;;14646:2:1;26376:168:0;;;14628:21:1;14685:2;14665:18;;;14658:30;14724:34;14704:18;;;14697:62;14795:26;14775:18;;;14768:54;14839:19;;26376:168:0;14444:420:1;26376:168:0;26557:21;26566:2;26570:7;26557:8;:21::i;:::-;26245:341;26175:411;;:::o;63119:153::-;61316:10;61309:18;;;;:6;:18;;;;;;;;61301:74;;;;-1:-1:-1;;;61301:74:0;;11519:2:1;61301:74:0;;;11501:21:1;11558:2;11538:18;;;11531:30;11597:34;11577:18;;;11570:62;11668:13;11648:18;;;11641:41;11699:19;;61301:74:0;11317:407:1;61301:74:0;63185:16:::1;:27:::0;;;63245:19:::1;63204:8:::0;63256::::1;63245:19;:::i;:::-;63223;:41:::0;-1:-1:-1;63119:153:0:o;62137:123::-;61316:10;61309:18;;;;:6;:18;;;;;;;;61301:74;;;;-1:-1:-1;;;61301:74:0;;11519:2:1;61301:74:0;;;11501:21:1;11558:2;11538:18;;;11531:30;11597:34;11577:18;;;11570:62;11668:13;11648:18;;;11641:41;11699:19;;61301:74:0;11317:407:1;61301:74:0;62224:28;;::::1;::::0;:10:::1;::::0;:28:::1;::::0;::::1;::::0;::::1;:::i;:::-;;62137:123:::0;:::o;65873:419::-;65937:10;65949:7;59486:2;61806:7;:19;;61798:62;;;;-1:-1:-1;;;61798:62:0;;18666:2:1;61798:62:0;;;18648:21:1;18705:2;18685:18;;;18678:30;18744:32;18724:18;;;18717:60;18794:18;;61798:62:0;18464:354:1;61798:62:0;61894:22;61879:11;:9;:11::i;:::-;:37;;;;;;;;:::i;:::-;;61871:77;;;;-1:-1:-1;;;61871:77:0;;11931:2:1;61871:77:0;;;11913:21:1;11970:2;11950:18;;;11943:30;12009:29;11989:18;;;11982:57;12056:18;;61871:77:0;11729:351:1;61871:77:0;61995:9;61967:24;61984:7;59533:8;61967:24;:::i;:::-;:37;;61959:76;;;;-1:-1:-1;;;61959:76:0;;15892:2:1;61959:76:0;;;15874:21:1;15931:2;15911:18;;;15904:30;15970:28;15950:18;;;15943:56;16016:18;;61959:76:0;15690:350:1;61959:76:0;59443:4;62054:26;62072:7;62054:13;:11;:13::i;:::-;:17;;:26::i;:::-;:42;;62046:63;;;;-1:-1:-1;;;62046:63:0;;19443:2:1;62046:63:0;;;19425:21:1;19482:1;19462:18;;;19455:29;19520:10;19500:18;;;19493:38;19548:18;;62046:63:0;19241:331:1;62046:63:0;65974:6:::1;65969:90;65990:7;65986:1;:11;65969:90;;;66019:28;66033:10;66045:1;66019:13;:28::i;:::-;65999:3:::0;::::1;::::0;::::1;:::i;:::-;;;;65969:90;;;;66077:5;66083:1;66077:8;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;::::1;;66069:59;66096:31;66110:16;:9;66124:1;66110:13;:16::i;:::-;66096:9;::::0;:13:::1;:31::i;:::-;66069:59;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;66190:5;66196:1;66190:8;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;::::1;;66182:44;66209:16;:9;66223:1;66209:13;:16::i;:::-;66182:44;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;65873:419:::0;;;:::o;66300:125::-;66371:7;66398:19;40793:10;:17;;40705:113;66398:19;66391:26;;66300:125;:::o;27542:339::-;27737:41;19699:10;27770:7;27737:18;:41::i;:::-;27729:103;;;;-1:-1:-1;;;27729:103:0;;19025:2:1;27729:103:0;;;19007:21:1;19064:2;19044:18;;;19037:30;19103:34;19083:18;;;19076:62;19174:19;19154:18;;;19147:47;19211:19;;27729:103:0;18823:413:1;27729:103:0;27845:28;27855:4;27861:2;27865:7;27845:9;:28::i;57168:239::-;57328:8;;57383:17;;57328:8;;;;;57269:16;;57359:42;;:19;:10;57374:3;57359:14;:19::i;:::-;:23;;:42::i;:::-;57343:58;;57168:239;;;;;:::o;40373:256::-;40470:7;40506:23;40523:5;40506:16;:23::i;:::-;40498:5;:31;40490:87;;;;-1:-1:-1;;;40490:87:0;;10331:2:1;40490:87:0;;;10313:21:1;10370:2;10350:18;;;10343:30;10409:34;10389:18;;;10382:62;10480:13;10460:18;;;10453:41;10511:19;;40490:87:0;10129:407:1;40490:87:0;-1:-1:-1;40595:19:0;;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;40373:256::o;27952:185::-;28090:39;28107:4;28113:2;28117:7;28090:39;;;;;;;;;;;;:16;:39::i;62813:298::-;62855:6;62896:19;;62877:15;:38;62874:199;;-1:-1:-1;62939:22:0;;62813:298::o;62874:199::-;63002:16;;62983:15;:35;62979:94;;-1:-1:-1;63042:19:0;;62813:298::o;62979:94::-;-1:-1:-1;63090:13:0;;62813:298::o;40895:233::-;40970:7;41006:30;40793:10;:17;;40705:113;41006:30;40998:5;:38;40990:95;;;;-1:-1:-1;;;40990:95:0;;19779:2:1;40990:95:0;;;19761:21:1;19818:2;19798:18;;;19791:30;19857:34;19837:18;;;19830:62;19928:14;19908:18;;;19901:42;19960:19;;40990:95:0;19577:408:1;40990:95:0;41103:10;41114:5;41103:17;;;;;;;;:::i;:::-;;;;;;;;;41096:24;;40895:233;;;:::o;62385:108::-;61316:10;61309:18;;;;:6;:18;;;;;;;;61301:74;;;;-1:-1:-1;;;61301:74:0;;11519:2:1;61301:74:0;;;11501:21:1;11558:2;11538:18;;;11531:30;11597:34;11577:18;;;11570:62;11668:13;11648:18;;;11641:41;11699:19;;61301:74:0;11317:407:1;61301:74:0;62458:27;;::::1;::::0;:16:::1;::::0;:27:::1;::::0;::::1;::::0;::::1;:::i;24787:239::-:0;24859:7;24895:16;;;:7;:16;;;;;;;;24930:19;24922:73;;;;-1:-1:-1;;;24922:73:0;;15482:2:1;24922:73:0;;;15464:21:1;15521:2;15501:18;;;15494:30;15560:34;15540:18;;;15533:62;15631:11;15611:18;;;15604:39;15660:19;;24922:73:0;15280:405:1;59326:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;24517:208::-;24589:7;24617:19;;;24609:74;;;;-1:-1:-1;;;24609:74:0;;15071:2:1;24609:74:0;;;15053:21:1;15110:2;15090:18;;;15083:30;15149:34;15129:18;;;15122:62;15220:12;15200:18;;;15193:40;15250:19;;24609:74:0;14869:406:1;24609:74:0;-1:-1:-1;24701:16:0;;;;;;:9;:16;;;;;;;24517:208::o;66687:496::-;61316:10;61309:18;;;;:6;:18;;;;;;;;61301:74;;;;-1:-1:-1;;;61301:74:0;;11519:2:1;61301:74:0;;;11501:21:1;11558:2;11538:18;;;11531:30;11597:34;11577:18;;;11570:62;11668:13;11648:18;;;11641:41;11699:19;;61301:74:0;11317:407:1;61301:74:0;66769:1:::1;66745:21;:25;66737:71;;;::::0;-1:-1:-1;;;66737:71:0;;12287:2:1;66737:71:0::1;::::0;::::1;12269:21:1::0;12326:2;12306:18;;;12299:30;12365:34;12345:18;;;12338:62;12436:3;12416:18;;;12409:31;12457:19;;66737:71:0::1;12085:397:1::0;66737:71:0::1;66821:19;66843:24;:22;:24::i;:::-;66821:46:::0;-1:-1:-1;66904:21:0::1;66880;66938:238;66959:5;:12:::0;66955:16;::::1;66938:238;;;66993:22;67026:5;67032:1;67026:8;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;::::1;::::0;67085:12:::1;:15:::0;;67026:8:::1;::::0;;::::1;::::0;-1:-1:-1;67104:11:0;;67098:1;;67085:15;::::1;;;;;:::i;:::-;;;;;;;;;67069:13;:31;;;;:::i;:::-;67068:47;;;;:::i;:::-;67050:65;;67130:34;67148:6;67156:7;67130:17;:34::i;:::-;66978:198;;66973:3;;;;;:::i;:::-;;;;66938:238;;25262:104:::0;25318:13;25351:7;25344:14;;;;;:::i;26945:295::-;27048:24;;;19699:10;27048:24;;27040:62;;;;-1:-1:-1;;;27040:62:0;;13094:2:1;27040:62:0;;;13076:21:1;13133:2;13113:18;;;13106:30;13172:27;13152:18;;;13145:55;13217:18;;27040:62:0;12892:349:1;27040:62:0;19699:10;27115:32;;;;:18;:32;;;;;;;;;:42;;;;;;;;;;;;:53;;;;;;;;;;;;;27184:48;;9033:41:1;;;27115:42:0;;19699:10;27184:48;;9006:18:1;27184:48:0;;;;;;;26945:295;;:::o;28208:328::-;28383:41;19699:10;28416:7;28383:18;:41::i;:::-;28375:103;;;;-1:-1:-1;;;28375:103:0;;19025:2:1;28375:103:0;;;19007:21:1;19064:2;19044:18;;;19037:30;19103:34;19083:18;;;19076:62;19174:19;19154:18;;;19147:47;19211:19;;28375:103:0;18823:413:1;28375:103:0;28489:39;28503:4;28509:2;28513:7;28522:5;28489:13;:39::i;62501:304::-;61316:10;61309:18;;;;:6;:18;;;;;;;;61301:74;;;;-1:-1:-1;;;61301:74:0;;11519:2:1;61301:74:0;;;11501:21:1;11558:2;11538:18;;;11531:30;11597:34;11577:18;;;11570:62;11668:13;11648:18;;;11641:41;11699:19;;61301:74:0;11317:407:1;61301:74:0;62625:5:::1;:12;62609:5;:12;:28;62601:91;;;::::0;-1:-1:-1;;;62601:91:0;;9912:2:1;62601:91:0::1;::::0;::::1;9894:21:1::0;9951:2;9931:18;;;9924:30;9990:34;9970:18;;;9963:62;10061:20;10041:18;;;10034:48;10099:19;;62601:91:0::1;9710:414:1::0;62601:91:0::1;62707:6;62703:95;62723:5;:12;62719:1;:16;62703:95;;;62778:5;62784:1;62778:8;;;;;;;;:::i;:::-;;;;;;;62756:9;:19;62766:5;62772:1;62766:8;;;;;;;;:::i;:::-;;;;;;;62756:19;;;;;;;;;;;;;;;:30;;;;62737:3;;;;;:::i;:::-;;;;62703:95;;65364:85:::0;61316:10;61309:18;;;;:6;:18;;;;;;;;61301:74;;;;-1:-1:-1;;;61301:74:0;;11519:2:1;61301:74:0;;;11501:21:1;11558:2;11538:18;;;11531:30;11597:34;11577:18;;;11570:62;11668:13;11648:18;;;11641:41;11699:19;;61301:74:0;11317:407:1;61301:74:0;65413:28:::1;65427:10;65439:1;65413:13;:28::i;:::-;65364:85::o:0;25437:334::-;30111:4;30135:16;;;:7;:16;;;;;;25510:13;;30135:30;:16;25536:76;;;;-1:-1:-1;;;25536:76:0;;17848:2:1;25536:76:0;;;17830:21:1;17887:2;17867:18;;;17860:30;17926:34;17906:18;;;17899:62;17997:17;17977:18;;;17970:45;18032:19;;25536:76:0;17646:411:1;25536:76:0;25625:21;25649:10;:8;:10::i;:::-;25625:34;;25701:1;25683:7;25677:21;:25;:86;;;;;;;;;;;;;;;;;25729:7;25738:18;:7;:16;:18::i;:::-;25712:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;25677:86;25670:93;25437:334;-1:-1:-1;;;25437:334:0:o;65457:408::-;65509:10;61476:1;61459:14;;;:9;:14;;;;;;61451:79;;;;-1:-1:-1;;;61451:79:0;;17021:2:1;61451:79:0;;;17003:21:1;17060:2;17040:18;;;17033:30;17099:34;17079:18;;;17072:62;17170:18;17150;;;17143:46;17206:19;;61451:79:0;16819:412:1;61451:79:0;61564:19;61549:11;:9;:11::i;:::-;:34;;;;;;;;:::i;:::-;;:75;;;-1:-1:-1;61602:22:0;61587:11;:9;:11::i;:::-;:37;;;;;;;;:::i;:::-;;61549:75;61541:111;;;;-1:-1:-1;;;61541:111:0;;20192:2:1;61541:111:0;;;20174:21:1;20231:2;20211:18;;;20204:30;20270:25;20250:18;;;20243:53;20313:18;;61541:111:0;19990:347:1;61541:111:0;59443:4;61671:13;:11;:13::i;:::-;:28;61663:49;;;;-1:-1:-1;;;61663:49:0;;19443:2:1;61663:49:0;;;19425:21:1;19482:1;19462:18;;;19455:29;19520:10;19500:18;;;19493:38;19548:18;;61663:49:0;19241:331:1;61663:49:0;65599:12:::1;65653:13;:11;:13::i;:::-;65638:28;::::0;59443:4:::1;65638:28;:::i;:::-;65624:10;65614:21;::::0;;;:9:::1;:21;::::0;;;;;:52:::1;:107;;65708:13;:11;:13::i;:::-;65693:28;::::0;59443:4:::1;65693:28;:::i;:::-;65614:107;;;65679:10;65669:21;::::0;;;:9:::1;:21;::::0;;;;;65614:107:::1;65599:122;;65737:6;65732:90;65753:7;65749:1;:11;65732:90;;;65782:28;65796:10;65808:1;65782:13;:28::i;:::-;65762:3:::0;::::1;::::0;::::1;:::i;:::-;;;;65732:90;;;-1:-1:-1::0;;65842:10:0::1;65856:1;65832:21:::0;;;:9:::1;:21;::::0;;;;:25;-1:-1:-1;65457:408:0:o;40065:224::-;40167:4;40191:50;;;40206:35;40191:50;;:90;;;40245:36;40269:11;40245:23;:36::i;34028:174::-;34103:24;;;;:15;:24;;;;;:29;;;;;;;;;;;;;:24;;34157:23;34103:24;34157:14;:23::i;:::-;34148:46;;;;;;;;;;;;34028:174;;:::o;48990:98::-;49048:7;49075:5;49079:1;49075;:5;:::i;63280:2076::-;63350:12;63393:14;;63365:25;;;;;;;;;;;;;;;;;;63385:4;63365:6;:25::i;:::-;:42;;;;:::i;:::-;63350:57;;63418:12;63433:10;63444:7;63433:19;;;;;;;:::i;:::-;;;63418:34;;59443:4;64745:20;64763:1;64745:13;:11;:13::i;:20::-;:35;64741:572;;;59789:3;64801:31;64818:13;:11;:13::i;:::-;59443:4;;64801:16;:31::i;:::-;:52;64797:505;;64896:43;64937:1;64896:36;59789:3;64896:13;:11;:13::i;:43::-;64874:10;64885:7;64874:19;;;;;;;:::i;:::-;;:65;64797:505;;;64997:14;;:21;;65016:1;64997:18;:21::i;:::-;64980:14;:38;;;65064:10;;:26;;;;;;;:::i;:::-;;;65041:10;65052:7;65041:19;;;;;;;:::i;:::-;;;:49;65037:250;;;65148:14;;65137:10;;65148:21;;65167:1;65148:18;:21::i;:::-;65137:33;;;;;;;:::i;:::-;;;65115:10;65126:7;65115:19;;;;;;;:::i;65037:250::-;65241:10;65252:14;;65241:26;;;;;;;:::i;:::-;;;65219:10;65230:7;65219:19;;;;;;;:::i;:::-;;:48;65037:250;65325:23;65335:3;65340:7;65325:9;:23::i;50127:98::-;50185:7;50212:5;50216:1;50212;:5;:::i;49371:98::-;49429:7;49456:5;49460:1;49456;:5;:::i;30340:348::-;30433:4;30135:16;;;:7;:16;;;;;;:30;:16;30450:73;;;;-1:-1:-1;;;30450:73:0;;14233:2:1;30450:73:0;;;14215:21:1;14272:2;14252:18;;;14245:30;14311:34;14291:18;;;14284:62;14382:14;14362:18;;;14355:42;14414:19;;30450:73:0;14031:408:1;30450:73:0;30534:13;30550:23;30565:7;30550:14;:23::i;:::-;30534:39;;30603:5;30592:16;;:7;:16;;;:51;;;;30636:7;30612:31;;:20;30624:7;30612:11;:20::i;:::-;:31;;;30592:51;:87;;;-1:-1:-1;27432:25:0;;;;27408:4;27432:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;30647:32;30584:96;30340:348;-1:-1:-1;;;;30340:348:0:o;33332:578::-;33491:4;33464:31;;:23;33479:7;33464:14;:23::i;:::-;:31;;;33456:85;;;;-1:-1:-1;;;33456:85:0;;17438:2:1;33456:85:0;;;17420:21:1;17477:2;17457:18;;;17450:30;17516:34;17496:18;;;17489:62;17587:11;17567:18;;;17560:39;17616:19;;33456:85:0;17236:405:1;33456:85:0;33560:16;;;33552:65;;;;-1:-1:-1;;;33552:65:0;;12689:2:1;33552:65:0;;;12671:21:1;12728:2;12708:18;;;12701:30;12767:34;12747:18;;;12740:62;12838:6;12818:18;;;12811:34;12862:19;;33552:65:0;12487:400:1;33552:65:0;33630:39;33651:4;33657:2;33661:7;33630:20;:39::i;:::-;33734:29;33751:1;33755:7;33734:8;:29::i;:::-;33776:15;;;;;;;:9;:15;;;;;:20;;33795:1;;33776:15;:20;;33795:1;;33776:20;:::i;:::-;;;;-1:-1:-1;;33807:13:0;;;;;;;:9;:13;;;;;:18;;33824:1;;33807:13;:18;;33824:1;;33807:18;:::i;:::-;;;;-1:-1:-1;;33836:16:0;;;;:7;:16;;;;;;:21;;;;;;;;;;;;;;33875:27;;33836:16;;33875:27;;;;;;;33332:578;;;:::o;49728:98::-;49786:7;49813:5;49817:1;49813;:5;:::i;66435:244::-;66492:7;;;66546:97;66567:5;:12;66563:16;;66546:97;;;66616:12;66629:1;66616:15;;;;;;;;:::i;:::-;;;;;;;;;66601:30;;;;;:::i;:::-;;-1:-1:-1;66581:3:0;;;;:::i;:::-;;;;66546:97;;;-1:-1:-1;66660:11:0;66435:244;-1:-1:-1;66435:244:0:o;13000:317::-;13115:6;13090:21;:31;;13082:73;;;;-1:-1:-1;;;13082:73:0;;13875:2:1;13082:73:0;;;13857:21:1;13914:2;13894:18;;;13887:30;13953:31;13933:18;;;13926:59;14002:18;;13082:73:0;13673:353:1;13082:73:0;13169:12;13187:9;:14;;13209:6;13187:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13168:52;;;13239:7;13231:78;;;;-1:-1:-1;;;13231:78:0;;13448:2:1;13231:78:0;;;13430:21:1;13487:2;13467:18;;;13460:30;13526:34;13506:18;;;13499:62;13597:28;13577:18;;;13570:56;13643:19;;13231:78:0;13246:422:1;29418:315:0;29575:28;29585:4;29591:2;29595:7;29575:9;:28::i;:::-;29622:48;29645:4;29651:2;29655:7;29664:5;29622:22;:48::i;:::-;29614:111;;;;-1:-1:-1;;;29614:111:0;;10743:2:1;29614:111:0;;;10725:21:1;10782:2;10762:18;;;10755:30;10821:34;10801:18;;;10794:62;10892:20;10872:18;;;10865:48;10930:19;;29614:111:0;10541:414:1;62268:109:0;62320:13;62353:16;62346:23;;;;;:::i;20129:723::-;20185:13;20406:10;20402:53;;-1:-1:-1;;20433:10:0;;;;;;;;;;;;;;;;;;20129:723::o;20402:53::-;20480:5;20465:12;20521:78;20528:9;;20521:78;;20554:8;;;;:::i;:::-;;-1:-1:-1;20577:10:0;;-1:-1:-1;20585:2:0;20577:10;;:::i;:::-;;;20521:78;;;20609:19;20641:6;20631:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20631:17:0;;20609:39;;20659:154;20666:10;;20659:154;;20693:11;20703:1;20693:11;;:::i;:::-;;-1:-1:-1;20762:10:0;20770:2;20762:5;:10;:::i;:::-;20749:24;;:2;:24;:::i;:::-;20736:39;;20719:6;20726;20719:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;20790:11:0;20799:2;20790:11;;:::i;:::-;;;20659:154;;24148:305;24250:4;24287:40;;;24302:25;24287:40;;:105;;-1:-1:-1;24344:48:0;;;24359:33;24344:48;24287:105;:158;;;-1:-1:-1;22793:25:0;22778:40;;;;24409:36;22669:157;67479:207;67553:7;67615:4;67621:15;67630:5;67621:8;:15::i;:::-;67638:25;67647:15;67638:8;:25::i;:::-;67665:10;67598:78;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;67588:89;;67598:78;67588:89;;;;;67479:207;-1:-1:-1;;;67479:207:0:o;31030:110::-;31106:26;31116:2;31120:7;31106:26;;;;;;;;;;;;:9;:26::i;41741:589::-;41947:18;;;41943:187;;41982:40;42014:7;43157:10;:17;;43130:24;;;;:15;:24;;;;;:44;;;43185:24;;;;;;;;;;;;43053:164;41982:40;41943:187;;;42052:2;42044:10;;:4;:10;;;42040:90;;42071:47;42104:4;42110:7;42071:32;:47::i;:::-;42144:16;;;42140:183;;42177:45;42214:7;42177:36;:45::i;42140:183::-;42250:4;42244:10;;:2;:10;;;42240:83;;42271:40;42299:2;42303:7;42271:27;:40::i;34767:799::-;34922:4;34943:13;;;12001:20;12049:8;34939:620;;34979:72;;;;;:36;;;;;;:72;;19699:10;;35030:4;;35036:7;;35045:5;;34979:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34979:72:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;34975:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35221:13:0;;35217:272;;35264:60;;-1:-1:-1;;;35264:60:0;;10743:2:1;35264:60:0;;;10725:21:1;10782:2;10762:18;;;10755:30;10821:34;10801:18;;;10794:62;10892:20;10872:18;;;10865:48;10930:19;;35264:60:0;10541:414:1;35217:272:0;35439:6;35433:13;35424:6;35420:2;35416:15;35409:38;34975:529;35102:51;;35112:41;35102:51;;-1:-1:-1;35095:58:0;;34939:620;-1:-1:-1;35543:4:0;34767:799;;;;;;:::o;67694:715::-;67750:13;67963:10;67959:53;;-1:-1:-1;;67990:10:0;;;;;;;;;;;;;;;;;;67694:715::o;67959:53::-;68037:5;68022:12;68078:78;68085:9;;68078:78;;68111:8;;;;:::i;:::-;;-1:-1:-1;68134:10:0;;-1:-1:-1;68142:2:0;68134:10;;:::i;:::-;;;68078:78;;;68166:19;68198:6;68188:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68188:17:0;;68166:39;;68216:154;68223:10;;68216:154;;68250:11;68260:1;68250:11;;:::i;:::-;;-1:-1:-1;68319:10:0;68327:2;68319:5;:10;:::i;:::-;68306:24;;:2;:24;:::i;:::-;68293:39;;68276:6;68283;68276:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;68347:11:0;68356:2;68347:11;;:::i;:::-;;;68216:154;;31367:321;31497:18;31503:2;31507:7;31497:5;:18::i;:::-;31548:54;31579:1;31583:2;31587:7;31596:5;31548:22;:54::i;:::-;31526:154;;;;-1:-1:-1;;;31526:154:0;;10743:2:1;31526:154:0;;;10725:21:1;10782:2;10762:18;;;10755:30;10821:34;10801:18;;;10794:62;10892:20;10872:18;;;10865:48;10930:19;;31526:154:0;10541:414:1;43844:988:0;44110:22;44160:1;44135:22;44152:4;44135:16;:22::i;:::-;:26;;;;:::i;:::-;44172:18;44193:26;;;:17;:26;;;;;;44110:51;;-1:-1:-1;44326:28:0;;;44322:328;;44393:18;;;44371:19;44393:18;;;:12;:18;;;;;;;;:34;;;;;;;;;44444:30;;;;;;:44;;;44561:30;;:17;:30;;;;;:43;;;44322:328;-1:-1:-1;44746:26:0;;;;:17;:26;;;;;;;;44739:33;;;44790:18;;;;;;:12;:18;;;;;:34;;;;;;;44783:41;43844:988::o;45127:1079::-;45405:10;:17;45380:22;;45405:21;;45425:1;;45405:21;:::i;:::-;45437:18;45458:24;;;:15;:24;;;;;;45831:10;:26;;45380:46;;-1:-1:-1;45458:24:0;;45380:46;;45831:26;;;;;;:::i;:::-;;;;;;;;;45809:48;;45895:11;45870:10;45881;45870:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;45975:28;;;:15;:28;;;;;;;:41;;;46147:24;;;;;46140:31;46182:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;45198:1008;;;45127:1079;:::o;42631:221::-;42716:14;42733:20;42750:2;42733:16;:20::i;:::-;42764:16;;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;42809:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;42631:221:0:o;32024:382::-;32104:16;;;32096:61;;;;-1:-1:-1;;;32096:61:0;;16247:2:1;32096:61:0;;;16229:21:1;;;16266:18;;;16259:30;16325:34;16305:18;;;16298:62;16377:18;;32096:61:0;16045:356:1;32096:61:0;30111:4;30135:16;;;:7;:16;;;;;;:30;:16;:30;32168:58;;;;-1:-1:-1;;;32168:58:0;;11162:2:1;32168:58:0;;;11144:21:1;11201:2;11181:18;;;11174:30;11240;11220:18;;;11213:58;11288:18;;32168:58:0;10960:352:1;32168:58:0;32239:45;32268:1;32272:2;32276:7;32239:20;:45::i;:::-;32297:13;;;;;;;:9;:13;;;;;:18;;32314:1;;32297:13;:18;;32314:1;;32297:18;:::i;:::-;;;;-1:-1:-1;;32326:16:0;;;;:7;:16;;;;;;:21;;;;;;;;;;;;;32365:33;;32326:16;;;32365:33;;32326:16;;32365:33;32024:382;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:465:1;78:5;112:18;104:6;101:30;98:56;;;134:18;;:::i;:::-;172:116;282:4;213:66;208:2;200:6;196:15;192:88;188:99;172:116;:::i;:::-;163:125;;311:6;304:5;297:21;351:3;342:6;337:3;333:16;330:25;327:45;;;368:1;365;358:12;327:45;417:6;412:3;405:4;398:5;394:16;381:43;471:1;464:4;455:6;448:5;444:18;440:29;433:40;14:465;;;;;:::o;484:196::-;552:20;;612:42;601:54;;591:65;;581:93;;670:1;667;660:12;581:93;484:196;;;:::o;685:673::-;739:5;792:3;785:4;777:6;773:17;769:27;759:55;;810:1;807;800:12;759:55;846:6;833:20;872:4;896:60;912:43;952:2;912:43;:::i;:::-;896:60;:::i;:::-;978:3;1002:2;997:3;990:15;1030:2;1025:3;1021:12;1014:19;;1065:2;1057:6;1053:15;1117:3;1112:2;1106;1103:1;1099:10;1091:6;1087:23;1083:32;1080:41;1077:61;;;1134:1;1131;1124:12;1077:61;1156:1;1166:163;1180:2;1177:1;1174:9;1166:163;;;1237:17;;1225:30;;1275:12;;;;1307;;;;1198:1;1191:9;1166:163;;;-1:-1:-1;1347:5:1;;685:673;-1:-1:-1;;;;;;;685:673:1:o;1363:186::-;1422:6;1475:2;1463:9;1454:7;1450:23;1446:32;1443:52;;;1491:1;1488;1481:12;1443:52;1514:29;1533:9;1514:29;:::i;1554:260::-;1622:6;1630;1683:2;1671:9;1662:7;1658:23;1654:32;1651:52;;;1699:1;1696;1689:12;1651:52;1722:29;1741:9;1722:29;:::i;:::-;1712:39;;1770:38;1804:2;1793:9;1789:18;1770:38;:::i;1819:328::-;1896:6;1904;1912;1965:2;1953:9;1944:7;1940:23;1936:32;1933:52;;;1981:1;1978;1971:12;1933:52;2004:29;2023:9;2004:29;:::i;:::-;1994:39;;2052:38;2086:2;2075:9;2071:18;2052:38;:::i;:::-;2042:48;;2137:2;2126:9;2122:18;2109:32;2099:42;;1819:328;;;;;:::o;2152:666::-;2247:6;2255;2263;2271;2324:3;2312:9;2303:7;2299:23;2295:33;2292:53;;;2341:1;2338;2331:12;2292:53;2364:29;2383:9;2364:29;:::i;:::-;2354:39;;2412:38;2446:2;2435:9;2431:18;2412:38;:::i;:::-;2402:48;;2497:2;2486:9;2482:18;2469:32;2459:42;;2552:2;2541:9;2537:18;2524:32;2579:18;2571:6;2568:30;2565:50;;;2611:1;2608;2601:12;2565:50;2634:22;;2687:4;2679:13;;2675:27;-1:-1:-1;2665:55:1;;2716:1;2713;2706:12;2665:55;2739:73;2804:7;2799:2;2786:16;2781:2;2777;2773:11;2739:73;:::i;:::-;2729:83;;;2152:666;;;;;;;:::o;2823:347::-;2888:6;2896;2949:2;2937:9;2928:7;2924:23;2920:32;2917:52;;;2965:1;2962;2955:12;2917:52;2988:29;3007:9;2988:29;:::i;:::-;2978:39;;3067:2;3056:9;3052:18;3039:32;3114:5;3107:13;3100:21;3093:5;3090:32;3080:60;;3136:1;3133;3126:12;3080:60;3159:5;3149:15;;;2823:347;;;;;:::o;3175:254::-;3243:6;3251;3304:2;3292:9;3283:7;3279:23;3275:32;3272:52;;;3320:1;3317;3310:12;3272:52;3343:29;3362:9;3343:29;:::i;:::-;3333:39;3419:2;3404:18;;;;3391:32;;-1:-1:-1;;;3175:254:1:o;3434:1157::-;3552:6;3560;3613:2;3601:9;3592:7;3588:23;3584:32;3581:52;;;3629:1;3626;3619:12;3581:52;3669:9;3656:23;3698:18;3739:2;3731:6;3728:14;3725:34;;;3755:1;3752;3745:12;3725:34;3793:6;3782:9;3778:22;3768:32;;3838:7;3831:4;3827:2;3823:13;3819:27;3809:55;;3860:1;3857;3850:12;3809:55;3896:2;3883:16;3918:4;3942:60;3958:43;3998:2;3958:43;:::i;3942:60::-;4024:3;4048:2;4043:3;4036:15;4076:2;4071:3;4067:12;4060:19;;4107:2;4103;4099:11;4155:7;4150:2;4144;4141:1;4137:10;4133:2;4129:19;4125:28;4122:41;4119:61;;;4176:1;4173;4166:12;4119:61;4198:1;4189:10;;4208:169;4222:2;4219:1;4216:9;4208:169;;;4279:23;4298:3;4279:23;:::i;:::-;4267:36;;4240:1;4233:9;;;;;4323:12;;;;4355;;4208:169;;;-1:-1:-1;4396:5:1;-1:-1:-1;;4439:18:1;;4426:32;;-1:-1:-1;;4470:16:1;;;4467:36;;;4499:1;4496;4489:12;4467:36;;4522:63;4577:7;4566:8;4555:9;4551:24;4522:63;:::i;:::-;4512:73;;;3434:1157;;;;;:::o;4596:245::-;4654:6;4707:2;4695:9;4686:7;4682:23;4678:32;4675:52;;;4723:1;4720;4713:12;4675:52;4762:9;4749:23;4781:30;4805:5;4781:30;:::i;4846:249::-;4915:6;4968:2;4956:9;4947:7;4943:23;4939:32;4936:52;;;4984:1;4981;4974:12;4936:52;5016:9;5010:16;5035:30;5059:5;5035:30;:::i;5100:450::-;5169:6;5222:2;5210:9;5201:7;5197:23;5193:32;5190:52;;;5238:1;5235;5228:12;5190:52;5278:9;5265:23;5311:18;5303:6;5300:30;5297:50;;;5343:1;5340;5333:12;5297:50;5366:22;;5419:4;5411:13;;5407:27;-1:-1:-1;5397:55:1;;5448:1;5445;5438:12;5397:55;5471:73;5536:7;5531:2;5518:16;5513:2;5509;5505:11;5471:73;:::i;5555:180::-;5614:6;5667:2;5655:9;5646:7;5642:23;5638:32;5635:52;;;5683:1;5680;5673:12;5635:52;-1:-1:-1;5706:23:1;;5555:180;-1:-1:-1;5555:180:1:o;5740:248::-;5808:6;5816;5869:2;5857:9;5848:7;5844:23;5840:32;5837:52;;;5885:1;5882;5875:12;5837:52;-1:-1:-1;;5908:23:1;;;5978:2;5963:18;;;5950:32;;-1:-1:-1;5740:248:1:o;5993:316::-;6034:3;6072:5;6066:12;6099:6;6094:3;6087:19;6115:63;6171:6;6164:4;6159:3;6155:14;6148:4;6141:5;6137:16;6115:63;:::i;:::-;6223:2;6211:15;6228:66;6207:88;6198:98;;;;6298:4;6194:109;;5993:316;-1:-1:-1;;5993:316:1:o;6314:470::-;6493:3;6531:6;6525:13;6547:53;6593:6;6588:3;6581:4;6573:6;6569:17;6547:53;:::i;:::-;6663:13;;6622:16;;;;6685:57;6663:13;6622:16;6719:4;6707:17;;6685:57;:::i;:::-;6758:20;;6314:470;-1:-1:-1;;;;6314:470:1:o;6789:840::-;7044:3;7082:6;7076:13;7098:53;7144:6;7139:3;7132:4;7124:6;7120:17;7098:53;:::i;:::-;7214:13;;7173:16;;;;7236:57;7214:13;7173:16;7270:4;7258:17;;7236:57;:::i;:::-;7360:13;;7315:20;;;7382:57;7360:13;7315:20;7416:4;7404:17;;7382:57;:::i;:::-;7512:2;7508:15;;;;7525:66;7504:88;7461:20;;7490:103;;;-1:-1:-1;;7620:2:1;7609:14;;6789:840;-1:-1:-1;;;6789:840:1:o;8075:511::-;8269:4;8298:42;8379:2;8371:6;8367:15;8356:9;8349:34;8431:2;8423:6;8419:15;8414:2;8403:9;8399:18;8392:43;;8471:6;8466:2;8455:9;8451:18;8444:34;8514:3;8509:2;8498:9;8494:18;8487:31;8535:45;8575:3;8564:9;8560:19;8552:6;8535:45;:::i;:::-;8527:53;8075:511;-1:-1:-1;;;;;;8075:511:1:o;9085:396::-;9228:2;9213:18;;9261:1;9250:13;;9240:201;;9297:77;9294:1;9287:88;9398:4;9395:1;9388:15;9426:4;9423:1;9416:15;9240:201;9450:25;;;9085:396;:::o;9486:219::-;9635:2;9624:9;9617:21;9598:4;9655:44;9695:2;9684:9;9680:18;9672:6;9655:44;:::i;20524:334::-;20595:2;20589:9;20651:2;20641:13;;20656:66;20637:86;20625:99;;20754:18;20739:34;;20775:22;;;20736:62;20733:88;;;20801:18;;:::i;:::-;20837:2;20830:22;20524:334;;-1:-1:-1;20524:334:1:o;20863:183::-;20923:4;20956:18;20948:6;20945:30;20942:56;;;20978:18;;:::i;:::-;-1:-1:-1;21023:1:1;21019:14;21035:4;21015:25;;20863:183::o;21051:128::-;21091:3;21122:1;21118:6;21115:1;21112:13;21109:39;;;21128:18;;:::i;:::-;-1:-1:-1;21164:9:1;;21051:128::o;21184:120::-;21224:1;21250;21240:35;;21255:18;;:::i;:::-;-1:-1:-1;21289:9:1;;21184:120::o;21309:228::-;21349:7;21475:1;21407:66;21403:74;21400:1;21397:81;21392:1;21385:9;21378:17;21374:105;21371:131;;;21482:18;;:::i;:::-;-1:-1:-1;21522:9:1;;21309:228::o;21542:125::-;21582:4;21610:1;21607;21604:8;21601:34;;;21615:18;;:::i;:::-;-1:-1:-1;21652:9:1;;21542:125::o;21672:258::-;21744:1;21754:113;21768:6;21765:1;21762:13;21754:113;;;21844:11;;;21838:18;21825:11;;;21818:39;21790:2;21783:10;21754:113;;;21885:6;21882:1;21879:13;21876:48;;;-1:-1:-1;;21920:1:1;21902:16;;21895:27;21672:258::o;21935:437::-;22014:1;22010:12;;;;22057;;;22078:61;;22132:4;22124:6;22120:17;22110:27;;22078:61;22185:2;22177:6;22174:14;22154:18;22151:38;22148:218;;;22222:77;22219:1;22212:88;22323:4;22320:1;22313:15;22351:4;22348:1;22341:15;22377:195;22416:3;22447:66;22440:5;22437:77;22434:103;;;22517:18;;:::i;:::-;-1:-1:-1;22564:1:1;22553:13;;22377:195::o;22577:112::-;22609:1;22635;22625:35;;22640:18;;:::i;:::-;-1:-1:-1;22674:9:1;;22577:112::o;22694:184::-;22746:77;22743:1;22736:88;22843:4;22840:1;22833:15;22867:4;22864:1;22857:15;22883:184;22935:77;22932:1;22925:88;23032:4;23029:1;23022:15;23056:4;23053:1;23046:15;23072:184;23124:77;23121:1;23114:88;23221:4;23218:1;23211:15;23245:4;23242:1;23235:15;23261:184;23313:77;23310:1;23303:88;23410:4;23407:1;23400:15;23434:4;23431:1;23424:15;23450:184;23502:77;23499:1;23492:88;23599:4;23596:1;23589:15;23623:4;23620:1;23613:15;23639:184;23691:77;23688:1;23681:88;23788:4;23785:1;23778:15;23812:4;23809:1;23802:15;23828:177;23913:66;23906:5;23902:78;23895:5;23892:89;23882:117;;23995:1;23992;23985:12;23882:117;23828:177;:::o

Swarm Source

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