ETH Price: $2,947.14 (-6.65%)
Gas: 7 Gwei

Token

Chaos Cube (CHAOSCUBE)
 

Overview

Max Total Supply

120 CHAOSCUBE

Holders

61

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
3 CHAOSCUBE
0x73fbac1ee844b93bd96146d567d16dd0c2cf9e34
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
ChaosCube

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
Yes with 500 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-06-21
*/

// Sources flattened with hardhat v2.14.1 https://hardhat.org

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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


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


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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


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


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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/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.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

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

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

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

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

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

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

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

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

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

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

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

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


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


// OpenZeppelin Contracts (last updated v4.7.0) (utils/escrow/Escrow.sol)

pragma solidity ^0.8.0;


/**
 * @title Escrow
 * @dev Base escrow contract, holds funds designated for a payee until they
 * withdraw them.
 *
 * Intended usage: This contract (and derived escrow contracts) should be a
 * standalone contract, that only interacts with the contract that instantiated
 * it. That way, it is guaranteed that all Ether will be handled according to
 * the `Escrow` rules, and there is no need to check for payable functions or
 * transfers in the inheritance tree. The contract that uses the escrow as its
 * payment method should be its owner, and provide public methods redirecting
 * to the escrow's deposit and withdraw.
 */
contract Escrow is Ownable {
    using Address for address payable;

    event Deposited(address indexed payee, uint256 weiAmount);
    event Withdrawn(address indexed payee, uint256 weiAmount);

    mapping(address => uint256) private _deposits;

    function depositsOf(address payee) public view returns (uint256) {
        return _deposits[payee];
    }

    /**
     * @dev Stores the sent amount as credit to be withdrawn.
     * @param payee The destination address of the funds.
     *
     * Emits a {Deposited} event.
     */
    function deposit(address payee) public payable virtual onlyOwner {
        uint256 amount = msg.value;
        _deposits[payee] += amount;
        emit Deposited(payee, amount);
    }

    /**
     * @dev Withdraw accumulated balance for a payee, forwarding all gas to the
     * recipient.
     *
     * WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities.
     * Make sure you trust the recipient, or are either following the
     * checks-effects-interactions pattern or using {ReentrancyGuard}.
     *
     * @param payee The address whose funds will be withdrawn and transferred to.
     *
     * Emits a {Withdrawn} event.
     */
    function withdraw(address payable payee) public virtual onlyOwner {
        uint256 payment = _deposits[payee];

        _deposits[payee] = 0;

        payee.sendValue(payment);

        emit Withdrawn(payee, payment);
    }
}


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


// OpenZeppelin Contracts (last updated v4.8.0) (security/PullPayment.sol)

pragma solidity ^0.8.0;

/**
 * @dev Simple implementation of a
 * https://consensys.github.io/smart-contract-best-practices/development-recommendations/general/external-calls/#favor-pull-over-push-for-external-calls[pull-payment]
 * strategy, where the paying contract doesn't interact directly with the
 * receiver account, which must withdraw its payments itself.
 *
 * Pull-payments are often considered the best practice when it comes to sending
 * Ether, security-wise. It prevents recipients from blocking execution, and
 * eliminates reentrancy concerns.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 *
 * To use, derive from the `PullPayment` contract, and use {_asyncTransfer}
 * instead of Solidity's `transfer` function. Payees can query their due
 * payments with {payments}, and retrieve them with {withdrawPayments}.
 */
abstract contract PullPayment {
    Escrow private immutable _escrow;

    constructor() {
        _escrow = new Escrow();
    }

    /**
     * @dev Withdraw accumulated payments, forwarding all gas to the recipient.
     *
     * Note that _any_ account can call this function, not just the `payee`.
     * This means that contracts unaware of the `PullPayment` protocol can still
     * receive funds this way, by having a separate account call
     * {withdrawPayments}.
     *
     * WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities.
     * Make sure you trust the recipient, or are either following the
     * checks-effects-interactions pattern or using {ReentrancyGuard}.
     *
     * @param payee Whose payments will be withdrawn.
     *
     * Causes the `escrow` to emit a {Withdrawn} event.
     */
    function withdrawPayments(address payable payee) public virtual {
        _escrow.withdraw(payee);
    }

    /**
     * @dev Returns the payments owed to an address.
     * @param dest The creditor's address.
     */
    function payments(address dest) public view returns (uint256) {
        return _escrow.depositsOf(dest);
    }

    /**
     * @dev Called by the payer to store the sent amount as credit to be pulled.
     * Funds sent in this way are stored in an intermediate {Escrow} contract, so
     * there is no danger of them being spent before withdrawal.
     *
     * @param dest The destination address of the funds.
     * @param amount The amount to transfer.
     *
     * Causes the `escrow` to emit a {Deposited} event.
     */
    function _asyncTransfer(address dest, uint256 amount) internal virtual {
        _escrow.deposit{value: amount}(dest);
    }
}


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


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

pragma solidity ^0.8.0;

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


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


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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


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


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

pragma solidity ^0.8.0;

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

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

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


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


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

pragma solidity ^0.8.0;

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


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


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

pragma solidity ^0.8.0;

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


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


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


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

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

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

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}


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


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

pragma solidity ^0.8.0;


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

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

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
    }

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

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

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

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}


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


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

pragma solidity ^0.8.0;







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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

        _owners[tokenId] = to;

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

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

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

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

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

        // Clear approvals
        delete _tokenApprovals[tokenId];

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId, 1);

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

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

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

        emit Transfer(from, to, tokenId);

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

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

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

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

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

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

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

    /**
     * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
     *
     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant
     * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such
     * that `ownerOf(tokenId)` is `a`.
     */
    // solhint-disable-next-line func-name-mixedcase
    function __unsafe_increaseBalance(address account, uint256 amount) internal {
        _balances[account] += amount;
    }
}


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


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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


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


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

pragma solidity ^0.8.0;

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

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

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

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

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


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


// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

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

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since 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 subtraction 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 contracts/common/meta-transactions/ContentMixin.sol



pragma solidity ^0.8.0;

abstract contract ContextMixin {
    function msgSender()
        internal
        view
        returns (address payable sender)
    {
        if (msg.sender == address(this)) {
            bytes memory array = msg.data;
            uint256 index = msg.data.length;
            assembly {
                // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
                sender := and(
                    mload(add(array, index)),
                    0xffffffffffffffffffffffffffffffffffffffff
                )
            }
        } else {
            sender = payable(msg.sender);
        }
        return sender;
    }
}


// File contracts/common/meta-transactions/Initializable.sol



pragma solidity ^0.8.0;

contract Initializable {
    bool inited = false;

    modifier initializer() {
        require(!inited, "already inited");
        _;
        inited = true;
    }
}


// File contracts/common/meta-transactions/EIP712Base.sol



pragma solidity ^0.8.0;

contract EIP712Base is Initializable {
    struct EIP712Domain {
        string name;
        string version;
        address verifyingContract;
        bytes32 salt;
    }

    string constant public ERC712_VERSION = "1";

    bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(
        bytes(
            "EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)"
        )
    );
    bytes32 internal domainSeperator;

    // supposed to be called once while initializing.
    // one of the contracts that inherits this contract follows proxy pattern
    // so it is not possible to do this in a constructor
    function _initializeEIP712(
        string memory name
    )
        internal
        initializer
    {
        _setDomainSeperator(name);
    }

    function _setDomainSeperator(string memory name) internal {
        domainSeperator = keccak256(
            abi.encode(
                EIP712_DOMAIN_TYPEHASH,
                keccak256(bytes(name)),
                keccak256(bytes(ERC712_VERSION)),
                address(this),
                bytes32(getChainId())
            )
        );
    }

    function getDomainSeperator() public view returns (bytes32) {
        return domainSeperator;
    }

    function getChainId() public view returns (uint256) {
        uint256 id;
        assembly {
            id := chainid()
        }
        return id;
    }

    /**
     * Accept message hash and returns hash message in EIP712 compatible form
     * So that it can be used to recover signer from signature signed using EIP712 formatted data
     * https://eips.ethereum.org/EIPS/eip-712
     * "\\x19" makes the encoding deterministic
     * "\\x01" is the version byte to make it compatible to EIP-191
     */
    function toTypedMessageHash(bytes32 messageHash)
        internal
        view
        returns (bytes32)
    {
        return
            keccak256(
                abi.encodePacked("\x19\x01", getDomainSeperator(), messageHash)
            );
    }
}


// File contracts/common/meta-transactions/NativeMetaTransaction.sol



pragma solidity ^0.8.0;


contract NativeMetaTransaction is EIP712Base {
    using SafeMath for uint256;
    bytes32 private constant META_TRANSACTION_TYPEHASH = keccak256(
        bytes(
            "MetaTransaction(uint256 nonce,address from,bytes functionSignature)"
        )
    );
    event MetaTransactionExecuted(
        address userAddress,
        address payable relayerAddress,
        bytes functionSignature
    );
    mapping(address => uint256) nonces;

    /*
     * Meta transaction structure.
     * No point of including value field here as if user is doing value transfer then he has the funds to pay for gas
     * He should call the desired function directly in that case.
     */
    struct MetaTransaction {
        uint256 nonce;
        address from;
        bytes functionSignature;
    }

    function executeMetaTransaction(
        address userAddress,
        bytes memory functionSignature,
        bytes32 sigR,
        bytes32 sigS,
        uint8 sigV
    ) public payable returns (bytes memory) {
        MetaTransaction memory metaTx = MetaTransaction({
            nonce: nonces[userAddress],
            from: userAddress,
            functionSignature: functionSignature
        });

        require(
            verify(userAddress, metaTx, sigR, sigS, sigV),
            "Signer and signature do not match"
        );

        // increase nonce for user (to avoid re-use)
        nonces[userAddress] = nonces[userAddress].add(1);

        emit MetaTransactionExecuted(
            userAddress,
            payable(msg.sender),
            functionSignature
        );

        // Append userAddress and relayer address at the end to extract it from calling context
        (bool success, bytes memory returnData) = address(this).call(
            abi.encodePacked(functionSignature, userAddress)
        );
        require(success, "Function call not successful");

        return returnData;
    }

    function hashMetaTransaction(MetaTransaction memory metaTx)
        internal
        pure
        returns (bytes32)
    {
        return
            keccak256(
                abi.encode(
                    META_TRANSACTION_TYPEHASH,
                    metaTx.nonce,
                    metaTx.from,
                    keccak256(metaTx.functionSignature)
                )
            );
    }

    function getNonce(address user) public view returns (uint256 nonce) {
        nonce = nonces[user];
    }

    function verify(
        address signer,
        MetaTransaction memory metaTx,
        bytes32 sigR,
        bytes32 sigS,
        uint8 sigV
    ) internal view returns (bool) {
        require(signer != address(0), "NativeMetaTransaction: INVALID_SIGNER");
        return
            signer ==
            ecrecover(
                toTypedMessageHash(hashMetaTransaction(metaTx)),
                sigV,
                sigR,
                sigS
            );
    }
}


// File contracts/ERC721ChaosCoinClub.sol



pragma solidity ^0.8.0;








contract OwnableDelegateProxy {}

/**
 * Used to delegate ownership of a contract to another address, to save on unneeded transactions to approve contract use for users
 */
contract ProxyRegistry {
    mapping(address => OwnableDelegateProxy) public proxies;
}

/**
 * @title ERC721ChaosCoinClub
 * ERC721ChaosCoinClub - ERC721 contract that can whitelists 2 trading proxy addresses, can approve other contract addresses, 
 * has minting functionality to mint with both Eth and a configurable ERC20, has an allow list for a certain number of discounted mints,
 * has multi-mint functionality with discount 
 */
abstract contract ERC721ChaosCoinClub is ERC721, ContextMixin, NativeMetaTransaction,  PullPayment, Ownable {
    using SafeMath for uint256;
    using Counters for Counters.Counter;

    /**
     * We rely on the OZ Counter util to keep track of the next available ID.
     * We track the nextTokenId instead of the currentTokenId to save users on gas costs. 
     */ 
    Counters.Counter internal _nextTokenId;
    address proxyRegistryAddress;
    address proxyRegistryAddress2;
    bool private _isMarketplace1Approved = true;
    bool private _isMarketplace2Approved = true;
    mapping(address=>bool) proxyAddressApproval;


    uint256 public mintingFee;
    uint256 public discountFee;
    uint256 public maxSupply;
    uint256 public maxMintSize;
    uint256 public maxMintBonusRounds;
    uint256 public maxMintDiscount;

    uint256 public mintingChaosFee;
    uint256 public nftsPerTier;

    mapping(address => uint256) public allowList;

    IERC20 public tokenAddress;
    bool mintingWithChaos = true;
    bool internal chaosLock;

modifier chaosGuard() {
     require(!chaosLock);
     chaosLock = true;
      _;
      chaosLock= false;
  }

  modifier callerIsUser() {
    require(tx.origin == msg.sender, "The caller is another contract");
    _;
  }

    constructor(
        string memory _name,
        string memory _symbol,
        address _proxyRegistryAddress,
        address _proxyRegistryAddress2,
        uint256 _mintingFee,
        uint256 _discountFee,
        uint256 _maxSupply,
        uint256 _maxMintSize,
        uint256 _maxMintBonusRounds,
        uint256 _maxMintDiscount,
        uint256 _nftsPerTier,
        uint256 _mintingChaosFee

    ) ERC721(_name, _symbol) {
        proxyRegistryAddress = _proxyRegistryAddress;
        proxyRegistryAddress2 = _proxyRegistryAddress2;
        mintingFee = _mintingFee;
        discountFee = _discountFee;
        maxSupply = _maxSupply;
        maxMintSize = _maxMintSize;
        maxMintBonusRounds = _maxMintBonusRounds;
        maxMintDiscount = _maxMintDiscount;
        nftsPerTier = _nftsPerTier;
        mintingChaosFee = _mintingChaosFee;
        
        // nextTokenId is initialized to 1, since starting at 0 leads to higher gas cost for the first minter
        _nextTokenId.increment();
        _initializeEIP712(_name);
    }


function chaosUnlock() external onlyOwner chaosGuard {
        chaosLock = false;
    }

    function checkChaosLock() public view returns (bool) {
      return chaosLock;
    }



    function mintTo(address _to, uint256 _count) public onlyOwner callerIsUser {
        require(totalSupply() + _count < maxSupply+1, "Maximum supply reached. Attempted to mint too many NFTs.");
        require(_count > 0 && _count < maxMintSize + 1, "Exceeds maximum tokens you can mint in a single transaction");        
        for(uint256 i = 0; i < _count; i++){
            uint256 currentTokenId = _nextTokenId.current();
            _nextTokenId.increment();
            //_safeMint(_to, currentTokenId);
            _mint(_to, currentTokenId);
        }
    }

    function mint(uint256 _count) external payable callerIsUser {
        require(totalSupply() + _count < maxSupply + 1, "Cannot Mint that many NFTs. Maximum supply reached");
        require(_count > 0 && _count < maxMintSize + 1, "Exceeds maximum tokens you can mint in a single transaction");

        if (allowList[msg.sender] > 0 && allowList[msg.sender] +1 > _count) {            
            require(msg.value >= discountFee * _count && msg.value < mintingFee * _count, "Incorrect payment amount.");
            allowList[msg.sender] -= _count;
            
            for(uint256 i = 0; i < _count; i++){
                uint256 currentTokenId = _nextTokenId.current();
                _nextTokenId.increment();
                _mint(msg.sender, currentTokenId);
            }

        } else {
            //require(msg.value >= mintingFee, "Insufficient funds to mint");
            //engage discount Bonus Rounds as maxMintSize is approached
            //uint discountedCount = _count;
            //uint discountPercent = 0;
            //uint256 discountRounds = 0;
            uint256 finalPrice = _count * (mintingFee * (1 + (totalSupply() / nftsPerTier)));

            if (_count > maxMintSize - maxMintBonusRounds)
            {
                //discountRounds = (_count - (maxMintSize - maxMintBonusRounds));
                //finalPrice = (finalPrice * (100-(discountRounds*maxMintDiscount)/maxMintBonusRounds))/100;
                finalPrice = (finalPrice * (100-((_count - (maxMintSize - maxMintBonusRounds))*maxMintDiscount)/maxMintBonusRounds))/100;
            }
            
            //require(msg.value >= discountedCount * (mintingFee * (1 + (totalSupply() / nftsPerTier))), "Ether value sent is not correct");
            require(msg.value >= finalPrice, "Ether value sent is not correct");
            
            for(uint256 i = 0; i < _count; i++){
                uint256 currentTokenId = _nextTokenId.current();
                _nextTokenId.increment();
                _mint(msg.sender, currentTokenId);
            }
        }
    }



    function mintWithChaos(uint256 _count) public chaosGuard callerIsUser {
        require(mintingWithChaos == true, "Minting with ERC20 token is Not Enabled.");
        require( _count > 0, "mintWithChaos _count must be greater than Zero");
        require(totalSupply()+ _count < maxSupply+1, "Maximum supply reached");
        //require(mintingChaosFee > 0, "Minting with ERC20 token is Not Enabled. mintingChaosFee must be greater than zero.");
        uint256 finalPrice = _count * (mintingChaosFee * (1 + (totalSupply() / nftsPerTier)));
        
        if (_count > maxMintSize - maxMintBonusRounds)
        {
            //discountRounds = (_count - (maxMintSize - maxMintBonusRounds));
            //finalPrice = (finalPrice * (100-(discountRounds*maxMintDiscount)/maxMintBonusRounds))/100;
            finalPrice = (finalPrice * (100-((_count - (maxMintSize - maxMintBonusRounds))*maxMintDiscount)/maxMintBonusRounds))/100;
        }

        tokenAddress.transferFrom(msg.sender, address(this), finalPrice);
   
       for(uint256 i = 0; i < _count; i++){
        
        uint256 currentTokenId = _nextTokenId.current();
        _nextTokenId.increment();
        _safeMint(msg.sender, currentTokenId);
        //_mint(msg.sender, currentTokenId);
       }
    }
    







    function setDiscountFee(uint256 _newFee) external onlyOwner {
        discountFee = _newFee;
    }

    function setMintingFee(uint256 _newFee) external onlyOwner {
        mintingFee = _newFee;
    }


    function checkMintPrice() public view returns (uint256) {
      return mintingFee * (1 + (totalSupply() / nftsPerTier));
    }


    function setChaosCoinAddress(address _newAddress) external onlyOwner {
        tokenAddress = IERC20(_newAddress);
    }

    function setMintingChaosFee(uint256 _newFee) external onlyOwner {
        mintingChaosFee = _newFee;
    }
    function setMintingWithChaos(bool _newState) external onlyOwner {
        mintingWithChaos = _newState;
    }

    function checkMintPriceChaos() public view returns (uint256) {
      return mintingChaosFee * (1 + (totalSupply() / nftsPerTier));
    }

    /**
        @dev Returns the total tokens minted so far.
        1 is always subtracted from the Counter since it tracks the next available tokenId.
     */
    function totalSupply() public view returns (uint256) {
        return _nextTokenId.current() - 1;
    }




    //changed from pure to view
    function baseTokenURI() virtual public view returns (string memory);

    //changed from pure to view
    function tokenURI(uint256 _tokenId) override public view returns (string memory) {
        return string(abi.encodePacked(baseTokenURI(), Strings.toString(_tokenId)));
    }

    function setMarketplace1(address _proxyRegistryAddress) external onlyOwner {
        proxyRegistryAddress = _proxyRegistryAddress;
    }

    function setMarketplace2(address _proxyRegistryAddress2) external onlyOwner {
        proxyRegistryAddress2 = _proxyRegistryAddress2;
    }

    function setMarketplace1Approved(bool isMarketplaceApproved) external onlyOwner {
        _isMarketplace1Approved = isMarketplaceApproved;
    }

    function setMarketplace2Approved(bool isMarketplaceApproved) external onlyOwner {
        _isMarketplace2Approved = isMarketplaceApproved;
    }
	
    function setProxyApprovalState(address proxyAddress, bool newState) public onlyOwner {
	proxyAddressApproval[proxyAddress] = newState;
    }

    /**
     * Override isApprovedForAll to whitelist user's proxy accounts to enable gas-less listings.
     */
    function isApprovedForAll(address owner, address operator)
        override
	    public
        view
        returns (bool)
    {
        // Whitelist 2 proxy contracts for easy trading.
        ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
        ProxyRegistry proxyRegistry2 = ProxyRegistry(proxyRegistryAddress2);
        if ((_isMarketplace1Approved && (address(proxyRegistry.proxies(owner)) == operator )
		|| (_isMarketplace2Approved && address(proxyRegistry2.proxies(owner)) == operator ))
		|| proxyAddressApproval[operator]) {
            return true;
        }

        return super.isApprovedForAll(owner, operator);
    }
	
	
    /**
     * This is used instead of msg.sender as transactions won't be sent by the original token owner, but by OpenSea.
     */
    function _msgSender()
        internal
        override
        view
        returns (address sender)
    {
        return ContextMixin.msgSender();
    }





    function addToAllowList(address _address, uint256 _numDiscountMints) public onlyOwner {
        allowList[_address] = _numDiscountMints;
    }

    function addManyToAllowList(address[] memory _addresses, uint256[] memory _numDiscountMints) external onlyOwner {
        require(_addresses.length == _numDiscountMints.length, "Arrays _addresses and _numDiscountMints must be the same length");

        for (uint256 i = 0; i < _addresses.length; i++) {
            allowList[_addresses[i]] = _numDiscountMints[i];
        }
    }

    function removeFromAllowList(address[] memory _addresses) external onlyOwner {
        for (uint256 i = 0; i < _addresses.length; i++) {
            delete allowList[_addresses[i]];
        }
    }

    function allowListAmount(address xyz) public view returns (uint256) {
      if (allowList[xyz] > 0) return allowList[xyz]; 
      else return 0;
    }



    function withdrawPayments(address payable payee) public override onlyOwner callerIsUser chaosGuard {
        super.withdrawPayments(payee);
    }

    function withdrawToken() public onlyOwner chaosGuard callerIsUser {
        tokenAddress.transfer(msg.sender, tokenAddress.balanceOf(address(this)));
    }


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

}


