ETH Price: $3,168.94 (+2.85%)

Token

AIT iPASS NFT (AITI)
 

Overview

Max Total Supply

92 AITI

Holders

90

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
1 AITI
0x21f0dfdf3534e87b4af29cf740deae7205955409
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:
AITNFT

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

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

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

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

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

pragma solidity ^0.8.0;

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


// File contracts/token/onft/IONFT721Core.sol

 

pragma solidity >=0.5.0;

/**
 * @dev Interface of the ONFT Core standard
 */
interface IONFT721Core is IERC165 {
    /**
     * @dev Emitted when `_tokenIds[]` are moved from the `_sender` to (`_dstChainId`, `_toAddress`)
     * `_nonce` is the outbound nonce from
     */
    event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes indexed _toAddress, uint[] _tokenIds);
    event ReceiveFromChain(uint16 indexed _srcChainId, bytes indexed _srcAddress, address indexed _toAddress, uint[] _tokenIds);

    /**
     * @dev Emitted when `_payload` was received from lz, but not enough gas to deliver all tokenIds
     */
    event CreditStored(bytes32 _hashedPayload, bytes _payload);
    /**
     * @dev Emitted when `_hashedPayload` has been completely delivered
     */
    event CreditCleared(bytes32 _hashedPayload);

    /**
     * @dev send token `_tokenId` to (`_dstChainId`, `_toAddress`) from `_from`
     * `_toAddress` can be any size depending on the `dstChainId`.
     * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
     * `_adapterParams` is a flexible bytes array to indicate messaging adapter services
     */
    function sendFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;
    /**
     * @dev send tokens `_tokenIds[]` to (`_dstChainId`, `_toAddress`) from `_from`
     * `_toAddress` can be any size depending on the `dstChainId`.
     * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
     * `_adapterParams` is a flexible bytes array to indicate messaging adapter services
     */
    function sendBatchFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint[] calldata _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;

    /**
     * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
     * _dstChainId - L0 defined chain id to send tokens too
     * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
     * _tokenId - token Id to transfer
     * _useZro - indicates to use zro to pay L0 fees
     * _adapterParams - flexible bytes array to indicate messaging adapter services in L0
     */
    function estimateSendFee(uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);
    /**
     * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
     * _dstChainId - L0 defined chain id to send tokens too
     * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
     * _tokenIds[] - token Ids to transfer
     * _useZro - indicates to use zro to pay L0 fees
     * _adapterParams - flexible bytes array to indicate messaging adapter services in L0
     */
    function estimateSendBatchFee(uint16 _dstChainId, bytes calldata _toAddress, uint[] calldata _tokenIds, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);
}


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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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


// File contracts/token/onft/IONFT721.sol

 

pragma solidity >=0.5.0;


/**
 * @dev Interface of the ONFT standard
 */
interface IONFT721 is IONFT721Core, IERC721 {

}


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

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

pragma solidity ^0.8.0;

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

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


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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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


// File contracts/interfaces/ILayerZeroReceiver.sol

 

pragma solidity >=0.5.0;

interface ILayerZeroReceiver {
    // @notice LayerZero endpoint will invoke this function to deliver the message on the destination
    // @param _srcChainId - the source endpoint identifier
    // @param _srcAddress - the source sending contract address from the source chain
    // @param _nonce - the ordered message nonce
    // @param _payload - the signed payload is the UA bytes has encoded to be sent
    function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;
}


// File contracts/interfaces/ILayerZeroUserApplicationConfig.sol

 

pragma solidity >=0.5.0;

interface ILayerZeroUserApplicationConfig {
    // @notice set the configuration of the LayerZero messaging library of the specified version
    // @param _version - messaging library version
    // @param _chainId - the chainId for the pending config change
    // @param _configType - type of configuration. every messaging library has its own convention.
    // @param _config - configuration in the bytes. can encode arbitrary content.
    function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external;

    // @notice set the send() LayerZero messaging library version to _version
    // @param _version - new messaging library version
    function setSendVersion(uint16 _version) external;

    // @notice set the lzReceive() LayerZero messaging library version to _version
    // @param _version - new messaging library version
    function setReceiveVersion(uint16 _version) external;

    // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload
    // @param _srcChainId - the chainId of the source chain
    // @param _srcAddress - the contract address of the source contract at the source chain
    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;
}


// File contracts/interfaces/ILayerZeroEndpoint.sol

 

pragma solidity >=0.5.0;

interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {
    // @notice send a LayerZero message to the specified address at a LayerZero endpoint.
    // @param _dstChainId - the destination chain identifier
    // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains
    // @param _payload - a custom bytes payload to send to the destination contract
    // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address
    // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction
    // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination
    function send(uint16 _dstChainId, bytes calldata _destination, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;

    // @notice used by the messaging library to publish verified payload
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source contract (as bytes) at the source chain
    // @param _dstAddress - the address on destination chain
    // @param _nonce - the unbound message ordering nonce
    // @param _gasLimit - the gas limit for external contract execution
    // @param _payload - verified payload to send to the destination contract
    function receivePayload(uint16 _srcChainId, bytes calldata _srcAddress, address _dstAddress, uint64 _nonce, uint _gasLimit, bytes calldata _payload) external;

    // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source chain contract address
    function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);

    // @notice get the outboundNonce from this source chain which, consequently, is always an EVM
    // @param _srcAddress - the source chain contract address
    function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);

    // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery
    // @param _dstChainId - the destination chain identifier
    // @param _userApplication - the user app address on this EVM chain
    // @param _payload - the custom message to send over LayerZero
    // @param _payInZRO - if false, user app pays the protocol fee in native token
    // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain
    function estimateFees(uint16 _dstChainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam) external view returns (uint nativeFee, uint zroFee);

    // @notice get this Endpoint's immutable source identifier
    function getChainId() external view returns (uint16);

    // @notice the interface to retry failed message on this Endpoint destination
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source chain contract address
    // @param _payload - the payload to be retried
    function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;

    // @notice query if any STORED payload (message blocking) at the endpoint.
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source chain contract address
    function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);

    // @notice query if the _libraryAddress is valid for sending msgs.
    // @param _userApplication - the user app address on this EVM chain
    function getSendLibraryAddress(address _userApplication) external view returns (address);

    // @notice query if the _libraryAddress is valid for receiving msgs.
    // @param _userApplication - the user app address on this EVM chain
    function getReceiveLibraryAddress(address _userApplication) external view returns (address);

    // @notice query if the non-reentrancy guard for send() is on
    // @return true if the guard is on. false otherwise
    function isSendingPayload() external view returns (bool);

    // @notice query if the non-reentrancy guard for receive() is on
    // @return true if the guard is on. false otherwise
    function isReceivingPayload() external view returns (bool);

    // @notice get the configuration of the LayerZero messaging library of the specified version
    // @param _version - messaging library version
    // @param _chainId - the chainId for the pending config change
    // @param _userApplication - the contract address of the user application
    // @param _configType - type of configuration. every messaging library has its own convention.
    function getConfig(uint16 _version, uint16 _chainId, address _userApplication, uint _configType) external view returns (bytes memory);

    // @notice get the send() LayerZero messaging library version
    // @param _userApplication - the contract address of the user application
    function getSendVersion(address _userApplication) external view returns (uint16);

    // @notice get the lzReceive() LayerZero messaging library version
    // @param _userApplication - the contract address of the user application
    function getReceiveVersion(address _userApplication) external view returns (uint16);
}


// File contracts/util/BytesLib.sol

/*
 * @title Solidity Bytes Arrays Utils
 * @author Gonçalo Sá <[email protected]>
 *
 * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
 *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
 */
pragma solidity >=0.8.0 <0.9.0;


library BytesLib {
    function concat(
        bytes memory _preBytes,
        bytes memory _postBytes
    )
    internal
    pure
    returns (bytes memory)
    {
        bytes memory tempBytes;

        assembly {
        // Get a location of some free memory and store it in tempBytes as
        // Solidity does for memory variables.
            tempBytes := mload(0x40)

        // Store the length of the first bytes array at the beginning of
        // the memory for tempBytes.
            let length := mload(_preBytes)
            mstore(tempBytes, length)

        // Maintain a memory counter for the current write location in the
        // temp bytes array by adding the 32 bytes for the array length to
        // the starting location.
            let mc := add(tempBytes, 0x20)
        // Stop copying when the memory counter reaches the length of the
        // first bytes array.
            let end := add(mc, length)

            for {
            // Initialize a copy counter to the start of the _preBytes data,
            // 32 bytes into its memory.
                let cc := add(_preBytes, 0x20)
            } lt(mc, end) {
            // Increase both counters by 32 bytes each iteration.
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
            // Write the _preBytes data into the tempBytes memory 32 bytes
            // at a time.
                mstore(mc, mload(cc))
            }

        // Add the length of _postBytes to the current length of tempBytes
        // and store it as the new length in the first 32 bytes of the
        // tempBytes memory.
            length := mload(_postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

        // Move the memory counter back from a multiple of 0x20 to the
        // actual end of the _preBytes data.
            mc := end
        // Stop copying when the memory counter reaches the new combined
        // length of the arrays.
            end := add(mc, length)

            for {
                let cc := add(_postBytes, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

        // Update the free-memory pointer by padding our last write location
        // to 32 bytes: add 31 bytes to the end of tempBytes to move to the
        // next 32 byte block, then round down to the nearest multiple of
        // 32. If the sum of the length of the two arrays is zero then add
        // one before rounding down to leave a blank 32 bytes (the length block with 0).
            mstore(0x40, and(
            add(add(end, iszero(add(length, mload(_preBytes)))), 31),
            not(31) // Round down to the nearest 32 bytes.
            ))
        }

        return tempBytes;
    }

    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
        assembly {
        // Read the first 32 bytes of _preBytes storage, which is the length
        // of the array. (We don't need to use the offset into the slot
        // because arrays use the entire slot.)
            let fslot := sload(_preBytes.slot)
        // Arrays of 31 bytes or less have an even value in their slot,
        // while longer arrays have an odd value. The actual length is
        // the slot divided by two for odd values, and the lowest order
        // byte divided by two for even values.
        // If the slot is even, bitwise and the slot with 255 and divide by
        // two to get the length. If the slot is odd, bitwise and the slot
        // with -1 and divide by two.
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)
            let newlength := add(slength, mlength)
        // slength can contain both the length and contents of the array
        // if length < 32 bytes so let's prepare for that
        // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
            switch add(lt(slength, 32), lt(newlength, 32))
            case 2 {
            // Since the new array still fits in the slot, we just need to
            // update the contents of the slot.
            // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
                sstore(
                _preBytes.slot,
                // all the modifications to the slot are inside this
                // next block
                add(
                // we can just add to the slot contents because the
                // bytes we want to change are the LSBs
                fslot,
                add(
                mul(
                div(
                // load the bytes from memory
                mload(add(_postBytes, 0x20)),
                // zero all bytes to the right
                exp(0x100, sub(32, mlength))
                ),
                // and now shift left the number of bytes to
                // leave space for the length in the slot
                exp(0x100, sub(32, newlength))
                ),
                // increase length by the double of the memory
                // bytes length
                mul(mlength, 2)
                )
                )
                )
            }
            case 1 {
            // The stored value fits in the slot, but the combined value
            // will exceed it.
            // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

            // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

            // The contents of the _postBytes array start 32 bytes into
            // the structure. Our first read should obtain the `submod`
            // bytes that can fit into the unused space in the last word
            // of the stored array. To get this, we read 32 bytes starting
            // from `submod`, so the data we read overlaps with the array
            // contents by `submod` bytes. Masking the lowest-order
            // `submod` bytes allows us to add that value directly to the
            // stored value.

                let submod := sub(32, slength)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(
                sc,
                add(
                and(
                fslot,
                0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
                ),
                and(mload(mc), mask)
                )
                )

                for {
                    mc := add(mc, 0x20)
                    sc := add(sc, 1)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
            default {
            // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
            // Start copying to the last used word of the stored array.
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

            // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

            // Copy over the first `submod` bytes of the new data as in
            // case 1 above.
                let slengthmod := mod(slength, 32)
                let mlengthmod := mod(mlength, 32)
                let submod := sub(32, slengthmod)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(sc, add(sload(sc), and(mload(mc), mask)))

                for {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
        }
    }

    function slice(
        bytes memory _bytes,
        uint256 _start,
        uint256 _length
    )
    internal
    pure
    returns (bytes memory)
    {
        require(_length + 31 >= _length, "slice_overflow");
        require(_bytes.length >= _start + _length, "slice_outOfBounds");

        bytes memory tempBytes;

        assembly {
            switch iszero(_length)
            case 0 {
            // Get a location of some free memory and store it in tempBytes as
            // Solidity does for memory variables.
                tempBytes := mload(0x40)

            // The first word of the slice result is potentially a partial
            // word read from the original array. To read it, we calculate
            // the length of that partial word and start copying that many
            // bytes into the array. The first word we copy will start with
            // data we don't care about, but the last `lengthmod` bytes will
            // land at the beginning of the contents of the new array. When
            // we're done copying, we overwrite the full first word with
            // the actual length of the slice.
                let lengthmod := and(_length, 31)

            // The multiplication in the next line is necessary
            // because when slicing multiples of 32 bytes (lengthmod == 0)
            // the following copy loop was copying the origin's length
            // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                // The multiplication in the next line has the same exact purpose
                // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    mstore(mc, mload(cc))
                }

                mstore(tempBytes, _length)

            //update free-memory pointer
            //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)
            //zero out the 32 bytes slice we are about to return
            //we need to do it because Solidity does not garbage collect
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
        require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
        address tempAddress;

        assembly {
            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
        }

        return tempAddress;
    }

    function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
        require(_bytes.length >= _start + 1 , "toUint8_outOfBounds");
        uint8 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x1), _start))
        }

        return tempUint;
    }

    function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
        require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
        uint16 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x2), _start))
        }

        return tempUint;
    }

    function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {
        require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
        uint32 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x4), _start))
        }

        return tempUint;
    }

    function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
        require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
        uint64 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x8), _start))
        }

        return tempUint;
    }

    function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
        require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
        uint96 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0xc), _start))
        }

        return tempUint;
    }

    function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
        require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
        uint128 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x10), _start))
        }

        return tempUint;
    }

    function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
        require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
        uint256 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }

        return tempUint;
    }

    function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
        require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
        bytes32 tempBytes32;

        assembly {
            tempBytes32 := mload(add(add(_bytes, 0x20), _start))
        }

        return tempBytes32;
    }

    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
        bool success = true;

        assembly {
            let length := mload(_preBytes)

        // if lengths don't match the arrays are not equal
            switch eq(length, mload(_postBytes))
            case 1 {
            // cb is a circuit breaker in the for loop since there's
            //  no said feature for inline assembly loops
            // cb = 1 - don't breaker
            // cb = 0 - break
                let cb := 1

                let mc := add(_preBytes, 0x20)
                let end := add(mc, length)

                for {
                    let cc := add(_postBytes, 0x20)
                // the next line is the loop condition:
                // while(uint256(mc < end) + cb == 2)
                } eq(add(lt(mc, end), cb), 2) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                // if any of these checks fails then arrays are not equal
                    if iszero(eq(mload(mc), mload(cc))) {
                    // unsuccess:
                        success := 0
                        cb := 0
                    }
                }
            }
            default {
            // unsuccess:
                success := 0
            }
        }

        return success;
    }

    function equalStorage(
        bytes storage _preBytes,
        bytes memory _postBytes
    )
    internal
    view
    returns (bool)
    {
        bool success = true;

        assembly {
        // we know _preBytes_offset is 0
            let fslot := sload(_preBytes.slot)
        // Decode the length of the stored array like in concatStorage().
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)

        // if lengths don't match the arrays are not equal
            switch eq(slength, mlength)
            case 1 {
            // slength can contain both the length and contents of the array
            // if length < 32 bytes so let's prepare for that
            // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
                if iszero(iszero(slength)) {
                    switch lt(slength, 32)
                    case 1 {
                    // blank the last byte which is the length
                        fslot := mul(div(fslot, 0x100), 0x100)

                        if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
                        // unsuccess:
                            success := 0
                        }
                    }
                    default {
                    // cb is a circuit breaker in the for loop since there's
                    //  no said feature for inline assembly loops
                    // cb = 1 - don't breaker
                    // cb = 0 - break
                        let cb := 1

                    // get the keccak hash to get the contents of the array
                        mstore(0x0, _preBytes.slot)
                        let sc := keccak256(0x0, 0x20)

                        let mc := add(_postBytes, 0x20)
                        let end := add(mc, mlength)

                    // the next line is the loop condition:
                    // while(uint256(mc < end) + cb == 2)
                        for {} eq(add(lt(mc, end), cb), 2) {
                            sc := add(sc, 1)
                            mc := add(mc, 0x20)
                        } {
                            if iszero(eq(sload(sc), mload(mc))) {
                            // unsuccess:
                                success := 0
                                cb := 0
                            }
                        }
                    }
                }
            }
            default {
            // unsuccess:
                success := 0
            }
        }

        return success;
    }
}


// File contracts/lzApp/LzApp.sol

 

pragma solidity ^0.8.0;





/*
 * a generic LzReceiver implementation
 */
abstract contract LzApp is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {
    using BytesLib for bytes;

    // ua can not send payload larger than this by default, but it can be changed by the ua owner
    uint constant public DEFAULT_PAYLOAD_SIZE_LIMIT = 10000;

    ILayerZeroEndpoint public immutable lzEndpoint;
    mapping(uint16 => bytes) public trustedRemoteLookup;
    mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;
    mapping(uint16 => uint) public payloadSizeLimitLookup;
    address public precrime;

    event SetPrecrime(address precrime);
    event SetTrustedRemote(uint16 _remoteChainId, bytes _path);
    event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);
    event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);

    constructor(address _endpoint) {
        lzEndpoint = ILayerZeroEndpoint(_endpoint);
    }

    function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual override {
        // lzReceive must be called by the endpoint for security
        require(_msgSender() == address(lzEndpoint), "LzApp: invalid endpoint caller");

        bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];
        // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.
        require(_srcAddress.length == trustedRemote.length && trustedRemote.length > 0 && keccak256(_srcAddress) == keccak256(trustedRemote), "LzApp: invalid source sending contract");

        _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
    }

    // abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging
    function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual;

    function _lzSend(uint16 _dstChainId, bytes memory _payload, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams, uint _nativeFee) internal virtual {
        bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];
        require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
        _checkPayloadSize(_dstChainId, _payload.length);
        lzEndpoint.send{value: _nativeFee}(_dstChainId, trustedRemote, _payload, _refundAddress, _zroPaymentAddress, _adapterParams);
    }

    function _checkGasLimit(uint16 _dstChainId, uint16 _type, bytes memory _adapterParams, uint _extraGas) internal view virtual {
        uint providedGasLimit = _getGasLimit(_adapterParams);
        uint minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;
        require(minGasLimit > 0, "LzApp: minGasLimit not set");
        require(providedGasLimit >= minGasLimit, "LzApp: gas limit is too low");
    }

    function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) {
        require(_adapterParams.length >= 34, "LzApp: invalid adapterParams");
        assembly {
            gasLimit := mload(add(_adapterParams, 34))
        }
    }

    function _checkPayloadSize(uint16 _dstChainId, uint _payloadSize) internal view virtual {
        uint payloadSizeLimit = payloadSizeLimitLookup[_dstChainId];
        if (payloadSizeLimit == 0) { // use default if not set
            payloadSizeLimit = DEFAULT_PAYLOAD_SIZE_LIMIT;
        }
        require(_payloadSize <= payloadSizeLimit, "LzApp: payload size is too large");
    }

    //---------------------------UserApplication config----------------------------------------
    function getConfig(uint16 _version, uint16 _chainId, address, uint _configType) external view returns (bytes memory) {
        return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);
    }

    // generic config for LayerZero user Application
    function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external override onlyOwner {
        lzEndpoint.setConfig(_version, _chainId, _configType, _config);
    }

    function setSendVersion(uint16 _version) external override onlyOwner {
        lzEndpoint.setSendVersion(_version);
    }

    function setReceiveVersion(uint16 _version) external override onlyOwner {
        lzEndpoint.setReceiveVersion(_version);
    }

    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {
        lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);
    }

    // _path = abi.encodePacked(remoteAddress, localAddress)
    // this function set the trusted path for the cross-chain communication
    function setTrustedRemote(uint16 _srcChainId, bytes calldata _path) external onlyOwner {
        trustedRemoteLookup[_srcChainId] = _path;
        emit SetTrustedRemote(_srcChainId, _path);
    }

    function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner {
        trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));
        emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);
    }

    function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) {
        bytes memory path = trustedRemoteLookup[_remoteChainId];
        require(path.length != 0, "LzApp: no trusted path record");
        return path.slice(0, path.length - 20); // the last 20 bytes should be address(this)
    }

    function setPrecrime(address _precrime) external onlyOwner {
        precrime = _precrime;
        emit SetPrecrime(_precrime);
    }

    function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint _minGas) external onlyOwner {
        require(_minGas > 0, "LzApp: invalid minGas");
        minDstGasLookup[_dstChainId][_packetType] = _minGas;
        emit SetMinDstGas(_dstChainId, _packetType, _minGas);
    }

    // if the size is 0, it means default size limit
    function setPayloadSizeLimit(uint16 _dstChainId, uint _size) external onlyOwner {
        payloadSizeLimitLookup[_dstChainId] = _size;
    }

    //--------------------------- VIEW FUNCTION ----------------------------------------
    function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {
        bytes memory trustedSource = trustedRemoteLookup[_srcChainId];
        return keccak256(trustedSource) == keccak256(_srcAddress);
    }
}


// File contracts/util/ExcessivelySafeCall.sol

//   OR Apache-2.0
pragma solidity >=0.7.6;

library ExcessivelySafeCall {
    uint256 constant LOW_28_MASK =
    0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

    /// @notice Use when you _really_ really _really_ don't trust the called
    /// contract. This prevents the called contract from causing reversion of
    /// the caller in as many ways as we can.
    /// @dev The main difference between this and a solidity low-level call is
    /// that we limit the number of bytes that the callee can cause to be
    /// copied to caller memory. This prevents stupid things like malicious
    /// contracts returning 10,000,000 bytes causing a local OOG when copying
    /// to memory.
    /// @param _target The address to call
    /// @param _gas The amount of gas to forward to the remote contract
    /// @param _maxCopy The maximum number of bytes of returndata to copy
    /// to memory.
    /// @param _calldata The data to send to the remote contract
    /// @return success and returndata, as `.call()`. Returndata is capped to
    /// `_maxCopy` bytes.
    function excessivelySafeCall(
        address _target,
        uint256 _gas,
        uint16 _maxCopy,
        bytes memory _calldata
    ) internal returns (bool, bytes memory) {
        // set up for assembly call
        uint256 _toCopy;
        bool _success;
        bytes memory _returnData = new bytes(_maxCopy);
        // dispatch message to recipient
        // by assembly calling "handle" function
        // we call via assembly to avoid memcopying a very large returndata
        // returned by a malicious contract
        assembly {
            _success := call(
            _gas, // gas
            _target, // recipient
            0, // ether value
            add(_calldata, 0x20), // inloc
            mload(_calldata), // inlen
            0, // outloc
            0 // outlen
            )
        // limit our copy to 256 bytes
            _toCopy := returndatasize()
            if gt(_toCopy, _maxCopy) {
                _toCopy := _maxCopy
            }
        // Store the length of the copied bytes
            mstore(_returnData, _toCopy)
        // copy the bytes from returndata[0:_toCopy]
            returndatacopy(add(_returnData, 0x20), 0, _toCopy)
        }
        return (_success, _returnData);
    }

    /// @notice Use when you _really_ really _really_ don't trust the called
    /// contract. This prevents the called contract from causing reversion of
    /// the caller in as many ways as we can.
    /// @dev The main difference between this and a solidity low-level call is
    /// that we limit the number of bytes that the callee can cause to be
    /// copied to caller memory. This prevents stupid things like malicious
    /// contracts returning 10,000,000 bytes causing a local OOG when copying
    /// to memory.
    /// @param _target The address to call
    /// @param _gas The amount of gas to forward to the remote contract
    /// @param _maxCopy The maximum number of bytes of returndata to copy
    /// to memory.
    /// @param _calldata The data to send to the remote contract
    /// @return success and returndata, as `.call()`. Returndata is capped to
    /// `_maxCopy` bytes.
    function excessivelySafeStaticCall(
        address _target,
        uint256 _gas,
        uint16 _maxCopy,
        bytes memory _calldata
    ) internal view returns (bool, bytes memory) {
        // set up for assembly call
        uint256 _toCopy;
        bool _success;
        bytes memory _returnData = new bytes(_maxCopy);
        // dispatch message to recipient
        // by assembly calling "handle" function
        // we call via assembly to avoid memcopying a very large returndata
        // returned by a malicious contract
        assembly {
            _success := staticcall(
            _gas, // gas
            _target, // recipient
            add(_calldata, 0x20), // inloc
            mload(_calldata), // inlen
            0, // outloc
            0 // outlen
            )
        // limit our copy to 256 bytes
            _toCopy := returndatasize()
            if gt(_toCopy, _maxCopy) {
                _toCopy := _maxCopy
            }
        // Store the length of the copied bytes
            mstore(_returnData, _toCopy)
        // copy the bytes from returndata[0:_toCopy]
            returndatacopy(add(_returnData, 0x20), 0, _toCopy)
        }
        return (_success, _returnData);
    }

    /**
     * @notice Swaps function selectors in encoded contract calls
     * @dev Allows reuse of encoded calldata for functions with identical
     * argument types but different names. It simply swaps out the first 4 bytes
     * for the new selector. This function modifies memory in place, and should
     * only be used with caution.
     * @param _newSelector The new 4-byte selector
     * @param _buf The encoded contract args
     */
    function swapSelector(bytes4 _newSelector, bytes memory _buf)
    internal
    pure
    {
        require(_buf.length >= 4);
        uint256 _mask = LOW_28_MASK;
        assembly {
        // load the first word of
            let _word := mload(add(_buf, 0x20))
        // mask out the top 4 bytes
        // /x
            _word := and(_word, _mask)
            _word := or(_newSelector, _word)
            mstore(add(_buf, 0x20), _word)
        }
    }
}


