ETH Price: $3,906.74 (+1.23%)

Token

MetaMafioso (METSIG)
 

Overview

Max Total Supply

1,073 METSIG

Holders

952

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
andrewberg.eth
Balance
1 METSIG
0x87ba3c38282409e6d13156303c43dd73b264010b
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:
MetaMafiosoContract

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

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

pragma solidity ^0.8.0;


// 
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
/**
 * @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;
    }
}

// 
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
/**
 * @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);
    }
}

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

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

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}

// 
error TransactionCapExceeded ();

error PublicMintingClosed ();

error ExcessiveOwnedMints ();

error MintZeroQuantity ();

error InvalidPayment ();

error SoftCapExceeded ();

error CapExceeded ();

error IsAlreadyUnveiled ();

error ValueCannotBeZero ();

error CannotBeNullAddress ();

error NoStateChange ();

error PublicMintClosed ();

error AllowlistMintClosed ();

error AddressNotAllowlisted ();

error AllowlistDropTimeHasNotPassed ();

error PublicDropTimeHasNotPassed ();

error DropTimeNotInFuture ();

error ClaimModeDisabled ();

error IneligibleRedemptionContract ();

error TokenAlreadyRedeemed ();

error InvalidOwnerForRedemption ();

error InvalidApprovalForRedemption ();

error ERC721RestrictedApprovalAddressRestricted ();

error NotMaintainer ();

error InvalidTeamAddress ();

error DuplicateTeamAddress ();

error AffiliateNotFound ();

// 
/**
 * Teams is a contract implementation to extend upon Ownable that allows multiple controllers
 * of a single contract to modify specific mint settings but not have overall ownership of the contract.
 * This will easily allow cross-collaboration via Mintplex.xyz.
 **/
abstract contract Teams is Ownable {
  mapping(address => bool) internal team;

  /**
   * @dev Adds an address to the team. Allows them to execute protected functions
   * @param _address the ETH address to add, cannot be 0x and cannot be in team already
   **/
  function addToTeam(address _address) public onlyOwner {
    if (_address == address(0)) revert InvalidTeamAddress();
    if (inTeam(_address)) revert DuplicateTeamAddress();
    team[_address] = true;
  }

  /**
   * @dev Removes an address to the team.
   * @param _address the ETH address to remove, cannot be 0x and must be in team
   **/
  function removeFromTeam(address _address) public onlyOwner {
    if (_address == address(0)) revert InvalidTeamAddress();
    if (!inTeam(_address)) revert InvalidTeamAddress();
    team[_address] = false;
  }

  /**
   * @dev Check if an address is valid and active in the team
   * @param _address ETH address to check for truthiness
   **/
  function inTeam(address _address) public view returns (bool) {
    if (_address == address(0)) revert InvalidTeamAddress();
    return team[_address] == true;
  }

  /**
   * @dev Throws if called by any account other than the owner or team member.
   */
  function _onlyTeamOrOwner() private view {
    bool _isOwner = owner() == _msgSender();
    bool _isTeam = inTeam(_msgSender());
    require(_isOwner || _isTeam, "Team: caller is not the owner or in Team.");
  }

  modifier onlyTeamOrOwner() {
    _onlyTeamOrOwner();
    _;
  }
}

// 
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
/**
 * @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);
}

// 
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
/**
 * @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;
    }
}

// 
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)
/**
 * @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);
}

// 
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
/**
 * @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);
}

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

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

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

// 
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
/**
 * @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);
        }
    }
}

// 
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
/**
 * @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);
        }
    }
}

// 
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)
/**
 * @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);
        }
    }
}

// 
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)
/**
 * @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));
    }
}

// 
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
/**
 * @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);
}

// 
interface IOperatorFilterRegistry {
  function isOperatorAllowed(address registrant, address operator) external view returns (bool);

  function register(address registrant) external;

  function registerAndSubscribe(address registrant, address subscription) external;

  function registerAndCopyEntries(address registrant, address registrantToCopy) external;

  function updateOperator(address registrant, address operator, bool filtered) external;

  function updateOperators(address registrant, address[] calldata operators, bool filtered) external;

  function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;

  function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;

  function subscribe(address registrant, address registrantToSubscribe) external;

  function unsubscribe(address registrant, bool copyExistingEntries) external;

  function subscriptionOf(address addr) external returns (address registrant);

  function subscribers(address registrant) external returns (address[] memory);

  function subscriberAt(address registrant, uint256 index) external returns (address);

  function copyEntriesOf(address registrant, address registrantToCopy) external;

  function isOperatorFiltered(address registrant, address operator) external returns (bool);

  function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);

  function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);

  function filteredOperators(address addr) external returns (address[] memory);

  function filteredCodeHashes(address addr) external returns (bytes32[] memory);

  function filteredOperatorAt(address registrant, uint256 index) external returns (address);

  function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);

  function isRegistered(address addr) external returns (bool);

  function codeHashOf(address addr) external returns (bytes32);
}

// 
abstract contract OperatorFilterer {
  error OperatorNotAllowed(address operator);
  IOperatorFilterRegistry constant operatorFilterRegistry =
    IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

  constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
    // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
    // will not revert, but the contract will need to be registered with the registry once it is deployed in
    // order for the modifier to filter addresses.
    if (address(operatorFilterRegistry).code.length > 0) {
      if (subscribe) {
        operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
      } else {
        if (subscriptionOrRegistrantToCopy != address(0)) {
          operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
        } else {
          operatorFilterRegistry.register(address(this));
        }
      }
    }
  }

  function _onlyAllowedOperator(address from) private view {
    if (
      !(operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender) &&
        operatorFilterRegistry.isOperatorAllowed(address(this), from))
    ) {
      revert OperatorNotAllowed(msg.sender);
    }
  }

  modifier onlyAllowedOperator(address from) virtual {
    // Check registry code length to facilitate testing in environments without a deployed registry.
    if (address(operatorFilterRegistry).code.length > 0) {
      // Allow spending tokens from addresses with balance
      // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
      // from an EOA.
      if (from == msg.sender) {
        _;
        return;
      }
      _onlyAllowedOperator(from);
    }
    _;
  }
  modifier onlyAllowedOperatorApproval(address operator) virtual {
    _checkFilterOperator(operator);
    _;
  }

  function _checkFilterOperator(address operator) internal view virtual {
    // Check registry code length to facilitate testing in environments without a deployed registry.
    if (address(operatorFilterRegistry).code.length > 0) {
      if (!operatorFilterRegistry.isOperatorAllowed(address(this), operator)) {
        revert OperatorNotAllowed(operator);
      }
    }
  }
}

// 
/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata and Enumerable extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes the number of issuable tokens (collection size) is capped and fits in a uint128.
 *
 * Does not support burning tokens to address(0).
 */
abstract contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable, Teams, OperatorFilterer {
  using Address for address;
  using Strings for uint256;
  struct TokenOwnership {
    address addr;
    uint64 startTimestamp;
  }
  struct AddressData {
    uint128 balance;
    uint128 numberMinted;
  }
  uint256 private currentIndex;
  uint256 public immutable collectionSize;
  uint256 public maxBatchSize;
  // Token name
  string private _name;
  // Token symbol
  string private _symbol;
  // Mapping from token ID to ownership details
  // An empty struct value does not necessarily mean the token is unowned. See ownershipOf implementation for details.
  mapping(uint256 => TokenOwnership) private _ownerships;
  // Mapping owner address to address data
  mapping(address => AddressData) private _addressData;
  // Mapping from token ID to approved address
  mapping(uint256 => address) private _tokenApprovals;
  // Mapping from owner to operator approvals
  mapping(address => mapping(address => bool)) private _operatorApprovals;
  /* @dev Mapping of restricted operator approvals set by contract Owner
   * This serves as an optional addition to ERC-721 so
   * that the contract owner can elect to prevent specific addresses/contracts
   * from being marked as the approver for a token. The reason for this
   * is that some projects may want to retain control of where their tokens can/can not be listed
   * either due to ethics, loyalty, or wanting trades to only occur on their personal marketplace.
   * By default, there are no restrictions. The contract owner must deliberatly block an address
   */
  mapping(address => bool) public restrictedApprovalAddresses;

  /**
   * @dev
   * maxBatchSize refers to how much a minter can mint at a time.
   * collectionSize_ refers to how many tokens are in the collection.
   */
  constructor(
    string memory name_,
    string memory symbol_,
    uint256 maxBatchSize_,
    uint256 collectionSize_
  ) OperatorFilterer(address(0), false) {
    require(collectionSize_ > 0, "ERC721A: collection must have a nonzero supply");
    require(maxBatchSize_ > 0, "ERC721A: max batch size must be nonzero");
    _name = name_;
    _symbol = symbol_;
    maxBatchSize = maxBatchSize_;
    collectionSize = collectionSize_;
    currentIndex = _startTokenId();
  }

  /**
   * To change the starting tokenId, please override this function.
   */
  function _startTokenId() internal view virtual returns (uint256) {
    return 1;
  }

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

  function currentTokenId() public view returns (uint256) {
    return _totalMinted();
  }

  function getNextTokenId() public view returns (uint256) {
    return _totalMinted() + 1;
  }

  /**
   * Returns the total amount of tokens minted in the contract.
   */
  function _totalMinted() internal view returns (uint256) {
    unchecked {
      return currentIndex - _startTokenId();
    }
  }

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

  /**
   * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
   * This read function is O(collectionSize). If calling from a separate contract, be sure to test gas first.
   * It may also degrade with extremely large collection sizes (e.g >> 10000), test for your use case.
   */
  function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) {
    require(index < balanceOf(owner), "ERC721A: owner index out of bounds");
    uint256 numMintedSoFar = totalSupply();
    uint256 tokenIdsIdx = 0;
    address currOwnershipAddr = address(0);
    for (uint256 i = 0; i < numMintedSoFar; i++) {
      TokenOwnership memory ownership = _ownerships[i];
      if (ownership.addr != address(0)) {
        currOwnershipAddr = ownership.addr;
      }
      if (currOwnershipAddr == owner) {
        if (tokenIdsIdx == index) {
          return i;
        }
        tokenIdsIdx++;
      }
    }
    revert("ERC721A: unable to get token of owner by index");
  }

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

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

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

  function ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
    uint256 curr = tokenId;
    unchecked {
      if (_startTokenId() <= curr && curr < currentIndex) {
        TokenOwnership memory ownership = _ownerships[curr];
        if (ownership.addr != address(0)) {
          return ownership;
        }
        // Invariant:
        // There will always be an ownership that has an address and is not burned
        // before an ownership that does not have an address and is not burned.
        // Hence, curr will not underflow.
        while (true) {
          curr--;
          ownership = _ownerships[curr];
          if (ownership.addr != address(0)) {
            return ownership;
          }
        }
      }
    }
    revert("ERC721A: unable to determine the owner of token");
  }

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

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

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

  /**
   * @dev See {IERC721Metadata-tokenURI}.
   */
  function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
    string memory baseURI = _baseURI();
    string memory extension = _baseURIExtension();
    return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString(), extension)) : "";
  }

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

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

  /**
   * @dev Sets the value for an address to be in the restricted approval address pool.
   * Setting an address to true will disable token owners from being able to mark the address
   * for approval for trading. This would be used in theory to prevent token owners from listing
   * on specific marketplaces or protcols. Only modifible by the contract owner/team.
   * @param _address the marketplace/user to modify restriction status of
   * @param _isRestricted restriction status of the _address to be set. true => Restricted, false => Open
   */
  function setApprovalRestriction(address _address, bool _isRestricted) public onlyTeamOrOwner {
    restrictedApprovalAddresses[_address] = _isRestricted;
  }

  /**
   * @dev See {IERC721-approve}.
   */
  function approve(address to, uint256 tokenId) public override onlyAllowedOperatorApproval(to) {
    address owner = ERC721A.ownerOf(tokenId);
    require(to != owner, "ERC721A: approval to current owner");
    if (restrictedApprovalAddresses[to]) revert ERC721RestrictedApprovalAddressRestricted();
    require(
      _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
      "ERC721A: approve caller is not owner nor approved for all"
    );
    _approve(to, tokenId, owner);
  }

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

  /**
   * @dev See {IERC721-setApprovalForAll}.
   */
  function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
    require(operator != _msgSender(), "ERC721A: approve to caller");
    if (restrictedApprovalAddresses[operator]) revert ERC721RestrictedApprovalAddressRestricted();
    _operatorApprovals[_msgSender()][operator] = approved;
    emit ApprovalForAll(_msgSender(), operator, approved);
  }

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

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

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

  /**
   * @dev See {IERC721-safeTransferFrom}.
   */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes memory _data
  ) public override onlyAllowedOperator(from) {
    _transfer(from, to, tokenId);
    require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721A: transfer to non ERC721Receiver implementer");
  }

  /**
   * @dev Returns whether tokenId exists.
   *
   * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
   *
   * Tokens start existing when they are minted (_mint),
   */
  function _exists(uint256 tokenId) internal view returns (bool) {
    return _startTokenId() <= tokenId && tokenId < currentIndex;
  }

  function _safeMint(address to, uint256 quantity, bool isAdminMint) internal {
    _safeMint(to, quantity, isAdminMint, "");
  }

  /**
   * @dev Mints quantity tokens and transfers them to to.
   *
   * Requirements:
   *
   * - there must be quantity tokens remaining unminted in the total collection.
   * - to cannot be the zero address.
   * - quantity cannot be larger than the max batch size.
   *
   * Emits a {Transfer} event.
   */
  function _safeMint(address to, uint256 quantity, bool isAdminMint, bytes memory _data) internal {
    uint256 startTokenId = currentIndex;
    require(to != address(0), "ERC721A: mint to the zero address");
    // We know if the first token in the batch doesn't exist, the other ones don't as well, because of serial ordering.
    require(!_exists(startTokenId), "ERC721A: token already minted");
    // For admin mints we do not want to enforce the maxBatchSize limit
    if (isAdminMint == false) {
      require(quantity <= maxBatchSize, "ERC721A: quantity to mint too high");
    }
    _beforeTokenTransfers(address(0), to, startTokenId, quantity);
    AddressData memory addressData = _addressData[to];
    _addressData[to] = AddressData(
      addressData.balance + uint128(quantity),
      addressData.numberMinted + (isAdminMint ? 0 : uint128(quantity))
    );
    _ownerships[startTokenId] = TokenOwnership(to, uint64(block.timestamp));
    uint256 updatedIndex = startTokenId;
    for (uint256 i = 0; i < quantity; i++) {
      emit Transfer(address(0), to, updatedIndex);
      require(
        _checkOnERC721Received(address(0), to, updatedIndex, _data),
        "ERC721A: transfer to non ERC721Receiver implementer"
      );
      updatedIndex++;
    }
    currentIndex = updatedIndex;
    _afterTokenTransfers(address(0), to, startTokenId, quantity);
  }

  /**
   * @dev Transfers tokenId from from to to.
   *
   * Requirements:
   *
   * - to cannot be the zero address.
   * - tokenId token must be owned by from.
   *
   * Emits a {Transfer} event.
   */
  function _transfer(address from, address to, uint256 tokenId) private {
    TokenOwnership memory prevOwnership = ownershipOf(tokenId);
    bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr ||
      getApproved(tokenId) == _msgSender() ||
      isApprovedForAll(prevOwnership.addr, _msgSender()));
    require(isApprovedOrOwner, "ERC721A: transfer caller is not owner nor approved");
    require(prevOwnership.addr == from, "ERC721A: transfer from incorrect owner");
    require(to != address(0), "ERC721A: transfer to the zero address");
    _beforeTokenTransfers(from, to, tokenId, 1);
    // Clear approvals from the previous owner
    _approve(address(0), tokenId, prevOwnership.addr);
    _addressData[from].balance -= 1;
    _addressData[to].balance += 1;
    _ownerships[tokenId] = TokenOwnership(to, uint64(block.timestamp));
    // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
    // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
    uint256 nextTokenId = tokenId + 1;
    if (_ownerships[nextTokenId].addr == address(0)) {
      if (_exists(nextTokenId)) {
        _ownerships[nextTokenId] = TokenOwnership(prevOwnership.addr, prevOwnership.startTimestamp);
      }
    }
    emit Transfer(from, to, tokenId);
    _afterTokenTransfers(from, to, tokenId, 1);
  }

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

  uint256 public nextOwnerToExplicitlySet = 0;

  /**
   * @dev Explicitly set owners to eliminate loops in future calls of ownerOf().
   */
  function _setOwnersExplicit(uint256 quantity) internal {
    uint256 oldNextOwnerToSet = nextOwnerToExplicitlySet;
    require(quantity > 0, "quantity must be nonzero");
    if (currentIndex == _startTokenId()) revert("No Tokens Minted Yet");
    uint256 endIndex = oldNextOwnerToSet + quantity - 1;
    if (endIndex > collectionSize - 1) {
      endIndex = collectionSize - 1;
    }
    // We know if the last one in the group exists, all in the group exist, due to serial ordering.
    require(_exists(endIndex), "not enough minted yet for this cleanup");
    for (uint256 i = oldNextOwnerToSet; i <= endIndex; i++) {
      if (_ownerships[i].addr == address(0)) {
        TokenOwnership memory ownership = ownershipOf(i);
        _ownerships[i] = TokenOwnership(ownership.addr, ownership.startTimestamp);
      }
    }
    nextOwnerToExplicitlySet = endIndex + 1;
  }

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

  /**
   * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
   *
   * startTokenId - the first token id to be transferred
   * quantity - the amount to be transferred
   *
   * Calling conditions:
   *
   * - When from and to are both non-zero, from's tokenId will be
   * transferred to to.
   * - When from is zero, tokenId will be minted for to.
   */
  function _beforeTokenTransfers(address from, address to, uint256 startTokenId, uint256 quantity) internal virtual {}

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

// 
contract Affiliate is Context, Teams {
    struct AffiliateAccount {
        address addr;
        uint256 rate;
        uint256 balance;
        uint256 lifetimeBalance;
        uint256 mints;
    }

    uint256 internal affiliateBalance = 0;
    mapping(string => AffiliateAccount) private affiliates;
    mapping(string => bool) internal affiliateExists;
    mapping(address => string) private affiliateCodes;

    function affiliateStatus(address _address) external view returns (string memory code, uint256 rate, uint256 mints, uint256 balance, uint256 lifetimeBalance) {
        string memory _code = affiliateCodes[_address];
        require(affiliateExists[_code], "Address is not an affiliate");
        AffiliateAccount memory affiliate = affiliates[_code];
        return (_code, affiliate.rate, affiliate.mints, affiliate.balance, affiliate.lifetimeBalance);
    }
    
    function addAffiliate(string calldata _code, address _address, uint256 _rate) external onlyTeamOrOwner {
        require(bytes(_code).length > 0, "Invalid code");
        require(_address != address(0), "Invalid address");
        require(_rate > 0, "Rate must be greater than zero");
        require(bytes(affiliateCodes[_address]).length == 0, "Affiliate address already exists");
        require(!affiliateExists[_code], "Affiliate code already exists");

        AffiliateAccount memory affiliate = AffiliateAccount(_address, _rate, 0, 0, 0);
        affiliates[_code] = affiliate;
        affiliateExists[_code] = true;
        affiliateCodes[_address] = _code;
    }

    function creditAffiliate(string calldata _code, uint256 _value, uint256 _mints) internal {
        if (affiliateExists[_code]) {
            AffiliateAccount storage affiliate = affiliates[_code];
            
            // Calculate their earnings from the transaction value
            uint256 earnings = (_value * affiliate.rate) / 100;

            // Update the balance of this affiliate
            affiliate.mints += _mints;
            affiliate.balance += earnings;
            affiliate.lifetimeBalance += earnings;

            // Save the total balance of all affiliates
            affiliateBalance += earnings;
        }
    }

    function _payAffiliate(string memory _code) private {
        require(affiliateExists[_code], "Affiliate does not exist");
        AffiliateAccount storage affiliate = affiliates[_code];
    
        uint256 _balance = affiliate.balance;
        address _address = affiliate.addr;
        require(_balance > 0, "Affiliate does not have a balance");
        require(_address != address(0), "Invalid address");

        (bool success, ) = _address.call{value: _balance}("");
        require(success, "Withdrawal failed");

        // Reset their balance
        affiliate.balance = 0;
        affiliateBalance -= _balance;
    }

    function affiliateWithdraw() external {
        string memory _code = affiliateCodes[_msgSender()];
        require(affiliateExists[_code], "You are not an affiliate");
        _payAffiliate(_code);
    }
}

// 
abstract contract WithdrawableV2 is Teams, Affiliate {
  address[] public payableAddresses = [
    0x8e8772E32F700C623FED03Ce29e2dE47073dB972,
    0x5b409126085223d28f3e2257bcf9eF6fB1c9D735
  ];
  uint256[] public payableFees = [2, 98];
  uint256 public payableAddressCount = 2;

  function withdrawAll() public onlyTeamOrOwner {
    uint256 _balance = address(this).balance;
    uint256 _availableBalance = _balance - affiliateBalance;

    if (_availableBalance <= 0) revert ValueCannotBeZero();
    _withdrawAll(_availableBalance);
  }

  function _withdrawAll(uint256 balance) private {
    for (uint i = 0; i < payableAddressCount; i++) {
      _widthdraw(payableAddresses[i], (balance * payableFees[i]) / 100);
    }
  }

  function _widthdraw(address _address, uint256 _amount) private {
    (bool success, ) = _address.call{value: _amount}("");
    require(success, "Transfer failed.");
  }
}