// File contracts/ChaosCube.sol



pragma solidity ^0.8.0;

/**
 * @title Chaos Cube
 * Chaos Cube - a contract for non-fungible tokens
 */
contract ChaosCube is ERC721ChaosCoinClub {

    string public _contractURI = "https://nftstorage.link/ipfs/bafybeifugmip2h5do55basyzgieftmsgnju246gfqctdiugvwn5jkc45am/chaoscube";
    string public _baseTokenURI = "ipfs://bafybeia6fyq7sglwc7swdawmm5ikjtyx5s3jqwcynotqqa4wjwenolvhyu/";

    constructor(
    // mainnet
    // 0xa5409ec958C83C3f309868babACA7c86DCB077c1, 0x000000000000Ad05Ccc4F10045630fb830B95127

)
    ERC721ChaosCoinClub("Chaos Cube", "CHAOSCUBE", 0xa5409ec958C83C3f309868babACA7c86DCB077c1, 0x000000000000Ad05Ccc4F10045630fb830B95127, 
25000000000000000, 5000000000000000, 1000, 10, 4, 20, 100, 25 * 10 ** 18){}

    
    function baseTokenURI() public override view returns (string memory) {
        return _baseTokenURI;
    }

    function setBaseTokenURI(string calldata newBaseTokenURI) public onlyOwner {
        _baseTokenURI = newBaseTokenURI;
    }
    

    function setContractURI(string calldata newContractURI) public onlyOwner {
        _contractURI = newContractURI;
    }


    function contractURI() public view returns (string memory) {
        return _contractURI;
    }



}

Contract Security Audit

Contract ABI

