ETH Price: $3,263.04 (+4.48%)
Gas: 2 Gwei

 

Overview

TokenID

888

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
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:
Omnihorse721

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: MIT
// ERC721A Contracts v4.1.0 sourced from Chiru Labs
// Creator: Bitus 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 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();

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

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

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

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

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

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

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

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

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

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

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

    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;
        // Arbitrary data similar to `startTimestamp` that can be set through `_extraData`.
        uint24 extraData;
    }

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

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

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId` (inclusive) is transferred from `from` to `to`,
     * as defined in the ERC2309 standard. See `_mintERC2309` for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

/**
 * @dev Interface of an ERC721AQueryable compliant contract.
 */
interface IERC721AQueryable is IERC721A {
    /**
     * Invalid query range (`start` >= `stop`).
     */
    error InvalidQueryRange();

    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *   - `addr` = `address(0)`
     *   - `startTimestamp` = `0`
     *   - `burned` = `false`
     *
     * If the `tokenId` is burned:
     *   - `addr` = `<Address of owner before token was burned>`
     *   - `startTimestamp` = `<Timestamp when token was burned>`
     *   - `burned = `true`
     *
     * Otherwise:
     *   - `addr` = `<Address of owner>`
     *   - `startTimestamp` = `<Timestamp of start of ownership>`
     *   - `burned = `false`
     */
    function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory);

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start` < `stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view returns (uint256[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(totalSupply) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K pfp collections should be fine).
     */
    function tokensOfOwner(address owner) external view returns (uint256[] memory);
}

/**
 * @dev Interface of an ERC721ABurnable compliant contract.
 */
interface IERC721ABurnable is IERC721A {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) external;
}

/**
 * @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 bit position of `extraData` in packed ownership.
    uint256 private constant BITPOS_EXTRA_DATA = 232;

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

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

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

    // The 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`
    // - [232..255] `extraData`
    mapping(uint256 => uint256) private _packedOwnerships;

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

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

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

    

    /**
     * @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 auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> BITPOS_AUX);
    }

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

    /**
     * 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;
        ownership.extraData = uint24(packed >> BITPOS_EXTRA_DATA);
    }

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

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

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

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

        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-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 {
        transferFrom(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.
     *
     * See {_mint}.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        _mint(to, quantity);

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

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mint(address to, uint256 quantity) internal {
        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` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << BITPOS_NUMBER_MINTED) | 1);

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

            uint256 tokenId = startTokenId;
            uint256 end = startTokenId + quantity;
            do {
                emit Transfer(address(0), to, tokenId++);
            } while (tokenId < end);

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

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

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

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

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

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

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

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        mapping(uint256 => address) storage tokenApprovalsPtr = _tokenApprovals;
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId]`.
        assembly {
            // Compute the slot.
            mstore(0x00, tokenId)
            mstore(0x20, tokenApprovalsPtr.slot)
            approvedAddressSlot := keccak256(0x00, 0x40)
            // Load the slot's value from storage.
            approvedAddress := sload(approvedAddressSlot)
        }
    }

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

    /**
     * @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 transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

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

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

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

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

        _beforeTokenTransfers(from, to, tokenId, 1);

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

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

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

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

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

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

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

        address from = address(uint160(prevOwnershipPacked));

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

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

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

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

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

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

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

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

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

    /**
     * @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 Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

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

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

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

/**
 * @title ERC721A Queryable
 * @dev ERC721A subclass with convenience query functions.
 */
abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable {
    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *   - `addr` = `address(0)`
     *   - `startTimestamp` = `0`
     *   - `burned` = `false`
     *   - `extraData` = `0`
     *
     * If the `tokenId` is burned:
     *   - `addr` = `<Address of owner before token was burned>`
     *   - `startTimestamp` = `<Timestamp when token was burned>`
     *   - `burned = `true`
     *   - `extraData` = `<Extra data when token was burned>`
     *
     * Otherwise:
     *   - `addr` = `<Address of owner>`
     *   - `startTimestamp` = `<Timestamp of start of ownership>`
     *   - `burned = `false`
     *   - `extraData` = `<Extra data at start of ownership>`
     */
    function explicitOwnershipOf(uint256 tokenId) public view override returns (TokenOwnership memory) {
        TokenOwnership memory ownership;
        if (tokenId < _startTokenId() || tokenId >= _nextTokenId()) {
            return ownership;
        }
        ownership = _ownershipAt(tokenId);
        if (ownership.burned) {
            return ownership;
        }
        return _ownershipOf(tokenId);
    }

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] memory tokenIds) external view override returns (TokenOwnership[] memory) {
        unchecked {
            uint256 tokenIdsLength = tokenIds.length;
            TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength);
            for (uint256 i; i != tokenIdsLength; ++i) {
                ownerships[i] = explicitOwnershipOf(tokenIds[i]);
            }
            return ownerships;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start` < `stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) public view override returns (uint256[] memory) {
        unchecked {
            if (start >= stop) revert InvalidQueryRange();
            uint256 tokenIdsIdx;
            uint256 stopLimit = _nextTokenId();
            // Set `start = max(start, _startTokenId())`.
            if (start < _startTokenId()) {
                start = _startTokenId();
            }
            // Set `stop = min(stop, stopLimit)`.
            if (stop > stopLimit) {
                stop = stopLimit;
            }
            uint256 tokenIdsMaxLength = balanceOf(owner);
            // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`,
            // to cater for cases where `balanceOf(owner)` is too big.
            if (start < stop) {
                uint256 rangeLength = stop - start;
                if (rangeLength < tokenIdsMaxLength) {
                    tokenIdsMaxLength = rangeLength;
                }
            } else {
                tokenIdsMaxLength = 0;
            }
            uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength);
            if (tokenIdsMaxLength == 0) {
                return tokenIds;
            }
            // We need to call `explicitOwnershipOf(start)`,
            // because the slot at `start` may not be initialized.
            TokenOwnership memory ownership = explicitOwnershipOf(start);
            address currOwnershipAddr;
            // If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`.
            // `ownership.address` will not be zero, as `start` is clamped to the valid token ID range.
            if (!ownership.burned) {
                currOwnershipAddr = ownership.addr;
            }
            for (uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            // Downsize the array to fit.
            assembly {
                mstore(tokenIds, tokenIdsIdx)
            }
            return tokenIds;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(totalSupply) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K pfp collections should be fine).
     */
    function tokensOfOwner(address owner) external view override returns (uint256[] memory) {
        unchecked {
            uint256 tokenIdsIdx;
            address currOwnershipAddr;
            uint256 tokenIdsLength = balanceOf(owner);
            uint256[] memory tokenIds = new uint256[](tokenIdsLength);
            TokenOwnership memory ownership;
            for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            return tokenIds;
        }
    }
}

/**
 * @title ERC721A Burnable Token
 * @dev ERC721A Token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721ABurnable is ERC721A, IERC721ABurnable {
    /**
     * @dev Burns `tokenId`. See {ERC721A-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual override {
        _burn(tokenId, true);
    }
}

contract Ownable {
    /**
     * @dev Error constants.
     */
    string public constant NOT_CURRENT_OWNER = '018001';
    string public constant CANNOT_TRANSFER_TO_ZERO_ADDRESS = '018002';

    /**
     * @dev Current owner address.
     */
    address public owner;

    /**
     * @dev An event which is triggered when the owner is changed.
     * @param previousOwner The address of the previous owner.
     * @param newOwner The address of the new owner.
     */
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev The constructor sets the original `owner` of the contract to the sender account.
     */
    constructor() {
        owner = msg.sender;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(msg.sender == owner, NOT_CURRENT_OWNER);
        _;
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param _newOwner The address to transfer ownership to.
     */
    function transferOwnership(address _newOwner) public onlyOwner {
        require(_newOwner != address(0), CANNOT_TRANSFER_TO_ZERO_ADDRESS);
        emit OwnershipTransferred(owner, _newOwner);
        owner = _newOwner;
    }
}

contract Omnihorse721 is ERC721A, Ownable, ERC721ABurnable, ERC721AQueryable {
    mapping(uint256 => string) private _tokenURIBase;
    mapping(uint256 => uint256) private indexCap;
    uint256 private indecies;
    string private _name;
    string private _symbol;
    string private baseURI;

    constructor() {
        _name = 'Omni Horse';
        _symbol = 'OmniHorse';
    }

    /**
     * @dev Returns URI based on IPFS upload batch
     */
    function tokenURI(uint256 tokenId) public view virtual override(ERC721A, IERC721A) returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        uint256 length = indecies;
        uint256 prevCap;
        for(uint256 i=0; i< length;) {
            if(tokenId <= indexCap[i]) {
                uint256 str = tokenId - prevCap;
                return string(abi.encodePacked(_tokenURIBase[i], uint2str(str)));
            }
            prevCap = indexCap[i];
            unchecked { i++; }
        }

        revert URIQueryForNonexistentToken();
    }

    /**
     * @dev Returns generic base that's not used
     */
    function _baseURI() internal view virtual override returns (string memory) {
        return 'https://omnihorse.io';
    }

    /**
     * @dev Mint batch group with it's own URI base
     */
    function batchMint(uint256 _quantity, string memory _uri) public onlyOwner {
        indexCap[indecies] = totalSupply() + _quantity;
        _tokenURIBase[indecies] = _uri;
        unchecked { indecies++; }
        _safeMint(msg.sender, _quantity);
    }

    function firstTokenOfOwner(address owner) internal virtual returns (uint256 tokenId) {
        unchecked {
            uint256 tokenIdsIdx;
            address currOwnershipAddr;
            uint256 tokenIdsLength = balanceOf(owner);
            TokenOwnership memory ownership;
            for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
                ownership = _ownershipAt(i);
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenId = i;
                    break;
                }
            }
            if(tokenId == 0 && _ownershipAt(0).addr != msg.sender) revert();
        }
    }

    /**
     * @dev Batch transfer using the lowest index of owner first
     */
    function batchTransfer(address[] calldata _address) public onlyOwner {
      uint256 length = _address.length;
      uint256 first = firstTokenOfOwner(msg.sender);
      uint256[] memory _nfts = tokensOfOwnerIn(msg.sender, first, first + length);
      for(uint256 i=0; i<length;) {
        transferFrom(msg.sender, _address[i], _nfts[i]);
        unchecked { i++; }
      }
    }
    
    /**
     * @dev Uint256 to String as documented in EIP
     */
    function uint2str(uint _i) internal pure returns (string memory _uintAsString) {
        if (_i == 0) { return "0"; }
        uint j = _i;
        uint len;
        while (j != 0) {
            len++;
            j /= 10;
        }
        bytes memory bstr = new bytes(len);
        uint k = len;
        while (_i != 0) {
            k = k-1;
            uint8 temp = (48 + uint8(_i - _i / 10 * 10));
            bytes1 b1 = bytes1(temp);
            bstr[k] = b1;
            _i /= 10;
        }
        return string(bstr);
    }

    function burnTokens(address _contract, address _to, uint256 _amount) external onlyOwner {
        bytes memory payload = abi.encodeWithSignature("transferFrom(address, address, uint256)", address(this), _to, _amount);
        (bool success, ) = _contract.call(payload);
        require(success);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"CANNOT_TRANSFER_TO_ZERO_ADDRESS","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NOT_CURRENT_OWNER","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"string","name":"_uri","type":"string"}],"name":"batchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_address","type":"address[]"}],"name":"batchTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","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":[{"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":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","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"}]