// 
abstract contract Feeable is Teams {
  uint256 public PRICE_BASE = 1 ether;
  uint256 public INCREMENT_PERCENT = 6;
  uint256 public INCREMENT_BATCH = 100;

  function setPriceBase(uint256 _feeInWei) external onlyTeamOrOwner {
    PRICE_BASE = _feeInWei;
  }

  function setPriceIncrementPercent(uint256 _incrementPercent) external onlyTeamOrOwner {
    INCREMENT_PERCENT = _incrementPercent;
  }

  function setPriceIncrementBatch(uint256 _incrementBatch) external onlyTeamOrOwner {
    INCREMENT_BATCH = _incrementBatch;
  }

  function getPrice(uint256 _count, uint256 _supply) internal view returns (uint256) {
    uint256 batch = _supply / INCREMENT_BATCH;
    uint256 price = PRICE_BASE;

    for (uint i = 0; i < batch; i++) {
      price += price * INCREMENT_PERCENT / 100;
    }

    return price * _count;
  }
}

// 
abstract contract Allowlist is Teams {
  bytes32 public merkleRoot;
  bool public onlyAllowlistMode = false;

  /**
   * @dev Update merkle root to reflect changes in Allowlist
   * @param _newMerkleRoot new merkle root to reflect most recent Allowlist
   */
  function updateMerkleRoot(bytes32 _newMerkleRoot) public onlyTeamOrOwner {
    if (_newMerkleRoot == merkleRoot) revert NoStateChange();
    merkleRoot = _newMerkleRoot;
  }

  /**
   * @dev Check the proof of an address if valid for merkle root
   * @param _to address to check for proof
   * @param _merkleProof Proof of the address to validate against root and leaf
   */
  function isAllowlisted(address _to, bytes32[] calldata _merkleProof) public view returns (bool) {
    if (merkleRoot == 0) revert ValueCannotBeZero();
    bytes32 leaf = keccak256(abi.encodePacked(_to));
    return MerkleProof.verify(_merkleProof, merkleRoot, leaf);
  }

  function enableAllowlistOnlyMode() public onlyTeamOrOwner {
    onlyAllowlistMode = true;
  }

  function disableAllowlistOnlyMode() public onlyTeamOrOwner {
    onlyAllowlistMode = false;
  }
}

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 */
library MerkleProof {
  /**
   * @dev Returns true if a 'leaf' can be proved to be a part of a Merkle tree
   * defined by 'root'. For this, a 'proof' must be provided, containing
   * sibling hashes on the branch from the leaf to the root of the tree. Each
   * pair of leaves and each pair of pre-images are assumed to be sorted.
   */
  function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
    return processProof(proof, leaf) == root;
  }

  /**
   * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
   * from 'leaf' using 'proof'. A 'proof' is valid if and only if the rebuilt
   * hash matches the root of the tree. When processing the proof, the pairs
   * of leafs & pre-images are assumed to be sorted.
   *
   * _Available since v4.4._
   */
  function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
    bytes32 computedHash = leaf;
    for (uint256 i = 0; i < proof.length; i++) {
      bytes32 proofElement = proof[i];
      if (computedHash <= proofElement) {
        // Hash(current computed hash + current element of the proof)
        computedHash = _efficientHash(computedHash, proofElement);
      } else {
        // Hash(current element of the proof + current computed hash)
        computedHash = _efficientHash(proofElement, computedHash);
      }
    }
    return computedHash;
  }

  function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
    assembly {
      mstore(0x00, a)
      mstore(0x20, b)
      value := keccak256(0x00, 0x40)
    }
  }
}

// 
abstract contract ERC721APlus is
  Ownable,
  Teams,
  ERC721A,
  WithdrawableV2,
  ReentrancyGuard,
  Feeable,
  Allowlist
{
  constructor(string memory tokenName, string memory tokenSymbol) ERC721A(tokenName, tokenSymbol, 20, 2000) {}

  uint8 public constant CONTRACT_VERSION = 2;
  uint256 public softCap = 100;
  bool public softCapEnforced = false;
  string public _baseTokenURI = "ipfs://QmPhkMVtcTCs3Y97XygG73aCj3dGhF1xZ4gwXjjWBRxC7i/";
  string public _baseTokenExtension = ".json";
  bool public mintingOpen = false;
  bool public soulbound = false;

  /**
   * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
   *
   * startTokenId - the first token id to be transferred
   * quantity - the amount to be transferred
   *
   * Calling conditions:
   *
   * - When from and to are both non-zero, from's tokenId will be
   * transferred to to.
   * - When from is zero, tokenId will be minted for to.
   */
  function _beforeTokenTransfers(address from, address to, uint256 startTokenId, uint256 quantity) internal override(ERC721A) {
    if (soulbound) {
      require(from == address(0), "Transfers are not permitted at the moment");
    }
    super._beforeTokenTransfers(from, to, startTokenId, quantity);
  }

  /////////////// Admin Mint Functions
  /**
   * @dev Mints a token to an address with a tokenURI.
   * This is owner only and allows a fee-free drop
   * @param _to address of the future owner of the token
   * @param _qty amount of tokens to drop the owner
   */
  function mintToAdminV2(address _to, uint256 _qty) public onlyTeamOrOwner {
    if (_qty == 0) revert MintZeroQuantity();
    if (currentTokenId() + _qty > collectionSize) revert CapExceeded();
    _safeMint(_to, _qty, true);
  }

  /////////////// PUBLIC MINT FUNCTIONS
  /**
   * @dev Mints tokens to an address in batch.
   * fee may or may not be required*
   * @param _to address of the future owner of the token
   * @param _amount number of tokens to mint
   */
  function mintToMultiple(address _to, uint256 _amount) public payable {
    if (_amount == 0) revert MintZeroQuantity();
    if (_amount > maxBatchSize) revert TransactionCapExceeded();
    if (!mintingOpen) revert PublicMintClosed();
    if (mintingOpen && onlyAllowlistMode) revert PublicMintClosed();
    if (currentTokenId() + _amount > softCap && softCapEnforced) revert SoftCapExceeded();
    if (currentTokenId() + _amount > collectionSize) revert CapExceeded();
    if (msg.value != getPrice(_amount)) revert InvalidPayment();
    _safeMint(_to, _amount, false);
  }

  /**
   * @dev Mints tokens to an address in batch and pays to an affiliate.
   * @param _to address of the future owner of the token
   * @param _amount number of tokens to mint
   * @param _code affiliate code
   */
  function mintToMultipleAF(address _to, uint256 _amount, string calldata _code) public payable {
    if (_amount == 0) revert MintZeroQuantity();
    if (_amount > maxBatchSize) revert TransactionCapExceeded();
    if (!mintingOpen) revert PublicMintClosed();
    if (mintingOpen && onlyAllowlistMode) revert PublicMintClosed();
    if (currentTokenId() + _amount > softCap && softCapEnforced) revert SoftCapExceeded();
    if (currentTokenId() + _amount > collectionSize) revert CapExceeded();
    if (msg.value != getPrice(_amount)) revert InvalidPayment();
    if (!affiliateExists[_code]) revert AffiliateNotFound();
    creditAffiliate(_code, msg.value, _amount);
    _safeMint(_to, _amount, false);
  }

  function openMinting() public onlyTeamOrOwner {
    mintingOpen = true;
  }

  function stopMinting() public onlyTeamOrOwner {
    mintingOpen = false;
  }

  ///////////// ALLOWLIST MINTING FUNCTIONS
  /**
   * @dev Mints tokens to an address using an allowlist.
   * fee may or may not be required*
   * @param _to address of the future owner of the token
   * @param _amount number of tokens to mint
   * @param _merkleProof merkle proof array
   */
  function mintToMultipleAL(address _to, uint256 _amount, bytes32[] calldata _merkleProof) public payable {
    if (!onlyAllowlistMode || !mintingOpen) revert AllowlistMintClosed();
    if (!isAllowlisted(_to, _merkleProof)) revert AddressNotAllowlisted();
    if (_amount == 0) revert MintZeroQuantity();
    if (_amount > maxBatchSize) revert TransactionCapExceeded();
    if (currentTokenId() + _amount > softCap && softCapEnforced) revert SoftCapExceeded();
    if (currentTokenId() + _amount > collectionSize) revert CapExceeded();
    if (msg.value != getPrice(_amount)) revert InvalidPayment();
    _safeMint(_to, _amount, false);
  }

  /**
   * @dev Mints tokens to an address using an allowlist.
   * fee may or may not be required*
   * @param _to address of the future owner of the token
   * @param _amount number of tokens to mint
   * @param _merkleProof merkle proof array
   */
  function mintToMultipleALAF(address _to, uint256 _amount, bytes32[] calldata _merkleProof, string calldata _code) public payable {
    if (!onlyAllowlistMode || !mintingOpen) revert AllowlistMintClosed();
    if (!isAllowlisted(_to, _merkleProof)) revert AddressNotAllowlisted();
    if (_amount == 0) revert MintZeroQuantity();
    if (_amount > maxBatchSize) revert TransactionCapExceeded();
    if (currentTokenId() + _amount > softCap && softCapEnforced) revert SoftCapExceeded();
    if (currentTokenId() + _amount > collectionSize) revert CapExceeded();
    if (msg.value != getPrice(_amount)) revert InvalidPayment();
    if (!affiliateExists[_code]) revert AffiliateNotFound();
    creditAffiliate(_code, msg.value, _amount);
    _safeMint(_to, _amount, false);
  }

  /**
   * @dev Enable allowlist minting fully by enabling both flags
   * This is a convenience function for the Rampp user
   */
  function openAllowlistMint() public onlyTeamOrOwner {
    enableAllowlistOnlyMode();
    mintingOpen = true;
  }

  /**
   * @dev Close allowlist minting fully by disabling both flags
   * This is a convenience function for the Rampp user
   */
  function closeAllowlistMint() public onlyTeamOrOwner {
    disableAllowlistOnlyMode();
    mintingOpen = false;
  }

  /**
   * @dev Allows owner to set Max mints per tx
   * @param _newMaxMint maximum amount of tokens allowed to mint per tx. Must be >= 1
   */
  function setMaxMint(uint256 _newMaxMint) public onlyTeamOrOwner {
    if (_newMaxMint == 0) revert ValueCannotBeZero();
    maxBatchSize = _newMaxMint;
  }

  function contractURI() public pure returns (string memory) {
    return "ipfs://QmXHmWuxDQSRK6JYahXzGK7um5tB5cyHahwaChyBj2DQNw";
  }

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

  function _baseURIExtension() internal view virtual override returns (string memory) {
    return _baseTokenExtension;
  }

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

  function setBaseURI(string calldata baseURI) external onlyTeamOrOwner {
    _baseTokenURI = baseURI;
  }

  function setBaseTokenExtension(string calldata baseExtension) external onlyTeamOrOwner {
    _baseTokenExtension = baseExtension;
  }

  function setSoftCap(uint256 _softCap) external onlyTeamOrOwner {
    softCap = _softCap;
  }

  function setSoftCapEnforced(bool _enforced) external onlyTeamOrOwner {
    softCapEnforced = _enforced;
  }

  function getPrice(uint256 _count) public view returns (uint256) {
    return super.getPrice(_count, totalSupply());
  }

  function setSoulbound(bool _sb) external onlyTeamOrOwner {
    soulbound = _sb;
  }

  function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A) returns (bool) {
    return super.supportsInterface(interfaceId);
  }
}

// 
interface IMetaSignals {
    function affiliateStatus(address _address) external view returns (string memory, uint256, uint256, uint256, uint256);
    function addAffiliate(string calldata _code, address _address, uint256 _rate) external;
    function affiliateWithdraw() external;
    function setPriceBase(uint256 _feeInWei) external;
    function setPriceIncrementPercent(uint256 _incrementPercent) external;
    function setPriceIncrementBatch(uint256 _incrementBatch) external;
    function setSoulbound(bool _sb) external;
}