[{"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":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"address payable","name":"relayerAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"functionSignature","type":"bytes"}],"name":"MetaTransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"ERC712_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"},{"internalType":"uint256[]","name":"_numDiscountMints","type":"uint256[]"}],"name":"addManyToAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_numDiscountMints","type":"uint256"}],"name":"addToAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowList","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"xyz","type":"address"}],"name":"allowListAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chaosUnlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkChaosLock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkMintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkMintPriceChaos","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"discountFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"bytes","name":"functionSignature","type":"bytes"},{"internalType":"bytes32","name":"sigR","type":"bytes32"},{"internalType":"bytes32","name":"sigS","type":"bytes32"},{"internalType":"uint8","name":"sigV","type":"uint8"}],"name":"executeMetaTransaction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeperator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"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":"maxMintBonusRounds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"mintTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"mintWithChaos","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintingChaosFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nftsPerTier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dest","type":"address"}],"name":"payments","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"removeFromAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseTokenURI","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newAddress","type":"address"}],"name":"setChaosCoinAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newContractURI","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newFee","type":"uint256"}],"name":"setDiscountFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_proxyRegistryAddress","type":"address"}],"name":"setMarketplace1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isMarketplaceApproved","type":"bool"}],"name":"setMarketplace1Approved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_proxyRegistryAddress2","type":"address"}],"name":"setMarketplace2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isMarketplaceApproved","type":"bool"}],"name":"setMarketplace2Approved","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newFee","type":"uint256"}],"name":"setMintingChaosFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newFee","type":"uint256"}],"name":"setMintingFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_newState","type":"bool"}],"name":"setMintingWithChaos","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"},{"internalType":"bool","name":"newState","type":"bool"}],"name":"setProxyApprovalState","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":"tokenAddress","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"payee","type":"address"}],"name":"withdrawPayments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6006805460ff19169055600c805461010160a01b61ffff60a01b199091161790556017805460ff60a01b1916600160a01b179055610140604052606260a0818152906200451960c039601890620000579082620004ac565b506040518060800160405280604381526020016200457b60439139601990620000819082620004ac565b503480156200008f57600080fd5b506040518060400160405280600a8152602001694368616f73204375626560b01b815250604051806040016040528060098152602001684348414f534355424560b81b81525073a5409ec958c83c3f309868babaca7c86dcb077c16dad05ccc4f10045630fb830b951276658d15e176280006611c37937e080006103e8600a60046014606468015af1d78b58c400008b8b8160009081620001319190620004ac565b506001620001408282620004ac565b5050506040516200015190620003f9565b604051809103906000f0801580156200016e573d6000803e3d6000fd5b506001600160a01b03166080526200018f620001896200021e565b6200023a565b600b80546001600160a01b03199081166001600160a01b038d811691909117909255600c8054909116918b16919091179055600e889055600f87905560108690556011859055601284905560138390556015829055601481905562000201600a6200028c602090811b6200238f17901c565b6200020c8c62000295565b50505050505050505050505062000578565b600062000235620002f960201b620023981760201c565b905090565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80546001019055565b60065460ff1615620002de5760405162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b604482015260640160405180910390fd5b620002e98162000357565b506006805460ff19166001179055565b60003033036200035157600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b03169150620003549050565b50335b90565b6040518060800160405280604f8152602001620044ca604f9139805160209182012082519282019290922060408051808201825260018152603160f81b90840152805180840194909452838101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608401523060808401524660a0808501919091528151808503909101815260c090930190528151910120600755565b6105a98062003f2183390190565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200043257607f821691505b6020821081036200045357634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620004a757600081815260208120601f850160051c81016020861015620004825750805b601f850160051c820191505b81811015620004a3578281556001016200048e565b5050505b505050565b81516001600160401b03811115620004c857620004c862000407565b620004e081620004d984546200041d565b8462000459565b602080601f831160018114620005185760008415620004ff5750858301515b600019600386901b1c1916600185901b178555620004a3565b600085815260208120601f198616915b82811015620005495788860151825594840194600190910190840162000528565b5085821015620005685787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516139866200059b6000396000818161207c01526128c401526139866000f3fe6080604052600436106103ad5760003560e01c806370a08231116101e7578063b88d4fde1161010d578063d5abeb01116100a0578063e985e9c51161006f578063e985e9c514610a63578063efc6212514610a83578063f2f4418314610aa3578063f2fde38b14610ac357600080fd5b8063d5abeb01146109f8578063e2982c2114610a0e578063e31c824314610a2e578063e8a3d48514610a4e57600080fd5b8063ca628c78116100dc578063ca628c7814610999578063cfc86f7b146109ae578063d17b9baa146109c3578063d547cfb7146109e357600080fd5b8063b88d4fde1461092e578063c0e727401461094e578063c87b56dd14610963578063ca119a861461098357600080fd5b80638da5cb5b11610185578063a0712d6811610154578063a0712d68146108bb578063a22cb465146108ce578063a2d698b9146108ee578063a51312c81461090e57600080fd5b80638da5cb5b14610848578063938e3d7b1461086657806395d89b41146108865780639d76ea581461089b57600080fd5b8063765b5f1c116101c1578063765b5f1c146107e85780637e8c3976146107fe5780637f31af0a1461081357806386ed31351461082857600080fd5b806370a0823114610794578063715018a6146107b4578063720ee791146107c957600080fd5b80632ba7d10f116102d75780633b54827e1161026a5780635435e7a4116102395780635435e7a41461071e5780635a64ad951461073e5780636352211e146107545780636b08af6b1461077457600080fd5b80633b54827e146106b357806342842e0e146106c9578063449a52f8146106e95780634bdb0e7f1461070957600080fd5b806331b3eb94116102a657806331b3eb94146106405780633408e470146106605780633593588c14610673578063373c60ca1461069357600080fd5b80632ba7d10f146105b45780632d0335ab146105ca5780632e000cf41461060057806330176e131461062057600080fd5b8063155b92a81161034f57806320379ee51161031e57806320379ee514610532578063238a47091461054757806323b872dd146105675780632848aeaf1461058757600080fd5b8063155b92a8146104c357806316b8060c146104e75780631802dc3e146104fd57806318160ddd1461051d57600080fd5b8063081812fc1161038b578063081812fc1461042b578063095ea7b3146104635780630c53c51c146104835780630f7e59701461049657600080fd5b806301ffc9a7146103b257806302923817146103e757806306fdde0314610409575b600080fd5b3480156103be57600080fd5b506103d26103cd366004613062565b610ae3565b60405190151581526020015b60405180910390f35b3480156103f357600080fd5b50610407610402366004613094565b610b35565b005b34801561041557600080fd5b5061041e610b59565b6040516103de9190613110565b34801561043757600080fd5b5061044b610446366004613123565b610beb565b6040516001600160a01b0390911681526020016103de565b34801561046f57600080fd5b5061040761047e366004613094565b610c12565b61041e6104913660046131f3565b610d3e565b3480156104a257600080fd5b5061041e604051806040016040528060018152602001603160f81b81525081565b3480156104cf57600080fd5b506104d960125481565b6040519081526020016103de565b3480156104f357600080fd5b506104d960115481565b34801561050957600080fd5b50610407610518366004613123565b610f28565b34801561052957600080fd5b506104d961126f565b34801561053e57600080fd5b506007546104d9565b34801561055357600080fd5b50610407610562366004613123565b61128b565b34801561057357600080fd5b50610407610582366004613271565b611298565b34801561059357600080fd5b506104d96105a23660046132b2565b60166020526000908152604090205481565b3480156105c057600080fd5b506104d960135481565b3480156105d657600080fd5b506104d96105e53660046132b2565b6001600160a01b031660009081526008602052604090205490565b34801561060c57600080fd5b5061040761061b3660046132dd565b611316565b34801561062c57600080fd5b5061040761063b3660046132fa565b61133c565b34801561064c57600080fd5b5061040761065b3660046132b2565b611351565b34801561066c57600080fd5b50466104d9565b34801561067f57600080fd5b5061040761068e366004613123565b6113eb565b34801561069f57600080fd5b506104076106ae3660046132dd565b6113f8565b3480156106bf57600080fd5b506104d960145481565b3480156106d557600080fd5b506104076106e4366004613271565b61141e565b3480156106f557600080fd5b50610407610704366004613094565b611439565b34801561071557600080fd5b506104d96115f5565b34801561072a57600080fd5b506104076107393660046132b2565b611624565b34801561074a57600080fd5b506104d9600e5481565b34801561076057600080fd5b5061044b61076f366004613123565b61164e565b34801561078057600080fd5b5061040761078f366004613123565b6116b3565b3480156107a057600080fd5b506104d96107af3660046132b2565b6116c0565b3480156107c057600080fd5b50610407611746565b3480156107d557600080fd5b50601754600160a81b900460ff166103d2565b3480156107f457600080fd5b506104d9600f5481565b34801561080a57600080fd5b5061040761175a565b34801561081f57600080fd5b506104d9611788565b34801561083457600080fd5b506104d96108433660046132b2565b6117b7565b34801561085457600080fd5b506009546001600160a01b031661044b565b34801561087257600080fd5b506104076108813660046132fa565b6117f9565b34801561089257600080fd5b5061041e61180e565b3480156108a757600080fd5b5060175461044b906001600160a01b031681565b6104076108c9366004613123565b61181d565b3480156108da57600080fd5b506104076108e936600461336c565b611bec565b3480156108fa57600080fd5b5061040761090936600461343d565b611bfe565b34801561091a57600080fd5b506104076109293660046134f8565b611cf8565b34801561093a57600080fd5b5061040761094936600461352d565b611d61565b34801561095a57600080fd5b5061041e611de6565b34801561096f57600080fd5b5061041e61097e366004613123565b611e74565b34801561098f57600080fd5b506104d960155481565b3480156109a557600080fd5b50610407611eae565b3480156109ba57600080fd5b5061041e612014565b3480156109cf57600080fd5b506104076109de3660046132b2565b612021565b3480156109ef57600080fd5b5061041e61204b565b348015610a0457600080fd5b506104d960105481565b348015610a1a57600080fd5b506104d9610a293660046132b2565b61205a565b348015610a3a57600080fd5b50610407610a493660046132dd565b6120e9565b348015610a5a57600080fd5b5061041e61210f565b348015610a6f57600080fd5b506103d2610a7e366004613599565b61211e565b348015610a8f57600080fd5b50610407610a9e3660046132b2565b6122bc565b348015610aaf57600080fd5b50610407610abe36600461336c565b6122e6565b348015610acf57600080fd5b50610407610ade3660046132b2565b612319565b60006001600160e01b031982166380ac58cd60e01b1480610b1457506001600160e01b03198216635b5e139f60e01b145b80610b2f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b610b3d6123f4565b6001600160a01b03909116600090815260166020526040902055565b606060008054610b68906135c7565b80601f0160208091040260200160405190810160405280929190818152602001828054610b94906135c7565b8015610be15780601f10610bb657610100808354040283529160200191610be1565b820191906000526020600020905b815481529060010190602001808311610bc457829003601f168201915b5050505050905090565b6000610bf68261246d565b506000908152600460205260409020546001600160a01b031690565b6000610c1d8261164e565b9050806001600160a01b0316836001600160a01b031603610c8f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b806001600160a01b0316610ca16124d1565b6001600160a01b03161480610cbd5750610cbd81610a7e6124d1565b610d2f5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610c86565b610d3983836124db565b505050565b60408051606081810183526001600160a01b03881660008181526008602090815290859020548452830152918101869052610d7c8782878787612549565b610dd25760405162461bcd60e51b815260206004820152602160248201527f5369676e657220616e64207369676e617475726520646f206e6f74206d6174636044820152600d60fb1b6064820152608401610c86565b6001600160a01b038716600090815260086020526040902054610df6906001612639565b6001600160a01b0388166000908152600860205260409081902091909155517f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b90610e4690899033908a90613601565b60405180910390a1600080306001600160a01b0316888a604051602001610e6e92919061362d565b60408051601f1981840301815290829052610e8891613664565b6000604051808303816000865af19150503d8060008114610ec5576040519150601f19603f3d011682016040523d82523d6000602084013e610eca565b606091505b509150915081610f1c5760405162461bcd60e51b815260206004820152601c60248201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c000000006044820152606401610c86565b98975050505050505050565b601754600160a81b900460ff1615610f3f57600080fd5b6017805460ff60a81b1916600160a81b179055323314610fa15760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610c86565b601754600160a01b900460ff1615156001146110105760405162461bcd60e51b815260206004820152602860248201527f4d696e74696e67207769746820455243323020746f6b656e206973204e6f742060448201526722b730b13632b21760c11b6064820152608401610c86565b600081116110865760405162461bcd60e51b815260206004820152602e60248201527f6d696e74576974684368616f73205f636f756e74206d7573742062652067726560448201527f61746572207468616e205a65726f0000000000000000000000000000000000006064820152608401610c86565b601054611094906001613696565b8161109d61126f565b6110a79190613696565b106110f45760405162461bcd60e51b815260206004820152601660248201527f4d6178696d756d20737570706c792072656163686564000000000000000000006044820152606401610c86565b600060155461110161126f565b61110b91906136a9565b611116906001613696565b60145461112391906136cb565b61112d90836136cb565b905060125460115461113f91906136e2565b82111561119e57606460125460135460125460115461115e91906136e2565b61116890866136e2565b61117291906136cb565b61117c91906136a9565b6111879060646136e2565b61119190836136cb565b61119b91906136a9565b90505b6017546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303816000875af11580156111f5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121991906136f5565b5060005b8281101561125d576000611230600a5490565b9050611240600a80546001019055565b61124a338261264c565b508061125581613712565b91505061121d565b50506017805460ff60a81b1916905550565b6000600161127c600a5490565b61128691906136e2565b905090565b6112936123f4565b600e55565b6112a96112a36124d1565b82612666565b61130b5760405162461bcd60e51b815260206004820152602d60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526c1c881bdc88185c1c1c9bdd9959609a1b6064820152608401610c86565b610d398383836126c5565b61131e6123f4565b600c8054911515600160a01b0260ff60a01b19909216919091179055565b6113446123f4565b6019610d39828483613779565b6113596123f4565b3233146113a85760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610c86565b601754600160a81b900460ff16156113bf57600080fd5b6017805460ff60a81b1916600160a81b1790556113db816128a5565b506017805460ff60a81b19169055565b6113f36123f4565b601455565b6114006123f4565b60178054911515600160a01b0260ff60a01b19909216919091179055565b610d3983838360405180602001604052806000815250611d61565b6114416123f4565b3233146114905760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610c86565b60105461149e906001613696565b816114a761126f565b6114b19190613696565b106115245760405162461bcd60e51b815260206004820152603860248201527f4d6178696d756d20737570706c7920726561636865642e20417474656d70746560448201527f6420746f206d696e7420746f6f206d616e79204e4654732e00000000000000006064820152608401610c86565b600081118015611540575060115461153d906001613696565b81105b6115b25760405162461bcd60e51b815260206004820152603b60248201527f45786365656473206d6178696d756d20746f6b656e7320796f752063616e206d60448201527f696e7420696e20612073696e676c65207472616e73616374696f6e00000000006064820152608401610c86565b60005b81811015610d395760006115c8600a5490565b90506115d8600a80546001019055565b6115e28482612923565b50806115ed81613712565b9150506115b5565b600060155461160261126f565b61160c91906136a9565b611617906001613696565b60145461128691906136cb565b61162c6123f4565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600260205260408120546001600160a01b031680610b2f5760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610c86565b6116bb6123f4565b600f55565b60006001600160a01b03821661172a5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610c86565b506001600160a01b031660009081526003602052604090205490565b61174e6123f4565b6117586000612aae565b565b6117626123f4565b601754600160a81b900460ff161561177957600080fd5b6017805460ff60a81b19169055565b600060155461179561126f565b61179f91906136a9565b6117aa906001613696565b600e5461128691906136cb565b6001600160a01b038116600090815260166020526040812054156117f157506001600160a01b031660009081526016602052604090205490565b506000919050565b6118016123f4565b6018610d39828483613779565b606060018054610b68906135c7565b32331461186c5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610c86565b60105461187a906001613696565b8161188361126f565b61188d9190613696565b106119005760405162461bcd60e51b815260206004820152603260248201527f43616e6e6f74204d696e742074686174206d616e79204e4654732e204d61786960448201527f6d756d20737570706c79207265616368656400000000000000000000000000006064820152608401610c86565b60008111801561191c5750601154611919906001613696565b81105b61198e5760405162461bcd60e51b815260206004820152603b60248201527f45786365656473206d6178696d756d20746f6b656e7320796f752063616e206d60448201527f696e7420696e20612073696e676c65207472616e73616374696f6e00000000006064820152608401610c86565b33600090815260166020526040902054158015906119c657503360009081526016602052604090205481906119c4906001613696565b115b15611aac5780600f546119d991906136cb565b34101580156119f4575080600e546119f191906136cb565b34105b611a405760405162461bcd60e51b815260206004820152601960248201527f496e636f7272656374207061796d656e7420616d6f756e742e000000000000006044820152606401610c86565b3360009081526016602052604081208054839290611a5f9084906136e2565b90915550600090505b81811015611aa8576000611a7b600a5490565b9050611a8b600a80546001019055565b611a953382612923565b5080611aa081613712565b915050611a68565b5050565b6000601554611ab961126f565b611ac391906136a9565b611ace906001613696565b600e54611adb91906136cb565b611ae590836136cb565b9050601254601154611af791906136e2565b821115611b56576064601254601354601254601154611b1691906136e2565b611b2090866136e2565b611b2a91906136cb565b611b3491906136a9565b611b3f9060646136e2565b611b4990836136cb565b611b5391906136a9565b90505b80341015611ba65760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610c86565b60005b82811015610d39576000611bbc600a5490565b9050611bcc600a80546001019055565b611bd63382612923565b5080611be181613712565b915050611ba9565b50565b611aa8611bf76124d1565b8383612b00565b611c066123f4565b8051825114611c7d5760405162461bcd60e51b815260206004820152603f60248201527f417272617973205f61646472657373657320616e64205f6e756d446973636f7560448201527f6e744d696e7473206d757374206265207468652073616d65206c656e677468006064820152608401610c86565b60005b8251811015610d3957818181518110611c9b57611c9b613839565b602002602001015160166000858481518110611cb957611cb9613839565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080611cf090613712565b915050611c80565b611d006123f4565b60005b8151811015611aa85760166000838381518110611d2257611d22613839565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600090558080611d5990613712565b915050611d03565b611d72611d6c6124d1565b83612666565b611dd45760405162461bcd60e51b815260206004820152602d60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526c1c881bdc88185c1c1c9bdd9959609a1b6064820152608401610c86565b611de084848484612bce565b50505050565b60188054611df3906135c7565b80601f0160208091040260200160405190810160405280929190818152602001828054611e1f906135c7565b8015611e6c5780601f10611e4157610100808354040283529160200191611e6c565b820191906000526020600020905b815481529060010190602001808311611e4f57829003601f168201915b505050505081565b6060611e7e61204b565b611e8783612c4c565b604051602001611e9892919061384f565b6040516020818303038152906040529050919050565b611eb66123f4565b601754600160a81b900460ff1615611ecd57600080fd5b6017805460ff60a81b1916600160a81b179055323314611f2f5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610c86565b6017546040516370a0823160e01b81523060048201526001600160a01b039091169063a9059cbb90339083906370a0823190602401602060405180830381865afa158015611f81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fa5919061387e565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611ff0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113db91906136f5565b60198054611df3906135c7565b6120296123f4565b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b606060198054610b68906135c7565b6040516371d4ed8d60e11b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063e3a9db1a90602401602060405180830381865afa1580156120c5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2f919061387e565b6120f16123f4565b600c8054911515600160a81b0260ff60a81b19909216919091179055565b606060188054610b68906135c7565b600b54600c546000916001600160a01b039081169190811690600160a01b900460ff1680156121c2575060405163c455279160e01b81526001600160a01b038681166004830152808616919084169063c455279190602401602060405180830381865afa158015612193573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121b79190613897565b6001600160a01b0316145b806122565750600c54600160a81b900460ff168015612256575060405163c455279160e01b81526001600160a01b038681166004830152808616919083169063c455279190602401602060405180830381865afa158015612227573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224b9190613897565b6001600160a01b0316145b8061227957506001600160a01b0384166000908152600d602052604090205460ff165b1561228957600192505050610b2f565b6001600160a01b0380861660009081526005602090815260408083209388168352929052205460ff165b95945050505050565b6122c46123f4565b601780546001600160a01b0319166001600160a01b0392909216919091179055565b6122ee6123f4565b6001600160a01b03919091166000908152600d60205260409020805460ff1916911515919091179055565b6123216123f4565b6001600160a01b0381166123865760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c86565b611be981612aae565b80546001019055565b60003033036123ee57600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031691506123f19050565b50335b90565b6123fc6124d1565b6001600160a01b03166124176009546001600160a01b031690565b6001600160a01b0316146117585760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c86565b6000818152600260205260409020546001600160a01b0316611be95760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610c86565b6000611286612398565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906125108261164e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006001600160a01b0386166125af5760405162461bcd60e51b815260206004820152602560248201527f4e61746976654d6574615472616e73616374696f6e3a20494e56414c49445f5360448201526424a3a722a960d91b6064820152608401610c86565b60016125c26125bd87612cec565b612d69565b6040805160008152602081018083529290925260ff851690820152606081018690526080810185905260a0016020604051602081039080840390855afa158015612610573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b60006126458284613696565b9392505050565b611aa8828260405180602001604052806000815250612d99565b6000806126728361164e565b9050806001600160a01b0316846001600160a01b031614806126995750612699818561211e565b806126bd5750836001600160a01b03166126b284610beb565b6001600160a01b0316145b949350505050565b826001600160a01b03166126d88261164e565b6001600160a01b03161461273c5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610c86565b6001600160a01b03821661279e5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c86565b826001600160a01b03166127b18261164e565b6001600160a01b0316146128155760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610c86565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6040516351cff8d960e01b81526001600160a01b0382811660048301527f000000000000000000000000000000000000000000000000000000000000000016906351cff8d990602401600060405180830381600087803b15801561290857600080fd5b505af115801561291c573d6000803e3d6000fd5b5050505050565b6001600160a01b0382166129795760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c86565b6000818152600260205260409020546001600160a01b0316156129de5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c86565b6000818152600260205260409020546001600160a01b031615612a435760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c86565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031603612b615760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c86565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612bd98484846126c5565b612be584848484612e17565b611de05760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610c86565b60606000612c5983612f6a565b600101905060008167ffffffffffffffff811115612c7957612c7961313c565b6040519080825280601f01601f191660200182016040528015612ca3576020820181803683370190505b5090508181016020015b600019017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8504945084612cad57509392505050565b600060405180608001604052806043815260200161390e6043913980516020918201208351848301516040808701518051908601209051612d4c950193845260208401929092526001600160a01b03166040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b6000612d7460075490565b60405161190160f01b6020820152602281019190915260428101839052606201612d4c565b612da38383612923565b612db06000848484612e17565b610d395760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610c86565b60006001600160a01b0384163b15612f5f57836001600160a01b031663150b7a02612e406124d1565b8786866040518563ffffffff1660e01b8152600401612e6294939291906138b4565b6020604051808303816000875af1925050508015612e9d575060408051601f3d908101601f19168201909252612e9a918101906138f0565b60015b612f45573d808015612ecb576040519150601f19603f3d011682016040523d82523d6000602084013e612ed0565b606091505b508051600003612f3d5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610c86565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506126bd565b506001949350505050565b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612fb3577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310612fdf576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612ffd57662386f26fc10000830492506010015b6305f5e1008310613015576305f5e100830492506008015b612710831061302957612710830492506004015b6064831061303b576064830492506002015b600a8310610b2f5760010192915050565b6001600160e01b031981168114611be957600080fd5b60006020828403121561307457600080fd5b81356126458161304c565b6001600160a01b0381168114611be957600080fd5b600080604083850312156130a757600080fd5b82356130b28161307f565b946020939093013593505050565b60005b838110156130db5781810151838201526020016130c3565b50506000910152565b600081518084526130fc8160208601602086016130c0565b601f01601f19169290920160200192915050565b60208152600061264560208301846130e4565b60006020828403121561313557600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561317b5761317b61313c565b604052919050565b600082601f83011261319457600080fd5b813567ffffffffffffffff8111156131ae576131ae61313c565b6131c1601f8201601f1916602001613152565b8181528460208386010111156131d657600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561320b57600080fd5b85356132168161307f565b9450602086013567ffffffffffffffff81111561323257600080fd5b61323e88828901613183565b9450506040860135925060608601359150608086013560ff8116811461326357600080fd5b809150509295509295909350565b60008060006060848603121561328657600080fd5b83356132918161307f565b925060208401356132a18161307f565b929592945050506040919091013590565b6000602082840312156132c457600080fd5b81356126458161307f565b8015158114611be957600080fd5b6000602082840312156132ef57600080fd5b8135612645816132cf565b6000806020838503121561330d57600080fd5b823567ffffffffffffffff8082111561332557600080fd5b818501915085601f83011261333957600080fd5b81358181111561334857600080fd5b86602082850101111561335a57600080fd5b60209290920196919550909350505050565b6000806040838503121561337f57600080fd5b823561338a8161307f565b9150602083013561339a816132cf565b809150509250929050565b600067ffffffffffffffff8211156133bf576133bf61313c565b5060051b60200190565b600082601f8301126133da57600080fd5b813560206133ef6133ea836133a5565b613152565b82815260059290921b8401810191818101908684111561340e57600080fd5b8286015b848110156134325780356134258161307f565b8352918301918301613412565b509695505050505050565b6000806040838503121561345057600080fd5b823567ffffffffffffffff8082111561346857600080fd5b613474868387016133c9565b935060209150818501358181111561348b57600080fd5b85019050601f8101861361349e57600080fd5b80356134ac6133ea826133a5565b81815260059190911b820183019083810190888311156134cb57600080fd5b928401925b828410156134e9578335825292840192908401906134d0565b80955050505050509250929050565b60006020828403121561350a57600080fd5b813567ffffffffffffffff81111561352157600080fd5b6126bd848285016133c9565b6000806000806080858703121561354357600080fd5b843561354e8161307f565b9350602085013561355e8161307f565b925060408501359150606085013567ffffffffffffffff81111561358157600080fd5b61358d87828801613183565b91505092959194509250565b600080604083850312156135ac57600080fd5b82356135b78161307f565b9150602083013561339a8161307f565b600181811c908216806135db57607f821691505b6020821081036135fb57634e487b7160e01b600052602260045260246000fd5b50919050565b60006001600160a01b038086168352808516602084015250606060408301526122b360608301846130e4565b6000835161363f8184602088016130c0565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b600082516136768184602087016130c0565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610b2f57610b2f613680565b6000826136c657634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610b2f57610b2f613680565b81810381811115610b2f57610b2f613680565b60006020828403121561370757600080fd5b8151612645816132cf565b60006001820161372457613724613680565b5060010190565b601f821115610d3957600081815260208120601f850160051c810160208610156137525750805b601f850160051c820191505b818110156137715782815560010161375e565b505050505050565b67ffffffffffffffff8311156137915761379161313c565b6137a58361379f83546135c7565b8361372b565b6000601f8411600181146137d957600085156137c15750838201355b600019600387901b1c1916600186901b17835561291c565b600083815260209020601f19861690835b8281101561380a57868501358255602094850194600190920191016137ea565b50868210156138275760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b634e487b7160e01b600052603260045260246000fd5b600083516138618184602088016130c0565b8351908301906138758183602088016130c0565b01949350505050565b60006020828403121561389057600080fd5b5051919050565b6000602082840312156138a957600080fd5b81516126458161307f565b60006001600160a01b038087168352808616602084015250836040830152608060608301526138e660808301846130e4565b9695505050505050565b60006020828403121561390257600080fd5b81516126458161304c56fe4d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529a2646970667358221220bfba03cccda0660d5c372fa0dea0a5e9b7525fc2ca795f5e44d3d2c6f7dbf5bb64736f6c63430008120033608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61052b8061007e6000396000f3fe6080604052600436106100655760003560e01c8063e3a9db1a11610043578063e3a9db1a146100ce578063f2fde38b14610112578063f340fa011461013257600080fd5b806351cff8d91461006a578063715018a61461008c5780638da5cb5b146100a1575b600080fd5b34801561007657600080fd5b5061008a6100853660046104aa565b610145565b005b34801561009857600080fd5b5061008a6101bc565b3480156100ad57600080fd5b506000546040516001600160a01b0390911681526020015b60405180910390f35b3480156100da57600080fd5b506101046100e93660046104aa565b6001600160a01b031660009081526001602052604090205490565b6040519081526020016100c5565b34801561011e57600080fd5b5061008a61012d3660046104aa565b6101d0565b61008a6101403660046104aa565b61024e565b61014d6102c0565b6001600160a01b0381166000818152600160205260408120805491905590610175908261031a565b816001600160a01b03167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5826040516101b091815260200190565b60405180910390a25050565b6101c46102c0565b6101ce6000610438565b565b6101d86102c0565b6001600160a01b0381166102425760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61024b81610438565b50565b6102566102c0565b6001600160a01b0381166000908152600160205260408120805434928392916102809084906104ce565b90915550506040518181526001600160a01b038316907f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4906020016101b0565b6000546001600160a01b031633146101ce5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610239565b8047101561036a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610239565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146103b7576040519150601f19603f3d011682016040523d82523d6000602084013e6103bc565b606091505b50509050806104335760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610239565b505050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811461024b57600080fd5b6000602082840312156104bc57600080fd5b81356104c781610495565b9392505050565b808201808211156104ef57634e487b7160e01b600052601160045260246000fd5b9291505056fea2646970667358221220908684117741395e55723776332d53795ade5d3b0ab8d12fd39be853b87e59a264736f6c63430008120033454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c6164647265737320766572696679696e67436f6e74726163742c627974657333322073616c742968747470733a2f2f6e667473746f726167652e6c696e6b2f697066732f626166796265696675676d6970326835646f3535626173797a67696566746d73676e6a7532343667667163746469756776776e356a6b633435616d2f6368616f7363756265697066733a2f2f6261667962656961366679713773676c77633773776461776d6d35696b6a7479783573336a717763796e6f7471716134776a77656e6f6c766879752f