60806040523480156200001157600080fd5b5033600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060400160405280600a81526020017f4f6d6e6920486f72736500000000000000000000000000000000000000000000815250600c908162000099919062000361565b506040518060400160405280600981526020017f4f6d6e69486f7273650000000000000000000000000000000000000000000000815250600d9081620000e0919062000361565b5062000448565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200016957607f821691505b6020821081036200017f576200017e62000121565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620001e97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82620001aa565b620001f58683620001aa565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620002426200023c62000236846200020d565b62000217565b6200020d565b9050919050565b6000819050919050565b6200025e8362000221565b620002766200026d8262000249565b848454620001b7565b825550505050565b600090565b6200028d6200027e565b6200029a81848462000253565b505050565b5b81811015620002c257620002b660008262000283565b600181019050620002a0565b5050565b601f8211156200031157620002db8162000185565b620002e6846200019a565b81016020851015620002f6578190505b6200030e62000305856200019a565b8301826200029f565b50505b505050565b600082821c905092915050565b6000620003366000198460080262000316565b1980831691505092915050565b600062000351838362000323565b9150826002028217905092915050565b6200036c82620000e7565b67ffffffffffffffff811115620003885762000387620000f2565b5b62000394825462000150565b620003a1828285620002c6565b600060209050601f831160018114620003d95760008415620003c4578287015190505b620003d0858262000343565b86555062000440565b601f198416620003e98662000185565b60005b828110156200041357848901518255600182019150602085019450602081019050620003ec565b868310156200043357848901516200042f601f89168262000323565b8355505b6001600288020188555050505b505050505050565b613bc080620004586000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c8063860d248a116100de578063c23dc68f11610097578063e985e9c511610071578063e985e9c5146104b9578063f12a8562146104e9578063f2fde38b14610505578063f3fe3bc3146105215761018e565b8063c23dc68f1461043d578063c87b56dd1461046d578063d3c1c8381461049d5761018e565b8063860d248a1461037b5780638da5cb5b1461039957806395d89b41146103b757806399a2557a146103d5578063a22cb46514610405578063b88d4fde146104215761018e565b8063423c3a481161014b5780635bbb2177116101255780635bbb2177146102bb5780636352211e146102eb57806370a082311461031b5780638462151c1461034b5761018e565b8063423c3a481461026757806342842e0e1461028357806342966c681461029f5761018e565b806301ffc9a71461019357806306fdde03146101c3578063081812fc146101e1578063095ea7b31461021157806318160ddd1461022d57806323b872dd1461024b575b600080fd5b6101ad60048036038101906101a891906128f9565b61053f565b6040516101ba9190612941565b60405180910390f35b6101cb6105d1565b6040516101d891906129f5565b60405180910390f35b6101fb60048036038101906101f69190612a4d565b610663565b6040516102089190612abb565b60405180910390f35b61022b60048036038101906102269190612b02565b6106df565b005b610235610820565b6040516102429190612b51565b60405180910390f35b61026560048036038101906102609190612b6c565b610837565b005b610281600480360381019061027c9190612b6c565b610b59565b005b61029d60048036038101906102989190612b6c565b610d36565b005b6102b960048036038101906102b49190612a4d565b610d56565b005b6102d560048036038101906102d09190612d07565b610d64565b6040516102e29190612eb3565b60405180910390f35b61030560048036038101906103009190612a4d565b610e25565b6040516103129190612abb565b60405180910390f35b61033560048036038101906103309190612ed5565b610e37565b6040516103429190612b51565b60405180910390f35b61036560048036038101906103609190612ed5565b610eef565b6040516103729190612fc0565b60405180910390f35b610383611032565b60405161039091906129f5565b60405180910390f35b6103a161106b565b6040516103ae9190612abb565b60405180910390f35b6103bf611091565b6040516103cc91906129f5565b60405180910390f35b6103ef60048036038101906103ea9190612fe2565b611123565b6040516103fc9190612fc0565b60405180910390f35b61041f600480360381019061041a9190613061565b61132f565b005b61043b60048036038101906104369190613156565b6114a6565b005b61045760048036038101906104529190612a4d565b611519565b604051610464919061322e565b60405180910390f35b61048760048036038101906104829190612a4d565b611583565b60405161049491906129f5565b60405180910390f35b6104b760048036038101906104b291906132a4565b6116a7565b005b6104d360048036038101906104ce91906132f1565b61180b565b6040516104e09190612941565b60405180910390f35b61050360048036038101906104fe91906133d2565b61189f565b005b61051f600480360381019061051a9190612ed5565b6119d7565b005b610529611c09565b60405161053691906129f5565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061059a57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806105ca5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546105e09061345d565b80601f016020809104026020016040519081016040528092919081815260200182805461060c9061345d565b80156106595780601f1061062e57610100808354040283529160200191610659565b820191906000526020600020905b81548152906001019060200180831161063c57829003601f168201915b5050505050905090565b600061066e82611c42565b6106a4576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006106ea82610e25565b90508073ffffffffffffffffffffffffffffffffffffffff1661070b611ca1565b73ffffffffffffffffffffffffffffffffffffffff161461076e5761073781610732611ca1565b61180b565b61076d576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600061082a611ca9565b6001546000540303905090565b600061084282611cae565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108a9576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806108b584611d7a565b915091506108cb81876108c6611ca1565b611d9c565b610917576108e0866108db611ca1565b61180b565b610916576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361097d576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61098a8686866001611de0565b801561099557600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610a6385610a3f888887611de6565b7c020000000000000000000000000000000000000000000000000000000017611e0e565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610ae95760006001850190506000600460008381526020019081526020016000205403610ae7576000548114610ae6578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610b518686866001611e39565b505050505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303138303031000000000000000000000000000000000000000000000000000081525090610c21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1891906129f5565b60405180910390fd5b506000308383604051602401610c399392919061348e565b6040516020818303038152906040527fb642fe57000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008473ffffffffffffffffffffffffffffffffffffffff1682604051610cdf919061350c565b6000604051808303816000865af19150503d8060008114610d1c576040519150601f19603f3d011682016040523d82523d6000602084013e610d21565b606091505b5050905080610d2f57600080fd5b5050505050565b610d51838383604051806020016040528060008152506114a6565b505050565b610d61816001611e3f565b50565b606060008251905060008167ffffffffffffffff811115610d8857610d87612bc4565b5b604051908082528060200260200182016040528015610dc157816020015b610dae61283e565b815260200190600190039081610da65790505b50905060005b828114610e1a57610df1858281518110610de457610de3613523565b5b6020026020010151611519565b828281518110610e0457610e03613523565b5b6020026020010181905250806001019050610dc7565b508092505050919050565b6000610e3082611cae565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e9e576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b60606000806000610eff85610e37565b905060008167ffffffffffffffff811115610f1d57610f1c612bc4565b5b604051908082528060200260200182016040528015610f4b5781602001602082028036833780820191505090505b509050610f5661283e565b6000610f60611ca9565b90505b83861461102457610f7381612091565b9150816040015161101957600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1614610fbe57816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611018578083878060010198508151811061100b5761100a613523565b5b6020026020010181815250505b5b806001019050610f63565b508195505050505050919050565b6040518060400160405280600681526020017f303138303032000000000000000000000000000000000000000000000000000081525081565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600380546110a09061345d565b80601f01602080910402602001604051908101604052809291908181526020018280546110cc9061345d565b80156111195780601f106110ee57610100808354040283529160200191611119565b820191906000526020600020905b8154815290600101906020018083116110fc57829003601f168201915b5050505050905090565b606081831061115e576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806111696120bc565b9050611173611ca9565b85101561118557611182611ca9565b94505b80841115611191578093505b600061119c87610e37565b9050848610156111bf5760008686039050818110156111b9578091505b506111c4565b600090505b60008167ffffffffffffffff8111156111e0576111df612bc4565b5b60405190808252806020026020018201604052801561120e5781602001602082028036833780820191505090505b509050600082036112255780945050505050611328565b600061123088611519565b90506000816040015161124557816000015190505b60008990505b88811415801561125b5750848714155b1561131a5761126981612091565b9250826040015161130f57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16146112b457826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361130e578084888060010199508151811061130157611300613523565b5b6020026020010181815250505b5b80600101905061124b565b508583528296505050505050505b9392505050565b611337611ca1565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361139b576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760006113a8611ca1565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611455611ca1565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161149a9190612941565b60405180910390a35050565b6114b1848484610837565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611513576114dc848484846120c5565b611512576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b61152161283e565b61152961283e565b611531611ca9565b83108061154557506115416120bc565b8310155b15611553578091505061157e565b61155c83612091565b9050806040015115611571578091505061157e565b61157a83612215565b9150505b919050565b606061158e82611c42565b6115c4576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600b549050600080600090505b8281101561166f57600a600082815260200190815260200160002054851161164c57600082866116039190613581565b90506009600083815260200190815260200160002061162182612235565b604051602001611632929190613689565b6040516020818303038152906040529450505050506116a2565b600a600082815260200190815260200160002054915080806001019150506115d3565b506040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f30313830303100000000000000000000000000000000000000000000000000008152509061176f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176691906129f5565b60405180910390fd5b5060008282905090506000611783336123bd565b9050600061179d3383858561179891906136ad565b611123565b905060005b83811015611803576117f6338787848181106117c1576117c0613523565b5b90506020020160208101906117d69190612ed5565b8484815181106117e9576117e8613523565b5b6020026020010151610837565b80806001019150506117a2565b505050505050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303138303031000000000000000000000000000000000000000000000000000081525090611967576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195e91906129f5565b60405180910390fd5b5081611971610820565b61197b91906136ad565b600a6000600b548152602001908152602001600020819055508060096000600b54815260200190815260200160002090816119b6919061389a565b50600b600081548092919060010191905055506119d333836124e2565b5050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303138303031000000000000000000000000000000000000000000000000000081525090611a9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9691906129f5565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303138303032000000000000000000000000000000000000000000000000000081525090611b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3f91906129f5565b60405180910390fd5b508073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060400160405280600681526020017f303138303031000000000000000000000000000000000000000000000000000081525081565b600081611c4d611ca9565b11158015611c5c575060005482105b8015611c9a575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600090565b60008082905080611cbd611ca9565b11611d4357600054811015611d425760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611d40575b60008103611d36576004600083600190039350838152602001908152602001600020549050611d0c565b8092505050611d75565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000806000600690508360005280602052604060002092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611dfd868684612500565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000611e4a83611cae565b90506000819050600080611e5d86611d7a565b915091508415611ec657611e798184611e74611ca1565b611d9c565b611ec557611e8e83611e89611ca1565b61180b565b611ec4576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b611ed4836000886001611de0565b8015611edf57600082555b600160806001901b03600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611f8783611f4485600088611de6565b7c02000000000000000000000000000000000000000000000000000000007c01000000000000000000000000000000000000000000000000000000001717611e0e565b600460008881526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000085160361200d576000600187019050600060046000838152602001908152602001600020540361200b57600054811461200a578460046000838152602001908152602001600020819055505b5b505b85600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612077836000886001611e39565b600160008154809291906001019190505550505050505050565b61209961283e565b6120b56004600084815260200190815260200160002054612509565b9050919050565b60008054905090565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026120eb611ca1565b8786866040518563ffffffff1660e01b815260040161210d94939291906139b6565b6020604051808303816000875af192505050801561214957506040513d601f19601f820116820180604052508101906121469190613a17565b60015b6121c2573d8060008114612179576040519150601f19603f3d011682016040523d82523d6000602084013e61217e565b606091505b5060008151036121ba576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b61221d61283e565b61222e61222983611cae565b612509565b9050919050565b60606000820361227c576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506123b8565b600082905060005b600082146122ae57808061229790613a44565b915050600a826122a79190613abb565b9150612284565b60008167ffffffffffffffff8111156122ca576122c9612bc4565b5b6040519080825280601f01601f1916602001820160405280156122fc5781602001600182028036833780820191505090505b50905060008290505b600086146123b05760018161231a9190613581565b90506000600a808861232c9190613abb565b6123369190613aec565b876123419190613581565b603061234d9190613b53565b905060008160f81b90508084848151811061236b5761236a613523565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a886123a79190613abb565b97505050612305565b819450505050505b919050565b6000806000806123cc85610e37565b90506123d661283e565b60006123e0611ca9565b90505b828514612485576123f381612091565b9150816040015161247a57600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff161461243e57816000015193505b8673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361247957809550612485565b5b8060010190506123e3565b506000851480156124cf57503373ffffffffffffffffffffffffffffffffffffffff166124b26000612091565b6000015173ffffffffffffffffffffffffffffffffffffffff1614155b156124d957600080fd5b50505050919050565b6124fc8282604051806020016040528060008152506125bf565b5050565b60009392505050565b61251161283e565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b6125c9838361265c565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461265757600080549050600083820390505b61260960008683806001019450866120c5565b61263f576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106125f657816000541461265457600080fd5b50505b505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036126c8576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008203612702576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61270f6000848385611de0565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612786836127776000866000611de6565b6127808561282e565b17611e0e565b60046000838152602001908152602001600020819055506000819050600083830190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082106127aa578060008190555050506128296000848385611e39565b505050565b60006001821460e11b9050919050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6128d6816128a1565b81146128e157600080fd5b50565b6000813590506128f3816128cd565b92915050565b60006020828403121561290f5761290e612897565b5b600061291d848285016128e4565b91505092915050565b60008115159050919050565b61293b81612926565b82525050565b60006020820190506129566000830184612932565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561299657808201518184015260208101905061297b565b838111156129a5576000848401525b50505050565b6000601f19601f8301169050919050565b60006129c78261295c565b6129d18185612967565b93506129e1818560208601612978565b6129ea816129ab565b840191505092915050565b60006020820190508181036000830152612a0f81846129bc565b905092915050565b6000819050919050565b612a2a81612a17565b8114612a3557600080fd5b50565b600081359050612a4781612a21565b92915050565b600060208284031215612a6357612a62612897565b5b6000612a7184828501612a38565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612aa582612a7a565b9050919050565b612ab581612a9a565b82525050565b6000602082019050612ad06000830184612aac565b92915050565b612adf81612a9a565b8114612aea57600080fd5b50565b600081359050612afc81612ad6565b92915050565b60008060408385031215612b1957612b18612897565b5b6000612b2785828601612aed565b9250506020612b3885828601612a38565b9150509250929050565b612b4b81612a17565b82525050565b6000602082019050612b666000830184612b42565b92915050565b600080600060608486031215612b8557612b84612897565b5b6000612b9386828701612aed565b9350506020612ba486828701612aed565b9250506040612bb586828701612a38565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612bfc826129ab565b810181811067ffffffffffffffff82111715612c1b57612c1a612bc4565b5b80604052505050565b6000612c2e61288d565b9050612c3a8282612bf3565b919050565b600067ffffffffffffffff821115612c5a57612c59612bc4565b5b602082029050602081019050919050565b600080fd5b6000612c83612c7e84612c3f565b612c24565b90508083825260208201905060208402830185811115612ca657612ca5612c6b565b5b835b81811015612ccf5780612cbb8882612a38565b845260208401935050602081019050612ca8565b5050509392505050565b600082601f830112612cee57612ced612bbf565b5b8135612cfe848260208601612c70565b91505092915050565b600060208284031215612d1d57612d1c612897565b5b600082013567ffffffffffffffff811115612d3b57612d3a61289c565b5b612d4784828501612cd9565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612d8581612a9a565b82525050565b600067ffffffffffffffff82169050919050565b612da881612d8b565b82525050565b612db781612926565b82525050565b600062ffffff82169050919050565b612dd581612dbd565b82525050565b608082016000820151612df16000850182612d7c565b506020820151612e046020850182612d9f565b506040820151612e176040850182612dae565b506060820151612e2a6060850182612dcc565b50505050565b6000612e3c8383612ddb565b60808301905092915050565b6000602082019050919050565b6000612e6082612d50565b612e6a8185612d5b565b9350612e7583612d6c565b8060005b83811015612ea6578151612e8d8882612e30565b9750612e9883612e48565b925050600181019050612e79565b5085935050505092915050565b60006020820190508181036000830152612ecd8184612e55565b905092915050565b600060208284031215612eeb57612eea612897565b5b6000612ef984828501612aed565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612f3781612a17565b82525050565b6000612f498383612f2e565b60208301905092915050565b6000602082019050919050565b6000612f6d82612f02565b612f778185612f0d565b9350612f8283612f1e565b8060005b83811015612fb3578151612f9a8882612f3d565b9750612fa583612f55565b925050600181019050612f86565b5085935050505092915050565b60006020820190508181036000830152612fda8184612f62565b905092915050565b600080600060608486031215612ffb57612ffa612897565b5b600061300986828701612aed565b935050602061301a86828701612a38565b925050604061302b86828701612a38565b9150509250925092565b61303e81612926565b811461304957600080fd5b50565b60008135905061305b81613035565b92915050565b6000806040838503121561307857613077612897565b5b600061308685828601612aed565b92505060206130978582860161304c565b9150509250929050565b600080fd5b600067ffffffffffffffff8211156130c1576130c0612bc4565b5b6130ca826129ab565b9050602081019050919050565b82818337600083830152505050565b60006130f96130f4846130a6565b612c24565b905082815260208101848484011115613115576131146130a1565b5b6131208482856130d7565b509392505050565b600082601f83011261313d5761313c612bbf565b5b813561314d8482602086016130e6565b91505092915050565b600080600080608085870312156131705761316f612897565b5b600061317e87828801612aed565b945050602061318f87828801612aed565b93505060406131a087828801612a38565b925050606085013567ffffffffffffffff8111156131c1576131c061289c565b5b6131cd87828801613128565b91505092959194509250565b6080820160008201516131ef6000850182612d7c565b5060208201516132026020850182612d9f565b5060408201516132156040850182612dae565b5060608201516132286060850182612dcc565b50505050565b600060808201905061324360008301846131d9565b92915050565b600080fd5b60008083601f84011261326457613263612bbf565b5b8235905067ffffffffffffffff81111561328157613280613249565b5b60208301915083602082028301111561329d5761329c612c6b565b5b9250929050565b600080602083850312156132bb576132ba612897565b5b600083013567ffffffffffffffff8111156132d9576132d861289c565b5b6132e58582860161324e565b92509250509250929050565b6000806040838503121561330857613307612897565b5b600061331685828601612aed565b925050602061332785828601612aed565b9150509250929050565b600067ffffffffffffffff82111561334c5761334b612bc4565b5b613355826129ab565b9050602081019050919050565b600061337561337084613331565b612c24565b905082815260208101848484011115613391576133906130a1565b5b61339c8482856130d7565b509392505050565b600082601f8301126133b9576133b8612bbf565b5b81356133c9848260208601613362565b91505092915050565b600080604083850312156133e9576133e8612897565b5b60006133f785828601612a38565b925050602083013567ffffffffffffffff8111156134185761341761289c565b5b613424858286016133a4565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061347557607f821691505b6020821081036134885761348761342e565b5b50919050565b60006060820190506134a36000830186612aac565b6134b06020830185612aac565b6134bd6040830184612b42565b949350505050565b600081519050919050565b600081905092915050565b60006134e6826134c5565b6134f081856134d0565b9350613500818560208601612978565b80840191505092915050565b600061351882846134db565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061358c82612a17565b915061359783612a17565b9250828210156135aa576135a9613552565b5b828203905092915050565b600081905092915050565b60008190508160005260206000209050919050565b600081546135e28161345d565b6135ec81866135b5565b94506001821660008114613607576001811461361c5761364f565b60ff198316865281151582028601935061364f565b613625856135c0565b60005b8381101561364757815481890152600182019150602081019050613628565b838801955050505b50505092915050565b60006136638261295c565b61366d81856135b5565b935061367d818560208601612978565b80840191505092915050565b600061369582856135d5565b91506136a18284613658565b91508190509392505050565b60006136b882612a17565b91506136c383612a17565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156136f8576136f7613552565b5b828201905092915050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026137507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613713565b61375a8683613713565b95508019841693508086168417925050509392505050565b6000819050919050565b600061379761379261378d84612a17565b613772565b612a17565b9050919050565b6000819050919050565b6137b18361377c565b6137c56137bd8261379e565b848454613720565b825550505050565b600090565b6137da6137cd565b6137e58184846137a8565b505050565b5b81811015613809576137fe6000826137d2565b6001810190506137eb565b5050565b601f82111561384e5761381f816135c0565b61382884613703565b81016020851015613837578190505b61384b61384385613703565b8301826137ea565b50505b505050565b600082821c905092915050565b600061387160001984600802613853565b1980831691505092915050565b600061388a8383613860565b9150826002028217905092915050565b6138a38261295c565b67ffffffffffffffff8111156138bc576138bb612bc4565b5b6138c6825461345d565b6138d182828561380d565b600060209050601f83116001811461390457600084156138f2578287015190505b6138fc858261387e565b865550613964565b601f198416613912866135c0565b60005b8281101561393a57848901518255600182019150602085019450602081019050613915565b868310156139575784890151613953601f891682613860565b8355505b6001600288020188555050505b505050505050565b600082825260208201905092915050565b6000613988826134c5565b613992818561396c565b93506139a2818560208601612978565b6139ab816129ab565b840191505092915050565b60006080820190506139cb6000830187612aac565b6139d86020830186612aac565b6139e56040830185612b42565b81810360608301526139f7818461397d565b905095945050505050565b600081519050613a11816128cd565b92915050565b600060208284031215613a2d57613a2c612897565b5b6000613a3b84828501613a02565b91505092915050565b6000613a4f82612a17565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613a8157613a80613552565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613ac682612a17565b9150613ad183612a17565b925082613ae157613ae0613a8c565b5b828204905092915050565b6000613af782612a17565b9150613b0283612a17565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613b3b57613b3a613552565b5b828202905092915050565b600060ff82169050919050565b6000613b5e82613b46565b9150613b6983613b46565b92508260ff03821115613b7f57613b7e613552565b5b82820190509291505056fea2646970667358221220f422a328cdbd117a27b0a9d6fa2817b4ce9f31920d35191c684b875e9c60816064736f6c634300080f0033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063860d248a116100de578063c23dc68f11610097578063e985e9c511610071578063e985e9c5146104b9578063f12a8562146104e9578063f2fde38b14610505578063f3fe3bc3146105215761018e565b8063c23dc68f1461043d578063c87b56dd1461046d578063d3c1c8381461049d5761018e565b8063860d248a1461037b5780638da5cb5b1461039957806395d89b41146103b757806399a2557a146103d5578063a22cb46514610405578063b88d4fde146104215761018e565b8063423c3a481161014b5780635bbb2177116101255780635bbb2177146102bb5780636352211e146102eb57806370a082311461031b5780638462151c1461034b5761018e565b8063423c3a481461026757806342842e0e1461028357806342966c681461029f5761018e565b806301ffc9a71461019357806306fdde03146101c3578063081812fc146101e1578063095ea7b31461021157806318160ddd1461022d57806323b872dd1461024b575b600080fd5b6101ad60048036038101906101a891906128f9565b61053f565b6040516101ba9190612941565b60405180910390f35b6101cb6105d1565b6040516101d891906129f5565b60405180910390f35b6101fb60048036038101906101f69190612a4d565b610663565b6040516102089190612abb565b60405180910390f35b61022b60048036038101906102269190612b02565b6106df565b005b610235610820565b6040516102429190612b51565b60405180910390f35b61026560048036038101906102609190612b6c565b610837565b005b610281600480360381019061027c9190612b6c565b610b59565b005b61029d60048036038101906102989190612b6c565b610d36565b005b6102b960048036038101906102b49190612a4d565b610d56565b005b6102d560048036038101906102d09190612d07565b610d64565b6040516102e29190612eb3565b60405180910390f35b61030560048036038101906103009190612a4d565b610e25565b6040516103129190612abb565b60405180910390f35b61033560048036038101906103309190612ed5565b610e37565b6040516103429190612b51565b60405180910390f35b61036560048036038101906103609190612ed5565b610eef565b6040516103729190612fc0565b60405180910390f35b610383611032565b60405161039091906129f5565b60405180910390f35b6103a161106b565b6040516103ae9190612abb565b60405180910390f35b6103bf611091565b6040516103cc91906129f5565b60405180910390f35b6103ef60048036038101906103ea9190612fe2565b611123565b6040516103fc9190612fc0565b60405180910390f35b61041f600480360381019061041a9190613061565b61132f565b005b61043b60048036038101906104369190613156565b6114a6565b005b61045760048036038101906104529190612a4d565b611519565b604051610464919061322e565b60405180910390f35b61048760048036038101906104829190612a4d565b611583565b60405161049491906129f5565b60405180910390f35b6104b760048036038101906104b291906132a4565b6116a7565b005b6104d360048036038101906104ce91906132f1565b61180b565b6040516104e09190612941565b60405180910390f35b61050360048036038101906104fe91906133d2565b61189f565b005b61051f600480360381019061051a9190612ed5565b6119d7565b005b610529611c09565b60405161053691906129f5565b60405180910390f35b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061059a57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806105ca5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b6060600280546105e09061345d565b80601f016020809104026020016040519081016040528092919081815260200182805461060c9061345d565b80156106595780601f1061062e57610100808354040283529160200191610659565b820191906000526020600020905b81548152906001019060200180831161063c57829003601f168201915b5050505050905090565b600061066e82611c42565b6106a4576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006106ea82610e25565b90508073ffffffffffffffffffffffffffffffffffffffff1661070b611ca1565b73ffffffffffffffffffffffffffffffffffffffff161461076e5761073781610732611ca1565b61180b565b61076d576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600061082a611ca9565b6001546000540303905090565b600061084282611cae565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108a9576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806108b584611d7a565b915091506108cb81876108c6611ca1565b611d9c565b610917576108e0866108db611ca1565b61180b565b610916576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff160361097d576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61098a8686866001611de0565b801561099557600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815460010191905081905550610a6385610a3f888887611de6565b7c020000000000000000000000000000000000000000000000000000000017611e0e565b600460008681526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000841603610ae95760006001850190506000600460008381526020019081526020016000205403610ae7576000548114610ae6578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4610b518686866001611e39565b505050505050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303138303031000000000000000000000000000000000000000000000000000081525090610c21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c1891906129f5565b60405180910390fd5b506000308383604051602401610c399392919061348e565b6040516020818303038152906040527fb642fe57000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008473ffffffffffffffffffffffffffffffffffffffff1682604051610cdf919061350c565b6000604051808303816000865af19150503d8060008114610d1c576040519150601f19603f3d011682016040523d82523d6000602084013e610d21565b606091505b5050905080610d2f57600080fd5b5050505050565b610d51838383604051806020016040528060008152506114a6565b505050565b610d61816001611e3f565b50565b606060008251905060008167ffffffffffffffff811115610d8857610d87612bc4565b5b604051908082528060200260200182016040528015610dc157816020015b610dae61283e565b815260200190600190039081610da65790505b50905060005b828114610e1a57610df1858281518110610de457610de3613523565b5b6020026020010151611519565b828281518110610e0457610e03613523565b5b6020026020010181905250806001019050610dc7565b508092505050919050565b6000610e3082611cae565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e9e576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b60606000806000610eff85610e37565b905060008167ffffffffffffffff811115610f1d57610f1c612bc4565b5b604051908082528060200260200182016040528015610f4b5781602001602082028036833780820191505090505b509050610f5661283e565b6000610f60611ca9565b90505b83861461102457610f7381612091565b9150816040015161101957600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1614610fbe57816000015194505b8773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611018578083878060010198508151811061100b5761100a613523565b5b6020026020010181815250505b5b806001019050610f63565b508195505050505050919050565b6040518060400160405280600681526020017f303138303032000000000000000000000000000000000000000000000000000081525081565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6060600380546110a09061345d565b80601f01602080910402602001604051908101604052809291908181526020018280546110cc9061345d565b80156111195780601f106110ee57610100808354040283529160200191611119565b820191906000526020600020905b8154815290600101906020018083116110fc57829003601f168201915b5050505050905090565b606081831061115e576040517f32c1995a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000806111696120bc565b9050611173611ca9565b85101561118557611182611ca9565b94505b80841115611191578093505b600061119c87610e37565b9050848610156111bf5760008686039050818110156111b9578091505b506111c4565b600090505b60008167ffffffffffffffff8111156111e0576111df612bc4565b5b60405190808252806020026020018201604052801561120e5781602001602082028036833780820191505090505b509050600082036112255780945050505050611328565b600061123088611519565b90506000816040015161124557816000015190505b60008990505b88811415801561125b5750848714155b1561131a5761126981612091565b9250826040015161130f57600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16146112b457826000015191505b8a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361130e578084888060010199508151811061130157611300613523565b5b6020026020010181815250505b5b80600101905061124b565b508583528296505050505050505b9392505050565b611337611ca1565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361139b576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600760006113a8611ca1565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611455611ca1565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161149a9190612941565b60405180910390a35050565b6114b1848484610837565b60008373ffffffffffffffffffffffffffffffffffffffff163b14611513576114dc848484846120c5565b611512576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b61152161283e565b61152961283e565b611531611ca9565b83108061154557506115416120bc565b8310155b15611553578091505061157e565b61155c83612091565b9050806040015115611571578091505061157e565b61157a83612215565b9150505b919050565b606061158e82611c42565b6115c4576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600b549050600080600090505b8281101561166f57600a600082815260200190815260200160002054851161164c57600082866116039190613581565b90506009600083815260200190815260200160002061162182612235565b604051602001611632929190613689565b6040516020818303038152906040529450505050506116a2565b600a600082815260200190815260200160002054915080806001019150506115d3565b506040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f30313830303100000000000000000000000000000000000000000000000000008152509061176f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176691906129f5565b60405180910390fd5b5060008282905090506000611783336123bd565b9050600061179d3383858561179891906136ad565b611123565b905060005b83811015611803576117f6338787848181106117c1576117c0613523565b5b90506020020160208101906117d69190612ed5565b8484815181106117e9576117e8613523565b5b6020026020010151610837565b80806001019150506117a2565b505050505050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303138303031000000000000000000000000000000000000000000000000000081525090611967576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161195e91906129f5565b60405180910390fd5b5081611971610820565b61197b91906136ad565b600a6000600b548152602001908152602001600020819055508060096000600b54815260200190815260200160002090816119b6919061389a565b50600b600081548092919060010191905055506119d333836124e2565b5050565b600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146040518060400160405280600681526020017f303138303031000000000000000000000000000000000000000000000000000081525090611a9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9691906129f5565b60405180910390fd5b50600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156040518060400160405280600681526020017f303138303032000000000000000000000000000000000000000000000000000081525090611b48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3f91906129f5565b60405180910390fd5b508073ffffffffffffffffffffffffffffffffffffffff16600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060400160405280600681526020017f303138303031000000000000000000000000000000000000000000000000000081525081565b600081611c4d611ca9565b11158015611c5c575060005482105b8015611c9a575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b600033905090565b600090565b60008082905080611cbd611ca9565b11611d4357600054811015611d425760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603611d40575b60008103611d36576004600083600190039350838152602001908152602001600020549050611d0c565b8092505050611d75565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000806000600690508360005280602052604060002092508254915050915091565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b50505050565b60008060e883901c905060e8611dfd868684612500565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6000611e4a83611cae565b90506000819050600080611e5d86611d7a565b915091508415611ec657611e798184611e74611ca1565b611d9c565b611ec557611e8e83611e89611ca1565b61180b565b611ec4576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b611ed4836000886001611de0565b8015611edf57600082555b600160806001901b03600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611f8783611f4485600088611de6565b7c02000000000000000000000000000000000000000000000000000000007c01000000000000000000000000000000000000000000000000000000001717611e0e565b600460008881526020019081526020016000208190555060007c020000000000000000000000000000000000000000000000000000000085160361200d576000600187019050600060046000838152602001908152602001600020540361200b57600054811461200a578460046000838152602001908152602001600020819055505b5b505b85600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612077836000886001611e39565b600160008154809291906001019190505550505050505050565b61209961283e565b6120b56004600084815260200190815260200160002054612509565b9050919050565b60008054905090565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a026120eb611ca1565b8786866040518563ffffffff1660e01b815260040161210d94939291906139b6565b6020604051808303816000875af192505050801561214957506040513d601f19601f820116820180604052508101906121469190613a17565b60015b6121c2573d8060008114612179576040519150601f19603f3d011682016040523d82523d6000602084013e61217e565b606091505b5060008151036121ba576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b61221d61283e565b61222e61222983611cae565b612509565b9050919050565b60606000820361227c576040518060400160405280600181526020017f300000000000000000000000000000000000000000000000000000000000000081525090506123b8565b600082905060005b600082146122ae57808061229790613a44565b915050600a826122a79190613abb565b9150612284565b60008167ffffffffffffffff8111156122ca576122c9612bc4565b5b6040519080825280601f01601f1916602001820160405280156122fc5781602001600182028036833780820191505090505b50905060008290505b600086146123b05760018161231a9190613581565b90506000600a808861232c9190613abb565b6123369190613aec565b876123419190613581565b603061234d9190613b53565b905060008160f81b90508084848151811061236b5761236a613523565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a886123a79190613abb565b97505050612305565b819450505050505b919050565b6000806000806123cc85610e37565b90506123d661283e565b60006123e0611ca9565b90505b828514612485576123f381612091565b9150816040015161247a57600073ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff161461243e57816000015193505b8673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff160361247957809550612485565b5b8060010190506123e3565b506000851480156124cf57503373ffffffffffffffffffffffffffffffffffffffff166124b26000612091565b6000015173ffffffffffffffffffffffffffffffffffffffff1614155b156124d957600080fd5b50505050919050565b6124fc8282604051806020016040528060008152506125bf565b5050565b60009392505050565b61251161283e565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b6125c9838361265c565b60008373ffffffffffffffffffffffffffffffffffffffff163b1461265757600080549050600083820390505b61260960008683806001019450866120c5565b61263f576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8181106125f657816000541461265457600080fd5b50505b505050565b600080549050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036126c8576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008203612702576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61270f6000848385611de0565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550612786836127776000866000611de6565b6127808561282e565b17611e0e565b60046000838152602001908152602001600020819055506000819050600083830190505b818060010192508573ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a48082106127aa578060008190555050506128296000848385611e39565b505050565b60006001821460e11b9050919050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6128d6816128a1565b81146128e157600080fd5b50565b6000813590506128f3816128cd565b92915050565b60006020828403121561290f5761290e612897565b5b600061291d848285016128e4565b91505092915050565b60008115159050919050565b61293b81612926565b82525050565b60006020820190506129566000830184612932565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561299657808201518184015260208101905061297b565b838111156129a5576000848401525b50505050565b6000601f19601f8301169050919050565b60006129c78261295c565b6129d18185612967565b93506129e1818560208601612978565b6129ea816129ab565b840191505092915050565b60006020820190508181036000830152612a0f81846129bc565b905092915050565b6000819050919050565b612a2a81612a17565b8114612a3557600080fd5b50565b600081359050612a4781612a21565b92915050565b600060208284031215612a6357612a62612897565b5b6000612a7184828501612a38565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612aa582612a7a565b9050919050565b612ab581612a9a565b82525050565b6000602082019050612ad06000830184612aac565b92915050565b612adf81612a9a565b8114612aea57600080fd5b50565b600081359050612afc81612ad6565b92915050565b60008060408385031215612b1957612b18612897565b5b6000612b2785828601612aed565b9250506020612b3885828601612a38565b9150509250929050565b612b4b81612a17565b82525050565b6000602082019050612b666000830184612b42565b92915050565b600080600060608486031215612b8557612b84612897565b5b6000612b9386828701612aed565b9350506020612ba486828701612aed565b9250506040612bb586828701612a38565b9150509250925092565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612bfc826129ab565b810181811067ffffffffffffffff82111715612c1b57612c1a612bc4565b5b80604052505050565b6000612c2e61288d565b9050612c3a8282612bf3565b919050565b600067ffffffffffffffff821115612c5a57612c59612bc4565b5b602082029050602081019050919050565b600080fd5b6000612c83612c7e84612c3f565b612c24565b90508083825260208201905060208402830185811115612ca657612ca5612c6b565b5b835b81811015612ccf5780612cbb8882612a38565b845260208401935050602081019050612ca8565b5050509392505050565b600082601f830112612cee57612ced612bbf565b5b8135612cfe848260208601612c70565b91505092915050565b600060208284031215612d1d57612d1c612897565b5b600082013567ffffffffffffffff811115612d3b57612d3a61289c565b5b612d4784828501612cd9565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612d8581612a9a565b82525050565b600067ffffffffffffffff82169050919050565b612da881612d8b565b82525050565b612db781612926565b82525050565b600062ffffff82169050919050565b612dd581612dbd565b82525050565b608082016000820151612df16000850182612d7c565b506020820151612e046020850182612d9f565b506040820151612e176040850182612dae565b506060820151612e2a6060850182612dcc565b50505050565b6000612e3c8383612ddb565b60808301905092915050565b6000602082019050919050565b6000612e6082612d50565b612e6a8185612d5b565b9350612e7583612d6c565b8060005b83811015612ea6578151612e8d8882612e30565b9750612e9883612e48565b925050600181019050612e79565b5085935050505092915050565b60006020820190508181036000830152612ecd8184612e55565b905092915050565b600060208284031215612eeb57612eea612897565b5b6000612ef984828501612aed565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612f3781612a17565b82525050565b6000612f498383612f2e565b60208301905092915050565b6000602082019050919050565b6000612f6d82612f02565b612f778185612f0d565b9350612f8283612f1e565b8060005b83811015612fb3578151612f9a8882612f3d565b9750612fa583612f55565b925050600181019050612f86565b5085935050505092915050565b60006020820190508181036000830152612fda8184612f62565b905092915050565b600080600060608486031215612ffb57612ffa612897565b5b600061300986828701612aed565b935050602061301a86828701612a38565b925050604061302b86828701612a38565b9150509250925092565b61303e81612926565b811461304957600080fd5b50565b60008135905061305b81613035565b92915050565b6000806040838503121561307857613077612897565b5b600061308685828601612aed565b92505060206130978582860161304c565b9150509250929050565b600080fd5b600067ffffffffffffffff8211156130c1576130c0612bc4565b5b6130ca826129ab565b9050602081019050919050565b82818337600083830152505050565b60006130f96130f4846130a6565b612c24565b905082815260208101848484011115613115576131146130a1565b5b6131208482856130d7565b509392505050565b600082601f83011261313d5761313c612bbf565b5b813561314d8482602086016130e6565b91505092915050565b600080600080608085870312156131705761316f612897565b5b600061317e87828801612aed565b945050602061318f87828801612aed565b93505060406131a087828801612a38565b925050606085013567ffffffffffffffff8111156131c1576131c061289c565b5b6131cd87828801613128565b91505092959194509250565b6080820160008201516131ef6000850182612d7c565b5060208201516132026020850182612d9f565b5060408201516132156040850182612dae565b5060608201516132286060850182612dcc565b50505050565b600060808201905061324360008301846131d9565b92915050565b600080fd5b60008083601f84011261326457613263612bbf565b5b8235905067ffffffffffffffff81111561328157613280613249565b5b60208301915083602082028301111561329d5761329c612c6b565b5b9250929050565b600080602083850312156132bb576132ba612897565b5b600083013567ffffffffffffffff8111156132d9576132d861289c565b5b6132e58582860161324e565b92509250509250929050565b6000806040838503121561330857613307612897565b5b600061331685828601612aed565b925050602061332785828601612aed565b9150509250929050565b600067ffffffffffffffff82111561334c5761334b612bc4565b5b613355826129ab565b9050602081019050919050565b600061337561337084613331565b612c24565b905082815260208101848484011115613391576133906130a1565b5b61339c8482856130d7565b509392505050565b600082601f8301126133b9576133b8612bbf565b5b81356133c9848260208601613362565b91505092915050565b600080604083850312156133e9576133e8612897565b5b60006133f785828601612a38565b925050602083013567ffffffffffffffff8111156134185761341761289c565b5b613424858286016133a4565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061347557607f821691505b6020821081036134885761348761342e565b5b50919050565b60006060820190506134a36000830186612aac565b6134b06020830185612aac565b6134bd6040830184612b42565b949350505050565b600081519050919050565b600081905092915050565b60006134e6826134c5565b6134f081856134d0565b9350613500818560208601612978565b80840191505092915050565b600061351882846134db565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061358c82612a17565b915061359783612a17565b9250828210156135aa576135a9613552565b5b828203905092915050565b600081905092915050565b60008190508160005260206000209050919050565b600081546135e28161345d565b6135ec81866135b5565b94506001821660008114613607576001811461361c5761364f565b60ff198316865281151582028601935061364f565b613625856135c0565b60005b8381101561364757815481890152600182019150602081019050613628565b838801955050505b50505092915050565b60006136638261295c565b61366d81856135b5565b935061367d818560208601612978565b80840191505092915050565b600061369582856135d5565b91506136a18284613658565b91508190509392505050565b60006136b882612a17565b91506136c383612a17565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156136f8576136f7613552565b5b828201905092915050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026137507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613713565b61375a8683613713565b95508019841693508086168417925050509392505050565b6000819050919050565b600061379761379261378d84612a17565b613772565b612a17565b9050919050565b6000819050919050565b6137b18361377c565b6137c56137bd8261379e565b848454613720565b825550505050565b600090565b6137da6137cd565b6137e58184846137a8565b505050565b5b81811015613809576137fe6000826137d2565b6001810190506137eb565b5050565b601f82111561384e5761381f816135c0565b61382884613703565b81016020851015613837578190505b61384b61384385613703565b8301826137ea565b50505b505050565b600082821c905092915050565b600061387160001984600802613853565b1980831691505092915050565b600061388a8383613860565b9150826002028217905092915050565b6138a38261295c565b67ffffffffffffffff8111156138bc576138bb612bc4565b5b6138c6825461345d565b6138d182828561380d565b600060209050601f83116001811461390457600084156138f2578287015190505b6138fc858261387e565b865550613964565b601f198416613912866135c0565b60005b8281101561393a57848901518255600182019150602085019450602081019050613915565b868310156139575784890151613953601f891682613860565b8355505b6001600288020188555050505b505050505050565b600082825260208201905092915050565b6000613988826134c5565b613992818561396c565b93506139a2818560208601612978565b6139ab816129ab565b840191505092915050565b60006080820190506139cb6000830187612aac565b6139d86020830186612aac565b6139e56040830185612b42565b81810360608301526139f7818461397d565b905095945050505050565b600081519050613a11816128cd565b92915050565b600060208284031215613a2d57613a2c612897565b5b6000613a3b84828501613a02565b91505092915050565b6000613a4f82612a17565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613a8157613a80613552565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000613ac682612a17565b9150613ad183612a17565b925082613ae157613ae0613a8c565b5b828204905092915050565b6000613af782612a17565b9150613b0283612a17565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613b3b57613b3a613552565b5b828202905092915050565b600060ff82169050919050565b6000613b5e82613b46565b9150613b6983613b46565b92508260ff03821115613b7f57613b7e613552565b5b82820190509291505056fea2646970667358221220f422a328cdbd117a27b0a9d6fa2817b4ce9f31920d35191c684b875e9c60816064736f6c634300080f0033