// 
contract MetaMafiosoContract is ERC721APlus {
  constructor() ERC721APlus("MetaMafioso", "METSIG") {}

  function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721APlus) returns (bool) {
    return interfaceId == type(IMetaSignals).interfaceId
        || super.supportsInterface(interfaceId);
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressNotAllowlisted","type":"error"},{"inputs":[],"name":"AffiliateNotFound","type":"error"},{"inputs":[],"name":"AllowlistMintClosed","type":"error"},{"inputs":[],"name":"CapExceeded","type":"error"},{"inputs":[],"name":"DuplicateTeamAddress","type":"error"},{"inputs":[],"name":"ERC721RestrictedApprovalAddressRestricted","type":"error"},{"inputs":[],"name":"InvalidPayment","type":"error"},{"inputs":[],"name":"InvalidTeamAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"NoStateChange","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"PublicMintClosed","type":"error"},{"inputs":[],"name":"SoftCapExceeded","type":"error"},{"inputs":[],"name":"TransactionCapExceeded","type":"error"},{"inputs":[],"name":"ValueCannotBeZero","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"CONTRACT_VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INCREMENT_BATCH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"INCREMENT_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_baseTokenExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_code","type":"string"},{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"addAffiliate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"addToTeam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"affiliateStatus","outputs":[{"internalType":"string","name":"code","type":"string"},{"internalType":"uint256","name":"rate","type":"uint256"},{"internalType":"uint256","name":"mints","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"lifetimeBalance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"affiliateWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closeAllowlistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectionSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"currentTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableAllowlistOnlyMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableAllowlistOnlyMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNextTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"inTeam","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"isAllowlisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxBatchSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_qty","type":"uint256"}],"name":"mintToAdminV2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mintToMultiple","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"_code","type":"string"}],"name":"mintToMultipleAF","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"}],"name":"mintToMultipleAL","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"},{"internalType":"string","name":"_code","type":"string"}],"name":"mintToMultipleALAF","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintingOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextOwnerToExplicitlySet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"onlyAllowlistMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openAllowlistMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"openMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payableAddressCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"payableAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"payableFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"removeFromTeam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"restrictedApprovalAddresses","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bool","name":"_isRestricted","type":"bool"}],"name":"setApprovalRestriction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseExtension","type":"string"}],"name":"setBaseTokenExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxMint","type":"uint256"}],"name":"setMaxMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feeInWei","type":"uint256"}],"name":"setPriceBase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_incrementBatch","type":"uint256"}],"name":"setPriceIncrementBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_incrementPercent","type":"uint256"}],"name":"setPriceIncrementPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_softCap","type":"uint256"}],"name":"setSoftCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enforced","type":"bool"}],"name":"setSoftCapEnforced","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_sb","type":"bool"}],"name":"setSoulbound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"softCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"softCapEnforced","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"soulbound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stopMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_newMerkleRoot","type":"bytes32"}],"name":"updateMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6000600b819055600c5560e0604052738e8772e32f700c623fed03ce29e2de47073db97260a0908152735b409126085223d28f3e2257bcf9ef6fb1c9d73560c0526200005090601090600262000442565b50604080518082019091526002808252606260208301526200007591601191620004ac565b506002601255670de0b6b3a76400006014556006601555606460168190556018805460ff19908116909155601991909155601a80549091169055604080516060810190915260368082526200493e60208301398051620000de91601b91602090910190620004ef565b5060408051808201909152600580825264173539b7b760d91b60209092019182526200010d91601c91620004ef565b50601d805461ffff191690553480156200012657600080fd5b506040518060400160405280600b81526020016a4d6574614d6166696f736f60a81b815250604051806040016040528060068152602001654d455453494760d01b815250818160146107d06000806200018e62000188620003ee60201b60201c565b620003f2565b6daaeb6d7670e522a718067333cd4e3b15620002d35780156200022157604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200020257600080fd5b505af115801562000217573d6000803e3d6000fd5b50505050620002d3565b6001600160a01b03821615620002725760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af290390604401620001e7565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b158015620002b957600080fd5b505af1158015620002ce573d6000803e3d6000fd5b505050505b505060008111620003425760405162461bcd60e51b815260206004820152602e60248201527f455243373231413a20636f6c6c656374696f6e206d757374206861766520612060448201526d6e6f6e7a65726f20737570706c7960901b60648201526084015b60405180910390fd5b60008211620003a45760405162461bcd60e51b815260206004820152602760248201527f455243373231413a206d61782062617463682073697a65206d757374206265206044820152666e6f6e7a65726f60c81b606482015260840162000339565b8351620003b9906004906020870190620004ef565b508251620003cf906005906020860190620004ef565b5060039190915560805250506001600281905560135550620005c09050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280548282559060005260206000209081019282156200049a579160200282015b828111156200049a57825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000463565b50620004a89291506200056c565b5090565b8280548282559060005260206000209081019282156200049a579160200282015b828111156200049a578251829060ff16905591602001919060010190620004cd565b828054620004fd9062000583565b90600052602060002090601f0160209004810192826200052157600085556200049a565b82601f106200053c57805160ff19168380011785556200049a565b828001600101855582156200049a579182015b828111156200049a5782518255916020019190600101906200054f565b5b80821115620004a857600081556001016200056d565b600181811c908216806200059857607f821691505b60208210811415620005ba57634e487b7160e01b600052602260045260246000fd5b50919050565b60805161433f620005ff6000396000818161076401528181610d9f01528181611540015281816118c101528181611e4e015261224d015261433f6000f3fe6080604052600436106104255760003560e01c806370a0823111610229578063b4d4261c1161012e578063df30e54b116100b6578063e985e9c51161007a578063e985e9c514610bd8578063ec34082614610c21578063f2fde38b14610c36578063f4ad071a14610c56578063f8c0fd2014610c7057600080fd5b8063df30e54b14610b49578063dfdedf6914610b69578063e6c6990a14610b89578063e757223014610ba3578063e8a3d48514610bc357600080fd5b8063cfc86f7b116100fd578063cfc86f7b14610ac9578063d547cfb714610ade578063d5cf5c7214610af3578063d7224ba014610b13578063d766401e14610b2957600080fd5b8063b4d4261c14610a61578063b88d4fde14610a74578063c87b56dd14610a94578063caa0f92a14610ab457600080fd5b80638da5cb5b116101b157806395d89b411161018057806395d89b41146109d7578063a1af10ca146109ec578063a22cb46514610a0c578063afe5608b14610a2c578063aff3e10b14610a4157600080fd5b80638da5cb5b146109735780638f4bb49714610991578063906a26e0146109ab57806393660a5c146109c157600080fd5b806379ab3c89116101f857806379ab3c89146108e957806380a75979146108fe57806383c81c411461091e578063853828b61461093e578063891bbe731461095357600080fd5b806370a0823114610870578063715018a614610890578063722edecd146108a557806377c858c1146108d657600080fd5b806338b903331161032f57806345c0f533116102b757806355f804b31161028657806355f804b3146107e657806362ca3c5c146108065780636352211e146108265780636ba9fd38146108465780636d3de8061461085b57600080fd5b806345c0f533146107525780634783f0ef146107865780634f6ccce7146107a6578063547520fe146107c657600080fd5b80633e3e0b12116102fe5780633e3e0b12146106c75780633ecb4051146106dc57806340ccc082146106f257806342842e0e1461071257806343696f181461073257600080fd5b806338b90333146106575780633c0032541461067e5780633deea144146106915780633e07311c146106b157600080fd5b80630fad0f51116103b2578063286c813711610381578063286c8137146105cb5780632913daa0146105eb5780632eb4a7ab146106015780632f745c5914610617578063330067861461063757600080fd5b80630fad0f511461057657806318160ddd1461042a5780631ddd1bf61461059557806323b872dd146105ab57600080fd5b806306fdde03116103f957806306fdde03146104c7578063081812fc146104e9578063095ea7b3146105215780630c834a38146105415780630ee7d0b01461056157600080fd5b80629a9b7b1461042a57806301ffc9a714610452578063043a2a40146104825780630644cefa146104b2575b600080fd5b34801561043657600080fd5b5061043f610c85565b6040519081526020015b60405180910390f35b34801561045e57600080fd5b5061047261046d366004613ede565b610c99565b6040519015158152602001610449565b34801561048e57600080fd5b5061047261049d366004613b3d565b600a6020526000908152604090205460ff1681565b6104c56104c0366004613d32565b610cc4565b005b3480156104d357600080fd5b506104dc610e28565b604051610449919061408c565b3480156104f557600080fd5b50610509610504366004613ec5565b610eba565b6040516001600160a01b039091168152602001610449565b34801561052d57600080fd5b506104c561053c366004613d32565b610f48565b34801561054d57600080fd5b506104c561055c366004613e8b565b6110a5565b34801561056d57600080fd5b506104c56110c0565b34801561058257600080fd5b50601d5461047290610100900460ff1681565b3480156105a157600080fd5b5061043f60145481565b3480156105b757600080fd5b506104c56105c6366004613b92565b6111d5565b3480156105d757600080fd5b5061043f6105e6366004613ec5565b611220565b3480156105f757600080fd5b5061043f60035481565b34801561060d57600080fd5b5061043f60175481565b34801561062357600080fd5b5061043f610632366004613d32565b611241565b34801561064357600080fd5b50610472610652366004613ca9565b6113b8565b34801561066357600080fd5b5061066c600281565b60405160ff9091168152602001610449565b6104c561068c366004613d5c565b61145f565b34801561069d57600080fd5b506104c56106ac366004613f59565b6115c5565b3480156106bd57600080fd5b5061043f60125481565b3480156106d357600080fd5b506104c5611885565b3480156106e857600080fd5b5061043f60165481565b3480156106fe57600080fd5b506104c561070d366004613d32565b611899565b34801561071e57600080fd5b506104c561072d366004613b92565b61191e565b34801561073e57600080fd5b506104c561074d366004613b3d565b611984565b34801561075e57600080fd5b5061043f7f000000000000000000000000000000000000000000000000000000000000000081565b34801561079257600080fd5b506104c56107a1366004613ec5565b611a00565b3480156107b257600080fd5b5061043f6107c1366004613ec5565b611a30565b3480156107d257600080fd5b506104c56107e1366004613ec5565b611a98565b3480156107f257600080fd5b506104c5610801366004613f18565b611ac3565b34801561081257600080fd5b506104c5610821366004613ec5565b611adc565b34801561083257600080fd5b50610509610841366004613ec5565b611ae9565b34801561085257600080fd5b506104c5611afb565b34801561086757600080fd5b506104c5611b12565b34801561087c57600080fd5b5061043f61088b366004613b3d565b611b26565b34801561089c57600080fd5b506104c5611bb7565b3480156108b157600080fd5b506108c56108c0366004613b3d565b611bcb565b60405161044995949392919061409f565b6104c56108e4366004613db5565b611d6d565b3480156108f557600080fd5b506104c5611f21565b34801561090a57600080fd5b506104c5610919366004613ec5565b611f38565b34801561092a57600080fd5b506104c5610939366004613cfb565b611f45565b34801561094a57600080fd5b506104c5611f78565b34801561095f57600080fd5b5061050961096e366004613ec5565b611fbe565b34801561097f57600080fd5b506000546001600160a01b0316610509565b34801561099d57600080fd5b50601d546104729060ff1681565b3480156109b757600080fd5b5061043f60195481565b3480156109cd57600080fd5b5061043f60155481565b3480156109e357600080fd5b506104dc611fe8565b3480156109f857600080fd5b50610472610a07366004613b3d565b611ff7565b348015610a1857600080fd5b506104c5610a27366004613cfb565b612044565b348015610a3857600080fd5b506104c561214e565b348015610a4d57600080fd5b506104c5610a5c366004613f18565b61215e565b6104c5610a6f366004613e3e565b612172565b348015610a8057600080fd5b506104c5610a8f366004613bce565b612314565b348015610aa057600080fd5b506104dc610aaf366004613ec5565b6123b6565b348015610ac057600080fd5b5061043f612423565b348015610ad557600080fd5b506104dc61243d565b348015610aea57600080fd5b506104dc6124cb565b348015610aff57600080fd5b506104c5610b0e366004613ec5565b6124da565b348015610b1f57600080fd5b5061043f600b5481565b348015610b3557600080fd5b506104c5610b44366004613ec5565b6124e7565b348015610b5557600080fd5b506104c5610b64366004613e8b565b6124f4565b348015610b7557600080fd5b506104c5610b84366004613b3d565b612516565b348015610b9557600080fd5b506018546104729060ff1681565b348015610baf57600080fd5b5061043f610bbe366004613ec5565b61258a565b348015610bcf57600080fd5b506104dc61259d565b348015610be457600080fd5b50610472610bf3366004613b5f565b6001600160a01b03918216600090815260096020908152604080832093909416825291909152205460ff1690565b348015610c2d57600080fd5b506104dc6125bd565b348015610c4257600080fd5b506104c5610c51366004613b3d565b6125ca565b348015610c6257600080fd5b50601a546104729060ff1681565b348015610c7c57600080fd5b506104c5612640565b6000610c946002546000190190565b905090565b60006001600160e01b0319821663ab1c6f4960e01b1480610cbe5750610cbe82612650565b92915050565b80610ce25760405163b562e8dd60e01b815260040160405180910390fd5b600354811115610d05576040516393eeb41560e01b815260040160405180910390fd5b601d5460ff16610d28576040516316851fc760e11b815260040160405180910390fd5b601d5460ff168015610d3c575060185460ff165b15610d5a576040516316851fc760e11b815260040160405180910390fd5b60195481610d66610c85565b610d709190614154565b118015610d7f5750601a5460ff165b15610d9d5760405163a9dd28bb60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000081610dc7610c85565b610dd19190614154565b1115610df05760405163a4875a4960e01b815260040160405180910390fd5b610df98161258a565b3414610e185760405163078d696560e31b815260040160405180910390fd5b610e248282600061265b565b5050565b606060048054610e3790614218565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6390614218565b8015610eb05780601f10610e8557610100808354040283529160200191610eb0565b820191906000526020600020905b815481529060010190602001808311610e9357829003601f168201915b5050505050905090565b6000610ec582612676565b610f2c5760405162461bcd60e51b815260206004820152602d60248201527f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560448201526c3c34b9ba32b73a103a37b5b2b760991b60648201526084015b60405180910390fd5b506000908152600860205260409020546001600160a01b031690565b81610f528161268c565b6000610f5d83611ae9565b9050806001600160a01b0316846001600160a01b03161415610fcc5760405162461bcd60e51b815260206004820152602260248201527f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60448201526132b960f11b6064820152608401610f23565b6001600160a01b0384166000908152600a602052604090205460ff16156110065760405163d947c35f60e01b815260040160405180910390fd5b336001600160a01b038216148061102257506110228133610bf3565b6110945760405162461bcd60e51b815260206004820152603960248201527f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656420666f7220616c6c000000000000006064820152608401610f23565b61109f848483612754565b50505050565b6110ad6127b0565b601a805460ff1916911515919091179055565b336000908152600f6020526040812080546110da90614218565b80601f016020809104026020016040519081016040528092919081815260200182805461110690614218565b80156111535780601f1061112857610100808354040283529160200191611153565b820191906000526020600020905b81548152906001019060200180831161113657829003601f168201915b50505050509050600e8160405161116a9190613ff0565b9081526040519081900360200190205460ff166111c95760405162461bcd60e51b815260206004820152601860248201527f596f7520617265206e6f7420616e20616666696c6961746500000000000000006044820152606401610f23565b6111d281612835565b50565b826daaeb6d7670e522a718067333cd4e3b15611215576001600160a01b03811633141561120c57611207848484612a37565b61109f565b61121581612dc4565b61109f848484612a37565b6011818154811061123057600080fd5b600091825260209091200154905081565b600061124c83611b26565b82106112a55760405162461bcd60e51b815260206004820152602260248201527f455243373231413a206f776e657220696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610f23565b60006112af610c85565b905060008060005b83811015611358576000818152600660209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b0316918301919091521561130957805192505b876001600160a01b0316836001600160a01b03161415611345578684141561133757509350610cbe92505050565b8361134181614253565b9450505b508061135081614253565b9150506112b7565b5060405162461bcd60e51b815260206004820152602e60248201527f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060448201526d0deeedccae440c4f240d2dcc8caf60931b6064820152608401610f23565b6017546000906113db576040516363868c5560e11b815260040160405180910390fd5b6040516bffffffffffffffffffffffff19606086901b166020820152600090603401604051602081830303815290604052805190602001209050611456848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506017549150849050612ef7565b95945050505050565b60185460ff1615806114745750601d5460ff16155b15611492576040516309c7220160e31b815260040160405180910390fd5b61149d8483836113b8565b6114ba5760405163097b24df60e41b815260040160405180910390fd5b826114d85760405163b562e8dd60e01b815260040160405180910390fd5b6003548311156114fb576040516393eeb41560e01b815260040160405180910390fd5b60195483611507610c85565b6115119190614154565b1180156115205750601a5460ff165b1561153e5760405163a9dd28bb60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000083611568610c85565b6115729190614154565b11156115915760405163a4875a4960e01b815260040160405180910390fd5b61159a8361258a565b34146115b95760405163078d696560e31b815260040160405180910390fd5b61109f8484600061265b565b6115cd6127b0565b826116095760405162461bcd60e51b815260206004820152600c60248201526b496e76616c696420636f646560a01b6044820152606401610f23565b6001600160a01b0382166116515760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610f23565b600081116116a15760405162461bcd60e51b815260206004820152601e60248201527f52617465206d7573742062652067726561746572207468616e207a65726f00006044820152606401610f23565b6001600160a01b0382166000908152600f6020526040902080546116c490614218565b1590506117135760405162461bcd60e51b815260206004820181905260248201527f416666696c69617465206164647265737320616c7265616479206578697374736044820152606401610f23565b600e8484604051611725929190613fe0565b9081526040519081900360200190205460ff16156117855760405162461bcd60e51b815260206004820152601d60248201527f416666696c6961746520636f646520616c7265616479206578697374730000006044820152606401610f23565b60006040518060a00160405280846001600160a01b0316815260200183815260200160008152602001600081526020016000815250905080600d86866040516117cf929190613fe0565b9081526040805160209281900383018120845181546001600160a01b0319166001600160a01b03909116178155928401516001808501919091559184015160028401556060840151600384015560809093015160049092019190915590600e9061183c9088908890613fe0565b9081526040805160209281900383019020805460ff1916931515939093179092556001600160a01b0385166000908152600f9091522061187d908686613a05565b505050505050565b61188d6127b0565b601d805460ff19169055565b6118a16127b0565b806118bf5760405163b562e8dd60e01b815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000816118e9610c85565b6118f39190614154565b11156119125760405163a4875a4960e01b815260040160405180910390fd5b610e248282600161265b565b826daaeb6d7670e522a718067333cd4e3b15611969576001600160a01b0381163314156119605761120784848460405180602001604052806000815250612314565b61196981612dc4565b61109f84848460405180602001604052806000815250612314565b61198c612f0d565b6001600160a01b0381166119b25760405162afb37360e31b815260040160405180910390fd5b6119bb81611ff7565b156119d957604051631002377360e01b815260040160405180910390fd5b6001600160a01b03166000908152600160208190526040909120805460ff19169091179055565b611a086127b0565b601754811415611a2b5760405163a28a88c160e01b815260040160405180910390fd5b601755565b6000611a3a610c85565b8210611a945760405162461bcd60e51b815260206004820152602360248201527f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f756044820152626e647360e81b6064820152608401610f23565b5090565b611aa06127b0565b80611abe576040516363868c5560e11b815260040160405180910390fd5b600355565b611acb6127b0565b611ad7601b8383613a05565b505050565b611ae46127b0565b601455565b6000611af482612f67565b5192915050565b611b036127b0565b601d805460ff19166001179055565b611b1a6127b0565b6018805460ff19169055565b60006001600160a01b038216611b925760405162461bcd60e51b815260206004820152602b60248201527f455243373231413a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b6064820152608401610f23565b506001600160a01b03166000908152600760205260409020546001600160801b031690565b611bbf612f0d565b611bc96000613095565b565b60606000806000806000600f6000886001600160a01b03166001600160a01b031681526020019081526020016000208054611c0590614218565b80601f0160208091040260200160405190810160405280929190818152602001828054611c3190614218565b8015611c7e5780601f10611c5357610100808354040283529160200191611c7e565b820191906000526020600020905b815481529060010190602001808311611c6157829003601f168201915b50505050509050600e81604051611c959190613ff0565b9081526040519081900360200190205460ff16611cf45760405162461bcd60e51b815260206004820152601b60248201527f41646472657373206973206e6f7420616e20616666696c6961746500000000006044820152606401610f23565b6000600d82604051611d069190613ff0565b908152604080516020928190038301812060a08201835280546001600160a01b03168252600181015493820184905260028101549282018390526003810154606083018190526004909101546080909201829052949b929a50985096509194509092505050565b60185460ff161580611d825750601d5460ff16155b15611da0576040516309c7220160e31b815260040160405180910390fd5b611dab8685856113b8565b611dc85760405163097b24df60e41b815260040160405180910390fd5b84611de65760405163b562e8dd60e01b815260040160405180910390fd5b600354851115611e09576040516393eeb41560e01b815260040160405180910390fd5b60195485611e15610c85565b611e1f9190614154565b118015611e2e5750601a5460ff165b15611e4c5760405163a9dd28bb60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000085611e76610c85565b611e809190614154565b1115611e9f5760405163a4875a4960e01b815260040160405180910390fd5b611ea88561258a565b3414611ec75760405163078d696560e31b815260040160405180910390fd5b600e8282604051611ed9929190613fe0565b9081526040519081900360200190205460ff16611f095760405163fa4f231b60e01b815260040160405180910390fd5b611f15828234886130e5565b61187d8686600061265b565b611f296127b0565b6018805460ff19166001179055565b611f406127b0565b601555565b611f4d6127b0565b6001600160a01b03919091166000908152600a60205260409020805460ff1916911515919091179055565b611f806127b0565b600c544790600090611f9290836141d5565b905060008111611fb5576040516363868c5560e11b815260040160405180910390fd5b610e24816131c3565b60108181548110611fce57600080fd5b6000918252602090912001546001600160a01b0316905081565b606060058054610e3790614218565b60006001600160a01b03821661201f5760405162afb37360e31b815260040160405180910390fd5b506001600160a01b031660009081526001602081905260409091205460ff1615151490565b8161204e8161268c565b6001600160a01b0383163314156120a75760405162461bcd60e51b815260206004820152601a60248201527f455243373231413a20617070726f766520746f2063616c6c65720000000000006044820152606401610f23565b6001600160a01b0383166000908152600a602052604090205460ff16156120e15760405163d947c35f60e01b815260040160405180910390fd5b3360008181526009602090815260408083206001600160a01b03881680855290835292819020805460ff191687151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6121566127b0565b61188d611b12565b6121666127b0565b611ad7601c8383613a05565b826121905760405163b562e8dd60e01b815260040160405180910390fd5b6003548311156121b3576040516393eeb41560e01b815260040160405180910390fd5b601d5460ff166121d6576040516316851fc760e11b815260040160405180910390fd5b601d5460ff1680156121ea575060185460ff165b15612208576040516316851fc760e11b815260040160405180910390fd5b60195483612214610c85565b61221e9190614154565b11801561222d5750601a5460ff165b1561224b5760405163a9dd28bb60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000083612275610c85565b61227f9190614154565b111561229e5760405163a4875a4960e01b815260040160405180910390fd5b6122a78361258a565b34146122c65760405163078d696560e31b815260040160405180910390fd5b600e82826040516122d8929190613fe0565b9081526040519081900360200190205460ff166123085760405163fa4f231b60e01b815260040160405180910390fd5b6115b9828234866130e5565b836daaeb6d7670e522a718067333cd4e3b1561237c576001600160a01b03811633141561237357612346858585612a37565b61235285858585613250565b61236e5760405162461bcd60e51b8152600401610f23906140d6565b6123af565b61237c81612dc4565b612387858585612a37565b61239385858585613250565b6123af5760405162461bcd60e51b8152600401610f23906140d6565b5050505050565b606060006123c26124cb565b905060006123ce61335d565b905060008251116123ee576040518060200160405280600081525061241b565b816123f88561336c565b8260405160200161240b9392919061400c565b6040516020818303038152906040525b949350505050565b60006124326002546000190190565b610c94906001614154565b601b805461244a90614218565b80601f016020809104026020016040519081016040528092919081815260200182805461247690614218565b80156124c35780601f10612498576101008083540402835291602001916124c3565b820191906000526020600020905b8154815290600101906020018083116124a657829003601f168201915b505050505081565b6060601b8054610e3790614218565b6124e26127b0565b601955565b6124ef6127b0565b601655565b6124fc6127b0565b601d80549115156101000261ff0019909216919091179055565b61251e612f0d565b6001600160a01b0381166125445760405162afb37360e31b815260040160405180910390fd5b61254d81611ff7565b6125695760405162afb37360e31b815260040160405180910390fd5b6001600160a01b03166000908152600160205260409020805460ff19169055565b6000610cbe82612598610c85565b613408565b60606040518060600160405280603581526020016142d560359139905090565b601c805461244a90614218565b6125d2612f0d565b6001600160a01b0381166126375760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610f23565b6111d281613095565b6126486127b0565b611b03611f21565b6000610cbe8261346d565b611ad7838383604051806020016040528060008152506134d8565b600081600111158015610cbe5750506002541190565b6daaeb6d7670e522a718067333cd4e3b156111d257604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c61711349060440160206040518083038186803b1580156126f457600080fd5b505afa158015612708573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061272c9190613ea8565b6111d257604051633b79c77360e21b81526001600160a01b0382166004820152602401610f23565b60008281526008602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600080546001600160a01b03163390811491906127cc90611ff7565b905081806127d75750805b610e245760405162461bcd60e51b815260206004820152602960248201527f5465616d3a2063616c6c6572206973206e6f7420746865206f776e6572206f726044820152681034b7102a32b0b69760b91b6064820152608401610f23565b600e816040516128459190613ff0565b9081526040519081900360200190205460ff166128a45760405162461bcd60e51b815260206004820152601860248201527f416666696c6961746520646f6573206e6f7420657869737400000000000000006044820152606401610f23565b6000600d826040516128b69190613ff0565b90815260405190819003602001902060028101548154919250906001600160a01b0316816129305760405162461bcd60e51b815260206004820152602160248201527f416666696c6961746520646f6573206e6f74206861766520612062616c616e636044820152606560f81b6064820152608401610f23565b6001600160a01b0381166129785760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610f23565b6000816001600160a01b03168360405160006040518083038185875af1925050503d80600081146129c5576040519150601f19603f3d011682016040523d82523d6000602084013e6129ca565b606091505b5050905080612a0f5760405162461bcd60e51b815260206004820152601160248201527015da5d1a191c985dd85b0819985a5b1959607a1b6044820152606401610f23565b6000846002018190555082600c6000828254612a2b91906141d5565b90915550505050505050565b6000612a4282612f67565b80519091506000906001600160a01b0316336001600160a01b03161480612a79575033612a6e84610eba565b6001600160a01b0316145b80612a8b57508151612a8b9033610bf3565b905080612af55760405162461bcd60e51b815260206004820152603260248201527f455243373231413a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b6064820152608401610f23565b846001600160a01b031682600001516001600160a01b031614612b695760405162461bcd60e51b815260206004820152602660248201527f455243373231413a207472616e736665722066726f6d20696e636f72726563746044820152651037bbb732b960d11b6064820152608401610f23565b6001600160a01b038416612bcd5760405162461bcd60e51b815260206004820152602560248201527f455243373231413a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610f23565b612bda85858560016137b2565b612bea6000848460000151612754565b6001600160a01b0385166000908152600760205260408120805460019290612c1c9084906001600160801b03166141ad565b82546101009290920a6001600160801b038181021990931691831602179091556001600160a01b03861660009081526007602052604081208054600194509092612c6891859116614129565b82546001600160801b039182166101009390930a9283029190920219909116179055506040805180820182526001600160a01b0380871682526001600160401b03428116602080850191825260008981526006909152948520935184549151909216600160a01b026001600160e01b03199091169190921617179055612cef846001614154565b6000818152600660205260409020549091506001600160a01b0316612d7e57612d1781612676565b15612d7e5760408051808201825284516001600160a01b0390811682526020808701516001600160401b039081168285019081526000878152600690935294909120925183549451909116600160a01b026001600160e01b03199094169116179190911790555b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461187d565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c61711349060440160206040518083038186803b158015612e0e57600080fd5b505afa158015612e22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e469190613ea8565b8015612ed85750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c61711349060440160206040518083038186803b158015612ea057600080fd5b505afa158015612eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ed89190613ea8565b6111d257604051633b79c77360e21b8152336004820152602401610f23565b600082612f04858461382b565b14949350505050565b6000546001600160a01b03163314611bc95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610f23565b60408051808201909152600080825260208201528180600111158015612f8e575060025481105b15613035576000818152600660209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b03169183019190915215612fdf579392505050565b50600019016000818152600660209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b03169183019190915215613030579392505050565b612fdf565b60405162461bcd60e51b815260206004820152602f60248201527f455243373231413a20756e61626c6520746f2064657465726d696e652074686560448201526e1037bbb732b91037b3103a37b5b2b760891b6064820152608401610f23565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600e84846040516130f7929190613fe0565b9081526040519081900360200190205460ff161561109f576000600d8585604051613123929190613fe0565b9081526020016040518091039020905060006064826001015485613147919061418e565b613151919061416c565b9050828260040160008282546131679190614154565b92505081905550808260020160008282546131829190614154565b925050819055508082600301600082825461319d9190614154565b9250508190555080600c60008282546131b69190614154565b9091555050505050505050565b60005b601254811015610e245761323e601082815481106131e6576131e6614284565b9060005260206000200160009054906101000a90046001600160a01b031660646011848154811061321957613219614284565b90600052602060002001548561322f919061418e565b613239919061416c565b613897565b8061324881614253565b9150506131c6565b60006001600160a01b0384163b1561335257604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061329490339089908890889060040161404f565b602060405180830381600087803b1580156132ae57600080fd5b505af19250505080156132de575060408051601f3d908101601f191682019092526132db91810190613efb565b60015b613338573d80801561330c576040519150601f19603f3d011682016040523d82523d6000602084013e613311565b606091505b5080516133305760405162461bcd60e51b8152600401610f23906140d6565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061241b565b506001949350505050565b6060601c8054610e3790614218565b606060006133798361392d565b60010190506000816001600160401b038111156133985761339861429a565b6040519080825280601f01601f1916602001820160405280156133c2576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846133fb57613400565b6133cc565b509392505050565b60008060165483613419919061416c565b60145490915060005b828110156134625760646015548361343a919061418e565b613444919061416c565b61344e9083614154565b91508061345a81614253565b915050613422565b50611456858261418e565b60006001600160e01b031982166380ac58cd60e01b148061349e57506001600160e01b03198216635b5e139f60e01b145b806134b957506001600160e01b0319821663780e9d6360e01b145b80610cbe57506301ffc9a760e01b6001600160e01b0319831614610cbe565b6002546001600160a01b03851661353b5760405162461bcd60e51b815260206004820152602160248201527f455243373231413a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610f23565b61354481612676565b156135915760405162461bcd60e51b815260206004820152601d60248201527f455243373231413a20746f6b656e20616c7265616479206d696e7465640000006044820152606401610f23565b826135f3576003548411156135f35760405162461bcd60e51b815260206004820152602260248201527f455243373231413a207175616e7469747920746f206d696e7420746f6f2068696044820152610ced60f31b6064820152608401610f23565b61360060008683876137b2565b6001600160a01b0385166000908152600760209081526040918290208251808401845290546001600160801b038082168352600160801b909104169181019190915281518083019092528051909190819061365c908890614129565b6001600160801b03168152602001856136755786613678565b60005b83602001516136879190614129565b6001600160801b039081169091526001600160a01b0380891660008181526007602090815260408083208751978301518716600160801b029790961696909617909455845180860186529182526001600160401b034281168386019081528883526006909552948120915182549451909516600160a01b026001600160e01b031990941694909216939093179190911790915582905b868110156137a65760405182906001600160a01b038a16906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a461376a6000898488613250565b6137865760405162461bcd60e51b8152600401610f23906140d6565b8161379081614253565b925050808061379e90614253565b91505061371d565b50600255505050505050565b601d54610100900460ff1615611207576001600160a01b038416156112075760405162461bcd60e51b815260206004820152602960248201527f5472616e736665727320617265206e6f74207065726d697474656420617420746044820152681a19481b5bdb595b9d60ba1b6064820152608401610f23565b600081815b845181101561340057600085828151811061384d5761384d614284565b602002602001015190508083116138735760008381526020829052604090209250613884565b600081815260208490526040902092505b508061388f81614253565b915050613830565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146138e4576040519150601f19603f3d011682016040523d82523d6000602084013e6138e9565b606091505b5050905080611ad75760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610f23565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061396c5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310613998576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106139b657662386f26fc10000830492506010015b6305f5e10083106139ce576305f5e100830492506008015b61271083106139e257612710830492506004015b606483106139f4576064830492506002015b600a8310610cbe5760010192915050565b828054613a1190614218565b90600052602060002090601f016020900481019282613a335760008555613a79565b82601f10613a4c5782800160ff19823516178555613a79565b82800160010185558215613a79579182015b82811115613a79578235825591602001919060010190613a5e565b50611a949291505b80821115611a945760008155600101613a81565b80356001600160a01b0381168114613aac57600080fd5b919050565b60008083601f840112613ac357600080fd5b5081356001600160401b03811115613ada57600080fd5b6020830191508360208260051b8501011115613af557600080fd5b9250929050565b60008083601f840112613b0e57600080fd5b5081356001600160401b03811115613b2557600080fd5b602083019150836020828501011115613af557600080fd5b600060208284031215613b4f57600080fd5b613b5882613a95565b9392505050565b60008060408385031215613b7257600080fd5b613b7b83613a95565b9150613b8960208401613a95565b90509250929050565b600080600060608486031215613ba757600080fd5b613bb084613a95565b9250613bbe60208501613a95565b9150604084013590509250925092565b60008060008060808587031215613be457600080fd5b613bed85613a95565b9350613bfb60208601613a95565b92506040850135915060608501356001600160401b0380821115613c1e57600080fd5b818701915087601f830112613c3257600080fd5b813581811115613c4457613c4461429a565b604051601f8201601f19908116603f01168101908382118183101715613c6c57613c6c61429a565b816040528281528a6020848701011115613c8557600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600080600060408486031215613cbe57600080fd5b613cc784613a95565b925060208401356001600160401b03811115613ce257600080fd5b613cee86828701613ab1565b9497909650939450505050565b60008060408385031215613d0e57600080fd5b613d1783613a95565b91506020830135613d27816142b0565b809150509250929050565b60008060408385031215613d4557600080fd5b613d4e83613a95565b946020939093013593505050565b60008060008060608587031215613d7257600080fd5b613d7b85613a95565b93506020850135925060408501356001600160401b03811115613d9d57600080fd5b613da987828801613ab1565b95989497509550505050565b60008060008060008060808789031215613dce57600080fd5b613dd787613a95565b95506020870135945060408701356001600160401b0380821115613dfa57600080fd5b613e068a838b01613ab1565b90965094506060890135915080821115613e1f57600080fd5b50613e2c89828a01613afc565b979a9699509497509295939492505050565b60008060008060608587031215613e5457600080fd5b613e5d85613a95565b93506020850135925060408501356001600160401b03811115613e7f57600080fd5b613da987828801613afc565b600060208284031215613e9d57600080fd5b8135613b58816142b0565b600060208284031215613eba57600080fd5b8151613b58816142b0565b600060208284031215613ed757600080fd5b5035919050565b600060208284031215613ef057600080fd5b8135613b58816142be565b600060208284031215613f0d57600080fd5b8151613b58816142be565b60008060208385031215613f2b57600080fd5b82356001600160401b03811115613f4157600080fd5b613f4d85828601613afc565b90969095509350505050565b60008060008060608587031215613f6f57600080fd5b84356001600160401b03811115613f8557600080fd5b613f9187828801613afc565b9095509350613fa4905060208601613a95565b9396929550929360400135925050565b60008151808452613fcc8160208601602086016141ec565b601f01601f19169290920160200192915050565b8183823760009101908152919050565b600082516140028184602087016141ec565b9190910192915050565b6000845161401e8184602089016141ec565b8451908301906140328183602089016141ec565b84519101906140458183602088016141ec565b0195945050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061408290830184613fb4565b9695505050505050565b602081526000613b586020830184613fb4565b60a0815260006140b260a0830188613fb4565b90508560208301528460408301528360608301528260808301529695505050505050565b60208082526033908201527f455243373231413a207472616e7366657220746f206e6f6e204552433732315260408201527232b1b2b4bb32b91034b6b83632b6b2b73a32b960691b606082015260800190565b60006001600160801b0380831681851680830382111561414b5761414b61426e565b01949350505050565b600082198211156141675761416761426e565b500190565b60008261418957634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156141a8576141a861426e565b500290565b60006001600160801b03838116908316818110156141cd576141cd61426e565b039392505050565b6000828210156141e7576141e761426e565b500390565b60005b838110156142075781810151838201526020016141ef565b8381111561109f5750506000910152565b600181811c9082168061422c57607f821691505b6020821081141561424d57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156142675761426761426e565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b80151581146111d257600080fd5b6001600160e01b0319811681146111d257600080fdfe697066733a2f2f516d58486d577578445153524b364a596168587a474b37756d3574423563794861687761436879426a3244514e77a264697066735822122013bec15537f6e54f9f8d4a7efee224977473e847dc899c97caf396ce2e75b78764736f6c63430008070033697066733a2f2f516d50686b4d5674635443733359393758796747373361436a336447684631785a346777586a6a574252784337692f