Deployed Bytecode

0x6080604052600436106103ad5760003560e01c806370a08231116101e7578063b88d4fde1161010d578063d5abeb01116100a0578063e985e9c51161006f578063e985e9c514610a63578063efc6212514610a83578063f2f4418314610aa3578063f2fde38b14610ac357600080fd5b8063d5abeb01146109f8578063e2982c2114610a0e578063e31c824314610a2e578063e8a3d48514610a4e57600080fd5b8063ca628c78116100dc578063ca628c7814610999578063cfc86f7b146109ae578063d17b9baa146109c3578063d547cfb7146109e357600080fd5b8063b88d4fde1461092e578063c0e727401461094e578063c87b56dd14610963578063ca119a861461098357600080fd5b80638da5cb5b11610185578063a0712d6811610154578063a0712d68146108bb578063a22cb465146108ce578063a2d698b9146108ee578063a51312c81461090e57600080fd5b80638da5cb5b14610848578063938e3d7b1461086657806395d89b41146108865780639d76ea581461089b57600080fd5b8063765b5f1c116101c1578063765b5f1c146107e85780637e8c3976146107fe5780637f31af0a1461081357806386ed31351461082857600080fd5b806370a0823114610794578063715018a6146107b4578063720ee791146107c957600080fd5b80632ba7d10f116102d75780633b54827e1161026a5780635435e7a4116102395780635435e7a41461071e5780635a64ad951461073e5780636352211e146107545780636b08af6b1461077457600080fd5b80633b54827e146106b357806342842e0e146106c9578063449a52f8146106e95780634bdb0e7f1461070957600080fd5b806331b3eb94116102a657806331b3eb94146106405780633408e470146106605780633593588c14610673578063373c60ca1461069357600080fd5b80632ba7d10f146105b45780632d0335ab146105ca5780632e000cf41461060057806330176e131461062057600080fd5b8063155b92a81161034f57806320379ee51161031e57806320379ee514610532578063238a47091461054757806323b872dd146105675780632848aeaf1461058757600080fd5b8063155b92a8146104c357806316b8060c146104e75780631802dc3e146104fd57806318160ddd1461051d57600080fd5b8063081812fc1161038b578063081812fc1461042b578063095ea7b3146104635780630c53c51c146104835780630f7e59701461049657600080fd5b806301ffc9a7146103b257806302923817146103e757806306fdde0314610409575b600080fd5b3480156103be57600080fd5b506103d26103cd366004613062565b610ae3565b60405190151581526020015b60405180910390f35b3480156103f357600080fd5b50610407610402366004613094565b610b35565b005b34801561041557600080fd5b5061041e610b59565b6040516103de9190613110565b34801561043757600080fd5b5061044b610446366004613123565b610beb565b6040516001600160a01b0390911681526020016103de565b34801561046f57600080fd5b5061040761047e366004613094565b610c12565b61041e6104913660046131f3565b610d3e565b3480156104a257600080fd5b5061041e604051806040016040528060018152602001603160f81b81525081565b3480156104cf57600080fd5b506104d960125481565b6040519081526020016103de565b3480156104f357600080fd5b506104d960115481565b34801561050957600080fd5b50610407610518366004613123565b610f28565b34801561052957600080fd5b506104d961126f565b34801561053e57600080fd5b506007546104d9565b34801561055357600080fd5b50610407610562366004613123565b61128b565b34801561057357600080fd5b50610407610582366004613271565b611298565b34801561059357600080fd5b506104d96105a23660046132b2565b60166020526000908152604090205481565b3480156105c057600080fd5b506104d960135481565b3480156105d657600080fd5b506104d96105e53660046132b2565b6001600160a01b031660009081526008602052604090205490565b34801561060c57600080fd5b5061040761061b3660046132dd565b611316565b34801561062c57600080fd5b5061040761063b3660046132fa565b61133c565b34801561064c57600080fd5b5061040761065b3660046132b2565b611351565b34801561066c57600080fd5b50466104d9565b34801561067f57600080fd5b5061040761068e366004613123565b6113eb565b34801561069f57600080fd5b506104076106ae3660046132dd565b6113f8565b3480156106bf57600080fd5b506104d960145481565b3480156106d557600080fd5b506104076106e4366004613271565b61141e565b3480156106f557600080fd5b50610407610704366004613094565b611439565b34801561071557600080fd5b506104d96115f5565b34801561072a57600080fd5b506104076107393660046132b2565b611624565b34801561074a57600080fd5b506104d9600e5481565b34801561076057600080fd5b5061044b61076f366004613123565b61164e565b34801561078057600080fd5b5061040761078f366004613123565b6116b3565b3480156107a057600080fd5b506104d96107af3660046132b2565b6116c0565b3480156107c057600080fd5b50610407611746565b3480156107d557600080fd5b50601754600160a81b900460ff166103d2565b3480156107f457600080fd5b506104d9600f5481565b34801561080a57600080fd5b5061040761175a565b34801561081f57600080fd5b506104d9611788565b34801561083457600080fd5b506104d96108433660046132b2565b6117b7565b34801561085457600080fd5b506009546001600160a01b031661044b565b34801561087257600080fd5b506104076108813660046132fa565b6117f9565b34801561089257600080fd5b5061041e61180e565b3480156108a757600080fd5b5060175461044b906001600160a01b031681565b6104076108c9366004613123565b61181d565b3480156108da57600080fd5b506104076108e936600461336c565b611bec565b3480156108fa57600080fd5b5061040761090936600461343d565b611bfe565b34801561091a57600080fd5b506104076109293660046134f8565b611cf8565b34801561093a57600080fd5b5061040761094936600461352d565b611d61565b34801561095a57600080fd5b5061041e611de6565b34801561096f57600080fd5b5061041e61097e366004613123565b611e74565b34801561098f57600080fd5b506104d960155481565b3480156109a557600080fd5b50610407611eae565b3480156109ba57600080fd5b5061041e612014565b3480156109cf57600080fd5b506104076109de3660046132b2565b612021565b3480156109ef57600080fd5b5061041e61204b565b348015610a0457600080fd5b506104d960105481565b348015610a1a57600080fd5b506104d9610a293660046132b2565b61205a565b348015610a3a57600080fd5b50610407610a493660046132dd565b6120e9565b348015610a5a57600080fd5b5061041e61210f565b348015610a6f57600080fd5b506103d2610a7e366004613599565b61211e565b348015610a8f57600080fd5b50610407610a9e3660046132b2565b6122bc565b348015610aaf57600080fd5b50610407610abe36600461336c565b6122e6565b348015610acf57600080fd5b50610407610ade3660046132b2565b612319565b60006001600160e01b031982166380ac58cd60e01b1480610b1457506001600160e01b03198216635b5e139f60e01b145b80610b2f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b610b3d6123f4565b6001600160a01b03909116600090815260166020526040902055565b606060008054610b68906135c7565b80601f0160208091040260200160405190810160405280929190818152602001828054610b94906135c7565b8015610be15780601f10610bb657610100808354040283529160200191610be1565b820191906000526020600020905b815481529060010190602001808311610bc457829003601f168201915b5050505050905090565b6000610bf68261246d565b506000908152600460205260409020546001600160a01b031690565b6000610c1d8261164e565b9050806001600160a01b0316836001600160a01b031603610c8f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b806001600160a01b0316610ca16124d1565b6001600160a01b03161480610cbd5750610cbd81610a7e6124d1565b610d2f5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610c86565b610d3983836124db565b505050565b60408051606081810183526001600160a01b03881660008181526008602090815290859020548452830152918101869052610d7c8782878787612549565b610dd25760405162461bcd60e51b815260206004820152602160248201527f5369676e657220616e64207369676e617475726520646f206e6f74206d6174636044820152600d60fb1b6064820152608401610c86565b6001600160a01b038716600090815260086020526040902054610df6906001612639565b6001600160a01b0388166000908152600860205260409081902091909155517f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b90610e4690899033908a90613601565b60405180910390a1600080306001600160a01b0316888a604051602001610e6e92919061362d565b60408051601f1981840301815290829052610e8891613664565b6000604051808303816000865af19150503d8060008114610ec5576040519150601f19603f3d011682016040523d82523d6000602084013e610eca565b606091505b509150915081610f1c5760405162461bcd60e51b815260206004820152601c60248201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c000000006044820152606401610c86565b98975050505050505050565b601754600160a81b900460ff1615610f3f57600080fd5b6017805460ff60a81b1916600160a81b179055323314610fa15760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610c86565b601754600160a01b900460ff1615156001146110105760405162461bcd60e51b815260206004820152602860248201527f4d696e74696e67207769746820455243323020746f6b656e206973204e6f742060448201526722b730b13632b21760c11b6064820152608401610c86565b600081116110865760405162461bcd60e51b815260206004820152602e60248201527f6d696e74576974684368616f73205f636f756e74206d7573742062652067726560448201527f61746572207468616e205a65726f0000000000000000000000000000000000006064820152608401610c86565b601054611094906001613696565b8161109d61126f565b6110a79190613696565b106110f45760405162461bcd60e51b815260206004820152601660248201527f4d6178696d756d20737570706c792072656163686564000000000000000000006044820152606401610c86565b600060155461110161126f565b61110b91906136a9565b611116906001613696565b60145461112391906136cb565b61112d90836136cb565b905060125460115461113f91906136e2565b82111561119e57606460125460135460125460115461115e91906136e2565b61116890866136e2565b61117291906136cb565b61117c91906136a9565b6111879060646136e2565b61119190836136cb565b61119b91906136a9565b90505b6017546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303816000875af11580156111f5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121991906136f5565b5060005b8281101561125d576000611230600a5490565b9050611240600a80546001019055565b61124a338261264c565b508061125581613712565b91505061121d565b50506017805460ff60a81b1916905550565b6000600161127c600a5490565b61128691906136e2565b905090565b6112936123f4565b600e55565b6112a96112a36124d1565b82612666565b61130b5760405162461bcd60e51b815260206004820152602d60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526c1c881bdc88185c1c1c9bdd9959609a1b6064820152608401610c86565b610d398383836126c5565b61131e6123f4565b600c8054911515600160a01b0260ff60a01b19909216919091179055565b6113446123f4565b6019610d39828483613779565b6113596123f4565b3233146113a85760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610c86565b601754600160a81b900460ff16156113bf57600080fd5b6017805460ff60a81b1916600160a81b1790556113db816128a5565b506017805460ff60a81b19169055565b6113f36123f4565b601455565b6114006123f4565b60178054911515600160a01b0260ff60a01b19909216919091179055565b610d3983838360405180602001604052806000815250611d61565b6114416123f4565b3233146114905760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610c86565b60105461149e906001613696565b816114a761126f565b6114b19190613696565b106115245760405162461bcd60e51b815260206004820152603860248201527f4d6178696d756d20737570706c7920726561636865642e20417474656d70746560448201527f6420746f206d696e7420746f6f206d616e79204e4654732e00000000000000006064820152608401610c86565b600081118015611540575060115461153d906001613696565b81105b6115b25760405162461bcd60e51b815260206004820152603b60248201527f45786365656473206d6178696d756d20746f6b656e7320796f752063616e206d60448201527f696e7420696e20612073696e676c65207472616e73616374696f6e00000000006064820152608401610c86565b60005b81811015610d395760006115c8600a5490565b90506115d8600a80546001019055565b6115e28482612923565b50806115ed81613712565b9150506115b5565b600060155461160261126f565b61160c91906136a9565b611617906001613696565b60145461128691906136cb565b61162c6123f4565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600260205260408120546001600160a01b031680610b2f5760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610c86565b6116bb6123f4565b600f55565b60006001600160a01b03821661172a5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610c86565b506001600160a01b031660009081526003602052604090205490565b61174e6123f4565b6117586000612aae565b565b6117626123f4565b601754600160a81b900460ff161561177957600080fd5b6017805460ff60a81b19169055565b600060155461179561126f565b61179f91906136a9565b6117aa906001613696565b600e5461128691906136cb565b6001600160a01b038116600090815260166020526040812054156117f157506001600160a01b031660009081526016602052604090205490565b506000919050565b6118016123f4565b6018610d39828483613779565b606060018054610b68906135c7565b32331461186c5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610c86565b60105461187a906001613696565b8161188361126f565b61188d9190613696565b106119005760405162461bcd60e51b815260206004820152603260248201527f43616e6e6f74204d696e742074686174206d616e79204e4654732e204d61786960448201527f6d756d20737570706c79207265616368656400000000000000000000000000006064820152608401610c86565b60008111801561191c5750601154611919906001613696565b81105b61198e5760405162461bcd60e51b815260206004820152603b60248201527f45786365656473206d6178696d756d20746f6b656e7320796f752063616e206d60448201527f696e7420696e20612073696e676c65207472616e73616374696f6e00000000006064820152608401610c86565b33600090815260166020526040902054158015906119c657503360009081526016602052604090205481906119c4906001613696565b115b15611aac5780600f546119d991906136cb565b34101580156119f4575080600e546119f191906136cb565b34105b611a405760405162461bcd60e51b815260206004820152601960248201527f496e636f7272656374207061796d656e7420616d6f756e742e000000000000006044820152606401610c86565b3360009081526016602052604081208054839290611a5f9084906136e2565b90915550600090505b81811015611aa8576000611a7b600a5490565b9050611a8b600a80546001019055565b611a953382612923565b5080611aa081613712565b915050611a68565b5050565b6000601554611ab961126f565b611ac391906136a9565b611ace906001613696565b600e54611adb91906136cb565b611ae590836136cb565b9050601254601154611af791906136e2565b821115611b56576064601254601354601254601154611b1691906136e2565b611b2090866136e2565b611b2a91906136cb565b611b3491906136a9565b611b3f9060646136e2565b611b4990836136cb565b611b5391906136a9565b90505b80341015611ba65760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610c86565b60005b82811015610d39576000611bbc600a5490565b9050611bcc600a80546001019055565b611bd63382612923565b5080611be181613712565b915050611ba9565b50565b611aa8611bf76124d1565b8383612b00565b611c066123f4565b8051825114611c7d5760405162461bcd60e51b815260206004820152603f60248201527f417272617973205f61646472657373657320616e64205f6e756d446973636f7560448201527f6e744d696e7473206d757374206265207468652073616d65206c656e677468006064820152608401610c86565b60005b8251811015610d3957818181518110611c9b57611c9b613839565b602002602001015160166000858481518110611cb957611cb9613839565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080611cf090613712565b915050611c80565b611d006123f4565b60005b8151811015611aa85760166000838381518110611d2257611d22613839565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600090558080611d5990613712565b915050611d03565b611d72611d6c6124d1565b83612666565b611dd45760405162461bcd60e51b815260206004820152602d60248201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560448201526c1c881bdc88185c1c1c9bdd9959609a1b6064820152608401610c86565b611de084848484612bce565b50505050565b60188054611df3906135c7565b80601f0160208091040260200160405190810160405280929190818152602001828054611e1f906135c7565b8015611e6c5780601f10611e4157610100808354040283529160200191611e6c565b820191906000526020600020905b815481529060010190602001808311611e4f57829003601f168201915b505050505081565b6060611e7e61204b565b611e8783612c4c565b604051602001611e9892919061384f565b6040516020818303038152906040529050919050565b611eb66123f4565b601754600160a81b900460ff1615611ecd57600080fd5b6017805460ff60a81b1916600160a81b179055323314611f2f5760405162461bcd60e51b815260206004820152601e60248201527f5468652063616c6c657220697320616e6f7468657220636f6e747261637400006044820152606401610c86565b6017546040516370a0823160e01b81523060048201526001600160a01b039091169063a9059cbb90339083906370a0823190602401602060405180830381865afa158015611f81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fa5919061387e565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611ff0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113db91906136f5565b60198054611df3906135c7565b6120296123f4565b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b606060198054610b68906135c7565b6040516371d4ed8d60e11b81526001600160a01b0382811660048301526000917f00000000000000000000000089221b906cfab36e7894de3ba9299ed2c6bf1f179091169063e3a9db1a90602401602060405180830381865afa1580156120c5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2f919061387e565b6120f16123f4565b600c8054911515600160a81b0260ff60a81b19909216919091179055565b606060188054610b68906135c7565b600b54600c546000916001600160a01b039081169190811690600160a01b900460ff1680156121c2575060405163c455279160e01b81526001600160a01b038681166004830152808616919084169063c455279190602401602060405180830381865afa158015612193573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121b79190613897565b6001600160a01b0316145b806122565750600c54600160a81b900460ff168015612256575060405163c455279160e01b81526001600160a01b038681166004830152808616919083169063c455279190602401602060405180830381865afa158015612227573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061224b9190613897565b6001600160a01b0316145b8061227957506001600160a01b0384166000908152600d602052604090205460ff165b1561228957600192505050610b2f565b6001600160a01b0380861660009081526005602090815260408083209388168352929052205460ff165b95945050505050565b6122c46123f4565b601780546001600160a01b0319166001600160a01b0392909216919091179055565b6122ee6123f4565b6001600160a01b03919091166000908152600d60205260409020805460ff1916911515919091179055565b6123216123f4565b6001600160a01b0381166123865760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610c86565b611be981612aae565b80546001019055565b60003033036123ee57600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031691506123f19050565b50335b90565b6123fc6124d1565b6001600160a01b03166124176009546001600160a01b031690565b6001600160a01b0316146117585760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610c86565b6000818152600260205260409020546001600160a01b0316611be95760405162461bcd60e51b815260206004820152601860248201527f4552433732313a20696e76616c696420746f6b656e20494400000000000000006044820152606401610c86565b6000611286612398565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906125108261164e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006001600160a01b0386166125af5760405162461bcd60e51b815260206004820152602560248201527f4e61746976654d6574615472616e73616374696f6e3a20494e56414c49445f5360448201526424a3a722a960d91b6064820152608401610c86565b60016125c26125bd87612cec565b612d69565b6040805160008152602081018083529290925260ff851690820152606081018690526080810185905260a0016020604051602081039080840390855afa158015612610573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b60006126458284613696565b9392505050565b611aa8828260405180602001604052806000815250612d99565b6000806126728361164e565b9050806001600160a01b0316846001600160a01b031614806126995750612699818561211e565b806126bd5750836001600160a01b03166126b284610beb565b6001600160a01b0316145b949350505050565b826001600160a01b03166126d88261164e565b6001600160a01b03161461273c5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610c86565b6001600160a01b03821661279e5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610c86565b826001600160a01b03166127b18261164e565b6001600160a01b0316146128155760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610c86565b600081815260046020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260038552838620805460001901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6040516351cff8d960e01b81526001600160a01b0382811660048301527f00000000000000000000000089221b906cfab36e7894de3ba9299ed2c6bf1f1716906351cff8d990602401600060405180830381600087803b15801561290857600080fd5b505af115801561291c573d6000803e3d6000fd5b5050505050565b6001600160a01b0382166129795760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610c86565b6000818152600260205260409020546001600160a01b0316156129de5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c86565b6000818152600260205260409020546001600160a01b031615612a435760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610c86565b6001600160a01b038216600081815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b816001600160a01b0316836001600160a01b031603612b615760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610c86565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612bd98484846126c5565b612be584848484612e17565b611de05760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610c86565b60606000612c5983612f6a565b600101905060008167ffffffffffffffff811115612c7957612c7961313c565b6040519080825280601f01601f191660200182016040528015612ca3576020820181803683370190505b5090508181016020015b600019017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8504945084612cad57509392505050565b600060405180608001604052806043815260200161390e6043913980516020918201208351848301516040808701518051908601209051612d4c950193845260208401929092526001600160a01b03166040830152606082015260800190565b604051602081830303815290604052805190602001209050919050565b6000612d7460075490565b60405161190160f01b6020820152602281019190915260428101839052606201612d4c565b612da38383612923565b612db06000848484612e17565b610d395760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610c86565b60006001600160a01b0384163b15612f5f57836001600160a01b031663150b7a02612e406124d1565b8786866040518563ffffffff1660e01b8152600401612e6294939291906138b4565b6020604051808303816000875af1925050508015612e9d575060408051601f3d908101601f19168201909252612e9a918101906138f0565b60015b612f45573d808015612ecb576040519150601f19603f3d011682016040523d82523d6000602084013e612ed0565b606091505b508051600003612f3d5760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b6064820152608401610c86565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506126bd565b506001949350505050565b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310612fb3577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310612fdf576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310612ffd57662386f26fc10000830492506010015b6305f5e1008310613015576305f5e100830492506008015b612710831061302957612710830492506004015b6064831061303b576064830492506002015b600a8310610b2f5760010192915050565b6001600160e01b031981168114611be957600080fd5b60006020828403121561307457600080fd5b81356126458161304c565b6001600160a01b0381168114611be957600080fd5b600080604083850312156130a757600080fd5b82356130b28161307f565b946020939093013593505050565b60005b838110156130db5781810151838201526020016130c3565b50506000910152565b600081518084526130fc8160208601602086016130c0565b601f01601f19169290920160200192915050565b60208152600061264560208301846130e4565b60006020828403121561313557600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561317b5761317b61313c565b604052919050565b600082601f83011261319457600080fd5b813567ffffffffffffffff8111156131ae576131ae61313c565b6131c1601f8201601f1916602001613152565b8181528460208386010111156131d657600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561320b57600080fd5b85356132168161307f565b9450602086013567ffffffffffffffff81111561323257600080fd5b61323e88828901613183565b9450506040860135925060608601359150608086013560ff8116811461326357600080fd5b809150509295509295909350565b60008060006060848603121561328657600080fd5b83356132918161307f565b925060208401356132a18161307f565b929592945050506040919091013590565b6000602082840312156132c457600080fd5b81356126458161307f565b8015158114611be957600080fd5b6000602082840312156132ef57600080fd5b8135612645816132cf565b6000806020838503121561330d57600080fd5b823567ffffffffffffffff8082111561332557600080fd5b818501915085601f83011261333957600080fd5b81358181111561334857600080fd5b86602082850101111561335a57600080fd5b60209290920196919550909350505050565b6000806040838503121561337f57600080fd5b823561338a8161307f565b9150602083013561339a816132cf565b809150509250929050565b600067ffffffffffffffff8211156133bf576133bf61313c565b5060051b60200190565b600082601f8301126133da57600080fd5b813560206133ef6133ea836133a5565b613152565b82815260059290921b8401810191818101908684111561340e57600080fd5b8286015b848110156134325780356134258161307f565b8352918301918301613412565b509695505050505050565b6000806040838503121561345057600080fd5b823567ffffffffffffffff8082111561346857600080fd5b613474868387016133c9565b935060209150818501358181111561348b57600080fd5b85019050601f8101861361349e57600080fd5b80356134ac6133ea826133a5565b81815260059190911b820183019083810190888311156134cb57600080fd5b928401925b828410156134e9578335825292840192908401906134d0565b80955050505050509250929050565b60006020828403121561350a57600080fd5b813567ffffffffffffffff81111561352157600080fd5b6126bd848285016133c9565b6000806000806080858703121561354357600080fd5b843561354e8161307f565b9350602085013561355e8161307f565b925060408501359150606085013567ffffffffffffffff81111561358157600080fd5b61358d87828801613183565b91505092959194509250565b600080604083850312156135ac57600080fd5b82356135b78161307f565b9150602083013561339a8161307f565b600181811c908216806135db57607f821691505b6020821081036135fb57634e487b7160e01b600052602260045260246000fd5b50919050565b60006001600160a01b038086168352808516602084015250606060408301526122b360608301846130e4565b6000835161363f8184602088016130c0565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b600082516136768184602087016130c0565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b80820180821115610b2f57610b2f613680565b6000826136c657634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610b2f57610b2f613680565b81810381811115610b2f57610b2f613680565b60006020828403121561370757600080fd5b8151612645816132cf565b60006001820161372457613724613680565b5060010190565b601f821115610d3957600081815260208120601f850160051c810160208610156137525750805b601f850160051c820191505b818110156137715782815560010161375e565b505050505050565b67ffffffffffffffff8311156137915761379161313c565b6137a58361379f83546135c7565b8361372b565b6000601f8411600181146137d957600085156137c15750838201355b600019600387901b1c1916600186901b17835561291c565b600083815260209020601f19861690835b8281101561380a57868501358255602094850194600190920191016137ea565b50868210156138275760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b634e487b7160e01b600052603260045260246000fd5b600083516138618184602088016130c0565b8351908301906138758183602088016130c0565b01949350505050565b60006020828403121561389057600080fd5b5051919050565b6000602082840312156138a957600080fd5b81516126458161307f565b60006001600160a01b038087168352808616602084015250836040830152608060608301526138e660808301846130e4565b9695505050505050565b60006020828403121561390257600080fd5b81516126458161304c56fe4d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529a2646970667358221220bfba03cccda0660d5c372fa0dea0a5e9b7525fc2ca795f5e44d3d2c6f7dbf5bb64736f6c63430008120033