// File contracts/lzApp/NonblockingLzApp.sol

 

pragma solidity ^0.8.0;


/*
 * the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel
 * this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking
 * NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress)
 */
abstract contract NonblockingLzApp is LzApp {
    using ExcessivelySafeCall for address;

    constructor(address _endpoint) LzApp(_endpoint) {}

    mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;

    event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);
    event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);

    // overriding the virtual function in LzReceiver
    function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual override {
        (bool success, bytes memory reason) = address(this).excessivelySafeCall(gasleft(), 150, abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload));
        // try-catch all errors/exceptions
        if (!success) {
            _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);
        }
    }

    function _storeFailedMessage(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload, bytes memory _reason) internal virtual {
        failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);
        emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);
    }

    function nonblockingLzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual {
        // only internal transaction
        require(_msgSender() == address(this), "NonblockingLzApp: caller must be LzApp");
        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
    }

    //@notice override this function
    function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual;

    function retryMessage(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public payable virtual {
        // assert there is message to retry
        bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];
        require(payloadHash != bytes32(0), "NonblockingLzApp: no stored message");
        require(keccak256(_payload) == payloadHash, "NonblockingLzApp: invalid payload");
        // clear the stored message
        failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);
        // execute the message. revert if it fails again
        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
        emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);
    }
}


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

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

pragma solidity ^0.8.0;

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


// File contracts/token/onft/ONFT721Core.sol

 

pragma solidity ^0.8.0;



abstract contract ONFT721Core is NonblockingLzApp, ERC165, IONFT721Core {
    uint16 public constant FUNCTION_TYPE_SEND = 1;

    struct StoredCredit {
        uint16 srcChainId;
        address toAddress;
        uint256 index; // which index of the tokenIds remain
        bool creditsRemain;
    }

    uint256 public minGasToTransferAndStore; // min amount of gas required to transfer, and also store the payload
    mapping(uint16 => uint256) public dstChainIdToBatchLimit;
    mapping(uint16 => uint256) public dstChainIdToTransferGas; // per transfer amount of gas required to mint/transfer on the dst
    mapping(bytes32 => StoredCredit) public storedCredits;

    constructor(uint256 _minGasToTransferAndStore, address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
        require(_minGasToTransferAndStore > 0, "ONFT721: minGasToTransferAndStore must be > 0");
        minGasToTransferAndStore = _minGasToTransferAndStore;
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IONFT721Core).interfaceId || super.supportsInterface(interfaceId);
    }

    function estimateSendFee(uint16 _dstChainId, bytes memory _toAddress, uint _tokenId, bool _useZro, bytes memory _adapterParams) public view virtual override returns (uint nativeFee, uint zroFee) {
        return estimateSendBatchFee(_dstChainId, _toAddress, _toSingletonArray(_tokenId), _useZro, _adapterParams);
    }

    function estimateSendBatchFee(uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, bool _useZro, bytes memory _adapterParams) public view virtual override returns (uint nativeFee, uint zroFee) {
        bytes memory payload = abi.encode(_toAddress, _tokenIds);
        return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);
    }

    function sendFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) public payable virtual override {
        _send(_from, _dstChainId, _toAddress, _toSingletonArray(_tokenId), _refundAddress, _zroPaymentAddress, _adapterParams);
    }

    function sendBatchFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) public payable virtual override {
        _send(_from, _dstChainId, _toAddress, _tokenIds, _refundAddress, _zroPaymentAddress, _adapterParams);
    }

    function _send(address _from, uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) internal virtual {
        // allow 1 by default
        require(_tokenIds.length > 0, "LzApp: tokenIds[] is empty");
        require(_tokenIds.length == 1 || _tokenIds.length <= dstChainIdToBatchLimit[_dstChainId], "ONFT721: batch size exceeds dst batch limit");

        for (uint i = 0; i < _tokenIds.length; i++) {
            _debitFrom(_from, _dstChainId, _toAddress, _tokenIds[i]);
        }

        bytes memory payload = abi.encode(_toAddress, _tokenIds);

        _checkGasLimit(_dstChainId, FUNCTION_TYPE_SEND, _adapterParams, dstChainIdToTransferGas[_dstChainId] * _tokenIds.length);
        _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);
        emit SendToChain(_dstChainId, _from, _toAddress, _tokenIds);
    }

    function _nonblockingLzReceive(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint64, /*_nonce*/
        bytes memory _payload
    ) internal virtual override {
        // decode and load the toAddress
        (bytes memory toAddressBytes, uint[] memory tokenIds) = abi.decode(_payload, (bytes, uint[]));

        address toAddress;
        assembly {
            toAddress := mload(add(toAddressBytes, 20))
        }

        uint nextIndex = _creditTill(_srcChainId, toAddress, 0, tokenIds);
        if (nextIndex < tokenIds.length) {
            // not enough gas to complete transfers, store to be cleared in another tx
            bytes32 hashedPayload = keccak256(_payload);
            storedCredits[hashedPayload] = StoredCredit(_srcChainId, toAddress, nextIndex, true);
            emit CreditStored(hashedPayload, _payload);
        }

        emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, tokenIds);
    }

    // Public function for anyone to clear and deliver the remaining batch sent tokenIds
    function clearCredits(bytes memory _payload) external {
        bytes32 hashedPayload = keccak256(_payload);
        require(storedCredits[hashedPayload].creditsRemain, "ONFT721: no credits stored");

        (, uint[] memory tokenIds) = abi.decode(_payload, (bytes, uint[]));

        uint nextIndex = _creditTill(storedCredits[hashedPayload].srcChainId, storedCredits[hashedPayload].toAddress, storedCredits[hashedPayload].index, tokenIds);
        require(nextIndex > storedCredits[hashedPayload].index, "ONFT721: not enough gas to process credit transfer");

        if (nextIndex == tokenIds.length) {
            // cleared the credits, delete the element
            delete storedCredits[hashedPayload];
            emit CreditCleared(hashedPayload);
        } else {
            // store the next index to mint
            storedCredits[hashedPayload] = StoredCredit(storedCredits[hashedPayload].srcChainId, storedCredits[hashedPayload].toAddress, nextIndex, true);
        }
    }

    // When a srcChain has the ability to transfer more chainIds in a single tx than the dst can do.
    // Needs the ability to iterate and stop if the minGasToTransferAndStore is not met
    function _creditTill(uint16 _srcChainId, address _toAddress, uint _startIndex, uint[] memory _tokenIds) internal returns (uint256){
        uint i = _startIndex;
        while (i < _tokenIds.length) {
            // if not enough gas to process, store this index for next loop
            if (gasleft() < minGasToTransferAndStore) break;

            _creditTo(_srcChainId, _toAddress, _tokenIds[i]);
            i++;
        }

        // indicates the next index to send of tokenIds,
        // if i == tokenIds.length, we are finished
        return i;
    }

    function setMinGasToTransferAndStore(uint256 _minGasToTransferAndStore) external onlyOwner {
        require(_minGasToTransferAndStore > 0, "ONFT721: minGasToTransferAndStore must be > 0");
        minGasToTransferAndStore = _minGasToTransferAndStore;
    }

    // ensures enough gas in adapter params to handle batch transfer gas amounts on the dst
    function setDstChainIdToTransferGas(uint16 _dstChainId, uint256 _dstChainIdToTransferGas) external onlyOwner {
        require(_dstChainIdToTransferGas > 0, "ONFT721: dstChainIdToTransferGas must be > 0");
        dstChainIdToTransferGas[_dstChainId] = _dstChainIdToTransferGas;
    }

    // limit on src the amount of tokens to batch send
    function setDstChainIdToBatchLimit(uint16 _dstChainId, uint256 _dstChainIdToBatchLimit) external onlyOwner {
        require(_dstChainIdToBatchLimit > 0, "ONFT721: dstChainIdToBatchLimit must be > 0");
        dstChainIdToBatchLimit[_dstChainId] = _dstChainIdToBatchLimit;
    }

    function _debitFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint _tokenId) internal virtual;

    function _creditTo(uint16 _srcChainId, address _toAddress, uint _tokenId) internal virtual;

    function _toSingletonArray(uint element) internal pure returns (uint[] memory) {
        uint[] memory array = new uint[](1);
        array[0] = element;
        return array;
    }
}


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

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

pragma solidity ^0.8.0;

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


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

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

pragma solidity ^0.8.0;

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

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

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


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

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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

pragma solidity ^0.8.0;

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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

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

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

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

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


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

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

pragma solidity ^0.8.0;







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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

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

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

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


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

 
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

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

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

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


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

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

pragma solidity ^0.8.0;


/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

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

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

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

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

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

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}


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

 
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}


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

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

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}


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

 
// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;




/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

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

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleGranted} event.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleRevoked} event.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     *
     * May emit a {RoleRevoked} event.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * May emit a {RoleGranted} event.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleGranted} event.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}


// File contracts/token/onft/ONFT721.sol

 

pragma solidity ^0.8.0;





// NOTE: this ONFT contract has no public minting logic.
// must implement your own minting logic in child classes
contract ONFT721 is ONFT721Core, ERC721, IONFT721, ERC721Enumerable, Pausable, AccessControl{
    constructor(string memory _name, string memory _symbol, uint256 _minGasToTransfer, address _lzEndpoint) ERC721(_name, _symbol) ONFT721Core(_minGasToTransfer, _lzEndpoint) {}

    function supportsInterface(bytes4 interfaceId) public view virtual override(ONFT721Core, ERC721, IERC165, ERC721Enumerable, AccessControl) returns (bool) {
        return interfaceId == type(IONFT721).interfaceId || super.supportsInterface(interfaceId);
    }

    function _debitFrom(address _from, uint16, bytes memory, uint _tokenId) internal virtual override {
        require(_isApprovedOrOwner(_msgSender(), _tokenId), "ONFT721: send caller is not owner nor approved");
        require(ERC721.ownerOf(_tokenId) == _from, "ONFT721: send from incorrect owner");
        _transfer(_from, address(this), _tokenId);
    }

    function _creditTo(uint16, address _toAddress, uint _tokenId) internal virtual override {
        require(!_exists(_tokenId) || (_exists(_tokenId) && ERC721.ownerOf(_tokenId) == address(this)));
        if (!_exists(_tokenId)) {
            _safeMint(_toAddress, _tokenId);
        } else {
            _transfer(address(this), _toAddress, _tokenId);
        }
    }

    function _beforeTokenTransfer(address from, address to, uint256 tokenId)
        internal
        whenNotPaused
        override(ERC721, ERC721Enumerable)
    {
        super._beforeTokenTransfer(from, to, tokenId);
    }
}


// File contracts/token/onft/extension/UniversalONFT721.sol



pragma solidity ^0.8.0;


/// @title Interface of the UniversalONFT standard
contract UniversalONFT721 is ONFT721 {
    uint public nextMintId;
    uint public maxMintId;
    string baseURI = "http://meta.ait.tech/"; 
    mapping(address => bool) public admin;
    /// @notice Constructor for the UniversalONFT
    /// @param _name the name of the token
    /// @param _symbol the token symbol
    /// @param _layerZeroEndpoint handles message transmission across chains
    /// @param _startMintId the starting mint number on this chain
    /// @param _endMintId the max number of mints on this chain
    constructor(string memory _name, string memory _symbol, uint256 _minGasToTransfer, address _layerZeroEndpoint, uint _startMintId, uint _endMintId) ONFT721(_name, _symbol, _minGasToTransfer, _layerZeroEndpoint) {
        nextMintId = _startMintId;
        maxMintId = _endMintId;
    }

    event ChangeRangeTokenId(
        uint min,
        uint max,
        uint blockTime
    );

    event AddAdmin(
        address admin,
        uint blockTime
    );

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

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

    function addAdmin(address _admin) external onlyOwner() {
        admin[_admin] = !admin[_admin];
        emit AddAdmin(_admin, block.timestamp);
    }

    function changeRangeTokenId(uint _min, uint _max) external onlyOwner() {
        require(maxMintId < _min && _min < _max, "NFT: RANGE_TOKEN_ID_WRONG");
        nextMintId = _min;
        maxMintId = _max;
        emit ChangeRangeTokenId(_min, _max, block.timestamp);
    }
    /// @notice Mint your ONFT
    function mint(address to) external {
        require(admin[msg.sender]);
        require(nextMintId <= maxMintId, "UniversalONFT721: max mint limit reached");

        uint newId = nextMintId;
        nextMintId++;

        _safeMint(to, newId);
    }
}



// File contracts/AITONFT.sol

pragma solidity ^0.8.0;

/// @title A LayerZero UniversalONFT example
/// @notice You can use this to mint ONFT and send nftIds across chain.
///  Each contract deployed to a chain should carefully set a `_startMintIndex` and a `_maxMint`
///  value to set a range of allowed mintable nftIds (so that no two chains can mint the same id!)
contract AITNFT is UniversalONFT721 {
    constructor(uint256 _minGasToStore, address _layerZeroEndpoint, uint _startMintId, uint _endMintId) UniversalONFT721("AIT iPASS NFT", "AITI", _minGasToStore, _layerZeroEndpoint, _startMintId, _endMintId) {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_minGasToStore","type":"uint256"},{"internalType":"address","name":"_layerZeroEndpoint","type":"address"},{"internalType":"uint256","name":"_startMintId","type":"uint256"},{"internalType":"uint256","name":"_endMintId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"blockTime","type":"uint256"}],"name":"AddAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"min","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"max","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockTime","type":"uint256"}],"name":"ChangeRangeTokenId","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_hashedPayload","type":"bytes32"}],"name":"CreditCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_hashedPayload","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"CreditStored","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"_reason","type":"bytes"}],"name":"MessageFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":true,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":true,"internalType":"address","name":"_toAddress","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"ReceiveFromChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"_payloadHash","type":"bytes32"}],"name":"RetryMessageSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"bytes","name":"_toAddress","type":"bytes"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"SendToChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"_type","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_minDstGas","type":"uint256"}],"name":"SetMinDstGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"precrime","type":"address"}],"name":"SetPrecrime","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_path","type":"bytes"}],"name":"SetTrustedRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"SetTrustedRemoteAddress","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_PAYLOAD_SIZE_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FUNCTION_TYPE_SEND","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"admin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"_min","type":"uint256"},{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"changeRangeTokenId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"clearCredits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"dstChainIdToBatchLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"dstChainIdToTransferGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendBatchFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"failedMessages","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"forceResumeReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"}],"name":"getTrustedRemoteAddress","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"isTrustedRemote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lzEndpoint","outputs":[{"internalType":"contract ILayerZeroEndpoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxMintId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"minDstGasLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minGasToTransferAndStore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextMintId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"nonblockingLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"payloadSizeLimitLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"precrime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"retryMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"sendBatchFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"sendFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseUri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_configType","type":"uint256"},{"internalType":"bytes","name":"_config","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstChainIdToBatchLimit","type":"uint256"}],"name":"setDstChainIdToBatchLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstChainIdToTransferGas","type":"uint256"}],"name":"setDstChainIdToTransferGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint16","name":"_packetType","type":"uint16"},{"internalType":"uint256","name":"_minGas","type":"uint256"}],"name":"setMinDstGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minGasToTransferAndStore","type":"uint256"}],"name":"setMinGasToTransferAndStore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"setPayloadSizeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_precrime","type":"address"}],"name":"setPrecrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setReceiveVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setSendVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_path","type":"bytes"}],"name":"setTrustedRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"setTrustedRemoteAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"storedCredits","outputs":[{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"address","name":"toAddress","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bool","name":"creditsRemain","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}]