Deployed Bytecode

0x6080604052600436106104255760003560e01c806370a0823111610229578063b4d4261c1161012e578063df30e54b116100b6578063e985e9c51161007a578063e985e9c514610bd8578063ec34082614610c21578063f2fde38b14610c36578063f4ad071a14610c56578063f8c0fd2014610c7057600080fd5b8063df30e54b14610b49578063dfdedf6914610b69578063e6c6990a14610b89578063e757223014610ba3578063e8a3d48514610bc357600080fd5b8063cfc86f7b116100fd578063cfc86f7b14610ac9578063d547cfb714610ade578063d5cf5c7214610af3578063d7224ba014610b13578063d766401e14610b2957600080fd5b8063b4d4261c14610a61578063b88d4fde14610a74578063c87b56dd14610a94578063caa0f92a14610ab457600080fd5b80638da5cb5b116101b157806395d89b411161018057806395d89b41146109d7578063a1af10ca146109ec578063a22cb46514610a0c578063afe5608b14610a2c578063aff3e10b14610a4157600080fd5b80638da5cb5b146109735780638f4bb49714610991578063906a26e0146109ab57806393660a5c146109c157600080fd5b806379ab3c89116101f857806379ab3c89146108e957806380a75979146108fe57806383c81c411461091e578063853828b61461093e578063891bbe731461095357600080fd5b806370a0823114610870578063715018a614610890578063722edecd146108a557806377c858c1146108d657600080fd5b806338b903331161032f57806345c0f533116102b757806355f804b31161028657806355f804b3146107e657806362ca3c5c146108065780636352211e146108265780636ba9fd38146108465780636d3de8061461085b57600080fd5b806345c0f533146107525780634783f0ef146107865780634f6ccce7146107a6578063547520fe146107c657600080fd5b80633e3e0b12116102fe5780633e3e0b12146106c75780633ecb4051146106dc57806340ccc082146106f257806342842e0e1461071257806343696f181461073257600080fd5b806338b90333146106575780633c0032541461067e5780633deea144146106915780633e07311c146106b157600080fd5b80630fad0f51116103b2578063286c813711610381578063286c8137146105cb5780632913daa0146105eb5780632eb4a7ab146106015780632f745c5914610617578063330067861461063757600080fd5b80630fad0f511461057657806318160ddd1461042a5780631ddd1bf61461059557806323b872dd146105ab57600080fd5b806306fdde03116103f957806306fdde03146104c7578063081812fc146104e9578063095ea7b3146105215780630c834a38146105415780630ee7d0b01461056157600080fd5b80629a9b7b1461042a57806301ffc9a714610452578063043a2a40146104825780630644cefa146104b2575b600080fd5b34801561043657600080fd5b5061043f610c85565b6040519081526020015b60405180910390f35b34801561045e57600080fd5b5061047261046d366004613ede565b610c99565b6040519015158152602001610449565b34801561048e57600080fd5b5061047261049d366004613b3d565b600a6020526000908152604090205460ff1681565b6104c56104c0366004613d32565b610cc4565b005b3480156104d357600080fd5b506104dc610e28565b604051610449919061408c565b3480156104f557600080fd5b50610509610504366004613ec5565b610eba565b6040516001600160a01b039091168152602001610449565b34801561052d57600080fd5b506104c561053c366004613d32565b610f48565b34801561054d57600080fd5b506104c561055c366004613e8b565b6110a5565b34801561056d57600080fd5b506104c56110c0565b34801561058257600080fd5b50601d5461047290610100900460ff1681565b3480156105a157600080fd5b5061043f60145481565b3480156105b757600080fd5b506104c56105c6366004613b92565b6111d5565b3480156105d757600080fd5b5061043f6105e6366004613ec5565b611220565b3480156105f757600080fd5b5061043f60035481565b34801561060d57600080fd5b5061043f60175481565b34801561062357600080fd5b5061043f610632366004613d32565b611241565b34801561064357600080fd5b50610472610652366004613ca9565b6113b8565b34801561066357600080fd5b5061066c600281565b60405160ff9091168152602001610449565b6104c561068c366004613d5c565b61145f565b34801561069d57600080fd5b506104c56106ac366004613f59565b6115c5565b3480156106bd57600080fd5b5061043f60125481565b3480156106d357600080fd5b506104c5611885565b3480156106e857600080fd5b5061043f60165481565b3480156106fe57600080fd5b506104c561070d366004613d32565b611899565b34801561071e57600080fd5b506104c561072d366004613b92565b61191e565b34801561073e57600080fd5b506104c561074d366004613b3d565b611984565b34801561075e57600080fd5b5061043f7f00000000000000000000000000000000000000000000000000000000000007d081565b34801561079257600080fd5b506104c56107a1366004613ec5565b611a00565b3480156107b257600080fd5b5061043f6107c1366004613ec5565b611a30565b3480156107d257600080fd5b506104c56107e1366004613ec5565b611a98565b3480156107f257600080fd5b506104c5610801366004613f18565b611ac3565b34801561081257600080fd5b506104c5610821366004613ec5565b611adc565b34801561083257600080fd5b50610509610841366004613ec5565b611ae9565b34801561085257600080fd5b506104c5611afb565b34801561086757600080fd5b506104c5611b12565b34801561087c57600080fd5b5061043f61088b366004613b3d565b611b26565b34801561089c57600080fd5b506104c5611bb7565b3480156108b157600080fd5b506108c56108c0366004613b3d565b611bcb565b60405161044995949392919061409f565b6104c56108e4366004613db5565b611d6d565b3480156108f557600080fd5b506104c5611f21565b34801561090a57600080fd5b506104c5610919366004613ec5565b611f38565b34801561092a57600080fd5b506104c5610939366004613cfb565b611f45565b34801561094a57600080fd5b506104c5611f78565b34801561095f57600080fd5b5061050961096e366004613ec5565b611fbe565b34801561097f57600080fd5b506000546001600160a01b0316610509565b34801561099d57600080fd5b50601d546104729060ff1681565b3480156109b757600080fd5b5061043f60195481565b3480156109cd57600080fd5b5061043f60155481565b3480156109e357600080fd5b506104dc611fe8565b3480156109f857600080fd5b50610472610a07366004613b3d565b611ff7565b348015610a1857600080fd5b506104c5610a27366004613cfb565b612044565b348015610a3857600080fd5b506104c561214e565b348015610a4d57600080fd5b506104c5610a5c366004613f18565b61215e565b6104c5610a6f366004613e3e565b612172565b348015610a8057600080fd5b506104c5610a8f366004613bce565b612314565b348015610aa057600080fd5b506104dc610aaf366004613ec5565b6123b6565b348015610ac057600080fd5b5061043f612423565b348015610ad557600080fd5b506104dc61243d565b348015610aea57600080fd5b506104dc6124cb565b348015610aff57600080fd5b506104c5610b0e366004613ec5565b6124da565b348015610b1f57600080fd5b5061043f600b5481565b348015610b3557600080fd5b506104c5610b44366004613ec5565b6124e7565b348015610b5557600080fd5b506104c5610b64366004613e8b565b6124f4565b348015610b7557600080fd5b506104c5610b84366004613b3d565b612516565b348015610b9557600080fd5b506018546104729060ff1681565b348015610baf57600080fd5b5061043f610bbe366004613ec5565b61258a565b348015610bcf57600080fd5b506104dc61259d565b348015610be457600080fd5b50610472610bf3366004613b5f565b6001600160a01b03918216600090815260096020908152604080832093909416825291909152205460ff1690565b348015610c2d57600080fd5b506104dc6125bd565b348015610c4257600080fd5b506104c5610c51366004613b3d565b6125ca565b348015610c6257600080fd5b50601a546104729060ff1681565b348015610c7c57600080fd5b506104c5612640565b6000610c946002546000190190565b905090565b60006001600160e01b0319821663ab1c6f4960e01b1480610cbe5750610cbe82612650565b92915050565b80610ce25760405163b562e8dd60e01b815260040160405180910390fd5b600354811115610d05576040516393eeb41560e01b815260040160405180910390fd5b601d5460ff16610d28576040516316851fc760e11b815260040160405180910390fd5b601d5460ff168015610d3c575060185460ff165b15610d5a576040516316851fc760e11b815260040160405180910390fd5b60195481610d66610c85565b610d709190614154565b118015610d7f5750601a5460ff165b15610d9d5760405163a9dd28bb60e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000007d081610dc7610c85565b610dd19190614154565b1115610df05760405163a4875a4960e01b815260040160405180910390fd5b610df98161258a565b3414610e185760405163078d696560e31b815260040160405180910390fd5b610e248282600061265b565b5050565b606060048054610e3790614218565b80601f0160208091040260200160405190810160405280929190818152602001828054610e6390614218565b8015610eb05780601f10610e8557610100808354040283529160200191610eb0565b820191906000526020600020905b815481529060010190602001808311610e9357829003601f168201915b5050505050905090565b6000610ec582612676565b610f2c5760405162461bcd60e51b815260206004820152602d60248201527f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560448201526c3c34b9ba32b73a103a37b5b2b760991b60648201526084015b60405180910390fd5b506000908152600860205260409020546001600160a01b031690565b81610f528161268c565b6000610f5d83611ae9565b9050806001600160a01b0316846001600160a01b03161415610fcc5760405162461bcd60e51b815260206004820152602260248201527f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60448201526132b960f11b6064820152608401610f23565b6001600160a01b0384166000908152600a602052604090205460ff16156110065760405163d947c35f60e01b815260040160405180910390fd5b336001600160a01b038216148061102257506110228133610bf3565b6110945760405162461bcd60e51b815260206004820152603960248201527f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656420666f7220616c6c000000000000006064820152608401610f23565b61109f848483612754565b50505050565b6110ad6127b0565b601a805460ff1916911515919091179055565b336000908152600f6020526040812080546110da90614218565b80601f016020809104026020016040519081016040528092919081815260200182805461110690614218565b80156111535780601f1061112857610100808354040283529160200191611153565b820191906000526020600020905b81548152906001019060200180831161113657829003601f168201915b50505050509050600e8160405161116a9190613ff0565b9081526040519081900360200190205460ff166111c95760405162461bcd60e51b815260206004820152601860248201527f596f7520617265206e6f7420616e20616666696c6961746500000000000000006044820152606401610f23565b6111d281612835565b50565b826daaeb6d7670e522a718067333cd4e3b15611215576001600160a01b03811633141561120c57611207848484612a37565b61109f565b61121581612dc4565b61109f848484612a37565b6011818154811061123057600080fd5b600091825260209091200154905081565b600061124c83611b26565b82106112a55760405162461bcd60e51b815260206004820152602260248201527f455243373231413a206f776e657220696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610f23565b60006112af610c85565b905060008060005b83811015611358576000818152600660209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b0316918301919091521561130957805192505b876001600160a01b0316836001600160a01b03161415611345578684141561133757509350610cbe92505050565b8361134181614253565b9450505b508061135081614253565b9150506112b7565b5060405162461bcd60e51b815260206004820152602e60248201527f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060448201526d0deeedccae440c4f240d2dcc8caf60931b6064820152608401610f23565b6017546000906113db576040516363868c5560e11b815260040160405180910390fd5b6040516bffffffffffffffffffffffff19606086901b166020820152600090603401604051602081830303815290604052805190602001209050611456848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506017549150849050612ef7565b95945050505050565b60185460ff1615806114745750601d5460ff16155b15611492576040516309c7220160e31b815260040160405180910390fd5b61149d8483836113b8565b6114ba5760405163097b24df60e41b815260040160405180910390fd5b826114d85760405163b562e8dd60e01b815260040160405180910390fd5b6003548311156114fb576040516393eeb41560e01b815260040160405180910390fd5b60195483611507610c85565b6115119190614154565b1180156115205750601a5460ff165b1561153e5760405163a9dd28bb60e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000007d083611568610c85565b6115729190614154565b11156115915760405163a4875a4960e01b815260040160405180910390fd5b61159a8361258a565b34146115b95760405163078d696560e31b815260040160405180910390fd5b61109f8484600061265b565b6115cd6127b0565b826116095760405162461bcd60e51b815260206004820152600c60248201526b496e76616c696420636f646560a01b6044820152606401610f23565b6001600160a01b0382166116515760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610f23565b600081116116a15760405162461bcd60e51b815260206004820152601e60248201527f52617465206d7573742062652067726561746572207468616e207a65726f00006044820152606401610f23565b6001600160a01b0382166000908152600f6020526040902080546116c490614218565b1590506117135760405162461bcd60e51b815260206004820181905260248201527f416666696c69617465206164647265737320616c7265616479206578697374736044820152606401610f23565b600e8484604051611725929190613fe0565b9081526040519081900360200190205460ff16156117855760405162461bcd60e51b815260206004820152601d60248201527f416666696c6961746520636f646520616c7265616479206578697374730000006044820152606401610f23565b60006040518060a00160405280846001600160a01b0316815260200183815260200160008152602001600081526020016000815250905080600d86866040516117cf929190613fe0565b9081526040805160209281900383018120845181546001600160a01b0319166001600160a01b03909116178155928401516001808501919091559184015160028401556060840151600384015560809093015160049092019190915590600e9061183c9088908890613fe0565b9081526040805160209281900383019020805460ff1916931515939093179092556001600160a01b0385166000908152600f9091522061187d908686613a05565b505050505050565b61188d6127b0565b601d805460ff19169055565b6118a16127b0565b806118bf5760405163b562e8dd60e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000007d0816118e9610c85565b6118f39190614154565b11156119125760405163a4875a4960e01b815260040160405180910390fd5b610e248282600161265b565b826daaeb6d7670e522a718067333cd4e3b15611969576001600160a01b0381163314156119605761120784848460405180602001604052806000815250612314565b61196981612dc4565b61109f84848460405180602001604052806000815250612314565b61198c612f0d565b6001600160a01b0381166119b25760405162afb37360e31b815260040160405180910390fd5b6119bb81611ff7565b156119d957604051631002377360e01b815260040160405180910390fd5b6001600160a01b03166000908152600160208190526040909120805460ff19169091179055565b611a086127b0565b601754811415611a2b5760405163a28a88c160e01b815260040160405180910390fd5b601755565b6000611a3a610c85565b8210611a945760405162461bcd60e51b815260206004820152602360248201527f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f756044820152626e647360e81b6064820152608401610f23565b5090565b611aa06127b0565b80611abe576040516363868c5560e11b815260040160405180910390fd5b600355565b611acb6127b0565b611ad7601b8383613a05565b505050565b611ae46127b0565b601455565b6000611af482612f67565b5192915050565b611b036127b0565b601d805460ff19166001179055565b611b1a6127b0565b6018805460ff19169055565b60006001600160a01b038216611b925760405162461bcd60e51b815260206004820152602b60248201527f455243373231413a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b6064820152608401610f23565b506001600160a01b03166000908152600760205260409020546001600160801b031690565b611bbf612f0d565b611bc96000613095565b565b60606000806000806000600f6000886001600160a01b03166001600160a01b031681526020019081526020016000208054611c0590614218565b80601f0160208091040260200160405190810160405280929190818152602001828054611c3190614218565b8015611c7e5780601f10611c5357610100808354040283529160200191611c7e565b820191906000526020600020905b815481529060010190602001808311611c6157829003601f168201915b50505050509050600e81604051611c959190613ff0565b9081526040519081900360200190205460ff16611cf45760405162461bcd60e51b815260206004820152601b60248201527f41646472657373206973206e6f7420616e20616666696c6961746500000000006044820152606401610f23565b6000600d82604051611d069190613ff0565b908152604080516020928190038301812060a08201835280546001600160a01b03168252600181015493820184905260028101549282018390526003810154606083018190526004909101546080909201829052949b929a50985096509194509092505050565b60185460ff161580611d825750601d5460ff16155b15611da0576040516309c7220160e31b815260040160405180910390fd5b611dab8685856113b8565b611dc85760405163097b24df60e41b815260040160405180910390fd5b84611de65760405163b562e8dd60e01b815260040160405180910390fd5b600354851115611e09576040516393eeb41560e01b815260040160405180910390fd5b60195485611e15610c85565b611e1f9190614154565b118015611e2e5750601a5460ff165b15611e4c5760405163a9dd28bb60e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000007d085611e76610c85565b611e809190614154565b1115611e9f5760405163a4875a4960e01b815260040160405180910390fd5b611ea88561258a565b3414611ec75760405163078d696560e31b815260040160405180910390fd5b600e8282604051611ed9929190613fe0565b9081526040519081900360200190205460ff16611f095760405163fa4f231b60e01b815260040160405180910390fd5b611f15828234886130e5565b61187d8686600061265b565b611f296127b0565b6018805460ff19166001179055565b611f406127b0565b601555565b611f4d6127b0565b6001600160a01b03919091166000908152600a60205260409020805460ff1916911515919091179055565b611f806127b0565b600c544790600090611f9290836141d5565b905060008111611fb5576040516363868c5560e11b815260040160405180910390fd5b610e24816131c3565b60108181548110611fce57600080fd5b6000918252602090912001546001600160a01b0316905081565b606060058054610e3790614218565b60006001600160a01b03821661201f5760405162afb37360e31b815260040160405180910390fd5b506001600160a01b031660009081526001602081905260409091205460ff1615151490565b8161204e8161268c565b6001600160a01b0383163314156120a75760405162461bcd60e51b815260206004820152601a60248201527f455243373231413a20617070726f766520746f2063616c6c65720000000000006044820152606401610f23565b6001600160a01b0383166000908152600a602052604090205460ff16156120e15760405163d947c35f60e01b815260040160405180910390fd5b3360008181526009602090815260408083206001600160a01b03881680855290835292819020805460ff191687151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6121566127b0565b61188d611b12565b6121666127b0565b611ad7601c8383613a05565b826121905760405163b562e8dd60e01b815260040160405180910390fd5b6003548311156121b3576040516393eeb41560e01b815260040160405180910390fd5b601d5460ff166121d6576040516316851fc760e11b815260040160405180910390fd5b601d5460ff1680156121ea575060185460ff165b15612208576040516316851fc760e11b815260040160405180910390fd5b60195483612214610c85565b61221e9190614154565b11801561222d5750601a5460ff165b1561224b5760405163a9dd28bb60e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000007d083612275610c85565b61227f9190614154565b111561229e5760405163a4875a4960e01b815260040160405180910390fd5b6122a78361258a565b34146122c65760405163078d696560e31b815260040160405180910390fd5b600e82826040516122d8929190613fe0565b9081526040519081900360200190205460ff166123085760405163fa4f231b60e01b815260040160405180910390fd5b6115b9828234866130e5565b836daaeb6d7670e522a718067333cd4e3b1561237c576001600160a01b03811633141561237357612346858585612a37565b61235285858585613250565b61236e5760405162461bcd60e51b8152600401610f23906140d6565b6123af565b61237c81612dc4565b612387858585612a37565b61239385858585613250565b6123af5760405162461bcd60e51b8152600401610f23906140d6565b5050505050565b606060006123c26124cb565b905060006123ce61335d565b905060008251116123ee576040518060200160405280600081525061241b565b816123f88561336c565b8260405160200161240b9392919061400c565b6040516020818303038152906040525b949350505050565b60006124326002546000190190565b610c94906001614154565b601b805461244a90614218565b80601f016020809104026020016040519081016040528092919081815260200182805461247690614218565b80156124c35780601f10612498576101008083540402835291602001916124c3565b820191906000526020600020905b8154815290600101906020018083116124a657829003601f168201915b505050505081565b6060601b8054610e3790614218565b6124e26127b0565b601955565b6124ef6127b0565b601655565b6124fc6127b0565b601d80549115156101000261ff0019909216919091179055565b61251e612f0d565b6001600160a01b0381166125445760405162afb37360e31b815260040160405180910390fd5b61254d81611ff7565b6125695760405162afb37360e31b815260040160405180910390fd5b6001600160a01b03166000908152600160205260409020805460ff19169055565b6000610cbe82612598610c85565b613408565b60606040518060600160405280603581526020016142d560359139905090565b601c805461244a90614218565b6125d2612f0d565b6001600160a01b0381166126375760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610f23565b6111d281613095565b6126486127b0565b611b03611f21565b6000610cbe8261346d565b611ad7838383604051806020016040528060008152506134d8565b600081600111158015610cbe5750506002541190565b6daaeb6d7670e522a718067333cd4e3b156111d257604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c61711349060440160206040518083038186803b1580156126f457600080fd5b505afa158015612708573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061272c9190613ea8565b6111d257604051633b79c77360e21b81526001600160a01b0382166004820152602401610f23565b60008281526008602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600080546001600160a01b03163390811491906127cc90611ff7565b905081806127d75750805b610e245760405162461bcd60e51b815260206004820152602960248201527f5465616d3a2063616c6c6572206973206e6f7420746865206f776e6572206f726044820152681034b7102a32b0b69760b91b6064820152608401610f23565b600e816040516128459190613ff0565b9081526040519081900360200190205460ff166128a45760405162461bcd60e51b815260206004820152601860248201527f416666696c6961746520646f6573206e6f7420657869737400000000000000006044820152606401610f23565b6000600d826040516128b69190613ff0565b90815260405190819003602001902060028101548154919250906001600160a01b0316816129305760405162461bcd60e51b815260206004820152602160248201527f416666696c6961746520646f6573206e6f74206861766520612062616c616e636044820152606560f81b6064820152608401610f23565b6001600160a01b0381166129785760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610f23565b6000816001600160a01b03168360405160006040518083038185875af1925050503d80600081146129c5576040519150601f19603f3d011682016040523d82523d6000602084013e6129ca565b606091505b5050905080612a0f5760405162461bcd60e51b815260206004820152601160248201527015da5d1a191c985dd85b0819985a5b1959607a1b6044820152606401610f23565b6000846002018190555082600c6000828254612a2b91906141d5565b90915550505050505050565b6000612a4282612f67565b80519091506000906001600160a01b0316336001600160a01b03161480612a79575033612a6e84610eba565b6001600160a01b0316145b80612a8b57508151612a8b9033610bf3565b905080612af55760405162461bcd60e51b815260206004820152603260248201527f455243373231413a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b6064820152608401610f23565b846001600160a01b031682600001516001600160a01b031614612b695760405162461bcd60e51b815260206004820152602660248201527f455243373231413a207472616e736665722066726f6d20696e636f72726563746044820152651037bbb732b960d11b6064820152608401610f23565b6001600160a01b038416612bcd5760405162461bcd60e51b815260206004820152602560248201527f455243373231413a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b6064820152608401610f23565b612bda85858560016137b2565b612bea6000848460000151612754565b6001600160a01b0385166000908152600760205260408120805460019290612c1c9084906001600160801b03166141ad565b82546101009290920a6001600160801b038181021990931691831602179091556001600160a01b03861660009081526007602052604081208054600194509092612c6891859116614129565b82546001600160801b039182166101009390930a9283029190920219909116179055506040805180820182526001600160a01b0380871682526001600160401b03428116602080850191825260008981526006909152948520935184549151909216600160a01b026001600160e01b03199091169190921617179055612cef846001614154565b6000818152600660205260409020549091506001600160a01b0316612d7e57612d1781612676565b15612d7e5760408051808201825284516001600160a01b0390811682526020808701516001600160401b039081168285019081526000878152600690935294909120925183549451909116600160a01b026001600160e01b03199094169116179190911790555b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461187d565b604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c61711349060440160206040518083038186803b158015612e0e57600080fd5b505afa158015612e22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e469190613ea8565b8015612ed85750604051633185c44d60e21b81523060048201526001600160a01b03821660248201526daaeb6d7670e522a718067333cd4e9063c61711349060440160206040518083038186803b158015612ea057600080fd5b505afa158015612eb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ed89190613ea8565b6111d257604051633b79c77360e21b8152336004820152602401610f23565b600082612f04858461382b565b14949350505050565b6000546001600160a01b03163314611bc95760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610f23565b60408051808201909152600080825260208201528180600111158015612f8e575060025481105b15613035576000818152600660209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b03169183019190915215612fdf579392505050565b50600019016000818152600660209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b03169183019190915215613030579392505050565b612fdf565b60405162461bcd60e51b815260206004820152602f60248201527f455243373231413a20756e61626c6520746f2064657465726d696e652074686560448201526e1037bbb732b91037b3103a37b5b2b760891b6064820152608401610f23565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600e84846040516130f7929190613fe0565b9081526040519081900360200190205460ff161561109f576000600d8585604051613123929190613fe0565b9081526020016040518091039020905060006064826001015485613147919061418e565b613151919061416c565b9050828260040160008282546131679190614154565b92505081905550808260020160008282546131829190614154565b925050819055508082600301600082825461319d9190614154565b9250508190555080600c60008282546131b69190614154565b9091555050505050505050565b60005b601254811015610e245761323e601082815481106131e6576131e6614284565b9060005260206000200160009054906101000a90046001600160a01b031660646011848154811061321957613219614284565b90600052602060002001548561322f919061418e565b613239919061416c565b613897565b8061324881614253565b9150506131c6565b60006001600160a01b0384163b1561335257604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061329490339089908890889060040161404f565b602060405180830381600087803b1580156132ae57600080fd5b505af19250505080156132de575060408051601f3d908101601f191682019092526132db91810190613efb565b60015b613338573d80801561330c576040519150601f19603f3d011682016040523d82523d6000602084013e613311565b606091505b5080516133305760405162461bcd60e51b8152600401610f23906140d6565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061241b565b506001949350505050565b6060601c8054610e3790614218565b606060006133798361392d565b60010190506000816001600160401b038111156133985761339861429a565b6040519080825280601f01601f1916602001820160405280156133c2576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846133fb57613400565b6133cc565b509392505050565b60008060165483613419919061416c565b60145490915060005b828110156134625760646015548361343a919061418e565b613444919061416c565b61344e9083614154565b91508061345a81614253565b915050613422565b50611456858261418e565b60006001600160e01b031982166380ac58cd60e01b148061349e57506001600160e01b03198216635b5e139f60e01b145b806134b957506001600160e01b0319821663780e9d6360e01b145b80610cbe57506301ffc9a760e01b6001600160e01b0319831614610cbe565b6002546001600160a01b03851661353b5760405162461bcd60e51b815260206004820152602160248201527f455243373231413a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b6064820152608401610f23565b61354481612676565b156135915760405162461bcd60e51b815260206004820152601d60248201527f455243373231413a20746f6b656e20616c7265616479206d696e7465640000006044820152606401610f23565b826135f3576003548411156135f35760405162461bcd60e51b815260206004820152602260248201527f455243373231413a207175616e7469747920746f206d696e7420746f6f2068696044820152610ced60f31b6064820152608401610f23565b61360060008683876137b2565b6001600160a01b0385166000908152600760209081526040918290208251808401845290546001600160801b038082168352600160801b909104169181019190915281518083019092528051909190819061365c908890614129565b6001600160801b03168152602001856136755786613678565b60005b83602001516136879190614129565b6001600160801b039081169091526001600160a01b0380891660008181526007602090815260408083208751978301518716600160801b029790961696909617909455845180860186529182526001600160401b034281168386019081528883526006909552948120915182549451909516600160a01b026001600160e01b031990941694909216939093179190911790915582905b868110156137a65760405182906001600160a01b038a16906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a461376a6000898488613250565b6137865760405162461bcd60e51b8152600401610f23906140d6565b8161379081614253565b925050808061379e90614253565b91505061371d565b50600255505050505050565b601d54610100900460ff1615611207576001600160a01b038416156112075760405162461bcd60e51b815260206004820152602960248201527f5472616e736665727320617265206e6f74207065726d697474656420617420746044820152681a19481b5bdb595b9d60ba1b6064820152608401610f23565b600081815b845181101561340057600085828151811061384d5761384d614284565b602002602001015190508083116138735760008381526020829052604090209250613884565b600081815260208490526040902092505b508061388f81614253565b915050613830565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146138e4576040519150601f19603f3d011682016040523d82523d6000602084013e6138e9565b606091505b5050905080611ad75760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b6044820152606401610f23565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b831061396c5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310613998576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106139b657662386f26fc10000830492506010015b6305f5e10083106139ce576305f5e100830492506008015b61271083106139e257612710830492506004015b606483106139f4576064830492506002015b600a8310610cbe5760010192915050565b828054613a1190614218565b90600052602060002090601f016020900481019282613a335760008555613a79565b82601f10613a4c5782800160ff19823516178555613a79565b82800160010185558215613a79579182015b82811115613a79578235825591602001919060010190613a5e565b50611a949291505b80821115611a945760008155600101613a81565b80356001600160a01b0381168114613aac57600080fd5b919050565b60008083601f840112613ac357600080fd5b5081356001600160401b03811115613ada57600080fd5b6020830191508360208260051b8501011115613af557600080fd5b9250929050565b60008083601f840112613b0e57600080fd5b5081356001600160401b03811115613b2557600080fd5b602083019150836020828501011115613af557600080fd5b600060208284031215613b4f57600080fd5b613b5882613a95565b9392505050565b60008060408385031215613b7257600080fd5b613b7b83613a95565b9150613b8960208401613a95565b90509250929050565b600080600060608486031215613ba757600080fd5b613bb084613a95565b9250613bbe60208501613a95565b9150604084013590509250925092565b60008060008060808587031215613be457600080fd5b613bed85613a95565b9350613bfb60208601613a95565b92506040850135915060608501356001600160401b0380821115613c1e57600080fd5b818701915087601f830112613c3257600080fd5b813581811115613c4457613c4461429a565b604051601f8201601f19908116603f01168101908382118183101715613c6c57613c6c61429a565b816040528281528a6020848701011115613c8557600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600080600060408486031215613cbe57600080fd5b613cc784613a95565b925060208401356001600160401b03811115613ce257600080fd5b613cee86828701613ab1565b9497909650939450505050565b60008060408385031215613d0e57600080fd5b613d1783613a95565b91506020830135613d27816142b0565b809150509250929050565b60008060408385031215613d4557600080fd5b613d4e83613a95565b946020939093013593505050565b60008060008060608587031215613d7257600080fd5b613d7b85613a95565b93506020850135925060408501356001600160401b03811115613d9d57600080fd5b613da987828801613ab1565b95989497509550505050565b60008060008060008060808789031215613dce57600080fd5b613dd787613a95565b95506020870135945060408701356001600160401b0380821115613dfa57600080fd5b613e068a838b01613ab1565b90965094506060890135915080821115613e1f57600080fd5b50613e2c89828a01613afc565b979a9699509497509295939492505050565b60008060008060608587031215613e5457600080fd5b613e5d85613a95565b93506020850135925060408501356001600160401b03811115613e7f57600080fd5b613da987828801613afc565b600060208284031215613e9d57600080fd5b8135613b58816142b0565b600060208284031215613eba57600080fd5b8151613b58816142b0565b600060208284031215613ed757600080fd5b5035919050565b600060208284031215613ef057600080fd5b8135613b58816142be565b600060208284031215613f0d57600080fd5b8151613b58816142be565b60008060208385031215613f2b57600080fd5b82356001600160401b03811115613f4157600080fd5b613f4d85828601613afc565b90969095509350505050565b60008060008060608587031215613f6f57600080fd5b84356001600160401b03811115613f8557600080fd5b613f9187828801613afc565b9095509350613fa4905060208601613a95565b9396929550929360400135925050565b60008151808452613fcc8160208601602086016141ec565b601f01601f19169290920160200192915050565b8183823760009101908152919050565b600082516140028184602087016141ec565b9190910192915050565b6000845161401e8184602089016141ec565b8451908301906140328183602089016141ec565b84519101906140458183602088016141ec565b0195945050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061408290830184613fb4565b9695505050505050565b602081526000613b586020830184613fb4565b60a0815260006140b260a0830188613fb4565b90508560208301528460408301528360608301528260808301529695505050505050565b60208082526033908201527f455243373231413a207472616e7366657220746f206e6f6e204552433732315260408201527232b1b2b4bb32b91034b6b83632b6b2b73a32b960691b606082015260800190565b60006001600160801b0380831681851680830382111561414b5761414b61426e565b01949350505050565b600082198211156141675761416761426e565b500190565b60008261418957634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156141a8576141a861426e565b500290565b60006001600160801b03838116908316818110156141cd576141cd61426e565b039392505050565b6000828210156141e7576141e761426e565b500390565b60005b838110156142075781810151838201526020016141ef565b8381111561109f5750506000910152565b600181811c9082168061422c57607f821691505b6020821081141561424d57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156142675761426761426e565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b80151581146111d257600080fd5b6001600160e01b0319811681146111d257600080fdfe697066733a2f2f516d58486d577578445153524b364a596168587a474b37756d3574423563794861687761436879426a3244514e77a264697066735822122013bec15537f6e54f9f8d4a7efee224977473e847dc899c97caf396ce2e75b78764736f6c63430008070033