Deployed Bytecode Sourcemap

92293:1147:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46180:305;;;;;;;;;;-1:-1:-1;46180:305:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;46180:305:0;;;;;;;;90358:144;;;;;;;;;;-1:-1:-1;90358:144:0;;;;;:::i;:::-;;:::i;:::-;;47108:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;48620:171::-;;;;;;;;;;-1:-1:-1;48620:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2176:55:1;;;2158:74;;2146:2;2131:18;48620:171:0;2012:226:1;48138:416:0;;;;;;;;;;-1:-1:-1;48138:416:0;;;;;:::i;:::-;;:::i;77493:1151::-;;;;;;:::i;:::-;;:::i;74651:43::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;74651:43:0;;;;;81177:33;;;;;;;;;;;;;;;;;;;4322:25:1;;;4310:2;4295:18;81177:33:0;4176:177:1;81144:26:0;;;;;;;;;;;;;;;;85700:1294;;;;;;;;;;-1:-1:-1;85700:1294:0;;;;;:::i;:::-;;:::i;88048:105::-;;;;;;;;;;;;;:::i;75660:101::-;;;;;;;;;;-1:-1:-1;75738:15:0;;75660:101;;87128:98;;;;;;;;;;-1:-1:-1;87128:98:0;;;;;:::i;:::-;;:::i;49320:301::-;;;;;;;;;;-1:-1:-1;49320:301:0;;;;;:::i;:::-;;:::i;81328:44::-;;;;;;;;;;-1:-1:-1;81328:44:0;;;;;:::i;:::-;;;;;;;;;;;;;;81217:30;;;;;;;;;;;;;;;;79070:107;;;;;;;;;;-1:-1:-1;79070:107:0;;;;;:::i;:::-;-1:-1:-1;;;;;79157:12:0;79123:13;79157:12;;;:6;:12;;;;;;;79070:107;88787:146;;;;;;;;;;-1:-1:-1;88787:146:0;;;;;:::i;:::-;;:::i;93064:125::-;;;;;;;;;;-1:-1:-1;93064:125:0;;;;;:::i;:::-;;:::i;91278:147::-;;;;;;;;;;-1:-1:-1;91278:147:0;;;;;:::i;:::-;;:::i;75769:161::-;;;;;;;;;;-1:-1:-1;75883:9:0;75769:161;;87504:108;;;;;;;;;;-1:-1:-1;87504:108:0;;;;;:::i;:::-;;:::i;87618:111::-;;;;;;;;;;-1:-1:-1;87618:111:0;;;;;:::i;:::-;;:::i;81256:30::-;;;;;;;;;;;;;;;;49692:151;;;;;;;;;;-1:-1:-1;49692:151:0;;;;;:::i;:::-;;:::i;82995:574::-;;;;;;;;;;-1:-1:-1;82995:574:0;;;;;:::i;:::-;;:::i;87737:138::-;;;;;;;;;;;;;:::i;88638:141::-;;;;;;;;;;-1:-1:-1;88638:141:0;;;;;:::i;:::-;;:::i;81048:25::-;;;;;;;;;;;;;;;;46818:223;;;;;;;;;;-1:-1:-1;46818:223:0;;;;;:::i;:::-;;:::i;87020:100::-;;;;;;;;;;-1:-1:-1;87020:100:0;;;;;:::i;:::-;;:::i;46549:207::-;;;;;;;;;;-1:-1:-1;46549:207:0;;;;;:::i;:::-;;:::i;2877:103::-;;;;;;;;;;;;;:::i;82897:86::-;;;;;;;;;;-1:-1:-1;82966:9:0;;-1:-1:-1;;;82966:9:0;;;;82897:86;;81080:26;;;;;;;;;;;;;;;;82800:89;;;;;;;;;;;;;:::i;87236:128::-;;;;;;;;;;;;;:::i;91113:153::-;;;;;;;;;;-1:-1:-1;91113:153:0;;;;;:::i;:::-;;:::i;2236:87::-;;;;;;;;;;-1:-1:-1;2309:6:0;;-1:-1:-1;;;;;2309:6:0;2236:87;;93203:121;;;;;;;;;;-1:-1:-1;93203:121:0;;;;;:::i;:::-;;:::i;47277:104::-;;;;;;;;;;;;;:::i;81381:26::-;;;;;;;;;;-1:-1:-1;81381:26:0;;;;-1:-1:-1;;;;;81381:26:0;;;83577:2111;;;;;;:::i;:::-;;:::i;48863:155::-;;;;;;;;;;-1:-1:-1;48863:155:0;;;;;:::i;:::-;;:::i;90510:386::-;;;;;;;;;;-1:-1:-1;90510:386:0;;;;;:::i;:::-;;:::i;90904:201::-;;;;;;;;;;-1:-1:-1;90904:201:0;;;;;:::i;:::-;;:::i;49914:279::-;;;;;;;;;;-1:-1:-1;49914:279:0;;;;;:::i;:::-;;:::i;92344:129::-;;;;;;;;;;;;;:::i;88309:175::-;;;;;;;;;;-1:-1:-1;88309:175:0;;;;;:::i;:::-;;:::i;81293:26::-;;;;;;;;;;;;;;;;91433:157;;;;;;;;;;;;;:::i;92480:99::-;;;;;;;;;;;;;:::i;88492:138::-;;;;;;;;;;-1:-1:-1;88492:138:0;;;;;:::i;:::-;;:::i;92948:108::-;;;;;;;;;;;;;:::i;81113:24::-;;;;;;;;;;;;;;;;17905:112;;;;;;;;;;-1:-1:-1;17905:112:0;;;;;:::i;:::-;;:::i;88941:146::-;;;;;;;;;;-1:-1:-1;88941:146:0;;;;;:::i;:::-;;:::i;93334:97::-;;;;;;;;;;;;;:::i;89362:671::-;;;;;;;;;;-1:-1:-1;89362:671:0;;;;;:::i;:::-;;:::i;87374:122::-;;;;;;;;;;-1:-1:-1;87374:122:0;;;;;:::i;:::-;;:::i;89096:142::-;;;;;;;;;;-1:-1:-1;89096:142:0;;;;;:::i;:::-;;:::i;3135:201::-;;;;;;;;;;-1:-1:-1;3135:201:0;;;;;:::i;:::-;;:::i;46180:305::-;46282:4;-1:-1:-1;;;;;;46319:40:0;;-1:-1:-1;;;46319:40:0;;:105;;-1:-1:-1;;;;;;;46376:48:0;;-1:-1:-1;;;46376:48:0;46319:105;:158;;;-1:-1:-1;;;;;;;;;;27368:40:0;;;46441:36;46299:178;46180:305;-1:-1:-1;;46180:305:0:o;90358:144::-;2122:13;:11;:13::i;:::-;-1:-1:-1;;;;;90455:19:0;;::::1;;::::0;;;:9:::1;:19;::::0;;;;:39;90358:144::o;47108:100::-;47162:13;47195:5;47188:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47108:100;:::o;48620:171::-;48696:7;48716:23;48731:7;48716:14;:23::i;:::-;-1:-1:-1;48759:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;48759:24:0;;48620:171::o;48138:416::-;48219:13;48235:23;48250:7;48235:14;:23::i;:::-;48219:39;;48283:5;-1:-1:-1;;;;;48277:11:0;:2;-1:-1:-1;;;;;48277:11:0;;48269:57;;;;-1:-1:-1;;;48269:57:0;;11188:2:1;48269:57:0;;;11170:21:1;11227:2;11207:18;;;11200:30;11266:34;11246:18;;;11239:62;-1:-1:-1;;;11317:18:1;;;11310:31;11358:19;;48269:57:0;;;;;;;;;48377:5;-1:-1:-1;;;;;48361:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;48361:21:0;;:62;;;;48386:37;48403:5;48410:12;:10;:12::i;48386:37::-;48339:173;;;;-1:-1:-1;;;48339:173:0;;11590:2:1;48339:173:0;;;11572:21:1;11629:2;11609:18;;;11602:30;11668:34;11648:18;;;11641:62;11739:31;11719:18;;;11712:59;11788:19;;48339:173:0;11388:425:1;48339:173:0;48525:21;48534:2;48538:7;48525:8;:21::i;:::-;48208:346;48138:416;;:::o;77493:1151::-;77751:152;;;77694:12;77751:152;;;;;-1:-1:-1;;;;;77789:19:0;;77719:29;77789:19;;;:6;:19;;;;;;;;;77751:152;;;;;;;;;;;77938:45;77796:11;77751:152;77966:4;77972;77978;77938:6;:45::i;:::-;77916:128;;;;-1:-1:-1;;;77916:128:0;;12020:2:1;77916:128:0;;;12002:21:1;12059:2;12039:18;;;12032:30;12098:34;12078:18;;;12071:62;-1:-1:-1;;;12149:18:1;;;12142:31;12190:19;;77916:128:0;11818:397:1;77916:128:0;-1:-1:-1;;;;;78133:19:0;;;;;;:6;:19;;;;;;:26;;78157:1;78133:23;:26::i;:::-;-1:-1:-1;;;;;78111:19:0;;;;;;:6;:19;;;;;;;:48;;;;78177:126;;;;;78118:11;;78249:10;;78275:17;;78177:126;:::i;:::-;;;;;;;;78414:12;78428:23;78463:4;-1:-1:-1;;;;;78455:18:0;78505:17;78524:11;78488:48;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;78488:48:0;;;;;;;;;;78455:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78413:134;;;;78566:7;78558:48;;;;-1:-1:-1;;;78558:48:0;;13607:2:1;78558:48:0;;;13589:21:1;13646:2;13626:18;;;13619:30;13685;13665:18;;;13658:58;13733:18;;78558:48:0;13405:352:1;78558:48:0;78626:10;77493:1151;-1:-1:-1;;;;;;;;77493:1151:0:o;85700:1294::-;81516:9;;-1:-1:-1;;;81516:9:0;;;;81515:10;81507:19;;;;;;81534:9;:16;;-1:-1:-1;;;;81534:16:0;-1:-1:-1;;;81534:16:0;;;81636:9:::1;81649:10;81636:23;81628:66;;;::::0;-1:-1:-1;;;81628:66:0;;13964:2:1;81628:66:0::1;::::0;::::1;13946:21:1::0;14003:2;13983:18;;;13976:30;14042:32;14022:18;;;14015:60;14092:18;;81628:66:0::1;13762:354:1::0;81628:66:0::1;85789:16:::2;::::0;-1:-1:-1;;;85789:16:0;::::2;;;:24;;85809:4;85789:24;85781:77;;;::::0;-1:-1:-1;;;85781:77:0;;14323:2:1;85781:77:0::2;::::0;::::2;14305:21:1::0;14362:2;14342:18;;;14335:30;14401:34;14381:18;;;14374:62;-1:-1:-1;;;14452:18:1;;;14445:38;14500:19;;85781:77:0::2;14121:404:1::0;85781:77:0::2;85887:1;85878:6;:10;85869:70;;;::::0;-1:-1:-1;;;85869:70:0;;14732:2:1;85869:70:0::2;::::0;::::2;14714:21:1::0;14771:2;14751:18;;;14744:30;14810:34;14790:18;;;14783:62;14881:16;14861:18;;;14854:44;14915:19;;85869:70:0::2;14530:410:1::0;85869:70:0::2;85982:9;::::0;:11:::2;::::0;85992:1:::2;85982:11;:::i;:::-;85973:6;85958:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:35;85950:70;;;::::0;-1:-1:-1;;;85950:70:0;;15409:2:1;85950:70:0::2;::::0;::::2;15391:21:1::0;15448:2;15428:18;;;15421:30;15487:24;15467:18;;;15460:52;15529:18;;85950:70:0::2;15207:346:1::0;85950:70:0::2;86159:18;86230:11;;86214:13;:11;:13::i;:::-;:27;;;;:::i;:::-;86209:33;::::0;:1:::2;:33;:::i;:::-;86190:15;;:53;;;;:::i;:::-;86180:64;::::0;:6;:64:::2;:::i;:::-;86159:85;;86292:18;;86278:11;;:32;;;;:::i;:::-;86269:6;:41;86265:388;;;86638:3;86617:18;;86600:15;;86579:18;;86565:11;;:32;;;;:::i;:::-;86555:43;::::0;:6;:43:::2;:::i;:::-;86554:61;;;;:::i;:::-;86553:82;;;;:::i;:::-;86549:86;::::0;:3:::2;:86;:::i;:::-;86535:101;::::0;:10;:101:::2;:::i;:::-;86534:107;;;;:::i;:::-;86521:120;;86265:388;86665:12;::::0;:64:::2;::::0;-1:-1:-1;;;86665:64:0;;86691:10:::2;86665:64;::::0;::::2;16481:34:1::0;86711:4:0::2;16531:18:1::0;;;16524:43;16583:18;;;16576:34;;;-1:-1:-1;;;;;86665:12:0;;::::2;::::0;:25:::2;::::0;16393:18:1;;86665:64:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;86748:9;86744:243;86767:6;86763:1;:10;86744:243;;;86800:22;86825;:12;65858:14:::0;;65766:114;86825:22:::2;86800:47;;86858:24;:12;65977:19:::0;;65995:1;65977:19;;;65888:127;86858:24:::2;86893:37;86903:10;86915:14;86893:9;:37::i;:::-;-1:-1:-1::0;86775:3:0;::::2;::::0;::::2;:::i;:::-;;;;86744:243;;;-1:-1:-1::0;;81569:9:0;:16;;-1:-1:-1;;;;81569:16:0;;;-1:-1:-1;85700:1294:0:o;88048:105::-;88092:7;88144:1;88119:22;:12;65858:14;;65766:114;88119:22;:26;;;;:::i;:::-;88112:33;;88048:105;:::o;87128:98::-;2122:13;:11;:13::i;:::-;87198:10:::1;:20:::0;87128:98::o;49320:301::-;49481:41;49500:12;:10;:12::i;:::-;49514:7;49481:18;:41::i;:::-;49473:99;;;;-1:-1:-1;;;49473:99:0;;17213:2:1;49473:99:0;;;17195:21:1;17252:2;17232:18;;;17225:30;17291:34;17271:18;;;17264:62;-1:-1:-1;;;17342:18:1;;;17335:43;17395:19;;49473:99:0;17011:409:1;49473:99:0;49585:28;49595:4;49601:2;49605:7;49585:9;:28::i;88787:146::-;2122:13;:11;:13::i;:::-;88878:23:::1;:47:::0;;;::::1;;-1:-1:-1::0;;;88878:47:0::1;-1:-1:-1::0;;;;88878:47:0;;::::1;::::0;;;::::1;::::0;;88787:146::o;93064:125::-;2122:13;:11;:13::i;:::-;93150::::1;:31;93166:15:::0;;93150:13;:31:::1;:::i;91278:147::-:0;2122:13;:11;:13::i;:::-;81636:9:::1;81649:10;81636:23;81628:66;;;::::0;-1:-1:-1;;;81628:66:0;;13964:2:1;81628:66:0::1;::::0;::::1;13946:21:1::0;14003:2;13983:18;;;13976:30;14042:32;14022:18;;;14015:60;14092:18;;81628:66:0::1;13762:354:1::0;81628:66:0::1;81516:9:::2;::::0;-1:-1:-1;;;81516:9:0;::::2;;;81515:10;81507:19;;;::::0;::::2;;81534:9;:16:::0;;-1:-1:-1;;;;81534:16:0::2;-1:-1:-1::0;;;81534:16:0::2;::::0;;91388:29:::3;91411:5:::0;91388:22:::3;:29::i;:::-;-1:-1:-1::0;81569:9:0::2;:16:::0;;-1:-1:-1;;;;81569:16:0::2;::::0;;91278:147::o;87504:108::-;2122:13;:11;:13::i;:::-;87579:15:::1;:25:::0;87504:108::o;87618:111::-;2122:13;:11;:13::i;:::-;87693:16:::1;:28:::0;;;::::1;;-1:-1:-1::0;;;87693:28:0::1;-1:-1:-1::0;;;;87693:28:0;;::::1;::::0;;;::::1;::::0;;87618:111::o;49692:151::-;49796:39;49813:4;49819:2;49823:7;49796:39;;;;;;;;;;;;:16;:39::i;82995:574::-;2122:13;:11;:13::i;:::-;81636:9:::1;81649:10;81636:23;81628:66;;;::::0;-1:-1:-1;;;81628:66:0;;13964:2:1;81628:66:0::1;::::0;::::1;13946:21:1::0;14003:2;13983:18;;;13976:30;14042:32;14022:18;;;14015:60;14092:18;;81628:66:0::1;13762:354:1::0;81628:66:0::1;83114:9:::2;::::0;:11:::2;::::0;83124:1:::2;83114:11;:::i;:::-;83105:6;83089:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:36;83081:105;;;::::0;-1:-1:-1;;;83081:105:0;;19685:2:1;83081:105:0::2;::::0;::::2;19667:21:1::0;19724:2;19704:18;;;19697:30;19763:34;19743:18;;;19736:62;19834:26;19814:18;;;19807:54;19878:19;;83081:105:0::2;19483:420:1::0;83081:105:0::2;83214:1;83205:6;:10;:38;;;;-1:-1:-1::0;83228:11:0::2;::::0;:15:::2;::::0;83242:1:::2;83228:15;:::i;:::-;83219:6;:24;83205:38;83197:110;;;::::0;-1:-1:-1;;;83197:110:0;;20110:2:1;83197:110:0::2;::::0;::::2;20092:21:1::0;20149:2;20129:18;;;20122:30;20188:34;20168:18;;;20161:62;20259:29;20239:18;;;20232:57;20306:19;;83197:110:0::2;19908:423:1::0;83197:110:0::2;83330:9;83326:236;83349:6;83345:1;:10;83326:236;;;83376:22;83401;:12;65858:14:::0;;65766:114;83401:22:::2;83376:47;;83438:24;:12;65977:19:::0;;65995:1;65977:19;;;65888:127;83438:24:::2;83524:26;83530:3;83535:14;83524:5;:26::i;:::-;-1:-1:-1::0;83357:3:0;::::2;::::0;::::2;:::i;:::-;;;;83326:236;;87737:138:::0;87789:7;87854:11;;87838:13;:11;:13::i;:::-;:27;;;;:::i;:::-;87833:33;;:1;:33;:::i;:::-;87814:15;;:53;;;;:::i;88638:141::-;2122:13;:11;:13::i;:::-;88725:21:::1;:46:::0;;-1:-1:-1;;;;;;88725:46:0::1;-1:-1:-1::0;;;;;88725:46:0;;;::::1;::::0;;;::::1;::::0;;88638:141::o;46818:223::-;46890:7;51551:16;;;:7;:16;;;;;;-1:-1:-1;;;;;51551:16:0;;46954:56;;;;-1:-1:-1;;;46954:56:0;;20538:2:1;46954:56:0;;;20520:21:1;20577:2;20557:18;;;20550:30;20616:26;20596:18;;;20589:54;20660:18;;46954:56:0;20336:348:1;87020:100:0;2122:13;:11;:13::i;:::-;87091:11:::1;:21:::0;87020:100::o;46549:207::-;46621:7;-1:-1:-1;;;;;46649:19:0;;46641:73;;;;-1:-1:-1;;;46641:73:0;;20891:2:1;46641:73:0;;;20873:21:1;20930:2;20910:18;;;20903:30;20969:34;20949:18;;;20942:62;-1:-1:-1;;;21020:18:1;;;21013:39;21069:19;;46641:73:0;20689:405:1;46641:73:0;-1:-1:-1;;;;;;46732:16:0;;;;;:9;:16;;;;;;;46549:207::o;2877:103::-;2122:13;:11;:13::i;:::-;2942:30:::1;2969:1;2942:18;:30::i;:::-;2877:103::o:0;82800:89::-;2122:13;:11;:13::i;:::-;81516:9:::1;::::0;-1:-1:-1;;;81516:9:0;::::1;;;81515:10;81507:19;;;::::0;::::1;;81534:9;:16:::0;;-1:-1:-1;;;;81534:16:0::1;82864:17:::0;;82800:89::o;87236:128::-;87283:7;87343:11;;87327:13;:11;:13::i;:::-;:27;;;;:::i;:::-;87322:33;;:1;:33;:::i;:::-;87308:10;;:48;;;;:::i;91113:153::-;-1:-1:-1;;;;;91194:14:0;;91172:7;91194:14;;;:9;:14;;;;;;:18;91190:68;;-1:-1:-1;;;;;;91221:14:0;;;;;:9;:14;;;;;;;91113:153::o;91190:68::-;-1:-1:-1;91257:1:0;;91113:153;-1:-1:-1;91113:153:0:o;93203:121::-;2122:13;:11;:13::i;:::-;93287:12:::1;:29;93302:14:::0;;93287:12;:29:::1;:::i;47277:104::-:0;47333:13;47366:7;47359:14;;;;;:::i;83577:2111::-;81636:9;81649:10;81636:23;81628:66;;;;-1:-1:-1;;;81628:66:0;;13964:2:1;81628:66:0;;;13946:21:1;14003:2;13983:18;;;13976:30;14042:32;14022:18;;;14015:60;14092:18;;81628:66:0;13762:354:1;81628:66:0;83681:9:::1;::::0;:13:::1;::::0;83693:1:::1;83681:13;:::i;:::-;83672:6;83656:13;:11;:13::i;:::-;:22;;;;:::i;:::-;:38;83648:101;;;::::0;-1:-1:-1;;;83648:101:0;;21301:2:1;83648:101:0::1;::::0;::::1;21283:21:1::0;21340:2;21320:18;;;21313:30;21379:34;21359:18;;;21352:62;21450:20;21430:18;;;21423:48;21488:19;;83648:101:0::1;21099:414:1::0;83648:101:0::1;83777:1;83768:6;:10;:38;;;;-1:-1:-1::0;83791:11:0::1;::::0;:15:::1;::::0;83805:1:::1;83791:15;:::i;:::-;83782:6;:24;83768:38;83760:110;;;::::0;-1:-1:-1;;;83760:110:0;;20110:2:1;83760:110:0::1;::::0;::::1;20092:21:1::0;20149:2;20129:18;;;20122:30;20188:34;20168:18;;;20161:62;20259:29;20239:18;;;20232:57;20306:19;;83760:110:0::1;19908:423:1::0;83760:110:0::1;83897:10;83911:1;83887:21:::0;;;:9:::1;:21;::::0;;;;;:25;;;;:62:::1;;-1:-1:-1::0;83926:10:0::1;83916:21;::::0;;;:9:::1;:21;::::0;;;;;83943:6;;83916:24:::1;::::0;83939:1:::1;83916:24;:::i;:::-;:33;83887:62;83883:1798;;;84013:6;83999:11;;:20;;;;:::i;:::-;83986:9;:33;;:68;;;;;84048:6;84035:10;;:19;;;;:::i;:::-;84023:9;:31;83986:68;83978:106;;;::::0;-1:-1:-1;;;83978:106:0;;21720:2:1;83978:106:0::1;::::0;::::1;21702:21:1::0;21759:2;21739:18;;;21732:30;21798:27;21778:18;;;21771:55;21843:18;;83978:106:0::1;21518:349:1::0;83978:106:0::1;84109:10;84099:21;::::0;;;:9:::1;:21;::::0;;;;:31;;84124:6;;84099:21;:31:::1;::::0;84124:6;;84099:31:::1;:::i;:::-;::::0;;;-1:-1:-1;84163:9:0::1;::::0;-1:-1:-1;84159:212:0::1;84182:6;84178:1;:10;84159:212;;;84213:22;84238;:12;65858:14:::0;;65766:114;84238:22:::1;84213:47;;84279:24;:12;65977:19:::0;;65995:1;65977:19;;;65888:127;84279:24:::1;84322:33;84328:10;84340:14;84322:5;:33::i;:::-;-1:-1:-1::0;84190:3:0;::::1;::::0;::::1;:::i;:::-;;;;84159:212;;;;83577:2111:::0;:::o;83883:1798::-:1;84687:18;84753:11;;84737:13;:11;:13::i;:::-;:27;;;;:::i;:::-;84732:33;::::0;:1:::1;:33;:::i;:::-;84718:10;;:48;;;;:::i;:::-;84708:59;::::0;:6;:59:::1;:::i;:::-;84687:80;;84811:18;;84797:11;;:32;;;;:::i;:::-;84788:6;:41;84784:408;;;85173:3;85152:18;;85135:15;;85114:18;;85100:11;;:32;;;;:::i;:::-;85090:43;::::0;:6;:43:::1;:::i;:::-;85089:61;;;;:::i;:::-;85088:82;;;;:::i;:::-;85084:86;::::0;:3:::1;:86;:::i;:::-;85070:101;::::0;:10;:101:::1;:::i;:::-;85069:107;;;;:::i;:::-;85056:120;;84784:408;85383:10;85370:9;:23;;85362:67;;;::::0;-1:-1:-1;;;85362:67:0;;22074:2:1;85362:67:0::1;::::0;::::1;22056:21:1::0;22113:2;22093:18;;;22086:30;22152:33;22132:18;;;22125:61;22203:18;;85362:67:0::1;21872:355:1::0;85362:67:0::1;85462:9;85458:212;85481:6;85477:1;:10;85458:212;;;85512:22;85537;:12;65858:14:::0;;65766:114;85537:22:::1;85512:47;;85578:24;:12;65977:19:::0;;65995:1;65977:19;;;65888:127;85578:24:::1;85621:33;85627:10;85639:14;85621:5;:33::i;:::-;-1:-1:-1::0;85489:3:0;::::1;::::0;::::1;:::i;:::-;;;;85458:212;;83883:1798;83577:2111:::0;:::o;48863:155::-;48958:52;48977:12;:10;:12::i;:::-;48991:8;49001;48958:18;:52::i;90510:386::-;2122:13;:11;:13::i;:::-;90662:17:::1;:24;90641:10;:17;:45;90633:121;;;::::0;-1:-1:-1;;;90633:121:0;;22434:2:1;90633:121:0::1;::::0;::::1;22416:21:1::0;22473:2;22453:18;;;22446:30;22512:34;22492:18;;;22485:62;22583:33;22563:18;;;22556:61;22634:19;;90633:121:0::1;22232:427:1::0;90633:121:0::1;90772:9;90767:122;90791:10;:17;90787:1;:21;90767:122;;;90857:17;90875:1;90857:20;;;;;;;;:::i;:::-;;;;;;;90830:9;:24;90840:10;90851:1;90840:13;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;90830:24:0::1;-1:-1:-1::0;;;;;90830:24:0::1;;;;;;;;;;;;:47;;;;90810:3;;;;;:::i;:::-;;;;90767:122;;90904:201:::0;2122:13;:11;:13::i;:::-;90997:9:::1;90992:106;91016:10;:17;91012:1;:21;90992:106;;;91062:9;:24;91072:10;91083:1;91072:13;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;91062:24:0::1;-1:-1:-1::0;;;;;91062:24:0::1;;;;;;;;;;;;91055:31;;;91035:3;;;;;:::i;:::-;;;;90992:106;;49914:279:::0;50045:41;50064:12;:10;:12::i;:::-;50078:7;50045:18;:41::i;:::-;50037:99;;;;-1:-1:-1;;;50037:99:0;;17213:2:1;50037:99:0;;;17195:21:1;17252:2;17232:18;;;17225:30;17291:34;17271:18;;;17264:62;-1:-1:-1;;;17342:18:1;;;17335:43;17395:19;;50037:99:0;17011:409:1;50037:99:0;50147:38;50161:4;50167:2;50171:7;50180:4;50147:13;:38::i;:::-;49914:279;;;;:::o;92344:129::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;88309:175::-;88375:13;88432:14;:12;:14::i;:::-;88448:26;88465:8;88448:16;:26::i;:::-;88415:60;;;;;;;;;:::i;:::-;;;;;;;;;;;;;88401:75;;88309:175;;;:::o;91433:157::-;2122:13;:11;:13::i;:::-;81516:9:::1;::::0;-1:-1:-1;;;81516:9:0;::::1;;;81515:10;81507:19;;;::::0;::::1;;81534:9;:16:::0;;-1:-1:-1;;;;81534:16:0::1;-1:-1:-1::0;;;81534:16:0::1;::::0;;81636:9:::2;81649:10;81636:23;81628:66;;;::::0;-1:-1:-1;;;81628:66:0;;13964:2:1;81628:66:0::2;::::0;::::2;13946:21:1::0;14003:2;13983:18;;;13976:30;14042:32;14022:18;;;14015:60;14092:18;;81628:66:0::2;13762:354:1::0;81628:66:0::2;91510:12:::3;::::0;91544:37:::3;::::0;-1:-1:-1;;;91544:37:0;;91575:4:::3;91544:37;::::0;::::3;2158:74:1::0;-1:-1:-1;;;;;91510:12:0;;::::3;::::0;:21:::3;::::0;91532:10:::3;::::0;91510:12;;91544:22:::3;::::0;2131:18:1;;91544:37:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91510:72;::::0;-1:-1:-1;;;;;;91510:72:0::3;::::0;;;;;;-1:-1:-1;;;;;23678:55:1;;;91510:72:0::3;::::0;::::3;23660:74:1::0;23750:18;;;23743:34;23633:18;;91510:72:0::3;;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;92480:99::-:0;;;;;;;:::i;88492:138::-;2122:13;:11;:13::i;:::-;88578:20:::1;:44:::0;;-1:-1:-1;;;;;;88578:44:0::1;-1:-1:-1::0;;;;;88578:44:0;;;::::1;::::0;;;::::1;::::0;;88492:138::o;92948:108::-;93002:13;93035;93028:20;;;;;:::i;17905:112::-;17985:24;;-1:-1:-1;;;17985:24:0;;-1:-1:-1;;;;;2176:55:1;;;17985:24:0;;;2158:74:1;17958:7:0;;17985;:18;;;;;;2131::1;;17985:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;88941:146::-;2122:13;:11;:13::i;:::-;89032:23:::1;:47:::0;;;::::1;;-1:-1:-1::0;;;89032:47:0::1;-1:-1:-1::0;;;;89032:47:0;;::::1;::::0;;;::::1;::::0;;88941:146::o;93334:97::-;93378:13;93411:12;93404:19;;;;;:::i;89362:671::-;89608:20;;89685:21;;89484:4;;-1:-1:-1;;;;;89608:20:0;;;;89685:21;;;;-1:-1:-1;;;89723:23:0;;;;:79;;;;-1:-1:-1;89759:28:0;;-1:-1:-1;;;89759:28:0;;-1:-1:-1;;;;;2176:55:1;;;89759:28:0;;;2158:74:1;89751:49:0;;;;89759:21;;;;;;2131:18:1;;89759:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;89751:49:0;;89723:79;:166;;;-1:-1:-1;89810:23:0;;-1:-1:-1;;;89810:23:0;;;;:77;;;;-1:-1:-1;89845:29:0;;-1:-1:-1;;;89845:29:0;;-1:-1:-1;;;;;2176:55:1;;;89845:29:0;;;2158:74:1;89837:50:0;;;;89845:22;;;;;;2131:18:1;;89845:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;89837:50:0;;89810:77;89722:205;;;-1:-1:-1;;;;;;89897:30:0;;;;;;:20;:30;;;;;;;;89722:205;89718:249;;;89951:4;89944:11;;;;;;89718:249;-1:-1:-1;;;;;49210:25:0;;;49186:4;49210:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;89986:39;89979:46;89362:671;-1:-1:-1;;;;;89362:671:0:o;87374:122::-;2122:13;:11;:13::i;:::-;87454:12:::1;:34:::0;;-1:-1:-1;;;;;;87454:34:0::1;-1:-1:-1::0;;;;;87454:34:0;;;::::1;::::0;;;::::1;::::0;;87374:122::o;89096:142::-;2122:13;:11;:13::i;:::-;-1:-1:-1;;;;;89185:34:0;;;::::1;;::::0;;;:20:::1;:34;::::0;;;;:45;;-1:-1:-1;;89185:45:0::1;::::0;::::1;;::::0;;;::::1;::::0;;89096:142::o;3135:201::-;2122:13;:11;:13::i;:::-;-1:-1:-1;;;;;3224:22:0;::::1;3216:73;;;::::0;-1:-1:-1;;;3216:73:0;;24275:2:1;3216:73:0::1;::::0;::::1;24257:21:1::0;24314:2;24294:18;;;24287:30;24353:34;24333:18;;;24326:62;-1:-1:-1;;;24404:18:1;;;24397:36;24450:19;;3216:73:0::1;24073:402:1::0;3216:73:0::1;3300:28;3319:8;3300:18;:28::i;65888:127::-:0;65977:19;;65995:1;65977:19;;;65888:127::o;73440:650::-;73511:22;73577:4;73555:10;:27;73551:508;;73599:18;73620:8;;73599:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;73659:8:0;73870:17;73864:24;-1:-1:-1;;;;;73838:134:0;;-1:-1:-1;73551:508:0;;-1:-1:-1;73551:508:0;;-1:-1:-1;74036:10:0;73551:508;73440:650;:::o;2401:132::-;2476:12;:10;:12::i;:::-;-1:-1:-1;;;;;2465:23:0;:7;2309:6;;-1:-1:-1;;;;;2309:6:0;;2236:87;2465:7;-1:-1:-1;;;;;2465:23:0;;2457:68;;;;-1:-1:-1;;;2457:68:0;;24682:2:1;2457:68:0;;;24664:21:1;;;24701:18;;;24694:30;24760:34;24740:18;;;24733:62;24812:18;;2457:68:0;24480:356:1;58183:135:0;51953:4;51551:16;;;:7;:16;;;;;;-1:-1:-1;;;;;51551:16:0;58257:53;;;;-1:-1:-1;;;58257:53:0;;20538:2:1;58257:53:0;;;20520:21:1;20577:2;20557:18;;;20550:30;20616:26;20596:18;;;20589:54;20660:18;;58257:53:0;20336:348:1;90181:161:0;90271:14;90310:24;:22;:24::i;57496:174::-;57571:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;57571:29:0;-1:-1:-1;;;;;57571:29:0;;;;;;;;:24;;57625:23;57571:24;57625:14;:23::i;:::-;-1:-1:-1;;;;;57616:46:0;;;;;;;;;;;57496:174;;:::o;79185:486::-;79363:4;-1:-1:-1;;;;;79388:20:0;;79380:70;;;;-1:-1:-1;;;79380:70:0;;25043:2:1;79380:70:0;;;25025:21:1;25082:2;25062:18;;;25055:30;25121:34;25101:18;;;25094:62;-1:-1:-1;;;25172:18:1;;;25165:35;25217:19;;79380:70:0;24841:401:1;79380:70:0;79504:159;79532:47;79551:27;79571:6;79551:19;:27::i;:::-;79532:18;:47::i;:::-;79504:159;;;;;;;;;;;;25474:25:1;;;;25547:4;25535:17;;25515:18;;;25508:45;25569:18;;;25562:34;;;25612:18;;;25605:34;;;25446:19;;79504:159:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;79481:182:0;:6;-1:-1:-1;;;;;79481:182:0;;79461:202;;79185:486;;;;;;;:::o;69243:98::-;69301:7;69328:5;69332:1;69328;:5;:::i;:::-;69321:12;69243:98;-1:-1:-1;;;69243:98:0:o;52789:110::-;52865:26;52875:2;52879:7;52865:26;;;;;;;;;;;;:9;:26::i;52183:264::-;52276:4;52293:13;52309:23;52324:7;52309:14;:23::i;:::-;52293:39;;52362:5;-1:-1:-1;;;;;52351:16:0;:7;-1:-1:-1;;;;;52351:16:0;;:52;;;;52371:32;52388:5;52395:7;52371:16;:32::i;:::-;52351:87;;;;52431:7;-1:-1:-1;;;;;52407:31:0;:20;52419:7;52407:11;:20::i;:::-;-1:-1:-1;;;;;52407:31:0;;52351:87;52343:96;52183:264;-1:-1:-1;;;;52183:264:0:o;56148:1229::-;56273:4;-1:-1:-1;;;;;56246:31:0;:23;56261:7;56246:14;:23::i;:::-;-1:-1:-1;;;;;56246:31:0;;56238:81;;;;-1:-1:-1;;;56238:81:0;;25852:2:1;56238:81:0;;;25834:21:1;25891:2;25871:18;;;25864:30;25930:34;25910:18;;;25903:62;-1:-1:-1;;;25981:18:1;;;25974:35;26026:19;;56238:81:0;25650:401:1;56238:81:0;-1:-1:-1;;;;;56338:16:0;;56330:65;;;;-1:-1:-1;;;56330:65:0;;26258:2:1;56330:65:0;;;26240:21:1;26297:2;26277:18;;;26270:30;26336:34;26316:18;;;26309:62;-1:-1:-1;;;26387:18:1;;;26380:34;26431:19;;56330:65:0;26056:400:1;56330:65:0;56580:4;-1:-1:-1;;;;;56553:31:0;:23;56568:7;56553:14;:23::i;:::-;-1:-1:-1;;;;;56553:31:0;;56545:81;;;;-1:-1:-1;;;56545:81:0;;25852:2:1;56545:81:0;;;25834:21:1;25891:2;25871:18;;;25864:30;25930:34;25910:18;;;25903:62;-1:-1:-1;;;25981:18:1;;;25974:35;26026:19;;56545:81:0;25650:401:1;56545:81:0;56698:24;;;;:15;:24;;;;;;;;56691:31;;-1:-1:-1;;;;;;56691:31:0;;;;;;-1:-1:-1;;;;;57174:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;57174:20:0;;;57209:13;;;;;;;;;:18;;56691:31;57209:18;;;57249:16;;;:7;:16;;;;;;:21;;;;;;;;;;57288:27;;56714:7;;57288:27;;;48208:346;48138:416;;:::o;17675:106::-;17750:23;;-1:-1:-1;;;17750:23:0;;-1:-1:-1;;;;;2176:55:1;;;17750:23:0;;;2158:74:1;17750:7:0;:16;;;;2131:18:1;;17750:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17675:106;:::o;53747:942::-;-1:-1:-1;;;;;53827:16:0;;53819:61;;;;-1:-1:-1;;;53819:61:0;;26910:2:1;53819:61:0;;;26892:21:1;;;26929:18;;;26922:30;26988:34;26968:18;;;26961:62;27040:18;;53819:61:0;26708:356:1;53819:61:0;51953:4;51551:16;;;:7;:16;;;;;;-1:-1:-1;;;;;51551:16:0;51977:31;53891:58;;;;-1:-1:-1;;;53891:58:0;;27271:2:1;53891:58:0;;;27253:21:1;27310:2;27290:18;;;27283:30;27349;27329:18;;;27322:58;27397:18;;53891:58:0;27069:352:1;53891:58:0;51953:4;51551:16;;;:7;:16;;;;;;-1:-1:-1;;;;;51551:16:0;51977:31;54100:58;;;;-1:-1:-1;;;54100:58:0;;27271:2:1;54100:58:0;;;27253:21:1;27310:2;27290:18;;;27283:30;27349;27329:18;;;27322:58;27397:18;;54100:58:0;27069:352:1;54100:58:0;-1:-1:-1;;;;;54507:13:0;;;;;;:9;:13;;;;;;;;:18;;54524:1;54507:18;;;54549:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;54549:21:0;;;;;54588:33;54557:7;;54507:13;;54588:33;;54507:13;;54588:33;84159:212:::1;83577:2111:::0;:::o;3496:191::-;3589:6;;;-1:-1:-1;;;;;3606:17:0;;;-1:-1:-1;;;;;;3606:17:0;;;;;;;3639:40;;3589:6;;;3606:17;3589:6;;3639:40;;3570:16;;3639:40;3559:128;3496:191;:::o;57813:281::-;57934:8;-1:-1:-1;;;;;57925:17:0;:5;-1:-1:-1;;;;;57925:17:0;;57917:55;;;;-1:-1:-1;;;57917:55:0;;27628:2:1;57917:55:0;;;27610:21:1;27667:2;27647:18;;;27640:30;27706:27;27686:18;;;27679:55;27751:18;;57917:55:0;27426:349:1;57917:55:0;-1:-1:-1;;;;;57983:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;57983:46:0;;;;;;;;;;58045:41;;540::1;;;58045::0;;513:18:1;58045:41:0;;;;;;;57813:281;;;:::o;51074:270::-;51187:28;51197:4;51203:2;51207:7;51187:9;:28::i;:::-;51234:47;51257:4;51263:2;51267:7;51276:4;51234:22;:47::i;:::-;51226:110;;;;-1:-1:-1;;;51226:110:0;;27982:2:1;51226:110:0;;;27964:21:1;28021:2;28001:18;;;27994:30;28060:34;28040:18;;;28033:62;-1:-1:-1;;;28111:18:1;;;28104:48;28169:19;;51226:110:0;27780:414:1;42365:716:0;42421:13;42472:14;42489:17;42500:5;42489:10;:17::i;:::-;42509:1;42489:21;42472:38;;42525:20;42559:6;42548:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42548:18:0;-1:-1:-1;42525:41:0;-1:-1:-1;42690:28:0;;;42706:2;42690:28;42747:288;-1:-1:-1;;42779:5:0;42921:8;42916:2;42905:14;;42900:30;42779:5;42887:44;42977:2;42968:11;;;-1:-1:-1;42998:21:0;42747:288;42998:21;-1:-1:-1;43056:6:0;42365:716;-1:-1:-1;;;42365:716:0:o;78652:410::-;78762:7;76829:100;;;;;;;;;;;;;;;;;76809:127;;;;;;;78916:12;;78951:11;;;;78995:24;;;;;78985:35;;;;;;78835:204;;;;;28430:25:1;;;28486:2;28471:18;;28464:34;;;;-1:-1:-1;;;;;28534:55:1;28529:2;28514:18;;28507:83;28621:2;28606:18;;28599:34;28417:3;28402:19;;28199:440;78835:204:0;;;;;;;;;;;;;78807:247;;;;;;78787:267;;78652:410;;;:::o;76299:258::-;76398:7;76500:20;75738:15;;;75660:101;76500:20;76471:63;;-1:-1:-1;;;76471:63:0;;;28902:27:1;28945:11;;;28938:27;;;;28981:12;;;28974:28;;;29018:12;;76471:63:0;28644:392:1;53126:285:0;53221:18;53227:2;53231:7;53221:5;:18::i;:::-;53272:53;53303:1;53307:2;53311:7;53320:4;53272:22;:53::i;:::-;53250:153;;;;-1:-1:-1;;;53250:153:0;;27982:2:1;53250:153:0;;;27964:21:1;28021:2;28001:18;;;27994:30;28060:34;28040:18;;;28033:62;-1:-1:-1;;;28111:18:1;;;28104:48;28169:19;;53250:153:0;27780:414:1;58882:853:0;59036:4;-1:-1:-1;;;;;59057:13:0;;5471:19;:23;59053:675;;59109:2;-1:-1:-1;;;;;59093:36:0;;59130:12;:10;:12::i;:::-;59144:4;59150:7;59159:4;59093:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59093:71:0;;;;;;;;-1:-1:-1;;59093:71:0;;;;;;;;;;;;:::i;:::-;;;59089:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59334:6;:13;59351:1;59334:18;59330:328;;59377:60;;-1:-1:-1;;;59377:60:0;;27982:2:1;59377:60:0;;;27964:21:1;28021:2;28001:18;;;27994:30;28060:34;28040:18;;;28033:62;-1:-1:-1;;;28111:18:1;;;28104:48;28169:19;;59377:60:0;27780:414:1;59330:328:0;59608:6;59602:13;59593:6;59589:2;59585:15;59578:38;59089:584;-1:-1:-1;;;;;;59215:51:0;-1:-1:-1;;;59215:51:0;;-1:-1:-1;59208:58:0;;59053:675;-1:-1:-1;59712:4:0;58882:853;;;;;;:::o;37846:948::-;37899:7;;37986:8;37977:17;;37973:106;;38024:8;38015:17;;;-1:-1:-1;38061:2:0;38051:12;37973:106;38106:8;38097:5;:17;38093:106;;38144:8;38135:17;;;-1:-1:-1;38181:2:0;38171:12;38093:106;38226:8;38217:5;:17;38213:106;;38264:8;38255:17;;;-1:-1:-1;38301:2:0;38291:12;38213:106;38346:7;38337:5;:16;38333:103;;38383:7;38374:16;;;-1:-1:-1;38419:1:0;38409:11;38333:103;38463:7;38454:5;:16;38450:103;;38500:7;38491:16;;;-1:-1:-1;38536:1:0;38526:11;38450:103;38580:7;38571:5;:16;38567:103;;38617:7;38608:16;;;-1:-1:-1;38653:1:0;38643:11;38567:103;38697:7;38688:5;:16;38684:68;;38735:1;38725:11;38780:6;37846:948;-1:-1:-1;;37846:948:0:o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:154::-;-1:-1:-1;;;;;671:5:1;667:54;660:5;657:65;647:93;;736:1;733;726:12;751:315;819:6;827;880:2;868:9;859:7;855:23;851:32;848:52;;;896:1;893;886:12;848:52;935:9;922:23;954:31;979:5;954:31;:::i;:::-;1004:5;1056:2;1041:18;;;;1028:32;;-1:-1:-1;;;751:315:1:o;1071:250::-;1156:1;1166:113;1180:6;1177:1;1174:13;1166:113;;;1256:11;;;1250:18;1237:11;;;1230:39;1202:2;1195:10;1166:113;;;-1:-1:-1;;1313:1:1;1295:16;;1288:27;1071:250::o;1326:271::-;1368:3;1406:5;1400:12;1433:6;1428:3;1421:19;1449:76;1518:6;1511:4;1506:3;1502:14;1495:4;1488:5;1484:16;1449:76;:::i;:::-;1579:2;1558:15;-1:-1:-1;;1554:29:1;1545:39;;;;1586:4;1541:50;;1326:271;-1:-1:-1;;1326:271:1:o;1602:220::-;1751:2;1740:9;1733:21;1714:4;1771:45;1812:2;1801:9;1797:18;1789:6;1771:45;:::i;1827:180::-;1886:6;1939:2;1927:9;1918:7;1914:23;1910:32;1907:52;;;1955:1;1952;1945:12;1907:52;-1:-1:-1;1978:23:1;;1827:180;-1:-1:-1;1827:180:1:o;2243:127::-;2304:10;2299:3;2295:20;2292:1;2285:31;2335:4;2332:1;2325:15;2359:4;2356:1;2349:15;2375:275;2446:2;2440:9;2511:2;2492:13;;-1:-1:-1;;2488:27:1;2476:40;;2546:18;2531:34;;2567:22;;;2528:62;2525:88;;;2593:18;;:::i;:::-;2629:2;2622:22;2375:275;;-1:-1:-1;2375:275:1:o;2655:530::-;2697:5;2750:3;2743:4;2735:6;2731:17;2727:27;2717:55;;2768:1;2765;2758:12;2717:55;2804:6;2791:20;2830:18;2826:2;2823:26;2820:52;;;2852:18;;:::i;:::-;2896:55;2939:2;2920:13;;-1:-1:-1;;2916:27:1;2945:4;2912:38;2896:55;:::i;:::-;2976:2;2967:7;2960:19;3022:3;3015:4;3010:2;3002:6;2998:15;2994:26;2991:35;2988:55;;;3039:1;3036;3029:12;2988:55;3104:2;3097:4;3089:6;3085:17;3078:4;3069:7;3065:18;3052:55;3152:1;3127:16;;;3145:4;3123:27;3116:38;;;;3131:7;2655:530;-1:-1:-1;;;2655:530:1:o;3190:758::-;3292:6;3300;3308;3316;3324;3377:3;3365:9;3356:7;3352:23;3348:33;3345:53;;;3394:1;3391;3384:12;3345:53;3433:9;3420:23;3452:31;3477:5;3452:31;:::i;:::-;3502:5;-1:-1:-1;3558:2:1;3543:18;;3530:32;3585:18;3574:30;;3571:50;;;3617:1;3614;3607:12;3571:50;3640:49;3681:7;3672:6;3661:9;3657:22;3640:49;:::i;:::-;3630:59;;;3736:2;3725:9;3721:18;3708:32;3698:42;;3787:2;3776:9;3772:18;3759:32;3749:42;;3843:3;3832:9;3828:19;3815:33;3892:4;3883:7;3879:18;3870:7;3867:31;3857:59;;3912:1;3909;3902:12;3857:59;3935:7;3925:17;;;3190:758;;;;;;;;:::o;4540:456::-;4617:6;4625;4633;4686:2;4674:9;4665:7;4661:23;4657:32;4654:52;;;4702:1;4699;4692:12;4654:52;4741:9;4728:23;4760:31;4785:5;4760:31;:::i;:::-;4810:5;-1:-1:-1;4867:2:1;4852:18;;4839:32;4880:33;4839:32;4880:33;:::i;:::-;4540:456;;4932:7;;-1:-1:-1;;;4986:2:1;4971:18;;;;4958:32;;4540:456::o;5001:247::-;5060:6;5113:2;5101:9;5092:7;5088:23;5084:32;5081:52;;;5129:1;5126;5119:12;5081:52;5168:9;5155:23;5187:31;5212:5;5187:31;:::i;5253:118::-;5339:5;5332:13;5325:21;5318:5;5315:32;5305:60;;5361:1;5358;5351:12;5376:241;5432:6;5485:2;5473:9;5464:7;5460:23;5456:32;5453:52;;;5501:1;5498;5491:12;5453:52;5540:9;5527:23;5559:28;5581:5;5559:28;:::i;5622:592::-;5693:6;5701;5754:2;5742:9;5733:7;5729:23;5725:32;5722:52;;;5770:1;5767;5760:12;5722:52;5810:9;5797:23;5839:18;5880:2;5872:6;5869:14;5866:34;;;5896:1;5893;5886:12;5866:34;5934:6;5923:9;5919:22;5909:32;;5979:7;5972:4;5968:2;5964:13;5960:27;5950:55;;6001:1;5998;5991:12;5950:55;6041:2;6028:16;6067:2;6059:6;6056:14;6053:34;;;6083:1;6080;6073:12;6053:34;6128:7;6123:2;6114:6;6110:2;6106:15;6102:24;6099:37;6096:57;;;6149:1;6146;6139:12;6096:57;6180:2;6172:11;;;;;6202:6;;-1:-1:-1;5622:592:1;;-1:-1:-1;;;;5622:592:1:o;6725:382::-;6790:6;6798;6851:2;6839:9;6830:7;6826:23;6822:32;6819:52;;;6867:1;6864;6857:12;6819:52;6906:9;6893:23;6925:31;6950:5;6925:31;:::i;:::-;6975:5;-1:-1:-1;7032:2:1;7017:18;;7004:32;7045:30;7004:32;7045:30;:::i;:::-;7094:7;7084:17;;;6725:382;;;;;:::o;7112:183::-;7172:4;7205:18;7197:6;7194:30;7191:56;;;7227:18;;:::i;:::-;-1:-1:-1;7272:1:1;7268:14;7284:4;7264:25;;7112:183::o;7300:737::-;7354:5;7407:3;7400:4;7392:6;7388:17;7384:27;7374:55;;7425:1;7422;7415:12;7374:55;7461:6;7448:20;7487:4;7511:60;7527:43;7567:2;7527:43;:::i;:::-;7511:60;:::i;:::-;7605:15;;;7691:1;7687:10;;;;7675:23;;7671:32;;;7636:12;;;;7715:15;;;7712:35;;;7743:1;7740;7733:12;7712:35;7779:2;7771:6;7767:15;7791:217;7807:6;7802:3;7799:15;7791:217;;;7887:3;7874:17;7904:31;7929:5;7904:31;:::i;:::-;7948:18;;7986:12;;;;7824;;7791:217;;;-1:-1:-1;8026:5:1;7300:737;-1:-1:-1;;;;;;7300:737:1:o;8042:1138::-;8160:6;8168;8221:2;8209:9;8200:7;8196:23;8192:32;8189:52;;;8237:1;8234;8227:12;8189:52;8277:9;8264:23;8306:18;8347:2;8339:6;8336:14;8333:34;;;8363:1;8360;8353:12;8333:34;8386:61;8439:7;8430:6;8419:9;8415:22;8386:61;:::i;:::-;8376:71;;8466:2;8456:12;;8521:2;8510:9;8506:18;8493:32;8550:2;8540:8;8537:16;8534:36;;;8566:1;8563;8556:12;8534:36;8589:24;;;-1:-1:-1;8644:4:1;8636:13;;8632:27;-1:-1:-1;8622:55:1;;8673:1;8670;8663:12;8622:55;8709:2;8696:16;8732:60;8748:43;8788:2;8748:43;:::i;8732:60::-;8826:15;;;8908:1;8904:10;;;;8896:19;;8892:28;;;8857:12;;;;8932:19;;;8929:39;;;8964:1;8961;8954:12;8929:39;8988:11;;;;9008:142;9024:6;9019:3;9016:15;9008:142;;;9090:17;;9078:30;;9041:12;;;;9128;;;;9008:142;;;9169:5;9159:15;;;;;;;8042:1138;;;;;:::o;9185:348::-;9269:6;9322:2;9310:9;9301:7;9297:23;9293:32;9290:52;;;9338:1;9335;9328:12;9290:52;9378:9;9365:23;9411:18;9403:6;9400:30;9397:50;;;9443:1;9440;9433:12;9397:50;9466:61;9519:7;9510:6;9499:9;9495:22;9466:61;:::i;9538:665::-;9633:6;9641;9649;9657;9710:3;9698:9;9689:7;9685:23;9681:33;9678:53;;;9727:1;9724;9717:12;9678:53;9766:9;9753:23;9785:31;9810:5;9785:31;:::i;:::-;9835:5;-1:-1:-1;9892:2:1;9877:18;;9864:32;9905:33;9864:32;9905:33;:::i;:::-;9957:7;-1:-1:-1;10011:2:1;9996:18;;9983:32;;-1:-1:-1;10066:2:1;10051:18;;10038:32;10093:18;10082:30;;10079:50;;;10125:1;10122;10115:12;10079:50;10148:49;10189:7;10180:6;10169:9;10165:22;10148:49;:::i;:::-;10138:59;;;9538:665;;;;;;;:::o;10208:388::-;10276:6;10284;10337:2;10325:9;10316:7;10312:23;10308:32;10305:52;;;10353:1;10350;10343:12;10305:52;10392:9;10379:23;10411:31;10436:5;10411:31;:::i;:::-;10461:5;-1:-1:-1;10518:2:1;10503:18;;10490:32;10531:33;10490:32;10531:33;:::i;10601:380::-;10680:1;10676:12;;;;10723;;;10744:61;;10798:4;10790:6;10786:17;10776:27;;10744:61;10851:2;10843:6;10840:14;10820:18;10817:38;10814:161;;10897:10;10892:3;10888:20;10885:1;10878:31;10932:4;10929:1;10922:15;10960:4;10957:1;10950:15;10814:161;;10601:380;;;:::o;12220:455::-;12402:4;-1:-1:-1;;;;;12512:2:1;12504:6;12500:15;12489:9;12482:34;12564:2;12556:6;12552:15;12547:2;12536:9;12532:18;12525:43;;12604:2;12599;12588:9;12584:18;12577:30;12624:45;12665:2;12654:9;12650:18;12642:6;12624:45;:::i;12680:428::-;12837:3;12875:6;12869:13;12891:66;12950:6;12945:3;12938:4;12930:6;12926:17;12891:66;:::i;:::-;13026:2;13022:15;;;;-1:-1:-1;;13018:53:1;12979:16;;;;13004:68;;;13099:2;13088:14;;12680:428;-1:-1:-1;;12680:428:1:o;13113:287::-;13242:3;13280:6;13274:13;13296:66;13355:6;13350:3;13343:4;13335:6;13331:17;13296:66;:::i;:::-;13378:16;;;;;13113:287;-1:-1:-1;;13113:287:1:o;14945:127::-;15006:10;15001:3;14997:20;14994:1;14987:31;15037:4;15034:1;15027:15;15061:4;15058:1;15051:15;15077:125;15142:9;;;15163:10;;;15160:36;;;15176:18;;:::i;15690:217::-;15730:1;15756;15746:132;;15800:10;15795:3;15791:20;15788:1;15781:31;15835:4;15832:1;15825:15;15863:4;15860:1;15853:15;15746:132;-1:-1:-1;15892:9:1;;15690:217::o;15912:168::-;15985:9;;;16016;;16033:15;;;16027:22;;16013:37;16003:71;;16054:18;;:::i;16085:128::-;16152:9;;;16173:11;;;16170:37;;;16187:18;;:::i;16621:245::-;16688:6;16741:2;16729:9;16720:7;16716:23;16712:32;16709:52;;;16757:1;16754;16747:12;16709:52;16789:9;16783:16;16808:28;16830:5;16808:28;:::i;16871:135::-;16910:3;16931:17;;;16928:43;;16951:18;;:::i;:::-;-1:-1:-1;16998:1:1;16987:13;;16871:135::o;17551:545::-;17653:2;17648:3;17645:11;17642:448;;;17689:1;17714:5;17710:2;17703:17;17759:4;17755:2;17745:19;17829:2;17817:10;17813:19;17810:1;17806:27;17800:4;17796:38;17865:4;17853:10;17850:20;17847:47;;;-1:-1:-1;17888:4:1;17847:47;17943:2;17938:3;17934:12;17931:1;17927:20;17921:4;17917:31;17907:41;;17998:82;18016:2;18009:5;18006:13;17998:82;;;18061:17;;;18042:1;18031:13;17998:82;;;18002:3;;;17551:545;;;:::o;18272:1206::-;18396:18;18391:3;18388:27;18385:53;;;18418:18;;:::i;:::-;18447:94;18537:3;18497:38;18529:4;18523:11;18497:38;:::i;:::-;18491:4;18447:94;:::i;:::-;18567:1;18592:2;18587:3;18584:11;18609:1;18604:616;;;;19264:1;19281:3;19278:93;;;-1:-1:-1;19337:19:1;;;19324:33;19278:93;-1:-1:-1;;18229:1:1;18225:11;;;18221:24;18217:29;18207:40;18253:1;18249:11;;;18204:57;19384:78;;18577:895;;18604:616;17498:1;17491:14;;;17535:4;17522:18;;-1:-1:-1;;18640:17:1;;;18741:9;18763:229;18777:7;18774:1;18771:14;18763:229;;;18866:19;;;18853:33;18838:49;;18973:4;18958:20;;;;18926:1;18914:14;;;;18793:12;18763:229;;;18767:3;19020;19011:7;19008:16;19005:159;;;19144:1;19140:6;19134:3;19128;19125:1;19121:11;19117:21;19113:34;19109:39;19096:9;19091:3;19087:19;19074:33;19070:79;19062:6;19055:95;19005:159;;;19207:1;19201:3;19198:1;19194:11;19190:19;19184:4;19177:33;18577:895;;18272:1206;;;:::o;22664:127::-;22725:10;22720:3;22716:20;22713:1;22706:31;22756:4;22753:1;22746:15;22780:4;22777:1;22770:15;22796:496;22975:3;23013:6;23007:13;23029:66;23088:6;23083:3;23076:4;23068:6;23064:17;23029:66;:::i;:::-;23158:13;;23117:16;;;;23180:70;23158:13;23117:16;23227:4;23215:17;;23180:70;:::i;:::-;23266:20;;22796:496;-1:-1:-1;;;;22796:496:1:o;23297:184::-;23367:6;23420:2;23408:9;23399:7;23395:23;23391:32;23388:52;;;23436:1;23433;23426:12;23388:52;-1:-1:-1;23459:16:1;;23297:184;-1:-1:-1;23297:184:1:o;23788:280::-;23887:6;23940:2;23928:9;23919:7;23915:23;23911:32;23908:52;;;23956:1;23953;23946:12;23908:52;23988:9;23982:16;24007:31;24032:5;24007:31;:::i;29041:512::-;29235:4;-1:-1:-1;;;;;29345:2:1;29337:6;29333:15;29322:9;29315:34;29397:2;29389:6;29385:15;29380:2;29369:9;29365:18;29358:43;;29437:6;29432:2;29421:9;29417:18;29410:34;29480:3;29475:2;29464:9;29460:18;29453:31;29501:46;29542:3;29531:9;29527:19;29519:6;29501:46;:::i;:::-;29493:54;29041:512;-1:-1:-1;;;;;;29041:512:1:o;29558:249::-;29627:6;29680:2;29668:9;29659:7;29655:23;29651:32;29648:52;;;29696:1;29693;29686:12;29648:52;29728:9;29722:16;29747:30;29771:5;29747:30;:::i

Swarm Source

ipfs://908684117741395e55723776332d53795ade5d3b0ab8d12fd39be853b87e59a2
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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