60e0604052601560a08190527f687474703a2f2f6d6574612e6169742e746563682f000000000000000000000060c0908152620000409160189190620001fd565b503480156200004e57600080fd5b50604051620056c0380380620056c08339810160408190526200007191620002a3565b6040518060400160405280600d81526020016c105255081a541054d4c8139195609a1b815250604051806040016040528060048152602001634149544960e01b8152508585858585858585838383838080620000dc620000d6620001a960201b60201c565b620001ad565b6001600160a01b03166080525081620001515760405162461bcd60e51b815260206004820152602d60248201527f4f4e46543732313a206d696e476173546f5472616e73666572416e6453746f7260448201526c065206d757374206265203e203609c1b606482015260840160405180910390fd5b5060065581516200016a90600a906020850190620001fd565b5080516200018090600b906020840190620001fd565b50506014805460ff1916905550505060169390935550601755506200032d975050505050505050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280546200020b90620002f0565b90600052602060002090601f0160209004810192826200022f57600085556200027a565b82601f106200024a57805160ff19168380011785556200027a565b828001600101855582156200027a579182015b828111156200027a5782518255916020019190600101906200025d565b50620002889291506200028c565b5090565b5b808211156200028857600081556001016200028d565b60008060008060808587031215620002ba57600080fd5b845160208601519094506001600160a01b0381168114620002da57600080fd5b6040860151606090960151949790965092505050565b600181811c908216806200030557607f821691505b602082108114156200032757634e487b7160e01b600052602260045260246000fd5b50919050565b60805161533f6200038160003960008181610b3d01528181610d770152818161107b015281816112d3015281816115a1015281816120da0152818161255a01528181612690015261380a015261533f6000f3fe6080604052600436106103ee5760003560e01c806370a0823111610208578063b353aaa711610118578063d547741f116100ab578063eb8d72b71161007a578063eb8d72b714610cc7578063f235364114610ce7578063f2fde38b14610d07578063f5ecbdbc14610d27578063fa25f9b614610d4757600080fd5b8063d547741f14610c28578063df2a5b3b14610c48578063e1d4c87014610c68578063e985e9c514610c7e57600080fd5b8063c87b56dd116100e7578063c87b56dd14610bb5578063cbed8b9c14610bd5578063d12473a514610bf5578063d1deba1f14610c1557600080fd5b8063b353aaa714610b2b578063b88d4fde14610b5f578063baf3292d14610b7f578063c446183414610b9f57600080fd5b806395d89b411161019b578063a217fddf1161016a578063a217fddf14610a9b578063a22cb46514610ab0578063a6c3d16514610ad0578063ab3ffb9314610af0578063af3fb21c14610b0357600080fd5b806395d89b4114610a265780639a03c1cd14610a3b5780639ea5d6b114610a5b5780639f38369a14610a7b57600080fd5b80638da5cb5b116101d75780638da5cb5b146109a85780638ffa1f2a146109c657806391d14854146109e6578063950c8a7414610a0657600080fd5b806370a082311461091b578063715018a61461093b5780637533d788146109505780638cfd8f5c1461097057600080fd5b80633d8b38f61161030357806355f804b31161029657806363a846f81161026557806363a846f81461087557806366ad5c8a146108a55780636a627842146108c55780636aa99da3146108e557806370480275146108fb57600080fd5b806355f804b3146107ce5780635b8c41e6146107ee5780635c975abb1461083d5780636352211e1461085557600080fd5b806348288190116102d257806348288190146107585780634ac3f4ff1461076e5780634f6ccce71461079b57806351905636146107bb57600080fd5b80633d8b38f6146106cb5780633f1f4fa4146106eb57806342842e0e1461071857806342d65a8d1461073857600080fd5b806310ddb13711610386578063248a9ca311610355578063248a9ca3146106065780632a205e3d146106365780632f2ff15d1461066b5780632f745c591461068b57806336568abe146106ab57600080fd5b806310ddb1371461052457806318160ddd1461054457806322a3ecf91461056357806323b872dd146105e657600080fd5b8063081812fc116103c2578063081812fc1461048c578063095ea7b3146104c45780630b4cad4c146104e45780630df374831461050457600080fd5b80621d3567146103f357806301ffc9a71461041557806306fdde031461044a57806307e0db171461046c575b600080fd5b3480156103ff57600080fd5b5061041361040e36600461427c565b610d74565b005b34801561042157600080fd5b50610435610430366004614325565b610fa5565b60405190151581526020015b60405180910390f35b34801561045657600080fd5b5061045f610fc8565b604051610441919061439a565b34801561047857600080fd5b506104136104873660046143ad565b61105a565b34801561049857600080fd5b506104ac6104a73660046143c8565b6110e3565b6040516001600160a01b039091168152602001610441565b3480156104d057600080fd5b506104136104df366004614401565b61110a565b3480156104f057600080fd5b506104136104ff3660046143c8565b611220565b34801561051057600080fd5b5061041361051f36600461442d565b611293565b34801561053057600080fd5b5061041361053f3660046143ad565b6112b2565b34801561055057600080fd5b506012545b604051908152602001610441565b34801561056f57600080fd5b506105b761057e3660046143c8565b60096020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b0390931660208501529183015215156060820152608001610441565b3480156105f257600080fd5b50610413610601366004614449565b61130a565b34801561061257600080fd5b506105556106213660046143c8565b60009081526015602052604090206001015490565b34801561064257600080fd5b50610656610651366004614565565b61133c565b60408051928352602083019190915201610441565b34801561067757600080fd5b506104136106863660046145f3565b611362565b34801561069757600080fd5b506105556106a6366004614401565b611387565b3480156106b757600080fd5b506104136106c63660046145f3565b61141d565b3480156106d757600080fd5b506104356106e6366004614623565b61149b565b3480156106f757600080fd5b506105556107063660046143ad565b60036020526000908152604090205481565b34801561072457600080fd5b50610413610733366004614449565b611567565b34801561074457600080fd5b50610413610753366004614623565b611582565b34801561076457600080fd5b5061055560065481565b34801561077a57600080fd5b506105556107893660046143ad565b60076020526000908152604090205481565b3480156107a757600080fd5b506105556107b63660046143c8565b611608565b6104136107c9366004614675565b61169b565b3480156107da57600080fd5b506104136107e936600461472e565b6116b2565b3480156107fa57600080fd5b50610555610809366004614776565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561084957600080fd5b5060145460ff16610435565b34801561086157600080fd5b506104ac6108703660046143c8565b6116cd565b34801561088157600080fd5b506104356108903660046147d3565b60196020526000908152604090205460ff1681565b3480156108b157600080fd5b506104136108c036600461427c565b61172d565b3480156108d157600080fd5b506104136108e03660046147d3565b611809565b3480156108f157600080fd5b5061055560165481565b34801561090757600080fd5b506104136109163660046147d3565b6118ab565b34801561092757600080fd5b506105556109363660046147d3565b611918565b34801561094757600080fd5b5061041361199e565b34801561095c57600080fd5b5061045f61096b3660046143ad565b6119b2565b34801561097c57600080fd5b5061055561098b3660046147f0565b600260209081526000928352604080842090915290825290205481565b3480156109b457600080fd5b506000546001600160a01b03166104ac565b3480156109d257600080fd5b506104136109e1366004614823565b611a4c565b3480156109f257600080fd5b50610435610a013660046145f3565b611c9b565b348015610a1257600080fd5b506004546104ac906001600160a01b031681565b348015610a3257600080fd5b5061045f611cc6565b348015610a4757600080fd5b50610413610a56366004614857565b611cd5565b348015610a6757600080fd5b50610413610a7636600461442d565b611d86565b348015610a8757600080fd5b5061045f610a963660046143ad565b611e09565b348015610aa757600080fd5b50610555600081565b348015610abc57600080fd5b50610413610acb366004614879565b611f20565b348015610adc57600080fd5b50610413610aeb366004614623565b611f2b565b610413610afe36600461492e565b611fbe565b348015610b0f57600080fd5b50610b18600181565b60405161ffff9091168152602001610441565b348015610b3757600080fd5b506104ac7f000000000000000000000000000000000000000000000000000000000000000081565b348015610b6b57600080fd5b50610413610b7a3660046149e3565b611fcd565b348015610b8b57600080fd5b50610413610b9a3660046147d3565b611fff565b348015610bab57600080fd5b5061055561271081565b348015610bc157600080fd5b5061045f610bd03660046143c8565b612055565b348015610be157600080fd5b50610413610bf0366004614a4e565b6120bb565b348015610c0157600080fd5b50610413610c1036600461442d565b612150565b610413610c2336600461427c565b6121d4565b348015610c3457600080fd5b50610413610c433660046145f3565b6123ea565b348015610c5457600080fd5b50610413610c63366004614abc565b61240f565b348015610c7457600080fd5b5061055560175481565b348015610c8a57600080fd5b50610435610c99366004614af8565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205460ff1690565b348015610cd357600080fd5b50610413610ce2366004614623565b6124c1565b348015610cf357600080fd5b50610656610d02366004614b26565b61251b565b348015610d1357600080fd5b50610413610d223660046147d3565b6125e6565b348015610d3357600080fd5b5061045f610d42366004614b9f565b61265f565b348015610d5357600080fd5b50610555610d623660046143ad565b60086020526000908152604090205481565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614610df15760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526001602052604081208054610e0f90614bec565b80601f0160208091040260200160405190810160405280929190818152602001828054610e3b90614bec565b8015610e885780601f10610e5d57610100808354040283529160200191610e88565b820191906000526020600020905b815481529060010190602001808311610e6b57829003601f168201915b50505050509050805186869050148015610ea3575060008151115b8015610ecb575080516020820120604051610ec19088908890614c27565b6040518091039020145b610f265760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610de8565b610f9c8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061271292505050565b50505050505050565b60006001600160e01b031982161580610fc25750610fc28261278b565b92915050565b6060600a8054610fd790614bec565b80601f016020809104026020016040519081016040528092919081815260200182805461100390614bec565b80156110505780601f1061102557610100808354040283529160200191611050565b820191906000526020600020905b81548152906001019060200180831161103357829003601f168201915b5050505050905090565b6110626127b0565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307e0db17906024015b600060405180830381600087803b1580156110c857600080fd5b505af11580156110dc573d6000803e3d6000fd5b5050505050565b60006110ee8261280a565b506000908152600e60205260409020546001600160a01b031690565b6000611115826116cd565b9050806001600160a01b0316836001600160a01b031614156111835760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610de8565b336001600160a01b038216148061119f575061119f8133610c99565b6112115760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610de8565b61121b8383612869565b505050565b6112286127b0565b6000811161128e5760405162461bcd60e51b815260206004820152602d60248201527f4f4e46543732313a206d696e476173546f5472616e73666572416e6453746f7260448201526c065206d757374206265203e203609c1b6064820152608401610de8565b600655565b61129b6127b0565b61ffff909116600090815260036020526040902055565b6112ba6127b0565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906310ddb137906024016110ae565b611315335b826128d7565b6113315760405162461bcd60e51b8152600401610de890614c37565b61121b838383612955565b600080611354878761134d88612afc565b878761251b565b915091509550959350505050565b60008281526015602052604090206001015461137d81612b47565b61121b8383612b51565b600061139283611918565b82106113f45760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610de8565b506001600160a01b03919091166000908152601060209081526040808320938352929052205490565b6001600160a01b038116331461148d5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610de8565b6114978282612bd7565b5050565b61ffff8316600090815260016020526040812080548291906114bc90614bec565b80601f01602080910402602001604051908101604052809291908181526020018280546114e890614bec565b80156115355780601f1061150a57610100808354040283529160200191611535565b820191906000526020600020905b81548152906001019060200180831161151857829003601f168201915b50505050509050838360405161154c929190614c27565b60405180910390208180519060200120149150509392505050565b61121b83838360405180602001604052806000815250611fcd565b61158a6127b0565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342d65a8d906115da90869086908690600401614cae565b600060405180830381600087803b1580156115f457600080fd5b505af1158015610f9c573d6000803e3d6000fd5b600061161360125490565b82106116765760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610de8565b6012828154811061168957611689614ccc565b90600052602060002001549050919050565b610f9c8787876116aa88612afc565b878787612c3e565b6116ba6127b0565b80516114979060189060208401906140f9565b6000818152600c60205260408120546001600160a01b031680610fc25760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610de8565b33301461178b5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610de8565b6118018686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f890181900481028201810190925287815289935091508790879081908401838280828437600092019190915250612e2592505050565b505050505050565b3360009081526019602052604090205460ff1661182557600080fd5b601754601654111561188a5760405162461bcd60e51b815260206004820152602860248201527f556e6976657273616c4f4e46543732313a206d6178206d696e74206c696d6974604482015267081c995858da195960c21b6064820152608401610de8565b60168054908190600061189c83614cf8565b91905055506114978282612f7c565b6118b36127b0565b6001600160a01b038116600081815260196020908152604091829020805460ff81161560ff19909116179055815192835242908301527fbd5dcf0b25226117c4a68a0129ffdd4b0541ef5e482ad7de9a96ccb6d6a8ebde91015b60405180910390a150565b60006001600160a01b0382166119825760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610de8565b506001600160a01b03166000908152600d602052604090205490565b6119a66127b0565b6119b06000612f96565b565b600160205260009081526040902080546119cb90614bec565b80601f01602080910402602001604051908101604052809291908181526020018280546119f790614bec565b8015611a445780601f10611a1957610100808354040283529160200191611a44565b820191906000526020600020905b815481529060010190602001808311611a2757829003601f168201915b505050505081565b80516020808301919091206000818152600990925260409091206002015460ff16611ab95760405162461bcd60e51b815260206004820152601a60248201527f4f4e46543732313a206e6f20637265646974732073746f7265640000000000006044820152606401610de8565b600082806020019051810190611acf9190614d58565b60008481526009602052604081208054600190910154929450909250611b0b9161ffff8216916201000090046001600160a01b03169085612fe6565b6000848152600960205260409020600101549091508111611b895760405162461bcd60e51b815260206004820152603260248201527f4f4e46543732313a206e6f7420656e6f7567682067617320746f2070726f636560448201527139b99031b932b234ba103a3930b739b332b960711b6064820152608401610de8565b8151811415611c015760008381526009602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba23390611bf49085815260200190565b60405180910390a1611c95565b60408051608081018252600085815260096020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b50505050565b60009182526015602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060600b8054610fd790614bec565b611cdd6127b0565b81601754108015611ced57508082105b611d395760405162461bcd60e51b815260206004820152601960248201527f4e46543a2052414e47455f544f4b454e5f49445f57524f4e47000000000000006044820152606401610de8565b601682905560178190556040805183815260208101839052428183015290517f7db56eb2742bf8b3ecbd53c305e1b52da85b7d34804466938417948949d91a209181900360600190a15050565b611d8e6127b0565b60008111611df25760405162461bcd60e51b815260206004820152602b60248201527f4f4e46543732313a20647374436861696e4964546f42617463684c696d69742060448201526a06d757374206265203e20360ac1b6064820152608401610de8565b61ffff909116600090815260076020526040902055565b61ffff8116600090815260016020526040812080546060929190611e2c90614bec565b80601f0160208091040260200160405190810160405280929190818152602001828054611e5890614bec565b8015611ea55780601f10611e7a57610100808354040283529160200191611ea5565b820191906000526020600020905b815481529060010190602001808311611e8857829003601f168201915b50505050509050805160001415611efe5760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f72640000006044820152606401610de8565b611f19600060148351611f119190614e12565b839190613038565b9392505050565b611497338383613145565b611f336127b0565b818130604051602001611f4893929190614e29565b60408051601f1981840301815291815261ffff85166000908152600160209081529190208251611f7d939192909101906140f9565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce838383604051611fb193929190614cae565b60405180910390a1505050565b610f9c87878787878787612c3e565b611fd733836128d7565b611ff35760405162461bcd60e51b8152600401610de890614c37565b611c9584848484613214565b6120076127b0565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b9060200161190d565b60606120608261280a565b600061206a613247565b9050600081511161208a5760405180602001604052806000815250611f19565b8061209484613256565b6040516020016120a5929190614e4f565b6040516020818303038152906040529392505050565b6120c36127b0565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbed8b9c906121179088908890889088908890600401614e7e565b600060405180830381600087803b15801561213157600080fd5b505af1158015612145573d6000803e3d6000fd5b505050505050505050565b6121586127b0565b600081116121bd5760405162461bcd60e51b815260206004820152602c60248201527f4f4e46543732313a20647374436861696e4964546f5472616e7366657247617360448201526b0206d757374206265203e20360a41b6064820152608401610de8565b61ffff909116600090815260086020526040902055565b61ffff861660009081526005602052604080822090516121f79088908890614c27565b90815260408051602092819003830190206001600160401b038716600090815292529020549050806122775760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610de8565b808383604051612288929190614c27565b6040518091039020146122e75760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610de8565b61ffff8716600090815260056020526040808220905161230a9089908990614c27565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f880182900482028301820190528682526123a2918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250612e2592505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e587878787856040516123d9959493929190614eb7565b60405180910390a150505050505050565b60008281526015602052604090206001015461240581612b47565b61121b8383612bd7565b6124176127b0565b6000811161245f5760405162461bcd60e51b81526020600482015260156024820152744c7a4170703a20696e76616c6964206d696e47617360581b6044820152606401610de8565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611fb1565b6124c96127b0565b61ffff831660009081526001602052604090206124e790838361417d565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab838383604051611fb193929190614cae565b60008060008686604051602001612533929190614f2d565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340a7bb1090612597908b90309086908b908b90600401614f5b565b6040805180830381865afa1580156125b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d79190614faf565b92509250509550959350505050565b6125ee6127b0565b6001600160a01b0381166126535760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610de8565b61265c81612f96565b50565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5ecbdbc90608401600060405180830381865afa1580156126df573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127079190810190614fd3565b90505b949350505050565b6000806127755a60966366ad5c8a60e01b8989898960405160240161273a9493929190615007565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915230929190613353565b91509150816118015761180186868686856133dd565b60006001600160e01b03198216637965db0b60e01b1480610fc25750610fc28261347a565b6000546001600160a01b031633146119b05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610de8565b6000818152600c60205260409020546001600160a01b031661265c5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610de8565b6000818152600e6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061289e826116cd565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806128e3836116cd565b9050806001600160a01b0316846001600160a01b0316148061292a57506001600160a01b038082166000908152600f602090815260408083209388168352929052205460ff165b8061270a5750836001600160a01b0316612943846110e3565b6001600160a01b031614949350505050565b826001600160a01b0316612968826116cd565b6001600160a01b0316146129cc5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610de8565b6001600160a01b038216612a2e5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610de8565b612a3983838361349f565b612a44600082612869565b6001600160a01b0383166000908152600d60205260408120805460019290612a6d908490614e12565b90915550506001600160a01b0382166000908152600d60205260408120805460019290612a9b908490615045565b90915550506000818152600c602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60408051600180825281830190925260609160009190602080830190803683370190505090508281600081518110612b3657612b36614ccc565b602090810291909101015292915050565b61265c81336134b2565b612b5b8282611c9b565b6114975760008281526015602090815260408083206001600160a01b03851684529091529020805460ff19166001179055612b933390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b612be18282611c9b565b156114975760008281526015602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000845111612c8f5760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a20746f6b656e4964735b5d20697320656d7074790000000000006044820152606401610de8565b835160011480612cb3575061ffff8616600090815260076020526040902054845111155b612d135760405162461bcd60e51b815260206004820152602b60248201527f4f4e46543732313a2062617463682073697a652065786365656473206473742060448201526a18985d18da081b1a5b5a5d60aa1b6064820152608401610de8565b60005b8451811015612d5657612d44888888888581518110612d3757612d37614ccc565b6020026020010151613516565b80612d4e81614cf8565b915050612d16565b5060008585604051602001612d6c929190614f2d565b6040516020818303038152906040529050612db1876001848851600860008d61ffff1661ffff16815260200190815260200160002054612dac919061505d565b613601565b612dbf8782868686346136e0565b85604051612dcd919061507c565b6040518091039020886001600160a01b03168861ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a88604051612e139190615098565b60405180910390a45050505050505050565b60008082806020019051810190612e3c9190614d58565b601482015191935091506000612e5488838386612fe6565b90508251811015612f285784516020808701919091206040805160808101825261ffff808d1682526001600160a01b0380881683870190815283850188815260016060860181815260008981526009909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad790612f1e90839089906150ab565b60405180910390a1505b816001600160a01b031687604051612f40919061507c565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026586604051612e139190615098565b611497828260405180602001604052806000815250613886565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000825b8251811015612707576006545a101561300257612707565b613026868685848151811061301957613019614ccc565b60200260200101516138b9565b8061303081614cf8565b915050612fea565b60608161304681601f615045565b10156130855760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610de8565b61308f8284615045565b845110156130d35760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610de8565b6060821580156130f2576040519150600082526020820160405261313c565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561312b578051835260209283019201613113565b5050858452601f01601f1916604052505b50949350505050565b816001600160a01b0316836001600160a01b031614156131a75760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610de8565b6001600160a01b038381166000818152600f6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61321f848484612955565b61322b84848484613948565b611c955760405162461bcd60e51b8152600401610de8906150c4565b606060188054610fd790614bec565b60608161327a5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156132a4578061328e81614cf8565b915061329d9050600a8361512c565b915061327e565b6000816001600160401b038111156132be576132be61448a565b6040519080825280601f01601f1916602001820160405280156132e8576020820181803683370190505b5090505b841561270a576132fd600183614e12565b915061330a600a86615140565b613315906030615045565b60f81b81838151811061332a5761332a614ccc565b60200101906001600160f81b031916908160001a90535061334c600a8661512c565b94506132ec565b6000606060008060008661ffff166001600160401b038111156133785761337861448a565b6040519080825280601f01601f1916602001820160405280156133a2576020820181803683370190505b50905060008087516020890160008d8df191503d9250868311156133c4578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff1681526020019081526020016000208560405161340e919061507c565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c9061346b9087908790879087908790615154565b60405180910390a15050505050565b60006001600160e01b0319821663780e9d6360e01b1480610fc25750610fc282613a43565b6134a7613a83565b61121b838383613ac9565b6134bc8282611c9b565b611497576134d4816001600160a01b03166014613b81565b6134df836020613b81565b6040516020016134f09291906151a6565b60408051601f198184030181529082905262461bcd60e51b8252610de89160040161439a565b61351f3361130f565b6135825760405162461bcd60e51b815260206004820152602e60248201527f4f4e46543732313a2073656e642063616c6c6572206973206e6f74206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b6064820152608401610de8565b836001600160a01b0316613595826116cd565b6001600160a01b0316146135f65760405162461bcd60e51b815260206004820152602260248201527f4f4e46543732313a2073656e642066726f6d20696e636f7272656374206f776e60448201526132b960f11b6064820152608401610de8565b611c95843083612955565b600061360c83613d1c565b61ffff80871660009081526002602090815260408083209389168352929052908120549192509061363e908490615045565b9050600081116136905760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f74207365740000000000006044820152606401610de8565b808210156118015760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f7700000000006044820152606401610de8565b61ffff8616600090815260016020526040812080546136fe90614bec565b80601f016020809104026020016040519081016040528092919081815260200182805461372a90614bec565b80156137775780601f1061374c57610100808354040283529160200191613777565b820191906000526020600020905b81548152906001019060200180831161375a57829003601f168201915b505050505090508051600014156137e95760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610de8565b6137f4878751613d78565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c580310090849061384b908b9086908c908c908c908c9060040161521b565b6000604051808303818588803b15801561386457600080fd5b505af1158015613878573d6000803e3d6000fd5b505050505050505050505050565b6138908383613de6565b61389d6000848484613948565b61121b5760405162461bcd60e51b8152600401610de8906150c4565b6000818152600c60205260409020546001600160a01b0316158061390e57506000818152600c60205260409020546001600160a01b03161515801561390e575030613903826116cd565b6001600160a01b0316145b61391757600080fd5b6000818152600c60205260409020546001600160a01b031661393d5761121b8282612f7c565b61121b308383612955565b60006001600160a01b0384163b15613a3b57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061398c903390899088908890600401615282565b6020604051808303816000875af19250505080156139c7575060408051601f3d908101601f191682019092526139c4918101906152bf565b60015b613a21573d8080156139f5576040519150601f19603f3d011682016040523d82523d6000602084013e6139fa565b606091505b508051613a195760405162461bcd60e51b8152600401610de8906150c4565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061270a565b50600161270a565b60006001600160e01b031982166380ac58cd60e01b1480613a7457506001600160e01b03198216635b5e139f60e01b145b80610fc25750610fc282613f34565b60145460ff16156119b05760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610de8565b6001600160a01b038316613b2457613b1f81601280546000838152601360205260408120829055600182018355919091527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440155565b613b47565b816001600160a01b0316836001600160a01b031614613b4757613b478382613f69565b6001600160a01b038216613b5e5761121b81614006565b826001600160a01b0316826001600160a01b03161461121b5761121b82826140b5565b60606000613b9083600261505d565b613b9b906002615045565b6001600160401b03811115613bb257613bb261448a565b6040519080825280601f01601f191660200182016040528015613bdc576020820181803683370190505b509050600360fc1b81600081518110613bf757613bf7614ccc565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613c2657613c26614ccc565b60200101906001600160f81b031916908160001a9053506000613c4a84600261505d565b613c55906001615045565b90505b6001811115613ccd576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613c8957613c89614ccc565b1a60f81b828281518110613c9f57613c9f614ccc565b60200101906001600160f81b031916908160001a90535060049490941c93613cc6816152dc565b9050613c58565b508315611f195760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610de8565b6000602282511015613d705760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d73000000006044820152606401610de8565b506022015190565b61ffff821660009081526003602052604090205480613d9657506127105b8082111561121b5760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c617267656044820152606401610de8565b6001600160a01b038216613e3c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610de8565b6000818152600c60205260409020546001600160a01b031615613ea15760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610de8565b613ead6000838361349f565b6001600160a01b0382166000908152600d60205260408120805460019290613ed6908490615045565b90915550506000818152600c602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160e01b031982166322bac5d960e01b1480610fc257506301ffc9a760e01b6001600160e01b0319831614610fc2565b60006001613f7684611918565b613f809190614e12565b600083815260116020526040902054909150808214613fd3576001600160a01b03841660009081526010602090815260408083208584528252808320548484528184208190558352601190915290208190555b5060009182526011602090815260408084208490556001600160a01b039094168352601081528383209183525290812055565b60125460009061401890600190614e12565b6000838152601360205260408120546012805493945090928490811061404057614040614ccc565b90600052602060002001549050806012838154811061406157614061614ccc565b6000918252602080832090910192909255828152601390915260408082208490558582528120556012805480614099576140996152f3565b6001900381819060005260206000200160009055905550505050565b60006140c083611918565b6001600160a01b039093166000908152601060209081526040808320868452825280832085905593825260119052919091209190915550565b82805461410590614bec565b90600052602060002090601f016020900481019282614127576000855561416d565b82601f1061414057805160ff191683800117855561416d565b8280016001018555821561416d579182015b8281111561416d578251825591602001919060010190614152565b506141799291506141f1565b5090565b82805461418990614bec565b90600052602060002090601f0160209004810192826141ab576000855561416d565b82601f106141c45782800160ff1982351617855561416d565b8280016001018555821561416d579182015b8281111561416d5782358255916020019190600101906141d6565b5b8082111561417957600081556001016141f2565b803561ffff8116811461421857600080fd5b919050565b60008083601f84011261422f57600080fd5b5081356001600160401b0381111561424657600080fd5b60208301915083602082850101111561425e57600080fd5b9250929050565b80356001600160401b038116811461421857600080fd5b6000806000806000806080878903121561429557600080fd5b61429e87614206565b955060208701356001600160401b03808211156142ba57600080fd5b6142c68a838b0161421d565b90975095508591506142da60408a01614265565b945060608901359150808211156142f057600080fd5b506142fd89828a0161421d565b979a9699509497509295939492505050565b6001600160e01b03198116811461265c57600080fd5b60006020828403121561433757600080fd5b8135611f198161430f565b60005b8381101561435d578181015183820152602001614345565b83811115611c955750506000910152565b60008151808452614386816020860160208601614342565b601f01601f19169290920160200192915050565b602081526000611f19602083018461436e565b6000602082840312156143bf57600080fd5b611f1982614206565b6000602082840312156143da57600080fd5b5035919050565b6001600160a01b038116811461265c57600080fd5b8035614218816143e1565b6000806040838503121561441457600080fd5b823561441f816143e1565b946020939093013593505050565b6000806040838503121561444057600080fd5b61441f83614206565b60008060006060848603121561445e57600080fd5b8335614469816143e1565b92506020840135614479816143e1565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156144c8576144c861448a565b604052919050565b60006001600160401b038211156144e9576144e961448a565b50601f01601f191660200190565b600061450a614505846144d0565b6144a0565b905082815283838301111561451e57600080fd5b828260208301376000602084830101529392505050565b600082601f83011261454657600080fd5b611f19838335602085016144f7565b8035801515811461421857600080fd5b600080600080600060a0868803121561457d57600080fd5b61458686614206565b945060208601356001600160401b03808211156145a257600080fd5b6145ae89838a01614535565b9550604088013594506145c360608901614555565b935060808801359150808211156145d957600080fd5b506145e688828901614535565b9150509295509295909350565b6000806040838503121561460657600080fd5b823591506020830135614618816143e1565b809150509250929050565b60008060006040848603121561463857600080fd5b61464184614206565b925060208401356001600160401b0381111561465c57600080fd5b6146688682870161421d565b9497909650939450505050565b600080600080600080600060e0888a03121561469057600080fd5b873561469b816143e1565b96506146a960208901614206565b955060408801356001600160401b03808211156146c557600080fd5b6146d18b838c01614535565b965060608a0135955060808a013591506146ea826143e1565b90935060a0890135906146fc826143e1565b90925060c0890135908082111561471257600080fd5b5061471f8a828b01614535565b91505092959891949750929550565b60006020828403121561474057600080fd5b81356001600160401b0381111561475657600080fd5b8201601f8101841361476757600080fd5b61270a848235602084016144f7565b60008060006060848603121561478b57600080fd5b61479484614206565b925060208401356001600160401b038111156147af57600080fd5b6147bb86828701614535565b9250506147ca60408501614265565b90509250925092565b6000602082840312156147e557600080fd5b8135611f19816143e1565b6000806040838503121561480357600080fd5b61480c83614206565b915061481a60208401614206565b90509250929050565b60006020828403121561483557600080fd5b81356001600160401b0381111561484b57600080fd5b61270a84828501614535565b6000806040838503121561486a57600080fd5b50508035926020909101359150565b6000806040838503121561488c57600080fd5b8235614897816143e1565b915061481a60208401614555565b60006001600160401b038211156148be576148be61448a565b5060051b60200190565b600082601f8301126148d957600080fd5b813560206148e9614505836148a5565b82815260059290921b8401810191818101908684111561490857600080fd5b8286015b84811015614923578035835291830191830161490c565b509695505050505050565b600080600080600080600060e0888a03121561494957600080fd5b8735614954816143e1565b965061496260208901614206565b955060408801356001600160401b038082111561497e57600080fd5b61498a8b838c01614535565b965060608a01359150808211156149a057600080fd5b6149ac8b838c016148c8565b955060808a013591506149be826143e1565b8194506149cd60a08b016143f6565b935060c08a013591508082111561471257600080fd5b600080600080608085870312156149f957600080fd5b8435614a04816143e1565b93506020850135614a14816143e1565b92506040850135915060608501356001600160401b03811115614a3657600080fd5b614a4287828801614535565b91505092959194509250565b600080600080600060808688031215614a6657600080fd5b614a6f86614206565b9450614a7d60208701614206565b93506040860135925060608601356001600160401b03811115614a9f57600080fd5b614aab8882890161421d565b969995985093965092949392505050565b600080600060608486031215614ad157600080fd5b614ada84614206565b9250614ae860208501614206565b9150604084013590509250925092565b60008060408385031215614b0b57600080fd5b8235614b16816143e1565b91506020830135614618816143e1565b600080600080600060a08688031215614b3e57600080fd5b614b4786614206565b945060208601356001600160401b0380821115614b6357600080fd5b614b6f89838a01614535565b95506040880135915080821115614b8557600080fd5b614b9189838a016148c8565b94506145c360608901614555565b60008060008060808587031215614bb557600080fd5b614bbe85614206565b9350614bcc60208601614206565b92506040850135614bdc816143e1565b9396929550929360600135925050565b600181811c90821680614c0057607f821691505b60208210811415614c2157634e487b7160e01b600052602260045260246000fd5b50919050565b8183823760009101908152919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff84168152604060208201526000612707604083018486614c85565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415614d0c57614d0c614ce2565b5060010190565b600082601f830112614d2457600080fd5b8151614d32614505826144d0565b818152846020838601011115614d4757600080fd5b61270a826020830160208701614342565b60008060408385031215614d6b57600080fd5b82516001600160401b0380821115614d8257600080fd5b614d8e86838701614d13565b9350602091508185015181811115614da557600080fd5b85019050601f81018613614db857600080fd5b8051614dc6614505826148a5565b81815260059190911b82018301908381019088831115614de557600080fd5b928401925b82841015614e0357835182529284019290840190614dea565b80955050505050509250929050565b600082821015614e2457614e24614ce2565b500390565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b60008351614e61818460208801614342565b835190830190614e75818360208801614342565b01949350505050565b600061ffff808816835280871660208401525084604083015260806060830152614eac608083018486614c85565b979650505050505050565b61ffff86168152608060208201526000614ed5608083018688614c85565b6001600160401b0394909416604083015250606001529392505050565b600081518084526020808501945080840160005b83811015614f2257815187529582019590820190600101614f06565b509495945050505050565b604081526000614f40604083018561436e565b8281036020840152614f528185614ef2565b95945050505050565b61ffff861681526001600160a01b038516602082015260a060408201819052600090614f899083018661436e565b84151560608401528281036080840152614fa3818561436e565b98975050505050505050565b60008060408385031215614fc257600080fd5b505080516020909101519092909150565b600060208284031215614fe557600080fd5b81516001600160401b03811115614ffb57600080fd5b61270a84828501614d13565b61ffff85168152608060208201526000615024608083018661436e565b6001600160401b03851660408401528281036060840152614eac818561436e565b6000821982111561505857615058614ce2565b500190565b600081600019048311821515161561507757615077614ce2565b500290565b6000825161508e818460208701614342565b9190910192915050565b602081526000611f196020830184614ef2565b82815260406020820152600061270a604083018461436e565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b60008261513b5761513b615116565b500490565b60008261514f5761514f615116565b500690565b61ffff8616815260a06020820152600061517160a083018761436e565b6001600160401b03861660408401528281036060840152615192818661436e565b90508281036080840152614fa3818561436e565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516151de816017850160208801614342565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161520f816028840160208801614342565b01602801949350505050565b61ffff8716815260c06020820152600061523860c083018861436e565b828103604084015261524a818861436e565b6001600160a01b0387811660608601528616608085015283810360a08501529050615275818561436e565b9998505050505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906152b59083018461436e565b9695505050505050565b6000602082840312156152d157600080fd5b8151611f198161430f565b6000816152eb576152eb614ce2565b506000190190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212209d435277c4fd257096e99d5ca0418c42cb647649db9f698ef6167b57e72579db64736f6c634300080c0033000000000000000000000000000000000000000000000000000000000000000100000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000002710