Deployed Bytecode Sourcemap

85196:329:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52944:90;;;;;;;;;;;;;:::i;:::-;;;11607:25:1;;;11595:2;11580:18;52944:90:0;;;;;;;;85304:218;;;;;;;;;;-1:-1:-1;85304:218:0;;;;;:::i;:::-;;:::i;:::-;;;11434:14:1;;11427:22;11409:41;;11397:2;11382:18;85304:218:0;11269:187:1;51883:59:0;;;;;;;;;;-1:-1:-1;51883:59:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;78774:582;;;;;;:::i;:::-;;:::i;:::-;;56587:94;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;59216:202::-;;;;;;;;;;-1:-1:-1;59216:202:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;10423:32:1;;;10405:51;;10393:2;10378:18;59216:202:0;10259:203:1;58657:501:0;;;;;;;;;;-1:-1:-1;58657:501:0;;;;;:::i;:::-;;:::i;84148:109::-;;;;;;;;;;-1:-1:-1;84148:109:0;;;;;:::i;:::-;;:::i;71278:208::-;;;;;;;;;;;;;:::i;77230:29::-;;;;;;;;;;-1:-1:-1;77230:29:0;;;;;;;;;;;72473:35;;;;;;;;;;;;;;;;60172:148;;;;;;;;;;-1:-1:-1;60172:148:0;;;;;:::i;:::-;;:::i;71700:38::-;;;;;;;;;;-1:-1:-1;71700:38:0;;;;;:::i;:::-;;:::i;50620:27::-;;;;;;;;;;;;;;;;73332:25;;;;;;;;;;;;;;;;53888:721;;;;;;;;;;-1:-1:-1;53888:721:0;;;;;:::i;:::-;;:::i;73946:274::-;;;;;;;;;;-1:-1:-1;73946:274:0;;;;;:::i;:::-;;:::i;76935:42::-;;;;;;;;;;;;76976:1;76935:42;;;;;24701:4:1;24689:17;;;24671:36;;24659:2;24644:18;76935:42:0;24529:184:1;80782:648:0;;;;;;:::i;:::-;;:::i;69274:683::-;;;;;;;;;;-1:-1:-1;69274:683:0;;;;;:::i;:::-;;:::i;71743:38::-;;;;;;;;;;;;;;;;80394:78;;;;;;;;;;;;;:::i;72554:36::-;;;;;;;;;;;;;;;;78291:232;;;;;;;;;;-1:-1:-1;78291:232:0;;;;;:::i;:::-;;:::i;60383:163::-;;;;;;;;;;-1:-1:-1;60383:163:0;;;;;:::i;:::-;;:::i;8077:208::-;;;;;;;;;;-1:-1:-1;8077:208:0;;;;;:::i;:::-;;:::i;50576:39::-;;;;;;;;;;;;;;;73559:176;;;;;;;;;;-1:-1:-1;73559:176:0;;;;;:::i;:::-;;:::i;53420:177::-;;;;;;;;;;-1:-1:-1;53420:177:0;;;;;:::i;:::-;;:::i;83149:158::-;;;;;;;;;;-1:-1:-1;83149:158:0;;;;;:::i;:::-;;:::i;83795:106::-;;;;;;;;;;-1:-1:-1;83795:106:0;;;;;:::i;:::-;;:::i;72597:101::-;;;;;;;;;;-1:-1:-1;72597:101:0;;;;;:::i;:::-;;:::i;56410:118::-;;;;;;;;;;-1:-1:-1;56410:118:0;;;;;:::i;:::-;;:::i;80311:77::-;;;;;;;;;;;;;:::i;74327:97::-;;;;;;;;;;;;;:::i;55071:211::-;;;;;;;;;;-1:-1:-1;55071:211:0;;;;;:::i;:::-;;:::i;2635:103::-;;;;;;;;;;;;;:::i;68799:463::-;;;;;;;;;;-1:-1:-1;68799:463:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;81695:784::-;;;;;;:::i;:::-;;:::i;74226:95::-;;;;;;;;;;;;;:::i;72704:136::-;;;;;;;;;;-1:-1:-1;72704:136:0;;;;;:::i;:::-;;:::i;58444:159::-;;;;;;;;;;-1:-1:-1;58444:159:0;;;;;:::i;:::-;;:::i;71788:262::-;;;;;;;;;;;;;:::i;71556:139::-;;;;;;;;;;-1:-1:-1;71556:139:0;;;;;:::i;:::-;;:::i;1994:87::-;;;;;;;;;;-1:-1:-1;2040:7:0;2067:6;-1:-1:-1;;;;;2067:6:0;1994:87;;77194:31;;;;;;;;;;-1:-1:-1;77194:31:0;;;;;;;;76982:28;;;;;;;;;;;;;;;;72513:36;;;;;;;;;;;;;;;;56742:98;;;;;;;;;;;;;:::i;8786:165::-;;;;;;;;;;-1:-1:-1;8786:165:0;;;;;:::i;:::-;;:::i;59482:410::-;;;;;;;;;;-1:-1:-1;59482:410:0;;;;;:::i;:::-;;:::i;82876:118::-;;;;;;;;;;;;;:::i;83907:135::-;;;;;;;;;;-1:-1:-1;83907:135:0;;;;;:::i;:::-;;:::i;79587:718::-;;;;;;:::i;:::-;;:::i;60609:316::-;;;;;;;;;;-1:-1:-1;60609:316:0;;;;;:::i;:::-;;:::i;56903:298::-;;;;;;;;;;-1:-1:-1;56903:298:0;;;;;:::i;:::-;;:::i;53040:94::-;;;;;;;;;;;;;:::i;77055:86::-;;;;;;;;;;;;;:::i;83696:93::-;;;;;;;;;;;;;:::i;84048:94::-;;;;;;;;;;-1:-1:-1;84048:94:0;;;;;:::i;:::-;;:::i;65052:43::-;;;;;;;;;;;;;;;;72846:128;;;;;;;;;;-1:-1:-1;72846:128:0;;;;;:::i;:::-;;:::i;84390:85::-;;;;;;;;;;-1:-1:-1;84390:85:0;;;;;:::i;:::-;;:::i;8431:213::-;;;;;;;;;;-1:-1:-1;8431:213:0;;;;;:::i;:::-;;:::i;73362:37::-;;;;;;;;;;-1:-1:-1;73362:37:0;;;;;;;;84263:121;;;;;;;;;;-1:-1:-1;84263:121:0;;;;;:::i;:::-;;:::i;83313:134::-;;;;;;;;;;;;;:::i;59955:158::-;;;;;;;;;;-1:-1:-1;59955:158:0;;;;;:::i;:::-;-1:-1:-1;;;;;60072:25:0;;;60052:4;60072:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;59955:158;77146:43;;;;;;;;;;;;;:::i;2893:201::-;;;;;;;;;;-1:-1:-1;2893:201:0;;;;;:::i;:::-;;:::i;77015:35::-;;;;;;;;;;-1:-1:-1;77015:35:0;;;;;;;;82620:115;;;;;;;;;;;;;:::i;52944:90::-;52991:7;53014:14;53308:12;;-1:-1:-1;;53308:30:0;;53219:132;53014:14;53007:21;;52944:90;:::o;85304:218::-;85402:4;-1:-1:-1;;;;;;85422:45:0;;-1:-1:-1;;;85422:45:0;;:94;;;85480:36;85504:11;85480:23;:36::i;:::-;85415:101;85304:218;-1:-1:-1;;85304:218:0:o;78774:582::-;78854:12;78850:43;;78875:18;;-1:-1:-1;;;78875:18:0;;;;;;;;;;;78850:43;78914:12;;78904:7;:22;78900:59;;;78935:24;;-1:-1:-1;;;78935:24:0;;;;;;;;;;;78900:59;78971:11;;;;78966:43;;78991:18;;-1:-1:-1;;;78991:18:0;;;;;;;;;;;78966:43;79020:11;;;;:32;;;;-1:-1:-1;79035:17:0;;;;79020:32;79016:63;;;79061:18;;-1:-1:-1;;;79061:18:0;;;;;;;;;;;79016:63;79119:7;;79109;79090:16;:14;:16::i;:::-;:26;;;;:::i;:::-;:36;:55;;;;-1:-1:-1;79130:15:0;;;;79090:55;79086:85;;;79154:17;;-1:-1:-1;;;79154:17:0;;;;;;;;;;;79086:85;79211:14;79201:7;79182:16;:14;:16::i;:::-;:26;;;;:::i;:::-;:43;79178:69;;;79234:13;;-1:-1:-1;;;79234:13:0;;;;;;;;;;;79178:69;79271:17;79280:7;79271:8;:17::i;:::-;79258:9;:30;79254:59;;79297:16;;-1:-1:-1;;;79297:16:0;;;;;;;;;;;79254:59;79320:30;79330:3;79335:7;79344:5;79320:9;:30::i;:::-;78774:582;;:::o;56587:94::-;56641:13;56670:5;56663:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56587:94;:::o;59216:202::-;59284:7;59308:16;59316:7;59308;:16::i;:::-;59300:74;;;;-1:-1:-1;;;59300:74:0;;23732:2:1;59300:74:0;;;23714:21:1;23771:2;23751:18;;;23744:30;23810:34;23790:18;;;23783:62;-1:-1:-1;;;23861:18:1;;;23854:43;23914:19;;59300:74:0;;;;;;;;;-1:-1:-1;59388:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;59388:24:0;;59216:202::o;58657:501::-;58747:2;49281:30;49302:8;49281:20;:30::i;:::-;58758:13:::1;58774:24;58790:7;58774:15;:24::i;:::-;58758:40;;58819:5;-1:-1:-1::0;;;;;58813:11:0::1;:2;-1:-1:-1::0;;;;;58813:11:0::1;;;58805:58;;;::::0;-1:-1:-1;;;58805:58:0;;20274:2:1;58805:58:0::1;::::0;::::1;20256:21:1::0;20313:2;20293:18;;;20286:30;20352:34;20332:18;;;20325:62;-1:-1:-1;;;20403:18:1;;;20396:32;20445:19;;58805:58:0::1;20072:398:1::0;58805:58:0::1;-1:-1:-1::0;;;;;58874:31:0;::::1;;::::0;;;:27:::1;:31;::::0;;;;;::::1;;58870:87;;;58914:43;;-1:-1:-1::0;;;58914:43:0::1;;;;;;;;;;;58870:87;708:10:::0;-1:-1:-1;;;;;58980:21:0;::::1;;::::0;:62:::1;;-1:-1:-1::0;59005:37:0::1;59022:5:::0;708:10;59955:158;:::i;59005:37::-:1;58964:153;;;::::0;-1:-1:-1;;;58964:153:0;;16009:2:1;58964:153:0::1;::::0;::::1;15991:21:1::0;16048:2;16028:18;;;16021:30;16087:34;16067:18;;;16060:62;16158:27;16138:18;;;16131:55;16203:19;;58964:153:0::1;15807:421:1::0;58964:153:0::1;59124:28;59133:2;59137:7;59146:5;59124:8;:28::i;:::-;58751:407;58657:501:::0;;;:::o;84148:109::-;9306:18;:16;:18::i;:::-;84224:15:::1;:27:::0;;-1:-1:-1;;84224:27:0::1;::::0;::::1;;::::0;;;::::1;::::0;;84148:109::o;71278:208::-;708:10;71327:19;71349:28;;;:14;:28;;;;;71327:50;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71396:15;71412:5;71396:22;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;71388:59;;;;-1:-1:-1;;;71388:59:0;;22617:2:1;71388:59:0;;;22599:21:1;22656:2;22636:18;;;22629:30;22695:26;22675:18;;;22668:54;22739:18;;71388:59:0;22415:348:1;71388:59:0;71458:20;71472:5;71458:13;:20::i;:::-;71316:170;71278:208::o;60172:148::-;60273:4;47509:42;48838:43;:47;48834:360;;-1:-1:-1;;;;;49093:18:0;;49101:10;49093:18;49089:63;;;60286:28:::1;60296:4;60302:2;60306:7;60286:9;:28::i;:::-;49136:7:::0;;49089:63;49160:26;49181:4;49160:20;:26::i;:::-;60286:28:::1;60296:4;60302:2;60306:7;60286:9;:28::i;71700:38::-:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71700:38:0;:::o;53888:721::-;53977:7;54009:16;54019:5;54009:9;:16::i;:::-;54001:5;:24;53993:71;;;;-1:-1:-1;;;53993:71:0;;12580:2:1;53993:71:0;;;12562:21:1;12619:2;12599:18;;;12592:30;12658:34;12638:18;;;12631:62;-1:-1:-1;;;12709:18:1;;;12702:32;12751:19;;53993:71:0;12378:398:1;53993:71:0;54071:22;54096:13;:11;:13::i;:::-;54071:38;;54116:19;54146:25;54196:9;54191:350;54215:14;54211:1;:18;54191:350;;;54245:31;54279:14;;;:11;:14;;;;;;;;;54245:48;;;;;;;;;-1:-1:-1;;;;;54245:48:0;;;;;-1:-1:-1;;;54245:48:0;;;-1:-1:-1;;;;;54245:48:0;;;;;;;;54306:28;54302:89;;54367:14;;;-1:-1:-1;54302:89:0;54424:5;-1:-1:-1;;;;;54403:26:0;:17;-1:-1:-1;;;;;54403:26:0;;54399:135;;;54461:5;54446:11;:20;54442:59;;;-1:-1:-1;54488:1:0;-1:-1:-1;54481:8:0;;-1:-1:-1;;;54481:8:0;54442:59;54511:13;;;;:::i;:::-;;;;54399:135;-1:-1:-1;54231:3:0;;;;:::i;:::-;;;;54191:350;;;-1:-1:-1;54547:56:0;;-1:-1:-1;;;54547:56:0;;22202:2:1;54547:56:0;;;22184:21:1;22241:2;22221:18;;;22214:30;22280:34;22260:18;;;22253:62;-1:-1:-1;;;22331:18:1;;;22324:44;22385:19;;54547:56:0;22000:410:1;73946:274:0;74053:10;;74036:4;;74049:47;;74077:19;;-1:-1:-1;;;74077:19:0;;;;;;;;;;;74049:47;74128:21;;-1:-1:-1;;8736:2:1;8732:15;;;8728:53;74128:21:0;;;8716:66:1;74103:12:0;;8798::1;;74128:21:0;;;;;;;;;;;;74118:32;;;;;;74103:47;;74164:50;74183:12;;74164:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;74197:10:0;;;-1:-1:-1;74209:4:0;;-1:-1:-1;74164:18:0;:50::i;:::-;74157:57;73946:274;-1:-1:-1;;;;;73946:274:0:o;80782:648::-;80898:17;;;;80897:18;;:34;;-1:-1:-1;80920:11:0;;;;80919:12;80897:34;80893:68;;;80940:21;;-1:-1:-1;;;80940:21:0;;;;;;;;;;;80893:68;80973:32;80987:3;80992:12;;80973:13;:32::i;:::-;80968:69;;81014:23;;-1:-1:-1;;;81014:23:0;;;;;;;;;;;80968:69;81048:12;81044:43;;81069:18;;-1:-1:-1;;;81069:18:0;;;;;;;;;;;81044:43;81108:12;;81098:7;:22;81094:59;;;81129:24;;-1:-1:-1;;;81129:24:0;;;;;;;;;;;81094:59;81193:7;;81183;81164:16;:14;:16::i;:::-;:26;;;;:::i;:::-;:36;:55;;;;-1:-1:-1;81204:15:0;;;;81164:55;81160:85;;;81228:17;;-1:-1:-1;;;81228:17:0;;;;;;;;;;;81160:85;81285:14;81275:7;81256:16;:14;:16::i;:::-;:26;;;;:::i;:::-;:43;81252:69;;;81308:13;;-1:-1:-1;;;81308:13:0;;;;;;;;;;;81252:69;81345:17;81354:7;81345:8;:17::i;:::-;81332:9;:30;81328:59;;81371:16;;-1:-1:-1;;;81371:16:0;;;;;;;;;;;81328:59;81394:30;81404:3;81409:7;81418:5;81394:9;:30::i;69274:683::-;9306:18;:16;:18::i;:::-;69396:23;69388:48:::1;;;::::0;-1:-1:-1;;;69388:48:0;;12983:2:1;69388:48:0::1;::::0;::::1;12965:21:1::0;13022:2;13002:18;;;12995:30;-1:-1:-1;;;13041:18:1;;;13034:42;13093:18;;69388:48:0::1;12781:336:1::0;69388:48:0::1;-1:-1:-1::0;;;;;69455:22:0;::::1;69447:50;;;::::0;-1:-1:-1;;;69447:50:0;;13324:2:1;69447:50:0::1;::::0;::::1;13306:21:1::0;13363:2;13343:18;;;13336:30;-1:-1:-1;;;13382:18:1;;;13375:45;13437:18;;69447:50:0::1;13122:339:1::0;69447:50:0::1;69524:1;69516:5;:9;69508:52;;;::::0;-1:-1:-1;;;69508:52:0;;16791:2:1;69508:52:0::1;::::0;::::1;16773:21:1::0;16830:2;16810:18;;;16803:30;16869:32;16849:18;;;16842:60;16919:18;;69508:52:0::1;16589:354:1::0;69508:52:0::1;-1:-1:-1::0;;;;;69585:24:0;::::1;;::::0;;;:14:::1;:24;::::0;;;;69579:38;;::::1;::::0;::::1;:::i;:::-;:43:::0;;-1:-1:-1;69571:88:0::1;;;::::0;-1:-1:-1;;;69571:88:0;;14832:2:1;69571:88:0::1;::::0;::::1;14814:21:1::0;;;14851:18;;;14844:30;14910:34;14890:18;;;14883:62;14962:18;;69571:88:0::1;14630:356:1::0;69571:88:0::1;69679:15;69695:5;;69679:22;;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;;::::1;;69678:23;69670:65;;;::::0;-1:-1:-1;;;69670:65:0;;18371:2:1;69670:65:0::1;::::0;::::1;18353:21:1::0;18410:2;18390:18;;;18383:30;18449:31;18429:18;;;18422:59;18498:18;;69670:65:0::1;18169:353:1::0;69670:65:0::1;69748:33;69784:42;;;;;;;;69801:8;-1:-1:-1::0;;;;;69784:42:0::1;;;;;69811:5;69784:42;;;;69818:1;69784:42;;;;69821:1;69784:42;;;;69824:1;69784:42;;::::0;69748:78:::1;;69857:9;69837:10;69848:5;;69837:17;;;;;;;:::i;:::-;::::0;;;::::1;::::0;;::::1;::::0;;;;;;;;:29;;;;-1:-1:-1;;;;;;69837:29:0::1;-1:-1:-1::0;;;;;69837:29:0;;::::1;;::::0;;;;::::1;::::0;-1:-1:-1;69837:29:0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;-1:-1:-1;69877:15:0::1;::::0;:22:::1;::::0;69893:5;;;;69877:22:::1;:::i;:::-;::::0;;;::::1;::::0;;::::1;::::0;;;;;;;;:29;;-1:-1:-1;;69877:29:0::1;::::0;::::1;;::::0;;;::::1;::::0;;;-1:-1:-1;;;;;69917:24:0;::::1;-1:-1:-1::0;69917:24:0;;;:14:::1;:24:::0;;;;:32:::1;::::0;69944:5;;69917:32:::1;:::i;:::-;;69377:580;69274:683:::0;;;;:::o;80394:78::-;9306:18;:16;:18::i;:::-;80447:11:::1;:19:::0;;-1:-1:-1;;80447:19:0::1;::::0;;80394:78::o;78291:232::-;9306:18;:16;:18::i;:::-;78375:9;78371:40:::1;;78393:18;;-1:-1:-1::0;;;78393:18:0::1;;;;;;;;;;;78371:40;78448:14;78441:4;78422:16;:14;:16::i;:::-;:23;;;;:::i;:::-;:40;78418:66;;;78471:13;;-1:-1:-1::0;;;78471:13:0::1;;;;;;;;;;;78418:66;78491:26;78501:3;78506:4;78512;78491:9;:26::i;60383:163::-:0;60488:4;47509:42;48838:43;:47;48834:360;;-1:-1:-1;;;;;49093:18:0;;49101:10;49093:18;49089:63;;;60501:39:::1;60518:4;60524:2;60528:7;60501:39;;;;;;;;;;;::::0;:16:::1;:39::i;49089:63::-:0;49160:26;49181:4;49160:20;:26::i;:::-;60501:39:::1;60518:4;60524:2;60528:7;60501:39;;;;;;;;;;;::::0;:16:::1;:39::i;8077:208::-:0;1880:13;:11;:13::i;:::-;-1:-1:-1;;;;;8142:22:0;::::1;8138:55;;8173:20;;-1:-1:-1::0;;;8173:20:0::1;;;;;;;;;;;8138:55;8204:16;8211:8;8204:6;:16::i;:::-;8200:51;;;8229:22;;-1:-1:-1::0;;;8229:22:0::1;;;;;;;;;;;8200:51;-1:-1:-1::0;;;;;8258:14:0::1;;::::0;;;8275:4:::1;8258:14;::::0;;;;;;;:21;;-1:-1:-1;;8258:21:0::1;::::0;;::::1;::::0;;8077:208::o;73559:176::-;9306:18;:16;:18::i;:::-;73661:10:::1;;73643:14;:28;73639:56;;;73680:15;;-1:-1:-1::0;;;73680:15:0::1;;;;;;;;;;;73639:56;73702:10;:27:::0;73559:176::o;53420:177::-;53487:7;53519:13;:11;:13::i;:::-;53511:5;:21;53503:69;;;;-1:-1:-1;;;53503:69:0;;14428:2:1;53503:69:0;;;14410:21:1;14467:2;14447:18;;;14440:30;14506:34;14486:18;;;14479:62;-1:-1:-1;;;14557:18:1;;;14550:33;14600:19;;53503:69:0;14226:399:1;53503:69:0;-1:-1:-1;53586:5:0;53420:177::o;83149:158::-;9306:18;:16;:18::i;:::-;83224:16;83220:48:::1;;83249:19;;-1:-1:-1::0;;;83249:19:0::1;;;;;;;;;;;83220:48;83275:12;:26:::0;83149:158::o;83795:106::-;9306:18;:16;:18::i;:::-;83872:23:::1;:13;83888:7:::0;;83872:23:::1;:::i;:::-;;83795:106:::0;;:::o;72597:101::-;9306:18;:16;:18::i;:::-;72670:10:::1;:22:::0;72597:101::o;56410:118::-;56474:7;56497:20;56509:7;56497:11;:20::i;:::-;:25;;56410:118;-1:-1:-1;;56410:118:0:o;80311:77::-;9306:18;:16;:18::i;:::-;80364:11:::1;:18:::0;;-1:-1:-1;;80364:18:0::1;80378:4;80364:18;::::0;;80311:77::o;74327:97::-;9306:18;:16;:18::i;:::-;74393:17:::1;:25:::0;;-1:-1:-1;;74393:25:0::1;::::0;;74327:97::o;55071:211::-;55135:7;-1:-1:-1;;;;;55159:19:0;;55151:75;;;;-1:-1:-1;;;55151:75:0;;17150:2:1;55151:75:0;;;17132:21:1;17189:2;17169:18;;;17162:30;17228:34;17208:18;;;17201:62;-1:-1:-1;;;17279:18:1;;;17272:41;17330:19;;55151:75:0;16948:407:1;55151:75:0;-1:-1:-1;;;;;;55248:19:0;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;55248:27:0;;55071:211::o;2635:103::-;1880:13;:11;:13::i;:::-;2700:30:::1;2727:1;2700:18;:30::i;:::-;2635:103::o:0;68799:463::-;68865:18;68885:12;68899:13;68914:15;68931:23;68967:19;68989:14;:24;69004:8;-1:-1:-1;;;;;68989:24:0;-1:-1:-1;;;;;68989:24:0;;;;;;;;;;;;68967:46;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69032:15;69048:5;69032:22;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;69024:62;;;;-1:-1:-1;;;69024:62:0;;16435:2:1;69024:62:0;;;16417:21:1;16474:2;16454:18;;;16447:30;16513:29;16493:18;;;16486:57;16560:18;;69024:62:0;16233:351:1;69024:62:0;69097:33;69133:10;69144:5;69133:17;;;;;;:::i;:::-;;;;;;;;;;;;;;;;69097:53;;;;;;;-1:-1:-1;;;;;69097:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69169:5;;69097:53;;-1:-1:-1;69097:53:0;-1:-1:-1;69097:53:0;-1:-1:-1;69097:53:0;;-1:-1:-1;68799:463:0;;-1:-1:-1;;;68799:463:0:o;81695:784::-;81836:17;;;;81835:18;;:34;;-1:-1:-1;81858:11:0;;;;81857:12;81835:34;81831:68;;;81878:21;;-1:-1:-1;;;81878:21:0;;;;;;;;;;;81831:68;81911:32;81925:3;81930:12;;81911:13;:32::i;:::-;81906:69;;81952:23;;-1:-1:-1;;;81952:23:0;;;;;;;;;;;81906:69;81986:12;81982:43;;82007:18;;-1:-1:-1;;;82007:18:0;;;;;;;;;;;81982:43;82046:12;;82036:7;:22;82032:59;;;82067:24;;-1:-1:-1;;;82067:24:0;;;;;;;;;;;82032:59;82131:7;;82121;82102:16;:14;:16::i;:::-;:26;;;;:::i;:::-;:36;:55;;;;-1:-1:-1;82142:15:0;;;;82102:55;82098:85;;;82166:17;;-1:-1:-1;;;82166:17:0;;;;;;;;;;;82098:85;82223:14;82213:7;82194:16;:14;:16::i;:::-;:26;;;;:::i;:::-;:43;82190:69;;;82246:13;;-1:-1:-1;;;82246:13:0;;;;;;;;;;;82190:69;82283:17;82292:7;82283:8;:17::i;:::-;82270:9;:30;82266:59;;82309:16;;-1:-1:-1;;;82309:16:0;;;;;;;;;;;82266:59;82337:15;82353:5;;82337:22;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;82332:55;;82368:19;;-1:-1:-1;;;82368:19:0;;;;;;;;;;;82332:55;82394:42;82410:5;;82417:9;82428:7;82394:15;:42::i;:::-;82443:30;82453:3;82458:7;82467:5;82443:9;:30::i;74226:95::-;9306:18;:16;:18::i;:::-;74291:17:::1;:24:::0;;-1:-1:-1;;74291:24:0::1;74311:4;74291:24;::::0;;74226:95::o;72704:136::-;9306:18;:16;:18::i;:::-;72797:17:::1;:37:::0;72704:136::o;58444:159::-;9306:18;:16;:18::i;:::-;-1:-1:-1;;;;;58544:37:0;;;::::1;;::::0;;;:27:::1;:37;::::0;;;;:53;;-1:-1:-1;;58544:53:0::1;::::0;::::1;;::::0;;;::::1;::::0;;58444:159::o;71788:262::-;9306:18;:16;:18::i;:::-;71927:16:::1;::::0;71860:21:::1;::::0;71841:16:::1;::::0;71916:27:::1;::::0;71860:21;71916:27:::1;:::i;:::-;71888:55;;71977:1;71956:17;:22;71952:54;;71987:19;;-1:-1:-1::0;;;71987:19:0::1;;;;;;;;;;;71952:54;72013:31;72026:17;72013:12;:31::i;71556:139::-:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;71556:139:0;;-1:-1:-1;71556:139:0;:::o;56742:98::-;56798:13;56827:7;56820:14;;;;;:::i;8786:165::-;8841:4;-1:-1:-1;;;;;8858:22:0;;8854:55;;8889:20;;-1:-1:-1;;;8889:20:0;;;;;;;;;;;8854:55;-1:-1:-1;;;;;;8923:14:0;;;;;:4;:14;;;;;;;;;;;:22;;;;8786:165::o;59482:410::-;59586:8;49281:30;49302:8;49281:20;:30::i;:::-;-1:-1:-1;;;;;59611:24:0;::::1;708:10:::0;59611:24:::1;;59603:63;;;::::0;-1:-1:-1;;;59603:63:0;;19090:2:1;59603:63:0::1;::::0;::::1;19072:21:1::0;19129:2;19109:18;;;19102:30;19168:28;19148:18;;;19141:56;19214:18;;59603:63:0::1;18888:350:1::0;59603:63:0::1;-1:-1:-1::0;;;;;59677:37:0;::::1;;::::0;;;:27:::1;:37;::::0;;;;;::::1;;59673:93;;;59723:43;;-1:-1:-1::0;;;59723:43:0::1;;;;;;;;;;;59673:93;708:10:::0;59773:32:::1;::::0;;;:18:::1;:32;::::0;;;;;;;-1:-1:-1;;;;;59773:42:0;::::1;::::0;;;;;;;;;;:53;;-1:-1:-1;;59773:53:0::1;::::0;::::1;;::::0;;::::1;::::0;;;59838:48;;11409:41:1;;;59773:42:0;;708:10;59838:48:::1;::::0;11382:18:1;59838:48:0::1;;;;;;;59482:410:::0;;;:::o;82876:118::-;9306:18;:16;:18::i;:::-;82936:26:::1;:24;:26::i;83907:135::-:0;9306:18;:16;:18::i;:::-;84001:35:::1;:19;84023:13:::0;;84001:35:::1;:::i;79587:718::-:0;79692:12;79688:43;;79713:18;;-1:-1:-1;;;79713:18:0;;;;;;;;;;;79688:43;79752:12;;79742:7;:22;79738:59;;;79773:24;;-1:-1:-1;;;79773:24:0;;;;;;;;;;;79738:59;79809:11;;;;79804:43;;79829:18;;-1:-1:-1;;;79829:18:0;;;;;;;;;;;79804:43;79858:11;;;;:32;;;;-1:-1:-1;79873:17:0;;;;79858:32;79854:63;;;79899:18;;-1:-1:-1;;;79899:18:0;;;;;;;;;;;79854:63;79957:7;;79947;79928:16;:14;:16::i;:::-;:26;;;;:::i;:::-;:36;:55;;;;-1:-1:-1;79968:15:0;;;;79928:55;79924:85;;;79992:17;;-1:-1:-1;;;79992:17:0;;;;;;;;;;;79924:85;80049:14;80039:7;80020:16;:14;:16::i;:::-;:26;;;;:::i;:::-;:43;80016:69;;;80072:13;;-1:-1:-1;;;80072:13:0;;;;;;;;;;;80016:69;80109:17;80118:7;80109:8;:17::i;:::-;80096:9;:30;80092:59;;80135:16;;-1:-1:-1;;;80135:16:0;;;;;;;;;;;80092:59;80163:15;80179:5;;80163:22;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;80158:55;;80194:19;;-1:-1:-1;;;80194:19:0;;;;;;;;;;;80158:55;80220:42;80236:5;;80243:9;80254:7;80220:15;:42::i;60609:316::-;60759:4;47509:42;48838:43;:47;48834:360;;-1:-1:-1;;;;;49093:18:0;;49101:10;49093:18;49089:63;;;60772:28:::1;60782:4;60788:2;60792:7;60772:9;:28::i;:::-;60815:48;60838:4;60844:2;60848:7;60857:5;60815:22;:48::i;:::-;60807:112;;;;-1:-1:-1::0;;;60807:112:0::1;;;;;;;:::i;:::-;49136:7:::0;;49089:63;49160:26;49181:4;49160:20;:26::i;:::-;60772:28:::1;60782:4;60788:2;60792:7;60772:9;:28::i;:::-;60815:48;60838:4;60844:2;60848:7;60857:5;60815:22;:48::i;:::-;60807:112;;;;-1:-1:-1::0;;;60807:112:0::1;;;;;;;:::i;:::-;60609:316:::0;;;;;:::o;56903:298::-;56976:13;56998:21;57022:10;:8;:10::i;:::-;56998:34;;57039:23;57065:19;:17;:19::i;:::-;57039:45;;57122:1;57104:7;57098:21;:25;:97;;;;;;;;;;;;;;;;;57150:7;57159:18;:7;:16;:18::i;:::-;57179:9;57133:56;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57098:97;57091:104;56903:298;-1:-1:-1;;;;56903:298:0:o;53040:94::-;53087:7;53110:14;53308:12;;-1:-1:-1;;53308:30:0;;53219:132;53110:14;:18;;53127:1;53110:18;:::i;77055:86::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;83696:93::-;83741:13;83770;83763:20;;;;;:::i;84048:94::-;9306:18;:16;:18::i;:::-;84118:7:::1;:18:::0;84048:94::o;72846:128::-;9306:18;:16;:18::i;:::-;72935:15:::1;:33:::0;72846:128::o;84390:85::-;9306:18;:16;:18::i;:::-;84454:9:::1;:15:::0;;;::::1;;;;-1:-1:-1::0;;84454:15:0;;::::1;::::0;;;::::1;::::0;;84390:85::o;8431:213::-;1880:13;:11;:13::i;:::-;-1:-1:-1;;;;;8501:22:0;::::1;8497:55;;8532:20;;-1:-1:-1::0;;;8532:20:0::1;;;;;;;;;;;8497:55;8564:16;8571:8;8564:6;:16::i;:::-;8559:50;;8589:20;;-1:-1:-1::0;;;8589:20:0::1;;;;;;;;;;;8559:50;-1:-1:-1::0;;;;;8616:14:0::1;8633:5;8616:14:::0;;;:4:::1;:14;::::0;;;;:22;;-1:-1:-1;;8616:22:0::1;::::0;;8431:213::o;84263:121::-;84318:7;84341:37;84356:6;84364:13;:11;:13::i;:::-;84341:14;:37::i;83313:134::-;83357:13;83379:62;;;;;;;;;;;;;;;;;;;83313:134;:::o;77146:43::-;;;;;;;:::i;2893:201::-;1880:13;:11;:13::i;:::-;-1:-1:-1;;;;;2982:22:0;::::1;2974:73;;;::::0;-1:-1:-1;;;2974:73:0;;14021:2:1;2974:73:0::1;::::0;::::1;14003:21:1::0;14060:2;14040:18;;;14033:30;14099:34;14079:18;;;14072:62;-1:-1:-1;;;14150:18:1;;;14143:36;14196:19;;2974:73:0::1;13819:402:1::0;2974:73:0::1;3058:28;3077:8;3058:18;:28::i;82620:115::-:0;9306:18;:16;:18::i;:::-;82679:25:::1;:23;:25::i;84481:156::-:0;84575:4;84595:36;84619:11;84595:23;:36::i;61301:129::-;61384:40;61394:2;61398:8;61408:11;61384:40;;;;;;;;;;;;:9;:40::i;61160:135::-;61217:4;61256:7;52767:1;61237:26;;:52;;;;-1:-1:-1;;61277:12:0;;-1:-1:-1;61267:22:0;61160:135::o;49331:381::-;47509:42;49514:43;:47;49510:197;;49577:65;;-1:-1:-1;;;49577:65:0;;49626:4;49577:65;;;10679:34:1;-1:-1:-1;;;;;10749:15:1;;10729:18;;;10722:43;47509:42:0;;49577:40;;10614:18:1;;49577:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49572:128;;49662:28;;-1:-1:-1;;;49662:28:0;;-1:-1:-1;;;;;10423:32:1;;49662:28:0;;;10405:51:1;10378:18;;49662:28:0;10259:203:1;64894:152:0;64971:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;64971:29:0;-1:-1:-1;;;;;64971:29:0;;;;;;;;;65012:28;;64971:24;;65012:28;;;;;;;64894:152;;;:::o;9051:215::-;9099:13;2067:6;;-1:-1:-1;;;;;2067:6:0;708:10;9115:23;;;;9099:13;9160:20;;8786:165;:::i;9160:20::-;9145:35;;9195:8;:19;;;;9207:7;9195:19;9187:73;;;;-1:-1:-1;;;9187:73:0;;15599:2:1;9187:73:0;;;15581:21:1;15638:2;15618:18;;;15611:30;15677:34;15657:18;;;15650:62;-1:-1:-1;;;15728:18:1;;;15721:39;15777:19;;9187:73:0;15397:405:1;70629:641:0;70700:15;70716:5;70700:22;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;70692:59;;;;-1:-1:-1;;;70692:59:0;;13668:2:1;70692:59:0;;;13650:21:1;13707:2;13687:18;;;13680:30;13746:26;13726:18;;;13719:54;13790:18;;70692:59:0;13466:348:1;70692:59:0;70762:34;70799:10;70810:5;70799:17;;;;;;:::i;:::-;;;;;;;;;;;;;;70852;;;;70899:14;;70799:17;;-1:-1:-1;70852:17:0;-1:-1:-1;;;;;70899:14:0;70932:12;70924:58;;;;-1:-1:-1;;;70924:58:0;;17562:2:1;70924:58:0;;;17544:21:1;17601:2;17581:18;;;17574:30;17640:34;17620:18;;;17613:62;-1:-1:-1;;;17691:18:1;;;17684:31;17732:19;;70924:58:0;17360:397:1;70924:58:0;-1:-1:-1;;;;;71001:22:0;;70993:50;;;;-1:-1:-1;;;70993:50:0;;13324:2:1;70993:50:0;;;13306:21:1;13363:2;13343:18;;;13336:30;-1:-1:-1;;;13382:18:1;;;13375:45;13437:18;;70993:50:0;13122:339:1;70993:50:0;71057:12;71075:8;-1:-1:-1;;;;;71075:13:0;71096:8;71075:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71056:53;;;71128:7;71120:37;;;;-1:-1:-1;;;71120:37:0;;22970:2:1;71120:37:0;;;22952:21:1;23009:2;22989:18;;;22982:30;-1:-1:-1;;;23028:18:1;;;23021:47;23085:18;;71120:37:0;22768:341:1;71120:37:0;71222:1;71202:9;:17;;:21;;;;71254:8;71234:16;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;70629:641:0:o;63374:1418::-;63451:35;63489:20;63501:7;63489:11;:20::i;:::-;63558:18;;63451:58;;-1:-1:-1;63516:22:0;;-1:-1:-1;;;;;63542:34:0;708:10;-1:-1:-1;;;;;63542:34:0;;:81;;;-1:-1:-1;708:10:0;63587:20;63599:7;63587:11;:20::i;:::-;-1:-1:-1;;;;;63587:36:0;;63542:81;:142;;;-1:-1:-1;63651:18:0;;63634:50;;708:10;59955:158;:::i;63634:50::-;63516:169;;63700:17;63692:80;;;;-1:-1:-1;;;63692:80:0;;19445:2:1;63692:80:0;;;19427:21:1;19484:2;19464:18;;;19457:30;19523:34;19503:18;;;19496:62;-1:-1:-1;;;19574:18:1;;;19567:48;19632:19;;63692:80:0;19243:414:1;63692:80:0;63809:4;-1:-1:-1;;;;;63787:26:0;:13;:18;;;-1:-1:-1;;;;;63787:26:0;;63779:77;;;;-1:-1:-1;;;63779:77:0;;17964:2:1;63779:77:0;;;17946:21:1;18003:2;17983:18;;;17976:30;18042:34;18022:18;;;18015:62;-1:-1:-1;;;18093:18:1;;;18086:36;18139:19;;63779:77:0;17762:402:1;63779:77:0;-1:-1:-1;;;;;63871:16:0;;63863:66;;;;-1:-1:-1;;;63863:66:0;;15193:2:1;63863:66:0;;;15175:21:1;15232:2;15212:18;;;15205:30;15271:34;15251:18;;;15244:62;-1:-1:-1;;;15322:18:1;;;15315:35;15367:19;;63863:66:0;14991:401:1;63863:66:0;63936:43;63958:4;63964:2;63968:7;63977:1;63936:21;:43::i;:::-;64034:49;64051:1;64055:7;64064:13;:18;;;64034:8;:49::i;:::-;-1:-1:-1;;;;;64090:18:0;;;;;;:12;:18;;;;;:31;;64120:1;;64090:18;:31;;64120:1;;-1:-1:-1;;;;;64090:31:0;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;64090:31:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;64128:16:0;;-1:-1:-1;64128:16:0;;;:12;:16;;;;;:29;;-1:-1:-1;;;64128:16:0;;:29;;-1:-1:-1;;64128:29:0;;:::i;:::-;;;-1:-1:-1;;;;;64128:29:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64187:43:0;;;;;;;;-1:-1:-1;;;;;64187:43:0;;;;;-1:-1:-1;;;;;64213:15:0;64187:43;;;;;;;;;-1:-1:-1;64164:20:0;;;:11;:20;;;;;;:66;;;;;;;;;-1:-1:-1;;;64164:66:0;-1:-1:-1;;;;;;64164:66:0;;;;;;;;;;;64478:11;64176:7;-1:-1:-1;64478:11:0;:::i;:::-;64541:1;64500:24;;;:11;:24;;;;;:29;64456:33;;-1:-1:-1;;;;;;64500:29:0;64496:203;;64558:20;64566:11;64558:7;:20::i;:::-;64554:138;;;64618:64;;;;;;;;64633:18;;-1:-1:-1;;;;;64618:64:0;;;;;;64653:28;;;;-1:-1:-1;;;;;64618:64:0;;;;;;;;;-1:-1:-1;64591:24:0;;;:11;:24;;;;;;;:91;;;;;;;;;-1:-1:-1;;;64591:91:0;-1:-1:-1;;;;;;64591:91:0;;;;;;;;;;;;64554:138;64729:7;64725:2;-1:-1:-1;;;;;64710:27:0;64719:4;-1:-1:-1;;;;;64710:27:0;;;;;;;;;;;64744:42;58657:501;48381:287;48459:67;;-1:-1:-1;;;48459:67:0;;48508:4;48459:67;;;10679:34:1;48515:10:0;10729:18:1;;;10722:43;47509:42:0;;48459:40;;10614:18:1;;48459:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:141;;;;-1:-1:-1;48539:61:0;;-1:-1:-1;;;48539:61:0;;48588:4;48539:61;;;10679:34:1;-1:-1:-1;;;;;10749:15:1;;10729:18;;;10722:43;47509:42:0;;48539:40;;10614:18:1;;48539:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48445:218;;48625:30;;-1:-1:-1;;;48625:30:0;;48644:10;48625:30;;;10405:51:1;10378:18;;48625:30:0;10259:203:1;75376:150:0;75467:4;75516;75487:25;75500:5;75507:4;75487:12;:25::i;:::-;:33;;75376:150;-1:-1:-1;;;;75376:150:0:o;2159:132::-;2040:7;2067:6;-1:-1:-1;;;;;2067:6:0;708:10;2223:23;2215:68;;;;-1:-1:-1;;;2215:68:0;;18729:2:1;2215:68:0;;;18711:21:1;;;18748:18;;;18741:30;18807:34;18787:18;;;18780:62;18859:18;;2215:68:0;18527:356:1;55513:843:0;-1:-1:-1;;;;;;;;;;;;;;;;;55619:7:0;;52767:1;55656:23;;:46;;;;;55690:12;;55683:4;:19;55656:46;55652:628;;;55715:31;55749:17;;;:11;:17;;;;;;;;;55715:51;;;;;;;;;-1:-1:-1;;;;;55715:51:0;;;;;-1:-1:-1;;;55715:51:0;;;-1:-1:-1;;;;;55715:51:0;;;;;;;;55781:28;55777:75;;55831:9;55513:843;-1:-1:-1;;;55513:843:0:o;55777:75::-;-1:-1:-1;;;56120:6:0;56151:17;;;;:11;:17;;;;;;;;;56139:29;;;;;;;;;-1:-1:-1;;;;;56139:29:0;;;;;-1:-1:-1;;;56139:29:0;;;-1:-1:-1;;;;;56139:29:0;;;;;;;;56185:28;56181:79;;56237:9;55513:843;-1:-1:-1;;;55513:843:0:o;56181:79::-;56094:177;;55652:628;56293:57;;-1:-1:-1;;;56293:57:0;;23316:2:1;56293:57:0;;;23298:21:1;23355:2;23335:18;;;23328:30;23394:34;23374:18;;;23367:62;-1:-1:-1;;;23445:18:1;;;23438:45;23500:19;;56293:57:0;23114:411:1;3254:191:0;3328:16;3347:6;;-1:-1:-1;;;;;3364:17:0;;;-1:-1:-1;;;;;;3364:17:0;;;;;;3397:40;;3347:6;;;;;;;3397:40;;3328:16;3397:40;3317:128;3254:191;:::o;69965:656::-;70069:15;70085:5;;70069:22;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;70065:549;;;70108:34;70145:10;70156:5;;70145:17;;;;;;;:::i;:::-;;;;;;;;;;;;;70108:54;;70259:16;70306:3;70288:9;:14;;;70279:6;:23;;;;:::i;:::-;70278:31;;;;:::i;:::-;70259:50;;70398:6;70379:9;:15;;;:25;;;;;;;:::i;:::-;;;;;;;;70440:8;70419:9;:17;;;:29;;;;;;;:::i;:::-;;;;;;;;70492:8;70463:9;:25;;;:37;;;;;;;:::i;:::-;;;;;;;;70594:8;70574:16;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;69965:656:0;;;;:::o;72056:188::-;72115:6;72110:129;72131:19;;72127:1;:23;72110:129;;;72166:65;72177:16;72194:1;72177:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;72177:19:0;72227:3;72209:11;72221:1;72209:14;;;;;;;;:::i;:::-;;;;;;;;;72199:7;:24;;;;:::i;:::-;72198:32;;;;:::i;:::-;72166:10;:65::i;:::-;72152:3;;;;:::i;:::-;;;;72110:129;;66628:674;66765:4;-1:-1:-1;;;;;66782:13:0;;19369:19;:23;66778:519;;66812:72;;-1:-1:-1;;;66812:72:0;;-1:-1:-1;;;;;66812:36:0;;;;;:72;;708:10;;66863:4;;66869:7;;66878:5;;66812:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66812:72:0;;;;;;;;-1:-1:-1;;66812:72:0;;;;;;;;;;;;:::i;:::-;;;66808:448;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67036:13:0;;67032:215;;67069:61;;-1:-1:-1;;;67069:61:0;;;;;;;:::i;67032:215::-;67215:6;67209:13;67200:6;67196:2;67192:15;67185:38;66808:448;-1:-1:-1;;;;;;66927:55:0;-1:-1:-1;;;66927:55:0;;-1:-1:-1;66920:62:0;;66778:519;-1:-1:-1;67285:4:0;66628:674;;;;;;:::o;83567:123::-;83636:13;83665:19;83658:26;;;;;:::i;41899:716::-;41955:13;42006:14;42023:17;42034:5;42023:10;:17::i;:::-;42043:1;42023:21;42006:38;;42059:20;42093:6;-1:-1:-1;;;;;42082:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42082:18:0;-1:-1:-1;42059:41:0;-1:-1:-1;42224:28:0;;;42240:2;42224:28;42281:288;-1:-1:-1;;42313:5:0;-1:-1:-1;;;42450:2:0;42439:14;;42434:30;42313:5;42421:44;42511:2;42502:11;;;-1:-1:-1;42536:10:0;42532:21;;42548:5;;42532:21;42281:288;;;-1:-1:-1;42590:6:0;41899:716;-1:-1:-1;;;41899:716:0:o;72980:298::-;73054:7;73070:13;73096:15;;73086:7;:25;;;;:::i;:::-;73134:10;;73070:41;;-1:-1:-1;73118:13:0;73153:90;73174:5;73170:1;:9;73153:90;;;73232:3;73212:17;;73204:5;:25;;;;:::i;:::-;:31;;;;:::i;:::-;73195:40;;;;:::i;:::-;;-1:-1:-1;73181:3:0;;;;:::i;:::-;;;;73153:90;;;-1:-1:-1;73258:14:0;73266:6;73258:5;:14;:::i;54673:342::-;54775:4;-1:-1:-1;;;;;;54802:40:0;;-1:-1:-1;;;54802:40:0;;:99;;-1:-1:-1;;;;;;;54853:48:0;;-1:-1:-1;;;54853:48:0;54802:99;:160;;;-1:-1:-1;;;;;;;54912:50:0;;-1:-1:-1;;;54912:50:0;54802:160;:207;;;-1:-1:-1;;;;;;;;;;11047:40:0;;;54973:36;10938:157;61759:1395;61885:12;;-1:-1:-1;;;;;61912:16:0;;61904:62;;;;-1:-1:-1;;;61904:62:0;;21800:2:1;61904:62:0;;;21782:21:1;21839:2;21819:18;;;21812:30;21878:34;21858:18;;;21851:62;-1:-1:-1;;;21929:18:1;;;21922:31;21970:19;;61904:62:0;21598:397:1;61904:62:0;62103:21;62111:12;62103:7;:21::i;:::-;62102:22;62094:64;;;;-1:-1:-1;;;62094:64:0;;21442:2:1;62094:64:0;;;21424:21:1;21481:2;21461:18;;;21454:30;21520:31;21500:18;;;21493:59;21569:18;;62094:64:0;21240:353:1;62094:64:0;62242:20;62238:114;;62293:12;;62281:8;:24;;62273:71;;;;-1:-1:-1;;;62273:71:0;;24146:2:1;62273:71:0;;;24128:21:1;24185:2;24165:18;;;24158:30;24224:34;24204:18;;;24197:62;-1:-1:-1;;;24275:18:1;;;24268:32;24317:19;;62273:71:0;23944:398:1;62273:71:0;62358:61;62388:1;62392:2;62396:12;62410:8;62358:21;:61::i;:::-;-1:-1:-1;;;;;62459:16:0;;62426:30;62459:16;;;:12;:16;;;;;;;;;62426:49;;;;;;;;;-1:-1:-1;;;;;62426:49:0;;;;;-1:-1:-1;;;62426:49:0;;;;;;;;;;;62501:139;;;;;;;;62521:19;;62426:49;;62501:139;;;62521:39;;62551:8;;62521:39;:::i;:::-;-1:-1:-1;;;;;62501:139:0;;;;;62597:11;:35;;62623:8;62597:35;;;62611:1;62597:35;62569:11;:24;;;:64;;;;:::i;:::-;-1:-1:-1;;;;;62501:139:0;;;;;;-1:-1:-1;;;;;62482:16:0;;;;;;;:12;:16;;;;;;;;:158;;;;;;;;-1:-1:-1;;;62482:158:0;;;;;;;;;;;;62675:43;;;;;;;;;;-1:-1:-1;;;;;62701:15:0;62675:43;;;;;;;;62647:25;;;:11;:25;;;;;;:71;;;;;;;;;-1:-1:-1;;;62647:71:0;-1:-1:-1;;;;;;62647:71:0;;;;;;;;;;;;;;;;;;62659:12;;62767:281;62791:8;62787:1;:12;62767:281;;;62820:38;;62845:12;;-1:-1:-1;;;;;62820:38:0;;;62837:1;;62820:38;;62837:1;;62820:38;62885:59;62916:1;62920:2;62924:12;62938:5;62885:22;:59::i;:::-;62867:150;;;;-1:-1:-1;;;62867:150:0;;;;;;;:::i;:::-;63026:14;;;;:::i;:::-;;;;62801:3;;;;;:::i;:::-;;;;62767:281;;;-1:-1:-1;63054:12:0;:27;-1:-1:-1;;;;;;61759:1395:0:o;77704:308::-;77839:9;;;;;;;77835:104;;;-1:-1:-1;;;;;77867:18:0;;;77859:72;;;;-1:-1:-1;;;77859:72:0;;19864:2:1;77859:72:0;;;19846:21:1;19903:2;19883:18;;;19876:30;19942:34;19922:18;;;19915:62;-1:-1:-1;;;19993:18:1;;;19986:39;20042:19;;77859:72:0;19662:405:1;75869:601:0;75952:7;75991:4;75952:7;76002:437;76026:5;:12;76022:1;:16;76002:437;;;76054:20;76077:5;76083:1;76077:8;;;;;;;;:::i;:::-;;;;;;;76054:31;;76114:12;76098;:28;76094:338;;76544:13;76584:15;;;76614:4;76607:15;;;76655:4;76639:21;;76210:57;;76094:338;;;76544:13;76584:15;;;76614:4;76607:15;;;76655:4;76639:21;;76365:57;;76094:338;-1:-1:-1;76040:3:0;;;;:::i;:::-;;;;76002:437;;72250:171;72321:12;72339:8;-1:-1:-1;;;;;72339:13:0;72360:7;72339:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72320:52;;;72387:7;72379:36;;;;-1:-1:-1;;;72379:36:0;;20677:2:1;72379:36:0;;;20659:21:1;20716:2;20696:18;;;20689:30;-1:-1:-1;;;20735:18:1;;;20728:46;20791:18;;72379:36:0;20475:340:1;37566:948:0;37619:7;;-1:-1:-1;;;37697:17:0;;37693:106;;-1:-1:-1;;;37735:17:0;;;-1:-1:-1;37781:2:0;37771:12;37693:106;37826:8;37817:5;:17;37813:106;;37864:8;37855:17;;;-1:-1:-1;37901:2:0;37891:12;37813:106;37946:8;37937:5;:17;37933:106;;37984:8;37975:17;;;-1:-1:-1;38021:2:0;38011:12;37933:106;38066:7;38057:5;:16;38053:103;;38103:7;38094:16;;;-1:-1:-1;38139:1:0;38129:11;38053:103;38183:7;38174:5;:16;38170:103;;38220:7;38211:16;;;-1:-1:-1;38256:1:0;38246:11;38170:103;38300:7;38291:5;:16;38287:103;;38337:7;38328:16;;;-1:-1:-1;38373:1:0;38363:11;38287:103;38417:7;38408:5;:16;38404:68;;38455:1;38445:11;38500:6;37566:948;-1:-1:-1;;37566:948:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:173:1;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:367::-;255:8;265:6;319:3;312:4;304:6;300:17;296:27;286:55;;337:1;334;327:12;286:55;-1:-1:-1;360:20:1;;-1:-1:-1;;;;;392:30:1;;389:50;;;435:1;432;425:12;389:50;472:4;464:6;460:17;448:29;;532:3;525:4;515:6;512:1;508:14;500:6;496:27;492:38;489:47;486:67;;;549:1;546;539:12;486:67;192:367;;;;;:::o;564:348::-;616:8;626:6;680:3;673:4;665:6;661:17;657:27;647:55;;698:1;695;688:12;647:55;-1:-1:-1;721:20:1;;-1:-1:-1;;;;;753:30:1;;750:50;;;796:1;793;786:12;750:50;833:4;825:6;821:17;809:29;;885:3;878:4;869:6;861;857:19;853:30;850:39;847:59;;;902:1;899;892:12;917:186;976:6;1029:2;1017:9;1008:7;1004:23;1000:32;997:52;;;1045:1;1042;1035:12;997:52;1068:29;1087:9;1068:29;:::i;:::-;1058:39;917:186;-1:-1:-1;;;917:186:1:o;1108:260::-;1176:6;1184;1237:2;1225:9;1216:7;1212:23;1208:32;1205:52;;;1253:1;1250;1243:12;1205:52;1276:29;1295:9;1276:29;:::i;:::-;1266:39;;1324:38;1358:2;1347:9;1343:18;1324:38;:::i;:::-;1314:48;;1108:260;;;;;:::o;1373:328::-;1450:6;1458;1466;1519:2;1507:9;1498:7;1494:23;1490:32;1487:52;;;1535:1;1532;1525:12;1487:52;1558:29;1577:9;1558:29;:::i;:::-;1548:39;;1606:38;1640:2;1629:9;1625:18;1606:38;:::i;:::-;1596:48;;1691:2;1680:9;1676:18;1663:32;1653:42;;1373:328;;;;;:::o;1706:1138::-;1801:6;1809;1817;1825;1878:3;1866:9;1857:7;1853:23;1849:33;1846:53;;;1895:1;1892;1885:12;1846:53;1918:29;1937:9;1918:29;:::i;:::-;1908:39;;1966:38;2000:2;1989:9;1985:18;1966:38;:::i;:::-;1956:48;;2051:2;2040:9;2036:18;2023:32;2013:42;;2106:2;2095:9;2091:18;2078:32;-1:-1:-1;;;;;2170:2:1;2162:6;2159:14;2156:34;;;2186:1;2183;2176:12;2156:34;2224:6;2213:9;2209:22;2199:32;;2269:7;2262:4;2258:2;2254:13;2250:27;2240:55;;2291:1;2288;2281:12;2240:55;2327:2;2314:16;2349:2;2345;2342:10;2339:36;;;2355:18;;:::i;:::-;2430:2;2424:9;2398:2;2484:13;;-1:-1:-1;;2480:22:1;;;2504:2;2476:31;2472:40;2460:53;;;2528:18;;;2548:22;;;2525:46;2522:72;;;2574:18;;:::i;:::-;2614:10;2610:2;2603:22;2649:2;2641:6;2634:18;2689:7;2684:2;2679;2675;2671:11;2667:20;2664:33;2661:53;;;2710:1;2707;2700:12;2661:53;2766:2;2761;2757;2753:11;2748:2;2740:6;2736:15;2723:46;2811:1;2806:2;2801;2793:6;2789:15;2785:24;2778:35;2832:6;2822:16;;;;;;;1706:1138;;;;;;;:::o;2849:511::-;2944:6;2952;2960;3013:2;3001:9;2992:7;2988:23;2984:32;2981:52;;;3029:1;3026;3019:12;2981:52;3052:29;3071:9;3052:29;:::i;:::-;3042:39;;3132:2;3121:9;3117:18;3104:32;-1:-1:-1;;;;;3151:6:1;3148:30;3145:50;;;3191:1;3188;3181:12;3145:50;3230:70;3292:7;3283:6;3272:9;3268:22;3230:70;:::i;:::-;2849:511;;3319:8;;-1:-1:-1;3204:96:1;;-1:-1:-1;;;;2849:511:1:o;3365:315::-;3430:6;3438;3491:2;3479:9;3470:7;3466:23;3462:32;3459:52;;;3507:1;3504;3497:12;3459:52;3530:29;3549:9;3530:29;:::i;:::-;3520:39;;3609:2;3598:9;3594:18;3581:32;3622:28;3644:5;3622:28;:::i;:::-;3669:5;3659:15;;;3365:315;;;;;:::o;3685:254::-;3753:6;3761;3814:2;3802:9;3793:7;3789:23;3785:32;3782:52;;;3830:1;3827;3820:12;3782:52;3853:29;3872:9;3853:29;:::i;:::-;3843:39;3929:2;3914:18;;;;3901:32;;-1:-1:-1;;;3685:254:1:o;3944:579::-;4048:6;4056;4064;4072;4125:2;4113:9;4104:7;4100:23;4096:32;4093:52;;;4141:1;4138;4131:12;4093:52;4164:29;4183:9;4164:29;:::i;:::-;4154:39;;4240:2;4229:9;4225:18;4212:32;4202:42;;4295:2;4284:9;4280:18;4267:32;-1:-1:-1;;;;;4314:6:1;4311:30;4308:50;;;4354:1;4351;4344:12;4308:50;4393:70;4455:7;4446:6;4435:9;4431:22;4393:70;:::i;:::-;3944:579;;;;-1:-1:-1;4482:8:1;-1:-1:-1;;;;3944:579:1:o;4528:890::-;4653:6;4661;4669;4677;4685;4693;4746:3;4734:9;4725:7;4721:23;4717:33;4714:53;;;4763:1;4760;4753:12;4714:53;4786:29;4805:9;4786:29;:::i;:::-;4776:39;;4862:2;4851:9;4847:18;4834:32;4824:42;;4917:2;4906:9;4902:18;4889:32;-1:-1:-1;;;;;4981:2:1;4973:6;4970:14;4967:34;;;4997:1;4994;4987:12;4967:34;5036:70;5098:7;5089:6;5078:9;5074:22;5036:70;:::i;:::-;5125:8;;-1:-1:-1;5010:96:1;-1:-1:-1;5213:2:1;5198:18;;5185:32;;-1:-1:-1;5229:16:1;;;5226:36;;;5258:1;5255;5248:12;5226:36;;5297:61;5350:7;5339:8;5328:9;5324:24;5297:61;:::i;:::-;4528:890;;;;-1:-1:-1;4528:890:1;;-1:-1:-1;4528:890:1;;5377:8;;4528:890;-1:-1:-1;;;4528:890:1:o;5423:553::-;5512:6;5520;5528;5536;5589:2;5577:9;5568:7;5564:23;5560:32;5557:52;;;5605:1;5602;5595:12;5557:52;5628:29;5647:9;5628:29;:::i;:::-;5618:39;;5704:2;5693:9;5689:18;5676:32;5666:42;;5759:2;5748:9;5744:18;5731:32;-1:-1:-1;;;;;5778:6:1;5775:30;5772:50;;;5818:1;5815;5808:12;5772:50;5857:59;5908:7;5899:6;5888:9;5884:22;5857:59;:::i;5981:241::-;6037:6;6090:2;6078:9;6069:7;6065:23;6061:32;6058:52;;;6106:1;6103;6096:12;6058:52;6145:9;6132:23;6164:28;6186:5;6164:28;:::i;6227:245::-;6294:6;6347:2;6335:9;6326:7;6322:23;6318:32;6315:52;;;6363:1;6360;6353:12;6315:52;6395:9;6389:16;6414:28;6436:5;6414:28;:::i;6477:180::-;6536:6;6589:2;6577:9;6568:7;6564:23;6560:32;6557:52;;;6605:1;6602;6595:12;6557:52;-1:-1:-1;6628:23:1;;6477:180;-1:-1:-1;6477:180:1:o;6662:245::-;6720:6;6773:2;6761:9;6752:7;6748:23;6744:32;6741:52;;;6789:1;6786;6779:12;6741:52;6828:9;6815:23;6847:30;6871:5;6847:30;:::i;6912:249::-;6981:6;7034:2;7022:9;7013:7;7009:23;7005:32;7002:52;;;7050:1;7047;7040:12;7002:52;7082:9;7076:16;7101:30;7125:5;7101:30;:::i;7166:411::-;7237:6;7245;7298:2;7286:9;7277:7;7273:23;7269:32;7266:52;;;7314:1;7311;7304:12;7266:52;7354:9;7341:23;-1:-1:-1;;;;;7379:6:1;7376:30;7373:50;;;7419:1;7416;7409:12;7373:50;7458:59;7509:7;7500:6;7489:9;7485:22;7458:59;:::i;:::-;7536:8;;7432:85;;-1:-1:-1;7166:411:1;-1:-1:-1;;;;7166:411:1:o;7582:553::-;7671:6;7679;7687;7695;7748:2;7736:9;7727:7;7723:23;7719:32;7716:52;;;7764:1;7761;7754:12;7716:52;7804:9;7791:23;-1:-1:-1;;;;;7829:6:1;7826:30;7823:50;;;7869:1;7866;7859:12;7823:50;7908:59;7959:7;7950:6;7939:9;7935:22;7908:59;:::i;:::-;7986:8;;-1:-1:-1;7882:85:1;-1:-1:-1;8040:38:1;;-1:-1:-1;8074:2:1;8059:18;;8040:38;:::i;:::-;7582:553;;;;-1:-1:-1;8030:48:1;;8125:2;8110:18;8097:32;;-1:-1:-1;;7582:553:1:o;8325:257::-;8366:3;8404:5;8398:12;8431:6;8426:3;8419:19;8447:63;8503:6;8496:4;8491:3;8487:14;8480:4;8473:5;8469:16;8447:63;:::i;:::-;8564:2;8543:15;-1:-1:-1;;8539:29:1;8530:39;;;;8571:4;8526:50;;8325:257;-1:-1:-1;;8325:257:1:o;8821:273::-;9006:6;8998;8993:3;8980:33;8962:3;9032:16;;9057:13;;;9032:16;8821:273;-1:-1:-1;8821:273:1:o;9099:276::-;9230:3;9268:6;9262:13;9284:53;9330:6;9325:3;9318:4;9310:6;9306:17;9284:53;:::i;:::-;9353:16;;;;;9099:276;-1:-1:-1;;9099:276:1:o;9380:664::-;9607:3;9645:6;9639:13;9661:53;9707:6;9702:3;9695:4;9687:6;9683:17;9661:53;:::i;:::-;9777:13;;9736:16;;;;9799:57;9777:13;9736:16;9833:4;9821:17;;9799:57;:::i;:::-;9923:13;;9878:20;;;9945:57;9923:13;9878:20;9979:4;9967:17;;9945:57;:::i;:::-;10018:20;;9380:664;-1:-1:-1;;;;;9380:664:1:o;10776:488::-;-1:-1:-1;;;;;11045:15:1;;;11027:34;;11097:15;;11092:2;11077:18;;11070:43;11144:2;11129:18;;11122:34;;;11192:3;11187:2;11172:18;;11165:31;;;10970:4;;11213:45;;11238:19;;11230:6;11213:45;:::i;:::-;11205:53;10776:488;-1:-1:-1;;;;;;10776:488:1:o;11643:219::-;11792:2;11781:9;11774:21;11755:4;11812:44;11852:2;11841:9;11837:18;11829:6;11812:44;:::i;11867:506::-;12128:3;12117:9;12110:22;12091:4;12149:45;12189:3;12178:9;12174:19;12166:6;12149:45;:::i;:::-;12141:53;;12230:6;12225:2;12214:9;12210:18;12203:34;12273:6;12268:2;12257:9;12253:18;12246:34;12316:6;12311:2;12300:9;12296:18;12289:34;12360:6;12354:3;12343:9;12339:19;12332:35;11867:506;;;;;;;;:::o;20820:415::-;21022:2;21004:21;;;21061:2;21041:18;;;21034:30;21100:34;21095:2;21080:18;;21073:62;-1:-1:-1;;;21166:2:1;21151:18;;21144:49;21225:3;21210:19;;20820:415::o;24718:253::-;24758:3;-1:-1:-1;;;;;24847:2:1;24844:1;24840:10;24877:2;24874:1;24870:10;24908:3;24904:2;24900:12;24895:3;24892:21;24889:47;;;24916:18;;:::i;:::-;24952:13;;24718:253;-1:-1:-1;;;;24718:253:1:o;24976:128::-;25016:3;25047:1;25043:6;25040:1;25037:13;25034:39;;;25053:18;;:::i;:::-;-1:-1:-1;25089:9:1;;24976:128::o;25109:217::-;25149:1;25175;25165:132;;25219:10;25214:3;25210:20;25207:1;25200:31;25254:4;25251:1;25244:15;25282:4;25279:1;25272:15;25165:132;-1:-1:-1;25311:9:1;;25109:217::o;25331:168::-;25371:7;25437:1;25433;25429:6;25425:14;25422:1;25419:21;25414:1;25407:9;25400:17;25396:45;25393:71;;;25444:18;;:::i;:::-;-1:-1:-1;25484:9:1;;25331:168::o;25504:246::-;25544:4;-1:-1:-1;;;;;25657:10:1;;;;25627;;25679:12;;;25676:38;;;25694:18;;:::i;:::-;25731:13;;25504:246;-1:-1:-1;;;25504:246:1:o;25755:125::-;25795:4;25823:1;25820;25817:8;25814:34;;;25828:18;;:::i;:::-;-1:-1:-1;25865:9:1;;25755:125::o;25885:258::-;25957:1;25967:113;25981:6;25978:1;25975:13;25967:113;;;26057:11;;;26051:18;26038:11;;;26031:39;26003:2;25996:10;25967:113;;;26098:6;26095:1;26092:13;26089:48;;;-1:-1:-1;;26133:1:1;26115:16;;26108:27;25885:258::o;26148:380::-;26227:1;26223:12;;;;26270;;;26291:61;;26345:4;26337:6;26333:17;26323:27;;26291:61;26398:2;26390:6;26387:14;26367:18;26364:38;26361:161;;;26444:10;26439:3;26435:20;26432:1;26425:31;26479:4;26476:1;26469:15;26507:4;26504:1;26497:15;26361:161;;26148:380;;;:::o;26533:135::-;26572:3;-1:-1:-1;;26593:17:1;;26590:43;;;26613:18;;:::i;:::-;-1:-1:-1;26660:1:1;26649:13;;26533:135::o;26673:127::-;26734:10;26729:3;26725:20;26722:1;26715:31;26765:4;26762:1;26755:15;26789:4;26786:1;26779:15;26937:127;26998:10;26993:3;26989:20;26986:1;26979:31;27029:4;27026:1;27019:15;27053:4;27050:1;27043:15;27069:127;27130:10;27125:3;27121:20;27118:1;27111:31;27161:4;27158:1;27151:15;27185:4;27182:1;27175:15;27201:118;27287:5;27280:13;27273:21;27266:5;27263:32;27253:60;;27309:1;27306;27299:12;27324:131;-1:-1:-1;;;;;;27398:32:1;;27388:43;;27378:71;;27445:1;27442;27435:12

Swarm Source

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