Deployed Bytecode Sourcemap

55103:3929:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16924:615;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22571:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24517:204;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24065:386;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;15978:315;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33782:2800;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58724:305;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;25407:185;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53650:94;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;48584:468;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22360:144;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;17603:224;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;52394:892;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;53881:65;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54009:20;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;22740:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;49442:2503;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24793:308;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;25663:399;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;48005:420;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55574:607;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57695:388;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;25172:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56459:259;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;54867:229;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;53823:51;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16924:615;17009:4;17324:10;17309:25;;:11;:25;;;;:102;;;;17401:10;17386:25;;:11;:25;;;;17309:102;:179;;;;17478:10;17463:25;;:11;:25;;;;17309:179;17289:199;;16924:615;;;:::o;22571:100::-;22625:13;22658:5;22651:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22571:100;:::o;24517:204::-;24585:7;24610:16;24618:7;24610;:16::i;:::-;24605:64;;24635:34;;;;;;;;;;;;;;24605:64;24689:15;:24;24705:7;24689:24;;;;;;;;;;;;;;;;;;;;;24682:31;;24517:204;;;:::o;24065:386::-;24138:13;24154:16;24162:7;24154;:16::i;:::-;24138:32;;24210:5;24187:28;;:19;:17;:19::i;:::-;:28;;;24183:175;;24235:44;24252:5;24259:19;:17;:19::i;:::-;24235:16;:44::i;:::-;24230:128;;24307:35;;;;;;;;;;;;;;24230:128;24183:175;24397:2;24370:15;:24;24386:7;24370:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;24435:7;24431:2;24415:28;;24424:5;24415:28;;;;;;;;;;;;24127:324;24065:386;;:::o;15978:315::-;16031:7;16259:15;:13;:15::i;:::-;16244:12;;16228:13;;:28;:46;16221:53;;15978:315;:::o;33782:2800::-;33916:27;33946;33965:7;33946:18;:27::i;:::-;33916:57;;34031:4;33990:45;;34006:19;33990:45;;;33986:86;;34044:28;;;;;;;;;;;;;;33986:86;34086:27;34115:23;34142:28;34162:7;34142:19;:28::i;:::-;34085:85;;;;34270:62;34289:15;34306:4;34312:19;:17;:19::i;:::-;34270:18;:62::i;:::-;34265:174;;34352:43;34369:4;34375:19;:17;:19::i;:::-;34352:16;:43::i;:::-;34347:92;;34404:35;;;;;;;;;;;;;;34347:92;34265:174;34470:1;34456:16;;:2;:16;;;34452:52;;34481:23;;;;;;;;;;;;;;34452:52;34517:43;34539:4;34545:2;34549:7;34558:1;34517:21;:43::i;:::-;34653:15;34650:160;;;34793:1;34772:19;34765:30;34650:160;35188:18;:24;35207:4;35188:24;;;;;;;;;;;;;;;;35186:26;;;;;;;;;;;;35257:18;:22;35276:2;35257:22;;;;;;;;;;;;;;;;35255:24;;;;;;;;;;;35579:145;35616:2;35664:45;35679:4;35685:2;35689:19;35664:14;:45::i;:::-;13364:8;35637:72;35579:18;:145::i;:::-;35550:17;:26;35568:7;35550:26;;;;;;;;;;;:174;;;;35894:1;13364:8;35844:19;:46;:51;35840:626;;35916:19;35948:1;35938:7;:11;35916:33;;36105:1;36071:17;:30;36089:11;36071:30;;;;;;;;;;;;:35;36067:384;;36209:13;;36194:11;:28;36190:242;;36389:19;36356:17;:30;36374:11;36356:30;;;;;;;;;;;:52;;;;36190:242;36067:384;35897:569;35840:626;36513:7;36509:2;36494:27;;36503:4;36494:27;;;;;;;;;;;;36532:42;36553:4;36559:2;36563:7;36572:1;36532:20;:42::i;:::-;33905:2677;;;33782:2800;;;:::o;58724:305::-;54644:5;;;;;;;;;;;54630:19;;:10;:19;;;54651:17;;;;;;;;;;;;;;;;;54622:47;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;58823:20:::1;58921:4;58928:3;58933:7;58846:95;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58823:118;;58953:12;58971:9;:14;;58986:7;58971:23;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58952:42;;;59013:7;59005:16;;;::::0;::::1;;58812:217;;58724:305:::0;;;:::o;25407:185::-;25545:39;25562:4;25568:2;25572:7;25545:39;;;;;;;;;;;;:16;:39::i;:::-;25407:185;;;:::o;53650:94::-;53716:20;53722:7;53731:4;53716:5;:20::i;:::-;53650:94;:::o;48584:468::-;48673:23;48734:22;48759:8;:15;48734:40;;48789:34;48847:14;48826:36;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;48789:73;;48882:9;48877:125;48898:14;48893:1;:19;48877:125;;48954:32;48974:8;48983:1;48974:11;;;;;;;;:::i;:::-;;;;;;;;48954:19;:32::i;:::-;48938:10;48949:1;48938:13;;;;;;;;:::i;:::-;;;;;;;:48;;;;48914:3;;;;;48877:125;;;;49023:10;49016:17;;;;48584:468;;;:::o;22360:144::-;22424:7;22467:27;22486:7;22467:18;:27::i;:::-;22444:52;;22360:144;;;:::o;17603:224::-;17667:7;17708:1;17691:19;;:5;:19;;;17687:60;;17719:28;;;;;;;;;;;;;;17687:60;12316:13;17765:18;:25;17784:5;17765:25;;;;;;;;;;;;;;;;:54;17758:61;;17603:224;;;:::o;52394:892::-;52464:16;52518:19;52552:25;52592:22;52617:16;52627:5;52617:9;:16::i;:::-;52592:41;;52648:25;52690:14;52676:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52648:57;;52720:31;;:::i;:::-;52771:9;52783:15;:13;:15::i;:::-;52771:27;;52766:472;52815:14;52800:11;:29;52766:472;;52867:15;52880:1;52867:12;:15::i;:::-;52855:27;;52905:9;:16;;;52946:8;52901:73;53022:1;52996:28;;:9;:14;;;:28;;;52992:111;;53069:9;:14;;;53049:34;;52992:111;53146:5;53125:26;;:17;:26;;;53121:102;;53202:1;53176:8;53185:13;;;;;;53176:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;53121:102;52766:472;52831:3;;;;;52766:472;;;;53259:8;53252:15;;;;;;;52394:892;;;:::o;53881:65::-;;;;;;;;;;;;;;;;;;;:::o;54009:20::-;;;;;;;;;;;;;:::o;22740:104::-;22796:13;22829:7;22822:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22740:104;:::o;49442:2503::-;49575:16;49642:4;49633:5;:13;49629:45;;49655:19;;;;;;;;;;;;;;49629:45;49689:19;49723:17;49743:14;:12;:14::i;:::-;49723:34;;49843:15;:13;:15::i;:::-;49835:5;:23;49831:87;;;49887:15;:13;:15::i;:::-;49879:23;;49831:87;49994:9;49987:4;:16;49983:73;;;50031:9;50024:16;;49983:73;50070:25;50098:16;50108:5;50098:9;:16::i;:::-;50070:44;;50292:4;50284:5;:12;50280:278;;;50317:19;50346:5;50339:4;:12;50317:34;;50388:17;50374:11;:31;50370:111;;;50450:11;50430:31;;50370:111;50298:198;50280:278;;;50541:1;50521:21;;50280:278;50572:25;50614:17;50600:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50572:60;;50672:1;50651:17;:22;50647:78;;50701:8;50694:15;;;;;;;;50647:78;50869:31;50903:26;50923:5;50903:19;:26::i;:::-;50869:60;;50944:25;51189:9;:16;;;51184:92;;51246:9;:14;;;51226:34;;51184:92;51295:9;51307:5;51295:17;;51290:478;51319:4;51314:1;:9;;:45;;;;;51342:17;51327:11;:32;;51314:45;51290:478;;;51397:15;51410:1;51397:12;:15::i;:::-;51385:27;;51435:9;:16;;;51476:8;51431:73;51552:1;51526:28;;:9;:14;;;:28;;;51522:111;;51599:9;:14;;;51579:34;;51522:111;51676:5;51655:26;;:17;:26;;;51651:102;;51732:1;51706:8;51715:13;;;;;;51706:23;;;;;;;;:::i;:::-;;;;;;;:27;;;;;51651:102;51290:478;51361:3;;;;;51290:478;;;;51870:11;51860:8;51853:29;51918:8;51911:15;;;;;;;;49442:2503;;;;;;:::o;24793:308::-;24904:19;:17;:19::i;:::-;24892:31;;:8;:31;;;24888:61;;24932:17;;;;;;;;;;;;;;24888:61;25014:8;24962:18;:39;24981:19;:17;:19::i;:::-;24962:39;;;;;;;;;;;;;;;:49;25002:8;24962:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;25074:8;25038:55;;25053:19;:17;:19::i;:::-;25038:55;;;25084:8;25038:55;;;;;;:::i;:::-;;;;;;;;24793:308;;:::o;25663:399::-;25830:31;25843:4;25849:2;25853:7;25830:12;:31::i;:::-;25894:1;25876:2;:14;;;:19;25872:183;;25915:56;25946:4;25952:2;25956:7;25965:5;25915:30;:56::i;:::-;25910:145;;25999:40;;;;;;;;;;;;;;25910:145;25872:183;25663:399;;;;:::o;48005:420::-;48081:21;;:::i;:::-;48115:31;;:::i;:::-;48171:15;:13;:15::i;:::-;48161:7;:25;:54;;;;48201:14;:12;:14::i;:::-;48190:7;:25;;48161:54;48157:103;;;48239:9;48232:16;;;;;48157:103;48282:21;48295:7;48282:12;:21::i;:::-;48270:33;;48318:9;:16;;;48314:65;;;48358:9;48351:16;;;;;48314:65;48396:21;48409:7;48396:12;:21::i;:::-;48389:28;;;48005:420;;;;:::o;55574:607::-;55666:13;55697:16;55705:7;55697;:16::i;:::-;55692:59;;55722:29;;;;;;;;;;;;;;55692:59;55764:14;55781:8;;55764:25;;55800:15;55830:9;55840:1;55830:11;;55826:299;55846:6;55843:1;:9;55826:299;;;55884:8;:11;55893:1;55884:11;;;;;;;;;;;;55873:7;:22;55870:176;;55916:11;55940:7;55930;:17;;;;:::i;:::-;55916:31;;55997:13;:16;56011:1;55997:16;;;;;;;;;;;56015:13;56024:3;56015:8;:13::i;:::-;55980:49;;;;;;;;;:::i;:::-;;;;;;;;;;;;;55966:64;;;;;;;;55870:176;56070:8;:11;56079:1;56070:11;;;;;;;;;;;;56060:21;;56108:3;;;;;;;55826:299;;;;56144:29;;;;;;;;;;;;;;55574:607;;;;:::o;57695:388::-;54644:5;;;;;;;;;;;54630:19;;:10;:19;;;54651:17;;;;;;;;;;;;;;;;;54622:47;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;57773:14:::1;57790:8;;:15;;57773:32;;57814:13;57830:29;57848:10;57830:17;:29::i;:::-;57814:45;;57868:22;57893:50;57909:10;57921:5;57936:6;57928:5;:14;;;;:::i;:::-;57893:15;:50::i;:::-;57868:75;;57956:9;57952:124;57971:6;57969:1;:8;57952:124;;;57991:47;58004:10;58016:8;;58025:1;58016:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;58029:5;58035:1;58029:8;;;;;;;;:::i;:::-;;;;;;;;57991:12;:47::i;:::-;58061:3;;;;;;;57952:124;;;;57764:319;;;57695:388:::0;;:::o;25172:164::-;25269:4;25293:18;:25;25312:5;25293:25;;;;;;;;;;;;;;;:35;25319:8;25293:35;;;;;;;;;;;;;;;;;;;;;;;;;25286:42;;25172:164;;;;:::o;56459:259::-;54644:5;;;;;;;;;;;54630:19;;:10;:19;;;54651:17;;;;;;;;;;;;;;;;;54622:47;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;56582:9:::1;56566:13;:11;:13::i;:::-;:25;;;;:::i;:::-;56545:8;:18;56554:8;;56545:18;;;;;;;;;;;:46;;;;56628:4;56602:13;:23;56616:8;;56602:23;;;;;;;;;;;:30;;;;;;:::i;:::-;;56655:8;;:10;;;;;;;;;;;;;56678:32;56688:10;56700:9;56678;:32::i;:::-;56459:259:::0;;:::o;54867:229::-;54644:5;;;;;;;;;;;54630:19;;:10;:19;;;54651:17;;;;;;;;;;;;;;;;;54622:47;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;54970:1:::1;54949:23;;:9;:23;;;;54974:31;;;;;;;;;;;;;;;;::::0;54941:65:::1;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;55050:9;55022:38;;55043:5;;;;;;;;;;;55022:38;;;;;;;;;;;;55079:9;55071:5;;:17;;;;;;;;;;;;;;;;;;54867:229:::0;:::o;53823:51::-;;;;;;;;;;;;;;;;;;;:::o;26317:273::-;26374:4;26430:7;26411:15;:13;:15::i;:::-;:26;;:66;;;;;26464:13;;26454:7;:23;26411:66;:152;;;;;26562:1;13086:8;26515:17;:26;26533:7;26515:26;;;;;;;;;;;;:43;:48;26411:152;26391:172;;26317:273;;;:::o;44878:105::-;44938:7;44965:10;44958:17;;44878:105;:::o;15502:92::-;15558:7;15502:92;:::o;19277:1129::-;19344:7;19364:12;19379:7;19364:22;;19447:4;19428:15;:13;:15::i;:::-;:23;19424:915;;19481:13;;19474:4;:20;19470:869;;;19519:14;19536:17;:23;19554:4;19536:23;;;;;;;;;;;;19519:40;;19652:1;13086:8;19625:6;:23;:28;19621:699;;20144:113;20161:1;20151:6;:11;20144:113;;20204:17;:25;20222:6;;;;;;;20204:25;;;;;;;;;;;;20195:34;;20144:113;;;20290:6;20283:13;;;;;;19621:699;19496:843;19470:869;19424:915;20367:31;;;;;;;;;;;;;;19277:1129;;;;:::o;32118:652::-;32213:27;32242:23;32283:53;32339:15;32283:71;;32525:7;32519:4;32512:21;32560:22;32554:4;32547:36;32636:4;32630;32620:21;32597:44;;32732:19;32726:26;32707:45;;32463:300;32118:652;;;:::o;32883:645::-;33025:11;33187:15;33181:4;33177:26;33169:34;;33346:15;33335:9;33331:31;33318:44;;33493:15;33482:9;33479:30;33472:4;33461:9;33458:19;33455:55;33445:65;;32883:645;;;;;:::o;43711:159::-;;;;;:::o;42023:309::-;42158:7;42178:16;13487:3;42204:19;:40;;42178:67;;13487:3;42271:31;42282:4;42288:2;42292:9;42271:10;:31::i;:::-;42263:40;;:61;;42256:68;;;42023:309;;;;;:::o;21851:447::-;21931:14;22099:15;22092:5;22088:27;22079:36;;22273:5;22259:11;22235:22;22231:40;22228:51;22221:5;22218:62;22208:72;;21851:447;;;;:::o;44529:158::-;;;;;:::o;36978:3063::-;37058:27;37088;37107:7;37088:18;:27::i;:::-;37058:57;;37128:12;37159:19;37128:52;;37194:27;37223:23;37250:28;37270:7;37250:19;:28::i;:::-;37193:85;;;;37295:13;37291:310;;;37416:62;37435:15;37452:4;37458:19;:17;:19::i;:::-;37416:18;:62::i;:::-;37411:178;;37502:43;37519:4;37525:19;:17;:19::i;:::-;37502:16;:43::i;:::-;37497:92;;37554:35;;;;;;;;;;;;;;37497:92;37411:178;37291:310;37613:51;37635:4;37649:1;37653:7;37662:1;37613:21;:51::i;:::-;37757:15;37754:160;;;37897:1;37876:19;37869:30;37754:160;38573:1;12579:3;38544:1;:25;;38543:31;38515:18;:24;38534:4;38515:24;;;;;;;;;;;;;;;;:59;;;;;;;;;;;38841:174;38878:4;38947:53;38962:4;38976:1;38980:19;38947:14;:53::i;:::-;13364:8;13086;38902:41;38901:99;38841:18;:174::i;:::-;38812:17;:26;38830:7;38812:26;;;;;;;;;;;:203;;;;39185:1;13364:8;39135:19;:46;:51;39131:626;;39207:19;39239:1;39229:7;:11;39207:33;;39396:1;39362:17;:30;39380:11;39362:30;;;;;;;;;;;;:35;39358:384;;39500:13;;39485:11;:28;39481:242;;39680:19;39647:17;:30;39665:11;39647:30;;;;;;;;;;;:52;;;;39481:242;39358:384;39188:569;39131:626;39812:7;39808:1;39785:35;;39794:4;39785:35;;;;;;;;;;;;39831:50;39852:4;39866:1;39870:7;39879:1;39831:20;:50::i;:::-;40008:12;;:14;;;;;;;;;;;;;37047:2994;;;;36978:3063;;:::o;20954:153::-;21014:21;;:::i;:::-;21055:44;21074:17;:24;21092:5;21074:24;;;;;;;;;;;;21055:18;:44::i;:::-;21048:51;;20954:153;;;:::o;15673:95::-;15720:7;15747:13;;15740:20;;15673:95;:::o;40533:716::-;40696:4;40742:2;40717:45;;;40763:19;:17;:19::i;:::-;40784:4;40790:7;40799:5;40717:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;40713:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41017:1;41000:6;:13;:18;40996:235;;41046:40;;;;;;;;;;;;;;40996:235;41189:6;41183:13;41174:6;41170:2;41166:15;41159:38;40713:529;40886:54;;;40876:64;;;:6;:64;;;;40869:71;;;40533:716;;;;;;:::o;21610:158::-;21672:21;;:::i;:::-;21713:47;21732:27;21751:7;21732:18;:27::i;:::-;21713:18;:47::i;:::-;21706:54;;21610:158;;;:::o;58165:551::-;58215:27;58265:1;58259:2;:7;58255:28;;58270:10;;;;;;;;;;;;;;;;;;;;;58255:28;58293:6;58302:2;58293:11;;58315:8;58334:69;58346:1;58341;:6;58334:69;;58364:5;;;;;:::i;:::-;;;;58389:2;58384:7;;;;;:::i;:::-;;;58334:69;;;58413:17;58443:3;58433:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58413:34;;58458:6;58467:3;58458:12;;58481:198;58494:1;58488:2;:7;58481:198;;58518:1;58516;:3;;;;:::i;:::-;58512:7;;58534:10;58574:2;58569;58564;:7;;;;:::i;:::-;:12;;;;:::i;:::-;58559:2;:17;;;;:::i;:::-;58548:2;:29;;;;:::i;:::-;58534:44;;58593:9;58612:4;58605:12;;58593:24;;58642:2;58632:4;58637:1;58632:7;;;;;;;;:::i;:::-;;;;;:12;;;;;;;;;;;58665:2;58659:8;;;;;:::i;:::-;;;58497:182;;58481:198;;;58703:4;58689:19;;;;;;58165:551;;;;:::o;56726:877::-;56794:15;56847:19;56881:25;56921:22;56946:16;56956:5;56946:9;:16::i;:::-;56921:41;;56977:31;;:::i;:::-;57028:9;57040:15;:13;:15::i;:::-;57028:27;;57023:484;57072:14;57057:11;:29;57023:484;;57124:15;57137:1;57124:12;:15::i;:::-;57112:27;;57162:9;:16;;;57203:8;57158:73;57279:1;57253:28;;:9;:14;;;:28;;;57249:111;;57326:9;:14;;;57306:34;;57249:111;57403:5;57382:26;;:17;:26;;;57378:114;;57443:1;57433:11;;57467:5;;57378:114;57023:484;57088:3;;;;;57023:484;;;;57535:1;57524:7;:12;:50;;;;;57564:10;57540:34;;:15;57553:1;57540:12;:15::i;:::-;:20;;;:34;;;;57524:50;57521:63;;;57576:8;;;57521:63;56822:774;;;;56726:877;;;:::o;26674:104::-;26743:27;26753:2;26757:8;26743:27;;;;;;;;;;;;:9;:27::i;:::-;26674:104;;:::o;42908:147::-;43045:6;42908:147;;;;;:::o;20500:363::-;20566:31;;:::i;:::-;20643:6;20610:9;:14;;:41;;;;;;;;;;;12970:3;20696:6;:32;;20662:9;:24;;:67;;;;;;;;;;;20786:1;13086:8;20759:6;:23;:28;;20740:9;:16;;:47;;;;;;;;;;;13487:3;20827:6;:27;;20798:9;:19;;:57;;;;;;;;;;;20500:363;;;:::o;27194:681::-;27317:19;27323:2;27327:8;27317:5;:19::i;:::-;27396:1;27378:2;:14;;;:19;27374:483;;27418:11;27432:13;;27418:27;;27464:13;27486:8;27480:3;:14;27464:30;;27513:233;27544:62;27583:1;27587:2;27591:7;;;;;;27600:5;27544:30;:62::i;:::-;27539:167;;27642:40;;;;;;;;;;;;;;27539:167;27741:3;27733:5;:11;27513:233;;27828:3;27811:13;;:20;27807:34;;27833:8;;;27807:34;27399:458;;27374:483;27194:681;;;:::o;28148:1529::-;28213:20;28236:13;;28213:36;;28278:1;28264:16;;:2;:16;;;28260:48;;28289:19;;;;;;;;;;;;;;28260:48;28335:1;28323:8;:13;28319:44;;28345:18;;;;;;;;;;;;;;28319:44;28376:61;28406:1;28410:2;28414:12;28428:8;28376:21;:61::i;:::-;28919:1;12453:2;28890:1;:25;;28889:31;28877:8;:44;28851:18;:22;28870:2;28851:22;;;;;;;;;;;;;;;;:70;;;;;;;;;;;29198:139;29235:2;29289:33;29312:1;29316:2;29320:1;29289:14;:33::i;:::-;29256:30;29277:8;29256:20;:30::i;:::-;:66;29198:18;:139::i;:::-;29164:17;:31;29182:12;29164:31;;;;;;;;;;;:173;;;;29354:15;29372:12;29354:30;;29399:11;29428:8;29413:12;:23;29399:37;;29451:101;29503:9;;;;;;29499:2;29478:35;;29495:1;29478:35;;;;;;;;;;;;29547:3;29537:7;:13;29451:101;;29584:3;29568:13;:19;;;;28625:974;;29609:60;29638:1;29642:2;29646:12;29660:8;29609:20;:60::i;:::-;28202:1475;28148:1529;;:::o;23681:322::-;23751:14;23982:1;23972:8;23969:15;23944:23;23940:45;23930:55;;23681:322;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::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:180;6086:77;6083:1;6076:88;6183:4;6180:1;6173:15;6207:4;6204:1;6197:15;6224:281;6307:27;6329:4;6307:27;:::i;:::-;6299:6;6295:40;6437:6;6425:10;6422:22;6401:18;6389:10;6386:34;6383:62;6380:88;;;6448:18;;:::i;:::-;6380:88;6488:10;6484:2;6477:22;6267:238;6224:281;;:::o;6511:129::-;6545:6;6572:20;;:::i;:::-;6562:30;;6601:33;6629:4;6621:6;6601:33;:::i;:::-;6511:129;;;:::o;6646:311::-;6723:4;6813:18;6805:6;6802:30;6799:56;;;6835:18;;:::i;:::-;6799:56;6885:4;6877:6;6873:17;6865:25;;6945:4;6939;6935:15;6927:23;;6646:311;;;:::o;6963:117::-;7072:1;7069;7062:12;7103:710;7199:5;7224:81;7240:64;7297:6;7240:64;:::i;:::-;7224:81;:::i;:::-;7215:90;;7325:5;7354:6;7347:5;7340:21;7388:4;7381:5;7377:16;7370:23;;7441:4;7433:6;7429:17;7421:6;7417:30;7470:3;7462:6;7459:15;7456:122;;;7489:79;;:::i;:::-;7456:122;7604:6;7587:220;7621:6;7616:3;7613:15;7587:220;;;7696:3;7725:37;7758:3;7746:10;7725:37;:::i;:::-;7720:3;7713:50;7792:4;7787:3;7783:14;7776:21;;7663:144;7647:4;7642:3;7638:14;7631:21;;7587:220;;;7591:21;7205:608;;7103:710;;;;;:::o;7836:370::-;7907:5;7956:3;7949:4;7941:6;7937:17;7933:27;7923:122;;7964:79;;:::i;:::-;7923:122;8081:6;8068:20;8106:94;8196:3;8188:6;8181:4;8173:6;8169:17;8106:94;:::i;:::-;8097:103;;7913:293;7836:370;;;;:::o;8212:539::-;8296:6;8345:2;8333:9;8324:7;8320:23;8316:32;8313:119;;;8351:79;;:::i;:::-;8313:119;8499:1;8488:9;8484:17;8471:31;8529:18;8521:6;8518:30;8515:117;;;8551:79;;:::i;:::-;8515:117;8656:78;8726:7;8717:6;8706:9;8702:22;8656:78;:::i;:::-;8646:88;;8442:302;8212:539;;;;:::o;8757:144::-;8854:6;8888:5;8882:12;8872:22;;8757:144;;;:::o;8907:214::-;9036:11;9070:6;9065:3;9058:19;9110:4;9105:3;9101:14;9086:29;;8907:214;;;;:::o;9127:162::-;9224:4;9247:3;9239:11;;9277:4;9272:3;9268:14;9260:22;;9127:162;;;:::o;9295:108::-;9372:24;9390:5;9372:24;:::i;:::-;9367:3;9360:37;9295:108;;:::o;9409:101::-;9445:7;9485:18;9478:5;9474:30;9463:41;;9409:101;;;:::o;9516:105::-;9591:23;9608:5;9591:23;:::i;:::-;9586:3;9579:36;9516:105;;:::o;9627:99::-;9698:21;9713:5;9698:21;:::i;:::-;9693:3;9686:34;9627:99;;:::o;9732:91::-;9768:7;9808:8;9801:5;9797:20;9786:31;;9732:91;;;:::o;9829:105::-;9904:23;9921:5;9904:23;:::i;:::-;9899:3;9892:36;9829:105;;:::o;10012:862::-;10159:4;10154:3;10150:14;10246:4;10239:5;10235:16;10229:23;10265:63;10322:4;10317:3;10313:14;10299:12;10265:63;:::i;:::-;10174:164;10430:4;10423:5;10419:16;10413:23;10449:61;10504:4;10499:3;10495:14;10481:12;10449:61;:::i;:::-;10348:172;10604:4;10597:5;10593:16;10587:23;10623:57;10674:4;10669:3;10665:14;10651:12;10623:57;:::i;:::-;10530:160;10777:4;10770:5;10766:16;10760:23;10796:61;10851:4;10846:3;10842:14;10828:12;10796:61;:::i;:::-;10700:167;10128:746;10012:862;;:::o;10880:299::-;11009:10;11030:106;11132:3;11124:6;11030:106;:::i;:::-;11168:4;11163:3;11159:14;11145:28;;10880:299;;;;:::o;11185:143::-;11285:4;11317;11312:3;11308:14;11300:22;;11185:143;;;:::o;11410:972::-;11589:3;11618:84;11696:5;11618:84;:::i;:::-;11718:116;11827:6;11822:3;11718:116;:::i;:::-;11711:123;;11858:86;11938:5;11858:86;:::i;:::-;11967:7;11998:1;11983:374;12008:6;12005:1;12002:13;11983:374;;;12084:6;12078:13;12111:123;12230:3;12215:13;12111:123;:::i;:::-;12104:130;;12257:90;12340:6;12257:90;:::i;:::-;12247:100;;12043:314;12030:1;12027;12023:9;12018:14;;11983:374;;;11987:14;12373:3;12366:10;;11594:788;;;11410:972;;;;:::o;12388:493::-;12591:4;12629:2;12618:9;12614:18;12606:26;;12678:9;12672:4;12668:20;12664:1;12653:9;12649:17;12642:47;12706:168;12869:4;12860:6;12706:168;:::i;:::-;12698:176;;12388:493;;;;:::o;12887:329::-;12946:6;12995:2;12983:9;12974:7;12970:23;12966:32;12963:119;;;13001:79;;:::i;:::-;12963:119;13121:1;13146:53;13191:7;13182:6;13171:9;13167:22;13146:53;:::i;:::-;13136:63;;13092:117;12887:329;;;;:::o;13222:114::-;13289:6;13323:5;13317:12;13307:22;;13222:114;;;:::o;13342:184::-;13441:11;13475:6;13470:3;13463:19;13515:4;13510:3;13506:14;13491:29;;13342:184;;;;:::o;13532:132::-;13599:4;13622:3;13614:11;;13652:4;13647:3;13643:14;13635:22;;13532:132;;;:::o;13670:108::-;13747:24;13765:5;13747:24;:::i;:::-;13742:3;13735:37;13670:108;;:::o;13784:179::-;13853:10;13874:46;13916:3;13908:6;13874:46;:::i;:::-;13952:4;13947:3;13943:14;13929:28;;13784:179;;;;:::o;13969:113::-;14039:4;14071;14066:3;14062:14;14054:22;;13969:113;;;:::o;14118:732::-;14237:3;14266:54;14314:5;14266:54;:::i;:::-;14336:86;14415:6;14410:3;14336:86;:::i;:::-;14329:93;;14446:56;14496:5;14446:56;:::i;:::-;14525:7;14556:1;14541:284;14566:6;14563:1;14560:13;14541:284;;;14642:6;14636:13;14669:63;14728:3;14713:13;14669:63;:::i;:::-;14662:70;;14755:60;14808:6;14755:60;:::i;:::-;14745:70;;14601:224;14588:1;14585;14581:9;14576:14;;14541:284;;;14545:14;14841:3;14834:10;;14242:608;;;14118:732;;;;:::o;14856:373::-;14999:4;15037:2;15026:9;15022:18;15014:26;;15086:9;15080:4;15076:20;15072:1;15061:9;15057:17;15050:47;15114:108;15217:4;15208:6;15114:108;:::i;:::-;15106:116;;14856:373;;;;:::o;15235:619::-;15312:6;15320;15328;15377:2;15365:9;15356:7;15352:23;15348:32;15345:119;;;15383:79;;:::i;:::-;15345:119;15503:1;15528:53;15573:7;15564:6;15553:9;15549:22;15528:53;:::i;:::-;15518:63;;15474:117;15630:2;15656:53;15701:7;15692:6;15681:9;15677:22;15656:53;:::i;:::-;15646:63;;15601:118;15758:2;15784:53;15829:7;15820:6;15809:9;15805:22;15784:53;:::i;:::-;15774:63;;15729:118;15235:619;;;;;:::o;15860:116::-;15930:21;15945:5;15930:21;:::i;:::-;15923:5;15920:32;15910:60;;15966:1;15963;15956:12;15910:60;15860:116;:::o;15982:133::-;16025:5;16063:6;16050:20;16041:29;;16079:30;16103:5;16079:30;:::i;:::-;15982:133;;;;:::o;16121:468::-;16186:6;16194;16243:2;16231:9;16222:7;16218:23;16214:32;16211:119;;;16249:79;;:::i;:::-;16211:119;16369:1;16394:53;16439:7;16430:6;16419:9;16415:22;16394:53;:::i;:::-;16384:63;;16340:117;16496:2;16522:50;16564:7;16555:6;16544:9;16540:22;16522:50;:::i;:::-;16512:60;;16467:115;16121:468;;;;;:::o;16595:117::-;16704:1;16701;16694:12;16718:307;16779:4;16869:18;16861:6;16858:30;16855:56;;;16891:18;;:::i;:::-;16855:56;16929:29;16951:6;16929:29;:::i;:::-;16921:37;;17013:4;17007;17003:15;16995:23;;16718:307;;;:::o;17031:154::-;17115:6;17110:3;17105;17092:30;17177:1;17168:6;17163:3;17159:16;17152:27;17031:154;;;:::o;17191:410::-;17268:5;17293:65;17309:48;17350:6;17309:48;:::i;:::-;17293:65;:::i;:::-;17284:74;;17381:6;17374:5;17367:21;17419:4;17412:5;17408:16;17457:3;17448:6;17443:3;17439:16;17436:25;17433:112;;;17464:79;;:::i;:::-;17433:112;17554:41;17588:6;17583:3;17578;17554:41;:::i;:::-;17274:327;17191:410;;;;;:::o;17620:338::-;17675:5;17724:3;17717:4;17709:6;17705:17;17701:27;17691:122;;17732:79;;:::i;:::-;17691:122;17849:6;17836:20;17874:78;17948:3;17940:6;17933:4;17925:6;17921:17;17874:78;:::i;:::-;17865:87;;17681:277;17620:338;;;;:::o;17964:943::-;18059:6;18067;18075;18083;18132:3;18120:9;18111:7;18107:23;18103:33;18100:120;;;18139:79;;:::i;:::-;18100:120;18259:1;18284:53;18329:7;18320:6;18309:9;18305:22;18284:53;:::i;:::-;18274:63;;18230:117;18386:2;18412:53;18457:7;18448:6;18437:9;18433:22;18412:53;:::i;:::-;18402:63;;18357:118;18514:2;18540:53;18585:7;18576:6;18565:9;18561:22;18540:53;:::i;:::-;18530:63;;18485:118;18670:2;18659:9;18655:18;18642:32;18701:18;18693:6;18690:30;18687:117;;;18723:79;;:::i;:::-;18687:117;18828:62;18882:7;18873:6;18862:9;18858:22;18828:62;:::i;:::-;18818:72;;18613:287;17964:943;;;;;;;:::o;18985:872::-;19142:4;19137:3;19133:14;19229:4;19222:5;19218:16;19212:23;19248:63;19305:4;19300:3;19296:14;19282:12;19248:63;:::i;:::-;19157:164;19413:4;19406:5;19402:16;19396:23;19432:61;19487:4;19482:3;19478:14;19464:12;19432:61;:::i;:::-;19331:172;19587:4;19580:5;19576:16;19570:23;19606:57;19657:4;19652:3;19648:14;19634:12;19606:57;:::i;:::-;19513:160;19760:4;19753:5;19749:16;19743:23;19779:61;19834:4;19829:3;19825:14;19811:12;19779:61;:::i;:::-;19683:167;19111:746;18985:872;;:::o;19863:343::-;20016:4;20054:3;20043:9;20039:19;20031:27;;20068:131;20196:1;20185:9;20181:17;20172:6;20068:131;:::i;:::-;19863:343;;;;:::o;20212:117::-;20321:1;20318;20311:12;20352:568;20425:8;20435:6;20485:3;20478:4;20470:6;20466:17;20462:27;20452:122;;20493:79;;:::i;:::-;20452:122;20606:6;20593:20;20583:30;;20636:18;20628:6;20625:30;20622:117;;;20658:79;;:::i;:::-;20622:117;20772:4;20764:6;20760:17;20748:29;;20826:3;20818:4;20810:6;20806:17;20796:8;20792:32;20789:41;20786:128;;;20833:79;;:::i;:::-;20786:128;20352:568;;;;;:::o;20926:559::-;21012:6;21020;21069:2;21057:9;21048:7;21044:23;21040:32;21037:119;;;21075:79;;:::i;:::-;21037:119;21223:1;21212:9;21208:17;21195:31;21253:18;21245:6;21242:30;21239:117;;;21275:79;;:::i;:::-;21239:117;21388:80;21460:7;21451:6;21440:9;21436:22;21388:80;:::i;:::-;21370:98;;;;21166:312;20926:559;;;;;:::o;21491:474::-;21559:6;21567;21616:2;21604:9;21595:7;21591:23;21587:32;21584:119;;;21622:79;;:::i;:::-;21584:119;21742:1;21767:53;21812:7;21803:6;21792:9;21788:22;21767:53;:::i;:::-;21757:63;;21713:117;21869:2;21895:53;21940:7;21931:6;21920:9;21916:22;21895:53;:::i;:::-;21885:63;;21840:118;21491:474;;;;;:::o;21971:308::-;22033:4;22123:18;22115:6;22112:30;22109:56;;;22145:18;;:::i;:::-;22109:56;22183:29;22205:6;22183:29;:::i;:::-;22175:37;;22267:4;22261;22257:15;22249:23;;21971:308;;;:::o;22285:412::-;22363:5;22388:66;22404:49;22446:6;22404:49;:::i;:::-;22388:66;:::i;:::-;22379:75;;22477:6;22470:5;22463:21;22515:4;22508:5;22504:16;22553:3;22544:6;22539:3;22535:16;22532:25;22529:112;;;22560:79;;:::i;:::-;22529:112;22650:41;22684:6;22679:3;22674;22650:41;:::i;:::-;22369:328;22285:412;;;;;:::o;22717:340::-;22773:5;22822:3;22815:4;22807:6;22803:17;22799:27;22789:122;;22830:79;;:::i;:::-;22789:122;22947:6;22934:20;22972:79;23047:3;23039:6;23032:4;23024:6;23020:17;22972:79;:::i;:::-;22963:88;;22779:278;22717:340;;;;:::o;23063:654::-;23141:6;23149;23198:2;23186:9;23177:7;23173:23;23169:32;23166:119;;;23204:79;;:::i;:::-;23166:119;23324:1;23349:53;23394:7;23385:6;23374:9;23370:22;23349:53;:::i;:::-;23339:63;;23295:117;23479:2;23468:9;23464:18;23451:32;23510:18;23502:6;23499:30;23496:117;;;23532:79;;:::i;:::-;23496:117;23637:63;23692:7;23683:6;23672:9;23668:22;23637:63;:::i;:::-;23627:73;;23422:288;23063:654;;;;;:::o;23723:180::-;23771:77;23768:1;23761:88;23868:4;23865:1;23858:15;23892:4;23889:1;23882:15;23909:320;23953:6;23990:1;23984:4;23980:12;23970:22;;24037:1;24031:4;24027:12;24058:18;24048:81;;24114:4;24106:6;24102:17;24092:27;;24048:81;24176:2;24168:6;24165:14;24145:18;24142:38;24139:84;;24195:18;;:::i;:::-;24139:84;23960:269;23909:320;;;:::o;24235:442::-;24384:4;24422:2;24411:9;24407:18;24399:26;;24435:71;24503:1;24492:9;24488:17;24479:6;24435:71;:::i;:::-;24516:72;24584:2;24573:9;24569:18;24560:6;24516:72;:::i;:::-;24598;24666:2;24655:9;24651:18;24642:6;24598:72;:::i;:::-;24235:442;;;;;;:::o;24683:98::-;24734:6;24768:5;24762:12;24752:22;;24683:98;;;:::o;24787:147::-;24888:11;24925:3;24910:18;;24787:147;;;;:::o;24940:373::-;25044:3;25072:38;25104:5;25072:38;:::i;:::-;25126:88;25207:6;25202:3;25126:88;:::i;:::-;25119:95;;25223:52;25268:6;25263:3;25256:4;25249:5;25245:16;25223:52;:::i;:::-;25300:6;25295:3;25291:16;25284:23;;25048:265;24940:373;;;;:::o;25319:271::-;25449:3;25471:93;25560:3;25551:6;25471:93;:::i;:::-;25464:100;;25581:3;25574:10;;25319:271;;;;:::o;25596:180::-;25644:77;25641:1;25634:88;25741:4;25738:1;25731:15;25765:4;25762:1;25755:15;25782:180;25830:77;25827:1;25820:88;25927:4;25924:1;25917:15;25951:4;25948:1;25941:15;25968:191;26008:4;26028:20;26046:1;26028:20;:::i;:::-;26023:25;;26062:20;26080:1;26062:20;:::i;:::-;26057:25;;26101:1;26098;26095:8;26092:34;;;26106:18;;:::i;:::-;26092:34;26151:1;26148;26144:9;26136:17;;25968:191;;;;:::o;26165:148::-;26267:11;26304:3;26289:18;;26165:148;;;;:::o;26319:141::-;26368:4;26391:3;26383:11;;26414:3;26411:1;26404:14;26448:4;26445:1;26435:18;26427:26;;26319:141;;;:::o;26490:874::-;26593:3;26630:5;26624:12;26659:36;26685:9;26659:36;:::i;:::-;26711:89;26793:6;26788:3;26711:89;:::i;:::-;26704:96;;26831:1;26820:9;26816:17;26847:1;26842:166;;;;27022:1;27017:341;;;;26809:549;;26842:166;26926:4;26922:9;26911;26907:25;26902:3;26895:38;26988:6;26981:14;26974:22;26966:6;26962:35;26957:3;26953:45;26946:52;;26842:166;;27017:341;27084:38;27116:5;27084:38;:::i;:::-;27144:1;27158:154;27172:6;27169:1;27166:13;27158:154;;;27246:7;27240:14;27236:1;27231:3;27227:11;27220:35;27296:1;27287:7;27283:15;27272:26;;27194:4;27191:1;27187:12;27182:17;;27158:154;;;27341:6;27336:3;27332:16;27325:23;;27024:334;;26809:549;;26597:767;;26490:874;;;;:::o;27370:377::-;27476:3;27504:39;27537:5;27504:39;:::i;:::-;27559:89;27641:6;27636:3;27559:89;:::i;:::-;27552:96;;27657:52;27702:6;27697:3;27690:4;27683:5;27679:16;27657:52;:::i;:::-;27734:6;27729:3;27725:16;27718:23;;27480:267;27370:377;;;;:::o;27753:429::-;27930:3;27952:92;28040:3;28031:6;27952:92;:::i;:::-;27945:99;;28061:95;28152:3;28143:6;28061:95;:::i;:::-;28054:102;;28173:3;28166:10;;27753:429;;;;;:::o;28188:305::-;28228:3;28247:20;28265:1;28247:20;:::i;:::-;28242:25;;28281:20;28299:1;28281:20;:::i;:::-;28276:25;;28435:1;28367:66;28363:74;28360:1;28357:81;28354:107;;;28441:18;;:::i;:::-;28354:107;28485:1;28482;28478:9;28471:16;;28188:305;;;;:::o;28499:93::-;28536:6;28583:2;28578;28571:5;28567:14;28563:23;28553:33;;28499:93;;;:::o;28598:107::-;28642:8;28692:5;28686:4;28682:16;28661:37;;28598:107;;;;:::o;28711:393::-;28780:6;28830:1;28818:10;28814:18;28853:97;28883:66;28872:9;28853:97;:::i;:::-;28971:39;29001:8;28990:9;28971:39;:::i;:::-;28959:51;;29043:4;29039:9;29032:5;29028:21;29019:30;;29092:4;29082:8;29078:19;29071:5;29068:30;29058:40;;28787:317;;28711:393;;;;;:::o;29110:60::-;29138:3;29159:5;29152:12;;29110:60;;;:::o;29176:142::-;29226:9;29259:53;29277:34;29286:24;29304:5;29286:24;:::i;:::-;29277:34;:::i;:::-;29259:53;:::i;:::-;29246:66;;29176:142;;;:::o;29324:75::-;29367:3;29388:5;29381:12;;29324:75;;;:::o;29405:269::-;29515:39;29546:7;29515:39;:::i;:::-;29576:91;29625:41;29649:16;29625:41;:::i;:::-;29617:6;29610:4;29604:11;29576:91;:::i;:::-;29570:4;29563:105;29481:193;29405:269;;;:::o;29680:73::-;29725:3;29680:73;:::o;29759:189::-;29836:32;;:::i;:::-;29877:65;29935:6;29927;29921:4;29877:65;:::i;:::-;29812:136;29759:189;;:::o;29954:186::-;30014:120;30031:3;30024:5;30021:14;30014:120;;;30085:39;30122:1;30115:5;30085:39;:::i;:::-;30058:1;30051:5;30047:13;30038:22;;30014:120;;;29954:186;;:::o;30146:543::-;30247:2;30242:3;30239:11;30236:446;;;30281:38;30313:5;30281:38;:::i;:::-;30365:29;30383:10;30365:29;:::i;:::-;30355:8;30351:44;30548:2;30536:10;30533:18;30530:49;;;30569:8;30554:23;;30530:49;30592:80;30648:22;30666:3;30648:22;:::i;:::-;30638:8;30634:37;30621:11;30592:80;:::i;:::-;30251:431;;30236:446;30146:543;;;:::o;30695:117::-;30749:8;30799:5;30793:4;30789:16;30768:37;;30695:117;;;;:::o;30818:169::-;30862:6;30895:51;30943:1;30939:6;30931:5;30928:1;30924:13;30895:51;:::i;:::-;30891:56;30976:4;30970;30966:15;30956:25;;30869:118;30818:169;;;;:::o;30992:295::-;31068:4;31214:29;31239:3;31233:4;31214:29;:::i;:::-;31206:37;;31276:3;31273:1;31269:11;31263:4;31260:21;31252:29;;30992:295;;;;:::o;31292:1395::-;31409:37;31442:3;31409:37;:::i;:::-;31511:18;31503:6;31500:30;31497:56;;;31533:18;;:::i;:::-;31497:56;31577:38;31609:4;31603:11;31577:38;:::i;:::-;31662:67;31722:6;31714;31708:4;31662:67;:::i;:::-;31756:1;31780:4;31767:17;;31812:2;31804:6;31801:14;31829:1;31824:618;;;;32486:1;32503:6;32500:77;;;32552:9;32547:3;32543:19;32537:26;32528:35;;32500:77;32603:67;32663:6;32656:5;32603:67;:::i;:::-;32597:4;32590:81;32459:222;31794:887;;31824:618;31876:4;31872:9;31864:6;31860:22;31910:37;31942:4;31910:37;:::i;:::-;31969:1;31983:208;31997:7;31994:1;31991:14;31983:208;;;32076:9;32071:3;32067:19;32061:26;32053:6;32046:42;32127:1;32119:6;32115:14;32105:24;;32174:2;32163:9;32159:18;32146:31;;32020:4;32017:1;32013:12;32008:17;;31983:208;;;32219:6;32210:7;32207:19;32204:179;;;32277:9;32272:3;32268:19;32262:26;32320:48;32362:4;32354:6;32350:17;32339:9;32320:48;:::i;:::-;32312:6;32305:64;32227:156;32204:179;32429:1;32425;32417:6;32413:14;32409:22;32403:4;32396:36;31831:611;;;31794:887;;31384:1303;;;31292:1395;;:::o;32693:168::-;32776:11;32810:6;32805:3;32798:19;32850:4;32845:3;32841:14;32826:29;;32693:168;;;;:::o;32867:360::-;32953:3;32981:38;33013:5;32981:38;:::i;:::-;33035:70;33098:6;33093:3;33035:70;:::i;:::-;33028:77;;33114:52;33159:6;33154:3;33147:4;33140:5;33136:16;33114:52;:::i;:::-;33191:29;33213:6;33191:29;:::i;:::-;33186:3;33182:39;33175:46;;32957:270;32867:360;;;;:::o;33233:640::-;33428:4;33466:3;33455:9;33451:19;33443:27;;33480:71;33548:1;33537:9;33533:17;33524:6;33480:71;:::i;:::-;33561:72;33629:2;33618:9;33614:18;33605:6;33561:72;:::i;:::-;33643;33711:2;33700:9;33696:18;33687:6;33643:72;:::i;:::-;33762:9;33756:4;33752:20;33747:2;33736:9;33732:18;33725:48;33790:76;33861:4;33852:6;33790:76;:::i;:::-;33782:84;;33233:640;;;;;;;:::o;33879:141::-;33935:5;33966:6;33960:13;33951:22;;33982:32;34008:5;33982:32;:::i;:::-;33879:141;;;;:::o;34026:349::-;34095:6;34144:2;34132:9;34123:7;34119:23;34115:32;34112:119;;;34150:79;;:::i;:::-;34112:119;34270:1;34295:63;34350:7;34341:6;34330:9;34326:22;34295:63;:::i;:::-;34285:73;;34241:127;34026:349;;;;:::o;34381:233::-;34420:3;34443:24;34461:5;34443:24;:::i;:::-;34434:33;;34489:66;34482:5;34479:77;34476:103;;34559:18;;:::i;:::-;34476:103;34606:1;34599:5;34595:13;34588:20;;34381:233;;;:::o;34620:180::-;34668:77;34665:1;34658:88;34765:4;34762:1;34755:15;34789:4;34786:1;34779:15;34806:185;34846:1;34863:20;34881:1;34863:20;:::i;:::-;34858:25;;34897:20;34915:1;34897:20;:::i;:::-;34892:25;;34936:1;34926:35;;34941:18;;:::i;:::-;34926:35;34983:1;34980;34976:9;34971:14;;34806:185;;;;:::o;34997:348::-;35037:7;35060:20;35078:1;35060:20;:::i;:::-;35055:25;;35094:20;35112:1;35094:20;:::i;:::-;35089:25;;35282:1;35214:66;35210:74;35207:1;35204:81;35199:1;35192:9;35185:17;35181:105;35178:131;;;35289:18;;:::i;:::-;35178:131;35337:1;35334;35330:9;35319:20;;34997:348;;;;:::o;35351:86::-;35386:7;35426:4;35419:5;35415:16;35404:27;;35351:86;;;:::o;35443:237::-;35481:3;35500:18;35516:1;35500:18;:::i;:::-;35495:23;;35532:18;35548:1;35532:18;:::i;:::-;35527:23;;35622:1;35616:4;35612:12;35609:1;35606:19;35603:45;;;35628:18;;:::i;:::-;35603:45;35672:1;35669;35665:9;35658:16;;35443:237;;;;:::o

Swarm Source

ipfs://f422a328cdbd117a27b0a9d6fa2817b4ce9f31920d35191c684b875e9c608160
Loading...
Loading
Loading...
Loading
[ 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.