Deployed Bytecode

0x6080604052600436106103ee5760003560e01c806370a0823111610208578063b353aaa711610118578063d547741f116100ab578063eb8d72b71161007a578063eb8d72b714610cc7578063f235364114610ce7578063f2fde38b14610d07578063f5ecbdbc14610d27578063fa25f9b614610d4757600080fd5b8063d547741f14610c28578063df2a5b3b14610c48578063e1d4c87014610c68578063e985e9c514610c7e57600080fd5b8063c87b56dd116100e7578063c87b56dd14610bb5578063cbed8b9c14610bd5578063d12473a514610bf5578063d1deba1f14610c1557600080fd5b8063b353aaa714610b2b578063b88d4fde14610b5f578063baf3292d14610b7f578063c446183414610b9f57600080fd5b806395d89b411161019b578063a217fddf1161016a578063a217fddf14610a9b578063a22cb46514610ab0578063a6c3d16514610ad0578063ab3ffb9314610af0578063af3fb21c14610b0357600080fd5b806395d89b4114610a265780639a03c1cd14610a3b5780639ea5d6b114610a5b5780639f38369a14610a7b57600080fd5b80638da5cb5b116101d75780638da5cb5b146109a85780638ffa1f2a146109c657806391d14854146109e6578063950c8a7414610a0657600080fd5b806370a082311461091b578063715018a61461093b5780637533d788146109505780638cfd8f5c1461097057600080fd5b80633d8b38f61161030357806355f804b31161029657806363a846f81161026557806363a846f81461087557806366ad5c8a146108a55780636a627842146108c55780636aa99da3146108e557806370480275146108fb57600080fd5b806355f804b3146107ce5780635b8c41e6146107ee5780635c975abb1461083d5780636352211e1461085557600080fd5b806348288190116102d257806348288190146107585780634ac3f4ff1461076e5780634f6ccce71461079b57806351905636146107bb57600080fd5b80633d8b38f6146106cb5780633f1f4fa4146106eb57806342842e0e1461071857806342d65a8d1461073857600080fd5b806310ddb13711610386578063248a9ca311610355578063248a9ca3146106065780632a205e3d146106365780632f2ff15d1461066b5780632f745c591461068b57806336568abe146106ab57600080fd5b806310ddb1371461052457806318160ddd1461054457806322a3ecf91461056357806323b872dd146105e657600080fd5b8063081812fc116103c2578063081812fc1461048c578063095ea7b3146104c45780630b4cad4c146104e45780630df374831461050457600080fd5b80621d3567146103f357806301ffc9a71461041557806306fdde031461044a57806307e0db171461046c575b600080fd5b3480156103ff57600080fd5b5061041361040e36600461427c565b610d74565b005b34801561042157600080fd5b50610435610430366004614325565b610fa5565b60405190151581526020015b60405180910390f35b34801561045657600080fd5b5061045f610fc8565b604051610441919061439a565b34801561047857600080fd5b506104136104873660046143ad565b61105a565b34801561049857600080fd5b506104ac6104a73660046143c8565b6110e3565b6040516001600160a01b039091168152602001610441565b3480156104d057600080fd5b506104136104df366004614401565b61110a565b3480156104f057600080fd5b506104136104ff3660046143c8565b611220565b34801561051057600080fd5b5061041361051f36600461442d565b611293565b34801561053057600080fd5b5061041361053f3660046143ad565b6112b2565b34801561055057600080fd5b506012545b604051908152602001610441565b34801561056f57600080fd5b506105b761057e3660046143c8565b60096020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b0390931660208501529183015215156060820152608001610441565b3480156105f257600080fd5b50610413610601366004614449565b61130a565b34801561061257600080fd5b506105556106213660046143c8565b60009081526015602052604090206001015490565b34801561064257600080fd5b50610656610651366004614565565b61133c565b60408051928352602083019190915201610441565b34801561067757600080fd5b506104136106863660046145f3565b611362565b34801561069757600080fd5b506105556106a6366004614401565b611387565b3480156106b757600080fd5b506104136106c63660046145f3565b61141d565b3480156106d757600080fd5b506104356106e6366004614623565b61149b565b3480156106f757600080fd5b506105556107063660046143ad565b60036020526000908152604090205481565b34801561072457600080fd5b50610413610733366004614449565b611567565b34801561074457600080fd5b50610413610753366004614623565b611582565b34801561076457600080fd5b5061055560065481565b34801561077a57600080fd5b506105556107893660046143ad565b60076020526000908152604090205481565b3480156107a757600080fd5b506105556107b63660046143c8565b611608565b6104136107c9366004614675565b61169b565b3480156107da57600080fd5b506104136107e936600461472e565b6116b2565b3480156107fa57600080fd5b50610555610809366004614776565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561084957600080fd5b5060145460ff16610435565b34801561086157600080fd5b506104ac6108703660046143c8565b6116cd565b34801561088157600080fd5b506104356108903660046147d3565b60196020526000908152604090205460ff1681565b3480156108b157600080fd5b506104136108c036600461427c565b61172d565b3480156108d157600080fd5b506104136108e03660046147d3565b611809565b3480156108f157600080fd5b5061055560165481565b34801561090757600080fd5b506104136109163660046147d3565b6118ab565b34801561092757600080fd5b506105556109363660046147d3565b611918565b34801561094757600080fd5b5061041361199e565b34801561095c57600080fd5b5061045f61096b3660046143ad565b6119b2565b34801561097c57600080fd5b5061055561098b3660046147f0565b600260209081526000928352604080842090915290825290205481565b3480156109b457600080fd5b506000546001600160a01b03166104ac565b3480156109d257600080fd5b506104136109e1366004614823565b611a4c565b3480156109f257600080fd5b50610435610a013660046145f3565b611c9b565b348015610a1257600080fd5b506004546104ac906001600160a01b031681565b348015610a3257600080fd5b5061045f611cc6565b348015610a4757600080fd5b50610413610a56366004614857565b611cd5565b348015610a6757600080fd5b50610413610a7636600461442d565b611d86565b348015610a8757600080fd5b5061045f610a963660046143ad565b611e09565b348015610aa757600080fd5b50610555600081565b348015610abc57600080fd5b50610413610acb366004614879565b611f20565b348015610adc57600080fd5b50610413610aeb366004614623565b611f2b565b610413610afe36600461492e565b611fbe565b348015610b0f57600080fd5b50610b18600181565b60405161ffff9091168152602001610441565b348015610b3757600080fd5b506104ac7f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67581565b348015610b6b57600080fd5b50610413610b7a3660046149e3565b611fcd565b348015610b8b57600080fd5b50610413610b9a3660046147d3565b611fff565b348015610bab57600080fd5b5061055561271081565b348015610bc157600080fd5b5061045f610bd03660046143c8565b612055565b348015610be157600080fd5b50610413610bf0366004614a4e565b6120bb565b348015610c0157600080fd5b50610413610c1036600461442d565b612150565b610413610c2336600461427c565b6121d4565b348015610c3457600080fd5b50610413610c433660046145f3565b6123ea565b348015610c5457600080fd5b50610413610c63366004614abc565b61240f565b348015610c7457600080fd5b5061055560175481565b348015610c8a57600080fd5b50610435610c99366004614af8565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205460ff1690565b348015610cd357600080fd5b50610413610ce2366004614623565b6124c1565b348015610cf357600080fd5b50610656610d02366004614b26565b61251b565b348015610d1357600080fd5b50610413610d223660046147d3565b6125e6565b348015610d3357600080fd5b5061045f610d42366004614b9f565b61265f565b348015610d5357600080fd5b50610555610d623660046143ad565b60086020526000908152604090205481565b337f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b031614610df15760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526001602052604081208054610e0f90614bec565b80601f0160208091040260200160405190810160405280929190818152602001828054610e3b90614bec565b8015610e885780601f10610e5d57610100808354040283529160200191610e88565b820191906000526020600020905b815481529060010190602001808311610e6b57829003601f168201915b50505050509050805186869050148015610ea3575060008151115b8015610ecb575080516020820120604051610ec19088908890614c27565b6040518091039020145b610f265760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610de8565b610f9c8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061271292505050565b50505050505050565b60006001600160e01b031982161580610fc25750610fc28261278b565b92915050565b6060600a8054610fd790614bec565b80601f016020809104026020016040519081016040528092919081815260200182805461100390614bec565b80156110505780601f1061102557610100808354040283529160200191611050565b820191906000526020600020905b81548152906001019060200180831161103357829003601f168201915b5050505050905090565b6110626127b0565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b0316906307e0db17906024015b600060405180830381600087803b1580156110c857600080fd5b505af11580156110dc573d6000803e3d6000fd5b5050505050565b60006110ee8261280a565b506000908152600e60205260409020546001600160a01b031690565b6000611115826116cd565b9050806001600160a01b0316836001600160a01b031614156111835760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610de8565b336001600160a01b038216148061119f575061119f8133610c99565b6112115760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610de8565b61121b8383612869565b505050565b6112286127b0565b6000811161128e5760405162461bcd60e51b815260206004820152602d60248201527f4f4e46543732313a206d696e476173546f5472616e73666572416e6453746f7260448201526c065206d757374206265203e203609c1b6064820152608401610de8565b600655565b61129b6127b0565b61ffff909116600090815260036020526040902055565b6112ba6127b0565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b0316906310ddb137906024016110ae565b611315335b826128d7565b6113315760405162461bcd60e51b8152600401610de890614c37565b61121b838383612955565b600080611354878761134d88612afc565b878761251b565b915091509550959350505050565b60008281526015602052604090206001015461137d81612b47565b61121b8383612b51565b600061139283611918565b82106113f45760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610de8565b506001600160a01b03919091166000908152601060209081526040808320938352929052205490565b6001600160a01b038116331461148d5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610de8565b6114978282612bd7565b5050565b61ffff8316600090815260016020526040812080548291906114bc90614bec565b80601f01602080910402602001604051908101604052809291908181526020018280546114e890614bec565b80156115355780601f1061150a57610100808354040283529160200191611535565b820191906000526020600020905b81548152906001019060200180831161151857829003601f168201915b50505050509050838360405161154c929190614c27565b60405180910390208180519060200120149150509392505050565b61121b83838360405180602001604052806000815250611fcd565b61158a6127b0565b6040516342d65a8d60e01b81526001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67516906342d65a8d906115da90869086908690600401614cae565b600060405180830381600087803b1580156115f457600080fd5b505af1158015610f9c573d6000803e3d6000fd5b600061161360125490565b82106116765760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610de8565b6012828154811061168957611689614ccc565b90600052602060002001549050919050565b610f9c8787876116aa88612afc565b878787612c3e565b6116ba6127b0565b80516114979060189060208401906140f9565b6000818152600c60205260408120546001600160a01b031680610fc25760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610de8565b33301461178b5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610de8565b6118018686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f890181900481028201810190925287815289935091508790879081908401838280828437600092019190915250612e2592505050565b505050505050565b3360009081526019602052604090205460ff1661182557600080fd5b601754601654111561188a5760405162461bcd60e51b815260206004820152602860248201527f556e6976657273616c4f4e46543732313a206d6178206d696e74206c696d6974604482015267081c995858da195960c21b6064820152608401610de8565b60168054908190600061189c83614cf8565b91905055506114978282612f7c565b6118b36127b0565b6001600160a01b038116600081815260196020908152604091829020805460ff81161560ff19909116179055815192835242908301527fbd5dcf0b25226117c4a68a0129ffdd4b0541ef5e482ad7de9a96ccb6d6a8ebde91015b60405180910390a150565b60006001600160a01b0382166119825760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610de8565b506001600160a01b03166000908152600d602052604090205490565b6119a66127b0565b6119b06000612f96565b565b600160205260009081526040902080546119cb90614bec565b80601f01602080910402602001604051908101604052809291908181526020018280546119f790614bec565b8015611a445780601f10611a1957610100808354040283529160200191611a44565b820191906000526020600020905b815481529060010190602001808311611a2757829003601f168201915b505050505081565b80516020808301919091206000818152600990925260409091206002015460ff16611ab95760405162461bcd60e51b815260206004820152601a60248201527f4f4e46543732313a206e6f20637265646974732073746f7265640000000000006044820152606401610de8565b600082806020019051810190611acf9190614d58565b60008481526009602052604081208054600190910154929450909250611b0b9161ffff8216916201000090046001600160a01b03169085612fe6565b6000848152600960205260409020600101549091508111611b895760405162461bcd60e51b815260206004820152603260248201527f4f4e46543732313a206e6f7420656e6f7567682067617320746f2070726f636560448201527139b99031b932b234ba103a3930b739b332b960711b6064820152608401610de8565b8151811415611c015760008381526009602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba23390611bf49085815260200190565b60405180910390a1611c95565b60408051608081018252600085815260096020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b50505050565b60009182526015602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060600b8054610fd790614bec565b611cdd6127b0565b81601754108015611ced57508082105b611d395760405162461bcd60e51b815260206004820152601960248201527f4e46543a2052414e47455f544f4b454e5f49445f57524f4e47000000000000006044820152606401610de8565b601682905560178190556040805183815260208101839052428183015290517f7db56eb2742bf8b3ecbd53c305e1b52da85b7d34804466938417948949d91a209181900360600190a15050565b611d8e6127b0565b60008111611df25760405162461bcd60e51b815260206004820152602b60248201527f4f4e46543732313a20647374436861696e4964546f42617463684c696d69742060448201526a06d757374206265203e20360ac1b6064820152608401610de8565b61ffff909116600090815260076020526040902055565b61ffff8116600090815260016020526040812080546060929190611e2c90614bec565b80601f0160208091040260200160405190810160405280929190818152602001828054611e5890614bec565b8015611ea55780601f10611e7a57610100808354040283529160200191611ea5565b820191906000526020600020905b815481529060010190602001808311611e8857829003601f168201915b50505050509050805160001415611efe5760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f72640000006044820152606401610de8565b611f19600060148351611f119190614e12565b839190613038565b9392505050565b611497338383613145565b611f336127b0565b818130604051602001611f4893929190614e29565b60408051601f1981840301815291815261ffff85166000908152600160209081529190208251611f7d939192909101906140f9565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce838383604051611fb193929190614cae565b60405180910390a1505050565b610f9c87878787878787612c3e565b611fd733836128d7565b611ff35760405162461bcd60e51b8152600401610de890614c37565b611c9584848484613214565b6120076127b0565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b9060200161190d565b60606120608261280a565b600061206a613247565b9050600081511161208a5760405180602001604052806000815250611f19565b8061209484613256565b6040516020016120a5929190614e4f565b6040516020818303038152906040529392505050565b6120c36127b0565b6040516332fb62e760e21b81526001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675169063cbed8b9c906121179088908890889088908890600401614e7e565b600060405180830381600087803b15801561213157600080fd5b505af1158015612145573d6000803e3d6000fd5b505050505050505050565b6121586127b0565b600081116121bd5760405162461bcd60e51b815260206004820152602c60248201527f4f4e46543732313a20647374436861696e4964546f5472616e7366657247617360448201526b0206d757374206265203e20360a41b6064820152608401610de8565b61ffff909116600090815260086020526040902055565b61ffff861660009081526005602052604080822090516121f79088908890614c27565b90815260408051602092819003830190206001600160401b038716600090815292529020549050806122775760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610de8565b808383604051612288929190614c27565b6040518091039020146122e75760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610de8565b61ffff8716600090815260056020526040808220905161230a9089908990614c27565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f880182900482028301820190528682526123a2918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250612e2592505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e587878787856040516123d9959493929190614eb7565b60405180910390a150505050505050565b60008281526015602052604090206001015461240581612b47565b61121b8383612bd7565b6124176127b0565b6000811161245f5760405162461bcd60e51b81526020600482015260156024820152744c7a4170703a20696e76616c6964206d696e47617360581b6044820152606401610de8565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611fb1565b6124c96127b0565b61ffff831660009081526001602052604090206124e790838361417d565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab838383604051611fb193929190614cae565b60008060008686604051602001612533929190614f2d565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67516906340a7bb1090612597908b90309086908b908b90600401614f5b565b6040805180830381865afa1580156125b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d79190614faf565b92509250509550959350505050565b6125ee6127b0565b6001600160a01b0381166126535760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610de8565b61265c81612f96565b50565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b03169063f5ecbdbc90608401600060405180830381865afa1580156126df573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526127079190810190614fd3565b90505b949350505050565b6000806127755a60966366ad5c8a60e01b8989898960405160240161273a9493929190615007565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915230929190613353565b91509150816118015761180186868686856133dd565b60006001600160e01b03198216637965db0b60e01b1480610fc25750610fc28261347a565b6000546001600160a01b031633146119b05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610de8565b6000818152600c60205260409020546001600160a01b031661265c5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610de8565b6000818152600e6020526040902080546001600160a01b0319166001600160a01b038416908117909155819061289e826116cd565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806128e3836116cd565b9050806001600160a01b0316846001600160a01b0316148061292a57506001600160a01b038082166000908152600f602090815260408083209388168352929052205460ff165b8061270a5750836001600160a01b0316612943846110e3565b6001600160a01b031614949350505050565b826001600160a01b0316612968826116cd565b6001600160a01b0316146129cc5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610de8565b6001600160a01b038216612a2e5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610de8565b612a3983838361349f565b612a44600082612869565b6001600160a01b0383166000908152600d60205260408120805460019290612a6d908490614e12565b90915550506001600160a01b0382166000908152600d60205260408120805460019290612a9b908490615045565b90915550506000818152600c602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60408051600180825281830190925260609160009190602080830190803683370190505090508281600081518110612b3657612b36614ccc565b602090810291909101015292915050565b61265c81336134b2565b612b5b8282611c9b565b6114975760008281526015602090815260408083206001600160a01b03851684529091529020805460ff19166001179055612b933390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b612be18282611c9b565b156114975760008281526015602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000845111612c8f5760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a20746f6b656e4964735b5d20697320656d7074790000000000006044820152606401610de8565b835160011480612cb3575061ffff8616600090815260076020526040902054845111155b612d135760405162461bcd60e51b815260206004820152602b60248201527f4f4e46543732313a2062617463682073697a652065786365656473206473742060448201526a18985d18da081b1a5b5a5d60aa1b6064820152608401610de8565b60005b8451811015612d5657612d44888888888581518110612d3757612d37614ccc565b6020026020010151613516565b80612d4e81614cf8565b915050612d16565b5060008585604051602001612d6c929190614f2d565b6040516020818303038152906040529050612db1876001848851600860008d61ffff1661ffff16815260200190815260200160002054612dac919061505d565b613601565b612dbf8782868686346136e0565b85604051612dcd919061507c565b6040518091039020886001600160a01b03168861ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a88604051612e139190615098565b60405180910390a45050505050505050565b60008082806020019051810190612e3c9190614d58565b601482015191935091506000612e5488838386612fe6565b90508251811015612f285784516020808701919091206040805160808101825261ffff808d1682526001600160a01b0380881683870190815283850188815260016060860181815260008981526009909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad790612f1e90839089906150ab565b60405180910390a1505b816001600160a01b031687604051612f40919061507c565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026586604051612e139190615098565b611497828260405180602001604052806000815250613886565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000825b8251811015612707576006545a101561300257612707565b613026868685848151811061301957613019614ccc565b60200260200101516138b9565b8061303081614cf8565b915050612fea565b60608161304681601f615045565b10156130855760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610de8565b61308f8284615045565b845110156130d35760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610de8565b6060821580156130f2576040519150600082526020820160405261313c565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561312b578051835260209283019201613113565b5050858452601f01601f1916604052505b50949350505050565b816001600160a01b0316836001600160a01b031614156131a75760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610de8565b6001600160a01b038381166000818152600f6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61321f848484612955565b61322b84848484613948565b611c955760405162461bcd60e51b8152600401610de8906150c4565b606060188054610fd790614bec565b60608161327a5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156132a4578061328e81614cf8565b915061329d9050600a8361512c565b915061327e565b6000816001600160401b038111156132be576132be61448a565b6040519080825280601f01601f1916602001820160405280156132e8576020820181803683370190505b5090505b841561270a576132fd600183614e12565b915061330a600a86615140565b613315906030615045565b60f81b81838151811061332a5761332a614ccc565b60200101906001600160f81b031916908160001a90535061334c600a8661512c565b94506132ec565b6000606060008060008661ffff166001600160401b038111156133785761337861448a565b6040519080825280601f01601f1916602001820160405280156133a2576020820181803683370190505b50905060008087516020890160008d8df191503d9250868311156133c4578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff1681526020019081526020016000208560405161340e919061507c565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c9061346b9087908790879087908790615154565b60405180910390a15050505050565b60006001600160e01b0319821663780e9d6360e01b1480610fc25750610fc282613a43565b6134a7613a83565b61121b838383613ac9565b6134bc8282611c9b565b611497576134d4816001600160a01b03166014613b81565b6134df836020613b81565b6040516020016134f09291906151a6565b60408051601f198184030181529082905262461bcd60e51b8252610de89160040161439a565b61351f3361130f565b6135825760405162461bcd60e51b815260206004820152602e60248201527f4f4e46543732313a2073656e642063616c6c6572206973206e6f74206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b6064820152608401610de8565b836001600160a01b0316613595826116cd565b6001600160a01b0316146135f65760405162461bcd60e51b815260206004820152602260248201527f4f4e46543732313a2073656e642066726f6d20696e636f7272656374206f776e60448201526132b960f11b6064820152608401610de8565b611c95843083612955565b600061360c83613d1c565b61ffff80871660009081526002602090815260408083209389168352929052908120549192509061363e908490615045565b9050600081116136905760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f74207365740000000000006044820152606401610de8565b808210156118015760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f7700000000006044820152606401610de8565b61ffff8616600090815260016020526040812080546136fe90614bec565b80601f016020809104026020016040519081016040528092919081815260200182805461372a90614bec565b80156137775780601f1061374c57610100808354040283529160200191613777565b820191906000526020600020905b81548152906001019060200180831161375a57829003601f168201915b505050505090508051600014156137e95760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610de8565b6137f4878751613d78565b60405162c5803160e81b81526001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675169063c580310090849061384b908b9086908c908c908c908c9060040161521b565b6000604051808303818588803b15801561386457600080fd5b505af1158015613878573d6000803e3d6000fd5b505050505050505050505050565b6138908383613de6565b61389d6000848484613948565b61121b5760405162461bcd60e51b8152600401610de8906150c4565b6000818152600c60205260409020546001600160a01b0316158061390e57506000818152600c60205260409020546001600160a01b03161515801561390e575030613903826116cd565b6001600160a01b0316145b61391757600080fd5b6000818152600c60205260409020546001600160a01b031661393d5761121b8282612f7c565b61121b308383612955565b60006001600160a01b0384163b15613a3b57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061398c903390899088908890600401615282565b6020604051808303816000875af19250505080156139c7575060408051601f3d908101601f191682019092526139c4918101906152bf565b60015b613a21573d8080156139f5576040519150601f19603f3d011682016040523d82523d6000602084013e6139fa565b606091505b508051613a195760405162461bcd60e51b8152600401610de8906150c4565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061270a565b50600161270a565b60006001600160e01b031982166380ac58cd60e01b1480613a7457506001600160e01b03198216635b5e139f60e01b145b80610fc25750610fc282613f34565b60145460ff16156119b05760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610de8565b6001600160a01b038316613b2457613b1f81601280546000838152601360205260408120829055600182018355919091527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440155565b613b47565b816001600160a01b0316836001600160a01b031614613b4757613b478382613f69565b6001600160a01b038216613b5e5761121b81614006565b826001600160a01b0316826001600160a01b03161461121b5761121b82826140b5565b60606000613b9083600261505d565b613b9b906002615045565b6001600160401b03811115613bb257613bb261448a565b6040519080825280601f01601f191660200182016040528015613bdc576020820181803683370190505b509050600360fc1b81600081518110613bf757613bf7614ccc565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613c2657613c26614ccc565b60200101906001600160f81b031916908160001a9053506000613c4a84600261505d565b613c55906001615045565b90505b6001811115613ccd576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613c8957613c89614ccc565b1a60f81b828281518110613c9f57613c9f614ccc565b60200101906001600160f81b031916908160001a90535060049490941c93613cc6816152dc565b9050613c58565b508315611f195760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610de8565b6000602282511015613d705760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d73000000006044820152606401610de8565b506022015190565b61ffff821660009081526003602052604090205480613d9657506127105b8082111561121b5760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c617267656044820152606401610de8565b6001600160a01b038216613e3c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610de8565b6000818152600c60205260409020546001600160a01b031615613ea15760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610de8565b613ead6000838361349f565b6001600160a01b0382166000908152600d60205260408120805460019290613ed6908490615045565b90915550506000818152600c602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160e01b031982166322bac5d960e01b1480610fc257506301ffc9a760e01b6001600160e01b0319831614610fc2565b60006001613f7684611918565b613f809190614e12565b600083815260116020526040902054909150808214613fd3576001600160a01b03841660009081526010602090815260408083208584528252808320548484528184208190558352601190915290208190555b5060009182526011602090815260408084208490556001600160a01b039094168352601081528383209183525290812055565b60125460009061401890600190614e12565b6000838152601360205260408120546012805493945090928490811061404057614040614ccc565b90600052602060002001549050806012838154811061406157614061614ccc565b6000918252602080832090910192909255828152601390915260408082208490558582528120556012805480614099576140996152f3565b6001900381819060005260206000200160009055905550505050565b60006140c083611918565b6001600160a01b039093166000908152601060209081526040808320868452825280832085905593825260119052919091209190915550565b82805461410590614bec565b90600052602060002090601f016020900481019282614127576000855561416d565b82601f1061414057805160ff191683800117855561416d565b8280016001018555821561416d579182015b8281111561416d578251825591602001919060010190614152565b506141799291506141f1565b5090565b82805461418990614bec565b90600052602060002090601f0160209004810192826141ab576000855561416d565b82601f106141c45782800160ff1982351617855561416d565b8280016001018555821561416d579182015b8281111561416d5782358255916020019190600101906141d6565b5b8082111561417957600081556001016141f2565b803561ffff8116811461421857600080fd5b919050565b60008083601f84011261422f57600080fd5b5081356001600160401b0381111561424657600080fd5b60208301915083602082850101111561425e57600080fd5b9250929050565b80356001600160401b038116811461421857600080fd5b6000806000806000806080878903121561429557600080fd5b61429e87614206565b955060208701356001600160401b03808211156142ba57600080fd5b6142c68a838b0161421d565b90975095508591506142da60408a01614265565b945060608901359150808211156142f057600080fd5b506142fd89828a0161421d565b979a9699509497509295939492505050565b6001600160e01b03198116811461265c57600080fd5b60006020828403121561433757600080fd5b8135611f198161430f565b60005b8381101561435d578181015183820152602001614345565b83811115611c955750506000910152565b60008151808452614386816020860160208601614342565b601f01601f19169290920160200192915050565b602081526000611f19602083018461436e565b6000602082840312156143bf57600080fd5b611f1982614206565b6000602082840312156143da57600080fd5b5035919050565b6001600160a01b038116811461265c57600080fd5b8035614218816143e1565b6000806040838503121561441457600080fd5b823561441f816143e1565b946020939093013593505050565b6000806040838503121561444057600080fd5b61441f83614206565b60008060006060848603121561445e57600080fd5b8335614469816143e1565b92506020840135614479816143e1565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156144c8576144c861448a565b604052919050565b60006001600160401b038211156144e9576144e961448a565b50601f01601f191660200190565b600061450a614505846144d0565b6144a0565b905082815283838301111561451e57600080fd5b828260208301376000602084830101529392505050565b600082601f83011261454657600080fd5b611f19838335602085016144f7565b8035801515811461421857600080fd5b600080600080600060a0868803121561457d57600080fd5b61458686614206565b945060208601356001600160401b03808211156145a257600080fd5b6145ae89838a01614535565b9550604088013594506145c360608901614555565b935060808801359150808211156145d957600080fd5b506145e688828901614535565b9150509295509295909350565b6000806040838503121561460657600080fd5b823591506020830135614618816143e1565b809150509250929050565b60008060006040848603121561463857600080fd5b61464184614206565b925060208401356001600160401b0381111561465c57600080fd5b6146688682870161421d565b9497909650939450505050565b600080600080600080600060e0888a03121561469057600080fd5b873561469b816143e1565b96506146a960208901614206565b955060408801356001600160401b03808211156146c557600080fd5b6146d18b838c01614535565b965060608a0135955060808a013591506146ea826143e1565b90935060a0890135906146fc826143e1565b90925060c0890135908082111561471257600080fd5b5061471f8a828b01614535565b91505092959891949750929550565b60006020828403121561474057600080fd5b81356001600160401b0381111561475657600080fd5b8201601f8101841361476757600080fd5b61270a848235602084016144f7565b60008060006060848603121561478b57600080fd5b61479484614206565b925060208401356001600160401b038111156147af57600080fd5b6147bb86828701614535565b9250506147ca60408501614265565b90509250925092565b6000602082840312156147e557600080fd5b8135611f19816143e1565b6000806040838503121561480357600080fd5b61480c83614206565b915061481a60208401614206565b90509250929050565b60006020828403121561483557600080fd5b81356001600160401b0381111561484b57600080fd5b61270a84828501614535565b6000806040838503121561486a57600080fd5b50508035926020909101359150565b6000806040838503121561488c57600080fd5b8235614897816143e1565b915061481a60208401614555565b60006001600160401b038211156148be576148be61448a565b5060051b60200190565b600082601f8301126148d957600080fd5b813560206148e9614505836148a5565b82815260059290921b8401810191818101908684111561490857600080fd5b8286015b84811015614923578035835291830191830161490c565b509695505050505050565b600080600080600080600060e0888a03121561494957600080fd5b8735614954816143e1565b965061496260208901614206565b955060408801356001600160401b038082111561497e57600080fd5b61498a8b838c01614535565b965060608a01359150808211156149a057600080fd5b6149ac8b838c016148c8565b955060808a013591506149be826143e1565b8194506149cd60a08b016143f6565b935060c08a013591508082111561471257600080fd5b600080600080608085870312156149f957600080fd5b8435614a04816143e1565b93506020850135614a14816143e1565b92506040850135915060608501356001600160401b03811115614a3657600080fd5b614a4287828801614535565b91505092959194509250565b600080600080600060808688031215614a6657600080fd5b614a6f86614206565b9450614a7d60208701614206565b93506040860135925060608601356001600160401b03811115614a9f57600080fd5b614aab8882890161421d565b969995985093965092949392505050565b600080600060608486031215614ad157600080fd5b614ada84614206565b9250614ae860208501614206565b9150604084013590509250925092565b60008060408385031215614b0b57600080fd5b8235614b16816143e1565b91506020830135614618816143e1565b600080600080600060a08688031215614b3e57600080fd5b614b4786614206565b945060208601356001600160401b0380821115614b6357600080fd5b614b6f89838a01614535565b95506040880135915080821115614b8557600080fd5b614b9189838a016148c8565b94506145c360608901614555565b60008060008060808587031215614bb557600080fd5b614bbe85614206565b9350614bcc60208601614206565b92506040850135614bdc816143e1565b9396929550929360600135925050565b600181811c90821680614c0057607f821691505b60208210811415614c2157634e487b7160e01b600052602260045260246000fd5b50919050565b8183823760009101908152919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff84168152604060208201526000612707604083018486614c85565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415614d0c57614d0c614ce2565b5060010190565b600082601f830112614d2457600080fd5b8151614d32614505826144d0565b818152846020838601011115614d4757600080fd5b61270a826020830160208701614342565b60008060408385031215614d6b57600080fd5b82516001600160401b0380821115614d8257600080fd5b614d8e86838701614d13565b9350602091508185015181811115614da557600080fd5b85019050601f81018613614db857600080fd5b8051614dc6614505826148a5565b81815260059190911b82018301908381019088831115614de557600080fd5b928401925b82841015614e0357835182529284019290840190614dea565b80955050505050509250929050565b600082821015614e2457614e24614ce2565b500390565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b60008351614e61818460208801614342565b835190830190614e75818360208801614342565b01949350505050565b600061ffff808816835280871660208401525084604083015260806060830152614eac608083018486614c85565b979650505050505050565b61ffff86168152608060208201526000614ed5608083018688614c85565b6001600160401b0394909416604083015250606001529392505050565b600081518084526020808501945080840160005b83811015614f2257815187529582019590820190600101614f06565b509495945050505050565b604081526000614f40604083018561436e565b8281036020840152614f528185614ef2565b95945050505050565b61ffff861681526001600160a01b038516602082015260a060408201819052600090614f899083018661436e565b84151560608401528281036080840152614fa3818561436e565b98975050505050505050565b60008060408385031215614fc257600080fd5b505080516020909101519092909150565b600060208284031215614fe557600080fd5b81516001600160401b03811115614ffb57600080fd5b61270a84828501614d13565b61ffff85168152608060208201526000615024608083018661436e565b6001600160401b03851660408401528281036060840152614eac818561436e565b6000821982111561505857615058614ce2565b500190565b600081600019048311821515161561507757615077614ce2565b500290565b6000825161508e818460208701614342565b9190910192915050565b602081526000611f196020830184614ef2565b82815260406020820152600061270a604083018461436e565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052601260045260246000fd5b60008261513b5761513b615116565b500490565b60008261514f5761514f615116565b500690565b61ffff8616815260a06020820152600061517160a083018761436e565b6001600160401b03861660408401528281036060840152615192818661436e565b90508281036080840152614fa3818561436e565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516151de816017850160208801614342565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161520f816028840160208801614342565b01602801949350505050565b61ffff8716815260c06020820152600061523860c083018861436e565b828103604084015261524a818861436e565b6001600160a01b0387811660608601528616608085015283810360a08501529050615275818561436e565b9998505050505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906152b59083018461436e565b9695505050505050565b6000602082840312156152d157600080fd5b8151611f198161430f565b6000816152eb576152eb614ce2565b506000190190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212209d435277c4fd257096e99d5ca0418c42cb647649db9f698ef6167b57e72579db64736f6c634300080c0033

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

