ETH Price: $3,512.09 (+0.72%)
Gas: 2 Gwei

Token

Yeti Frens (YETIFRENS)
 

Overview

Max Total Supply

715 YETIFRENS

Holders

278

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
betozeph.eth
Balance
2 YETIFRENS
0x2758B31c399baFF893C085F2b2Ba2bDd8772bb99
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:
YetiFrens

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-12-22
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

/*                                       
 * @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
     * ====
     *
     * [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://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

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

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

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

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

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

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

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

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

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

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

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

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

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

abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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

interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the
     * ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    /**
     * The `quantity` minted with ERC2309 exceeds the safety limit.
     */
    error MintERC2309QuantityExceedsLimit();

    /**
     * The `extraData` cannot be set on an unintialized ownership slot.
     */
    error OwnershipNotInitializedForExtraData();

    // =============================================================
    //                            STRUCTS
    // =============================================================

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Stores the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
        uint24 extraData;
    }

    // =============================================================
    //                         TOKEN COUNTERS
    // =============================================================

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() external view returns (uint256);

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

    // =============================================================
    //                            IERC721
    // =============================================================

    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

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

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

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

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

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

    // =============================================================
    //                           IERC2309
    // =============================================================

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
     *
     * See {_mintERC2309} for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

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

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

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

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

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

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

library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

library Strings {
    bytes16 private constant _HEX_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) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

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

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

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

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 anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _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);
    }
}

library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

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

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

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

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

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

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

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

        return (signer, RecoverError.NoError);
    }

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

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

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

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

contract PaymentSplitter is Context {
    event PayeeAdded(address account, uint256 shares);
    event PaymentReleased(address to, uint256 amount);
    event ERC20PaymentReleased(IERC20 indexed token, address to, uint256 amount);
    event PaymentReceived(address from, uint256 amount);

    uint256 private _totalShares;
    uint256 private _totalReleased;

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

    mapping(IERC20 => uint256) private _erc20TotalReleased;
    mapping(IERC20 => mapping(address => uint256)) private _erc20Released;

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

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

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

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

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

    /**
     * @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20
     * contract.
     */
    function totalReleased(IERC20 token) public view returns (uint256) {
        return _erc20TotalReleased[token];
    }

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

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

    /**
     * @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an
     * IERC20 contract.
     */
    function released(IERC20 token, address account) public view returns (uint256) {
        return _erc20Released[token][account];
    }

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

    /**
     * @dev Getter for the amount of payee's releasable Ether.
     */
    function releasable(address account) public view returns (uint256) {
        uint256 totalReceived = address(this).balance + totalReleased();
        return _pendingPayment(account, totalReceived, released(account));
    }

    /**
     * @dev Getter for the amount of payee's releasable `token` tokens. `token` should be the address of an
     * IERC20 contract.
     */
    function releasable(IERC20 token, address account) public view returns (uint256) {
        uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token);
        return _pendingPayment(account, totalReceived, released(token, account));
    }

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

        uint256 payment = releasable(account);

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

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

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

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

        uint256 payment = releasable(token, account);

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

        _erc20Released[token][account] += payment;
        _erc20TotalReleased[token] += payment;

        SafeERC20.safeTransfer(token, account, payment);
        emit ERC20PaymentReleased(token, account, payment);
    }

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

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

        _payees.push(account);
        _shares[account] = shares_;
        _totalShares = _totalShares + shares_;
        emit PayeeAdded(account, shares_);
    }
}

