ETH Price: $3,097.57 (+0.94%)
Gas: 7 Gwei

Token

JPEG Coffee (JPEG)
 

Overview

Max Total Supply

166 JPEG

Holders

27

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 JPEG
0x4031c03871a3e1ed5557f527d9cb983dd4797ac8
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:
JPEG

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: MIT
// File: JPEGCoffee_flat.sol


// File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol


// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

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

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

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

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

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

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

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

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

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

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

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

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

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

// File: contracts/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;


interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}
// File: contracts/OperatorFilterer.sol


pragma solidity ^0.8.13;


contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry constant operatorFilterRegistry =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

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

    modifier onlyAllowedOperator() virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(operatorFilterRegistry).code.length > 0) {
            if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {
                revert OperatorNotAllowed(msg.sender);
            }
        }
        _;
    }
}
// File: contracts/DefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}
// File: contracts/JPEGCOFFEE.SOL



// You own whatever image your token points to! do whatever you please with it!

// File: https://github.com/chiru-labs/ERC721A/blob/main/contracts/IERC721A.sol


// ERC721A Contracts v3.3.0
// Creator: Chiru Labs


pragma solidity ^0.8.4;

 
/**
 * @dev Interface of an ERC721A compliant contract.
 */
 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();

    /**
     * The caller cannot approve to the current owner.
     */
    error ApprovalToCurrentOwner();

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

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     *
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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

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

// File: https://github.com/chiru-labs/ERC721A/blob/main/contracts/ERC721A.sol


// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;


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

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // 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 tokenId of the next token 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`
    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 => address) private _tokenApprovals;

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

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

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

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view 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 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 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 returns (uint256) {
        return _burnCounter;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    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: 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.
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view 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 auxillary 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 auxillary 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 {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        assembly { // Cast aux without masking.
            auxCasted := aux
        }
        packed = (packed & BITMASK_AUX_COMPLEMENT) | (auxCasted << BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    /**
     * 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 ownership that has an address and is not burned
                        // before an ownership that does not have an address and is not burned.
                        // Hence, curr will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed is zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        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, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return '';
    }

    /**
     * @dev Casts the address to uint256 without masking.
     */
    function _addressToUint256(address value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

    /**
     * @dev Casts the boolean to uint256 without branching.
     */
    function _boolToUint256(bool value) private pure returns (uint256 result) {
        assembly {
            result := value
        }
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public override {
        address owner = address(uint160(_packedOwnershipOf(tokenId)));
        if (to == owner) revert ApprovalToCurrentOwner();

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

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

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        if (operator == _msgSenderERC721A()) revert ApproveToCaller();

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

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

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

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        _transfer(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & BITMASK_BURNED == 0; // and not burned.
    }

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

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

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _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] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (to.code.length != 0) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex < end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex < end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

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

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the balance and number minted.
            _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] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                (_boolToUint256(quantity == 1) << BITPOS_NEXT_INITIALIZED);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex < end);

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) private {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

        bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
            isApprovedForAll(from, _msgSenderERC721A()) ||
            getApproved(tokenId) == _msgSenderERC721A());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

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

        // 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] =
                _addressToUint256(to) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_NEXT_INITIALIZED;

            // 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 `_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));

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSenderERC721A() == from ||
                isApprovedForAll(from, _msgSenderERC721A()) ||
                getApproved(tokenId) == _msgSenderERC721A());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

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

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

        // 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] =
                _addressToUint256(from) |
                (block.timestamp << BITPOS_START_TIMESTAMP) |
                BITMASK_BURNED | 
                BITMASK_NEXT_INITIALIZED;

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

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _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))
                }
            }
        }
    }

    /**
     * @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 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 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. 48 is the ASCII index of '0'.
                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)
        }
    }
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol


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

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
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);
    }
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol


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

pragma solidity ^0.8.0;

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol


// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol


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

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721Receiver.sol


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

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol


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

pragma solidity ^0.8.0;

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/ERC165.sol


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

pragma solidity ^0.8.0;


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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: 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);
}

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/IERC721Metadata.sol


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

pragma solidity ^0.8.0;


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

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

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

// File: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol


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

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

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

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}



pragma solidity ^0.8.0;


contract JPEG is ERC721A, Ownable, DefaultOperatorFilterer  {
    using Strings for uint256;

    string private baseURI;

    uint256 public price = 0.1 ether;

    uint256 public maxPerTx = 15;

    uint256 public maxFreePerWallet = 0;

    uint256 public totalFree = 0;

    uint256 public maxSupply = 3000;

    bool public mintEnabled = false;

    mapping(address => uint256) private _mintedFreeAmount;

    constructor() ERC721A("JPEG Coffee", "JPEG") {
        _safeMint(msg.sender, 150);
        setBaseURI("");
    }

    function mint(uint256 count) external payable {
        uint256 cost = price;
        bool isFree = ((totalSupply() + count < totalFree + 1) &&
            (_mintedFreeAmount[msg.sender] + count <= maxFreePerWallet));

        if (isFree) {
            cost = 0;
        }

        require(msg.value >= count * cost, "Please send the exact amount.");
        require(totalSupply() + count < maxSupply + 1, "No more");
        require(mintEnabled, "Minting is not live yet");
        require(count < maxPerTx + 1, "Max per TX reached.");

        if (isFree) {
            _mintedFreeAmount[msg.sender] += count;
        }

        _safeMint(msg.sender, count);
    }

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

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
    {
        require(
            _exists(tokenId),
            "ERC721Metadata: URI query for nonexistent token"
        );
        return string(abi.encodePacked(baseURI, tokenId.toString(), ".json"));
    }

    function setBaseURI(string memory uri) public onlyOwner {
        baseURI = uri;
    }

    function setFreeAmount(uint256 amount) external onlyOwner {
        totalFree = amount;
    }

    function setPrice(uint256 _newPrice) external onlyOwner {
        price = _newPrice;
    }
    function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
        public
        override
        onlyAllowedOperator
    {
        super.safeTransferFrom(from, to, tokenId, data);
    }


    function flipSale() external onlyOwner {
        mintEnabled = !mintEnabled;
    }

    function withdraw() external onlyOwner {
        (bool success, ) = payable(msg.sender).call{
            value: address(this).balance
        }("");
        require(success, "Transfer failed.");
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","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":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"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":"flipSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"maxFreePerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","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":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setFreeAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFree","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":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405267016345785d8a0000600a55600f600b556000600c556000600d55610bb8600e556000600f60006101000a81548160ff0219169083151502179055503480156200004d57600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600b81526020017f4a50454720436f666665650000000000000000000000000000000000000000008152506040518060400160405280600481526020017f4a504547000000000000000000000000000000000000000000000000000000008152508160029080519060200190620000e9929190620009a5565b50806003908051906020019062000102929190620009a5565b50620001136200036b60201b60201c565b60008190555050506200013b6200012f6200037060201b60201c565b6200037860201b60201c565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111562000330578015620001f6576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620001bc92919062000a9a565b600060405180830381600087803b158015620001d757600080fd5b505af1158015620001ec573d6000803e3d6000fd5b505050506200032f565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620002b0576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b81526004016200027692919062000a9a565b600060405180830381600087803b1580156200029157600080fd5b505af1158015620002a6573d6000803e3d6000fd5b505050506200032e565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620002f9919062000ac7565b600060405180830381600087803b1580156200031457600080fd5b505af115801562000329573d6000803e3d6000fd5b505050505b5b5b5050620003453360966200043e60201b60201c565b62000365604051806020016040528060008152506200046460201b60201c565b62000d72565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620004608282604051806020016040528060008152506200050f60201b60201c565b5050565b620004746200037060201b60201c565b73ffffffffffffffffffffffffffffffffffffffff166200049a620007f260201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1614620004f3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004ea9062000b45565b60405180910390fd5b80600990805190602001906200050b929190620009a5565b5050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036200057c576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008303620005b7576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b620005cc60008583866200081c60201b60201c565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e162000639600185146200082260201b60201c565b901b60a042901b62000651866200082c60201b60201c565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b1462000762575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46200070e60008784806001019550876200083660201b60201c565b62000745576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808210620006975782600054146200075c57600080fd5b620007ce565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a480821062000763575b816000819055505050620007ec60008583866200099760201b60201c565b50505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b50505050565b6000819050919050565b6000819050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a02620008646200099d60201b60201c565b8786866040518563ffffffff1660e01b815260040162000888949392919062000c26565b6020604051808303816000875af1925050508015620008c757506040513d601f19601f82011682018060405250810190620008c4919062000cdc565b60015b62000944573d8060008114620008fa576040519150601f19603f3d011682016040523d82523d6000602084013e620008ff565b606091505b5060008151036200093c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b50505050565b600033905090565b828054620009b39062000d3d565b90600052602060002090601f016020900481019282620009d7576000855562000a23565b82601f10620009f257805160ff191683800117855562000a23565b8280016001018555821562000a23579182015b8281111562000a2257825182559160200191906001019062000a05565b5b50905062000a32919062000a36565b5090565b5b8082111562000a5157600081600090555060010162000a37565b5090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000a828262000a55565b9050919050565b62000a948162000a75565b82525050565b600060408201905062000ab1600083018562000a89565b62000ac0602083018462000a89565b9392505050565b600060208201905062000ade600083018462000a89565b92915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600062000b2d60208362000ae4565b915062000b3a8262000af5565b602082019050919050565b6000602082019050818103600083015262000b608162000b1e565b9050919050565b6000819050919050565b62000b7c8162000b67565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101562000bbe57808201518184015260208101905062000ba1565b8381111562000bce576000848401525b50505050565b6000601f19601f8301169050919050565b600062000bf28262000b82565b62000bfe818562000b8d565b935062000c1081856020860162000b9e565b62000c1b8162000bd4565b840191505092915050565b600060808201905062000c3d600083018762000a89565b62000c4c602083018662000a89565b62000c5b604083018562000b71565b818103606083015262000c6f818462000be5565b905095945050505050565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b62000cb68162000c7f565b811462000cc257600080fd5b50565b60008151905062000cd68162000cab565b92915050565b60006020828403121562000cf55762000cf462000c7a565b5b600062000d058482850162000cc5565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062000d5657607f821691505b60208210810362000d6c5762000d6b62000d0e565b5b50919050565b6135338062000d826000396000f3fe6080604052600436106101c25760003560e01c80638da5cb5b116100f7578063a702735711610095578063d5abeb0111610064578063d5abeb01146105f9578063e985e9c514610624578063f2fde38b14610661578063f968adbe1461068a576101c2565b8063a70273571461053d578063b88d4fde14610568578063c87b56dd14610591578063d1239730146105ce576101c2565b806395d89b41116100d157806395d89b41146104a2578063a035b1fe146104cd578063a0712d68146104f8578063a22cb46514610514576101c2565b80638da5cb5b1461042557806391b7f5ed1461045057806392910eec14610479576101c2565b80633ccfd60b116101645780636352211e1161013e5780636352211e1461037d57806370a08231146103ba578063715018a6146103f75780637ba5e6211461040e576101c2565b80633ccfd60b1461031457806342842e0e1461032b57806355f804b314610354576101c2565b8063095ea7b3116101a0578063095ea7b31461026c57806318160ddd1461029557806323b872dd146102c0578063333e44e6146102e9576101c2565b806301ffc9a7146101c757806306fdde0314610204578063081812fc1461022f575b600080fd5b3480156101d357600080fd5b506101ee60048036038101906101e991906125b6565b6106b5565b6040516101fb91906125fe565b60405180910390f35b34801561021057600080fd5b50610219610747565b60405161022691906126b2565b60405180910390f35b34801561023b57600080fd5b506102566004803603810190610251919061270a565b6107d9565b6040516102639190612778565b60405180910390f35b34801561027857600080fd5b50610293600480360381019061028e91906127bf565b610855565b005b3480156102a157600080fd5b506102aa6109fb565b6040516102b7919061280e565b60405180910390f35b3480156102cc57600080fd5b506102e760048036038101906102e29190612829565b610a12565b005b3480156102f557600080fd5b506102fe610b1e565b60405161030b919061280e565b60405180910390f35b34801561032057600080fd5b50610329610b24565b005b34801561033757600080fd5b50610352600480360381019061034d9190612829565b610c4f565b005b34801561036057600080fd5b5061037b600480360381019061037691906129b1565b610d5b565b005b34801561038957600080fd5b506103a4600480360381019061039f919061270a565b610df1565b6040516103b19190612778565b60405180910390f35b3480156103c657600080fd5b506103e160048036038101906103dc91906129fa565b610e03565b6040516103ee919061280e565b60405180910390f35b34801561040357600080fd5b5061040c610ebb565b005b34801561041a57600080fd5b50610423610f43565b005b34801561043157600080fd5b5061043a610feb565b6040516104479190612778565b60405180910390f35b34801561045c57600080fd5b506104776004803603810190610472919061270a565b611015565b005b34801561048557600080fd5b506104a0600480360381019061049b919061270a565b61109b565b005b3480156104ae57600080fd5b506104b7611121565b6040516104c491906126b2565b60405180910390f35b3480156104d957600080fd5b506104e26111b3565b6040516104ef919061280e565b60405180910390f35b610512600480360381019061050d919061270a565b6111b9565b005b34801561052057600080fd5b5061053b60048036038101906105369190612a53565b611405565b005b34801561054957600080fd5b5061055261157c565b60405161055f919061280e565b60405180910390f35b34801561057457600080fd5b5061058f600480360381019061058a9190612b34565b611582565b005b34801561059d57600080fd5b506105b860048036038101906105b3919061270a565b611690565b6040516105c591906126b2565b60405180910390f35b3480156105da57600080fd5b506105e361170c565b6040516105f091906125fe565b60405180910390f35b34801561060557600080fd5b5061060e61171f565b60405161061b919061280e565b60405180910390f35b34801561063057600080fd5b5061064b60048036038101906106469190612bb7565b611725565b60405161065891906125fe565b60405180910390f35b34801561066d57600080fd5b50610688600480360381019061068391906129fa565b6117b9565b005b34801561069657600080fd5b5061069f6118b0565b6040516106ac919061280e565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061071057506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107405750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461075690612c26565b80601f016020809104026020016040519081016040528092919081815260200182805461078290612c26565b80156107cf5780601f106107a4576101008083540402835291602001916107cf565b820191906000526020600020905b8154815290600101906020018083116107b257829003601f168201915b5050505050905090565b60006107e4826118b6565b61081a576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061086082611915565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036108c7576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108e66119e1565b73ffffffffffffffffffffffffffffffffffffffff1614610949576109128161090d6119e1565b611725565b610948576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610a056119e9565b6001546000540303905090565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610b0e576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610a89929190612c57565b6020604051808303816000875af1158015610aa8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acc9190612c95565b610b0d57336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610b049190612778565b60405180910390fd5b5b610b198383836119ee565b505050565b600d5481565b610b2c6119fe565b73ffffffffffffffffffffffffffffffffffffffff16610b4a610feb565b73ffffffffffffffffffffffffffffffffffffffff1614610ba0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9790612d0e565b60405180910390fd5b60003373ffffffffffffffffffffffffffffffffffffffff1647604051610bc690612d5f565b60006040518083038185875af1925050503d8060008114610c03576040519150601f19603f3d011682016040523d82523d6000602084013e610c08565b606091505b5050905080610c4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4390612dc0565b60405180910390fd5b50565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610d4b576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610cc6929190612c57565b6020604051808303816000875af1158015610ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d099190612c95565b610d4a57336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610d419190612778565b60405180910390fd5b5b610d56838383611a06565b505050565b610d636119fe565b73ffffffffffffffffffffffffffffffffffffffff16610d81610feb565b73ffffffffffffffffffffffffffffffffffffffff1614610dd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dce90612d0e565b60405180910390fd5b8060099080519060200190610ded9291906124a7565b5050565b6000610dfc82611915565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e6a576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610ec36119fe565b73ffffffffffffffffffffffffffffffffffffffff16610ee1610feb565b73ffffffffffffffffffffffffffffffffffffffff1614610f37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2e90612d0e565b60405180910390fd5b610f416000611a26565b565b610f4b6119fe565b73ffffffffffffffffffffffffffffffffffffffff16610f69610feb565b73ffffffffffffffffffffffffffffffffffffffff1614610fbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb690612d0e565b60405180910390fd5b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61101d6119fe565b73ffffffffffffffffffffffffffffffffffffffff1661103b610feb565b73ffffffffffffffffffffffffffffffffffffffff1614611091576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108890612d0e565b60405180910390fd5b80600a8190555050565b6110a36119fe565b73ffffffffffffffffffffffffffffffffffffffff166110c1610feb565b73ffffffffffffffffffffffffffffffffffffffff1614611117576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110e90612d0e565b60405180910390fd5b80600d8190555050565b60606003805461113090612c26565b80601f016020809104026020016040519081016040528092919081815260200182805461115c90612c26565b80156111a95780601f1061117e576101008083540402835291602001916111a9565b820191906000526020600020905b81548152906001019060200180831161118c57829003601f168201915b5050505050905090565b600a5481565b6000600a54905060006001600d546111d19190612e0f565b836111da6109fb565b6111e49190612e0f565b10801561123d5750600c5483601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461123a9190612e0f565b11155b9050801561124a57600091505b81836112569190612e65565b341015611298576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128f90612f0b565b60405180910390fd5b6001600e546112a79190612e0f565b836112b06109fb565b6112ba9190612e0f565b106112fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112f190612f77565b60405180910390fd5b600f60009054906101000a900460ff16611349576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134090612fe3565b60405180910390fd5b6001600b546113589190612e0f565b8310611399576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113909061304f565b60405180910390fd5b80156113f65782601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113ee9190612e0f565b925050819055505b6114003384611aec565b505050565b61140d6119e1565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611471576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806007600061147e6119e1565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661152b6119e1565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161157091906125fe565b60405180910390a35050565b600c5481565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561167e576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016115f9929190612c57565b6020604051808303816000875af1158015611618573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163c9190612c95565b61167d57336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016116749190612778565b60405180910390fd5b5b61168a84848484611b0a565b50505050565b606061169b826118b6565b6116da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d1906130e1565b60405180910390fd5b60096116e583611b7d565b6040516020016116f692919061321d565b6040516020818303038152906040529050919050565b600f60009054906101000a900460ff1681565b600e5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6117c16119fe565b73ffffffffffffffffffffffffffffffffffffffff166117df610feb565b73ffffffffffffffffffffffffffffffffffffffff1614611835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182c90612d0e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189b906132be565b60405180910390fd5b6118ad81611a26565b50565b600b5481565b6000816118c16119e9565b111580156118d0575060005482105b801561190e575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600080829050806119246119e9565b116119aa576000548110156119a95760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036119a7575b6000810361199d576004600083600190039350838152602001908152602001600020549050611973565b80925050506119dc565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b600090565b6119f9838383611cdd565b505050565b600033905090565b611a2183838360405180602001604052806000815250611582565b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611b06828260405180602001604052806000815250612084565b5050565b611b15848484611cdd565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611b7757611b4084848484612337565b611b76576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b606060008203611bc4576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611cd8565b600082905060005b60008214611bf6578080611bdf906132de565b915050600a82611bef9190613355565b9150611bcc565b60008167ffffffffffffffff811115611c1257611c11612886565b5b6040519080825280601f01601f191660200182016040528015611c445781602001600182028036833780820191505090505b5090505b60008514611cd157600182611c5d9190613386565b9150600a85611c6c91906133ba565b6030611c789190612e0f565b60f81b818381518110611c8e57611c8d6133eb565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85611cca9190613355565b9450611c48565b8093505050505b919050565b6000611ce882611915565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611d4f576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16611d706119e1565b73ffffffffffffffffffffffffffffffffffffffff161480611d9f5750611d9e85611d996119e1565b611725565b5b80611de45750611dad6119e1565b73ffffffffffffffffffffffffffffffffffffffff16611dcc846107d9565b73ffffffffffffffffffffffffffffffffffffffff16145b905080611e1d576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611e83576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e908585856001612487565b6006600084815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b611f8d8661248d565b1717600460008581526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008316036120155760006001840190506000600460008381526020019081526020016000205403612013576000548114612012578260046000838152602001908152602001600020819055505b5b505b828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461207d8585856001612497565b5050505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036120f0576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000830361212a576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121376000858386612487565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e161219c6001851461249d565b901b60a042901b6121ac8661248d565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b146122b0575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46122606000878480600101955087612337565b612296576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082106121f15782600054146122ab57600080fd5b61231b565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082106122b1575b8160008190555050506123316000858386612497565b50505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261235d6119e1565b8786866040518563ffffffff1660e01b815260040161237f949392919061346f565b6020604051808303816000875af19250505080156123bb57506040513d601f19601f820116820180604052508101906123b891906134d0565b60015b612434573d80600081146123eb576040519150601f19603f3d011682016040523d82523d6000602084013e6123f0565b606091505b50600081510361242c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b50505050565b6000819050919050565b50505050565b6000819050919050565b8280546124b390612c26565b90600052602060002090601f0160209004810192826124d5576000855561251c565b82601f106124ee57805160ff191683800117855561251c565b8280016001018555821561251c579182015b8281111561251b578251825591602001919060010190612500565b5b509050612529919061252d565b5090565b5b8082111561254657600081600090555060010161252e565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6125938161255e565b811461259e57600080fd5b50565b6000813590506125b08161258a565b92915050565b6000602082840312156125cc576125cb612554565b5b60006125da848285016125a1565b91505092915050565b60008115159050919050565b6125f8816125e3565b82525050565b600060208201905061261360008301846125ef565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612653578082015181840152602081019050612638565b83811115612662576000848401525b50505050565b6000601f19601f8301169050919050565b600061268482612619565b61268e8185612624565b935061269e818560208601612635565b6126a781612668565b840191505092915050565b600060208201905081810360008301526126cc8184612679565b905092915050565b6000819050919050565b6126e7816126d4565b81146126f257600080fd5b50565b600081359050612704816126de565b92915050565b6000602082840312156127205761271f612554565b5b600061272e848285016126f5565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061276282612737565b9050919050565b61277281612757565b82525050565b600060208201905061278d6000830184612769565b92915050565b61279c81612757565b81146127a757600080fd5b50565b6000813590506127b981612793565b92915050565b600080604083850312156127d6576127d5612554565b5b60006127e4858286016127aa565b92505060206127f5858286016126f5565b9150509250929050565b612808816126d4565b82525050565b600060208201905061282360008301846127ff565b92915050565b60008060006060848603121561284257612841612554565b5b6000612850868287016127aa565b9350506020612861868287016127aa565b9250506040612872868287016126f5565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6128be82612668565b810181811067ffffffffffffffff821117156128dd576128dc612886565b5b80604052505050565b60006128f061254a565b90506128fc82826128b5565b919050565b600067ffffffffffffffff82111561291c5761291b612886565b5b61292582612668565b9050602081019050919050565b82818337600083830152505050565b600061295461294f84612901565b6128e6565b9050828152602081018484840111156129705761296f612881565b5b61297b848285612932565b509392505050565b600082601f8301126129985761299761287c565b5b81356129a8848260208601612941565b91505092915050565b6000602082840312156129c7576129c6612554565b5b600082013567ffffffffffffffff8111156129e5576129e4612559565b5b6129f184828501612983565b91505092915050565b600060208284031215612a1057612a0f612554565b5b6000612a1e848285016127aa565b91505092915050565b612a30816125e3565b8114612a3b57600080fd5b50565b600081359050612a4d81612a27565b92915050565b60008060408385031215612a6a57612a69612554565b5b6000612a78858286016127aa565b9250506020612a8985828601612a3e565b9150509250929050565b600067ffffffffffffffff821115612aae57612aad612886565b5b612ab782612668565b9050602081019050919050565b6000612ad7612ad284612a93565b6128e6565b905082815260208101848484011115612af357612af2612881565b5b612afe848285612932565b509392505050565b600082601f830112612b1b57612b1a61287c565b5b8135612b2b848260208601612ac4565b91505092915050565b60008060008060808587031215612b4e57612b4d612554565b5b6000612b5c878288016127aa565b9450506020612b6d878288016127aa565b9350506040612b7e878288016126f5565b925050606085013567ffffffffffffffff811115612b9f57612b9e612559565b5b612bab87828801612b06565b91505092959194509250565b60008060408385031215612bce57612bcd612554565b5b6000612bdc858286016127aa565b9250506020612bed858286016127aa565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612c3e57607f821691505b602082108103612c5157612c50612bf7565b5b50919050565b6000604082019050612c6c6000830185612769565b612c796020830184612769565b9392505050565b600081519050612c8f81612a27565b92915050565b600060208284031215612cab57612caa612554565b5b6000612cb984828501612c80565b91505092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612cf8602083612624565b9150612d0382612cc2565b602082019050919050565b60006020820190508181036000830152612d2781612ceb565b9050919050565b600081905092915050565b50565b6000612d49600083612d2e565b9150612d5482612d39565b600082019050919050565b6000612d6a82612d3c565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b6000612daa601083612624565b9150612db582612d74565b602082019050919050565b60006020820190508181036000830152612dd981612d9d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612e1a826126d4565b9150612e25836126d4565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612e5a57612e59612de0565b5b828201905092915050565b6000612e70826126d4565b9150612e7b836126d4565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612eb457612eb3612de0565b5b828202905092915050565b7f506c656173652073656e642074686520657861637420616d6f756e742e000000600082015250565b6000612ef5601d83612624565b9150612f0082612ebf565b602082019050919050565b60006020820190508181036000830152612f2481612ee8565b9050919050565b7f4e6f206d6f726500000000000000000000000000000000000000000000000000600082015250565b6000612f61600783612624565b9150612f6c82612f2b565b602082019050919050565b60006020820190508181036000830152612f9081612f54565b9050919050565b7f4d696e74696e67206973206e6f74206c69766520796574000000000000000000600082015250565b6000612fcd601783612624565b9150612fd882612f97565b602082019050919050565b60006020820190508181036000830152612ffc81612fc0565b9050919050565b7f4d61782070657220545820726561636865642e00000000000000000000000000600082015250565b6000613039601383612624565b915061304482613003565b602082019050919050565b600060208201905081810360008301526130688161302c565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b60006130cb602f83612624565b91506130d68261306f565b604082019050919050565b600060208201905081810360008301526130fa816130be565b9050919050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461312e81612c26565b6131388186613101565b94506001821660008114613153576001811461316457613197565b60ff19831686528186019350613197565b61316d8561310c565b60005b8381101561318f57815481890152600182019150602081019050613170565b838801955050505b50505092915050565b60006131ab82612619565b6131b58185613101565b93506131c5818560208601612635565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000613207600583613101565b9150613212826131d1565b600582019050919050565b60006132298285613121565b915061323582846131a0565b9150613240826131fa565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006132a8602683612624565b91506132b38261324c565b604082019050919050565b600060208201905081810360008301526132d78161329b565b9050919050565b60006132e9826126d4565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361331b5761331a612de0565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613360826126d4565b915061336b836126d4565b92508261337b5761337a613326565b5b828204905092915050565b6000613391826126d4565b915061339c836126d4565b9250828210156133af576133ae612de0565b5b828203905092915050565b60006133c5826126d4565b91506133d0836126d4565b9250826133e0576133df613326565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b60006134418261341a565b61344b8185613425565b935061345b818560208601612635565b61346481612668565b840191505092915050565b60006080820190506134846000830187612769565b6134916020830186612769565b61349e60408301856127ff565b81810360608301526134b08184613436565b905095945050505050565b6000815190506134ca8161258a565b92915050565b6000602082840312156134e6576134e5612554565b5b60006134f4848285016134bb565b9150509291505056fea2646970667358221220f79522d47a5a3f96b72246aaadac1173fd836ba38f06e5ee130465cef6526ba264736f6c634300080d0033

Deployed Bytecode

0x6080604052600436106101c25760003560e01c80638da5cb5b116100f7578063a702735711610095578063d5abeb0111610064578063d5abeb01146105f9578063e985e9c514610624578063f2fde38b14610661578063f968adbe1461068a576101c2565b8063a70273571461053d578063b88d4fde14610568578063c87b56dd14610591578063d1239730146105ce576101c2565b806395d89b41116100d157806395d89b41146104a2578063a035b1fe146104cd578063a0712d68146104f8578063a22cb46514610514576101c2565b80638da5cb5b1461042557806391b7f5ed1461045057806392910eec14610479576101c2565b80633ccfd60b116101645780636352211e1161013e5780636352211e1461037d57806370a08231146103ba578063715018a6146103f75780637ba5e6211461040e576101c2565b80633ccfd60b1461031457806342842e0e1461032b57806355f804b314610354576101c2565b8063095ea7b3116101a0578063095ea7b31461026c57806318160ddd1461029557806323b872dd146102c0578063333e44e6146102e9576101c2565b806301ffc9a7146101c757806306fdde0314610204578063081812fc1461022f575b600080fd5b3480156101d357600080fd5b506101ee60048036038101906101e991906125b6565b6106b5565b6040516101fb91906125fe565b60405180910390f35b34801561021057600080fd5b50610219610747565b60405161022691906126b2565b60405180910390f35b34801561023b57600080fd5b506102566004803603810190610251919061270a565b6107d9565b6040516102639190612778565b60405180910390f35b34801561027857600080fd5b50610293600480360381019061028e91906127bf565b610855565b005b3480156102a157600080fd5b506102aa6109fb565b6040516102b7919061280e565b60405180910390f35b3480156102cc57600080fd5b506102e760048036038101906102e29190612829565b610a12565b005b3480156102f557600080fd5b506102fe610b1e565b60405161030b919061280e565b60405180910390f35b34801561032057600080fd5b50610329610b24565b005b34801561033757600080fd5b50610352600480360381019061034d9190612829565b610c4f565b005b34801561036057600080fd5b5061037b600480360381019061037691906129b1565b610d5b565b005b34801561038957600080fd5b506103a4600480360381019061039f919061270a565b610df1565b6040516103b19190612778565b60405180910390f35b3480156103c657600080fd5b506103e160048036038101906103dc91906129fa565b610e03565b6040516103ee919061280e565b60405180910390f35b34801561040357600080fd5b5061040c610ebb565b005b34801561041a57600080fd5b50610423610f43565b005b34801561043157600080fd5b5061043a610feb565b6040516104479190612778565b60405180910390f35b34801561045c57600080fd5b506104776004803603810190610472919061270a565b611015565b005b34801561048557600080fd5b506104a0600480360381019061049b919061270a565b61109b565b005b3480156104ae57600080fd5b506104b7611121565b6040516104c491906126b2565b60405180910390f35b3480156104d957600080fd5b506104e26111b3565b6040516104ef919061280e565b60405180910390f35b610512600480360381019061050d919061270a565b6111b9565b005b34801561052057600080fd5b5061053b60048036038101906105369190612a53565b611405565b005b34801561054957600080fd5b5061055261157c565b60405161055f919061280e565b60405180910390f35b34801561057457600080fd5b5061058f600480360381019061058a9190612b34565b611582565b005b34801561059d57600080fd5b506105b860048036038101906105b3919061270a565b611690565b6040516105c591906126b2565b60405180910390f35b3480156105da57600080fd5b506105e361170c565b6040516105f091906125fe565b60405180910390f35b34801561060557600080fd5b5061060e61171f565b60405161061b919061280e565b60405180910390f35b34801561063057600080fd5b5061064b60048036038101906106469190612bb7565b611725565b60405161065891906125fe565b60405180910390f35b34801561066d57600080fd5b50610688600480360381019061068391906129fa565b6117b9565b005b34801561069657600080fd5b5061069f6118b0565b6040516106ac919061280e565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061071057506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806107405750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b60606002805461075690612c26565b80601f016020809104026020016040519081016040528092919081815260200182805461078290612c26565b80156107cf5780601f106107a4576101008083540402835291602001916107cf565b820191906000526020600020905b8154815290600101906020018083116107b257829003601f168201915b5050505050905090565b60006107e4826118b6565b61081a576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061086082611915565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036108c7576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166108e66119e1565b73ffffffffffffffffffffffffffffffffffffffff1614610949576109128161090d6119e1565b611725565b610948576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b6000610a056119e9565b6001546000540303905090565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610b0e576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610a89929190612c57565b6020604051808303816000875af1158015610aa8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610acc9190612c95565b610b0d57336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610b049190612778565b60405180910390fd5b5b610b198383836119ee565b505050565b600d5481565b610b2c6119fe565b73ffffffffffffffffffffffffffffffffffffffff16610b4a610feb565b73ffffffffffffffffffffffffffffffffffffffff1614610ba0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9790612d0e565b60405180910390fd5b60003373ffffffffffffffffffffffffffffffffffffffff1647604051610bc690612d5f565b60006040518083038185875af1925050503d8060008114610c03576040519150601f19603f3d011682016040523d82523d6000602084013e610c08565b606091505b5050905080610c4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c4390612dc0565b60405180910390fd5b50565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610d4b576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610cc6929190612c57565b6020604051808303816000875af1158015610ce5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d099190612c95565b610d4a57336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610d419190612778565b60405180910390fd5b5b610d56838383611a06565b505050565b610d636119fe565b73ffffffffffffffffffffffffffffffffffffffff16610d81610feb565b73ffffffffffffffffffffffffffffffffffffffff1614610dd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dce90612d0e565b60405180910390fd5b8060099080519060200190610ded9291906124a7565b5050565b6000610dfc82611915565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e6a576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b610ec36119fe565b73ffffffffffffffffffffffffffffffffffffffff16610ee1610feb565b73ffffffffffffffffffffffffffffffffffffffff1614610f37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2e90612d0e565b60405180910390fd5b610f416000611a26565b565b610f4b6119fe565b73ffffffffffffffffffffffffffffffffffffffff16610f69610feb565b73ffffffffffffffffffffffffffffffffffffffff1614610fbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fb690612d0e565b60405180910390fd5b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61101d6119fe565b73ffffffffffffffffffffffffffffffffffffffff1661103b610feb565b73ffffffffffffffffffffffffffffffffffffffff1614611091576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161108890612d0e565b60405180910390fd5b80600a8190555050565b6110a36119fe565b73ffffffffffffffffffffffffffffffffffffffff166110c1610feb565b73ffffffffffffffffffffffffffffffffffffffff1614611117576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110e90612d0e565b60405180910390fd5b80600d8190555050565b60606003805461113090612c26565b80601f016020809104026020016040519081016040528092919081815260200182805461115c90612c26565b80156111a95780601f1061117e576101008083540402835291602001916111a9565b820191906000526020600020905b81548152906001019060200180831161118c57829003601f168201915b5050505050905090565b600a5481565b6000600a54905060006001600d546111d19190612e0f565b836111da6109fb565b6111e49190612e0f565b10801561123d5750600c5483601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461123a9190612e0f565b11155b9050801561124a57600091505b81836112569190612e65565b341015611298576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128f90612f0b565b60405180910390fd5b6001600e546112a79190612e0f565b836112b06109fb565b6112ba9190612e0f565b106112fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112f190612f77565b60405180910390fd5b600f60009054906101000a900460ff16611349576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134090612fe3565b60405180910390fd5b6001600b546113589190612e0f565b8310611399576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113909061304f565b60405180910390fd5b80156113f65782601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546113ee9190612e0f565b925050819055505b6114003384611aec565b505050565b61140d6119e1565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611471576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806007600061147e6119e1565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661152b6119e1565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161157091906125fe565b60405180910390a35050565b600c5481565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b111561167e576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b81526004016115f9929190612c57565b6020604051808303816000875af1158015611618573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163c9190612c95565b61167d57336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016116749190612778565b60405180910390fd5b5b61168a84848484611b0a565b50505050565b606061169b826118b6565b6116da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116d1906130e1565b60405180910390fd5b60096116e583611b7d565b6040516020016116f692919061321d565b6040516020818303038152906040529050919050565b600f60009054906101000a900460ff1681565b600e5481565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6117c16119fe565b73ffffffffffffffffffffffffffffffffffffffff166117df610feb565b73ffffffffffffffffffffffffffffffffffffffff1614611835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161182c90612d0e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189b906132be565b60405180910390fd5b6118ad81611a26565b50565b600b5481565b6000816118c16119e9565b111580156118d0575060005482105b801561190e575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600080829050806119246119e9565b116119aa576000548110156119a95760006004600083815260200190815260200160002054905060007c01000000000000000000000000000000000000000000000000000000008216036119a7575b6000810361199d576004600083600190039350838152602001908152602001600020549050611973565b80925050506119dc565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600033905090565b600090565b6119f9838383611cdd565b505050565b600033905090565b611a2183838360405180602001604052806000815250611582565b505050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b611b06828260405180602001604052806000815250612084565b5050565b611b15848484611cdd565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611b7757611b4084848484612337565b611b76576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b606060008203611bc4576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050611cd8565b600082905060005b60008214611bf6578080611bdf906132de565b915050600a82611bef9190613355565b9150611bcc565b60008167ffffffffffffffff811115611c1257611c11612886565b5b6040519080825280601f01601f191660200182016040528015611c445781602001600182028036833780820191505090505b5090505b60008514611cd157600182611c5d9190613386565b9150600a85611c6c91906133ba565b6030611c789190612e0f565b60f81b818381518110611c8e57611c8d6133eb565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85611cca9190613355565b9450611c48565b8093505050505b919050565b6000611ce882611915565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611d4f576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008473ffffffffffffffffffffffffffffffffffffffff16611d706119e1565b73ffffffffffffffffffffffffffffffffffffffff161480611d9f5750611d9e85611d996119e1565b611725565b5b80611de45750611dad6119e1565b73ffffffffffffffffffffffffffffffffffffffff16611dcc846107d9565b73ffffffffffffffffffffffffffffffffffffffff16145b905080611e1d576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611e83576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611e908585856001612487565b6006600084815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154600101919050819055507c020000000000000000000000000000000000000000000000000000000060a042901b611f8d8661248d565b1717600460008581526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008316036120155760006001840190506000600460008381526020019081526020016000205403612013576000548114612012578260046000838152602001908152602001600020819055505b5b505b828473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461207d8585856001612497565b5050505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16036120f0576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000830361212a576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6121376000858386612487565b600160406001901b178302600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555060e161219c6001851461249d565b901b60a042901b6121ac8661248d565b1717600460008381526020019081526020016000208190555060008190506000848201905060008673ffffffffffffffffffffffffffffffffffffffff163b146122b0575b818673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46122606000878480600101955087612337565b612296576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8082106121f15782600054146122ab57600080fd5b61231b565b5b818060010192508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082106122b1575b8160008190555050506123316000858386612497565b50505050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261235d6119e1565b8786866040518563ffffffff1660e01b815260040161237f949392919061346f565b6020604051808303816000875af19250505080156123bb57506040513d601f19601f820116820180604052508101906123b891906134d0565b60015b612434573d80600081146123eb576040519150601f19603f3d011682016040523d82523d6000602084013e6123f0565b606091505b50600081510361242c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b50505050565b6000819050919050565b50505050565b6000819050919050565b8280546124b390612c26565b90600052602060002090601f0160209004810192826124d5576000855561251c565b82601f106124ee57805160ff191683800117855561251c565b8280016001018555821561251c579182015b8281111561251b578251825591602001919060010190612500565b5b509050612529919061252d565b5090565b5b8082111561254657600081600090555060010161252e565b5090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6125938161255e565b811461259e57600080fd5b50565b6000813590506125b08161258a565b92915050565b6000602082840312156125cc576125cb612554565b5b60006125da848285016125a1565b91505092915050565b60008115159050919050565b6125f8816125e3565b82525050565b600060208201905061261360008301846125ef565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612653578082015181840152602081019050612638565b83811115612662576000848401525b50505050565b6000601f19601f8301169050919050565b600061268482612619565b61268e8185612624565b935061269e818560208601612635565b6126a781612668565b840191505092915050565b600060208201905081810360008301526126cc8184612679565b905092915050565b6000819050919050565b6126e7816126d4565b81146126f257600080fd5b50565b600081359050612704816126de565b92915050565b6000602082840312156127205761271f612554565b5b600061272e848285016126f5565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061276282612737565b9050919050565b61277281612757565b82525050565b600060208201905061278d6000830184612769565b92915050565b61279c81612757565b81146127a757600080fd5b50565b6000813590506127b981612793565b92915050565b600080604083850312156127d6576127d5612554565b5b60006127e4858286016127aa565b92505060206127f5858286016126f5565b9150509250929050565b612808816126d4565b82525050565b600060208201905061282360008301846127ff565b92915050565b60008060006060848603121561284257612841612554565b5b6000612850868287016127aa565b9350506020612861868287016127aa565b9250506040612872868287016126f5565b9150509250925092565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6128be82612668565b810181811067ffffffffffffffff821117156128dd576128dc612886565b5b80604052505050565b60006128f061254a565b90506128fc82826128b5565b919050565b600067ffffffffffffffff82111561291c5761291b612886565b5b61292582612668565b9050602081019050919050565b82818337600083830152505050565b600061295461294f84612901565b6128e6565b9050828152602081018484840111156129705761296f612881565b5b61297b848285612932565b509392505050565b600082601f8301126129985761299761287c565b5b81356129a8848260208601612941565b91505092915050565b6000602082840312156129c7576129c6612554565b5b600082013567ffffffffffffffff8111156129e5576129e4612559565b5b6129f184828501612983565b91505092915050565b600060208284031215612a1057612a0f612554565b5b6000612a1e848285016127aa565b91505092915050565b612a30816125e3565b8114612a3b57600080fd5b50565b600081359050612a4d81612a27565b92915050565b60008060408385031215612a6a57612a69612554565b5b6000612a78858286016127aa565b9250506020612a8985828601612a3e565b9150509250929050565b600067ffffffffffffffff821115612aae57612aad612886565b5b612ab782612668565b9050602081019050919050565b6000612ad7612ad284612a93565b6128e6565b905082815260208101848484011115612af357612af2612881565b5b612afe848285612932565b509392505050565b600082601f830112612b1b57612b1a61287c565b5b8135612b2b848260208601612ac4565b91505092915050565b60008060008060808587031215612b4e57612b4d612554565b5b6000612b5c878288016127aa565b9450506020612b6d878288016127aa565b9350506040612b7e878288016126f5565b925050606085013567ffffffffffffffff811115612b9f57612b9e612559565b5b612bab87828801612b06565b91505092959194509250565b60008060408385031215612bce57612bcd612554565b5b6000612bdc858286016127aa565b9250506020612bed858286016127aa565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612c3e57607f821691505b602082108103612c5157612c50612bf7565b5b50919050565b6000604082019050612c6c6000830185612769565b612c796020830184612769565b9392505050565b600081519050612c8f81612a27565b92915050565b600060208284031215612cab57612caa612554565b5b6000612cb984828501612c80565b91505092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000612cf8602083612624565b9150612d0382612cc2565b602082019050919050565b60006020820190508181036000830152612d2781612ceb565b9050919050565b600081905092915050565b50565b6000612d49600083612d2e565b9150612d5482612d39565b600082019050919050565b6000612d6a82612d3c565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b6000612daa601083612624565b9150612db582612d74565b602082019050919050565b60006020820190508181036000830152612dd981612d9d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612e1a826126d4565b9150612e25836126d4565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612e5a57612e59612de0565b5b828201905092915050565b6000612e70826126d4565b9150612e7b836126d4565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612eb457612eb3612de0565b5b828202905092915050565b7f506c656173652073656e642074686520657861637420616d6f756e742e000000600082015250565b6000612ef5601d83612624565b9150612f0082612ebf565b602082019050919050565b60006020820190508181036000830152612f2481612ee8565b9050919050565b7f4e6f206d6f726500000000000000000000000000000000000000000000000000600082015250565b6000612f61600783612624565b9150612f6c82612f2b565b602082019050919050565b60006020820190508181036000830152612f9081612f54565b9050919050565b7f4d696e74696e67206973206e6f74206c69766520796574000000000000000000600082015250565b6000612fcd601783612624565b9150612fd882612f97565b602082019050919050565b60006020820190508181036000830152612ffc81612fc0565b9050919050565b7f4d61782070657220545820726561636865642e00000000000000000000000000600082015250565b6000613039601383612624565b915061304482613003565b602082019050919050565b600060208201905081810360008301526130688161302c565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b60006130cb602f83612624565b91506130d68261306f565b604082019050919050565b600060208201905081810360008301526130fa816130be565b9050919050565b600081905092915050565b60008190508160005260206000209050919050565b6000815461312e81612c26565b6131388186613101565b94506001821660008114613153576001811461316457613197565b60ff19831686528186019350613197565b61316d8561310c565b60005b8381101561318f57815481890152600182019150602081019050613170565b838801955050505b50505092915050565b60006131ab82612619565b6131b58185613101565b93506131c5818560208601612635565b80840191505092915050565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000600082015250565b6000613207600583613101565b9150613212826131d1565b600582019050919050565b60006132298285613121565b915061323582846131a0565b9150613240826131fa565b91508190509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b60006132a8602683612624565b91506132b38261324c565b604082019050919050565b600060208201905081810360008301526132d78161329b565b9050919050565b60006132e9826126d4565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361331b5761331a612de0565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613360826126d4565b915061336b836126d4565b92508261337b5761337a613326565b5b828204905092915050565b6000613391826126d4565b915061339c836126d4565b9250828210156133af576133ae612de0565b5b828203905092915050565b60006133c5826126d4565b91506133d0836126d4565b9250826133e0576133df613326565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600081519050919050565b600082825260208201905092915050565b60006134418261341a565b61344b8185613425565b935061345b818560208601612635565b61346481612668565b840191505092915050565b60006080820190506134846000830187612769565b6134916020830186612769565b61349e60408301856127ff565b81810360608301526134b08184613436565b905095945050505050565b6000815190506134ca8161258a565b92915050565b6000602082840312156134e6576134e5612554565b5b60006134f4848285016134bb565b9150509291505056fea2646970667358221220f79522d47a5a3f96b72246aaadac1173fd836ba38f06e5ee130465cef6526ba264736f6c634300080d0033

Deployed Bytecode Sourcemap

94237:2891:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30792:615;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35805:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37873:204;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37333:474;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;29846:315;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96257:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94491:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96919:206;;;;;;;;;;;;;:::i;:::-;;96422:165;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95960:88;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35594:144;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31471:224;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61313:103;;;;;;;;;;;;;:::i;:::-;;96827:84;;;;;;;;;;;;;:::i;:::-;;60662:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96159:92;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;96056:95;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;35974:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94369:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94793:685;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;38149:308;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94447:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96595:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95602:350;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94568:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94528;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38528:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61571:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94410:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30792:615;30877:4;31192:10;31177:25;;:11;:25;;;;:102;;;;31269:10;31254:25;;:11;:25;;;;31177:102;:179;;;;31346:10;31331:25;;:11;:25;;;;31177:179;31157:199;;30792:615;;;:::o;35805:100::-;35859:13;35892:5;35885:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35805:100;:::o;37873:204::-;37941:7;37966:16;37974:7;37966;:16::i;:::-;37961:64;;37991:34;;;;;;;;;;;;;;37961:64;38045:15;:24;38061:7;38045:24;;;;;;;;;;;;;;;;;;;;;38038:31;;37873:204;;;:::o;37333:474::-;37406:13;37438:27;37457:7;37438:18;:27::i;:::-;37406:61;;37488:5;37482:11;;:2;:11;;;37478:48;;37502:24;;;;;;;;;;;;;;37478:48;37566:5;37543:28;;:19;:17;:19::i;:::-;:28;;;37539:175;;37591:44;37608:5;37615:19;:17;:19::i;:::-;37591:16;:44::i;:::-;37586:128;;37663:35;;;;;;;;;;;;;;37586:128;37539:175;37753:2;37726:15;:24;37742:7;37726:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;37791:7;37787:2;37771:28;;37780:5;37771:28;;;;;;;;;;;;37395:412;37333:474;;:::o;29846:315::-;29899:7;30127:15;:13;:15::i;:::-;30112:12;;30096:13;;:28;:46;30089:53;;29846:315;:::o;96257:157::-;17002:1;15828:42;16956:43;;;:47;16952:225;;;15828:42;17025:40;;;17074:4;17081:10;17025:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17020:146;;17139:10;17120:30;;;;;;;;;;;:::i;:::-;;;;;;;;17020:146;16952:225;96369:37:::1;96388:4;96394:2;96398:7;96369:18;:37::i;:::-;96257:157:::0;;;:::o;94491:28::-;;;;:::o;96919:206::-;60893:12;:10;:12::i;:::-;60882:23;;:7;:5;:7::i;:::-;:23;;;60874:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96970:12:::1;96996:10;96988:24;;97034:21;96988:82;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96969:101;;;97089:7;97081:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;96958:167;96919:206::o:0;96422:165::-;17002:1;15828:42;16956:43;;;:47;16952:225;;;15828:42;17025:40;;;17074:4;17081:10;17025:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17020:146;;17139:10;17120:30;;;;;;;;;;;:::i;:::-;;;;;;;;17020:146;16952:225;96538:41:::1;96561:4;96567:2;96571:7;96538:22;:41::i;:::-;96422:165:::0;;;:::o;95960:88::-;60893:12;:10;:12::i;:::-;60882:23;;:7;:5;:7::i;:::-;:23;;;60874:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96037:3:::1;96027:7;:13;;;;;;;;;;;;:::i;:::-;;95960:88:::0;:::o;35594:144::-;35658:7;35701:27;35720:7;35701:18;:27::i;:::-;35678:52;;35594:144;;;:::o;31471:224::-;31535:7;31576:1;31559:19;;:5;:19;;;31555:60;;31587:28;;;;;;;;;;;;;;31555:60;26810:13;31633:18;:25;31652:5;31633:25;;;;;;;;;;;;;;;;:54;31626:61;;31471:224;;;:::o;61313:103::-;60893:12;:10;:12::i;:::-;60882:23;;:7;:5;:7::i;:::-;:23;;;60874:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;61378:30:::1;61405:1;61378:18;:30::i;:::-;61313:103::o:0;96827:84::-;60893:12;:10;:12::i;:::-;60882:23;;:7;:5;:7::i;:::-;:23;;;60874:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96892:11:::1;;;;;;;;;;;96891:12;96877:11;;:26;;;;;;;;;;;;;;;;;;96827:84::o:0;60662:87::-;60708:7;60735:6;;;;;;;;;;;60728:13;;60662:87;:::o;96159:92::-;60893:12;:10;:12::i;:::-;60882:23;;:7;:5;:7::i;:::-;:23;;;60874:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96234:9:::1;96226:5;:17;;;;96159:92:::0;:::o;96056:95::-;60893:12;:10;:12::i;:::-;60882:23;;:7;:5;:7::i;:::-;:23;;;60874:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;96137:6:::1;96125:9;:18;;;;96056:95:::0;:::o;35974:104::-;36030:13;36063:7;36056:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35974:104;:::o;94369:32::-;;;;:::o;94793:685::-;94850:12;94865:5;;94850:20;;94881:11;94933:1;94921:9;;:13;;;;:::i;:::-;94913:5;94897:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:37;94896:115;;;;;94994:16;;94985:5;94953:17;:29;94971:10;94953:29;;;;;;;;;;;;;;;;:37;;;;:::i;:::-;:57;;94896:115;94881:131;;95029:6;95025:47;;;95059:1;95052:8;;95025:47;95113:4;95105:5;:12;;;;:::i;:::-;95092:9;:25;;95084:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;95206:1;95194:9;;:13;;;;:::i;:::-;95186:5;95170:13;:11;:13::i;:::-;:21;;;;:::i;:::-;:37;95162:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;95238:11;;;;;;;;;;;95230:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;95315:1;95304:8;;:12;;;;:::i;:::-;95296:5;:20;95288:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;95357:6;95353:77;;;95413:5;95380:17;:29;95398:10;95380:29;;;;;;;;;;;;;;;;:38;;;;;;;:::i;:::-;;;;;;;;95353:77;95442:28;95452:10;95464:5;95442:9;:28::i;:::-;94839:639;;94793:685;:::o;38149:308::-;38260:19;:17;:19::i;:::-;38248:31;;:8;:31;;;38244:61;;38288:17;;;;;;;;;;;;;;38244:61;38370:8;38318:18;:39;38337:19;:17;:19::i;:::-;38318:39;;;;;;;;;;;;;;;:49;38358:8;38318:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;38430:8;38394:55;;38409:19;:17;:19::i;:::-;38394:55;;;38440:8;38394:55;;;;;;:::i;:::-;;;;;;;;38149:308;;:::o;94447:35::-;;;;:::o;96595:222::-;17002:1;15828:42;16956:43;;;:47;16952:225;;;15828:42;17025:40;;;17074:4;17081:10;17025:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17020:146;;17139:10;17120:30;;;;;;;;;;;:::i;:::-;;;;;;;;17020:146;16952:225;96762:47:::1;96785:4;96791:2;96795:7;96804:4;96762:22;:47::i;:::-;96595:222:::0;;;;:::o;95602:350::-;95720:13;95773:16;95781:7;95773;:16::i;:::-;95751:113;;;;;;;;;;;;:::i;:::-;;;;;;;;;95906:7;95915:18;:7;:16;:18::i;:::-;95889:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;95875:69;;95602:350;;;:::o;94568:31::-;;;;;;;;;;;;;:::o;94528:::-;;;;:::o;38528:164::-;38625:4;38649:18;:25;38668:5;38649:25;;;;;;;;;;;;;;;:35;38675:8;38649:35;;;;;;;;;;;;;;;;;;;;;;;;;38642:42;;38528:164;;;;:::o;61571:201::-;60893:12;:10;:12::i;:::-;60882:23;;:7;:5;:7::i;:::-;:23;;;60874:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;61680:1:::1;61660:22;;:8;:22;;::::0;61652:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;61736:28;61755:8;61736:18;:28::i;:::-;61571:201:::0;:::o;94410:28::-;;;;:::o;39907:273::-;39964:4;40020:7;40001:15;:13;:15::i;:::-;:26;;:66;;;;;40054:13;;40044:7;:23;40001:66;:152;;;;;40152:1;27580:8;40105:17;:26;40123:7;40105:26;;;;;;;;;;;;:43;:48;40001:152;39981:172;;39907:273;;;:::o;33109:1129::-;33176:7;33196:12;33211:7;33196:22;;33279:4;33260:15;:13;:15::i;:::-;:23;33256:915;;33313:13;;33306:4;:20;33302:869;;;33351:14;33368:17;:23;33386:4;33368:23;;;;;;;;;;;;33351:40;;33484:1;27580:8;33457:6;:23;:28;33453:699;;33976:113;33993:1;33983:6;:11;33976:113;;34036:17;:25;34054:6;;;;;;;34036:25;;;;;;;;;;;;34027:34;;33976:113;;;34122:6;34115:13;;;;;;33453:699;33328:843;33302:869;33256:915;34199:31;;;;;;;;;;;;;;33109:1129;;;;:::o;53889:105::-;53949:7;53976:10;53969:17;;53889:105;:::o;29369:92::-;29425:7;29369:92;:::o;38759:170::-;38893:28;38903:4;38909:2;38913:7;38893:9;:28::i;:::-;38759:170;;;:::o;59333:98::-;59386:7;59413:10;59406:17;;59333:98;:::o;39000:185::-;39138:39;39155:4;39161:2;39165:7;39138:39;;;;;;;;;;;;:16;:39::i;:::-;39000:185;;;:::o;61932:191::-;62006:16;62025:6;;;;;;;;;;;62006:25;;62051:8;62042:6;;:17;;;;;;;;;;;;;;;;;;62106:8;62075:40;;62096:8;62075:40;;;;;;;;;;;;61995:128;61932:191;:::o;40264:104::-;40333:27;40343:2;40347:8;40333:27;;;;;;;;;;;;:9;:27::i;:::-;40264:104;;:::o;39256:396::-;39423:28;39433:4;39439:2;39443:7;39423:9;:28::i;:::-;39484:1;39466:2;:14;;;:19;39462:183;;39505:56;39536:4;39542:2;39546:7;39555:5;39505:30;:56::i;:::-;39500:145;;39589:40;;;;;;;;;;;;;;39500:145;39462:183;39256:396;;;;:::o;56534:723::-;56590:13;56820:1;56811:5;:10;56807:53;;56838:10;;;;;;;;;;;;;;;;;;;;;56807:53;56870:12;56885:5;56870:20;;56901:14;56926:78;56941:1;56933:4;:9;56926:78;;56959:8;;;;;:::i;:::-;;;;56990:2;56982:10;;;;;:::i;:::-;;;56926:78;;;57014:19;57046:6;57036:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57014:39;;57064:154;57080:1;57071:5;:10;57064:154;;57108:1;57098:11;;;;;:::i;:::-;;;57175:2;57167:5;:10;;;;:::i;:::-;57154:2;:24;;;;:::i;:::-;57141:39;;57124:6;57131;57124:14;;;;;;;;:::i;:::-;;;;;:56;;;;;;;;;;;57204:2;57195:11;;;;;:::i;:::-;;;57064:154;;;57242:6;57228:21;;;;;56534:723;;;;:::o;45146:2515::-;45261:27;45291;45310:7;45291:18;:27::i;:::-;45261:57;;45376:4;45335:45;;45351:19;45335:45;;;45331:86;;45389:28;;;;;;;;;;;;;;45331:86;45430:22;45479:4;45456:27;;:19;:17;:19::i;:::-;:27;;;:87;;;;45500:43;45517:4;45523:19;:17;:19::i;:::-;45500:16;:43::i;:::-;45456:87;:147;;;;45584:19;:17;:19::i;:::-;45560:43;;:20;45572:7;45560:11;:20::i;:::-;:43;;;45456:147;45430:174;;45622:17;45617:66;;45648:35;;;;;;;;;;;;;;45617:66;45712:1;45698:16;;:2;:16;;;45694:52;;45723:23;;;;;;;;;;;;;;45694:52;45759:43;45781:4;45787:2;45791:7;45800:1;45759:21;:43::i;:::-;45875:15;:24;45891:7;45875:24;;;;;;;;;;;;45868:31;;;;;;;;;;;46267:18;:24;46286:4;46267:24;;;;;;;;;;;;;;;;46265:26;;;;;;;;;;;;46336:18;:22;46355:2;46336:22;;;;;;;;;;;;;;;;46334:24;;;;;;;;;;;27862:8;27464:3;46717:15;:41;;46675:21;46693:2;46675:17;:21::i;:::-;:84;:128;46629:17;:26;46647:7;46629:26;;;;;;;;;;;:174;;;;46973:1;27862:8;46923:19;:46;:51;46919:626;;46995:19;47027:1;47017:7;:11;46995:33;;47184:1;47150:17;:30;47168:11;47150:30;;;;;;;;;;;;:35;47146:384;;47288:13;;47273:11;:28;47269:242;;47468:19;47435:17;:30;47453:11;47435:30;;;;;;;;;;;:52;;;;47269:242;47146:384;46976:569;46919:626;47592:7;47588:2;47573:27;;47582:4;47573:27;;;;;;;;;;;;47611:42;47632:4;47638:2;47642:7;47651:1;47611:20;:42::i;:::-;45250:2411;;45146:2515;;;:::o;40741:2236::-;40864:20;40887:13;;40864:36;;40929:1;40915:16;;:2;:16;;;40911:48;;40940:19;;;;;;;;;;;;;;40911:48;40986:1;40974:8;:13;40970:44;;40996:18;;;;;;;;;;;;;;40970:44;41027:61;41057:1;41061:2;41065:12;41079:8;41027:21;:61::i;:::-;41631:1;26947:2;41602:1;:25;;41601:31;41589:8;:44;41563:18;:22;41582:2;41563:22;;;;;;;;;;;;;;;;:70;;;;;;;;;;;27727:3;42032:29;42059:1;42047:8;:13;42032:14;:29::i;:::-;:56;;27464:3;41969:15;:41;;41927:21;41945:2;41927:17;:21::i;:::-;:84;:162;41876:17;:31;41894:12;41876:31;;;;;;;;;;;:213;;;;42106:20;42129:12;42106:35;;42156:11;42185:8;42170:12;:23;42156:37;;42232:1;42214:2;:14;;;:19;42210:635;;42254:313;42310:12;42306:2;42285:38;;42302:1;42285:38;;;;;;;;;;;;42351:69;42390:1;42394:2;42398:14;;;;;;42414:5;42351:30;:69::i;:::-;42346:174;;42456:40;;;;;;;;;;;;;;42346:174;42562:3;42547:12;:18;42254:313;;42648:12;42631:13;;:29;42627:43;;42662:8;;;42627:43;42210:635;;;42711:119;42767:14;;;;;;42763:2;42742:40;;42759:1;42742:40;;;;;;;;;;;;42825:3;42810:12;:18;42711:119;;42210:635;42875:12;42859:13;:28;;;;41340:1559;;42909:60;42938:1;42942:2;42946:12;42960:8;42909:20;:60::i;:::-;40853:2124;40741:2236;;;:::o;51358:716::-;51521:4;51567:2;51542:45;;;51588:19;:17;:19::i;:::-;51609:4;51615:7;51624:5;51542:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;51538:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51842:1;51825:6;:13;:18;51821:235;;51871:40;;;;;;;;;;;;;;51821:235;52014:6;52008:13;51999:6;51995:2;51991:15;51984:38;51538:529;51711:54;;;51701:64;;;:6;:64;;;;51694:71;;;51358:716;;;;;;:::o;52722:159::-;;;;;:::o;36894:148::-;36958:14;37019:5;37009:15;;36894:148;;;:::o;53540:158::-;;;;;:::o;37129:142::-;37187:14;37248:5;37238:15;;37129:142;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:307::-;1866:1;1876:113;1890:6;1887:1;1884:13;1876:113;;;1975:1;1970:3;1966:11;1960:18;1956:1;1951:3;1947:11;1940:39;1912:2;1909:1;1905:10;1900:15;;1876:113;;;2007:6;2004:1;2001:13;1998:101;;;2087:1;2078:6;2073:3;2069:16;2062:27;1998:101;1847:258;1798:307;;;:::o;2111:102::-;2152:6;2203:2;2199:7;2194:2;2187:5;2183:14;2179:28;2169:38;;2111:102;;;:::o;2219:364::-;2307:3;2335:39;2368:5;2335:39;:::i;:::-;2390:71;2454:6;2449:3;2390:71;:::i;:::-;2383:78;;2470:52;2515:6;2510:3;2503:4;2496:5;2492:16;2470:52;:::i;:::-;2547:29;2569:6;2547:29;:::i;:::-;2542:3;2538:39;2531:46;;2311:272;2219:364;;;;:::o;2589:313::-;2702:4;2740:2;2729:9;2725:18;2717:26;;2789:9;2783:4;2779:20;2775:1;2764:9;2760:17;2753:47;2817:78;2890:4;2881:6;2817:78;:::i;:::-;2809:86;;2589:313;;;;:::o;2908:77::-;2945:7;2974:5;2963:16;;2908:77;;;:::o;2991:122::-;3064:24;3082:5;3064:24;:::i;:::-;3057:5;3054:35;3044:63;;3103:1;3100;3093:12;3044:63;2991:122;:::o;3119:139::-;3165:5;3203:6;3190:20;3181:29;;3219:33;3246:5;3219:33;:::i;:::-;3119:139;;;;:::o;3264:329::-;3323:6;3372:2;3360:9;3351:7;3347:23;3343:32;3340:119;;;3378:79;;:::i;:::-;3340:119;3498:1;3523:53;3568:7;3559:6;3548:9;3544:22;3523:53;:::i;:::-;3513:63;;3469:117;3264:329;;;;:::o;3599:126::-;3636:7;3676:42;3669:5;3665:54;3654:65;;3599:126;;;:::o;3731:96::-;3768:7;3797:24;3815:5;3797:24;:::i;:::-;3786:35;;3731:96;;;:::o;3833:118::-;3920:24;3938:5;3920:24;:::i;:::-;3915:3;3908:37;3833:118;;:::o;3957:222::-;4050:4;4088:2;4077:9;4073:18;4065:26;;4101:71;4169:1;4158:9;4154:17;4145:6;4101:71;:::i;:::-;3957:222;;;;:::o;4185:122::-;4258:24;4276:5;4258:24;:::i;:::-;4251:5;4248:35;4238:63;;4297:1;4294;4287:12;4238:63;4185:122;:::o;4313:139::-;4359:5;4397:6;4384:20;4375:29;;4413:33;4440:5;4413:33;:::i;:::-;4313:139;;;;:::o;4458:474::-;4526:6;4534;4583:2;4571:9;4562:7;4558:23;4554:32;4551:119;;;4589:79;;:::i;:::-;4551:119;4709:1;4734:53;4779:7;4770:6;4759:9;4755:22;4734:53;:::i;:::-;4724:63;;4680:117;4836:2;4862:53;4907:7;4898:6;4887:9;4883:22;4862:53;:::i;:::-;4852:63;;4807:118;4458:474;;;;;:::o;4938:118::-;5025:24;5043:5;5025:24;:::i;:::-;5020:3;5013:37;4938:118;;:::o;5062:222::-;5155:4;5193:2;5182:9;5178:18;5170:26;;5206:71;5274:1;5263:9;5259:17;5250:6;5206:71;:::i;:::-;5062:222;;;;:::o;5290:619::-;5367:6;5375;5383;5432:2;5420:9;5411:7;5407:23;5403:32;5400:119;;;5438:79;;:::i;:::-;5400:119;5558:1;5583:53;5628:7;5619:6;5608:9;5604:22;5583:53;:::i;:::-;5573:63;;5529:117;5685:2;5711:53;5756:7;5747:6;5736:9;5732:22;5711:53;:::i;:::-;5701:63;;5656:118;5813:2;5839:53;5884:7;5875:6;5864:9;5860:22;5839:53;:::i;:::-;5829:63;;5784:118;5290:619;;;;;:::o;5915:117::-;6024:1;6021;6014:12;6038:117;6147:1;6144;6137:12;6161:180;6209:77;6206:1;6199:88;6306:4;6303:1;6296:15;6330:4;6327:1;6320:15;6347:281;6430:27;6452:4;6430:27;:::i;:::-;6422:6;6418:40;6560:6;6548:10;6545:22;6524:18;6512:10;6509:34;6506:62;6503:88;;;6571:18;;:::i;:::-;6503:88;6611:10;6607:2;6600:22;6390:238;6347:281;;:::o;6634:129::-;6668:6;6695:20;;:::i;:::-;6685:30;;6724:33;6752:4;6744:6;6724:33;:::i;:::-;6634:129;;;:::o;6769:308::-;6831:4;6921:18;6913:6;6910:30;6907:56;;;6943:18;;:::i;:::-;6907:56;6981:29;7003:6;6981:29;:::i;:::-;6973:37;;7065:4;7059;7055:15;7047:23;;6769:308;;;:::o;7083:154::-;7167:6;7162:3;7157;7144:30;7229:1;7220:6;7215:3;7211:16;7204:27;7083:154;;;:::o;7243:412::-;7321:5;7346:66;7362:49;7404:6;7362:49;:::i;:::-;7346:66;:::i;:::-;7337:75;;7435:6;7428:5;7421:21;7473:4;7466:5;7462:16;7511:3;7502:6;7497:3;7493:16;7490:25;7487:112;;;7518:79;;:::i;:::-;7487:112;7608:41;7642:6;7637:3;7632;7608:41;:::i;:::-;7327:328;7243:412;;;;;:::o;7675:340::-;7731:5;7780:3;7773:4;7765:6;7761:17;7757:27;7747:122;;7788:79;;:::i;:::-;7747:122;7905:6;7892:20;7930:79;8005:3;7997:6;7990:4;7982:6;7978:17;7930:79;:::i;:::-;7921:88;;7737:278;7675:340;;;;:::o;8021:509::-;8090:6;8139:2;8127:9;8118:7;8114:23;8110:32;8107:119;;;8145:79;;:::i;:::-;8107:119;8293:1;8282:9;8278:17;8265:31;8323:18;8315:6;8312:30;8309:117;;;8345:79;;:::i;:::-;8309:117;8450:63;8505:7;8496:6;8485:9;8481:22;8450:63;:::i;:::-;8440:73;;8236:287;8021:509;;;;:::o;8536:329::-;8595:6;8644:2;8632:9;8623:7;8619:23;8615:32;8612:119;;;8650:79;;:::i;:::-;8612:119;8770:1;8795:53;8840:7;8831:6;8820:9;8816:22;8795:53;:::i;:::-;8785:63;;8741:117;8536:329;;;;:::o;8871:116::-;8941:21;8956:5;8941:21;:::i;:::-;8934:5;8931:32;8921:60;;8977:1;8974;8967:12;8921:60;8871:116;:::o;8993:133::-;9036:5;9074:6;9061:20;9052:29;;9090:30;9114:5;9090:30;:::i;:::-;8993:133;;;;:::o;9132:468::-;9197:6;9205;9254:2;9242:9;9233:7;9229:23;9225:32;9222:119;;;9260:79;;:::i;:::-;9222:119;9380:1;9405:53;9450:7;9441:6;9430:9;9426:22;9405:53;:::i;:::-;9395:63;;9351:117;9507:2;9533:50;9575:7;9566:6;9555:9;9551:22;9533:50;:::i;:::-;9523:60;;9478:115;9132:468;;;;;:::o;9606:307::-;9667:4;9757:18;9749:6;9746:30;9743:56;;;9779:18;;:::i;:::-;9743:56;9817:29;9839:6;9817:29;:::i;:::-;9809:37;;9901:4;9895;9891:15;9883:23;;9606:307;;;:::o;9919:410::-;9996:5;10021:65;10037:48;10078:6;10037:48;:::i;:::-;10021:65;:::i;:::-;10012:74;;10109:6;10102:5;10095:21;10147:4;10140:5;10136:16;10185:3;10176:6;10171:3;10167:16;10164:25;10161:112;;;10192:79;;:::i;:::-;10161:112;10282:41;10316:6;10311:3;10306;10282:41;:::i;:::-;10002:327;9919:410;;;;;:::o;10348:338::-;10403:5;10452:3;10445:4;10437:6;10433:17;10429:27;10419:122;;10460:79;;:::i;:::-;10419:122;10577:6;10564:20;10602:78;10676:3;10668:6;10661:4;10653:6;10649:17;10602:78;:::i;:::-;10593:87;;10409:277;10348:338;;;;:::o;10692:943::-;10787:6;10795;10803;10811;10860:3;10848:9;10839:7;10835:23;10831:33;10828:120;;;10867:79;;:::i;:::-;10828:120;10987:1;11012:53;11057:7;11048:6;11037:9;11033:22;11012:53;:::i;:::-;11002:63;;10958:117;11114:2;11140:53;11185:7;11176:6;11165:9;11161:22;11140:53;:::i;:::-;11130:63;;11085:118;11242:2;11268:53;11313:7;11304:6;11293:9;11289:22;11268:53;:::i;:::-;11258:63;;11213:118;11398:2;11387:9;11383:18;11370:32;11429:18;11421:6;11418:30;11415:117;;;11451:79;;:::i;:::-;11415:117;11556:62;11610:7;11601:6;11590:9;11586:22;11556:62;:::i;:::-;11546:72;;11341:287;10692:943;;;;;;;:::o;11641:474::-;11709:6;11717;11766:2;11754:9;11745:7;11741:23;11737:32;11734:119;;;11772:79;;:::i;:::-;11734:119;11892:1;11917:53;11962:7;11953:6;11942:9;11938:22;11917:53;:::i;:::-;11907:63;;11863:117;12019:2;12045:53;12090:7;12081:6;12070:9;12066:22;12045:53;:::i;:::-;12035:63;;11990:118;11641:474;;;;;:::o;12121:180::-;12169:77;12166:1;12159:88;12266:4;12263:1;12256:15;12290:4;12287:1;12280:15;12307:320;12351:6;12388:1;12382:4;12378:12;12368:22;;12435:1;12429:4;12425:12;12456:18;12446:81;;12512:4;12504:6;12500:17;12490:27;;12446:81;12574:2;12566:6;12563:14;12543:18;12540:38;12537:84;;12593:18;;:::i;:::-;12537:84;12358:269;12307:320;;;:::o;12633:332::-;12754:4;12792:2;12781:9;12777:18;12769:26;;12805:71;12873:1;12862:9;12858:17;12849:6;12805:71;:::i;:::-;12886:72;12954:2;12943:9;12939:18;12930:6;12886:72;:::i;:::-;12633:332;;;;;:::o;12971:137::-;13025:5;13056:6;13050:13;13041:22;;13072:30;13096:5;13072:30;:::i;:::-;12971:137;;;;:::o;13114:345::-;13181:6;13230:2;13218:9;13209:7;13205:23;13201:32;13198:119;;;13236:79;;:::i;:::-;13198:119;13356:1;13381:61;13434:7;13425:6;13414:9;13410:22;13381:61;:::i;:::-;13371:71;;13327:125;13114:345;;;;:::o;13465:182::-;13605:34;13601:1;13593:6;13589:14;13582:58;13465:182;:::o;13653:366::-;13795:3;13816:67;13880:2;13875:3;13816:67;:::i;:::-;13809:74;;13892:93;13981:3;13892:93;:::i;:::-;14010:2;14005:3;14001:12;13994:19;;13653:366;;;:::o;14025:419::-;14191:4;14229:2;14218:9;14214:18;14206:26;;14278:9;14272:4;14268:20;14264:1;14253:9;14249:17;14242:47;14306:131;14432:4;14306:131;:::i;:::-;14298:139;;14025:419;;;:::o;14450:147::-;14551:11;14588:3;14573:18;;14450:147;;;;:::o;14603:114::-;;:::o;14723:398::-;14882:3;14903:83;14984:1;14979:3;14903:83;:::i;:::-;14896:90;;14995:93;15084:3;14995:93;:::i;:::-;15113:1;15108:3;15104:11;15097:18;;14723:398;;;:::o;15127:379::-;15311:3;15333:147;15476:3;15333:147;:::i;:::-;15326:154;;15497:3;15490:10;;15127:379;;;:::o;15512:166::-;15652:18;15648:1;15640:6;15636:14;15629:42;15512:166;:::o;15684:366::-;15826:3;15847:67;15911:2;15906:3;15847:67;:::i;:::-;15840:74;;15923:93;16012:3;15923:93;:::i;:::-;16041:2;16036:3;16032:12;16025:19;;15684:366;;;:::o;16056:419::-;16222:4;16260:2;16249:9;16245:18;16237:26;;16309:9;16303:4;16299:20;16295:1;16284:9;16280:17;16273:47;16337:131;16463:4;16337:131;:::i;:::-;16329:139;;16056:419;;;:::o;16481:180::-;16529:77;16526:1;16519:88;16626:4;16623:1;16616:15;16650:4;16647:1;16640:15;16667:305;16707:3;16726:20;16744:1;16726:20;:::i;:::-;16721:25;;16760:20;16778:1;16760:20;:::i;:::-;16755:25;;16914:1;16846:66;16842:74;16839:1;16836:81;16833:107;;;16920:18;;:::i;:::-;16833:107;16964:1;16961;16957:9;16950:16;;16667:305;;;;:::o;16978:348::-;17018:7;17041:20;17059:1;17041:20;:::i;:::-;17036:25;;17075:20;17093:1;17075:20;:::i;:::-;17070:25;;17263:1;17195:66;17191:74;17188:1;17185:81;17180:1;17173:9;17166:17;17162:105;17159:131;;;17270:18;;:::i;:::-;17159:131;17318:1;17315;17311:9;17300:20;;16978:348;;;;:::o;17332:179::-;17472:31;17468:1;17460:6;17456:14;17449:55;17332:179;:::o;17517:366::-;17659:3;17680:67;17744:2;17739:3;17680:67;:::i;:::-;17673:74;;17756:93;17845:3;17756:93;:::i;:::-;17874:2;17869:3;17865:12;17858:19;;17517:366;;;:::o;17889:419::-;18055:4;18093:2;18082:9;18078:18;18070:26;;18142:9;18136:4;18132:20;18128:1;18117:9;18113:17;18106:47;18170:131;18296:4;18170:131;:::i;:::-;18162:139;;17889:419;;;:::o;18314:157::-;18454:9;18450:1;18442:6;18438:14;18431:33;18314:157;:::o;18477:365::-;18619:3;18640:66;18704:1;18699:3;18640:66;:::i;:::-;18633:73;;18715:93;18804:3;18715:93;:::i;:::-;18833:2;18828:3;18824:12;18817:19;;18477:365;;;:::o;18848:419::-;19014:4;19052:2;19041:9;19037:18;19029:26;;19101:9;19095:4;19091:20;19087:1;19076:9;19072:17;19065:47;19129:131;19255:4;19129:131;:::i;:::-;19121:139;;18848:419;;;:::o;19273:173::-;19413:25;19409:1;19401:6;19397:14;19390:49;19273:173;:::o;19452:366::-;19594:3;19615:67;19679:2;19674:3;19615:67;:::i;:::-;19608:74;;19691:93;19780:3;19691:93;:::i;:::-;19809:2;19804:3;19800:12;19793:19;;19452:366;;;:::o;19824:419::-;19990:4;20028:2;20017:9;20013:18;20005:26;;20077:9;20071:4;20067:20;20063:1;20052:9;20048:17;20041:47;20105:131;20231:4;20105:131;:::i;:::-;20097:139;;19824:419;;;:::o;20249:169::-;20389:21;20385:1;20377:6;20373:14;20366:45;20249:169;:::o;20424:366::-;20566:3;20587:67;20651:2;20646:3;20587:67;:::i;:::-;20580:74;;20663:93;20752:3;20663:93;:::i;:::-;20781:2;20776:3;20772:12;20765:19;;20424:366;;;:::o;20796:419::-;20962:4;21000:2;20989:9;20985:18;20977:26;;21049:9;21043:4;21039:20;21035:1;21024:9;21020:17;21013:47;21077:131;21203:4;21077:131;:::i;:::-;21069:139;;20796:419;;;:::o;21221:234::-;21361:34;21357:1;21349:6;21345:14;21338:58;21430:17;21425:2;21417:6;21413:15;21406:42;21221:234;:::o;21461:366::-;21603:3;21624:67;21688:2;21683:3;21624:67;:::i;:::-;21617:74;;21700:93;21789:3;21700:93;:::i;:::-;21818:2;21813:3;21809:12;21802:19;;21461:366;;;:::o;21833:419::-;21999:4;22037:2;22026:9;22022:18;22014:26;;22086:9;22080:4;22076:20;22072:1;22061:9;22057:17;22050:47;22114:131;22240:4;22114:131;:::i;:::-;22106:139;;21833:419;;;:::o;22258:148::-;22360:11;22397:3;22382:18;;22258:148;;;;:::o;22412:141::-;22461:4;22484:3;22476:11;;22507:3;22504:1;22497:14;22541:4;22538:1;22528:18;22520:26;;22412:141;;;:::o;22583:845::-;22686:3;22723:5;22717:12;22752:36;22778:9;22752:36;:::i;:::-;22804:89;22886:6;22881:3;22804:89;:::i;:::-;22797:96;;22924:1;22913:9;22909:17;22940:1;22935:137;;;;23086:1;23081:341;;;;22902:520;;22935:137;23019:4;23015:9;23004;23000:25;22995:3;22988:38;23055:6;23050:3;23046:16;23039:23;;22935:137;;23081:341;23148:38;23180:5;23148:38;:::i;:::-;23208:1;23222:154;23236:6;23233:1;23230:13;23222:154;;;23310:7;23304:14;23300:1;23295:3;23291:11;23284:35;23360:1;23351:7;23347:15;23336:26;;23258:4;23255:1;23251:12;23246:17;;23222:154;;;23405:6;23400:3;23396:16;23389:23;;23088:334;;22902:520;;22690:738;;22583:845;;;;:::o;23434:377::-;23540:3;23568:39;23601:5;23568:39;:::i;:::-;23623:89;23705:6;23700:3;23623:89;:::i;:::-;23616:96;;23721:52;23766:6;23761:3;23754:4;23747:5;23743:16;23721:52;:::i;:::-;23798:6;23793:3;23789:16;23782:23;;23544:267;23434:377;;;;:::o;23817:155::-;23957:7;23953:1;23945:6;23941:14;23934:31;23817:155;:::o;23978:400::-;24138:3;24159:84;24241:1;24236:3;24159:84;:::i;:::-;24152:91;;24252:93;24341:3;24252:93;:::i;:::-;24370:1;24365:3;24361:11;24354:18;;23978:400;;;:::o;24384:695::-;24662:3;24684:92;24772:3;24763:6;24684:92;:::i;:::-;24677:99;;24793:95;24884:3;24875:6;24793:95;:::i;:::-;24786:102;;24905:148;25049:3;24905:148;:::i;:::-;24898:155;;25070:3;25063:10;;24384:695;;;;;:::o;25085:225::-;25225:34;25221:1;25213:6;25209:14;25202:58;25294:8;25289:2;25281:6;25277:15;25270:33;25085:225;:::o;25316:366::-;25458:3;25479:67;25543:2;25538:3;25479:67;:::i;:::-;25472:74;;25555:93;25644:3;25555:93;:::i;:::-;25673:2;25668:3;25664:12;25657:19;;25316:366;;;:::o;25688:419::-;25854:4;25892:2;25881:9;25877:18;25869:26;;25941:9;25935:4;25931:20;25927:1;25916:9;25912:17;25905:47;25969:131;26095:4;25969:131;:::i;:::-;25961:139;;25688:419;;;:::o;26113:233::-;26152:3;26175:24;26193:5;26175:24;:::i;:::-;26166:33;;26221:66;26214:5;26211:77;26208:103;;26291:18;;:::i;:::-;26208:103;26338:1;26331:5;26327:13;26320:20;;26113:233;;;:::o;26352:180::-;26400:77;26397:1;26390:88;26497:4;26494:1;26487:15;26521:4;26518:1;26511:15;26538:185;26578:1;26595:20;26613:1;26595:20;:::i;:::-;26590:25;;26629:20;26647:1;26629:20;:::i;:::-;26624:25;;26668:1;26658:35;;26673:18;;:::i;:::-;26658:35;26715:1;26712;26708:9;26703:14;;26538:185;;;;:::o;26729:191::-;26769:4;26789:20;26807:1;26789:20;:::i;:::-;26784:25;;26823:20;26841:1;26823:20;:::i;:::-;26818:25;;26862:1;26859;26856:8;26853:34;;;26867:18;;:::i;:::-;26853:34;26912:1;26909;26905:9;26897:17;;26729:191;;;;:::o;26926:176::-;26958:1;26975:20;26993:1;26975:20;:::i;:::-;26970:25;;27009:20;27027:1;27009:20;:::i;:::-;27004:25;;27048:1;27038:35;;27053:18;;:::i;:::-;27038:35;27094:1;27091;27087:9;27082:14;;26926:176;;;;:::o;27108:180::-;27156:77;27153:1;27146:88;27253:4;27250:1;27243:15;27277:4;27274:1;27267:15;27294:98;27345:6;27379:5;27373:12;27363:22;;27294:98;;;:::o;27398:168::-;27481:11;27515:6;27510:3;27503:19;27555:4;27550:3;27546:14;27531:29;;27398:168;;;;:::o;27572:360::-;27658:3;27686:38;27718:5;27686:38;:::i;:::-;27740:70;27803:6;27798:3;27740:70;:::i;:::-;27733:77;;27819:52;27864:6;27859:3;27852:4;27845:5;27841:16;27819:52;:::i;:::-;27896:29;27918:6;27896:29;:::i;:::-;27891:3;27887:39;27880:46;;27662:270;27572:360;;;;:::o;27938:640::-;28133:4;28171:3;28160:9;28156:19;28148:27;;28185:71;28253:1;28242:9;28238:17;28229:6;28185:71;:::i;:::-;28266:72;28334:2;28323:9;28319:18;28310:6;28266:72;:::i;:::-;28348;28416:2;28405:9;28401:18;28392:6;28348:72;:::i;:::-;28467:9;28461:4;28457:20;28452:2;28441:9;28437:18;28430:48;28495:76;28566:4;28557:6;28495:76;:::i;:::-;28487:84;;27938:640;;;;;;;:::o;28584:141::-;28640:5;28671:6;28665:13;28656:22;;28687:32;28713:5;28687:32;:::i;:::-;28584:141;;;;:::o;28731:349::-;28800:6;28849:2;28837:9;28828:7;28824:23;28820:32;28817:119;;;28855:79;;:::i;:::-;28817:119;28975:1;29000:63;29055:7;29046:6;29035:9;29031:22;29000:63;:::i;:::-;28990:73;;28946:127;28731:349;;;;:::o

Swarm Source

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