000000000000000000000000000000000000000000000000000000000000000100000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000002710

-----Decoded View---------------
Arg [0] : _minGasToStore (uint256): 1
Arg [1] : _layerZeroEndpoint (address): 0x66A71Dcef29A0fFBDBE3c6a460a3B5BC225Cd675
Arg [2] : _startMintId (uint256): 1
Arg [3] : _endMintId (uint256): 10000

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [1] : 00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [3] : 0000000000000000000000000000000000000000000000000000000000002710


Deployed Bytecode Sourcemap

118370:252:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40938:762;;;;;;;;;;-1:-1:-1;40938:762:0;;;;;:::i;:::-;;:::i;:::-;;114603:261;;;;;;;;;;-1:-1:-1;114603:261:0;;;;;:::i;:::-;;:::i;:::-;;;2124:14:1;;2117:22;2099:41;;2087:2;2072:18;114603:261:0;;;;;;;;79634:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;44236:123::-;;;;;;;;;;-1:-1:-1;44236:123:0;;;;;:::i;:::-;;:::i;81147:171::-;;;;;;;;;;-1:-1:-1;81147:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3440:32:1;;;3422:51;;3410:2;3395:18;81147:171:0;3276:203:1;80664:417:0;;;;;;;;;;-1:-1:-1;80664:417:0;;;;;:::i;:::-;;:::i;62930:260::-;;;;;;;;;;-1:-1:-1;62930:260:0;;;;;:::i;:::-;;:::i;46152:142::-;;;;;;;;;;-1:-1:-1;46152:142:0;;;;;:::i;:::-;;:::i;44367:129::-;;;;;;;;;;-1:-1:-1;44367:129:0;;;;;:::i;:::-;;:::i;94634:113::-;;;;;;;;;;-1:-1:-1;94722:10:0;:17;94634:113;;;4482:25:1;;;4470:2;4455:18;94634:113:0;4336:177:1;57082:53:0;;;;;;;;;;-1:-1:-1;57082:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57082:53:0;;;;;;;;;;;4956:6:1;4944:19;;;4926:38;;-1:-1:-1;;;;;5000:32:1;;;4995:2;4980:18;;4973:60;5049:18;;;5042:34;5119:14;5112:22;5107:2;5092:18;;5085:50;4913:3;4898:19;57082:53:0;4703:438:1;81847:336:0;;;;;;;;;;-1:-1:-1;81847:336:0;;;;;:::i;:::-;;:::i;110274:131::-;;;;;;;;;;-1:-1:-1;110274:131:0;;;;;:::i;:::-;110348:7;110375:12;;;:6;:12;;;;;:22;;;;110274:131;57646:320;;;;;;;;;;-1:-1:-1;57646:320:0;;;;;:::i;:::-;;:::i;:::-;;;;8051:25:1;;;8107:2;8092:18;;8085:34;;;;8024:18;57646:320:0;7877:248:1;110715:147:0;;;;;;;;;;-1:-1:-1;110715:147:0;;;;;:::i;:::-;;:::i;94302:256::-;;;;;;;;;;-1:-1:-1;94302:256:0;;;;;:::i;:::-;;:::i;111859:218::-;;;;;;;;;;-1:-1:-1;111859:218:0;;;;;:::i;:::-;;:::i;46392:250::-;;;;;;;;;;-1:-1:-1;46392:250:0;;;;;:::i;:::-;;:::i;40480:53::-;;;;;;;;;;-1:-1:-1;40480:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;82254:185;;;;;;;;;;-1:-1:-1;82254:185:0;;;;;:::i;:::-;;:::i;44504:178::-;;;;;;;;;;-1:-1:-1;44504:178:0;;;;;:::i;:::-;;:::i;56772:39::-;;;;;;;;;;;;;;;;56888:56;;;;;;;;;;-1:-1:-1;56888:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;94824:233;;;;;;;;;;-1:-1:-1;94824:233:0;;;;;:::i;:::-;;:::i;58370:351::-;;;;;;:::i;:::-;;:::i;117139:100::-;;;;;;;;;;-1:-1:-1;117139:100:0;;;;;:::i;:::-;;:::i;52806:85::-;;;;;;;;;;-1:-1:-1;52806:85:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101822:86;;;;;;;;;;-1:-1:-1;101893:7:0;;;;101822:86;;79345:222;;;;;;;;;;-1:-1:-1;79345:222:0;;;;;:::i;:::-;;:::i;116155:37::-;;;;;;;;;;-1:-1:-1;116155:37:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;54028:346;;;;;;;;;;-1:-1:-1;54028:346:0;;;;;:::i;:::-;;:::i;117723:259::-;;;;;;;;;;-1:-1:-1;117723:259:0;;;;;:::i;:::-;;:::i;116050:22::-;;;;;;;;;;;;;;;;117247:153;;;;;;;;;;-1:-1:-1;117247:153:0;;;;;:::i;:::-;;:::i;79076:207::-;;;;;;;;;;-1:-1:-1;79076:207:0;;;;;:::i;:::-;;:::i;12252:103::-;;;;;;;;;;;;;:::i;40350:51::-;;;;;;;;;;-1:-1:-1;40350:51:0;;;;;:::i;:::-;;:::i;40408:65::-;;;;;;;;;;-1:-1:-1;40408:65:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;11604:87;;;;;;;;;;-1:-1:-1;11650:7:0;11677:6;-1:-1:-1;;;;;11677:6:0;11604:87;;61143:1006;;;;;;;;;;-1:-1:-1;61143:1006:0;;;;;:::i;:::-;;:::i;108734:147::-;;;;;;;;;;-1:-1:-1;108734:147:0;;;;;:::i;:::-;;:::i;40540:23::-;;;;;;;;;;-1:-1:-1;40540:23:0;;;;-1:-1:-1;;;;;40540:23:0;;;79803:104;;;;;;;;;;;;;:::i;117408:277::-;;;;;;;;;;-1:-1:-1;117408:277:0;;;;;:::i;:::-;;:::i;63642:281::-;;;;;;;;;;-1:-1:-1;63642:281:0;;;;;:::i;:::-;;:::i;45324:330::-;;;;;;;;;;-1:-1:-1;45324:330:0;;;;;:::i;:::-;;:::i;107839:49::-;;;;;;;;;;-1:-1:-1;107839:49:0;107884:4;107839:49;;81390:155;;;;;;;;;;-1:-1:-1;81390:155:0;;;;;:::i;:::-;;:::i;45035:281::-;;;;;;;;;;-1:-1:-1;45035:281:0;;;;;:::i;:::-;;:::i;58729:348::-;;;;;;:::i;:::-;;:::i;56535:45::-;;;;;;;;;;;;56579:1;56535:45;;;;;14840:6:1;14828:19;;;14810:38;;14798:2;14783:18;56535:45:0;14666:188:1;40297:46:0;;;;;;;;;;;;;;;82510:323;;;;;;;;;;-1:-1:-1;82510:323:0;;;;;:::i;:::-;;:::i;45662:136::-;;;;;;;;;;-1:-1:-1;45662:136:0;;;;;:::i;:::-;;:::i;40233:55::-;;;;;;;;;;;;40283:5;40233:55;;79978:281;;;;;;;;;;-1:-1:-1;79978:281:0;;;;;:::i;:::-;;:::i;44024:204::-;;;;;;;;;;-1:-1:-1;44024:204:0;;;;;:::i;:::-;;:::i;63291:287::-;;;;;;;;;;-1:-1:-1;63291:287:0;;;;;:::i;:::-;;:::i;54560:767::-;;;;;;:::i;:::-;;:::i;111155:149::-;;;;;;;;;;-1:-1:-1;111155:149:0;;;;;:::i;:::-;;:::i;45806:284::-;;;;;;;;;;-1:-1:-1;45806:284:0;;;;;:::i;:::-;;:::i;116079:21::-;;;;;;;;;;;;;;;;81616:164;;;;;;;;;;-1:-1:-1;81616:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;81737:25:0;;;81713:4;81737:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;81616:164;44829:198;;;;;;;;;;-1:-1:-1;44829:198:0;;;;;:::i;:::-;;:::i;57974:388::-;;;;;;;;;;-1:-1:-1;57974:388:0;;;;;:::i;:::-;;:::i;12510:201::-;;;;;;;;;;-1:-1:-1;12510:201:0;;;;;:::i;:::-;;:::i;43751:211::-;;;;;;;;;;-1:-1:-1;43751:211:0;;;;;:::i;:::-;;:::i;56951:57::-;;;;;;;;;;-1:-1:-1;56951:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;40938:762;10228:10;41178;-1:-1:-1;;;;;41154:35:0;;41146:78;;;;-1:-1:-1;;;41146:78:0;;18691:2:1;41146:78:0;;;18673:21:1;18730:2;18710:18;;;18703:30;18769:32;18749:18;;;18742:60;18819:18;;41146:78:0;;;;;;;;;41266:32;;;41237:26;41266:32;;;:19;:32;;;;;41237:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41472:13;:20;41450:11;;:18;;:42;:70;;;;;41519:1;41496:13;:20;:24;41450:70;:124;;;;-1:-1:-1;41550:24:0;;;;;;41524:22;;;;41534:11;;;;41524:22;:::i;:::-;;;;;;;;:50;41450:124;41442:175;;;;-1:-1:-1;;;41442:175:0;;19711:2:1;41442:175:0;;;19693:21:1;19750:2;19730:18;;;19723:30;19789:34;19769:18;;;19762:62;-1:-1:-1;;;19840:18:1;;;19833:36;19886:19;;41442:175:0;19509:402:1;41442:175:0;41630:62;41649:11;41662;;41630:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;41630:62:0;;;;;;;;;;;;;;;;;;;;;;41675:6;;-1:-1:-1;41630:62:0;-1:-1:-1;41683:8:0;;;;;;41630:62;;41683:8;;;;41630:62;;;;;;;;;-1:-1:-1;41630:18:0;;-1:-1:-1;;;41630:62:0:i;:::-;41069:631;40938:762;;;;;;:::o;114603:261::-;114751:4;-1:-1:-1;;;;;;114775:41:0;;;;:81;;;114820:36;114844:11;114820:23;:36::i;:::-;114768:88;114603:261;-1:-1:-1;;114603:261:0:o;79634:100::-;79688:13;79721:5;79714:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79634:100;:::o;44236:123::-;11490:13;:11;:13::i;:::-;44316:35:::1;::::0;-1:-1:-1;;;44316:35:0;;14840:6:1;14828:19;;44316:35:0::1;::::0;::::1;14810:38:1::0;44316:10:0::1;-1:-1:-1::0;;;;;44316:25:0::1;::::0;::::1;::::0;14783:18:1;;44316:35:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;44236:123:::0;:::o;81147:171::-;81223:7;81243:23;81258:7;81243:14;:23::i;:::-;-1:-1:-1;81286:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;81286:24:0;;81147:171::o;80664:417::-;80745:13;80761:23;80776:7;80761:14;:23::i;:::-;80745:39;;80809:5;-1:-1:-1;;;;;80803:11:0;:2;-1:-1:-1;;;;;80803:11:0;;;80795:57;;;;-1:-1:-1;;;80795:57:0;;20118:2:1;80795:57:0;;;20100:21:1;20157:2;20137:18;;;20130:30;20196:34;20176:18;;;20169:62;-1:-1:-1;;;20247:18:1;;;20240:31;20288:19;;80795:57:0;19916:397:1;80795:57:0;10228:10;-1:-1:-1;;;;;80887:21:0;;;;:62;;-1:-1:-1;80912:37:0;80929:5;10228:10;81616:164;:::i;80912:37::-;80865:174;;;;-1:-1:-1;;;80865:174:0;;20520:2:1;80865:174:0;;;20502:21:1;20559:2;20539:18;;;20532:30;20598:34;20578:18;;;20571:62;20669:32;20649:18;;;20642:60;20719:19;;80865:174:0;20318:426:1;80865:174:0;81052:21;81061:2;81065:7;81052:8;:21::i;:::-;80734:347;80664:417;;:::o;62930:260::-;11490:13;:11;:13::i;:::-;63068:1:::1;63040:25;:29;63032:87;;;::::0;-1:-1:-1;;;63032:87:0;;20951:2:1;63032:87:0::1;::::0;::::1;20933:21:1::0;20990:2;20970:18;;;20963:30;21029:34;21009:18;;;21002:62;-1:-1:-1;;;21080:18:1;;;21073:43;21133:19;;63032:87:0::1;20749:409:1::0;63032:87:0::1;63130:24;:52:::0;62930:260::o;46152:142::-;11490:13;:11;:13::i;:::-;46243:35:::1;::::0;;::::1;;::::0;;;:22:::1;:35;::::0;;;;:43;46152:142::o;44367:129::-;11490:13;:11;:13::i;:::-;44450:38:::1;::::0;-1:-1:-1;;;44450:38:0;;14840:6:1;14828:19;;44450:38:0::1;::::0;::::1;14810::1::0;44450:10:0::1;-1:-1:-1::0;;;;;44450:28:0::1;::::0;::::1;::::0;14783:18:1;;44450:38:0::1;14666:188:1::0;81847:336:0;82042:41;10228:10;82061:12;82075:7;82042:18;:41::i;:::-;82034:100;;;;-1:-1:-1;;;82034:100:0;;;;;;;:::i;:::-;82147:28;82157:4;82163:2;82167:7;82147:9;:28::i;57646:320::-;57812:14;57828:11;57859:99;57880:11;57893:10;57905:27;57923:8;57905:17;:27::i;:::-;57934:7;57943:14;57859:20;:99::i;:::-;57852:106;;;;57646:320;;;;;;;;:::o;110715:147::-;110348:7;110375:12;;;:6;:12;;;;;:22;;;108330:16;108341:4;108330:10;:16::i;:::-;110829:25:::1;110840:4;110846:7;110829:10;:25::i;94302:256::-:0;94399:7;94435:23;94452:5;94435:16;:23::i;:::-;94427:5;:31;94419:87;;;;-1:-1:-1;;;94419:87:0;;21780:2:1;94419:87:0;;;21762:21:1;21819:2;21799:18;;;21792:30;21858:34;21838:18;;;21831:62;-1:-1:-1;;;21909:18:1;;;21902:41;21960:19;;94419:87:0;21578:407:1;94419:87:0;-1:-1:-1;;;;;;94524:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;94302:256::o;111859:218::-;-1:-1:-1;;;;;111955:23:0;;10228:10;111955:23;111947:83;;;;-1:-1:-1;;;111947:83:0;;22192:2:1;111947:83:0;;;22174:21:1;22231:2;22211:18;;;22204:30;22270:34;22250:18;;;22243:62;-1:-1:-1;;;22321:18:1;;;22314:45;22376:19;;111947:83:0;21990:411:1;111947:83:0;112043:26;112055:4;112061:7;112043:11;:26::i;:::-;111859:218;;:::o;46392:250::-;46534:32;;;46488:4;46534:32;;;:19;:32;;;;;46505:61;;46488:4;;46534:32;46505:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46622:11;;46612:22;;;;;;;:::i;:::-;;;;;;;;46594:13;46584:24;;;;;;:50;46577:57;;;46392:250;;;;;:::o;82254:185::-;82392:39;82409:4;82415:2;82419:7;82392:39;;;;;;;;;;;;:16;:39::i;44504:178::-;11490:13;:11;:13::i;:::-;44619:55:::1;::::0;-1:-1:-1;;;44619:55:0;;-1:-1:-1;;;;;44619:10:0::1;:29;::::0;::::1;::::0;:55:::1;::::0;44649:11;;44662;;;;44619:55:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;94824:233:::0;94899:7;94935:30;94722:10;:17;;94634:113;94935:30;94927:5;:38;94919:95;;;;-1:-1:-1;;;94919:95:0;;23210:2:1;94919:95:0;;;23192:21:1;23249:2;23229:18;;;23222:30;23288:34;23268:18;;;23261:62;-1:-1:-1;;;23339:18:1;;;23332:42;23391:19;;94919:95:0;23008:408:1;94919:95:0;95032:10;95043:5;95032:17;;;;;;;;:::i;:::-;;;;;;;;;95025:24;;94824:233;;;:::o;58370:351::-;58595:118;58601:5;58608:11;58621:10;58633:27;58651:8;58633:17;:27::i;:::-;58662:14;58678:18;58698:14;58595:5;:118::i;117139:100::-;11490:13;:11;:13::i;:::-;117213:18;;::::1;::::0;:7:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;79345:222::-:0;79417:7;79453:16;;;:7;:16;;;;;;-1:-1:-1;;;;;79453:16:0;79488:19;79480:56;;;;-1:-1:-1;;;79480:56:0;;23755:2:1;79480:56:0;;;23737:21:1;23794:2;23774:18;;;23767:30;-1:-1:-1;;;23813:18:1;;;23806:54;23877:18;;79480:56:0;23553:348:1;54028:346:0;10228:10;54242:4;54218:29;54210:80;;;;-1:-1:-1;;;54210:80:0;;24108:2:1;54210:80:0;;;24090:21:1;24147:2;24127:18;;;24120:30;24186:34;24166:18;;;24159:62;-1:-1:-1;;;24237:18:1;;;24230:36;24283:19;;54210:80:0;23906:402:1;54210:80:0;54301:65;54323:11;54336;;54301:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;54301:65:0;;;;;;;;;;;;;;;;;;;;;;54349:6;;-1:-1:-1;54301:65:0;-1:-1:-1;54357:8:0;;;;;;54301:65;;54357:8;;;;54301:65;;;;;;;;;-1:-1:-1;54301:21:0;;-1:-1:-1;;;54301:65:0:i;:::-;54028:346;;;;;;:::o;117723:259::-;117783:10;117777:17;;;;:5;:17;;;;;;;;117769:26;;;;;;117828:9;;117814:10;;:23;;117806:76;;;;-1:-1:-1;;;117806:76:0;;24515:2:1;117806:76:0;;;24497:21:1;24554:2;24534:18;;;24527:30;24593:34;24573:18;;;24566:62;-1:-1:-1;;;24644:18:1;;;24637:38;24692:19;;117806:76:0;24313:404:1;117806:76:0;117908:10;;;;;;117895;117929:12;117908:10;117929:12;:::i;:::-;;;;;;117954:20;117964:2;117968:5;117954:9;:20::i;117247:153::-;11490:13;:11;:13::i;:::-;-1:-1:-1;;;;;117330:13:0;::::1;;::::0;;;:5:::1;:13;::::0;;;;;;;;;;::::1;::::0;::::1;117329:14;-1:-1:-1::0;;117313:30:0;;::::1;;::::0;;117359:33;;25168:51:1;;;117376:15:0::1;25235:18:1::0;;;25228:34;117359:33:0::1;::::0;25141:18:1;117359:33:0::1;;;;;;;;117247:153:::0;:::o;79076:207::-;79148:7;-1:-1:-1;;;;;79176:19:0;;79168:73;;;;-1:-1:-1;;;79168:73:0;;25475:2:1;79168:73:0;;;25457:21:1;25514:2;25494:18;;;25487:30;25553:34;25533:18;;;25526:62;-1:-1:-1;;;25604:18:1;;;25597:39;25653:19;;79168:73:0;25273:405:1;79168:73:0;-1:-1:-1;;;;;;79259:16:0;;;;;:9;:16;;;;;;;79076:207::o;12252:103::-;11490:13;:11;:13::i;:::-;12317:30:::1;12344:1;12317:18;:30::i;:::-;12252:103::o:0;40350:51::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;61143:1006::-;61232:19;;;;;;;;;;61208:21;61270:28;;;:13;:28;;;;;;;:42;;;;;61262:81;;;;-1:-1:-1;;;61262:81:0;;25885:2:1;61262:81:0;;;25867:21:1;25924:2;25904:18;;;25897:30;25963:28;25943:18;;;25936:56;26009:18;;61262:81:0;25683:350:1;61262:81:0;61359:22;61396:8;61385:37;;;;;;;;;;;;:::i;:::-;61435:14;61464:28;;;:13;:28;;;;;:39;;;61545:34;;;;61356:66;;-1:-1:-1;61435:14:0;;-1:-1:-1;61452:138:0;;61464:39;;;;61505:38;;;-1:-1:-1;;;;;61505:38:0;;61356:66;61452:11;:138::i;:::-;61621:28;;;;:13;:28;;;;;:34;;;61435:155;;-1:-1:-1;61609:46:0;;61601:109;;;;-1:-1:-1;;;61601:109:0;;27782:2:1;61601:109:0;;;27764:21:1;27821:2;27801:18;;;27794:30;27860:34;27840:18;;;27833:62;-1:-1:-1;;;27911:18:1;;;27904:48;27969:19;;61601:109:0;27580:414:1;61601:109:0;61740:8;:15;61727:9;:28;61723:419;;;61835:28;;;;:13;:28;;;;;;61828:35;;-1:-1:-1;;;;;;61828:35:0;;;;;;;;;;;;;;;;-1:-1:-1;;61828:35:0;;;61883:28;;;;;61849:13;4482:25:1;;4470:2;4455:18;;4336:177;61883:28:0;;;;;;;;61723:419;;;62020:110;;;;;;;;-1:-1:-1;62033:28:0;;;:13;:28;;;;;;;:39;;;;;;62020:110;;-1:-1:-1;;;;;62074:38:0;;;;;;62020:110;;;;;;;;;;;;62033:39;62020:110;;;;;;61989:28;;;;;;;;:141;;;;;;;;-1:-1:-1;;;;;;61989:141:0;;;;;;;;;;;;;;;;;;;;;;;;;;;62074:38;61989:141;;;;;;;;-1:-1:-1;;61989:141:0;;;;;;;;;61723:419;61197:952;;;61143:1006;:::o;108734:147::-;108820:4;108844:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;108844:29:0;;;;;;;;;;;;;;;108734:147::o;79803:104::-;79859:13;79892:7;79885:14;;;;;:::i;117408:277::-;11490:13;:11;:13::i;:::-;117510:4:::1;117498:9;;:16;:31;;;;;117525:4;117518;:11;117498:31;117490:69;;;::::0;-1:-1:-1;;;117490:69:0;;28201:2:1;117490:69:0::1;::::0;::::1;28183:21:1::0;28240:2;28220:18;;;28213:30;28279:27;28259:18;;;28252:55;28324:18;;117490:69:0::1;27999:349:1::0;117490:69:0::1;117570:10;:17:::0;;;117598:9:::1;:16:::0;;;117630:47:::1;::::0;;28555:25:1;;;28611:2;28596:18;;28589:34;;;117661:15:0::1;28639:18:1::0;;;28632:34;117630:47:0;;::::1;::::0;;;;28543:2:1;117630:47:0;;::::1;117408:277:::0;;:::o;63642:281::-;11490:13;:11;:13::i;:::-;63794:1:::1;63768:23;:27;63760:83;;;::::0;-1:-1:-1;;;63760:83:0;;28879:2:1;63760:83:0::1;::::0;::::1;28861:21:1::0;28918:2;28898:18;;;28891:30;28957:34;28937:18;;;28930:62;-1:-1:-1;;;29008:18:1;;;29001:41;29059:19;;63760:83:0::1;28677:407:1::0;63760:83:0::1;63854:35;::::0;;::::1;;::::0;;;:22:::1;:35;::::0;;;;:61;63642:281::o;45324:330::-;45448:35;;;45428:17;45448:35;;;:19;:35;;;;;45428:55;;45403:12;;45428:17;45448:35;45428:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45502:4;:11;45517:1;45502:16;;45494:58;;;;-1:-1:-1;;;45494:58:0;;29291:2:1;45494:58:0;;;29273:21:1;29330:2;29310:18;;;29303:30;29369:31;29349:18;;;29342:59;29418:18;;45494:58:0;29089:353:1;45494:58:0;45570:31;45581:1;45598:2;45584:4;:11;:16;;;;:::i;:::-;45570:4;;:31;:10;:31::i;:::-;45563:38;45324:330;-1:-1:-1;;;45324:330:0:o;81390:155::-;81485:52;10228:10;81518:8;81528;81485:18;:52::i;45035:281::-;11490:13;:11;:13::i;:::-;45207:14:::1;;45231:4;45190:47;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;45190:47:0;;::::1;::::0;;;;;;45152:35:::1;::::0;::::1;;::::0;;;:19:::1;45190:47;45152:35:::0;;;;;;:85;;::::1;::::0;:35;;:85;;::::1;::::0;::::1;:::i;:::-;;45253:55;45277:14;45293;;45253:55;;;;;;;;:::i;:::-;;;;;;;;45035:281:::0;;;:::o;58729:348::-;58969:100;58975:5;58982:11;58995:10;59007:9;59018:14;59034:18;59054:14;58969:5;:100::i;82510:323::-;82684:41;10228:10;82717:7;82684:18;:41::i;:::-;82676:100;;;;-1:-1:-1;;;82676:100:0;;;;;;;:::i;:::-;82787:38;82801:4;82807:2;82811:7;82820:4;82787:13;:38::i;45662:136::-;11490:13;:11;:13::i;:::-;45732:8:::1;:20:::0;;-1:-1:-1;;;;;;45732:20:0::1;-1:-1:-1::0;;;;;45732:20:0;::::1;::::0;;::::1;::::0;;;45768:22:::1;::::0;3422:51:1;;;45768:22:0::1;::::0;3410:2:1;3395:18;45768:22:0::1;3276:203:1::0;79978:281:0;80051:13;80077:23;80092:7;80077:14;:23::i;:::-;80113:21;80137:10;:8;:10::i;:::-;80113:34;;80189:1;80171:7;80165:21;:25;:86;;;;;;;;;;;;;;;;;80217:7;80226:18;:7;:16;:18::i;:::-;80200:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;80158:93;79978:281;-1:-1:-1;;;79978:281:0:o;44024:204::-;11490:13;:11;:13::i;:::-;44158:62:::1;::::0;-1:-1:-1;;;44158:62:0;;-1:-1:-1;;;;;44158:10:0::1;:20;::::0;::::1;::::0;:62:::1;::::0;44179:8;;44189;;44199:11;;44212:7;;;;44158:62:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;44024:204:::0;;;;;:::o;63291:287::-;11490:13;:11;:13::i;:::-;63446:1:::1;63419:24;:28;63411:85;;;::::0;-1:-1:-1;;;63411:85:0;;31144:2:1;63411:85:0::1;::::0;::::1;31126:21:1::0;31183:2;31163:18;;;31156:30;31222:34;31202:18;;;31195:62;-1:-1:-1;;;31273:18:1;;;31266:42;31325:19;;63411:85:0::1;30942:408:1::0;63411:85:0::1;63507:36;::::0;;::::1;;::::0;;;:23:::1;:36;::::0;;;;:63;63291:287::o;54560:767::-;54771:27;;;54749:19;54771:27;;;:14;:27;;;;;;:40;;;;54799:11;;;;54771:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54771:48:0;;;;;;;;;;;;-1:-1:-1;54771:48:0;54830:73;;;;-1:-1:-1;;;54830:73:0;;31557:2:1;54830:73:0;;;31539:21:1;31596:2;31576:18;;;31569:30;31635:34;31615:18;;;31608:62;-1:-1:-1;;;31686:18:1;;;31679:33;31729:19;;54830:73:0;31355:399:1;54830:73:0;54945:11;54932:8;;54922:19;;;;;;;:::i;:::-;;;;;;;;:34;54914:80;;;;-1:-1:-1;;;54914:80:0;;31961:2:1;54914:80:0;;;31943:21:1;32000:2;31980:18;;;31973:30;32039:34;32019:18;;;32012:62;-1:-1:-1;;;32090:18:1;;;32083:31;32131:19;;54914:80:0;31759:397:1;54914:80:0;55042:27;;;55101:1;55042:27;;;:14;:27;;;;;;:40;;;;55070:11;;;;55042:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55042:48:0;;;;;;;;;;;;:61;;;;55172:65;;;;;;;;;;;;;;;;;;;55194:11;;55207;;55172:65;;;;;;55207:11;55172:65;;55207:11;55172:65;;;;;;;;;-1:-1:-1;;55172:65:0;;;;;;;;;;;;;;;;;;;;;;55220:6;;-1:-1:-1;55172:65:0;-1:-1:-1;55228:8:0;;;;;;55172:65;;55228:8;;;;55172:65;;;;;;;;;-1:-1:-1;55172:21:0;;-1:-1:-1;;;55172:65:0:i;:::-;55253:66;55273:11;55286;;55299:6;55307:11;55253:66;;;;;;;;;;:::i;:::-;;;;;;;;54693:634;54560:767;;;;;;:::o;111155:149::-;110348:7;110375:12;;;:6;:12;;;;;:22;;;108330:16;108341:4;108330:10;:16::i;:::-;111270:26:::1;111282:4;111288:7;111270:11;:26::i;45806:284::-:0;11490:13;:11;:13::i;:::-;45930:1:::1;45920:7;:11;45912:45;;;::::0;-1:-1:-1;;;45912:45:0;;32861:2:1;45912:45:0::1;::::0;::::1;32843:21:1::0;32900:2;32880:18;;;32873:30;-1:-1:-1;;;32919:18:1;;;32912:51;32980:18;;45912:45:0::1;32659:345:1::0;45912:45:0::1;45968:28;::::0;;::::1;;::::0;;;:15:::1;:28;::::0;;;;;;;:41;;::::1;::::0;;;;;;;;;;:51;;;46035:47;;33232:34:1;;;33282:18;;33275:43;;;;33334:18;;;33327:34;;;46035:47:0::1;::::0;33195:2:1;33180:18;46035:47:0::1;33009:358:1::0;44829:198:0;11490:13;:11;:13::i;:::-;44927:32:::1;::::0;::::1;;::::0;;;:19:::1;:32;::::0;;;;:40:::1;::::0;44962:5;;44927:40:::1;:::i;:::-;;44983:36;45000:11;45013:5;;44983:36;;;;;;;;:::i;57974:388::-:0;58155:14;58171:11;58195:20;58229:10;58241:9;58218:33;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;58218:33:0;;;;;;;;;;-1:-1:-1;;;58269:85:0;;58218:33;-1:-1:-1;;;;;;58269:10:0;:23;;;;:85;;58293:11;;58314:4;;58218:33;;58330:7;;58339:14;;58269:85;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58262:92;;;;;57974:388;;;;;;;;:::o;12510:201::-;11490:13;:11;:13::i;:::-;-1:-1:-1;;;;;12599:22:0;::::1;12591:73;;;::::0;-1:-1:-1;;;12591:73:0;;35338:2:1;12591:73:0::1;::::0;::::1;35320:21:1::0;35377:2;35357:18;;;35350:30;35416:34;35396:18;;;35389:62;-1:-1:-1;;;35467:18:1;;;35460:36;35513:19;;12591:73:0::1;35136:402:1::0;12591:73:0::1;12675:28;12694:8;12675:18;:28::i;:::-;12510:201:::0;:::o;43751:211::-;43886:68;;-1:-1:-1;;;43886:68:0;;35780:6:1;35813:15;;;43886:68:0;;;35795:34:1;35865:15;;35845:18;;;35838:43;43935:4:0;35897:18:1;;;35890:60;35966:18;;;35959:34;;;43854:12:0;;43886:10;-1:-1:-1;;;;;43886:20:0;;;;35742:19:1;;43886:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43886:68:0;;;;;;;;;;;;:::i;:::-;43879:75;;43751:211;;;;;;;:::o;53175:514::-;53325:12;53339:19;53362:153;53396:9;53407:3;53435:34;;;53471:11;53484;53497:6;53505:8;53412:102;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;53412:102:0;;;;;;;;;;;;;;-1:-1:-1;;;;;53412:102:0;-1:-1:-1;;;;;;53412:102:0;;;;;;;;;;53370:4;;53362:153;;:33;:153::i;:::-;53324:191;;;;53575:7;53570:112;;53599:71;53619:11;53632;53645:6;53653:8;53663:6;53599:19;:71::i;108438:204::-;108523:4;-1:-1:-1;;;;;;108547:47:0;;-1:-1:-1;;;108547:47:0;;:87;;;108598:36;108622:11;108598:23;:36::i;11769:132::-;11650:7;11677:6;-1:-1:-1;;;;;11677:6:0;10228:10;11833:23;11825:68;;;;-1:-1:-1;;;11825:68:0;;37108:2:1;11825:68:0;;;37090:21:1;;;37127:18;;;37120:30;37186:34;37166:18;;;37159:62;37238:18;;11825:68:0;36906:356:1;89122:135:0;84405:4;84429:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84429:16:0;89196:53;;;;-1:-1:-1;;;89196:53:0;;23755:2:1;89196:53:0;;;23737:21:1;23794:2;23774:18;;;23767:30;-1:-1:-1;;;23813:18:1;;;23806:54;23877:18;;89196:53:0;23553:348:1;88401:174:0;88476:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;88476:29:0;-1:-1:-1;;;;;88476:29:0;;;;;;;;:24;;88530:23;88476:24;88530:14;:23::i;:::-;-1:-1:-1;;;;;88521:46:0;;;;;;;;;;;88401:174;;:::o;84634:264::-;84727:4;84744:13;84760:23;84775:7;84760:14;:23::i;:::-;84744:39;;84813:5;-1:-1:-1;;;;;84802:16:0;:7;-1:-1:-1;;;;;84802:16:0;;:52;;;-1:-1:-1;;;;;;81737:25:0;;;81713:4;81737:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;84822:32;84802:87;;;;84882:7;-1:-1:-1;;;;;84858:31:0;:20;84870:7;84858:11;:20::i;:::-;-1:-1:-1;;;;;84858:31:0;;84794:96;84634:264;-1:-1:-1;;;;84634:264:0:o;87657:625::-;87816:4;-1:-1:-1;;;;;87789:31:0;:23;87804:7;87789:14;:23::i;:::-;-1:-1:-1;;;;;87789:31:0;;87781:81;;;;-1:-1:-1;;;87781:81:0;;37469:2:1;87781:81:0;;;37451:21:1;37508:2;37488:18;;;37481:30;37547:34;37527:18;;;37520:62;-1:-1:-1;;;37598:18:1;;;37591:35;37643:19;;87781:81:0;37267:401:1;87781:81:0;-1:-1:-1;;;;;87881:16:0;;87873:65;;;;-1:-1:-1;;;87873:65:0;;37875:2:1;87873:65:0;;;37857:21:1;37914:2;37894:18;;;37887:30;37953:34;37933:18;;;37926:62;-1:-1:-1;;;38004:18:1;;;37997:34;38048:19;;87873:65:0;37673:400:1;87873:65:0;87951:39;87972:4;87978:2;87982:7;87951:20;:39::i;:::-;88055:29;88072:1;88076:7;88055:8;:29::i;:::-;-1:-1:-1;;;;;88097:15:0;;;;;;:9;:15;;;;;:20;;88116:1;;88097:15;:20;;88116:1;;88097:20;:::i;:::-;;;;-1:-1:-1;;;;;;;88128:13:0;;;;;;:9;:13;;;;;:18;;88145:1;;88128:13;:18;;88145:1;;88128:18;:::i;:::-;;;;-1:-1:-1;;88157:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;88157:21:0;-1:-1:-1;;;;;88157:21:0;;;;;;;;;88196:27;;88157:16;;88196:27;;;;;;;80734:347;80664:417;;:::o;64150:185::-;64262:13;;;64273:1;64262:13;;;;;;;;;64214;;64240:19;;64262:13;;;;;;;;;;;;-1:-1:-1;64262:13:0;64240:35;;64297:7;64286:5;64292:1;64286:8;;;;;;;;:::i;:::-;;;;;;;;;;:18;64322:5;64150:185;-1:-1:-1;;64150:185:0:o;109185:105::-;109252:30;109263:4;10228:10;109252;:30::i;113456:238::-;113540:22;113548:4;113554:7;113540;:22::i;:::-;113535:152;;113579:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;113579:29:0;;;;;;;;;:36;;-1:-1:-1;;113579:36:0;113611:4;113579:36;;;113662:12;10228:10;;10148:98;113662:12;-1:-1:-1;;;;;113635:40:0;113653:7;-1:-1:-1;;;;;113635:40:0;113647:4;113635:40;;;;;;;;;;113456:238;;:::o;113874:239::-;113958:22;113966:4;113972:7;113958;:22::i;:::-;113954:152;;;114029:5;113997:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;113997:29:0;;;;;;;;;;:37;;-1:-1:-1;;113997:37:0;;;114054:40;10228:10;;113997:12;;114054:40;;114029:5;114054:40;113874:239;;:::o;59085:976::-;59360:1;59341:9;:16;:20;59333:59;;;;-1:-1:-1;;;59333:59:0;;38413:2:1;59333:59:0;;;38395:21:1;38452:2;38432:18;;;38425:30;38491:28;38471:18;;;38464:56;38537:18;;59333:59:0;38211:350:1;59333:59:0;59411:9;:16;59431:1;59411:21;:80;;;-1:-1:-1;59456:35:0;;;;;;;:22;:35;;;;;;59436:16;;:55;;59411:80;59403:136;;;;-1:-1:-1;;;59403:136:0;;38768:2:1;59403:136:0;;;38750:21:1;38807:2;38787:18;;;38780:30;38846:34;38826:18;;;38819:62;-1:-1:-1;;;38897:18:1;;;38890:41;38948:19;;59403:136:0;38566:407:1;59403:136:0;59557:6;59552:127;59573:9;:16;59569:1;:20;59552:127;;;59611:56;59622:5;59629:11;59642:10;59654:9;59664:1;59654:12;;;;;;;;:::i;:::-;;;;;;;59611:10;:56::i;:::-;59591:3;;;;:::i;:::-;;;;59552:127;;;;59691:20;59725:10;59737:9;59714:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59691:56;;59760:120;59775:11;56579:1;59808:14;59863:9;:16;59824:23;:36;59848:11;59824:36;;;;;;;;;;;;;;;;:55;;;;:::i;:::-;59760:14;:120::i;:::-;59891:92;59899:11;59912:7;59921:14;59937:18;59957:14;59973:9;59891:7;:92::i;:::-;60031:10;59999:54;;;;;;:::i;:::-;;;;;;;;60024:5;-1:-1:-1;;;;;59999:54:0;60011:11;59999:54;;;60043:9;59999:54;;;;;;:::i;:::-;;;;;;;;59291:770;59085:976;;;;;;;:::o;60069:::-;60311:27;60340:22;60377:8;60366:37;;;;;;;;;;;;:::i;:::-;60507:2;60487:23;;60481:30;60310:93;;-1:-1:-1;60310:93:0;-1:-1:-1;60416:17:0;60551:48;60563:11;60481:30;60416:17;60310:93;60551:11;:48::i;:::-;60534:65;;60626:8;:15;60614:9;:27;60610:347;;;60770:19;;;;;;;;;;60835:53;;;;;;;;;;;;;;-1:-1:-1;;;;;60835:53:0;;;;;;;;;;;;;;;60883:4;60835:53;;;;;;60746:21;60804:28;;;:13;:28;;;;;;;:84;;;;;;;;;;;-1:-1:-1;;;;;;60804:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;60804:84:0;;;;;;;;;;60908:37;;;;;;60770:19;;60780:8;;60908:37;:::i;:::-;;;;;;;;60643:314;60610:347;61017:9;-1:-1:-1;;;;;60974:63:0;61004:11;60974:63;;;;;;:::i;:::-;;;;;;;;60991:11;60974:63;;;61028:8;60974:63;;;;;;:::i;85240:110::-;85316:26;85326:2;85330:7;85316:26;;;;;;;;;;;;:9;:26::i;12871:191::-;12945:16;12964:6;;-1:-1:-1;;;;;12981:17:0;;;-1:-1:-1;;;;;;12981:17:0;;;;;;13014:40;;12964:6;;;;;;;13014:40;;12945:16;13014:40;12934:128;12871:191;:::o;62348:574::-;62470:7;62498:11;62520:263;62531:9;:16;62527:1;:20;62520:263;;;62657:24;;62645:9;:36;62641:47;;;62683:5;;62641:47;62705:48;62715:11;62728:10;62740:9;62750:1;62740:12;;;;;;;;:::i;:::-;;;;;;;62705:9;:48::i;:::-;62768:3;;;;:::i;:::-;;;;62520:263;;29979:2779;30120:12;30174:7;30158:12;30174:7;30168:2;30158:12;:::i;:::-;:23;;30150:50;;;;-1:-1:-1;;;30150:50:0;;40192:2:1;30150:50:0;;;40174:21:1;40231:2;40211:18;;;40204:30;-1:-1:-1;;;40250:18:1;;;40243:44;40304:18;;30150:50:0;39990:338:1;30150:50:0;30236:16;30245:7;30236:6;:16;:::i;:::-;30219:6;:13;:33;;30211:63;;;;-1:-1:-1;;;30211:63:0;;40535:2:1;30211:63:0;;;40517:21:1;40574:2;40554:18;;;40547:30;-1:-1:-1;;;40593:18:1;;;40586:47;40650:18;;30211:63:0;40333:341:1;30211:63:0;30287:22;30353:15;;30382:1933;;;;32459:4;32453:11;32440:24;;32640:1;32629:9;32622:20;32690:4;32679:9;32675:20;32669:4;32662:34;30346:2365;;30382:1933;30559:4;30553:11;30540:24;;31196:2;31187:7;31183:16;31568:9;31561:17;31555:4;31551:28;31539:9;31528;31524:25;31520:60;31617:7;31613:2;31609:16;31866:6;31852:9;31845:17;31839:4;31835:28;31823:9;31815:6;31811:22;31807:57;31803:70;31645:426;31900:3;31896:2;31893:11;31645:426;;;32042:9;;32031:21;;31942:4;31934:13;;;;31975;31645:426;;;-1:-1:-1;;32091:26:0;;;32295:2;32278:11;-1:-1:-1;;32274:25:0;32268:4;32261:39;-1:-1:-1;30346:2365:0;-1:-1:-1;32741:9:0;29979:2779;-1:-1:-1;;;;29979:2779:0:o;88718:315::-;88873:8;-1:-1:-1;;;;;88864:17:0;:5;-1:-1:-1;;;;;88864:17:0;;;88856:55;;;;-1:-1:-1;;;88856:55:0;;40881:2:1;88856:55:0;;;40863:21:1;40920:2;40900:18;;;40893:30;40959:27;40939:18;;;40932:55;41004:18;;88856:55:0;40679:349:1;88856:55:0;-1:-1:-1;;;;;88922:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;88922:46:0;;;;;;;;;;88984:41;;2099::1;;;88984::0;;2072:18:1;88984:41:0;;;;;;;88718:315;;;:::o;83714:313::-;83870:28;83880:4;83886:2;83890:7;83870:9;:28::i;:::-;83917:47;83940:4;83946:2;83950:7;83959:4;83917:22;:47::i;:::-;83909:110;;;;-1:-1:-1;;;83909:110:0;;;;;;;:::i;117023:108::-;117083:13;117116:7;117109:14;;;;;:::i;75226:723::-;75282:13;75503:10;75499:53;;-1:-1:-1;;75530:10:0;;;;;;;;;;;;-1:-1:-1;;;75530:10:0;;;;;75226:723::o;75499:53::-;75577:5;75562:12;75618:78;75625:9;;75618:78;;75651:8;;;;:::i;:::-;;-1:-1:-1;75674:10:0;;-1:-1:-1;75682:2:0;75674:10;;:::i;:::-;;;75618:78;;;75706:19;75738:6;-1:-1:-1;;;;;75728:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75728:17:0;;75706:39;;75756:154;75763:10;;75756:154;;75790:11;75800:1;75790:11;;:::i;:::-;;-1:-1:-1;75859:10:0;75867:2;75859:5;:10;:::i;:::-;75846:24;;:2;:24;:::i;:::-;75833:39;;75816:6;75823;75816:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;75816:56:0;;;;;;;;-1:-1:-1;75887:11:0;75896:2;75887:11;;:::i;:::-;;;75756:154;;47814:1275;47976:4;47982:12;48044:15;48070:13;48094:24;48131:8;48121:19;;-1:-1:-1;;;;;48121:19:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48121:19:0;;48094:46;;48622:1;48596;48562:9;48556:16;48527:4;48516:9;48512:20;48481:1;48446:7;48420:4;48401:247;48389:259;;48713:16;48702:27;;48758:8;48749:7;48746:21;48743:78;;;48798:8;48787:19;;48743:78;48904:7;48891:11;48884:28;49022:7;49019:1;49012:4;48999:11;48995:22;48980:50;49059:8;;;;-1:-1:-1;47814:1275:0;-1:-1:-1;;;;;;47814:1275:0:o;53697:323::-;53921:8;53911:19;;;;;;53860:14;:27;53875:11;53860:27;;;;;;;;;;;;;;;53888:11;53860:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;53860:48:0;;;;;;;;;:70;;;;53946:66;;;;53960:11;;53973;;53901:6;;53994:8;;54004:7;;53946:66;:::i;:::-;;;;;;;;53697:323;;;;;:::o;93994:224::-;94096:4;-1:-1:-1;;;;;;94120:50:0;;-1:-1:-1;;;94120:50:0;;:90;;;94174:36;94198:11;94174:23;:36::i;115622:227::-;101427:19;:17;:19::i;:::-;115796:45:::1;115823:4;115829:2;115833:7;115796:26;:45::i;109580:505::-:0;109669:22;109677:4;109683:7;109669;:22::i;:::-;109664:414;;109857:41;109885:7;-1:-1:-1;;;;;109857:41:0;109895:2;109857:19;:41::i;:::-;109971:38;109999:4;110006:2;109971:19;:38::i;:::-;109762:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;109762:270:0;;;;;;;;;;-1:-1:-1;;;109708:358:0;;;;;;;:::i;114872:361::-;114989:42;10228:10;115008:12;10148:98;114989:42;114981:101;;;;-1:-1:-1;;;114981:101:0;;43543:2:1;114981:101:0;;;43525:21:1;43582:2;43562:18;;;43555:30;43621:34;43601:18;;;43594:62;-1:-1:-1;;;43672:18:1;;;43665:44;43726:19;;114981:101:0;43341:410:1;114981:101:0;115129:5;-1:-1:-1;;;;;115101:33:0;:24;115116:8;115101:14;:24::i;:::-;-1:-1:-1;;;;;115101:33:0;;115093:80;;;;-1:-1:-1;;;115093:80:0;;43958:2:1;115093:80:0;;;43940:21:1;43997:2;43977:18;;;43970:30;44036:34;44016:18;;;44009:62;-1:-1:-1;;;44087:18:1;;;44080:32;44129:19;;115093:80:0;43756:398:1;115093:80:0;115184:41;115194:5;115209:4;115216:8;115184:9;:41::i;42550:420::-;42686:21;42710:28;42723:14;42710:12;:28::i;:::-;42768;;;;42749:16;42768:28;;;:15;:28;;;;;;;;:35;;;;;;;;;;;;42686:52;;-1:-1:-1;42749:16:0;42768:47;;42806:9;;42768:47;:::i;:::-;42749:66;;42848:1;42834:11;:15;42826:54;;;;-1:-1:-1;;;42826:54:0;;44361:2:1;42826:54:0;;;44343:21:1;44400:2;44380:18;;;44373:30;44439:28;44419:18;;;44412:56;44485:18;;42826:54:0;44159:350:1;42826:54:0;42919:11;42899:16;:31;;42891:71;;;;-1:-1:-1;;;42891:71:0;;44716:2:1;42891:71:0;;;44698:21:1;44755:2;44735:18;;;44728:30;44794:29;44774:18;;;44767:57;44841:18;;42891:71:0;44514:351:1;41989:553:0;42212:32;;;42183:26;42212:32;;;:19;:32;;;;;42183:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42263:13;:20;42287:1;42263:25;;42255:86;;;;-1:-1:-1;;;42255:86:0;;45072:2:1;42255:86:0;;;45054:21:1;45111:2;45091:18;;;45084:30;45150:34;45130:18;;;45123:62;-1:-1:-1;;;45201:18:1;;;45194:46;45257:19;;42255:86:0;44870:412:1;42255:86:0;42352:47;42370:11;42383:8;:15;42352:17;:47::i;:::-;42410:124;;-1:-1:-1;;;42410:124:0;;-1:-1:-1;;;;;42410:10:0;:15;;;;42433:10;;42410:124;;42445:11;;42458:13;;42473:8;;42483:14;;42499:18;;42519:14;;42410:124;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42172:370;41989:553;;;;;;:::o;85577:319::-;85706:18;85712:2;85716:7;85706:5;:18::i;:::-;85757:53;85788:1;85792:2;85796:7;85805:4;85757:22;:53::i;:::-;85735:153;;;;-1:-1:-1;;;85735:153:0;;;;;;;:::i;115241:373::-;84405:4;84429:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84429:16:0;:30;;115348:86;;-1:-1:-1;84405:4:0;84429:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84429:16:0;:30;;115371:62;;;;-1:-1:-1;115428:4:0;115392:24;115407:8;115392:14;:24::i;:::-;-1:-1:-1;;;;;115392:41:0;;115371:62;115340:95;;;;;;84405:4;84429:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84429:16:0;115446:161;;115485:31;115495:10;115507:8;115485:9;:31::i;115446:161::-;115549:46;115567:4;115574:10;115586:8;115549:9;:46::i;89821:853::-;89975:4;-1:-1:-1;;;;;89996:13:0;;67762:19;:23;89992:675;;90032:71;;-1:-1:-1;;;90032:71:0;;-1:-1:-1;;;;;90032:36:0;;;;;:71;;10228:10;;90083:4;;90089:7;;90098:4;;90032:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90032:71:0;;;;;;;;-1:-1:-1;;90032:71:0;;;;;;;;;;;;:::i;:::-;;;90028:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90273:13:0;;90269:328;;90316:60;;-1:-1:-1;;;90316:60:0;;;;;;;:::i;90269:328::-;90547:6;90541:13;90532:6;90528:2;90524:15;90517:38;90028:584;-1:-1:-1;;;;;;90154:51:0;-1:-1:-1;;;90154:51:0;;-1:-1:-1;90147:58:0;;89992:675;-1:-1:-1;90651:4:0;90644:11;;78707:305;78809:4;-1:-1:-1;;;;;;78846:40:0;;-1:-1:-1;;;78846:40:0;;:105;;-1:-1:-1;;;;;;;78903:48:0;;-1:-1:-1;;;78903:48:0;78846:105;:158;;;;78968:36;78992:11;78968:23;:36::i;101981:108::-;101893:7;;;;102051:9;102043:38;;;;-1:-1:-1;;;102043:38:0;;47082:2:1;102043:38:0;;;47064:21:1;47121:2;47101:18;;;47094:30;-1:-1:-1;;;47140:18:1;;;47133:46;47196:18;;102043:38:0;46880:340:1;95670:589:0;-1:-1:-1;;;;;95876:18:0;;95872:187;;95911:40;95943:7;97086:10;:17;;97059:24;;;;:15;:24;;;;;:44;;;97114:24;;;;;;;;;;;;96982:164;95911:40;95872:187;;;95981:2;-1:-1:-1;;;;;95973:10:0;:4;-1:-1:-1;;;;;95973:10:0;;95969:90;;96000:47;96033:4;96039:7;96000:32;:47::i;:::-;-1:-1:-1;;;;;96073:16:0;;96069:183;;96106:45;96143:7;96106:36;:45::i;96069:183::-;96179:4;-1:-1:-1;;;;;96173:10:0;:2;-1:-1:-1;;;;;96173:10:0;;96169:83;;96200:40;96228:2;96232:7;96200:27;:40::i;76527:451::-;76602:13;76628:19;76660:10;76664:6;76660:1;:10;:::i;:::-;:14;;76673:1;76660:14;:::i;:::-;-1:-1:-1;;;;;76650:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;76650:25:0;;76628:47;;-1:-1:-1;;;76686:6:0;76693:1;76686:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;76686:15:0;;;;;;;;;-1:-1:-1;;;76712:6:0;76719:1;76712:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;76712:15:0;;;;;;;;-1:-1:-1;76743:9:0;76755:10;76759:6;76755:1;:10;:::i;:::-;:14;;76768:1;76755:14;:::i;:::-;76743:26;;76738:135;76775:1;76771;:5;76738:135;;;-1:-1:-1;;;76823:5:0;76831:3;76823:11;76810:25;;;;;;;:::i;:::-;;;;76798:6;76805:1;76798:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;76798:37:0;;;;;;;;-1:-1:-1;76860:1:0;76850:11;;;;;76778:3;;;:::i;:::-;;;76738:135;;;-1:-1:-1;76891:10:0;;76883:55;;;;-1:-1:-1;;;76883:55:0;;47568:2:1;76883:55:0;;;47550:21:1;;;47587:18;;;47580:30;47646:34;47626:18;;;47619:62;47698:18;;76883:55:0;47366:356:1;42978:271:0;43060:13;43119:2;43094:14;:21;:27;;43086:68;;;;-1:-1:-1;;;43086:68:0;;47929:2:1;43086:68:0;;;47911:21:1;47968:2;47948:18;;;47941:30;48007;47987:18;;;47980:58;48055:18;;43086:68:0;47727:352:1;43086:68:0;-1:-1:-1;43227:2:0;43207:23;43201:30;;42978:271::o;43257:389::-;43380:35;;;43356:21;43380:35;;;:22;:35;;;;;;43430:21;43426:125;;-1:-1:-1;40283:5:0;43426:125;43585:16;43569:12;:32;;43561:77;;;;-1:-1:-1;;;43561:77:0;;48286:2:1;43561:77:0;;;48268:21:1;;;48305:18;;;48298:30;48364:34;48344:18;;;48337:62;48416:18;;43561:77:0;48084:356:1;86232:439:0;-1:-1:-1;;;;;86312:16:0;;86304:61;;;;-1:-1:-1;;;86304:61:0;;48647:2:1;86304:61:0;;;48629:21:1;;;48666:18;;;48659:30;48725:34;48705:18;;;48698:62;48777:18;;86304:61:0;48445:356:1;86304:61:0;84405:4;84429:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84429:16:0;:30;86376:58;;;;-1:-1:-1;;;86376:58:0;;49008:2:1;86376:58:0;;;48990:21:1;49047:2;49027:18;;;49020:30;49086;49066:18;;;49059:58;49134:18;;86376:58:0;48806:352:1;86376:58:0;86447:45;86476:1;86480:2;86484:7;86447:20;:45::i;:::-;-1:-1:-1;;;;;86505:13:0;;;;;;:9;:13;;;;;:18;;86522:1;;86505:13;:18;;86522:1;;86505:18;:::i;:::-;;;;-1:-1:-1;;86534:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;86534:21:0;-1:-1:-1;;;;;86534:21:0;;;;;;;;86573:33;;86534:16;;;86573:33;;86534:16;;86573:33;111859:218;;:::o;57419:219::-;57521:4;-1:-1:-1;;;;;;57545:45:0;;-1:-1:-1;;;57545:45:0;;:85;;-1:-1:-1;;;;;;;;;;56315:40:0;;;57594:36;56206:157;97773:988;98039:22;98089:1;98064:22;98081:4;98064:16;:22::i;:::-;:26;;;;:::i;:::-;98101:18;98122:26;;;:17;:26;;;;;;98039:51;;-1:-1:-1;98255:28:0;;;98251:328;;-1:-1:-1;;;;;98322:18:0;;98300:19;98322:18;;;:12;:18;;;;;;;;:34;;;;;;;;;98373:30;;;;;;:44;;;98490:30;;:17;:30;;;;;:43;;;98251:328;-1:-1:-1;98675:26:0;;;;:17;:26;;;;;;;;98668:33;;;-1:-1:-1;;;;;98719:18:0;;;;;:12;:18;;;;;:34;;;;;;;98712:41;97773:988::o;99056:1079::-;99334:10;:17;99309:22;;99334:21;;99354:1;;99334:21;:::i;:::-;99366:18;99387:24;;;:15;:24;;;;;;99760:10;:26;;99309:46;;-1:-1:-1;99387:24:0;;99309:46;;99760:26;;;;;;:::i;:::-;;;;;;;;;99738:48;;99824:11;99799:10;99810;99799:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;99904:28;;;:15;:28;;;;;;;:41;;;100076:24;;;;;100069:31;100111:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;99127:1008;;;99056:1079;:::o;96560:221::-;96645:14;96662:20;96679:2;96662:16;:20::i;:::-;-1:-1:-1;;;;;96693:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;96738:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;96560:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:159:1;81:20;;141:6;130:18;;120:29;;110:57;;163:1;160;153:12;110:57;14:159;;;:::o;178:347::-;229:8;239:6;293:3;286:4;278:6;274:17;270:27;260:55;;311:1;308;301:12;260:55;-1:-1:-1;334:20:1;;-1:-1:-1;;;;;366:30:1;;363:50;;;409:1;406;399:12;363:50;446:4;438:6;434:17;422:29;;498:3;491:4;482:6;474;470:19;466:30;463:39;460:59;;;515:1;512;505:12;460:59;178:347;;;;;:::o;530:171::-;597:20;;-1:-1:-1;;;;;646:30:1;;636:41;;626:69;;691:1;688;681:12;706:862;812:6;820;828;836;844;852;905:3;893:9;884:7;880:23;876:33;873:53;;;922:1;919;912:12;873:53;945:28;963:9;945:28;:::i;:::-;935:38;;1024:2;1013:9;1009:18;996:32;-1:-1:-1;;;;;1088:2:1;1080:6;1077:14;1074:34;;;1104:1;1101;1094:12;1074:34;1143:58;1193:7;1184:6;1173:9;1169:22;1143:58;:::i;:::-;1220:8;;-1:-1:-1;1117:84:1;-1:-1:-1;1117:84:1;;-1:-1:-1;1274:37:1;1307:2;1292:18;;1274:37;:::i;:::-;1264:47;;1364:2;1353:9;1349:18;1336:32;1320:48;;1393:2;1383:8;1380:16;1377:36;;;1409:1;1406;1399:12;1377:36;;1448:60;1500:7;1489:8;1478:9;1474:24;1448:60;:::i;:::-;706:862;;;;-1:-1:-1;706:862:1;;-1:-1:-1;706:862:1;;1527:8;;706:862;-1:-1:-1;;;706:862:1:o;1573:131::-;-1:-1:-1;;;;;;1647:32:1;;1637:43;;1627:71;;1694:1;1691;1684:12;1709:245;1767:6;1820:2;1808:9;1799:7;1795:23;1791:32;1788:52;;;1836:1;1833;1826:12;1788:52;1875:9;1862:23;1894:30;1918:5;1894:30;:::i;2151:258::-;2223:1;2233:113;2247:6;2244:1;2241:13;2233:113;;;2323:11;;;2317:18;2304:11;;;2297:39;2269:2;2262:10;2233:113;;;2364:6;2361:1;2358:13;2355:48;;;-1:-1:-1;;2399:1:1;2381:16;;2374:27;2151:258::o;2414:::-;2456:3;2494:5;2488:12;2521:6;2516:3;2509:19;2537:63;2593:6;2586:4;2581:3;2577:14;2570:4;2563:5;2559:16;2537:63;:::i;:::-;2654:2;2633:15;-1:-1:-1;;2629:29:1;2620:39;;;;2661:4;2616:50;;2414:258;-1:-1:-1;;2414:258:1:o;2677:220::-;2826:2;2815:9;2808:21;2789:4;2846:45;2887:2;2876:9;2872:18;2864:6;2846:45;:::i;2902:184::-;2960:6;3013:2;3001:9;2992:7;2988:23;2984:32;2981:52;;;3029:1;3026;3019:12;2981:52;3052:28;3070:9;3052:28;:::i;3091:180::-;3150:6;3203:2;3191:9;3182:7;3178:23;3174:32;3171:52;;;3219:1;3216;3209:12;3171:52;-1:-1:-1;3242:23:1;;3091:180;-1:-1:-1;3091:180:1:o;3484:131::-;-1:-1:-1;;;;;3559:31:1;;3549:42;;3539:70;;3605:1;3602;3595:12;3620:134;3688:20;;3717:31;3688:20;3717:31;:::i;3759:315::-;3827:6;3835;3888:2;3876:9;3867:7;3863:23;3859:32;3856:52;;;3904:1;3901;3894:12;3856:52;3943:9;3930:23;3962:31;3987:5;3962:31;:::i;:::-;4012:5;4064:2;4049:18;;;;4036:32;;-1:-1:-1;;;3759:315:1:o;4079:252::-;4146:6;4154;4207:2;4195:9;4186:7;4182:23;4178:32;4175:52;;;4223:1;4220;4213:12;4175:52;4246:28;4264:9;4246:28;:::i;5146:456::-;5223:6;5231;5239;5292:2;5280:9;5271:7;5267:23;5263:32;5260:52;;;5308:1;5305;5298:12;5260:52;5347:9;5334:23;5366:31;5391:5;5366:31;:::i;:::-;5416:5;-1:-1:-1;5473:2:1;5458:18;;5445:32;5486:33;5445:32;5486:33;:::i;:::-;5146:456;;5538:7;;-1:-1:-1;;;5592:2:1;5577:18;;;;5564:32;;5146:456::o;5789:127::-;5850:10;5845:3;5841:20;5838:1;5831:31;5881:4;5878:1;5871:15;5905:4;5902:1;5895:15;5921:275;5992:2;5986:9;6057:2;6038:13;;-1:-1:-1;;6034:27:1;6022:40;;-1:-1:-1;;;;;6077:34:1;;6113:22;;;6074:62;6071:88;;;6139:18;;:::i;:::-;6175:2;6168:22;5921:275;;-1:-1:-1;5921:275:1:o;6201:186::-;6249:4;-1:-1:-1;;;;;6274:6:1;6271:30;6268:56;;;6304:18;;:::i;:::-;-1:-1:-1;6370:2:1;6349:15;-1:-1:-1;;6345:29:1;6376:4;6341:40;;6201:186::o;6392:336::-;6456:5;6485:52;6501:35;6529:6;6501:35;:::i;:::-;6485:52;:::i;:::-;6476:61;;6560:6;6553:5;6546:21;6600:3;6591:6;6586:3;6582:16;6579:25;6576:45;;;6617:1;6614;6607:12;6576:45;6666:6;6661:3;6654:4;6647:5;6643:16;6630:43;6720:1;6713:4;6704:6;6697:5;6693:18;6689:29;6682:40;6392:336;;;;;:::o;6733:220::-;6775:5;6828:3;6821:4;6813:6;6809:17;6805:27;6795:55;;6846:1;6843;6836:12;6795:55;6868:79;6943:3;6934:6;6921:20;6914:4;6906:6;6902:17;6868:79;:::i;6958:160::-;7023:20;;7079:13;;7072:21;7062:32;;7052:60;;7108:1;7105;7098:12;7123:749;7232:6;7240;7248;7256;7264;7317:3;7305:9;7296:7;7292:23;7288:33;7285:53;;;7334:1;7331;7324:12;7285:53;7357:28;7375:9;7357:28;:::i;:::-;7347:38;;7436:2;7425:9;7421:18;7408:32;-1:-1:-1;;;;;7500:2:1;7492:6;7489:14;7486:34;;;7516:1;7513;7506:12;7486:34;7539:49;7580:7;7571:6;7560:9;7556:22;7539:49;:::i;:::-;7529:59;;7635:2;7624:9;7620:18;7607:32;7597:42;;7658:35;7689:2;7678:9;7674:18;7658:35;:::i;:::-;7648:45;;7746:3;7735:9;7731:19;7718:33;7702:49;;7776:2;7766:8;7763:16;7760:36;;;7792:1;7789;7782:12;7760:36;;7815:51;7858:7;7847:8;7836:9;7832:24;7815:51;:::i;:::-;7805:61;;;7123:749;;;;;;;;:::o;8130:315::-;8198:6;8206;8259:2;8247:9;8238:7;8234:23;8230:32;8227:52;;;8275:1;8272;8265:12;8227:52;8311:9;8298:23;8288:33;;8371:2;8360:9;8356:18;8343:32;8384:31;8409:5;8384:31;:::i;:::-;8434:5;8424:15;;;8130:315;;;;;:::o;8450:481::-;8528:6;8536;8544;8597:2;8585:9;8576:7;8572:23;8568:32;8565:52;;;8613:1;8610;8603:12;8565:52;8636:28;8654:9;8636:28;:::i;:::-;8626:38;;8715:2;8704:9;8700:18;8687:32;-1:-1:-1;;;;;8734:6:1;8731:30;8728:50;;;8774:1;8771;8764:12;8728:50;8813:58;8863:7;8854:6;8843:9;8839:22;8813:58;:::i;:::-;8450:481;;8890:8;;-1:-1:-1;8787:84:1;;-1:-1:-1;;;;8450:481:1:o;8936:1108::-;9074:6;9082;9090;9098;9106;9114;9122;9175:3;9163:9;9154:7;9150:23;9146:33;9143:53;;;9192:1;9189;9182:12;9143:53;9231:9;9218:23;9250:31;9275:5;9250:31;:::i;:::-;9300:5;-1:-1:-1;9324:37:1;9357:2;9342:18;;9324:37;:::i;:::-;9314:47;;9412:2;9401:9;9397:18;9384:32;-1:-1:-1;;;;;9476:2:1;9468:6;9465:14;9462:34;;;9492:1;9489;9482:12;9462:34;9515:49;9556:7;9547:6;9536:9;9532:22;9515:49;:::i;:::-;9505:59;;9611:2;9600:9;9596:18;9583:32;9573:42;;9667:3;9656:9;9652:19;9639:33;9624:48;;9681:33;9706:7;9681:33;:::i;:::-;9733:7;;-1:-1:-1;9792:3:1;9777:19;;9764:33;;9806;9764;9806;:::i;:::-;9858:7;;-1:-1:-1;9918:3:1;9903:19;;9890:33;;9935:16;;;9932:36;;;9964:1;9961;9954:12;9932:36;;9987:51;10030:7;10019:8;10008:9;10004:24;9987:51;:::i;:::-;9977:61;;;8936:1108;;;;;;;;;;:::o;10049:450::-;10118:6;10171:2;10159:9;10150:7;10146:23;10142:32;10139:52;;;10187:1;10184;10177:12;10139:52;10227:9;10214:23;-1:-1:-1;;;;;10252:6:1;10249:30;10246:50;;;10292:1;10289;10282:12;10246:50;10315:22;;10368:4;10360:13;;10356:27;-1:-1:-1;10346:55:1;;10397:1;10394;10387:12;10346:55;10420:73;10485:7;10480:2;10467:16;10462:2;10458;10454:11;10420:73;:::i;10504:464::-;10588:6;10596;10604;10657:2;10645:9;10636:7;10632:23;10628:32;10625:52;;;10673:1;10670;10663:12;10625:52;10696:28;10714:9;10696:28;:::i;:::-;10686:38;;10775:2;10764:9;10760:18;10747:32;-1:-1:-1;;;;;10794:6:1;10791:30;10788:50;;;10834:1;10831;10824:12;10788:50;10857:49;10898:7;10889:6;10878:9;10874:22;10857:49;:::i;:::-;10847:59;;;10925:37;10958:2;10947:9;10943:18;10925:37;:::i;:::-;10915:47;;10504:464;;;;;:::o;10973:247::-;11032:6;11085:2;11073:9;11064:7;11060:23;11056:32;11053:52;;;11101:1;11098;11091:12;11053:52;11140:9;11127:23;11159:31;11184:5;11159:31;:::i;11448:256::-;11514:6;11522;11575:2;11563:9;11554:7;11550:23;11546:32;11543:52;;;11591:1;11588;11581:12;11543:52;11614:28;11632:9;11614:28;:::i;:::-;11604:38;;11661:37;11694:2;11683:9;11679:18;11661:37;:::i;:::-;11651:47;;11448:256;;;;;:::o;11709:320::-;11777:6;11830:2;11818:9;11809:7;11805:23;11801:32;11798:52;;;11846:1;11843;11836:12;11798:52;11886:9;11873:23;-1:-1:-1;;;;;11911:6:1;11908:30;11905:50;;;11951:1;11948;11941:12;11905:50;11974:49;12015:7;12006:6;11995:9;11991:22;11974:49;:::i;12034:248::-;12102:6;12110;12163:2;12151:9;12142:7;12138:23;12134:32;12131:52;;;12179:1;12176;12169:12;12131:52;-1:-1:-1;;12202:23:1;;;12272:2;12257:18;;;12244:32;;-1:-1:-1;12034:248:1:o;12287:315::-;12352:6;12360;12413:2;12401:9;12392:7;12388:23;12384:32;12381:52;;;12429:1;12426;12419:12;12381:52;12468:9;12455:23;12487:31;12512:5;12487:31;:::i;:::-;12537:5;-1:-1:-1;12561:35:1;12592:2;12577:18;;12561:35;:::i;12607:183::-;12667:4;-1:-1:-1;;;;;12692:6:1;12689:30;12686:56;;;12722:18;;:::i;:::-;-1:-1:-1;12767:1:1;12763:14;12779:4;12759:25;;12607:183::o;12795:662::-;12849:5;12902:3;12895:4;12887:6;12883:17;12879:27;12869:55;;12920:1;12917;12910:12;12869:55;12956:6;12943:20;12982:4;13006:60;13022:43;13062:2;13022:43;:::i;13006:60::-;13100:15;;;13186:1;13182:10;;;;13170:23;;13166:32;;;13131:12;;;;13210:15;;;13207:35;;;13238:1;13235;13228:12;13207:35;13274:2;13266:6;13262:15;13286:142;13302:6;13297:3;13294:15;13286:142;;;13368:17;;13356:30;;13406:12;;;;13319;;13286:142;;;-1:-1:-1;13446:5:1;12795:662;-1:-1:-1;;;;;;12795:662:1:o;13462:1199::-;13625:6;13633;13641;13649;13657;13665;13673;13726:3;13714:9;13705:7;13701:23;13697:33;13694:53;;;13743:1;13740;13733:12;13694:53;13782:9;13769:23;13801:31;13826:5;13801:31;:::i;:::-;13851:5;-1:-1:-1;13875:37:1;13908:2;13893:18;;13875:37;:::i;:::-;13865:47;;13963:2;13952:9;13948:18;13935:32;-1:-1:-1;;;;;14027:2:1;14019:6;14016:14;14013:34;;;14043:1;14040;14033:12;14013:34;14066:49;14107:7;14098:6;14087:9;14083:22;14066:49;:::i;:::-;14056:59;;14168:2;14157:9;14153:18;14140:32;14124:48;;14197:2;14187:8;14184:16;14181:36;;;14213:1;14210;14203:12;14181:36;14236:63;14291:7;14280:8;14269:9;14265:24;14236:63;:::i;:::-;14226:73;;14351:3;14340:9;14336:19;14323:33;14308:48;;14365:33;14390:7;14365:33;:::i;:::-;14417:7;14407:17;;14443:39;14477:3;14466:9;14462:19;14443:39;:::i;:::-;14433:49;;14535:3;14524:9;14520:19;14507:33;14491:49;;14565:2;14555:8;14552:16;14549:36;;;14581:1;14578;14571:12;15093:665;15188:6;15196;15204;15212;15265:3;15253:9;15244:7;15240:23;15236:33;15233:53;;;15282:1;15279;15272:12;15233:53;15321:9;15308:23;15340:31;15365:5;15340:31;:::i;:::-;15390:5;-1:-1:-1;15447:2:1;15432:18;;15419:32;15460:33;15419:32;15460:33;:::i;:::-;15512:7;-1:-1:-1;15566:2:1;15551:18;;15538:32;;-1:-1:-1;15621:2:1;15606:18;;15593:32;-1:-1:-1;;;;;15637:30:1;;15634:50;;;15680:1;15677;15670:12;15634:50;15703:49;15744:7;15735:6;15724:9;15720:22;15703:49;:::i;:::-;15693:59;;;15093:665;;;;;;;:::o;15763:622::-;15858:6;15866;15874;15882;15890;15943:3;15931:9;15922:7;15918:23;15914:33;15911:53;;;15960:1;15957;15950:12;15911:53;15983:28;16001:9;15983:28;:::i;:::-;15973:38;;16030:37;16063:2;16052:9;16048:18;16030:37;:::i;:::-;16020:47;;16114:2;16103:9;16099:18;16086:32;16076:42;;16169:2;16158:9;16154:18;16141:32;-1:-1:-1;;;;;16188:6:1;16185:30;16182:50;;;16228:1;16225;16218:12;16182:50;16267:58;16317:7;16308:6;16297:9;16293:22;16267:58;:::i;:::-;15763:622;;;;-1:-1:-1;15763:622:1;;-1:-1:-1;16344:8:1;;16241:84;15763:622;-1:-1:-1;;;15763:622:1:o;16390:324::-;16465:6;16473;16481;16534:2;16522:9;16513:7;16509:23;16505:32;16502:52;;;16550:1;16547;16540:12;16502:52;16573:28;16591:9;16573:28;:::i;:::-;16563:38;;16620:37;16653:2;16642:9;16638:18;16620:37;:::i;:::-;16610:47;;16704:2;16693:9;16689:18;16676:32;16666:42;;16390:324;;;;;:::o;16719:388::-;16787:6;16795;16848:2;16836:9;16827:7;16823:23;16819:32;16816:52;;;16864:1;16861;16854:12;16816:52;16903:9;16890:23;16922:31;16947:5;16922:31;:::i;:::-;16972:5;-1:-1:-1;17029:2:1;17014:18;;17001:32;17042:33;17001:32;17042:33;:::i;17112:907::-;17246:6;17254;17262;17270;17278;17331:3;17319:9;17310:7;17306:23;17302:33;17299:53;;;17348:1;17345;17338:12;17299:53;17371:28;17389:9;17371:28;:::i;:::-;17361:38;;17450:2;17439:9;17435:18;17422:32;-1:-1:-1;;;;;17514:2:1;17506:6;17503:14;17500:34;;;17530:1;17527;17520:12;17500:34;17553:49;17594:7;17585:6;17574:9;17570:22;17553:49;:::i;:::-;17543:59;;17655:2;17644:9;17640:18;17627:32;17611:48;;17684:2;17674:8;17671:16;17668:36;;;17700:1;17697;17690:12;17668:36;17723:63;17778:7;17767:8;17756:9;17752:24;17723:63;:::i;:::-;17713:73;;17805:35;17836:2;17825:9;17821:18;17805:35;:::i;18024:460::-;18108:6;18116;18124;18132;18185:3;18173:9;18164:7;18160:23;18156:33;18153:53;;;18202:1;18199;18192:12;18153:53;18225:28;18243:9;18225:28;:::i;:::-;18215:38;;18272:37;18305:2;18294:9;18290:18;18272:37;:::i;:::-;18262:47;;18359:2;18348:9;18344:18;18331:32;18372:31;18397:5;18372:31;:::i;:::-;18024:460;;;;-1:-1:-1;18422:5:1;;18474:2;18459:18;18446:32;;-1:-1:-1;;18024:460:1:o;18848:380::-;18927:1;18923:12;;;;18970;;;18991:61;;19045:4;19037:6;19033:17;19023:27;;18991:61;19098:2;19090:6;19087:14;19067:18;19064:38;19061:161;;;19144:10;19139:3;19135:20;19132:1;19125:31;19179:4;19176:1;19169:15;19207:4;19204:1;19197:15;19061:161;;18848:380;;;:::o;19233:271::-;19416:6;19408;19403:3;19390:33;19372:3;19442:16;;19467:13;;;19442:16;19233:271;-1:-1:-1;19233:271:1:o;21163:410::-;21365:2;21347:21;;;21404:2;21384:18;;;21377:30;21443:34;21438:2;21423:18;;21416:62;-1:-1:-1;;;21509:2:1;21494:18;;21487:44;21563:3;21548:19;;21163:410::o;22406:266::-;22494:6;22489:3;22482:19;22546:6;22539:5;22532:4;22527:3;22523:14;22510:43;-1:-1:-1;22598:1:1;22573:16;;;22591:4;22569:27;;;22562:38;;;;22654:2;22633:15;;;-1:-1:-1;;22629:29:1;22620:39;;;22616:50;;22406:266::o;22677:326::-;22872:6;22864;22860:19;22849:9;22842:38;22916:2;22911;22900:9;22896:18;22889:30;22823:4;22936:61;22993:2;22982:9;22978:18;22970:6;22962;22936:61;:::i;23421:127::-;23482:10;23477:3;23473:20;23470:1;23463:31;23513:4;23510:1;23503:15;23537:4;23534:1;23527:15;24722:127;24783:10;24778:3;24774:20;24771:1;24764:31;24814:4;24811:1;24804:15;24838:4;24835:1;24828:15;24854:135;24893:3;-1:-1:-1;;24914:17:1;;24911:43;;;24934:18;;:::i;:::-;-1:-1:-1;24981:1:1;24970:13;;24854:135::o;26038:428::-;26091:5;26144:3;26137:4;26129:6;26125:17;26121:27;26111:55;;26162:1;26159;26152:12;26111:55;26191:6;26185:13;26222:48;26238:31;26266:2;26238:31;:::i;26222:48::-;26295:2;26286:7;26279:19;26341:3;26334:4;26329:2;26321:6;26317:15;26313:26;26310:35;26307:55;;;26358:1;26355;26348:12;26307:55;26371:64;26432:2;26425:4;26416:7;26412:18;26405:4;26397:6;26393:17;26371:64;:::i;26471:1104::-;26584:6;26592;26645:2;26633:9;26624:7;26620:23;26616:32;26613:52;;;26661:1;26658;26651:12;26613:52;26694:9;26688:16;-1:-1:-1;;;;;26764:2:1;26756:6;26753:14;26750:34;;;26780:1;26777;26770:12;26750:34;26803:60;26855:7;26846:6;26835:9;26831:22;26803:60;:::i;:::-;26793:70;;26882:2;26872:12;;26930:2;26919:9;26915:18;26909:25;26959:2;26949:8;26946:16;26943:36;;;26975:1;26972;26965:12;26943:36;26998:24;;;-1:-1:-1;27053:4:1;27045:13;;27041:27;-1:-1:-1;27031:55:1;;27082:1;27079;27072:12;27031:55;27111:2;27105:9;27134:60;27150:43;27190:2;27150:43;:::i;27134:60::-;27228:15;;;27310:1;27306:10;;;;27298:19;;27294:28;;;27259:12;;;;27334:19;;;27331:39;;;27366:1;27363;27356:12;27331:39;27390:11;;;;27410:135;27426:6;27421:3;27418:15;27410:135;;;27492:10;;27480:23;;27443:12;;;;27523;;;;27410:135;;;27564:5;27554:15;;;;;;;26471:1104;;;;;:::o;29447:125::-;29487:4;29515:1;29512;29509:8;29506:34;;;29520:18;;:::i;:::-;-1:-1:-1;29557:9:1;;29447:125::o;29577:382::-;29788:6;29780;29775:3;29762:33;29880:2;29876:15;;;;-1:-1:-1;;29872:53:1;29814:16;;29861:65;;;29950:2;29942:11;;29577:382;-1:-1:-1;29577:382:1:o;29964:470::-;30143:3;30181:6;30175:13;30197:53;30243:6;30238:3;30231:4;30223:6;30219:17;30197:53;:::i;:::-;30313:13;;30272:16;;;;30335:57;30313:13;30272:16;30369:4;30357:17;;30335:57;:::i;:::-;30408:20;;29964:470;-1:-1:-1;;;;29964:470:1:o;30439:498::-;30639:4;30668:6;30713:2;30705:6;30701:15;30690:9;30683:34;30765:2;30757:6;30753:15;30748:2;30737:9;30733:18;30726:43;;30805:6;30800:2;30789:9;30785:18;30778:34;30848:3;30843:2;30832:9;30828:18;30821:31;30869:62;30926:3;30915:9;30911:19;30903:6;30895;30869:62;:::i;:::-;30861:70;30439:498;-1:-1:-1;;;;;;;30439:498:1:o;32161:493::-;32410:6;32402;32398:19;32387:9;32380:38;32454:3;32449:2;32438:9;32434:18;32427:31;32361:4;32475:62;32532:3;32521:9;32517:19;32509:6;32501;32475:62;:::i;:::-;-1:-1:-1;;;;;32573:31:1;;;;32568:2;32553:18;;32546:59;-1:-1:-1;32636:2:1;32621:18;32614:34;32467:70;32161:493;-1:-1:-1;;;32161:493:1:o;33372:435::-;33425:3;33463:5;33457:12;33490:6;33485:3;33478:19;33516:4;33545:2;33540:3;33536:12;33529:19;;33582:2;33575:5;33571:14;33603:1;33613:169;33627:6;33624:1;33621:13;33613:169;;;33688:13;;33676:26;;33722:12;;;;33757:15;;;;33649:1;33642:9;33613:169;;;-1:-1:-1;33798:3:1;;33372:435;-1:-1:-1;;;;;33372:435:1:o;33812:422::-;34037:2;34026:9;34019:21;34000:4;34063:45;34104:2;34093:9;34089:18;34081:6;34063:45;:::i;:::-;34156:9;34148:6;34144:22;34139:2;34128:9;34124:18;34117:50;34184:44;34221:6;34213;34184:44;:::i;:::-;34176:52;33812:422;-1:-1:-1;;;;;33812:422:1:o;34239:642::-;34520:6;34508:19;;34490:38;;-1:-1:-1;;;;;34564:32:1;;34559:2;34544:18;;34537:60;34584:3;34628:2;34613:18;;34606:31;;;-1:-1:-1;;34660:46:1;;34686:19;;34678:6;34660:46;:::i;:::-;34756:6;34749:14;34742:22;34737:2;34726:9;34722:18;34715:50;34814:9;34806:6;34802:22;34796:3;34785:9;34781:19;34774:51;34842:33;34868:6;34860;34842:33;:::i;:::-;34834:41;34239:642;-1:-1:-1;;;;;;;;34239:642:1:o;34886:245::-;34965:6;34973;35026:2;35014:9;35005:7;35001:23;34997:32;34994:52;;;35042:1;35039;35032:12;34994:52;-1:-1:-1;;35065:16:1;;35121:2;35106:18;;;35100:25;35065:16;;35100:25;;-1:-1:-1;34886:245:1:o;36004:335::-;36083:6;36136:2;36124:9;36115:7;36111:23;36107:32;36104:52;;;36152:1;36149;36142:12;36104:52;36185:9;36179:16;-1:-1:-1;;;;;36210:6:1;36207:30;36204:50;;;36250:1;36247;36240:12;36204:50;36273:60;36325:7;36316:6;36305:9;36301:22;36273:60;:::i;36344:557::-;36601:6;36593;36589:19;36578:9;36571:38;36645:3;36640:2;36629:9;36625:18;36618:31;36552:4;36672:46;36713:3;36702:9;36698:19;36690:6;36672:46;:::i;:::-;-1:-1:-1;;;;;36758:6:1;36754:31;36749:2;36738:9;36734:18;36727:59;36834:9;36826:6;36822:22;36817:2;36806:9;36802:18;36795:50;36862:33;36888:6;36880;36862:33;:::i;38078:128::-;38118:3;38149:1;38145:6;38142:1;38139:13;38136:39;;;38155:18;;:::i;:::-;-1:-1:-1;38191:9:1;;38078:128::o;38978:168::-;39018:7;39084:1;39080;39076:6;39072:14;39069:1;39066:21;39061:1;39054:9;39047:17;39043:45;39040:71;;;39091:18;;:::i;:::-;-1:-1:-1;39131:9:1;;38978:168::o;39151:274::-;39280:3;39318:6;39312:13;39334:53;39380:6;39375:3;39368:4;39360:6;39356:17;39334:53;:::i;:::-;39403:16;;;;;39151:274;-1:-1:-1;;39151:274:1:o;39430:261::-;39609:2;39598:9;39591:21;39572:4;39629:56;39681:2;39670:9;39666:18;39658:6;39629:56;:::i;39696:289::-;39871:6;39860:9;39853:25;39914:2;39909;39898:9;39894:18;39887:30;39834:4;39934:45;39975:2;39964:9;39960:18;39952:6;39934:45;:::i;41033:414::-;41235:2;41217:21;;;41274:2;41254:18;;;41247:30;41313:34;41308:2;41293:18;;41286:62;-1:-1:-1;;;41379:2:1;41364:18;;41357:48;41437:3;41422:19;;41033:414::o;41452:127::-;41513:10;41508:3;41504:20;41501:1;41494:31;41544:4;41541:1;41534:15;41568:4;41565:1;41558:15;41584:120;41624:1;41650;41640:35;;41655:18;;:::i;:::-;-1:-1:-1;41689:9:1;;41584:120::o;41709:112::-;41741:1;41767;41757:35;;41772:18;;:::i;:::-;-1:-1:-1;41806:9:1;;41709:112::o;41826:719::-;42129:6;42121;42117:19;42106:9;42099:38;42173:3;42168:2;42157:9;42153:18;42146:31;42080:4;42200:46;42241:3;42230:9;42226:19;42218:6;42200:46;:::i;:::-;-1:-1:-1;;;;;42286:6:1;42282:31;42277:2;42266:9;42262:18;42255:59;42362:9;42354:6;42350:22;42345:2;42334:9;42330:18;42323:50;42396:33;42422:6;42414;42396:33;:::i;:::-;42382:47;;42478:9;42470:6;42466:22;42460:3;42449:9;42445:19;42438:51;42506:33;42532:6;42524;42506:33;:::i;42550:786::-;42961:25;42956:3;42949:38;42931:3;43016:6;43010:13;43032:62;43087:6;43082:2;43077:3;43073:12;43066:4;43058:6;43054:17;43032:62;:::i;:::-;-1:-1:-1;;;43153:2:1;43113:16;;;43145:11;;;43138:40;43203:13;;43225:63;43203:13;43274:2;43266:11;;43259:4;43247:17;;43225:63;:::i;:::-;43308:17;43327:2;43304:26;;42550:786;-1:-1:-1;;;;42550:786:1:o;45287:840::-;45636:6;45628;45624:19;45613:9;45606:38;45680:3;45675:2;45664:9;45660:18;45653:31;45587:4;45707:46;45748:3;45737:9;45733:19;45725:6;45707:46;:::i;:::-;45801:9;45793:6;45789:22;45784:2;45773:9;45769:18;45762:50;45835:33;45861:6;45853;45835:33;:::i;:::-;-1:-1:-1;;;;;45942:15:1;;;45937:2;45922:18;;45915:43;45995:15;;45989:3;45974:19;;45967:44;46048:22;;;45895:3;46027:19;;46020:51;45821:47;-1:-1:-1;46088:33:1;45821:47;46106:6;46088:33;:::i;:::-;46080:41;45287:840;-1:-1:-1;;;;;;;;;45287:840:1:o;46132:489::-;-1:-1:-1;;;;;46401:15:1;;;46383:34;;46453:15;;46448:2;46433:18;;46426:43;46500:2;46485:18;;46478:34;;;46548:3;46543:2;46528:18;;46521:31;;;46326:4;;46569:46;;46595:19;;46587:6;46569:46;:::i;:::-;46561:54;46132:489;-1:-1:-1;;;;;;46132:489:1:o;46626:249::-;46695:6;46748:2;46736:9;46727:7;46723:23;46719:32;46716:52;;;46764:1;46761;46754:12;46716:52;46796:9;46790:16;46815:30;46839:5;46815:30;:::i;47225:136::-;47264:3;47292:5;47282:39;;47301:18;;:::i;:::-;-1:-1:-1;;;47337:18:1;;47225:136::o;49163:127::-;49224:10;49219:3;49215:20;49212:1;49205:31;49255:4;49252:1;49245:15;49279:4;49276:1;49269:15

Swarm Source

ipfs://9d435277c4fd257096e99d5ca0418c42cb647649db9f698ef6167b57e72579db
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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