/**
 * @dev Interface of ERC721 token receiver.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @title ERC721A
 *
 * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
 * Non-Fungible Token Standard, including the Metadata extension.
 * Optimized for lower gas during batch mints.
 *
 * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
 * starting from `_startTokenId()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Reference type for token approval.
    struct TokenApprovalRef {
        address value;
    }

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    // Mask of an entry in packed address data.
    uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

    // The bit position of `numberMinted` in packed address data.
    uint256 private constant _BITPOS_NUMBER_MINTED = 64;

    // The bit position of `numberBurned` in packed address data.
    uint256 private constant _BITPOS_NUMBER_BURNED = 128;

    // The bit position of `aux` in packed address data.
    uint256 private constant _BITPOS_AUX = 192;

    // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
    uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

    // The bit position of `startTimestamp` in packed ownership.
    uint256 private constant _BITPOS_START_TIMESTAMP = 160;

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant _BITMASK_BURNED = 1 << 224;

    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;

    // The bit mask of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;

    // The bit position of `extraData` in packed ownership.
    uint256 private constant _BITPOS_EXTRA_DATA = 232;

    // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
    uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;

    // The maximum `quantity` that can be minted with {_mintERC2309}.
    // This limit is to prevent overflows on the address data entries.
    // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
    // is required to cause an overflow, which is unrealistic.
    uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

    // The `Transfer` event signature is given by:
    // `keccak256(bytes("Transfer(address,address,uint256)"))`.
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    // =============================================================
    //                            STORAGE
    // =============================================================

    // The next token ID to be minted.
    uint256 private _currentIndex;

    // The number of tokens burned.
    uint256 private _burnCounter;

    // 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 {_packedOwnershipOf} implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    // - [232..255] `extraData`
    mapping(uint256 => uint256) private _packedOwnerships;

    // Mapping owner address to address data.
    //
    // Bits Layout:
    // - [0..63]    `balance`
    // - [64..127]  `numberMinted`
    // - [128..191] `numberBurned`
    // - [192..255] `aux`
    mapping(address => uint256) private _packedAddressData;

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

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

    // =============================================================
    //                          CONSTRUCTOR
    // =============================================================

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

    // =============================================================
    //                   TOKEN COUNTING OPERATIONS
    // =============================================================

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

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view virtual returns (uint256) {
        return _currentIndex;
    }

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view virtual returns (uint256) {
        // Counter underflow is impossible as `_currentIndex` does not decrement,
        // and it is initialized to `_startTokenId()`.
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev Returns the total number of tokens burned.
     */
    function _totalBurned() internal view virtual returns (uint256) {
        return _burnCounter;
    }

    // =============================================================
    //                    ADDRESS DATA OPERATIONS
    // =============================================================

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
    }

    /**
     * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal virtual {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        // Cast `aux` with assembly to avoid redundant masking.
        assembly {
            auxCasted := aux
        }
        packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes
        // of the XOR of all function selectors in the interface.
        // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
        // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

    /**
     * @dev Returns the token collection name.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
    }

    /**
     * @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, it can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    // =============================================================
    //                     OWNERSHIPS OPERATIONS
    // =============================================================

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

    /**
     * @dev Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around over time.
     */
    function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnershipOf(tokenId));
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct at `index`.
     */
    function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnerships[index]);
    }

    /**
     * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
     */
    function _initializeOwnershipAt(uint256 index) internal virtual {
        if (_packedOwnerships[index] == 0) {
            _packedOwnerships[index] = _packedOwnershipOf(index);
        }
    }

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & _BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an initialized ownership slot
                        // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                        // before an unintialized ownership slot
                        // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                        // Hence, `curr` will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed will be zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
        ownership.burned = packed & _BITMASK_BURNED != 0;
        ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
    }

    /**
     * @dev Packs ownership data into a single uint256.
     */
    function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
            result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
        }
    }

    /**
     * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
     */
    function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
        // For branchless setting of the `nextInitialized` flag.
        assembly {
            // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
            result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
        }
    }

    // =============================================================
    //                      APPROVAL OPERATIONS
    // =============================================================

    /**
     * @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) public virtual override {
        address owner = ownerOf(tokenId);

        if (_msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                revert ApprovalCallerNotOwnerNorApproved();
            }

        _tokenApprovals[tokenId].value = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId].value;
    }

    /**
     * @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) public virtual override {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

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

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

    /**
     * @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. See {_mint}.
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
     */
    function _isSenderApprovedOrOwner(
        address approvedAddress,
        address owner,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, _BITMASK_ADDRESS)
            // `msgSender == owner || msgSender == approvedAddress`.
            result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
        }
    }

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedSlotAndAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId]`.
        assembly {
            approvedAddressSlot := tokenApproval.slot
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    // =============================================================
    //                      TRANSFER OPERATIONS
    // =============================================================

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * 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
    ) public virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
            if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

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

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

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

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @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 memory _data
    ) public virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token IDs
     * are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * `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`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    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.
     * And also called after one token has been burned.
     *
     * `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` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * `from` - Previous owner of the given token ID.
     * `to` - Target address that will receive the token.
     * `tokenId` - Token ID to be transferred.
     * `_data` - Optional data to send along with the call.
     *
     * Returns whether the call correctly returned the expected magic value.
     */
    function _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    // =============================================================
    //                        MINT OPERATIONS
    // =============================================================

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mint(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

            // Use assembly to loop and emit the `Transfer` event for gas savings.
            assembly {
                // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
                toMasked := and(to, _BITMASK_ADDRESS)
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    startTokenId // `tokenId`.
                )

                for {
                    let tokenId := add(startTokenId, 1)
                } iszero(eq(tokenId, end)) {
                    tokenId := add(tokenId, 1)
                } {
                    // Emit the `Transfer` event. Similar to above.
                    log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                }
            }
            if (toMasked == 0) revert MintToZeroAddress();

            _currentIndex = end;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * This function is intended for efficient minting only during contract creation.
     *
     * It emits only one {ConsecutiveTransfer} as defined in
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
     * instead of a sequence of {Transfer} event(s).
     *
     * Calling this function outside of contract creation WILL make your contract
     * non-compliant with the ERC721 standard.
     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
     * {ConsecutiveTransfer} event is only permissible during contract creation.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {ConsecutiveTransfer} event.
     */
    function _mintERC2309(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();
        if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();

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

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);

            _currentIndex = startTokenId + quantity;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

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

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal virtual {
        _safeMint(to, quantity, '');
    }

    // =============================================================
    //                        BURN OPERATIONS
    // =============================================================

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

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

        address from = address(uint160(prevOwnershipPacked));

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        if (approvalCheck) {
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
                if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                from,
                (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    // =============================================================
    //                     EXTRA DATA OPERATIONS
    // =============================================================

    /**
     * @dev Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

    /**
     * @dev Returns the next extra data for the packed ownership data.
     * The returned result is shifted into position.
     */
    function _nextExtraData(
        address from,
        address to,
        uint256 prevOwnershipPacked
    ) private view returns (uint256) {
        uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
        return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
    }

    // =============================================================
    //                       OTHER OPERATIONS
    // =============================================================

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     *
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @dev Converts a uint256 to its ASCII string decimal representation.
     */
    function _toString(uint256 value) internal pure virtual returns (string memory ptr) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit),
            // but we allocate 128 bytes to keep the free memory pointer 32-byte word aliged.
            // We will need 1 32-byte word to store the length,
            // and 3 32-byte words to store a maximum of 78 digits. Total: 32 + 3 * 32 = 128.
            ptr := add(mload(0x40), 128)
            // Update the free memory pointer to allocate.
            mstore(0x40, ptr)

            // Cache the end of the memory to calculate the length later.
            let end := ptr

            // We write the string from the rightmost digit to the leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // Costs a bit more than early returning for the zero case,
            // but cheaper in terms of deployment and overall runtime costs.
            for {
                // Initialize and perform the first pass without check.
                let temp := value
                // Move the pointer 1 byte leftwards to point to an empty character slot.
                ptr := sub(ptr, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(ptr, add(48, mod(temp, 10)))
                temp := div(temp, 10)
            } temp {
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
            } {
                // Body of the for loop.
                ptr := sub(ptr, 1)
                mstore8(ptr, add(48, mod(temp, 10)))
            }

            let length := sub(end, ptr)
            // Move the pointer 32 bytes leftwards to make room for the length.
            ptr := sub(ptr, 32)
            // Store the length.
            mstore(ptr, length)
        }
    }
}

contract YetiFrens is Ownable, ERC721A, PaymentSplitter {

    using ECDSA for bytes32;
    using Strings for uint;

    address private signerAddressVIP;
    address private signerAddressWL;

    enum Step {
        Before,
        VIPSale,
        WhitelistSale,
        PublicSale,
        SoldOut,
        Reveal
    }

    string public baseURI;

    Step public sellingStep;

    uint private constant MAX_SUPPLY = 5000;

    uint public wlSalePrice = 0.02 ether;
    uint public publicSalePrice = 0.03 ether;
    uint public vipSalePrice = 0.02 ether;

    mapping(address => uint) public mintedAmountNFTsperWalletOGs;

    uint public maxMintAmountPerOGs = 2;

    uint public maxAmountPerTxnPublic = 5; 

    uint private teamLength;

    constructor(address[] memory _team, uint[] memory _teamShares, address _signerAddressVIP, address _signerAddressWL, string memory _baseURI) ERC721A("Yeti Frens", "YETIFRENS")
    PaymentSplitter(_team, _teamShares) {
        signerAddressVIP = _signerAddressVIP;
        signerAddressWL = _signerAddressWL;
        baseURI = _baseURI;
        teamLength = _team.length;
    }

    function mintForOpensea() external onlyOwner{
        if(totalSupply() != 0) revert("Only one mint for deployer");
        _mint(msg.sender, 1);
    }

    function VIPMint(uint _quantity, bytes calldata signature) external payable{
        uint price = vipSalePrice;
        if(price <= 0) revert("Price is 0");
        if(msg.value < price * _quantity) revert("Not enough funds");
        if(sellingStep != Step.VIPSale) revert("VIP Mint is not open");
        if(totalSupply() + _quantity > MAX_SUPPLY) revert("Max supply for VIP exceeded");
        if(signerAddressVIP != keccak256(
            abi.encodePacked(
                "\x19Ethereum Signed Message:\n32",
                bytes32(uint256(uint160(msg.sender)))
            )
        ).recover(signature)) revert("You are not a VIP");
        if(mintedAmountNFTsperWalletOGs[msg.sender] + _quantity > maxMintAmountPerOGs) revert("Max exceeded for VIP Sale");
        mintedAmountNFTsperWalletOGs[msg.sender] += _quantity;
        _mint(msg.sender, _quantity);
    }

    function publicSaleMint(uint _quantity) external payable {
        uint price = publicSalePrice;
        if(price <= 0) revert("Price is 0");
        if(msg.value < price * _quantity) revert("Not enough funds");
        if(_quantity > maxAmountPerTxnPublic) revert("Over max amount per txn");
        if(sellingStep != Step.PublicSale) revert("Public Mint not live.");
        if(totalSupply() + _quantity > MAX_SUPPLY) revert("Max supply exceeded");
        _mint(msg.sender, _quantity);
    }

    function WLMint(uint _quantity, bytes calldata signature) external payable {
        uint price = wlSalePrice;
        if(price <= 0) revert("Price is 0");
        if(msg.value < price * _quantity) revert("Not enough funds"); 
        if(sellingStep != Step.WhitelistSale) revert("WL Mint not live.");
        if(totalSupply() + _quantity > MAX_SUPPLY) revert("Max supply exceeded for WL");
        if(signerAddressWL != keccak256(
            abi.encodePacked(
                "\x19Ethereum Signed Message:\n32",
                bytes32(uint256(uint160(msg.sender)))
            )
        ).recover(signature)) revert("You are not in WL whitelist");
        if(mintedAmountNFTsperWalletOGs[msg.sender] + _quantity > maxMintAmountPerOGs) revert("Max exceeded for Whitelist Sale");
            
        mintedAmountNFTsperWalletOGs[msg.sender] += _quantity;
        _mint(msg.sender, _quantity);
    }

    function currentState() external view returns (Step, uint, uint, uint, uint, uint) {
        return (sellingStep, publicSalePrice, wlSalePrice, vipSalePrice, maxMintAmountPerOGs, maxAmountPerTxnPublic);
    }

    function changeWlSalePrice(uint256 new_price) external onlyOwner{
        wlSalePrice = new_price;
    }

    function changePublicSalePrice(uint256 new_price) external onlyOwner{
        publicSalePrice = new_price;
    }

    function changeVIPSalePrice(uint256 new_price) external onlyOwner{
        vipSalePrice = new_price;
    }

    function setBaseUri(string memory _baseURI) external onlyOwner {
        baseURI = _baseURI;
    }

    function setStep(uint _step) external onlyOwner {
        sellingStep = Step(_step);
    }

    function setMaxMintPerOGs(uint amount) external onlyOwner {
        maxMintAmountPerOGs = amount;
    }

    function setMaxTxnPublic(uint amount) external onlyOwner{
        maxAmountPerTxnPublic = amount;
    }

    function getNumberMinted(address account) external view returns (uint256) {
        return _numberMinted(account);
    }

    function getNumberOGMinted(address account) external view returns (uint256) {
        return mintedAmountNFTsperWalletOGs[account];
    }

    function tokenURI(uint _tokenId) public view virtual override returns (string memory) {
        require(_exists(_tokenId), "URI query for nonexistent token");
        return string(abi.encodePacked(baseURI, _toString(_tokenId), ".json"));
    }

    function releaseAll() external {
        for(uint i = 0 ; i < teamLength ; i++) {
            release(payable(payee(i)));
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address[]","name":"_team","type":"address[]"},{"internalType":"uint256[]","name":"_teamShares","type":"uint256[]"},{"internalType":"address","name":"_signerAddressVIP","type":"address"},{"internalType":"address","name":"_signerAddressWL","type":"address"},{"internalType":"string","name":"_baseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","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":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","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":[{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"VIPMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"WLMint","outputs":[],"stateMutability":"payable","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":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"new_price","type":"uint256"}],"name":"changePublicSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"new_price","type":"uint256"}],"name":"changeVIPSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"new_price","type":"uint256"}],"name":"changeWlSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentState","outputs":[{"internalType":"enum YetiFrens.Step","name":"","type":"uint8"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getNumberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getNumberOGMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAmountPerTxnPublic","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintAmountPerOGs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintForOpensea","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mintedAmountNFTsperWalletOGs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"}],"name":"publicSaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicSalePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"releasable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"releasable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"releaseAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sellingStep","outputs":[{"internalType":"enum YetiFrens.Step","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxMintPerOGs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxTxnPublic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_step","type":"uint256"}],"name":"setStep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vipSalePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wlSalePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405266470de4df820000601455666a94d74f43000060155566470de4df820000601655600260185560056019553480156200003c57600080fd5b5060405162003744380380620037448339810160408190526200005f9162000635565b84846040518060400160405280600a81526020016959657469204672656e7360b01b81525060405180604001604052806009815260200168594554494652454e5360b81b815250620000c0620000ba6200026760201b60201c565b6200026b565b6003620000ce8382620007e1565b506004620000dd8282620007e1565b506001805550508051825114620001565760405162461bcd60e51b815260206004820152603260248201527f5061796d656e7453706c69747465723a2070617965657320616e6420736861726044820152710cae640d8cadccee8d040dad2e6dac2e8c6d60731b60648201526084015b60405180910390fd5b6000825111620001a95760405162461bcd60e51b815260206004820152601a60248201527f5061796d656e7453706c69747465723a206e6f2070617965657300000000000060448201526064016200014d565b60005b8251811015620002155762000200838281518110620001cf57620001cf620008ad565b6020026020010151838381518110620001ec57620001ec620008ad565b6020026020010151620002bb60201b60201c565b806200020c81620008d9565b915050620001ac565b5050601080546001600160a01b038087166001600160a01b0319928316179092556011805492861692909116919091179055506012620002568282620007e1565b50509251601a555062000911915050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038216620003285760405162461bcd60e51b815260206004820152602c60248201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060448201526b7a65726f206164647265737360a01b60648201526084016200014d565b600081116200037a5760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a2073686172657320617265203000000060448201526064016200014d565b6001600160a01b0382166000908152600b602052604090205415620003f65760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960448201526a206861732073686172657360a81b60648201526084016200014d565b600d8054600181019091557fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb50180546001600160a01b0319166001600160a01b0384169081179091556000908152600b6020526040902081905560095462000460908290620008f5565b600955604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910160405180910390a15050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620004ea57620004ea620004a9565b604052919050565b60006001600160401b038211156200050e576200050e620004a9565b5060051b60200190565b80516001600160a01b03811681146200053057600080fd5b919050565b600082601f8301126200054757600080fd5b81516020620005606200055a83620004f2565b620004bf565b82815260059290921b840181019181810190868411156200058057600080fd5b8286015b848110156200059d578051835291830191830162000584565b509695505050505050565b600082601f830112620005ba57600080fd5b81516001600160401b03811115620005d657620005d6620004a9565b6020620005ec601f8301601f19168201620004bf565b82815285828487010111156200060157600080fd5b60005b838110156200062157858101830151828201840152820162000604565b506000928101909101919091529392505050565b600080600080600060a086880312156200064e57600080fd5b85516001600160401b03808211156200066657600080fd5b818801915088601f8301126200067b57600080fd5b815160206200068e6200055a83620004f2565b82815260059290921b8401810191818101908c841115620006ae57600080fd5b948201945b83861015620006d757620006c78662000518565b82529482019490820190620006b3565b918b0151919950909350505080821115620006f157600080fd5b620006ff89838a0162000535565b95506200070f6040890162000518565b94506200071f6060890162000518565b935060808801519150808211156200073657600080fd5b506200074588828901620005a8565b9150509295509295909350565b600181811c908216806200076757607f821691505b6020821081036200078857634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620007dc57600081815260208120601f850160051c81016020861015620007b75750805b601f850160051c820191505b81811015620007d857828155600101620007c3565b5050505b505050565b81516001600160401b03811115620007fd57620007fd620004a9565b62000815816200080e845462000752565b846200078e565b602080601f8311600181146200084d5760008415620008345750858301515b600019600386901b1c1916600185901b178555620007d8565b600085815260208120601f198616915b828110156200087e578886015182559484019460019091019084016200085d565b50858210156200089d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620008ee57620008ee620008c3565b5060010190565b808201808211156200090b576200090b620008c3565b92915050565b612e2380620009216000396000f3fe6080604052600436106102e85760003560e01c8063734c66bd11610190578063c45ac050116100dc578063d79779b211610095578063ee70c7cb1161006f578063ee70c7cb1461097b578063f2fde38b14610991578063f8dcbddb146109b1578063fe8ce064146109d157600080fd5b8063d79779b2146108e7578063e33b7de31461091d578063e985e9c51461093257600080fd5b8063c45ac050146107ff578063c87b56dd1461081f578063c893575a1461083f578063cbccefb214610854578063ce7c2ac21461087b578063cf01342b146108b157600080fd5b80639852595c11610149578063a22cb46511610123578063a22cb4651461078c578063a3f8eace146107ac578063b3ab66b0146107cc578063b88d4fde146107df57600080fd5b80639852595c146107205780639b6860c814610756578063a0bcfc7f1461076c57600080fd5b8063734c66bd146106775780638a02e3b91461068d5780638a59a7fd146106ad5780638b83209b146106cd5780638da5cb5b146106ed57806395d89b411461070b57600080fd5b806348b750441161024f5780635be7fde8116102085780636bb0b37b116101e25780636bb0b37b146106005780636c0360eb1461062d57806370a0823114610642578063715018a61461066257600080fd5b80635be7fde8146105b55780635e8bada0146105ca5780636352211e146105e057600080fd5b806348b750441461050c5780634e821a311461052c5780634f8aed6e1461054c5780634fda72851461056257806359d20e61146105825780635b2fda67146105a257600080fd5b806318160ddd116102a157806318160ddd1461042e578063191655871461045157806323b872dd146104715780633a98ef3914610491578063406072a9146104a657806342842e0e146104ec57600080fd5b806301ffc9a71461033657806306fdde031461036b578063081812fc1461038d578063093cf9fe146103c5578063095ea7b3146103da5780630c3f6acf146103fa57600080fd5b36610331577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b34801561034257600080fd5b506103566103513660046125ed565b6109f1565b60405190151581526020015b60405180910390f35b34801561037757600080fd5b50610380610a43565b604051610362919061265a565b34801561039957600080fd5b506103ad6103a836600461266d565b610ad5565b6040516001600160a01b039091168152602001610362565b6103d86103d3366004612686565b610b19565b005b3480156103e657600080fd5b506103d86103f5366004612717565b610db4565b34801561040657600080fd5b506013546015546014546016546018546019546040516103629660ff1695949392919061277b565b34801561043a57600080fd5b50610443610e54565b604051908152602001610362565b34801561045d57600080fd5b506103d861046c3660046127b1565b610e62565b34801561047d57600080fd5b506103d861048c3660046127ce565b610f5b565b34801561049d57600080fd5b50600954610443565b3480156104b257600080fd5b506104436104c136600461280f565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205490565b3480156104f857600080fd5b506103d86105073660046127ce565b6110f4565b34801561051857600080fd5b506103d861052736600461280f565b611114565b34801561053857600080fd5b506103d861054736600461266d565b611237565b34801561055857600080fd5b5061044360165481565b34801561056e57600080fd5b506103d861057d36600461266d565b611244565b34801561058e57600080fd5b506103d861059d36600461266d565b611251565b6103d86105b0366004612686565b61125e565b3480156105c157600080fd5b506103d86114a0565b3480156105d657600080fd5b5061044360185481565b3480156105ec57600080fd5b506103ad6105fb36600461266d565b6114ce565b34801561060c57600080fd5b5061044361061b3660046127b1565b60176020526000908152604090205481565b34801561063957600080fd5b506103806114d9565b34801561064e57600080fd5b5061044361065d3660046127b1565b611567565b34801561066e57600080fd5b506103d86115b6565b34801561068357600080fd5b5061044360145481565b34801561069957600080fd5b506103d86106a836600461266d565b6115ca565b3480156106b957600080fd5b506104436106c83660046127b1565b6115d7565b3480156106d957600080fd5b506103ad6106e836600461266d565b611602565b3480156106f957600080fd5b506000546001600160a01b03166103ad565b34801561071757600080fd5b50610380611632565b34801561072c57600080fd5b5061044361073b3660046127b1565b6001600160a01b03166000908152600c602052604090205490565b34801561076257600080fd5b5061044360155481565b34801561077857600080fd5b506103d86107873660046128d4565b611641565b34801561079857600080fd5b506103d86107a736600461292b565b611659565b3480156107b857600080fd5b506104436107c73660046127b1565b6116ee565b6103d86107da36600461266d565b611736565b3480156107eb57600080fd5b506103d86107fa366004612959565b611893565b34801561080b57600080fd5b5061044361081a36600461280f565b6118d7565b34801561082b57600080fd5b5061038061083a36600461266d565b6119a2565b34801561084b57600080fd5b506103d8611a2b565b34801561086057600080fd5b5060135461086e9060ff1681565b60405161036291906129d9565b34801561088757600080fd5b506104436108963660046127b1565b6001600160a01b03166000908152600b602052604090205490565b3480156108bd57600080fd5b506104436108cc3660046127b1565b6001600160a01b031660009081526017602052604090205490565b3480156108f357600080fd5b506104436109023660046127b1565b6001600160a01b03166000908152600e602052604090205490565b34801561092957600080fd5b50600a54610443565b34801561093e57600080fd5b5061035661094d36600461280f565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205460ff1690565b34801561098757600080fd5b5061044360195481565b34801561099d57600080fd5b506103d86109ac3660046127b1565b611a93565b3480156109bd57600080fd5b506103d86109cc36600461266d565b611b09565b3480156109dd57600080fd5b506103d86109ec36600461266d565b611b47565b60006301ffc9a760e01b6001600160e01b031983161480610a2257506380ac58cd60e01b6001600160e01b03198316145b80610a3d5750635b5e139f60e01b6001600160e01b03198316145b92915050565b606060038054610a52906129e7565b80601f0160208091040260200160405190810160405280929190818152602001828054610a7e906129e7565b8015610acb5780601f10610aa057610100808354040283529160200191610acb565b820191906000526020600020905b815481529060010190602001808311610aae57829003601f168201915b5050505050905090565b6000610ae082611b54565b610afd576040516333d1c03960e21b815260040160405180910390fd5b506000908152600760205260409020546001600160a01b031690565b60165480610b425760405162461bcd60e51b8152600401610b3990612a21565b60405180910390fd5b610b4c8482612a5b565b341015610b6b5760405162461bcd60e51b8152600401610b3990612a72565b600160135460ff166005811115610b8457610b84612743565b14610bc85760405162461bcd60e51b81526020600482015260146024820152732b24a81026b4b73a1034b9903737ba1037b832b760611b6044820152606401610b39565b61138884610bd4610e54565b610bde9190612a9c565b1115610c2c5760405162461bcd60e51b815260206004820152601b60248201527f4d617820737570706c7920666f722056495020657863656564656400000000006044820152606401610b39565b610cc283838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602082015233603c820152605c019150610c9e9050565b60405160208183030381529060405280519060200120611b8990919063ffffffff16565b6010546001600160a01b03908116911614610d135760405162461bcd60e51b81526020600482015260116024820152700596f7520617265206e6f7420612056495607c1b6044820152606401610b39565b60185433600090815260176020526040902054610d31908690612a9c565b1115610d7f5760405162461bcd60e51b815260206004820152601960248201527f4d617820657863656564656420666f72205649502053616c65000000000000006044820152606401610b39565b3360009081526017602052604081208054869290610d9e908490612a9c565b90915550610dae90503385611bad565b50505050565b6000610dbf826114ce565b9050336001600160a01b03821614610df857610ddb813361094d565b610df8576040516367d9dca160e11b815260040160405180910390fd5b60008281526007602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600254600154036000190190565b6001600160a01b0381166000908152600b6020526040902054610e975760405162461bcd60e51b8152600401610b3990612aaf565b6000610ea2826116ee565b905080600003610ec45760405162461bcd60e51b8152600401610b3990612af5565b6001600160a01b0382166000908152600c602052604081208054839290610eec908490612a9c565b9250508190555080600a6000828254610f059190612a9c565b90915550610f1590508282611cab565b604080516001600160a01b0384168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a15050565b6000610f6682611dc4565b9050836001600160a01b0316816001600160a01b031614610f995760405162a1148160e81b815260040160405180910390fd5b60008281526007602052604090208054338082146001600160a01b03881690911417610fe657610fc9863361094d565b610fe657604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03851661100d57604051633a954ecd60e21b815260040160405180910390fd5b801561101857600082555b6001600160a01b038681166000908152600660205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260056020526040812091909155600160e11b841690036110aa576001840160008181526005602052604081205490036110a85760015481146110a85760008181526005602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b61110f83838360405180602001604052806000815250611893565b505050565b6001600160a01b0381166000908152600b60205260409020546111495760405162461bcd60e51b8152600401610b3990612aaf565b600061115583836118d7565b9050806000036111775760405162461bcd60e51b8152600401610b3990612af5565b6001600160a01b038084166000908152600f60209081526040808320938616835292905290812080548392906111ae908490612a9c565b90915550506001600160a01b0383166000908152600e6020526040812080548392906111db908490612a9c565b909155506111ec9050838383611e33565b604080516001600160a01b038481168252602082018490528516917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a2505050565b61123f611e85565b601655565b61124c611e85565b601555565b611259611e85565b601455565b6014548061127e5760405162461bcd60e51b8152600401610b3990612a21565b6112888482612a5b565b3410156112a75760405162461bcd60e51b8152600401610b3990612a72565b600260135460ff1660058111156112c0576112c0612743565b146113015760405162461bcd60e51b81526020600482015260116024820152702ba61026b4b73a103737ba103634bb329760791b6044820152606401610b39565b6113888461130d610e54565b6113179190612a9c565b11156113655760405162461bcd60e51b815260206004820152601a60248201527f4d617820737570706c7920657863656564656420666f7220574c0000000000006044820152606401610b39565b6113d783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602082015233603c820152605c019150610c9e9050565b6011546001600160a01b039081169116146114345760405162461bcd60e51b815260206004820152601b60248201527f596f7520617265206e6f7420696e20574c2077686974656c69737400000000006044820152606401610b39565b60185433600090815260176020526040902054611452908690612a9c565b1115610d7f5760405162461bcd60e51b815260206004820152601f60248201527f4d617820657863656564656420666f722057686974656c6973742053616c65006044820152606401610b39565b60005b601a548110156114cb576114b961046c82611602565b806114c381612b40565b9150506114a3565b50565b6000610a3d82611dc4565b601280546114e6906129e7565b80601f0160208091040260200160405190810160405280929190818152602001828054611512906129e7565b801561155f5780601f106115345761010080835404028352916020019161155f565b820191906000526020600020905b81548152906001019060200180831161154257829003601f168201915b505050505081565b60006001600160a01b038216611590576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526006602052604090205467ffffffffffffffff1690565b6115be611e85565b6115c86000611edf565b565b6115d2611e85565b601955565b6001600160a01b0381166000908152600660205260408082205467ffffffffffffffff911c16610a3d565b6000600d828154811061161757611617612b59565b6000918252602090912001546001600160a01b031692915050565b606060048054610a52906129e7565b611649611e85565b60126116558282612bb5565b5050565b336001600160a01b038316036116825760405163b06307db60e01b815260040160405180910390fd5b3360008181526008602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000806116fa600a5490565b6117049047612a9c565b905061172f838261172a866001600160a01b03166000908152600c602052604090205490565b611f2f565b9392505050565b601554806117565760405162461bcd60e51b8152600401610b3990612a21565b6117608282612a5b565b34101561177f5760405162461bcd60e51b8152600401610b3990612a72565b6019548211156117d15760405162461bcd60e51b815260206004820152601760248201527f4f766572206d617820616d6f756e74207065722074786e0000000000000000006044820152606401610b39565b600360135460ff1660058111156117ea576117ea612743565b1461182f5760405162461bcd60e51b8152602060048201526015602482015274283ab13634b19026b4b73a103737ba103634bb329760591b6044820152606401610b39565b6113888261183b610e54565b6118459190612a9c565b11156118895760405162461bcd60e51b815260206004820152601360248201527213585e081cdd5c1c1b1e48195e18d959591959606a1b6044820152606401610b39565b6116553383611bad565b61189e848484610f5b565b6001600160a01b0383163b15610dae576118ba84848484611f6d565b610dae576040516368d2bf6b60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600e602052604081205481906040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa158015611936573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195a9190612c75565b6119649190612a9c565b6001600160a01b038086166000908152600f602090815260408083209388168352929052205490915061199a9084908390611f2f565b949350505050565b60606119ad82611b54565b6119f95760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e006044820152606401610b39565b6012611a0483612058565b604051602001611a15929190612c8e565b6040516020818303038152906040529050919050565b611a33611e85565b611a3b610e54565b15611a885760405162461bcd60e51b815260206004820152601a60248201527f4f6e6c79206f6e65206d696e7420666f72206465706c6f7965720000000000006044820152606401610b39565b6115c8336001611bad565b611a9b611e85565b6001600160a01b038116611b005760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b39565b6114cb81611edf565b611b11611e85565b806005811115611b2357611b23612743565b6013805460ff19166001836005811115611b3f57611b3f612743565b021790555050565b611b4f611e85565b601855565b600081600111158015611b68575060015482105b8015610a3d575050600090815260056020526040902054600160e01b161590565b6000806000611b9885856120a7565b91509150611ba581612115565b509392505050565b6001546000829003611bd25760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526006602090815260408083208054680100000000000000018802019055848352600590915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114611c8157808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101611c49565b5081600003611ca257604051622e076360e81b815260040160405180910390fd5b60015550505050565b80471015611cfb5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610b39565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611d48576040519150601f19603f3d011682016040523d82523d6000602084013e611d4d565b606091505b505090508061110f5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610b39565b60008180600111611e1a57600154811015611e1a5760008181526005602052604081205490600160e01b82169003611e18575b8060000361172f575060001901600081815260056020526040902054611df7565b505b604051636f96cda160e11b815260040160405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261110f9084906122cb565b6000546001600160a01b031633146115c85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b39565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6009546001600160a01b0384166000908152600b602052604081205490918391611f599086612a5b565b611f639190612d25565b61199a9190612d47565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611fa2903390899088908890600401612d5a565b6020604051808303816000875af1925050508015611fdd575060408051601f3d908101601f19168201909252611fda91810190612d97565b60015b61203b573d80801561200b576040519150601f19603f3d011682016040523d82523d6000602084013e612010565b606091505b508051600003612033576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b604080516080810191829052607f0190826030600a8206018353600a90045b801561209557600183039250600a81066030018353600a9004612077565b50819003601f19909101908152919050565b60008082516041036120dd5760208301516040840151606085015160001a6120d18782858561239d565b9450945050505061210e565b825160400361210657602083015160408401516120fb86838361248a565b93509350505061210e565b506000905060025b9250929050565b600081600481111561212957612129612743565b036121315750565b600181600481111561214557612145612743565b036121925760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610b39565b60028160048111156121a6576121a6612743565b036121f35760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610b39565b600381600481111561220757612207612743565b0361225f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610b39565b600481600481111561227357612273612743565b036114cb5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610b39565b6000612320826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166124c39092919063ffffffff16565b80519091501561110f578080602001905181019061233e9190612db4565b61110f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610b39565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156123d45750600090506003612481565b8460ff16601b141580156123ec57508460ff16601c14155b156123fd5750600090506004612481565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612451573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661247a57600060019250925050612481565b9150600090505b94509492505050565b6000806001600160ff1b038316816124a760ff86901c601b612a9c565b90506124b58782888561239d565b935093505050935093915050565b606061199a8484600085856001600160a01b0385163b6125255760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b39565b600080866001600160a01b031685876040516125419190612dd1565b60006040518083038185875af1925050503d806000811461257e576040519150601f19603f3d011682016040523d82523d6000602084013e612583565b606091505b509150915061259382828661259e565b979650505050505050565b606083156125ad57508161172f565b8251156125bd5782518084602001fd5b8160405162461bcd60e51b8152600401610b39919061265a565b6001600160e01b0319811681146114cb57600080fd5b6000602082840312156125ff57600080fd5b813561172f816125d7565b60005b8381101561262557818101518382015260200161260d565b50506000910152565b6000815180845261264681602086016020860161260a565b601f01601f19169290920160200192915050565b60208152600061172f602083018461262e565b60006020828403121561267f57600080fd5b5035919050565b60008060006040848603121561269b57600080fd5b83359250602084013567ffffffffffffffff808211156126ba57600080fd5b818601915086601f8301126126ce57600080fd5b8135818111156126dd57600080fd5b8760208285010111156126ef57600080fd5b6020830194508093505050509250925092565b6001600160a01b03811681146114cb57600080fd5b6000806040838503121561272a57600080fd5b823561273581612702565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b6006811061277757634e487b7160e01b600052602160045260246000fd5b9052565b60c081016127898289612759565b602082019690965260408101949094526060840192909252608083015260a090910152919050565b6000602082840312156127c357600080fd5b813561172f81612702565b6000806000606084860312156127e357600080fd5b83356127ee81612702565b925060208401356127fe81612702565b929592945050506040919091013590565b6000806040838503121561282257600080fd5b823561282d81612702565b9150602083013561283d81612702565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff8084111561287957612879612848565b604051601f8501601f19908116603f011681019082821181831017156128a1576128a1612848565b816040528093508581528686860111156128ba57600080fd5b858560208301376000602087830101525050509392505050565b6000602082840312156128e657600080fd5b813567ffffffffffffffff8111156128fd57600080fd5b8201601f8101841361290e57600080fd5b61199a8482356020840161285e565b80151581146114cb57600080fd5b6000806040838503121561293e57600080fd5b823561294981612702565b9150602083013561283d8161291d565b6000806000806080858703121561296f57600080fd5b843561297a81612702565b9350602085013561298a81612702565b925060408501359150606085013567ffffffffffffffff8111156129ad57600080fd5b8501601f810187136129be57600080fd5b6129cd8782356020840161285e565b91505092959194509250565b60208101610a3d8284612759565b600181811c908216806129fb57607f821691505b602082108103612a1b57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600a90820152690507269636520697320360b41b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610a3d57610a3d612a45565b60208082526010908201526f4e6f7420656e6f7567682066756e647360801b604082015260600190565b80820180821115610a3d57610a3d612a45565b60208082526026908201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060408201526573686172657360d01b606082015260800190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b600060018201612b5257612b52612a45565b5060010190565b634e487b7160e01b600052603260045260246000fd5b601f82111561110f57600081815260208120601f850160051c81016020861015612b965750805b601f850160051c820191505b818110156110ec57828155600101612ba2565b815167ffffffffffffffff811115612bcf57612bcf612848565b612be381612bdd84546129e7565b84612b6f565b602080601f831160018114612c185760008415612c005750858301515b600019600386901b1c1916600185901b1785556110ec565b600085815260208120601f198616915b82811015612c4757888601518255948401946001909101908401612c28565b5085821015612c655787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215612c8757600080fd5b5051919050565b6000808454612c9c816129e7565b60018281168015612cb45760018114612cc957612cf8565b60ff1984168752821515830287019450612cf8565b8860005260208060002060005b85811015612cef5781548a820152908401908201612cd6565b50505082870194505b505050508351612d0c81836020880161260a565b64173539b7b760d91b9101908152600501949350505050565b600082612d4257634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610a3d57610a3d612a45565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612d8d9083018461262e565b9695505050505050565b600060208284031215612da957600080fd5b815161172f816125d7565b600060208284031215612dc657600080fd5b815161172f8161291d565b60008251612de381846020870161260a565b919091019291505056fea26469706673582212206246a1af63d0940e55e1de7f8fb95343036774259500e4b23d696ef27c5fd74264736f6c6343000811003300000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000180000000000000000000000000d88306b19a660836379dab1845624b3a879989170000000000000000000000006d5cffbcbef82b9e7e302a195ffdb282c188addb000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000060000000000000000000000007c4df0782556a79c22faf9f0a70dd83f5c7c504b00000000000000000000000012d8f2dfc00e95e446b5f07d48ebf5750711295a00000000000000000000000098107155eb5ff8cd5402d2b2dd7a9b06cfbb32fc00000000000000000000000065b8be9afad72c7c1fd3a2f3f4347f23c3797b46000000000000000000000000802a2102ec07e0bdeac0e0958d609d81197e41830000000000000000000000006e145a9a8770dd1c73d790b2c290bccb46eb91710000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000a20000000000000000000000000000000000000000000000000000000000000043697066733a2f2f62616679626569663564357a6b61776e77766d78326971763672786867673766763568326e626761366f726c3535796a6f6b6e73693472766d376d2f0000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106102e85760003560e01c8063734c66bd11610190578063c45ac050116100dc578063d79779b211610095578063ee70c7cb1161006f578063ee70c7cb1461097b578063f2fde38b14610991578063f8dcbddb146109b1578063fe8ce064146109d157600080fd5b8063d79779b2146108e7578063e33b7de31461091d578063e985e9c51461093257600080fd5b8063c45ac050146107ff578063c87b56dd1461081f578063c893575a1461083f578063cbccefb214610854578063ce7c2ac21461087b578063cf01342b146108b157600080fd5b80639852595c11610149578063a22cb46511610123578063a22cb4651461078c578063a3f8eace146107ac578063b3ab66b0146107cc578063b88d4fde146107df57600080fd5b80639852595c146107205780639b6860c814610756578063a0bcfc7f1461076c57600080fd5b8063734c66bd146106775780638a02e3b91461068d5780638a59a7fd146106ad5780638b83209b146106cd5780638da5cb5b146106ed57806395d89b411461070b57600080fd5b806348b750441161024f5780635be7fde8116102085780636bb0b37b116101e25780636bb0b37b146106005780636c0360eb1461062d57806370a0823114610642578063715018a61461066257600080fd5b80635be7fde8146105b55780635e8bada0146105ca5780636352211e146105e057600080fd5b806348b750441461050c5780634e821a311461052c5780634f8aed6e1461054c5780634fda72851461056257806359d20e61146105825780635b2fda67146105a257600080fd5b806318160ddd116102a157806318160ddd1461042e578063191655871461045157806323b872dd146104715780633a98ef3914610491578063406072a9146104a657806342842e0e146104ec57600080fd5b806301ffc9a71461033657806306fdde031461036b578063081812fc1461038d578063093cf9fe146103c5578063095ea7b3146103da5780630c3f6acf146103fa57600080fd5b36610331577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b600080fd5b34801561034257600080fd5b506103566103513660046125ed565b6109f1565b60405190151581526020015b60405180910390f35b34801561037757600080fd5b50610380610a43565b604051610362919061265a565b34801561039957600080fd5b506103ad6103a836600461266d565b610ad5565b6040516001600160a01b039091168152602001610362565b6103d86103d3366004612686565b610b19565b005b3480156103e657600080fd5b506103d86103f5366004612717565b610db4565b34801561040657600080fd5b506013546015546014546016546018546019546040516103629660ff1695949392919061277b565b34801561043a57600080fd5b50610443610e54565b604051908152602001610362565b34801561045d57600080fd5b506103d861046c3660046127b1565b610e62565b34801561047d57600080fd5b506103d861048c3660046127ce565b610f5b565b34801561049d57600080fd5b50600954610443565b3480156104b257600080fd5b506104436104c136600461280f565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205490565b3480156104f857600080fd5b506103d86105073660046127ce565b6110f4565b34801561051857600080fd5b506103d861052736600461280f565b611114565b34801561053857600080fd5b506103d861054736600461266d565b611237565b34801561055857600080fd5b5061044360165481565b34801561056e57600080fd5b506103d861057d36600461266d565b611244565b34801561058e57600080fd5b506103d861059d36600461266d565b611251565b6103d86105b0366004612686565b61125e565b3480156105c157600080fd5b506103d86114a0565b3480156105d657600080fd5b5061044360185481565b3480156105ec57600080fd5b506103ad6105fb36600461266d565b6114ce565b34801561060c57600080fd5b5061044361061b3660046127b1565b60176020526000908152604090205481565b34801561063957600080fd5b506103806114d9565b34801561064e57600080fd5b5061044361065d3660046127b1565b611567565b34801561066e57600080fd5b506103d86115b6565b34801561068357600080fd5b5061044360145481565b34801561069957600080fd5b506103d86106a836600461266d565b6115ca565b3480156106b957600080fd5b506104436106c83660046127b1565b6115d7565b3480156106d957600080fd5b506103ad6106e836600461266d565b611602565b3480156106f957600080fd5b506000546001600160a01b03166103ad565b34801561071757600080fd5b50610380611632565b34801561072c57600080fd5b5061044361073b3660046127b1565b6001600160a01b03166000908152600c602052604090205490565b34801561076257600080fd5b5061044360155481565b34801561077857600080fd5b506103d86107873660046128d4565b611641565b34801561079857600080fd5b506103d86107a736600461292b565b611659565b3480156107b857600080fd5b506104436107c73660046127b1565b6116ee565b6103d86107da36600461266d565b611736565b3480156107eb57600080fd5b506103d86107fa366004612959565b611893565b34801561080b57600080fd5b5061044361081a36600461280f565b6118d7565b34801561082b57600080fd5b5061038061083a36600461266d565b6119a2565b34801561084b57600080fd5b506103d8611a2b565b34801561086057600080fd5b5060135461086e9060ff1681565b60405161036291906129d9565b34801561088757600080fd5b506104436108963660046127b1565b6001600160a01b03166000908152600b602052604090205490565b3480156108bd57600080fd5b506104436108cc3660046127b1565b6001600160a01b031660009081526017602052604090205490565b3480156108f357600080fd5b506104436109023660046127b1565b6001600160a01b03166000908152600e602052604090205490565b34801561092957600080fd5b50600a54610443565b34801561093e57600080fd5b5061035661094d36600461280f565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205460ff1690565b34801561098757600080fd5b5061044360195481565b34801561099d57600080fd5b506103d86109ac3660046127b1565b611a93565b3480156109bd57600080fd5b506103d86109cc36600461266d565b611b09565b3480156109dd57600080fd5b506103d86109ec36600461266d565b611b47565b60006301ffc9a760e01b6001600160e01b031983161480610a2257506380ac58cd60e01b6001600160e01b03198316145b80610a3d5750635b5e139f60e01b6001600160e01b03198316145b92915050565b606060038054610a52906129e7565b80601f0160208091040260200160405190810160405280929190818152602001828054610a7e906129e7565b8015610acb5780601f10610aa057610100808354040283529160200191610acb565b820191906000526020600020905b815481529060010190602001808311610aae57829003601f168201915b5050505050905090565b6000610ae082611b54565b610afd576040516333d1c03960e21b815260040160405180910390fd5b506000908152600760205260409020546001600160a01b031690565b60165480610b425760405162461bcd60e51b8152600401610b3990612a21565b60405180910390fd5b610b4c8482612a5b565b341015610b6b5760405162461bcd60e51b8152600401610b3990612a72565b600160135460ff166005811115610b8457610b84612743565b14610bc85760405162461bcd60e51b81526020600482015260146024820152732b24a81026b4b73a1034b9903737ba1037b832b760611b6044820152606401610b39565b61138884610bd4610e54565b610bde9190612a9c565b1115610c2c5760405162461bcd60e51b815260206004820152601b60248201527f4d617820737570706c7920666f722056495020657863656564656400000000006044820152606401610b39565b610cc283838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602082015233603c820152605c019150610c9e9050565b60405160208183030381529060405280519060200120611b8990919063ffffffff16565b6010546001600160a01b03908116911614610d135760405162461bcd60e51b81526020600482015260116024820152700596f7520617265206e6f7420612056495607c1b6044820152606401610b39565b60185433600090815260176020526040902054610d31908690612a9c565b1115610d7f5760405162461bcd60e51b815260206004820152601960248201527f4d617820657863656564656420666f72205649502053616c65000000000000006044820152606401610b39565b3360009081526017602052604081208054869290610d9e908490612a9c565b90915550610dae90503385611bad565b50505050565b6000610dbf826114ce565b9050336001600160a01b03821614610df857610ddb813361094d565b610df8576040516367d9dca160e11b815260040160405180910390fd5b60008281526007602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600254600154036000190190565b6001600160a01b0381166000908152600b6020526040902054610e975760405162461bcd60e51b8152600401610b3990612aaf565b6000610ea2826116ee565b905080600003610ec45760405162461bcd60e51b8152600401610b3990612af5565b6001600160a01b0382166000908152600c602052604081208054839290610eec908490612a9c565b9250508190555080600a6000828254610f059190612a9c565b90915550610f1590508282611cab565b604080516001600160a01b0384168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a15050565b6000610f6682611dc4565b9050836001600160a01b0316816001600160a01b031614610f995760405162a1148160e81b815260040160405180910390fd5b60008281526007602052604090208054338082146001600160a01b03881690911417610fe657610fc9863361094d565b610fe657604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b03851661100d57604051633a954ecd60e21b815260040160405180910390fd5b801561101857600082555b6001600160a01b038681166000908152600660205260408082208054600019019055918716808252919020805460010190554260a01b17600160e11b17600085815260056020526040812091909155600160e11b841690036110aa576001840160008181526005602052604081205490036110a85760015481146110a85760008181526005602052604090208490555b505b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b61110f83838360405180602001604052806000815250611893565b505050565b6001600160a01b0381166000908152600b60205260409020546111495760405162461bcd60e51b8152600401610b3990612aaf565b600061115583836118d7565b9050806000036111775760405162461bcd60e51b8152600401610b3990612af5565b6001600160a01b038084166000908152600f60209081526040808320938616835292905290812080548392906111ae908490612a9c565b90915550506001600160a01b0383166000908152600e6020526040812080548392906111db908490612a9c565b909155506111ec9050838383611e33565b604080516001600160a01b038481168252602082018490528516917f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a910160405180910390a2505050565b61123f611e85565b601655565b61124c611e85565b601555565b611259611e85565b601455565b6014548061127e5760405162461bcd60e51b8152600401610b3990612a21565b6112888482612a5b565b3410156112a75760405162461bcd60e51b8152600401610b3990612a72565b600260135460ff1660058111156112c0576112c0612743565b146113015760405162461bcd60e51b81526020600482015260116024820152702ba61026b4b73a103737ba103634bb329760791b6044820152606401610b39565b6113888461130d610e54565b6113179190612a9c565b11156113655760405162461bcd60e51b815260206004820152601a60248201527f4d617820737570706c7920657863656564656420666f7220574c0000000000006044820152606401610b39565b6113d783838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602082015233603c820152605c019150610c9e9050565b6011546001600160a01b039081169116146114345760405162461bcd60e51b815260206004820152601b60248201527f596f7520617265206e6f7420696e20574c2077686974656c69737400000000006044820152606401610b39565b60185433600090815260176020526040902054611452908690612a9c565b1115610d7f5760405162461bcd60e51b815260206004820152601f60248201527f4d617820657863656564656420666f722057686974656c6973742053616c65006044820152606401610b39565b60005b601a548110156114cb576114b961046c82611602565b806114c381612b40565b9150506114a3565b50565b6000610a3d82611dc4565b601280546114e6906129e7565b80601f0160208091040260200160405190810160405280929190818152602001828054611512906129e7565b801561155f5780601f106115345761010080835404028352916020019161155f565b820191906000526020600020905b81548152906001019060200180831161154257829003601f168201915b505050505081565b60006001600160a01b038216611590576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b031660009081526006602052604090205467ffffffffffffffff1690565b6115be611e85565b6115c86000611edf565b565b6115d2611e85565b601955565b6001600160a01b0381166000908152600660205260408082205467ffffffffffffffff911c16610a3d565b6000600d828154811061161757611617612b59565b6000918252602090912001546001600160a01b031692915050565b606060048054610a52906129e7565b611649611e85565b60126116558282612bb5565b5050565b336001600160a01b038316036116825760405163b06307db60e01b815260040160405180910390fd5b3360008181526008602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000806116fa600a5490565b6117049047612a9c565b905061172f838261172a866001600160a01b03166000908152600c602052604090205490565b611f2f565b9392505050565b601554806117565760405162461bcd60e51b8152600401610b3990612a21565b6117608282612a5b565b34101561177f5760405162461bcd60e51b8152600401610b3990612a72565b6019548211156117d15760405162461bcd60e51b815260206004820152601760248201527f4f766572206d617820616d6f756e74207065722074786e0000000000000000006044820152606401610b39565b600360135460ff1660058111156117ea576117ea612743565b1461182f5760405162461bcd60e51b8152602060048201526015602482015274283ab13634b19026b4b73a103737ba103634bb329760591b6044820152606401610b39565b6113888261183b610e54565b6118459190612a9c565b11156118895760405162461bcd60e51b815260206004820152601360248201527213585e081cdd5c1c1b1e48195e18d959591959606a1b6044820152606401610b39565b6116553383611bad565b61189e848484610f5b565b6001600160a01b0383163b15610dae576118ba84848484611f6d565b610dae576040516368d2bf6b60e11b815260040160405180910390fd5b6001600160a01b0382166000908152600e602052604081205481906040516370a0823160e01b81523060048201526001600160a01b038616906370a0823190602401602060405180830381865afa158015611936573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195a9190612c75565b6119649190612a9c565b6001600160a01b038086166000908152600f602090815260408083209388168352929052205490915061199a9084908390611f2f565b949350505050565b60606119ad82611b54565b6119f95760405162461bcd60e51b815260206004820152601f60248201527f55524920717565727920666f72206e6f6e6578697374656e7420746f6b656e006044820152606401610b39565b6012611a0483612058565b604051602001611a15929190612c8e565b6040516020818303038152906040529050919050565b611a33611e85565b611a3b610e54565b15611a885760405162461bcd60e51b815260206004820152601a60248201527f4f6e6c79206f6e65206d696e7420666f72206465706c6f7965720000000000006044820152606401610b39565b6115c8336001611bad565b611a9b611e85565b6001600160a01b038116611b005760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610b39565b6114cb81611edf565b611b11611e85565b806005811115611b2357611b23612743565b6013805460ff19166001836005811115611b3f57611b3f612743565b021790555050565b611b4f611e85565b601855565b600081600111158015611b68575060015482105b8015610a3d575050600090815260056020526040902054600160e01b161590565b6000806000611b9885856120a7565b91509150611ba581612115565b509392505050565b6001546000829003611bd25760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b03831660008181526006602090815260408083208054680100000000000000018802019055848352600590915281206001851460e11b4260a01b178317905582840190839083907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8180a4600183015b818114611c8157808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600101611c49565b5081600003611ca257604051622e076360e81b815260040160405180910390fd5b60015550505050565b80471015611cfb5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610b39565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611d48576040519150601f19603f3d011682016040523d82523d6000602084013e611d4d565b606091505b505090508061110f5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610b39565b60008180600111611e1a57600154811015611e1a5760008181526005602052604081205490600160e01b82169003611e18575b8060000361172f575060001901600081815260056020526040902054611df7565b505b604051636f96cda160e11b815260040160405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261110f9084906122cb565b6000546001600160a01b031633146115c85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b39565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6009546001600160a01b0384166000908152600b602052604081205490918391611f599086612a5b565b611f639190612d25565b61199a9190612d47565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611fa2903390899088908890600401612d5a565b6020604051808303816000875af1925050508015611fdd575060408051601f3d908101601f19168201909252611fda91810190612d97565b60015b61203b573d80801561200b576040519150601f19603f3d011682016040523d82523d6000602084013e612010565b606091505b508051600003612033576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050949350505050565b604080516080810191829052607f0190826030600a8206018353600a90045b801561209557600183039250600a81066030018353600a9004612077565b50819003601f19909101908152919050565b60008082516041036120dd5760208301516040840151606085015160001a6120d18782858561239d565b9450945050505061210e565b825160400361210657602083015160408401516120fb86838361248a565b93509350505061210e565b506000905060025b9250929050565b600081600481111561212957612129612743565b036121315750565b600181600481111561214557612145612743565b036121925760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610b39565b60028160048111156121a6576121a6612743565b036121f35760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610b39565b600381600481111561220757612207612743565b0361225f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610b39565b600481600481111561227357612273612743565b036114cb5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610b39565b6000612320826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166124c39092919063ffffffff16565b80519091501561110f578080602001905181019061233e9190612db4565b61110f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610b39565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156123d45750600090506003612481565b8460ff16601b141580156123ec57508460ff16601c14155b156123fd5750600090506004612481565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612451573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661247a57600060019250925050612481565b9150600090505b94509492505050565b6000806001600160ff1b038316816124a760ff86901c601b612a9c565b90506124b58782888561239d565b935093505050935093915050565b606061199a8484600085856001600160a01b0385163b6125255760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b39565b600080866001600160a01b031685876040516125419190612dd1565b60006040518083038185875af1925050503d806000811461257e576040519150601f19603f3d011682016040523d82523d6000602084013e612583565b606091505b509150915061259382828661259e565b979650505050505050565b606083156125ad57508161172f565b8251156125bd5782518084602001fd5b8160405162461bcd60e51b8152600401610b39919061265a565b6001600160e01b0319811681146114cb57600080fd5b6000602082840312156125ff57600080fd5b813561172f816125d7565b60005b8381101561262557818101518382015260200161260d565b50506000910152565b6000815180845261264681602086016020860161260a565b601f01601f19169290920160200192915050565b60208152600061172f602083018461262e565b60006020828403121561267f57600080fd5b5035919050565b60008060006040848603121561269b57600080fd5b83359250602084013567ffffffffffffffff808211156126ba57600080fd5b818601915086601f8301126126ce57600080fd5b8135818111156126dd57600080fd5b8760208285010111156126ef57600080fd5b6020830194508093505050509250925092565b6001600160a01b03811681146114cb57600080fd5b6000806040838503121561272a57600080fd5b823561273581612702565b946020939093013593505050565b634e487b7160e01b600052602160045260246000fd5b6006811061277757634e487b7160e01b600052602160045260246000fd5b9052565b60c081016127898289612759565b602082019690965260408101949094526060840192909252608083015260a090910152919050565b6000602082840312156127c357600080fd5b813561172f81612702565b6000806000606084860312156127e357600080fd5b83356127ee81612702565b925060208401356127fe81612702565b929592945050506040919091013590565b6000806040838503121561282257600080fd5b823561282d81612702565b9150602083013561283d81612702565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff8084111561287957612879612848565b604051601f8501601f19908116603f011681019082821181831017156128a1576128a1612848565b816040528093508581528686860111156128ba57600080fd5b858560208301376000602087830101525050509392505050565b6000602082840312156128e657600080fd5b813567ffffffffffffffff8111156128fd57600080fd5b8201601f8101841361290e57600080fd5b61199a8482356020840161285e565b80151581146114cb57600080fd5b6000806040838503121561293e57600080fd5b823561294981612702565b9150602083013561283d8161291d565b6000806000806080858703121561296f57600080fd5b843561297a81612702565b9350602085013561298a81612702565b925060408501359150606085013567ffffffffffffffff8111156129ad57600080fd5b8501601f810187136129be57600080fd5b6129cd8782356020840161285e565b91505092959194509250565b60208101610a3d8284612759565b600181811c908216806129fb57607f821691505b602082108103612a1b57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600a90820152690507269636520697320360b41b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610a3d57610a3d612a45565b60208082526010908201526f4e6f7420656e6f7567682066756e647360801b604082015260600190565b80820180821115610a3d57610a3d612a45565b60208082526026908201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060408201526573686172657360d01b606082015260800190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b600060018201612b5257612b52612a45565b5060010190565b634e487b7160e01b600052603260045260246000fd5b601f82111561110f57600081815260208120601f850160051c81016020861015612b965750805b601f850160051c820191505b818110156110ec57828155600101612ba2565b815167ffffffffffffffff811115612bcf57612bcf612848565b612be381612bdd84546129e7565b84612b6f565b602080601f831160018114612c185760008415612c005750858301515b600019600386901b1c1916600185901b1785556110ec565b600085815260208120601f198616915b82811015612c4757888601518255948401946001909101908401612c28565b5085821015612c655787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600060208284031215612c8757600080fd5b5051919050565b6000808454612c9c816129e7565b60018281168015612cb45760018114612cc957612cf8565b60ff1984168752821515830287019450612cf8565b8860005260208060002060005b85811015612cef5781548a820152908401908201612cd6565b50505082870194505b505050508351612d0c81836020880161260a565b64173539b7b760d91b9101908152600501949350505050565b600082612d4257634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610a3d57610a3d612a45565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612d8d9083018461262e565b9695505050505050565b600060208284031215612da957600080fd5b815161172f816125d7565b600060208284031215612dc657600080fd5b815161172f8161291d565b60008251612de381846020870161260a565b919091019291505056fea26469706673582212206246a1af63d0940e55e1de7f8fb95343036774259500e4b23d696ef27c5fd74264736f6c63430008110033

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

00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000180000000000000000000000000d88306b19a660836379dab1845624b3a879989170000000000000000000000006d5cffbcbef82b9e7e302a195ffdb282c188addb000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000060000000000000000000000007c4df0782556a79c22faf9f0a70dd83f5c7c504b00000000000000000000000012d8f2dfc00e95e446b5f07d48ebf5750711295a00000000000000000000000098107155eb5ff8cd5402d2b2dd7a9b06cfbb32fc00000000000000000000000065b8be9afad72c7c1fd3a2f3f4347f23c3797b46000000000000000000000000802a2102ec07e0bdeac0e0958d609d81197e41830000000000000000000000006e145a9a8770dd1c73d790b2c290bccb46eb91710000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000a20000000000000000000000000000000000000000000000000000000000000043697066733a2f2f62616679626569663564357a6b61776e77766d78326971763672786867673766763568326e626761366f726c3535796a6f6b6e73693472766d376d2f0000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _team (address[]): 0x7c4dF0782556a79c22Faf9F0a70dD83F5c7c504B,0x12D8f2DFC00e95e446b5F07d48ebF5750711295A,0x98107155EB5Ff8CD5402d2b2dd7a9b06cFBB32FC,0x65B8Be9afAd72C7c1fD3A2f3f4347f23c3797b46,0x802A2102Ec07e0bdEaC0E0958D609d81197E4183,0x6E145A9A8770dd1C73D790b2C290bCcb46Eb9171
Arg [1] : _teamShares (uint256[]): 400,200,160,48,30,162
Arg [2] : _signerAddressVIP (address): 0xd88306B19A660836379dAb1845624b3a87998917
Arg [3] : _signerAddressWL (address): 0x6d5cffBcbeF82B9E7E302A195fFDb282C188AddB
Arg [4] : _baseURI (string): ipfs://bafybeif5d5zkawnwvmx2iqv6rxhgg7fv5h2nbga6orl55yjoknsi4rvm7m/

-----Encoded View---------------
23 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [2] : 000000000000000000000000d88306b19a660836379dab1845624b3a87998917
Arg [3] : 0000000000000000000000006d5cffbcbef82b9e7e302a195ffdb282c188addb
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000260
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [6] : 0000000000000000000000007c4df0782556a79c22faf9f0a70dd83f5c7c504b
Arg [7] : 00000000000000000000000012d8f2dfc00e95e446b5f07d48ebf5750711295a
Arg [8] : 00000000000000000000000098107155eb5ff8cd5402d2b2dd7a9b06cfbb32fc
Arg [9] : 00000000000000000000000065b8be9afad72c7c1fd3a2f3f4347f23c3797b46
Arg [10] : 000000000000000000000000802a2102ec07e0bdeac0e0958d609d81197e4183
Arg [11] : 0000000000000000000000006e145a9a8770dd1c73d790b2c290bccb46eb9171
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000190
Arg [14] : 00000000000000000000000000000000000000000000000000000000000000c8
Arg [15] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000030
Arg [17] : 000000000000000000000000000000000000000000000000000000000000001e
Arg [18] : 00000000000000000000000000000000000000000000000000000000000000a2
Arg [19] : 0000000000000000000000000000000000000000000000000000000000000043
Arg [20] : 697066733a2f2f62616679626569663564357a6b61776e77766d783269717636
Arg [21] : 72786867673766763568326e626761366f726c3535796a6f6b6e73693472766d
Arg [22] : 376d2f0000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

88241:5340:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41351:40;8611:10;41351:40;;;-1:-1:-1;;;;;206:32:1;;;188:51;;41381:9:0;270:2:1;255:18;;248:34;161:18;41351:40:0;;;;;;;88241:5340;;;;;55429:639;;;;;;;;;;-1:-1:-1;55429:639:0;;;;;:::i;:::-;;:::i;:::-;;;844:14:1;;837:22;819:41;;807:2;792:18;55429:639:0;;;;;;;;56331:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;62814:218::-;;;;;;;;;;-1:-1:-1;62814:218:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1976:32:1;;;1958:51;;1946:2;1931:18;62814:218:0;1812:203:1;89574:885:0;;;;;;:::i;:::-;;:::i;:::-;;62255:400;;;;;;;;;;-1:-1:-1;62255:400:0;;;;;:::i;:::-;;:::i;91901:210::-;;;;;;;;;;-1:-1:-1;92003:11:0;;92016:15;;92033:11;;92046:12;;92060:19;;92081:21;;91901:210;;;;92003:11;;;92016:15;92033:11;92046:12;92060:19;92081:21;91901:210;:::i;52082:323::-;;;;;;;;;;;;;:::i;:::-;;;4216:25:1;;;4204:2;4189:18;52082:323:0;4070:177:1;43872:453:0;;;;;;;;;;-1:-1:-1;43872:453:0;;;;;:::i;:::-;;:::i;66521:2817::-;;;;;;;;;;-1:-1:-1;66521:2817:0;;;;;:::i;:::-;;:::i;41482:91::-;;;;;;;;;;-1:-1:-1;41553:12:0;;41482:91;;42611:135;;;;;;;;;;-1:-1:-1;42611:135:0;;;;;:::i;:::-;-1:-1:-1;;;;;42708:21:0;;;42681:7;42708:21;;;:14;:21;;;;;;;;:30;;;;;;;;;;;;;42611:135;69434:185;;;;;;;;;;-1:-1:-1;69434:185:0;;;;;:::i;:::-;;:::i;44593:514::-;;;;;;;;;;-1:-1:-1;44593:514:0;;;;;:::i;:::-;;:::i;92355:108::-;;;;;;;;;;-1:-1:-1;92355:108:0;;;;;:::i;:::-;;:::i;88786:37::-;;;;;;;;;;;;;;;;92233:114;;;;;;;;;;-1:-1:-1;92233:114:0;;;;;:::i;:::-;;:::i;92119:106::-;;;;;;;;;;-1:-1:-1;92119:106:0;;;;;:::i;:::-;;:::i;90977:916::-;;;;;;:::i;:::-;;:::i;93437:141::-;;;;;;;;;;;;;:::i;88901:35::-;;;;;;;;;;;;;;;;57724:152;;;;;;;;;;-1:-1:-1;57724:152:0;;;;;:::i;:::-;;:::i;88832:60::-;;;;;;;;;;-1:-1:-1;88832:60:0;;;;;:::i;:::-;;;;;;;;;;;;;;88586:21;;;;;;;;;;;;;:::i;53266:233::-;;;;;;;;;;-1:-1:-1;53266:233:0;;;;;:::i;:::-;;:::i;29354:103::-;;;;;;;;;;;;;:::i;88696:36::-;;;;;;;;;;;;;;;;92792:105;;;;;;;;;;-1:-1:-1;92792:105:0;;;;;:::i;:::-;;:::i;92905:122::-;;;;;;;;;;-1:-1:-1;92905:122:0;;;;;:::i;:::-;;:::i;42837:100::-;;;;;;;;;;-1:-1:-1;42837:100:0;;;;;:::i;:::-;;:::i;28706:87::-;;;;;;;;;;-1:-1:-1;28752:7:0;28779:6;-1:-1:-1;;;;;28779:6:0;28706:87;;56507:104;;;;;;;;;;;;;:::i;42333:109::-;;;;;;;;;;-1:-1:-1;42333:109:0;;;;;:::i;:::-;-1:-1:-1;;;;;42416:18:0;42389:7;42416:18;;;:9;:18;;;;;;;42333:109;88739:40;;;;;;;;;;;;;;;;92471:100;;;;;;;;;;-1:-1:-1;92471:100:0;;;;;:::i;:::-;;:::i;63372:308::-;;;;;;;;;;-1:-1:-1;63372:308:0;;;;;:::i;:::-;;:::i;43027:225::-;;;;;;;;;;-1:-1:-1;43027:225:0;;;;;:::i;:::-;;:::i;90467:502::-;;;;;;:::i;:::-;;:::i;70217:399::-;;;;;;;;;;-1:-1:-1;70217:399:0;;;;;:::i;:::-;;:::i;43412:260::-;;;;;;;;;;-1:-1:-1;43412:260:0;;;;;:::i;:::-;;:::i;93182:247::-;;;;;;;;;;-1:-1:-1;93182:247:0;;;;;:::i;:::-;;:::i;89413:153::-;;;;;;;;;;;;;:::i;88616:23::-;;;;;;;;;;-1:-1:-1;88616:23:0;;;;;;;;;;;;;;;:::i;42129:105::-;;;;;;;;;;-1:-1:-1;42129:105:0;;;;;:::i;:::-;-1:-1:-1;;;;;42210:16:0;42183:7;42210:16;;;:7;:16;;;;;;;42129:105;93035:139;;;;;;;;;;-1:-1:-1;93035:139:0;;;;;:::i;:::-;-1:-1:-1;;;;;93129:37:0;93102:7;93129:37;;;:28;:37;;;;;;;93035:139;41919:119;;;;;;;;;;-1:-1:-1;41919:119:0;;;;;:::i;:::-;-1:-1:-1;;;;;42004:26:0;41977:7;42004:26;;;:19;:26;;;;;;;41919:119;41667:95;;;;;;;;;;-1:-1:-1;41740:14:0;;41667:95;;63837:164;;;;;;;;;;-1:-1:-1;63837:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;63958:25:0;;;63934:4;63958:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;63837:164;88945:37;;;;;;;;;;;;;;;;29612:201;;;;;;;;;;-1:-1:-1;29612:201:0;;;;;:::i;:::-;;:::i;92579:92::-;;;;;;;;;;-1:-1:-1;92579:92:0;;;;;:::i;:::-;;:::i;92679:105::-;;;;;;;;;;-1:-1:-1;92679:105:0;;;;;:::i;:::-;;:::i;55429:639::-;55514:4;-1:-1:-1;;;;;;;;;55838:25:0;;;;:102;;-1:-1:-1;;;;;;;;;;55915:25:0;;;55838:102;:179;;;-1:-1:-1;;;;;;;;;;55992:25:0;;;55838:179;55818:199;55429:639;-1:-1:-1;;55429:639:0:o;56331:100::-;56385:13;56418:5;56411:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56331:100;:::o;62814:218::-;62890:7;62915:16;62923:7;62915;:16::i;:::-;62910:64;;62940:34;;-1:-1:-1;;;62940:34:0;;;;;;;;;;;62910:64;-1:-1:-1;62994:24:0;;;;:15;:24;;;;;:30;-1:-1:-1;;;;;62994:30:0;;62814:218::o;89574:885::-;89673:12;;89699:10;89696:35;;89711:20;;-1:-1:-1;;;89711:20:0;;;;;;;:::i;:::-;;;;;;;;89696:35;89757:17;89765:9;89757:5;:17;:::i;:::-;89745:9;:29;89742:60;;;89776:26;;-1:-1:-1;;;89776:26:0;;;;;;;:::i;89742:60::-;89831:12;89816:11;;;;:27;;;;;;;;:::i;:::-;;89813:62;;89845:30;;-1:-1:-1;;;89845:30:0;;10605:2:1;89845:30:0;;;10587:21:1;10644:2;10624:18;;;10617:30;-1:-1:-1;;;10663:18:1;;;10656:50;10723:18;;89845:30:0;10403:344:1;89813:62:0;88683:4;89905:9;89889:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:38;89886:80;;;89929:37;;-1:-1:-1;;;89929:37:0;;11084:2:1;89929:37:0;;;11066:21:1;11123:2;11103:18;;;11096:30;11162:29;11142:18;;;11135:57;11209:18;;89929:37:0;10882:351:1;89886:80:0;90000:194;90184:9;;90000:194;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;90024:140:0;;11480:66:1;90024:140:0;;;11468:79:1;90136:10:0;11563:12:1;;;11556:28;11600:12;;;-1:-1:-1;90024:140:0;;-1:-1:-1;11238:380:1;90024:140:0;;;;;;;;;;;;;90000:175;;;;;;:183;;:194;;;;:::i;:::-;89980:16;;-1:-1:-1;;;;;89980:16:0;;;:214;;;89977:246;;90196:27;;-1:-1:-1;;;90196:27:0;;11825:2:1;90196:27:0;;;11807:21:1;11864:2;11844:18;;;11837:30;-1:-1:-1;;;11883:18:1;;;11876:47;11940:18;;90196:27:0;11623:341:1;89977:246:0;90292:19;;90266:10;90237:40;;;;:28;:40;;;;;;:52;;90280:9;;90237:52;:::i;:::-;:74;90234:114;;;90313:35;;-1:-1:-1;;;90313:35:0;;12171:2:1;90313:35:0;;;12153:21:1;12210:2;12190:18;;;12183:30;12249:27;12229:18;;;12222:55;12294:18;;90313:35:0;11969:349:1;90234:114:0;90388:10;90359:40;;;;:28;:40;;;;;:53;;90403:9;;90359:40;:53;;90403:9;;90359:53;:::i;:::-;;;;-1:-1:-1;90423:28:0;;-1:-1:-1;90429:10:0;90441:9;90423:5;:28::i;:::-;89649:810;89574:885;;;:::o;62255:400::-;62336:13;62352:16;62360:7;62352;:16::i;:::-;62336:32;-1:-1:-1;8611:10:0;-1:-1:-1;;;;;62385:28:0;;;62381:175;;62433:44;62450:5;8611:10;63837:164;:::i;62433:44::-;62428:128;;62505:35;;-1:-1:-1;;;62505:35:0;;;;;;;;;;;62428:128;62568:24;;;;:15;:24;;;;;;:35;;-1:-1:-1;;;;;;62568:35:0;-1:-1:-1;;;;;62568:35:0;;;;;;;;;62619:28;;62568:24;;62619:28;;;;;;;62325:330;62255:400;;:::o;52082:323::-;52356:12;;51681:1;52340:13;:28;-1:-1:-1;;52340:46:0;;52082:323::o;43872:453::-;-1:-1:-1;;;;;43948:16:0;;43967:1;43948:16;;;:7;:16;;;;;;43940:71;;;;-1:-1:-1;;;43940:71:0;;;;;;;:::i;:::-;44024:15;44042:19;44053:7;44042:10;:19::i;:::-;44024:37;;44082:7;44093:1;44082:12;44074:68;;;;-1:-1:-1;;;44074:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;44155:18:0;;;;;;:9;:18;;;;;:29;;44177:7;;44155:18;:29;;44177:7;;44155:29;:::i;:::-;;;;;;;;44213:7;44195:14;;:25;;;;;;;:::i;:::-;;;;-1:-1:-1;44233:35:0;;-1:-1:-1;44251:7:0;44260;44233:17;:35::i;:::-;44284:33;;;-1:-1:-1;;;;;206:32:1;;188:51;;270:2;255:18;;248:34;;;44284:33:0;;161:18:1;44284:33:0;;;;;;;43929:396;43872:453;:::o;66521:2817::-;66655:27;66685;66704:7;66685:18;:27::i;:::-;66655:57;;66770:4;-1:-1:-1;;;;;66729:45:0;66745:19;-1:-1:-1;;;;;66729:45:0;;66725:86;;66783:28;;-1:-1:-1;;;66783:28:0;;;;;;;;;;;66725:86;66825:27;65635:24;;;:15;:24;;;;;65857:26;;8611:10;65260:30;;;-1:-1:-1;;;;;64953:28:0;;65238:20;;;65235:56;67011:180;;67104:43;67121:4;8611:10;63837:164;:::i;67104:43::-;67099:92;;67156:35;;-1:-1:-1;;;67156:35:0;;;;;;;;;;;67099:92;-1:-1:-1;;;;;67208:16:0;;67204:52;;67233:23;;-1:-1:-1;;;67233:23:0;;;;;;;;;;;67204:52;67405:15;67402:160;;;67545:1;67524:19;67517:30;67402:160;-1:-1:-1;;;;;67942:24:0;;;;;;;:18;:24;;;;;;67940:26;;-1:-1:-1;;67940:26:0;;;68011:22;;;;;;;;;68009:24;;-1:-1:-1;68009:24:0;;;61113:11;61088:23;61084:41;61071:63;-1:-1:-1;;;61071:63:0;68304:26;;;;:17;:26;;;;;:175;;;;-1:-1:-1;;;68599:47:0;;:52;;68595:627;;68704:1;68694:11;;68672:19;68827:30;;;:17;:30;;;;;;:35;;68823:384;;68965:13;;68950:11;:28;68946:242;;69112:30;;;;:17;:30;;;;;:52;;;68946:242;68653:569;68595:627;69269:7;69265:2;-1:-1:-1;;;;;69250:27:0;69259:4;-1:-1:-1;;;;;69250:27:0;;;;;;;;;;;69288:42;66644:2694;;;66521:2817;;;:::o;69434:185::-;69572:39;69589:4;69595:2;69599:7;69572:39;;;;;;;;;;;;:16;:39::i;:::-;69434:185;;;:::o;44593:514::-;-1:-1:-1;;;;;44675:16:0;;44694:1;44675:16;;;:7;:16;;;;;;44667:71;;;;-1:-1:-1;;;44667:71:0;;;;;;;:::i;:::-;44751:15;44769:26;44780:5;44787:7;44769:10;:26::i;:::-;44751:44;;44816:7;44827:1;44816:12;44808:68;;;;-1:-1:-1;;;44808:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;44889:21:0;;;;;;;:14;:21;;;;;;;;:30;;;;;;;;;;;:41;;44923:7;;44889:21;:41;;44923:7;;44889:41;:::i;:::-;;;;-1:-1:-1;;;;;;;44941:26:0;;;;;;:19;:26;;;;;:37;;44971:7;;44941:26;:37;;44971:7;;44941:37;:::i;:::-;;;;-1:-1:-1;44991:47:0;;-1:-1:-1;45014:5:0;45021:7;45030;44991:22;:47::i;:::-;45054:45;;;-1:-1:-1;;;;;206:32:1;;;188:51;;270:2;255:18;;248:34;;;45054:45:0;;;;;161:18:1;45054:45:0;;;;;;;44656:451;44593:514;;:::o;92355:108::-;28592:13;:11;:13::i;:::-;92431:12:::1;:24:::0;92355:108::o;92233:114::-;28592:13;:11;:13::i;:::-;92312:15:::1;:27:::0;92233:114::o;92119:106::-;28592:13;:11;:13::i;:::-;92194:11:::1;:23:::0;92119:106::o;90977:916::-;91076:11;;91101:10;91098:35;;91113:20;;-1:-1:-1;;;91113:20:0;;;;;;;:::i;91098:35::-;91159:17;91167:9;91159:5;:17;:::i;:::-;91147:9;:29;91144:60;;;91178:26;;-1:-1:-1;;;91178:26:0;;;;;;;:::i;91144:60::-;91234:18;91219:11;;;;:33;;;;;;;;:::i;:::-;;91216:65;;91254:27;;-1:-1:-1;;;91254:27:0;;13631:2:1;91254:27:0;;;13613:21:1;13670:2;13650:18;;;13643:30;-1:-1:-1;;;13689:18:1;;;13682:47;13746:18;;91254:27:0;13429:341:1;91216:65:0;88683:4;91311:9;91295:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:38;91292:79;;;91335:36;;-1:-1:-1;;;91335:36:0;;13977:2:1;91335:36:0;;;13959:21:1;14016:2;13996:18;;;13989:30;14055:28;14035:18;;;14028:56;14101:18;;91335:36:0;13775:350:1;91292:79:0;91404:194;91588:9;;91404:194;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;91428:140:0;;11480:66:1;91428:140:0;;;11468:79:1;91540:10:0;11563:12:1;;;11556:28;11600:12;;;-1:-1:-1;91428:140:0;;-1:-1:-1;11238:380:1;91404:194:0;91385:15;;-1:-1:-1;;;;;91385:15:0;;;:213;;;91382:255;;91600:37;;-1:-1:-1;;;91600:37:0;;14332:2:1;91600:37:0;;;14314:21:1;14371:2;14351:18;;;14344:30;14410:29;14390:18;;;14383:57;14457:18;;91600:37:0;14130:351:1;91382:255:0;91706:19;;91680:10;91651:40;;;;:28;:40;;;;;;:52;;91694:9;;91651:52;:::i;:::-;:74;91648:120;;;91727:41;;-1:-1:-1;;;91727:41:0;;14688:2:1;91727:41:0;;;14670:21:1;14727:2;14707:18;;;14700:30;14766:33;14746:18;;;14739:61;14817:18;;91727:41:0;14486:355:1;93437:141:0;93483:6;93479:92;93500:10;;93496:1;:14;93479:92;;;93533:26;93549:8;93555:1;93549:5;:8::i;93533:26::-;93513:3;;;;:::i;:::-;;;;93479:92;;;;93437:141::o;57724:152::-;57796:7;57839:27;57858:7;57839:18;:27::i;88586:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;53266:233::-;53338:7;-1:-1:-1;;;;;53362:19:0;;53358:60;;53390:28;;-1:-1:-1;;;53390:28:0;;;;;;;;;;;53358:60;-1:-1:-1;;;;;;53436:25:0;;;;;:18;:25;;;;;;47425:13;53436:55;;53266:233::o;29354:103::-;28592:13;:11;:13::i;:::-;29419:30:::1;29446:1;29419:18;:30::i;:::-;29354:103::o:0;92792:105::-;28592:13;:11;:13::i;:::-;92859:21:::1;:30:::0;92792:105::o;92905:122::-;-1:-1:-1;;;;;53670:25:0;;92970:7;53670:25;;;:18;:25;;47563:2;53670:25;;;;47425:13;53670:50;;53669:82;92997:22;53581:178;42837:100;42888:7;42915;42923:5;42915:14;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;42915:14:0;;42837:100;-1:-1:-1;;42837:100:0:o;56507:104::-;56563:13;56596:7;56589:14;;;;;:::i;92471:100::-;28592:13;:11;:13::i;:::-;92545:7:::1;:18;92555:8:::0;92545:7;:18:::1;:::i;:::-;;92471:100:::0;:::o;63372:308::-;8611:10;-1:-1:-1;;;;;63471:31:0;;;63467:61;;63511:17;;-1:-1:-1;;;63511:17:0;;;;;;;;;;;63467:61;8611:10;63541:39;;;;:18;:39;;;;;;;;-1:-1:-1;;;;;63541:49:0;;;;;;;;;;;;:60;;-1:-1:-1;;63541:60:0;;;;;;;;;;63617:55;;819:41:1;;;63541:49:0;;8611:10;63617:55;;792:18:1;63617:55:0;;;;;;;63372:308;;:::o;43027:225::-;43085:7;43105:21;43153:15;41740:14;;;41667:95;43153:15;43129:39;;:21;:39;:::i;:::-;43105:63;;43186:58;43202:7;43211:13;43226:17;43235:7;-1:-1:-1;;;;;42416:18:0;42389:7;42416:18;;;:9;:18;;;;;;;42333:109;43226:17;43186:15;:58::i;:::-;43179:65;43027:225;-1:-1:-1;;;43027:225:0:o;90467:502::-;90548:15;;90577:10;90574:35;;90589:20;;-1:-1:-1;;;90589:20:0;;;;;;;:::i;90574:35::-;90635:17;90643:9;90635:5;:17;:::i;:::-;90623:9;:29;90620:60;;;90654:26;;-1:-1:-1;;;90654:26:0;;;;;;;:::i;90620:60::-;90706:21;;90694:9;:33;90691:71;;;90729:33;;-1:-1:-1;;;90729:33:0;;17524:2:1;90729:33:0;;;17506:21:1;17563:2;17543:18;;;17536:30;17602:25;17582:18;;;17575:53;17645:18;;90729:33:0;17322:347:1;90691:71:0;90791:15;90776:11;;;;:30;;;;;;;;:::i;:::-;;90773:66;;90808:31;;-1:-1:-1;;;90808:31:0;;17876:2:1;90808:31:0;;;17858:21:1;17915:2;17895:18;;;17888:30;-1:-1:-1;;;17934:18:1;;;17927:51;17995:18;;90808:31:0;17674:345:1;90773:66:0;88683:4;90869:9;90853:13;:11;:13::i;:::-;:25;;;;:::i;:::-;:38;90850:72;;;90893:29;;-1:-1:-1;;;90893:29:0;;18226:2:1;90893:29:0;;;18208:21:1;18265:2;18245:18;;;18238:30;-1:-1:-1;;;18284:18:1;;;18277:49;18343:18;;90893:29:0;18024:343:1;90850:72:0;90933:28;90939:10;90951:9;90933:5;:28::i;70217:399::-;70384:31;70397:4;70403:2;70407:7;70384:12;:31::i;:::-;-1:-1:-1;;;;;70430:14:0;;;:19;70426:183;;70469:56;70500:4;70506:2;70510:7;70519:5;70469:30;:56::i;:::-;70464:145;;70553:40;;-1:-1:-1;;;70553:40:0;;;;;;;;;;;43412:260;-1:-1:-1;;;;;42004:26:0;;43484:7;42004:26;;;:19;:26;;;;;;43484:7;;43528:30;;-1:-1:-1;;;43528:30:0;;43552:4;43528:30;;;1958:51:1;-1:-1:-1;;;;;43528:15:0;;;;;1931:18:1;;43528:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;-1:-1:-1;;;;;42708:21:0;;;42681:7;42708:21;;;:14;:21;;;;;;;;:30;;;;;;;;;;43504:77;;-1:-1:-1;43599:65:0;;43615:7;;43504:77;;43186:15;:58::i;43599:65::-;43592:72;43412:260;-1:-1:-1;;;;43412:260:0:o;93182:247::-;93253:13;93287:17;93295:8;93287:7;:17::i;:::-;93279:61;;;;-1:-1:-1;;;93279:61:0;;18763:2:1;93279:61:0;;;18745:21:1;18802:2;18782:18;;;18775:30;18841:33;18821:18;;;18814:61;18892:18;;93279:61:0;18561:355:1;93279:61:0;93382:7;93391:19;93401:8;93391:9;:19::i;:::-;93365:55;;;;;;;;;:::i;:::-;;;;;;;;;;;;;93351:70;;93182:247;;;:::o;89413:153::-;28592:13;:11;:13::i;:::-;89471::::1;:11;:13::i;:::-;:18:::0;89468:59:::1;;89491:36;::::0;-1:-1:-1;;;89491:36:0;;20315:2:1;89491:36:0::1;::::0;::::1;20297:21:1::0;20354:2;20334:18;;;20327:30;20393:28;20373:18;;;20366:56;20439:18;;89491:36:0::1;20113:350:1::0;89468:59:0::1;89538:20;89544:10;89556:1;89538:5;:20::i;29612:201::-:0;28592:13;:11;:13::i;:::-;-1:-1:-1;;;;;29701:22:0;::::1;29693:73;;;::::0;-1:-1:-1;;;29693:73:0;;20670:2:1;29693:73:0::1;::::0;::::1;20652:21:1::0;20709:2;20689:18;;;20682:30;20748:34;20728:18;;;20721:62;-1:-1:-1;;;20799:18:1;;;20792:36;20845:19;;29693:73:0::1;20468:402:1::0;29693:73:0::1;29777:28;29796:8;29777:18;:28::i;92579:92::-:0;28592:13;:11;:13::i;:::-;92657:5:::1;92652:11;;;;;;;;:::i;:::-;92638;:25:::0;;-1:-1:-1;;92638:25:0::1;::::0;;::::1;::::0;::::1;;;;;;:::i;:::-;;;;;;92579:92:::0;:::o;92679:105::-;28592:13;:11;:13::i;:::-;92748:19:::1;:28:::0;92679:105::o;64259:282::-;64324:4;64380:7;51681:1;64361:26;;:66;;;;;64414:13;;64404:7;:23;64361:66;:153;;;;-1:-1:-1;;64465:26:0;;;;:17;:26;;;;;;-1:-1:-1;;;64465:44:0;:49;;64259:282::o;34294:231::-;34372:7;34393:17;34412:18;34434:27;34445:4;34451:9;34434:10;:27::i;:::-;34392:69;;;;34472:18;34484:5;34472:11;:18::i;:::-;-1:-1:-1;34508:9:0;34294:231;-1:-1:-1;;;34294:231:0:o;73878:2454::-;73974:13;;73951:20;74002:13;;;73998:44;;74024:18;;-1:-1:-1;;;74024:18:0;;;;;;;;;;;73998:44;-1:-1:-1;;;;;74530:22:0;;;;;;:18;:22;;;;47563:2;74530:22;;;:71;;74568:32;74556:45;;74530:71;;;74844:31;;;:17;:31;;;;;-1:-1:-1;61544:15:0;;61518:24;61514:46;61113:11;61088:23;61084:41;61081:52;61071:63;;74844:173;;75079:23;;;;74844:31;;74530:22;;75578:25;74530:22;;75431:335;75846:1;75832:12;75828:20;75786:346;75887:3;75878:7;75875:16;75786:346;;76105:7;76095:8;76092:1;76065:25;76062:1;76059;76054:59;75940:1;75927:15;75786:346;;;75790:77;76165:8;76177:1;76165:13;76161:45;;76187:19;;-1:-1:-1;;;76187:19:0;;;;;;;;;;;76161:45;76223:13;:19;-1:-1:-1;69434:185:0;;;:::o;2439:317::-;2554:6;2529:21;:31;;2521:73;;;;-1:-1:-1;;;2521:73:0;;21077:2:1;2521:73:0;;;21059:21:1;21116:2;21096:18;;;21089:30;21155:31;21135:18;;;21128:59;21204:18;;2521:73:0;20875:353:1;2521:73:0;2608:12;2626:9;-1:-1:-1;;;;;2626:14:0;2648:6;2626:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2607:52;;;2678:7;2670:78;;;;-1:-1:-1;;;2670:78:0;;21645:2:1;2670:78:0;;;21627:21:1;21684:2;21664:18;;;21657:30;21723:34;21703:18;;;21696:62;21794:28;21774:18;;;21767:56;21840:19;;2670:78:0;21443:422:1;58879:1275:0;58946:7;58981;;51681:1;59030:23;59026:1061;;59083:13;;59076:4;:20;59072:1015;;;59121:14;59138:23;;;:17;:23;;;;;;;-1:-1:-1;;;59227:24:0;;:29;;59223:845;;59892:113;59899:6;59909:1;59899:11;59892:113;;-1:-1:-1;;;59970:6:0;59952:25;;;;:17;:25;;;;;;59892:113;;59223:845;59098:989;59072:1015;60115:31;;-1:-1:-1;;;60115:31:0;;;;;;;;;;;22041:211;22185:58;;;-1:-1:-1;;;;;206:32:1;;22185:58:0;;;188:51:1;255:18;;;;248:34;;;22185:58:0;;;;;;;;;;161:18:1;;;;22185:58:0;;;;;;;;-1:-1:-1;;;;;22185:58:0;-1:-1:-1;;;22185:58:0;;;22158:86;;22178:5;;22158:19;:86::i;28871:132::-;28752:7;28779:6;-1:-1:-1;;;;;28779:6:0;8611:10;28935:23;28927:68;;;;-1:-1:-1;;;28927:68:0;;22072:2:1;28927:68:0;;;22054:21:1;;;22091:18;;;22084:30;22150:34;22130:18;;;22123:62;22202:18;;28927:68:0;21870:356:1;29973:191:0;30047:16;30066:6;;-1:-1:-1;;;;;30083:17:0;;;-1:-1:-1;;;;;;30083:17:0;;;;;;30116:40;;30066:6;;;;;;;30116:40;;30047:16;30116:40;30036:128;29973:191;:::o;45285:248::-;45495:12;;-1:-1:-1;;;;;45475:16:0;;45431:7;45475:16;;;:7;:16;;;;;;45431:7;;45510:15;;45459:32;;:13;:32;:::i;:::-;45458:49;;;;:::i;:::-;:67;;;;:::i;72700:716::-;72884:88;;-1:-1:-1;;;72884:88:0;;72863:4;;-1:-1:-1;;;;;72884:45:0;;;;;:88;;8611:10;;72951:4;;72957:7;;72966:5;;72884:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72884:88:0;;;;;;;;-1:-1:-1;;72884:88:0;;;;;;;;;;;;:::i;:::-;;;72880:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73167:6;:13;73184:1;73167:18;73163:235;;73213:40;;-1:-1:-1;;;73213:40:0;;;;;;;;;;;73163:235;73356:6;73350:13;73341:6;73337:2;73333:15;73326:38;72880:529;-1:-1:-1;;;;;;73043:64:0;-1:-1:-1;;;73043:64:0;;-1:-1:-1;72700:716:0;;;;;;:::o;86232:2002::-;86709:4;86703:11;;86716:3;86699:21;;86794:17;;;;87490:11;;;87369:5;87656:2;87670;87660:13;;87652:22;87490:11;87639:36;87711:2;87701:13;;87261:731;87730:4;87261:731;;;87921:1;87916:3;87912:11;87905:18;;87972:2;87966:4;87962:13;87958:2;87954:22;87949:3;87941:36;87825:2;87815:13;;87261:731;;;-1:-1:-1;88022:13:0;;;-1:-1:-1;;88137:12:0;;;88197:19;;;88137:12;86232:2002;-1:-1:-1;86232:2002:0:o;32088:1404::-;32169:7;32178:12;32403:9;:16;32423:2;32403:22;32399:1086;;32747:4;32732:20;;32726:27;32797:4;32782:20;;32776:27;32855:4;32840:20;;32834:27;32442:9;32826:36;32898:25;32909:4;32826:36;32726:27;32776;32898:10;:25::i;:::-;32891:32;;;;;;;;;32399:1086;32945:9;:16;32965:2;32945:22;32941:544;;33268:4;33253:20;;33247:27;33319:4;33304:20;;33298:27;33361:23;33372:4;33247:27;33298;33361:10;:23::i;:::-;33354:30;;;;;;;;32941:544;-1:-1:-1;33433:1:0;;-1:-1:-1;33437:35:0;32941:544;32088:1404;;;;;:::o;30359:643::-;30437:20;30428:5;:29;;;;;;;;:::i;:::-;;30424:571;;30359:643;:::o;30424:571::-;30535:29;30526:5;:38;;;;;;;;:::i;:::-;;30522:473;;30581:34;;-1:-1:-1;;;30581:34:0;;23536:2:1;30581:34:0;;;23518:21:1;23575:2;23555:18;;;23548:30;23614:26;23594:18;;;23587:54;23658:18;;30581:34:0;23334:348:1;30522:473:0;30646:35;30637:5;:44;;;;;;;;:::i;:::-;;30633:362;;30698:41;;-1:-1:-1;;;30698:41:0;;23889:2:1;30698:41:0;;;23871:21:1;23928:2;23908:18;;;23901:30;23967:33;23947:18;;;23940:61;24018:18;;30698:41:0;23687:355:1;30633:362:0;30770:30;30761:5;:39;;;;;;;;:::i;:::-;;30757:238;;30817:44;;-1:-1:-1;;;30817:44:0;;24249:2:1;30817:44:0;;;24231:21:1;24288:2;24268:18;;;24261:30;24327:34;24307:18;;;24300:62;-1:-1:-1;;;24378:18:1;;;24371:32;24420:19;;30817:44:0;24047:398:1;30757:238:0;30892:30;30883:5;:39;;;;;;;;:::i;:::-;;30879:116;;30939:44;;-1:-1:-1;;;30939:44:0;;24652:2:1;30939:44:0;;;24634:21:1;24691:2;24671:18;;;24664:30;24730:34;24710:18;;;24703:62;-1:-1:-1;;;24781:18:1;;;24774:32;24823:19;;30939:44:0;24450:398:1;25108:716:0;25532:23;25558:69;25586:4;25558:69;;;;;;;;;;;;;;;;;25566:5;-1:-1:-1;;;;;25558:27:0;;;:69;;;;;:::i;:::-;25642:17;;25532:95;;-1:-1:-1;25642:21:0;25638:179;;25739:10;25728:30;;;;;;;;;;;;:::i;:::-;25720:85;;;;-1:-1:-1;;;25720:85:0;;25305:2:1;25720:85:0;;;25287:21:1;25344:2;25324:18;;;25317:30;25383:34;25363:18;;;25356:62;-1:-1:-1;;;25434:18:1;;;25427:40;25484:19;;25720:85:0;25103:406:1;35746:1632:0;35877:7;;36811:66;36798:79;;36794:163;;;-1:-1:-1;36910:1:0;;-1:-1:-1;36914:30:0;36894:51;;36794:163;36971:1;:7;;36976:2;36971:7;;:18;;;;;36982:1;:7;;36987:2;36982:7;;36971:18;36967:102;;;-1:-1:-1;37022:1:0;;-1:-1:-1;37026:30:0;37006:51;;36967:102;37183:24;;;37166:14;37183:24;;;;;;;;;25741:25:1;;;25814:4;25802:17;;25782:18;;;25775:45;;;;25836:18;;;25829:34;;;25879:18;;;25872:34;;;37183:24:0;;25713:19:1;;37183:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;37183:24:0;;-1:-1:-1;;37183:24:0;;;-1:-1:-1;;;;;;;37222:20:0;;37218:103;;37275:1;37279:29;37259:50;;;;;;;37218:103;37341:6;-1:-1:-1;37349:20:0;;-1:-1:-1;35746:1632:0;;;;;;;;:::o;34788:344::-;34902:7;;-1:-1:-1;;;;;34948:80:0;;34902:7;35055:25;35071:3;35056:18;;;35078:2;35055:25;:::i;:::-;35039:42;;35099:25;35110:4;35116:1;35119;35122;35099:10;:25::i;:::-;35092:32;;;;;;34788:344;;;;;;:::o;3923:229::-;4060:12;4092:52;4114:6;4122:4;4128:1;4131:12;4060;-1:-1:-1;;;;;1473:19:0;;;5330:60;;;;-1:-1:-1;;;5330:60:0;;26526:2:1;5330:60:0;;;26508:21:1;26565:2;26545:18;;;26538:30;26604:31;26584:18;;;26577:59;26653:18;;5330:60:0;26324:353:1;5330:60:0;5404:12;5418:23;5445:6;-1:-1:-1;;;;;5445:11:0;5464:5;5471:4;5445:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5403:73;;;;5494:51;5511:7;5520:10;5532:12;5494:16;:51::i;:::-;5487:58;5043:510;-1:-1:-1;;;;;;;5043:510:0:o;7729:762::-;7879:12;7908:7;7904:580;;;-1:-1:-1;7939:10:0;7932:17;;7904:580;8053:17;;:21;8049:424;;8301:10;8295:17;8362:15;8349:10;8345:2;8341:19;8334:44;8049:424;8444:12;8437:20;;-1:-1:-1;;;8437:20:0;;;;;;;;:::i;293:131:1:-;-1:-1:-1;;;;;;367:32:1;;357:43;;347:71;;414:1;411;404:12;429:245;487:6;540:2;528:9;519:7;515:23;511:32;508:52;;;556:1;553;546:12;508:52;595:9;582:23;614:30;638:5;614:30;:::i;871:250::-;956:1;966:113;980:6;977:1;974:13;966:113;;;1056:11;;;1050:18;1037:11;;;1030:39;1002:2;995:10;966:113;;;-1:-1:-1;;1113:1:1;1095:16;;1088:27;871:250::o;1126:271::-;1168:3;1206:5;1200:12;1233:6;1228:3;1221:19;1249:76;1318:6;1311:4;1306:3;1302:14;1295:4;1288:5;1284:16;1249:76;:::i;:::-;1379:2;1358:15;-1:-1:-1;;1354:29:1;1345:39;;;;1386:4;1341:50;;1126:271;-1:-1:-1;;1126:271:1:o;1402:220::-;1551:2;1540:9;1533:21;1514:4;1571:45;1612:2;1601:9;1597:18;1589:6;1571:45;:::i;1627:180::-;1686:6;1739:2;1727:9;1718:7;1714:23;1710:32;1707:52;;;1755:1;1752;1745:12;1707:52;-1:-1:-1;1778:23:1;;1627:180;-1:-1:-1;1627:180:1:o;2020:659::-;2099:6;2107;2115;2168:2;2156:9;2147:7;2143:23;2139:32;2136:52;;;2184:1;2181;2174:12;2136:52;2220:9;2207:23;2197:33;;2281:2;2270:9;2266:18;2253:32;2304:18;2345:2;2337:6;2334:14;2331:34;;;2361:1;2358;2351:12;2331:34;2399:6;2388:9;2384:22;2374:32;;2444:7;2437:4;2433:2;2429:13;2425:27;2415:55;;2466:1;2463;2456:12;2415:55;2506:2;2493:16;2532:2;2524:6;2521:14;2518:34;;;2548:1;2545;2538:12;2518:34;2593:7;2588:2;2579:6;2575:2;2571:15;2567:24;2564:37;2561:57;;;2614:1;2611;2604:12;2561:57;2645:2;2641;2637:11;2627:21;;2667:6;2657:16;;;;;2020:659;;;;;:::o;2684:131::-;-1:-1:-1;;;;;2759:31:1;;2749:42;;2739:70;;2805:1;2802;2795:12;2820:315;2888:6;2896;2949:2;2937:9;2928:7;2924:23;2920:32;2917:52;;;2965:1;2962;2955:12;2917:52;3004:9;2991:23;3023:31;3048:5;3023:31;:::i;:::-;3073:5;3125:2;3110:18;;;;3097:32;;-1:-1:-1;;;2820:315:1:o;3140:127::-;3201:10;3196:3;3192:20;3189:1;3182:31;3232:4;3229:1;3222:15;3256:4;3253:1;3246:15;3272:232;3348:1;3341:5;3338:12;3328:143;;3393:10;3388:3;3384:20;3381:1;3374:31;3428:4;3425:1;3418:15;3456:4;3453:1;3446:15;3328:143;3480:18;;3272:232::o;3509:556::-;3790:3;3775:19;;3803:39;3779:9;3824:6;3803:39;:::i;:::-;3873:2;3858:18;;3851:34;;;;3916:2;3901:18;;3894:34;;;;3959:2;3944:18;;3937:34;;;;4002:3;3987:19;;3980:35;4046:3;4031:19;;;4024:35;3509:556;;-1:-1:-1;3509:556:1:o;4252:255::-;4319:6;4372:2;4360:9;4351:7;4347:23;4343:32;4340:52;;;4388:1;4385;4378:12;4340:52;4427:9;4414:23;4446:31;4471:5;4446:31;:::i;4512:456::-;4589:6;4597;4605;4658:2;4646:9;4637:7;4633:23;4629:32;4626:52;;;4674:1;4671;4664:12;4626:52;4713:9;4700:23;4732:31;4757:5;4732:31;:::i;:::-;4782:5;-1:-1:-1;4839:2:1;4824:18;;4811:32;4852:33;4811:32;4852:33;:::i;:::-;4512:456;;4904:7;;-1:-1:-1;;;4958:2:1;4943:18;;;;4930:32;;4512:456::o;4973:402::-;5055:6;5063;5116:2;5104:9;5095:7;5091:23;5087:32;5084:52;;;5132:1;5129;5122:12;5084:52;5171:9;5158:23;5190:31;5215:5;5190:31;:::i;:::-;5240:5;-1:-1:-1;5297:2:1;5282:18;;5269:32;5310:33;5269:32;5310:33;:::i;:::-;5362:7;5352:17;;;4973:402;;;;;:::o;5632:127::-;5693:10;5688:3;5684:20;5681:1;5674:31;5724:4;5721:1;5714:15;5748:4;5745:1;5738:15;5764:632;5829:5;5859:18;5900:2;5892:6;5889:14;5886:40;;;5906:18;;:::i;:::-;5981:2;5975:9;5949:2;6035:15;;-1:-1:-1;;6031:24:1;;;6057:2;6027:33;6023:42;6011:55;;;6081:18;;;6101:22;;;6078:46;6075:72;;;6127:18;;:::i;:::-;6167:10;6163:2;6156:22;6196:6;6187:15;;6226:6;6218;6211:22;6266:3;6257:6;6252:3;6248:16;6245:25;6242:45;;;6283:1;6280;6273:12;6242:45;6333:6;6328:3;6321:4;6313:6;6309:17;6296:44;6388:1;6381:4;6372:6;6364;6360:19;6356:30;6349:41;;;;5764:632;;;;;:::o;6401:451::-;6470:6;6523:2;6511:9;6502:7;6498:23;6494:32;6491:52;;;6539:1;6536;6529:12;6491:52;6579:9;6566:23;6612:18;6604:6;6601:30;6598:50;;;6644:1;6641;6634:12;6598:50;6667:22;;6720:4;6712:13;;6708:27;-1:-1:-1;6698:55:1;;6749:1;6746;6739:12;6698:55;6772:74;6838:7;6833:2;6820:16;6815:2;6811;6807:11;6772:74;:::i;6857:118::-;6943:5;6936:13;6929:21;6922:5;6919:32;6909:60;;6965:1;6962;6955:12;6980:382;7045:6;7053;7106:2;7094:9;7085:7;7081:23;7077:32;7074:52;;;7122:1;7119;7112:12;7074:52;7161:9;7148:23;7180:31;7205:5;7180:31;:::i;:::-;7230:5;-1:-1:-1;7287:2:1;7272:18;;7259:32;7300:30;7259:32;7300:30;:::i;7367:795::-;7462:6;7470;7478;7486;7539:3;7527:9;7518:7;7514:23;7510:33;7507:53;;;7556:1;7553;7546:12;7507:53;7595:9;7582:23;7614:31;7639:5;7614:31;:::i;:::-;7664:5;-1:-1:-1;7721:2:1;7706:18;;7693:32;7734:33;7693:32;7734:33;:::i;:::-;7786:7;-1:-1:-1;7840:2:1;7825:18;;7812:32;;-1:-1:-1;7895:2:1;7880:18;;7867:32;7922:18;7911:30;;7908:50;;;7954:1;7951;7944:12;7908:50;7977:22;;8030:4;8022:13;;8018:27;-1:-1:-1;8008:55:1;;8059:1;8056;8049:12;8008:55;8082:74;8148:7;8143:2;8130:16;8125:2;8121;8117:11;8082:74;:::i;:::-;8072:84;;;7367:795;;;;;;;:::o;8167:198::-;8308:2;8293:18;;8320:39;8297:9;8341:6;8320:39;:::i;9029:380::-;9108:1;9104:12;;;;9151;;;9172:61;;9226:4;9218:6;9214:17;9204:27;;9172:61;9279:2;9271:6;9268:14;9248:18;9245:38;9242:161;;9325:10;9320:3;9316:20;9313:1;9306:31;9360:4;9357:1;9350:15;9388:4;9385:1;9378:15;9242:161;;9029:380;;;:::o;9414:334::-;9616:2;9598:21;;;9655:2;9635:18;;;9628:30;-1:-1:-1;;;9689:2:1;9674:18;;9667:40;9739:2;9724:18;;9414:334::o;9753:127::-;9814:10;9809:3;9805:20;9802:1;9795:31;9845:4;9842:1;9835:15;9869:4;9866:1;9859:15;9885:168;9958:9;;;9989;;10006:15;;;10000:22;;9986:37;9976:71;;10027:18;;:::i;10058:340::-;10260:2;10242:21;;;10299:2;10279:18;;;10272:30;-1:-1:-1;;;10333:2:1;10318:18;;10311:46;10389:2;10374:18;;10058:340::o;10752:125::-;10817:9;;;10838:10;;;10835:36;;;10851:18;;:::i;12323:402::-;12525:2;12507:21;;;12564:2;12544:18;;;12537:30;12603:34;12598:2;12583:18;;12576:62;-1:-1:-1;;;12669:2:1;12654:18;;12647:36;12715:3;12700:19;;12323:402::o;12730:407::-;12932:2;12914:21;;;12971:2;12951:18;;;12944:30;13010:34;13005:2;12990:18;;12983:62;-1:-1:-1;;;13076:2:1;13061:18;;13054:41;13127:3;13112:19;;12730:407::o;14846:135::-;14885:3;14906:17;;;14903:43;;14926:18;;:::i;:::-;-1:-1:-1;14973:1:1;14962:13;;14846:135::o;14986:127::-;15047:10;15042:3;15038:20;15035:1;15028:31;15078:4;15075:1;15068:15;15102:4;15099:1;15092:15;15244:545;15346:2;15341:3;15338:11;15335:448;;;15382:1;15407:5;15403:2;15396:17;15452:4;15448:2;15438:19;15522:2;15510:10;15506:19;15503:1;15499:27;15493:4;15489:38;15558:4;15546:10;15543:20;15540:47;;;-1:-1:-1;15581:4:1;15540:47;15636:2;15631:3;15627:12;15624:1;15620:20;15614:4;15610:31;15600:41;;15691:82;15709:2;15702:5;15699:13;15691:82;;;15754:17;;;15735:1;15724:13;15691:82;;15965:1352;16091:3;16085:10;16118:18;16110:6;16107:30;16104:56;;;16140:18;;:::i;:::-;16169:97;16259:6;16219:38;16251:4;16245:11;16219:38;:::i;:::-;16213:4;16169:97;:::i;:::-;16321:4;;16385:2;16374:14;;16402:1;16397:663;;;;17104:1;17121:6;17118:89;;;-1:-1:-1;17173:19:1;;;17167:26;17118:89;-1:-1:-1;;15922:1:1;15918:11;;;15914:24;15910:29;15900:40;15946:1;15942:11;;;15897:57;17220:81;;16367:944;;16397:663;15191:1;15184:14;;;15228:4;15215:18;;-1:-1:-1;;16433:20:1;;;16551:236;16565:7;16562:1;16559:14;16551:236;;;16654:19;;;16648:26;16633:42;;16746:27;;;;16714:1;16702:14;;;;16581:19;;16551:236;;;16555:3;16815:6;16806:7;16803:19;16800:201;;;16876:19;;;16870:26;-1:-1:-1;;16959:1:1;16955:14;;;16971:3;16951:24;16947:37;16943:42;16928:58;16913:74;;16800:201;-1:-1:-1;;;;;17047:1:1;17031:14;;;17027:22;17014:36;;-1:-1:-1;15965:1352:1:o;18372:184::-;18442:6;18495:2;18483:9;18474:7;18470:23;18466:32;18463:52;;;18511:1;18508;18501:12;18463:52;-1:-1:-1;18534:16:1;;18372:184;-1:-1:-1;18372:184:1:o;18921:1187::-;19198:3;19227:1;19260:6;19254:13;19290:36;19316:9;19290:36;:::i;:::-;19345:1;19362:18;;;19389:133;;;;19536:1;19531:356;;;;19355:532;;19389:133;-1:-1:-1;;19422:24:1;;19410:37;;19495:14;;19488:22;19476:35;;19467:45;;;-1:-1:-1;19389:133:1;;19531:356;19562:6;19559:1;19552:17;19592:4;19637:2;19634:1;19624:16;19662:1;19676:165;19690:6;19687:1;19684:13;19676:165;;;19768:14;;19755:11;;;19748:35;19811:16;;;;19705:10;;19676:165;;;19680:3;;;19870:6;19865:3;19861:16;19854:23;;19355:532;;;;;19918:6;19912:13;19934:68;19993:8;19988:3;19981:4;19973:6;19969:17;19934:68;:::i;:::-;-1:-1:-1;;;20024:18:1;;20051:22;;;20100:1;20089:13;;18921:1187;-1:-1:-1;;;;18921:1187:1:o;22231:217::-;22271:1;22297;22287:132;;22341:10;22336:3;22332:20;22329:1;22322:31;22376:4;22373:1;22366:15;22404:4;22401:1;22394:15;22287:132;-1:-1:-1;22433:9:1;;22231:217::o;22453:128::-;22520:9;;;22541:11;;;22538:37;;;22555:18;;:::i;22586:489::-;-1:-1:-1;;;;;22855:15:1;;;22837:34;;22907:15;;22902:2;22887:18;;22880:43;22954:2;22939:18;;22932:34;;;23002:3;22997:2;22982:18;;22975:31;;;22780:4;;23023:46;;23049:19;;23041:6;23023:46;:::i;:::-;23015:54;22586:489;-1:-1:-1;;;;;;22586:489:1:o;23080:249::-;23149:6;23202:2;23190:9;23181:7;23177:23;23173:32;23170:52;;;23218:1;23215;23208:12;23170:52;23250:9;23244:16;23269:30;23293:5;23269:30;:::i;24853:245::-;24920:6;24973:2;24961:9;24952:7;24948:23;24944:32;24941:52;;;24989:1;24986;24979:12;24941:52;25021:9;25015:16;25040:28;25062:5;25040:28;:::i;26682:287::-;26811:3;26849:6;26843:13;26865:66;26924:6;26919:3;26912:4;26904:6;26900:17;26865:66;:::i;:::-;26947:16;;;;;26682:287;-1:-1:-1;;26682:287:1:o

Swarm Source

ipfs://6246a1af63d0940e55e1de7f8fb95343036774259500e4b23d696ef27c5fd742
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.